diff --git a/.codespell_ignorelines b/.codespell_ignorelines deleted file mode 100644 index ae00dfdf8e..0000000000 --- a/.codespell_ignorelines +++ /dev/null @@ -1 +0,0 @@ - diff --git a/.codespell_ignorewords b/.codespell_ignorewords new file mode 100644 index 0000000000..b03acdedca --- /dev/null +++ b/.codespell_ignorewords @@ -0,0 +1,5 @@ + nam + sherif + falsy + medias + strager diff --git a/.codespellrc b/.codespellrc index f12f26b4c9..3e5e3ff0f8 100644 --- a/.codespellrc +++ b/.codespellrc @@ -1,4 +1,4 @@ [codespell] -exclude-file=.codespell_ignorelines -check-hidden=True -ignore-words-list = sherif +check-hidden = True +skip = .git,*.js,*.js.map,*.css,*.css.map,*.html,*.po,*.pot,uv.lock,*.log,*.svg +ignore-words = .codespell_ignorewords diff --git a/.flake8 b/.flake8 index 4907a2f6d6..b80d86a0fd 100644 --- a/.flake8 +++ b/.flake8 @@ -1,7 +1,8 @@ [flake8] # Exclude the grpc generated code -exclude = ./manim/grpc/gen/* -max-complexity = 15 +exclude = ./manim/grpc/gen/*, __pycache__,.git, +per-file-ignores = __init__.py:F401 +max-complexity = 29 max-line-length = 88 statistics = True # Prevents some flake8-rst-docstrings errors @@ -9,7 +10,7 @@ rst-roles = attr,class,func,meth,mod,obj,ref,doc,exc rst-directives = manim, SEEALSO, seealso docstring-convention=numpy -select = A,A00,B,B9,C4,C90,D,E,F,F,PT,RST,SIM,W +select = A,A00,B,B9,C4,C90,D,E,F,F,PT,RST,SIM,W,F401 # General Compatibility extend-ignore = E203, W503, D202, D212, D213, D404 @@ -17,18 +18,18 @@ extend-ignore = E203, W503, D202, D212, D213, D404 # Misc F401, F403, F405, F841, E501, E731, E402, F811, F821, + # multiple statements on one line (overload) + E704, + # Plug-in: flake8-builtins A001, A002, A003, # Plug-in: flake8-bugbear - B006, B007, B008, B009, B010, + B006, B007, B008, B009, B010, B903, B950, # Plug-in: flake8-simplify SIM105, SIM106, SIM119, - # Plug-in: flake8-comprehensions - C901 - # Plug-in: flake8-pytest-style PT001, PT004, PT006, PT011, PT018, PT022, PT023, @@ -40,4 +41,4 @@ extend-ignore = E203, W503, D202, D212, D213, D404 # Plug-in: flake8-rst-docstrings RST201, RST203, RST210, RST212, RST213, RST215, - RST301, RST303, + RST301, RST303, RST499 diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 0000000000..bfe85b8cae --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,2 @@ +# Switched to ruff format: +24025b60d57301b0a59754c38d77bccd8ed69feb diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index a3fb7d05ed..f575567e6f 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -70,14 +70,5 @@ PASTE HERE -
FFMPEG - -Output of `ffmpeg -version`: - -``` -PASTE HERE -``` -
- ## Additional comments diff --git a/.github/ISSUE_TEMPLATE/installation_issue.md b/.github/ISSUE_TEMPLATE/installation_issue.md index b3e6d423c7..6a720f0f49 100644 --- a/.github/ISSUE_TEMPLATE/installation_issue.md +++ b/.github/ISSUE_TEMPLATE/installation_issue.md @@ -11,7 +11,7 @@ assignees: '' - [ ] I have followed the latest version of the [installation instructions](https://docs.manim.community/en/stable/installation.html). -- [ ] I have checked the [troubleshooting page](https://docs.manim.community/en/stable/installation/troubleshooting.html) and my problem is either not mentioned there, +- [ ] I have checked the [installation FAQ](https://docs.manim.community/en/stable/faq/installation.html) and my problem is either not mentioned there, or the solution given there does not help. ## Description of error @@ -53,14 +53,5 @@ PASTE HERE -
FFMPEG - -Output of `ffmpeg -version`: - -``` -PASTE HERE -``` -
- ## Additional comments diff --git a/.github/ISSUE_TEMPLATE/suggestion.md b/.github/ISSUE_TEMPLATE/suggestion.md deleted file mode 100644 index 0d758dd5d8..0000000000 --- a/.github/ISSUE_TEMPLATE/suggestion.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -name: Suggestion -about: Make a suggestion for the enhancement of existing features -title: "" -labels: enhancement -assignees: '' - ---- - -## Enhancement proposal - - - -## Additional comments - diff --git a/.github/codeql.yml b/.github/codeql.yml new file mode 100644 index 0000000000..be207a077c --- /dev/null +++ b/.github/codeql.yml @@ -0,0 +1,16 @@ +query-filters: + - exclude: + id: py/init-calls-subclass + - exclude: + id: py/unexpected-raise-in-special-method + - exclude: + id: py/modification-of-locals + - exclude: + id: py/multiple-calls-to-init + - exclude: + id: py/missing-call-to-init +paths: + - manim +paths-ignore: + - tests/ + - example_scenes/ diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 0000000000..147079c447 --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,11 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" + ignore: + - dependency-name: "*" + update-types: + - "version-update:semver-minor" + - "version-update:semver-patch" diff --git a/.github/manimdependency.json b/.github/manimdependency.json index 32e62e7ecf..93827c1502 100644 --- a/.github/manimdependency.json +++ b/.github/manimdependency.json @@ -4,7 +4,10 @@ "standalone", "preview", "doublestroke", - "ms", + "count1to", + "multitoc", + "prelim2e", + "ragged2e", "everysel", "setspace", "rsfs", @@ -29,7 +32,10 @@ "standalone", "preview", "doublestroke", - "ms", + "count1to", + "multitoc", + "prelim2e", + "ragged2e", "everysel", "setspace", "rsfs", diff --git a/.github/scripts/ci_build_cairo.py b/.github/scripts/ci_build_cairo.py new file mode 100644 index 0000000000..469db7b452 --- /dev/null +++ b/.github/scripts/ci_build_cairo.py @@ -0,0 +1,209 @@ +# Logic is as follows: +# 1. Download cairo source code: https://cairographics.org/releases/cairo-.tar.xz +# 2. Verify the downloaded file using the sha256sums file: https://cairographics.org/releases/cairo-.tar.xz.sha256sum +# 3. Extract the downloaded file. +# 4. Create a virtual environment and install meson and ninja. +# 5. Run meson build in the extracted directory. Also, set required prefix. +# 6. Run meson compile -C build. +# 7. Run meson install -C build. + +import hashlib +import logging +import os +import subprocess +import sys +import tarfile +import tempfile +import typing +import urllib.request +from contextlib import contextmanager +from pathlib import Path +from sys import stdout + +CAIRO_VERSION = "1.18.0" +CAIRO_URL = f"https://cairographics.org/releases/cairo-{CAIRO_VERSION}.tar.xz" +CAIRO_SHA256_URL = f"{CAIRO_URL}.sha256sum" + +VENV_NAME = "meson-venv" +BUILD_DIR = "build" +INSTALL_PREFIX = Path(__file__).parent.parent.parent / "third_party" / "cairo" + +logging.basicConfig(level=logging.INFO, format="%(asctime)s %(levelname)s %(message)s") +logger = logging.getLogger(__name__) + + +def is_ci(): + return os.getenv("CI", None) is not None + + +def download_file(url, path): + logger.info(f"Downloading {url} to {path}") + block_size = 1024 * 1024 + with urllib.request.urlopen(url) as response, open(path, "wb") as file: + while True: + data = response.read(block_size) + if not data: + break + file.write(data) + + +def verify_sha256sum(path, sha256sum): + with open(path, "rb") as file: + file_hash = hashlib.sha256(file.read()).hexdigest() + if file_hash != sha256sum: + raise Exception("SHA256SUM does not match") + + +def extract_tar_xz(path, directory): + with tarfile.open(path) as file: + file.extractall(directory) + + +def run_command(command, cwd=None, env=None): + process = subprocess.Popen(command, cwd=cwd, env=env) + process.communicate() + if process.returncode != 0: + raise Exception("Command failed") + + +@contextmanager +def gha_group(title: str) -> typing.Generator: + if not is_ci(): + yield + return + print(f"\n::group::{title}") + stdout.flush() + try: + yield + finally: + print("::endgroup::") + stdout.flush() + + +def set_env_var_gha(name: str, value: str) -> None: + if not is_ci(): + return + env_file = os.getenv("GITHUB_ENV", None) + if env_file is None: + return + with open(env_file, "a") as file: + file.write(f"{name}={value}\n") + stdout.flush() + + +def get_ld_library_path(prefix: Path) -> str: + # given a prefix, the ld library path can be found at + # /lib/* or sometimes just /lib + # this function returns the path to the ld library path + + # first, check if the ld library path exists at /lib/* + ld_library_paths = list(prefix.glob("lib/*")) + if len(ld_library_paths) == 1: + return ld_library_paths[0].absolute().as_posix() + + # if the ld library path does not exist at /lib/*, + # return /lib + ld_library_path = prefix / "lib" + if ld_library_path.exists(): + return ld_library_path.absolute().as_posix() + return "" + + +def main(): + if sys.platform == "win32": + logger.info("Skipping build on windows") + return + + with tempfile.TemporaryDirectory() as tmpdir: + with gha_group("Downloading and Extracting Cairo"): + logger.info(f"Downloading cairo version {CAIRO_VERSION}") + download_file(CAIRO_URL, os.path.join(tmpdir, "cairo.tar.xz")) + + logger.info("Downloading cairo sha256sum") + download_file(CAIRO_SHA256_URL, os.path.join(tmpdir, "cairo.sha256sum")) + + logger.info("Verifying cairo sha256sum") + with open(os.path.join(tmpdir, "cairo.sha256sum")) as file: + sha256sum = file.read().split()[0] + verify_sha256sum(os.path.join(tmpdir, "cairo.tar.xz"), sha256sum) + + logger.info("Extracting cairo") + extract_tar_xz(os.path.join(tmpdir, "cairo.tar.xz"), tmpdir) + + with gha_group("Installing meson and ninja"): + logger.info("Creating virtual environment") + run_command([sys.executable, "-m", "venv", os.path.join(tmpdir, VENV_NAME)]) + + logger.info("Installing meson and ninja") + run_command( + [ + os.path.join(tmpdir, VENV_NAME, "bin", "pip"), + "install", + "meson", + "ninja", + ] + ) + + env_vars = { + # add the venv bin directory to PATH so that meson can find ninja + "PATH": f"{os.path.join(tmpdir, VENV_NAME, 'bin')}{os.pathsep}{os.environ['PATH']}", + } + + with gha_group("Building and Installing Cairo"): + logger.info("Running meson setup") + run_command( + [ + os.path.join(tmpdir, VENV_NAME, "bin", "meson"), + "setup", + BUILD_DIR, + f"--prefix={INSTALL_PREFIX.absolute().as_posix()}", + "--buildtype=release", + "-Dtests=disabled", + ], + cwd=os.path.join(tmpdir, f"cairo-{CAIRO_VERSION}"), + env=env_vars, + ) + + logger.info("Running meson compile") + run_command( + [ + os.path.join(tmpdir, VENV_NAME, "bin", "meson"), + "compile", + "-C", + BUILD_DIR, + ], + cwd=os.path.join(tmpdir, f"cairo-{CAIRO_VERSION}"), + env=env_vars, + ) + + logger.info("Running meson install") + run_command( + [ + os.path.join(tmpdir, VENV_NAME, "bin", "meson"), + "install", + "-C", + BUILD_DIR, + ], + cwd=os.path.join(tmpdir, f"cairo-{CAIRO_VERSION}"), + env=env_vars, + ) + + logger.info(f"Successfully built cairo and installed it to {INSTALL_PREFIX}") + + +if __name__ == "__main__": + if "--set-env-vars" in sys.argv: + with gha_group("Setting environment variables"): + # append the pkgconfig directory to PKG_CONFIG_PATH + set_env_var_gha( + "PKG_CONFIG_PATH", + f"{Path(get_ld_library_path(INSTALL_PREFIX), 'pkgconfig').as_posix()}{os.pathsep}" + f'{os.getenv("PKG_CONFIG_PATH", "")}', + ) + set_env_var_gha( + "LD_LIBRARY_PATH", + f"{get_ld_library_path(INSTALL_PREFIX)}{os.pathsep}" + f'{os.getenv("LD_LIBRARY_PATH", "")}', + ) + sys.exit(0) + main() diff --git a/.github/workflows/cffconvert.yml b/.github/workflows/cffconvert.yml index 707a71c4b2..7144363717 100644 --- a/.github/workflows/cffconvert.yml +++ b/.github/workflows/cffconvert.yml @@ -11,7 +11,7 @@ jobs: runs-on: ubuntu-latest steps: - name: Check out a copy of the repository - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Check whether the citation metadata from CITATION.cff is valid uses: citation-file-format/cffconvert-github-action@2.0.0 diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 1562099233..1d59b4661d 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -18,62 +18,73 @@ jobs: env: DISPLAY: :0 PYTEST_ADDOPTS: "--color=yes" # colors in pytest - GLCONTEXT_WIN_LIBGL: C:\msys64\mingw64\bin\opengl32.dll + PYTHONIOENCODING: "utf8" strategy: fail-fast: false matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - python: ['3.7', '3.8', '3.9', '3.10'] + os: [ubuntu-22.04, macos-13, windows-latest] + python: ["3.9", "3.10", "3.11", "3.12", "3.13"] steps: - name: Checkout the repository - uses: actions/checkout@v2 + uses: actions/checkout@v4 - name: Setup Python ${{ matrix.python }} - uses: actions/setup-python@v2 + uses: actions/setup-python@v5 with: python-version: ${{ matrix.python }} - - name: Install Poetry - run: | - pip install --user poetry - - - name: Setup macOS PATH - if: runner.os == 'macOS' - run: | - echo "$HOME/.local/bin" >> $GITHUB_PATH + - name: Install uv + uses: astral-sh/setup-uv@v5 + with: + enable-cache: true - name: Setup cache variables shell: bash id: cache-vars run: | - echo "::set-output name=poetry-venv-dir::$(poetry config virtualenvs.path)" - echo "::set-output name=date::$(/bin/date -u "+%m%w%Y")" + echo "date=$(/bin/date -u "+%m%w%Y")" >> $GITHUB_OUTPUT - - name: Setup Poetry cache - uses: actions/cache@v2 + - name: Install system dependencies (Linux) + if: runner.os == 'Linux' + uses: awalsh128/cache-apt-pkgs-action@latest with: - path: ${{ steps.cache-vars.outputs.poetry-venv-dir }} - key: ${{ runner.os }}-poetry-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml') }}-${{ hashFiles('poetry.lock') }} + packages: python3-opengl libpango1.0-dev xvfb freeglut3-dev + version: 1.0 - - name: Install and cache ffmpeg (all OS) - uses: FedericoCarboni/setup-ffmpeg@v1.1.0 + - name: Install Texlive (Linux) + if: runner.os == 'Linux' + uses: teatimeguest/setup-texlive-action@v3 with: - token: ${{ secrets.GITHUB_TOKEN }} - id: setup-ffmpeg + cache: true + packages: scheme-basic fontspec inputenc fontenc tipa mathrsfs calligra xcolor standalone preview doublestroke ms everysel setspace rsfs relsize ragged2e fundus-calligra microtype wasysym physics dvisvgm jknapltx wasy cm-super babel-english gnu-freefont mathastext cbfonts-fd xetex - - name: Install system dependencies (Linux) + - name: Start virtual display (Linux) if: runner.os == 'Linux' run: | - sudo apt update - sudo apt-get -y install texlive texlive-latex-extra texlive-fonts-extra texlive-latex-recommended texlive-science texlive-fonts-extra tipa python-opengl libpango1.0-dev xvfb # start xvfb in background sudo /usr/bin/Xvfb $DISPLAY -screen 0 1280x1024x24 & + - name: Setup Cairo Cache + uses: actions/cache@v4 + id: cache-cairo + if: runner.os == 'Linux' || runner.os == 'macOS' + with: + path: ${{ github.workspace }}/third_party + key: ${{ runner.os }}-dependencies-cairo-${{ hashFiles('.github/scripts/ci_build_cairo.py') }} + + - name: Build and install Cairo (Linux and macOS) + if: (runner.os == 'Linux' || runner.os == 'macOS') && steps.cache-cairo.outputs.cache-hit != 'true' + run: python .github/scripts/ci_build_cairo.py + + - name: Set env vars for Cairo (Linux and macOS) + if: runner.os == 'Linux' || runner.os == 'macOS' + run: python .github/scripts/ci_build_cairo.py --set-env-vars + - name: Setup macOS cache + uses: actions/cache@v4 id: cache-macos if: runner.os == 'macOS' - uses: actions/cache@v2 with: path: ${{ github.workspace }}/macos-cache key: ${{ runner.os }}-dependencies-tinytex-${{ hashFiles('.github/manimdependency.json') }}-${{ steps.cache-vars.outputs.date }}-1 @@ -97,35 +108,22 @@ jobs: export PATH="$oriPath" echo "Completed TinyTeX" - - name: Install cairo (MacOS) - if: runner.os == 'macOS' - run: brew install cairo - - name: Add macOS dependencies to PATH if: runner.os == 'macOS' shell: bash run: | echo "/Library/TeX/texbin" >> $GITHUB_PATH - echo "$HOME/.poetry/bin" >> $GITHUB_PATH echo "$PWD/macos-cache/TinyTeX/bin/universal-darwin" >> $GITHUB_PATH - name: Setup Windows cache id: cache-windows if: runner.os == 'Windows' - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ${{ github.workspace }}\ManimCache key: ${{ runner.os }}-dependencies-tinytex-${{ hashFiles('.github/manimdependency.json') }}-${{ steps.cache-vars.outputs.date }}-1 - - name: Setup MSYS2 (Windows) - if: runner.os == 'Windows' - uses: msys2/setup-msys2@v2 - with: - release: false - msystem: MINGW64 - path-type: inherit - install: >- - mingw-w64-x86_64-mesa + - uses: ssciwr/setup-mesa-dist-win@v2 - name: Install system dependencies (Windows) if: runner.os == 'Windows' && steps.cache-windows.outputs.cache-hit != 'true' @@ -133,41 +131,32 @@ jobs: $tinyTexPackages = $(python -c "import json;print(' '.join(json.load(open('.github/manimdependency.json'))['windows']['tinytex']))") -Split ' ' $OriPath = $env:PATH echo "Install Tinytex" - Invoke-WebRequest "https://github.com/yihui/tinytex-releases/releases/download/daily/TinyTeX-1.zip" -O "$($env:TMP)\TinyTex.zip" + Invoke-WebRequest "https://github.com/yihui/tinytex-releases/releases/download/daily/TinyTeX-1.zip" -OutFile "$($env:TMP)\TinyTex.zip" Expand-Archive -LiteralPath "$($env:TMP)\TinyTex.zip" -DestinationPath "$($PWD)\ManimCache\LatexWindows" - $env:Path = "$($PWD)\ManimCache\LatexWindows\TinyTeX\bin\win32;$($env:PATH)" + $env:Path = "$($PWD)\ManimCache\LatexWindows\TinyTeX\bin\windows;$($env:PATH)" tlmgr update --self - foreach ($c in $tinyTexPackages){ - $c=$c.Trim() - tlmgr install $c - } + tlmgr install $tinyTexPackages $env:PATH=$OriPath echo "Completed Latex" - name: Add Windows dependencies to PATH if: runner.os == 'Windows' run: | - $env:Path += ";" + "$($PWD)\ManimCache\LatexWindows\TinyTeX\bin\win32" - $env:Path = "$env:USERPROFILE\.poetry\bin;$($env:PATH)" - $env:PATH = "C:\msys64\mingw64\bin;$($env:PATH)" + $env:Path += ";" + "$($PWD)\ManimCache\LatexWindows\TinyTeX\bin\windows" echo "$env:Path" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append - - name: Install manim + - name: Install dependencies and manim run: | - poetry config experimental.new-installer false - poetry install -E webgl_renderer + uv sync --all-extras --locked - name: Run tests run: | - poetry run pytest + uv run python -m pytest - name: Run module doctests run: | - poetry run pytest --cov-append --doctest-modules --ignore-glob="*opengl*" manim + uv run python -m pytest -v --cov-append --ignore-glob="*opengl*" --doctest-modules manim - name: Run doctests in rst files run: | - cd docs && pip install -r requirements.txt && poetry run make doctest O=-tskip-manim - - - name: Upload coverage - uses: codecov/codecov-action@v1 + cd docs && uv run make doctest O=-tskip-manim diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml new file mode 100644 index 0000000000..2ba46fee14 --- /dev/null +++ b/.github/workflows/codeql.yml @@ -0,0 +1,42 @@ +name: "CodeQL" + +on: + push: + branches: [ "main" ] + pull_request: + branches: [ "main" ] + schedule: + - cron: "21 16 * * 3" + +jobs: + analyze: + name: Analyze + runs-on: ubuntu-latest + permissions: + actions: read + contents: read + security-events: write + + strategy: + fail-fast: false + matrix: + language: [ python ] + + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Initialize CodeQL + uses: github/codeql-action/init@v3 + with: + languages: ${{ matrix.language }} + config-file: ./.github/codeql.yml + queries: +security-and-quality + + - name: Autobuild + uses: github/codeql-action/autobuild@v3 + + - name: Perform CodeQL Analysis + uses: github/codeql-action/analyze@v3 + with: + category: "/language:${{ matrix.language }}" diff --git a/.github/workflows/publish-docker.yml b/.github/workflows/publish-docker.yml new file mode 100644 index 0000000000..4dd14f281a --- /dev/null +++ b/.github/workflows/publish-docker.yml @@ -0,0 +1,72 @@ +name: Publish Docker Image + +on: + push: + branches: + - main + release: + types: [released] + +jobs: + docker-latest: + runs-on: ubuntu-latest + if: github.event_name != 'release' + steps: + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Build and push + uses: docker/build-push-action@v6 + with: + platforms: linux/arm64,linux/amd64 + push: true + file: docker/Dockerfile + tags: | + manimcommunity/manim:latest + + docker-release: + runs-on: ubuntu-latest + if: github.event_name == 'release' + steps: + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + + - name: Login to DockerHub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKERHUB_USERNAME }} + password: ${{ secrets.DOCKERHUB_TOKEN }} + + - name: Get Version + id: create_release + shell: python + env: + tag_act: ${{ github.ref }} + run: | + import os + ref_tag = os.getenv('tag_act').split('/')[-1] + with open(os.getenv('GITHUB_OUTPUT'), 'w') as f: + print(f"tag_name={ref_tag}", file=f) + + - name: Build and push + uses: docker/build-push-action@v6 + with: + platforms: linux/arm64,linux/amd64 + push: true + file: docker/Dockerfile + tags: | + manimcommunity/manim:stable + manimcommunity/manim:latest + manimcommunity/manim:${{ steps.create_release.outputs.tag_name }} diff --git a/.github/workflows/python-publish.yml b/.github/workflows/python-publish.yml index d091c857e8..b74c25b597 100644 --- a/.github/workflows/python-publish.yml +++ b/.github/workflows/python-publish.yml @@ -6,31 +6,31 @@ on: jobs: release: + name: "Publish release" runs-on: ubuntu-latest + environment: release + permissions: + id-token: write + steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 - - name: Set up Python 3.8 - uses: actions/setup-python@v2 + - name: Set up Python 3.13 + uses: actions/setup-python@v5 with: - python-version: 3.8 - - - name: Install dependencies - run: python -m pip install --upgrade poetry + python-version: 3.13 - # TODO: Set PYPI_API_TOKEN to api token from pip in secrets - - name: Configure pypi credentials - env: - PYPI_API_TOKEN: ${{ secrets.PYPI_API_TOKEN }} - run: poetry config http-basic.pypi __token__ "$PYPI_API_TOKEN" + - name: Install uv + uses: astral-sh/setup-uv@v5 - - name: Publish release to pypi + - name: Build and push release to PyPI run: | - poetry publish --build - poetry build + uv sync + uv build + uv publish - name: Store artifacts - uses: actions/upload-artifact@v2 + uses: actions/upload-artifact@v4 with: path: dist/*.tar.gz name: manim.tar.gz @@ -54,8 +54,9 @@ jobs: url = f"https://api.github.com/repos/ManimCommunity/manim/releases/tags/{ref_tag}" c = requests.get(url,headers=headers) upload_url=c.json()['upload_url'] - print(f"::set-output name=upload_url::{upload_url}") - print(f"::set-output name=tag_name::{ref_tag[1:]}") + with open(os.getenv('GITHUB_OUTPUT'), 'w') as f: + print(f"upload_url={upload_url}", file=f) + print(f"tag_name={ref_tag[1:]}", file=f) - name: Upload Release Asset id: upload-release diff --git a/.github/workflows/release-publish-documentation.yml b/.github/workflows/release-publish-documentation.yml new file mode 100644 index 0000000000..3983a69800 --- /dev/null +++ b/.github/workflows/release-publish-documentation.yml @@ -0,0 +1,87 @@ +name: Publish downloadable documentation + +on: + release: + types: [released] + workflow_dispatch: + +jobs: + build-and-publish-htmldocs: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Set up Python + uses: actions/setup-python@v5 + with: + python-version: 3.13 + + - name: Install uv + uses: astral-sh/setup-uv@v5 + + - name: Install system dependencies + run: | + sudo apt update && sudo apt install -y \ + pkg-config libcairo-dev libpango1.0-dev wget fonts-roboto + wget -qO- "https://yihui.org/tinytex/install-bin-unix.sh" | sh + echo ${HOME}/.TinyTeX/bin/x86_64-linux >> $GITHUB_PATH + + - name: Install LaTeX and Python dependencies + run: | + tlmgr update --self + tlmgr install \ + babel-english ctex doublestroke dvisvgm frcursive fundus-calligra jknapltx \ + mathastext microtype physics preview ragged2e relsize rsfs setspace standalone \ + wasy wasysym + uv sync + + - name: Build and package documentation + run: | + cd docs/ + uv run make html + cd build/html/ + tar -czvf ../html-docs.tar.gz * + + - name: Store artifacts + uses: actions/upload-artifact@v4 + with: + path: ${{ github.workspace }}/docs/build/html-docs.tar.gz + name: html-docs.tar.gz + + - name: Install Dependency + run: pip install requests + + - name: Get Upload URL + if: github.event == 'release' + id: create_release + shell: python + env: + access_token: ${{ secrets.GITHUB_TOKEN }} + tag_act: ${{ github.ref }} + run: | + import requests + import os + ref_tag = os.getenv('tag_act').split('/')[-1] + access_token = os.getenv('access_token') + headers = { + "Accept":"application/vnd.github.v3+json", + "Authorization": f"token {access_token}" + } + url = f"https://api.github.com/repos/ManimCommunity/manim/releases/tags/{ref_tag}" + c = requests.get(url,headers=headers) + upload_url=c.json()['upload_url'] + with open(os.getenv('GITHUB_OUTPUT'), 'w') as f: + print(f"upload_url={upload_url}", file=f) + print(f"tag_name={ref_tag[1:]}", file=f) + + - name: Upload Release Asset + if: github.event == 'release' + id: upload-release + uses: actions/upload-release-asset@v1 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + upload_url: ${{ steps.create_release.outputs.upload_url }} + asset_path: ${{ github.workspace }}/docs/build/html-docs.tar.gz + asset_name: manim-htmldocs-${{ steps.create_release.outputs.tag_name }}.tar.gz + asset_content_type: application/gzip diff --git a/.gitignore b/.gitignore index 153717f347..abec5da495 100644 --- a/.gitignore +++ b/.gitignore @@ -131,3 +131,6 @@ dist/ /media_dir.txt # ^TODO: Remove the need for this with a proper config file + +# Ignore the built dependencies +third_party/* diff --git a/.mypy.ini b/.mypy.ini deleted file mode 100644 index 591ec89451..0000000000 --- a/.mypy.ini +++ /dev/null @@ -1,88 +0,0 @@ -[mypy] -show_error_codes = True - -# ignore most files; should be checked once proper types have been implemented -[mypy-manim.__main__] -ignore_errors = True - -[mypy-manim.camera.*] -ignore_errors = True - -[mypy-manim.scene.*] -ignore_errors = True - -[mypy-manim.cli.cfg.*] -ignore_errors = True - -[mypy-manim.mobject.*] -ignore_errors = True - -[mypy-manim._config.*] -ignore_errors = True - -[mypy-manim.utils.*] -ignore_errors = True - -[mypy-manim.animation.*] -ignore_errors = True - -# ---------------- We can't properly type this ------------------------ - -[mypy-manim.grpc.*] -ignore_errors = True - -# ---------------- Stubless imported Modules -------------------------- - -# We should be able to create stubs for this or type hint it -[mypy-manimpango] -ignore_missing_imports = True - -# Has stubs in 3.8 -[mypy-numpy] -ignore_missing_imports = True - -# Has stubs in 3.8 -[mypy-pydub] -ignore_missing_imports = True - -[mypy-matplotlib] -ignore_missing_imports = True - -[mypy-scipy.*] -ignore_missing_imports = True - -[mypy-networkx] -ignore_missing_imports = True - -[mypy-git] -ignore_missing_imports = True - -[mypy-moderngl.*] -ignore_missing_imports = True - -[mypy-moderngl_window.*] -ignore_missing_imports = True - -[mypy-colour] -ignore_missing_imports = True - -[mypy-dearpygui.*] -ignore_missing_imports = True - -[mypy-screeninfo] -ignore_missing_imports = True - -[mypy-IPython.*] -ignore_missing_imports = True - -[mypy-watchdog.*] -ignore_missing_imports = True - -[mypy-tqdm] -ignore_missing_imports = True - -[mypy-mapbox_earcut] -ignore_missing_imports = True - -[mypy-click_default_group] -ignore_missing_imports = True diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 032c6143b4..fdc48e8371 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,9 +1,9 @@ -default_stages: [commit, push] +default_stages: [pre-commit, pre-push] fail_fast: false exclude: ^(manim/grpc/gen/|docs/i18n/) repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.1.0 + rev: v5.0.0 hooks: - id: check-ast name: Validate Python @@ -11,57 +11,33 @@ repos: - id: mixed-line-ending - id: end-of-file-fixer - id: check-toml - name: Validate Poetry - - repo: https://github.com/pycqa/isort - rev: 5.10.1 - hooks: - - id: isort - name: isort (python) - - id: isort - name: isort (cython) - types: [cython] - - id: isort - name: isort (pyi) - types: [pyi] - - repo: https://github.com/asottile/pyupgrade - rev: v2.31.1 - hooks: - - id: pyupgrade - name: Update code to new python versions - args: [--py37-plus] - - repo: https://github.com/pre-commit/pygrep-hooks - rev: v1.9.0 - hooks: - - id: python-check-blanket-noqa - name: Precision flake ignores - - repo: https://github.com/psf/black - rev: 22.1.0 - hooks: - - id: black - - repo: https://github.com/asottile/blacken-docs - rev: v1.12.1 - hooks: - - id: blacken-docs - additional_dependencies: [black==20.8b1] - - repo: https://github.com/asottile/yesqa - rev: v1.3.0 - hooks: - - id: yesqa - name: Remove unneeded flake ignores - - repo: https://github.com/PyCQA/flake8 - rev: 4.0.1 - hooks: - - id: flake8 - additional_dependencies: [flake8-builtins==1.5.3, flake8-bugbear==21.4.3, - flake8-docstrings==1.6.0, flake8-rst-docstrings==0.2.3, - flake8-pytest-style==1.5.0, flake8-simplify==0.14.1, flake8-comprehensions>=3.6.1] + name: Validate pyproject.toml + - repo: https://github.com/astral-sh/ruff-pre-commit + rev: v0.11.0 + hooks: + - id: ruff + name: ruff lint + types: [python] + args: [--exit-non-zero-on-fix] + - id: ruff-format + types: [python] - repo: https://github.com/pre-commit/mirrors-mypy - rev: 'v0.940' + rev: v1.15.0 hooks: - id: mypy - additional_dependencies: [types-decorator, types-docutils, types-requests, types-setuptools] + additional_dependencies: + [ + types-backports, + types-decorator, + types-docutils, + types-requests, + types-setuptools, + ] + files: ^manim/ - repo: https://github.com/codespell-project/codespell - rev: v2.1.0 + rev: v2.4.1 hooks: - id: codespell + files: ^.*\.(py|md|rst)$ + args: ["-L", "medias,nam"] diff --git a/.readthedocs.yml b/.readthedocs.yml index 87f178a53b..9b66a51cf3 100644 --- a/.readthedocs.yml +++ b/.readthedocs.yml @@ -1,11 +1,19 @@ version: 2 + +sphinx: + configuration: docs/source/conf.py + build: - image: latest + os: ubuntu-22.04 + + tools: + python: "3.13" + apt_packages: - libpango1.0-dev - - ffmpeg + - graphviz + python: - version: 3.8 install: - requirements: docs/rtd-requirements.txt - requirements: docs/requirements.txt diff --git a/CITATION.cff b/CITATION.cff index 3e5fa0ab7b..9f5fd91613 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -4,10 +4,10 @@ authors: - name: "The Manim Community Developers" cff-version: "1.2.0" -date-released: 2022-03-08 +date-released: 2025-01-20 license: MIT message: "We acknowledge the importance of good software to support research, and we note that research becomes more valuable when it is communicated effectively. To demonstrate the value of Manim, we ask that you cite Manim in your work." title: Manim – Mathematical Animation Framework url: "https://www.manim.community/" -version: "v0.15.1" +version: "v0.19.0" ... diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index f57e842b7e..bbe20e6004 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -152,6 +152,7 @@ Examples of conflicts of interest include: * The reporter or reported person is a maintainer who regularly reviews your contributions * The reporter or reported person is your metamour. * The reporter or reported person is your family member + Committee members do not need to state why they have a conflict of interest, only that one exists. Other team members should not ask why the person has a conflict of interest. Anyone who has a conflict of interest will remove themselves from the discussion of the incident, and recluse themselves from voting on a response to the report. diff --git a/LICENSE.community b/LICENSE.community index 8e35bc50b2..c1c149f1eb 100644 --- a/LICENSE.community +++ b/LICENSE.community @@ -1,6 +1,6 @@ MIT License -Copyright (c) 2021, the Manim Community Developers +Copyright (c) 2024, the Manim Community Developers Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.md b/README.md index 1b8c3d5bfd..0b3b6b44db 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,8 @@ Manim is an animation engine for explanatory math videos. It's used to create precise animations programmatically, as demonstrated in the videos of [3Blue1Brown](https://www.3blue1brown.com/). -> NOTE: This repository is maintained by the Manim Community and is not associated with Grant Sanderson or 3Blue1Brown in any way (although we are definitely indebted to him for providing his work to the world). If you would like to study how Grant makes his videos, head over to his repository ([3b1b/manim](https://github.com/3b1b/manim)). This fork is updated more frequently than his, and it's recommended to use this fork if you'd like to use Manim for your own projects. +> [!NOTE] +> The community edition of Manim has been forked from 3b1b/manim, a tool originally created and open-sourced by Grant Sanderson, also creator of the 3Blue1Brown educational math videos. While Grant Sanderson’s repository continues to be maintained separately by him, he is not among the maintainers of the community edition. We recommend this version for its continued development, improved features, enhanced documentation, and more active community-driven maintenance. If you would like to study how Grant makes his videos, head over to his repository ([3b1b/manim](https://github.com/3b1b/manim)). ## Table of Contents: @@ -35,7 +36,8 @@ Manim is an animation engine for explanatory math videos. It's used to create pr ## Installation -> **WARNING:** These instructions are for the community version _only_. Trying to use these instructions to install [3b1b/manim](https://github.com/3b1b/manim) or instructions there to install this version will cause problems. Read [this](https://docs.manim.community/en/stable/installation/versions.html) and decide which version you wish to install, then only follow the instructions for your desired version. +> [!CAUTION] +> These instructions are for the community version _only_. Trying to use these instructions to install [3b1b/manim](https://github.com/3b1b/manim) or instructions there to install this version will cause problems. Read [this](https://docs.manim.community/en/stable/faq/installation.html#why-are-there-different-versions-of-manim) and decide which version you wish to install, then only follow the instructions for your desired version. Manim requires a few dependencies that must be installed prior to using it. If you want to try it out first before installing it locally, you can do so @@ -92,7 +94,7 @@ Some other useful flags include: - `-n ` to skip ahead to the `n`'th animation of a scene. - `-f` show the file in the file browser. -For a thorough list of command line arguments, visit the [documentation](https://docs.manim.community/en/stable/tutorials/configuration.html). +For a thorough list of command line arguments, visit the [documentation](https://docs.manim.community/en/stable/guides/configuration.html). ## Documentation @@ -118,8 +120,8 @@ The contribution guide may become outdated quickly; we highly recommend joining [Discord server](https://www.manim.community/discord/) to discuss any potential contributions and keep up to date with the latest developments. -Most developers on the project use `poetry` for management. You'll want to have poetry installed and available in your environment. -Learn more about `poetry` at its [documentation](https://python-poetry.org/docs/) and find out how to install manim with poetry at the [manim dev-installation guide](https://docs.manim.community/en/stable/contributing/development.html) in the manim documentation. +Most developers on the project use `uv` for management. You'll want to have uv installed and available in your environment. +Learn more about `uv` at its [documentation](https://docs.astral.sh/uv/) and find out how to install manim with uv at the [manim dev-installation guide](https://docs.manim.community/en/latest/contributing/development.html) in the manim documentation. ## How to Cite Manim diff --git a/conftest.py b/conftest.py deleted file mode 100644 index 842ab76dd7..0000000000 --- a/conftest.py +++ /dev/null @@ -1,26 +0,0 @@ -# This file is automatically picked by pytest -# while running tests. So, that each test is -# run on difference temporary directories and avoiding -# errors. - -from __future__ import annotations - -# If it is running Doctest the current directory -# is changed because it also tests the config module -# itself. If it's a normal test then it uses the -# tempconfig to change directories. -import pytest -from _pytest.doctest import DoctestItem - -from manim import config, tempconfig - - -@pytest.fixture(autouse=True) -def temp_media_dir(tmpdir, monkeypatch, request): - if isinstance(request.node, DoctestItem): - monkeypatch.chdir(tmpdir) - yield tmpdir - else: - with tempconfig({"media_dir": str(tmpdir)}): - assert config.media_dir == str(tmpdir) - yield tmpdir diff --git a/docker/Dockerfile b/docker/Dockerfile index 309c4cd15b..ba2f436e37 100644 --- a/docker/Dockerfile +++ b/docker/Dockerfile @@ -1,8 +1,7 @@ -FROM python:3.8-slim +FROM python:3.11-slim RUN apt-get update -qq \ && apt-get install --no-install-recommends -y \ - ffmpeg \ build-essential \ gcc \ cmake \ @@ -10,9 +9,14 @@ RUN apt-get update -qq \ libffi-dev \ libpango1.0-dev \ freeglut3-dev \ + ffmpeg \ pkg-config \ make \ - wget + wget \ + ghostscript \ + fonts-noto + +RUN fc-cache -fv # setup a minimal texlive installation COPY docker/texlive-profile.txt /tmp/ @@ -22,23 +26,23 @@ RUN wget -O /tmp/install-tl-unx.tar.gz http://mirror.ctan.org/systems/texlive/tl tar -xzf /tmp/install-tl-unx.tar.gz -C /tmp/install-tl --strip-components=1 && \ /tmp/install-tl/install-tl --profile=/tmp/texlive-profile.txt \ && tlmgr install \ - amsmath babel-english cbfonts-fd cm-super ctex doublestroke dvisvgm everysel \ + amsmath babel-english cbfonts-fd cm-super count1to ctex doublestroke dvisvgm everysel \ fontspec frcursive fundus-calligra gnu-freefont jknapltx latex-bin \ - mathastext microtype ms physics preview ragged2e relsize rsfs \ + mathastext microtype multitoc physics prelim2e preview ragged2e relsize rsfs \ setspace standalone tipa wasy wasysym xcolor xetex xkeyval # clone and build manim COPY . /opt/manim WORKDIR /opt/manim -RUN pip install --no-cache .[jupyterlab,webgl_renderer] +RUN pip install --no-cache .[jupyterlab] RUN pip install -r docs/requirements.txt ARG NB_USER=manimuser ARG NB_UID=1000 -ENV USER ${NB_USER} -ENV NB_UID ${NB_UID} -ENV HOME /manim +ENV USER=${NB_USER} +ENV NB_UID=${NB_UID} +ENV HOME=/manim RUN adduser --disabled-password \ --gecos "Default user" \ diff --git a/manim/cli/new/__init__.py b/docs/html similarity index 100% rename from manim/cli/new/__init__.py rename to docs/html diff --git a/docs/i18n/gettext/changelog/0.14.0-changelog.pot b/docs/i18n/gettext/changelog/0.14.0-changelog.pot index a6c4cb0ae3..d21eb867fd 100644 --- a/docs/i18n/gettext/changelog/0.14.0-changelog.pot +++ b/docs/i18n/gettext/changelog/0.14.0-changelog.pot @@ -255,7 +255,7 @@ msgid ":pr:`2415`: Removed instructions on using and installing Docker in README msgstr "" #: ../../source/changelog/0.14.0-changelog.rst:114 -msgid ":pr:`2414`: Made improvements to the :doc:`configuration` tutorial" +msgid ":pr:`2414`: Made improvements to the :doc:`/guides/configuration` tutorial" msgstr "" #: ../../source/changelog/0.14.0-changelog.rst:117 diff --git a/docs/i18n/gettext/changelog/0.15.2-changelog.pot b/docs/i18n/gettext/changelog/0.15.2-changelog.pot new file mode 100644 index 0000000000..404506e0ab --- /dev/null +++ b/docs/i18n/gettext/changelog/0.15.2-changelog.pot @@ -0,0 +1,426 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Manim \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../source/changelog/0.15.2-changelog.rst:3 +msgid "v0.15.2" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:0 +msgid "Date" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:5 +msgid "April 25, 2022" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:8 +msgid "Contributors" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:10 +msgid "A total of 33 people contributed to this release. People with a '+' by their names authored a patch for the first time." +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:14 +msgid "Bailey Powers +" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:15 +#: ../../source/changelog/0.15.2-changelog.rst:44 +msgid "Benjamin Hackl" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:16 +msgid "Dan Walsh +" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:17 +msgid "Darigov Research" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:18 +#: ../../source/changelog/0.15.2-changelog.rst:46 +msgid "Darylgolden" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:19 +msgid "David Millard +" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:20 +msgid "Hamidreza Hashemi +" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:21 +#: ../../source/changelog/0.15.2-changelog.rst:49 +msgid "Jan-Hendrik Müller" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:22 +#: ../../source/changelog/0.15.2-changelog.rst:50 +msgid "Jason Villanueva" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:23 +msgid "Jonathan Alpert +" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:24 +msgid "Joy Bhalla" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:25 +msgid "Kian Cross +" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:26 +msgid "Luca +" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:27 +msgid "Mohsin Shaikh +" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:28 +#: ../../source/changelog/0.15.2-changelog.rst:53 +msgid "Naveen M K" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:29 +msgid "Prismo +" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:30 +#: ../../source/changelog/0.15.2-changelog.rst:55 +msgid "Ryan McCauley" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:31 +msgid "WillSoltas +" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:32 +#: ../../source/changelog/0.15.2-changelog.rst:56 +msgid "ad_chaos" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:33 +msgid "darkways +" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:34 +msgid "dawn*squirryl +" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:35 +#: ../../source/changelog/0.15.2-changelog.rst:59 +msgid "icedcoffeeee" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:36 +#: ../../source/changelog/0.15.2-changelog.rst:60 +msgid "peaceheis" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:37 +msgid "sparshg" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:38 +msgid "trickypr +" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:41 +msgid "The patches included in this release have been reviewed by the following contributors." +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:45 +msgid "Dan Walsh" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:47 +msgid "GameDungeon" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:48 +msgid "Hugues Devimeux" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:51 +msgid "Jonathan Alpert" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:52 +msgid "Luca" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:54 +msgid "Prismo" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:57 +msgid "darkways" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:58 +msgid "hickmott99" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:63 +msgid "Pull requests merged" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:65 +msgid "A total of 39 pull requests were merged for this release." +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:68 +msgid "New features" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:74 +msgid ":pr:`1975`: Improved CLI help page styling" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:71 +msgid "Updates dependencies on Click and Cloup libraries for CLI help page styling." +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:72 +msgid "Removed the dependency on click-default-group." +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:73 +msgid "Added ``no_args_is_help`` parameter for ``manim render`` to allow easy access to help page." +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:74 +msgid "Added note to ``manim`` help page epilog on how to access other command help pages." +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:77 +msgid ":pr:`2404`: Add :class:`.SpiralIn` Animation" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:77 +msgid "Make :class:`.ManimBanner` to use :class:`.SpiralIn`." +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:79 +msgid ":pr:`2534`: Implement :class:`~.OpenGLImageMobject`" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:82 +msgid ":pr:`2684`: Created a more accessible way to create Angles with line.py angle function - :meth:`.Angle.from_three_points`" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:86 +msgid "Enhancements" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:88 +msgid ":pr:`2062`: Reuse shader wrappers and shader data" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:92 +msgid ":pr:`2642`: Migrated ``file_ops.py`` and ``scene_file_writer.py`` from os.path to Pathlib" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:92 +msgid "In ``file_ops.py`` and ``scene_file_writer.py``: Uses of str type file names have been mostly (see further information) converted to pathlib's Path objects. Uses of ``os.path`` methods have been converted to equivalent pathlib methods." +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:94 +msgid ":pr:`2655`: Fix :func:`.assert_is_mobject_method` when using OpenGL" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:97 +msgid ":pr:`2665`: Improved handling of attributes when using the ``.animate`` syntax" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:102 +msgid ":pr:`2674`: Document and type ``simple_functions.py``" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:101 +msgid "Add documentation for ``simple_functions.py``." +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:102 +msgid "Small additions with some extra clarity for these functions." +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:105 +msgid ":pr:`2693`: Allow using :meth:`.MovingCamera.auto_zoom` without animation" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:105 +msgid "Allows auto zooming camera without having to play an animation by passing an ``animation=False`` argument" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:108 +msgid "Fixed bugs" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:110 +msgid ":pr:`2546`: Fixed a file logging bug and some maintenance" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:116 +msgid ":pr:`2597`: Fix Bug in :class:`.Uncreate` with ``rate_func`` via introducing new parameter ``reversed`` to :class:`.Animation`" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:114 +msgid "Refractor the :class:`.Uncreate`. The new implementation uses a flag member ``reversed``. Set it to ``True`` and its superclass handles the reverse." +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:115 +msgid "Introduce a bool parameter ``reversed`` to :class:`.Animation`. It decides whether the animation needs to be played backwards. Default to be False." +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:116 +msgid "Add conditional branches in :meth:`.Animation.get_sub_alpha`. If the parameter ``reversed`` is True, it would set ``rate_func(t)`` to ``rate_func(1 - t)``." +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:118 +msgid ":pr:`2613`: Fixed bug in :meth:`.Circle.point_at_angle` when the angle is not in the interval :math:`[0, 2\\pi]`" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:121 +msgid ":pr:`2634`: Fix background lines drawn twice in :class:`.NumberPlane`" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:124 +msgid ":pr:`2648`: Handle user-defined centers for Wiggle animation" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:128 +msgid ":pr:`2658`: Fix arguments of overridden ``set_style`` for :class:`.BackgroundRectangle`" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:128 +msgid "Using :class:`.Write` animation on a :class:`.Text` object with ``.add_background_rectangle()`` applied no longer generates a ``TypeError``." +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:130 +msgid ":pr:`2668`: (Re)set background color of :class:`.OpenGLRenderer` when initializing scene" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:133 +msgid ":pr:`2676`: Fixed propagation of custom attributes in animations for the OpenGL renderer" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:136 +msgid ":pr:`2688`: Fixed two minor issues of :class:`.SpiralIn` and :class:`.ManimBanner`" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:140 +msgid "Documentation-related changes" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:142 +msgid ":pr:`2609`: Copyedit troubleshooting.rst" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:145 +msgid ":pr:`2610`: Add example PolygonOnAxes" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:148 +msgid ":pr:`2617`: Re-added :mod:`.value_tracker` documentation" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:151 +msgid ":pr:`2619`: Improve Example for arrange_in_grid" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:154 +msgid ":pr:`2620`: Fixed typo in :meth:`.Animation.is_introducer`" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:158 +msgid ":pr:`2640`: Copyedited Documentation" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:158 +msgid "Reviewed ``tutorials/configurations.rst``. Edited simple mistakes such as Manim not being capitalized and commas." +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:160 +msgid ":pr:`2649`: Document and type utils/iterables.py" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:163 +msgid ":pr:`2651`: Update copyright year in documentation to 2020-2022" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:165 +msgid ":pr:`2663`: Added documentation for scene updater functions" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:168 +msgid ":pr:`2686`: Add instructions to install extra dependencies with poetry" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:172 +msgid "Changes to our development infrastructure" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:174 +msgid ":pr:`2561`: Run tests on Linux-aarch64" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:177 +msgid ":pr:`2656`: Fixed incompatibility with black version" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:181 +msgid "Code quality improvements and similar refactors" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:184 +msgid ":pr:`2630`: Remove WebGL renderer" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:184 +msgid "The WebGL renderer is broken and unmaintained. The support for it in Manim is removed." +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:186 +msgid ":pr:`2652`: Update ``cloup`` version to 0.13.0 from 0.7.0" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:189 +msgid ":pr:`2678`: Require ``backports-cached-property`` only for Python < 3.8" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:193 +msgid ":pr:`2685`: Migrate from ``os.path`` to ``pathlib`` in testing scripts" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:193 +msgid "This pull request changes a number of instances of ``os.path`` to Pathlib objects and functions. In addition, this PR modifies the SVGMobject constructor to accept both a Pathlib object or a string variable pathname its constructor." +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:195 +msgid ":pr:`2691`: Removed :class:`CameraFrame`" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:198 +msgid ":pr:`2696`: Made changelog generation run in parallel plus further improvements to ``scripts/dev_changelog.py``" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:201 +msgid ":pr:`2697`: Sort PRs by number in changelog sections before writing" +msgstr "" + +#: ../../source/changelog/0.15.2-changelog.rst:205 +msgid "New releases" +msgstr "" + + diff --git a/docs/i18n/gettext/changelog/0.16.0-changelog.pot b/docs/i18n/gettext/changelog/0.16.0-changelog.pot new file mode 100644 index 0000000000..342965b5ef --- /dev/null +++ b/docs/i18n/gettext/changelog/0.16.0-changelog.pot @@ -0,0 +1,501 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Manim \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../source/changelog/0.16.0-changelog.rst:3 +msgid "v0.16.0" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:0 +msgid "Date" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:5 +msgid "July 13, 2022" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:8 +msgid "Contributors" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:10 +msgid "A total of 44 people contributed to this release. People with a '+' by their names authored a patch for the first time." +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:14 +#: ../../source/changelog/0.16.0-changelog.rst:51 +msgid "Alex Lembcke" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:15 +msgid "Baroudi Aymen +" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:16 +#: ../../source/changelog/0.16.0-changelog.rst:52 +msgid "Benjamin Hackl" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:17 +msgid "Charalampos Georgiou +" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:18 +msgid "Cindy Park +" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:19 +msgid "Ejar +" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:20 +msgid "Francesco Frassinelli +" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:21 +msgid "Francisco Manríquez Novoa +" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:22 +msgid "Jacob Evan Shreve +" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:23 +msgid "Jaime Santos +" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:24 +#: ../../source/changelog/0.16.0-changelog.rst:58 +msgid "Jonathan Alpert" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:25 +msgid "Joshua Mankelow +" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:26 +msgid "Kevin Lubick +" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:27 +#: ../../source/changelog/0.16.0-changelog.rst:60 +msgid "Laith Bahodi" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:28 +msgid "Lingren Kong +" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:29 +msgid "Logen +" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:30 +#: ../../source/changelog/0.16.0-changelog.rst:61 +msgid "Naveen M K" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:31 +msgid "Noam Zaks" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:32 +msgid "Pedro Lamkowski +" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:33 +#: ../../source/changelog/0.16.0-changelog.rst:64 +msgid "Raghav Goel" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:34 +msgid "Simeon Widdis" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:35 +#: ../../source/changelog/0.16.0-changelog.rst:66 +msgid "Sparsh Goenka" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:36 +msgid "TornaxO7 +" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:37 +msgid "Tristan Schulz +" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:38 +msgid "WillSoltas" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:39 +#: ../../source/changelog/0.16.0-changelog.rst:69 +msgid "ad_chaos" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:40 +msgid "conor-oneill-2 +" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:41 +msgid "fcrozatier +" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:42 +msgid "mooncaker816 +" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:43 +msgid "niklebedenko +" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:44 +msgid "nyabkun +" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:45 +msgid "quark67" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:48 +msgid "The patches included in this release have been reviewed by the following contributors." +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:53 +msgid "Darylgolden" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:54 +msgid "Francesco Frassinelli" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:55 +msgid "Francisco Manríquez Novoa" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:56 +msgid "Gianluca Gippetto" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:57 +msgid "Jan-Hendrik Müller" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:59 +msgid "Kevin Lubick" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:62 +msgid "Pedro Lamkowski" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:63 +msgid "Philipp Imhof" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:65 +msgid "Ryan McCauley" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:67 +msgid "TornaxO7" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:68 +msgid "Tristan Schulz" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:70 +msgid "hickmott99" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:73 +msgid "Pull requests merged" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:75 +msgid "A total of 56 pull requests were merged for this release." +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:78 +msgid "Highlights" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:82 +msgid ":pr:`2550`: New thematic guide: a deep dive into the internals of the library" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:81 +msgid "This new :doc:`thematic guide ` aims to be a comprehensive walkthrough describing all the things that Manim does when you run it to produce a video." +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:84 +msgid ":pr:`2732`: Improved overall structure of deployed documentation; added a dedicated :doc:`FAQ section `" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:90 +msgid ":pr:`2749`: Added :class:`.ChangeSpeed`, an animation wrapper that allows to smoothly change the speed at which an animation is played" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:88 +msgid "The speed of any animation can be changed by wrapping the animation with :class:`.ChangeSpeed` and passing a dictionary as ``speedinfo`` whose keys are the relative animation run time stamps and whose values are the absolute speed factors; e.g., ``{0.5: 2, 0.75: 0.25}`` smoothly speeds up the animation by a factor of 2 once it has been completed to 50%, and then it is smoothly slowed down to 1/4 of the default run speed after 75% of the animation are completed. The ``run_time`` of the animation will be adjusted to match the changed play speed." +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:90 +msgid "It is also possible to add time-based updaters that respect the change in speed, use the auxiliary :meth:`.ChangeSpeed.add_updater` method to do so." +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:93 +msgid "New features" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:95 +msgid ":pr:`2667`: Made FFmpeg executable path configurable" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:98 +msgid ":pr:`2739`: Added vectorized plotting functionality via keyword argument ``use_vectorized`` to improve performance" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:102 +msgid "Enhancements" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:104 +msgid ":pr:`2186`: Enabled filling color by value for :class:`.OpenGLSurface`, replaced ``colors`` keyword argument of :meth:`.Surface.set_fill_by_value` with ``colorscale``" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:107 +msgid ":pr:`2288`: Added warning when attempting to add same mobject as child twice" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:112 +msgid ":pr:`2707`: Fixed missing ``get_nth_curve_length_pieces`` method of :class:`.OpenGLVMobject`" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:111 +msgid "Removed duplicate definition of ``get_curve_functions_with_lengths`` in ``OpenGLVMobject``" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:112 +msgid "Added definition of ``get_nth_curve_length_pieces`` to ``OpenGLVMobject``" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:114 +msgid ":pr:`2709`: Improved the look of the brackets of :class:`.Matrix`" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:117 +msgid ":pr:`2714`: Fixed :meth:`.OpenGLVMobject.pointwise_become_partial` to improve stroke rendering" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:120 +msgid ":pr:`2727`: Slight performance improvement for :class:`.ArrowVectorField` and Bézier curve computation" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:123 +msgid ":pr:`2728`: Added :meth:`.VectorField.fit_to_coordinate_system` to fit a vector field to a given coordinate system" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:126 +msgid ":pr:`2730`: Added note to let users find documentation of default CLI subcommand easier" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:129 +msgid ":pr:`2746`: Installed ghostscript in the docker image" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:132 +msgid ":pr:`2841`: Added :func:`.split_quadratic_bezier` and :func:`.subdivide_quadratic_bezier`" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:135 +msgid ":pr:`2842`: CLI: Moved functionality from ``manim new`` to ``manim init`` and added deprecation warning for ``manim new``" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:138 +msgid ":pr:`2866`: Reorganize test files to match library module structure" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:142 +msgid "Fixed bugs" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:144 +msgid ":pr:`2567`: Use tempconfig for every scene render" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:147 +msgid ":pr:`2638`: Fixed :meth:`BarChart.change_bar_values` not updating when height is 0" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:150 +msgid ":pr:`2661`: Fixed tip resize functionality for :class:`.Axes` to match documentation" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:153 +msgid ":pr:`2703`: Default to utf-8 when reading files in :class:`.Code`" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:156 +msgid ":pr:`2721`: Fixed bad text slicing for lines in :class:`.Paragraph`" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:159 +msgid ":pr:`2725`: Fixed wrong indentation in :class:`.Code`" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:162 +msgid ":pr:`2734`: Fixed OpenGL segfaults when running :meth:`.Scene.play` or :meth:`.Scene.wait` in interactive mode" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:165 +msgid ":pr:`2753`: Fixed multiplatform builds for docker images in pipeline" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:168 +msgid ":pr:`2757`: Added missing ``__init__.py`` file in :mod:`.docbuild` module" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:171 +msgid ":pr:`2770`: Fixed bug in :meth:`.VMobject.proportion_from_point` that caused proportions greater than 1 to be returned" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:174 +msgid ":pr:`2826`: Fixed leaked mobjects coming from :class:`.TransformMatchingAbstractBase`" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:177 +msgid ":pr:`2870`: Fixed issue with ``manim init scene SCENE_NAME filename.py`` and removed necessity of ``main.py`` to be present in working directory" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:181 +msgid "Documentation-related changes" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:183 +msgid ":pr:`2704`: Updated URL to Pango Markup formatting page" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:186 +msgid ":pr:`2716`: Improved the order of the reference manuals" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:189 +msgid ":pr:`2720`: Fixed typo in docstring of :class:`.Angle`" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:192 +msgid ":pr:`2722`: Fixed typos in docstrings of classes in :mod:`.mobject.table`" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:195 +msgid ":pr:`2726`: Edited note on :class:`.NumberPlane` length and added another example" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:198 +msgid ":pr:`2740`: Fixed documentation of :meth:`.Cylinder.get_direction`" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:201 +msgid ":pr:`2755`: Fixed docstring of :meth:`.VMobject.get_end_anchors`" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:204 +msgid ":pr:`2760`: Removed ``cmake`` from the MacOS installation section" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:207 +msgid ":pr:`2767`: Added more questions and answers to FAQ section, new :doc:`OpenGL FAQ `" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:210 +msgid ":pr:`2771`: Added documentation and testing for ``path_func`` keyword argument of :class:`.Transform`" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:213 +msgid ":pr:`2828`: Removed suggestion issue template, added FAQ answer regarding proposing new features" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:216 +msgid ":pr:`2849`: Added example for ``path_arc`` keyword argument of :class:`.Transform`" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:219 +msgid ":pr:`2851`: Added an example on constructing a (neural) network using a partite :class:`.Graph`" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:222 +msgid ":pr:`2855`: Added implicit ``docker.io/`` URL base in reference to docker images" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:225 +msgid ":pr:`2861`: Added docstring for :meth:`.CoordinateSystem.plot_parametric_curve`" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:229 +msgid "Changes concerning the testing system" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:231 +msgid ":pr:`2743`: Replaced ``assert`` statements with with assertion functions from ``np.testing``" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:235 +msgid "Changes to our development infrastructure" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:237 +msgid ":pr:`2700`: CI: updated Python versions" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:240 +msgid ":pr:`2701`: CI: added a workflow to publish docker image after releases and commits to main branch" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:244 +msgid "Code quality improvements and similar refactors" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:246 +msgid ":pr:`2680`: Increased minimum required version of ``numpy`` to 1.19" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:249 +msgid ":pr:`2687`: Migrated from ``os.path`` to ``pathlib`` in :class:`.SVGMobject` and other locations" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:252 +msgid ":pr:`2715`: Updated deprecated ``pillow`` constants" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:255 +msgid ":pr:`2735`: Bump pyjwt from 2.3.0 to 2.4.0" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:258 +msgid ":pr:`2748`: Bump pillow from 9.1.0 to 9.1.1" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:261 +msgid ":pr:`2751`: Fixed flake C417 and improved a comment" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:264 +msgid ":pr:`2825`: Bump notebook from 6.4.11 to 6.4.12" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:267 +msgid ":pr:`2864`: Updated lockfile" +msgstr "" + +#: ../../source/changelog/0.16.0-changelog.rst:271 +msgid "New releases" +msgstr "" + + diff --git a/docs/i18n/gettext/conduct.pot b/docs/i18n/gettext/conduct.pot index 924b2161e7..82654e3b00 100644 --- a/docs/i18n/gettext/conduct.pot +++ b/docs/i18n/gettext/conduct.pot @@ -11,7 +11,7 @@ msgid "Code of Conduct" msgstr "" #: ../../source/conduct.md:7 -msgid "TL;DR Be excellent to each other; we're a community after all. If you run into issues with others in our community, please contact a Manim Community Dev, or Moderator." +msgid "TL;DR Be excellent to each other; we're a community after all. If you run into issues with others in our community, please [contact](https://www.manim.community/discord/) a Manim Community Dev, or Moderator." msgstr "" #: ../../source/conduct.md:9 @@ -31,31 +31,31 @@ msgid "Members of Manim Community are respectful, open, and considerate. Behavio msgstr "" #: ../../source/conduct.md:19 -msgid "Being respectful. Respectful of others, their positions, experiences, viewpoints, skills, commitments, time, and efforts." +msgid "**Being respectful.** Respectful of others, their positions, experiences, viewpoints, skills, commitments, time, and efforts." msgstr "" #: ../../source/conduct.md:21 -msgid "Being open. Open to collaboration, whether it's on problems, Pull Requests, issues, or otherwise." +msgid "**Being open.** Open to collaboration, whether it's on problems, Pull Requests, issues, or otherwise." msgstr "" #: ../../source/conduct.md:23 -msgid "Being considerate. Considerate of their peers -- other Manim users and developers." +msgid "**Being considerate.** Considerate of their peers -- other Manim users and developers." msgstr "" #: ../../source/conduct.md:25 -msgid "Focusing on what is best for the community. We're respectful of the processes set forth in the community, and we work within them." +msgid "**Focusing on what is best for the community.** We're respectful of the processes set forth in the community, and we work within them." msgstr "" #: ../../source/conduct.md:27 -msgid "Showing empathy towards other community members. We're attentive in our communications, whether in person or online, and we're tactful when approaching differing views." +msgid "**Showing empathy towards other community members.** We're attentive in our communications, whether in person or online, and we're tactful when approaching differing views." msgstr "" #: ../../source/conduct.md:29 -msgid "Gracefully accepting constructive criticism. When we disagree, we are courteous in raising our issues." +msgid "**Gracefully accepting constructive criticism.** When we disagree, we are courteous in raising our issues." msgstr "" #: ../../source/conduct.md:31 -msgid "Using welcoming and inclusive language. We're accepting of all who wish to take part in our activities, fostering an environment where anyone can participate and everyone can make a difference." +msgid "**Using welcoming and inclusive language.** We're accepting of all who wish to take part in our activities, fostering an environment where anyone can participate and everyone can make a difference." msgstr "" #: ../../source/conduct.md:35 @@ -147,19 +147,19 @@ msgid "This Code of Conduct applies to the following online spaces:" msgstr "" #: ../../source/conduct.md:69 -msgid "The ManimCommunity GitHub Organization and all of its repositories" +msgid "The [ManimCommunity GitHub Organization](https://github.com/ManimCommunity) and all of its repositories" msgstr "" #: ../../source/conduct.md:71 -msgid "The Manim Discord" +msgid "The Manim [Discord](https://www.manim.community/discord/)" msgstr "" #: ../../source/conduct.md:73 -msgid "The Manim Reddit" +msgid "The Manim [Reddit](https://www.reddit.com/r/manim/)" msgstr "" #: ../../source/conduct.md:75 -msgid "The Manim Twitter" +msgid "The Manim [Twitter](https://twitter.com/manim\\_community/)" msgstr "" #: ../../source/conduct.md:77 @@ -211,7 +211,7 @@ msgid "Contact Information" msgstr "" #: ../../source/conduct.md:107 -msgid "If you believe someone is violating the code of conduct, or have any other concerns, please contact a Manim Community Dev, or Moderator immediately. They can be reached on Manim's Community Discord." +msgid "If you believe someone is violating the code of conduct, or have any other concerns, please contact a Manim Community Dev, or Moderator immediately. They can be reached on Manim's Community [Discord](https://www.manim.community/discord/)." msgstr "" #: ../../source/conduct.md:117 @@ -323,11 +323,11 @@ msgid "Jurisdiction" msgstr "" #: ../../source/conduct.md:165 -msgid "Is this a Code of Conduct violation? Is this behavior on our list of inappropriate behavior? Is it borderline inappropriate behavior? Does it violate our community norms?" +msgid "*Is this a Code of Conduct violation?* Is this behavior on our list of inappropriate behavior? Is it borderline inappropriate behavior? Does it violate our community norms?" msgstr "" #: ../../source/conduct.md:166 -msgid "Did this occur in a space that is within our Code of Conduct's scope? If the incident occurred outside the community, but a community member's mental health or physical safety may be negatively impacted if no action is taken, the incident may be in scope. Private conversations in community spaces are also in scope." +msgid "*Did this occur in a space that is within our Code of Conduct's scope?* If the incident occurred outside the community, but a community member's mental health or physical safety may be negatively impacted if no action is taken, the incident may be in scope. Private conversations in community spaces are also in scope." msgstr "" #: ../../source/conduct.md:167 @@ -335,15 +335,15 @@ msgid "Impact" msgstr "" #: ../../source/conduct.md:169 -msgid "Did this incident occur in a private conversation or a public space? Incidents that all community members can see will have a more negative impact." +msgid "*Did this incident occur in a private conversation or a public space?* Incidents that all community members can see will have a more negative impact." msgstr "" #: ../../source/conduct.md:170 -msgid "Does this behavior negatively impact a marginalized group in our community? Is the reporter a person from a marginalized group in our community? How is the reporter being negatively impacted by the reported person's behavior? Are members of the marginalized group likely to disengage with the community if no action was taken on this report?" +msgid "*Does this behavior negatively impact a marginalized group in our community?* Is the reporter a person from a marginalized group in our community? How is the reporter being negatively impacted by the reported person's behavior? Are members of the marginalized group likely to disengage with the community if no action was taken on this report?" msgstr "" #: ../../source/conduct.md:171 -msgid "Does this incident involve a community leader? Community members often look up to community leaders to set the standard of acceptable behavior" +msgid "*Does this incident involve a community leader?* Community members often look up to community leaders to set the standard of acceptable behavior" msgstr "" #: ../../source/conduct.md:172 @@ -351,15 +351,15 @@ msgid "Risk" msgstr "" #: ../../source/conduct.md:174 -msgid "Does this incident include sexual harassment?" +msgid "*Does this incident include sexual harassment?*" msgstr "" #: ../../source/conduct.md:175 -msgid "Does this pose a safety risk? Does the behavior put a person's physical safety at risk? Will this incident severely negatively impact someone's mental health?" +msgid "*Does this pose a safety risk?* Does the behavior put a person's physical safety at risk? Will this incident severely negatively impact someone's mental health?" msgstr "" #: ../../source/conduct.md:176 -msgid "Is there a risk of this behavior being repeated? Does the reported person understand why their behavior was inappropriate? Is there an established pattern of behavior from past reports?" +msgid "*Is there a risk of this behavior being repeated?* Does the reported person understand why their behavior was inappropriate? Is there an established pattern of behavior from past reports?" msgstr "" #: ../../source/conduct.md:179 @@ -479,15 +479,15 @@ msgid "When discussing a change to the Manim Community code of conduct or enforc msgstr "" #: ../../source/conduct.md:241 -msgid "Brainstorm options. Team members should discuss any relevant context and brainstorm a set of possible options. It is important to provide constructive feedback without getting side-tracked from the main question." +msgid "**Brainstorm options.** Team members should discuss any relevant context and brainstorm a set of possible options. It is important to provide constructive feedback without getting side-tracked from the main question." msgstr "" #: ../../source/conduct.md:242 -msgid "Vote. Proposed changes to the code of conduct will be decided by a two-thirds majority of all voting members of the Code of Conduct team. Team members are listed in the charter. Currently active voting members are listed in the following section." +msgid "**Vote.** Proposed changes to the code of conduct will be decided by a two-thirds majority of all voting members of the Code of Conduct team. Team members are listed in the charter. Currently active voting members are listed in the following section." msgstr "" #: ../../source/conduct.md:243 -msgid "Board Vote. Once a working draft is in place for the Code of Conduct and procedures, the Code of Conduct team shall provide the Manim Community Moderators with a draft of the changes. The Manim Community Moderators will vote on the changes at a board meeting." +msgid "**Board Vote.** Once a working draft is in place for the Code of Conduct and procedures, the Code of Conduct team shall provide the Manim Community Moderators with a draft of the changes. The Manim Community Moderators will vote on the changes at a board meeting." msgstr "" #: ../../source/conduct.md:246 @@ -503,7 +503,7 @@ msgid "License" msgstr "" #: ../../source/conduct.md:254 -msgid "This Code of Conduct is licensed under the Creative Commons Attribution-ShareAlike 3.0 Unported License." +msgid "This Code of Conduct is licensed under the [Creative Commons Attribution-ShareAlike 3.0 Unported License](https://creativecommons.org/licenses/by-sa/3.0/)." msgstr "" #: ../../source/conduct.md:258 diff --git a/docs/i18n/gettext/contributing.pot b/docs/i18n/gettext/contributing.pot index 4f7b8a936a..b26b14ef44 100644 --- a/docs/i18n/gettext/contributing.pot +++ b/docs/i18n/gettext/contributing.pot @@ -11,7 +11,7 @@ msgid "Contributing" msgstr "" #: ../../source/contributing.rst:5 -msgid "Manim is currently undergoing a major refactor. In general, contributions implementing new features will not be accepted in this period. Other contributions unrelated to cleaning up the codebase may also take a longer period of time to be reviewed. This guide may quickly become outdated quickly; we highly recommend joining our `Discord server `_ to discuss any potential contributions and keep up to date with the latest developments." +msgid "Manim is currently undergoing a major refactor. In general, contributions implementing new features will not be accepted in this period. Other contributions unrelated to cleaning up the codebase may also take a longer period of time to be reviewed. This guide may quickly become outdated quickly; we highly recommend joining our `Discord server `__ to discuss any potential contributions and keep up to date with the latest developments." msgstr "" #: ../../source/contributing.rst:12 @@ -50,7 +50,11 @@ msgstr "" msgid "Translating documentation and docstrings" msgstr "" -#: ../../source/contributing.rst:31 +#: ../../source/contributing.rst:30 +msgid "To get an overview of what our community is currently working on, check out `our development project board `__." +msgstr "" + +#: ../../source/contributing.rst:34 msgid "Please ensure that you are reading the latest version of this guide by ensuring that \"latest\" is selected in the version switcher." msgstr "" diff --git a/docs/i18n/gettext/contributing/development.pot b/docs/i18n/gettext/contributing/development.pot index c624d1807e..2ee98c893c 100644 --- a/docs/i18n/gettext/contributing/development.pot +++ b/docs/i18n/gettext/contributing/development.pot @@ -75,202 +75,202 @@ msgid "If you choose to use Poetry as well, follow `Poetry's installation guidel msgstr "" #: ../../source/contributing/development.rst:69 +msgid "In case you want to install extra dependencies that are defined in the ``[tool.poetry.extras]`` section of ``pyproject.toml``, this can be done by passing the ``-E`` flag, for example ``poetry install -E jupyterlab -E gui``." +msgstr "" + +#: ../../source/contributing/development.rst:73 msgid "In case you decided against Poetry, you can install Manim via pip by running ``python3 -m pip install .``. Note that due to our development infrastructure being based on Poetry, we currently do not support editable installs via ``pip``, so you will have to re-run this command every time you make changes to the source code." msgstr "" -#: ../../source/contributing/development.rst:78 +#: ../../source/contributing/development.rst:82 msgid "The following steps assume that you chose to install and work with Poetry." msgstr "" -#: ../../source/contributing/development.rst:81 +#: ../../source/contributing/development.rst:85 msgid "Install Pre-Commit:" msgstr "" -#: ../../source/contributing/development.rst:87 +#: ../../source/contributing/development.rst:91 msgid "This will ensure during development that each of your commits is properly formatted against our linter and formatters, ``black``, ``flake8``, ``isort`` and ``codespell``." msgstr "" -#: ../../source/contributing/development.rst:91 +#: ../../source/contributing/development.rst:95 msgid "You are now ready to work on manim!" msgstr "" -#: ../../source/contributing/development.rst:94 +#: ../../source/contributing/development.rst:98 msgid "Develop your contribution" msgstr "" -#: ../../source/contributing/development.rst:96 +#: ../../source/contributing/development.rst:100 msgid "Checkout your local repository's main branch and pull the latest changes from ManimCommunity, ``upstream``, into your local repository:" msgstr "" -#: ../../source/contributing/development.rst:104 +#: ../../source/contributing/development.rst:108 msgid "Create a branch for the changes you want to work on rather than working off of your local main branch:" msgstr "" -#: ../../source/contributing/development.rst:111 +#: ../../source/contributing/development.rst:115 msgid "This ensures you can easily update your local repository's main with the first step and switch branches to work on multiple features." msgstr "" -#: ../../source/contributing/development.rst:114 +#: ../../source/contributing/development.rst:118 msgid "Write some awesome code!" msgstr "" -#: ../../source/contributing/development.rst:116 +#: ../../source/contributing/development.rst:120 msgid "You're ready to make changes in your local repository's branch. You can add local files you've changed within the current directory with ``git add .``, or add specific files with" msgstr "" -#: ../../source/contributing/development.rst:124 +#: ../../source/contributing/development.rst:128 msgid "and commit these changes to your local history with ``git commit``. If you have installed pre-commit, your commit will succeed only if none of the hooks fail." msgstr "" -#: ../../source/contributing/development.rst:130 +#: ../../source/contributing/development.rst:134 msgid "When crafting commit messages, it is highly recommended that you adhere to `these guidelines `_." msgstr "" -#: ../../source/contributing/development.rst:133 +#: ../../source/contributing/development.rst:137 msgid "Add new or update existing tests." msgstr "" -#: ../../source/contributing/development.rst:135 +#: ../../source/contributing/development.rst:139 msgid "Depending on your changes, you may need to update or add new tests. For new features, it is required that you include tests with your PR. Details of our testing system are explained in the :doc:`testing guide `." msgstr "" -#: ../../source/contributing/development.rst:140 +#: ../../source/contributing/development.rst:144 msgid "Update docstrings and documentation:" msgstr "" -#: ../../source/contributing/development.rst:142 +#: ../../source/contributing/development.rst:146 msgid "Update the docstrings (the text in triple quotation marks) of any functions or classes you change and include them with any new functions you add. See the :doc:`documentation guide ` for more information about how we prefer our code to be documented. The content of the docstrings will be rendered in the :doc:`reference manual <../reference>`." msgstr "" -#: ../../source/contributing/development.rst:150 +#: ../../source/contributing/development.rst:154 msgid "Use the :mod:`manim directive for Sphinx ` to add examples to the documentation!" msgstr "" -#: ../../source/contributing/development.rst:156::1 -msgid "A directive for including Manim videos in a Sphinx document" -msgstr "" - -#: ../../source/contributing/development.rst:158 +#: ../../source/contributing/development.rst:157 msgid "As far as development on your local machine goes, these are the main steps you should follow." msgstr "" -#: ../../source/contributing/development.rst:162 +#: ../../source/contributing/development.rst:161 msgid "Polishing Changes and Submitting a Pull Request" msgstr "" -#: ../../source/contributing/development.rst:164 +#: ../../source/contributing/development.rst:163 msgid "As soon as you are ready to share your local changes with the community so that they can be discussed, go through the following steps to open a pull request. A pull request signifies to the ManimCommunity organization, \"Here are some changes I wrote; I think it's worthwhile for you to maintain them.\"" msgstr "" -#: ../../source/contributing/development.rst:172 +#: ../../source/contributing/development.rst:171 msgid "You do not need to have everything (code/documentation/tests) complete to open a pull request (PR). If the PR is still under development, please mark it as a draft. Community developers will still be able to review the changes, discuss yet-to-be-implemented changes, and offer advice; however, the more complete your PR, the quicker it will be merged." msgstr "" -#: ../../source/contributing/development.rst:178 +#: ../../source/contributing/development.rst:177 msgid "Update your fork on GitHub to reflect your local changes:" msgstr "" -#: ../../source/contributing/development.rst:184 +#: ../../source/contributing/development.rst:183 msgid "Doing so creates a new branch on your remote fork, ``origin``, with the contents of your local repository on GitHub. In subsequent pushes, this local branch will track the branch ``origin`` and ``git push`` is enough." msgstr "" -#: ../../source/contributing/development.rst:189 +#: ../../source/contributing/development.rst:188 msgid "Make a pull request (PR) on GitHub." msgstr "" -#: ../../source/contributing/development.rst:191 +#: ../../source/contributing/development.rst:190 msgid "In order to make the ManimCommunity development team aware of your changes, you can make a PR to the ManimCommunity repository from your fork." msgstr "" -#: ../../source/contributing/development.rst:196 +#: ../../source/contributing/development.rst:195 msgid "Make sure to select ``ManimCommunity/manim`` instead of ``3b1b/manim`` as the base repository!" msgstr "" -#: ../../source/contributing/development.rst:199 +#: ../../source/contributing/development.rst:198 msgid "Choose the branch from your fork as the head repository - see the screenshot below." msgstr "" -#: ../../source/contributing/development.rst:205 +#: ../../source/contributing/development.rst:204 msgid "Please make sure you follow the template (this is the default text you are shown when first opening the 'New Pull Request' page)." msgstr "" -#: ../../source/contributing/development.rst:209 +#: ../../source/contributing/development.rst:208 msgid "Your changes are eligible to be merged if:" msgstr "" -#: ../../source/contributing/development.rst:211 +#: ../../source/contributing/development.rst:210 msgid "there are no merge conflicts" msgstr "" -#: ../../source/contributing/development.rst:212 +#: ../../source/contributing/development.rst:211 msgid "the tests in our pipeline pass" msgstr "" -#: ../../source/contributing/development.rst:213 +#: ../../source/contributing/development.rst:212 msgid "at least one (two for more complex changes) Community Developer approves the changes" msgstr "" -#: ../../source/contributing/development.rst:215 +#: ../../source/contributing/development.rst:214 msgid "You can check for merge conflicts between the current upstream/main and your branch by executing ``git pull upstream main`` locally. If this generates any merge conflicts, you need to resolve them and push an updated version of the branch to your fork of the repository." msgstr "" -#: ../../source/contributing/development.rst:220 +#: ../../source/contributing/development.rst:219 msgid "Our pipeline consists of a series of different tests that ensure that manim still works as intended and that the code you added sticks to our coding conventions." msgstr "" -#: ../../source/contributing/development.rst:224 +#: ../../source/contributing/development.rst:223 msgid "**Code style**: We use the code style imposed by `Black `_, `isort `_ and `flake8 `_. The GitHub pipeline makes sure that the (Python) files changed in your pull request also adhere to this code style. If this step of the pipeline fails, fix your code formatting automatically by running ``black `` and ``isort ``. To fix code style problems, run ``flake8 `` for a style report, and then fix the problems manually that were detected by ``flake8``." msgstr "" -#: ../../source/contributing/development.rst:233 +#: ../../source/contributing/development.rst:232 msgid "**Tests**: The pipeline runs manim's test suite on different operating systems (the latest versions of Ubuntu, MacOS, and Windows) for different versions of Python. The test suite consists of two different kinds of tests: integration tests and doctests. You can run them locally by executing ``poetry run pytest`` and ``poetry run pytest --doctest-modules manim``, respectively, from the root directory of your cloned fork." msgstr "" -#: ../../source/contributing/development.rst:240 +#: ../../source/contributing/development.rst:239 msgid "**Documentation**: We also build a version of the documentation corresponding to your pull request. Make sure not to introduce any Sphinx errors, and have a look at the built HTML files to see whether the formatting of the documentation you added looks as you intended. You can build the documentation locally by running ``make html`` from the ``docs`` directory. Since the inheritance diagrams require you to have `Graphviz `_ installed locally." msgstr "" -#: ../../source/contributing/development.rst:247 +#: ../../source/contributing/development.rst:246 msgid "Finally, if the pipeline passes and you are satisfied with your changes: wait for feedback and iterate over any requested changes. You will likely be asked to edit or modify your PR in one way or another during this process. This is not an indictment of your work, but rather a strong signal that the community wants to merge your changes! Once approved, your changes may be merged!" msgstr "" -#: ../../source/contributing/development.rst:254 +#: ../../source/contributing/development.rst:253 msgid "Further useful guidelines" msgstr "" -#: ../../source/contributing/development.rst:256 +#: ../../source/contributing/development.rst:255 msgid "When submitting a PR, please mention explicitly if it includes breaking changes." msgstr "" -#: ../../source/contributing/development.rst:258 +#: ../../source/contributing/development.rst:257 msgid "When submitting a PR, make sure that your proposed changes are as general as possible, and ready to be taken advantage of by all of manim's users. In particular, leave out any machine-specific configurations, or any personal information it may contain." msgstr "" -#: ../../source/contributing/development.rst:263 +#: ../../source/contributing/development.rst:262 msgid "If you are a maintainer, please label issues and PRs appropriately and frequently." msgstr "" -#: ../../source/contributing/development.rst:266 +#: ../../source/contributing/development.rst:265 msgid "When opening a new issue, if there are old issues that are related, add a link to them in your new issue (even if the old ones are closed)." msgstr "" -#: ../../source/contributing/development.rst:269 +#: ../../source/contributing/development.rst:268 msgid "When submitting a code review, it is highly recommended that you adhere to `these general guidelines `_." msgstr "" -#: ../../source/contributing/development.rst:272 +#: ../../source/contributing/development.rst:271 msgid "If you find stale or inactive issues that seem to be irrelevant, please post a comment saying 'This issue should be closed', and a community developer will take a look." msgstr "" -#: ../../source/contributing/development.rst:276 +#: ../../source/contributing/development.rst:275 msgid "Please do as much as possible to keep issues, PRs, and development in general as tidy as possible." msgstr "" -#: ../../source/contributing/development.rst:280 -msgid "You can find examples for the ``docs`` in several places: the :doc:`Example Gallery <../examples>`, :doc:`Tutorials <../tutorials>`, and :doc:`Reference Classes <../reference>`." +#: ../../source/contributing/development.rst:279 +msgid "You can find examples for the ``docs`` in several places: the :doc:`Example Gallery <../examples>`, :doc:`Tutorials <../tutorials/index>`, and :doc:`Reference Classes <../reference>`." msgstr "" -#: ../../source/contributing/development.rst:284 +#: ../../source/contributing/development.rst:283 msgid "In case you are contributing, please have a look at this flowchart:" msgstr "" diff --git a/docs/i18n/gettext/examples.pot b/docs/i18n/gettext/examples.pot index d15e7cabdc..d9a94edd27 100644 --- a/docs/i18n/gettext/examples.pot +++ b/docs/i18n/gettext/examples.pot @@ -42,7 +42,7 @@ msgstr "" msgid "Plotting with Manim" msgstr "" -#: ../../source/examples.rst:438 +#: ../../source/examples.rst:496 msgid "Special Camera Settings" msgstr "" diff --git a/docs/i18n/gettext/faq/general.pot b/docs/i18n/gettext/faq/general.pot new file mode 100644 index 0000000000..27a612bd64 --- /dev/null +++ b/docs/i18n/gettext/faq/general.pot @@ -0,0 +1,181 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Manim \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../source/faq/general.md:1 +msgid "FAQ: General Usage" +msgstr "" + +#: ../../source/faq/general.md:3 +msgid "Why does Manim say that \"there are no scenes inside that module\"?" +msgstr "" + +#: ../../source/faq/general.md:5 +msgid "There are two main reasons why this error appears: if you have edited the file containing your `Scene` class and forgot to save it, or if you have accidentally passed the name of a wrong file to `manim`, this is a likely outcome. Check that you have spelled everything correctly." +msgstr "" + +#: ../../source/faq/general.md:10 +msgid "Otherwise you are likely mixing up Manim versions. See {ref}`this FAQ answer ` for an explanation regarding why there are different versions. Under the assumption that you are trying to use the `manim` executable from the terminal to run a scene that has been written for the community version (i.e., there is `from manim import *`, or more specifically `from manim import Scene`)" +msgstr "" + +#: ../../source/faq/general.md:18 +msgid "No matter what code I put in my file, Manim only renders a black frame! Why?" +msgstr "" + +#: ../../source/faq/general.md:20 +msgid "If you are using the usual pattern to write a `Scene`, i.e.," +msgstr "" + +#: ../../source/faq/general.md:27 +msgid "then double check whether you have spelled `construct` correctly. If the method containing your code is not called `construct` (or if you are not calling a different, custom method from `construct`), Manim will not call your method and simply output a black frame." +msgstr "" + +#: ../../source/faq/general.md:34 +msgid "What are the default measurements for Manim's scene?" +msgstr "" + +#: ../../source/faq/general.md:36 +msgid "The scene measures 8 units in height and has a default ratio of 16:9, which means that it measures {math}`8 \\cdot 16 / 9 = 14 + 2/9` units in width. The origin is in the center of the scene, which means that, for example, the upper left corner of the scene has coordinates `[-7-1/9, 4, 0]`." +msgstr "" + +#: ../../source/faq/general.md:43 +msgid "How do I find out which keyword arguments I can pass when creating a `Mobject`?" +msgstr "" + +#: ../../source/faq/general.md:45 +msgid "Let us consider some specific example, like the {class}`.Circle` class. When looking at its documentation page, only two specific keyword arguments are listed (`radius`, and `color`). Besides these concrete arguments, there is also a catchall `**kwargs` argument which captures all other arguments that are passed to `Circle`, and passes them on to the base class of {class}`.Circle`, {class}`.Arc`." +msgstr "" + +#: ../../source/faq/general.md:51 +msgid "The same holds for {class}`.Arc`: some arguments are explicitly documented, and there is again a catchall `**kwargs` argument that passes unprocessed arguments to the next base class -- and so on." +msgstr "" + +#: ../../source/faq/general.md:55 +msgid "The most important keyword arguments relevant to styling your mobjects are the ones that are documented for the base classes {class}`.VMobject` and {class}`.Mobject`." +msgstr "" + +#: ../../source/faq/general.md:61 +msgid "Can Manim render a video with transparent background?" +msgstr "" + +#: ../../source/faq/general.md:63 +msgid "Yes: simply pass the CLI flag `-t` (or its long form `--transparent`). Note that the default video file format does not support transparency, which is why Manim will output a `.mov` instead of a `.mp4` when rendering with a transparent background. Other movie file formats that support transparency can be obtained by passing `--format=webm` or `--format=gif`." +msgstr "" + +#: ../../source/faq/general.md:72 +msgid "I have watched a video where a creator ran command X, but it does not work for me. Why?" +msgstr "" + +#: ../../source/faq/general.md:74 +msgid "The video you have been watching is likely outdated. If you want to follow along, you either need to use the same version used in the video, or modify the code (in many cases it is just a method having been renamed etc.) accordingly. Check the video description, in some cases creators point out whether changes need to be applied to the code shown in the video." +msgstr "" + +#: ../../source/faq/general.md:82 +msgid "When using `Tex` or `MathTex`, some letters are missing. How can I fix this?" +msgstr "" + +#: ../../source/faq/general.md:84 +msgid "It is possible that you have to (re)build some fonts used by LaTeX. For some distributions, you can do this manually by running" +msgstr "" + +#: ../../source/faq/general.md:89 +msgid "We recommend consulting the documentation of your LaTeX distribution for more information." +msgstr "" + +#: ../../source/faq/general.md:94 +msgid "I want to translate some code from `manimgl` to `manim`, what do I do with `CONFIG` dictionaries?" +msgstr "" + +#: ../../source/faq/general.md:96 +msgid "The community maintained version has dropped the use of `CONFIG` dictionaries very early, with {doc}`version v0.2.0 ` released in January 2021." +msgstr "" + +#: ../../source/faq/general.md:100 +msgid "Before that, Manim's classes basically processed `CONFIG` dictionaries by mimicking inheritance (to properly process `CONFIG` dictionaries set by parent classes) and then assigning all of the key-value-pairs in the dictionary as attributes of the corresponding object." +msgstr "" + +#: ../../source/faq/general.md:105 +msgid "In situations where there is not much inheritance going on, or for any custom setting, you should set these attributes yourself. For example, for an old-style `Scene` with custom attributes like" +msgstr "" + +#: ../../source/faq/general.md:114 +msgid "should be written as" +msgstr "" + +#: ../../source/faq/general.md:122 +msgid "In situations where values should be properly inherited, the arguments should be added to the initialization function of the class. An old-style mobject `Thing` could look like" +msgstr "" + +#: ../../source/faq/general.md:135 +msgid "where `stroke_color` and `fill_opacity` are arguments that concern the parent class of `Thing`, and `my_awesome_argument` is a custom argument that only concerns `Thing`. A version without `CONFIG` could look like this:" +msgstr "" + +#: ../../source/faq/general.md:150 +msgid "My installation does not support converting PDF to SVG, help?" +msgstr "" + +#: ../../source/faq/general.md:152 +msgid "This is an issue with `dvisvgm`, the tool shipped with LaTeX that transforms LaTeX output to a `.svg` file that Manim can parse." +msgstr "" + +#: ../../source/faq/general.md:156 +msgid "First, make sure your ``dvisvgm`` version is at least 2.4 by checking the output of" +msgstr "" + +#: ../../source/faq/general.md:163 +msgid "If you do not know how to update `dvisvgm`, please refer to your LaTeX distributions documentation (or the documentation of your operating system, if `dvisvgm` was installed as a system package)." +msgstr "" + +#: ../../source/faq/general.md:167 +msgid "Second, check whether your ``dvisvgm`` supports PostScript specials. This is needed to convert from PDF to SVG. Run:" +msgstr "" + +#: ../../source/faq/general.md:174 +msgid "If the output to this command does **not** contain `ps dvips PostScript specials`, this is a bad sign. In this case, run" +msgstr "" + +#: ../../source/faq/general.md:181 +msgid "If the output does **not** contain `--libgs=filename`, this means your `dvisvgm` does not currently support PostScript. You must get another binary." +msgstr "" + +#: ../../source/faq/general.md:184 +msgid "If, however, `--libgs=filename` appears in the help, that means that your `dvisvgm` needs the Ghostscript library to support PostScript. Search for `libgs.so` (on Linux, probably in `/usr/local/lib` or `/usr/lib`) or `gsdll32.dll` (on 32-bit Windows, probably in `C:\\windows\\system32`) or `gsdll64.dll` (on 64-bit Windows, also probably in `C:\\windows\\system32`) or `libgsl.dylib` (on MacOS, probably in `/usr/local/lib` or `/opt/local/lib`). Please look carefully, as the file might be located elsewhere, e.g. in the directory where Ghostscript is installed." +msgstr "" + +#: ../../source/faq/general.md:193 +msgid "When you have found the library, try (on MacOS or Linux)" +msgstr "" + +#: ../../source/faq/general.md:200 +msgid "or (on Windows)" +msgstr "" + +#: ../../source/faq/general.md:207 +msgid "You should now see `ps dvips PostScript specials` in the output. Refer to your operating system's documentation to find out how you can set or export the environment variable ``LIBGS`` automatically whenever you open a shell." +msgstr "" + +#: ../../source/faq/general.md:211 +msgid "As a last check, you can run" +msgstr "" + +#: ../../source/faq/general.md:217 +msgid "(while still having `LIBGS` set to the correct path, of course.) If `dvisvgm` can find your Ghostscript installation, it will be shown in the output together with the version number." +msgstr "" + +#: ../../source/faq/general.md:221 +msgid "If you do not have the necessary library on your system, please refer to your operating system's documentation to find out where you can get it and how you have to install it." +msgstr "" + +#: ../../source/faq/general.md:225 +msgid "If you are unable to solve your problem, check out the [dvisvgm FAQ](https://dvisvgm.de/FAQ/)." +msgstr "" + +#: ../../source/faq/general.md:230 +msgid "Where can I find more resources for learning Manim?" +msgstr "" + + diff --git a/docs/i18n/gettext/faq/help.pot b/docs/i18n/gettext/faq/help.pot new file mode 100644 index 0000000000..d488fd4b49 --- /dev/null +++ b/docs/i18n/gettext/faq/help.pot @@ -0,0 +1,105 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Manim \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../source/faq/help.md:1 +msgid "FAQ: Getting Help" +msgstr "" + +#: ../../source/faq/help.md:3 +msgid "How do I animate X? Why do I get error Y? Can someone help me?" +msgstr "" + +#: ../../source/faq/help.md:5 +msgid "Before asking the community, please make sure that the issue you are having is not already discussed in our {doc}`FAQ section ` sufficiently well so that you can resolve the problem yourself. You can also try to use your favorite search engine, if you are lucky you might find a blog post, a question on [StackOverflow](https://stackoverflow.com/questions/tagged/manim), or a post in the [r/manim subreddit](https://reddit.com/r/manim)." +msgstr "" + +#: ../../source/faq/help.md:12 +msgid "If this is not the case, please take a moment to properly prepare your question: the better you manage to explain what exactly it is you are struggling with, the more efficient people will be able to help you. Regardless of the platform you choose in the next step, StackOverflow has a good guide on [asking good questions](https://stackoverflow.com/help/how-to-ask)." +msgstr "" + +#: ../../source/faq/help.md:18 +msgid "As soon as you have a good idea of what exactly you want to ask, pick one of the following communication channels:" +msgstr "" + +#: ../../source/faq/help.md:21 +msgid "The community is most active [in our Discord server](https://manim.community/discord/). Click the link to join, then pick one of the `#manim-help` channels in the sidebar, and post your question there. If you are comfortable with using Discord, try to search for your problem using the search function of our server; perhaps people have been talking about it before!" +msgstr "" + +#: ../../source/faq/help.md:26 +msgid "We are also monitoring questions on [StackOverflow](https://stackoverflow.com/questions/tagged/manim) that are tagged with `manim`." +msgstr "" + +#: ../../source/faq/help.md:29 +msgid "Many people are also active in our [r/manim subreddit](https://reddit.com/r/manim), feel free to post there if you are an avid Redditor -- but be aware that Discord or StackOverflow might be better choices." +msgstr "" + +#: ../../source/faq/help.md:32 +msgid "And finally, you can also start a new [discussion on GitHub](https://github.com/ManimCommunity/manim/discussions) if you dislike all other options." +msgstr "" + +#: ../../source/faq/help.md:35 +msgid "In all of these channels, please make sure to abide by Manim's {doc}`Code of Conduct ` -- in short, be *excellent* to one another: be friendly and patient, considerate, and respectful." +msgstr "" + +#: ../../source/faq/help.md:41 +msgid "What should I do if nobody answers my question?" +msgstr "" + +#: ../../source/faq/help.md:43 +msgid "Try and see whether your question can be improved: did you include all relevant information (in case of errors: the full stack trace, the code that you were rendering, and the command you used to run Manim?). In case you used a very long example, is it possible to construct a more minimal version that has the same (faulty) behavior?" +msgstr "" + +#: ../../source/faq/help.md:49 +msgid "If you posted in one of our help channels on Discord and your question got buried, you are allowed to ping the `@Manim Helper` role to bring it to the attention of the volunteers who are willing to take a look. Please refrain from pinging the role immediately when asking your question for the first time, this is considered impolite." +msgstr "" + +#: ../../source/faq/help.md:54 +msgid "You can also try to post your question to a different channel if you feel that you are not having any success with your initial choice -- but please do not spam your question in all of our communication channels (and in particular for Discord: please don't use multiple help channels at once)." +msgstr "" + +#: ../../source/faq/help.md:59 +msgid "In the end, it is as for most open-source projects: our community members are volunteers. If you do not receive a quick answer to your question, it may be because nobody knows the answer, or because your question is not clear enough, or it could be that everyone who can help you with your problem is busy doing other things." +msgstr "" + +#: ../../source/faq/help.md:67 +msgid "The library does not behave as documented, or something broke in a new release. What should I do?" +msgstr "" + +#: ../../source/faq/help.md:69 +msgid "Sounds like you have found a bug. One of the best ways of contributing to the development of Manim is by reporting it!" +msgstr "" + +#: ../../source/faq/help.md:72 +msgid "Check our list of known issues and feature requests [in our GitHub repository](https://github.com/ManimCommunity/manim/issues). If the problem you have found is not listed there yet (use the search function; also check whether there is a corresponding closed issue, it is possible that your problem has already been resolved and will be fixed with the next release), please consider the following steps to submit a new issue." +msgstr "" + +#: ../../source/faq/help.md:80 +msgid "If you are unsure whether or not you should file a new issue for some odd behavior that you found, feel free to ask the community developers, preferably in one of our `#manim-dev` channels in [our Discord](https://manim.community/discord/)." +msgstr "" + +#: ../../source/faq/help.md:85 +msgid "Make sure you are running the latest released version of Manim, your problem might otherwise already be fixed in a more recent version. Check the {doc}`/changelog` for a full list of changes between Manim releases." +msgstr "" + +#: ../../source/faq/help.md:89 +msgid "Choose the correct category for your report when [creating a new issue](https://github.com/ManimCommunity/manim/issues/new/choose). We have dedicated issue templates for *bug reports*, *feature requests*, and *installation issues*. If your report falls into one of these categories, read the issue template carefully! Instructions are given in the `` sections of the text field. If you want to suggest a new feature without concrete implementation details, see {ref}`the instructions given in this answer `." +msgstr "" + +#: ../../source/faq/help.md:98 +msgid "For bug reports: prepare a minimal example that can be used to illustrate the issue. Examples with hundreds of lines are very inefficient and tedious to debug. Your problem needs to be reproducible for others, so please make sure to prepare a suitable example." +msgstr "" + +#: ../../source/faq/help.md:103 +msgid "This is mentioned in the bug report template as well, but it is very important: if you report that some code raises an error, make sure to include the full terminal output, from the command you used to run the library up to and including the last line with the error message. Read carefully: if the message mentions that there is another relevant log file, include this other file as well!" +msgstr "" + +#: ../../source/faq/help.md:112 +msgid "I have an idea for a really cool feature that should be implemented, where should I share my idea?" +msgstr "" + + diff --git a/docs/i18n/gettext/faq/index.pot b/docs/i18n/gettext/faq/index.pot new file mode 100644 index 0000000000..90fbbebace --- /dev/null +++ b/docs/i18n/gettext/faq/index.pot @@ -0,0 +1,14 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Manim \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../source/faq/index.rst:4 +#: ../../source/faq/index.rst:4 +msgid "Table of Contents" +msgstr "" + + diff --git a/docs/i18n/gettext/faq/installation.pot b/docs/i18n/gettext/faq/installation.pot new file mode 100644 index 0000000000..efb566e4cb --- /dev/null +++ b/docs/i18n/gettext/faq/installation.pot @@ -0,0 +1,165 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Manim \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../source/faq/installation.md:1 +msgid "FAQ: Installation" +msgstr "" + +#: ../../source/faq/installation.md:4 +msgid "Why are there different versions of Manim?" +msgstr "" + +#: ../../source/faq/installation.md:6 +msgid "Manim was originally created by Grant Sanderson as a personal project and for use in his YouTube channel, [3Blue1Brown](https://www.youtube.com/channel/UCYO_jab_esuFRV4b17AJtAw). As his channel gained popularity, many grew to like the style of his animations and wanted to use manim for their own projects. However, as manim was only intended for personal use, it was very difficult for other users to install and use it." +msgstr "" + +#: ../../source/faq/installation.md:13 +msgid "In late 2019, Grant started working on faster OpenGL rendering in a new branch, known as the `shaders` branch. In mid-2020, a group of developers forked it into what is now the community edition; this is the version documented on this website. In early 2021, Grant merged the shaders branch back into master, making it the default branch in his repository -- and this is what `manimgl` is. The old version, before merging the `shaders` branch is sometimes referred to as `ManimCairo` and is, at this point, only useful for one singular purpose: rendering Grant's old videos locally on your machine. It is still available in his GitHub repository in form of the `cairo-backend` branch." +msgstr "" + +#: ../../source/faq/installation.md:22 +msgid "To summarize:" +msgstr "" + +#: ../../source/faq/installation.md:23 +msgid "[**Manim**, or **ManimCE**](https://manim.community) refers to the community maintained version of the library. This is the version documented on this website; the package name on PyPI is [`manim`](https://pypi.org/project/manim/)." +msgstr "" + +#: ../../source/faq/installation.md:26 +msgid "[ManimGL](https://github.com/3b1b/manim) is the latest released version of the version of the library developed by Grant \"3b1b\" Sanderson. It has more experimental features and breaking changes between versions are not documented. Check out its documentation [here](https://3b1b.github.io/manim/index.html); on PyPI the package name is [`manimgl`](https://pypi.org/project/manimgl/)." +msgstr "" + +#: ../../source/faq/installation.md:31 +msgid "[ManimCairo](https://github.com/3b1b/manim/tree/cairo-backend) is the name that is sometimes used for the old, pre-OpenGL version of `manimgl`. The latest version of it is available [on PyPI as `manimlib`](https://pypi.org/project/manimgl/), but note that if you intend to use it to compile some old project of Grant, you will likely have to install the exact version from the time the project was created from source." +msgstr "" + +#: ../../source/faq/installation.md:40 +msgid "Which version should I use?" +msgstr "" + +#: ../../source/faq/installation.md:42 +msgid "We recommend the community maintained version especially for beginners. It has been developed to be more stable, better tested and documented (!), and quicker to respond to community contributions. It is also perfectly reasonable to start learning with the community maintained version and then switch to a different version later on." +msgstr "" + +#: ../../source/faq/installation.md:47 +msgid "If you do not care so much about documentation or stability, and would like to use the exact same version that Grant is using, then use ManimGL." +msgstr "" + +#: ../../source/faq/installation.md:50 +msgid "And as mentioned above, ManimCairo should only be used for (re)rendering old 3Blue1Brown projects (basically 2019 and before)." +msgstr "" + +#: ../../source/faq/installation.md:55 +msgid "What are the differences between Manim, ManimGL, ManimCairo? Can I tell for which version a scene was written for?" +msgstr "" + +#: ../../source/faq/installation.md:57 +msgid "You can! The thing that usually gives it away is the `import` statement at the top of the file; depending on how the code imports Manim you can tell for which version of the code it was written for:" +msgstr "" + +#: ../../source/faq/installation.md:61 +msgid "If the code imports from `manim` (i.e., `from manim import *`, `import manim as mn`, etc.), then the code you are reading is supposed to be run with the community maintained version." +msgstr "" + +#: ../../source/faq/installation.md:63 +msgid "If the import reads `import manimlib` (or `from manimlib import *`), you are likely reading a file to be rendered with ManimGL." +msgstr "" + +#: ../../source/faq/installation.md:65 +msgid "And if the import reads `from manimlib.imports import *`, or perhaps even `from big_ol_pile_of_manim_imports import *` you are reading a snippet that is supposed to be rendered with an early, or very early version of ManimCairo, respectively." +msgstr "" + +#: ../../source/faq/installation.md:71 +msgid "How do I know which version of Manim I have installed?" +msgstr "" + +#: ../../source/faq/installation.md:73 +msgid "Assuming you can run `manim` in your terminal and there is some output, check the first line of the text being produced. If you are using the community maintained version, the first line of any output will be `Manim Community `. If it does not say that, you are likely using ManimGL." +msgstr "" + +#: ../../source/faq/installation.md:78 +msgid "You can also check the list of packages you have installed: if typing `python` in your terminal spawns the interpreter that corresponds to the Python installation you use (might also be `py`, or `python3`, depending on your operating system), running `python -m pip list` will print a list of all installed packages. Check whether `manim` or `manimgl` appear in that list." +msgstr "" + +#: ../../source/faq/installation.md:84 +msgid "Similarly, you can use `python -m pip install ` and `python -m pip uninstall ` to install and uninstall packages from that list, respectively." +msgstr "" + +#: ../../source/faq/installation.md:90 +msgid "I am following the video guide X to install Manim, but some step fails. What do I do?" +msgstr "" + +#: ../../source/faq/installation.md:92 +msgid "It is only natural that there are many video guides on installing Manim out there, given that Manim is a library used for creating videos. Unfortunately however, (YouTube) videos can't be updated easily (without uploading a new one, that is) when some step in the installation process changes, and so there are many **severely outdated** resources out there." +msgstr "" + +#: ../../source/faq/installation.md:98 +msgid "This is why we strongly recommend following our {doc}`written installation guide ` to guide you through the process. In case you prefer using a video guide regardless, please check whether the creator whose guide you have been watching has made a more recent version available, and otherwise please contact them directly. Asking for help in the community will likely lead to being suggested to follow our written guide." +msgstr "" + +#: ../../source/faq/installation.md:107 +msgid "Why does ManimPango fail to install when running `pip install manim`?" +msgstr "" + +#: ../../source/faq/installation.md:109 +msgid "This most likely means that pip was not able to use our pre-built wheels of the `manimpango` dependency. Let us know (via [Discord](https://www.manim.community/discord/) or by opening a [new issue on GitHub](https://github.com/ManimCommunity/ManimPango/issues/new)) which architecture you would like to see supported, and we'll see what we can do about it." +msgstr "" + +#: ../../source/faq/installation.md:116 +msgid "To fix errors when installing `manimpango`, you need to make sure you have all the necessary build requirements. Check out the detailed instructions given in [the BUILDING section](https://github.com/ManimCommunity/ManimPango#BUILDING) of [ManimPango's README](https://github.com/ManimCommunity/ManimPango)." +msgstr "" + +#: ../../source/faq/installation.md:123 +msgid "I am using Windows and get the error `X is not recognized as an internal or external command, operable program or batch file`" +msgstr "" + +#: ../../source/faq/installation.md:125 +msgid "Regardless of whether `X` says `python` or `manim`, this means that the executable you are trying to run is not located in one of the directories your system is looking for them (specified by the `PATH` variable). Take a look at the instructions {doc}`in the installation guide for Windows `, or [this StackExchange answer](https://superuser.com/questions/143119/how-do-i-add-python-to-the-windows-path/143121#143121) to get help with editing the `PATH` variable manually." +msgstr "" + +#: ../../source/faq/installation.md:132 +msgid "If `python` is recognized but not `manim` or `pip`, you can try running commands by prepending `python -m`. That is, `manim` becomes `python -m manim`, and `pip` becomes `python -m pip`." +msgstr "" + +#: ../../source/faq/installation.md:138 +msgid "I have tried using Chocolatey (`choco install manimce`) to install Manim, but it failed!" +msgstr "" + +#: ../../source/faq/installation.md:140 +msgid "Make sure that you were running the command with administrator permissions, otherwise there can be problems. If this is not the issue, read Chocolatey's output carefully, it should mention a `.log` file containing information why the process failed." +msgstr "" + +#: ../../source/faq/installation.md:145 +msgid "You are welcome to take this file (and any other input you feel might be relevant) and submit it to Manim's community to ask for help with your problem. See the {doc}`FAQ on getting help ` for instructions." +msgstr "" + +#: ../../source/faq/installation.md:151 +msgid "On Windows, when typing `python` or `python3` the Windows store is opened, can I fix this?" +msgstr "" + +#: ../../source/faq/installation.md:153 +msgid "Yes: you can remove these aliases with these steps:" +msgstr "" + +#: ../../source/faq/installation.md:155 +msgid "Go to the Windows Setting." +msgstr "" + +#: ../../source/faq/installation.md:156 +msgid "Under *Apps and Features* you will find application execution aliases." +msgstr "" + +#: ../../source/faq/installation.md:157 +msgid "Within this menu, disable the alias(es) that are causing the issue (`python` and/or `python3`)." +msgstr "" + +#: ../../source/faq/installation.md:162 +msgid "I am using Anaconda and get an `ImportError` mentioning that some Symbol is not found." +msgstr "" + + diff --git a/docs/i18n/gettext/faq/internals.pot b/docs/i18n/gettext/faq/internals.pot new file mode 100644 index 0000000000..abecf638d8 --- /dev/null +++ b/docs/i18n/gettext/faq/internals.pot @@ -0,0 +1,17 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Manim \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../source/faq/internals.md:1 +msgid "Where can I learn more about Manim's internal structure?" +msgstr "" + +#: ../../source/faq/internals.md:3 +msgid "Efforts to document the internal structure of Manim is ongoing on our [wiki](https://github.com/ManimCommunity/manim/wiki/Developer-documentation-(WIP))." +msgstr "" + + diff --git a/docs/i18n/gettext/faq/opengl.pot b/docs/i18n/gettext/faq/opengl.pot new file mode 100644 index 0000000000..21682a831d --- /dev/null +++ b/docs/i18n/gettext/faq/opengl.pot @@ -0,0 +1,29 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Manim \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../source/faq/opengl.md:1 +msgid "FAQ: OpenGL rendering" +msgstr "" + +#: ../../source/faq/opengl.md:3 +msgid "Are there any resources on how the OpenGL renderer in the community maintained version can be used?" +msgstr "" + +#: ../../source/faq/opengl.md:5 +msgid "Yes. Unfortunately, at this point, the official online documentation does not contain the relevant base classes like `OpenGLMobject` and `OpenGLVMobject` or specific OpenGL classes like `OpenGLSurface`, but documentation for some of them is available in form of docstrings [in the source code](https://github.com/ManimCommunity/manim/tree/main/manim/mobject/opengl)." +msgstr "" + +#: ../../source/faq/opengl.md:11 +msgid "Furthermore, [this user guide by *aquabeam*](https://www.aquabeam.me/manim/opengl_guide/) can be helpful to get started using the OpenGL renderer." +msgstr "" + +#: ../../source/faq/opengl.md:16 +msgid "I am trying to run an interactive scene with `--renderer=opengl` and `Scene.interactive_embed`, but an error (`sqlite3.ProgrammingError`) is raised. How can I fix this?" +msgstr "" + + diff --git a/docs/i18n/gettext/guides/configuration.pot b/docs/i18n/gettext/guides/configuration.pot new file mode 100644 index 0000000000..a7b66dda87 --- /dev/null +++ b/docs/i18n/gettext/guides/configuration.pot @@ -0,0 +1,313 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Manim \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../source/guides/configuration.rst:2 +msgid "Configuration" +msgstr "" + +#: ../../source/guides/configuration.rst:4 +msgid "Manim provides an extensive configuration system that allows it to adapt to many different use cases. There are many configuration options that can be configured at different times during the scene rendering process. Each option can be configured programmatically via `the ManimConfig class`_, at the time of command invocation via `command-line arguments`_, or at the time the library is first imported via `the config files`_." +msgstr "" + +#: ../../source/guides/configuration.rst:11 +msgid "The most common, simplest, and recommended way to configure Manim is via the command-line interface (CLI), which is described directly below." +msgstr "" + +#: ../../source/guides/configuration.rst:15 +msgid "Command-line arguments" +msgstr "" + +#: ../../source/guides/configuration.rst:17 +msgid "By far the most commonly used command in the CLI is the ``render`` command, which is used to render scene(s) to an output file. It is used with the following arguments:" +msgstr "" + +#: ../../source/guides/configuration.rst:24 +msgid "However, since Manim defaults to the :code:`render` command whenever no command is specified, the following form is far more common and can be used instead:" +msgstr "" + +#: ../../source/guides/configuration.rst:31 +msgid "An example of using the above form is:" +msgstr "" + +#: ../../source/guides/configuration.rst:37 +msgid "This asks Manim to search for a Scene class called :code:`SceneOne` inside the file ``file.py`` and render it with medium quality (specified by the ``-qm`` flag)." +msgstr "" + +#: ../../source/guides/configuration.rst:40 +msgid "Another frequently used flag is ``-p`` (\"preview\"), which makes manim open the rendered video after it's done rendering." +msgstr "" + +#: ../../source/guides/configuration.rst:43 +msgid "The ``-p`` flag does not change any properties of the global ``config`` dict. The ``-p`` flag is only a command-line convenience." +msgstr "" + +#: ../../source/guides/configuration.rst:47 +msgid "Advanced examples" +msgstr "" + +#: ../../source/guides/configuration.rst:49 +msgid "To render a scene in high quality, but only output the last frame of the scene instead of the whole video, you can execute" +msgstr "" + +#: ../../source/guides/configuration.rst:56 +msgid "The following example specifies the output file name (with the :code:`-o` flag), renders only the first ten animations (:code:`-n` flag) with a white background (:code:`-c` flag), and saves the animation as a ``.gif`` instead of as a ``.mp4`` file (``--format=gif`` flag). It uses the default quality and does not try to open the file after it is rendered." +msgstr "" + +#: ../../source/guides/configuration.rst:67 +msgid "A list of all CLI flags" +msgstr "" + +#: ../../source/guides/configuration.rst:75 +msgid "The ManimConfig class" +msgstr "" + +#: ../../source/guides/configuration.rst:77 +msgid "The most direct way of configuring Manim is through the global ``config`` object, which is an instance of :class:`.ManimConfig`. Each property of this class is a config option that can be accessed either with standard attribute syntax or with dict-like syntax:" +msgstr "" + +#: ../../source/guides/configuration.rst:88 +msgid "The former is preferred; the latter is provided for backwards compatibility." +msgstr "" + +#: ../../source/guides/configuration.rst:91 +msgid "Most classes, including :class:`.Camera`, :class:`.Mobject`, and :class:`.Animation`, read some of their default configuration from the global ``config``." +msgstr "" + +#: ../../source/guides/configuration.rst:103 +msgid ":class:`.ManimConfig` is designed to keep internal consistency. For example, setting ``frame_y_radius`` will affect ``frame_height``:" +msgstr "" + +#: ../../source/guides/configuration.rst:114 +msgid "The global ``config`` object is meant to be the single source of truth for all config options. All of the other ways of setting config options ultimately change the values of the global ``config`` object." +msgstr "" + +#: ../../source/guides/configuration.rst:118 +msgid "The following example illustrates the video resolution chosen for examples rendered in our documentation with a reference frame." +msgstr "" + +#: ../../source/guides/configuration.rst:140 +msgid "The config files" +msgstr "" + +#: ../../source/guides/configuration.rst:142 +msgid "As the last example shows, executing Manim from the command line may involve using many flags simultaneously. This may become a nuisance if you must execute the same script many times in a short time period, for example, when making small incremental tweaks to your scene script. For this reason, Manim can also be configured using a configuration file. A configuration file is a file ending with the suffix ``.cfg``." +msgstr "" + +#: ../../source/guides/configuration.rst:149 +msgid "To use a local configuration file when rendering your scene, you must create a file with the name ``manim.cfg`` in the same directory as your scene code." +msgstr "" + +#: ../../source/guides/configuration.rst:152 +msgid "The config file **must** be named ``manim.cfg``. Currently, Manim does not support config files with any other name." +msgstr "" + +#: ../../source/guides/configuration.rst:155 +msgid "The config file must start with the section header ``[CLI]``. The configuration options under this header have the same name as the CLI flags and serve the same purpose. Take, for example, the following config file." +msgstr "" + +#: ../../source/guides/configuration.rst:167 +msgid "Config files are parsed with the standard python library ``configparser``. In particular, they will ignore any line that starts with a pound symbol ``#``." +msgstr "" + +#: ../../source/guides/configuration.rst:170 +msgid "Now, executing the following command" +msgstr "" + +#: ../../source/guides/configuration.rst:176 +msgid "is equivalent to executing the following command, provided that ``manim.cfg`` is in the same directory as ," +msgstr "" + +#: ../../source/guides/configuration.rst:183 +msgid "The names of the configuration options admissible in config files are exactly the same as the **long names** of the corresponding command- line flags. For example, the ``-c`` and ``--background_color`` flags are interchangeable, but the config file only accepts :code:`background_color` as an admissible option." +msgstr "" + +#: ../../source/guides/configuration.rst:189 +msgid "Since config files are meant to replace CLI flags, all CLI flags can be set via a config file. Moreover, any config option can be set via a config file, whether or not it has an associated CLI flag. See the bottom of this document for a list of all CLI flags and config options." +msgstr "" + +#: ../../source/guides/configuration.rst:194 +msgid "Manim will look for a ``manim.cfg`` config file in the same directory as the file being rendered, and **not** in the directory of execution. For example," +msgstr "" + +#: ../../source/guides/configuration.rst:201 +msgid "will use the config file found in ``path/to/file.py``, if any. It will **not** use the config file found in the current working directory, even if it exists. In this way, the user may keep different config files for different scenes or projects, and execute them with the right configuration from anywhere in the system." +msgstr "" + +#: ../../source/guides/configuration.rst:207 +msgid "The file described here is called the **folder-wide** config file because it affects all scene scripts found in the same folder." +msgstr "" + +#: ../../source/guides/configuration.rst:212 +msgid "The user config file" +msgstr "" + +#: ../../source/guides/configuration.rst:214 +msgid "As explained in the previous section, a :code:`manim.cfg` config file only affects the scene scripts in its same folder. However, the user may also create a special config file that will apply to all scenes rendered by that user. This is referred to as the **user-wide** config file, and it will apply regardless of where Manim is executed from, and regardless of where the scene script is stored." +msgstr "" + +#: ../../source/guides/configuration.rst:221 +msgid "The user-wide config file lives in a special folder, depending on the operating system." +msgstr "" + +#: ../../source/guides/configuration.rst:224 +msgid "Windows: :code:`UserDirectory`/AppData/Roaming/Manim/manim.cfg" +msgstr "" + +#: ../../source/guides/configuration.rst:225 +msgid "MacOS: :code:`UserDirectory`/.config/manim/manim.cfg" +msgstr "" + +#: ../../source/guides/configuration.rst:226 +msgid "Linux: :code:`UserDirectory`/.config/manim/manim.cfg" +msgstr "" + +#: ../../source/guides/configuration.rst:228 +msgid "Here, :code:`UserDirectory` is the user's home folder." +msgstr "" + +#: ../../source/guides/configuration.rst:231 +msgid "A user may have many **folder-wide** config files, one per folder, but only one **user-wide** config file. Different users in the same computer may each have their own user-wide config file." +msgstr "" + +#: ../../source/guides/configuration.rst:235 +msgid "Do not store scene scripts in the same folder as the user-wide config file. In this case, the behavior is undefined." +msgstr "" + +#: ../../source/guides/configuration.rst:238 +msgid "Whenever you use Manim from anywhere in the system, Manim will look for a user-wide config file and read its configuration." +msgstr "" + +#: ../../source/guides/configuration.rst:243 +msgid "Cascading config files" +msgstr "" + +#: ../../source/guides/configuration.rst:245 +msgid "What happens if you execute Manim and it finds both a folder-wide config file and a user-wide config file? Manim will read both files, but if they are incompatible, **the folder-wide file takes precedence**." +msgstr "" + +#: ../../source/guides/configuration.rst:249 +msgid "For example, take the following user-wide config file" +msgstr "" + +#: ../../source/guides/configuration.rst:259 +msgid "and the following folder-wide file" +msgstr "" + +#: ../../source/guides/configuration.rst:267 +msgid "Then, executing :code:`manim SceneName` will be equivalent to not using any config files and executing" +msgstr "" + +#: ../../source/guides/configuration.rst:274 +msgid "Any command-line flags have precedence over any config file. For example, using the previous two config files and executing :code:`manim -c RED SceneName` is equivalent to not using any config files and executing" +msgstr "" + +#: ../../source/guides/configuration.rst:283 +msgid "There is also a **library-wide** config file that determines Manim's default behavior and applies to every user of the library. It has the least precedence, so any config options in the user-wide and any folder-wide files will override the library-wide file. This is referred to as the *cascading* config file system." +msgstr "" + +#: ../../source/guides/configuration.rst:289 +msgid "**The user should not try to modify the library-wide file**. Contributors should receive explicit confirmation from the core developer team before modifying it." +msgstr "" + +#: ../../source/guides/configuration.rst:295 +msgid "Order of operations" +msgstr "" + +#: ../../source/guides/configuration.rst:304 +msgid "With so many different ways of configuring Manim, it can be difficult to know when each config option is being set. In fact, this will depend on how Manim is being used." +msgstr "" + +#: ../../source/guides/configuration.rst:308 +msgid "If Manim is imported from a module, then the configuration system will follow these steps:" +msgstr "" + +#: ../../source/guides/configuration.rst:311 +msgid "The library-wide config file is loaded." +msgstr "" + +#: ../../source/guides/configuration.rst:312 +msgid "The user-wide and folder-wide files are loaded if they exist." +msgstr "" + +#: ../../source/guides/configuration.rst:313 +msgid "All files found in the previous two steps are parsed in a single :class:`ConfigParser` object, called ``parser``. This is where *cascading* happens." +msgstr "" + +#: ../../source/guides/configuration.rst:316 +msgid ":class:`logging.Logger` is instantiated to create Manim's global ``logger`` object. It is configured using the \"logger\" section of the parser, i.e. ``parser['logger']``." +msgstr "" + +#: ../../source/guides/configuration.rst:319 +msgid ":class:`ManimConfig` is instantiated to create the global ``config`` object." +msgstr "" + +#: ../../source/guides/configuration.rst:320 +msgid "The ``parser`` from step 3 is fed into the ``config`` from step 5 via :meth:`ManimConfig.digest_parser`." +msgstr "" + +#: ../../source/guides/configuration.rst:322 +msgid "Both ``logger`` and ``config`` are exposed to the user." +msgstr "" + +#: ../../source/guides/configuration.rst:324 +msgid "If Manim is being invoked from the command line, all of the previous steps happen, and are complemented by:" +msgstr "" + +#: ../../source/guides/configuration.rst:327 +msgid "The CLI flags are parsed and fed into ``config`` via :meth:`~ManimConfig.digest_args`." +msgstr "" + +#: ../../source/guides/configuration.rst:329 +msgid "If the ``--config_file`` flag was used, a new :class:`ConfigParser` object is created with the contents of the library-wide file, the user-wide file if it exists, and the file passed via ``--config_file``. In this case, the folder-wide file, if it exists, is ignored." +msgstr "" + +#: ../../source/guides/configuration.rst:333 +msgid "The new parser is fed into ``config``." +msgstr "" + +#: ../../source/guides/configuration.rst:334 +msgid "The rest of the CLI flags are processed." +msgstr "" + +#: ../../source/guides/configuration.rst:336 +msgid "To summarize, the order of precedence for configuration options, from lowest to highest precedence is:" +msgstr "" + +#: ../../source/guides/configuration.rst:339 +msgid "Library-wide config file," +msgstr "" + +#: ../../source/guides/configuration.rst:340 +msgid "user-wide config file, if it exists," +msgstr "" + +#: ../../source/guides/configuration.rst:341 +msgid "folder-wide config file, if it exists OR custom config file, if passed via ``--config_file``," +msgstr "" + +#: ../../source/guides/configuration.rst:343 +msgid "other CLI flags, and" +msgstr "" + +#: ../../source/guides/configuration.rst:344 +msgid "any programmatic changes made after the config system is set." +msgstr "" + +#: ../../source/guides/configuration.rst:348 +msgid "A list of all config options" +msgstr "" + +#: ../../source/guides/configuration.rst:369 +msgid "Accessing CLI command options" +msgstr "" + +#: ../../source/guides/configuration.rst:371 +msgid "Entering ``manim``, or ``manim --help``, will open the main help page." +msgstr "" + + diff --git a/docs/i18n/gettext/guides/deep_dive.pot b/docs/i18n/gettext/guides/deep_dive.pot new file mode 100644 index 0000000000..bb0c89af4d --- /dev/null +++ b/docs/i18n/gettext/guides/deep_dive.pot @@ -0,0 +1,633 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Manim \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../source/guides/deep_dive.rst:2 +msgid "A deep dive into Manim's internals" +msgstr "" + +#: ../../source/guides/deep_dive.rst:4 +msgid "**Author:** `Benjamin Hackl `__" +msgstr "" + +#: ../../source/guides/deep_dive.rst:6 +msgid "Disclaimer" +msgstr "" + +#: ../../source/guides/deep_dive.rst:8 +msgid "This guide reflects the state of the library as of version ``v0.16.0`` and primarily treats the Cairo renderer. The situation in the latest version of Manim might be different; in case of substantial deviations we will add a note below." +msgstr "" + +#: ../../source/guides/deep_dive.rst:14 +msgid "Introduction" +msgstr "" + +#: ../../source/guides/deep_dive.rst:16 +msgid "Manim can be a wonderful library, if it behaves the way you would like it to, and/or the way you expect it to. Unfortunately, this is not always the case (as you probably know if you have played with some manimations yourself already). To understand where things *go wrong*, digging through the library's source code is sometimes the only option -- but in order to do that, you need to know where to start digging." +msgstr "" + +#: ../../source/guides/deep_dive.rst:23 +msgid "This article is intended as some sort of life line through the render process. We aim to give an appropriate amount of detail describing what happens when Manim reads your scene code and produces the corresponding animation. Throughout this article, we will focus on the following toy example::" +msgstr "" + +#: ../../source/guides/deep_dive.rst:43 +msgid "Before we go into details or even look at the rendered output of this scene, let us first describe verbally what happens in this *manimation*. In the first three lines of the ``construct`` method, a :class:`.Square` and a :class:`.Circle` are initialized, then the square is added to the scene. The first frame of the rendered output should thus show an orange square." +msgstr "" + +#: ../../source/guides/deep_dive.rst:49 +msgid "Then the actual animations happen: the square first transforms into a circle, then a :class:`.Dot` is created (Where do you guess the dot is located when it is first added to the scene? Answering this already requires detailed knowledge about the render process.). The dot has an updater attached to it, and as the circle moves right, the dot moves with it. In the end, all mobjects are faded out." +msgstr "" + +#: ../../source/guides/deep_dive.rst:56 +msgid "Actually rendering the code yields the following video:" +msgstr "" + +#: ../../source/guides/deep_dive.rst:75 +msgid "For this example, the output (fortunately) coincides with our expectations." +msgstr "" + +#: ../../source/guides/deep_dive.rst:78 +msgid "Overview" +msgstr "" + +#: ../../source/guides/deep_dive.rst:80 +msgid "Because there is a lot of information in this article, here is a brief overview discussing the contents of the following chapters on a very high level." +msgstr "" + +#: ../../source/guides/deep_dive.rst:83 +msgid "`Preliminaries`_: In this chapter we unravel all the steps that take place to prepare a scene for rendering; right until the point where the user-overridden ``construct`` method is ran. This includes a brief discussion on using Manim's CLI versus other means of rendering (e.g., via Jupyter notebooks, or in your Python script by calling the :meth:`.Scene.render` method yourself)." +msgstr "" + +#: ../../source/guides/deep_dive.rst:88 +msgid "`Mobject Initialization`_: For the second chapter we dive into creating and handling Mobjects, the basic elements that should be displayed in our scene. We discuss the :class:`.Mobject` base class, how there are essentially three different types of Mobjects, and then discuss the most important of them, vectorized Mobjects. In particular, we describe the internal point data structure that governs how the mechanism responsible for drawing the vectorized Mobject to the screen sets the corresponding Bézier curves. We conclude the chapter with a tour into :meth:`.Scene.add`, the bookkeeping mechanism controlling which mobjects should be rendered." +msgstr "" + +#: ../../source/guides/deep_dive.rst:97 +msgid "`Animations and the Render Loop`_: And finally, in the last chapter we walk through the instantiation of :class:`.Animation` objects (the blueprints that hold information on how Mobjects should be modified when the render loop runs), followed by a investigation of the infamous :meth:`.Scene.play` call. We will see that there are three relevant parts in a :meth:`.Scene.play` call; a part in which the passed animations and keyword arguments are processed and prepared, followed by the actual \"render loop\" in which the library steps through a time line and renders frame by frame. The final part does some post-processing to save a short video segment (\"partial movie file\") and cleanup for the next call to :meth:`.Scene.play`. In the end, after all of :meth:`.Scene.construct` has been run, the library combines the partial movie files to one video." +msgstr "" + +#: ../../source/guides/deep_dive.rst:110 +msgid "And with that, let us get *in medias res*." +msgstr "" + +#: ../../source/guides/deep_dive.rst:113 +msgid "Preliminaries" +msgstr "" + +#: ../../source/guides/deep_dive.rst:116 +msgid "Importing the library" +msgstr "" + +#: ../../source/guides/deep_dive.rst:118 +msgid "Independent of how exactly you are telling your system to render the scene, i.e., whether you run ``manim -qm -p file_name.py ToyExample``, or whether you are rendering the scene directly from the Python script via a snippet like" +msgstr "" + +#: ../../source/guides/deep_dive.rst:129 +msgid "or whether you are rendering the code in a Jupyter notebook, you are still telling your python interpreter to import the library. The usual pattern used to do this is" +msgstr "" + +#: ../../source/guides/deep_dive.rst:136 +msgid "which (while being a debatable strategy in general) imports a lot of classes and functions shipped with the library and makes them available in your global name space. I explicitly avoided stating that it imports **all** classes and functions of the library, because it does not do that: Manim makes use of the practice described in `Section 6.4.1 of the Python tutorial `__, and all module members that should be exposed to the user upon running the ``*``-import are explicitly declared in the ``__all__`` variable of the module." +msgstr "" + +#: ../../source/guides/deep_dive.rst:144 +msgid "Manim also uses this strategy internally: taking a peek at the file that is run when the import is called, ``__init__.py`` (see `here `__), you will notice that most of the code in that module is concerned with importing members from various different submodules, again using ``*``-imports." +msgstr "" + +#: ../../source/guides/deep_dive.rst:152 +msgid "If you would ever contribute a new submodule to Manim, the main ``__init__.py`` is where it would have to be listed in order to make its members accessible to users after importing the library." +msgstr "" + +#: ../../source/guides/deep_dive.rst:156 +msgid "In that file, there is one particular import at the beginning of the file however, namely::" +msgstr "" + +#: ../../source/guides/deep_dive.rst:161 +msgid "This initializes Manim's global configuration system, which is used in various places throughout the library. After the library runs this line, the current configuration options are set. The code in there takes care of reading the options in your ``.cfg`` files (all users have at least the global one that is shipped with the library) as well as correctly handling command line arguments (if you used the CLI to render)." +msgstr "" + +#: ../../source/guides/deep_dive.rst:167 +msgid "You can read more about the config system in the :doc:`corresponding thematic guide `, and if you are interested in learning more about the internals of the configuration system and how it is initialized, follow the code flow starting in `the config module's init file `__." +msgstr "" + +#: ../../source/guides/deep_dive.rst:173 +msgid "Now that the library is imported, we can turn our attention to the next step: reading your scene code (which is not particularly exciting, Python just creates a new class ``ToyExample`` based on our code; Manim is virtually not involved in that step, with the exception that ``ToyExample`` inherits from ``Scene``)." +msgstr "" + +#: ../../source/guides/deep_dive.rst:178 +msgid "However, with the ``ToyExample`` class created and ready to go, there is a new excellent question to answer: how is the code in our ``construct`` method actually executed?" +msgstr "" + +#: ../../source/guides/deep_dive.rst:183 +msgid "Scene instantiation and rendering" +msgstr "" + +#: ../../source/guides/deep_dive.rst:185 +msgid "The answer to this question depends on how exactly you are running the code. To make things a bit clearer, let us first consider the case that you have created a file ``toy_example.py`` which looks like this::" +msgstr "" + +#: ../../source/guides/deep_dive.rst:208 +msgid "With such a file, the desired scene is rendered by simply running this Python script via ``python toy_example.py``. Then, as described above, the library is imported and Python has read and defined the ``ToyExample`` class (but, read carefully: *no instance of this class has been created yet*)." +msgstr "" + +#: ../../source/guides/deep_dive.rst:213 +msgid "At this point, the interpreter is about to enter the ``tempconfig`` context manager. Even if you have not seen Manim's ``tempconfig`` before, it's name already suggests what it does: it creates a copy of the current state of the configuration, applies the changes to the key-value pairs in the passed dictionary, and upon leaving the context the original version of the configuration is restored. TL;DR: it provides a fancy way of temporarily setting configuration options." +msgstr "" + +#: ../../source/guides/deep_dive.rst:221 +msgid "Inside the context manager, two things happen: an actual ``ToyExample``-scene object is instantiated, and the ``render`` method is called. Every way of using Manim ultimately does something along of these lines, the library always instantiates the scene object and then calls its ``render`` method. To illustrate that this really is the case, let us briefly look at the two most common ways of rendering scenes:" +msgstr "" + +#: ../../source/guides/deep_dive.rst:228 +msgid "**Command Line Interface.** When using the CLI and running the command ``manim -qm -p toy_example.py ToyExample`` in your terminal, the actual entry point is Manim's ``__main__.py`` file (located `here `__. Manim uses `Click `__ to implement the command line interface, and the corresponding code is located in Manim's ``cli`` module (https://github.com/ManimCommunity/manim/tree/main/manim/cli). The corresponding code creating the scene class and calling its render method is located `here `__." +msgstr "" + +#: ../../source/guides/deep_dive.rst:238 +msgid "**Jupyter notebooks.** In Jupyter notebooks, the communication with the library is handled by the ``%%manim`` magic command, which is implemented in the ``manim.utils.ipython_magic`` module. There is :meth:`some documentation <.ManimMagic.manim>` available for the magic command, and the code creating the scene class and calling its render method is located `here `__." +msgstr "" + +#: ../../source/guides/deep_dive.rst:246 +msgid "Now that we know that either way, a :class:`.Scene` object is created, let us investigate what Manim does when that happens. When instantiating our scene object" +msgstr "" + +#: ../../source/guides/deep_dive.rst:253 +msgid "the ``Scene.__init__`` method is called, given that we did not implement our own initialization method. Inspecting the corresponding code (see `here `__) reveals that ``Scene.__init__`` first sets several attributes of the scene objects that do not depend on any configuration options set in ``config``. Then the scene inspects the value of ``config.renderer``, and based on its value, either instantiates a ``CairoRenderer`` or an ``OpenGLRenderer`` object and assigns it to its ``renderer`` attribute." +msgstr "" + +#: ../../source/guides/deep_dive.rst:261 +msgid "The scene then asks its renderer to initialize the scene by calling" +msgstr "" + +#: ../../source/guides/deep_dive.rst:267 +msgid "Inspecting both the default Cairo renderer and the OpenGL renderer shows that the ``init_scene`` method effectively makes the renderer instantiate a :class:`.SceneFileWriter` object, which basically is Manim's interface to ``ffmpeg`` and actually writes the movie file. The Cairo renderer (see the implementation `here `__) does not require any further initialization. The OpenGL renderer does some additional setup to enable the realtime rendering preview window, which we do not go into detail further here." +msgstr "" + +#: ../../source/guides/deep_dive.rst:276 +msgid "Currently, there is a lot of interplay between a scene and its renderer. This is a flaw in Manim's current architecture, and we are working on reducing this interdependency to achieve a less convoluted code flow." +msgstr "" + +#: ../../source/guides/deep_dive.rst:280 +msgid "After the renderer has been instantiated and initialized its file writer, the scene populates further initial attributes (notable mention: the ``mobjects`` attribute which keeps track of the mobjects that have been added to the scene). It is then done with its instantiation and ready to be rendered." +msgstr "" + +#: ../../source/guides/deep_dive.rst:285 +msgid "The rest of this article is concerned with the last line in our toy example script::" +msgstr "" + +#: ../../source/guides/deep_dive.rst:289 +msgid "This is where the actual magic happens." +msgstr "" + +#: ../../source/guides/deep_dive.rst:291 +msgid "Inspecting the `implementation of the render method `__ reveals that there are several hooks that can be used for pre- or postprocessing a scene. Unsurprisingly, :meth:`.Scene.render` describes the full *render cycle* of a scene. During this life cycle, there are three custom methods whose base implementation is empty and that can be overwritten to suit your purposes. In the order they are called, these customizable methods are:" +msgstr "" + +#: ../../source/guides/deep_dive.rst:298 +msgid ":meth:`.Scene.setup`, which is intended for preparing and, well, *setting up* the scene for your animation (e.g., adding initial mobjects, assigning custom attributes to your scene class, etc.)," +msgstr "" + +#: ../../source/guides/deep_dive.rst:301 +msgid ":meth:`.Scene.construct`, which is the *script* for your screen play and contains programmatic descriptions of your animations, and" +msgstr "" + +#: ../../source/guides/deep_dive.rst:303 +msgid ":meth:`.Scene.tear_down`, which is intended for any operations you might want to run on the scene after the last frame has already been rendered (for example, this could run some code that generates a custom thumbnail for the video based on the state of the objects in the scene -- this hook is more relevant for situations where Manim is used within other Python scripts)." +msgstr "" + +#: ../../source/guides/deep_dive.rst:310 +msgid "After these three methods are run, the animations have been fully rendered, and Manim calls :meth:`.CairoRenderer.scene_finished` to gracefully complete the rendering process. This checks whether any animations have been played -- and if so, it tells the :class:`.SceneFileWriter` to close the pipe to ``ffmpeg``. If not, Manim assumes that a static image should be output which it then renders using the same strategy by calling the render loop (see below) once." +msgstr "" + +#: ../../source/guides/deep_dive.rst:318 +msgid "**Back in our toy example,** the call to :meth:`.Scene.render` first triggers :meth:`.Scene.setup` (which only consists of ``pass``), followed by a call of :meth:`.Scene.construct`. At this point, our *animation script* is run, starting with the initialization of ``orange_square``." +msgstr "" + +#: ../../source/guides/deep_dive.rst:325 +msgid "Mobject Initialization" +msgstr "" + +#: ../../source/guides/deep_dive.rst:327 +msgid "Mobjects are, in a nutshell, the Python objects that represent all the *things* we want to display in our scene. Before we follow our debugger into the depths of mobject initialization code, it makes sense to discuss Manim's different types of Mobjects and their basic data structure." +msgstr "" + +#: ../../source/guides/deep_dive.rst:334 +msgid "What even is a Mobject?" +msgstr "" + +#: ../../source/guides/deep_dive.rst:336 +msgid ":class:`.Mobject` stands for *mathematical object* or *Manim object* (depends on who you ask 😄). The Python class :class:`.Mobject` is the base class for all objects that should be displayed on screen. Looking at the `initialization method `__ of :class:`.Mobject`, you will find that not too much happens in there:" +msgstr "" + +#: ../../source/guides/deep_dive.rst:343 +msgid "some initial attribute values are assigned, like ``name`` (which makes the render logs mention the name of the mobject instead of its type), ``submobjects`` (initially an empty list), ``color``, and some others." +msgstr "" + +#: ../../source/guides/deep_dive.rst:346 +msgid "Then, two methods related to *points* are called: ``reset_points`` followed by ``generate_points``," +msgstr "" + +#: ../../source/guides/deep_dive.rst:348 +msgid "and finally, ``init_colors`` is called." +msgstr "" + +#: ../../source/guides/deep_dive.rst:350 +msgid "Digging deeper, you will find that :meth:`.Mobject.reset_points` simply sets the ``points`` attribute of the mobject to an empty NumPy vector, while the other two methods, :meth:`.Mobject.generate_points` and :meth:`.Mobject.init_colors` are just implemented as ``pass``." +msgstr "" + +#: ../../source/guides/deep_dive.rst:355 +msgid "This makes sense: :class:`.Mobject` is not supposed to be used as an *actual* object that is displayed on screen; in fact the camera (which we will discuss later in more detail; it is the class that is, for the Cairo renderer, responsible for \"taking a picture\" of the current scene) does not process \"pure\" :class:`Mobjects <.Mobject>` in any way, they *cannot* even appear in the rendered output." +msgstr "" + +#: ../../source/guides/deep_dive.rst:362 +msgid "This is where different types of mobjects come into play. Roughly speaking, the Cairo renderer setup knows three different types of mobjects that can be rendered:" +msgstr "" + +#: ../../source/guides/deep_dive.rst:366 +msgid ":class:`.ImageMobject`, which represent images that you can display in your scene," +msgstr "" + +#: ../../source/guides/deep_dive.rst:368 +msgid ":class:`.PMobject`, which are very special mobjects used to represent point clouds; we will not discuss them further in this guide," +msgstr "" + +#: ../../source/guides/deep_dive.rst:370 +msgid ":class:`.VMobject`, which are *vectorized mobjects*, that is, mobjects that consist of points that are connected via curves. These are pretty much everywhere, and we will discuss them in detail in the next section." +msgstr "" + +#: ../../source/guides/deep_dive.rst:375 +msgid "... and what are VMobjects?" +msgstr "" + +#: ../../source/guides/deep_dive.rst:377 +msgid "As just mentioned, :class:`VMobjects <.VMobject>` represent vectorized mobjects. To render a :class:`.VMobject`, the camera looks at the ``points`` attribute of a :class:`.VMobject` and divides it into sets of four points each. Each of these sets is then used to construct a cubic Bézier curve with the first and last entry describing the end points of the curve (\"anchors\"), and the second and third entry describing the control points in between (\"handles\")." +msgstr "" + +#: ../../source/guides/deep_dive.rst:386 +msgid "To learn more about Bézier curves, take a look at the excellent online textbook `A Primer on Bézier curves `__ by `Pomax `__ -- there is an playground representing cubic Bézier curves `in §1 `__, the red and yellow points are \"anchors\", and the green and blue points are \"handles\"." +msgstr "" + +#: ../../source/guides/deep_dive.rst:393 +msgid "In contrast to :class:`.Mobject`, :class:`.VMobject` can be displayed on screen (even though, technically, it is still considered a base class). To illustrate how points are processed, consider the following short example of a :class:`.VMobject` with 8 points (and thus made out of 8/4 = 2 cubic Bézier curves). The resulting :class:`.VMobject` is drawn in green. The handles are drawn as red dots with a line to their closest anchor." +msgstr "" + +#: ../../source/guides/deep_dive.rst:433 +msgid "Manually setting the points of your :class:`.VMobject` is usually discouraged; there are specialized methods that can take care of that for you -- but it might be relevant when implementing your own, custom :class:`.VMobject`." +msgstr "" + +#: ../../source/guides/deep_dive.rst:441 +msgid "Squares and Circles: back to our Toy Example" +msgstr "" + +#: ../../source/guides/deep_dive.rst:443 +msgid "With a basic understanding of different types of mobjects, and an idea of how vectorized mobjects are built we can now come back to our toy example and the execution of the :meth:`.Scene.construct` method. In the first two lines of our animation script, the ``orange_square`` and the ``blue_circle`` are initialized." +msgstr "" + +#: ../../source/guides/deep_dive.rst:450 +msgid "When creating the orange square by running" +msgstr "" + +#: ../../source/guides/deep_dive.rst:456 +msgid "the initialization method of :class:`.Square`, ``Square.__init__``, is called. `Looking at the implementation `__, we can see that the ``side_length`` attribute of the square is set, and then" +msgstr "" + +#: ../../source/guides/deep_dive.rst:466 +msgid "is called. This ``super`` call is the Python way of calling the initialization function of the parent class. As :class:`.Square` inherits from :class:`.Rectangle`, the next method called is ``Rectangle.__init__``. There, only the first three lines are really relevant for us::" +msgstr "" + +#: ../../source/guides/deep_dive.rst:476 +msgid "First, the initialization function of the parent class of :class:`.Rectangle` -- :class:`.Polygon` -- is called. The four positional arguments passed are the four corners of the polygon: ``UR`` is up right (and equal to ``UP + RIGHT``), ``UL`` is up left (and equal to ``UP + LEFT``), and so forth. Before we follow our debugger deeper, let us observe what happens with the constructed polygon: the remaining two lines stretch the polygon to fit the specified width and height such that a rectangle with the desired measurements is created." +msgstr "" + +#: ../../source/guides/deep_dive.rst:486 +msgid "The initialization function of :class:`.Polygon` is particularly simple, it only calls the initialization function of its parent class, :class:`.Polygram`. There, we have almost reached the end of the chain: :class:`.Polygram` inherits from :class:`.VMobject`, whose initialization function mainly sets the values of some attributes (quite similar to ``Mobject.__init__``, but more specific to the Bézier curves that make up the mobject)." +msgstr "" + +#: ../../source/guides/deep_dive.rst:494 +msgid "After calling the initialization function of :class:`.VMobject`, the constructor of :class:`.Polygram` also does something somewhat odd: it sets the points (which, you might remember above, should actually be set in a corresponding ``generate_points`` method of :class:`.Polygram`)." +msgstr "" + +#: ../../source/guides/deep_dive.rst:501 +msgid "In several instances, the implementation of mobjects does not really stick to all aspects of Manim's interface. This is unfortunate, and increasing consistency is something that we actively work on. Help is welcome!" +msgstr "" + +#: ../../source/guides/deep_dive.rst:506 +msgid "Without going too much into detail, :class:`.Polygram` sets its ``points`` attribute via :meth:`.VMobject.start_new_path`, :meth:`.VMobject.add_points_as_corners`, which take care of setting the quadruples of anchors and handles appropriately. After the points are set, Python continues to process the call stack until it reaches the method that was first called; the initialization method of :class:`.Square`. After this, the square is initialized and assigned to the ``orange_square`` variable." +msgstr "" + +#: ../../source/guides/deep_dive.rst:516 +msgid "The initialization of ``blue_circle`` is similar to the one of ``orange_square``, with the main difference being that the inheritance chain of :class:`.Circle` is different. Let us briefly follow the trace of the debugger:" +msgstr "" + +#: ../../source/guides/deep_dive.rst:521 +msgid "The implementation of :meth:`.Circle.__init__` immediately calls the initialization method of :class:`.Arc`, as a circle in Manim is simply an arc with an angle of :math:`\\tau = 2\\pi`. When initializing the arc, some basic attributes are set (like ``Arc.radius``, ``Arc.arc_center``, ``Arc.start_angle``, and ``Arc.angle``), and then the initialization method of its parent class, :class:`.TipableVMobject`, is called (which is a rather abstract base class for mobjects which a arrow tip can be attached to). Note that in contrast to :class:`.Polygram`, this class does **not** preemptively generate the points of the circle." +msgstr "" + +#: ../../source/guides/deep_dive.rst:532 +msgid "After that, things are less exciting: :class:`.TipableVMobject` again sets some attributes relevant for adding arrow tips, and afterwards passes to the initialization method of :class:`.VMobject`. From there, :class:`.Mobject` is initialized and :meth:`.Mobject.generate_points` is called, which actually runs the method implemented in :meth:`.Arc.generate_points`." +msgstr "" + +#: ../../source/guides/deep_dive.rst:539 +msgid "After both our ``orange_square`` and the ``blue_circle`` are initialized, the square is actually added to the scene. The :meth:`.Scene.add` method is actually doing a few interesting things, so it is worth to dig a bit deeper in the next section." +msgstr "" + +#: ../../source/guides/deep_dive.rst:546 +msgid "Adding Mobjects to the Scene" +msgstr "" + +#: ../../source/guides/deep_dive.rst:548 +msgid "The code in our ``construct`` method that is run next is" +msgstr "" + +#: ../../source/guides/deep_dive.rst:554 +msgid "From a high-level point of view, :meth:`.Scene.add` adds the ``orange_square`` to the list of mobjects that should be rendered, which is stored in the ``mobjects`` attribute of the scene. However, it does so in a very careful way to avoid the situation that a mobject is being added to the scene more than once. At a first glance, this sounds like a simple task -- the problem is that ``Scene.mobjects`` is not a \"flat\" list of mobjects, but a list of mobjects which might contain mobjects themselves, and so on." +msgstr "" + +#: ../../source/guides/deep_dive.rst:563 +msgid "Stepping through the code in :meth:`.Scene.add`, we see that first it is checked whether we are currently using the OpenGL renderer (which we are not) -- adding mobjects to the scene works slightly different (and actually easier!) for the OpenGL renderer. Then, the code branch for the Cairo renderer is entered and the list of so-called foreground mobjects (which are rendered on top of all other mobjects) is added to the list of passed mobjects. This is to ensure that the foreground mobjects will stay above of the other mobjects, even after adding the new ones. In our case, the list of foreground mobjects is actually empty, and nothing changes." +msgstr "" + +#: ../../source/guides/deep_dive.rst:574 +msgid "Next, :meth:`.Scene.restructure_mobjects` is called with the list of mobjects to be added as the ``to_remove`` argument, which might sound odd at first. Practically, this ensures that mobjects are not added twice, as mentioned above: if they were present in the scene ``Scene.mobjects`` list before (even if they were contained as a child of some other mobject), they are first removed from the list. The way :meth:`.Scene.restrucutre_mobjects` works is rather aggressive: It always operates on a given list of mobjects; in the ``add`` method two different lists occur: the default one, ``Scene.mobjects`` (no extra keyword argument is passed), and ``Scene.moving_mobjects`` (which we will discuss later in more detail). It iterates through all of the members of the list, and checks whether any of the mobjects passed in ``to_remove`` are contained as children (in any nesting level). If so, **their parent mobject is deconstructed** and their siblings are inserted directly one level higher. Consider the following example::" +msgstr "" + +#: ../../source/guides/deep_dive.rst:604 +msgid "Note that the group is disbanded and the circle moves into the root layer of mobjects in ``test_scene.mobjects``." +msgstr "" + +#: ../../source/guides/deep_dive.rst:607 +msgid "After the mobject list is \"restructured\", the mobject to be added are simply appended to ``Scene.mobjects``. In our toy example, the ``Scene.mobjects`` list is actually empty, so the ``restructure_mobjects`` method does not actually do anything. The ``orange_square`` is simply added to ``Scene.mobjects``, and as the aforementioned ``Scene.moving_mobjects`` list is, at this point, also still empty, nothing happens and :meth:`.Scene.add` returns." +msgstr "" + +#: ../../source/guides/deep_dive.rst:615 +msgid "We will hear more about the ``moving_mobject`` list when we discuss the render loop. Before we do that, let us look at the next line of code in our toy example, which includes the initialization of an animation class, ::" +msgstr "" + +#: ../../source/guides/deep_dive.rst:623 +msgid "Hence it is time to talk about :class:`.Animation`." +msgstr "" + +#: ../../source/guides/deep_dive.rst:627 +msgid "Animations and the Render Loop" +msgstr "" + +#: ../../source/guides/deep_dive.rst:630 +msgid "Initializing animations" +msgstr "" + +#: ../../source/guides/deep_dive.rst:632 +msgid "Before we follow the trace of the debugger, let us briefly discuss the general structure of the (abstract) base class :class:`.Animation`. An animation object holds all the information necessary for the renderer to generate the corresponding frames. Animations (in the sense of animation objects) in Manim are *always* tied to a specific mobject; even in the case of :class:`.AnimationGroup` (which you should actually think of as an animation on a group of mobjects rather than a group of animations). Moreover, except for in a particular special case, the run time of animations is also fixed and known beforehand." +msgstr "" + +#: ../../source/guides/deep_dive.rst:642 +msgid "The initialization of animations actually is not very exciting, :meth:`.Animation.__init__` merely sets some attributes derived from the passed keyword arguments and additionally ensures that the ``Animation.starting_mobject`` and ``Animation.mobject`` attributes are populated. Once the animation is played, the ``starting_mobject`` attribute holds an unmodified copy of the mobject the animation is attached to; during the initialization it is set to a placeholder mobject. The ``mobject`` attribute is set to the mobject the animation is attached to." +msgstr "" + +#: ../../source/guides/deep_dive.rst:652 +msgid "Animations have a few special methods which are called during the render loop:" +msgstr "" + +#: ../../source/guides/deep_dive.rst:655 +msgid ":meth:`.Animation.begin`, which is called (as hinted by its name) at the beginning of every animation, so before the first frame is rendered. In it, all the required setup for the animation happens." +msgstr "" + +#: ../../source/guides/deep_dive.rst:658 +msgid ":meth:`.Animation.finish` is the counterpart to the ``begin`` method which is called at the end of the life cycle of the animation (after the last frame has been rendered)." +msgstr "" + +#: ../../source/guides/deep_dive.rst:661 +msgid ":meth:`.Animation.interpolate` is the method that updates the mobject attached to the animation to the corresponding animation completion percentage. For example, if in the render loop, ``some_animation.interpolate(0.5)`` is called, the attached mobject will be updated to the state where 50% of the animation are completed." +msgstr "" + +#: ../../source/guides/deep_dive.rst:667 +msgid "We will discuss details about these and some further animation methods once we walk through the actual render loop. For now, we continue with our toy example and the code that is run when initializing the :class:`.ReplacementTransform` animation." +msgstr "" + +#: ../../source/guides/deep_dive.rst:672 +msgid "The initialization method of :class:`.ReplacementTransform` only consists of a call to the constructor of its parent class, :class:`.Transform`, with the additional keyword argument ``replace_mobject_with_target_in_scene`` set to ``True``. :class:`.Transform` then sets attributes that control how the points of the starting mobject are deformed into the points of the target mobject, and then passes on to the initialization method of :class:`.Animation`. Other basic properties of the animation (like its ``run_time``, the ``rate_func``, etc.) are processed there -- and then the animation object is fully initialized and ready to be played." +msgstr "" + +#: ../../source/guides/deep_dive.rst:685 +msgid "The ``play`` call: preparing to enter Manim's render loop" +msgstr "" + +#: ../../source/guides/deep_dive.rst:687 +msgid "We are finally there, the render loop is in our reach. Let us walk through the code that is run when :meth:`.Scene.play` is called." +msgstr "" + +#: ../../source/guides/deep_dive.rst:692 +msgid "Recall that this article is specifically about the Cairo renderer. Up to here, things were more or less the same for the OpenGL renderer as well; while some base mobjects might be different, the control flow and lifecycle of mobjects is still more or less the same. There are more substantial differences when it comes to the rendering loop." +msgstr "" + +#: ../../source/guides/deep_dive.rst:698 +msgid "As you will see when inspecting the method, :meth:`.Scene.play` almost immediately passes over to the ``play`` method of the renderer, in our case :class:`.CairoRenderer.play`. The one thing :meth:`.Scene.play` takes care of is the management of subcaptions that you might have passed to it (see the the documentation of :meth:`.Scene.play` and :meth:`.Scene.add_subcaption` for more information)." +msgstr "" + +#: ../../source/guides/deep_dive.rst:707 +msgid "As has been said before, the communication between scene and renderer is not in a very clean state at this point, so the following paragraphs might be confusing if you don't run a debugger and step through the code yourself a bit." +msgstr "" + +#: ../../source/guides/deep_dive.rst:712 +msgid "Inside :meth:`.CairoRenderer.play`, the renderer first checks whether it may skip rendering of the current play call. This might happen, for example, when ``-s`` is passed to the CLI (i.e., only the last frame should be rendered), or when the ``-n`` flag is passed and the current play call is outside of the specified render bounds. The \"skipping status\" is updated in form of the call to :meth:`.CairoRenderer.update_skipping_status`." +msgstr "" + +#: ../../source/guides/deep_dive.rst:719 +msgid "Next, the renderer asks the scene to process the animations in the play call so that renderer obtains all of the information it needs. To be more concrete, :meth:`.Scene.compile_animation_data` is called, which then takes care of several things:" +msgstr "" + +#: ../../source/guides/deep_dive.rst:724 +msgid "The method processes all animations and the keyword arguments passed to the initial :meth:`.Scene.play` call. In particular, this means that it makes sure all arguments passed to the play call are actually animations (or ``.animate`` syntax calls, which are also assembled to be actual :class:`.Animation`-objects at that point). It also propagates any animation-related keyword arguments (like ``run_time``, or ``rate_func``) passed to :class:`.Scene.play` to each individual animation. The processed animations are then stored in the ``animations`` attribute of the scene (which the renderer later reads...)." +msgstr "" + +#: ../../source/guides/deep_dive.rst:733 +msgid "It adds all mobjects to which the animations that are played are bound to to the scene (provided the animation is not an mobject-introducing animation -- for these, the addition to the scene happens later)." +msgstr "" + +#: ../../source/guides/deep_dive.rst:736 +msgid "In case the played animation is a :class:`.Wait` animation (this is the case in a :meth:`.Scene.wait` call), the method checks whether a static image should be rendered, or whether the render loop should be processed as usual (see :meth:`.Scene.should_update_mobjects` for the exact conditions, basically it checks whether there are any time-dependent updater functions and so on)." +msgstr "" + +#: ../../source/guides/deep_dive.rst:742 +msgid "Finally, the method determines the total run time of the play call (which at this point is computed as the maximum of the run times of the passed animations). This is stored in the ``duration`` attribute of the scene." +msgstr "" + +#: ../../source/guides/deep_dive.rst:747 +msgid "After the animation data has been compiled by the scene, the renderer continues to prepare for entering the render loop. It now checks the skipping status which has been determined before. If the renderer can skip this play call, it does so: it sets the current play call hash (which we will get back to in a moment) to ``None`` and increases the time of the renderer by the determined animation run time." +msgstr "" + +#: ../../source/guides/deep_dive.rst:754 +msgid "Otherwise, the renderer checks whether or not Manim's caching system should be used. The idea of the caching system is simple: for every play call, a hash value is computed, which is then stored and upon re-rendering the scene, the hash is generated again and checked against the stored value. If it is the same, the cached output is reused, otherwise it is fully rerendered again. We will not go into details of the caching system here; if you would like to learn more, the :func:`.get_hash_from_play_call` function in the :mod:`.utils.hashing` module is essentially the entry point to the caching mechanism." +msgstr "" + +#: ../../source/guides/deep_dive.rst:764 +msgid "In the event that the animation has to be rendered, the renderer asks its :class:`.SceneFileWriter` to start a writing process. The process is started by a call to ``ffmpeg`` and opens a pipe to which rendered raw frames can be written. As long as the pipe is open, the process can be accessed via the ``writing_process`` attribute of the file writer. With the writing process in place, the renderer then asks the scene to \"begin\" the animations." +msgstr "" + +#: ../../source/guides/deep_dive.rst:772 +msgid "First, it literally *begins* all of the animations by calling their setup methods (:meth:`.Animation._setup_scene`, :meth:`.Animation.begin`). In doing so, the mobjects that are newly introduced by an animation (like via :class:`.Create` etc.) are added to the scene. Furthermore, the animation suspends updater functions being called on its mobject, and it sets its mobject to the state that corresponds to the first frame of the animation." +msgstr "" + +#: ../../source/guides/deep_dive.rst:780 +msgid "After this has happened for all animations in the current ``play`` call, the Cairo renderer determines which of the scene's mobjects can be painted statically to the background, and which ones have to be redrawn every frame. It does so by calling :meth:`.Scene.get_moving_and_static_mobjects`, and the resulting partition of mobjects is stored in the corresponding ``moving_mobjects`` and ``static_mobjects`` attributes." +msgstr "" + +#: ../../source/guides/deep_dive.rst:790 +msgid "The mechanism that determines static and moving mobjects is specific for the Cairo renderer, the OpenGL renderer works differently. Basically, moving mobjects are determined by checking whether they, any of their children, or any of the mobjects \"below\" them (in the sense of the order in which mobjects are processed in the scene) either have an update function attached, or whether they appear in one of the current animations. See the implementation of :meth:`.Scene.get_moving_mobjects` for more details." +msgstr "" + +#: ../../source/guides/deep_dive.rst:799 +msgid "Up to this very point, we did not actually render any (partial) image or movie files from the scene yet. This is, however, about to change. Before we enter the render loop, let us briefly revisit our toy example and discuss how the generic :meth:`.Scene.play` call setup looks like there." +msgstr "" + +#: ../../source/guides/deep_dive.rst:805 +msgid "For the call that plays the :class:`.ReplacementTransform`, there is no subcaption to be taken care of. The renderer then asks the scene to compile the animation data: the passed argument already is an animation (no additional preparations needed), there is no need for processing any keyword arguments (as we did not specify any additional ones to ``play``). The mobject bound to the animation, ``orange_square``, is already part of the scene (so again, no action taken). Finally, the run time is extracted (3 seconds long) and stored in ``Scene.duration``. The renderer then checks whether it should skip (it should not), then whether the animation is already cached (it is not). The corresponding animation hash value is determined and passed to the file writer, which then also calls ``ffmpeg`` to start the writing process which waits for rendered frames from the library." +msgstr "" + +#: ../../source/guides/deep_dive.rst:821 +msgid "The scene then ``begin``\\ s the animation: for the :class:`.ReplacementTransform` this means that the animation populates all of its relevant animation attributes (i.e., compatible copies of the starting and the target mobject so that it can safely interpolate between the two)." +msgstr "" + +#: ../../source/guides/deep_dive.rst:827 +msgid "The mechanism determining static and moving mobjects considers all of the scenes mobjects (at this point only the ``orange_square``), and determines that the ``orange_square`` is bound to an animation that is currently played. As a result, the square is classified as a \"moving mobject\"." +msgstr "" + +#: ../../source/guides/deep_dive.rst:833 +msgid "Time to render some frames." +msgstr "" + +#: ../../source/guides/deep_dive.rst:837 +msgid "The render loop (for real this time)" +msgstr "" + +#: ../../source/guides/deep_dive.rst:839 +msgid "As mentioned above, due to the mechanism that determines static and moving mobjects in the scene, the renderer knows which mobjects it can paint statically to the background of the scene. Practically, this means that it partially renders a scene (to produce a background image), and then when iterating through the time progression of the animation only the \"moving mobjects\" are re-painted on top of the static background." +msgstr "" + +#: ../../source/guides/deep_dive.rst:846 +msgid "The renderer calls :meth:`.CairoRenderer.save_static_frame_data`, which first checks whether there are currently any static mobjects, and if there are, it updates the frame (only with the static mobjects; more about how exactly this works in a moment) and then saves a NumPy array representing the rendered frame in the ``static_image`` attribute. In our toy example, there are no static mobjects, and so the ``static_image`` attribute is simply set to ``None``." +msgstr "" + +#: ../../source/guides/deep_dive.rst:854 +msgid "Next, the renderer asks the scene whether the current animation is a \"frozen frame\" animation, which would mean that the renderer actually does not have to repaint the moving mobjects in every frame of the time progression. It can then just take the latest static frame, and display it throughout the animation." +msgstr "" + +#: ../../source/guides/deep_dive.rst:862 +msgid "An animation is considered a \"frozen frame\" animation if only a static :class:`.Wait` animation is played. See the description of :meth:`.Scene.compile_animation_data` above, or the implementation of :meth:`.Scene.should_update_mobjects` for more details." +msgstr "" + +#: ../../source/guides/deep_dive.rst:868 +msgid "If this is not the case (just as in our toy example), the renderer then calls the :meth:`.Scene.play_internal` method, which is the integral part of the render loop (in which the library steps through the time progression of the animation and renders the corresponding frames)." +msgstr "" + +#: ../../source/guides/deep_dive.rst:874 +msgid "Within :meth:`.Scene.play_internal`, the following steps are performed:" +msgstr "" + +#: ../../source/guides/deep_dive.rst:876 +msgid "The scene determines the run time of the animations by calling :meth:`.Scene.get_run_time`. This method basically takes the maximum ``run_time`` attribute of all of the animations passed to the :meth:`.Scene.play` call." +msgstr "" + +#: ../../source/guides/deep_dive.rst:880 +msgid "Then the *time progression* is constructed via the (internal) :meth:`.Scene._get_animation_time_progression` method, which wraps the actual :meth:`.Scene.get_time_progression` method. The time progression is a ``tqdm`` `progress bar object `__ for an iterator over ``np.arange(0, run_time, 1 / config.frame_rate)``. In other words, the time progression holds the time stamps (relative to the current animations, so starting at 0 and ending at the total animation run time, with the step size determined by the render frame rate) of the timeline where a new animation frame should be rendered." +msgstr "" + +#: ../../source/guides/deep_dive.rst:889 +msgid "Then the scene iterates over the time progression: for each time stamp ``t``, :meth:`.Scene.update_to_time` is called, which ..." +msgstr "" + +#: ../../source/guides/deep_dive.rst:892 +msgid "... first computes the time passed since the last update (which might be 0, especially for the initial call) and references it as ``dt``," +msgstr "" + +#: ../../source/guides/deep_dive.rst:894 +msgid "then (in the order in which the animations are passed to :meth:`.Scene.play`) calls :meth:`.Animation.update_mobjects` to trigger all updater functions that are attached to the respective animation except for the \"main mobject\" of the animation (that is, for example, for :class:`.Transform` the unmodified copies of start and target mobject -- see :meth:`.Animation.get_all_mobjects_to_update` for more details)," +msgstr "" + +#: ../../source/guides/deep_dive.rst:900 +msgid "then the relative time progression with respect to the current animation is computed (``alpha = t / animation.run_time``), which is then used to update the state of the animation with a call to :meth:`.Animation.interpolate`." +msgstr "" + +#: ../../source/guides/deep_dive.rst:903 +msgid "After all of the passed animations have been processed, the updater functions of all mobjects in the scene, all meshes, and finally those attached to the scene itself are run." +msgstr "" + +#: ../../source/guides/deep_dive.rst:907 +msgid "At this point, the internal (Python) state of all mobjects has been updated to match the currently processed timestamp. If rendering should not be skipped, then it is now time to *take a picture*!" +msgstr "" + +#: ../../source/guides/deep_dive.rst:913 +msgid "The update of the internal state (iteration over the time progression) happens *always* once :meth:`.Scene.play_internal` is entered. This ensures that even if frames do not need to be rendered (because, e.g., the ``-n`` CLI flag has been passed, something has been cached, or because we might be in a *Section* with skipped rendering), updater functions still run correctly, and the state of the first frame that *is* rendered is kept consistent." +msgstr "" + +#: ../../source/guides/deep_dive.rst:920 +msgid "To render an image, the scene calls the corresponding method of its renderer, :meth:`.CairoRenderer.render` and passes just the list of *moving mobjects* (remember, the *static mobjects* are assumed to have already been painted statically to the background of the scene). All of the hard work then happens when the renderer updates its current frame via a call to :meth:`.CairoRenderer.update_frame`:" +msgstr "" + +#: ../../source/guides/deep_dive.rst:926 +msgid "First, the renderer prepares its :class:`.Camera` by checking whether the renderer has a ``static_image`` different from ``None`` stored already. If so, it sets the image as the *background image* of the camera via :meth:`.Camera.set_frame_to_background`, and otherwise it just resets the camera via :meth:`.Camera.reset`. The camera is then asked to capture the scene with a call to :meth:`.Camera.camture_mobjects`." +msgstr "" + +#: ../../source/guides/deep_dive.rst:932 +msgid "Things get a bit technical here, and at some point it is more efficient to delve into the implementation -- but here is a summary of what happens once the camera is asked to capture the scene:" +msgstr "" + +#: ../../source/guides/deep_dive.rst:936 +msgid "First, a flat list of mobjects is created (so submobjects get extracted from their parents). This list is then processed in groups of the same type of mobjects (e.g., a batch of vectorized mobjects, followed by a batch of image mobjects, followed by more vectorized mobjects, etc. -- in many cases there will just be one batch of vectorized mobjects)." +msgstr "" + +#: ../../source/guides/deep_dive.rst:941 +msgid "Depending on the type of the currently processed batch, the camera uses dedicated *display functions* to convert the :class:`.Mobject` Python object to a NumPy array stored in the camera's ``pixel_array`` attribute. The most important example in that context is the display function for vectorized mobjects, :meth:`.Camera.display_multiple_vectorized_mobjects`, or the more particular (in case you did not add a background image to your :class:`.VMobject`), :meth:`.Camera.display_multiple_non_background_colored_vmobjects`. This method first gets the current Cairo context, and then, for every (vectorized) mobject in the batch, calls :meth:`.Camera.display_vectorized`. There, the actual background stroke, fill, and then stroke of the mobject is drawn onto the context. See :meth:`.Camera.apply_stroke` and :meth:`.Camera.set_cairo_context_color` for more details -- but it does not get much deeper than that, in the latter method the actual Bézier curves determined by the points of the mobject are drawn; this is where the low-level interaction with Cairo happens." +msgstr "" + +#: ../../source/guides/deep_dive.rst:957 +msgid "After all batches have been processed, the camera has an image representation of the Scene at the current time stamp in form of a NumPy array stored in its ``pixel_array`` attribute. The renderer then takes this array and passes it to its :class:`.SceneFileWriter`. This concludes one iteration of the render loop, and once the time progression has been processed completely, a final bit of cleanup is performed before the :meth:`.Scene.play_internal` call is completed." +msgstr "" + +#: ../../source/guides/deep_dive.rst:964 +msgid "A TL;DR for the render loop, in the context of our toy example, reads as follows:" +msgstr "" + +#: ../../source/guides/deep_dive.rst:966 +msgid "The scene finds that a 3 second long animation (the :class:`.ReplacementTransform` changing the orange square to the blue circle) should be played. Given the requested medium render quality, the frame rate is 30 frames per second, and so the time progression with steps ``[0, 1/30, 2/30, ..., 89/30]`` is created." +msgstr "" + +#: ../../source/guides/deep_dive.rst:970 +msgid "In the internal render loop, each of these time stamps is processed: there are no updater functions, so effectively the scene updates the state of the transformation animation to the desired time stamp (for example, at time stamp ``t = 45/30``, the animation is completed to a rate of ``alpha = 0.5``)." +msgstr "" + +#: ../../source/guides/deep_dive.rst:975 +msgid "Then the scene asks the renderer to do its job. The renderer asks its camera to capture the scene, the only mobject that needs to be processed at this point is the main mobject attached to the transformation; the camera converts the current state of the mobject to entries in a NumPy array. The renderer passes this array to the file writer." +msgstr "" + +#: ../../source/guides/deep_dive.rst:980 +msgid "At the end of the loop, 90 frames have been passed to the file writer." +msgstr "" + +#: ../../source/guides/deep_dive.rst:983 +msgid "Completing the render loop" +msgstr "" + +#: ../../source/guides/deep_dive.rst:985 +msgid "The last few steps in the :meth:`.Scene.play_internal` call are not too exciting: for every animation, the corresponding :meth:`.Animation.finish` and :meth:`.Animation.clean_up_from_scene` methods are called." +msgstr "" + +#: ../../source/guides/deep_dive.rst:991 +msgid "Note that as part of :meth:`.Animation.finish`, the :meth:`.Animation.interpolate` method is called with an argument of 1.0 -- you might have noticed already that the last frame of an animation can sometimes be a bit off or incomplete. This is by current design! The last frame rendered in the render loop (and displayed for a duration of ``1 / frame_rate`` seconds in the rendered video) corresponds to the state of the animation ``1 / frame_rate`` seconds before it ends. To display the final frame as well in the video, we would need to append another ``1 / frame_rate`` seconds to the video -- which would then mean that a 1 second rendered Manim video would be slightly longer than 1 second. We decided against this at some point." +msgstr "" + +#: ../../source/guides/deep_dive.rst:1001 +msgid "In the end, the time progression is closed (which completes the displayed progress bar) in the terminal. With the closing of the time progression, the :meth:`.Scene.play_internal` call is completed, and we return to the renderer, which now orders the :class:`.SceneFileWriter` to close the movie pipe that has been opened for this animation: a partial movie file is written." +msgstr "" + +#: ../../source/guides/deep_dive.rst:1007 +msgid "This pretty much concludes the walkthrough of a :class:`.Scene.play` call, and actually there is not too much more to say for our toy example either: at this point, a partial movie file that represents playing the :class:`.ReplacementTransform` has been written. The initialization of the :class:`.Dot` happens analogous to the initialization of ``blue_circle``, which has been discussed above. The :meth:`.Mobject.add_updater` call literally just attaches a function to the ``updaters`` attribute of the ``small_dot``. And the remaining :meth:`.Scene.play` and :meth:`.Scene.wait` calls follow the exact same procedure as discussed in the render loop section above; each such call produces a corresponding partial movie file." +msgstr "" + +#: ../../source/guides/deep_dive.rst:1018 +msgid "Once the :meth:`.Scene.construct` method has been fully processed (and thus all of the corresponding partial movie files have been written), the scene calls its cleanup method :meth:`.Scene.tear_down`, and then asks its renderer to finish the scene. The renderer, in turn, asks its scene file writer to wrap things up by calling :meth:`.SceneFileWriter.finish`, which triggers the combination of the partial movie files into the final product." +msgstr "" + + diff --git a/docs/i18n/gettext/guides/index.pot b/docs/i18n/gettext/guides/index.pot new file mode 100644 index 0000000000..b163d6b4a2 --- /dev/null +++ b/docs/i18n/gettext/guides/index.pot @@ -0,0 +1,14 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Manim \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../source/guides/index.rst:4 +#: ../../source/guides/index.rst:4 +msgid "Table of Contents" +msgstr "" + + diff --git a/docs/i18n/gettext/guides/using_text.pot b/docs/i18n/gettext/guides/using_text.pot new file mode 100644 index 0000000000..1358ff998d --- /dev/null +++ b/docs/i18n/gettext/guides/using_text.pot @@ -0,0 +1,269 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Manim \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../source/guides/using_text.rst:3 +msgid "Rendering Text and Formulas" +msgstr "" + +#: ../../source/guides/using_text.rst:5 +msgid "There are two different ways by which you can render **Text** in videos:" +msgstr "" + +#: ../../source/guides/using_text.rst:7 +msgid "Using Pango (:mod:`~.text_mobject`)" +msgstr "" + +#: ../../source/guides/using_text.rst:8 +msgid "Using LaTeX (:mod:`~.tex_mobject`)" +msgstr "" + +#: ../../source/guides/using_text.rst:10 +msgid "If you want to render simple text, you should use either :class:`~.Text` or :class:`~.MarkupText`, or one of its derivatives like :class:`~.Paragraph`. See :ref:`using-text-objects` for more information." +msgstr "" + +#: ../../source/guides/using_text.rst:14 +msgid "LaTeX should be used when you need mathematical typesetting. See :ref:`rendering-with-latex` for more information." +msgstr "" + +#: ../../source/guides/using_text.rst:20 +msgid "Text Without LaTeX" +msgstr "" + +#: ../../source/guides/using_text.rst:22 +msgid "The simplest way to add text to your animations is to use the :class:`~.Text` class. It uses the `Pango library`_ to render text. With Pango, you can also render non-English alphabets like 你好 or こんにちは or 안녕하세요 or مرحبا بالعالم." +msgstr "" + +#: ../../source/guides/using_text.rst:27 +msgid "Here is a simple *Hello World* animation." +msgstr "" + +#: ../../source/guides/using_text.rst:38 +msgid "You can also use :class:`~.MarkupText` which allows the use of PangoMarkup (see the documentation of :class:`~.MarkupText` for details) to render text. For example:" +msgstr "" + +#: ../../source/guides/using_text.rst:56 +msgid "Working with :class:`~.Text`" +msgstr "" + +#: ../../source/guides/using_text.rst:58 +msgid "This section explains the properties of :class:`~.Text` and how can it be used in your animations." +msgstr "" + +#: ../../source/guides/using_text.rst:62 +msgid "Using Fonts" +msgstr "" + +#: ../../source/guides/using_text.rst:64 +msgid "You can set a different font using :attr:`~.Text.font`." +msgstr "" + +#: ../../source/guides/using_text.rst:68 +msgid "The font used must be installed in your system, and Pango should know about it. You can get a list of fonts using :func:`manimpango.list_fonts`." +msgstr "" + +#: ../../source/guides/using_text.rst:85 +msgid "Setting Slant and Weight" +msgstr "" + +#: ../../source/guides/using_text.rst:86 +msgid "Slant is the style of the Text, and it can be ``NORMAL`` (the default), ``ITALIC`` or ``OBLIQUE``. Usually, for many fonts both ``ITALIC`` and ``OBLIQUE`` look similar, but ``ITALIC`` uses **Roman Style**, whereas ``OBLIQUE`` uses **Italic Style**." +msgstr "" + +#: ../../source/guides/using_text.rst:91 +msgid "Weight specifies the boldness of a font. You can see a list of weights in :class:`manimpango.Weight`." +msgstr "" + +#: ../../source/guides/using_text.rst:126 +msgid "Using Colors" +msgstr "" + +#: ../../source/guides/using_text.rst:128 +msgid "You can set the color of the text using :attr:`~.Text.color`:" +msgstr "" + +#: ../../source/guides/using_text.rst:138 +msgid "You can use utilities like :attr:`~.Text.t2c` for coloring specific characters. This may be problematic if your text contains ligatures as explained in :ref:`iterating-text`." +msgstr "" + +#: ../../source/guides/using_text.rst:142 +msgid ":attr:`~Text.t2c` accepts two types of dictionaries," +msgstr "" + +#: ../../source/guides/using_text.rst:144 +msgid "The keys can contain indices like ``[2:-1]`` or ``[4:8]``, this works similar to how `slicing `_ works in Python. The values should be the color of the Text from :class:`~.Color`." +msgstr "" + +#: ../../source/guides/using_text.rst:149 +msgid "The keys contain words or characters which should be colored separately and the values should be the color from :class:`~.Color`:" +msgstr "" + +#: ../../source/guides/using_text.rst:161 +msgid "If you want to avoid problems when using colors (due to ligatures), consider using :class:`MarkupText`." +msgstr "" + +#: ../../source/guides/using_text.rst:166 +msgid "Using Gradients" +msgstr "" + +#: ../../source/guides/using_text.rst:168 +msgid "You can add a gradient using :attr:`~.Text.gradient`. The value must be an iterable of any length:" +msgstr "" + +#: ../../source/guides/using_text.rst:179 +msgid "You can also use :attr:`~.Text.t2g` for gradients with specific characters of the text. It shares a similar syntax to :ref:`the interface for colors `:" +msgstr "" + +#: ../../source/guides/using_text.rst:203 +msgid "Setting Line Spacing" +msgstr "" + +#: ../../source/guides/using_text.rst:205 +msgid "You can set the line spacing using :attr:`~.Text.line_spacing`:" +msgstr "" + +#: ../../source/guides/using_text.rst:220 +msgid "Disabling Ligatures" +msgstr "" + +#: ../../source/guides/using_text.rst:222 +msgid "By disabling ligatures you would get a one-to-one mapping between characters and submobjects. This fixes the issues with coloring text." +msgstr "" + +#: ../../source/guides/using_text.rst:228 +msgid "Be aware that using this method with text that heavily depends on ligatures (Arabic text) may yield unexpected results." +msgstr "" + +#: ../../source/guides/using_text.rst:231 +msgid "You can disable ligatures by passing ``disable_ligatures`` to :class:`Text`. For example:" +msgstr "" + +#: ../../source/guides/using_text.rst:246 +msgid "Iterating :class:`~.Text`" +msgstr "" + +#: ../../source/guides/using_text.rst:248 +msgid "Text objects behave like :class:`VGroups <.VGroup>`. Therefore, you can slice and index the text." +msgstr "" + +#: ../../source/guides/using_text.rst:251 +msgid "For example, you can set each letter to different color by iterating it." +msgstr "" + +#: ../../source/guides/using_text.rst:265 +msgid "Please note that `Ligature`_ can cause problems here. If you need a one-to-one mapping of characters to submobjects you should pass the ``disable_ligatures`` parameter to :class:`~.Text`. See :ref:`disable-ligatures`." +msgstr "" + +#: ../../source/guides/using_text.rst:273 +msgid "Working with :class:`~.MarkupText`" +msgstr "" + +#: ../../source/guides/using_text.rst:275 +msgid "MarkupText is similar to :class:`~.Text`, the only difference between them is that this accepts and processes PangoMarkup (which is similar to html), instead of just rendering plain text." +msgstr "" + +#: ../../source/guides/using_text.rst:279 +msgid "Consult the documentation of :class:`~.MarkupText` for more details and further references about PangoMarkup." +msgstr "" + +#: ../../source/guides/using_text.rst:297 +msgid "Text With LaTeX" +msgstr "" + +#: ../../source/guides/using_text.rst:299 +msgid "Just as you can use :class:`~.Text` to add text to your videos, you can use :class:`~.Tex` to insert LaTeX." +msgstr "" + +#: ../../source/guides/using_text.rst:302 +msgid "For example," +msgstr "" + +#: ../../source/guides/using_text.rst:314 +msgid "Note that we are using a raw string (``r'...'``) instead of a regular string (``'...'``). This is because TeX code uses a lot of special characters - like ``\\`` for example - that have special meaning within a regular python string. An alternative would have been to write ``\\\\`` to escape the backslash: ``Tex('\\\\LaTeX')``." +msgstr "" + +#: ../../source/guides/using_text.rst:320 +msgid "Working with :class:`~.MathTex`" +msgstr "" + +#: ../../source/guides/using_text.rst:322 +msgid "Everything passed to :class:`~.MathTex` is in math mode by default. To be more precise, :class:`~.MathTex` is processed within an ``align*`` environment. You can achieve a similar effect with :class:`~.Tex` by enclosing your formula with ``$`` symbols: ``$\\xrightarrow{x^6y^8}$``:" +msgstr "" + +#: ../../source/guides/using_text.rst:339 +msgid "LaTeX commands and keyword arguments" +msgstr "" + +#: ../../source/guides/using_text.rst:341 +msgid "We can use any standard LaTeX commands in the AMS maths packages. Such as the ``mathtt`` math-text type or the ``looparrowright`` arrow." +msgstr "" + +#: ../../source/guides/using_text.rst:352 +msgid "On the Manim side, the :class:`~.Tex` class also accepts attributes to change the appearance of the output. This is very similar to the :class:`~.Text` class. For example, the ``color`` keyword changes the color of the TeX mobject." +msgstr "" + +#: ../../source/guides/using_text.rst:366 +msgid "Extra LaTeX Packages" +msgstr "" + +#: ../../source/guides/using_text.rst:368 +msgid "Some commands require special packages to be loaded into the TeX template. For example, to use the ``mathscr`` script, we need to add the ``mathrsfs`` package. Since this package isn't loaded into Manim's tex template by default, we have to add it manually." +msgstr "" + +#: ../../source/guides/using_text.rst:388 +msgid "Substrings and parts" +msgstr "" + +#: ../../source/guides/using_text.rst:390 +msgid "The TeX mobject can accept multiple strings as arguments. Afterwards you can refer to the individual parts either by their index (like ``tex[1]``), or by selecting parts of the tex code. In this example, we set the color of the ``\\bigstar`` using :func:`~.set_color_by_tex`:" +msgstr "" + +#: ../../source/guides/using_text.rst:404 +msgid "Note that :func:`~.set_color_by_tex` colors the entire substring containing the Tex, not just the specific symbol or Tex expression. Consider the following example:" +msgstr "" + +#: ../../source/guides/using_text.rst:418 +msgid "As you can see, this colors the entire equation yellow, contrary to what may be expected. To color only ``x`` yellow, we have to do the following:" +msgstr "" + +#: ../../source/guides/using_text.rst:433 +msgid "By setting ``substrings_to_isolate`` to ``x``, we split up the :class:`~.MathTex` into substrings automatically and isolate the ``x`` components into individual substrings. Only then can :meth:`~.set_color_by_tex` be used to achieve the desired result." +msgstr "" + +#: ../../source/guides/using_text.rst:438 +msgid "Note that Manim also supports a custom syntax that allows splitting a TeX string into substrings easily: simply enclose parts of your formula that you want to isolate with double braces. In the string ``MathTex(r\"{{ a^2 }} + {{ b^2 }} = {{ c^2 }}\")``, the rendered mobject will consist of the substrings ``a^2``, ``+``, ``b^2``, ``=``, and ``c^2``. This makes transformations between similar text fragments easy to write using :class:`~.TransformMatchingTex`." +msgstr "" + +#: ../../source/guides/using_text.rst:447 +msgid "Using ``index_labels`` to work with complicated strings" +msgstr "" + +#: ../../source/guides/using_text.rst:449 +msgid "You might sometimes be working with a very complicated :class:`~.MathTex` mobject that makes it difficult to work with its individual components. This is where the debugging function :func:`.index_labels` is very useful." +msgstr "" + +#: ../../source/guides/using_text.rst:453 +msgid "The method shows the index of a mobject's submobjects, allowing you to easily find the components of the mobject you would like to change." +msgstr "" + +#: ../../source/guides/using_text.rst:472 +msgid "LaTeX Maths Fonts - The Template Library" +msgstr "" + +#: ../../source/guides/using_text.rst:474 +msgid "Changing fonts in LaTeX when typesetting mathematical formulae is trickier than regular text. It requires changing the template that is used to compile the TeX. Manim comes with a collection of :class:`~.TexFontTemplates` ready for you to use. These templates will all work in math mode:" +msgstr "" + +#: ../../source/guides/using_text.rst:491 +msgid "Manim also has a :class:`~.TexTemplateLibrary` containing the TeX templates used by 3Blue1Brown. One example is the ctex template, used for typesetting Chinese script. For this to work, the ctex LaTeX package must be installed on your system. Furthermore, if you are only typesetting Text, you probably do not need :class:`~.Tex` at all, and should use :class:`~.Text` instead." +msgstr "" + +#: ../../source/guides/using_text.rst:508 +msgid "Aligning formulae" +msgstr "" + + diff --git a/docs/i18n/gettext/index.pot b/docs/i18n/gettext/index.pot index 378cbf0228..8c4c97230f 100644 --- a/docs/i18n/gettext/index.pot +++ b/docs/i18n/gettext/index.pot @@ -7,15 +7,107 @@ msgstr "" "Content-Transfer-Encoding: 8bit\n" #: ../../source/index.rst:7 -msgid "Manim Community Overview" +msgid "Manim Community Edition" msgstr "" #: ../../source/index.rst:9 msgid "Animating technical concepts is traditionally pretty tedious since it can be difficult to make the animations precise enough to convey them accurately. Manim relies on Python's simplicity to generate animations programmatically, making it convenient to specify exactly how each one should run. Take a look at the :doc:`Example Gallery <../examples>` for some inspiration on how to create beautiful images and videos with Manim." msgstr "" -#: ../../source/index.rst:16 +#: ../../source/index.rst:17 +msgid "First Steps" +msgstr "" + +#: ../../source/index.rst:19 +msgid "Are you new to Manim and are looking for where to get started? Then you are in the right place!" +msgstr "" + +#: ../../source/index.rst:24 +msgid "Please be aware that there are different, incompatible versions of Manim available. Check our :ref:`installation FAQ ` to learn more!" +msgstr "" + +#: ../../source/index.rst:28 +msgid "The :doc:`Installation ` section has the latest and up-to-date installation instructions for Windows, MacOS, and Linux. You can also find information on Manim's docker images and (online) notebook environments there." +msgstr "" + +#: ../../source/index.rst:32 +msgid "Want to try the library before installing it? Take a look at our interactive online playground at https://try.manim.community in form of a Jupyter notebook." +msgstr "" + +#: ../../source/index.rst:35 +msgid "In our :doc:`Tutorials ` section you will find a collection of resources that will teach you how to use Manim. In particular, the :doc:`tutorials/quickstart` tutorial teaches you Manim's basics, and in :doc:`tutorials/building_blocks` the classes used to compose your animations are described in more detail." +msgstr "" + +#: ../../source/index.rst:43 +msgid "Finding Help" +msgstr "" + +#: ../../source/index.rst:45 +msgid "Are you struggling with installing or using Manim? Don't worry, we've all been there. Here are some good resources to help you out:" +msgstr "" + +#: ../../source/index.rst:48 +msgid "Perhaps your problem is one that occurs frequently, then chances are it is addressed in our :doc:`collection of FAQs `." +msgstr "" + +#: ../../source/index.rst:50 +msgid "If you are looking for information on some specific class, look for it in the :doc:`reference manual ` and/or use the search feature of the documentation." +msgstr "" + +#: ../../source/index.rst:53 +msgid "Still no luck? Then you are welcome to ask the community for help, together we usually manage to find a solution for your problem! Consult the :doc:`FAQ page on getting help ` for instructions." +msgstr "" + +#: ../../source/index.rst:59 +msgid "Navigating the Documentation" +msgstr "" + +#: ../../source/index.rst:61 +msgid "Here are some short summaries for all of the sections in this documentation:" +msgstr "" + +#: ../../source/index.rst:63 +msgid "The :doc:`Example Gallery ` is a collection of examples (rendered videos and images together with the code they were generated from) that show a few different, simple things that you can do with Manim." +msgstr "" + +#: ../../source/index.rst:66 +msgid "The :doc:`Installation ` section has information on installing Manim." +msgstr "" + +#: ../../source/index.rst:67 +msgid "In :doc:`Tutorials & Guides ` you can find learning resources: proper tutorials that guide you through the process of creating a video are in the :doc:`Tutorial ` section; guides on specific topics are in the :doc:`Guides ` section, and the answers to frequently asked questions can be found in the :doc:`FAQ ` section." +msgstr "" + +#: ../../source/index.rst:72 +msgid "The :doc:`Reference Manual ` contains a comprehensive list of all of Manim's (documented) modules, classes, and functions. If you are somewhat familiar with Manim's module structure feel free to browse the manual directly. If you are searching for something specific, feel free to use the documentation's search feature in the sidebar. Many classes and methods come with their own illustrated examples too!" +msgstr "" + +#: ../../source/index.rst:77 +msgid "The :doc:`Plugins ` page documents how to install, write, and distribute plugins (that is, separate Python packages that extend the feature set of the core library)." +msgstr "" + +#: ../../source/index.rst:79 +msgid "Changes between versions are documented in our :doc:`Changelog `." +msgstr "" + +#: ../../source/index.rst:80 +msgid "If you are looking into contributing to the development of Manim, you can find information on how to get involved in our :doc:`Contributing ` section." +msgstr "" + +#: ../../source/index.rst:82 +msgid "And finally, the :doc:`Code of Conduct ` page has a formal description of the rules you should abide by when interacting within our community." +msgstr "" + +#: ../../source/index.rst:86 +msgid "Sharing Your Work" +msgstr "" + +#: ../../source/index.rst:88 msgid "We'd love to hear from you and see your manimations `on Twitter `_, `Reddit `_, or `Discord `_. If you're using Manim in a scientific context, instructions on how to cite a particular release can be found `in our README `_." msgstr "" +#: ../../source/index.rst:95 +msgid "Index" +msgstr "" + diff --git a/docs/i18n/gettext/installation.pot b/docs/i18n/gettext/installation.pot index 7d2d56328d..956ccbdfc3 100644 --- a/docs/i18n/gettext/installation.pot +++ b/docs/i18n/gettext/installation.pot @@ -19,7 +19,7 @@ msgid "Otherwise, if you intend to use Manim to work on an animation project, we msgstr "" #: ../../source/installation.rst:16 -msgid "Note that there are several different versions of Manim. The instructions on this website are **only** for the *community edition*. Find out more about the :doc:`differences between Manim versions ` if you are unsure which version you should install." +msgid "Note that there are several different versions of Manim. The instructions on this website are **only** for the *community edition*. Find out more about the :ref:`differences between Manim versions ` if you are unsure which version you should install." msgstr "" #: ../../source/installation.rst:22 @@ -50,47 +50,47 @@ msgstr "" msgid "Depending on your particular setup, the installation process might be slightly different. Make sure that you have tried to follow the steps on the following pages carefully, but in case you hit a wall we are happy to help: either `join our Discord `__, or start a new Discussion `directly on GitHub `__." msgstr "" -#: ../../source/installation.rst:59 +#: ../../source/installation.rst:58 msgid "Once Manim is installed locally, you can proceed to our :doc:`quickstart guide ` which walks you through rendering a first simple scene." msgstr "" -#: ../../source/installation.rst:63 -msgid "As mentioned above, do not worry if there are errors or other problems: consult our :doc:`troubleshooting guide ` for help, or get in touch with the community via `GitHub discussions `__ or `Discord `__." +#: ../../source/installation.rst:62 +msgid "As mentioned above, do not worry if there are errors or other problems: consult our :doc:`FAQ section ` for help (including instructions for how to ask Manim's community for help)." msgstr "" -#: ../../source/installation.rst:75 +#: ../../source/installation.rst:71 msgid "Using Manim via Docker" msgstr "" -#: ../../source/installation.rst:77 +#: ../../source/installation.rst:73 msgid "`Docker `__ is a virtualization tool that allows the distribution of encapsulated software environments (containers)." msgstr "" -#: ../../source/installation.rst:80 +#: ../../source/installation.rst:76 msgid "The following pages contain more information about the docker image maintained by the community, ``manimcommunity/manim``:" msgstr "" -#: ../../source/installation.rst:91 +#: ../../source/installation.rst:87 msgid "Interactive Jupyter notebooks for your browser" msgstr "" -#: ../../source/installation.rst:93 +#: ../../source/installation.rst:89 msgid "Manim ships with a built-in ``%%manim`` IPython magic command designed for the use within `Jupyter notebooks `__. Our interactive tutorial over at https://try.manim.community illustrates how Manim can be used from within a Jupyter notebook." msgstr "" -#: ../../source/installation.rst:98 +#: ../../source/installation.rst:94 msgid "The following pages explain how you can setup interactive environments like that yourself:" msgstr "" -#: ../../source/installation.rst:108 +#: ../../source/installation.rst:104 msgid "Editors" msgstr "" -#: ../../source/installation.rst:110 +#: ../../source/installation.rst:106 msgid "If you're using Visual Studio Code you can install an extension called *Manim Sideview* which provides automated rendering and an integrated preview of the animation inside the editor. The extension can be installed through the `marketplace of VS Code `__." msgstr "" -#: ../../source/installation.rst:117 +#: ../../source/installation.rst:113 msgid "Installation for developers" msgstr "" diff --git a/docs/i18n/gettext/installation/troubleshooting.pot b/docs/i18n/gettext/installation/troubleshooting.pot index c4857b3edb..8b13789179 100644 --- a/docs/i18n/gettext/installation/troubleshooting.pot +++ b/docs/i18n/gettext/installation/troubleshooting.pot @@ -1,305 +1 @@ -msgid "" -msgstr "" -"Project-Id-Version: Manim \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: ../../source/installation/troubleshooting.rst:2 -msgid "Troubleshooting" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:5 -msgid "Version incompatibility" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:7 -msgid "Confusion and conflict between versions is by far the most common reason for installation failures. Some signs and errors resulting from this are as follows:" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:11 -msgid "``There are no scenes in that module``" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:12 -msgid "``ModuleNotFoundError: No module named 'manim'``" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:13 -msgid "``ModuleNotFoundError: No module named 'manimlib'``" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:14 -msgid "You followed any tutorial created before October 2020 (because the community edition did not exist before then)" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:15 -msgid "You cloned a repository on GitHub (installation of the community version for normal use does not require the cloning of any repository)" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:16 -msgid "Different import statements (explained below)" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:17 -msgid "You used documentation for multiple versions (such as the readme for 3b1b/manim and this documentation)" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:20 -msgid "As this is the documentation for the community version, we can only help with the installation of this library. If you would like to install other versions of manim, please refer to their documentation." -msgstr "" - -#: ../../source/installation/troubleshooting.rst:25 -msgid "Identifying files written for a different version of manim" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:27 -msgid "There are some distinctive features of different versions of manim that can help in identifying what version of manim files are written for:" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:31 -msgid "Feature" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:31 -msgid "ManimCE (this version)" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:31 -msgid "ManimGL" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:31 -msgid "ManimCairo" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:33 -msgid "Import statement" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:33 -msgid "``from manim import *``" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:33 -msgid "``from manimlib import *``" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:33 -msgid "``from manimlib.imports import *``" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:37 -msgid "If you are a beginner, you should only attempt to run files written for your version. Files written for a different version of manim will generally not work without some modification." -msgstr "" - -#: ../../source/installation/troubleshooting.rst:42 -msgid "Identifying the version you are running" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:44 -msgid "The community edition of manim should always state `Manim Community ` as its first line of any command you run." -msgstr "" - -#: ../../source/installation/troubleshooting.rst:48 -msgid "Identifying and removing conflicting versions of manim" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:50 -msgid "Within the system or environment you are using to run manim, run the following command in the terminal:" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:57 -msgid "The correct package for the community edition is simply ``manim``. If you do not see this package listed, please refer back to our installation guide to install it. If you see ``manimlib`` or ``manimce`` (actually an old version of the community edition), you should remove them with:" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:68 -msgid "If you have cloned a repository from GitHub, you should either remove it or run manim outside that folder." -msgstr "" - -#: ../../source/installation/troubleshooting.rst:72 -msgid "Other errors" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:75 -msgid "``pip install manim`` fails when installing manimpango?" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:76 -msgid "Most likely this means that pip was not able to use our pre-built wheels of ``manimpango``. Let us know (via our `Discord `_ or by opening a `new issue on GitHub `_) which architecture you would like to see supported, and we'll see what we can do about it." -msgstr "" - -#: ../../source/installation/troubleshooting.rst:83 -msgid "To fix errors when installing ``manimpango``, you need to make sure you have all the necessary build requirements. Check out the detailed instructions given in `the BUILDING section `_ of the corresponding `GitHub repository `_." -msgstr "" - -#: ../../source/installation/troubleshooting.rst:91 -msgid "(Windows) OSError: dlopen() failed to load a library: pango?" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:93 -msgid "This should be fixed in Manim's latest version, update using ``pip install --upgrade manim``." -msgstr "" - -#: ../../source/installation/troubleshooting.rst:99 -msgid "Some letters are missing from Text/Tex output?" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:101 -msgid "If you have recently installed TeX you may need to build the fonts it uses. Which can be done by running:" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:112 -msgid "Installation does not support converting PDF to SVG?" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:114 -msgid "First, make sure your ``dvisvgm`` version is at least 2.4:" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:121 -msgid "If you do not know how to update ``dvisvgm``, please refer to your operating system's documentation." -msgstr "" - -#: ../../source/installation/troubleshooting.rst:123 -msgid "Second, check whether your ``dvisvgm`` supports PostScript specials. This is needed to convert from PDF to SVG." -msgstr "" - -#: ../../source/installation/troubleshooting.rst:131 -msgid "If the output to this command does **not** contain ``ps dvips PostScript specials``, this is a bad sign. In this case, run" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:139 -msgid "If the output does **not** contain ``--libgs=filename``, this means your ``dvisvgm`` does not currently support PostScript. You must get another binary." -msgstr "" - -#: ../../source/installation/troubleshooting.rst:142 -msgid "If, however, ``--libgs=filename`` appears in the help, that means that your ``dvisvgm`` needs the Ghostscript library to support PostScript. Search for ``libgs.so`` (on Linux, probably in ``/usr/local/lib`` or ``/usr/lib``) or ``gsdll32.dll`` (on 32-bit Windows, probably in ``C:\\windows\\system32``) or ``gsdll64.dll`` (on 64-bit Windows, probably in ``c:\\windows\\system32`` -- yes 32) or ``libgsl.dylib`` (on Mac OS, probably in ``/usr/local/lib`` or ``/opt/local/lib``). Please look carefully, as the file might be located elsewhere, e.g. in the directory where Ghostscript is installed." -msgstr "" - -#: ../../source/installation/troubleshooting.rst:151 -msgid "As soon as you have found the library, try (on Mac OS or Linux)" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:158 -msgid "or (on Windows)" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:166 -msgid "You should now see ``ps dvips PostScript specials`` in the output. Refer to your operating system's documentation to find out how you can set or export the environment variable ``LIBGS`` automatically whenever you open a shell." -msgstr "" - -#: ../../source/installation/troubleshooting.rst:170 -msgid "As a last check, you can run" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:176 -msgid "while still having ``LIBGS`` set to the correct path, of course. If ``dvisvgm`` can find your Ghostscript installation, it will be shown in the output together with the version number." -msgstr "" - -#: ../../source/installation/troubleshooting.rst:180 -msgid "If you do not have the necessary library on your system, please refer to your operating system's documentation to find out where you can get it and how you have to install it." -msgstr "" - -#: ../../source/installation/troubleshooting.rst:184 -msgid "If you are unable to solve your problem, check out the `dvisvgm FAQ `_." -msgstr "" - -#: ../../source/installation/troubleshooting.rst:187 -msgid "(Windows) ``Python is not recognized as an internal or external command, operable program or batch file.``" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:189 -msgid "To fix this, you need to add the Python executable to your ``PATH`` environment variable. Follow the steps in `this StackExchange answer `__." -msgstr "" - -#: ../../source/installation/troubleshooting.rst:193 -msgid "``choco install manimce`` failed" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:195 -msgid "If ``choco install manimce`` failed, it is likely being caused by Python not being added to your ``PATH`` variable properly. Try running the following commands in your terminal:" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:199 -msgid "``py --version``" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:200 -msgid "``python --version``" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:201 -msgid "``py3 --version``" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:202 -msgid "``python3 --version``" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:204 -msgid "Minimally, ``py --version`` and ``python --version`` should return a version. If none of these commands are recognized, this means that Python was installed on your system, but was not added to PATH. See above for directions to add it to your PATH variable." -msgstr "" - -#: ../../source/installation/troubleshooting.rst:209 -msgid "If any of these commands opens up the Windows store, this is likely interfering with the process. This is because Chocolatey runs a command that calls python or python3, and opening up the Windows store is not the expected behavior. See below to fix aliases." -msgstr "" - -#: ../../source/installation/troubleshooting.rst:216 -msgid "(Windows) Fix Aliases" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:218 -msgid "Go to the Windows Settings." -msgstr "" - -#: ../../source/installation/troubleshooting.rst:219 -msgid "Under Apps and Features, there are an application execution aliases." -msgstr "" - -#: ../../source/installation/troubleshooting.rst:220 -msgid "Within this menu disable the alias(es) that is causing the issue (``python`` and/or ``python3``)." -msgstr "" - -#: ../../source/installation/troubleshooting.rst:223 -msgid "``IndexError: List index out of range``" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:225 -msgid "Did you install LaTeX using MiKTeX? If so, open the MiKTeX console, install the ``cm-super`` package, then delete the ``media`` directory and try to render the scene again." -msgstr "" - -#: ../../source/installation/troubleshooting.rst:230 -msgid "Config" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:232 -msgid "We've dropped the use of CONFIG in the Community Version :doc:`version 0.2.0<../changelog/0.2.0-changelog>`, released in January 2021. This means parameters that were previously specified in the CONFIG dictionary should now be passed directly into the constructor. Practically, this means that old constructions like:" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:249 -msgid "should now be defined like:" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:269 -msgid "For scenes, this is even easier:" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:276 -msgid "becomes:" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:286 -msgid "A python command does not work" -msgstr "" - -#: ../../source/installation/troubleshooting.rst:288 -msgid "If a python command does not work, try adding ``python -m`` in front of it. For example, if ``pip install manim`` does not work, you can try ``python -m pip install manim``." -msgstr "" - -#: ../../source/installation/troubleshooting.rst:293 -msgid "undefined symbol" -msgstr "" - - diff --git a/docs/i18n/gettext/installation/versions.pot b/docs/i18n/gettext/installation/versions.pot index 067dbd674c..8b13789179 100644 --- a/docs/i18n/gettext/installation/versions.pot +++ b/docs/i18n/gettext/installation/versions.pot @@ -1,69 +1 @@ -msgid "" -msgstr "" -"Project-Id-Version: Manim \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: ../../source/installation/versions.rst:2 -msgid "Differences between Manim Versions" -msgstr "" - -#: ../../source/installation/versions.rst:4 -msgid "While originally a single library, there are now three main versions of manim, each with their own advantages, disadvantages, and ideal use cases. It is important to understand these differences in order to select the best version for your use case and avoid confusion arising from version mismatches." -msgstr "" - -#: ../../source/installation/versions.rst:10 -msgid "A brief history of Manim" -msgstr "" - -#: ../../source/installation/versions.rst:12 -msgid "Manim was originally created by Grant Sanderson as a personal project and for use in his YouTube channel, `3Blue1Brown `_. As his channel gained popularity, many grew to like the style of his animations and wanted to use manim for their own projects. However, as manim was only intended for personal use, it was very difficult for other users to install and use it." -msgstr "" - -#: ../../source/installation/versions.rst:18 -msgid "In late 2019, Grant started working on faster OpenGL rendering in a new branch, known as the shaders branch. In mid-2020, a group of developers forked it into what is now the community edition; this is the version documented on this website. In early 2021, Grant merged the shaders branch back into master, making it the default branch in his repository. The old version is still available as the branch ``cairo-backend``." -msgstr "" - -#: ../../source/installation/versions.rst:25 -msgid "The three versions of Manim" -msgstr "" - -#: ../../source/installation/versions.rst:27 -msgid "There are currently three main versions of manim. They are as follows:" -msgstr "" - -#: ../../source/installation/versions.rst:29 -msgid "**ManimCE**: The community edition of manim. This is the version documented by this website, and is named `manim `_ on pip." -msgstr "" - -#: ../../source/installation/versions.rst:30 -msgid "`ManimGL `_: The current version of manim that is used by 3blue1brown. It supports OpenGL rendering and interactivity, and is named ``manimgl`` on pip. You can find documentation for it `here `_." -msgstr "" - -#: ../../source/installation/versions.rst:31 -msgid "`ManimCairo `_: The old version of manim originally used by 3blue1brown. It is not available on pip." -msgstr "" - -#: ../../source/installation/versions.rst:34 -msgid "Which version to use" -msgstr "" - -#: ../../source/installation/versions.rst:35 -msgid "We recommend using the community edition for most purposes, as it has been developed to be more stable, better tested, quicker to respond to community contributions, and easier for beginners to use. It also has partial experimental OpenGL support and should have full support shortly (as of April 2021)." -msgstr "" - -#: ../../source/installation/versions.rst:39 -msgid "If you would like to use a version with full OpenGL support or render recent 3Blue1Brown videos (2020 onwards), you should use ManimGL." -msgstr "" - -#: ../../source/installation/versions.rst:41 -msgid "If you would like to render old 3Blue1Brown projects (2019 and before), you should use ManimCairo." -msgstr "" - -#: ../../source/installation/versions.rst:44 -msgid "Notes on installation, documentation, and use" -msgstr "" - - diff --git a/docs/i18n/gettext/internals.pot b/docs/i18n/gettext/internals.pot index e3fe41bd9a..8b13789179 100644 --- a/docs/i18n/gettext/internals.pot +++ b/docs/i18n/gettext/internals.pot @@ -1,17 +1 @@ -msgid "" -msgstr "" -"Project-Id-Version: Manim \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: ../../source/internals.rst:2 -msgid "Internal structure" -msgstr "" - -#: ../../source/internals.rst:4 -msgid "Efforts to document the internal structure of Manim is ongoing on our `wiki `_." -msgstr "" - - diff --git a/docs/i18n/gettext/reference.pot b/docs/i18n/gettext/reference.pot index 16adfb4682..acbf07c446 100644 --- a/docs/i18n/gettext/reference.pot +++ b/docs/i18n/gettext/reference.pot @@ -11,7 +11,7 @@ msgid "Reference Manual" msgstr "" #: ../../source/reference.rst:4 -msgid "This reference manual details modules, functions, and variables included in Manim, describing what they are and what they do. For learning how to use Manim, see :doc:`tutorials`. For a list of changes since the last release, see the :doc:`changelog`." +msgid "This reference manual details modules, functions, and variables included in Manim, describing what they are and what they do. For learning how to use Manim, see :doc:`tutorials/index`. For a list of changes since the last release, see the :doc:`changelog`." msgstr "" #: ../../source/reference.rst:9 @@ -26,15 +26,15 @@ msgstr "" msgid "Animations" msgstr "" -#: ../../source/reference.rst:37 +#: ../../source/reference.rst:38 msgid "Cameras" msgstr "" -#: ../../source/reference.rst:49 +#: ../../source/reference.rst:50 msgid "Mobjects" msgstr "" -#: ../../source/reference.rst:87 +#: ../../source/reference.rst:88 msgid "Scenes" msgstr "" diff --git a/docs/i18n/gettext/reference/manim._config.logger_utils.pot b/docs/i18n/gettext/reference/manim._config.logger_utils.pot index 85dfc0a6ad..8e4b7536c7 100644 --- a/docs/i18n/gettext/reference/manim._config.logger_utils.pot +++ b/docs/i18n/gettext/reference/manim._config.logger_utils.pot @@ -50,7 +50,6 @@ msgid "A parser containing any .cfg files in use." msgstr "" #: ../../../manim/_config/logger_utils.py:docstring of manim._config.logger_utils.make_logger:5 -#: ../../../manim/_config/logger_utils.py:docstring of manim._config.logger_utils.set_file_logger:7 msgid "The verbosity level of the logger." msgstr "" @@ -70,7 +69,6 @@ msgid "Return type" msgstr "" #: ../../../manim/_config/logger_utils.py:docstring of manim._config.logger_utils.make_logger:16 -#: ../../../manim/_config/logger_utils.py:docstring of manim._config.logger_utils.set_file_logger:11 msgid "Notes" msgstr "" @@ -94,8 +92,4 @@ msgstr "" msgid "The path to the file is built using ``config.log_dir``." msgstr "" -#: ../../../manim/_config/logger_utils.py:docstring of manim._config.logger_utils.set_file_logger:5 -msgid "The global config, used to determine the log file path." -msgstr "" - diff --git a/docs/i18n/gettext/reference/manim._config.utils.ManimConfig.pot b/docs/i18n/gettext/reference/manim._config.utils.ManimConfig.pot index 093944a0aa..c5d7878d63 100644 --- a/docs/i18n/gettext/reference/manim._config.utils.ManimConfig.pot +++ b/docs/i18n/gettext/reference/manim._config.utils.ManimConfig.pot @@ -54,50 +54,54 @@ msgid "Examples" msgstr "" #: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig:25 +msgid "We use a copy of the global configuration object in the following examples for the sake of demonstration; you can skip these lines and just import ``config`` directly if you actually want to modify the configuration:" +msgstr "" + +#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig:35 msgid "Each config option allows for dict syntax and attribute syntax. For example, the following two lines are equivalent," msgstr "" -#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig:34 +#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig:44 msgid "The former is preferred; the latter is provided mostly for backwards compatibility." msgstr "" -#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig:37 +#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig:47 msgid "The config options are designed to keep internal consistency. For example, setting ``frame_y_radius`` will affect ``frame_height``:" msgstr "" -#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig:48 +#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig:58 msgid "There are many ways of interacting with config options. Take for example the config option ``background_color``. There are three ways to change it: via a config file, via CLI flags, or programmatically." msgstr "" -#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig:52 +#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig:62 msgid "To set the background color via a config file, save the following ``manim.cfg`` file with the following contents." msgstr "" -#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig:60 +#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig:70 msgid "In order to have this ``.cfg`` file apply to a manim scene, it needs to be placed in the same directory as the script," msgstr "" -#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig:69 +#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig:79 msgid "Now, when the user executes" msgstr "" -#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig:75 +#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig:85 msgid "the background of the scene will be set to ``WHITE``. This applies regardless of where the manim command is invoked from." msgstr "" -#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig:78 +#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig:88 msgid "Command line arguments override ``.cfg`` files. In the previous example, executing" msgstr "" -#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig:85 +#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig:95 msgid "will set the background color to BLUE, regardless of the contents of ``manim.cfg``." msgstr "" -#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig:88 +#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig:98 msgid "Finally, any programmatic changes made within the scene script itself will override the command line arguments. For example, if ``scene.py`` contains the following" msgstr "" -#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig:101 +#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig:111 msgid "the background color will be set to RED, regardless of the contents of ``manim.cfg`` or the CLI arguments used when invoking manim." msgstr "" @@ -196,6 +200,11 @@ msgstr "" msgid "Enable wireframe debugging mode in opengl." msgstr "" +#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig.aspect_ratio:1::1 +#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig.ffmpeg_executable:1 +msgid "Manually specify the path to the ffmpeg executable" +msgstr "" + #: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig.aspect_ratio:1::1 #: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig.ffmpeg_loglevel:1 msgid "Verbosity level of ffmpeg (no flag)." @@ -348,7 +357,7 @@ msgstr "" #: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig.aspect_ratio:1::1 #: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig.renderer:1 -msgid "\"cairo\", \"opengl\", \"webgl" +msgid "\"cairo\", \"opengl" msgstr "" #: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig.aspect_ratio:1::1 @@ -435,11 +444,6 @@ msgstr "" msgid "Use shaders for OpenGLVMobject stroke which are compatible with transformation matrices." msgstr "" -#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig.aspect_ratio:1::1 -#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig.use_webgl_renderer:1 -msgid "Whether or not to use WebGL renderer." -msgstr "" - #: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig.aspect_ratio:1::1 #: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig.verbosity:1 msgid "Logger verbosity; \"DEBUG\", \"INFO\", \"WARNING\", \"ERROR\", or \"CRITICAL\" (-v)." @@ -449,11 +453,6 @@ msgstr "" msgid "Directory to place videos (no flag)." msgstr "" -#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig.aspect_ratio:1::1 -#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig.webgl_renderer_path:1 -msgid "Path to WebGL renderer." -msgstr "" - #: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig.aspect_ratio:1::1 #: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig.window_monitor:1 msgid "The monitor on which the scene will be rendered" @@ -597,23 +596,23 @@ msgstr "" msgid "The value of ``config.tex_dir`` is ``'{media_dir}/Tex'`` by default, i.e. it is a subfolder of wherever ``config.media_dir`` is located. In order to get the *actual* directory, use :meth:`~ManimConfig.get_dir`." msgstr "" -#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig.get_dir:40 +#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig.get_dir:41 msgid "Resolving directories is done in a lazy way, at the last possible moment, to reflect any changes in other config options:" msgstr "" -#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig.get_dir:49 +#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig.get_dir:50 msgid "Some directories depend on information that is not available to :class:`ManimConfig`. For example, the default value of `video_dir` includes the name of the input file and the video quality (e.g. 480p15). This informamtion has to be supplied via ``kwargs``:" msgstr "" -#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig.get_dir:64 +#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig.get_dir:65 msgid "Note the quality does not need to be passed as keyword argument since :class:`ManimConfig` does store information about quality." msgstr "" -#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig.get_dir:67 +#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig.get_dir:68 msgid "Directories may be recursively defined. For example, the config option ``partial_movie_dir`` depends on ``video_dir``, which in turn depends on ``media_dir``:" msgstr "" -#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig.get_dir:83 +#: ../../../manim/_config/utils.py:docstring of manim._config.utils.ManimConfig.get_dir:84 msgid "Standard f-string syntax is used. Arbitrary names can be used when defining directories, as long as the corresponding values are passed to :meth:`ManimConfig.get_dir` via ``kwargs``." msgstr "" diff --git a/docs/i18n/gettext/reference/manim._config.utils.pot b/docs/i18n/gettext/reference/manim._config.utils.pot index 02c1066d28..97c2d9774a 100644 --- a/docs/i18n/gettext/reference/manim._config.utils.pot +++ b/docs/i18n/gettext/reference/manim._config.utils.pot @@ -19,7 +19,7 @@ msgid "The main class exported by this module is :class:`ManimConfig`. This cla msgstr "" #: ../../../manim/_config/utils.py:docstring of manim._config.utils:9 -msgid "See :doc:`/tutorials/configuration` for an introduction to Manim's configuration system." +msgid "See :doc:`/guides/configuration` for an introduction to Manim's configuration system." msgstr "" #: ../../source/reference/manim._config.utils.rst:15 diff --git a/docs/i18n/gettext/reference/manim.animation.animation.Animation.pot b/docs/i18n/gettext/reference/manim.animation.animation.Animation.pot index 1590490bb5..6c94f8f840 100644 --- a/docs/i18n/gettext/reference/manim.animation.animation.Animation.pot +++ b/docs/i18n/gettext/reference/manim.animation.animation.Animation.pot @@ -70,23 +70,43 @@ msgstr "" msgid "For example ``rate_func(0.5)`` is the proportion of the animation that is done after half of the animations run time." msgstr "" -#: ../../../manim/animation/animation.py:docstring of manim.animation.animation.Animation:17 -msgid "The name of the animation. This gets displayed while rendering the animation. Defaults to ()." +#: ../../../manim/animation/animation.py:docstring of manim.animation.animation.Animation:21 +msgid "reverse_rate_function" msgstr "" #: ../../../manim/animation/animation.py:docstring of manim.animation.animation.Animation:19 +msgid "Reverses the rate function of the animation. Setting ``reverse_rate_function`` does not have any effect on ``remover`` or ``introducer``. These need to be set explicitly if an introducer-animation should be turned into a remover one and vice versa." +msgstr "" + +#: ../../../manim/animation/animation.py:docstring of manim.animation.animation.Animation:24 +msgid "name" +msgstr "" + +#: ../../../manim/animation/animation.py:docstring of manim.animation.animation.Animation:24 +msgid "The name of the animation. This gets displayed while rendering the animation. Defaults to ()." +msgstr "" + +#: ../../../manim/animation/animation.py:docstring of manim.animation.animation.Animation:26 +msgid "remover" +msgstr "" + +#: ../../../manim/animation/animation.py:docstring of manim.animation.animation.Animation:27 msgid "Whether the given mobject should be removed from the scene after this animation." msgstr "" -#: ../../../manim/animation/animation.py:docstring of manim.animation.animation.Animation:20 +#: ../../../manim/animation/animation.py:docstring of manim.animation.animation.Animation:30 +msgid "suspend_mobject_updating" +msgstr "" + +#: ../../../manim/animation/animation.py:docstring of manim.animation.animation.Animation:29 msgid "Whether updaters of the mobject should be suspended during the animation." msgstr "" -#: ../../../manim/animation/animation.py:docstring of manim.animation.animation.Animation:24 +#: ../../../manim/animation/animation.py:docstring of manim.animation.animation.Animation:34 msgid "In the current implementation of this class, the specified rate function is applied within :meth:`.Animation.interpolate_mobject` call as part of the call to :meth:`.Animation.interpolate_submobject`. For subclasses of :class:`.Animation` that are implemented by overriding :meth:`interpolate_mobject`, the rate function has to be applied manually (e.g., by passing ``self.rate_func(alpha)`` instead of just ``alpha``)." msgstr "" -#: ../../../manim/animation/animation.py:docstring of manim.animation.animation.Animation:33 +#: ../../../manim/animation/animation.py:docstring of manim.animation.animation.Animation:43 msgid "Examples" msgstr "" @@ -149,11 +169,14 @@ msgstr "" msgid "Interpolates the mobject of the :class:`Animation` based on alpha value." msgstr "" -#: ../../../manim/animation/animation.py:docstring of manim.animation.animation.Animation.begin:1::1 #: ../../../manim/animation/animation.py:docstring of manim.animation.animation.Animation.begin:1::1 #: ../../../manim/animation/animation.py:docstring of manim.animation.animation.Animation.is_introducer:1 +msgid "Test if the animation is an introducer." +msgstr "" + +#: ../../../manim/animation/animation.py:docstring of manim.animation.animation.Animation.begin:1::1 #: ../../../manim/animation/animation.py:docstring of manim.animation.animation.Animation.is_remover:1 -msgid "Test if a the animation is a remover." +msgid "Test if the animation is a remover." msgstr "" #: ../../../manim/animation/animation.py:docstring of manim.animation.animation.Animation.begin:1::1 @@ -278,6 +301,9 @@ msgid "A float between 0 and 1 expressing the ratio to which the animation is co msgstr "" #: ../../../manim/animation/animation.py:docstring of manim.animation.animation.Animation.is_introducer:3 +msgid "``True`` if the animation is an introducer, ``False`` otherwise." +msgstr "" + #: ../../../manim/animation/animation.py:docstring of manim.animation.animation.Animation.is_remover:3 msgid "``True`` if the animation is a remover, ``False`` otherwise." msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.composition.AnimationGroup.pot b/docs/i18n/gettext/reference/manim.animation.composition.AnimationGroup.pot index 7aac5c939a..059e7e9e22 100644 --- a/docs/i18n/gettext/reference/manim.animation.composition.AnimationGroup.pot +++ b/docs/i18n/gettext/reference/manim.animation.composition.AnimationGroup.pot @@ -56,14 +56,10 @@ msgstr "" msgid "Updates things like starting_mobject, and (for Transforms) target_mobject." msgstr "" -#: ../../../manim/animation/composition.py:docstring of manim.animation.composition.AnimationGroup:0 -#: ../../../manim/animation/composition.py:docstring of manim.animation.composition.AnimationGroup.clean_up_from_scene:0 -#: ../../../manim/animation/composition.py:docstring of manim.animation.composition.AnimationGroup.interpolate:0 -#: ../../../manim/animation/composition.py:docstring of manim.animation.composition.AnimationGroup.update_mobjects:0 -msgid "Parameters" +#: ../../../manim/animation/composition.py:docstring of manim.animation.composition.AnimationGroup.begin:3 +msgid "This method is called right as an animation is being played. As much initialization as possible, especially any mobject copying, should live in this method." msgstr "" -#: ../../../manim/animation/composition.py:docstring of manim.animation.composition.AnimationGroup:0 #: ../../../manim/animation/composition.py:docstring of manim.animation.composition.AnimationGroup.begin:0 #: ../../../manim/animation/composition.py:docstring of manim.animation.composition.AnimationGroup.build_animations_with_timings:0 #: ../../../manim/animation/composition.py:docstring of manim.animation.composition.AnimationGroup.clean_up_from_scene:0 @@ -74,14 +70,16 @@ msgstr "" msgid "Return type" msgstr "" -#: ../../../manim/animation/composition.py:docstring of manim.animation.composition.AnimationGroup.begin:3 -msgid "This method is called right as an animation is being played. As much initialization as possible, especially any mobject copying, should live in this method." -msgstr "" - #: ../../../manim/animation/composition.py:docstring of manim.animation.composition.AnimationGroup.clean_up_from_scene:3 msgid "This includes to :meth:`~.Scene.remove` the Animation's :class:`~.Mobject` if the animation is a remover." msgstr "" +#: ../../../manim/animation/composition.py:docstring of manim.animation.composition.AnimationGroup.clean_up_from_scene:0 +#: ../../../manim/animation/composition.py:docstring of manim.animation.composition.AnimationGroup.interpolate:0 +#: ../../../manim/animation/composition.py:docstring of manim.animation.composition.AnimationGroup.update_mobjects:0 +msgid "Parameters" +msgstr "" + #: ../../../manim/animation/composition.py:docstring of manim.animation.composition.AnimationGroup.clean_up_from_scene:6 msgid "The scene the animation should be cleaned up from." msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.composition.LaggedStart.pot b/docs/i18n/gettext/reference/manim.animation.composition.LaggedStart.pot index f4f2993b9a..3f5aa193b3 100644 --- a/docs/i18n/gettext/reference/manim.animation.composition.LaggedStart.pot +++ b/docs/i18n/gettext/reference/manim.animation.composition.LaggedStart.pot @@ -18,8 +18,4 @@ msgstr "" msgid "Bases: :py:class:`manim.animation.composition.AnimationGroup`" msgstr "" -#: ../../source/reference/manim.animation.composition.LaggedStart.rst:14 -msgid "Methods" -msgstr "" - diff --git a/docs/i18n/gettext/reference/manim.animation.composition.LaggedStartMap.pot b/docs/i18n/gettext/reference/manim.animation.composition.LaggedStartMap.pot index 15c9a872b8..885a4730de 100644 --- a/docs/i18n/gettext/reference/manim.animation.composition.LaggedStartMap.pot +++ b/docs/i18n/gettext/reference/manim.animation.composition.LaggedStartMap.pot @@ -18,12 +18,4 @@ msgstr "" msgid "Bases: :py:class:`manim.animation.composition.LaggedStart`" msgstr "" -#: ../../source/reference/manim.animation.composition.LaggedStartMap.rst:14 -msgid "Methods" -msgstr "" - -#: ../../../manim/animation/composition.py:docstring of manim.animation.composition.LaggedStartMap:0 -msgid "Parameters" -msgstr "" - diff --git a/docs/i18n/gettext/reference/manim.animation.composition.Succession.pot b/docs/i18n/gettext/reference/manim.animation.composition.Succession.pot index a9d1e954f8..0b9c73266d 100644 --- a/docs/i18n/gettext/reference/manim.animation.composition.Succession.pot +++ b/docs/i18n/gettext/reference/manim.animation.composition.Succession.pot @@ -41,13 +41,10 @@ msgstr "" msgid "Updates things like starting_mobject, and (for Transforms) target_mobject." msgstr "" -#: ../../../manim/animation/composition.py:docstring of manim.animation.composition.Succession:0 -#: ../../../manim/animation/composition.py:docstring of manim.animation.composition.Succession.interpolate:0 -#: ../../../manim/animation/composition.py:docstring of manim.animation.composition.Succession.update_mobjects:0 -msgid "Parameters" +#: ../../../manim/animation/composition.py:docstring of manim.animation.composition.Succession.begin:3 +msgid "This method is called right as an animation is being played. As much initialization as possible, especially any mobject copying, should live in this method." msgstr "" -#: ../../../manim/animation/composition.py:docstring of manim.animation.composition.Succession:0 #: ../../../manim/animation/composition.py:docstring of manim.animation.composition.Succession.begin:0 #: ../../../manim/animation/composition.py:docstring of manim.animation.composition.Succession.finish:0 #: ../../../manim/animation/composition.py:docstring of manim.animation.composition.Succession.interpolate:0 @@ -55,10 +52,6 @@ msgstr "" msgid "Return type" msgstr "" -#: ../../../manim/animation/composition.py:docstring of manim.animation.composition.Succession.begin:3 -msgid "This method is called right as an animation is being played. As much initialization as possible, especially any mobject copying, should live in this method." -msgstr "" - #: ../../../manim/animation/composition.py:docstring of manim.animation.composition.Succession.finish:3 msgid "This method gets called when the animation is over." msgstr "" @@ -67,6 +60,11 @@ msgstr "" msgid "This method gets called for every frame during an animation." msgstr "" +#: ../../../manim/animation/composition.py:docstring of manim.animation.composition.Succession.interpolate:0 +#: ../../../manim/animation/composition.py:docstring of manim.animation.composition.Succession.update_mobjects:0 +msgid "Parameters" +msgstr "" + #: ../../../manim/animation/composition.py:docstring of manim.animation.composition.Succession.interpolate:5 msgid "The relative time to set the animation to, 0 meaning the start, 1 meaning the end." msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.creation.AddTextLetterByLetter.pot b/docs/i18n/gettext/reference/manim.animation.creation.AddTextLetterByLetter.pot index 3414c38344..21768a4061 100644 --- a/docs/i18n/gettext/reference/manim.animation.creation.AddTextLetterByLetter.pot +++ b/docs/i18n/gettext/reference/manim.animation.creation.AddTextLetterByLetter.pot @@ -34,8 +34,4 @@ msgstr "" msgid "This is currently only possible for class:`~.Text` and not for class:`~.MathTex`" msgstr "" -#: ../../../manim/animation/creation.py:docstring of manim.animation.creation.AddTextLetterByLetter:0 -msgid "Return type" -msgstr "" - diff --git a/docs/i18n/gettext/reference/manim.animation.creation.AddTextWordByWord.pot b/docs/i18n/gettext/reference/manim.animation.creation.AddTextWordByWord.pot index 13ff1286af..a37c706b12 100644 --- a/docs/i18n/gettext/reference/manim.animation.creation.AddTextWordByWord.pot +++ b/docs/i18n/gettext/reference/manim.animation.creation.AddTextWordByWord.pot @@ -22,12 +22,4 @@ msgstr "" msgid "Show a :class:`~.Text` word by word on the scene. Note: currently broken." msgstr "" -#: ../../source/reference/manim.animation.creation.AddTextWordByWord.rst:14 -msgid "Methods" -msgstr "" - -#: ../../../manim/animation/creation.py:docstring of manim.animation.creation.AddTextWordByWord:0 -msgid "Parameters" -msgstr "" - diff --git a/docs/i18n/gettext/reference/manim.animation.creation.Create.pot b/docs/i18n/gettext/reference/manim.animation.creation.Create.pot index 9fe7cffa91..f8f9b51069 100644 --- a/docs/i18n/gettext/reference/manim.animation.creation.Create.pot +++ b/docs/i18n/gettext/reference/manim.animation.creation.Create.pot @@ -38,10 +38,6 @@ msgstr "" msgid "If ``mobject`` is not an instance of :class:`~.VMobject`." msgstr "" -#: ../../../manim/animation/creation.py:docstring of manim.animation.creation.Create:0 -msgid "Return type" -msgstr "" - #: ../../../manim/animation/creation.py:docstring of manim.animation.creation.Create:9 msgid "Examples" msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.creation.DrawBorderThenFill.pot b/docs/i18n/gettext/reference/manim.animation.creation.DrawBorderThenFill.pot index 5e8dd83cfd..cd9c033b3a 100644 --- a/docs/i18n/gettext/reference/manim.animation.creation.DrawBorderThenFill.pot +++ b/docs/i18n/gettext/reference/manim.animation.creation.DrawBorderThenFill.pot @@ -40,20 +40,15 @@ msgstr "" msgid "Get all mobjects involved in the animation." msgstr "" -#: ../../../manim/animation/creation.py:docstring of manim.animation.creation.DrawBorderThenFill:0 -msgid "Parameters" +#: ../../../manim/animation/creation.py:docstring of manim.animation.creation.DrawBorderThenFill.begin:3 +msgid "This method is called right as an animation is being played. As much initialization as possible, especially any mobject copying, should live in this method." msgstr "" -#: ../../../manim/animation/creation.py:docstring of manim.animation.creation.DrawBorderThenFill:0 #: ../../../manim/animation/creation.py:docstring of manim.animation.creation.DrawBorderThenFill.begin:0 #: ../../../manim/animation/creation.py:docstring of manim.animation.creation.DrawBorderThenFill.get_all_mobjects:0 msgid "Return type" msgstr "" -#: ../../../manim/animation/creation.py:docstring of manim.animation.creation.DrawBorderThenFill.begin:3 -msgid "This method is called right as an animation is being played. As much initialization as possible, especially any mobject copying, should live in this method." -msgstr "" - #: ../../../manim/animation/creation.py:docstring of manim.animation.creation.DrawBorderThenFill.get_all_mobjects:3 msgid "Ordering must match the ordering of arguments to interpolate_submobject" msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.creation.ShowIncreasingSubsets.pot b/docs/i18n/gettext/reference/manim.animation.creation.ShowIncreasingSubsets.pot index bbcf77d718..0cb0e993c6 100644 --- a/docs/i18n/gettext/reference/manim.animation.creation.ShowIncreasingSubsets.pot +++ b/docs/i18n/gettext/reference/manim.animation.creation.ShowIncreasingSubsets.pot @@ -35,14 +35,12 @@ msgstr "" msgid "Interpolates the mobject of the :class:`Animation` based on alpha value." msgstr "" -#: ../../../manim/animation/creation.py:docstring of manim.animation.creation.ShowIncreasingSubsets:0 #: ../../../manim/animation/creation.py:docstring of manim.animation.creation.ShowIncreasingSubsets.interpolate_mobject:0 msgid "Parameters" msgstr "" -#: ../../../manim/animation/creation.py:docstring of manim.animation.creation.ShowIncreasingSubsets:0 -#: ../../../manim/animation/creation.py:docstring of manim.animation.creation.ShowIncreasingSubsets.interpolate_mobject:0 -msgid "Return type" +#: ../../../manim/animation/creation.py:docstring of manim.animation.creation.ShowIncreasingSubsets.interpolate_mobject:3 +msgid "A float between 0 and 1 expressing the ratio to which the animation is completed. For example, alpha-values of 0, 0.5, and 1 correspond to the animation being completed 0%, 50%, and 100%, respectively." msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.creation.ShowPartial.pot b/docs/i18n/gettext/reference/manim.animation.creation.ShowPartial.pot index 2cb7468858..6abed1c161 100644 --- a/docs/i18n/gettext/reference/manim.animation.creation.ShowPartial.pot +++ b/docs/i18n/gettext/reference/manim.animation.creation.ShowPartial.pot @@ -30,10 +30,6 @@ msgstr "" msgid "If ``mobject`` is not an instance of :class:`~.VMobject`." msgstr "" -#: ../../../manim/animation/creation.py:docstring of manim.animation.creation.ShowPartial:0 -msgid "Parameters" -msgstr "" - #: ../../source/reference/manim.animation.creation.ShowPartial.rst:14 msgid "Methods" msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.creation.ShowSubmobjectsOneByOne.pot b/docs/i18n/gettext/reference/manim.animation.creation.ShowSubmobjectsOneByOne.pot index 2eeaf09a24..f8f58f258a 100644 --- a/docs/i18n/gettext/reference/manim.animation.creation.ShowSubmobjectsOneByOne.pot +++ b/docs/i18n/gettext/reference/manim.animation.creation.ShowSubmobjectsOneByOne.pot @@ -26,8 +26,4 @@ msgstr "" msgid "Methods" msgstr "" -#: ../../../manim/animation/creation.py:docstring of manim.animation.creation.ShowSubmobjectsOneByOne:0 -msgid "Parameters" -msgstr "" - diff --git a/docs/i18n/gettext/reference/manim.animation.creation.SpiralIn.pot b/docs/i18n/gettext/reference/manim.animation.creation.SpiralIn.pot new file mode 100644 index 0000000000..dad241e4f7 --- /dev/null +++ b/docs/i18n/gettext/reference/manim.animation.creation.SpiralIn.pot @@ -0,0 +1,59 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Manim \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../source/reference/manim.animation.creation.SpiralIn.rst:2 +msgid "SpiralIn" +msgstr "" + +#: ../../source/reference/manim.animation.creation.SpiralIn.rst:4 +msgid "Qualified name: ``manim.animation.creation.SpiralIn``" +msgstr "" + +#: ../../../manim/animation/creation.py:docstring of manim.animation.creation.SpiralIn:1 +msgid "Bases: :py:class:`manim.animation.animation.Animation`" +msgstr "" + +#: ../../../manim/animation/creation.py:docstring of manim.animation.creation.SpiralIn:1 +msgid "Create the Mobject with sub-Mobjects flying in on spiral trajectories." +msgstr "" + +#: ../../../manim/animation/creation.py:docstring of manim.animation.creation.SpiralIn:0 +#: ../../../manim/animation/creation.py:docstring of manim.animation.creation.SpiralIn.interpolate_mobject:0 +msgid "Parameters" +msgstr "" + +#: ../../../manim/animation/creation.py:docstring of manim.animation.creation.SpiralIn:3 +msgid "The Mobject on which to be operated." +msgstr "" + +#: ../../../manim/animation/creation.py:docstring of manim.animation.creation.SpiralIn:4 +msgid "The factor used for scaling the effect." +msgstr "" + +#: ../../../manim/animation/creation.py:docstring of manim.animation.creation.SpiralIn:5 +msgid "Fractional duration of initial fade-in of sub-Mobjects as they fly inward." +msgstr "" + +#: ../../../manim/animation/creation.py:docstring of manim.animation.creation.SpiralIn:8 +msgid "Examples" +msgstr "" + +#: ../../source/reference/manim.animation.creation.SpiralIn.rst:14 +msgid "Methods" +msgstr "" + +#: ../../../manim/animation/creation.py:docstring of manim.animation.creation.SpiralIn.interpolate_mobject:1::1 +#: ../../../manim/animation/creation.py:docstring of manim.animation.creation.SpiralIn.interpolate_mobject:1 +msgid "Interpolates the mobject of the :class:`Animation` based on alpha value." +msgstr "" + +#: ../../../manim/animation/creation.py:docstring of manim.animation.creation.SpiralIn.interpolate_mobject:3 +msgid "A float between 0 and 1 expressing the ratio to which the animation is completed. For example, alpha-values of 0, 0.5, and 1 correspond to the animation being completed 0%, 50%, and 100%, respectively." +msgstr "" + + diff --git a/docs/i18n/gettext/reference/manim.animation.creation.Uncreate.pot b/docs/i18n/gettext/reference/manim.animation.creation.Uncreate.pot index 04cd9b9084..5ce7effd57 100644 --- a/docs/i18n/gettext/reference/manim.animation.creation.Uncreate.pot +++ b/docs/i18n/gettext/reference/manim.animation.creation.Uncreate.pot @@ -26,12 +26,4 @@ msgstr "" msgid "Examples" msgstr "" -#: ../../source/reference/manim.animation.creation.Uncreate.rst:14 -msgid "Methods" -msgstr "" - -#: ../../../manim/animation/creation.py:docstring of manim.animation.creation.Uncreate:0 -msgid "Parameters" -msgstr "" - diff --git a/docs/i18n/gettext/reference/manim.animation.creation.Unwrite.pot b/docs/i18n/gettext/reference/manim.animation.creation.Unwrite.pot index 2cf6060fd8..553eae3646 100644 --- a/docs/i18n/gettext/reference/manim.animation.creation.Unwrite.pot +++ b/docs/i18n/gettext/reference/manim.animation.creation.Unwrite.pot @@ -30,10 +30,6 @@ msgstr "" msgid "Set True to have the animation start erasing from the last submobject first." msgstr "" -#: ../../../manim/animation/creation.py:docstring of manim.animation.creation.Unwrite:0 -msgid "Return type" -msgstr "" - #: ../../../manim/animation/creation.py:docstring of manim.animation.creation.Unwrite:7 msgid "Examples" msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.creation.Write.pot b/docs/i18n/gettext/reference/manim.animation.creation.Write.pot index 4a179e9e39..62551c553a 100644 --- a/docs/i18n/gettext/reference/manim.animation.creation.Write.pot +++ b/docs/i18n/gettext/reference/manim.animation.creation.Write.pot @@ -40,18 +40,13 @@ msgstr "" msgid "Finish the animation." msgstr "" -#: ../../../manim/animation/creation.py:docstring of manim.animation.creation.Write:0 -msgid "Parameters" +#: ../../../manim/animation/creation.py:docstring of manim.animation.creation.Write.begin:3 +msgid "This method is called right as an animation is being played. As much initialization as possible, especially any mobject copying, should live in this method." msgstr "" -#: ../../../manim/animation/creation.py:docstring of manim.animation.creation.Write:0 #: ../../../manim/animation/creation.py:docstring of manim.animation.creation.Write.begin:0 #: ../../../manim/animation/creation.py:docstring of manim.animation.creation.Write.finish:0 msgid "Return type" msgstr "" -#: ../../../manim/animation/creation.py:docstring of manim.animation.creation.Write.begin:3 -msgid "This method is called right as an animation is being played. As much initialization as possible, especially any mobject copying, should live in this method." -msgstr "" - diff --git a/docs/i18n/gettext/reference/manim.animation.creation.pot b/docs/i18n/gettext/reference/manim.animation.creation.pot index a50531d589..490ed23815 100644 --- a/docs/i18n/gettext/reference/manim.animation.creation.pot +++ b/docs/i18n/gettext/reference/manim.animation.creation.pot @@ -18,39 +18,43 @@ msgstr "" msgid "Classes" msgstr "" -#: ../../source/reference/manim.animation.creation.rst:38::1 +#: ../../source/reference/manim.animation.creation.rst:40::1 msgid "Show a :class:`~.Text` letter by letter on the scene." msgstr "" -#: ../../source/reference/manim.animation.creation.rst:38::1 +#: ../../source/reference/manim.animation.creation.rst:40::1 msgid "Show a :class:`~.Text` word by word on the scene." msgstr "" -#: ../../source/reference/manim.animation.creation.rst:38::1 +#: ../../source/reference/manim.animation.creation.rst:40::1 msgid "Incrementally show a VMobject." msgstr "" -#: ../../source/reference/manim.animation.creation.rst:38::1 +#: ../../source/reference/manim.animation.creation.rst:40::1 msgid "Draw the border first and then show the fill." msgstr "" -#: ../../source/reference/manim.animation.creation.rst:38::1 +#: ../../source/reference/manim.animation.creation.rst:40::1 msgid "Show one submobject at a time, leaving all previous ones displayed on screen." msgstr "" -#: ../../source/reference/manim.animation.creation.rst:38::1 +#: ../../source/reference/manim.animation.creation.rst:40::1 msgid "Abstract class for Animations that show the VMobject partially." msgstr "" -#: ../../source/reference/manim.animation.creation.rst:38::1 +#: ../../source/reference/manim.animation.creation.rst:40::1 msgid "Show one submobject at a time, removing all previously displayed ones from screen." msgstr "" -#: ../../source/reference/manim.animation.creation.rst:38::1 +#: ../../source/reference/manim.animation.creation.rst:40::1 +msgid "Create the Mobject with sub-Mobjects flying in on spiral trajectories." +msgstr "" + +#: ../../source/reference/manim.animation.creation.rst:40::1 msgid "Like :class:`Create` but in reverse." msgstr "" -#: ../../source/reference/manim.animation.creation.rst:38::1 +#: ../../source/reference/manim.animation.creation.rst:40::1 msgid "Simulate erasing by hand a :class:`~.Text` or a :class:`~.VMobject`." msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.fading.FadeIn.pot b/docs/i18n/gettext/reference/manim.animation.fading.FadeIn.pot index e906160605..dca41945e4 100644 --- a/docs/i18n/gettext/reference/manim.animation.fading.FadeIn.pot +++ b/docs/i18n/gettext/reference/manim.animation.fading.FadeIn.pot @@ -42,10 +42,6 @@ msgstr "" msgid "The factor by which the mobject is scaled initially before being rescaling to its original size while being faded in." msgstr "" -#: ../../../manim/animation/fading.py:docstring of manim.animation.fading.FadeIn:0 -msgid "Return type" -msgstr "" - #: ../../../manim/animation/fading.py:docstring of manim.animation.fading.FadeIn:11 msgid "Examples" msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.fading.FadeOut.pot b/docs/i18n/gettext/reference/manim.animation.fading.FadeOut.pot index 61f74f992b..928f9ff500 100644 --- a/docs/i18n/gettext/reference/manim.animation.fading.FadeOut.pot +++ b/docs/i18n/gettext/reference/manim.animation.fading.FadeOut.pot @@ -43,11 +43,6 @@ msgstr "" msgid "The factor by which the mobject is scaled while being faded out." msgstr "" -#: ../../../manim/animation/fading.py:docstring of manim.animation.fading.FadeOut:0 -#: ../../../manim/animation/fading.py:docstring of manim.animation.fading.FadeOut.clean_up_from_scene:0 -msgid "Return type" -msgstr "" - #: ../../../manim/animation/fading.py:docstring of manim.animation.fading.FadeOut:10 msgid "Examples" msgstr "" @@ -69,4 +64,8 @@ msgstr "" msgid "This includes to :meth:`~.Scene.remove` the Animation's :class:`~.Mobject` if the animation is a remover." msgstr "" +#: ../../../manim/animation/fading.py:docstring of manim.animation.fading.FadeOut.clean_up_from_scene:6 +msgid "The scene the animation should be cleaned up from." +msgstr "" + diff --git a/docs/i18n/gettext/reference/manim.animation.growing.GrowArrow.pot b/docs/i18n/gettext/reference/manim.animation.growing.GrowArrow.pot index 7ed156b655..b4fe1544f5 100644 --- a/docs/i18n/gettext/reference/manim.animation.growing.GrowArrow.pot +++ b/docs/i18n/gettext/reference/manim.animation.growing.GrowArrow.pot @@ -34,10 +34,6 @@ msgstr "" msgid "Initial color of the arrow before growing to its full size. Leave empty to match arrow's color." msgstr "" -#: ../../../manim/animation/growing.py:docstring of manim.animation.growing.GrowArrow:0 -msgid "Return type" -msgstr "" - #: ../../../manim/animation/growing.py:docstring of manim.animation.growing.GrowArrow:7 msgid "Examples" msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.growing.GrowFromCenter.pot b/docs/i18n/gettext/reference/manim.animation.growing.GrowFromCenter.pot index c0e21d1181..07bb84a79b 100644 --- a/docs/i18n/gettext/reference/manim.animation.growing.GrowFromCenter.pot +++ b/docs/i18n/gettext/reference/manim.animation.growing.GrowFromCenter.pot @@ -34,10 +34,6 @@ msgstr "" msgid "Initial color of the mobject before growing to its full size. Leave empty to match mobject's color." msgstr "" -#: ../../../manim/animation/growing.py:docstring of manim.animation.growing.GrowFromCenter:0 -msgid "Return type" -msgstr "" - #: ../../../manim/animation/growing.py:docstring of manim.animation.growing.GrowFromCenter:7 msgid "Examples" msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.growing.GrowFromEdge.pot b/docs/i18n/gettext/reference/manim.animation.growing.GrowFromEdge.pot index 640811c03b..3b5d7def14 100644 --- a/docs/i18n/gettext/reference/manim.animation.growing.GrowFromEdge.pot +++ b/docs/i18n/gettext/reference/manim.animation.growing.GrowFromEdge.pot @@ -38,10 +38,6 @@ msgstr "" msgid "Initial color of the mobject before growing to its full size. Leave empty to match mobject's color." msgstr "" -#: ../../../manim/animation/growing.py:docstring of manim.animation.growing.GrowFromEdge:0 -msgid "Return type" -msgstr "" - #: ../../../manim/animation/growing.py:docstring of manim.animation.growing.GrowFromEdge:8 msgid "Examples" msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.growing.GrowFromPoint.pot b/docs/i18n/gettext/reference/manim.animation.growing.GrowFromPoint.pot index 4aec39fc18..6d0672b1e0 100644 --- a/docs/i18n/gettext/reference/manim.animation.growing.GrowFromPoint.pot +++ b/docs/i18n/gettext/reference/manim.animation.growing.GrowFromPoint.pot @@ -38,10 +38,6 @@ msgstr "" msgid "Initial color of the mobject before growing to its full size. Leave empty to match mobject's color." msgstr "" -#: ../../../manim/animation/growing.py:docstring of manim.animation.growing.GrowFromPoint:0 -msgid "Return type" -msgstr "" - #: ../../../manim/animation/growing.py:docstring of manim.animation.growing.GrowFromPoint:8 msgid "Examples" msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.growing.SpinInFromNothing.pot b/docs/i18n/gettext/reference/manim.animation.growing.SpinInFromNothing.pot index 718ff0b5b1..b910e735ca 100644 --- a/docs/i18n/gettext/reference/manim.animation.growing.SpinInFromNothing.pot +++ b/docs/i18n/gettext/reference/manim.animation.growing.SpinInFromNothing.pot @@ -38,10 +38,6 @@ msgstr "" msgid "Initial color of the mobject before growing to its full size. Leave empty to match mobject's color." msgstr "" -#: ../../../manim/animation/growing.py:docstring of manim.animation.growing.SpinInFromNothing:0 -msgid "Return type" -msgstr "" - #: ../../../manim/animation/growing.py:docstring of manim.animation.growing.SpinInFromNothing:9 msgid "Examples" msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.indication.ApplyWave.pot b/docs/i18n/gettext/reference/manim.animation.indication.ApplyWave.pot index d5ae851381..e1822d9d93 100644 --- a/docs/i18n/gettext/reference/manim.animation.indication.ApplyWave.pot +++ b/docs/i18n/gettext/reference/manim.animation.indication.ApplyWave.pot @@ -54,16 +54,8 @@ msgstr "" msgid "The duration of the animation." msgstr "" -#: ../../../manim/animation/indication.py:docstring of manim.animation.indication.ApplyWave:0 -msgid "Return type" -msgstr "" - #: ../../../manim/animation/indication.py:docstring of manim.animation.indication.ApplyWave:12 msgid "Examples" msgstr "" -#: ../../../manim/animation/indication.py:docstring of manim.animation.indication.ApplyWave:31 -msgid "Homotopy is a function from (x, y, z, t) to (x', y', z')" -msgstr "" - diff --git a/docs/i18n/gettext/reference/manim.animation.indication.Flash.pot b/docs/i18n/gettext/reference/manim.animation.indication.Flash.pot index 24eb2b599b..3467a3a8de 100644 --- a/docs/i18n/gettext/reference/manim.animation.indication.Flash.pot +++ b/docs/i18n/gettext/reference/manim.animation.indication.Flash.pot @@ -62,10 +62,6 @@ msgstr "" msgid "Additional arguments to be passed to the :class:`~.Succession` constructor" msgstr "" -#: ../../../manim/animation/indication.py:docstring of manim.animation.indication.Flash:0 -msgid "Return type" -msgstr "" - #: ../../../manim/animation/indication.py:docstring of manim.animation.indication.Flash:15 msgid "Examples" msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.indication.FocusOn.pot b/docs/i18n/gettext/reference/manim.animation.indication.FocusOn.pot index 040e38d293..482c7f82b1 100644 --- a/docs/i18n/gettext/reference/manim.animation.indication.FocusOn.pot +++ b/docs/i18n/gettext/reference/manim.animation.indication.FocusOn.pot @@ -46,10 +46,6 @@ msgstr "" msgid "Additional arguments to be passed to the :class:`~.Succession` constructor" msgstr "" -#: ../../../manim/animation/indication.py:docstring of manim.animation.indication.FocusOn:0 -msgid "Return type" -msgstr "" - #: ../../../manim/animation/indication.py:docstring of manim.animation.indication.FocusOn:11 msgid "Examples" msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.indication.Indicate.pot b/docs/i18n/gettext/reference/manim.animation.indication.Indicate.pot index c90485d5e9..136caba7f9 100644 --- a/docs/i18n/gettext/reference/manim.animation.indication.Indicate.pot +++ b/docs/i18n/gettext/reference/manim.animation.indication.Indicate.pot @@ -46,10 +46,6 @@ msgstr "" msgid "Additional arguments to be passed to the :class:`~.Succession` constructor" msgstr "" -#: ../../../manim/animation/indication.py:docstring of manim.animation.indication.Indicate:0 -msgid "Return type" -msgstr "" - #: ../../../manim/animation/indication.py:docstring of manim.animation.indication.Indicate:11 msgid "Examples" msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.indication.ShowCreationThenFadeOut.pot b/docs/i18n/gettext/reference/manim.animation.indication.ShowCreationThenFadeOut.pot index 82b3ca4f6f..aff5c1edea 100644 --- a/docs/i18n/gettext/reference/manim.animation.indication.ShowCreationThenFadeOut.pot +++ b/docs/i18n/gettext/reference/manim.animation.indication.ShowCreationThenFadeOut.pot @@ -19,19 +19,7 @@ msgid "Bases: :py:class:`manim.animation.composition.Succession`" msgstr "" #: ../../../manim/animation/indication.py:docstring of manim.animation.indication.ShowCreationThenFadeOut:1 -msgid "Deprecated" -msgstr "" - -#: ../../../manim/animation/indication.py:docstring of manim.animation.indication.ShowCreationThenFadeOut:4 -msgid "The class ShowCreationThenFadeOut has been deprecated since v0.15.0 and is expected to be removed after v0.16.0. Use Create then FadeOut to achieve this effect." -msgstr "" - -#: ../../source/reference/manim.animation.indication.ShowCreationThenFadeOut.rst:14 -msgid "Methods" -msgstr "" - -#: ../../../manim/animation/indication.py:docstring of manim.animation.indication.ShowCreationThenFadeOut:0 -msgid "Parameters" +msgid "Deprecated The class ShowCreationThenFadeOut has been deprecated since v0.15.0 and is expected to be removed after v0.16.0. Use Create then FadeOut to achieve this effect." msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.indication.ShowPassingFlash.pot b/docs/i18n/gettext/reference/manim.animation.indication.ShowPassingFlash.pot index 02acdc6b96..0cad303763 100644 --- a/docs/i18n/gettext/reference/manim.animation.indication.ShowPassingFlash.pot +++ b/docs/i18n/gettext/reference/manim.animation.indication.ShowPassingFlash.pot @@ -35,11 +35,6 @@ msgstr "" msgid "The length of the sliver relative to the length of the stroke." msgstr "" -#: ../../../manim/animation/indication.py:docstring of manim.animation.indication.ShowPassingFlash:0 -#: ../../../manim/animation/indication.py:docstring of manim.animation.indication.ShowPassingFlash.clean_up_from_scene:0 -msgid "Return type" -msgstr "" - #: ../../../manim/animation/indication.py:docstring of manim.animation.indication.ShowPassingFlash:7 msgid "Examples" msgstr "" @@ -57,4 +52,8 @@ msgstr "" msgid "This includes to :meth:`~.Scene.remove` the Animation's :class:`~.Mobject` if the animation is a remover." msgstr "" +#: ../../../manim/animation/indication.py:docstring of manim.animation.indication.ShowPassingFlash.clean_up_from_scene:6 +msgid "The scene the animation should be cleaned up from." +msgstr "" + diff --git a/docs/i18n/gettext/reference/manim.animation.indication.Wiggle.pot b/docs/i18n/gettext/reference/manim.animation.indication.Wiggle.pot index 3cc8218912..a1e7b8201d 100644 --- a/docs/i18n/gettext/reference/manim.animation.indication.Wiggle.pot +++ b/docs/i18n/gettext/reference/manim.animation.indication.Wiggle.pot @@ -54,10 +54,6 @@ msgstr "" msgid "The duration of the animation" msgstr "" -#: ../../../manim/animation/indication.py:docstring of manim.animation.indication.Wiggle:0 -msgid "Return type" -msgstr "" - #: ../../../manim/animation/indication.py:docstring of manim.animation.indication.Wiggle:13 msgid "Examples" msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.indication.pot b/docs/i18n/gettext/reference/manim.animation.indication.pot index 445048431b..5724a18b18 100644 --- a/docs/i18n/gettext/reference/manim.animation.indication.pot +++ b/docs/i18n/gettext/reference/manim.animation.indication.pot @@ -42,6 +42,10 @@ msgstr "" msgid "Indicate a Mobject by temporarily resizing and recoloring it." msgstr "" +#: ../../source/reference/manim.animation.indication.rst:36::1 +msgid "Deprecated" +msgstr "" + #: ../../source/reference/manim.animation.indication.rst:36::1 msgid "Show only a sliver of the VMobject each frame." msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.movement.ComplexHomotopy.pot b/docs/i18n/gettext/reference/manim.animation.movement.ComplexHomotopy.pot index 1b5f7adaea..2c202d313f 100644 --- a/docs/i18n/gettext/reference/manim.animation.movement.ComplexHomotopy.pot +++ b/docs/i18n/gettext/reference/manim.animation.movement.ComplexHomotopy.pot @@ -22,12 +22,4 @@ msgstr "" msgid "Complex Homotopy a function Cx[0, 1] to C" msgstr "" -#: ../../source/reference/manim.animation.movement.ComplexHomotopy.rst:14 -msgid "Methods" -msgstr "" - -#: ../../../manim/animation/movement.py:docstring of manim.animation.movement.ComplexHomotopy:0 -msgid "Parameters" -msgstr "" - diff --git a/docs/i18n/gettext/reference/manim.animation.movement.Homotopy.pot b/docs/i18n/gettext/reference/manim.animation.movement.Homotopy.pot index b96b29a460..b4d2762f55 100644 --- a/docs/i18n/gettext/reference/manim.animation.movement.Homotopy.pot +++ b/docs/i18n/gettext/reference/manim.animation.movement.Homotopy.pot @@ -19,15 +19,39 @@ msgid "Bases: :py:class:`manim.animation.animation.Animation`" msgstr "" #: ../../../manim/animation/movement.py:docstring of manim.animation.movement.Homotopy:1 -msgid "Homotopy is a function from (x, y, z, t) to (x', y', z')" +msgid "A Homotopy." msgstr "" -#: ../../source/reference/manim.animation.movement.Homotopy.rst:14 -msgid "Methods" +#: ../../../manim/animation/movement.py:docstring of manim.animation.movement.Homotopy:3 +msgid "This is an animation transforming the points of a mobject according to the specified transformation function. With the parameter :math:`t` moving from 0 to 1 throughout the animation and :math:`(x, y, z)` describing the coordinates of the point of a mobject, the function passed to the ``homotopy`` keyword argument should transform the tuple :math:`(x, y, z, t)` to :math:`(x', y', z')`, the coordinates the original point is transformed to at time :math:`t`." msgstr "" #: ../../../manim/animation/movement.py:docstring of manim.animation.movement.Homotopy:0 msgid "Parameters" msgstr "" +#: ../../../manim/animation/movement.py:docstring of manim.animation.movement.Homotopy:11 +msgid "A function mapping :math:`(x, y, z, t)` to :math:`(x', y', z')`." +msgstr "" + +#: ../../../manim/animation/movement.py:docstring of manim.animation.movement.Homotopy:12 +msgid "The mobject transformed under the given homotopy." +msgstr "" + +#: ../../../manim/animation/movement.py:docstring of manim.animation.movement.Homotopy:13 +msgid "The run time of the animation." +msgstr "" + +#: ../../../manim/animation/movement.py:docstring of manim.animation.movement.Homotopy:14 +msgid "Keyword arguments propagated to :meth:`.Mobject.apply_function`." +msgstr "" + +#: ../../../manim/animation/movement.py:docstring of manim.animation.movement.Homotopy:15 +msgid "Further keyword arguments passed to the parent class." +msgstr "" + +#: ../../source/reference/manim.animation.movement.Homotopy.rst:14 +msgid "Methods" +msgstr "" + diff --git a/docs/i18n/gettext/reference/manim.animation.movement.MoveAlongPath.pot b/docs/i18n/gettext/reference/manim.animation.movement.MoveAlongPath.pot index f30d54ef24..5fe157f9cb 100644 --- a/docs/i18n/gettext/reference/manim.animation.movement.MoveAlongPath.pot +++ b/docs/i18n/gettext/reference/manim.animation.movement.MoveAlongPath.pot @@ -31,14 +31,12 @@ msgstr "" msgid "Interpolates the mobject of the :class:`Animation` based on alpha value." msgstr "" -#: ../../../manim/animation/movement.py:docstring of manim.animation.movement.MoveAlongPath:0 #: ../../../manim/animation/movement.py:docstring of manim.animation.movement.MoveAlongPath.interpolate_mobject:0 msgid "Parameters" msgstr "" -#: ../../../manim/animation/movement.py:docstring of manim.animation.movement.MoveAlongPath:0 -#: ../../../manim/animation/movement.py:docstring of manim.animation.movement.MoveAlongPath.interpolate_mobject:0 -msgid "Return type" +#: ../../../manim/animation/movement.py:docstring of manim.animation.movement.MoveAlongPath.interpolate_mobject:3 +msgid "A float between 0 and 1 expressing the ratio to which the animation is completed. For example, alpha-values of 0, 0.5, and 1 correspond to the animation being completed 0%, 50%, and 100%, respectively." msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.movement.PhaseFlow.pot b/docs/i18n/gettext/reference/manim.animation.movement.PhaseFlow.pot index 54c2cc2f4b..52540ff949 100644 --- a/docs/i18n/gettext/reference/manim.animation.movement.PhaseFlow.pot +++ b/docs/i18n/gettext/reference/manim.animation.movement.PhaseFlow.pot @@ -27,14 +27,12 @@ msgstr "" msgid "Interpolates the mobject of the :class:`Animation` based on alpha value." msgstr "" -#: ../../../manim/animation/movement.py:docstring of manim.animation.movement.PhaseFlow:0 #: ../../../manim/animation/movement.py:docstring of manim.animation.movement.PhaseFlow.interpolate_mobject:0 msgid "Parameters" msgstr "" -#: ../../../manim/animation/movement.py:docstring of manim.animation.movement.PhaseFlow:0 -#: ../../../manim/animation/movement.py:docstring of manim.animation.movement.PhaseFlow.interpolate_mobject:0 -msgid "Return type" +#: ../../../manim/animation/movement.py:docstring of manim.animation.movement.PhaseFlow.interpolate_mobject:3 +msgid "A float between 0 and 1 expressing the ratio to which the animation is completed. For example, alpha-values of 0, 0.5, and 1 correspond to the animation being completed 0%, 50%, and 100%, respectively." msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.movement.SmoothedVectorizedHomotopy.pot b/docs/i18n/gettext/reference/manim.animation.movement.SmoothedVectorizedHomotopy.pot index 59e693eb6a..6259c703bf 100644 --- a/docs/i18n/gettext/reference/manim.animation.movement.SmoothedVectorizedHomotopy.pot +++ b/docs/i18n/gettext/reference/manim.animation.movement.SmoothedVectorizedHomotopy.pot @@ -18,10 +18,6 @@ msgstr "" msgid "Bases: :py:class:`manim.animation.movement.Homotopy`" msgstr "" -#: ../../../manim/animation/movement.py:docstring of manim.animation.movement.SmoothedVectorizedHomotopy:1 -msgid "Homotopy is a function from (x, y, z, t) to (x', y', z')" -msgstr "" - #: ../../source/reference/manim.animation.movement.SmoothedVectorizedHomotopy.rst:14 msgid "Methods" msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.movement.pot b/docs/i18n/gettext/reference/manim.animation.movement.pot index 77ad3fe2f4..52b838bf07 100644 --- a/docs/i18n/gettext/reference/manim.animation.movement.pot +++ b/docs/i18n/gettext/reference/manim.animation.movement.pot @@ -23,8 +23,7 @@ msgid "Complex Homotopy a function Cx[0, 1] to C" msgstr "" #: ../../source/reference/manim.animation.movement.rst:28::1 -#: ../../source/reference/manim.animation.movement.rst:28::1 -msgid "Homotopy is a function from (x, y, z, t) to (x', y', z')" +msgid "A Homotopy." msgstr "" #: ../../source/reference/manim.animation.movement.rst:28::1 diff --git a/docs/i18n/gettext/reference/manim.animation.numbers.ChangeDecimalToValue.pot b/docs/i18n/gettext/reference/manim.animation.numbers.ChangeDecimalToValue.pot index 7972854c8c..1836100e7c 100644 --- a/docs/i18n/gettext/reference/manim.animation.numbers.ChangeDecimalToValue.pot +++ b/docs/i18n/gettext/reference/manim.animation.numbers.ChangeDecimalToValue.pot @@ -18,12 +18,4 @@ msgstr "" msgid "Bases: :py:class:`manim.animation.numbers.ChangingDecimal`" msgstr "" -#: ../../source/reference/manim.animation.numbers.ChangeDecimalToValue.rst:14 -msgid "Methods" -msgstr "" - -#: ../../../manim/animation/numbers.py:docstring of manim.animation.numbers.ChangeDecimalToValue:0 -msgid "Parameters" -msgstr "" - diff --git a/docs/i18n/gettext/reference/manim.animation.numbers.ChangingDecimal.pot b/docs/i18n/gettext/reference/manim.animation.numbers.ChangingDecimal.pot index 7a75504c01..de340bcf66 100644 --- a/docs/i18n/gettext/reference/manim.animation.numbers.ChangingDecimal.pot +++ b/docs/i18n/gettext/reference/manim.animation.numbers.ChangingDecimal.pot @@ -27,14 +27,12 @@ msgstr "" msgid "Interpolates the mobject of the :class:`Animation` based on alpha value." msgstr "" -#: ../../../manim/animation/numbers.py:docstring of manim.animation.numbers.ChangingDecimal:0 #: ../../../manim/animation/numbers.py:docstring of manim.animation.numbers.ChangingDecimal.interpolate_mobject:0 msgid "Parameters" msgstr "" -#: ../../../manim/animation/numbers.py:docstring of manim.animation.numbers.ChangingDecimal:0 -#: ../../../manim/animation/numbers.py:docstring of manim.animation.numbers.ChangingDecimal.interpolate_mobject:0 -msgid "Return type" +#: ../../../manim/animation/numbers.py:docstring of manim.animation.numbers.ChangingDecimal.interpolate_mobject:3 +msgid "A float between 0 and 1 expressing the ratio to which the animation is completed. For example, alpha-values of 0, 0.5, and 1 correspond to the animation being completed 0%, 50%, and 100%, respectively." msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.rotation.Rotate.pot b/docs/i18n/gettext/reference/manim.animation.rotation.Rotate.pot index b4f89cba93..c8b0b5458c 100644 --- a/docs/i18n/gettext/reference/manim.animation.rotation.Rotate.pot +++ b/docs/i18n/gettext/reference/manim.animation.rotation.Rotate.pot @@ -46,10 +46,6 @@ msgstr "" msgid "If ``about_point``is ``None``, this argument specifies the direction of the bounding box point to be taken as the rotation center." msgstr "" -#: ../../../manim/animation/rotation.py:docstring of manim.animation.rotation.Rotate:0 -msgid "Return type" -msgstr "" - #: ../../../manim/animation/rotation.py:docstring of manim.animation.rotation.Rotate:12 msgid "Examples" msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.rotation.Rotating.pot b/docs/i18n/gettext/reference/manim.animation.rotation.Rotating.pot index 72c2c4ea53..c94ddcd187 100644 --- a/docs/i18n/gettext/reference/manim.animation.rotation.Rotating.pot +++ b/docs/i18n/gettext/reference/manim.animation.rotation.Rotating.pot @@ -27,14 +27,12 @@ msgstr "" msgid "Interpolates the mobject of the :class:`Animation` based on alpha value." msgstr "" -#: ../../../manim/animation/rotation.py:docstring of manim.animation.rotation.Rotating:0 #: ../../../manim/animation/rotation.py:docstring of manim.animation.rotation.Rotating.interpolate_mobject:0 msgid "Parameters" msgstr "" -#: ../../../manim/animation/rotation.py:docstring of manim.animation.rotation.Rotating:0 -#: ../../../manim/animation/rotation.py:docstring of manim.animation.rotation.Rotating.interpolate_mobject:0 -msgid "Return type" +#: ../../../manim/animation/rotation.py:docstring of manim.animation.rotation.Rotating.interpolate_mobject:3 +msgid "A float between 0 and 1 expressing the ratio to which the animation is completed. For example, alpha-values of 0, 0.5, and 1 correspond to the animation being completed 0%, 50%, and 100%, respectively." msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.speedmodifier.ChangeSpeed.pot b/docs/i18n/gettext/reference/manim.animation.speedmodifier.ChangeSpeed.pot new file mode 100644 index 0000000000..e9ac21bd31 --- /dev/null +++ b/docs/i18n/gettext/reference/manim.animation.speedmodifier.ChangeSpeed.pot @@ -0,0 +1,144 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Manim \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../source/reference/manim.animation.speedmodifier.ChangeSpeed.rst:2 +msgid "ChangeSpeed" +msgstr "" + +#: ../../source/reference/manim.animation.speedmodifier.ChangeSpeed.rst:4 +msgid "Qualified name: ``manim.animation.speedmodifier.ChangeSpeed``" +msgstr "" + +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed:1 +msgid "Bases: :py:class:`manim.animation.animation.Animation`" +msgstr "" + +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed:1 +msgid "Modifies the speed of passed animation. :class:`AnimationGroup` with different ``lag_ratio`` can also be used which combines multiple animations into one. The ``run_time`` of the passed animation is changed to modify the speed." +msgstr "" + +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed:0 +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed.add_updater:0 +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed.clean_up_from_scene:0 +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed.interpolate:0 +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed.update_mobjects:0 +msgid "Parameters" +msgstr "" + +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed:6 +msgid "Animation of which the speed is to be modified." +msgstr "" + +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed:7 +msgid "Contains nodes (percentage of ``run_time``) and its corresponding speed factor." +msgstr "" + +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed:8 +msgid "Overrides ``rate_func`` of passed animation, applied before changing speed." +msgstr "" + +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed:11 +msgid "Examples" +msgstr "" + +#: ../../source/reference/manim.animation.speedmodifier.ChangeSpeed.rst:14 +msgid "Methods" +msgstr "" + +#: ../../source/reference/manim.animation.speedmodifier.ChangeSpeed.rst:27::1 +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed.add_updater:1 +msgid "This static method can be used to apply speed change to updaters." +msgstr "" + +#: ../../source/reference/manim.animation.speedmodifier.ChangeSpeed.rst:27::1 +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed.begin:1 +msgid "Begin the animation." +msgstr "" + +#: ../../source/reference/manim.animation.speedmodifier.ChangeSpeed.rst:27::1 +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed.clean_up_from_scene:1 +msgid "Clean up the :class:`~.Scene` after finishing the animation." +msgstr "" + +#: ../../source/reference/manim.animation.speedmodifier.ChangeSpeed.rst:27::1 +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed.finish:1 +msgid "Finish the animation." +msgstr "" + +#: ../../source/reference/manim.animation.speedmodifier.ChangeSpeed.rst:27::1 +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed.get_scaled_total_time:1 +msgid "The time taken by the animation under the assumption that the ``run_time`` is 1." +msgstr "" + +#: ../../source/reference/manim.animation.speedmodifier.ChangeSpeed.rst:27::1 +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed.interpolate:1 +msgid "Set the animation progress." +msgstr "" + +#: ../../source/reference/manim.animation.speedmodifier.ChangeSpeed.rst:27::1 +msgid "Updates things like starting_mobject, and (for Transforms) target_mobject." +msgstr "" + +#: ../../source/reference/manim.animation.speedmodifier.ChangeSpeed.rst:29 +msgid "Attributes" +msgstr "" + +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed.add_updater:3 +msgid "This updater will follow speed and rate function of any :class:`.ChangeSpeed` animation that is playing with ``affects_speed_updaters=True``. By default, updater functions added via the usual :meth:`.Mobject.add_updater` method do not respect the change of animation speed." +msgstr "" + +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed.add_updater:8 +msgid "The mobject to which the updater should be attached." +msgstr "" + +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed.add_updater:9 +msgid "The function that is called whenever a new frame is rendered." +msgstr "" + +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed.add_updater:10 +msgid "The position in the list of the mobject's updaters at which the function should be inserted." +msgstr "" + +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed.add_updater:12 +msgid "If ``True``, calls the update function when attaching it to the mobject." +msgstr "" + +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed.begin:3 +msgid "This method is called right as an animation is being played. As much initialization as possible, especially any mobject copying, should live in this method." +msgstr "" + +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed.begin:0 +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed.clean_up_from_scene:0 +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed.finish:0 +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed.get_scaled_total_time:0 +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed.interpolate:0 +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed.update_mobjects:0 +msgid "Return type" +msgstr "" + +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed.clean_up_from_scene:3 +msgid "This includes to :meth:`~.Scene.remove` the Animation's :class:`~.Mobject` if the animation is a remover." +msgstr "" + +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed.clean_up_from_scene:6 +msgid "The scene the animation should be cleaned up from." +msgstr "" + +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed.finish:3 +msgid "This method gets called when the animation is over." +msgstr "" + +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed.interpolate:3 +msgid "This method gets called for every frame during an animation." +msgstr "" + +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier.ChangeSpeed.interpolate:5 +msgid "The relative time to set the animation to, 0 meaning the start, 1 meaning the end." +msgstr "" + + diff --git a/docs/i18n/gettext/reference/manim.animation.speedmodifier.pot b/docs/i18n/gettext/reference/manim.animation.speedmodifier.pot new file mode 100644 index 0000000000..e44ae23c43 --- /dev/null +++ b/docs/i18n/gettext/reference/manim.animation.speedmodifier.pot @@ -0,0 +1,21 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Manim \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../source/reference/manim.animation.speedmodifier.rst:2 +msgid "speedmodifier" +msgstr "" + +#: ../../../manim/animation/speedmodifier.py:docstring of manim.animation.speedmodifier:1 +msgid "Utilities for modifying the speed at which animations are played." +msgstr "" + +#: ../../source/reference/manim.animation.speedmodifier.rst:15 +msgid "Classes" +msgstr "" + + diff --git a/docs/i18n/gettext/reference/manim.animation.transform.ApplyComplexFunction.pot b/docs/i18n/gettext/reference/manim.animation.transform.ApplyComplexFunction.pot index 112a2c6873..a087a06b63 100644 --- a/docs/i18n/gettext/reference/manim.animation.transform.ApplyComplexFunction.pot +++ b/docs/i18n/gettext/reference/manim.animation.transform.ApplyComplexFunction.pot @@ -26,8 +26,4 @@ msgstr "" msgid "Attributes" msgstr "" -#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.ApplyComplexFunction:0 -msgid "Parameters" -msgstr "" - diff --git a/docs/i18n/gettext/reference/manim.animation.transform.ApplyFunction.pot b/docs/i18n/gettext/reference/manim.animation.transform.ApplyFunction.pot index 20a44312a6..30cd26b0a1 100644 --- a/docs/i18n/gettext/reference/manim.animation.transform.ApplyFunction.pot +++ b/docs/i18n/gettext/reference/manim.animation.transform.ApplyFunction.pot @@ -26,8 +26,4 @@ msgstr "" msgid "Attributes" msgstr "" -#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.ApplyFunction:0 -msgid "Parameters" -msgstr "" - diff --git a/docs/i18n/gettext/reference/manim.animation.transform.ApplyMatrix.pot b/docs/i18n/gettext/reference/manim.animation.transform.ApplyMatrix.pot index b3a8bf609a..49331eeb99 100644 --- a/docs/i18n/gettext/reference/manim.animation.transform.ApplyMatrix.pot +++ b/docs/i18n/gettext/reference/manim.animation.transform.ApplyMatrix.pot @@ -42,10 +42,6 @@ msgstr "" msgid "Further keyword arguments that are passed to :class:`ApplyPointwiseFunction`." msgstr "" -#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.ApplyMatrix:0 -msgid "Return type" -msgstr "" - #: ../../../manim/animation/transform.py:docstring of manim.animation.transform.ApplyMatrix:9 msgid "Examples" msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.transform.ApplyMethod.pot b/docs/i18n/gettext/reference/manim.animation.transform.ApplyMethod.pot index d9c6a1eedc..320085ca09 100644 --- a/docs/i18n/gettext/reference/manim.animation.transform.ApplyMethod.pot +++ b/docs/i18n/gettext/reference/manim.animation.transform.ApplyMethod.pot @@ -42,10 +42,6 @@ msgstr "" msgid "Any keyword arguments passed to :class:`~.Transform`." msgstr "" -#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.ApplyMethod:0 -msgid "Return type" -msgstr "" - #: ../../source/reference/manim.animation.transform.ApplyMethod.rst:14 msgid "Methods" msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.transform.ApplyPointwiseFunction.pot b/docs/i18n/gettext/reference/manim.animation.transform.ApplyPointwiseFunction.pot index 5291a225bb..36d818db66 100644 --- a/docs/i18n/gettext/reference/manim.animation.transform.ApplyPointwiseFunction.pot +++ b/docs/i18n/gettext/reference/manim.animation.transform.ApplyPointwiseFunction.pot @@ -34,8 +34,4 @@ msgstr "" msgid "Attributes" msgstr "" -#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.ApplyPointwiseFunction:0 -msgid "Parameters" -msgstr "" - diff --git a/docs/i18n/gettext/reference/manim.animation.transform.ApplyPointwiseFunctionToCenter.pot b/docs/i18n/gettext/reference/manim.animation.transform.ApplyPointwiseFunctionToCenter.pot index e5d7f648cd..84ed1cd0e4 100644 --- a/docs/i18n/gettext/reference/manim.animation.transform.ApplyPointwiseFunctionToCenter.pot +++ b/docs/i18n/gettext/reference/manim.animation.transform.ApplyPointwiseFunctionToCenter.pot @@ -31,13 +31,8 @@ msgstr "" msgid "Attributes" msgstr "" -#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.ApplyPointwiseFunctionToCenter:0 -msgid "Parameters" -msgstr "" - -#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.ApplyPointwiseFunctionToCenter:0 -#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.ApplyPointwiseFunctionToCenter.begin:0 -msgid "Return type" +#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.ApplyPointwiseFunctionToCenter.begin:3 +msgid "This method is called right as an animation is being played. As much initialization as possible, especially any mobject copying, should live in this method." msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.transform.ClockwiseTransform.pot b/docs/i18n/gettext/reference/manim.animation.transform.ClockwiseTransform.pot index 99ce9194c2..331c76c280 100644 --- a/docs/i18n/gettext/reference/manim.animation.transform.ClockwiseTransform.pot +++ b/docs/i18n/gettext/reference/manim.animation.transform.ClockwiseTransform.pot @@ -34,8 +34,4 @@ msgstr "" msgid "Attributes" msgstr "" -#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.ClockwiseTransform:0 -msgid "Parameters" -msgstr "" - diff --git a/docs/i18n/gettext/reference/manim.animation.transform.CounterclockwiseTransform.pot b/docs/i18n/gettext/reference/manim.animation.transform.CounterclockwiseTransform.pot index bd9b425a0b..41d2723333 100644 --- a/docs/i18n/gettext/reference/manim.animation.transform.CounterclockwiseTransform.pot +++ b/docs/i18n/gettext/reference/manim.animation.transform.CounterclockwiseTransform.pot @@ -34,8 +34,4 @@ msgstr "" msgid "Attributes" msgstr "" -#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.CounterclockwiseTransform:0 -msgid "Parameters" -msgstr "" - diff --git a/docs/i18n/gettext/reference/manim.animation.transform.CyclicReplace.pot b/docs/i18n/gettext/reference/manim.animation.transform.CyclicReplace.pot index 90209fce40..54881283d2 100644 --- a/docs/i18n/gettext/reference/manim.animation.transform.CyclicReplace.pot +++ b/docs/i18n/gettext/reference/manim.animation.transform.CyclicReplace.pot @@ -26,8 +26,4 @@ msgstr "" msgid "Attributes" msgstr "" -#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.CyclicReplace:0 -msgid "Parameters" -msgstr "" - diff --git a/docs/i18n/gettext/reference/manim.animation.transform.FadeToColor.pot b/docs/i18n/gettext/reference/manim.animation.transform.FadeToColor.pot index ab7fb81ea0..9385df131f 100644 --- a/docs/i18n/gettext/reference/manim.animation.transform.FadeToColor.pot +++ b/docs/i18n/gettext/reference/manim.animation.transform.FadeToColor.pot @@ -34,8 +34,4 @@ msgstr "" msgid "Attributes" msgstr "" -#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.FadeToColor:0 -msgid "Parameters" -msgstr "" - diff --git a/docs/i18n/gettext/reference/manim.animation.transform.MoveToTarget.pot b/docs/i18n/gettext/reference/manim.animation.transform.MoveToTarget.pot index b375158de4..50a593be89 100644 --- a/docs/i18n/gettext/reference/manim.animation.transform.MoveToTarget.pot +++ b/docs/i18n/gettext/reference/manim.animation.transform.MoveToTarget.pot @@ -38,8 +38,4 @@ msgstr "" msgid "Attributes" msgstr "" -#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.MoveToTarget:0 -msgid "Parameters" -msgstr "" - diff --git a/docs/i18n/gettext/reference/manim.animation.transform.ReplacementTransform.pot b/docs/i18n/gettext/reference/manim.animation.transform.ReplacementTransform.pot index 428ecf85bb..707df6190e 100644 --- a/docs/i18n/gettext/reference/manim.animation.transform.ReplacementTransform.pot +++ b/docs/i18n/gettext/reference/manim.animation.transform.ReplacementTransform.pot @@ -38,10 +38,6 @@ msgstr "" msgid "Further keyword arguments that are passed to :class:`Transform`." msgstr "" -#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.ReplacementTransform:0 -msgid "Return type" -msgstr "" - #: ../../../manim/animation/transform.py:docstring of manim.animation.transform.ReplacementTransform:8 msgid "Examples" msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.transform.Restore.pot b/docs/i18n/gettext/reference/manim.animation.transform.Restore.pot index c79a64a83a..bb8983d573 100644 --- a/docs/i18n/gettext/reference/manim.animation.transform.Restore.pot +++ b/docs/i18n/gettext/reference/manim.animation.transform.Restore.pot @@ -38,8 +38,4 @@ msgstr "" msgid "Attributes" msgstr "" -#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.Restore:0 -msgid "Parameters" -msgstr "" - diff --git a/docs/i18n/gettext/reference/manim.animation.transform.ScaleInPlace.pot b/docs/i18n/gettext/reference/manim.animation.transform.ScaleInPlace.pot index a87c08d9a2..5fcf2fb7a8 100644 --- a/docs/i18n/gettext/reference/manim.animation.transform.ScaleInPlace.pot +++ b/docs/i18n/gettext/reference/manim.animation.transform.ScaleInPlace.pot @@ -34,8 +34,4 @@ msgstr "" msgid "Attributes" msgstr "" -#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.ScaleInPlace:0 -msgid "Parameters" -msgstr "" - diff --git a/docs/i18n/gettext/reference/manim.animation.transform.ShrinkToCenter.pot b/docs/i18n/gettext/reference/manim.animation.transform.ShrinkToCenter.pot index 704df9cf06..afb2b118db 100644 --- a/docs/i18n/gettext/reference/manim.animation.transform.ShrinkToCenter.pot +++ b/docs/i18n/gettext/reference/manim.animation.transform.ShrinkToCenter.pot @@ -34,8 +34,4 @@ msgstr "" msgid "Attributes" msgstr "" -#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.ShrinkToCenter:0 -msgid "Parameters" -msgstr "" - diff --git a/docs/i18n/gettext/reference/manim.animation.transform.Transform.pot b/docs/i18n/gettext/reference/manim.animation.transform.Transform.pot index e305a2c686..33af82e09b 100644 --- a/docs/i18n/gettext/reference/manim.animation.transform.Transform.pot +++ b/docs/i18n/gettext/reference/manim.animation.transform.Transform.pot @@ -18,6 +18,63 @@ msgstr "" msgid "Bases: :py:class:`manim.animation.animation.Animation`" msgstr "" +#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.Transform:1 +msgid "A Transform transforms a Mobject into a target Mobject." +msgstr "" + +#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.Transform:0 +#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.Transform.clean_up_from_scene:0 +msgid "Parameters" +msgstr "" + +#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.Transform:3 +msgid "The :class:`.Mobject` to be transformed. It will be mutated to become the ``target_mobject``." +msgstr "" + +#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.Transform:4 +msgid "The target of the transformation." +msgstr "" + +#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.Transform:5 +msgid "A function defining the path that the points of the ``mobject`` are being moved along until they match the points of the ``target_mobject``, see :mod:`.utils.paths`." +msgstr "" + +#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.Transform:7 +msgid "The arc angle (in radians) that the points of ``mobject`` will follow to reach the points of the target if using a circular path arc, see ``path_arc_centers``. See also :func:`manim.utils.paths.path_along_arc`." +msgstr "" + +#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.Transform:10 +msgid "The axis to rotate along if using a circular path arc, see ``path_arc_centers``." +msgstr "" + +#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.Transform:11 +msgid "The center of the circular arcs along which the points of ``mobject`` are moved by the transformation. If this is set and ``path_func`` is not set, then a ``path_along_circles`` path will be generated using the ``path_arc`` parameters and stored in ``path_func``. If ``path_func`` is set, this and the other ``path_arc`` fields are set as attributes, but a ``path_func`` is not generated from it." +msgstr "" + +#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.Transform:11 +msgid "The center of the circular arcs along which the points of ``mobject`` are moved by the transformation." +msgstr "" + +#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.Transform:14 +msgid "If this is set and ``path_func`` is not set, then a ``path_along_circles`` path will be generated using the ``path_arc`` parameters and stored in ``path_func``. If ``path_func`` is set, this and the other ``path_arc`` fields are set as attributes, but a ``path_func`` is not generated from it." +msgstr "" + +#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.Transform:17 +msgid "Controls which mobject is replaced when the transformation is complete. If set to True, ``mobject`` will be removed from the scene and ``target_mobject`` will replace it. Otherwise, ``target_mobject`` is never added and ``mobject`` just takes its shape." +msgstr "" + +#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.Transform:17 +msgid "Controls which mobject is replaced when the transformation is complete." +msgstr "" + +#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.Transform:19 +msgid "If set to True, ``mobject`` will be removed from the scene and ``target_mobject`` will replace it. Otherwise, ``target_mobject`` is never added and ``mobject`` just takes its shape." +msgstr "" + +#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.Transform:23 +msgid "Examples" +msgstr "" + #: ../../source/reference/manim.animation.transform.Transform.rst:14 msgid "Methods" msgstr "" @@ -41,22 +98,16 @@ msgstr "" msgid "Attributes" msgstr "" -#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.Transform:0 -#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.Transform.clean_up_from_scene:0 -msgid "Parameters" +#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.Transform.begin:3 +msgid "This method is called right as an animation is being played. As much initialization as possible, especially any mobject copying, should live in this method." msgstr "" -#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.Transform:0 #: ../../../manim/animation/transform.py:docstring of manim.animation.transform.Transform.begin:0 #: ../../../manim/animation/transform.py:docstring of manim.animation.transform.Transform.clean_up_from_scene:0 #: ../../../manim/animation/transform.py:docstring of manim.animation.transform.Transform.get_all_mobjects:0 msgid "Return type" msgstr "" -#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.Transform.begin:3 -msgid "This method is called right as an animation is being played. As much initialization as possible, especially any mobject copying, should live in this method." -msgstr "" - #: ../../../manim/animation/transform.py:docstring of manim.animation.transform.Transform.clean_up_from_scene:3 msgid "This includes to :meth:`~.Scene.remove` the Animation's :class:`~.Mobject` if the animation is a remover." msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.transform.TransformAnimations.pot b/docs/i18n/gettext/reference/manim.animation.transform.TransformAnimations.pot index be48e628a4..b753ae9f62 100644 --- a/docs/i18n/gettext/reference/manim.animation.transform.TransformAnimations.pot +++ b/docs/i18n/gettext/reference/manim.animation.transform.TransformAnimations.pot @@ -31,18 +31,16 @@ msgstr "" msgid "Attributes" msgstr "" -#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.TransformAnimations:0 -#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.TransformAnimations.interpolate:0 -msgid "Parameters" +#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.TransformAnimations.interpolate:3 +msgid "This method gets called for every frame during an animation." msgstr "" -#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.TransformAnimations:0 #: ../../../manim/animation/transform.py:docstring of manim.animation.transform.TransformAnimations.interpolate:0 -msgid "Return type" +msgid "Parameters" msgstr "" -#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.TransformAnimations.interpolate:3 -msgid "This method gets called for every frame during an animation." +#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.TransformAnimations.interpolate:5 +msgid "The relative time to set the animation to, 0 meaning the start, 1 meaning the end." msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.transform.TransformFromCopy.pot b/docs/i18n/gettext/reference/manim.animation.transform.TransformFromCopy.pot index c79f095c34..48930a5725 100644 --- a/docs/i18n/gettext/reference/manim.animation.transform.TransformFromCopy.pot +++ b/docs/i18n/gettext/reference/manim.animation.transform.TransformFromCopy.pot @@ -35,18 +35,16 @@ msgstr "" msgid "Attributes" msgstr "" -#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.TransformFromCopy:0 -#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.TransformFromCopy.interpolate:0 -msgid "Parameters" +#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.TransformFromCopy.interpolate:3 +msgid "This method gets called for every frame during an animation." msgstr "" -#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.TransformFromCopy:0 #: ../../../manim/animation/transform.py:docstring of manim.animation.transform.TransformFromCopy.interpolate:0 -msgid "Return type" +msgid "Parameters" msgstr "" -#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.TransformFromCopy.interpolate:3 -msgid "This method gets called for every frame during an animation." +#: ../../../manim/animation/transform.py:docstring of manim.animation.transform.TransformFromCopy.interpolate:5 +msgid "The relative time to set the animation to, 0 meaning the start, 1 meaning the end." msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.transform.pot b/docs/i18n/gettext/reference/manim.animation.transform.pot index 9956c62eb3..13575090ea 100644 --- a/docs/i18n/gettext/reference/manim.animation.transform.pot +++ b/docs/i18n/gettext/reference/manim.animation.transform.pot @@ -70,4 +70,8 @@ msgstr "" msgid "Animation that makes a mobject shrink to center." msgstr "" +#: ../../source/reference/manim.animation.transform.rst:60::1 +msgid "A Transform transforms a Mobject into a target Mobject." +msgstr "" + diff --git a/docs/i18n/gettext/reference/manim.animation.updaters.update.MaintainPositionRelativeTo.pot b/docs/i18n/gettext/reference/manim.animation.updaters.update.MaintainPositionRelativeTo.pot index 7d0930de33..348be8cd65 100644 --- a/docs/i18n/gettext/reference/manim.animation.updaters.update.MaintainPositionRelativeTo.pot +++ b/docs/i18n/gettext/reference/manim.animation.updaters.update.MaintainPositionRelativeTo.pot @@ -27,14 +27,12 @@ msgstr "" msgid "Interpolates the mobject of the :class:`Animation` based on alpha value." msgstr "" -#: ../../../manim/animation/updaters/update.py:docstring of manim.animation.updaters.update.MaintainPositionRelativeTo:0 #: ../../../manim/animation/updaters/update.py:docstring of manim.animation.updaters.update.MaintainPositionRelativeTo.interpolate_mobject:0 msgid "Parameters" msgstr "" -#: ../../../manim/animation/updaters/update.py:docstring of manim.animation.updaters.update.MaintainPositionRelativeTo:0 -#: ../../../manim/animation/updaters/update.py:docstring of manim.animation.updaters.update.MaintainPositionRelativeTo.interpolate_mobject:0 -msgid "Return type" +#: ../../../manim/animation/updaters/update.py:docstring of manim.animation.updaters.update.MaintainPositionRelativeTo.interpolate_mobject:3 +msgid "A float between 0 and 1 expressing the ratio to which the animation is completed. For example, alpha-values of 0, 0.5, and 1 correspond to the animation being completed 0%, 50%, and 100%, respectively." msgstr "" diff --git a/docs/i18n/gettext/reference/manim.animation.updaters.update.UpdateFromFunc.pot b/docs/i18n/gettext/reference/manim.animation.updaters.update.UpdateFromFunc.pot index bed3f29766..f976b33052 100644 --- a/docs/i18n/gettext/reference/manim.animation.updaters.update.UpdateFromFunc.pot +++ b/docs/i18n/gettext/reference/manim.animation.updaters.update.UpdateFromFunc.pot @@ -31,14 +31,12 @@ msgstr "" msgid "Interpolates the mobject of the :class:`Animation` based on alpha value." msgstr "" -#: ../../../manim/animation/updaters/update.py:docstring of manim.animation.updaters.update.UpdateFromFunc:0 #: ../../../manim/animation/updaters/update.py:docstring of manim.animation.updaters.update.UpdateFromFunc.interpolate_mobject:0 msgid "Parameters" msgstr "" -#: ../../../manim/animation/updaters/update.py:docstring of manim.animation.updaters.update.UpdateFromFunc:0 -#: ../../../manim/animation/updaters/update.py:docstring of manim.animation.updaters.update.UpdateFromFunc.interpolate_mobject:0 -msgid "Return type" +#: ../../../manim/animation/updaters/update.py:docstring of manim.animation.updaters.update.UpdateFromFunc.interpolate_mobject:3 +msgid "A float between 0 and 1 expressing the ratio to which the animation is completed. For example, alpha-values of 0, 0.5, and 1 correspond to the animation being completed 0%, 50%, and 100%, respectively." msgstr "" diff --git a/docs/i18n/gettext/reference/manim.camera.moving_camera.CameraFrame.pot b/docs/i18n/gettext/reference/manim.camera.moving_camera.CameraFrame.pot index 047c6e4cc2..8b13789179 100644 --- a/docs/i18n/gettext/reference/manim.camera.moving_camera.CameraFrame.pot +++ b/docs/i18n/gettext/reference/manim.camera.moving_camera.CameraFrame.pot @@ -1,45 +1 @@ -msgid "" -msgstr "" -"Project-Id-Version: Manim \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: ../../source/reference/manim.camera.moving_camera.CameraFrame.rst:2 -msgid "CameraFrame" -msgstr "" - -#: ../../source/reference/manim.camera.moving_camera.CameraFrame.rst:4 -msgid "Qualified name: ``manim.camera.moving\\_camera.CameraFrame``" -msgstr "" - -#: ../../../manim/camera/moving_camera.py:docstring of manim.camera.moving_camera.CameraFrame:1 -msgid "Bases: :py:class:`manim.mobject.types.vectorized_mobject.VGroup`" -msgstr "" - -#: ../../source/reference/manim.camera.moving_camera.CameraFrame.rst:14 -msgid "Methods" -msgstr "" - -#: ../../source/reference/manim.camera.moving_camera.CameraFrame.rst:21 -msgid "Attributes" -msgstr "" - -#: ../../source/reference/manim.camera.moving_camera.CameraFrame.rst:32::1 -msgid "Used to animate the application of any method of :code:`self`." -msgstr "" - -#: ../../source/reference/manim.camera.moving_camera.CameraFrame.rst:32::1 -msgid "The depth of the mobject." -msgstr "" - -#: ../../source/reference/manim.camera.moving_camera.CameraFrame.rst:32::1 -msgid "If there are multiple colors (for gradient) this returns the first one" -msgstr "" - -#: ../../source/reference/manim.camera.moving_camera.CameraFrame.rst:32::1 -msgid "The height of the mobject." -msgstr "" - - diff --git a/docs/i18n/gettext/reference/manim.camera.moving_camera.MovingCamera.pot b/docs/i18n/gettext/reference/manim.camera.moving_camera.MovingCamera.pot index 11d7cd810a..37e3cfc10d 100644 --- a/docs/i18n/gettext/reference/manim.camera.moving_camera.MovingCamera.pot +++ b/docs/i18n/gettext/reference/manim.camera.moving_camera.MovingCamera.pot @@ -90,6 +90,10 @@ msgstr "" msgid "If set to ``True``, only allows focusing on mobjects that are already in frame." msgstr "" +#: ../../../manim/camera/moving_camera.py:docstring of manim.camera.moving_camera.MovingCamera.auto_zoom:12 +msgid "If set to ``False``, applies the changes instead of returning the corresponding animation" +msgstr "" + #: ../../../manim/camera/moving_camera.py:docstring of manim.camera.moving_camera.MovingCamera.auto_zoom:0 #: ../../../manim/camera/moving_camera.py:docstring of manim.camera.moving_camera.MovingCamera.frame_center:0 #: ../../../manim/camera/moving_camera.py:docstring of manim.camera.moving_camera.MovingCamera.frame_height:0 @@ -97,8 +101,8 @@ msgstr "" msgid "Returns" msgstr "" -#: ../../../manim/camera/moving_camera.py:docstring of manim.camera.moving_camera.MovingCamera.auto_zoom:13 -msgid "Returns an animation that zooms the camera view to a given list of mobjects." +#: ../../../manim/camera/moving_camera.py:docstring of manim.camera.moving_camera.MovingCamera.auto_zoom:14 +msgid "_AnimationBuilder that zooms the camera view to a given list of mobjects or ScreenRectangle with position and size updated to zoomed position." msgstr "" #: ../../../manim/camera/moving_camera.py:docstring of manim.camera.moving_camera.MovingCamera.auto_zoom:0 diff --git a/docs/i18n/gettext/reference/manim.mobject.geometry.Arc.pot b/docs/i18n/gettext/reference/manim.mobject.geometry.arc.pot similarity index 100% rename from docs/i18n/gettext/reference/manim.mobject.geometry.Arc.pot rename to docs/i18n/gettext/reference/manim.mobject.geometry.arc.pot diff --git a/docs/i18n/gettext/reference/manim.mobject.geometry.line.Angle.pot b/docs/i18n/gettext/reference/manim.mobject.geometry.line.Angle.pot index 193feb1640..e62b85dd8c 100644 --- a/docs/i18n/gettext/reference/manim.mobject.geometry.line.Angle.pot +++ b/docs/i18n/gettext/reference/manim.mobject.geometry.line.Angle.pot @@ -23,6 +23,7 @@ msgid "A circular arc or elbow-type mobject representing an angle of two lines." msgstr "" #: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle:0 +#: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.from_three_points:0 #: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.get_value:0 msgid "Parameters" msgstr "" @@ -72,6 +73,7 @@ msgid "Further keyword arguments that are passed to the constructor of :class:`A msgstr "" #: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle:30 +#: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.from_three_points:15 #: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.get_lines:7 #: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.get_value:9 msgid "Examples" @@ -85,54 +87,85 @@ msgstr "" msgid "Methods" msgstr "" -#: ../../source/reference/manim.mobject.geometry.line.Angle.rst:21::1 +#: ../../source/reference/manim.mobject.geometry.line.Angle.rst:22::1 +#: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.from_three_points:1 +msgid "The angle between the lines AB and BC." +msgstr "" + +#: ../../source/reference/manim.mobject.geometry.line.Angle.rst:22::1 #: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.get_lines:1 msgid "Get the lines forming an angle of the :class:`Angle` class." msgstr "" -#: ../../source/reference/manim.mobject.geometry.line.Angle.rst:21::1 +#: ../../source/reference/manim.mobject.geometry.line.Angle.rst:22::1 #: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.get_value:1 msgid "Get the value of an angle of the :class:`Angle` class." msgstr "" -#: ../../source/reference/manim.mobject.geometry.line.Angle.rst:23 +#: ../../source/reference/manim.mobject.geometry.line.Angle.rst:24 msgid "Attributes" msgstr "" -#: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.get_lines:1::1 +#: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.from_three_points:1::1 msgid "Used to animate the application of any method of :code:`self`." msgstr "" -#: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.get_lines:1::1 +#: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.from_three_points:1::1 msgid "The depth of the mobject." msgstr "" -#: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.get_lines:1::1 +#: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.from_three_points:1::1 msgid "If there are multiple colors (for gradient) this returns the first one" msgstr "" -#: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.get_lines:1::1 +#: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.from_three_points:1::1 msgid "The height of the mobject." msgstr "" -#: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.get_lines:1::1 +#: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.from_three_points:1::1 msgid "The width of the mobject." msgstr "" +#: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.from_three_points:3 +msgid "This constructs the angle :math:`\\angle ABC`." +msgstr "" + +#: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.from_three_points:5 +msgid "The endpoint of the first angle leg" +msgstr "" + +#: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.from_three_points:6 +msgid "The vertex of the angle" +msgstr "" + +#: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.from_three_points:7 +msgid "The endpoint of the second angle leg" +msgstr "" + +#: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.from_three_points:8 +msgid "Further keyword arguments are passed to :class:`.Angle`" +msgstr "" + +#: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.from_three_points:0 #: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.get_lines:0 #: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.get_value:0 msgid "Returns" msgstr "" -#: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.get_lines:3 -msgid "A :class:`~.VGroup` containing the lines that form the angle of the :class:`Angle` class." +#: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.from_three_points:10 +msgid "Angle(line1, line2, radius=0.5, quadrant=(-1,1), stroke_width=8), Angle(line1, line2, radius=0.7, quadrant=(-1,-1), color=RED, other_angle=True)," msgstr "" +#: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.from_three_points:0 #: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.get_lines:0 #: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.get_value:0 msgid "Return type" msgstr "" +#: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.get_lines:3 +msgid "A :class:`~.VGroup` containing the lines that form the angle of the :class:`Angle` class." +msgstr "" + #: ../../../manim/mobject/geometry/line.py:docstring of manim.mobject.geometry.line.Angle.get_value:3 msgid "A boolean to decide the unit (deg/rad) in which the value of the angle is returned." msgstr "" diff --git a/docs/i18n/gettext/reference/manim.mobject.geometry.Line.pot b/docs/i18n/gettext/reference/manim.mobject.geometry.line.pot similarity index 100% rename from docs/i18n/gettext/reference/manim.mobject.geometry.Line.pot rename to docs/i18n/gettext/reference/manim.mobject.geometry.line.pot diff --git a/docs/i18n/gettext/reference/manim.mobject.geometry.Polygram.pot b/docs/i18n/gettext/reference/manim.mobject.geometry.polygram.pot similarity index 100% rename from docs/i18n/gettext/reference/manim.mobject.geometry.Polygram.pot rename to docs/i18n/gettext/reference/manim.mobject.geometry.polygram.pot diff --git a/docs/i18n/gettext/reference/manim.mobject.graph.Graph.pot b/docs/i18n/gettext/reference/manim.mobject.graph.Graph.pot index e144a57769..ded7c4d5b4 100644 --- a/docs/i18n/gettext/reference/manim.mobject.graph.Graph.pot +++ b/docs/i18n/gettext/reference/manim.mobject.graph.Graph.pot @@ -135,10 +135,14 @@ msgid "All vertices in your graph which are not listed in any of the partitions msgstr "" #: ../../../manim/mobject/graph.py:docstring of manim.mobject.graph.Graph:159 +msgid "The representation of a linear artificial neural network is facilitated by the use of the partite layout and defining partitions for each layer." +msgstr "" + +#: ../../../manim/mobject/graph.py:docstring of manim.mobject.graph.Graph:193 msgid "The custom tree layout can be used to show the graph by distance from the root vertex. You must pass the root vertex of the tree." msgstr "" -#: ../../../manim/mobject/graph.py:docstring of manim.mobject.graph.Graph:185 +#: ../../../manim/mobject/graph.py:docstring of manim.mobject.graph.Graph:219 msgid "The following code sample illustrates the use of the ``vertex_spacing`` layout parameter specific to the ``\"tree\"`` layout. As mentioned above, setting ``vertex_spacing`` overrides the specified value for ``layout_scale``, and as such it is harder to control the size of the mobject. However, we can adjust the captured frame and zoom out by using a :class:`.MovingCameraScene`::" msgstr "" diff --git a/docs/i18n/gettext/reference/manim.mobject.graphing.coordinate_systems.Axes.pot b/docs/i18n/gettext/reference/manim.mobject.graphing.coordinate_systems.Axes.pot index 994cd3f671..9eba72c307 100644 --- a/docs/i18n/gettext/reference/manim.mobject.graphing.coordinate_systems.Axes.pot +++ b/docs/i18n/gettext/reference/manim.mobject.graphing.coordinate_systems.Axes.pot @@ -66,9 +66,9 @@ msgid "Additional arguments to be passed to :class:`CoordinateSystem` and :class msgstr "" #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.Axes:14 -#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.Axes.coords_to_point:9 +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.Axes.coords_to_point:16 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.Axes.plot_line_graph:21 -#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.Axes.point_to_coords:9 +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.Axes.point_to_coords:11 msgid "Examples" msgstr "" @@ -120,10 +120,26 @@ msgstr "" msgid "The width of the mobject." msgstr "" +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.Axes.coords_to_point:3 +msgid "The coordinates. Each coord is passed as a separate argument: ``ax.coords_to_point(1, 2, 3)``. Also accepts a list of coordinates ``ax.coords_to_point( [x_0, x_1, ...], [y_0, y_1, ...], ... )`` ``ax.coords_to_point( [[x_0, y_0, z_0], [x_1, y_1, z_1]] )``" +msgstr "" + #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.Axes.coords_to_point:3 msgid "The coordinates. Each coord is passed as a separate argument: ``ax.coords_to_point(1, 2, 3)``." msgstr "" +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.Axes.coords_to_point:5 +msgid "Also accepts a list of coordinates" +msgstr "" + +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.Axes.coords_to_point:7 +msgid "``ax.coords_to_point( [x_0, x_1, ...], [y_0, y_1, ...], ... )``" +msgstr "" + +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.Axes.coords_to_point:9 +msgid "``ax.coords_to_point( [[x_0, y_0, z_0], [x_1, y_1, z_1]] )``" +msgstr "" + #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.Axes.coords_to_point:0 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.Axes.get_axes:0 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.Axes.plot_line_graph:0 @@ -131,8 +147,8 @@ msgstr "" msgid "Returns" msgstr "" -#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.Axes.coords_to_point:5 -msgid "A point with respect to the scene's coordinate system." +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.Axes.coords_to_point:11 +msgid "A point with respect to the scene's coordinate system. The shape of the array will be similar to the shape of the input." msgstr "" #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.Axes.coords_to_point:0 @@ -187,7 +203,7 @@ msgid "A VDict containing both the line and dots (if specified). The line can be msgstr "" #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.Axes.point_to_coords:3 -msgid "The point, i.e. ``RIGHT`` or ``[0, 1, 0]``." +msgid "The point, i.e. ``RIGHT`` or ``[0, 1, 0]``. Also accepts a list of points as ``[RIGHT, [0, 1, 0]]``." msgstr "" diff --git a/docs/i18n/gettext/reference/manim.mobject.graphing.coordinate_systems.CoordinateSystem.pot b/docs/i18n/gettext/reference/manim.mobject.graphing.coordinate_systems.CoordinateSystem.pot index f49f657bd0..b2f20b2dd5 100644 --- a/docs/i18n/gettext/reference/manim.mobject.graphing.coordinate_systems.CoordinateSystem.pot +++ b/docs/i18n/gettext/reference/manim.mobject.graphing.coordinate_systems.CoordinateSystem.pot @@ -19,7 +19,7 @@ msgid "Bases: :py:class:`object`" msgstr "" #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem:1 -msgid "Abstract class for Axes and NumberPlane" +msgid "Abstract base class for Axes and NumberPlane." msgstr "" #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem:4 @@ -27,7 +27,7 @@ msgstr "" #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.angle_of_tangent:12 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.get_T_label:17 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.get_area:16 -#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.get_axis_labels:15 +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.get_axis_labels:17 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.get_graph_label:16 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.get_horizontal_line:10 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.get_lines_to_point:14 @@ -39,11 +39,12 @@ msgstr "" #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.get_y_axis_label:12 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.input_to_graph_coords:5 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.input_to_graph_point:12 -#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot:16 -#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_antiderivative_graph:17 +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot:18 +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_antiderivative_graph:20 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_derivative_graph:11 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_implicit_curve:9 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_polar_graph:8 +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_surface:17 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.polar_to_point:10 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.slope_of_tangent:11 msgid "Examples" @@ -64,7 +65,7 @@ msgstr "" #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.add_coordinates:1::1 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.c2p:1 -msgid "Abbreviation for coords_to_point" +msgid "Abbreviation for :meth:`coords_to_point`" msgstr "" #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.add_coordinates:1::1 @@ -78,6 +79,7 @@ msgid "Returns a :class:`~.Polygon` representing the area under the graph passed msgstr "" #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.add_coordinates:1::1 +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.get_axis_labels:1 msgid "Defines labels for the x_axis and y_axis of the graph." msgstr "" @@ -158,7 +160,7 @@ msgstr "" #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.add_coordinates:1::1 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.p2c:1 -msgid "Abbreviation for point_to_coords" +msgid "Abbreviation for :meth:`point_to_coords`" msgstr "" #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.add_coordinates:1::1 @@ -181,11 +183,21 @@ msgstr "" msgid "Creates the curves of an implicit function." msgstr "" +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.add_coordinates:1::1 +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_parametric_curve:1 +msgid "A parametric curve." +msgstr "" + #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.add_coordinates:1::1 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_polar_graph:1 msgid "A polar graph." msgstr "" +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.add_coordinates:1::1 +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_surface:1 +msgid "Generates a surface based on a function." +msgstr "" + #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.add_coordinates:1::1 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.point_to_polar:1 msgid "Gets polar coordinates from a point." @@ -238,7 +250,9 @@ msgstr "" #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_antiderivative_graph:0 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_derivative_graph:0 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_implicit_curve:0 +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_parametric_curve:0 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_polar_graph:0 +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_surface:0 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.point_to_polar:0 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.polar_to_point:0 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.pr2pt:0 @@ -288,6 +302,7 @@ msgstr "" #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot:0 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_antiderivative_graph:0 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_derivative_graph:0 +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_surface:0 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.point_to_polar:0 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.polar_to_point:0 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.slope_of_tangent:0 @@ -321,7 +336,9 @@ msgstr "" #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_antiderivative_graph:0 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_derivative_graph:0 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_implicit_curve:0 +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_parametric_curve:0 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_polar_graph:0 +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_surface:0 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.point_to_polar:0 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.polar_to_point:0 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.pr2pt:0 @@ -403,23 +420,23 @@ msgstr "" msgid "When x_ranges do not match (either area x_range, graph's x_range or bounded_graph's x_range)." msgstr "" -#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.get_axis_labels:1 -msgid "Defines labels for the x_axis and y_axis of the graph. For increased control over the position of the labels, use :meth:`get_x_axis_label` and :meth:`get_y_axis_label`." +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.get_axis_labels:3 +msgid "For increased control over the position of the labels, use :meth:`get_x_axis_label` and :meth:`get_y_axis_label`." msgstr "" -#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.get_axis_labels:4 +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.get_axis_labels:6 msgid "The label for the x_axis. Defaults to :class:`~.MathTex` for ``str`` and ``float`` inputs." msgstr "" -#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.get_axis_labels:5 +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.get_axis_labels:7 msgid "The label for the y_axis. Defaults to :class:`~.MathTex` for ``str`` and ``float`` inputs." msgstr "" -#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.get_axis_labels:7 +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.get_axis_labels:9 msgid "A :class:`~.Vgroup` of the labels for the x_axis and y_axis." msgstr "" -#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.get_axis_labels:11 +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.get_axis_labels:13 msgid ":class:`get_x_axis_label` :class:`get_y_axis_label`" msgstr "" @@ -702,14 +719,18 @@ msgid "The range of the curve along the axes. ``x_range = [x_min, x_max, x_step] msgstr "" #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot:5 -msgid "Additional parameters to be passed to :class:`~.ParametricFunction`." +msgid "Whether to pass in the generated t value array to the function. Only use this if your function supports it. Output should be a numpy array of shape ``[y_0, y_1, ...]``" msgstr "" #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot:7 +msgid "Additional parameters to be passed to :class:`~.ParametricFunction`." +msgstr "" + +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot:9 msgid "The plotted curve." msgstr "" -#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot:11 +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot:13 msgid "This method may not produce accurate graphs since Manim currently relies on interpolation between evenly-spaced samples of the curve, instead of intelligent plotting. See the example below for some solutions to this problem." msgstr "" @@ -726,15 +747,19 @@ msgid "The number of points to take the area under the graph." msgstr "" #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_antiderivative_graph:6 +msgid "Whether to use the vectorized version of the antiderivative. This means to pass in the generated t value array to the function. Only use this if your function supports it. Output should be a numpy array of shape ``[y_0, y_1, ...]``" +msgstr "" + +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_antiderivative_graph:9 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_derivative_graph:5 msgid "Any valid keyword argument of :class:`~.ParametricFunction`." msgstr "" -#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_antiderivative_graph:8 +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_antiderivative_graph:11 msgid "The curve of the antiderivative." msgstr "" -#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_antiderivative_graph:12 +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_antiderivative_graph:15 msgid "This graph is plotted from the values of area under the reference graph. The result might not be ideal if the reference graph contains uncalculatable areas from x=0." msgstr "" @@ -766,6 +791,22 @@ msgstr "" msgid "Additional parameters to pass into :class:`ImplicitFunction`." msgstr "" +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_parametric_curve:3 +msgid "A parametric function mapping a number to a point in the coordinate system." +msgstr "" + +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_parametric_curve:5 +msgid "Whether to pass in the generated t value array to the function. Only use this if your function supports it." +msgstr "" + +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_parametric_curve:6 +msgid "Any further keyword arguments are passed to :class:`.ParametricFunction`." +msgstr "" + +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_parametric_curve:9 +msgid "Example" +msgstr "" + #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_polar_graph:3 msgid "The function r of theta." msgstr "" @@ -778,6 +819,34 @@ msgstr "" msgid "Additional parameters passed to :class:`~.ParametricFunction`." msgstr "" +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_surface:3 +msgid "The function used to construct the :class:`~.Surface`." +msgstr "" + +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_surface:4 +msgid "The range of the ``u`` variable: ``(u_min, u_max)``." +msgstr "" + +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_surface:5 +msgid "The range of the ``v`` variable: ``(v_min, v_max)``." +msgstr "" + +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_surface:6 +msgid "Colors of the surface. Passing a list of colors will color the surface by z-value. Passing a list of tuples in the form ``(color, pivot)`` allows user-defined pivots where the color transitions." +msgstr "" + +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_surface:9 +msgid "Defines the axis on which the colorscale is applied (0 = x, 1 = y, 2 = z), default is z-axis (2)." +msgstr "" + +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_surface:11 +msgid "Additional parameters to be passed to :class:`~.Surface`." +msgstr "" + +#: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.plot_surface:13 +msgid "The plotted surface." +msgstr "" + #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.point_to_polar:3 #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.CoordinateSystem.polar_to_point:6 msgid "The point." diff --git a/docs/i18n/gettext/reference/manim.mobject.graphing.coordinate_systems.NumberPlane.pot b/docs/i18n/gettext/reference/manim.mobject.graphing.coordinate_systems.NumberPlane.pot index 0b2f123e73..e31a3beee6 100644 --- a/docs/i18n/gettext/reference/manim.mobject.graphing.coordinate_systems.NumberPlane.pot +++ b/docs/i18n/gettext/reference/manim.mobject.graphing.coordinate_systems.NumberPlane.pot @@ -63,7 +63,7 @@ msgid "Additional arguments to be passed to :class:`Axes`." msgstr "" #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.NumberPlane:14 -msgid "If :attr:`x_length` or :attr:`y_length` are not defined, the plane automatically adjusts its lengths based on the :attr:`x_range` and :attr:`y_range` values to set the ``unit_size`` to 1." +msgid "If :attr:`x_length` or :attr:`y_length` are not defined, they are automatically calculated such that one unit on each axis is one Manim unit long." msgstr "" #: ../../../manim/mobject/graphing/coordinate_systems.py:docstring of manim.mobject.graphing.coordinate_systems.NumberPlane:18 diff --git a/docs/i18n/gettext/reference/manim.mobject.graphing.coordinate_systems.pot b/docs/i18n/gettext/reference/manim.mobject.graphing.coordinate_systems.pot index 4ca16af714..dff35f65a2 100644 --- a/docs/i18n/gettext/reference/manim.mobject.graphing.coordinate_systems.pot +++ b/docs/i18n/gettext/reference/manim.mobject.graphing.coordinate_systems.pot @@ -27,7 +27,7 @@ msgid "A :class:`~.NumberPlane` specialized for use with complex numbers." msgstr "" #: ../../source/reference/manim.mobject.graphing.coordinate_systems.rst:30::1 -msgid "Abstract class for Axes and NumberPlane" +msgid "Abstract base class for Axes and NumberPlane." msgstr "" #: ../../source/reference/manim.mobject.graphing.coordinate_systems.rst:30::1 diff --git a/docs/i18n/gettext/reference/manim.mobject.graphing.functions.ParametricFunction.pot b/docs/i18n/gettext/reference/manim.mobject.graphing.functions.ParametricFunction.pot index bbf76c1e1a..7548f5c5af 100644 --- a/docs/i18n/gettext/reference/manim.mobject.graphing.functions.ParametricFunction.pot +++ b/docs/i18n/gettext/reference/manim.mobject.graphing.functions.ParametricFunction.pot @@ -43,18 +43,22 @@ msgid "Whether to interpolate between the points of the function after they have msgstr "" #: ../../../manim/mobject/graphing/functions.py:docstring of manim.mobject.graphing.functions.ParametricFunction:8 +msgid "Whether to pass in the generated t value array to the function as ``[t_0, t_1, ...]``. Only use this if your function supports it. Output should be a numpy array of shape ``[[x_0, x_1, ...], [y_0, y_1, ...], [z_0, z_1, ...]]`` but ``z`` can also be 0 if the Axes is 2D" +msgstr "" + +#: ../../../manim/mobject/graphing/functions.py:docstring of manim.mobject.graphing.functions.ParametricFunction:12 msgid "Values of t at which the function experiences discontinuity." msgstr "" -#: ../../../manim/mobject/graphing/functions.py:docstring of manim.mobject.graphing.functions.ParametricFunction:9 +#: ../../../manim/mobject/graphing/functions.py:docstring of manim.mobject.graphing.functions.ParametricFunction:13 msgid "The left and right tolerance for the discontinuities." msgstr "" -#: ../../../manim/mobject/graphing/functions.py:docstring of manim.mobject.graphing.functions.ParametricFunction:12 +#: ../../../manim/mobject/graphing/functions.py:docstring of manim.mobject.graphing.functions.ParametricFunction:16 msgid "Examples" msgstr "" -#: ../../../manim/mobject/graphing/functions.py:docstring of manim.mobject.graphing.functions.ParametricFunction:42 +#: ../../../manim/mobject/graphing/functions.py:docstring of manim.mobject.graphing.functions.ParametricFunction:46 msgid "If your function has discontinuities, you'll have to specify the location of the discontinuities manually. See the following example for guidance." msgstr "" diff --git a/docs/i18n/gettext/reference/manim.mobject.graphing.number_line.NumberLine.pot b/docs/i18n/gettext/reference/manim.mobject.graphing.number_line.NumberLine.pot index 9544f8bf5b..42be00957c 100644 --- a/docs/i18n/gettext/reference/manim.mobject.graphing.number_line.NumberLine.pot +++ b/docs/i18n/gettext/reference/manim.mobject.graphing.number_line.NumberLine.pot @@ -127,6 +127,8 @@ msgid "Number ranges that include both negative and positive values will be gene msgstr "" #: ../../../manim/mobject/graphing/number_line.py:docstring of manim.mobject.graphing.number_line.NumberLine:34 +#: ../../../manim/mobject/graphing/number_line.py:docstring of manim.mobject.graphing.number_line.NumberLine.number_to_point:10 +#: ../../../manim/mobject/graphing/number_line.py:docstring of manim.mobject.graphing.number_line.NumberLine.point_to_number:10 msgid "Examples" msgstr "" @@ -308,11 +310,11 @@ msgid "A numpy array of floats represnting values along the number line." msgstr "" #: ../../../manim/mobject/graphing/number_line.py:docstring of manim.mobject.graphing.number_line.NumberLine.number_to_point:4 -msgid "The value to be transformed into a coordinate." +msgid "The value to be transformed into a coordinate. Or a list of values." msgstr "" #: ../../../manim/mobject/graphing/number_line.py:docstring of manim.mobject.graphing.number_line.NumberLine.number_to_point:6 -msgid "A point with respect to the scene's coordinate system." +msgid "A point with respect to the scene's coordinate system. Or a list of points." msgstr "" #: ../../../manim/mobject/graphing/number_line.py:docstring of manim.mobject.graphing.number_line.NumberLine.point_to_number:4 diff --git a/docs/i18n/gettext/reference/manim.mobject.graphing.probability.BarChart.pot b/docs/i18n/gettext/reference/manim.mobject.graphing.probability.BarChart.pot index 9fa6bfdcc6..18f5e0e4c1 100644 --- a/docs/i18n/gettext/reference/manim.mobject.graphing.probability.BarChart.pot +++ b/docs/i18n/gettext/reference/manim.mobject.graphing.probability.BarChart.pot @@ -29,11 +29,11 @@ msgid "Parameters" msgstr "" #: ../../../manim/mobject/graphing/probability.py:docstring of manim.mobject.graphing.probability.BarChart:5 -msgid "An iterable of values that determines the height of each bar. Accepts negative values." +msgid "A sequence of values that determines the height of each bar. Accepts negative values." msgstr "" #: ../../../manim/mobject/graphing/probability.py:docstring of manim.mobject.graphing.probability.BarChart:6 -msgid "An iterable of names for each bar. Does not have to match the length of ``values``." +msgid "A sequence of names for each bar. Does not have to match the length of ``values``." msgstr "" #: ../../../manim/mobject/graphing/probability.py:docstring of manim.mobject.graphing.probability.BarChart:7 @@ -49,7 +49,7 @@ msgid "The length of the y-axis." msgstr "" #: ../../../manim/mobject/graphing/probability.py:docstring of manim.mobject.graphing.probability.BarChart:12 -msgid "The color for the bars. Accepts a single color or an iterable of colors. If the length of``bar_colors`` does not match that of ``values``, intermediate colors will be automatically determined." +msgid "The color for the bars. Accepts a sequence of colors (can contain just one item). If the length of``bar_colors`` does not match that of ``values``, intermediate colors will be automatically determined." msgstr "" #: ../../../manim/mobject/graphing/probability.py:docstring of manim.mobject.graphing.probability.BarChart:15 @@ -65,7 +65,7 @@ msgid "The stroke width of the bars." msgstr "" #: ../../../manim/mobject/graphing/probability.py:docstring of manim.mobject.graphing.probability.BarChart:20 -#: ../../../manim/mobject/graphing/probability.py:docstring of manim.mobject.graphing.probability.BarChart.change_bar_values:7 +#: ../../../manim/mobject/graphing/probability.py:docstring of manim.mobject.graphing.probability.BarChart.change_bar_values:8 #: ../../../manim/mobject/graphing/probability.py:docstring of manim.mobject.graphing.probability.BarChart.get_bar_labels:10 msgid "Examples" msgstr "" @@ -111,6 +111,10 @@ msgstr "" msgid "The values that will be used to update the height of the bars. Does not have to match the number of bars." msgstr "" +#: ../../../manim/mobject/graphing/probability.py:docstring of manim.mobject.graphing.probability.BarChart.change_bar_values:5 +msgid "Whether to re-initalize the colors of the bars based on ``self.bar_colors``." +msgstr "" + #: ../../../manim/mobject/graphing/probability.py:docstring of manim.mobject.graphing.probability.BarChart.get_bar_labels:1 msgid "Annotates each bar with its corresponding value. Use ``self.bar_labels`` to access the labels after creation." msgstr "" diff --git a/docs/i18n/gettext/reference/manim.mobject.matrix.Matrix.pot b/docs/i18n/gettext/reference/manim.mobject.matrix.Matrix.pot index a81b5c3354..996df14df3 100644 --- a/docs/i18n/gettext/reference/manim.mobject.matrix.Matrix.pot +++ b/docs/i18n/gettext/reference/manim.mobject.matrix.Matrix.pot @@ -91,6 +91,10 @@ msgid "The right bracket type, by default ``\"]\"``." msgstr "" #: ../../../manim/mobject/matrix.py:docstring of manim.mobject.matrix.Matrix:69 +msgid "``True`` if should stretch the brackets to fit the height of matrix contents, by default ``True``." +msgstr "" + +#: ../../../manim/mobject/matrix.py:docstring of manim.mobject.matrix.Matrix:70 msgid "Additional arguments to be passed to :class:`~.MathTex` when constructing the brackets." msgstr "" diff --git a/docs/i18n/gettext/reference/manim.mobject.matrix.MobjectMatrix.pot b/docs/i18n/gettext/reference/manim.mobject.matrix.MobjectMatrix.pot index 4c402dd5bd..e7a29ce27b 100644 --- a/docs/i18n/gettext/reference/manim.mobject.matrix.MobjectMatrix.pot +++ b/docs/i18n/gettext/reference/manim.mobject.matrix.MobjectMatrix.pot @@ -79,6 +79,10 @@ msgid "The right bracket type, by default ``\"]\"``." msgstr "" #: ../../../manim/mobject/matrix.py:docstring of manim.mobject.matrix.MobjectMatrix:30 +msgid "``True`` if should stretch the brackets to fit the height of matrix contents, by default ``True``." +msgstr "" + +#: ../../../manim/mobject/matrix.py:docstring of manim.mobject.matrix.MobjectMatrix:31 msgid "Additional arguments to be passed to :class:`~.MathTex` when constructing the brackets." msgstr "" diff --git a/docs/i18n/gettext/reference/manim.mobject.mobject.Group.pot b/docs/i18n/gettext/reference/manim.mobject.mobject.Group.pot index 5e44eb075d..f22c37b286 100644 --- a/docs/i18n/gettext/reference/manim.mobject.mobject.Group.pot +++ b/docs/i18n/gettext/reference/manim.mobject.mobject.Group.pot @@ -22,6 +22,14 @@ msgstr "" msgid "Groups together multiple :class:`Mobjects <.Mobject>`." msgstr "" +#: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Group:4 +msgid "Notes" +msgstr "" + +#: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Group:5 +msgid "When adding the same mobject more than once, repetitions are ignored. Use :meth:`.Mobject.copy` to create a separate copy which can then be added to the group." +msgstr "" + #: ../../source/reference/manim.mobject.mobject.Group.rst:14 msgid "Methods" msgstr "" diff --git a/docs/i18n/gettext/reference/manim.mobject.mobject.Mobject.pot b/docs/i18n/gettext/reference/manim.mobject.mobject.Mobject.pot index 0b80228c7d..c1b1b0e014 100644 --- a/docs/i18n/gettext/reference/manim.mobject.mobject.Mobject.pot +++ b/docs/i18n/gettext/reference/manim.mobject.mobject.Mobject.pot @@ -47,469 +47,474 @@ msgstr "" msgid "Methods" msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.add:1 msgid "Add mobjects as submobjects." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.add_animation_override:1 msgid "Add an animation override." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.add_background_rectangle:1 msgid "Add a BackgroundRectangle as submobject." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.add_to_back:1 msgid "Add all passed mobjects to the back of the submobjects." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.add_updater:1 msgid "Add an update function to this mobject." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.align_data:1 msgid "Aligns the data of this mobject with another mobject." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.align_on_border:1 msgid "Direction just needs to be a vector pointing towards side or corner in the 2d plane." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.align_to:1 msgid "Aligns mobject to another :class:`~.Mobject` in a certain direction." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.animation_override_for:1 msgid "Returns the function defining a specific animation override for this class." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 msgid "Applies a complex function to a :class:`Mobject`." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.apply_to_family:1 msgid "Apply a function to ``self`` and every submobject with points recursively." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.arrange:1 msgid "Sorts :class:`~.Mobject` next to each other on screen." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.arrange_in_grid:1 msgid "Arrange submobjects in a grid." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.arrange_submobjects:1 msgid "Arrange the position of :attr:`submobjects` with a small buffer." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.become:1 msgid "Edit points, colors and submobjects to be identical to another :class:`~.Mobject`" msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.clear_updaters:1 msgid "Remove every updater." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.copy:1 msgid "Create and return an identical copy of the :class:`Mobject` including all :attr:`submobjects`." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.flip:1 msgid "Flips/Mirrors an mobject about its center." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.generate_points:1 msgid "Initializes :attr:`points` and therefore the shape." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.get_bottom:1 msgid "Get bottom coordinates of a box bounding the :class:`~.Mobject`" msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.get_center:1 msgid "Get center coordinates" msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.get_color:1 msgid "Returns the color of the :class:`~.Mobject`" msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.get_coord:1 msgid "Meant to generalize ``get_x``, ``get_y`` and ``get_z``" msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.get_corner:1 msgid "Get corner coordinates for certain direction." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 msgid "Picture a box bounding the :class:`~.Mobject`." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.get_edge_center:1 msgid "Get edge coordinates for certain direction." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.get_end:1 msgid "Returns the point, where the stroke that surrounds the :class:`~.Mobject` ends." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.get_left:1 msgid "Get left coordinates of a box bounding the :class:`~.Mobject`" msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.get_midpoint:1 msgid "Get coordinates of the middle of the path that forms the :class:`~.Mobject`." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.get_nadir:1 msgid "Get nadir (opposite the zenith) coordinates of a box bounding a 3D :class:`~.Mobject`." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 msgid "The simplest :class:`~.Mobject` to be transformed to or from self." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.get_right:1 msgid "Get right coordinates of a box bounding the :class:`~.Mobject`" msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.get_start:1 msgid "Returns the point, where the stroke that surrounds the :class:`~.Mobject` starts." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.get_start_and_end:1 msgid "Returns starting and ending point of a stroke as a ``tuple``." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.get_time_based_updaters:1 msgid "Return all updaters using the ``dt`` parameter." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.get_top:1 msgid "Get top coordinates of a box bounding the :class:`~.Mobject`" msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.get_updaters:1 msgid "Return all updaters." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.get_x:1 msgid "Returns x coordinate of the center of the :class:`~.Mobject` as ``float``" msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.get_y:1 msgid "Returns y coordinate of the center of the :class:`~.Mobject` as ``float``" msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.get_z:1 msgid "Returns z coordinate of the center of the :class:`~.Mobject` as ``float``" msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.get_zenith:1 msgid "Get zenith coordinates of a box bounding a 3D :class:`~.Mobject`." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.has_no_points:1 msgid "Check if :class:`~.Mobject` *does not* contains points." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.has_points:1 msgid "Check if :class:`~.Mobject` contains points." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.has_time_based_updater:1 msgid "Test if ``self`` has a time based updater." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.init_colors:1 msgid "Initializes the colors." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 +#: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.insert:1 +msgid "Inserts a mobject at a specific position into self.submobjects" +msgstr "" + +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.interpolate:1 msgid "Turns this :class:`~.Mobject` into an interpolation between ``mobject1`` and ``mobject2``." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.invert:1 msgid "Inverts the list of :attr:`submobjects`." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.length_over_dim:1 msgid "Measure the length of an :class:`~.Mobject` in a certain direction." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.match_color:1 msgid "Match the color with the color of another :class:`~.Mobject`." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.match_coord:1 msgid "Match the coordinates with the coordinates of another :class:`~.Mobject`." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.match_depth:1 msgid "Match the depth with the depth of another :class:`~.Mobject`." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.match_dim_size:1 msgid "Match the specified dimension with the dimension of another :class:`~.Mobject`." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.match_height:1 msgid "Match the height with the height of another :class:`~.Mobject`." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.match_points:1 msgid "Edit points, positions, and submobjects to be identical to another :class:`~.Mobject`, while keeping the style unchanged." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.match_updaters:1 msgid "Match the updaters of the given mobject." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.match_width:1 msgid "Match the width with the width of another :class:`~.Mobject`." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 msgid "Match x coord." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 msgid "Match y coord." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 msgid "Match z coord." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.move_to:1 msgid "Move center of the :class:`~.Mobject` to certain coordinate." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.next_to:1 msgid "Move this :class:`~.Mobject` next to another's :class:`~.Mobject` or coordinate." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.null_point_align:1 msgid "If a :class:`~.Mobject` with points is being aligned to one without, treat both as groups, and push the one with points into its own submobjects list." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.remove:1 msgid "Remove :attr:`submobjects`." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.remove_updater:1 msgid "Remove an updater." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.repeat:1 msgid "This can make transition animations nicer" msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.reset_points:1 msgid "Sets :attr:`points` to be an empty array." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.restore:1 msgid "Restores the state that was previously saved with :meth:`~.Mobject.save_state`." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.resume_updating:1 msgid "Enable updating from updaters and animations." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.rotate:1 msgid "Rotates the :class:`~.Mobject` about a certain point." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.rotate_about_origin:1 msgid "Rotates the :class:`~.Mobject` about the ORIGIN, which is at [0,0,0]." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.save_image:1 msgid "Saves an image of only this :class:`Mobject` at its position to a png file." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 msgid "Save the current state (position, color & size)." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.scale:1 msgid "Scale the size by a factor." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.scale_to_fit_depth:1 msgid "Scales the :class:`~.Mobject` to fit a depth while keeping width/height proportional." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.scale_to_fit_height:1 msgid "Scales the :class:`~.Mobject` to fit a height while keeping width/depth proportional." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.scale_to_fit_width:1 msgid "Scales the :class:`~.Mobject` to fit a width while keeping height/depth proportional." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.set:1 msgid "Sets attributes." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 msgid "Condition is function which takes in one arguments, (x, y, z)." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.set_default:1 msgid "Sets the default values of keyword arguments." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.set_x:1 msgid "Set x value of the center of the :class:`~.Mobject` (``int`` or ``float``)" msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.set_y:1 msgid "Set y value of the center of the :class:`~.Mobject` (``int`` or ``float``)" msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.set_z:1 msgid "Set z value of the center of the :class:`~.Mobject` (``int`` or ``float``)" msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.set_z_index:1 msgid "Sets the :class:`~.Mobject`'s :attr:`z_index` to the value specified in `z_index_value`." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.set_z_index_by_z_coordinate:1 msgid "Sets the :class:`~.Mobject`'s z coordinate to the value of :attr:`z_index`." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.shift:1 msgid "Shift by the given vectors." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.shuffle:1 msgid "Shuffles the list of :attr:`submobjects`." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.shuffle_submobjects:1 msgid "Shuffles the order of :attr:`submobjects`" msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.sort:1 msgid "Sorts the list of :attr:`submobjects` by a function defined by ``submob_func``." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.sort_submobjects:1 msgid "Sort the :attr:`submobjects`" msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.stretch_to_fit_depth:1 msgid "Stretches the :class:`~.Mobject` to fit a depth, not keeping width/height proportional." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.stretch_to_fit_height:1 msgid "Stretches the :class:`~.Mobject` to fit a height, not keeping width/depth proportional." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.stretch_to_fit_width:1 msgid "Stretches the :class:`~.Mobject` to fit a width, not keeping height/depth proportional." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.suspend_updating:1 msgid "Disable updating from updaters and animations." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:174::1 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:175::1 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.update:1 msgid "Apply all updaters." msgstr "" -#: ../../source/reference/manim.mobject.mobject.Mobject.rst:176 +#: ../../source/reference/manim.mobject.mobject.Mobject.rst:177 msgid "Attributes" msgstr "" @@ -556,6 +561,7 @@ msgstr "" #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.become:0 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.clear_updaters:0 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.copy:0 +#: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.insert:0 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.invert:0 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.match_color:0 #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.match_coord:0 @@ -757,6 +763,10 @@ msgstr "" msgid "Adding an object to itself raises an error::" msgstr "" +#: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.add:45 +msgid "A given mobject cannot be added as a submobject twice to some parent::" +msgstr "" + #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.add_animation_override:3 msgid "This does not apply to subclasses." msgstr "" @@ -1019,6 +1029,22 @@ msgstr "" msgid "`bool`" msgstr "" +#: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.insert:3 +msgid "Effectively just calls ``self.submobjects.insert(index, mobject)``, where ``self.submobjects`` is a list." +msgstr "" + +#: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.insert:6 +msgid "Highly adapted from ``Mobject.add``." +msgstr "" + +#: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.insert:8 +msgid "The index at which" +msgstr "" + +#: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.insert:9 +msgid "The mobject to be inserted." +msgstr "" + #: ../../../manim/mobject/mobject.py:docstring of manim.mobject.mobject.Mobject.invert:3 msgid "If ``True``, all submobject lists of this mobject's family are inverted." msgstr "" diff --git a/docs/i18n/gettext/reference/manim.mobject.table.DecimalTable.pot b/docs/i18n/gettext/reference/manim.mobject.table.DecimalTable.pot index 24ccb3a5b0..6f0eeeb40e 100644 --- a/docs/i18n/gettext/reference/manim.mobject.table.DecimalTable.pot +++ b/docs/i18n/gettext/reference/manim.mobject.table.DecimalTable.pot @@ -19,7 +19,7 @@ msgid "Bases: :py:class:`manim.mobject.table.Table`" msgstr "" #: ../../../manim/mobject/table.py:docstring of manim.mobject.table.DecimalTable:1 -msgid "A specialized :class:`~.Table` mobject for use with with :class:`~.DecimalNumber` to display decimal entries." +msgid "A specialized :class:`~.Table` mobject for use with :class:`~.DecimalNumber` to display decimal entries." msgstr "" #: ../../../manim/mobject/table.py:docstring of manim.mobject.table.DecimalTable:4 diff --git a/docs/i18n/gettext/reference/manim.mobject.table.IntegerTable.pot b/docs/i18n/gettext/reference/manim.mobject.table.IntegerTable.pot index ba3128a7c6..b90d65c359 100644 --- a/docs/i18n/gettext/reference/manim.mobject.table.IntegerTable.pot +++ b/docs/i18n/gettext/reference/manim.mobject.table.IntegerTable.pot @@ -19,7 +19,7 @@ msgid "Bases: :py:class:`manim.mobject.table.Table`" msgstr "" #: ../../../manim/mobject/table.py:docstring of manim.mobject.table.IntegerTable:1 -msgid "A specialized :class:`~.Table` mobject for use with with :class:`~.Integer`." +msgid "A specialized :class:`~.Table` mobject for use with :class:`~.Integer`." msgstr "" #: ../../../manim/mobject/table.py:docstring of manim.mobject.table.IntegerTable:4 diff --git a/docs/i18n/gettext/reference/manim.mobject.table.MathTable.pot b/docs/i18n/gettext/reference/manim.mobject.table.MathTable.pot index 27388822b6..f13ff50680 100644 --- a/docs/i18n/gettext/reference/manim.mobject.table.MathTable.pot +++ b/docs/i18n/gettext/reference/manim.mobject.table.MathTable.pot @@ -19,7 +19,7 @@ msgid "Bases: :py:class:`manim.mobject.table.Table`" msgstr "" #: ../../../manim/mobject/table.py:docstring of manim.mobject.table.MathTable:1 -msgid "A specialized :class:`~.Table` mobject for use with with LaTeX." +msgid "A specialized :class:`~.Table` mobject for use with LaTeX." msgstr "" #: ../../../manim/mobject/table.py:docstring of manim.mobject.table.MathTable:4 diff --git a/docs/i18n/gettext/reference/manim.mobject.table.MobjectTable.pot b/docs/i18n/gettext/reference/manim.mobject.table.MobjectTable.pot index 834b89fbcd..32b21bfc5a 100644 --- a/docs/i18n/gettext/reference/manim.mobject.table.MobjectTable.pot +++ b/docs/i18n/gettext/reference/manim.mobject.table.MobjectTable.pot @@ -19,7 +19,7 @@ msgid "Bases: :py:class:`manim.mobject.table.Table`" msgstr "" #: ../../../manim/mobject/table.py:docstring of manim.mobject.table.MobjectTable:1 -msgid "A specialized :class:`~.Table` mobject for use with with :class:`~.Mobject`." +msgid "A specialized :class:`~.Table` mobject for use with :class:`~.Mobject`." msgstr "" #: ../../../manim/mobject/table.py:docstring of manim.mobject.table.MobjectTable:4 diff --git a/docs/i18n/gettext/reference/manim.mobject.table.pot b/docs/i18n/gettext/reference/manim.mobject.table.pot index fffec1c1a4..9dbab0b358 100644 --- a/docs/i18n/gettext/reference/manim.mobject.table.pot +++ b/docs/i18n/gettext/reference/manim.mobject.table.pot @@ -23,19 +23,19 @@ msgid "Classes" msgstr "" #: ../../source/reference/manim.mobject.table.rst:28::1 -msgid "A specialized :class:`~.Table` mobject for use with with :class:`~.DecimalNumber` to display decimal entries." +msgid "A specialized :class:`~.Table` mobject for use with :class:`~.DecimalNumber` to display decimal entries." msgstr "" #: ../../source/reference/manim.mobject.table.rst:28::1 -msgid "A specialized :class:`~.Table` mobject for use with with :class:`~.Integer`." +msgid "A specialized :class:`~.Table` mobject for use with :class:`~.Integer`." msgstr "" #: ../../source/reference/manim.mobject.table.rst:28::1 -msgid "A specialized :class:`~.Table` mobject for use with with LaTeX." +msgid "A specialized :class:`~.Table` mobject for use with LaTeX." msgstr "" #: ../../source/reference/manim.mobject.table.rst:28::1 -msgid "A specialized :class:`~.Table` mobject for use with with :class:`~.Mobject`." +msgid "A specialized :class:`~.Table` mobject for use with :class:`~.Mobject`." msgstr "" diff --git a/docs/i18n/gettext/reference/manim.mobject.text.text_mobject.MarkupText.pot b/docs/i18n/gettext/reference/manim.mobject.text.text_mobject.MarkupText.pot index 30fc0bd4fb..66bb467eb4 100644 --- a/docs/i18n/gettext/reference/manim.mobject.text.text_mobject.MarkupText.pot +++ b/docs/i18n/gettext/reference/manim.mobject.text.text_mobject.MarkupText.pot @@ -147,7 +147,7 @@ msgid "Escaping of special characters: ``>`` **should** be written as ``>`` w msgstr "" #: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.MarkupText:103 -msgid "You can find more information about Pango markup formatting at the corresponding documentation page: `Pango Markup `_. Please be aware that not all features are supported by this class and that the ```` tag mentioned above is not supported by Pango." +msgid "You can find more information about Pango markup formatting at the corresponding documentation page: `Pango Markup `_. Please be aware that not all features are supported by this class and that the ```` tag mentioned above is not supported by Pango." msgstr "" #: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.MarkupText:0 @@ -155,38 +155,38 @@ msgid "Parameters" msgstr "" #: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.MarkupText:109 -msgid "The text that need to created as mobject." +msgid "The text that needs to be created as mobject." msgstr "" -#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.MarkupText:111 -msgid "The fill opacity with 1 meaning opaque and 0 meaning transparent." +#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.MarkupText:110 +msgid "The fill opacity, with 1 meaning opaque and 0 meaning transparent." msgstr "" -#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.MarkupText:113 +#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.MarkupText:111 msgid "Stroke width." msgstr "" -#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.MarkupText:115 +#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.MarkupText:112 msgid "Font size." msgstr "" -#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.MarkupText:117 +#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.MarkupText:113 msgid "Line spacing." msgstr "" -#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.MarkupText:119 +#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.MarkupText:114 msgid "Global font setting for the entire text. Local overrides are possible." msgstr "" -#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.MarkupText:121 +#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.MarkupText:115 msgid "Global slant setting, e.g. `NORMAL` or `ITALIC`. Local overrides are possible." msgstr "" -#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.MarkupText:123 +#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.MarkupText:116 msgid "Global weight setting, e.g. `NORMAL` or `BOLD`. Local overrides are possible." msgstr "" -#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.MarkupText:125 +#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.MarkupText:117 msgid "Global gradient setting. Local overrides are possible." msgstr "" @@ -194,7 +194,7 @@ msgstr "" msgid "Returns" msgstr "" -#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.MarkupText:128 +#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.MarkupText:119 msgid "The text displayed in form of a :class:`.VGroup`-like mobject." msgstr "" @@ -202,23 +202,23 @@ msgstr "" msgid "Return type" msgstr "" -#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.MarkupText:132 +#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.MarkupText:123 msgid "Examples" msgstr "" -#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.MarkupText:233 +#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.MarkupText:224 msgid "As :class:`MarkupText` uses Pango to render text, rendering non-English characters is easily possible:" msgstr "" -#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.MarkupText:252 +#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.MarkupText:243 msgid "You can justify the text by passing :attr:`justify` parameter." msgstr "" -#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.MarkupText:287 +#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.MarkupText:278 msgid "Tests" msgstr "" -#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.MarkupText:288 +#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.MarkupText:279 msgid "Check that the creation of :class:`~.MarkupText` works::" msgstr "" diff --git a/docs/i18n/gettext/reference/manim.mobject.text.text_mobject.Paragraph.pot b/docs/i18n/gettext/reference/manim.mobject.text.text_mobject.Paragraph.pot index ea2abf6139..8cff47aff6 100644 --- a/docs/i18n/gettext/reference/manim.mobject.text.text_mobject.Paragraph.pot +++ b/docs/i18n/gettext/reference/manim.mobject.text.text_mobject.Paragraph.pot @@ -31,22 +31,26 @@ msgid "Parameters" msgstr "" #: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.Paragraph:8 -msgid "Represents the spacing between lines. Default to -1, which means auto." +msgid "Represents the spacing between lines. Defaults to -1, which means auto." msgstr "" -#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.Paragraph:10 -msgid "Defines the alignment of paragraph. Default to \"left\". Possible values are \"left\", \"right\", \"center\"" +#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.Paragraph:9 +msgid "Defines the alignment of paragraph. Defaults to None. Possible values are \"left\", \"right\" or \"center\"." msgstr "" -#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.Paragraph:14 +#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.Paragraph:0 +msgid "Return type" +msgstr "" + +#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.Paragraph:12 msgid "Examples" msgstr "" -#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.Paragraph:15 +#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.Paragraph:13 msgid "Normal usage::" msgstr "" -#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.Paragraph:22 +#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.Paragraph:20 msgid "Remove unwanted invisible characters::" msgstr "" diff --git a/docs/i18n/gettext/reference/manim.mobject.text.text_mobject.Text.pot b/docs/i18n/gettext/reference/manim.mobject.text.text_mobject.Text.pot index 20971ad133..5fdf413089 100644 --- a/docs/i18n/gettext/reference/manim.mobject.text.text_mobject.Text.pot +++ b/docs/i18n/gettext/reference/manim.mobject.text.text_mobject.Text.pot @@ -31,34 +31,34 @@ msgid "Parameters" msgstr "" #: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.Text:6 -msgid "The text that need to created as mobject." +msgid "The text that needs to be created as a mobject." msgstr "" #: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.Text:0 msgid "Returns" msgstr "" -#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.Text:9 -msgid "The mobject like :class:`.VGroup`." +#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.Text:8 +msgid "The mobject-like :class:`.VGroup`." msgstr "" #: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.Text:0 msgid "Return type" msgstr "" -#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.Text:13 +#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.Text:12 msgid "Examples" msgstr "" -#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.Text:62 +#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.Text:61 msgid "As :class:`Text` uses Pango to render text, rendering non-English characters is easily possible:" msgstr "" -#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.Text:95 +#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.Text:94 msgid "Tests" msgstr "" -#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.Text:96 +#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.Text:95 msgid "Check that the creation of :class:`~.Text` works::" msgstr "" diff --git a/docs/i18n/gettext/reference/manim.mobject.text.text_mobject.pot b/docs/i18n/gettext/reference/manim.mobject.text.text_mobject.pot index 724ed064c3..315e8436d7 100644 --- a/docs/i18n/gettext/reference/manim.mobject.text.text_mobject.pot +++ b/docs/i18n/gettext/reference/manim.mobject.text.text_mobject.pot @@ -114,7 +114,7 @@ msgstr "" msgid "Returns" msgstr "" -#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.remove_invisible_chars:6 +#: ../../../manim/mobject/text/text_mobject.py:docstring of manim.mobject.text.text_mobject.remove_invisible_chars:5 msgid "The SVGMobject without unwanted invisible characters." msgstr "" diff --git a/docs/i18n/gettext/reference/manim.mobject.three_d.three_dimensions.Cylinder.pot b/docs/i18n/gettext/reference/manim.mobject.three_d.three_dimensions.Cylinder.pot index e4b4aefef3..1a0faa8e5e 100644 --- a/docs/i18n/gettext/reference/manim.mobject.three_d.three_dimensions.Cylinder.pot +++ b/docs/i18n/gettext/reference/manim.mobject.three_d.three_dimensions.Cylinder.pot @@ -23,7 +23,6 @@ msgid "A cylinder, defined by its height, radius and direction," msgstr "" #: ../../../manim/mobject/three_d/three_dimensions.py:docstring of manim.mobject.three_d.three_dimensions.Cylinder:4 -#: ../../../manim/mobject/three_d/three_dimensions.py:docstring of manim.mobject.three_d.three_dimensions.Cylinder.get_direction:6 msgid "Examples" msgstr "" @@ -65,7 +64,8 @@ msgid "Converts from cylindrical coordinates to cartesian." msgstr "" #: ../../source/reference/manim.mobject.three_d.three_dimensions.Cylinder.rst:23::1 -msgid "Uses :func:`~.space_ops.shoelace_direction` to calculate the direction." +#: ../../../manim/mobject/three_d/three_dimensions.py:docstring of manim.mobject.three_d.three_dimensions.Cylinder.get_direction:1 +msgid "Returns the direction of the central axis of the cylinder." msgstr "" #: ../../source/reference/manim.mobject.three_d.three_dimensions.Cylinder.rst:25 @@ -92,28 +92,4 @@ msgstr "" msgid "The width of the mobject." msgstr "" -#: ../../../manim/mobject/three_d/three_dimensions.py:docstring of manim.mobject.three_d.three_dimensions.Cylinder.func:1 -msgid "Converts from cylindrical coordinates to cartesian. :param u: The height. :type u: :class:`float` :param v: The azimuthal angle. :type v: :class:`float`" -msgstr "" - -#: ../../../manim/mobject/three_d/three_dimensions.py:docstring of manim.mobject.three_d.three_dimensions.Cylinder.get_direction:1 -msgid "Uses :func:`~.space_ops.shoelace_direction` to calculate the direction. The direction of points determines in which direction the object is drawn, clockwise or counterclockwise." -msgstr "" - -#: ../../../manim/mobject/three_d/three_dimensions.py:docstring of manim.mobject.three_d.three_dimensions.Cylinder.get_direction:7 -msgid "The default direction of a :class:`~.Circle` is counterclockwise::" -msgstr "" - -#: ../../../manim/mobject/three_d/three_dimensions.py:docstring of manim.mobject.three_d.three_dimensions.Cylinder.get_direction:0 -msgid "Returns" -msgstr "" - -#: ../../../manim/mobject/three_d/three_dimensions.py:docstring of manim.mobject.three_d.three_dimensions.Cylinder.get_direction:13 -msgid "Either ``\"CW\"`` or ``\"CCW\"``." -msgstr "" - -#: ../../../manim/mobject/three_d/three_dimensions.py:docstring of manim.mobject.three_d.three_dimensions.Cylinder.get_direction:0 -msgid "Return type" -msgstr "" - diff --git a/docs/i18n/gettext/reference/manim.mobject.types.image_mobject.ImageMobject.pot b/docs/i18n/gettext/reference/manim.mobject.types.image_mobject.ImageMobject.pot index fe4da00bda..f834d456fc 100644 --- a/docs/i18n/gettext/reference/manim.mobject.types.image_mobject.ImageMobject.pot +++ b/docs/i18n/gettext/reference/manim.mobject.types.image_mobject.ImageMobject.pot @@ -45,52 +45,47 @@ msgstr "" msgid "Methods" msgstr "" -#: ../../source/reference/manim.mobject.types.image_mobject.ImageMobject.rst:26::1 -#: ../../../manim/mobject/types/image_mobject.py:docstring of manim.mobject.types.image_mobject.ImageMobject.change_to_rgba_array:1 -msgid "Converts an RGB array into RGBA with the alpha value opacity maxed." -msgstr "" - -#: ../../source/reference/manim.mobject.types.image_mobject.ImageMobject.rst:26::1 +#: ../../source/reference/manim.mobject.types.image_mobject.ImageMobject.rst:25::1 #: ../../../manim/mobject/types/image_mobject.py:docstring of manim.mobject.types.image_mobject.ImageMobject.fade:1 msgid "Sets the image's opacity using a 1 - alpha relationship." msgstr "" -#: ../../source/reference/manim.mobject.types.image_mobject.ImageMobject.rst:26::1 +#: ../../source/reference/manim.mobject.types.image_mobject.ImageMobject.rst:25::1 #: ../../../manim/mobject/types/image_mobject.py:docstring of manim.mobject.types.image_mobject.ImageMobject.get_pixel_array:1 msgid "A simple getter method." msgstr "" -#: ../../source/reference/manim.mobject.types.image_mobject.ImageMobject.rst:26::1 +#: ../../source/reference/manim.mobject.types.image_mobject.ImageMobject.rst:25::1 #: ../../../manim/mobject/types/image_mobject.py:docstring of manim.mobject.types.image_mobject.ImageMobject.interpolate_color:1 msgid "Interpolates an array of pixel color values into another array of equal size." msgstr "" -#: ../../source/reference/manim.mobject.types.image_mobject.ImageMobject.rst:26::1 +#: ../../source/reference/manim.mobject.types.image_mobject.ImageMobject.rst:25::1 msgid "Condition is function which takes in one arguments, (x, y, z)." msgstr "" -#: ../../source/reference/manim.mobject.types.image_mobject.ImageMobject.rst:26::1 +#: ../../source/reference/manim.mobject.types.image_mobject.ImageMobject.rst:25::1 #: ../../../manim/mobject/types/image_mobject.py:docstring of manim.mobject.types.image_mobject.ImageMobject.set_opacity:1 msgid "Sets the image's opacity." msgstr "" -#: ../../source/reference/manim.mobject.types.image_mobject.ImageMobject.rst:28 +#: ../../source/reference/manim.mobject.types.image_mobject.ImageMobject.rst:27 msgid "Attributes" msgstr "" -#: ../../../manim/mobject/types/image_mobject.py:docstring of manim.mobject.types.image_mobject.ImageMobject.change_to_rgba_array:1::1 +#: ../../../manim/mobject/types/image_mobject.py:docstring of manim.mobject.types.image_mobject.ImageMobject.fade:1::1 msgid "Used to animate the application of any method of :code:`self`." msgstr "" -#: ../../../manim/mobject/types/image_mobject.py:docstring of manim.mobject.types.image_mobject.ImageMobject.change_to_rgba_array:1::1 +#: ../../../manim/mobject/types/image_mobject.py:docstring of manim.mobject.types.image_mobject.ImageMobject.fade:1::1 msgid "The depth of the mobject." msgstr "" -#: ../../../manim/mobject/types/image_mobject.py:docstring of manim.mobject.types.image_mobject.ImageMobject.change_to_rgba_array:1::1 +#: ../../../manim/mobject/types/image_mobject.py:docstring of manim.mobject.types.image_mobject.ImageMobject.fade:1::1 msgid "The height of the mobject." msgstr "" -#: ../../../manim/mobject/types/image_mobject.py:docstring of manim.mobject.types.image_mobject.ImageMobject.change_to_rgba_array:1::1 +#: ../../../manim/mobject/types/image_mobject.py:docstring of manim.mobject.types.image_mobject.ImageMobject.fade:1::1 msgid "The width of the mobject." msgstr "" diff --git a/docs/i18n/gettext/reference/manim.mobject.types.vectorized_mobject.VGroup.pot b/docs/i18n/gettext/reference/manim.mobject.types.vectorized_mobject.VGroup.pot index b00c58b3a3..6ad6e4cf0e 100644 --- a/docs/i18n/gettext/reference/manim.mobject.types.vectorized_mobject.VGroup.pot +++ b/docs/i18n/gettext/reference/manim.mobject.types.vectorized_mobject.VGroup.pot @@ -27,11 +27,19 @@ msgid "This can be used to group multiple :class:`~.VMobject` instances together msgstr "" #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VGroup:7 +msgid "Notes" +msgstr "" + +#: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VGroup:8 +msgid "When adding the same mobject more than once, repetitions are ignored. Use :meth:`.Mobject.copy` to create a separate copy which can then be added to the group." +msgstr "" + +#: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VGroup:13 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VGroup.add:11 msgid "Examples" msgstr "" -#: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VGroup:8 +#: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VGroup:14 msgid "To add :class:`~.VMobject`s to a :class:`~.VGroup`, you can either use the :meth:`~.VGroup.add` method, or use the `+` and `+=` operators. Similarly, you can subtract elements of a VGroup via :meth:`~.VGroup.remove` method, or `-` and `-=` operators:" msgstr "" diff --git a/docs/i18n/gettext/reference/manim.mobject.types.vectorized_mobject.VMobject.pot b/docs/i18n/gettext/reference/manim.mobject.types.vectorized_mobject.VMobject.pot index 502a99b733..2030503e47 100644 --- a/docs/i18n/gettext/reference/manim.mobject.types.vectorized_mobject.VMobject.pot +++ b/docs/i18n/gettext/reference/manim.mobject.types.vectorized_mobject.VMobject.pot @@ -76,230 +76,230 @@ msgstr "" msgid "Methods" msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.add_cubic_bezier_curve_to:1 msgid "Add cubic bezier curve to the path." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.add_line_to:1 msgid "Add a straight line from the last point of VMobject to the given point." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.add_quadratic_bezier_curve_to:1 msgid "Add Quadratic bezier curve to the path." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 msgid "Creates a smooth curve from given points and add it to the VMobject." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.align_points:1 msgid "Adds points to self and vmobject so that they both have the same number of subpaths, with corresponding subpaths each containing the same number of points." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 msgid "Changes the anchor mode of the bezier curves." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.consider_points_equals_2d:1 msgid "Determine if two points are close enough to be considered equal." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.force_direction:1 msgid "Makes sure that points are either directed clockwise or counterclockwise." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.gen_cubic_bezier_tuples_from_points:1 msgid "Returns the bezier tuples from an array of points." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 msgid "First arg can be either a color, or a tuple/list of colors." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.get_anchors:1 msgid "Returns the anchors of the curves forming the VMobject." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.get_anchors_and_handles:1 msgid "Returns anchors1, handles1, handles2, anchors2, where (anchors1[i], handles1[i], handles2[i], anchors2[i]) will be four points defining a cubic bezier curve for any i in range(0, len(anchors1))" msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.get_arc_length:1 msgid "Return the approximated length of the whole curve." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.get_color:1 msgid "Returns the color of the :class:`~.Mobject`" msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.get_curve_functions:1 msgid "Gets the functions for the curves of the mobject." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.get_curve_functions_with_lengths:1 msgid "Gets the functions and lengths of the curves for the mobject." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 msgid "Uses :func:`~.space_ops.shoelace_direction` to calculate the direction." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.get_end_anchors:1 -msgid "Return the starting anchors of the bezier curves." +msgid "Return the end anchors of the bezier curves." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.add_cubic_bezier_curve_to:1::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.fill_color:1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.get_fill_color:1 msgid "If there are multiple colors (for gradient) this returns the first one" msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.get_fill_opacity:1 msgid "If there are multiple opacities, this returns the first" msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.get_nth_curve_function:1 msgid "Returns the expression of the nth curve." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.get_nth_curve_function_with_length:1 msgid "Returns the expression of the nth curve along with its (approximate) length." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.get_nth_curve_length:1 msgid "Returns the (approximate) length of the nth curve." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.get_nth_curve_length_pieces:1 msgid "Returns the array of short line lengths used for length approximation." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.get_nth_curve_points:1 msgid "Returns the points defining the nth curve of the vmobject." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.get_num_curves:1 msgid "Returns the number of curves of the vmobject." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 msgid "The simplest :class:`~.Mobject` to be transformed to or from self." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.get_start_anchors:1 msgid "Returns the start anchors of the bezier curves." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 msgid "Returns the subcurve of the VMobject between the interval [a, b]." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.get_subpaths:1 msgid "Returns subpaths formed by the curves of the VMobject." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.init_colors:1 msgid "Initializes the colors." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.insert_n_curves:1 msgid "Inserts n curves to the bezier curves of the vmobject." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.insert_n_curves_to_point_list:1 msgid "Given an array of k points defining a bezier curves (anchors and handles), returns points defining exactly k + n bezier curves." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.point_from_proportion:1 msgid "Gets the point at a proportion along the path of the :class:`VMobject`." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 msgid "Given two bounds a and b, transforms the points of the self vmobject into the points of the vmobject passed as parameter with respect to the bounds." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.proportion_from_point:1 msgid "Returns the proportion along the path of the :class:`VMobject` a particular given point is at." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.reverse_direction:1 msgid "Reverts the point direction by inverting the point order." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.rotate:1 msgid "Rotates the :class:`~.Mobject` about a certain point." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.rotate_sheen_direction:1 msgid "Rotates the direction of the applied sheen." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 msgid "If the distance between a given handle point H and its associated anchor point A is d, then it changes H to be a distances factor*d away from A, but so that the line from A to H doesn't change." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.set_anchors_and_handles:1 msgid "Given two sets of anchors and handles, process them to set them as anchors and handles of the VMobject." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 msgid "Condition is function which takes in one arguments, (x, y, z)." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.set_fill:1 msgid "Set the fill color and fill opacity of a :class:`VMobject`." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.set_points_as_corners:1 msgid "Given an array of points, set them as corner of the vmobject." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.set_sheen:1 msgid "Applies a color gradient from a direction." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:113::1 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:114::1 #: ../../../manim/mobject/types/vectorized_mobject.py:docstring of manim.mobject.types.vectorized_mobject.VMobject.set_sheen_direction:1 msgid "Sets the direction of the applied sheen." msgstr "" -#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:115 +#: ../../source/reference/manim.mobject.types.vectorized_mobject.VMobject.rst:116 msgid "Attributes" msgstr "" diff --git a/docs/i18n/gettext/reference/manim.mobject.value_tracker.ComplexValueTracker.pot b/docs/i18n/gettext/reference/manim.mobject.value_tracker.ComplexValueTracker.pot index 8b13789179..f8d1c8929a 100644 --- a/docs/i18n/gettext/reference/manim.mobject.value_tracker.ComplexValueTracker.pot +++ b/docs/i18n/gettext/reference/manim.mobject.value_tracker.ComplexValueTracker.pot @@ -1 +1,67 @@ +msgid "" +msgstr "" +"Project-Id-Version: Manim \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../source/reference/manim.mobject.value_tracker.ComplexValueTracker.rst:2 +msgid "ComplexValueTracker" +msgstr "" + +#: ../../source/reference/manim.mobject.value_tracker.ComplexValueTracker.rst:4 +msgid "Qualified name: ``manim.mobject.value\\_tracker.ComplexValueTracker``" +msgstr "" + +#: ../../../manim/mobject/value_tracker.py:docstring of manim.mobject.value_tracker.ComplexValueTracker:1 +msgid "Bases: :py:class:`manim.mobject.value_tracker.ValueTracker`" +msgstr "" + +#: ../../../manim/mobject/value_tracker.py:docstring of manim.mobject.value_tracker.ComplexValueTracker:1 +msgid "Tracks a complex-valued parameter." +msgstr "" + +#: ../../../manim/mobject/value_tracker.py:docstring of manim.mobject.value_tracker.ComplexValueTracker:3 +msgid "When the value is set through :attr:`animate`, the value will take a straight path from the source point to the destination point." +msgstr "" + +#: ../../../manim/mobject/value_tracker.py:docstring of manim.mobject.value_tracker.ComplexValueTracker:7 +msgid "Examples" +msgstr "" + +#: ../../source/reference/manim.mobject.value_tracker.ComplexValueTracker.rst:14 +msgid "Methods" +msgstr "" + +#: ../../source/reference/manim.mobject.value_tracker.ComplexValueTracker.rst:21::1 +#: ../../../manim/mobject/value_tracker.py:docstring of manim.mobject.value_tracker.ComplexValueTracker.get_value:1 +msgid "Get the current value of this value tracker as a complex number." +msgstr "" + +#: ../../source/reference/manim.mobject.value_tracker.ComplexValueTracker.rst:21::1 +#: ../../../manim/mobject/value_tracker.py:docstring of manim.mobject.value_tracker.ComplexValueTracker.set_value:1 +msgid "Sets a new complex value to the ComplexValueTracker" +msgstr "" + +#: ../../source/reference/manim.mobject.value_tracker.ComplexValueTracker.rst:23 +msgid "Attributes" +msgstr "" + +#: ../../../manim/mobject/value_tracker.py:docstring of manim.mobject.value_tracker.ComplexValueTracker.get_value:1::1 +msgid "Used to animate the application of any method of :code:`self`." +msgstr "" + +#: ../../../manim/mobject/value_tracker.py:docstring of manim.mobject.value_tracker.ComplexValueTracker.get_value:1::1 +msgid "The depth of the mobject." +msgstr "" + +#: ../../../manim/mobject/value_tracker.py:docstring of manim.mobject.value_tracker.ComplexValueTracker.get_value:1::1 +msgid "The height of the mobject." +msgstr "" + +#: ../../../manim/mobject/value_tracker.py:docstring of manim.mobject.value_tracker.ComplexValueTracker.get_value:1::1 +msgid "The width of the mobject." +msgstr "" + + diff --git a/docs/i18n/gettext/reference/manim.mobject.value_tracker.ValueTracker.pot b/docs/i18n/gettext/reference/manim.mobject.value_tracker.ValueTracker.pot index 8b13789179..f56be56bb3 100644 --- a/docs/i18n/gettext/reference/manim.mobject.value_tracker.ValueTracker.pot +++ b/docs/i18n/gettext/reference/manim.mobject.value_tracker.ValueTracker.pot @@ -1 +1,89 @@ +msgid "" +msgstr "" +"Project-Id-Version: Manim \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../source/reference/manim.mobject.value_tracker.ValueTracker.rst:2 +msgid "ValueTracker" +msgstr "" + +#: ../../source/reference/manim.mobject.value_tracker.ValueTracker.rst:4 +msgid "Qualified name: ``manim.mobject.value\\_tracker.ValueTracker``" +msgstr "" + +#: ../../../manim/mobject/value_tracker.py:docstring of manim.mobject.value_tracker.ValueTracker:1 +msgid "Bases: :py:class:`manim.mobject.mobject.Mobject`" +msgstr "" + +#: ../../../manim/mobject/value_tracker.py:docstring of manim.mobject.value_tracker.ValueTracker:1 +msgid "A mobject that can be used for tracking (real-valued) parameters. Useful for animating parameter changes." +msgstr "" + +#: ../../../manim/mobject/value_tracker.py:docstring of manim.mobject.value_tracker.ValueTracker:4 +msgid "Not meant to be displayed. Instead the position encodes some number, often one which another animation or continual_animation uses for its update function, and by treating it as a mobject it can still be animated and manipulated just like anything else." +msgstr "" + +#: ../../../manim/mobject/value_tracker.py:docstring of manim.mobject.value_tracker.ValueTracker:9 +msgid "This value changes continuously when animated using the :attr:`animate` syntax." +msgstr "" + +#: ../../../manim/mobject/value_tracker.py:docstring of manim.mobject.value_tracker.ValueTracker:12 +msgid "Examples" +msgstr "" + +#: ../../../manim/mobject/value_tracker.py:docstring of manim.mobject.value_tracker.ValueTracker:41 +msgid "You can also link ValueTrackers to updaters. In this case, you have to make sure that the ValueTracker is added to the scene by ``add``" +msgstr "" + +#: ../../source/reference/manim.mobject.value_tracker.ValueTracker.rst:14 +msgid "Methods" +msgstr "" + +#: ../../source/reference/manim.mobject.value_tracker.ValueTracker.rst:23::1 +#: ../../../manim/mobject/value_tracker.py:docstring of manim.mobject.value_tracker.ValueTracker.get_value:1 +msgid "Get the current value of this ValueTracker." +msgstr "" + +#: ../../source/reference/manim.mobject.value_tracker.ValueTracker.rst:23::1 +#: ../../../manim/mobject/value_tracker.py:docstring of manim.mobject.value_tracker.ValueTracker.increment_value:1 +msgid "Increments (adds) a scalar value to the ValueTracker" +msgstr "" + +#: ../../source/reference/manim.mobject.value_tracker.ValueTracker.rst:23::1 +#: ../../../manim/mobject/value_tracker.py:docstring of manim.mobject.value_tracker.ValueTracker.interpolate:1 +msgid "Turns self into an interpolation between mobject1 and mobject2." +msgstr "" + +#: ../../source/reference/manim.mobject.value_tracker.ValueTracker.rst:23::1 +#: ../../../manim/mobject/value_tracker.py:docstring of manim.mobject.value_tracker.ValueTracker.set_value:1 +msgid "Sets a new scalar value to the ValueTracker" +msgstr "" + +#: ../../source/reference/manim.mobject.value_tracker.ValueTracker.rst:25 +msgid "Attributes" +msgstr "" + +#: ../../../manim/mobject/value_tracker.py:docstring of manim.mobject.value_tracker.ValueTracker.get_value:1::1 +msgid "Used to animate the application of any method of :code:`self`." +msgstr "" + +#: ../../../manim/mobject/value_tracker.py:docstring of manim.mobject.value_tracker.ValueTracker.get_value:1::1 +msgid "The depth of the mobject." +msgstr "" + +#: ../../../manim/mobject/value_tracker.py:docstring of manim.mobject.value_tracker.ValueTracker.get_value:1::1 +msgid "The height of the mobject." +msgstr "" + +#: ../../../manim/mobject/value_tracker.py:docstring of manim.mobject.value_tracker.ValueTracker.get_value:1::1 +msgid "The width of the mobject." +msgstr "" + +#: ../../../manim/mobject/value_tracker.py:docstring of manim.mobject.value_tracker.ValueTracker.get_value:0 +msgid "Return type" +msgstr "" + + diff --git a/docs/i18n/gettext/reference/manim.mobject.value_tracker.pot b/docs/i18n/gettext/reference/manim.mobject.value_tracker.pot index 8b13789179..d2e20ae2cc 100644 --- a/docs/i18n/gettext/reference/manim.mobject.value_tracker.pot +++ b/docs/i18n/gettext/reference/manim.mobject.value_tracker.pot @@ -1 +1,25 @@ +msgid "" +msgstr "" +"Project-Id-Version: Manim \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../source/reference/manim.mobject.value_tracker.rst:2 +msgid "value\\_tracker" +msgstr "" + +#: ../../../manim/mobject/value_tracker.py:docstring of manim.mobject.value_tracker:1 +msgid "Simple mobjects that can be used for storing (and updating) a value." +msgstr "" + +#: ../../source/reference/manim.mobject.value_tracker.rst:15 +msgid "Classes" +msgstr "" + +#: ../../source/reference/manim.mobject.value_tracker.rst:22::1 +msgid "Tracks a complex-valued parameter." +msgstr "" + + diff --git a/docs/i18n/gettext/reference/manim.mobject.vector_field.VectorField.pot b/docs/i18n/gettext/reference/manim.mobject.vector_field.VectorField.pot index bfd00886cb..636e41dee3 100644 --- a/docs/i18n/gettext/reference/manim.mobject.vector_field.VectorField.pot +++ b/docs/i18n/gettext/reference/manim.mobject.vector_field.VectorField.pot @@ -27,6 +27,7 @@ msgid "Vector fields are based on a function defining a vector at every position msgstr "" #: ../../../manim/mobject/vector_field.py:docstring of manim.mobject.vector_field.VectorField:0 +#: ../../../manim/mobject/vector_field.py:docstring of manim.mobject.vector_field.VectorField.fit_to_coordinate_system:0 #: ../../../manim/mobject/vector_field.py:docstring of manim.mobject.vector_field.VectorField.get_colored_background_image:0 #: ../../../manim/mobject/vector_field.py:docstring of manim.mobject.vector_field.VectorField.get_nudge_updater:0 #: ../../../manim/mobject/vector_field.py:docstring of manim.mobject.vector_field.VectorField.get_vectorized_rgba_gradient_function:0 @@ -71,75 +72,92 @@ msgstr "" msgid "Methods" msgstr "" -#: ../../source/reference/manim.mobject.vector_field.VectorField.rst:28::1 +#: ../../source/reference/manim.mobject.vector_field.VectorField.rst:29::1 +#: ../../../manim/mobject/vector_field.py:docstring of manim.mobject.vector_field.VectorField.fit_to_coordinate_system:1 +msgid "Scale the vector field to fit a coordinate system." +msgstr "" + +#: ../../source/reference/manim.mobject.vector_field.VectorField.rst:29::1 #: ../../../manim/mobject/vector_field.py:docstring of manim.mobject.vector_field.VectorField.get_colored_background_image:1 msgid "Generate an image that displays the vector field." msgstr "" -#: ../../source/reference/manim.mobject.vector_field.VectorField.rst:28::1 +#: ../../source/reference/manim.mobject.vector_field.VectorField.rst:29::1 #: ../../../manim/mobject/vector_field.py:docstring of manim.mobject.vector_field.VectorField.get_nudge_updater:1 msgid "Get an update function to move a :class:`~.Mobject` along the vector field." msgstr "" -#: ../../source/reference/manim.mobject.vector_field.VectorField.rst:28::1 +#: ../../source/reference/manim.mobject.vector_field.VectorField.rst:29::1 #: ../../../manim/mobject/vector_field.py:docstring of manim.mobject.vector_field.VectorField.get_vectorized_rgba_gradient_function:1 msgid "Generates a gradient of rgbas as a numpy array" msgstr "" -#: ../../source/reference/manim.mobject.vector_field.VectorField.rst:28::1 +#: ../../source/reference/manim.mobject.vector_field.VectorField.rst:29::1 #: ../../../manim/mobject/vector_field.py:docstring of manim.mobject.vector_field.VectorField.nudge:1 msgid "Nudge a :class:`~.Mobject` along the vector field." msgstr "" -#: ../../source/reference/manim.mobject.vector_field.VectorField.rst:28::1 +#: ../../source/reference/manim.mobject.vector_field.VectorField.rst:29::1 #: ../../../manim/mobject/vector_field.py:docstring of manim.mobject.vector_field.VectorField.nudge_submobjects:1 msgid "Apply a nudge along the vector field to all submobjects." msgstr "" -#: ../../source/reference/manim.mobject.vector_field.VectorField.rst:28::1 +#: ../../source/reference/manim.mobject.vector_field.VectorField.rst:29::1 #: ../../../manim/mobject/vector_field.py:docstring of manim.mobject.vector_field.VectorField.scale_func:1 msgid "Scale a vector field function." msgstr "" -#: ../../source/reference/manim.mobject.vector_field.VectorField.rst:28::1 +#: ../../source/reference/manim.mobject.vector_field.VectorField.rst:29::1 #: ../../../manim/mobject/vector_field.py:docstring of manim.mobject.vector_field.VectorField.shift_func:1 msgid "Shift a vector field function." msgstr "" -#: ../../source/reference/manim.mobject.vector_field.VectorField.rst:28::1 +#: ../../source/reference/manim.mobject.vector_field.VectorField.rst:29::1 #: ../../../manim/mobject/vector_field.py:docstring of manim.mobject.vector_field.VectorField.start_submobject_movement:1 msgid "Start continuously moving all submobjects along the vector field." msgstr "" -#: ../../source/reference/manim.mobject.vector_field.VectorField.rst:28::1 +#: ../../source/reference/manim.mobject.vector_field.VectorField.rst:29::1 #: ../../../manim/mobject/vector_field.py:docstring of manim.mobject.vector_field.VectorField.stop_submobject_movement:1 msgid "Stops the continuous movement started using :meth:`start_submobject_movement`." msgstr "" -#: ../../source/reference/manim.mobject.vector_field.VectorField.rst:30 +#: ../../source/reference/manim.mobject.vector_field.VectorField.rst:31 msgid "Attributes" msgstr "" -#: ../../../manim/mobject/vector_field.py:docstring of manim.mobject.vector_field.VectorField.get_colored_background_image:1::1 +#: ../../../manim/mobject/vector_field.py:docstring of manim.mobject.vector_field.VectorField.fit_to_coordinate_system:1::1 msgid "Used to animate the application of any method of :code:`self`." msgstr "" -#: ../../../manim/mobject/vector_field.py:docstring of manim.mobject.vector_field.VectorField.get_colored_background_image:1::1 +#: ../../../manim/mobject/vector_field.py:docstring of manim.mobject.vector_field.VectorField.fit_to_coordinate_system:1::1 msgid "The depth of the mobject." msgstr "" -#: ../../../manim/mobject/vector_field.py:docstring of manim.mobject.vector_field.VectorField.get_colored_background_image:1::1 +#: ../../../manim/mobject/vector_field.py:docstring of manim.mobject.vector_field.VectorField.fit_to_coordinate_system:1::1 msgid "If there are multiple colors (for gradient) this returns the first one" msgstr "" -#: ../../../manim/mobject/vector_field.py:docstring of manim.mobject.vector_field.VectorField.get_colored_background_image:1::1 +#: ../../../manim/mobject/vector_field.py:docstring of manim.mobject.vector_field.VectorField.fit_to_coordinate_system:1::1 msgid "The height of the mobject." msgstr "" -#: ../../../manim/mobject/vector_field.py:docstring of manim.mobject.vector_field.VectorField.get_colored_background_image:1::1 +#: ../../../manim/mobject/vector_field.py:docstring of manim.mobject.vector_field.VectorField.fit_to_coordinate_system:1::1 msgid "The width of the mobject." msgstr "" +#: ../../../manim/mobject/vector_field.py:docstring of manim.mobject.vector_field.VectorField.fit_to_coordinate_system:3 +msgid "This method is useful when the vector field is defined in a coordinate system different from the one used to display the vector field." +msgstr "" + +#: ../../../manim/mobject/vector_field.py:docstring of manim.mobject.vector_field.VectorField.fit_to_coordinate_system:6 +msgid "This method can only be used once because it transforms the origin of each vector." +msgstr "" + +#: ../../../manim/mobject/vector_field.py:docstring of manim.mobject.vector_field.VectorField.fit_to_coordinate_system:8 +msgid "The coordinate system to fit the vector field to." +msgstr "" + #: ../../../manim/mobject/vector_field.py:docstring of manim.mobject.vector_field.VectorField.get_colored_background_image:3 msgid "The color at each position is calculated by passing the positing through a series of steps: Calculate the vector field function at that position, map that vector to a single value using `self.color_scheme` and finally generate a color from that value using the color gradient." msgstr "" diff --git a/docs/i18n/gettext/reference/manim.scene.scene.Scene.pot b/docs/i18n/gettext/reference/manim.scene.scene.Scene.pot index 6d148bef57..0ef62d99fd 100644 --- a/docs/i18n/gettext/reference/manim.scene.scene.Scene.pot +++ b/docs/i18n/gettext/reference/manim.scene.scene.Scene.pot @@ -78,6 +78,11 @@ msgstr "" msgid "Adds an entry in the corresponding subcaption file at the current time stamp." msgstr "" +#: ../../source/reference/manim.scene.scene.Scene.rst:74::1 +#: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.add_updater:1 +msgid "Add an update function to the scene." +msgstr "" + #: ../../source/reference/manim.scene.scene.Scene.rst:74::1 #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.begin_animations:1 msgid "Start the animations of the scene." @@ -190,6 +195,11 @@ msgstr "" msgid "Removes mobjects from the foreground, and internally from the list foreground_mobjects." msgstr "" +#: ../../source/reference/manim.scene.scene.Scene.rst:74::1 +#: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.remove_updater:1 +msgid "Remove an update function from the scene." +msgstr "" + #: ../../source/reference/manim.scene.scene.Scene.rst:74::1 #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.render:1 msgid "Renders this Scene." @@ -220,6 +230,11 @@ msgstr "" msgid "Begins updating all mobjects in the Scene." msgstr "" +#: ../../source/reference/manim.scene.scene.Scene.rst:74::1 +#: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.update_self:1 +msgid "Run all scene updater functions." +msgstr "" + #: ../../source/reference/manim.scene.scene.Scene.rst:74::1 #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.wait:1 msgid "Plays a \"no operation\" animation." @@ -238,6 +253,7 @@ msgstr "" #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.add_foreground_mobjects:0 #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.add_sound:0 #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.add_subcaption:0 +#: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.add_updater:0 #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.bring_to_back:0 #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.bring_to_front:0 #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.compile_animation_data:0 @@ -254,9 +270,11 @@ msgstr "" #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.remove:0 #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.remove_foreground_mobject:0 #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.remove_foreground_mobjects:0 +#: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.remove_updater:0 #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.render:0 #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.restructure_mobjects:0 #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.update_mobjects:0 +#: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.update_self:0 #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.wait:0 #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.wait_until:0 msgid "Parameters" @@ -295,6 +313,7 @@ msgstr "" #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.add_foreground_mobject:0 #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.add_foreground_mobjects:0 #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.add_subcaption:0 +#: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.add_updater:0 #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.begin_animations:0 #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.bring_to_back:0 #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.bring_to_front:0 @@ -312,6 +331,7 @@ msgstr "" #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.next_section:0 #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.remove_foreground_mobject:0 #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.remove_foreground_mobjects:0 +#: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.remove_updater:0 #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.restructure_mobjects:0 #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.should_update_mobjects:0 msgid "Return type" @@ -369,6 +389,22 @@ msgstr "" msgid "This example illustrates both possibilities for adding subcaptions to Manimations::" msgstr "" +#: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.add_updater:3 +msgid "The scene updater functions are run every frame, and they are the last type of updaters to run." +msgstr "" + +#: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.add_updater:8 +msgid "When using the Cairo renderer, scene updaters that modify mobjects are not detected in the same way that mobject updaters are. To be more concrete, a mobject only modified via a scene updater will not necessarily be added to the list of *moving mobjects* and thus might not be updated every frame." +msgstr "" + +#: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.add_updater:15 +msgid "TL;DR: Use mobject updaters to update mobjects." +msgstr "" + +#: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.add_updater:17 +msgid "The updater function. It takes a float, which is the time difference since the last update (usually equal to the frame rate)." +msgstr "" + #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.bring_to_back:4 msgid "The mobject(s) to push to the back of the scene." msgstr "" @@ -504,7 +540,7 @@ msgid "List of top level mobjects." msgstr "" #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.next_section:1 -msgid "Create separation here; the last section gets finished and a new one gets created. ``skip_animations`` skips the rendering of all animations in this section. Refer to :doc:`the documentation` on how to use sections." +msgid "Create separation here; the last section gets finished and a new one gets created. ``skip_animations`` skips the rendering of all animations in this section. Refer to :doc:`the documentation` on how to use sections." msgstr "" #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.pause:3 @@ -559,6 +595,10 @@ msgstr "" msgid "The Scene, with the foreground mobjects removed." msgstr "" +#: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.remove_updater:3 +msgid "The updater function to be removed." +msgstr "" + #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.render:3 msgid "If true, opens scene in a file viewer." msgstr "" @@ -611,6 +651,14 @@ msgstr "" msgid "Change in time between updates. Defaults (mostly) to 1/frames_per_second" msgstr "" +#: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.update_self:3 +msgid "Among all types of update functions (mobject updaters, mesh updaters, scene updaters), scene update functions are called last." +msgstr "" + +#: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.update_self:6 +msgid "Scene time since last update." +msgstr "" + #: ../../../manim/scene/scene.py:docstring of manim.scene.scene.Scene.wait:3 msgid "The run time of the animation." msgstr "" diff --git a/docs/i18n/gettext/reference/manim.scene.section.Section.pot b/docs/i18n/gettext/reference/manim.scene.section.Section.pot index 58f8a5ed5c..0db463d896 100644 --- a/docs/i18n/gettext/reference/manim.scene.section.Section.pot +++ b/docs/i18n/gettext/reference/manim.scene.section.Section.pot @@ -19,7 +19,7 @@ msgid "Bases: :py:class:`object`" msgstr "" #: ../../../manim/scene/section.py:docstring of manim.scene.section.Section:1 -msgid "A :class:`.Scene` can be segmented into multiple Sections. Refer to :doc:`the documentation` for more info. It consists of multiple animations." +msgid "A :class:`.Scene` can be segmented into multiple Sections. Refer to :doc:`the documentation` for more info. It consists of multiple animations." msgstr "" #: ../../../manim/scene/section.py:docstring of manim.scene.section.Section:0 diff --git a/docs/i18n/gettext/reference/manim.utils.bezier.pot b/docs/i18n/gettext/reference/manim.utils.bezier.pot index f7c8ebf845..91eea0758e 100644 --- a/docs/i18n/gettext/reference/manim.utils.bezier.pot +++ b/docs/i18n/gettext/reference/manim.utils.bezier.pot @@ -34,6 +34,9 @@ msgstr "" #: ../../../manim/utils/bezier.py:docstring of manim.utils.bezier.partial_bezier_points:0 #: ../../../manim/utils/bezier.py:docstring of manim.utils.bezier.point_lies_on_bezier:0 #: ../../../manim/utils/bezier.py:docstring of manim.utils.bezier.proportions_along_bezier_curve_for_point:0 +#: ../../../manim/utils/bezier.py:docstring of manim.utils.bezier.quadratic_bezier_remap:0 +#: ../../../manim/utils/bezier.py:docstring of manim.utils.bezier.split_quadratic_bezier:0 +#: ../../../manim/utils/bezier.py:docstring of manim.utils.bezier.subdivide_quadratic_bezier:0 msgid "Parameters" msgstr "" @@ -46,6 +49,7 @@ msgstr "" #: ../../../manim/utils/bezier.py:docstring of manim.utils.bezier.partial_bezier_points:0 #: ../../../manim/utils/bezier.py:docstring of manim.utils.bezier.point_lies_on_bezier:0 #: ../../../manim/utils/bezier.py:docstring of manim.utils.bezier.proportions_along_bezier_curve_for_point:0 +#: ../../../manim/utils/bezier.py:docstring of manim.utils.bezier.split_quadratic_bezier:0 msgid "Returns" msgstr "" @@ -65,6 +69,9 @@ msgstr "" #: ../../../manim/utils/bezier.py:docstring of manim.utils.bezier.partial_bezier_points:0 #: ../../../manim/utils/bezier.py:docstring of manim.utils.bezier.point_lies_on_bezier:0 #: ../../../manim/utils/bezier.py:docstring of manim.utils.bezier.proportions_along_bezier_curve_for_point:0 +#: ../../../manim/utils/bezier.py:docstring of manim.utils.bezier.quadratic_bezier_remap:0 +#: ../../../manim/utils/bezier.py:docstring of manim.utils.bezier.split_quadratic_bezier:0 +#: ../../../manim/utils/bezier.py:docstring of manim.utils.bezier.subdivide_quadratic_bezier:0 msgid "Return type" msgstr "" @@ -162,4 +169,60 @@ msgstr "" msgid "Raises" msgstr "" +#: ../../../manim/utils/bezier.py:docstring of manim.utils.bezier.proportions_along_bezier_curve_for_point:25 +msgid "When ``point`` and the control points have different shapes." +msgstr "" + +#: ../../../manim/utils/bezier.py:docstring of manim.utils.bezier.quadratic_bezier_remap:1 +msgid "Remaps the number of curves to a higher amount by splitting bezier curves" +msgstr "" + +#: ../../../manim/utils/bezier.py:docstring of manim.utils.bezier.quadratic_bezier_remap:3 +msgid "The triplets of the quadratic bezier curves to be remapped" +msgstr "" + +#: ../../../manim/utils/bezier.py:docstring of manim.utils.bezier.quadratic_bezier_remap:4 +msgid "The number of curves that the output will contain. This needs to be higher than the current number." +msgstr "" + +#: ../../../manim/utils/bezier.py:docstring of manim.utils.bezier.split_quadratic_bezier:1 +msgid "Split a quadratic Bézier curve at argument ``t`` into two quadratic curves." +msgstr "" + +#: ../../../manim/utils/bezier.py:docstring of manim.utils.bezier.split_quadratic_bezier:3 +msgid "The control points of the bezier curve has shape ``[a1, h1, b1]``" +msgstr "" + +#: ../../../manim/utils/bezier.py:docstring of manim.utils.bezier.split_quadratic_bezier:5 +msgid "The ``t``-value at which to split the Bézier curve" +msgstr "" + +#: ../../../manim/utils/bezier.py:docstring of manim.utils.bezier.split_quadratic_bezier:7 +msgid "* *The two Bézier curves as a list of tuples,* * has the shape ``[a1, h1, b1], [a2, h2, b2]``" +msgstr "" + +#: ../../../manim/utils/bezier.py:docstring of manim.utils.bezier.split_quadratic_bezier:7 +msgid "*The two Bézier curves as a list of tuples,*" +msgstr "" + +#: ../../../manim/utils/bezier.py:docstring of manim.utils.bezier.split_quadratic_bezier:8 +msgid "has the shape ``[a1, h1, b1], [a2, h2, b2]``" +msgstr "" + +#: ../../../manim/utils/bezier.py:docstring of manim.utils.bezier.subdivide_quadratic_bezier:1 +msgid "Subdivide a quadratic Bézier curve into ``n`` subcurves which have the same shape." +msgstr "" + +#: ../../../manim/utils/bezier.py:docstring of manim.utils.bezier.subdivide_quadratic_bezier:3 +msgid "The points at which the curve is split are located at the arguments :math:`t = i/n` for :math:`i = 1, ..., n-1`." +msgstr "" + +#: ../../../manim/utils/bezier.py:docstring of manim.utils.bezier.subdivide_quadratic_bezier:6 +msgid "The control points of the Bézier curve in form ``[a1, h1, b1]``" +msgstr "" + +#: ../../../manim/utils/bezier.py:docstring of manim.utils.bezier.subdivide_quadratic_bezier:7 +msgid "The number of curves to subdivide the Bézier curve into" +msgstr "" + diff --git a/docs/i18n/gettext/reference/manim.utils.docbuild.manim_directive.ManimDirective.pot b/docs/i18n/gettext/reference/manim.utils.docbuild.manim_directive.ManimDirective.pot index 3b45641217..8b13789179 100644 --- a/docs/i18n/gettext/reference/manim.utils.docbuild.manim_directive.ManimDirective.pot +++ b/docs/i18n/gettext/reference/manim.utils.docbuild.manim_directive.ManimDirective.pot @@ -1,53 +1 @@ -msgid "" -msgstr "" -"Project-Id-Version: Manim \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: ../../source/reference/manim.utils.docbuild.manim_directive.ManimDirective.rst:2 -msgid "ManimDirective" -msgstr "" - -#: ../../source/reference/manim.utils.docbuild.manim_directive.ManimDirective.rst:4 -msgid "Qualified name: ``manim.utils.docbuild.manim\\_directive.ManimDirective``" -msgstr "" - -#: ../../../manim/utils/docbuild/manim_directive.py:docstring of manim.utils.docbuild.manim_directive.ManimDirective:1 -msgid "Bases: :py:class:`docutils.parsers.rst.Directive`" -msgstr "" - -#: ../../../manim/utils/docbuild/manim_directive.py:docstring of manim.utils.docbuild.manim_directive.ManimDirective:1 -msgid "The manim directive, rendering videos while building the documentation." -msgstr "" - -#: ../../../manim/utils/docbuild/manim_directive.py:docstring of manim.utils.docbuild.manim_directive.ManimDirective:4 -msgid "See the module docstring for documentation." -msgstr "" - -#: ../../source/reference/manim.utils.docbuild.manim_directive.ManimDirective.rst:14 -msgid "Methods" -msgstr "" - -#: ../../source/reference/manim.utils.docbuild.manim_directive.ManimDirective.rst:22 -msgid "Attributes" -msgstr "" - -#: ../../source/reference/manim.utils.docbuild.manim_directive.ManimDirective.rst:29::1 -msgid "May the final argument contain whitespace?" -msgstr "" - -#: ../../source/reference/manim.utils.docbuild.manim_directive.ManimDirective.rst:29::1 -msgid "May the directive have content?" -msgstr "" - -#: ../../source/reference/manim.utils.docbuild.manim_directive.ManimDirective.rst:29::1 -msgid "Mapping of option names to validator functions." -msgstr "" - -#: ../../source/reference/manim.utils.docbuild.manim_directive.ManimDirective.rst:29::1 -msgid "Number of optional arguments after the required arguments." -msgstr "" - - diff --git a/docs/i18n/gettext/reference/manim.utils.docbuild.manim_directive.pot b/docs/i18n/gettext/reference/manim.utils.docbuild.manim_directive.pot index d352b7656d..8b13789179 100644 --- a/docs/i18n/gettext/reference/manim.utils.docbuild.manim_directive.pot +++ b/docs/i18n/gettext/reference/manim.utils.docbuild.manim_directive.pot @@ -1,125 +1 @@ -msgid "" -msgstr "" -"Project-Id-Version: Manim \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: ../../../manim/utils/docbuild/manim_directive.py:docstring of manim.utils.docbuild.manim_directive:2 -msgid "A directive for including Manim videos in a Sphinx document" -msgstr "" - -#: ../../../manim/utils/docbuild/manim_directive.py:docstring of manim.utils.docbuild.manim_directive:4 -msgid "When rendering the HTML documentation, the ``.. manim::`` directive implemented here allows to include rendered videos." -msgstr "" - -#: ../../../manim/utils/docbuild/manim_directive.py:docstring of manim.utils.docbuild.manim_directive:7 -msgid "Its basic usage that allows processing **inline content** looks as follows::" -msgstr "" - -#: ../../../manim/utils/docbuild/manim_directive.py:docstring of manim.utils.docbuild.manim_directive:16 -msgid "It is required to pass the name of the class representing the scene to be rendered to the directive." -msgstr "" - -#: ../../../manim/utils/docbuild/manim_directive.py:docstring of manim.utils.docbuild.manim_directive:19 -msgid "As a second application, the directive can also be used to render scenes that are defined within doctests, for example::" -msgstr "" - -#: ../../../manim/utils/docbuild/manim_directive.py:docstring of manim.utils.docbuild.manim_directive:35 -msgid "Options" -msgstr "" - -#: ../../../manim/utils/docbuild/manim_directive.py:docstring of manim.utils.docbuild.manim_directive:37 -msgid "Options can be passed as follows::" -msgstr "" - -#: ../../../manim/utils/docbuild/manim_directive.py:docstring of manim.utils.docbuild.manim_directive:42 -msgid "The following configuration options are supported by the directive:" -msgstr "" - -#: ../../../manim/utils/docbuild/manim_directive.py:docstring of manim.utils.docbuild.manim_directive:47 -msgid "hide_source" -msgstr "" - -#: ../../../manim/utils/docbuild/manim_directive.py:docstring of manim.utils.docbuild.manim_directive:46 -msgid "If this flag is present without argument, the source code is not displayed above the rendered video." -msgstr "" - -#: ../../../manim/utils/docbuild/manim_directive.py:docstring of manim.utils.docbuild.manim_directive:51 -msgid "quality" -msgstr "" - -#: ../../../manim/utils/docbuild/manim_directive.py:docstring of manim.utils.docbuild.manim_directive:None -msgid "{'low', 'medium', 'high', 'fourk'}" -msgstr "" - -#: ../../../manim/utils/docbuild/manim_directive.py:docstring of manim.utils.docbuild.manim_directive:50 -msgid "Controls render quality of the video, in analogy to the corresponding command line flags." -msgstr "" - -#: ../../../manim/utils/docbuild/manim_directive.py:docstring of manim.utils.docbuild.manim_directive:55 -msgid "save_as_gif" -msgstr "" - -#: ../../../manim/utils/docbuild/manim_directive.py:docstring of manim.utils.docbuild.manim_directive:54 -msgid "If this flag is present without argument, the scene is rendered as a gif." -msgstr "" - -#: ../../../manim/utils/docbuild/manim_directive.py:docstring of manim.utils.docbuild.manim_directive:60 -msgid "save_last_frame" -msgstr "" - -#: ../../../manim/utils/docbuild/manim_directive.py:docstring of manim.utils.docbuild.manim_directive:58 -msgid "If this flag is present without argument, an image representing the last frame of the scene will be rendered and displayed, instead of a video." -msgstr "" - -#: ../../../manim/utils/docbuild/manim_directive.py:docstring of manim.utils.docbuild.manim_directive:64 -msgid "ref_classes" -msgstr "" - -#: ../../../manim/utils/docbuild/manim_directive.py:docstring of manim.utils.docbuild.manim_directive:63 -msgid "A list of classes, separated by spaces, that is rendered in a reference block after the source code." -msgstr "" - -#: ../../../manim/utils/docbuild/manim_directive.py:docstring of manim.utils.docbuild.manim_directive:68 -msgid "ref_functions" -msgstr "" - -#: ../../../manim/utils/docbuild/manim_directive.py:docstring of manim.utils.docbuild.manim_directive:67 -msgid "A list of functions, separated by spaces, that is rendered in a reference block after the source code." -msgstr "" - -#: ../../../manim/utils/docbuild/manim_directive.py:docstring of manim.utils.docbuild.manim_directive:72 -msgid "ref_methods" -msgstr "" - -#: ../../../manim/utils/docbuild/manim_directive.py:docstring of manim.utils.docbuild.manim_directive:71 -msgid "A list of methods, separated by spaces, that is rendered in a reference block after the source code." -msgstr "" - -#: ../../source/reference/manim.utils.docbuild.manim_directive.rst:15 -msgid "Classes" -msgstr "" - -#: ../../source/reference/manim.utils.docbuild.manim_directive.rst:28::1 -msgid "The manim directive, rendering videos while building the documentation." -msgstr "" - -#: ../../source/reference/manim.utils.docbuild.manim_directive.rst:31 -msgid "Functions" -msgstr "" - -#: ../../../manim/utils/docbuild/manim_directive.py:docstring of manim.utils.docbuild.manim_directive.process_name_list:1 -msgid "Reformats a string of space separated class names as a list of strings containing valid Sphinx references." -msgstr "" - -#: ../../../manim/utils/docbuild/manim_directive.py:docstring of manim.utils.docbuild.manim_directive.process_name_list:5 -msgid "Tests" -msgstr "" - -#: ../../../manim/utils/docbuild/manim_directive.py:docstring of manim.utils.docbuild.manim_directive.process_name_list:0 -msgid "Parameters" -msgstr "" - - diff --git a/docs/i18n/gettext/reference/manim.utils.docbuild.manim_directive.skip_manim_node.pot b/docs/i18n/gettext/reference/manim.utils.docbuild.manim_directive.skip_manim_node.pot index 53a5e8abc8..8b13789179 100644 --- a/docs/i18n/gettext/reference/manim.utils.docbuild.manim_directive.skip_manim_node.pot +++ b/docs/i18n/gettext/reference/manim.utils.docbuild.manim_directive.skip_manim_node.pot @@ -1,65 +1 @@ -msgid "" -msgstr "" -"Project-Id-Version: Manim \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: ../../source/reference/manim.utils.docbuild.manim_directive.skip_manim_node.rst:2 -msgid "skip\\_manim\\_node" -msgstr "" - -#: ../../source/reference/manim.utils.docbuild.manim_directive.skip_manim_node.rst:4 -msgid "Qualified name: ``manim.utils.docbuild.manim\\_directive.skip\\_manim\\_node``" -msgstr "" - -#: ../../../manim/utils/docbuild/manim_directive.py:docstring of manim.utils.docbuild.manim_directive.skip_manim_node:1 -msgid "Bases: :py:class:`docutils.nodes.Admonition`, :py:class:`docutils.nodes.Element`" -msgstr "" - -#: ../../source/reference/manim.utils.docbuild.manim_directive.skip_manim_node.rst:14 -msgid "Methods" -msgstr "" - -#: ../../source/reference/manim.utils.docbuild.manim_directive.skip_manim_node.rst:21 -msgid "Attributes" -msgstr "" - -#: ../../source/reference/manim.utils.docbuild.manim_directive.skip_manim_node.rst:36::1 -msgid "List attributes which are defined for every Element-derived class instance and can be safely transferred to a different node." -msgstr "" - -#: ../../source/reference/manim.utils.docbuild.manim_directive.skip_manim_node.rst:36::1 -msgid "Separator for child nodes, used by `astext()` method." -msgstr "" - -#: ../../source/reference/manim.utils.docbuild.manim_directive.skip_manim_node.rst:36::1 -msgid "Return the `document` node at the root of the tree containing this Node." -msgstr "" - -#: ../../source/reference/manim.utils.docbuild.manim_directive.skip_manim_node.rst:36::1 -msgid "List attributes that are known to the Element base class." -msgstr "" - -#: ../../source/reference/manim.utils.docbuild.manim_directive.skip_manim_node.rst:36::1 -msgid "The line number (1-based) of the beginning of this Node in `source`." -msgstr "" - -#: ../../source/reference/manim.utils.docbuild.manim_directive.skip_manim_node.rst:36::1 -msgid "List attributes, automatically initialized to empty lists for all nodes." -msgstr "" - -#: ../../source/reference/manim.utils.docbuild.manim_directive.skip_manim_node.rst:36::1 -msgid "A list of class-specific attributes that should not be copied with the standard attributes when replacing a node." -msgstr "" - -#: ../../source/reference/manim.utils.docbuild.manim_directive.skip_manim_node.rst:36::1 -msgid "Back-reference to the Node immediately containing this Node." -msgstr "" - -#: ../../source/reference/manim.utils.docbuild.manim_directive.skip_manim_node.rst:36::1 -msgid "Path or description of the input source which generated this Node." -msgstr "" - - diff --git a/docs/i18n/gettext/reference/manim.utils.docbuild.pot b/docs/i18n/gettext/reference/manim.utils.docbuild.pot new file mode 100644 index 0000000000..d881a71ccf --- /dev/null +++ b/docs/i18n/gettext/reference/manim.utils.docbuild.pot @@ -0,0 +1,9 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Manim \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + + diff --git a/docs/i18n/gettext/reference/manim.utils.images.pot b/docs/i18n/gettext/reference/manim.utils.images.pot index 9d0b3d5973..0423696fe9 100644 --- a/docs/i18n/gettext/reference/manim.utils.images.pot +++ b/docs/i18n/gettext/reference/manim.utils.images.pot @@ -18,6 +18,10 @@ msgstr "" msgid "Functions" msgstr "" +#: ../../../manim/utils/images.py:docstring of manim.utils.images.change_to_rgba_array:1 +msgid "Converts an RGB array into RGBA with the alpha value opacity maxed." +msgstr "" + #: ../../../manim/utils/images.py:docstring of manim.utils.images.drag_pixels:0 #: ../../../manim/utils/images.py:docstring of manim.utils.images.get_full_raster_image_path:0 #: ../../../manim/utils/images.py:docstring of manim.utils.images.invert_image:0 diff --git a/docs/i18n/gettext/reference/manim.utils.ipython_magic.ManimMagic.pot b/docs/i18n/gettext/reference/manim.utils.ipython_magic.ManimMagic.pot index 1548a46a5c..778c678992 100644 --- a/docs/i18n/gettext/reference/manim.utils.ipython_magic.ManimMagic.pot +++ b/docs/i18n/gettext/reference/manim.utils.ipython_magic.ManimMagic.pot @@ -35,11 +35,6 @@ msgstr "" msgid "The parent Configurable instance of this object." msgstr "" -#: ../../../manim/utils/ipython_magic.py:docstring of manim.utils.ipython_magic.ManimMagic:0 -#: ../../../manim/utils/ipython_magic.py:docstring of manim.utils.ipython_magic.ManimMagic.manim:0 -msgid "Return type" -msgstr "" - #: ../../../manim/utils/ipython_magic.py:docstring of manim.utils.ipython_magic.ManimMagic:11 msgid "Notes" msgstr "" @@ -121,4 +116,8 @@ msgstr "" msgid "Evaluating this cell will render and display the ``BannerExample`` scene defined in the body of the cell." msgstr "" +#: ../../../manim/utils/ipython_magic.py:docstring of manim.utils.ipython_magic.ManimMagic.manim:68 +msgid "In case you want to hide the red box containing the output progress bar, the ``progress_bar`` config option should be set to ``None``. This can also be done by passing ``--progress_bar None`` as a CLI flag." +msgstr "" + diff --git a/docs/i18n/gettext/reference/manim.utils.iterables.pot b/docs/i18n/gettext/reference/manim.utils.iterables.pot index 551d7bb73a..442b4d673c 100644 --- a/docs/i18n/gettext/reference/manim.utils.iterables.pot +++ b/docs/i18n/gettext/reference/manim.utils.iterables.pot @@ -18,12 +18,201 @@ msgstr "" msgid "Functions" msgstr "" +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.adjacent_n_tuples:1 +msgid "Returns the Sequence objects cyclically split into n length tuples." +msgstr "" + +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.adjacent_n_tuples:6 +msgid "alias with n=2" +msgstr "" + +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.adjacent_n_tuples:9 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.adjacent_pairs:6 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.batch_by_property:8 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.concatenate_lists:4 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.list_difference_update:4 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.list_update:6 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.listify:4 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.make_even:10 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.make_even_by_cycling:10 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.remove_nones:4 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.resize_array:13 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.resize_preserving_order:16 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.resize_with_interpolation:16 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.tuplify:4 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.uniq_chain:5 +msgid "Examples" +msgstr "" + +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.adjacent_n_tuples:10 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.adjacent_pairs:7 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.batch_by_property:9 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.concatenate_lists:5 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.list_difference_update:5 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.list_update:7 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.listify:5 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.make_even:11 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.make_even_by_cycling:11 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.remove_nones:5 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.resize_array:14 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.resize_preserving_order:17 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.resize_with_interpolation:17 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.tuplify:5 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.uniq_chain:6 +msgid "Normal usage::" +msgstr "" + +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.adjacent_n_tuples:0 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.adjacent_pairs:0 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.all_elements_are_instances:0 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.batch_by_property:0 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.concatenate_lists:0 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.list_difference_update:0 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.list_update:0 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.make_even:0 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.make_even_by_cycling:0 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.remove_list_redundancies:0 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.remove_nones:0 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.resize_array:0 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.resize_preserving_order:0 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.resize_with_interpolation:0 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.stretch_array_to_length:0 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.uniq_chain:0 +msgid "Parameters" +msgstr "" + +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.adjacent_n_tuples:0 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.adjacent_pairs:0 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.all_elements_are_instances:0 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.batch_by_property:0 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.concatenate_lists:0 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.list_difference_update:0 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.list_update:0 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.listify:0 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.make_even:0 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.make_even_by_cycling:0 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.remove_list_redundancies:0 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.remove_nones:0 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.resize_array:0 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.resize_preserving_order:0 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.resize_with_interpolation:0 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.stretch_array_to_length:0 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.tuplify:0 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.uniq_chain:0 +msgid "Return type" +msgstr "" + +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.adjacent_pairs:1 +msgid "Alias for ``adjacent_n_tuples(objects, 2)``." +msgstr "" + +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.all_elements_are_instances:1 +msgid "Returns ``True`` if all elements of iterable are instances of Class. False otherwise." +msgstr "" + #: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.batch_by_property:1 -msgid "Takes in a list, and returns a list of tuples, (batch, prop) such that all items in a batch have the same output when put into property_func, and such that chaining all these batches together would give the original list (i.e. order is preserved)" +msgid "Takes in a Sequence, and returns a list of tuples, (batch, prop) such that all items in a batch have the same output when put into the Callable property_func, and such that chaining all these batches together would give the original Sequence (i.e. order is preserved)." +msgstr "" + +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.concatenate_lists:1 +msgid "Combines the Iterables provided as arguments into one list." +msgstr "" + +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.list_difference_update:1 +msgid "Returns a list containing all the elements of l1 not in l2." +msgstr "" + +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.list_update:3 +msgid "Used instead of ``set.update()`` to maintain order," +msgstr "" + +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.list_update:2 +msgid "making sure duplicates are removed from l1, not l2. Removes overlap of l1 and l2 and then concatenates l2 unchanged." +msgstr "" + +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.listify:1 +msgid "Converts obj to a list intelligently." +msgstr "" + +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.make_even:2 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.make_even_by_cycling:2 +msgid "Extends the shorter of the two iterables with duplicate values until its" +msgstr "" + +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.make_even:2 +msgid "length is equal to the longer iterable (favours earlier elements)." +msgstr "" + +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.make_even:7 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.resize_preserving_order:10 +msgid "cycles elements instead of favouring earlier ones" +msgstr "" + +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.make_even_by_cycling:2 +msgid "length is equal to the longer iterable (cycles over shorter iterable)." +msgstr "" + +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.make_even_by_cycling:7 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.resize_array:7 +msgid "favours earlier elements instead of cycling them" +msgstr "" + +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.remove_list_redundancies:1 +msgid "Used instead of ``list(set(l))`` to maintain order. Keeps the last occurrence of each element." +msgstr "" + +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.remove_nones:1 +msgid "Removes elements where bool(x) evaluates to False." +msgstr "" + +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.resize_array:2 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.resize_preserving_order:5 +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.resize_with_interpolation:5 +msgid "Extends/truncates nparray so that ``len(result) == length``." +msgstr "" + +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.resize_array:2 +msgid "The elements of nparray are cycled to achieve the desired length." +msgstr "" + +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.resize_array:10 +msgid "similar cycling behaviour for balancing 2 iterables" +msgstr "" + +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.resize_preserving_order:2 +msgid "The elements of nparray are duplicated to achieve the desired length (favours earlier elements)." +msgstr "" + +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.resize_preserving_order:5 +msgid "Constructs a zeroes array of length if nparray is empty." +msgstr "" + +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.resize_preserving_order:13 +msgid "similar earlier-favouring behaviour for balancing 2 iterables" +msgstr "" + +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.resize_with_interpolation:2 +msgid "New elements are interpolated to achieve the desired length." +msgstr "" + +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.resize_with_interpolation:4 +msgid "Note that if nparray's length changes, its dtype may too (e.g. int -> float: see Examples)" +msgstr "" + +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.resize_with_interpolation:10 +msgid "cycles elements instead of interpolating" +msgstr "" + +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.resize_with_interpolation:13 +msgid "favours earlier elements instead of interpolating" +msgstr "" + +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.tuplify:1 +msgid "Converts obj to a tuple intelligently." msgstr "" -#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.list_update:1 -msgid "Used instead of list(set(l1).update(l2)) to maintain order, making sure duplicates are removed from l1, not l2." +#: ../../../manim/utils/iterables.py:docstring of manim.utils.iterables.uniq_chain:2 +msgid "Returns a generator that yields all unique elements of the Iterables" msgstr "" diff --git a/docs/i18n/gettext/reference/manim.utils.simple_functions.pot b/docs/i18n/gettext/reference/manim.utils.simple_functions.pot index 2639ffa55a..9c39b35b23 100644 --- a/docs/i18n/gettext/reference/manim.utils.simple_functions.pot +++ b/docs/i18n/gettext/reference/manim.utils.simple_functions.pot @@ -14,4 +14,89 @@ msgstr "" msgid "A collection of simple functions." msgstr "" +#: ../../source/reference/manim.utils.simple_functions.rst:20 +msgid "Functions" +msgstr "" + +#: ../../../manim/utils/simple_functions.py:docstring of manim.utils.simple_functions.binary_search:1 +msgid "Searches for a value in a range by repeatedly dividing the range in half." +msgstr "" + +#: ../../../manim/utils/simple_functions.py:docstring of manim.utils.simple_functions.binary_search:3 +msgid "To be more precise, performs numerical binary search to determine the input to ``function``, between the bounds given, that outputs ``target`` to within ``tolerance`` (default of 0.0001). Returns ``None`` if no input can be found within the bounds." +msgstr "" + +#: ../../../manim/utils/simple_functions.py:docstring of manim.utils.simple_functions.binary_search:9 +#: ../../../manim/utils/simple_functions.py:docstring of manim.utils.simple_functions.clip:8 +#: ../../../manim/utils/simple_functions.py:docstring of manim.utils.simple_functions.get_parameters:5 +msgid "Examples" +msgstr "" + +#: ../../../manim/utils/simple_functions.py:docstring of manim.utils.simple_functions.binary_search:10 +msgid "Consider the polynomial :math:`x^2 + 3x + 1` where we search for a target value of :math:`11`. An exact solution is :math:`x = 2`." +msgstr "" + +#: ../../../manim/utils/simple_functions.py:docstring of manim.utils.simple_functions.binary_search:22 +msgid "Searching in the interval :math:`[0, 5]` for a target value of :math:`71` does not yield a solution::" +msgstr "" + +#: ../../../manim/utils/simple_functions.py:docstring of manim.utils.simple_functions.binary_search:0 +#: ../../../manim/utils/simple_functions.py:docstring of manim.utils.simple_functions.choose:0 +#: ../../../manim/utils/simple_functions.py:docstring of manim.utils.simple_functions.get_parameters:0 +#: ../../../manim/utils/simple_functions.py:docstring of manim.utils.simple_functions.sigmoid:0 +msgid "Parameters" +msgstr "" + +#: ../../../manim/utils/simple_functions.py:docstring of manim.utils.simple_functions.binary_search:0 +#: ../../../manim/utils/simple_functions.py:docstring of manim.utils.simple_functions.choose:0 +#: ../../../manim/utils/simple_functions.py:docstring of manim.utils.simple_functions.get_parameters:0 +#: ../../../manim/utils/simple_functions.py:docstring of manim.utils.simple_functions.sigmoid:0 +msgid "Return type" +msgstr "" + +#: ../../../manim/utils/simple_functions.py:docstring of manim.utils.simple_functions.choose:1 +msgid "The binomial coefficient n choose k." +msgstr "" + +#: ../../../manim/utils/simple_functions.py:docstring of manim.utils.simple_functions.choose:3 +msgid ":math:`\\binom{n}{k}` describes the number of possible choices of :math:`k` elements from a set of :math:`n` elements." +msgstr "" + +#: ../../../manim/utils/simple_functions.py:docstring of manim.utils.simple_functions.choose:7 +#: ../../../manim/utils/simple_functions.py:docstring of manim.utils.simple_functions.sigmoid:7 +msgid "References" +msgstr "" + +#: ../../../manim/utils/simple_functions.py:docstring of manim.utils.simple_functions.choose:8 +msgid "https://en.wikipedia.org/wiki/Combination" +msgstr "" + +#: ../../../manim/utils/simple_functions.py:docstring of manim.utils.simple_functions.choose:9 +msgid "https://docs.scipy.org/doc/scipy/reference/generated/scipy.special.comb.html" +msgstr "" + +#: ../../../manim/utils/simple_functions.py:docstring of manim.utils.simple_functions.clip:1 +msgid "Clips ``a`` to the interval [``min_a``, ``max_a``]." +msgstr "" + +#: ../../../manim/utils/simple_functions.py:docstring of manim.utils.simple_functions.clip:3 +msgid "Accepts any comparable objects (i.e. those that support <, >). Returns ``a`` if it is between ``min_a`` and ``max_a``. Otherwise, whichever of ``min_a`` and ``max_a`` is closest." +msgstr "" + +#: ../../../manim/utils/simple_functions.py:docstring of manim.utils.simple_functions.get_parameters:1 +msgid "Return the parameters of ``function`` as an ordered mapping of parameters' names to their corresponding ``Parameter`` objects." +msgstr "" + +#: ../../../manim/utils/simple_functions.py:docstring of manim.utils.simple_functions.sigmoid:1 +msgid "Returns the output of the logistic function." +msgstr "" + +#: ../../../manim/utils/simple_functions.py:docstring of manim.utils.simple_functions.sigmoid:3 +msgid "The logistic function, a common example of a sigmoid function, is defined as :math:`\\frac{1}{1 + e^{-x}}`." +msgstr "" + +#: ../../../manim/utils/simple_functions.py:docstring of manim.utils.simple_functions.sigmoid:8 +msgid "https://en.wikipedia.org/wiki/Sigmoid_function" +msgstr "" + diff --git a/docs/i18n/gettext/reference_index/animations.pot b/docs/i18n/gettext/reference_index/animations.pot index fac595137d..406b4afeea 100644 --- a/docs/i18n/gettext/reference_index/animations.pot +++ b/docs/i18n/gettext/reference_index/animations.pot @@ -10,51 +10,55 @@ msgstr "" msgid "Animations" msgstr "" -#: ../../source/reference_index/animations.rst:22::1 +#: ../../source/reference_index/animations.rst:23::1 msgid "Animate mobjects." msgstr "" -#: ../../source/reference_index/animations.rst:22::1 +#: ../../source/reference_index/animations.rst:23::1 msgid "Animation of a mobject boundary and tracing of points." msgstr "" -#: ../../source/reference_index/animations.rst:22::1 +#: ../../source/reference_index/animations.rst:23::1 msgid "Tools for displaying multiple animations at once." msgstr "" -#: ../../source/reference_index/animations.rst:22::1 +#: ../../source/reference_index/animations.rst:23::1 msgid "Animate the display or removal of a mobject from a scene." msgstr "" -#: ../../source/reference_index/animations.rst:22::1 +#: ../../source/reference_index/animations.rst:23::1 msgid "Fading in and out of view." msgstr "" -#: ../../source/reference_index/animations.rst:22::1 +#: ../../source/reference_index/animations.rst:23::1 msgid "Animations that introduce mobjects to scene by growing them from points." msgstr "" -#: ../../source/reference_index/animations.rst:22::1 +#: ../../source/reference_index/animations.rst:23::1 msgid "Animations drawing attention to particular mobjects." msgstr "" -#: ../../source/reference_index/animations.rst:22::1 +#: ../../source/reference_index/animations.rst:23::1 msgid "Animations related to movement." msgstr "" -#: ../../source/reference_index/animations.rst:22::1 +#: ../../source/reference_index/animations.rst:23::1 msgid "Animations for changing numbers." msgstr "" -#: ../../source/reference_index/animations.rst:22::1 +#: ../../source/reference_index/animations.rst:23::1 msgid "Animations related to rotation." msgstr "" -#: ../../source/reference_index/animations.rst:22::1 +#: ../../source/reference_index/animations.rst:23::1 +msgid "Utilities for modifying the speed at which animations are played." +msgstr "" + +#: ../../source/reference_index/animations.rst:23::1 msgid "Animations transforming one mobject into another." msgstr "" -#: ../../source/reference_index/animations.rst:22::1 +#: ../../source/reference_index/animations.rst:23::1 msgid "Animations that try to transform Mobjects while keeping track of identical parts." msgstr "" diff --git a/docs/i18n/gettext/reference_index/mobjects.pot b/docs/i18n/gettext/reference_index/mobjects.pot index 81a4b653f8..8fe6870a0b 100644 --- a/docs/i18n/gettext/reference_index/mobjects.pot +++ b/docs/i18n/gettext/reference_index/mobjects.pot @@ -10,52 +10,56 @@ msgstr "" msgid "Mobjects" msgstr "" -#: ../../source/reference_index/mobjects.rst:21::1 +#: ../../source/reference_index/mobjects.rst:22::1 msgid "Special rectangles." msgstr "" -#: ../../source/reference_index/mobjects.rst:21::1 +#: ../../source/reference_index/mobjects.rst:22::1 msgid "Various geometric Mobjects." msgstr "" -#: ../../source/reference_index/mobjects.rst:21::1 +#: ../../source/reference_index/mobjects.rst:22::1 msgid "Mobjects used to represent mathematical graphs (think graph theory, not plotting)." msgstr "" -#: ../../source/reference_index/mobjects.rst:21::1 +#: ../../source/reference_index/mobjects.rst:22::1 msgid "Coordinate systems and function graphing related mobjects." msgstr "" -#: ../../source/reference_index/mobjects.rst:21::1 +#: ../../source/reference_index/mobjects.rst:22::1 msgid "Utilities for Manim's logo and banner." msgstr "" -#: ../../source/reference_index/mobjects.rst:21::1 +#: ../../source/reference_index/mobjects.rst:22::1 msgid "Mobjects representing matrices." msgstr "" -#: ../../source/reference_index/mobjects.rst:21::1 +#: ../../source/reference_index/mobjects.rst:22::1 msgid "Base classes for objects that can be displayed." msgstr "" -#: ../../source/reference_index/mobjects.rst:21::1 +#: ../../source/reference_index/mobjects.rst:22::1 msgid "Mobjects related to SVG images." msgstr "" -#: ../../source/reference_index/mobjects.rst:21::1 +#: ../../source/reference_index/mobjects.rst:22::1 msgid "Mobjects representing tables." msgstr "" -#: ../../source/reference_index/mobjects.rst:21::1 +#: ../../source/reference_index/mobjects.rst:22::1 msgid "Mobjects used to display Text using Pango or LaTeX." msgstr "" -#: ../../source/reference_index/mobjects.rst:21::1 +#: ../../source/reference_index/mobjects.rst:22::1 msgid "Three-dimensional mobjects." msgstr "" -#: ../../source/reference_index/mobjects.rst:21::1 +#: ../../source/reference_index/mobjects.rst:22::1 msgid "Specialized mobject base classes." msgstr "" +#: ../../source/reference_index/mobjects.rst:22::1 +msgid "Simple mobjects that can be used for storing (and updating) a value." +msgstr "" + diff --git a/docs/i18n/gettext/reference_index/utilities_misc.pot b/docs/i18n/gettext/reference_index/utilities_misc.pot index 73a1550386..f17bc661a1 100644 --- a/docs/i18n/gettext/reference_index/utilities_misc.pot +++ b/docs/i18n/gettext/reference_index/utilities_misc.pot @@ -14,71 +14,71 @@ msgstr "" msgid "Module Index" msgstr "" -#: ../../source/reference_index/utilities_misc.rst:30::1 +#: ../../source/reference_index/utilities_misc.rst:31::1 msgid "Constant definitions." msgstr "" -#: ../../source/reference_index/utilities_misc.rst:30::1 +#: ../../source/reference_index/utilities_misc.rst:31::1 msgid "Utility functions related to Bézier curves." msgstr "" -#: ../../source/reference_index/utilities_misc.rst:30::1 +#: ../../source/reference_index/utilities_misc.rst:31::1 msgid "Colors and utility functions for conversion between different color models." msgstr "" -#: ../../source/reference_index/utilities_misc.rst:30::1 +#: ../../source/reference_index/utilities_misc.rst:31::1 msgid "Utilities that might be useful for configuration dictionaries." msgstr "" -#: ../../source/reference_index/utilities_misc.rst:30::1 +#: ../../source/reference_index/utilities_misc.rst:31::1 msgid "Decorators for deprecating classes, functions and function parameters." msgstr "" -#: ../../source/reference_index/utilities_misc.rst:30::1 +#: ../../source/reference_index/utilities_misc.rst:31::1 msgid "Debugging utilities." msgstr "" -#: ../../source/reference_index/utilities_misc.rst:30::1 +#: ../../source/reference_index/utilities_misc.rst:31::1 msgid "Utilities for scene caching." msgstr "" -#: ../../source/reference_index/utilities_misc.rst:30::1 +#: ../../source/reference_index/utilities_misc.rst:31::1 msgid "Utilities for using Manim with IPython (in particular: Jupyter notebooks)" msgstr "" -#: ../../source/reference_index/utilities_misc.rst:30::1 +#: ../../source/reference_index/utilities_misc.rst:31::1 msgid "Image manipulation utilities." msgstr "" -#: ../../source/reference_index/utilities_misc.rst:30::1 +#: ../../source/reference_index/utilities_misc.rst:31::1 msgid "Operations on iterables." msgstr "" -#: ../../source/reference_index/utilities_misc.rst:30::1 +#: ../../source/reference_index/utilities_misc.rst:31::1 msgid "Functions determining transformation paths between sets of points." msgstr "" -#: ../../source/reference_index/utilities_misc.rst:30::1 +#: ../../source/reference_index/utilities_misc.rst:31::1 msgid "A selection of rate functions, i.e., *speed curves* for animations." msgstr "" -#: ../../source/reference_index/utilities_misc.rst:30::1 +#: ../../source/reference_index/utilities_misc.rst:31::1 msgid "A collection of simple functions." msgstr "" -#: ../../source/reference_index/utilities_misc.rst:30::1 +#: ../../source/reference_index/utilities_misc.rst:31::1 msgid "Sound-related utility functions." msgstr "" -#: ../../source/reference_index/utilities_misc.rst:30::1 +#: ../../source/reference_index/utilities_misc.rst:31::1 msgid "Utility functions for two- and three-dimensional vectors." msgstr "" -#: ../../source/reference_index/utilities_misc.rst:30::1 +#: ../../source/reference_index/utilities_misc.rst:31::1 msgid "Utilities for processing LaTeX templates." msgstr "" -#: ../../source/reference_index/utilities_misc.rst:30::1 +#: ../../source/reference_index/utilities_misc.rst:31::1 msgid "A library of LaTeX templates." msgstr "" diff --git a/docs/i18n/gettext/reporting_bugs.pot b/docs/i18n/gettext/reporting_bugs.pot index af1af500db..8b13789179 100644 --- a/docs/i18n/gettext/reporting_bugs.pot +++ b/docs/i18n/gettext/reporting_bugs.pot @@ -1,41 +1 @@ -msgid "" -msgstr "" -"Project-Id-Version: Manim \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: ../../source/reporting_bugs.rst:2 -msgid "Reporting bugs" -msgstr "" - -#: ../../source/reporting_bugs.rst:4 -msgid "One of the best ways of contributing to Manim is by reporting bugs. If you have encountered something that you believe is a bug, please follow these steps:" -msgstr "" - -#: ../../source/reporting_bugs.rst:8 -msgid "First of all, make sure you are running the latest version of manim. If not, update your version and try again." -msgstr "" - -#: ../../source/reporting_bugs.rst:11 -msgid "Search for other users who may have had similar issues in the past. Search the repository's `issues page `_ (don't forget to search closed issues), bring it up on our `Discord server `_, use sites like StackOverflow, and exercise your best Google practices. If you can't find anything helpful, then go to the next step." -msgstr "" - -#: ../../source/reporting_bugs.rst:17 -msgid "Can reproduce the issue, i.e. that you have some code that illustrates the bug **every time** (or at least most of the time) it is executed." -msgstr "" - -#: ../../source/reporting_bugs.rst:21 -msgid "Clarify what behavior you expected, and how the actual behavior differs from your expectation." -msgstr "" - -#: ../../source/reporting_bugs.rst:24 -msgid "Gather information about your environment, such as your operating system, python version, and any stack traces that the code may have generated (if applicable)." -msgstr "" - -#: ../../source/reporting_bugs.rst:28 -msgid "Please open an issue only after you have gathered this information. When submitting an issue, make sure to follow the template (this is the default text you are shown when first opening the 'New Issue' page). A community member will (hopefully) respond and start a conversation to address the issue." -msgstr "" - - diff --git a/docs/i18n/gettext/tutorials.pot b/docs/i18n/gettext/tutorials.pot index a62dc41cf8..8b13789179 100644 --- a/docs/i18n/gettext/tutorials.pot +++ b/docs/i18n/gettext/tutorials.pot @@ -1,14 +1 @@ -msgid "" -msgstr "" -"Project-Id-Version: Manim \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: ../../source/tutorials.rst:4 -#: ../../source/tutorials.rst:4 -msgid "Table of Contents" -msgstr "" - - diff --git a/docs/i18n/gettext/tutorials/a_deeper_look.pot b/docs/i18n/gettext/tutorials/a_deeper_look.pot index aa77b8257a..8b13789179 100644 --- a/docs/i18n/gettext/tutorials/a_deeper_look.pot +++ b/docs/i18n/gettext/tutorials/a_deeper_look.pot @@ -1,129 +1 @@ -msgid "" -msgstr "" -"Project-Id-Version: Manim \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: ../../source/tutorials/a_deeper_look.rst:2 -msgid "A deeper look" -msgstr "" - -#: ../../source/tutorials/a_deeper_look.rst:4 -msgid "This document will focus on understanding manim's output files and some of the main command-line flags available." -msgstr "" - -#: ../../source/tutorials/a_deeper_look.rst:7 -msgid "This tutorial picks up where :doc:`quickstart` left off, so please read that document before starting this one." -msgstr "" - -#: ../../source/tutorials/a_deeper_look.rst:11 -msgid "Manim output folders" -msgstr "" - -#: ../../source/tutorials/a_deeper_look.rst:13 -msgid "At this point, you have just executed the following command." -msgstr "" - -#: ../../source/tutorials/a_deeper_look.rst:19 -msgid "Let's dissect what just happened step by step. First, this command executes manim on the file ``scene.py``, which contains our animation code. Further, this command tells manim exactly which ``Scene`` is to be rendered, in this case, it is ``SquareToCircle``. This is necessary because a single scene file may contain more than one scene. Next, the flag `-p` tells manim to play the scene once it's rendered, and the `-ql` flag tells manim to render the scene in low quality." -msgstr "" - -#: ../../source/tutorials/a_deeper_look.rst:27 -msgid "After the video is rendered, you will see that manim has generated some new files and the project folder will look as follows." -msgstr "" - -#: ../../source/tutorials/a_deeper_look.rst:44 -msgid "There are quite a few new files. The main output is in ``media/videos/scene/480p15/SquareToCircle.mp4``. By default, the ``media`` folder will contain all of manim's output files. The ``media/videos`` subfolder contains the rendered videos. Inside of it, you will find one folder for each different video quality. In our case, since we used the ``-l`` flag, the video was generated at 480 resolution at 15 frames per second from the ``scene.py`` file. Therefore, the output can be found inside ``media/videos/scene/480p15``. The additional folders ``media/videos/scene/480p15/partial_movie_files`` as well as ``media/text`` and ``media/Tex`` contain files that are used by manim internally." -msgstr "" - -#: ../../source/tutorials/a_deeper_look.rst:55 -msgid "You can see how manim makes use of the generated folder structure by executing the following command," -msgstr "" - -#: ../../source/tutorials/a_deeper_look.rst:62 -msgid "The ``-ql`` flag (for low quality) has been replaced by the ``-qh`` flag, for high quality. Manim will take considerably longer to render this file, and it will play it once it's done since we are using the ``-p`` flag. The output should look like this:" -msgstr "" - -#: ../../source/tutorials/a_deeper_look.rst:84 -msgid "And the folder structure should look as follows." -msgstr "" - -#: ../../source/tutorials/a_deeper_look.rst:102 -msgid "Manim has created a new folder ``media/videos/1080p60``, which corresponds to the high resolution and the 60 frames per second. Inside of it, you can find the new ``SquareToCircle.mp4``, as well as the corresponding ``partial_movie_files``." -msgstr "" - -#: ../../source/tutorials/a_deeper_look.rst:107 -msgid "When working on a project with multiple scenes, and trying out multiple resolutions, the structure of the output directories will keep all your videos organized." -msgstr "" - -#: ../../source/tutorials/a_deeper_look.rst:111 -msgid "Further, manim has the option to output the last frame of a scene, when adding the flag ``-s``. This is the fastest option to quickly get a preview of a scene. The corresponding folder structure looks like this:" -msgstr "" - -#: ../../source/tutorials/a_deeper_look.rst:134 -msgid "Saving the last frame with ``-s`` can be combined with the flags for different resolutions, e.g. ``-s -ql``, ``-s -qh``" -msgstr "" - -#: ../../source/tutorials/a_deeper_look.rst:141 -msgid "Sections" -msgstr "" - -#: ../../source/tutorials/a_deeper_look.rst:143 -msgid "In addition to the movie output file one can use sections. Each section produces its own output video. The cuts between two sections can be set like this:" -msgstr "" - -#: ../../source/tutorials/a_deeper_look.rst:157 -msgid "All the animations between two of these cuts get concatenated into a single output video file. Be aware that you need at least one animation in each section. For example this wouldn't create an output video:" -msgstr "" - -#: ../../source/tutorials/a_deeper_look.rst:171 -msgid "One way of fixing this is to wait a little:" -msgstr "" - -#: ../../source/tutorials/a_deeper_look.rst:182 -msgid "For videos to be created for each section you have to add the ``--save_sections`` flag to the Manim call like this:" -msgstr "" - -#: ../../source/tutorials/a_deeper_look.rst:188 -msgid "If you do this, the ``media`` folder will look like this:" -msgstr "" - -#: ../../source/tutorials/a_deeper_look.rst:214 -msgid "As you can see each section receives their own output video in the ``sections`` directory. The JSON file in here contains some useful information for each section:" -msgstr "" - -#: ../../source/tutorials/a_deeper_look.rst:255 -msgid "This data can be used by third party applications, like a presentation system or automated video editing tool." -msgstr "" - -#: ../../source/tutorials/a_deeper_look.rst:257 -msgid "You can also skip rendering all animations belonging to a section like this:" -msgstr "" - -#: ../../source/tutorials/a_deeper_look.rst:271 -msgid "Some command line flags" -msgstr "" - -#: ../../source/tutorials/a_deeper_look.rst:273 -msgid "When executing the command" -msgstr "" - -#: ../../source/tutorials/a_deeper_look.rst:279 -msgid "it was necessary to specify which ``Scene`` class to render. This is because a single file can contain more than one ``Scene`` class. If your file contains multiple ``Scene`` classes, and you want to render them all, you can use the ``-a`` flag." -msgstr "" - -#: ../../source/tutorials/a_deeper_look.rst:284 -msgid "As discussed previously, the ``-ql`` specifies low render quality. This does not look very good, but is very useful for rapid prototyping and testing. The other options that specify render quality are ``-qm``, ``-qh``, and ``-qk`` for medium, high, and 4k quality, respectively." -msgstr "" - -#: ../../source/tutorials/a_deeper_look.rst:289 -msgid "The ``-p`` flag plays the animation once it is rendered. If you want to open the file browser at the location of the animation instead of playing it, you can use the ``-f`` flag. You can also omit these two flags." -msgstr "" - -#: ../../source/tutorials/a_deeper_look.rst:293 -msgid "Finally, by default manim will output .mp4 files. If you want your animations in .gif format instead, use the ``-i`` flag. The output files will be in the same folder as the .mp4 files, and with the same name, but a different file extension." -msgstr "" - - diff --git a/docs/i18n/gettext/tutorials/building_blocks.pot b/docs/i18n/gettext/tutorials/building_blocks.pot index 705f5f83b9..21212cdc0e 100644 --- a/docs/i18n/gettext/tutorials/building_blocks.pot +++ b/docs/i18n/gettext/tutorials/building_blocks.pot @@ -19,7 +19,7 @@ msgid "Essentially, manim puts at your disposal three different concepts that yo msgstr "" #: ../../source/tutorials/building_blocks.rst:15 -msgid "It is recommended that you read the tutorials :doc:`quickstart` and :doc:`a_deeper_look` before reading this page." +msgid "It is recommended that you read the tutorials :doc:`quickstart` and :doc:`output_and_config` before reading this page." msgstr "" #: ../../source/tutorials/building_blocks.rst:21 diff --git a/docs/i18n/gettext/tutorials/configuration.pot b/docs/i18n/gettext/tutorials/configuration.pot index 568f12b2ba..8b13789179 100644 --- a/docs/i18n/gettext/tutorials/configuration.pot +++ b/docs/i18n/gettext/tutorials/configuration.pot @@ -1,301 +1 @@ -msgid "" -msgstr "" -"Project-Id-Version: Manim \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: ../../source/tutorials/configuration.rst:2 -msgid "Configuration" -msgstr "" - -#: ../../source/tutorials/configuration.rst:4 -msgid "Manim provides an extensive configuration system that allows it to adapt to many different use cases. There are many configuration options that can be configured at different times during the scene rendering process. Each option can be configured programmatically via `the ManimConfig class`_, at the time of command invocation via `command-line arguments`_, or at the time the library is first imported via `the config files`_." -msgstr "" - -#: ../../source/tutorials/configuration.rst:11 -msgid "The most common, simplest and recommended way to set the configure Manim is via the command-line interface (CLI), which is described directly below." -msgstr "" - -#: ../../source/tutorials/configuration.rst:15 -msgid "Command-line arguments" -msgstr "" - -#: ../../source/tutorials/configuration.rst:17 -msgid "By far the most commonly used command in the CLI is the ``render`` command, which is used to render scene(s) to an output file. It is used with the following arguments:" -msgstr "" - -#: ../../source/tutorials/configuration.rst:24 -msgid "However, since manim defaults to the :code:`render` command whenever no command is specified, the following form is far more common and can be used instead:" -msgstr "" - -#: ../../source/tutorials/configuration.rst:31 -msgid "An example of using the above form is:" -msgstr "" - -#: ../../source/tutorials/configuration.rst:37 -msgid "This asks manim to search for a Scene class called :code:`SceneOne` inside the file ``file.py`` and render it with medium quality (specified by the ``-qm`` flag)." -msgstr "" - -#: ../../source/tutorials/configuration.rst:40 -msgid "Another frequently used flag is ``-p`` (\"preview\"), which makes manim open the rendered video after it's done rendering." -msgstr "" - -#: ../../source/tutorials/configuration.rst:43 -msgid "The ``-p`` flag does not change any properties of the global ``config`` dict. The ``-p`` flag is only a command-line convenience." -msgstr "" - -#: ../../source/tutorials/configuration.rst:47 -msgid "Advanced examples" -msgstr "" - -#: ../../source/tutorials/configuration.rst:49 -msgid "To render a scene in high quality, but only output the last frame of the scene instead of the whole video, you can execute" -msgstr "" - -#: ../../source/tutorials/configuration.rst:56 -msgid "The following example specifies the output file name (with the :code:`-o` flag), renders only the first ten animations (:code:`-n` flag) with a white background (:code:`-c` flag), and saves the animation as a ``.gif`` instead of as a ``.mp4`` file (``--format=gif`` flag). It uses the default quality and does not try to open the file after it is rendered." -msgstr "" - -#: ../../source/tutorials/configuration.rst:67 -msgid "A list of all CLI flags" -msgstr "" - -#: ../../source/tutorials/configuration.rst:75 -msgid "The ManimConfig class" -msgstr "" - -#: ../../source/tutorials/configuration.rst:77 -msgid "The most direct way of configuring manim is through the global ``config`` object, which is an instance of :class:`.ManimConfig`. Each property of this class is a config option that can be accessed either with standard attribute syntax or with dict-like syntax:" -msgstr "" - -#: ../../source/tutorials/configuration.rst:88 -msgid "The former is preferred; the latter is provided for backwards compatibility." -msgstr "" - -#: ../../source/tutorials/configuration.rst:91 -msgid "Most classes, including :class:`.Camera`, :class:`.Mobject`, and :class:`.Animation`, read some of their default configuration from the global ``config``." -msgstr "" - -#: ../../source/tutorials/configuration.rst:103 -msgid ":class:`.ManimConfig` is designed to keep internal consistency. For example, setting ``frame_y_radius`` will affect ``frame_height``:" -msgstr "" - -#: ../../source/tutorials/configuration.rst:114 -msgid "The global ``config`` object is meant to be the single source of truth for all config options. All of the other ways of setting config options ultimately change the values of the global ``config`` object." -msgstr "" - -#: ../../source/tutorials/configuration.rst:118 -msgid "The following example illustrates the video resolution chosen for examples rendered in our documentation with a reference frame." -msgstr "" - -#: ../../source/tutorials/configuration.rst:140 -msgid "The config files" -msgstr "" - -#: ../../source/tutorials/configuration.rst:142 -msgid "As the last example shows, executing manim from the command-line may involve using many flags at the same time. This may become a nuisance if you must execute the same script many times in a short time period, for example when making small incremental tweaks to your scene script. For this reason, manim can also be configured using a configuration file. A configuration file is a file ending with the suffix ``.cfg``." -msgstr "" - -#: ../../source/tutorials/configuration.rst:149 -msgid "To use a local configuration file when rendering your scene, you must create a file with name ``manim.cfg`` in the same directory as your scene code." -msgstr "" - -#: ../../source/tutorials/configuration.rst:152 -msgid "The config file **must** be named ``manim.cfg``. Currently, manim does not support config files with any other name." -msgstr "" - -#: ../../source/tutorials/configuration.rst:155 -msgid "The config file must start with the section header ``[CLI]``. The configuration options under this header have the same name as the CLI flags, and serve the same purpose. Take for example the following config file." -msgstr "" - -#: ../../source/tutorials/configuration.rst:167 -msgid "Config files are parsed with the standard python library ``configparser``. In particular, they will ignore any line that starts with a pound symbol ``#``." -msgstr "" - -#: ../../source/tutorials/configuration.rst:170 -msgid "Now, executing the following command" -msgstr "" - -#: ../../source/tutorials/configuration.rst:176 -msgid "is equivalent to executing the following command, provided that ``manim.cfg`` is in the same directory as ," -msgstr "" - -#: ../../source/tutorials/configuration.rst:183 -msgid "The names of the configuration options admissible in config files are exactly the same as the **long names** of the corresponding command- line flags. For example, the ``-c`` and ``--background_color`` flags are interchangeable, but the config file only accepts :code:`background_color` as an admissible option." -msgstr "" - -#: ../../source/tutorials/configuration.rst:189 -msgid "Since config files are meant to replace CLI flags, all CLI flags can be set via a config file. Moreover, any config option can be set via a config file, whether or not it has an associated CLI flag. For a list of all CLI flags and all config options, see the bottom of this document." -msgstr "" - -#: ../../source/tutorials/configuration.rst:194 -msgid "Manim will look for a ``manim.cfg`` config file in the same directory as the file being rendered, and **not** in the directory of execution. For example," -msgstr "" - -#: ../../source/tutorials/configuration.rst:201 -msgid "will use the config file found in ``path/to/file.py``, if any. It will **not** use the config file found in the current working directory, even if it exists. In this way, the user may keep different config files for different scenes or projects, and execute them with the right configuration from anywhere in the system." -msgstr "" - -#: ../../source/tutorials/configuration.rst:207 -msgid "The file described here is called the **folder-wide** config file because it affects all scene scripts found in the same folder." -msgstr "" - -#: ../../source/tutorials/configuration.rst:212 -msgid "The user config file" -msgstr "" - -#: ../../source/tutorials/configuration.rst:214 -msgid "As explained in the previous section, a :code:`manim.cfg` config file only affects the scene scripts in its same folder. However, the user may also create a special config file that will apply to all scenes rendered by that user. This is referred to as the **user-wide** config file, and it will apply regardless of where manim is executed from, and regardless of where the scene script is stored." -msgstr "" - -#: ../../source/tutorials/configuration.rst:221 -msgid "The user-wide config file lives in a special folder, depending on the operating system." -msgstr "" - -#: ../../source/tutorials/configuration.rst:224 -msgid "Windows: :code:`UserDirectory`/AppData/Roaming/Manim/manim.cfg" -msgstr "" - -#: ../../source/tutorials/configuration.rst:225 -msgid "MacOS: :code:`UserDirectory`/.config/manim/manim.cfg" -msgstr "" - -#: ../../source/tutorials/configuration.rst:226 -msgid "Linux: :code:`UserDirectory`/.config/manim/manim.cfg" -msgstr "" - -#: ../../source/tutorials/configuration.rst:228 -msgid "Here, :code:`UserDirectory` is the user's home folder." -msgstr "" - -#: ../../source/tutorials/configuration.rst:231 -msgid "A user may have many **folder-wide** config files, one per folder, but only one **user-wide** config file. Different users in the same computer may each have their own user-wide config file." -msgstr "" - -#: ../../source/tutorials/configuration.rst:235 -msgid "Do not store scene scripts in the same folder as the user-wide config file. In this case, the behavior is undefined." -msgstr "" - -#: ../../source/tutorials/configuration.rst:238 -msgid "Whenever you use manim from anywhere in the system, manim will look for a user-wide config file and read its configuration." -msgstr "" - -#: ../../source/tutorials/configuration.rst:243 -msgid "Cascading config files" -msgstr "" - -#: ../../source/tutorials/configuration.rst:245 -msgid "What happens if you execute manim and it finds both a folder-wide config file and a user-wide config file? Manim will read both files, but if they are incompatible, **the folder-wide file takes precedence**." -msgstr "" - -#: ../../source/tutorials/configuration.rst:249 -msgid "For example, take the following user-wide config file" -msgstr "" - -#: ../../source/tutorials/configuration.rst:259 -msgid "and the following folder-wide file" -msgstr "" - -#: ../../source/tutorials/configuration.rst:267 -msgid "Then, executing :code:`manim SceneName` will be equivalent to not using any config files and executing" -msgstr "" - -#: ../../source/tutorials/configuration.rst:274 -msgid "Any command-line flags have precedence over any config file. For example, using the previous two config files and executing :code:`manim -c RED SceneName` is equivalent to not using any config files and executing" -msgstr "" - -#: ../../source/tutorials/configuration.rst:283 -msgid "There is also a **library-wide** config file that determines manim's default behavior and applies to every user of the library. It has the least precedence, so any config options in the user-wide and any folder-wide files will override the library-wide file. This is referred to as the *cascading* config file system." -msgstr "" - -#: ../../source/tutorials/configuration.rst:289 -msgid "**The user should not try to modify the library-wide file**. Contributors should receive explicit confirmation from the core developer team before modifying it." -msgstr "" - -#: ../../source/tutorials/configuration.rst:295 -msgid "Order of operations" -msgstr "" - -#: ../../source/tutorials/configuration.rst:304 -msgid "With so many different ways of configuring manim, it can be difficult to know when each config option is being set. In fact, this will depend on how manim is being used." -msgstr "" - -#: ../../source/tutorials/configuration.rst:308 -msgid "If manim is imported from a module, then the configuration system will follow these steps:" -msgstr "" - -#: ../../source/tutorials/configuration.rst:311 -msgid "The library-wide config file is loaded." -msgstr "" - -#: ../../source/tutorials/configuration.rst:312 -msgid "The user-wide and folder-wide files are loaded, if they exist." -msgstr "" - -#: ../../source/tutorials/configuration.rst:313 -msgid "All files found in the previous two steps are parsed in a single :class:`ConfigParser` object, called ``parser``. This is where *cascading* happens." -msgstr "" - -#: ../../source/tutorials/configuration.rst:316 -msgid ":class:`logging.Logger` is instantiated to create manim's global ``logger`` object. It is configured using the \"logger\" section of the parser, i.e. ``parser['logger']``." -msgstr "" - -#: ../../source/tutorials/configuration.rst:319 -msgid ":class:`ManimConfig` is instantiated to create the global ``config`` object." -msgstr "" - -#: ../../source/tutorials/configuration.rst:320 -msgid "The ``parser`` from step 3 is fed into the ``config`` from step 5 via :meth:`ManimConfig.digest_parser`." -msgstr "" - -#: ../../source/tutorials/configuration.rst:322 -msgid "Both ``logger`` and ``config`` are exposed to the user." -msgstr "" - -#: ../../source/tutorials/configuration.rst:324 -msgid "If manim is being invoked from the command-line, all of the previous steps happen, and are complemented by:" -msgstr "" - -#: ../../source/tutorials/configuration.rst:327 -msgid "The CLI flags are parsed and fed into ``config`` via :meth:`~ManimConfig.digest_args`." -msgstr "" - -#: ../../source/tutorials/configuration.rst:329 -msgid "If the ``--config_file`` flag was used, a new :class:`ConfigParser` object is created with the contents of the library-wide file, the user-wide file if it exists, and the file passed via ``--config_file``. In this case, the folder-wide file, if it exists, is ignored." -msgstr "" - -#: ../../source/tutorials/configuration.rst:333 -msgid "The new parser is fed into ``config``." -msgstr "" - -#: ../../source/tutorials/configuration.rst:334 -msgid "The rest of the CLI flags are processed." -msgstr "" - -#: ../../source/tutorials/configuration.rst:336 -msgid "To summarize, the order of precedence for configuration options, from lowest to highest precedence is:" -msgstr "" - -#: ../../source/tutorials/configuration.rst:339 -msgid "Library-wide config file," -msgstr "" - -#: ../../source/tutorials/configuration.rst:340 -msgid "user-wide config file, if it exists," -msgstr "" - -#: ../../source/tutorials/configuration.rst:341 -msgid "folder-wide config file, if it exists OR custom config file, if passed via ``--config_file``," -msgstr "" - -#: ../../source/tutorials/configuration.rst:343 -msgid "other CLI flags, and" -msgstr "" - -#: ../../source/tutorials/configuration.rst:344 -msgid "any programmatic changes made after the config system is set." -msgstr "" - - diff --git a/docs/i18n/gettext/tutorials/index.pot b/docs/i18n/gettext/tutorials/index.pot new file mode 100644 index 0000000000..e44d718cbd --- /dev/null +++ b/docs/i18n/gettext/tutorials/index.pot @@ -0,0 +1,14 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Manim \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../source/tutorials/index.rst:4 +#: ../../source/tutorials/index.rst:4 +msgid "Table of Contents" +msgstr "" + + diff --git a/docs/i18n/gettext/tutorials/output_and_config.pot b/docs/i18n/gettext/tutorials/output_and_config.pot new file mode 100644 index 0000000000..3b9e720250 --- /dev/null +++ b/docs/i18n/gettext/tutorials/output_and_config.pot @@ -0,0 +1,129 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Manim \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../source/tutorials/output_and_config.rst:2 +msgid "Manim's Output Settings" +msgstr "" + +#: ../../source/tutorials/output_and_config.rst:4 +msgid "This document will focus on understanding manim's output files and some of the main command-line flags available." +msgstr "" + +#: ../../source/tutorials/output_and_config.rst:7 +msgid "This tutorial picks up where :doc:`quickstart` left off, so please read that document before starting this one." +msgstr "" + +#: ../../source/tutorials/output_and_config.rst:11 +msgid "Manim output folders" +msgstr "" + +#: ../../source/tutorials/output_and_config.rst:13 +msgid "At this point, you have just executed the following command." +msgstr "" + +#: ../../source/tutorials/output_and_config.rst:19 +msgid "Let's dissect what just happened step by step. First, this command executes manim on the file ``scene.py``, which contains our animation code. Further, this command tells manim exactly which ``Scene`` is to be rendered, in this case, it is ``SquareToCircle``. This is necessary because a single scene file may contain more than one scene. Next, the flag `-p` tells manim to play the scene once it's rendered, and the `-ql` flag tells manim to render the scene in low quality." +msgstr "" + +#: ../../source/tutorials/output_and_config.rst:27 +msgid "After the video is rendered, you will see that manim has generated some new files and the project folder will look as follows." +msgstr "" + +#: ../../source/tutorials/output_and_config.rst:44 +msgid "There are quite a few new files. The main output is in ``media/videos/scene/480p15/SquareToCircle.mp4``. By default, the ``media`` folder will contain all of manim's output files. The ``media/videos`` subfolder contains the rendered videos. Inside of it, you will find one folder for each different video quality. In our case, since we used the ``-l`` flag, the video was generated at 480 resolution at 15 frames per second from the ``scene.py`` file. Therefore, the output can be found inside ``media/videos/scene/480p15``. The additional folders ``media/videos/scene/480p15/partial_movie_files`` as well as ``media/text`` and ``media/Tex`` contain files that are used by manim internally." +msgstr "" + +#: ../../source/tutorials/output_and_config.rst:55 +msgid "You can see how manim makes use of the generated folder structure by executing the following command," +msgstr "" + +#: ../../source/tutorials/output_and_config.rst:62 +msgid "The ``-ql`` flag (for low quality) has been replaced by the ``-qh`` flag, for high quality. Manim will take considerably longer to render this file, and it will play it once it's done since we are using the ``-p`` flag. The output should look like this:" +msgstr "" + +#: ../../source/tutorials/output_and_config.rst:84 +msgid "And the folder structure should look as follows." +msgstr "" + +#: ../../source/tutorials/output_and_config.rst:102 +msgid "Manim has created a new folder ``media/videos/1080p60``, which corresponds to the high resolution and the 60 frames per second. Inside of it, you can find the new ``SquareToCircle.mp4``, as well as the corresponding ``partial_movie_files``." +msgstr "" + +#: ../../source/tutorials/output_and_config.rst:107 +msgid "When working on a project with multiple scenes, and trying out multiple resolutions, the structure of the output directories will keep all your videos organized." +msgstr "" + +#: ../../source/tutorials/output_and_config.rst:111 +msgid "Further, manim has the option to output the last frame of a scene, when adding the flag ``-s``. This is the fastest option to quickly get a preview of a scene. The corresponding folder structure looks like this:" +msgstr "" + +#: ../../source/tutorials/output_and_config.rst:134 +msgid "Saving the last frame with ``-s`` can be combined with the flags for different resolutions, e.g. ``-s -ql``, ``-s -qh``" +msgstr "" + +#: ../../source/tutorials/output_and_config.rst:141 +msgid "Sections" +msgstr "" + +#: ../../source/tutorials/output_and_config.rst:143 +msgid "In addition to the movie output file one can use sections. Each section produces its own output video. The cuts between two sections can be set like this:" +msgstr "" + +#: ../../source/tutorials/output_and_config.rst:157 +msgid "All the animations between two of these cuts get concatenated into a single output video file. Be aware that you need at least one animation in each section. For example this wouldn't create an output video:" +msgstr "" + +#: ../../source/tutorials/output_and_config.rst:171 +msgid "One way of fixing this is to wait a little:" +msgstr "" + +#: ../../source/tutorials/output_and_config.rst:182 +msgid "For videos to be created for each section you have to add the ``--save_sections`` flag to the Manim call like this:" +msgstr "" + +#: ../../source/tutorials/output_and_config.rst:188 +msgid "If you do this, the ``media`` folder will look like this:" +msgstr "" + +#: ../../source/tutorials/output_and_config.rst:214 +msgid "As you can see each section receives their own output video in the ``sections`` directory. The JSON file in here contains some useful information for each section:" +msgstr "" + +#: ../../source/tutorials/output_and_config.rst:255 +msgid "This data can be used by third party applications, like a presentation system or automated video editing tool." +msgstr "" + +#: ../../source/tutorials/output_and_config.rst:257 +msgid "You can also skip rendering all animations belonging to a section like this:" +msgstr "" + +#: ../../source/tutorials/output_and_config.rst:271 +msgid "Some command line flags" +msgstr "" + +#: ../../source/tutorials/output_and_config.rst:273 +msgid "When executing the command" +msgstr "" + +#: ../../source/tutorials/output_and_config.rst:279 +msgid "it was necessary to specify which ``Scene`` class to render. This is because a single file can contain more than one ``Scene`` class. If your file contains multiple ``Scene`` classes, and you want to render them all, you can use the ``-a`` flag." +msgstr "" + +#: ../../source/tutorials/output_and_config.rst:284 +msgid "As discussed previously, the ``-ql`` specifies low render quality. This does not look very good, but is very useful for rapid prototyping and testing. The other options that specify render quality are ``-qm``, ``-qh``, and ``-qk`` for medium, high, and 4k quality, respectively." +msgstr "" + +#: ../../source/tutorials/output_and_config.rst:289 +msgid "The ``-p`` flag plays the animation once it is rendered. If you want to open the file browser at the location of the animation instead of playing it, you can use the ``-f`` flag. You can also omit these two flags." +msgstr "" + +#: ../../source/tutorials/output_and_config.rst:293 +msgid "Finally, by default manim will output .mp4 files. If you want your animations in .gif format instead, use the ``-i`` flag. The output files will be in the same folder as the .mp4 files, and with the same name, but a different file extension." +msgstr "" + + diff --git a/docs/i18n/gettext/tutorials/quickstart.pot b/docs/i18n/gettext/tutorials/quickstart.pot index f5d3ab23c3..04a2c393a7 100644 --- a/docs/i18n/gettext/tutorials/quickstart.pot +++ b/docs/i18n/gettext/tutorials/quickstart.pot @@ -63,7 +63,7 @@ msgid "If you see an animation of a pink circle being drawn, congratulations! Yo msgstr "" #: ../../source/tutorials/quickstart.rst:86 -msgid "If you get an error message instead, you do not see a video, or if the video output does not look like the preceding animation, it is likely that Manim has not been installed correctly. Please refer to the :doc:`../installation/troubleshooting` page for more information." +msgid "If you get an error message instead, you do not see a video, or if the video output does not look like the preceding animation, it is likely that Manim has not been installed correctly. Please refer to our :doc:`FAQ section ` for help with the most common issues." msgstr "" #: ../../source/tutorials/quickstart.rst:95 @@ -202,7 +202,7 @@ msgid "This ``Scene`` illustrates the quirks of ``.animate``. When using ``.anim msgstr "" #: ../../source/tutorials/quickstart.rst:344 -msgid "In ``DifferentRotations``, the difference between ``.animate``'s interpretation of rotation and the ``Rotate`` method is far more apparent. The starting and ending states of a ``Mobject`` rotated 360 degrees are the same, so ``.animate`` tries to interpolate two identical objects and the result is the left square. If you find that your own usage of ``.animate`` is causing similar unwanted behavior, consider using conventional animation methods like the right square, which uses ``Rotate``." +msgid "In ``DifferentRotations``, the difference between ``.animate``'s interpretation of rotation and the ``Rotate`` method is far more apparent. The starting and ending states of a ``Mobject`` rotated 180 degrees are the same, so ``.animate`` tries to interpolate two identical objects and the result is the left square. If you find that your own usage of ``.animate`` is causing similar unwanted behavior, consider using conventional animation methods like the right square, which uses ``Rotate``." msgstr "" #: ../../source/tutorials/quickstart.rst:353 diff --git a/docs/i18n/gettext/tutorials/using_text.pot b/docs/i18n/gettext/tutorials/using_text.pot index c8f47f3a2e..8b13789179 100644 --- a/docs/i18n/gettext/tutorials/using_text.pot +++ b/docs/i18n/gettext/tutorials/using_text.pot @@ -1,269 +1 @@ -msgid "" -msgstr "" -"Project-Id-Version: Manim \n" -"MIME-Version: 1.0\n" -"Content-Type: text/plain; charset=UTF-8\n" -"Content-Transfer-Encoding: 8bit\n" - -#: ../../source/tutorials/using_text.rst:3 -msgid "Using Text" -msgstr "" - -#: ../../source/tutorials/using_text.rst:5 -msgid "There are two different ways by which you can render **Text** in videos:" -msgstr "" - -#: ../../source/tutorials/using_text.rst:7 -msgid "Using Pango (:mod:`~.text_mobject`)" -msgstr "" - -#: ../../source/tutorials/using_text.rst:8 -msgid "Using LaTeX (:mod:`~.tex_mobject`)" -msgstr "" - -#: ../../source/tutorials/using_text.rst:10 -msgid "If you want to render simple text, you should use either :class:`~.Text` or :class:`~.MarkupText`, or one of its derivatives like :class:`~.Paragraph`. See :ref:`using-text-objects` for more information." -msgstr "" - -#: ../../source/tutorials/using_text.rst:14 -msgid "LaTeX should be used when you need mathematical typesetting. See :ref:`rendering-with-latex` for more information." -msgstr "" - -#: ../../source/tutorials/using_text.rst:20 -msgid "Text Without LaTeX" -msgstr "" - -#: ../../source/tutorials/using_text.rst:22 -msgid "The simplest way to add text to your animations is to use the :class:`~.Text` class. It uses the `Pango library`_ to render text. With Pango, you can also render non-English alphabets like 你好 or こんにちは or 안녕하세요 or مرحبا بالعالم." -msgstr "" - -#: ../../source/tutorials/using_text.rst:27 -msgid "Here is a simple *Hello World* animation." -msgstr "" - -#: ../../source/tutorials/using_text.rst:38 -msgid "You can also use :class:`~.MarkupText` which allows the use of PangoMarkup (see the documentation of :class:`~.MarkupText` for details) to render text. For example:" -msgstr "" - -#: ../../source/tutorials/using_text.rst:56 -msgid "Working with :class:`~.Text`" -msgstr "" - -#: ../../source/tutorials/using_text.rst:58 -msgid "This section explains the properties of :class:`~.Text` and how can it be used in your animations." -msgstr "" - -#: ../../source/tutorials/using_text.rst:62 -msgid "Using Fonts" -msgstr "" - -#: ../../source/tutorials/using_text.rst:64 -msgid "You can set a different font using :attr:`~.Text.font`." -msgstr "" - -#: ../../source/tutorials/using_text.rst:68 -msgid "The font used must be installed in your system, and Pango should know about it. You can get a list of fonts using :func:`manimpango.list_fonts`." -msgstr "" - -#: ../../source/tutorials/using_text.rst:85 -msgid "Setting Slant and Weight" -msgstr "" - -#: ../../source/tutorials/using_text.rst:86 -msgid "Slant is the style of the Text, and it can be ``NORMAL`` (the default), ``ITALIC`` or ``OBLIQUE``. Usually, for many fonts both ``ITALIC`` and ``OBLIQUE`` look similar, but ``ITALIC`` uses **Roman Style**, whereas ``OBLIQUE`` uses **Italic Style**." -msgstr "" - -#: ../../source/tutorials/using_text.rst:91 -msgid "Weight specifies the boldness of a font. You can see a list of weights in :class:`manimpango.Weight`." -msgstr "" - -#: ../../source/tutorials/using_text.rst:126 -msgid "Using Colors" -msgstr "" - -#: ../../source/tutorials/using_text.rst:128 -msgid "You can set the color of the text using :attr:`~.Text.color`:" -msgstr "" - -#: ../../source/tutorials/using_text.rst:138 -msgid "You can use utilities like :attr:`~.Text.t2c` for coloring specific characters. This may be problematic if your text contains ligatures as explained in :ref:`iterating-text`." -msgstr "" - -#: ../../source/tutorials/using_text.rst:142 -msgid ":attr:`~Text.t2c` accepts two types of dictionaries," -msgstr "" - -#: ../../source/tutorials/using_text.rst:144 -msgid "The keys can contain indices like ``[2:-1]`` or ``[4:8]``, this works similar to how `slicing `_ works in Python. The values should be the color of the Text from :class:`~.Color`." -msgstr "" - -#: ../../source/tutorials/using_text.rst:149 -msgid "The keys contain words or characters which should be colored separately and the values should be the color from :class:`~.Color`:" -msgstr "" - -#: ../../source/tutorials/using_text.rst:161 -msgid "If you want to avoid problems when using colors (due to ligatures), consider using :class:`MarkupText`." -msgstr "" - -#: ../../source/tutorials/using_text.rst:166 -msgid "Using Gradients" -msgstr "" - -#: ../../source/tutorials/using_text.rst:168 -msgid "You can add a gradient using :attr:`~.Text.gradient`. The value must be an iterable of any length:" -msgstr "" - -#: ../../source/tutorials/using_text.rst:179 -msgid "You can also use :attr:`~.Text.t2g` for gradients with specific characters of the text. It shares a similar syntax to :ref:`the interface for colors `:" -msgstr "" - -#: ../../source/tutorials/using_text.rst:203 -msgid "Setting Line Spacing" -msgstr "" - -#: ../../source/tutorials/using_text.rst:205 -msgid "You can set the line spacing using :attr:`~.Text.line_spacing`:" -msgstr "" - -#: ../../source/tutorials/using_text.rst:220 -msgid "Disabling Ligatures" -msgstr "" - -#: ../../source/tutorials/using_text.rst:222 -msgid "By disabling ligatures you would get a one-to-one mapping between characters and submobjects. This fixes the issues with coloring text." -msgstr "" - -#: ../../source/tutorials/using_text.rst:228 -msgid "Be aware that using this method with text that heavily depends on ligatures (Arabic text) may yield unexpected results." -msgstr "" - -#: ../../source/tutorials/using_text.rst:231 -msgid "You can disable ligatures by passing ``disable_ligatures`` to :class:`Text`. For example:" -msgstr "" - -#: ../../source/tutorials/using_text.rst:246 -msgid "Iterating :class:`~.Text`" -msgstr "" - -#: ../../source/tutorials/using_text.rst:248 -msgid "Text objects behave like :class:`VGroups <.VGroup>`. Therefore, you can slice and index the text." -msgstr "" - -#: ../../source/tutorials/using_text.rst:251 -msgid "For example, you can set each letter to different color by iterating it." -msgstr "" - -#: ../../source/tutorials/using_text.rst:265 -msgid "Please note that `Ligature`_ can cause problems here. If you need a one-to-one mapping of characters to submobjects you should pass the ``disable_ligatures`` parameter to :class:`~.Text`. See :ref:`disable-ligatures`." -msgstr "" - -#: ../../source/tutorials/using_text.rst:273 -msgid "Working with :class:`~.MarkupText`" -msgstr "" - -#: ../../source/tutorials/using_text.rst:275 -msgid "MarkupText is similar to :class:`~.Text`, the only difference between them is that this accepts and processes PangoMarkup (which is similar to html), instead of just rendering plain text." -msgstr "" - -#: ../../source/tutorials/using_text.rst:279 -msgid "Consult the documentation of :class:`~.MarkupText` for more details and further references about PangoMarkup." -msgstr "" - -#: ../../source/tutorials/using_text.rst:297 -msgid "Text With LaTeX" -msgstr "" - -#: ../../source/tutorials/using_text.rst:299 -msgid "Just as you can use :class:`~.Text` to add text to your videos, you can use :class:`~.Tex` to insert LaTeX." -msgstr "" - -#: ../../source/tutorials/using_text.rst:302 -msgid "For example," -msgstr "" - -#: ../../source/tutorials/using_text.rst:314 -msgid "Note that we are using a raw string (``r'...'``) instead of a regular string (``'...'``). This is because TeX code uses a lot of special characters - like ``\\`` for example - that have special meaning within a regular python string. An alternative would have been to write ``\\\\`` to escape the backslash: ``Tex('\\\\LaTeX')``." -msgstr "" - -#: ../../source/tutorials/using_text.rst:320 -msgid "Working with :class:`~.MathTex`" -msgstr "" - -#: ../../source/tutorials/using_text.rst:322 -msgid "Everything passed to :class:`~.MathTex` is in math mode by default. To be more precise, :class:`~.MathTex` is processed within an ``align*`` environment. You can achieve a similar effect with :class:`~.Tex` by enclosing your formula with ``$`` symbols: ``$\\xrightarrow{x^6y^8}$``:" -msgstr "" - -#: ../../source/tutorials/using_text.rst:339 -msgid "LaTeX commands and keyword arguments" -msgstr "" - -#: ../../source/tutorials/using_text.rst:341 -msgid "We can use any standard LaTeX commands in the AMS maths packages. Such as the ``mathtt`` math-text type or the ``looparrowright`` arrow." -msgstr "" - -#: ../../source/tutorials/using_text.rst:352 -msgid "On the Manim side, the :class:`~.Tex` class also accepts attributes to change the appearance of the output. This is very similar to the :class:`~.Text` class. For example, the ``color`` keyword changes the color of the TeX mobject." -msgstr "" - -#: ../../source/tutorials/using_text.rst:366 -msgid "Extra LaTeX Packages" -msgstr "" - -#: ../../source/tutorials/using_text.rst:368 -msgid "Some commands require special packages to be loaded into the TeX template. For example, to use the ``mathscr`` script, we need to add the ``mathrsfs`` package. Since this package isn't loaded into Manim's tex template by default, we have to add it manually." -msgstr "" - -#: ../../source/tutorials/using_text.rst:388 -msgid "Substrings and parts" -msgstr "" - -#: ../../source/tutorials/using_text.rst:390 -msgid "The TeX mobject can accept multiple strings as arguments. Afterwards you can refer to the individual parts either by their index (like ``tex[1]``), or by selecting parts of the tex code. In this example, we set the color of the ``\\bigstar`` using :func:`~.set_color_by_tex`:" -msgstr "" - -#: ../../source/tutorials/using_text.rst:404 -msgid "Note that :func:`~.set_color_by_tex` colors the entire substring containing the Tex, not just the specific symbol or Tex expression. Consider the following example:" -msgstr "" - -#: ../../source/tutorials/using_text.rst:418 -msgid "As you can see, this colors the entire equation yellow, contrary to what may be expected. To color only ``x`` yellow, we have to do the following:" -msgstr "" - -#: ../../source/tutorials/using_text.rst:433 -msgid "By setting ``substrings_to_isolate`` to ``x``, we split up the :class:`~.MathTex` into substrings automatically and isolate the ``x`` components into individual substrings. Only then can :meth:`~.set_color_by_tex` be used to achieve the desired result." -msgstr "" - -#: ../../source/tutorials/using_text.rst:438 -msgid "Note that Manim also supports a custom syntax that allows splitting a TeX string into substrings easily: simply enclose parts of your formula that you want to isolate with double braces. In the string ``MathTex(r\"{{ a^2 }} + {{ b^2 }} = {{ c^2 }}\")``, the rendered mobject will consist of the substrings ``a^2``, ``+``, ``b^2``, ``=``, and ``c^2``. This makes transformations between similar text fragments easy to write using :class:`~.TransformMatchingTex`." -msgstr "" - -#: ../../source/tutorials/using_text.rst:447 -msgid "Using ``index_labels`` to work with complicated strings" -msgstr "" - -#: ../../source/tutorials/using_text.rst:449 -msgid "You might sometimes be working with a very complicated :class:`~.MathTex` mobject that makes it difficult to work with its individual components. This is where the debugging function :func:`.index_labels` is very useful." -msgstr "" - -#: ../../source/tutorials/using_text.rst:453 -msgid "The method shows the index of a mobject's submobjects, allowing you to easily find the components of the mobject you would like to change." -msgstr "" - -#: ../../source/tutorials/using_text.rst:472 -msgid "LaTeX Maths Fonts - The Template Library" -msgstr "" - -#: ../../source/tutorials/using_text.rst:474 -msgid "Changing fonts in LaTeX when typesetting mathematical formulae is trickier than regular text. It requires changing the template that is used to compile the TeX. Manim comes with a collection of :class:`~.TexFontTemplates` ready for you to use. These templates will all work in math mode:" -msgstr "" - -#: ../../source/tutorials/using_text.rst:491 -msgid "Manim also has a :class:`~.TexTemplateLibrary` containing the TeX templates used by 3Blue1Brown. One example is the ctex template, used for typesetting Chinese script. For this to work, the ctex LaTeX package must be installed on your system. Furthermore, if you are only typesetting Text, you probably do not need :class:`~.Tex` at all, and should use :class:`~.Text` instead." -msgstr "" - -#: ../../source/tutorials/using_text.rst:508 -msgid "Aligning formulae" -msgstr "" - - diff --git a/docs/i18n/gettext/tutorials_guides.pot b/docs/i18n/gettext/tutorials_guides.pot new file mode 100644 index 0000000000..8215184f81 --- /dev/null +++ b/docs/i18n/gettext/tutorials_guides.pot @@ -0,0 +1,14 @@ + +msgid "" +msgstr "" +"Project-Id-Version: Manim \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: 8bit\n" + +#: ../../source/tutorials_guides.rst:4 +#: ../../source/tutorials_guides.rst:4 +msgid "Table of Contents" +msgstr "" + + diff --git a/docs/i18n/readyForTranslation b/docs/i18n/readyForTranslation index 5f6d57a20e..c2397ab8db 100644 --- a/docs/i18n/readyForTranslation +++ b/docs/i18n/readyForTranslation @@ -9,6 +9,12 @@ examples.po reference.po tutorials.po tutorials/building_blocks.po -tutorials/a_deeper_look.po tutorials/quickstart.po -tutorials/configuration.po +guides/output_and_config.po +guides/configuration.po +guides/deep_dive.po +guides/using_text.po +faq/general.po +faq/help.po +faq/installation.po +faq/opengl.po diff --git a/docs/i18n/stripUntranslatable.awk b/docs/i18n/stripUntranslatable.awk index 22f633d594..6c2a7a3641 100644 --- a/docs/i18n/stripUntranslatable.awk +++ b/docs/i18n/stripUntranslatable.awk @@ -25,7 +25,7 @@ BEGIN { # The file location of where to put everything # that has been stripped out untranslatablefile="./untranslatable.po" - # Wether we are still reading the licence text + # Whether we are still reading the licence text licencetext=1 } diff --git a/docs/requirements.txt b/docs/requirements.txt index a5ff99adb2..5b607e9c8b 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,5 +1,7 @@ -sphinx==4.1.2 furo -recommonmark>=0.5.0 +myst-parser +sphinx>=7.3 sphinx-copybutton sphinxext-opengraph +sphinx-design +sphinx-reredirects diff --git a/manim/grpc/__init__.py b/docs/skip-manim similarity index 100% rename from manim/grpc/__init__.py rename to docs/skip-manim diff --git a/docs/source/_static/bezier_subdivision_example.png b/docs/source/_static/bezier_subdivision_example.png new file mode 100644 index 0000000000..8cdb8f241d Binary files /dev/null and b/docs/source/_static/bezier_subdivision_example.png differ diff --git a/docs/source/_static/custom.css b/docs/source/_static/custom.css index 59e8cb3e35..2b17007fdc 100644 --- a/docs/source/_static/custom.css +++ b/docs/source/_static/custom.css @@ -82,3 +82,22 @@ h4, h5, h6{ .sidebar-tree a.internal.reference { display: table-cell; } + +.manim-binder-button { + text-transform: capitalize; + padding: 10px 20px; + margin: 10px 0; +} + +.manim-binder-wrapper { + background-color: var(--color-code-background); + color: var(--color-code-foreground); +} + +.manim-binder-title { + margin-top: 0; +} + +.manim-binder-button-wrapper { + margin: 0px 10px; +} diff --git a/docs/source/_static/logo.png b/docs/source/_static/logo.png new file mode 100644 index 0000000000..96f6490bcb Binary files /dev/null and b/docs/source/_static/logo.png differ diff --git a/docs/source/_static/manim-binder.min.js b/docs/source/_static/manim-binder.min.js new file mode 100644 index 0000000000..2e076c9645 --- /dev/null +++ b/docs/source/_static/manim-binder.min.js @@ -0,0 +1,3 @@ +/*! For license information please see manim-binder.min.js.LICENSE.txt */ +(()=>{var __webpack_modules__={5067:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.ActivityMonitor=void 0;const n=i(6424);t.ActivityMonitor=class{constructor(e){this._timer=-1,this._timeout=-1,this._isDisposed=!1,this._activityStopped=new n.Signal(this),e.signal.connect(this._onSignalFired,this),this._timeout=e.timeout||1e3}get activityStopped(){return this._activityStopped}get timeout(){return this._timeout}set timeout(e){this._timeout=e}get isDisposed(){return this._isDisposed}dispose(){this._isDisposed||(this._isDisposed=!0,n.Signal.clearData(this))}_onSignalFired(e,t){clearTimeout(this._timer),this._sender=e,this._args=t,this._timer=setTimeout((()=>{this._activityStopped.emit({sender:this._sender,args:this._args})}),this._timeout)}}},4251:function(e,t,i){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__exportStar||function(e,t){for(var i in e)"default"===i||Object.prototype.hasOwnProperty.call(t,i)||n(t,e,i)};Object.defineProperty(t,"__esModule",{value:!0}),s(i(5067),t),s(i(6742),t),s(i(5366),t),s(i(6470),t),s(i(5675),t),s(i(5571),t),s(i(1735),t),s(i(1152),t),s(i(5248),t)},6742:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},5366:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.MarkdownCodeBlocks=void 0,function(e){e.CODE_BLOCK_MARKER="```";const t=[".markdown",".mdown",".mkdn",".md",".mkd",".mdwn",".mdtxt",".mdtext",".text",".txt",".Rmd"];class i{constructor(e){this.startLine=e,this.code="",this.endLine=-1}}e.MarkdownCodeBlock=i,e.isMarkdown=function(e){return t.indexOf(e)>-1},e.findMarkdownCodeBlocks=function(t){if(!t||""===t)return[];const n=t.split("\n"),s=[];let r=null;for(let t=0;te===t||n&&e===n))},e.isDisabled=function(t){const i=t.indexOf(":");let n="";return-1!==i&&(n=t.slice(0,i)),e.disabled.some((e=>e===t||n&&e===n))}}(Extension=PageConfig.Extension||(PageConfig.Extension={}))})(PageConfig=exports.PageConfig||(exports.PageConfig={}))},5675:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.PathExt=void 0;const n=i(2005);!function(e){function t(e){return 0===e.indexOf("/")&&(e=e.slice(1)),e}e.join=function(...e){const i=n.posix.join(...e);return"."===i?"":t(i)},e.basename=function(e,t){return n.posix.basename(e,t)},e.dirname=function(e){const i=t(n.posix.dirname(e));return"."===i?"":i},e.extname=function(e){return n.posix.extname(e)},e.normalize=function(e){return""===e?"":t(n.posix.normalize(e))},e.resolve=function(...e){return t(n.posix.resolve(...e))},e.relative=function(e,i){return t(n.posix.relative(e,i))},e.normalizeExtension=function(e){return e.length>0&&0!==e.indexOf(".")&&(e=`.${e}`),e},e.removeSlash=t}(t.PathExt||(t.PathExt={}))},5571:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.signalToPromise=void 0;const n=i(3911);t.signalToPromise=function(e,t){const i=new n.PromiseDelegate;function s(){e.disconnect(r)}function r(e,t){s(),i.resolve([e,t])}return e.connect(r),(null!=t?t:0)>0&&setTimeout((()=>{s(),i.reject(`Signal not emitted within ${t} ms.`)}),t),i.promise}},1735:(e,t)=>{"use strict";var i;Object.defineProperty(t,"__esModule",{value:!0}),t.Text=void 0,(i=t.Text||(t.Text={})).jsIndexToCharIndex=function(e,t){return e},i.charIndexToJsIndex=function(e,t){return e},i.camelCase=function(e,t=!1){return e.replace(/^(\w)|[\s-_:]+(\w)/g,(function(e,i,n){return n?n.toUpperCase():t?i.toUpperCase():i.toLowerCase()}))},i.titleCase=function(e){return(e||"").toLowerCase().split(" ").map((e=>e.charAt(0).toUpperCase()+e.slice(1))).join(" ")}},1152:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.Time=void 0;const i=[{name:"years",milliseconds:31536e6},{name:"months",milliseconds:2592e6},{name:"days",milliseconds:864e5},{name:"hours",milliseconds:36e5},{name:"minutes",milliseconds:6e4},{name:"seconds",milliseconds:1e3}];var n;(n=t.Time||(t.Time={})).formatHuman=function(e){const t=document.documentElement.lang||"en",n=new Intl.RelativeTimeFormat(t,{numeric:"auto"}),s=new Date(e).getTime()-Date.now();for(let e of i){const t=Math.ceil(s/e.milliseconds);if(0!==t)return n.format(t,e.name)}return n.format(0,"seconds")},n.format=function(e){const t=document.documentElement.lang||"en";return new Intl.DateTimeFormat(t,{dateStyle:"short",timeStyle:"short"}).format(new Date(e))}},5248:function(e,t,i){"use strict";var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.URLExt=void 0;const s=i(2005),r=n(i(2296));!function(e){function t(e){if("undefined"!=typeof document&&document){const t=document.createElement("a");return t.href=e,t}return(0,r.default)(e)}function i(...e){let t=(0,r.default)(e[0],{});const i=""===t.protocol&&t.slashes;i&&(t=(0,r.default)(e[0],"https:"+e[0]));const n=`${i?"":t.protocol}${t.slashes?"//":""}${t.auth}${t.auth?"@":""}${t.host}`,o=s.posix.join(`${n&&"/"!==t.pathname[0]?"/":""}${t.pathname}`,...e.slice(1));return`${n}${"."===o?"":o}`}e.parse=t,e.getHostName=function(e){return(0,r.default)(e).hostname},e.normalize=function(e){return e&&t(e).toString()},e.join=i,e.encodeParts=function(e){return i(...e.split("/").map(encodeURIComponent))},e.objectToQueryString=function(e){const t=Object.keys(e).filter((e=>e.length>0));return t.length?"?"+t.map((t=>{const i=encodeURIComponent(String(e[t]));return t+(i?"="+i:"")})).join("&"):""},e.queryStringToObject=function(e){return e.replace(/^\?/,"").split("&").reduce(((e,t)=>{const[i,n]=t.split("=");return i.length>0&&(e[i]=decodeURIComponent(n||"")),e}),{})},e.isLocal=function(e){const{protocol:i}=t(e);return(!i||0!==e.toLowerCase().indexOf(i))&&0!==e.indexOf("/")}}(t.URLExt||(t.URLExt={}))},7524:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.BaseManager=void 0;const n=i(6424),s=i(538);t.BaseManager=class{constructor(e){var t;this._isDisposed=!1,this._disposed=new n.Signal(this),this.serverSettings=null!==(t=e.serverSettings)&&void 0!==t?t:s.ServerConnection.makeSettings()}get disposed(){return this._disposed}get isDisposed(){return this._isDisposed}get isActive(){return!0}dispose(){this.isDisposed||(this._disposed.emit(void 0),n.Signal.clearData(this))}}},4011:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.BuildManager=void 0;const n=i(4251),s=i(538);t.BuildManager=class{constructor(e={}){var t;this._url="",this.serverSettings=null!==(t=e.serverSettings)&&void 0!==t?t:s.ServerConnection.makeSettings();const{baseUrl:i,appUrl:r}=this.serverSettings;this._url=n.URLExt.join(i,r,"api/build")}get isAvailable(){return"true"===n.PageConfig.getOption("buildAvailable").toLowerCase()}get shouldCheck(){return"true"===n.PageConfig.getOption("buildCheck").toLowerCase()}getStatus(){const{_url:e,serverSettings:t}=this;return s.ServerConnection.makeRequest(e,{},t).then((e=>{if(200!==e.status)throw new s.ServerConnection.ResponseError(e);return e.json()})).then((e=>{if("string"!=typeof e.status)throw new Error("Invalid data");if("string"!=typeof e.message)throw new Error("Invalid data");return e}))}build(){const{_url:e,serverSettings:t}=this;return s.ServerConnection.makeRequest(e,{method:"POST"},t).then((e=>{if(400===e.status)throw new s.ServerConnection.ResponseError(e,"Build aborted");if(200!==e.status){const t=`Build failed with ${e.status}.\n\n If you are experiencing the build failure after installing an extension (or trying to include previously installed extension after updating JupyterLab) please check the extension repository for new installation instructions as many extensions migrated to the prebuilt extensions system which no longer requires rebuilding JupyterLab (but uses a different installation procedure, typically involving a package manager such as 'pip' or 'conda').\n\n If you specifically intended to install a source extension, please run 'jupyter lab build' on the server for full output.`;throw new s.ServerConnection.ResponseError(e,t)}}))}cancel(){const{_url:e,serverSettings:t}=this;return s.ServerConnection.makeRequest(e,{method:"DELETE"},t).then((e=>{if(204!==e.status)throw new s.ServerConnection.ResponseError(e)}))}}},7302:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.ConfigWithDefaults=t.ConfigSection=void 0;const n=i(4251),s=i(5247);(t.ConfigSection||(t.ConfigSection={})).create=function(e){const t=new r(e);return t.load().then((()=>t))};class r{constructor(e){var t;this._url="unknown";const i=this.serverSettings=null!==(t=e.serverSettings)&&void 0!==t?t:s.ServerConnection.makeSettings();this._url=n.URLExt.join(i.baseUrl,"api/config",encodeURIComponent(e.name))}get data(){return this._data}async load(){const e=await s.ServerConnection.makeRequest(this._url,{},this.serverSettings);if(200!==e.status)throw await s.ServerConnection.ResponseError.create(e);this._data=await e.json()}async update(e){this._data={...this._data,...e};const t={method:"PATCH",body:JSON.stringify(e)},i=await s.ServerConnection.makeRequest(this._url,t,this.serverSettings);if(200!==i.status)throw await s.ServerConnection.ResponseError.create(i);return this._data=await i.json(),this._data}}t.ConfigWithDefaults=class{constructor(e){var t,i;this._className="",this._section=e.section,this._defaults=null!==(t=e.defaults)&&void 0!==t?t:{},this._className=null!==(i=e.className)&&void 0!==i?i:""}get(e){const t=this._classData();return e in t?t[e]:this._defaults[e]}set(e,t){const i={};if(i[e]=t,this._className){const e={};return e[this._className]=i,this._section.update(e)}return this._section.update(i)}_classData(){const e=this._section.data;return this._className&&this._className in e?e[this._className]:e}}},1708:function(e,t,i){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.Drive=t.ContentsManager=t.Contents=void 0;const o=i(4251),a=i(6424),l=i(5247),h=r(i(3394));var c,d;(d=t.Contents||(t.Contents={})).validateContentsModel=function(e){h.validateContentsModel(e)},d.validateCheckpointModel=function(e){h.validateCheckpointModel(e)},t.ContentsManager=class{constructor(e={}){var t,i;this._isDisposed=!1,this._additionalDrives=new Map,this._fileChanged=new a.Signal(this);const n=this.serverSettings=null!==(t=e.serverSettings)&&void 0!==t?t:l.ServerConnection.makeSettings();this._defaultDrive=null!==(i=e.defaultDrive)&&void 0!==i?i:new u({serverSettings:n}),this._defaultDrive.fileChanged.connect(this._onFileChanged,this)}get fileChanged(){return this._fileChanged}get isDisposed(){return this._isDisposed}dispose(){this.isDisposed||(this._isDisposed=!0,a.Signal.clearData(this))}addDrive(e){this._additionalDrives.set(e.name,e),e.fileChanged.connect(this._onFileChanged,this)}getSharedModelFactory(e){var t;const[i]=this._driveForPath(e);return null!==(t=null==i?void 0:i.sharedModelFactory)&&void 0!==t?t:null}localPath(e){const t=e.split("/"),i=t[0].split(":");return 1!==i.length&&this._additionalDrives.has(i[0])?o.PathExt.join(i.slice(1).join(":"),...t.slice(1)):o.PathExt.removeSlash(e)}normalize(e){const t=e.split(":");return 1===t.length?o.PathExt.normalize(e):`${t[0]}:${o.PathExt.normalize(t.slice(1).join(":"))}`}resolvePath(e,t){const i=this.driveName(e),n=this.localPath(e),s=o.PathExt.resolve("/",n,t);return i?`${i}:${s}`:s}driveName(e){const t=e.split("/")[0].split(":");return 1===t.length?"":this._additionalDrives.has(t[0])?t[0]:""}get(e,t){const[i,n]=this._driveForPath(e);return i.get(n,t).then((e=>{const t=[];if("directory"===e.type&&e.content){for(const n of e.content)t.push({...n,path:this._toGlobalPath(i,n.path)});return{...e,path:this._toGlobalPath(i,n),content:t,serverPath:e.path}}return{...e,path:this._toGlobalPath(i,n),serverPath:e.path}}))}getDownloadUrl(e){const[t,i]=this._driveForPath(e);return t.getDownloadUrl(i)}newUntitled(e={}){if(e.path){const t=this.normalize(e.path),[i,n]=this._driveForPath(t);return i.newUntitled({...e,path:n}).then((e=>({...e,path:o.PathExt.join(t,e.name),serverPath:e.path})))}return this._defaultDrive.newUntitled(e)}delete(e){const[t,i]=this._driveForPath(e);return t.delete(i)}rename(e,t){const[i,n]=this._driveForPath(e),[s,r]=this._driveForPath(t);if(i!==s)throw Error("ContentsManager: renaming files must occur within a Drive");return i.rename(n,r).then((e=>({...e,path:this._toGlobalPath(i,r),serverPath:e.path})))}save(e,t={}){const i=this.normalize(e),[n,s]=this._driveForPath(e);return n.save(s,{...t,path:s}).then((e=>({...e,path:i,serverPath:e.path})))}copy(e,t){const[i,n]=this._driveForPath(e),[s,r]=this._driveForPath(t);if(i===s)return i.copy(n,r).then((e=>({...e,path:this._toGlobalPath(i,e.path),serverPath:e.path})));throw Error("Copying files between drives is not currently implemented")}createCheckpoint(e){const[t,i]=this._driveForPath(e);return t.createCheckpoint(i)}listCheckpoints(e){const[t,i]=this._driveForPath(e);return t.listCheckpoints(i)}restoreCheckpoint(e,t){const[i,n]=this._driveForPath(e);return i.restoreCheckpoint(n,t)}deleteCheckpoint(e,t){const[i,n]=this._driveForPath(e);return i.deleteCheckpoint(n,t)}_toGlobalPath(e,t){return e===this._defaultDrive?o.PathExt.removeSlash(t):`${e.name}:${o.PathExt.removeSlash(t)}`}_driveForPath(e){const t=this.driveName(e),i=this.localPath(e);return t?[this._additionalDrives.get(t),i]:[this._defaultDrive,i]}_onFileChanged(e,t){var i,n;if(e===this._defaultDrive)this._fileChanged.emit(t);else{let s=null,r=null;(null===(i=t.newValue)||void 0===i?void 0:i.path)&&(s={...t.newValue,path:this._toGlobalPath(e,t.newValue.path)}),(null===(n=t.oldValue)||void 0===n?void 0:n.path)&&(r={...t.oldValue,path:this._toGlobalPath(e,t.oldValue.path)}),this._fileChanged.emit({type:t.type,newValue:s,oldValue:r})}}};class u{constructor(e={}){var t,i,n;this._isDisposed=!1,this._fileChanged=new a.Signal(this),this.name=null!==(t=e.name)&&void 0!==t?t:"Default",this._apiEndpoint=null!==(i=e.apiEndpoint)&&void 0!==i?i:"api/contents",this.serverSettings=null!==(n=e.serverSettings)&&void 0!==n?n:l.ServerConnection.makeSettings()}get fileChanged(){return this._fileChanged}get isDisposed(){return this._isDisposed}dispose(){this.isDisposed||(this._isDisposed=!0,a.Signal.clearData(this))}async get(e,t){let i=this._getUrl(e);if(t){"notebook"===t.type&&delete t.format;const e=t.content?"1":"0",n={...t,content:e};i+=o.URLExt.objectToQueryString(n)}const n=this.serverSettings,s=await l.ServerConnection.makeRequest(i,{},n);if(200!==s.status)throw await l.ServerConnection.ResponseError.create(s);const r=await s.json();return h.validateContentsModel(r),r}getDownloadUrl(e){const t=this.serverSettings.baseUrl;let i=o.URLExt.join(t,"files",o.URLExt.encodeParts(e));const n=document.cookie.match("\\b_xsrf=([^;]*)\\b");if(n){const e=new URL(i);e.searchParams.append("_xsrf",n[1]),i=e.toString()}return Promise.resolve(i)}async newUntitled(e={}){var t;let i="{}";e&&(e.ext&&(e.ext=c.normalizeExtension(e.ext)),i=JSON.stringify(e));const n=this.serverSettings,s=this._getUrl(null!==(t=e.path)&&void 0!==t?t:""),r={method:"POST",body:i},o=await l.ServerConnection.makeRequest(s,r,n);if(201!==o.status)throw await l.ServerConnection.ResponseError.create(o);const a=await o.json();return h.validateContentsModel(a),this._fileChanged.emit({type:"new",oldValue:null,newValue:a}),a}async delete(e){const t=this._getUrl(e),i=this.serverSettings,n=await l.ServerConnection.makeRequest(t,{method:"DELETE"},i);if(204!==n.status)throw await l.ServerConnection.ResponseError.create(n);this._fileChanged.emit({type:"delete",oldValue:{path:e},newValue:null})}async rename(e,t){const i=this.serverSettings,n=this._getUrl(e),s={method:"PATCH",body:JSON.stringify({path:t})},r=await l.ServerConnection.makeRequest(n,s,i);if(200!==r.status)throw await l.ServerConnection.ResponseError.create(r);const o=await r.json();return h.validateContentsModel(o),this._fileChanged.emit({type:"rename",oldValue:{path:e},newValue:o}),o}async save(e,t={}){const i=this.serverSettings,n=this._getUrl(e),s={method:"PUT",body:JSON.stringify(t)},r=await l.ServerConnection.makeRequest(n,s,i);if(200!==r.status&&201!==r.status)throw await l.ServerConnection.ResponseError.create(r);const o=await r.json();return h.validateContentsModel(o),this._fileChanged.emit({type:"save",oldValue:null,newValue:o}),o}async copy(e,t){const i=this.serverSettings,n=this._getUrl(t),s={method:"POST",body:JSON.stringify({copy_from:e})},r=await l.ServerConnection.makeRequest(n,s,i);if(201!==r.status)throw await l.ServerConnection.ResponseError.create(r);const o=await r.json();return h.validateContentsModel(o),this._fileChanged.emit({type:"new",oldValue:null,newValue:o}),o}async createCheckpoint(e){const t=this._getUrl(e,"checkpoints"),i=await l.ServerConnection.makeRequest(t,{method:"POST"},this.serverSettings);if(201!==i.status)throw await l.ServerConnection.ResponseError.create(i);const n=await i.json();return h.validateCheckpointModel(n),n}async listCheckpoints(e){const t=this._getUrl(e,"checkpoints"),i=await l.ServerConnection.makeRequest(t,{},this.serverSettings);if(200!==i.status)throw await l.ServerConnection.ResponseError.create(i);const n=await i.json();if(!Array.isArray(n))throw new Error("Invalid Checkpoint list");for(let e=0;eo.URLExt.encodeParts(e))),i=this.serverSettings.baseUrl;return o.URLExt.join(i,this._apiEndpoint,...t)}}t.Drive=u,function(e){e.normalizeExtension=function(e){return e.length>0&&0!==e.indexOf(".")&&(e=`.${e}`),e}}(c||(c={}))},3394:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.validateCheckpointModel=t.validateContentsModel=void 0;const n=i(3247);t.validateContentsModel=function(e){(0,n.validateProperty)(e,"name","string"),(0,n.validateProperty)(e,"path","string"),(0,n.validateProperty)(e,"type","string"),(0,n.validateProperty)(e,"created","string"),(0,n.validateProperty)(e,"last_modified","string"),(0,n.validateProperty)(e,"mimetype","object"),(0,n.validateProperty)(e,"content","object"),(0,n.validateProperty)(e,"format","object")},t.validateCheckpointModel=function(e){(0,n.validateProperty)(e,"id","string"),(0,n.validateProperty)(e,"last_modified","string")}},5657:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.EventManager=void 0;const n=i(4251),s=i(9044),r=i(6424),o=i(538),a="api/events";t.EventManager=class{constructor(e={}){var t;this._socket=null,this.serverSettings=null!==(t=e.serverSettings)&&void 0!==t?t:o.ServerConnection.makeSettings(),this._poll=new s.Poll({factory:()=>this._subscribe()}),this._stream=new r.Stream(this),this._poll.start()}get isDisposed(){return this._poll.isDisposed}get stream(){return this._stream}dispose(){if(this.isDisposed)return;this._poll.dispose();const e=this._socket;e&&(this._socket=null,e.onopen=()=>{},e.onerror=()=>{},e.onmessage=()=>{},e.onclose=()=>{},e.close()),r.Signal.clearData(this),this._stream.stop()}async emit(e){const{serverSettings:t}=this,{baseUrl:i,token:s}=t,{makeRequest:r,ResponseError:l}=o.ServerConnection,h=n.URLExt.join(i,a)+(s?`?token=${s}`:""),c={body:JSON.stringify(e),method:"POST"},d=await r(h,c,t);if(204!==d.status)throw new l(d)}_subscribe(){return new Promise(((e,t)=>{if(this.isDisposed)return;const{token:i,WebSocket:s,wsUrl:r}=this.serverSettings,o=n.URLExt.join(r,a,"subscribe")+(i?`?token=${encodeURIComponent(i)}`:""),l=this._socket=new s(o),h=this._stream;l.onclose=()=>t(new Error("EventManager socket closed")),l.onmessage=e=>e.data&&h.emit(JSON.parse(e.data))}))}}},5247:function(e,t,i){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__exportStar||function(e,t){for(var i in e)"default"===i||Object.prototype.hasOwnProperty.call(t,i)||n(t,e,i)};Object.defineProperty(t,"__esModule",{value:!0}),s(i(7524),t),s(i(7302),t),s(i(1708),t),s(i(5657),t),s(i(5674),t),s(i(3490),t),s(i(7797),t),s(i(538),t),s(i(3561),t),s(i(9188),t),s(i(3185),t),s(i(1014),t),s(i(9090),t),s(i(6624),t)},8341:function(e,t,i){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.CommHandler=void 0;const o=i(1122),a=r(i(1736));class l extends o.DisposableDelegate{constructor(e,t,i,n){super(n),this._target="",this._id="",this._id=t,this._target=e,this._kernel=i}get commId(){return this._id}get targetName(){return this._target}get onClose(){return this._onClose}set onClose(e){this._onClose=e}get onMsg(){return this._onMsg}set onMsg(e){this._onMsg=e}open(e,t,i=[]){if(this.isDisposed||this._kernel.isDisposed)throw new Error("Cannot open");const n=a.createMessage({msgType:"comm_open",channel:"shell",username:this._kernel.username,session:this._kernel.clientId,content:{comm_id:this._id,target_name:this._target,data:null!=e?e:{}},metadata:t,buffers:i});return this._kernel.sendShellMessage(n,!1,!0)}send(e,t,i=[],n=!0){if(this.isDisposed||this._kernel.isDisposed)throw new Error("Cannot send");const s=a.createMessage({msgType:"comm_msg",channel:"shell",username:this._kernel.username,session:this._kernel.clientId,content:{comm_id:this._id,data:e},metadata:t,buffers:i});return this._kernel.sendShellMessage(s,!1,n)}close(e,t,i=[]){if(this.isDisposed||this._kernel.isDisposed)throw new Error("Cannot close");const n=a.createMessage({msgType:"comm_close",channel:"shell",username:this._kernel.username,session:this._kernel.clientId,content:{comm_id:this._id,data:null!=e?e:{}},metadata:t,buffers:i}),s=this._kernel.sendShellMessage(n,!1,!0),r=this._onClose;return r&&r(a.createMessage({msgType:"comm_close",channel:"iopub",username:this._kernel.username,session:this._kernel.clientId,content:{comm_id:this._id,data:null!=e?e:{}},metadata:t,buffers:i})),this.dispose(),s}}t.CommHandler=l},5306:function(e,t,i){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.KernelConnection=void 0;const o=i(4251),a=i(3911),l=i(6424),h=i(5247),c=i(8341),d=r(i(1736)),u=i(217),p=i(8206),f=r(i(776)),m=i(3490),g=r(i(9753)),v="_RESTARTING_";class O{constructor(e){var t,i,n,s;this._createSocket=(e=!0)=>{this._errorIfDisposed(),this._clearSocket(),this._updateConnectionStatus("connecting");const t=this.serverSettings,i=o.URLExt.join(t.wsUrl,g.KERNEL_SERVICE_URL,encodeURIComponent(this._id)),n=i.replace(/^((?:\w+:)?\/\/)(?:[^@\/]+@)/,"$1");console.debug(`Starting WebSocket: ${n}`);let s=o.URLExt.join(i,"channels?session_id="+encodeURIComponent(this._clientId));const r=t.token;t.appendToken&&""!==r&&(s+=`&token=${encodeURIComponent(r)}`);const a=e?this._supportedProtocols:[];this._ws=new t.WebSocket(s,a),this._ws.binaryType="arraybuffer";let l=!1;const c=async e=>{var i,n;if(!this._isDisposed){this._reason="",this._model=void 0;try{const i=await g.getKernelModel(this._id,t);this._model=i,"dead"===(null==i?void 0:i.execution_state)?this._updateStatus("dead"):this._onWSClose(e)}catch(t){if(t instanceof h.ServerConnection.NetworkError||503===(null===(i=t.response)||void 0===i?void 0:i.status)||424===(null===(n=t.response)||void 0===n?void 0:n.status)){const t=1e3*b.getRandomIntInclusive(10,30);setTimeout(c,t,e)}else this._reason="Kernel died unexpectedly",this._updateStatus("dead")}}},d=async e=>{l||(l=!0,await c(e))};this._ws.onmessage=this._onWSMessage,this._ws.onopen=this._onWSOpen,this._ws.onclose=d,this._ws.onerror=d},this._onWSOpen=e=>{if(""!==this._ws.protocol&&!this._supportedProtocols.includes(this._ws.protocol))throw console.log("Server selected unknown kernel wire protocol:",this._ws.protocol),this._updateStatus("dead"),new Error(`Unknown kernel wire protocol: ${this._ws.protocol}`);this._selectedProtocol=this._ws.protocol,this._ws.onclose=this._onWSClose,this._ws.onerror=this._onWSClose,this._updateConnectionStatus("connected")},this._onWSMessage=e=>{let t;try{t=(0,p.deserialize)(e.data,this._ws.protocol),f.validateMessage(t)}catch(e){throw e.message=`Kernel message validation error: ${e.message}`,e}this._kernelSession=t.header.session,this._msgChain=this._msgChain.then((()=>this._handleMessage(t))).catch((e=>{e.message.startsWith("Canceled future for ")&&console.error(e)})),this._anyMessage.emit({msg:t,direction:"recv"})},this._onWSClose=e=>{this.isDisposed||this._reconnect()},this._id="",this._name="",this._status="unknown",this._connectionStatus="connecting",this._kernelSession="",this._isDisposed=!1,this._ws=null,this._username="",this._reconnectLimit=7,this._reconnectAttempt=0,this._reconnectTimeout=null,this._supportedProtocols=Object.values(d.supportedKernelWebSocketProtocols),this._selectedProtocol="",this._futures=new Map,this._comms=new Map,this._targetRegistry=Object.create(null),this._info=new a.PromiseDelegate,this._pendingMessages=[],this._statusChanged=new l.Signal(this),this._connectionStatusChanged=new l.Signal(this),this._disposed=new l.Signal(this),this._iopubMessage=new l.Signal(this),this._anyMessage=new l.Signal(this),this._pendingInput=new l.Signal(this),this._unhandledMessage=new l.Signal(this),this._displayIdToParentIds=new Map,this._msgIdToDisplayIds=new Map,this._msgChain=Promise.resolve(),this._hasPendingInput=!1,this._reason="",this._noOp=()=>{},this._name=e.model.name,this._id=e.model.id,this.serverSettings=null!==(t=e.serverSettings)&&void 0!==t?t:h.ServerConnection.makeSettings(),this._clientId=null!==(i=e.clientId)&&void 0!==i?i:a.UUID.uuid4(),this._username=null!==(n=e.username)&&void 0!==n?n:"",this.handleComms=null===(s=e.handleComms)||void 0===s||s,this._createSocket()}get disposed(){return this._disposed}get statusChanged(){return this._statusChanged}get connectionStatusChanged(){return this._connectionStatusChanged}get iopubMessage(){return this._iopubMessage}get unhandledMessage(){return this._unhandledMessage}get model(){return this._model||{id:this.id,name:this.name,reason:this._reason}}get anyMessage(){return this._anyMessage}get pendingInput(){return this._pendingInput}get id(){return this._id}get name(){return this._name}get username(){return this._username}get clientId(){return this._clientId}get status(){return this._status}get connectionStatus(){return this._connectionStatus}get isDisposed(){return this._isDisposed}get info(){return this._info.promise}get spec(){return this._specPromise||(this._specPromise=m.KernelSpecAPI.getSpecs(this.serverSettings).then((e=>e.kernelspecs[this._name]))),this._specPromise}clone(e={}){return new O({model:this.model,username:this.username,serverSettings:this.serverSettings,handleComms:!1,...e})}dispose(){this.isDisposed||(this._isDisposed=!0,this._disposed.emit(),this._updateConnectionStatus("disconnected"),this._clearKernelState(),this._pendingMessages=[],this._clearSocket(),l.Signal.clearData(this))}sendShellMessage(e,t=!1,i=!0){return this._sendKernelShellControl(u.KernelShellFutureHandler,e,t,i)}sendControlMessage(e,t=!1,i=!0){return this._sendKernelShellControl(u.KernelControlFutureHandler,e,t,i)}_sendKernelShellControl(e,t,i=!1,n=!0){this._sendMessage(t),this._anyMessage.emit({msg:t,direction:"send"});const s=new e((()=>{const e=t.header.msg_id;this._futures.delete(e);const i=this._msgIdToDisplayIds.get(e);i&&(i.forEach((t=>{const i=this._displayIdToParentIds.get(t);if(i){const n=i.indexOf(e);if(-1===n)return;1===i.length?this._displayIdToParentIds.delete(t):(i.splice(n,1),this._displayIdToParentIds.set(t,i))}})),this._msgIdToDisplayIds.delete(e))}),t,i,n,this);return this._futures.set(t.header.msg_id,s),s}_sendMessage(e,t=!0){if("dead"===this.status)throw new Error("Kernel is dead");if((""===this._kernelSession||this._kernelSession===v)&&d.isInfoRequestMsg(e)){if("connected"===this.connectionStatus)return void this._ws.send((0,p.serialize)(e,this._ws.protocol));throw new Error("Could not send message: status is not connected")}if(t&&this._pendingMessages.length>0)this._pendingMessages.push(e);else if("connected"===this.connectionStatus&&this._kernelSession!==v)this._ws.send((0,p.serialize)(e,this._ws.protocol));else{if(!t)throw new Error("Could not send message");this._pendingMessages.push(e)}}async interrupt(){if(this.hasPendingInput=!1,"dead"===this.status)throw new Error("Kernel is dead");return g.interruptKernel(this.id,this.serverSettings)}async restart(){if("dead"===this.status)throw new Error("Kernel is dead");this._updateStatus("restarting"),this._clearKernelState(),this._kernelSession=v,await g.restartKernel(this.id,this.serverSettings),await this.reconnect(),this.hasPendingInput=!1}reconnect(){this._errorIfDisposed();const e=new a.PromiseDelegate,t=(i,n)=>{"connected"===n?(e.resolve(),this.connectionStatusChanged.disconnect(t,this)):"disconnected"===n&&(e.reject(new Error("Kernel connection disconnected")),this.connectionStatusChanged.disconnect(t,this))};return this.connectionStatusChanged.connect(t,this),this._reconnectAttempt=0,this._reconnect(),e.promise}async shutdown(){"dead"!==this.status&&await g.shutdownKernel(this.id,this.serverSettings),this.handleShutdown()}handleShutdown(){this._updateStatus("dead"),this.dispose()}async requestKernelInfo(){const e=d.createMessage({msgType:"kernel_info_request",channel:"shell",username:this._username,session:this._clientId,content:{}});let t;try{t=await b.handleShellMessage(this,e)}catch(e){if(this.isDisposed)return;throw e}if(this._errorIfDisposed(),t)return void 0===t.content.status&&(t.content.status="ok"),"ok"!==t.content.status?(this._info.reject("Kernel info reply errored"),t):(this._info.resolve(t.content),this._kernelSession=t.header.session,t)}requestComplete(e){const t=d.createMessage({msgType:"complete_request",channel:"shell",username:this._username,session:this._clientId,content:e});return b.handleShellMessage(this,t)}requestInspect(e){const t=d.createMessage({msgType:"inspect_request",channel:"shell",username:this._username,session:this._clientId,content:e});return b.handleShellMessage(this,t)}requestHistory(e){const t=d.createMessage({msgType:"history_request",channel:"shell",username:this._username,session:this._clientId,content:e});return b.handleShellMessage(this,t)}requestExecute(e,t=!0,i){const n=d.createMessage({msgType:"execute_request",channel:"shell",username:this._username,session:this._clientId,content:{silent:!1,store_history:!0,user_expressions:{},allow_stdin:!0,stop_on_error:!1,...e},metadata:i});return this.sendShellMessage(n,!0,t)}requestDebug(e,t=!0){const i=d.createMessage({msgType:"debug_request",channel:"control",username:this._username,session:this._clientId,content:e});return this.sendControlMessage(i,!0,t)}requestIsComplete(e){const t=d.createMessage({msgType:"is_complete_request",channel:"shell",username:this._username,session:this._clientId,content:e});return b.handleShellMessage(this,t)}requestCommInfo(e){const t=d.createMessage({msgType:"comm_info_request",channel:"shell",username:this._username,session:this._clientId,content:e});return b.handleShellMessage(this,t)}sendInputReply(e,t){const i=d.createMessage({msgType:"input_reply",channel:"stdin",username:this._username,session:this._clientId,content:e});i.parent_header=t,this._sendMessage(i),this._anyMessage.emit({msg:i,direction:"send"}),this.hasPendingInput=!1}createComm(e,t=a.UUID.uuid4()){if(!this.handleComms)throw new Error("Comms are disabled on this kernel connection");if(this._comms.has(t))throw new Error("Comm is already created");const i=new c.CommHandler(e,t,this,(()=>{this._unregisterComm(t)}));return this._comms.set(t,i),i}hasComm(e){return this._comms.has(e)}registerCommTarget(e,t){this.handleComms&&(this._targetRegistry[e]=t)}removeCommTarget(e,t){this.handleComms&&(this.isDisposed||this._targetRegistry[e]!==t||delete this._targetRegistry[e])}registerMessageHook(e,t){var i;const n=null===(i=this._futures)||void 0===i?void 0:i.get(e);n&&n.registerMessageHook(t)}removeMessageHook(e,t){var i;const n=null===(i=this._futures)||void 0===i?void 0:i.get(e);n&&n.removeMessageHook(t)}removeInputGuard(){this.hasPendingInput=!1}async _handleDisplayId(e,t){var i,n;const s=t.parent_header.msg_id;let r=this._displayIdToParentIds.get(e);if(r){const e={header:a.JSONExt.deepCopy(t.header),parent_header:a.JSONExt.deepCopy(t.parent_header),metadata:a.JSONExt.deepCopy(t.metadata),content:a.JSONExt.deepCopy(t.content),channel:t.channel,buffers:t.buffers?t.buffers.slice():[]};e.header.msg_type="update_display_data",await Promise.all(r.map((async t=>{const i=this._futures&&this._futures.get(t);i&&await i.handleMsg(e)})))}if("update_display_data"===t.header.msg_type)return!0;r=null!==(i=this._displayIdToParentIds.get(e))&&void 0!==i?i:[],-1===r.indexOf(s)&&r.push(s),this._displayIdToParentIds.set(e,r);const o=null!==(n=this._msgIdToDisplayIds.get(s))&&void 0!==n?n:[];return-1===o.indexOf(s)&&o.push(s),this._msgIdToDisplayIds.set(s,o),!1}_clearSocket(){null!==this._ws&&(this._ws.onopen=this._noOp,this._ws.onclose=this._noOp,this._ws.onerror=this._noOp,this._ws.onmessage=this._noOp,this._ws.close(),this._ws=null)}_updateStatus(e){this._status!==e&&"dead"!==this._status&&(this._status=e,b.logKernelStatus(this),this._statusChanged.emit(e),"dead"===e&&this.dispose())}_sendPending(){for(;"connected"===this.connectionStatus&&this._kernelSession!==v&&this._pendingMessages.length>0;)this._sendMessage(this._pendingMessages[0],!1),this._pendingMessages.shift()}_clearKernelState(){this._kernelSession="",this._pendingMessages=[],this._futures.forEach((e=>{e.dispose()})),this._comms.forEach((e=>{e.dispose()})),this._msgChain=Promise.resolve(),this._futures=new Map,this._comms=new Map,this._displayIdToParentIds.clear(),this._msgIdToDisplayIds.clear()}_assertCurrentMessage(e){if(this._errorIfDisposed(),e.header.session!==this._kernelSession)throw new Error(`Canceling handling of old message: ${e.header.msg_type}`)}async _handleCommOpen(e){this._assertCurrentMessage(e);const t=e.content,i=new c.CommHandler(t.target_name,t.comm_id,this,(()=>{this._unregisterComm(t.comm_id)}));this._comms.set(t.comm_id,i);try{const n=await b.loadObject(t.target_name,t.target_module,this._targetRegistry);await n(i,e)}catch(e){throw i.close(),console.error("Exception opening new comm"),e}}async _handleCommClose(e){this._assertCurrentMessage(e);const t=e.content,i=this._comms.get(t.comm_id);if(!i)return void console.error("Comm not found for comm id "+t.comm_id);this._unregisterComm(i.commId);const n=i.onClose;n&&await n(e),i.dispose()}async _handleCommMsg(e){this._assertCurrentMessage(e);const t=e.content,i=this._comms.get(t.comm_id);if(!i)return;const n=i.onMsg;n&&await n(e)}_unregisterComm(e){this._comms.delete(e)}_updateConnectionStatus(e){if(this._connectionStatus!==e){if(this._connectionStatus=e,"connecting"!==e&&(this._reconnectAttempt=0,clearTimeout(this._reconnectTimeout)),"dead"!==this.status)if("connected"===e){let e=this._kernelSession===v,t=this.requestKernelInfo(),i=!1,n=()=>{i||(i=!0,e&&this._kernelSession===v&&(this._kernelSession=""),clearTimeout(s),this._pendingMessages.length>0&&this._sendPending())};t.then(n);let s=setTimeout(n,3e3)}else this._updateStatus("unknown");this._connectionStatusChanged.emit(e)}}async _handleMessage(e){var t,i;let n=!1;if(e.parent_header&&"iopub"===e.channel&&(d.isDisplayDataMsg(e)||d.isUpdateDisplayDataMsg(e)||d.isExecuteResultMsg(e))){const i=(null!==(t=e.content.transient)&&void 0!==t?t:{}).display_id;i&&(n=await this._handleDisplayId(i,e),this._assertCurrentMessage(e))}if(!n&&e.parent_header){const t=e.parent_header,n=null===(i=this._futures)||void 0===i?void 0:i.get(t.msg_id);if(n)await n.handleMsg(e),this._assertCurrentMessage(e);else{const i=t.session===this.clientId;"iopub"!==e.channel&&i&&this._unhandledMessage.emit(e)}}if("iopub"===e.channel){switch(e.header.msg_type){case"status":{const t=e.content.execution_state;"restarting"===t&&Promise.resolve().then((async()=>{this._updateStatus("autorestarting"),this._clearKernelState(),await this.reconnect()})),this._updateStatus(t);break}case"comm_open":this.handleComms&&await this._handleCommOpen(e);break;case"comm_msg":this.handleComms&&await this._handleCommMsg(e);break;case"comm_close":this.handleComms&&await this._handleCommClose(e)}this.isDisposed||(this._assertCurrentMessage(e),this._iopubMessage.emit(e))}}_reconnect(){if(this._errorIfDisposed(),clearTimeout(this._reconnectTimeout),this._reconnectAttempt{if(t){if("undefined"==typeof requirejs)throw new Error("requirejs not found");requirejs([t],(i=>{void 0===i[e]?s(new Error(`Object '${e}' not found in module '${t}'`)):n(i[e])}),s)}else(null==i?void 0:i[e])?n(i[e]):s(new Error(`Object '${e}' not found in registry`))}))},e.getRandomIntInclusive=function(e,t){return e=Math.ceil(e),t=Math.floor(t),Math.floor(Math.random()*(t-e+1))+e}}(b||(b={}))},217:function(e,t,i){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.KernelShellFutureHandler=t.KernelControlFutureHandler=t.KernelFutureHandler=void 0;const o=i(3911),a=i(1122),l=r(i(1736));class h extends a.DisposableDelegate{constructor(e,t,i,n,s){super(e),this._status=0,this._stdin=c.noOp,this._iopub=c.noOp,this._reply=c.noOp,this._done=new o.PromiseDelegate,this._hooks=new c.HookList,this._disposeOnDone=!0,this._msg=t,i||this._setFlag(c.KernelFutureFlag.GotReply),this._disposeOnDone=n,this._kernel=s}get msg(){return this._msg}get done(){return this._done.promise}get onReply(){return this._reply}set onReply(e){this._reply=e}get onIOPub(){return this._iopub}set onIOPub(e){this._iopub=e}get onStdin(){return this._stdin}set onStdin(e){this._stdin=e}registerMessageHook(e){if(this.isDisposed)throw new Error("Kernel future is disposed");this._hooks.add(e)}removeMessageHook(e){this.isDisposed||this._hooks.remove(e)}sendInputReply(e,t){this._kernel.sendInputReply(e,t)}dispose(){this._stdin=c.noOp,this._iopub=c.noOp,this._reply=c.noOp,this._hooks=null,this._testFlag(c.KernelFutureFlag.IsDone)||(this._done.promise.catch((()=>{})),this._done.reject(new Error(`Canceled future for ${this.msg.header.msg_type} message before replies were done`))),super.dispose()}async handleMsg(e){switch(e.channel){case"control":case"shell":e.channel===this.msg.channel&&e.parent_header.msg_id===this.msg.header.msg_id&&await this._handleReply(e);break;case"stdin":await this._handleStdin(e);break;case"iopub":await this._handleIOPub(e)}}async _handleReply(e){const t=this._reply;t&&await t(e),this._replyMsg=e,this._setFlag(c.KernelFutureFlag.GotReply),this._testFlag(c.KernelFutureFlag.GotIdle)&&this._handleDone()}async _handleStdin(e){this._kernel.hasPendingInput=!0;const t=this._stdin;t&&await t(e)}async _handleIOPub(e){const t=await this._hooks.process(e),i=this._iopub;t&&i&&await i(e),l.isStatusMsg(e)&&"idle"===e.content.execution_state&&(this._setFlag(c.KernelFutureFlag.GotIdle),this._testFlag(c.KernelFutureFlag.GotReply)&&this._handleDone())}_handleDone(){this._testFlag(c.KernelFutureFlag.IsDone)||(this._setFlag(c.KernelFutureFlag.IsDone),this._done.resolve(this._replyMsg),this._disposeOnDone&&this.dispose())}_testFlag(e){return 0!=(this._status&e)}_setFlag(e){this._status|=e}}var c;t.KernelFutureHandler=h,t.KernelControlFutureHandler=class extends h{},t.KernelShellFutureHandler=class extends h{},function(e){e.noOp=()=>{};const t="function"==typeof requestAnimationFrame?requestAnimationFrame:setImmediate;let i;e.HookList=class{constructor(){this._hooks=[]}add(e){this.remove(e),this._hooks.push(e)}remove(e){const t=this._hooks.indexOf(e);t>=0&&(this._hooks[t]=null,this._scheduleCompact())}async process(e){await this._processing;const t=new o.PromiseDelegate;let i;this._processing=t.promise;for(let n=this._hooks.length-1;n>=0;n--){const s=this._hooks[n];if(null!==s){try{i=await s(e)}catch(e){i=!0,console.error(e)}if(!1===i)return t.resolve(void 0),!1}}return t.resolve(void 0),!0}_scheduleCompact(){this._compactScheduled||(this._compactScheduled=!0,t((()=>{this._processing=this._processing.then((()=>{this._compactScheduled=!1,this._compact()}))})))}_compact(){let e=0;for(let t=0,i=this._hooks.length;t{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},2298:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.KernelManager=void 0;const n=i(9044),s=i(6424),r=i(5247),o=i(7524),a=i(9753),l=i(5306);class h extends o.BaseManager{constructor(e={}){var t;super(e),this._isReady=!1,this._kernelConnections=new Set,this._models=new Map,this._runningChanged=new s.Signal(this),this._connectionFailure=new s.Signal(this),this._pollModels=new n.Poll({auto:!1,factory:()=>this.requestRunning(),frequency:{interval:1e4,backoff:!0,max:3e5},name:"@jupyterlab/services:KernelManager#models",standby:null!==(t=e.standby)&&void 0!==t?t:"when-hidden"}),this._ready=(async()=>{await this._pollModels.start(),await this._pollModels.tick,this._isReady=!0})()}get isReady(){return this._isReady}get ready(){return this._ready}get runningChanged(){return this._runningChanged}get connectionFailure(){return this._connectionFailure}dispose(){this.isDisposed||(this._models.clear(),this._kernelConnections.forEach((e=>e.dispose())),this._pollModels.dispose(),super.dispose())}connectTo(e){var t;const{id:i}=e.model;let n=null===(t=e.handleComms)||void 0===t||t;if(void 0===e.handleComms)for(const e of this._kernelConnections)if(e.id===i&&e.handleComms){n=!1;break}const s=new l.KernelConnection({handleComms:n,...e,serverSettings:this.serverSettings});return this._onStarted(s),this._models.has(i)||this.refreshRunning().catch((()=>{})),s}running(){return this._models.values()}async refreshRunning(){await this._pollModels.refresh(),await this._pollModels.tick}async startNew(e={},t={}){const i=await(0,a.startNew)(e,this.serverSettings);return this.connectTo({...t,model:i})}async shutdown(e){await(0,a.shutdownKernel)(e,this.serverSettings),await this.refreshRunning()}async shutdownAll(){await this.refreshRunning(),await Promise.all([...this._models.keys()].map((e=>(0,a.shutdownKernel)(e,this.serverSettings)))),await this.refreshRunning()}async findById(e){return this._models.has(e)||await this.refreshRunning(),this._models.get(e)}async requestRunning(){var e,t;let i;try{i=await(0,a.listRunning)(this.serverSettings)}catch(i){throw(i instanceof r.ServerConnection.NetworkError||503===(null===(e=i.response)||void 0===e?void 0:e.status)||424===(null===(t=i.response)||void 0===t?void 0:t.status))&&this._connectionFailure.emit(i),i}this.isDisposed||this._models.size===i.length&&i.every((e=>{const t=this._models.get(e.id);return!!t&&t.connections===e.connections&&t.execution_state===e.execution_state&&t.last_activity===e.last_activity&&t.name===e.name&&t.reason===e.reason&&t.traceback===e.traceback}))||(this._models=new Map(i.map((e=>[e.id,e]))),this._kernelConnections.forEach((e=>{this._models.has(e.id)||e.handleShutdown()})),this._runningChanged.emit(i))}_onStarted(e){this._kernelConnections.add(e),e.statusChanged.connect(this._onStatusChanged,this),e.disposed.connect(this._onDisposed,this)}_onDisposed(e){this._kernelConnections.delete(e),this.refreshRunning().catch((()=>{}))}_onStatusChanged(e,t){"dead"===t&&this.refreshRunning().catch((()=>{}))}}t.KernelManager=h,function(e){e.NoopManager=class extends e{constructor(){super(...arguments),this._readyPromise=new Promise((()=>{}))}get isActive(){return!1}get parentReady(){return super.ready}async startNew(e={},t={}){return Promise.reject(new Error("Not implemented in no-op Kernel Manager"))}connectTo(e){throw new Error("Not implemented in no-op Kernel Manager")}async shutdown(e){return Promise.reject(new Error("Not implemented in no-op Kernel Manager"))}get ready(){return this.parentReady.then((()=>this._readyPromise))}async requestRunning(){return Promise.resolve()}}}(h=t.KernelManager||(t.KernelManager={}))},1736:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.supportedKernelWebSocketProtocols=t.isInputReplyMsg=t.isInputRequestMsg=t.isDebugReplyMsg=t.isDebugRequestMsg=t.isExecuteReplyMsg=t.isInfoRequestMsg=t.isCommMsgMsg=t.isCommCloseMsg=t.isCommOpenMsg=t.isDebugEventMsg=t.isClearOutputMsg=t.isStatusMsg=t.isErrorMsg=t.isExecuteResultMsg=t.isExecuteInputMsg=t.isUpdateDisplayDataMsg=t.isDisplayDataMsg=t.isStreamMsg=t.createMessage=void 0;const n=i(3911);t.createMessage=function(e){var t,i,s,r,o;return{buffers:null!==(t=e.buffers)&&void 0!==t?t:[],channel:e.channel,content:e.content,header:{date:(new Date).toISOString(),msg_id:null!==(i=e.msgId)&&void 0!==i?i:n.UUID.uuid4(),msg_type:e.msgType,session:e.session,username:null!==(s=e.username)&&void 0!==s?s:"",version:"5.2"},metadata:null!==(r=e.metadata)&&void 0!==r?r:{},parent_header:null!==(o=e.parentHeader)&&void 0!==o?o:{}}},t.isStreamMsg=function(e){return"stream"===e.header.msg_type},t.isDisplayDataMsg=function(e){return"display_data"===e.header.msg_type},t.isUpdateDisplayDataMsg=function(e){return"update_display_data"===e.header.msg_type},t.isExecuteInputMsg=function(e){return"execute_input"===e.header.msg_type},t.isExecuteResultMsg=function(e){return"execute_result"===e.header.msg_type},t.isErrorMsg=function(e){return"error"===e.header.msg_type},t.isStatusMsg=function(e){return"status"===e.header.msg_type},t.isClearOutputMsg=function(e){return"clear_output"===e.header.msg_type},t.isDebugEventMsg=function(e){return"debug_event"===e.header.msg_type},t.isCommOpenMsg=function(e){return"comm_open"===e.header.msg_type},t.isCommCloseMsg=function(e){return"comm_close"===e.header.msg_type},t.isCommMsgMsg=function(e){return"comm_msg"===e.header.msg_type},t.isInfoRequestMsg=function(e){return"kernel_info_request"===e.header.msg_type},t.isExecuteReplyMsg=function(e){return"execute_reply"===e.header.msg_type},t.isDebugRequestMsg=function(e){return"debug_request"===e.header.msg_type},t.isDebugReplyMsg=function(e){return"debug_reply"===e.header.msg_type},t.isInputRequestMsg=function(e){return"input_request"===e.header.msg_type},t.isInputReplyMsg=function(e){return"input_reply"===e.header.msg_type},(t.supportedKernelWebSocketProtocols||(t.supportedKernelWebSocketProtocols={})).v1KernelWebsocketJupyterOrg="v1.kernel.websocket.jupyter.org"},9753:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getKernelModel=t.shutdownKernel=t.interruptKernel=t.restartKernel=t.startNew=t.listRunning=t.KERNEL_SERVICE_URL=void 0;const n=i(538),s=i(4251),r=i(776);t.KERNEL_SERVICE_URL="api/kernels",t.listRunning=async function(e=n.ServerConnection.makeSettings()){const i=s.URLExt.join(e.baseUrl,t.KERNEL_SERVICE_URL),o=await n.ServerConnection.makeRequest(i,{},e);if(200!==o.status)throw await n.ServerConnection.ResponseError.create(o);const a=await o.json();return(0,r.validateModels)(a),a},t.startNew=async function(e={},i=n.ServerConnection.makeSettings()){const o=s.URLExt.join(i.baseUrl,t.KERNEL_SERVICE_URL),a={method:"POST",body:JSON.stringify(e)},l=await n.ServerConnection.makeRequest(o,a,i);if(201!==l.status)throw await n.ServerConnection.ResponseError.create(l);const h=await l.json();return(0,r.validateModel)(h),h},t.restartKernel=async function(e,i=n.ServerConnection.makeSettings()){const o=s.URLExt.join(i.baseUrl,t.KERNEL_SERVICE_URL,encodeURIComponent(e),"restart"),a=await n.ServerConnection.makeRequest(o,{method:"POST"},i);if(200!==a.status)throw await n.ServerConnection.ResponseError.create(a);const l=await a.json();(0,r.validateModel)(l)},t.interruptKernel=async function(e,i=n.ServerConnection.makeSettings()){const r=s.URLExt.join(i.baseUrl,t.KERNEL_SERVICE_URL,encodeURIComponent(e),"interrupt"),o=await n.ServerConnection.makeRequest(r,{method:"POST"},i);if(204!==o.status)throw await n.ServerConnection.ResponseError.create(o)},t.shutdownKernel=async function(e,i=n.ServerConnection.makeSettings()){const r=s.URLExt.join(i.baseUrl,t.KERNEL_SERVICE_URL,encodeURIComponent(e)),o=await n.ServerConnection.makeRequest(r,{method:"DELETE"},i);if(404===o.status){const t=`The kernel "${e}" does not exist on the server`;console.warn(t)}else if(204!==o.status)throw await n.ServerConnection.ResponseError.create(o)},t.getKernelModel=async function(e,i=n.ServerConnection.makeSettings()){const o=s.URLExt.join(i.baseUrl,t.KERNEL_SERVICE_URL,encodeURIComponent(e)),a=await n.ServerConnection.makeRequest(o,{},i);if(404===a.status)return;if(200!==a.status)throw await n.ServerConnection.ResponseError.create(a);const l=await a.json();return(0,r.validateModel)(l),l}},8206:function(e,t,i){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.deserialize=t.serialize=void 0;const o=r(i(1736));var a;t.serialize=function(e,t=""){return t===o.supportedKernelWebSocketProtocols.v1KernelWebsocketJupyterOrg?a.serializeV1KernelWebsocketJupyterOrg(e):a.serializeDefault(e)},t.deserialize=function(e,t=""){return t===o.supportedKernelWebSocketProtocols.v1KernelWebsocketJupyterOrg?a.deserializeV1KernelWebsocketJupyterOrg(e):a.deserializeDefault(e)},function(e){e.deserializeV1KernelWebsocketJupyterOrg=function(e){let t;const i=new DataView(e),n=Number(i.getBigUint64(0,!0));let s=[];for(let e=0;e{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.validateModels=t.validateModel=t.validateMessage=void 0;const n=i(3247),s=["username","version","session","msg_id","msg_type"],r={stream:{name:"string",text:"string"},display_data:{data:"object",metadata:"object"},execute_input:{code:"string",execution_count:"number"},execute_result:{execution_count:"number",data:"object",metadata:"object"},error:{ename:"string",evalue:"string",traceback:"object"},status:{execution_state:["string",["starting","idle","busy","restarting","dead"]]},clear_output:{wait:"boolean"},comm_open:{comm_id:"string",target_name:"string",data:"object"},comm_msg:{comm_id:"string",data:"object"},comm_close:{comm_id:"string"},shutdown_reply:{restart:"boolean"}};function o(e){(0,n.validateProperty)(e,"name","string"),(0,n.validateProperty)(e,"id","string")}t.validateMessage=function(e){(0,n.validateProperty)(e,"metadata","object"),(0,n.validateProperty)(e,"content","object"),(0,n.validateProperty)(e,"channel","string"),function(e){for(let t=0;to(e)))}},3490:function(e,t,i){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t},o=this&&this.__exportStar||function(e,t){for(var i in e)"default"===i||Object.prototype.hasOwnProperty.call(t,i)||n(t,e,i)};Object.defineProperty(t,"__esModule",{value:!0}),t.KernelSpecAPI=t.KernelSpec=void 0;const a=r(i(6060));t.KernelSpec=a;const l=r(i(1598));t.KernelSpecAPI=l,o(i(7307),t)},6060:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},7307:function(e,t,i){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t};Object.defineProperty(t,"__esModule",{value:!0}),t.KernelSpecManager=void 0;const o=i(3911),a=i(9044),l=i(6424),h=r(i(1598)),c=i(7524);class d extends c.BaseManager{constructor(e={}){var t;super(e),this._isReady=!1,this._connectionFailure=new l.Signal(this),this._specs=null,this._specsChanged=new l.Signal(this),this._ready=Promise.all([this.requestSpecs()]).then((e=>{})).catch((e=>{})).then((()=>{this.isDisposed||(this._isReady=!0)})),this._pollSpecs=new a.Poll({auto:!1,factory:()=>this.requestSpecs(),frequency:{interval:61e3,backoff:!0,max:3e5},name:"@jupyterlab/services:KernelSpecManager#specs",standby:null!==(t=e.standby)&&void 0!==t?t:"when-hidden"}),this.ready.then((()=>{this._pollSpecs.start()}))}get isReady(){return this._isReady}get ready(){return this._ready}get specs(){return this._specs}get specsChanged(){return this._specsChanged}get connectionFailure(){return this._connectionFailure}dispose(){this._pollSpecs.dispose(),super.dispose()}async refreshSpecs(){await this._pollSpecs.refresh(),await this._pollSpecs.tick}async requestSpecs(){const e=await h.getSpecs(this.serverSettings);this.isDisposed||o.JSONExt.deepEqual(e,this._specs)||(this._specs=e,this._specsChanged.emit(e))}}t.KernelSpecManager=d},1598:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getSpecs=void 0;const n=i(538),s=i(4286),r=i(4251);t.getSpecs=async function(e=n.ServerConnection.makeSettings()){const t=r.URLExt.join(e.baseUrl,"api/kernelspecs"),i=await n.ServerConnection.makeRequest(t,{},e);if(200!==i.status)throw await n.ServerConnection.ResponseError.create(i);const o=await i.json();return(0,s.validateSpecModels)(o)}},4286:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.validateSpecModels=t.validateSpecModel=void 0;const n=i(3247);function s(e){const t=e.spec;if(!t)throw new Error("Invalid kernel spec");(0,n.validateProperty)(e,"name","string"),(0,n.validateProperty)(e,"resources","object"),(0,n.validateProperty)(t,"language","string"),(0,n.validateProperty)(t,"display_name","string"),(0,n.validateProperty)(t,"argv","array");let i=null;t.hasOwnProperty("metadata")&&((0,n.validateProperty)(t,"metadata","object"),i=t.metadata);let s=null;return t.hasOwnProperty("env")&&((0,n.validateProperty)(t,"env","object"),s=t.env),{name:e.name,resources:e.resources,language:t.language,display_name:t.display_name,argv:t.argv,metadata:i,env:s}}t.validateSpecModel=s,t.validateSpecModels=function(e){if(!e.hasOwnProperty("kernelspecs"))throw new Error("No kernelspecs found");let t=Object.keys(e.kernelspecs);const i=Object.create(null);let n=e.default;for(let n=0;n{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.ServiceManager=void 0;const n=i(6424),s=i(4011),r=i(1708),o=i(5657),a=i(5674),l=i(3490),h=i(6624),c=i(538),d=i(3561),u=i(9188),p=i(3185),f=i(1014),m=i(9090);t.ServiceManager=class{constructor(e={}){var t,i;this._isDisposed=!1,this._connectionFailure=new n.Signal(this),this._isReady=!1;const g=e.defaultDrive,v=null!==(t=e.serverSettings)&&void 0!==t?t:c.ServerConnection.makeSettings(),O={defaultDrive:g,serverSettings:v,standby:null!==(i=e.standby)&&void 0!==i?i:"when-hidden"};this.serverSettings=v,this.contents=e.contents||new r.ContentsManager(O),this.events=e.events||new o.EventManager(O),this.kernels=e.kernels||new a.KernelManager(O),this.sessions=e.sessions||new d.SessionManager({...O,kernelManager:this.kernels}),this.settings=e.settings||new u.SettingManager(O),this.terminals=e.terminals||new p.TerminalManager(O),this.builder=e.builder||new s.BuildManager(O),this.workspaces=e.workspaces||new m.WorkspaceManager(O),this.nbconvert=e.nbconvert||new h.NbConvertManager(O),this.kernelspecs=e.kernelspecs||new l.KernelSpecManager(O),this.user=e.user||new f.UserManager(O),this.kernelspecs.connectionFailure.connect(this._onConnectionFailure,this),this.sessions.connectionFailure.connect(this._onConnectionFailure,this),this.terminals.connectionFailure.connect(this._onConnectionFailure,this);const b=[this.sessions.ready,this.kernelspecs.ready];this.terminals.isAvailable()&&b.push(this.terminals.ready),this._readyPromise=Promise.all(b).then((()=>{this._isReady=!0}))}get connectionFailure(){return this._connectionFailure}get isDisposed(){return this._isDisposed}dispose(){this.isDisposed||(this._isDisposed=!0,n.Signal.clearData(this),this.contents.dispose(),this.events.dispose(),this.sessions.dispose(),this.terminals.dispose())}get isReady(){return this._isReady}get ready(){return this._readyPromise}_onConnectionFailure(e,t){this._connectionFailure.emit(t)}}},6624:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.NbConvertManager=void 0;const n=i(4251),s=i(538),r=i(3911);t.NbConvertManager=class{constructor(e={}){var t;this._exportFormats=null,this.serverSettings=null!==(t=e.serverSettings)&&void 0!==t?t:s.ServerConnection.makeSettings()}async fetchExportFormats(){this._requestingFormats=new r.PromiseDelegate,this._exportFormats=null;const e=this.serverSettings.baseUrl,t=n.URLExt.join(e,"api/nbconvert"),{serverSettings:i}=this,o=await s.ServerConnection.makeRequest(t,{},i);if(200!==o.status)throw await s.ServerConnection.ResponseError.create(o);const a=await o.json(),l={};return Object.keys(a).forEach((function(e){const t=a[e].output_mimetype;l[e]={output_mimetype:t}})),this._exportFormats=l,this._requestingFormats.resolve(l),l}async getExportFormats(e=!0){return this._requestingFormats?this._requestingFormats.promise:e||!this._exportFormats?await this.fetchExportFormats():this._exportFormats}}},538:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.ServerConnection=void 0;const n=i(4251);let s;var r,o;s="undefined"==typeof window?i(8354):WebSocket,function(e){e.makeSettings=function(e){return o.makeSettings(e)},e.makeRequest=function(e,t,i){return o.handleRequest(e,t,i)};class t extends Error{static async create(e){try{const i=await e.json(),{message:n,traceback:s}=i;return s&&console.error(s),new t(e,null!=n?n:t._defaultMessage(e),null!=s?s:"")}catch(i){return console.debug(i),new t(e)}}constructor(e,i=t._defaultMessage(e),n=""){super(i),this.response=e,this.traceback=n}static _defaultMessage(e){return`Invalid response: ${e.status} ${e.statusText}`}}e.ResponseError=t;class i extends TypeError{constructor(e){super(e.message),this.stack=e.stack}}e.NetworkError=i}(r=t.ServerConnection||(t.ServerConnection={})),function(e){e.makeSettings=function(e={}){var t;const i=n.PageConfig.getBaseUrl(),r=n.PageConfig.getWsUrl(),o=n.URLExt.normalize(e.baseUrl)||i;let a=e.wsUrl;return a||o!==i||(a=r),a||0!==o.indexOf("http")||(a="ws"+o.slice(4)),a=null!=a?a:r,{init:{cache:"no-store",credentials:"same-origin"},fetch,Headers,Request,WebSocket:s,token:n.PageConfig.getToken(),appUrl:n.PageConfig.getOption("appUrl"),appendToken:"undefined"==typeof window||"undefined"!=typeof process&&void 0!==(null===(t=null===process||void 0===process?void 0:{})||void 0===t?void 0:t.JEST_WORKER_ID)||n.URLExt.getHostName(i)!==n.URLExt.getHostName(a),...e,baseUrl:o,wsUrl:a}},e.handleRequest=function(e,t,i){var n;if(0!==e.indexOf(i.baseUrl))throw new Error("Can only be used for notebook server requests");"no-store"===(null!==(n=t.cache)&&void 0!==n?n:i.init.cache)&&(e+=(/\?/.test(e)?"&":"?")+(new Date).getTime());const s=new i.Request(e,{...i.init,...t});let o=!1;if(i.token&&(o=!0,s.headers.append("Authorization",`token ${i.token}`)),"undefined"!=typeof document&&(null===document||void 0===document?void 0:document.cookie)){const e=function(e){const t=document.cookie.match("\\b_xsrf=([^;]*)\\b");return null==t?void 0:t[1]}();void 0!==e&&(o=!0,s.headers.append("X-XSRFToken",e))}return!s.headers.has("Content-Type")&&o&&s.headers.set("Content-Type","application/json"),i.fetch.call(null,s).catch((e=>{throw new r.NetworkError(e)}))}}(o||(o={}))},6512:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SessionConnection=void 0;const n=i(6424),s=i(5247),r=i(1975),o=i(3911);t.SessionConnection=class{constructor(e){var t,i,r,a;this._id="",this._path="",this._name="",this._type="",this._kernel=null,this._isDisposed=!1,this._disposed=new n.Signal(this),this._kernelChanged=new n.Signal(this),this._statusChanged=new n.Signal(this),this._connectionStatusChanged=new n.Signal(this),this._pendingInput=new n.Signal(this),this._iopubMessage=new n.Signal(this),this._unhandledMessage=new n.Signal(this),this._anyMessage=new n.Signal(this),this._propertyChanged=new n.Signal(this),this._id=e.model.id,this._name=e.model.name,this._path=e.model.path,this._type=e.model.type,this._username=null!==(t=e.username)&&void 0!==t?t:"",this._clientId=null!==(i=e.clientId)&&void 0!==i?i:o.UUID.uuid4(),this._connectToKernel=e.connectToKernel,this._kernelConnectionOptions=null!==(r=e.kernelConnectionOptions)&&void 0!==r?r:{},this.serverSettings=null!==(a=e.serverSettings)&&void 0!==a?a:s.ServerConnection.makeSettings(),this.setupKernel(e.model.kernel)}get disposed(){return this._disposed}get kernelChanged(){return this._kernelChanged}get statusChanged(){return this._statusChanged}get connectionStatusChanged(){return this._connectionStatusChanged}get pendingInput(){return this._pendingInput}get iopubMessage(){return this._iopubMessage}get unhandledMessage(){return this._unhandledMessage}get anyMessage(){return this._anyMessage}get propertyChanged(){return this._propertyChanged}get id(){return this._id}get kernel(){return this._kernel}get path(){return this._path}get type(){return this._type}get name(){return this._name}get model(){return{id:this.id,kernel:this.kernel&&{id:this.kernel.id,name:this.kernel.name},path:this._path,type:this._type,name:this._name}}get isDisposed(){return this._isDisposed}update(e){const t=this.model;if(this._path=e.path,this._name=e.name,this._type=e.type,null===this._kernel&&null!==e.kernel||null!==this._kernel&&null===e.kernel||null!==this._kernel&&null!==e.kernel&&this._kernel.id!==e.kernel.id){null!==this._kernel&&this._kernel.dispose();const t=this._kernel||null;this.setupKernel(e.kernel);const i=this._kernel||null;this._kernelChanged.emit({name:"kernel",oldValue:t,newValue:i})}this._handleModelChange(t)}dispose(){if(!this.isDisposed){if(this._isDisposed=!0,this._disposed.emit(),this._kernel){this._kernel.dispose();const e=this._kernel;this._kernel=null;const t=this._kernel;this._kernelChanged.emit({name:"kernel",oldValue:e,newValue:t})}n.Signal.clearData(this)}}async setPath(e){if(this.isDisposed)throw new Error("Session is disposed");await this._patch({path:e})}async setName(e){if(this.isDisposed)throw new Error("Session is disposed");await this._patch({name:e})}async setType(e){if(this.isDisposed)throw new Error("Session is disposed");await this._patch({type:e})}async changeKernel(e){if(this.isDisposed)throw new Error("Session is disposed");return await this._patch({kernel:e}),this.kernel}async shutdown(){if(this.isDisposed)throw new Error("Session is disposed");await(0,r.shutdownSession)(this.id,this.serverSettings),this.dispose()}setupKernel(e){if(null===e)return void(this._kernel=null);const t=this._connectToKernel({...this._kernelConnectionOptions,model:e,username:this._username,clientId:this._clientId,serverSettings:this.serverSettings});this._kernel=t,t.statusChanged.connect(this.onKernelStatus,this),t.connectionStatusChanged.connect(this.onKernelConnectionStatus,this),t.pendingInput.connect(this.onPendingInput,this),t.unhandledMessage.connect(this.onUnhandledMessage,this),t.iopubMessage.connect(this.onIOPubMessage,this),t.anyMessage.connect(this.onAnyMessage,this)}onKernelStatus(e,t){this._statusChanged.emit(t)}onKernelConnectionStatus(e,t){this._connectionStatusChanged.emit(t)}onPendingInput(e,t){this._pendingInput.emit(t)}onIOPubMessage(e,t){this._iopubMessage.emit(t)}onUnhandledMessage(e,t){this._unhandledMessage.emit(t)}onAnyMessage(e,t){this._anyMessage.emit(t)}async _patch(e){const t=await(0,r.updateSession)({...e,id:this._id},this.serverSettings);return this.update(t),t}_handleModelChange(e){e.name!==this._name&&this._propertyChanged.emit("name"),e.type!==this._type&&this._propertyChanged.emit("type"),e.path!==this._path&&this._propertyChanged.emit("path")}}},3561:function(e,t,i){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),r=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&n(t,e,i);return s(t,e),t},o=this&&this.__exportStar||function(e,t){for(var i in e)"default"===i||Object.prototype.hasOwnProperty.call(t,i)||n(t,e,i)};Object.defineProperty(t,"__esModule",{value:!0}),t.SessionAPI=t.Session=void 0;const a=r(i(7993));t.Session=a;const l=r(i(1975));t.SessionAPI=l,o(i(8137),t)},8137:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SessionManager=void 0;const n=i(9044),s=i(6424),r=i(538),o=i(7524),a=i(6512),l=i(1975);class h extends o.BaseManager{constructor(e){var t;super(e),this._isReady=!1,this._sessionConnections=new Set,this._models=new Map,this._runningChanged=new s.Signal(this),this._connectionFailure=new s.Signal(this),this._connectToKernel=e=>this._kernelManager.connectTo(e),this._kernelManager=e.kernelManager,this._pollModels=new n.Poll({auto:!1,factory:()=>this.requestRunning(),frequency:{interval:1e4,backoff:!0,max:3e5},name:"@jupyterlab/services:SessionManager#models",standby:null!==(t=e.standby)&&void 0!==t?t:"when-hidden"}),this._ready=(async()=>{await this._pollModels.start(),await this._pollModels.tick,this._kernelManager.isActive&&await this._kernelManager.ready,this._isReady=!0})()}get isReady(){return this._isReady}get ready(){return this._ready}get runningChanged(){return this._runningChanged}get connectionFailure(){return this._connectionFailure}dispose(){this.isDisposed||(this._models.clear(),this._sessionConnections.forEach((e=>e.dispose())),this._pollModels.dispose(),super.dispose())}connectTo(e){const t=new a.SessionConnection({...e,connectToKernel:this._connectToKernel,serverSettings:this.serverSettings});return this._onStarted(t),this._models.has(e.model.id)||this.refreshRunning().catch((()=>{})),t}running(){return this._models.values()}async refreshRunning(){await this._pollModels.refresh(),await this._pollModels.tick}async startNew(e,t={}){const i=await(0,l.startSession)(e,this.serverSettings);return await this.refreshRunning(),this.connectTo({...t,model:i})}async shutdown(e){await(0,l.shutdownSession)(e,this.serverSettings),await this.refreshRunning()}async shutdownAll(){await this.refreshRunning(),await Promise.all([...this._models.keys()].map((e=>(0,l.shutdownSession)(e,this.serverSettings)))),await this.refreshRunning()}async stopIfNeeded(e){try{const t=(await(0,l.listRunning)(this.serverSettings)).filter((t=>t.path===e));if(1===t.length){const e=t[0].id;await this.shutdown(e)}}catch(e){}}async findById(e){return this._models.has(e)||await this.refreshRunning(),this._models.get(e)}async findByPath(e){for(const t of this._models.values())if(t.path===e)return t;await this.refreshRunning();for(const t of this._models.values())if(t.path===e)return t}async requestRunning(){var e,t;let i;try{i=await(0,l.listRunning)(this.serverSettings)}catch(i){throw(i instanceof r.ServerConnection.NetworkError||503===(null===(e=i.response)||void 0===e?void 0:e.status)||424===(null===(t=i.response)||void 0===t?void 0:t.status))&&this._connectionFailure.emit(i),i}this.isDisposed||this._models.size===i.length&&i.every((e=>{var t,i,n,s;const r=this._models.get(e.id);return!!r&&(null===(t=r.kernel)||void 0===t?void 0:t.id)===(null===(i=e.kernel)||void 0===i?void 0:i.id)&&(null===(n=r.kernel)||void 0===n?void 0:n.name)===(null===(s=e.kernel)||void 0===s?void 0:s.name)&&r.name===e.name&&r.path===e.path&&r.type===e.type}))||(this._models=new Map(i.map((e=>[e.id,e]))),this._sessionConnections.forEach((e=>{this._models.has(e.id)?e.update(this._models.get(e.id)):e.dispose()})),this._runningChanged.emit(i))}_onStarted(e){this._sessionConnections.add(e),e.disposed.connect(this._onDisposed,this),e.propertyChanged.connect(this._onChanged,this),e.kernelChanged.connect(this._onChanged,this)}_onDisposed(e){this._sessionConnections.delete(e),this.refreshRunning().catch((()=>{}))}_onChanged(){this.refreshRunning().catch((()=>{}))}}t.SessionManager=h,function(e){e.NoopManager=class extends e{constructor(){super(...arguments),this._readyPromise=new Promise((()=>{}))}get isActive(){return!1}get parentReady(){return super.ready}async startNew(e,t={}){return Promise.reject(new Error("Not implemented in no-op Session Manager"))}connectTo(e){throw Error("Not implemented in no-op Session Manager")}get ready(){return this.parentReady.then((()=>this._readyPromise))}async shutdown(e){return Promise.reject(new Error("Not implemented in no-op Session Manager"))}async requestRunning(){return Promise.resolve()}}}(h=t.SessionManager||(t.SessionManager={}))},1975:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.updateSession=t.startSession=t.getSessionModel=t.shutdownSession=t.getSessionUrl=t.listRunning=t.SESSION_SERVICE_URL=void 0;const n=i(538),s=i(4251),r=i(9590);function o(e,i){return s.URLExt.join(e,t.SESSION_SERVICE_URL,i)}t.SESSION_SERVICE_URL="api/sessions",t.listRunning=async function(e=n.ServerConnection.makeSettings()){const i=s.URLExt.join(e.baseUrl,t.SESSION_SERVICE_URL),o=await n.ServerConnection.makeRequest(i,{},e);if(200!==o.status)throw await n.ServerConnection.ResponseError.create(o);const a=await o.json();if(!Array.isArray(a))throw new Error("Invalid Session list");return a.forEach((e=>{(0,r.updateLegacySessionModel)(e),(0,r.validateModel)(e)})),a},t.getSessionUrl=o,t.shutdownSession=async function(e,t=n.ServerConnection.makeSettings()){var i;const s=o(t.baseUrl,e),r=await n.ServerConnection.makeRequest(s,{method:"DELETE"},t);if(404===r.status){const t=null!==(i=(await r.json()).message)&&void 0!==i?i:`The session "${e}"" does not exist on the server`;console.warn(t)}else{if(410===r.status)throw new n.ServerConnection.ResponseError(r,"The kernel was deleted but the session was not");if(204!==r.status)throw await n.ServerConnection.ResponseError.create(r)}},t.getSessionModel=async function(e,t=n.ServerConnection.makeSettings()){const i=o(t.baseUrl,e),s=await n.ServerConnection.makeRequest(i,{},t);if(200!==s.status)throw await n.ServerConnection.ResponseError.create(s);const a=await s.json();return(0,r.updateLegacySessionModel)(a),(0,r.validateModel)(a),a},t.startSession=async function(e,i=n.ServerConnection.makeSettings()){const o=s.URLExt.join(i.baseUrl,t.SESSION_SERVICE_URL),a={method:"POST",body:JSON.stringify(e)},l=await n.ServerConnection.makeRequest(o,a,i);if(201!==l.status)throw await n.ServerConnection.ResponseError.create(l);const h=await l.json();return(0,r.updateLegacySessionModel)(h),(0,r.validateModel)(h),h},t.updateSession=async function(e,t=n.ServerConnection.makeSettings()){const i=o(t.baseUrl,e.id),s={method:"PATCH",body:JSON.stringify(e)},a=await n.ServerConnection.makeRequest(i,s,t);if(200!==a.status)throw await n.ServerConnection.ResponseError.create(a);const l=await a.json();return(0,r.updateLegacySessionModel)(l),(0,r.validateModel)(l),l}},7993:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},9590:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.validateModels=t.updateLegacySessionModel=t.validateModel=void 0;const n=i(776),s=i(3247);function r(e){(0,s.validateProperty)(e,"id","string"),(0,s.validateProperty)(e,"type","string"),(0,s.validateProperty)(e,"name","string"),(0,s.validateProperty)(e,"path","string"),(0,s.validateProperty)(e,"kernel","object"),(0,n.validateModel)(e.kernel)}t.validateModel=r,t.updateLegacySessionModel=function(e){void 0===e.path&&void 0!==e.notebook&&(e.path=e.notebook.path,e.type="notebook",e.name="")},t.validateModels=function(e){if(!Array.isArray(e))throw new Error("Invalid session list");e.forEach((e=>r(e)))}},9188:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.SettingManager=void 0;const n=i(4251),s=i(5895),r=i(538);class o extends s.DataConnector{constructor(e={}){var t;super(),this.serverSettings=null!==(t=e.serverSettings)&&void 0!==t?t:r.ServerConnection.makeSettings()}async fetch(e){if(!e)throw new Error("Plugin `id` parameter is required for settings fetch.");const{serverSettings:t}=this,{baseUrl:i,appUrl:n}=t,{makeRequest:s,ResponseError:o}=r.ServerConnection,l=i+n,h=a.url(l,e),c=await s(h,{},t);if(200!==c.status)throw await o.create(c);return c.json()}async list(e){var t,i,n,s;const{serverSettings:o}=this,{baseUrl:l,appUrl:h}=o,{makeRequest:c,ResponseError:d}=r.ServerConnection,u=l+h,p=a.url(u,"","ids"===e),f=await c(p,{},o);if(200!==f.status)throw new d(f);const m=await f.json(),g=null!==(i=null===(t=null==m?void 0:m.settings)||void 0===t?void 0:t.map((e=>e.id)))&&void 0!==i?i:[];let v=[];return e||(v=null!==(s=null===(n=null==m?void 0:m.settings)||void 0===n?void 0:n.map((e=>(e.data={composite:{},user:{}},e))))&&void 0!==s?s:[]),{ids:g,values:v}}async save(e,t){const{serverSettings:i}=this,{baseUrl:n,appUrl:s}=i,{makeRequest:o,ResponseError:l}=r.ServerConnection,h=n+s,c=a.url(h,e),d={body:JSON.stringify({raw:t}),method:"PUT"},u=await o(c,d,i);if(204!==u.status)throw new l(u)}}var a;t.SettingManager=o,function(e){e.url=function(e,t,i){const s=i?n.URLExt.objectToQueryString({ids_only:!0}):"";return`${n.URLExt.join(e,"api/settings",t)}${s}`}}(a||(a={}))},8354:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.default=WebSocket},7685:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.TerminalConnection=void 0;const n=i(4251),s=i(3911),r=i(6424),o=i(5247),a=i(7384);class l{constructor(e){var t;this._createSocket=()=>{this._errorIfDisposed(),this._clearSocket(),this._updateConnectionStatus("connecting");const e=this._name,t=this.serverSettings;let i=n.URLExt.join(t.wsUrl,"terminals","websocket",encodeURIComponent(e));const s=t.token;t.appendToken&&""!==s&&(i+=`?token=${encodeURIComponent(s)}`),this._ws=new t.WebSocket(i),this._ws.onmessage=this._onWSMessage,this._ws.onclose=this._onWSClose,this._ws.onerror=this._onWSClose},this._onWSMessage=e=>{if(this._isDisposed)return;const t=JSON.parse(e.data);"disconnect"===t[0]&&this.dispose(),"connecting"!==this._connectionStatus?this._messageReceived.emit({type:t[0],content:t.slice(1)}):"setup"===t[0]&&this._updateConnectionStatus("connected")},this._onWSClose=e=>{console.warn(`Terminal websocket closed: ${e.code}`),this.isDisposed||this._reconnect()},this._connectionStatus="connecting",this._connectionStatusChanged=new r.Signal(this),this._isDisposed=!1,this._disposed=new r.Signal(this),this._messageReceived=new r.Signal(this),this._reconnectTimeout=null,this._ws=null,this._noOp=()=>{},this._reconnectLimit=7,this._reconnectAttempt=0,this._pendingMessages=[],this._name=e.model.name,this.serverSettings=null!==(t=e.serverSettings)&&void 0!==t?t:o.ServerConnection.makeSettings(),this._createSocket()}get disposed(){return this._disposed}get messageReceived(){return this._messageReceived}get name(){return this._name}get model(){return{name:this._name}}get isDisposed(){return this._isDisposed}dispose(){this._isDisposed||(this._isDisposed=!0,this._disposed.emit(),this._updateConnectionStatus("disconnected"),this._clearSocket(),r.Signal.clearData(this))}send(e){this._sendMessage(e)}_sendMessage(e,t=!0){if(!this._isDisposed&&e.content)if("connected"===this.connectionStatus&&this._ws){const t=[e.type,...e.content];this._ws.send(JSON.stringify(t))}else{if(!t)throw new Error(`Could not send message: ${JSON.stringify(e)}`);this._pendingMessages.push(e)}}_sendPending(){for(;"connected"===this.connectionStatus&&this._pendingMessages.length>0;)this._sendMessage(this._pendingMessages[0],!1),this._pendingMessages.shift()}reconnect(){this._errorIfDisposed();const e=new s.PromiseDelegate,t=(i,n)=>{"connected"===n?(e.resolve(),this.connectionStatusChanged.disconnect(t,this)):"disconnected"===n&&(e.reject(new Error("Terminal connection disconnected")),this.connectionStatusChanged.disconnect(t,this))};return this.connectionStatusChanged.connect(t,this),this._reconnectAttempt=0,this._reconnect(),e.promise}_reconnect(){if(this._errorIfDisposed(),clearTimeout(this._reconnectTimeout),this._reconnectAttempt{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.TerminalManager=void 0;const n=i(9044),s=i(6424),r=i(5247),o=i(7524),a=i(7384),l=i(7685);class h extends o.BaseManager{constructor(e={}){var t;if(super(e),this._isReady=!1,this._names=[],this._terminalConnections=new Set,this._runningChanged=new s.Signal(this),this._connectionFailure=new s.Signal(this),!this.isAvailable())return this._ready=Promise.reject("Terminals unavailable"),void this._ready.catch((e=>{}));this._pollModels=new n.Poll({auto:!1,factory:()=>this.requestRunning(),frequency:{interval:1e4,backoff:!0,max:3e5},name:"@jupyterlab/services:TerminalManager#models",standby:null!==(t=e.standby)&&void 0!==t?t:"when-hidden"}),this._ready=(async()=>{await this._pollModels.start(),await this._pollModels.tick,this._isReady=!0})()}get isReady(){return this._isReady}get ready(){return this._ready}get runningChanged(){return this._runningChanged}get connectionFailure(){return this._connectionFailure}dispose(){this.isDisposed||(this._names.length=0,this._terminalConnections.forEach((e=>e.dispose())),this._pollModels.dispose(),super.dispose())}isAvailable(){return(0,a.isAvailable)()}connectTo(e){const t=new l.TerminalConnection({...e,serverSettings:this.serverSettings});return this._onStarted(t),this._names.includes(e.model.name)||this.refreshRunning().catch((()=>{})),t}running(){return this._models[Symbol.iterator]()}async refreshRunning(){await this._pollModels.refresh(),await this._pollModels.tick}async startNew(e){const t=await(0,a.startNew)(this.serverSettings,null==e?void 0:e.name,null==e?void 0:e.cwd);return await this.refreshRunning(),this.connectTo({model:t})}async shutdown(e){await(0,a.shutdownTerminal)(e,this.serverSettings),await this.refreshRunning()}async shutdownAll(){await this.refreshRunning(),await Promise.all(this._names.map((e=>(0,a.shutdownTerminal)(e,this.serverSettings)))),await this.refreshRunning()}async requestRunning(){var e,t;let i;try{i=await(0,a.listRunning)(this.serverSettings)}catch(i){throw(i instanceof r.ServerConnection.NetworkError||503===(null===(e=i.response)||void 0===e?void 0:e.status)||424===(null===(t=i.response)||void 0===t?void 0:t.status))&&this._connectionFailure.emit(i),i}if(this.isDisposed)return;const n=i.map((({name:e})=>e)).sort();n!==this._names&&(this._names=n,this._terminalConnections.forEach((e=>{n.includes(e.name)||e.dispose()})),this._runningChanged.emit(this._models))}_onStarted(e){this._terminalConnections.add(e),e.disposed.connect(this._onDisposed,this)}_onDisposed(e){this._terminalConnections.delete(e),this.refreshRunning().catch((()=>{}))}get _models(){return this._names.map((e=>({name:e})))}}t.TerminalManager=h,function(e){e.NoopManager=class extends e{constructor(){super(...arguments),this._readyPromise=new Promise((()=>{}))}get isActive(){return!1}get parentReady(){return super.ready}get ready(){return this.parentReady.then((()=>this._readyPromise))}async startNew(e){return Promise.reject(new Error("Not implemented in no-op Terminal Manager"))}connectTo(e){throw Error("Not implemented in no-op Terminal Manager")}async shutdown(e){return Promise.reject(new Error("Not implemented in no-op Terminal Manager"))}async requestRunning(){return Promise.resolve()}}}(h=t.TerminalManager||(t.TerminalManager={}))},7384:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.shutdownTerminal=t.listRunning=t.startNew=t.isAvailable=t.TERMINAL_SERVICE_URL=void 0;const n=i(4251),s=i(538);function r(){return"true"===String(n.PageConfig.getOption("terminalsAvailable")).toLowerCase()}var o;t.TERMINAL_SERVICE_URL="api/terminals",t.isAvailable=r,t.startNew=async function(e=s.ServerConnection.makeSettings(),i,r){o.errorIfNotAvailable();const a=n.URLExt.join(e.baseUrl,t.TERMINAL_SERVICE_URL),l={method:"POST",body:JSON.stringify({name:i,cwd:r})},h=await s.ServerConnection.makeRequest(a,l,e);if(200!==h.status)throw await s.ServerConnection.ResponseError.create(h);return await h.json()},t.listRunning=async function(e=s.ServerConnection.makeSettings()){o.errorIfNotAvailable();const i=n.URLExt.join(e.baseUrl,t.TERMINAL_SERVICE_URL),r=await s.ServerConnection.makeRequest(i,{},e);if(200!==r.status)throw await s.ServerConnection.ResponseError.create(r);const a=await r.json();if(!Array.isArray(a))throw new Error("Invalid terminal list");return a},t.shutdownTerminal=async function(e,i=s.ServerConnection.makeSettings()){var r;o.errorIfNotAvailable();const a=n.URLExt.join(i.baseUrl,t.TERMINAL_SERVICE_URL,e),l=await s.ServerConnection.makeRequest(a,{method:"DELETE"},i);if(404===l.status){const t=null!==(r=(await l.json()).message)&&void 0!==r?r:`The terminal session "${e}"" does not exist on the server`;console.warn(t)}else if(204!==l.status)throw await s.ServerConnection.ResponseError.create(l)},function(e){e.errorIfNotAvailable=function(){if(!r())throw new Error("Terminals Unavailable")}}(o||(o={}))},3828:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.isAvailable=void 0;const n=i(7384);Object.defineProperty(t,"isAvailable",{enumerable:!0,get:function(){return n.isAvailable}})},1014:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.UserManager=void 0;const n=i(4251),s=i(3911),r=i(9044),o=i(6424),a=i(538),l=i(7524),h="@jupyterlab/services:UserManager#user";class c extends l.BaseManager{constructor(e={}){var t;super(e),this._isReady=!1,this._userChanged=new o.Signal(this),this._connectionFailure=new o.Signal(this),this._ready=this.requestUser().then((()=>{this.isDisposed||(this._isReady=!0)})).catch((e=>new Promise((()=>{})))),this._pollSpecs=new r.Poll({auto:!1,factory:()=>this.requestUser(),frequency:{interval:61e3,backoff:!0,max:3e5},name:h,standby:null!==(t=e.standby)&&void 0!==t?t:"when-hidden"}),this.ready.then((()=>{this._pollSpecs.start()}))}get isReady(){return this._isReady}get ready(){return this._ready}get identity(){return this._identity}get permissions(){return this._permissions}get userChanged(){return this._userChanged}get connectionFailure(){return this._connectionFailure}dispose(){this._pollSpecs.dispose(),super.dispose()}async refreshUser(){await this._pollSpecs.refresh(),await this._pollSpecs.tick}async requestUser(){if(this.isDisposed)return;const{baseUrl:e}=this.serverSettings,{makeRequest:t,ResponseError:i}=a.ServerConnection,r=n.URLExt.join(e,"api/me"),o=await t(r,{},this.serverSettings);if(200!==o.status)throw await i.create(o);const l={identity:this._identity,permissions:this._permissions},c=await o.json(),u=c.identity,{localStorage:p}=window,f=p.getItem(h);if(f&&(!u.initials||!u.color)){const e=JSON.parse(f);u.initials=u.initials||e.initials||u.name.substring(0,1),u.color=u.color||e.color||d.getRandomColor()}s.JSONExt.deepEqual(c,l)||(this._identity=u,this._permissions=c.permissions,p.setItem(h,JSON.stringify(u)),this._userChanged.emit(c))}}var d;t.UserManager=c,function(e){const t=["var(--jp-collaborator-color1)","var(--jp-collaborator-color2)","var(--jp-collaborator-color3)","var(--jp-collaborator-color4)","var(--jp-collaborator-color5)","var(--jp-collaborator-color6)","var(--jp-collaborator-color7)"];e.getRandomColor=()=>t[Math.floor(Math.random()*t.length)]}(d||(d={}))},3247:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.validateProperty=void 0,t.validateProperty=function(e,t,i,n=[]){if(!e.hasOwnProperty(t))throw Error(`Missing property '${t}'`);const s=e[t];if(void 0!==i){let e=!0;switch(i){case"array":e=Array.isArray(s);break;case"object":e=void 0!==s;break;default:e=typeof s===i}if(!e)throw new Error(`Property '${t}' is not of type '${i}'`);if(n.length>0){let e=!0;switch(i){case"string":case"number":case"boolean":e=n.includes(s);break;default:e=n.findIndex((e=>e===s))>=0}if(!e)throw new Error(`Property '${t}' is not one of the valid values ${JSON.stringify(n)}`)}}}},9090:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.WorkspaceManager=void 0;const n=i(4251),s=i(5895),r=i(538);class o extends s.DataConnector{constructor(e={}){var t;super(),this.serverSettings=null!==(t=e.serverSettings)&&void 0!==t?t:r.ServerConnection.makeSettings()}async fetch(e){const{serverSettings:t}=this,{baseUrl:i,appUrl:n}=t,{makeRequest:s,ResponseError:o}=r.ServerConnection,l=i+n,h=a.url(l,e),c=await s(h,{},t);if(200!==c.status)throw await o.create(c);return c.json()}async list(){const{serverSettings:e}=this,{baseUrl:t,appUrl:i}=e,{makeRequest:n,ResponseError:s}=r.ServerConnection,o=t+i,l=a.url(o,""),h=await n(l,{},e);if(200!==h.status)throw await s.create(h);return(await h.json()).workspaces}async remove(e){const{serverSettings:t}=this,{baseUrl:i,appUrl:n}=t,{makeRequest:s,ResponseError:o}=r.ServerConnection,l=i+n,h=a.url(l,e),c=await s(h,{method:"DELETE"},t);if(204!==c.status)throw await o.create(c)}async save(e,t){const{serverSettings:i}=this,{baseUrl:n,appUrl:s}=i,{makeRequest:o,ResponseError:l}=r.ServerConnection,h=n+s,c=a.url(h,e),d={body:JSON.stringify(t),method:"PUT"},u=await o(c,d,i);if(204!==u.status)throw await l.create(u)}}var a;t.WorkspaceManager=o,function(e){e.url=function(e,t){return n.URLExt.join(e,"api/workspaces",t)}}(a||(a={}))},1150:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.DataConnector=void 0,t.DataConnector=class{async list(e){throw new Error("DataConnector#list method has not been implemented.")}async remove(e){throw new Error("DataConnector#remove method has not been implemented.")}async save(e,t){throw new Error("DataConnector#save method has not been implemented.")}}},5895:function(e,t,i){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__exportStar||function(e,t){for(var i in e)"default"===i||Object.prototype.hasOwnProperty.call(t,i)||n(t,e,i)};Object.defineProperty(t,"__esModule",{value:!0}),s(i(1150),t),s(i(4995),t),s(i(2763),t),s(i(4611),t),s(i(2594),t)},4995:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0})},2763:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.RestorablePool=void 0;const n=i(3911),s=i(4050),r=i(6424);var o;t.RestorablePool=class{constructor(e){this._added=new r.Signal(this),this._current=null,this._currentChanged=new r.Signal(this),this._hasRestored=!1,this._isDisposed=!1,this._objects=new Set,this._restore=null,this._restored=new n.PromiseDelegate,this._updated=new r.Signal(this),this.namespace=e.namespace}get added(){return this._added}get current(){return this._current}set current(e){this._current!==e&&null!==e&&this._objects.has(e)&&(this._current=e,this._currentChanged.emit(this._current))}get currentChanged(){return this._currentChanged}get isDisposed(){return this._isDisposed}get restored(){return this._restored.promise}get size(){return this._objects.size}get updated(){return this._updated}async add(e){var t,i;if(e.isDisposed){const t="A disposed object cannot be added.";throw console.warn(t,e),new Error(t)}if(this._objects.has(e)){const t="This object already exists in the pool.";throw console.warn(t,e),new Error(t)}if(this._objects.add(e),e.disposed.connect(this._onInstanceDisposed,this),!o.injectedProperty.get(e)){if(this._restore){const{connector:n}=this._restore,s=this._restore.name(e);if(s){const r=`${this.namespace}:${s}`,a=null===(i=(t=this._restore).args)||void 0===i?void 0:i.call(t,e);o.nameProperty.set(e,r),await n.save(r,{data:a})}}this._added.emit(e)}}dispose(){this.isDisposed||(this._current=null,this._isDisposed=!0,this._objects.clear(),r.Signal.clearData(this))}find(e){const t=this._objects.values();for(const i of t)if(e(i))return i}forEach(e){this._objects.forEach(e)}filter(e){const t=[];return this.forEach((i=>{e(i)&&t.push(i)})),t}inject(e){return o.injectedProperty.set(e,!0),this.add(e)}has(e){return this._objects.has(e)}async restore(e){if(this._hasRestored)throw new Error("This pool has already been restored.");this._hasRestored=!0;const{command:t,connector:i,registry:n,when:s}=e,r=this.namespace,o=s?[i.list(r)].concat(s):[i.list(r)];this._restore=e;const[a]=await Promise.all(o),l=await Promise.all(a.ids.map((async(e,s)=>{const r=a.values[s],o=r&&r.data;return void 0===o?i.remove(e):n.execute(t,o).catch((()=>i.remove(e)))})));return this._restored.resolve(),l}async save(e){var t,i;const n=o.injectedProperty.get(e);if(!this._restore||!this.has(e)||n)return;const{connector:s}=this._restore,r=this._restore.name(e),a=o.nameProperty.get(e),l=r?`${this.namespace}:${r}`:"";if(a&&a!==l&&await s.remove(a),o.nameProperty.set(e,l),l){const n=null===(i=(t=this._restore).args)||void 0===i?void 0:i.call(t,e);await s.save(l,{data:n})}a!==l&&this._updated.emit(e)}_onInstanceDisposed(e){if(this._objects.delete(e),e===this._current&&(this._current=null,this._currentChanged.emit(this._current)),o.injectedProperty.get(e))return;if(!this._restore)return;const{connector:t}=this._restore,i=o.nameProperty.get(e);i&&t.remove(i)}},function(e){e.injectedProperty=new s.AttachedProperty({name:"injected",create:()=>!1}),e.nameProperty=new s.AttachedProperty({name:"name",create:()=>""})}(o||(o={}))},4611:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.StateDB=void 0;const n=i(6424);class s{constructor(e={}){this._changed=new n.Signal(this);const{connector:t,transform:i}=e;this._connector=t||new s.Connector,this._ready=i?i.then((e=>{const{contents:t,type:i}=e;switch(i){case"cancel":default:return;case"clear":return this._clear();case"merge":return this._merge(t||{});case"overwrite":return this._overwrite(t||{})}})):Promise.resolve(void 0)}get changed(){return this._changed}async clear(){await this._ready,await this._clear()}async fetch(e){return await this._ready,this._fetch(e)}async list(e){return await this._ready,this._list(e)}async remove(e){await this._ready,await this._remove(e),this._changed.emit({id:e,type:"remove"})}async save(e,t){await this._ready,await this._save(e,t),this._changed.emit({id:e,type:"save"})}async toJSON(){await this._ready;const{ids:e,values:t}=await this._list();return t.reduce(((t,i,n)=>(t[e[n]]=i,t)),{})}async _clear(){await Promise.all((await this._list()).ids.map((e=>this._remove(e))))}async _fetch(e){const t=await this._connector.fetch(e);if(t)return JSON.parse(t).v}async _list(e=""){const{ids:t,values:i}=await this._connector.list(e);return{ids:t,values:i.map((e=>JSON.parse(e).v))}}async _merge(e){await Promise.all(Object.keys(e).map((t=>e[t]&&this._save(t,e[t]))))}async _overwrite(e){await this._clear(),await this._merge(e)}async _remove(e){return this._connector.remove(e)}async _save(e,t){return this._connector.save(e,JSON.stringify({v:t}))}}t.StateDB=s,function(e){e.Connector=class{constructor(){this._storage={}}async fetch(e){return this._storage[e]}async list(e=""){return Object.keys(this._storage).reduce(((t,i)=>(""!==e&&e!==i.split(":")[0]||(t.ids.push(i),t.values.push(this._storage[i])),t)),{ids:[],values:[]})}async remove(e){delete this._storage[e]}async save(e,t){this._storage[e]=t}}}(s=t.StateDB||(t.StateDB={}))},2594:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.IStateDB=void 0;const n=i(3911);t.IStateDB=new n.Token("@jupyterlab/coreutils:IStateDB",'A service for the JupyterLab state database.\n Use this if you want to store data that will persist across page loads.\n See "state database" for more information.')},7564:(e,t,i)=>{"use strict";var n,s,r;function*o(){}function a(e,t){let i=0;for(const n of e)if(t(n,i++))return n}function l(e,t){let i;for(const n of e)void 0!==i?t(n,i)>0&&(i=n):i=n;return i}function h(e,t){let i=0;for(const n of e)if(!1===t(n,i++))return!1;return!0}function c(e,t){let i=0;for(const n of e)if(t(n,i++))return!0;return!1}function*d(e,t){let i=0;for(const n of e)yield t(n,i++)}function*u(e){if("function"==typeof e.retro)yield*e.retro();else for(let t=e.length-1;t>-1;t--)yield e[t]}i.d(t,{Fp:()=>l,G:()=>c,RO:()=>n,UI:()=>d,cS:()=>o,kf:()=>r,kh:()=>u,sE:()=>a,yW:()=>h}),function(e){function t(e,t,i=0,n=-1){let s,r=e.length;if(0===r)return-1;i=i<0?Math.max(0,i+r):Math.min(i,r-1),s=(n=n<0?Math.max(0,n+r):Math.min(n,r-1))=i)return;let n=e[t];for(let n=t+1;n0;){let n=a>>1,s=o+n;i(e[s],t)<0?(o=s+1,a-=n+1):a=n}return o},e.upperBound=function(e,t,i,n=0,s=-1){let r=e.length;if(0===r)return 0;let o=n=n<0?Math.max(0,n+r):Math.min(n,r-1),a=(s=s<0?Math.max(0,s+r):Math.min(s,r-1))-n+1;for(;a>0;){let n=a>>1,s=o+n;i(e[s],t)>0?a=n:(o=s+1,a-=n+1)}return o},e.shallowEqual=function(e,t,i){if(e===t)return!0;if(e.length!==t.length)return!1;for(let n=0,s=e.length;n=o&&(i=s<0?o-1:o),void 0===n?n=s<0?-1:o:n<0?n=Math.max(n+o,s<0?-1:0):n>=o&&(n=s<0?o-1:o),r=s<0&&n>=i||s>0&&i>=n?0:s<0?Math.floor((n-i+1)/s+1):Math.floor((n-i-1)/s+1);let a=[];for(let t=0;t=(n=n<0?Math.max(0,n+s):Math.min(n,s-1)))return;let o=n-i+1;if(t>0?t%=o:t<0&&(t=(t%o+o)%o),0===t)return;let a=i+t;r(e,i,a-1),r(e,a,n),r(e,i,n)},e.fill=function(e,t,i=0,n=-1){let s,r=e.length;if(0!==r){i=i<0?Math.max(0,i+r):Math.min(i,r-1),s=(n=n<0?Math.max(0,n+r):Math.min(n,r-1))t;--i)e[i]=e[i-1];e[t]=i},e.removeAt=o,e.removeFirstOf=function(e,i,n=0,s=-1){let r=t(e,i,n,s);return-1!==r&&o(e,r),r},e.removeLastOf=function(e,t,n=-1,s=0){let r=i(e,t,n,s);return-1!==r&&o(e,r),r},e.removeAllOf=function(e,t,i=0,n=-1){let s=e.length;if(0===s)return 0;i=i<0?Math.max(0,i+s):Math.min(i,s-1),n=n<0?Math.max(0,n+s):Math.min(n,s-1);let r=0;for(let o=0;o=i&&o<=n&&e[o]===t||n=i)&&e[o]===t?r++:r>0&&(e[o-r]=e[o]);return r>0&&(e.length=s-r),r},e.removeFirstWhere=function(e,t,i=0,s=-1){let r,a=n(e,t,i,s);return-1!==a&&(r=o(e,a)),{index:a,value:r}},e.removeLastWhere=function(e,t,i=-1,n=0){let r,a=s(e,t,i,n);return-1!==a&&(r=o(e,a)),{index:a,value:r}},e.removeAllWhere=function(e,t,i=0,n=-1){let s=e.length;if(0===s)return 0;i=i<0?Math.max(0,i+s):Math.min(i,s-1),n=n<0?Math.max(0,n+s):Math.min(n,s-1);let r=0;for(let o=0;o=i&&o<=n&&t(e[o],o)||n=i)&&t(e[o],o)?r++:r>0&&(e[o-r]=e[o]);return r>0&&(e.length=s-r),r}}(n||(n={})),function(e){e.rangeLength=function(e,t,i){return 0===i?1/0:e>t&&i>0||et?1:0}}(r||(r={}))},3911:function(e,t){!function(e){"use strict";e.JSONExt=void 0,function(e){function t(e){return null===e||"boolean"==typeof e||"number"==typeof e||"string"==typeof e}function i(e){return Array.isArray(e)}function n(e,s){if(e===s)return!0;if(t(e)||t(s))return!1;let r=i(e),o=i(s);return r===o&&(r&&o?function(e,t){if(e===t)return!0;if(e.length!==t.length)return!1;for(let i=0,s=e.length;i>>0),e[i]=255&t,t>>>=8}e.Random=void 0,(e.Random||(e.Random={})).getRandomValues=(()=>{const e="undefined"!=typeof window&&(window.crypto||window.msCrypto)||null;return e&&"function"==typeof e.getRandomValues?function(t){return e.getRandomValues(t)}:t})(),e.UUID=void 0,(e.UUID||(e.UUID={})).uuid4=function(e){const t=new Uint8Array(16),i=new Array(256);for(let e=0;e<16;++e)i[e]="0"+e.toString(16);for(let e=16;e<256;++e)i[e]=e.toString(16);return function(){return e(t),t[6]=64|15&t[6],t[8]=128|63&t[8],i[t[0]]+i[t[1]]+i[t[2]]+i[t[3]]+"-"+i[t[4]]+i[t[5]]+"-"+i[t[6]]+i[t[7]]+"-"+i[t[8]]+i[t[9]]+"-"+i[t[10]]+i[t[11]]+i[t[12]]+i[t[13]]+i[t[14]]+i[t[15]]}}(e.Random.getRandomValues),e.MimeData=class{constructor(){this._types=[],this._values=[]}types(){return this._types.slice()}hasData(e){return-1!==this._types.indexOf(e)}getData(e){let t=this._types.indexOf(e);return-1!==t?this._values[t]:void 0}setData(e,t){this.clearData(e),this._types.push(e),this._values.push(t)}clearData(e){let t=this._types.indexOf(e);-1!==t&&(this._types.splice(t,1),this._values.splice(t,1))}clear(){this._types.length=0,this._values.length=0}},e.PromiseDelegate=class{constructor(){this.promise=new Promise(((e,t)=>{this._resolve=e,this._reject=t}))}resolve(e){(0,this._resolve)(e)}reject(e){(0,this._reject)(e)}},e.Token=class{constructor(e,t){this.name=e,this.description=null!=t?t:"",this._tokenStructuralPropertyT=null}}}(t)},1122:(e,t,i)=>{"use strict";i.r(t),i.d(t,{DisposableDelegate:()=>s,DisposableSet:()=>o,ObservableDisposableDelegate:()=>r,ObservableDisposableSet:()=>a});var n=i(6424);class s{constructor(e){this._fn=e}get isDisposed(){return!this._fn}dispose(){if(!this._fn)return;let e=this._fn;this._fn=null,e()}}class r extends s{constructor(){super(...arguments),this._disposed=new n.Signal(this)}get disposed(){return this._disposed}dispose(){this.isDisposed||(super.dispose(),this._disposed.emit(void 0),n.Signal.clearData(this))}}class o{constructor(){this._isDisposed=!1,this._items=new Set}get isDisposed(){return this._isDisposed}dispose(){this._isDisposed||(this._isDisposed=!0,this._items.forEach((e=>{e.dispose()})),this._items.clear())}contains(e){return this._items.has(e)}add(e){this._items.add(e)}remove(e){this._items.delete(e)}clear(){this._items.clear()}}!function(e){e.from=function(t){let i=new e;for(const e of t)i.add(e);return i}}(o||(o={}));class a extends o{constructor(){super(...arguments),this._disposed=new n.Signal(this)}get disposed(){return this._disposed}dispose(){this.isDisposed||(super.dispose(),this._disposed.emit(void 0),n.Signal.clearData(this))}}!function(e){e.from=function(t){let i=new e;for(const e of t)i.add(e);return i}}(a||(a={}))},9044:(e,t,i)=>{"use strict";i.r(t),i.d(t,{Debouncer:()=>l,Poll:()=>o,RateLimiter:()=>a,Throttler:()=>h});var n,s=i(3911),r=i(6424);class o{constructor(e){var t;this._disposed=new r.Signal(this),this._lingered=0,this._tick=new s.PromiseDelegate,this._ticked=new r.Signal(this),this._factory=e.factory,this._linger=null!==(t=e.linger)&&void 0!==t?t:n.DEFAULT_LINGER,this._standby=e.standby||n.DEFAULT_STANDBY,this._state={...n.DEFAULT_STATE,timestamp:(new Date).getTime()};const i=e.frequency||{},o=Math.max(i.interval||0,i.max||0,n.DEFAULT_FREQUENCY.max);this.frequency={...n.DEFAULT_FREQUENCY,...i,max:o},this.name=e.name||n.DEFAULT_NAME,"auto"in e&&!e.auto||setTimeout((()=>this.start()))}get disposed(){return this._disposed}get frequency(){return this._frequency}set frequency(e){if(this.isDisposed||s.JSONExt.deepEqual(e,this.frequency||{}))return;let{backoff:t,interval:i,max:n}=e;if(i=Math.round(i),n=Math.round(n),"number"==typeof t&&t<1)throw new Error("Poll backoff growth factor must be at least 1");if((i<0||i>n)&&i!==o.NEVER)throw new Error("Poll interval must be between 0 and max");if(n>o.MAX_INTERVAL&&n!==o.NEVER)throw new Error(`Max interval must be less than ${o.MAX_INTERVAL}`);this._frequency={backoff:t,interval:i,max:n}}get isDisposed(){return"disposed"===this.state.phase}get standby(){return this._standby}set standby(e){this.isDisposed||this.standby===e||(this._standby=e)}get state(){return this._state}get tick(){return this._tick.promise}get ticked(){return this._ticked}async*[Symbol.asyncIterator](){for(;!this.isDisposed;)yield this.state,await this.tick.catch((()=>{}))}dispose(){this.isDisposed||(this._state={...n.DISPOSED_STATE,timestamp:(new Date).getTime()},this._tick.promise.catch((e=>{})),this._tick.reject(new Error(`Poll (${this.name}) is disposed.`)),this._disposed.emit(void 0),r.Signal.clearData(this))}refresh(){return this.schedule({cancel:({phase:e})=>"refreshed"===e,interval:o.IMMEDIATE,phase:"refreshed"})}async schedule(e={}){if(this.isDisposed)return;if(e.cancel&&e.cancel(this.state))return;const t=this._tick,i=new s.PromiseDelegate,n={interval:this.frequency.interval,payload:null,phase:"standby",timestamp:(new Date).getTime(),...e};this._state=n,this._tick=i,clearTimeout(this._timeout),this._ticked.emit(this.state),t.resolve(this),await t.promise,n.interval!==o.NEVER?this._timeout=setTimeout((()=>{this.isDisposed||this.tick!==i.promise||this._execute()}),n.interval):this._timeout=void 0}start(){return this.schedule({cancel:({phase:e})=>"constructed"!==e&&"standby"!==e&&"stopped"!==e,interval:o.IMMEDIATE,phase:"started"})}stop(){return this.schedule({cancel:({phase:e})=>"stopped"===e,interval:o.NEVER,phase:"stopped"})}get hidden(){return n.hidden}_execute(){let e="function"==typeof this.standby?this.standby():this.standby;if("never"===e?e=!1:"when-hidden"===e&&(this.hidden?e=++this._lingered>this._linger:(this._lingered=0,e=!1)),e)return void this.schedule();const t=this.tick;this._factory(this.state).then((e=>{this.isDisposed||this.tick!==t||this.schedule({payload:e,phase:"rejected"===this.state.phase?"reconnected":"resolved"})})).catch((e=>{this.isDisposed||this.tick!==t||this.schedule({interval:n.sleep(this.frequency,this.state),payload:e,phase:"rejected"})}))}}!function(e){e.IMMEDIATE=0,e.MAX_INTERVAL=2147483647,e.NEVER=1/0}(o||(o={})),function(e){e.DEFAULT_BACKOFF=3,e.DEFAULT_FREQUENCY={backoff:!0,interval:1e3,max:3e4},e.DEFAULT_LINGER=1,e.DEFAULT_NAME="unknown",e.DEFAULT_STANDBY="when-hidden",e.DEFAULT_STATE={interval:o.NEVER,payload:null,phase:"constructed",timestamp:new Date(0).getTime()},e.DISPOSED_STATE={interval:o.NEVER,payload:null,phase:"disposed",timestamp:new Date(0).getTime()},e.sleep=function(t,i){const{backoff:n,interval:s,max:r}=t;if(s===o.NEVER)return s;const a=!0===n?e.DEFAULT_BACKOFF:!1===n?1:n,l=function(e,t){return e=Math.ceil(e),t=Math.floor(t),Math.floor(Math.random()*(t-e+1))+e}(s,i.interval*a);return Math.min(r,l)},e.hidden="undefined"!=typeof document&&(document.addEventListener("visibilitychange",(()=>{e.hidden="hidden"===document.visibilityState})),document.addEventListener("pagehide",(()=>{e.hidden="hidden"===document.visibilityState})),"hidden"===document.visibilityState)}(n||(n={}));class a{constructor(e,t=500){this.args=void 0,this.payload=null,this.limit=t,this.poll=new o({auto:!1,factory:async()=>{const{args:t}=this;return this.args=void 0,e(...t)},frequency:{backoff:!1,interval:o.NEVER,max:o.NEVER},standby:"never"}),this.payload=new s.PromiseDelegate,this.poll.ticked.connect(((e,t)=>{const{payload:i}=this;return"resolved"===t.phase?(this.payload=new s.PromiseDelegate,void i.resolve(t.payload)):"rejected"===t.phase||"stopped"===t.phase?(this.payload=new s.PromiseDelegate,i.promise.catch((e=>{})),void i.reject(t.payload)):void 0}),this)}get isDisposed(){return null===this.payload}dispose(){this.isDisposed||(this.args=void 0,this.payload=null,this.poll.dispose())}async stop(){return this.poll.stop()}}class l extends a{invoke(...e){return this.args=e,this.poll.schedule({interval:this.limit,phase:"invoked"}),this.payload.promise}}class h extends a{constructor(e,t){super(e,"number"==typeof t?t:t&&t.limit),this._trailing=!1,"number"!=typeof t&&t&&"trailing"===t.edge&&(this._trailing=!0),this._interval=this._trailing?this.limit:o.IMMEDIATE}invoke(...e){const t="invoked"!==this.poll.state.phase;return(t||this._trailing)&&(this.args=e),t&&this.poll.schedule({interval:this._interval,phase:"invoked"}),this.payload.promise}}},4050:(e,t,i)=>{"use strict";i.r(t),i.d(t,{AttachedProperty:()=>n});class n{constructor(e){this._pid=s.nextPID(),this.name=e.name,this._create=e.create,this._coerce=e.coerce||null,this._compare=e.compare||null,this._changed=e.changed||null}get(e){let t,i=s.ensureMap(e);return t=this._pid in i?i[this._pid]:i[this._pid]=this._createValue(e),t}set(e,t){let i,n=s.ensureMap(e);i=this._pid in n?n[this._pid]:n[this._pid]=this._createValue(e);let r=this._coerceValue(e,t);this._maybeNotify(e,i,n[this._pid]=r)}coerce(e){let t,i=s.ensureMap(e);t=this._pid in i?i[this._pid]:i[this._pid]=this._createValue(e);let n=this._coerceValue(e,t);this._maybeNotify(e,t,i[this._pid]=n)}_createValue(e){return(0,this._create)(e)}_coerceValue(e,t){let i=this._coerce;return i?i(e,t):t}_compareValue(e,t){let i=this._compare;return i?i(e,t):e===t}_maybeNotify(e,t,i){let n=this._changed;n&&!this._compareValue(t,i)&&n(e,t,i)}}var s;!function(e){e.clearData=function(e){s.ownerData.delete(e)}}(n||(n={})),function(e){e.ownerData=new WeakMap,e.nextPID=(()=>{let e=0;return()=>`pid-${`${Math.random()}`.slice(2)}-${e++}`})(),e.ensureMap=function(t){let i=e.ownerData.get(t);return i||(i=Object.create(null),e.ownerData.set(t,i),i)}}(s||(s={}))},6424:(e,t,i)=>{"use strict";i.r(t),i.d(t,{Signal:()=>o,Stream:()=>a});var n,s=i(7564),r=i(3911);class o{constructor(e){this.sender=e}connect(e,t){return n.connect(this,e,t)}disconnect(e,t){return n.disconnect(this,e,t)}emit(e){n.emit(this,e)}}!function(e){e.disconnectBetween=function(e,t){n.disconnectBetween(e,t)},e.disconnectSender=function(e){n.disconnectSender(e)},e.disconnectReceiver=function(e){n.disconnectReceiver(e)},e.disconnectAll=function(e){n.disconnectAll(e)},e.clearData=function(e){n.disconnectAll(e)},e.getExceptionHandler=function(){return n.exceptionHandler},e.setExceptionHandler=function(e){let t=n.exceptionHandler;return n.exceptionHandler=e,t}}(o||(o={}));class a extends o{constructor(){super(...arguments),this._pending=new r.PromiseDelegate}async*[Symbol.asyncIterator](){let e=this._pending;for(;;)try{const{args:t,next:i}=await e.promise;e=i,yield t}catch(e){return}}emit(e){const t=this._pending,i=this._pending=new r.PromiseDelegate;t.resolve({args:e,next:i}),super.emit(e)}stop(){this._pending.promise.catch((()=>{})),this._pending.reject("stop"),this._pending=new r.PromiseDelegate}}!function(e){function t(e){let t=n.get(e);if(t&&0!==t.length){for(const e of t){if(!e.signal)continue;let t=e.thisArg||e.slot;e.signal=null,c(r.get(t))}c(t)}}function i(e){let t=r.get(e);if(t&&0!==t.length){for(const e of t){if(!e.signal)continue;let t=e.signal.sender;e.signal=null,c(n.get(t))}c(t)}}e.exceptionHandler=e=>{console.error(e)},e.connect=function(e,t,i){i=i||void 0;let s=n.get(e.sender);if(s||(s=[],n.set(e.sender,s)),l(s,e,t,i))return!1;let o=i||t,a=r.get(o);a||(a=[],r.set(o,a));let h={signal:e,slot:t,thisArg:i};return s.push(h),a.push(h),!0},e.disconnect=function(e,t,i){i=i||void 0;let s=n.get(e.sender);if(!s||0===s.length)return!1;let o=l(s,e,t,i);if(!o)return!1;let a=i||t,h=r.get(a);return o.signal=null,c(s),c(h),!0},e.disconnectBetween=function(e,t){let i=n.get(e);if(!i||0===i.length)return;let s=r.get(t);if(s&&0!==s.length){for(const t of s)t.signal&&t.signal.sender===e&&(t.signal=null);c(i),c(s)}},e.disconnectSender=t,e.disconnectReceiver=i,e.disconnectAll=function(e){t(e),i(e)},e.emit=function(e,t){let i=n.get(e.sender);if(i&&0!==i.length)for(let n=0,s=i.length;ne.signal===t&&e.slot===i&&e.thisArg===n))}function h(t,i){let{signal:n,slot:s,thisArg:r}=t;try{s.call(r,n.sender,i)}catch(t){e.exceptionHandler(t)}}function c(e){0===o.size&&a(d),o.add(e)}function d(){o.forEach(u),o.clear()}function u(e){s.RO.removeAllWhere(e,p)}function p(e){return null===e.signal}}(n||(n={}))},2454:e=>{"use strict";var t=function(e){return function(e){return!!e&&"object"==typeof e}(e)&&!function(e){var t=Object.prototype.toString.call(e);return"[object RegExp]"===t||"[object Date]"===t||function(e){return e.$$typeof===i}(e)}(e)},i="function"==typeof Symbol&&Symbol.for?Symbol.for("react.element"):60103;function n(e,t){return!1!==t.clone&&t.isMergeableObject(e)?a((i=e,Array.isArray(i)?[]:{}),e,t):e;var i}function s(e,t,i){return e.concat(t).map((function(e){return n(e,i)}))}function r(e){return Object.keys(e).concat(function(e){return Object.getOwnPropertySymbols?Object.getOwnPropertySymbols(e).filter((function(t){return Object.propertyIsEnumerable.call(e,t)})):[]}(e))}function o(e,t){try{return t in e}catch(e){return!1}}function a(e,i,l){(l=l||{}).arrayMerge=l.arrayMerge||s,l.isMergeableObject=l.isMergeableObject||t,l.cloneUnlessOtherwiseSpecified=n;var h=Array.isArray(i);return h===Array.isArray(e)?h?l.arrayMerge(e,i,l):function(e,t,i){var s={};return i.isMergeableObject(e)&&r(e).forEach((function(t){s[t]=n(e[t],i)})),r(t).forEach((function(r){(function(e,t){return o(e,t)&&!(Object.hasOwnProperty.call(e,t)&&Object.propertyIsEnumerable.call(e,t))})(e,r)||(o(e,r)&&i.isMergeableObject(t[r])?s[r]=function(e,t){if(!t.customMerge)return a;var i=t.customMerge(e);return"function"==typeof i?i:a}(r,i)(e[r],t[r],i):s[r]=n(t[r],i))})),s}(e,i,l):n(i,l)}a.all=function(e,t){if(!Array.isArray(e))throw new Error("first argument should be an array");return e.reduce((function(e,i){return a(e,i,t)}),{})};var l=a;e.exports=l},8002:(e,t)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.attributeNames=t.elementNames=void 0,t.elementNames=new Map([["altglyph","altGlyph"],["altglyphdef","altGlyphDef"],["altglyphitem","altGlyphItem"],["animatecolor","animateColor"],["animatemotion","animateMotion"],["animatetransform","animateTransform"],["clippath","clipPath"],["feblend","feBlend"],["fecolormatrix","feColorMatrix"],["fecomponenttransfer","feComponentTransfer"],["fecomposite","feComposite"],["feconvolvematrix","feConvolveMatrix"],["fediffuselighting","feDiffuseLighting"],["fedisplacementmap","feDisplacementMap"],["fedistantlight","feDistantLight"],["fedropshadow","feDropShadow"],["feflood","feFlood"],["fefunca","feFuncA"],["fefuncb","feFuncB"],["fefuncg","feFuncG"],["fefuncr","feFuncR"],["fegaussianblur","feGaussianBlur"],["feimage","feImage"],["femerge","feMerge"],["femergenode","feMergeNode"],["femorphology","feMorphology"],["feoffset","feOffset"],["fepointlight","fePointLight"],["fespecularlighting","feSpecularLighting"],["fespotlight","feSpotLight"],["fetile","feTile"],["feturbulence","feTurbulence"],["foreignobject","foreignObject"],["glyphref","glyphRef"],["lineargradient","linearGradient"],["radialgradient","radialGradient"],["textpath","textPath"]]),t.attributeNames=new Map([["definitionurl","definitionURL"],["attributename","attributeName"],["attributetype","attributeType"],["basefrequency","baseFrequency"],["baseprofile","baseProfile"],["calcmode","calcMode"],["clippathunits","clipPathUnits"],["diffuseconstant","diffuseConstant"],["edgemode","edgeMode"],["filterunits","filterUnits"],["glyphref","glyphRef"],["gradienttransform","gradientTransform"],["gradientunits","gradientUnits"],["kernelmatrix","kernelMatrix"],["kernelunitlength","kernelUnitLength"],["keypoints","keyPoints"],["keysplines","keySplines"],["keytimes","keyTimes"],["lengthadjust","lengthAdjust"],["limitingconeangle","limitingConeAngle"],["markerheight","markerHeight"],["markerunits","markerUnits"],["markerwidth","markerWidth"],["maskcontentunits","maskContentUnits"],["maskunits","maskUnits"],["numoctaves","numOctaves"],["pathlength","pathLength"],["patterncontentunits","patternContentUnits"],["patterntransform","patternTransform"],["patternunits","patternUnits"],["pointsatx","pointsAtX"],["pointsaty","pointsAtY"],["pointsatz","pointsAtZ"],["preservealpha","preserveAlpha"],["preserveaspectratio","preserveAspectRatio"],["primitiveunits","primitiveUnits"],["refx","refX"],["refy","refY"],["repeatcount","repeatCount"],["repeatdur","repeatDur"],["requiredextensions","requiredExtensions"],["requiredfeatures","requiredFeatures"],["specularconstant","specularConstant"],["specularexponent","specularExponent"],["spreadmethod","spreadMethod"],["startoffset","startOffset"],["stddeviation","stdDeviation"],["stitchtiles","stitchTiles"],["surfacescale","surfaceScale"],["systemlanguage","systemLanguage"],["tablevalues","tableValues"],["targetx","targetX"],["targety","targetY"],["textlength","textLength"],["viewbox","viewBox"],["viewtarget","viewTarget"],["xchannelselector","xChannelSelector"],["ychannelselector","yChannelSelector"],["zoomandpan","zoomAndPan"]])},2721:function(e,t,i){"use strict";var n=this&&this.__assign||function(){return n=Object.assign||function(e){for(var t,i=1,n=arguments.length;i";case a.Comment:return"\x3c!--"+e.data+"--\x3e";case a.CDATA:return function(e){return""}(e);case a.Script:case a.Style:case a.Tag:return function(e,t){var i;"foreign"===t.xmlMode&&(e.name=null!==(i=h.elementNames.get(e.name))&&void 0!==i?i:e.name,e.parent&&f.has(e.parent.name)&&(t=n(n({},t),{xmlMode:!1}))),!t.xmlMode&&m.has(e.name)&&(t=n(n({},t),{xmlMode:"foreign"}));var s="<"+e.name,r=function(e,t){if(e)return Object.keys(e).map((function(i){var n,s,r=null!==(n=e[i])&&void 0!==n?n:"";return"foreign"===t.xmlMode&&(i=null!==(s=h.attributeNames.get(i))&&void 0!==s?s:i),t.emptyAttrs||t.xmlMode||""!==r?i+'="'+(!1!==t.decodeEntities?l.encodeXML(r):r.replace(/"/g,"""))+'"':i})).join(" ")}(e.attribs,t);return r&&(s+=" "+r),0===e.children.length&&(t.xmlMode?!1!==t.selfClosingTags:t.selfClosingTags&&d.has(e.name))?(t.xmlMode||(s+=" "),s+="/>"):(s+=">",e.children.length>0&&(s+=u(e.children,t)),!t.xmlMode&&d.has(e.name)||(s+="")),s}(e,t);case a.Text:return function(e,t){var i=e.data||"";return!1===t.decodeEntities||!t.xmlMode&&e.parent&&c.has(e.parent.name)||(i=l.encodeXML(i)),i}(e,t)}}t.default=u;var f=new Set(["mi","mo","mn","ms","mtext","annotation-xml","foreignObject","desc","title"]),m=new Set(["svg","math"])},3706:(e,t)=>{"use strict";var i;Object.defineProperty(t,"__esModule",{value:!0}),t.Doctype=t.CDATA=t.Tag=t.Style=t.Script=t.Comment=t.Directive=t.Text=t.Root=t.isTag=t.ElementType=void 0,function(e){e.Root="root",e.Text="text",e.Directive="directive",e.Comment="comment",e.Script="script",e.Style="style",e.Tag="tag",e.CDATA="cdata",e.Doctype="doctype"}(i=t.ElementType||(t.ElementType={})),t.isTag=function(e){return e.type===i.Tag||e.type===i.Script||e.type===i.Style},t.Root=i.Root,t.Text=i.Text,t.Directive=i.Directive,t.Comment=i.Comment,t.Script=i.Script,t.Style=i.Style,t.Tag=i.Tag,t.CDATA=i.CDATA,t.Doctype=i.Doctype},9425:function(e,t,i){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i);var s=Object.getOwnPropertyDescriptor(t,i);s&&!("get"in s?!t.__esModule:s.writable||s.configurable)||(s={enumerable:!0,get:function(){return t[i]}}),Object.defineProperty(e,n,s)}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__exportStar||function(e,t){for(var i in e)"default"===i||Object.prototype.hasOwnProperty.call(t,i)||n(t,e,i)};Object.defineProperty(t,"__esModule",{value:!0}),t.DomHandler=void 0;var r=i(3706),o=i(4862);s(i(4862),t);var a=/\s+/g,l={normalizeWhitespace:!1,withStartIndices:!1,withEndIndices:!1,xmlMode:!1},h=function(){function e(e,t,i){this.dom=[],this.root=new o.Document(this.dom),this.done=!1,this.tagStack=[this.root],this.lastNode=null,this.parser=null,"function"==typeof t&&(i=t,t=l),"object"==typeof e&&(t=e,e=void 0),this.callback=null!=e?e:null,this.options=null!=t?t:l,this.elementCB=null!=i?i:null}return e.prototype.onparserinit=function(e){this.parser=e},e.prototype.onreset=function(){this.dom=[],this.root=new o.Document(this.dom),this.done=!1,this.tagStack=[this.root],this.lastNode=null,this.parser=null},e.prototype.onend=function(){this.done||(this.done=!0,this.parser=null,this.handleCallback(null))},e.prototype.onerror=function(e){this.handleCallback(e)},e.prototype.onclosetag=function(){this.lastNode=null;var e=this.tagStack.pop();this.options.withEndIndices&&(e.endIndex=this.parser.endIndex),this.elementCB&&this.elementCB(e)},e.prototype.onopentag=function(e,t){var i=this.options.xmlMode?r.ElementType.Tag:void 0,n=new o.Element(e,t,void 0,i);this.addNode(n),this.tagStack.push(n)},e.prototype.ontext=function(e){var t=this.options.normalizeWhitespace,i=this.lastNode;if(i&&i.type===r.ElementType.Text)t?i.data=(i.data+e).replace(a," "):i.data+=e,this.options.withEndIndices&&(i.endIndex=this.parser.endIndex);else{t&&(e=e.replace(a," "));var n=new o.Text(e);this.addNode(n),this.lastNode=n}},e.prototype.oncomment=function(e){if(this.lastNode&&this.lastNode.type===r.ElementType.Comment)this.lastNode.data+=e;else{var t=new o.Comment(e);this.addNode(t),this.lastNode=t}},e.prototype.oncommentend=function(){this.lastNode=null},e.prototype.oncdatastart=function(){var e=new o.Text(""),t=new o.NodeWithChildren(r.ElementType.CDATA,[e]);this.addNode(t),e.parent=t,this.lastNode=e},e.prototype.oncdataend=function(){this.lastNode=null},e.prototype.onprocessinginstruction=function(e,t){var i=new o.ProcessingInstruction(e,t);this.addNode(i)},e.prototype.handleCallback=function(e){if("function"==typeof this.callback)this.callback(e,this.dom);else if(e)throw e},e.prototype.addNode=function(e){var t=this.tagStack[this.tagStack.length-1],i=t.children[t.children.length-1];this.options.withStartIndices&&(e.startIndex=this.parser.startIndex),this.options.withEndIndices&&(e.endIndex=this.parser.endIndex),t.children.push(e),i&&(e.prev=i,i.next=e),e.parent=t,this.lastNode=null},e}();t.DomHandler=h,t.default=h},4862:function(e,t,i){"use strict";var n,s=this&&this.__extends||(n=function(e,t){return n=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i])},n(e,t)},function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function i(){this.constructor=e}n(e,t),e.prototype=null===t?Object.create(t):(i.prototype=t.prototype,new i)}),r=this&&this.__assign||function(){return r=Object.assign||function(e){for(var t,i=1,n=arguments.length;i0?this.children[this.children.length-1]:null},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"childNodes",{get:function(){return this.children},set:function(e){this.children=e},enumerable:!1,configurable:!0}),t}(l);t.NodeWithChildren=p;var f=function(e){function t(t){return e.call(this,o.ElementType.Root,t)||this}return s(t,e),t}(p);t.Document=f;var m=function(e){function t(t,i,n,s){void 0===n&&(n=[]),void 0===s&&(s="script"===t?o.ElementType.Script:"style"===t?o.ElementType.Style:o.ElementType.Tag);var r=e.call(this,s,n)||this;return r.name=t,r.attribs=i,r}return s(t,e),Object.defineProperty(t.prototype,"tagName",{get:function(){return this.name},set:function(e){this.name=e},enumerable:!1,configurable:!0}),Object.defineProperty(t.prototype,"attributes",{get:function(){var e=this;return Object.keys(this.attribs).map((function(t){var i,n;return{name:t,value:e.attribs[t],namespace:null===(i=e["x-attribsNamespace"])||void 0===i?void 0:i[t],prefix:null===(n=e["x-attribsPrefix"])||void 0===n?void 0:n[t]}}))},enumerable:!1,configurable:!0}),t}(p);function g(e){return(0,o.isTag)(e)}function v(e){return e.type===o.ElementType.CDATA}function O(e){return e.type===o.ElementType.Text}function b(e){return e.type===o.ElementType.Comment}function _(e){return e.type===o.ElementType.Directive}function y(e){return e.type===o.ElementType.Root}function w(e,t){var i;if(void 0===t&&(t=!1),O(e))i=new c(e.data);else if(b(e))i=new d(e.data);else if(g(e)){var n=t?x(e.children):[],s=new m(e.name,r({},e.attribs),n);n.forEach((function(e){return e.parent=s})),null!=e.namespace&&(s.namespace=e.namespace),e["x-attribsNamespace"]&&(s["x-attribsNamespace"]=r({},e["x-attribsNamespace"])),e["x-attribsPrefix"]&&(s["x-attribsPrefix"]=r({},e["x-attribsPrefix"])),i=s}else if(v(e)){n=t?x(e.children):[];var a=new p(o.ElementType.CDATA,n);n.forEach((function(e){return e.parent=a})),i=a}else if(y(e)){n=t?x(e.children):[];var l=new f(n);n.forEach((function(e){return e.parent=l})),e["x-mode"]&&(l["x-mode"]=e["x-mode"]),i=l}else{if(!_(e))throw new Error("Not implemented yet: ".concat(e.type));var h=new u(e.name,e.data);null!=e["x-name"]&&(h["x-name"]=e["x-name"],h["x-publicId"]=e["x-publicId"],h["x-systemId"]=e["x-systemId"]),i=h}return i.startIndex=e.startIndex,i.endIndex=e.endIndex,null!=e.sourceCodeLocation&&(i.sourceCodeLocation=e.sourceCodeLocation),i}function x(e){for(var t=e.map((function(e){return w(e,!0)})),i=1;i{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getFeed=void 0;var n=i(3017),s=i(9319);t.getFeed=function(e){var t=l(d,e);return t?"feed"===t.name?function(e){var t,i=e.children,n={type:"atom",items:(0,s.getElementsByTagName)("entry",i).map((function(e){var t,i=e.children,n={media:a(i)};c(n,"id","id",i),c(n,"title","title",i);var s=null===(t=l("link",i))||void 0===t?void 0:t.attribs.href;s&&(n.link=s);var r=h("summary",i)||h("content",i);r&&(n.description=r);var o=h("updated",i);return o&&(n.pubDate=new Date(o)),n}))};c(n,"id","id",i),c(n,"title","title",i);var r=null===(t=l("link",i))||void 0===t?void 0:t.attribs.href;r&&(n.link=r),c(n,"description","subtitle",i);var o=h("updated",i);return o&&(n.updated=new Date(o)),c(n,"author","email",i,!0),n}(t):function(e){var t,i,n=null!==(i=null===(t=l("channel",e.children))||void 0===t?void 0:t.children)&&void 0!==i?i:[],r={type:e.name.substr(0,3),id:"",items:(0,s.getElementsByTagName)("item",e.children).map((function(e){var t=e.children,i={media:a(t)};c(i,"id","guid",t),c(i,"title","title",t),c(i,"link","link",t),c(i,"description","description",t);var n=h("pubDate",t);return n&&(i.pubDate=new Date(n)),i}))};c(r,"title","title",n),c(r,"link","link",n),c(r,"description","description",n);var o=h("lastBuildDate",n);return o&&(r.updated=new Date(o)),c(r,"author","managingEditor",n,!0),r}(t):null};var r=["url","type","lang"],o=["fileSize","bitrate","framerate","samplingrate","channels","duration","height","width"];function a(e){return(0,s.getElementsByTagName)("media:content",e).map((function(e){for(var t=e.attribs,i={medium:t.medium,isDefault:!!t.isDefault},n=0,s=r;n{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.uniqueSort=t.compareDocumentPosition=t.removeSubsets=void 0;var n=i(9425);function s(e,t){var i=[],s=[];if(e===t)return 0;for(var r=(0,n.hasChildren)(e)?e:e.parent;r;)i.unshift(r),r=r.parent;for(r=(0,n.hasChildren)(t)?t:t.parent;r;)s.unshift(r),r=r.parent;for(var o=Math.min(i.length,s.length),a=0;ah.indexOf(d)?l===t?20:4:l===e?10:2}t.removeSubsets=function(e){for(var t=e.length;--t>=0;){var i=e[t];if(t>0&&e.lastIndexOf(i,t-1)>=0)e.splice(t,1);else for(var n=i.parent;n;n=n.parent)if(e.includes(n)){e.splice(t,1);break}}return e},t.compareDocumentPosition=s,t.uniqueSort=function(e){return(e=e.filter((function(e,t,i){return!i.includes(e,t+1)}))).sort((function(e,t){var i=s(e,t);return 2&i?-1:4&i?1:0})),e}},5030:function(e,t,i){"use strict";var n=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i),Object.defineProperty(e,n,{enumerable:!0,get:function(){return t[i]}})}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),s=this&&this.__exportStar||function(e,t){for(var i in e)"default"===i||Object.prototype.hasOwnProperty.call(t,i)||n(t,e,i)};Object.defineProperty(t,"__esModule",{value:!0}),t.hasChildren=t.isDocument=t.isComment=t.isText=t.isCDATA=t.isTag=void 0,s(i(3017),t),s(i(8563),t),s(i(378),t),s(i(1446),t),s(i(9319),t),s(i(6850),t),s(i(9904),t);var r=i(9425);Object.defineProperty(t,"isTag",{enumerable:!0,get:function(){return r.isTag}}),Object.defineProperty(t,"isCDATA",{enumerable:!0,get:function(){return r.isCDATA}}),Object.defineProperty(t,"isText",{enumerable:!0,get:function(){return r.isText}}),Object.defineProperty(t,"isComment",{enumerable:!0,get:function(){return r.isComment}}),Object.defineProperty(t,"isDocument",{enumerable:!0,get:function(){return r.isDocument}}),Object.defineProperty(t,"hasChildren",{enumerable:!0,get:function(){return r.hasChildren}})},9319:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getElementsByTagType=t.getElementsByTagName=t.getElementById=t.getElements=t.testElement=void 0;var n=i(9425),s=i(1446),r={tag_name:function(e){return"function"==typeof e?function(t){return(0,n.isTag)(t)&&e(t.name)}:"*"===e?n.isTag:function(t){return(0,n.isTag)(t)&&t.name===e}},tag_type:function(e){return"function"==typeof e?function(t){return e(t.type)}:function(t){return t.type===e}},tag_contains:function(e){return"function"==typeof e?function(t){return(0,n.isText)(t)&&e(t.data)}:function(t){return(0,n.isText)(t)&&t.data===e}}};function o(e,t){return"function"==typeof t?function(i){return(0,n.isTag)(i)&&t(i.attribs[e])}:function(i){return(0,n.isTag)(i)&&i.attribs[e]===t}}function a(e,t){return function(i){return e(i)||t(i)}}function l(e){var t=Object.keys(e).map((function(t){var i=e[t];return Object.prototype.hasOwnProperty.call(r,t)?r[t](i):o(t,i)}));return 0===t.length?null:t.reduce(a)}t.testElement=function(e,t){var i=l(e);return!i||i(t)},t.getElements=function(e,t,i,n){void 0===n&&(n=1/0);var r=l(e);return r?(0,s.filter)(r,t,i,n):[]},t.getElementById=function(e,t,i){return void 0===i&&(i=!0),Array.isArray(t)||(t=[t]),(0,s.findOne)(o("id",e),t,i)},t.getElementsByTagName=function(e,t,i,n){return void 0===i&&(i=!0),void 0===n&&(n=1/0),(0,s.filter)(r.tag_name(e),t,i,n)},t.getElementsByTagType=function(e,t,i,n){return void 0===i&&(i=!0),void 0===n&&(n=1/0),(0,s.filter)(r.tag_type(e),t,i,n)}},378:(e,t)=>{"use strict";function i(e){if(e.prev&&(e.prev.next=e.next),e.next&&(e.next.prev=e.prev),e.parent){var t=e.parent.children;t.splice(t.lastIndexOf(e),1)}}Object.defineProperty(t,"__esModule",{value:!0}),t.prepend=t.prependChild=t.append=t.appendChild=t.replaceElement=t.removeElement=void 0,t.removeElement=i,t.replaceElement=function(e,t){var i=t.prev=e.prev;i&&(i.next=t);var n=t.next=e.next;n&&(n.prev=t);var s=t.parent=e.parent;if(s){var r=s.children;r[r.lastIndexOf(e)]=t}},t.appendChild=function(e,t){if(i(t),t.next=null,t.parent=e,e.children.push(t)>1){var n=e.children[e.children.length-2];n.next=t,t.prev=n}else t.prev=null},t.append=function(e,t){i(t);var n=e.parent,s=e.next;if(t.next=s,t.prev=e,e.next=t,t.parent=n,s){if(s.prev=t,n){var r=n.children;r.splice(r.lastIndexOf(s),0,t)}}else n&&n.children.push(t)},t.prependChild=function(e,t){if(i(t),t.parent=e,t.prev=null,1!==e.children.unshift(t)){var n=e.children[1];n.prev=t,t.next=n}else t.next=null},t.prepend=function(e,t){i(t);var n=e.parent;if(n){var s=n.children;s.splice(s.indexOf(e),0,t)}e.prev&&(e.prev.next=t),t.parent=n,t.prev=e.prev,t.next=e,e.prev=t}},1446:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.findAll=t.existsOne=t.findOne=t.findOneChild=t.find=t.filter=void 0;var n=i(9425);function s(e,t,i,r){for(var o=[],a=0,l=t;a0){var c=s(e,h.children,i,r);if(o.push.apply(o,c),(r-=c.length)<=0)break}}return o}t.filter=function(e,t,i,n){return void 0===i&&(i=!0),void 0===n&&(n=1/0),Array.isArray(t)||(t=[t]),s(e,t,i,n)},t.find=s,t.findOneChild=function(e,t){return t.find(e)},t.findOne=function e(t,i,s){void 0===s&&(s=!0);for(var r=null,o=0;o0&&(r=e(t,a.children)))}return r},t.existsOne=function e(t,i){return i.some((function(i){return(0,n.isTag)(i)&&(t(i)||i.children.length>0&&e(t,i.children))}))},t.findAll=function(e,t){for(var i,s,r=[],o=t.filter(n.isTag);s=o.shift();){var a=null===(i=s.children)||void 0===i?void 0:i.filter(n.isTag);a&&a.length>0&&o.unshift.apply(o,a),e(s)&&r.push(s)}return r}},3017:function(e,t,i){"use strict";var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.innerText=t.textContent=t.getText=t.getInnerHTML=t.getOuterHTML=void 0;var s=i(9425),r=n(i(2721)),o=i(3706);function a(e,t){return(0,r.default)(e,t)}t.getOuterHTML=a,t.getInnerHTML=function(e,t){return(0,s.hasChildren)(e)?e.children.map((function(e){return a(e,t)})).join(""):""},t.getText=function e(t){return Array.isArray(t)?t.map(e).join(""):(0,s.isTag)(t)?"br"===t.name?"\n":e(t.children):(0,s.isCDATA)(t)?e(t.children):(0,s.isText)(t)?t.data:""},t.textContent=function e(t){return Array.isArray(t)?t.map(e).join(""):(0,s.hasChildren)(t)&&!(0,s.isComment)(t)?e(t.children):(0,s.isText)(t)?t.data:""},t.innerText=function e(t){return Array.isArray(t)?t.map(e).join(""):(0,s.hasChildren)(t)&&(t.type===o.ElementType.Tag||(0,s.isCDATA)(t))?e(t.children):(0,s.isText)(t)?t.data:""}},8563:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.prevElementSibling=t.nextElementSibling=t.getName=t.hasAttrib=t.getAttributeValue=t.getSiblings=t.getParent=t.getChildren=void 0;var n=i(9425),s=[];function r(e){var t;return null!==(t=e.children)&&void 0!==t?t:s}function o(e){return e.parent||null}t.getChildren=r,t.getParent=o,t.getSiblings=function(e){var t=o(e);if(null!=t)return r(t);for(var i=[e],n=e.prev,s=e.next;null!=n;)i.unshift(n),n=n.prev;for(;null!=s;)i.push(s),s=s.next;return i},t.getAttributeValue=function(e,t){var i;return null===(i=e.attribs)||void 0===i?void 0:i[t]},t.hasAttrib=function(e,t){return null!=e.attribs&&Object.prototype.hasOwnProperty.call(e.attribs,t)&&null!=e.attribs[t]},t.getName=function(e){return e.name},t.nextElementSibling=function(e){for(var t=e.next;null!==t&&!(0,n.isTag)(t);)t=t.next;return t},t.prevElementSibling=function(e){for(var t=e.prev;null!==t&&!(0,n.isTag)(t);)t=t.prev;return t}},4080:function(e,t,i){"use strict";var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.decodeHTML=t.decodeHTMLStrict=t.decodeXML=void 0;var s=n(i(2810)),r=n(i(2836)),o=n(i(8689)),a=n(i(7826)),l=/&(?:[a-zA-Z0-9]+|#[xX][\da-fA-F]+|#\d+);/g;function h(e){var t=d(e);return function(e){return String(e).replace(l,t)}}t.decodeXML=h(o.default),t.decodeHTMLStrict=h(s.default);var c=function(e,t){return e65535&&(e-=65536,t+=String.fromCharCode(e>>>10&1023|55296),e=56320|1023&e),t+String.fromCharCode(e)};t.default=function(e){return e>=55296&&e<=57343||e>1114111?"�":(e in s.default&&(e=s.default[e]),r(e))}},956:function(e,t,i){"use strict";var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.escapeUTF8=t.escape=t.encodeNonAsciiHTML=t.encodeHTML=t.encodeXML=void 0;var s=c(n(i(8689)).default),r=d(s);t.encodeXML=g(s);var o,a,l=c(n(i(2810)).default),h=d(l);function c(e){return Object.keys(e).sort().reduce((function(t,i){return t[e[i]]="&"+i+";",t}),{})}function d(e){for(var t=[],i=[],n=0,s=Object.keys(e);n1?p(e):e.charCodeAt(0)).toString(16).toUpperCase()+";"}var m=new RegExp(r.source+"|"+u.source,"g");function g(e){return function(t){return t.replace(m,(function(t){return e[t]||f(t)}))}}t.escape=function(e){return e.replace(m,f)},t.escapeUTF8=function(e){return e.replace(r,f)}},2593:(e,t,i)=>{"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.decodeXMLStrict=t.decodeHTML5Strict=t.decodeHTML4Strict=t.decodeHTML5=t.decodeHTML4=t.decodeHTMLStrict=t.decodeHTML=t.decodeXML=t.encodeHTML5=t.encodeHTML4=t.escapeUTF8=t.escape=t.encodeNonAsciiHTML=t.encodeHTML=t.encodeXML=t.encode=t.decodeStrict=t.decode=void 0;var n=i(4080),s=i(956);t.decode=function(e,t){return(!t||t<=0?n.decodeXML:n.decodeHTML)(e)},t.decodeStrict=function(e,t){return(!t||t<=0?n.decodeXML:n.decodeHTMLStrict)(e)},t.encode=function(e,t){return(!t||t<=0?s.encodeXML:s.encodeHTML)(e)};var r=i(956);Object.defineProperty(t,"encodeXML",{enumerable:!0,get:function(){return r.encodeXML}}),Object.defineProperty(t,"encodeHTML",{enumerable:!0,get:function(){return r.encodeHTML}}),Object.defineProperty(t,"encodeNonAsciiHTML",{enumerable:!0,get:function(){return r.encodeNonAsciiHTML}}),Object.defineProperty(t,"escape",{enumerable:!0,get:function(){return r.escape}}),Object.defineProperty(t,"escapeUTF8",{enumerable:!0,get:function(){return r.escapeUTF8}}),Object.defineProperty(t,"encodeHTML4",{enumerable:!0,get:function(){return r.encodeHTML}}),Object.defineProperty(t,"encodeHTML5",{enumerable:!0,get:function(){return r.encodeHTML}});var o=i(4080);Object.defineProperty(t,"decodeXML",{enumerable:!0,get:function(){return o.decodeXML}}),Object.defineProperty(t,"decodeHTML",{enumerable:!0,get:function(){return o.decodeHTML}}),Object.defineProperty(t,"decodeHTMLStrict",{enumerable:!0,get:function(){return o.decodeHTMLStrict}}),Object.defineProperty(t,"decodeHTML4",{enumerable:!0,get:function(){return o.decodeHTML}}),Object.defineProperty(t,"decodeHTML5",{enumerable:!0,get:function(){return o.decodeHTML}}),Object.defineProperty(t,"decodeHTML4Strict",{enumerable:!0,get:function(){return o.decodeHTMLStrict}}),Object.defineProperty(t,"decodeHTML5Strict",{enumerable:!0,get:function(){return o.decodeHTMLStrict}}),Object.defineProperty(t,"decodeXMLStrict",{enumerable:!0,get:function(){return o.decodeXML}})},3419:e=>{"use strict";e.exports=e=>{if("string"!=typeof e)throw new TypeError("Expected a string");return e.replace(/[|\\{}()[\]^$+*?.]/g,"\\$&").replace(/-/g,"\\x2d")}},995:function(e,t,i){"use strict";var n,s=this&&this.__extends||(n=function(e,t){return n=Object.setPrototypeOf||{__proto__:[]}instanceof Array&&function(e,t){e.__proto__=t}||function(e,t){for(var i in t)Object.prototype.hasOwnProperty.call(t,i)&&(e[i]=t[i])},n(e,t)},function(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Class extends value "+String(t)+" is not a constructor or null");function i(){this.constructor=e}n(e,t),e.prototype=null===t?Object.create(t):(i.prototype=t.prototype,new i)}),r=this&&this.__createBinding||(Object.create?function(e,t,i,n){void 0===n&&(n=i),Object.defineProperty(e,n,{enumerable:!0,get:function(){return t[i]}})}:function(e,t,i,n){void 0===n&&(n=i),e[n]=t[i]}),o=this&&this.__setModuleDefault||(Object.create?function(e,t){Object.defineProperty(e,"default",{enumerable:!0,value:t})}:function(e,t){e.default=t}),a=this&&this.__importStar||function(e){if(e&&e.__esModule)return e;var t={};if(null!=e)for(var i in e)"default"!==i&&Object.prototype.hasOwnProperty.call(e,i)&&r(t,e,i);return o(t,e),t},l=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.parseFeed=t.FeedHandler=void 0;var h,c,d=l(i(9425)),u=a(i(5030)),p=i(7361);!function(e){e[e.image=0]="image",e[e.audio=1]="audio",e[e.video=2]="video",e[e.document=3]="document",e[e.executable=4]="executable"}(h||(h={})),function(e){e[e.sample=0]="sample",e[e.full=1]="full",e[e.nonstop=2]="nonstop"}(c||(c={}));var f=function(e){function t(t,i){return"object"==typeof t&&(i=t=void 0),e.call(this,t,i)||this}return s(t,e),t.prototype.onend=function(){var e,t,i=v(y,this.dom);if(i){var n={};if("feed"===i.name){var s=i.children;n.type="atom",_(n,"id","id",s),_(n,"title","title",s);var r=b("href",v("link",s));r&&(n.link=r),_(n,"description","subtitle",s),(o=O("updated",s))&&(n.updated=new Date(o)),_(n,"author","email",s,!0),n.items=g("entry",s).map((function(e){var t={},i=e.children;_(t,"id","id",i),_(t,"title","title",i);var n=b("href",v("link",i));n&&(t.link=n);var s=O("summary",i)||O("content",i);s&&(t.description=s);var r=O("updated",i);return r&&(t.pubDate=new Date(r)),t.media=m(i),t}))}else{var o;s=null!==(t=null===(e=v("channel",i.children))||void 0===e?void 0:e.children)&&void 0!==t?t:[],n.type=i.name.substr(0,3),n.id="",_(n,"title","title",s),_(n,"link","link",s),_(n,"description","description",s),(o=O("lastBuildDate",s))&&(n.updated=new Date(o)),_(n,"author","managingEditor",s,!0),n.items=g("item",i.children).map((function(e){var t={},i=e.children;_(t,"id","guid",i),_(t,"title","title",i),_(t,"link","link",i),_(t,"description","description",i);var n=O("pubDate",i);return n&&(t.pubDate=new Date(n)),t.media=m(i),t}))}this.feed=n,this.handleCallback(null)}else this.handleCallback(new Error("couldn't find root of feed"))},t}(d.default);function m(e){return g("media:content",e).map((function(e){var t={medium:e.attribs.medium,isDefault:!!e.attribs.isDefault};return e.attribs.url&&(t.url=e.attribs.url),e.attribs.fileSize&&(t.fileSize=parseInt(e.attribs.fileSize,10)),e.attribs.type&&(t.type=e.attribs.type),e.attribs.expression&&(t.expression=e.attribs.expression),e.attribs.bitrate&&(t.bitrate=parseInt(e.attribs.bitrate,10)),e.attribs.framerate&&(t.framerate=parseInt(e.attribs.framerate,10)),e.attribs.samplingrate&&(t.samplingrate=parseInt(e.attribs.samplingrate,10)),e.attribs.channels&&(t.channels=parseInt(e.attribs.channels,10)),e.attribs.duration&&(t.duration=parseInt(e.attribs.duration,10)),e.attribs.height&&(t.height=parseInt(e.attribs.height,10)),e.attribs.width&&(t.width=parseInt(e.attribs.width,10)),e.attribs.lang&&(t.lang=e.attribs.lang),t}))}function g(e,t){return u.getElementsByTagName(e,t,!0)}function v(e,t){return u.getElementsByTagName(e,t,!0,1)[0]}function O(e,t,i){return void 0===i&&(i=!1),u.getText(u.getElementsByTagName(e,t,i,1)).trim()}function b(e,t){return t?t.attribs[e]:null}function _(e,t,i,n,s){void 0===s&&(s=!1);var r=O(i,n,s);r&&(e[t]=r)}function y(e){return"rss"===e||"feed"===e||"rdf:RDF"===e}t.FeedHandler=f,t.parseFeed=function(e,t){void 0===t&&(t={xmlMode:!0});var i=new f(t);return new p.Parser(i,t).end(e),i.feed}},7361:function(e,t,i){"use strict";var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0}),t.Parser=void 0;var s=n(i(1941)),r=new Set(["input","option","optgroup","select","button","datalist","textarea"]),o=new Set(["p"]),a={tr:new Set(["tr","th","td"]),th:new Set(["th"]),td:new Set(["thead","th","td"]),body:new Set(["head","link","script"]),li:new Set(["li"]),p:o,h1:o,h2:o,h3:o,h4:o,h5:o,h6:o,select:r,input:r,output:r,button:r,datalist:r,textarea:r,option:new Set(["option"]),optgroup:new Set(["optgroup","option"]),dd:new Set(["dt","dd"]),dt:new Set(["dt","dd"]),address:o,article:o,aside:o,blockquote:o,details:o,div:o,dl:o,fieldset:o,figcaption:o,figure:o,footer:o,form:o,header:o,hr:o,main:o,nav:o,ol:o,pre:o,section:o,table:o,ul:o,rt:new Set(["rt","rp"]),rp:new Set(["rt","rp"]),tbody:new Set(["thead","tbody"]),tfoot:new Set(["thead","tbody"])},l=new Set(["area","base","basefont","br","col","command","embed","frame","hr","img","input","isindex","keygen","link","meta","param","source","track","wbr"]),h=new Set(["math","svg"]),c=new Set(["mi","mo","mn","ms","mtext","annotation-xml","foreignObject","desc","title"]),d=/\s|\//,u=function(){function e(e,t){var i,n,r,o,a;void 0===t&&(t={}),this.startIndex=0,this.endIndex=null,this.tagname="",this.attribname="",this.attribvalue="",this.attribs=null,this.stack=[],this.foreignContext=[],this.options=t,this.cbs=null!=e?e:{},this.lowerCaseTagNames=null!==(i=t.lowerCaseTags)&&void 0!==i?i:!t.xmlMode,this.lowerCaseAttributeNames=null!==(n=t.lowerCaseAttributeNames)&&void 0!==n?n:!t.xmlMode,this.tokenizer=new(null!==(r=t.Tokenizer)&&void 0!==r?r:s.default)(this.options,this),null===(a=(o=this.cbs).onparserinit)||void 0===a||a.call(o,this)}return e.prototype.updatePosition=function(e){null===this.endIndex?this.tokenizer.sectionStart<=e?this.startIndex=0:this.startIndex=this.tokenizer.sectionStart-e:this.startIndex=this.endIndex+1,this.endIndex=this.tokenizer.getAbsoluteIndex()},e.prototype.ontext=function(e){var t,i;this.updatePosition(1),this.endIndex--,null===(i=(t=this.cbs).ontext)||void 0===i||i.call(t,e)},e.prototype.onopentagname=function(e){var t,i;if(this.lowerCaseTagNames&&(e=e.toLowerCase()),this.tagname=e,!this.options.xmlMode&&Object.prototype.hasOwnProperty.call(a,e))for(var n=void 0;this.stack.length>0&&a[e].has(n=this.stack[this.stack.length-1]);)this.onclosetag(n);!this.options.xmlMode&&l.has(e)||(this.stack.push(e),h.has(e)?this.foreignContext.push(!0):c.has(e)&&this.foreignContext.push(!1)),null===(i=(t=this.cbs).onopentagname)||void 0===i||i.call(t,e),this.cbs.onopentag&&(this.attribs={})},e.prototype.onopentagend=function(){var e,t;this.updatePosition(1),this.attribs&&(null===(t=(e=this.cbs).onopentag)||void 0===t||t.call(e,this.tagname,this.attribs),this.attribs=null),!this.options.xmlMode&&this.cbs.onclosetag&&l.has(this.tagname)&&this.cbs.onclosetag(this.tagname),this.tagname=""},e.prototype.onclosetag=function(e){if(this.updatePosition(1),this.lowerCaseTagNames&&(e=e.toLowerCase()),(h.has(e)||c.has(e))&&this.foreignContext.pop(),!this.stack.length||!this.options.xmlMode&&l.has(e))this.options.xmlMode||"br"!==e&&"p"!==e||(this.onopentagname(e),this.closeCurrentTag());else{var t=this.stack.lastIndexOf(e);if(-1!==t)if(this.cbs.onclosetag)for(t=this.stack.length-t;t--;)this.cbs.onclosetag(this.stack.pop());else this.stack.length=t;else"p"!==e||this.options.xmlMode||(this.onopentagname(e),this.closeCurrentTag())}},e.prototype.onselfclosingtag=function(){this.options.xmlMode||this.options.recognizeSelfClosing||this.foreignContext[this.foreignContext.length-1]?this.closeCurrentTag():this.onopentagend()},e.prototype.closeCurrentTag=function(){var e,t,i=this.tagname;this.onopentagend(),this.stack[this.stack.length-1]===i&&(null===(t=(e=this.cbs).onclosetag)||void 0===t||t.call(e,i),this.stack.pop())},e.prototype.onattribname=function(e){this.lowerCaseAttributeNames&&(e=e.toLowerCase()),this.attribname=e},e.prototype.onattribdata=function(e){this.attribvalue+=e},e.prototype.onattribend=function(e){var t,i;null===(i=(t=this.cbs).onattribute)||void 0===i||i.call(t,this.attribname,this.attribvalue,e),this.attribs&&!Object.prototype.hasOwnProperty.call(this.attribs,this.attribname)&&(this.attribs[this.attribname]=this.attribvalue),this.attribname="",this.attribvalue=""},e.prototype.getInstructionName=function(e){var t=e.search(d),i=t<0?e:e.substr(0,t);return this.lowerCaseTagNames&&(i=i.toLowerCase()),i},e.prototype.ondeclaration=function(e){if(this.cbs.onprocessinginstruction){var t=this.getInstructionName(e);this.cbs.onprocessinginstruction("!"+t,"!"+e)}},e.prototype.onprocessinginstruction=function(e){if(this.cbs.onprocessinginstruction){var t=this.getInstructionName(e);this.cbs.onprocessinginstruction("?"+t,"?"+e)}},e.prototype.oncomment=function(e){var t,i,n,s;this.updatePosition(4),null===(i=(t=this.cbs).oncomment)||void 0===i||i.call(t,e),null===(s=(n=this.cbs).oncommentend)||void 0===s||s.call(n)},e.prototype.oncdata=function(e){var t,i,n,s,r,o;this.updatePosition(1),this.options.xmlMode||this.options.recognizeCDATA?(null===(i=(t=this.cbs).oncdatastart)||void 0===i||i.call(t),null===(s=(n=this.cbs).ontext)||void 0===s||s.call(n,e),null===(o=(r=this.cbs).oncdataend)||void 0===o||o.call(r)):this.oncomment("[CDATA["+e+"]]")},e.prototype.onerror=function(e){var t,i;null===(i=(t=this.cbs).onerror)||void 0===i||i.call(t,e)},e.prototype.onend=function(){var e,t;if(this.cbs.onclosetag)for(var i=this.stack.length;i>0;this.cbs.onclosetag(this.stack[--i]));null===(t=(e=this.cbs).onend)||void 0===t||t.call(e)},e.prototype.reset=function(){var e,t,i,n;null===(t=(e=this.cbs).onreset)||void 0===t||t.call(e),this.tokenizer.reset(),this.tagname="",this.attribname="",this.attribs=null,this.stack=[],null===(n=(i=this.cbs).onparserinit)||void 0===n||n.call(i,this)},e.prototype.parseComplete=function(e){this.reset(),this.end(e)},e.prototype.write=function(e){this.tokenizer.write(e)},e.prototype.end=function(e){this.tokenizer.end(e)},e.prototype.pause=function(){this.tokenizer.pause()},e.prototype.resume=function(){this.tokenizer.resume()},e.prototype.parseChunk=function(e){this.write(e)},e.prototype.done=function(e){this.end(e)},e}();t.Parser=u},1941:function(e,t,i){"use strict";var n=this&&this.__importDefault||function(e){return e&&e.__esModule?e:{default:e}};Object.defineProperty(t,"__esModule",{value:!0});var s=n(i(7826)),r=n(i(2810)),o=n(i(2836)),a=n(i(8689));function l(e){return" "===e||"\n"===e||"\t"===e||"\f"===e||"\r"===e}function h(e){return e>="a"&&e<="z"||e>="A"&&e<="Z"}function c(e,t,i){var n=e.toLowerCase();return e===n?function(e,s){s===n?e._state=t:(e._state=i,e._index--)}:function(s,r){r===n||r===e?s._state=t:(s._state=i,s._index--)}}function d(e,t){var i=e.toLowerCase();return function(n,s){s===i||s===e?n._state=t:(n._state=3,n._index--)}}var u=c("C",24,16),p=c("D",25,16),f=c("A",26,16),m=c("T",27,16),g=c("A",28,16),v=d("R",35),O=d("I",36),b=d("P",37),_=d("T",38),y=c("R",40,1),w=c("I",41,1),x=c("P",42,1),S=c("T",43,1),k=d("Y",45),T=d("L",46),C=d("E",47),P=c("Y",49,1),M=c("L",50,1),E=c("E",51,1),A=d("I",54),R=d("T",55),D=d("L",56),I=d("E",57),q=c("I",58,1),L=c("T",59,1),N=c("L",60,1),B=c("E",61,1),$=c("#",63,64),Q=c("X",66,65),z=function(){function e(e,t){var i;this._state=1,this.buffer="",this.sectionStart=0,this._index=0,this.bufferOffset=0,this.baseState=1,this.special=1,this.running=!0,this.ended=!1,this.cbs=t,this.xmlMode=!!(null==e?void 0:e.xmlMode),this.decodeEntities=null===(i=null==e?void 0:e.decodeEntities)||void 0===i||i}return e.prototype.reset=function(){this._state=1,this.buffer="",this.sectionStart=0,this._index=0,this.bufferOffset=0,this.baseState=1,this.special=1,this.running=!0,this.ended=!1},e.prototype.write=function(e){this.ended&&this.cbs.onerror(Error(".write() after done!")),this.buffer+=e,this.parse()},e.prototype.end=function(e){this.ended&&this.cbs.onerror(Error(".end() after done!")),e&&this.write(e),this.ended=!0,this.running&&this.finish()},e.prototype.pause=function(){this.running=!1},e.prototype.resume=function(){this.running=!0,this._indexthis.sectionStart&&this.cbs.ontext(this.getSection()),this._state=2,this.sectionStart=this._index):!this.decodeEntities||"&"!==e||1!==this.special&&4!==this.special||(this._index>this.sectionStart&&this.cbs.ontext(this.getSection()),this.baseState=1,this._state=62,this.sectionStart=this._index)},e.prototype.isTagStartChar=function(e){return h(e)||this.xmlMode&&!l(e)&&"/"!==e&&">"!==e},e.prototype.stateBeforeTagName=function(e){"/"===e?this._state=5:"<"===e?(this.cbs.ontext(this.getSection()),this.sectionStart=this._index):">"===e||1!==this.special||l(e)?this._state=1:"!"===e?(this._state=15,this.sectionStart=this._index+1):"?"===e?(this._state=17,this.sectionStart=this._index+1):this.isTagStartChar(e)?(this._state=this.xmlMode||"s"!==e&&"S"!==e?this.xmlMode||"t"!==e&&"T"!==e?3:52:32,this.sectionStart=this._index):this._state=1},e.prototype.stateInTagName=function(e){("/"===e||">"===e||l(e))&&(this.emitToken("onopentagname"),this._state=8,this._index--)},e.prototype.stateBeforeClosingTagName=function(e){l(e)||(">"===e?this._state=1:1!==this.special?4===this.special||"s"!==e&&"S"!==e?4!==this.special||"t"!==e&&"T"!==e?(this._state=1,this._index--):this._state=53:this._state=33:this.isTagStartChar(e)?(this._state=6,this.sectionStart=this._index):(this._state=20,this.sectionStart=this._index))},e.prototype.stateInClosingTagName=function(e){(">"===e||l(e))&&(this.emitToken("onclosetag"),this._state=7,this._index--)},e.prototype.stateAfterClosingTagName=function(e){">"===e&&(this._state=1,this.sectionStart=this._index+1)},e.prototype.stateBeforeAttributeName=function(e){">"===e?(this.cbs.onopentagend(),this._state=1,this.sectionStart=this._index+1):"/"===e?this._state=4:l(e)||(this._state=9,this.sectionStart=this._index)},e.prototype.stateInSelfClosingTag=function(e){">"===e?(this.cbs.onselfclosingtag(),this._state=1,this.sectionStart=this._index+1,this.special=1):l(e)||(this._state=8,this._index--)},e.prototype.stateInAttributeName=function(e){("="===e||"/"===e||">"===e||l(e))&&(this.cbs.onattribname(this.getSection()),this.sectionStart=-1,this._state=10,this._index--)},e.prototype.stateAfterAttributeName=function(e){"="===e?this._state=11:"/"===e||">"===e?(this.cbs.onattribend(void 0),this._state=8,this._index--):l(e)||(this.cbs.onattribend(void 0),this._state=9,this.sectionStart=this._index)},e.prototype.stateBeforeAttributeValue=function(e){'"'===e?(this._state=12,this.sectionStart=this._index+1):"'"===e?(this._state=13,this.sectionStart=this._index+1):l(e)||(this._state=14,this.sectionStart=this._index,this._index--)},e.prototype.handleInAttributeValue=function(e,t){e===t?(this.emitToken("onattribdata"),this.cbs.onattribend(t),this._state=8):this.decodeEntities&&"&"===e&&(this.emitToken("onattribdata"),this.baseState=this._state,this._state=62,this.sectionStart=this._index)},e.prototype.stateInAttributeValueDoubleQuotes=function(e){this.handleInAttributeValue(e,'"')},e.prototype.stateInAttributeValueSingleQuotes=function(e){this.handleInAttributeValue(e,"'")},e.prototype.stateInAttributeValueNoQuotes=function(e){l(e)||">"===e?(this.emitToken("onattribdata"),this.cbs.onattribend(null),this._state=8,this._index--):this.decodeEntities&&"&"===e&&(this.emitToken("onattribdata"),this.baseState=this._state,this._state=62,this.sectionStart=this._index)},e.prototype.stateBeforeDeclaration=function(e){this._state="["===e?23:"-"===e?18:16},e.prototype.stateInDeclaration=function(e){">"===e&&(this.cbs.ondeclaration(this.getSection()),this._state=1,this.sectionStart=this._index+1)},e.prototype.stateInProcessingInstruction=function(e){">"===e&&(this.cbs.onprocessinginstruction(this.getSection()),this._state=1,this.sectionStart=this._index+1)},e.prototype.stateBeforeComment=function(e){"-"===e?(this._state=19,this.sectionStart=this._index+1):this._state=16},e.prototype.stateInComment=function(e){"-"===e&&(this._state=21)},e.prototype.stateInSpecialComment=function(e){">"===e&&(this.cbs.oncomment(this.buffer.substring(this.sectionStart,this._index)),this._state=1,this.sectionStart=this._index+1)},e.prototype.stateAfterComment1=function(e){this._state="-"===e?22:19},e.prototype.stateAfterComment2=function(e){">"===e?(this.cbs.oncomment(this.buffer.substring(this.sectionStart,this._index-2)),this._state=1,this.sectionStart=this._index+1):"-"!==e&&(this._state=19)},e.prototype.stateBeforeCdata6=function(e){"["===e?(this._state=29,this.sectionStart=this._index+1):(this._state=16,this._index--)},e.prototype.stateInCdata=function(e){"]"===e&&(this._state=30)},e.prototype.stateAfterCdata1=function(e){this._state="]"===e?31:29},e.prototype.stateAfterCdata2=function(e){">"===e?(this.cbs.oncdata(this.buffer.substring(this.sectionStart,this._index-2)),this._state=1,this.sectionStart=this._index+1):"]"!==e&&(this._state=29)},e.prototype.stateBeforeSpecialS=function(e){"c"===e||"C"===e?this._state=34:"t"===e||"T"===e?this._state=44:(this._state=3,this._index--)},e.prototype.stateBeforeSpecialSEnd=function(e){2!==this.special||"c"!==e&&"C"!==e?3!==this.special||"t"!==e&&"T"!==e?this._state=1:this._state=48:this._state=39},e.prototype.stateBeforeSpecialLast=function(e,t){("/"===e||">"===e||l(e))&&(this.special=t),this._state=3,this._index--},e.prototype.stateAfterSpecialLast=function(e,t){">"===e||l(e)?(this.special=1,this._state=6,this.sectionStart=this._index-t,this._index--):this._state=1},e.prototype.parseFixedEntity=function(e){if(void 0===e&&(e=this.xmlMode?a.default:r.default),this.sectionStart+1=2;){var i=this.buffer.substr(e,t);if(Object.prototype.hasOwnProperty.call(o.default,i))return this.emitPartial(o.default[i]),void(this.sectionStart+=t+1);t--}},e.prototype.stateInNamedEntity=function(e){";"===e?(this.parseFixedEntity(),1===this.baseState&&this.sectionStart+1"9")&&!h(e)&&(this.xmlMode||this.sectionStart+1===this._index||(1!==this.baseState?"="!==e&&this.parseFixedEntity(o.default):this.parseLegacyEntity()),this._state=this.baseState,this._index--)},e.prototype.decodeNumericEntity=function(e,t,i){var n=this.sectionStart+e;if(n!==this._index){var r=this.buffer.substring(n,this._index),o=parseInt(r,t);this.emitPartial(s.default(o)),this.sectionStart=i?this._index+1:this._index}this._state=this.baseState},e.prototype.stateInNumericEntity=function(e){";"===e?this.decodeNumericEntity(2,10,!0):(e<"0"||e>"9")&&(this.xmlMode?this._state=this.baseState:this.decodeNumericEntity(2,10,!1),this._index--)},e.prototype.stateInHexEntity=function(e){";"===e?this.decodeNumericEntity(3,16,!0):(e<"a"||e>"f")&&(e<"A"||e>"F")&&(e<"0"||e>"9")&&(this.xmlMode?this._state=this.baseState:this.decodeNumericEntity(3,16,!1),this._index--)},e.prototype.cleanup=function(){this.sectionStart<0?(this.buffer="",this.bufferOffset+=this._index,this._index=0):this.running&&(1===this._state?(this.sectionStart!==this._index&&this.cbs.ontext(this.buffer.substr(this.sectionStart)),this.buffer="",this.bufferOffset+=this._index,this._index=0):this.sectionStart===this._index?(this.buffer="",this.bufferOffset+=this._index,this._index=0):(this.buffer=this.buffer.substr(this.sectionStart),this._index-=this.sectionStart,this.bufferOffset+=this.sectionStart),this.sectionStart=0)},e.prototype.parse=function(){for(;this._index{"use strict";function i(e){return"[object Object]"===Object.prototype.toString.call(e)}Object.defineProperty(t,"__esModule",{value:!0}),t.isPlainObject=function(e){var t,n;return!1!==i(e)&&(void 0===(t=e.constructor)||!1!==i(n=t.prototype)&&!1!==n.hasOwnProperty("isPrototypeOf"))}},6145:(e,t,i)=>{var n,s=/[&<>"'`]/g,r=RegExp(s.source),o="object"==typeof i.g&&i.g&&i.g.Object===Object&&i.g,a="object"==typeof self&&self&&self.Object===Object&&self,l=o||a||Function("return this")(),h=(n={"&":"&","<":"<",">":">",'"':""","'":"'","`":"`"},function(e){return null==n?void 0:n[e]}),c=Object.prototype.toString,d=l.Symbol,u=d?d.prototype:void 0,p=u?u.toString:void 0;e.exports=function(e){var t;return(e=null==(t=e)?"":function(e){if("string"==typeof e)return e;if(function(e){return"symbol"==typeof e||function(e){return!!e&&"object"==typeof e}(e)&&"[object Symbol]"==c.call(e)}(e))return p?p.call(e):"";var t=e+"";return"0"==t&&1/e==-1/0?"-0":t}(t))&&r.test(e)?e.replace(s,h):e}},6965:e=>{"use strict";function t(e){return"number"==typeof e||!!/^0x[0-9a-f]+$/i.test(e)||/^[-+]?(?:\d+(?:\.\d*)?|\.\d+)(e[-+]?\d+)?$/.test(e)}function i(e,t){return"constructor"===t&&"function"==typeof e[t]||"__proto__"===t}e.exports=function(e,n){n||(n={});var s={bools:{},strings:{},unknownFn:null};"function"==typeof n.unknown&&(s.unknownFn=n.unknown),"boolean"==typeof n.boolean&&n.boolean?s.allBools=!0:[].concat(n.boolean).filter(Boolean).forEach((function(e){s.bools[e]=!0}));var r={};function o(e){return r[e].some((function(e){return s.bools[e]}))}Object.keys(n.alias||{}).forEach((function(e){r[e]=[].concat(n.alias[e]),r[e].forEach((function(t){r[t]=[e].concat(r[e].filter((function(e){return t!==e})))}))})),[].concat(n.string).filter(Boolean).forEach((function(e){s.strings[e]=!0,r[e]&&[].concat(r[e]).forEach((function(e){s.strings[e]=!0}))}));var a=n.default||{},l={_:[]};function h(e,t,n){for(var r=e,o=0;o=l)return g;n=i(d),s=[],","===n.slice(-1)?(n=n.replace(u,""),O()):v()}function v(){for(i(h),r="",o="in descriptor";;){if(a=e.charAt(m),"in descriptor"===o)if(t(a))r&&(s.push(r),r="",o="after descriptor");else{if(","===a)return m+=1,r&&s.push(r),void O();if("("===a)r+=a,o="in parens";else{if(""===a)return r&&s.push(r),void O();r+=a}}else if("in parens"===o)if(")"===a)r+=a,o="in descriptor";else{if(""===a)return s.push(r),void O();r+=a}else if("after descriptor"===o)if(t(a));else{if(""===a)return void O();o="in descriptor",m-=1}m+=1}}function O(){var t,i,r,o,a,l,h,c,d,u=!1,m={};for(o=0;o{"use strict";function t(e){if("string"!=typeof e)throw new TypeError("Path must be a string. Received "+JSON.stringify(e))}function i(e,t){for(var i,n="",s=0,r=-1,o=0,a=0;a<=e.length;++a){if(a2){var l=n.lastIndexOf("/");if(l!==n.length-1){-1===l?(n="",s=0):s=(n=n.slice(0,l)).length-1-n.lastIndexOf("/"),r=a,o=0;continue}}else if(2===n.length||1===n.length){n="",s=0,r=a,o=0;continue}t&&(n.length>0?n+="/..":n="..",s=2)}else n.length>0?n+="/"+e.slice(r+1,a):n=e.slice(r+1,a),s=a-r-1;r=a,o=0}else 46===i&&-1!==o?++o:o=-1}return n}var n={resolve:function(){for(var e,n="",s=!1,r=arguments.length-1;r>=-1&&!s;r--){var o;r>=0?o=arguments[r]:(void 0===e&&(e=process.cwd()),o=e),t(o),0!==o.length&&(n=o+"/"+n,s=47===o.charCodeAt(0))}return n=i(n,!s),s?n.length>0?"/"+n:"/":n.length>0?n:"."},normalize:function(e){if(t(e),0===e.length)return".";var n=47===e.charCodeAt(0),s=47===e.charCodeAt(e.length-1);return 0!==(e=i(e,!n)).length||n||(e="."),e.length>0&&s&&(e+="/"),n?"/"+e:e},isAbsolute:function(e){return t(e),e.length>0&&47===e.charCodeAt(0)},join:function(){if(0===arguments.length)return".";for(var e,i=0;i0&&(void 0===e?e=s:e+="/"+s)}return void 0===e?".":n.normalize(e)},relative:function(e,i){if(t(e),t(i),e===i)return"";if((e=n.resolve(e))===(i=n.resolve(i)))return"";for(var s=1;sh){if(47===i.charCodeAt(a+d))return i.slice(a+d+1);if(0===d)return i.slice(a+d)}else o>h&&(47===e.charCodeAt(s+d)?c=d:0===d&&(c=0));break}var u=e.charCodeAt(s+d);if(u!==i.charCodeAt(a+d))break;47===u&&(c=d)}var p="";for(d=s+c+1;d<=r;++d)d!==r&&47!==e.charCodeAt(d)||(0===p.length?p+="..":p+="/..");return p.length>0?p+i.slice(a+c):(a+=c,47===i.charCodeAt(a)&&++a,i.slice(a))},_makeLong:function(e){return e},dirname:function(e){if(t(e),0===e.length)return".";for(var i=e.charCodeAt(0),n=47===i,s=-1,r=!0,o=e.length-1;o>=1;--o)if(47===(i=e.charCodeAt(o))){if(!r){s=o;break}}else r=!1;return-1===s?n?"/":".":n&&1===s?"//":e.slice(0,s)},basename:function(e,i){if(void 0!==i&&"string"!=typeof i)throw new TypeError('"ext" argument must be a string');t(e);var n,s=0,r=-1,o=!0;if(void 0!==i&&i.length>0&&i.length<=e.length){if(i.length===e.length&&i===e)return"";var a=i.length-1,l=-1;for(n=e.length-1;n>=0;--n){var h=e.charCodeAt(n);if(47===h){if(!o){s=n+1;break}}else-1===l&&(o=!1,l=n+1),a>=0&&(h===i.charCodeAt(a)?-1==--a&&(r=n):(a=-1,r=l))}return s===r?r=l:-1===r&&(r=e.length),e.slice(s,r)}for(n=e.length-1;n>=0;--n)if(47===e.charCodeAt(n)){if(!o){s=n+1;break}}else-1===r&&(o=!1,r=n+1);return-1===r?"":e.slice(s,r)},extname:function(e){t(e);for(var i=-1,n=0,s=-1,r=!0,o=0,a=e.length-1;a>=0;--a){var l=e.charCodeAt(a);if(47!==l)-1===s&&(r=!1,s=a+1),46===l?-1===i?i=a:1!==o&&(o=1):-1!==i&&(o=-1);else if(!r){n=a+1;break}}return-1===i||-1===s||0===o||1===o&&i===s-1&&i===n+1?"":e.slice(i,s)},format:function(e){if(null===e||"object"!=typeof e)throw new TypeError('The "pathObject" argument must be of type Object. Received type '+typeof e);return function(e,t){var i=t.dir||t.root,n=t.base||(t.name||"")+(t.ext||"");return i?i===t.root?i+n:i+"/"+n:n}(0,e)},parse:function(e){t(e);var i={root:"",dir:"",base:"",ext:"",name:""};if(0===e.length)return i;var n,s=e.charCodeAt(0),r=47===s;r?(i.root="/",n=1):n=0;for(var o=-1,a=0,l=-1,h=!0,c=e.length-1,d=0;c>=n;--c)if(47!==(s=e.charCodeAt(c)))-1===l&&(h=!1,l=c+1),46===s?-1===o?o=c:1!==d&&(d=1):-1!==o&&(d=-1);else if(!h){a=c+1;break}return-1===o||-1===l||0===d||1===d&&o===l-1&&o===a+1?-1!==l&&(i.base=i.name=0===a&&r?e.slice(1,l):e.slice(a,l)):(0===a&&r?(i.name=e.slice(1,o),i.base=e.slice(1,l)):(i.name=e.slice(a,o),i.base=e.slice(a,l)),i.ext=e.slice(o,l)),a>0?i.dir=e.slice(0,a-1):r&&(i.dir="/"),i},sep:"/",delimiter:":",win32:null,posix:null};n.posix=n,e.exports=n},1435:e=>{var t=String,i=function(){return{isColorSupported:!1,reset:t,bold:t,dim:t,italic:t,underline:t,inverse:t,hidden:t,strikethrough:t,black:t,red:t,green:t,yellow:t,blue:t,magenta:t,cyan:t,white:t,gray:t,bgBlack:t,bgRed:t,bgGreen:t,bgYellow:t,bgBlue:t,bgMagenta:t,bgCyan:t,bgWhite:t}};e.exports=i(),e.exports.createColors=i},7983:(e,t,i)=>{"use strict";let n=i(9930);class s extends n{constructor(e){super(e),this.type="atrule"}append(...e){return this.proxyOf.nodes||(this.nodes=[]),super.append(...e)}prepend(...e){return this.proxyOf.nodes||(this.nodes=[]),super.prepend(...e)}}e.exports=s,s.default=s,n.registerAtRule(s)},1044:(e,t,i)=>{"use strict";let n=i(322);class s extends n{constructor(e){super(e),this.type="comment"}}e.exports=s,s.default=s},9930:(e,t,i)=>{"use strict";let n,s,r,o,{isClean:a,my:l}=i(2450),h=i(9026),c=i(1044),d=i(322);function u(e){return e.map((e=>(e.nodes&&(e.nodes=u(e.nodes)),delete e.source,e)))}function p(e){if(e[a]=!1,e.proxyOf.nodes)for(let t of e.proxyOf.nodes)p(t)}class f extends d{append(...e){for(let t of e){let e=this.normalize(t,this.last);for(let t of e)this.proxyOf.nodes.push(t)}return this.markDirty(),this}cleanRaws(e){if(super.cleanRaws(e),this.nodes)for(let t of this.nodes)t.cleanRaws(e)}each(e){if(!this.proxyOf.nodes)return;let t,i,n=this.getIterator();for(;this.indexes[n]"proxyOf"===t?e:e[t]?"each"===t||"string"==typeof t&&t.startsWith("walk")?(...i)=>e[t](...i.map((e=>"function"==typeof e?(t,i)=>e(t.toProxy(),i):e))):"every"===t||"some"===t?i=>e[t](((e,...t)=>i(e.toProxy(),...t))):"root"===t?()=>e.root().toProxy():"nodes"===t?e.nodes.map((e=>e.toProxy())):"first"===t||"last"===t?e[t].toProxy():e[t]:e[t],set:(e,t,i)=>(e[t]===i||(e[t]=i,"name"!==t&&"params"!==t&&"selector"!==t||e.markDirty()),!0)}}index(e){return"number"==typeof e?e:(e.proxyOf&&(e=e.proxyOf),this.proxyOf.nodes.indexOf(e))}insertAfter(e,t){let i,n=this.index(e),s=this.normalize(t,this.proxyOf.nodes[n]).reverse();n=this.index(e);for(let e of s)this.proxyOf.nodes.splice(n+1,0,e);for(let e in this.indexes)i=this.indexes[e],n(e[l]||f.rebuild(e),(e=e.proxyOf).parent&&e.parent.removeChild(e),e[a]&&p(e),void 0===e.raws.before&&t&&void 0!==t.raws.before&&(e.raws.before=t.raws.before.replace(/\S/g,"")),e.parent=this.proxyOf,e)))}prepend(...e){e=e.reverse();for(let t of e){let e=this.normalize(t,this.first,"prepend").reverse();for(let t of e)this.proxyOf.nodes.unshift(t);for(let t in this.indexes)this.indexes[t]=this.indexes[t]+e.length}return this.markDirty(),this}push(e){return e.parent=this,this.proxyOf.nodes.push(e),this}removeAll(){for(let e of this.proxyOf.nodes)e.parent=void 0;return this.proxyOf.nodes=[],this.markDirty(),this}removeChild(e){let t;e=this.index(e),this.proxyOf.nodes[e].parent=void 0,this.proxyOf.nodes.splice(e,1);for(let i in this.indexes)t=this.indexes[i],t>=e&&(this.indexes[i]=t-1);return this.markDirty(),this}replaceValues(e,t,i){return i||(i=t,t={}),this.walkDecls((n=>{t.props&&!t.props.includes(n.prop)||t.fast&&!n.value.includes(t.fast)||(n.value=n.value.replace(e,i))})),this.markDirty(),this}some(e){return this.nodes.some(e)}walk(e){return this.each(((t,i)=>{let n;try{n=e(t,i)}catch(e){throw t.addToError(e)}return!1!==n&&t.walk&&(n=t.walk(e)),n}))}walkAtRules(e,t){return t?e instanceof RegExp?this.walk(((i,n)=>{if("atrule"===i.type&&e.test(i.name))return t(i,n)})):this.walk(((i,n)=>{if("atrule"===i.type&&i.name===e)return t(i,n)})):(t=e,this.walk(((e,i)=>{if("atrule"===e.type)return t(e,i)})))}walkComments(e){return this.walk(((t,i)=>{if("comment"===t.type)return e(t,i)}))}walkDecls(e,t){return t?e instanceof RegExp?this.walk(((i,n)=>{if("decl"===i.type&&e.test(i.prop))return t(i,n)})):this.walk(((i,n)=>{if("decl"===i.type&&i.prop===e)return t(i,n)})):(t=e,this.walk(((e,i)=>{if("decl"===e.type)return t(e,i)})))}walkRules(e,t){return t?e instanceof RegExp?this.walk(((i,n)=>{if("rule"===i.type&&e.test(i.selector))return t(i,n)})):this.walk(((i,n)=>{if("rule"===i.type&&i.selector===e)return t(i,n)})):(t=e,this.walk(((e,i)=>{if("rule"===e.type)return t(e,i)})))}get first(){if(this.proxyOf.nodes)return this.proxyOf.nodes[0]}get last(){if(this.proxyOf.nodes)return this.proxyOf.nodes[this.proxyOf.nodes.length-1]}}f.registerParse=e=>{n=e},f.registerRule=e=>{s=e},f.registerAtRule=e=>{r=e},f.registerRoot=e=>{o=e},e.exports=f,f.default=f,f.rebuild=e=>{"atrule"===e.type?Object.setPrototypeOf(e,r.prototype):"rule"===e.type?Object.setPrototypeOf(e,s.prototype):"decl"===e.type?Object.setPrototypeOf(e,h.prototype):"comment"===e.type?Object.setPrototypeOf(e,c.prototype):"root"===e.type&&Object.setPrototypeOf(e,o.prototype),e[l]=!0,e.nodes&&e.nodes.forEach((e=>{f.rebuild(e)}))}},2604:(e,t,i)=>{"use strict";let n=i(1435),s=i(2940);class r extends Error{constructor(e,t,i,n,s,o){super(e),this.name="CssSyntaxError",this.reason=e,s&&(this.file=s),n&&(this.source=n),o&&(this.plugin=o),void 0!==t&&void 0!==i&&("number"==typeof t?(this.line=t,this.column=i):(this.line=t.line,this.column=t.column,this.endLine=i.line,this.endColumn=i.column)),this.setMessage(),Error.captureStackTrace&&Error.captureStackTrace(this,r)}setMessage(){this.message=this.plugin?this.plugin+": ":"",this.message+=this.file?this.file:"",void 0!==this.line&&(this.message+=":"+this.line+":"+this.column),this.message+=": "+this.reason}showSourceCode(e){if(!this.source)return"";let t=this.source;null==e&&(e=n.isColorSupported),s&&e&&(t=s(t));let i,r,o=t.split(/\r?\n/),a=Math.max(this.line-3,0),l=Math.min(this.line+2,o.length),h=String(l).length;if(e){let{bold:e,gray:t,red:s}=n.createColors(!0);i=t=>e(s(t)),r=e=>t(e)}else i=r=e=>e;return o.slice(a,l).map(((e,t)=>{let n=a+1+t,s=" "+(" "+n).slice(-h)+" | ";if(n===this.line){let t=r(s.replace(/\d/g," "))+e.slice(0,this.column-1).replace(/[^\t]/g," ");return i(">")+r(s)+e+"\n "+t+i("^")}return" "+r(s)+e})).join("\n")}toString(){let e=this.showSourceCode();return e&&(e="\n\n"+e+"\n"),this.name+": "+this.message+e}}e.exports=r,r.default=r},9026:(e,t,i)=>{"use strict";let n=i(322);class s extends n{constructor(e){e&&void 0!==e.value&&"string"!=typeof e.value&&(e={...e,value:String(e.value)}),super(e),this.type="decl"}get variable(){return this.prop.startsWith("--")||"$"===this.prop[0]}}e.exports=s,s.default=s},2900:(e,t,i)=>{"use strict";let n,s,r=i(9930);class o extends r{constructor(e){super({type:"document",...e}),this.nodes||(this.nodes=[])}toResult(e={}){return new n(new s,this,e).stringify()}}o.registerLazyResult=e=>{n=e},o.registerProcessor=e=>{s=e},e.exports=o,o.default=o},4899:(e,t,i)=>{"use strict";let n=i(9026),s=i(2764),r=i(1044),o=i(7983),a=i(6970),l=i(4539),h=i(4146);function c(e,t){if(Array.isArray(e))return e.map((e=>c(e)));let{inputs:i,...d}=e;if(i){t=[];for(let e of i){let i={...e,__proto__:a.prototype};i.map&&(i.map={...i.map,__proto__:s.prototype}),t.push(i)}}if(d.nodes&&(d.nodes=e.nodes.map((e=>c(e,t)))),d.source){let{inputId:e,...i}=d.source;d.source=i,null!=e&&(d.source.input=t[e])}if("root"===d.type)return new l(d);if("decl"===d.type)return new n(d);if("rule"===d.type)return new h(d);if("comment"===d.type)return new r(d);if("atrule"===d.type)return new o(d);throw new Error("Unknown node type: "+e.type)}e.exports=c,c.default=c},6970:(e,t,i)=>{"use strict";let{SourceMapConsumer:n,SourceMapGenerator:s}=i(9059),{fileURLToPath:r,pathToFileURL:o}=i(415),{isAbsolute:a,resolve:l}=i(2666),{nanoid:h}=i(8845),c=i(2940),d=i(2604),u=i(2764),p=Symbol("fromOffsetCache"),f=Boolean(n&&s),m=Boolean(l&&a);class g{constructor(e,t={}){if(null==e||"object"==typeof e&&!e.toString)throw new Error(`PostCSS received ${e} instead of CSS string`);if(this.css=e.toString(),"\ufeff"===this.css[0]||"￾"===this.css[0]?(this.hasBOM=!0,this.css=this.css.slice(1)):this.hasBOM=!1,t.from&&(!m||/^\w+:\/\//.test(t.from)||a(t.from)?this.file=t.from:this.file=l(t.from)),m&&f){let e=new u(this.css,t);if(e.text){this.map=e;let t=e.consumer().file;!this.file&&t&&(this.file=this.mapResolve(t))}}this.file||(this.id=""),this.map&&(this.map.file=this.from)}error(e,t,i,n={}){let s,r,a;if(t&&"object"==typeof t){let e=t,n=i;if("number"==typeof e.offset){let n=this.fromOffset(e.offset);t=n.line,i=n.col}else t=e.line,i=e.column;if("number"==typeof n.offset){let e=this.fromOffset(n.offset);r=e.line,a=e.col}else r=n.line,a=n.column}else if(!i){let e=this.fromOffset(t);t=e.line,i=e.col}let l=this.origin(t,i,r,a);return s=l?new d(e,void 0===l.endLine?l.line:{column:l.column,line:l.line},void 0===l.endLine?l.column:{column:l.endColumn,line:l.endLine},l.source,l.file,n.plugin):new d(e,void 0===r?t:{column:i,line:t},void 0===r?i:{column:a,line:r},this.css,this.file,n.plugin),s.input={column:i,endColumn:a,endLine:r,line:t,source:this.css},this.file&&(o&&(s.input.url=o(this.file).toString()),s.input.file=this.file),s}fromOffset(e){let t,i;if(this[p])i=this[p];else{let e=this.css.split("\n");i=new Array(e.length);let t=0;for(let n=0,s=e.length;n=t)n=i.length-1;else{let t,s=i.length-2;for(;n>1),e=i[t+1])){n=t;break}n=t+1}}return{col:e-i[n]+1,line:n+1}}mapResolve(e){return/^\w+:\/\//.test(e)?e:l(this.map.consumer().sourceRoot||this.map.root||".",e)}origin(e,t,i,n){if(!this.map)return!1;let s,l,h=this.map.consumer(),c=h.originalPositionFor({column:t,line:e});if(!c.source)return!1;"number"==typeof i&&(s=h.originalPositionFor({column:n,line:i})),l=a(c.source)?o(c.source):new URL(c.source,this.map.consumer().sourceRoot||o(this.map.mapFile));let d={column:c.column,endColumn:s&&s.column,endLine:s&&s.line,line:c.line,url:l.toString()};if("file:"===l.protocol){if(!r)throw new Error("file: protocol is not available in this PostCSS build");d.file=r(l)}let u=h.sourceContentFor(c.source);return u&&(d.source=u),d}toJSON(){let e={};for(let t of["hasBOM","css","file","id"])null!=this[t]&&(e[t]=this[t]);return this.map&&(e.map={...this.map},e.map.consumerCache&&(e.map.consumerCache=void 0)),e}get from(){return this.file||this.id}}e.exports=g,g.default=g,c&&c.registerInput&&c.registerInput(g)},427:(e,t,i)=>{"use strict";let{isClean:n,my:s}=i(2450),r=i(4342),o=i(9573),a=i(9930),l=i(2900),h=(i(5411),i(165)),c=i(6214),d=i(4539);const u={atrule:"AtRule",comment:"Comment",decl:"Declaration",document:"Document",root:"Root",rule:"Rule"},p={AtRule:!0,AtRuleExit:!0,Comment:!0,CommentExit:!0,Declaration:!0,DeclarationExit:!0,Document:!0,DocumentExit:!0,Once:!0,OnceExit:!0,postcssPlugin:!0,prepare:!0,Root:!0,RootExit:!0,Rule:!0,RuleExit:!0},f={Once:!0,postcssPlugin:!0,prepare:!0},m=0;function g(e){return"object"==typeof e&&"function"==typeof e.then}function v(e){let t=!1,i=u[e.type];return"decl"===e.type?t=e.prop.toLowerCase():"atrule"===e.type&&(t=e.name.toLowerCase()),t&&e.append?[i,i+"-"+t,m,i+"Exit",i+"Exit-"+t]:t?[i,i+"-"+t,i+"Exit",i+"Exit-"+t]:e.append?[i,m,i+"Exit"]:[i,i+"Exit"]}function O(e){let t;return t="document"===e.type?["Document",m,"DocumentExit"]:"root"===e.type?["Root",m,"RootExit"]:v(e),{eventIndex:0,events:t,iterator:0,node:e,visitorIndex:0,visitors:[]}}function b(e){return e[n]=!1,e.nodes&&e.nodes.forEach((e=>b(e))),e}let _={};class y{constructor(e,t,i){let n;if(this.stringified=!1,this.processed=!1,"object"!=typeof t||null===t||"root"!==t.type&&"document"!==t.type)if(t instanceof y||t instanceof h)n=b(t.root),t.map&&(void 0===i.map&&(i.map={}),i.map.inline||(i.map.inline=!1),i.map.prev=t.map);else{let e=c;i.syntax&&(e=i.syntax.parse),i.parser&&(e=i.parser),e.parse&&(e=e.parse);try{n=e(t,i)}catch(e){this.processed=!0,this.error=e}n&&!n[s]&&a.rebuild(n)}else n=b(t);this.result=new h(e,n,i),this.helpers={..._,postcss:_,result:this.result},this.plugins=this.processor.plugins.map((e=>"object"==typeof e&&e.prepare?{...e,...e.prepare(this.result)}:e))}async(){return this.error?Promise.reject(this.error):this.processed?Promise.resolve(this.result):(this.processing||(this.processing=this.runAsync()),this.processing)}catch(e){return this.async().catch(e)}finally(e){return this.async().then(e,e)}getAsyncError(){throw new Error("Use process(css).then(cb) to work with async plugins")}handleError(e,t){let i=this.result.lastPlugin;try{t&&t.addToError(e),this.error=e,"CssSyntaxError"!==e.name||e.plugin?i.postcssVersion:(e.plugin=i.postcssPlugin,e.setMessage())}catch(e){console&&console.error&&console.error(e)}return e}prepareVisitors(){this.listeners={};let e=(e,t,i)=>{this.listeners[t]||(this.listeners[t]=[]),this.listeners[t].push([e,i])};for(let t of this.plugins)if("object"==typeof t)for(let i in t){if(!p[i]&&/^[A-Z]/.test(i))throw new Error(`Unknown event ${i} in ${t.postcssPlugin}. Try to update PostCSS (${this.processor.version} now).`);if(!f[i])if("object"==typeof t[i])for(let n in t[i])e(t,"*"===n?i:i+"-"+n.toLowerCase(),t[i][n]);else"function"==typeof t[i]&&e(t,i,t[i])}this.hasListener=Object.keys(this.listeners).length>0}async runAsync(){this.plugin=0;for(let e=0;e0;){let e=this.visitTick(t);if(g(e))try{await e}catch(e){let i=t[t.length-1].node;throw this.handleError(e,i)}}}if(this.listeners.OnceExit)for(let[t,i]of this.listeners.OnceExit){this.result.lastPlugin=t;try{if("document"===e.type){let t=e.nodes.map((e=>i(e,this.helpers)));await Promise.all(t)}else await i(e,this.helpers)}catch(e){throw this.handleError(e)}}}return this.processed=!0,this.stringify()}runOnRoot(e){this.result.lastPlugin=e;try{if("object"==typeof e&&e.Once){if("document"===this.result.root.type){let t=this.result.root.nodes.map((t=>e.Once(t,this.helpers)));return g(t[0])?Promise.all(t):t}return e.Once(this.result.root,this.helpers)}if("function"==typeof e)return e(this.result.root,this.result)}catch(e){throw this.handleError(e)}}stringify(){if(this.error)throw this.error;if(this.stringified)return this.result;this.stringified=!0,this.sync();let e=this.result.opts,t=o;e.syntax&&(t=e.syntax.stringify),e.stringifier&&(t=e.stringifier),t.stringify&&(t=t.stringify);let i=new r(t,this.result.root,this.result.opts).generate();return this.result.css=i[0],this.result.map=i[1],this.result}sync(){if(this.error)throw this.error;if(this.processed)return this.result;if(this.processed=!0,this.processing)throw this.getAsyncError();for(let e of this.plugins)if(g(this.runOnRoot(e)))throw this.getAsyncError();if(this.prepareVisitors(),this.hasListener){let e=this.result.root;for(;!e[n];)e[n]=!0,this.walkSync(e);if(this.listeners.OnceExit)if("document"===e.type)for(let t of e.nodes)this.visitSync(this.listeners.OnceExit,t);else this.visitSync(this.listeners.OnceExit,e)}return this.result}then(e,t){return this.async().then(e,t)}toString(){return this.css}visitSync(e,t){for(let[i,n]of e){let e;this.result.lastPlugin=i;try{e=n(t,this.helpers)}catch(e){throw this.handleError(e,t.proxyOf)}if("root"!==t.type&&"document"!==t.type&&!t.parent)return!0;if(g(e))throw this.getAsyncError()}}visitTick(e){let t=e[e.length-1],{node:i,visitors:s}=t;if("root"!==i.type&&"document"!==i.type&&!i.parent)return void e.pop();if(s.length>0&&t.visitorIndex{e[n]||this.walkSync(e)}));else{let t=this.listeners[i];if(t&&this.visitSync(t,e.toProxy()))return}}warnings(){return this.sync().warnings()}get content(){return this.stringify().content}get css(){return this.stringify().css}get map(){return this.stringify().map}get messages(){return this.sync().messages}get opts(){return this.result.opts}get processor(){return this.result.processor}get root(){return this.sync().root}get[Symbol.toStringTag](){return"LazyResult"}}y.registerPostcss=e=>{_=e},e.exports=y,y.default=y,d.registerLazyResult(y),l.registerLazyResult(y)},6065:e=>{"use strict";let t={comma:e=>t.split(e,[","],!0),space:e=>t.split(e,[" ","\n","\t"]),split(e,t,i){let n=[],s="",r=!1,o=0,a=!1,l="",h=!1;for(let i of e)h?h=!1:"\\"===i?h=!0:a?i===l&&(a=!1):'"'===i||"'"===i?(a=!0,l=i):"("===i?o+=1:")"===i?o>0&&(o-=1):0===o&&t.includes(i)&&(r=!0),r?(""!==s&&n.push(s.trim()),s="",r=!1):s+=i;return(i||""!==s)&&n.push(s.trim()),n}};e.exports=t,t.default=t},4342:(e,t,i)=>{"use strict";let{SourceMapConsumer:n,SourceMapGenerator:s}=i(9059),{dirname:r,relative:o,resolve:a,sep:l}=i(2666),{pathToFileURL:h}=i(415),c=i(6970),d=Boolean(n&&s),u=Boolean(r&&a&&o&&l);e.exports=class{constructor(e,t,i,n){this.stringify=e,this.mapOpts=i.map||{},this.root=t,this.opts=i,this.css=n,this.usesFileUrls=!this.mapOpts.from&&this.mapOpts.absolute,this.memoizedFileURLs=new Map,this.memoizedPaths=new Map,this.memoizedURLs=new Map}addAnnotation(){let e;e=this.isInline()?"data:application/json;base64,"+this.toBase64(this.map.toString()):"string"==typeof this.mapOpts.annotation?this.mapOpts.annotation:"function"==typeof this.mapOpts.annotation?this.mapOpts.annotation(this.opts.to,this.root):this.outputFile()+".map";let t="\n";this.css.includes("\r\n")&&(t="\r\n"),this.css+=t+"/*# sourceMappingURL="+e+" */"}applyPrevMaps(){for(let e of this.previous()){let t,i=this.toUrl(this.path(e.file)),s=e.root||r(e.file);!1===this.mapOpts.sourcesContent?(t=new n(e.text),t.sourcesContent&&(t.sourcesContent=t.sourcesContent.map((()=>null)))):t=e.consumer(),this.map.applySourceMap(t,i,this.toUrl(this.path(s)))}}clearAnnotation(){if(!1!==this.mapOpts.annotation)if(this.root){let e;for(let t=this.root.nodes.length-1;t>=0;t--)e=this.root.nodes[t],"comment"===e.type&&0===e.text.indexOf("# sourceMappingURL=")&&this.root.removeChild(t)}else this.css&&(this.css=this.css.replace(/(\n)?\/\*#[\S\s]*?\*\/$/gm,""))}generate(){if(this.clearAnnotation(),u&&d&&this.isMap())return this.generateMap();{let e="";return this.stringify(this.root,(t=>{e+=t})),[e]}}generateMap(){if(this.root)this.generateString();else if(1===this.previous().length){let e=this.previous()[0].consumer();e.file=this.outputFile(),this.map=s.fromSourceMap(e)}else this.map=new s({file:this.outputFile()}),this.map.addMapping({generated:{column:0,line:1},original:{column:0,line:1},source:this.opts.from?this.toUrl(this.path(this.opts.from)):""});return this.isSourcesContent()&&this.setSourcesContent(),this.root&&this.previous().length>0&&this.applyPrevMaps(),this.isAnnotation()&&this.addAnnotation(),this.isInline()?[this.css]:[this.css,this.map]}generateString(){this.css="",this.map=new s({file:this.outputFile()});let e,t,i=1,n=1,r="",o={generated:{column:0,line:0},original:{column:0,line:0},source:""};this.stringify(this.root,((s,a,l)=>{if(this.css+=s,a&&"end"!==l&&(o.generated.line=i,o.generated.column=n-1,a.source&&a.source.start?(o.source=this.sourcePath(a),o.original.line=a.source.start.line,o.original.column=a.source.start.column-1,this.map.addMapping(o)):(o.source=r,o.original.line=1,o.original.column=0,this.map.addMapping(o))),e=s.match(/\n/g),e?(i+=e.length,t=s.lastIndexOf("\n"),n=s.length-t):n+=s.length,a&&"start"!==l){let e=a.parent||{raws:{}};("decl"===a.type||"atrule"===a.type&&!a.nodes)&&a===e.last&&!e.raws.semicolon||(a.source&&a.source.end?(o.source=this.sourcePath(a),o.original.line=a.source.end.line,o.original.column=a.source.end.column-1,o.generated.line=i,o.generated.column=n-2,this.map.addMapping(o)):(o.source=r,o.original.line=1,o.original.column=0,o.generated.line=i,o.generated.column=n-1,this.map.addMapping(o)))}}))}isAnnotation(){return!!this.isInline()||(void 0!==this.mapOpts.annotation?this.mapOpts.annotation:!this.previous().length||this.previous().some((e=>e.annotation)))}isInline(){if(void 0!==this.mapOpts.inline)return this.mapOpts.inline;let e=this.mapOpts.annotation;return(void 0===e||!0===e)&&(!this.previous().length||this.previous().some((e=>e.inline)))}isMap(){return void 0!==this.opts.map?!!this.opts.map:this.previous().length>0}isSourcesContent(){return void 0!==this.mapOpts.sourcesContent?this.mapOpts.sourcesContent:!this.previous().length||this.previous().some((e=>e.withContent()))}outputFile(){return this.opts.to?this.path(this.opts.to):this.opts.from?this.path(this.opts.from):"to.css"}path(e){if(this.mapOpts.absolute)return e;if(60===e.charCodeAt(0))return e;if(/^\w+:\/\//.test(e))return e;let t=this.memoizedPaths.get(e);if(t)return t;let i=this.opts.to?r(this.opts.to):".";"string"==typeof this.mapOpts.annotation&&(i=r(a(i,this.mapOpts.annotation)));let n=o(i,e);return this.memoizedPaths.set(e,n),n}previous(){if(!this.previousMaps)if(this.previousMaps=[],this.root)this.root.walk((e=>{if(e.source&&e.source.input.map){let t=e.source.input.map;this.previousMaps.includes(t)||this.previousMaps.push(t)}}));else{let e=new c(this.css,this.opts);e.map&&this.previousMaps.push(e.map)}return this.previousMaps}setSourcesContent(){let e={};if(this.root)this.root.walk((t=>{if(t.source){let i=t.source.input.from;if(i&&!e[i]){e[i]=!0;let n=this.usesFileUrls?this.toFileUrl(i):this.toUrl(this.path(i));this.map.setSourceContent(n,t.source.input.css)}}}));else if(this.css){let e=this.opts.from?this.toUrl(this.path(this.opts.from)):"";this.map.setSourceContent(e,this.css)}}sourcePath(e){return this.mapOpts.from?this.toUrl(this.mapOpts.from):this.usesFileUrls?this.toFileUrl(e.source.input.from):this.toUrl(this.path(e.source.input.from))}toBase64(e){return Buffer?Buffer.from(e).toString("base64"):window.btoa(unescape(encodeURIComponent(e)))}toFileUrl(e){let t=this.memoizedFileURLs.get(e);if(t)return t;if(h){let t=h(e).toString();return this.memoizedFileURLs.set(e,t),t}throw new Error("`map.absolute` option is not available in this PostCSS build")}toUrl(e){let t=this.memoizedURLs.get(e);if(t)return t;"\\"===l&&(e=e.replace(/\\/g,"/"));let i=encodeURI(e).replace(/[#?]/g,encodeURIComponent);return this.memoizedURLs.set(e,i),i}}},7744:(e,t,i)=>{"use strict";let n=i(4342),s=i(9573),r=(i(5411),i(6214));const o=i(165);class a{constructor(e,t,i){let r;t=t.toString(),this.stringified=!1,this._processor=e,this._css=t,this._opts=i,this._map=void 0;let a=s;this.result=new o(this._processor,r,this._opts),this.result.css=t;let l=this;Object.defineProperty(this.result,"root",{get:()=>l.root});let h=new n(a,r,this._opts,t);if(h.isMap()){let[e,t]=h.generate();e&&(this.result.css=e),t&&(this.result.map=t)}}async(){return this.error?Promise.reject(this.error):Promise.resolve(this.result)}catch(e){return this.async().catch(e)}finally(e){return this.async().then(e,e)}sync(){if(this.error)throw this.error;return this.result}then(e,t){return this.async().then(e,t)}toString(){return this._css}warnings(){return[]}get content(){return this.result.css}get css(){return this.result.css}get map(){return this.result.map}get messages(){return[]}get opts(){return this.result.opts}get processor(){return this.result.processor}get root(){if(this._root)return this._root;let e,t=r;try{e=t(this._css,this._opts)}catch(e){this.error=e}if(this.error)throw this.error;return this._root=e,e}get[Symbol.toStringTag](){return"NoWorkResult"}}e.exports=a,a.default=a},322:(e,t,i)=>{"use strict";let{isClean:n,my:s}=i(2450),r=i(2604),o=i(9906),a=i(9573);function l(e,t){let i=new e.constructor;for(let n in e){if(!Object.prototype.hasOwnProperty.call(e,n))continue;if("proxyCache"===n)continue;let s=e[n],r=typeof s;"parent"===n&&"object"===r?t&&(i[n]=t):"source"===n?i[n]=s:Array.isArray(s)?i[n]=s.map((e=>l(e,i))):("object"===r&&null!==s&&(s=l(s)),i[n]=s)}return i}class h{constructor(e={}){this.raws={},this[n]=!1,this[s]=!0;for(let t in e)if("nodes"===t){this.nodes=[];for(let i of e[t])"function"==typeof i.clone?this.append(i.clone()):this.append(i)}else this[t]=e[t]}addToError(e){if(e.postcssNode=this,e.stack&&this.source&&/\n\s{4}at /.test(e.stack)){let t=this.source;e.stack=e.stack.replace(/\n\s{4}at /,`$&${t.input.from}:${t.start.line}:${t.start.column}$&`)}return e}after(e){return this.parent.insertAfter(this,e),this}assign(e={}){for(let t in e)this[t]=e[t];return this}before(e){return this.parent.insertBefore(this,e),this}cleanRaws(e){delete this.raws.before,delete this.raws.after,e||delete this.raws.between}clone(e={}){let t=l(this);for(let i in e)t[i]=e[i];return t}cloneAfter(e={}){let t=this.clone(e);return this.parent.insertAfter(this,t),t}cloneBefore(e={}){let t=this.clone(e);return this.parent.insertBefore(this,t),t}error(e,t={}){if(this.source){let{end:i,start:n}=this.rangeBy(t);return this.source.input.error(e,{column:n.column,line:n.line},{column:i.column,line:i.line},t)}return new r(e)}getProxyProcessor(){return{get:(e,t)=>"proxyOf"===t?e:"root"===t?()=>e.root().toProxy():e[t],set:(e,t,i)=>(e[t]===i||(e[t]=i,"prop"!==t&&"value"!==t&&"name"!==t&&"params"!==t&&"important"!==t&&"text"!==t||e.markDirty()),!0)}}markDirty(){if(this[n]){this[n]=!1;let e=this;for(;e=e.parent;)e[n]=!1}}next(){if(!this.parent)return;let e=this.parent.index(this);return this.parent.nodes[e+1]}positionBy(e,t){let i=this.source.start;if(e.index)i=this.positionInside(e.index,t);else if(e.word){let n=(t=this.toString()).indexOf(e.word);-1!==n&&(i=this.positionInside(n,t))}return i}positionInside(e,t){let i=t||this.toString(),n=this.source.start.column,s=this.source.start.line;for(let t=0;t"object"==typeof e&&e.toJSON?e.toJSON(null,t):e));else if("object"==typeof n&&n.toJSON)i[e]=n.toJSON(null,t);else if("source"===e){let r=t.get(n.input);null==r&&(r=s,t.set(n.input,s),s++),i[e]={end:n.end,inputId:r,start:n.start}}else i[e]=n}return n&&(i.inputs=[...t.keys()].map((e=>e.toJSON()))),i}toProxy(){return this.proxyCache||(this.proxyCache=new Proxy(this,this.getProxyProcessor())),this.proxyCache}toString(e=a){e.stringify&&(e=e.stringify);let t="";return e(this,(e=>{t+=e})),t}warn(e,t,i){let n={node:this};for(let e in i)n[e]=i[e];return e.warn(t,n)}get proxyOf(){return this}}e.exports=h,h.default=h},6214:(e,t,i)=>{"use strict";let n=i(9930),s=i(6992),r=i(6970);function o(e,t){let i=new r(e,t),n=new s(i);try{n.parse()}catch(e){throw e}return n.root}e.exports=o,o.default=o,n.registerParse(o)},6992:(e,t,i)=>{"use strict";let n=i(9026),s=i(9985),r=i(1044),o=i(7983),a=i(4539),l=i(4146);const h={empty:!0,space:!0};e.exports=class{constructor(e){this.input=e,this.root=new a,this.current=this.root,this.spaces="",this.semicolon=!1,this.customProperty=!1,this.createTokenizer(),this.root.source={input:e,start:{column:1,line:1,offset:0}}}atrule(e){let t,i,n,s=new o;s.name=e[1].slice(1),""===s.name&&this.unnamedAtrule(s,e),this.init(s,e[2]);let r=!1,a=!1,l=[],h=[];for(;!this.tokenizer.endOfFile();){if(t=(e=this.tokenizer.nextToken())[0],"("===t||"["===t?h.push("("===t?")":"]"):"{"===t&&h.length>0?h.push("}"):t===h[h.length-1]&&h.pop(),0===h.length){if(";"===t){s.source.end=this.getPosition(e[2]),s.source.end.offset++,this.semicolon=!0;break}if("{"===t){a=!0;break}if("}"===t){if(l.length>0){for(n=l.length-1,i=l[n];i&&"space"===i[0];)i=l[--n];i&&(s.source.end=this.getPosition(i[3]||i[2]),s.source.end.offset++)}this.end(e);break}l.push(e)}else l.push(e);if(this.tokenizer.endOfFile()){r=!0;break}}s.raws.between=this.spacesAndCommentsFromEnd(l),l.length?(s.raws.afterName=this.spacesAndCommentsFromStart(l),this.raw(s,"params",l),r&&(e=l[l.length-1],s.source.end=this.getPosition(e[3]||e[2]),s.source.end.offset++,this.spaces=s.raws.between,s.raws.between="")):(s.raws.afterName="",s.params=""),a&&(s.nodes=[],this.current=s)}checkMissedSemicolon(e){let t=this.colon(e);if(!1===t)return;let i,n=0;for(let s=t-1;s>=0&&(i=e[s],"space"===i[0]||(n+=1,2!==n));s--);throw this.input.error("Missed semicolon","word"===i[0]?i[3]+1:i[2])}colon(e){let t,i,n,s=0;for(let[r,o]of e.entries()){if(t=o,i=t[0],"("===i&&(s+=1),")"===i&&(s-=1),0===s&&":"===i){if(n){if("word"===n[0]&&"progid"===n[1])continue;return r}this.doubleColon(t)}n=t}return!1}comment(e){let t=new r;this.init(t,e[2]),t.source.end=this.getPosition(e[3]||e[2]),t.source.end.offset++;let i=e[1].slice(2,-2);if(/^\s*$/.test(i))t.text="",t.raws.left=i,t.raws.right="";else{let e=i.match(/^(\s*)([^]*\S)(\s*)$/);t.text=e[2],t.raws.left=e[1],t.raws.right=e[3]}}createTokenizer(){this.tokenizer=s(this.input)}decl(e,t){let i=new n;this.init(i,e[0][2]);let s,r=e[e.length-1];for(";"===r[0]&&(this.semicolon=!0,e.pop()),i.source.end=this.getPosition(r[3]||r[2]||function(e){for(let t=e.length-1;t>=0;t--){let i=e[t],n=i[3]||i[2];if(n)return n}}(e)),i.source.end.offset++;"word"!==e[0][0];)1===e.length&&this.unknownWord(e),i.raws.before+=e.shift()[1];for(i.source.start=this.getPosition(e[0][2]),i.prop="";e.length;){let t=e[0][0];if(":"===t||"space"===t||"comment"===t)break;i.prop+=e.shift()[1]}for(i.raws.between="";e.length;){if(s=e.shift(),":"===s[0]){i.raws.between+=s[1];break}"word"===s[0]&&/\w/.test(s[1])&&this.unknownWord([s]),i.raws.between+=s[1]}"_"!==i.prop[0]&&"*"!==i.prop[0]||(i.raws.before+=i.prop[0],i.prop=i.prop.slice(1));let o,a=[];for(;e.length&&(o=e[0][0],"space"===o||"comment"===o);)a.push(e.shift());this.precheckMissedSemicolon(e);for(let t=e.length-1;t>=0;t--){if(s=e[t],"!important"===s[1].toLowerCase()){i.important=!0;let n=this.stringFrom(e,t);n=this.spacesFromEnd(e)+n," !important"!==n&&(i.raws.important=n);break}if("important"===s[1].toLowerCase()){let n=e.slice(0),s="";for(let e=t;e>0;e--){let t=n[e][0];if(0===s.trim().indexOf("!")&&"space"!==t)break;s=n.pop()[1]+s}0===s.trim().indexOf("!")&&(i.important=!0,i.raws.important=s,e=n)}if("space"!==s[0]&&"comment"!==s[0])break}e.some((e=>"space"!==e[0]&&"comment"!==e[0]))&&(i.raws.between+=a.map((e=>e[1])).join(""),a=[]),this.raw(i,"value",a.concat(e),t),i.value.includes(":")&&!t&&this.checkMissedSemicolon(e)}doubleColon(e){throw this.input.error("Double colon",{offset:e[2]},{offset:e[2]+e[1].length})}emptyRule(e){let t=new l;this.init(t,e[2]),t.selector="",t.raws.between="",this.current=t}end(e){this.current.nodes&&this.current.nodes.length&&(this.current.raws.semicolon=this.semicolon),this.semicolon=!1,this.current.raws.after=(this.current.raws.after||"")+this.spaces,this.spaces="",this.current.parent?(this.current.source.end=this.getPosition(e[2]),this.current.source.end.offset++,this.current=this.current.parent):this.unexpectedClose(e)}endFile(){this.current.parent&&this.unclosedBlock(),this.current.nodes&&this.current.nodes.length&&(this.current.raws.semicolon=this.semicolon),this.current.raws.after=(this.current.raws.after||"")+this.spaces,this.root.source.end=this.getPosition(this.tokenizer.position())}freeSemicolon(e){if(this.spaces+=e[1],this.current.nodes){let e=this.current.nodes[this.current.nodes.length-1];e&&"rule"===e.type&&!e.raws.ownSemicolon&&(e.raws.ownSemicolon=this.spaces,this.spaces="")}}getPosition(e){let t=this.input.fromOffset(e);return{column:t.col,line:t.line,offset:e}}init(e,t){this.current.push(e),e.source={input:this.input,start:this.getPosition(t)},e.raws.before=this.spaces,this.spaces="","comment"!==e.type&&(this.semicolon=!1)}other(e){let t=!1,i=null,n=!1,s=null,r=[],o=e[1].startsWith("--"),a=[],l=e;for(;l;){if(i=l[0],a.push(l),"("===i||"["===i)s||(s=l),r.push("("===i?")":"]");else if(o&&n&&"{"===i)s||(s=l),r.push("}");else if(0===r.length){if(";"===i){if(n)return void this.decl(a,o);break}if("{"===i)return void this.rule(a);if("}"===i){this.tokenizer.back(a.pop()),t=!0;break}":"===i&&(n=!0)}else i===r[r.length-1]&&(r.pop(),0===r.length&&(s=null));l=this.tokenizer.nextToken()}if(this.tokenizer.endOfFile()&&(t=!0),r.length>0&&this.unclosedBracket(s),t&&n){if(!o)for(;a.length&&(l=a[a.length-1][0],"space"===l||"comment"===l);)this.tokenizer.back(a.pop());this.decl(a,o)}else this.unknownWord(a)}parse(){let e;for(;!this.tokenizer.endOfFile();)switch(e=this.tokenizer.nextToken(),e[0]){case"space":this.spaces+=e[1];break;case";":this.freeSemicolon(e);break;case"}":this.end(e);break;case"comment":this.comment(e);break;case"at-word":this.atrule(e);break;case"{":this.emptyRule(e);break;default:this.other(e)}this.endFile()}precheckMissedSemicolon(){}raw(e,t,i,n){let s,r,o,a,l=i.length,c="",d=!0;for(let e=0;ee+t[1]),"");e.raws[t]={raw:n,value:c}}e[t]=c}rule(e){e.pop();let t=new l;this.init(t,e[0][2]),t.raws.between=this.spacesAndCommentsFromEnd(e),this.raw(t,"selector",e),this.current=t}spacesAndCommentsFromEnd(e){let t,i="";for(;e.length&&(t=e[e.length-1][0],"space"===t||"comment"===t);)i=e.pop()[1]+i;return i}spacesAndCommentsFromStart(e){let t,i="";for(;e.length&&(t=e[0][0],"space"===t||"comment"===t);)i+=e.shift()[1];return i}spacesFromEnd(e){let t,i="";for(;e.length&&(t=e[e.length-1][0],"space"===t);)i=e.pop()[1]+i;return i}stringFrom(e,t){let i="";for(let n=t;n{"use strict";let n=i(2604),s=i(9026),r=i(427),o=i(9930),a=i(540),l=i(9573),h=i(4899),c=i(2900),d=i(860),u=i(1044),p=i(7983),f=i(165),m=i(6970),g=i(6214),v=i(6065),O=i(4146),b=i(4539),_=i(322);function y(...e){return 1===e.length&&Array.isArray(e[0])&&(e=e[0]),new a(e)}y.plugin=function(e,t){let i,n=!1;function s(...i){console&&console.warn&&!n&&(n=!0,console.warn(e+": postcss.plugin was deprecated. Migration guide:\nhttps://evilmartians.com/chronicles/postcss-8-plugin-migration"),{}.LANG&&{}.LANG.startsWith("cn")&&console.warn(e+": 里面 postcss.plugin 被弃用. 迁移指南:\nhttps://www.w3ctech.com/topic/2226"));let s=t(...i);return s.postcssPlugin=e,s.postcssVersion=(new a).version,s}return Object.defineProperty(s,"postcss",{get:()=>(i||(i=s()),i)}),s.process=function(e,t,i){return y([s(i)]).process(e,t)},s},y.stringify=l,y.parse=g,y.fromJSON=h,y.list=v,y.comment=e=>new u(e),y.atRule=e=>new p(e),y.decl=e=>new s(e),y.rule=e=>new O(e),y.root=e=>new b(e),y.document=e=>new c(e),y.CssSyntaxError=n,y.Declaration=s,y.Container=o,y.Processor=a,y.Document=c,y.Comment=u,y.Warning=d,y.AtRule=p,y.Result=f,y.Input=m,y.Rule=O,y.Root=b,y.Node=_,r.registerPostcss(y),e.exports=y,y.default=y},2764:(e,t,i)=>{"use strict";let{SourceMapConsumer:n,SourceMapGenerator:s}=i(9059),{existsSync:r,readFileSync:o}=i(1336),{dirname:a,join:l}=i(2666);class h{constructor(e,t){if(!1===t.map)return;this.loadAnnotation(e),this.inline=this.startWith(this.annotation,"data:");let i=t.map?t.map.prev:void 0,n=this.loadMap(t.from,i);!this.mapFile&&t.from&&(this.mapFile=t.from),this.mapFile&&(this.root=a(this.mapFile)),n&&(this.text=n)}consumer(){return this.consumerCache||(this.consumerCache=new n(this.text)),this.consumerCache}decodeInline(e){if(/^data:application\/json;charset=utf-?8,/.test(e)||/^data:application\/json,/.test(e))return decodeURIComponent(e.substr(RegExp.lastMatch.length));if(/^data:application\/json;charset=utf-?8;base64,/.test(e)||/^data:application\/json;base64,/.test(e))return t=e.substr(RegExp.lastMatch.length),Buffer?Buffer.from(t,"base64").toString():window.atob(t);var t;let i=e.match(/data:application\/json;([^,]+),/)[1];throw new Error("Unsupported source map encoding "+i)}getAnnotationURL(e){return e.replace(/^\/\*\s*# sourceMappingURL=/,"").trim()}isMap(e){return"object"==typeof e&&("string"==typeof e.mappings||"string"==typeof e._mappings||Array.isArray(e.sections))}loadAnnotation(e){let t=e.match(/\/\*\s*# sourceMappingURL=/gm);if(!t)return;let i=e.lastIndexOf(t.pop()),n=e.indexOf("*/",i);i>-1&&n>-1&&(this.annotation=this.getAnnotationURL(e.substring(i,n)))}loadFile(e){if(this.root=a(e),r(e))return this.mapFile=e,o(e,"utf-8").toString().trim()}loadMap(e,t){if(!1===t)return!1;if(t){if("string"==typeof t)return t;if("function"!=typeof t){if(t instanceof n)return s.fromSourceMap(t).toString();if(t instanceof s)return t.toString();if(this.isMap(t))return JSON.stringify(t);throw new Error("Unsupported previous source map format: "+t.toString())}{let i=t(e);if(i){let e=this.loadFile(i);if(!e)throw new Error("Unable to load previous source map: "+i.toString());return e}}}else{if(this.inline)return this.decodeInline(this.annotation);if(this.annotation){let t=this.annotation;return e&&(t=l(a(e),t)),this.loadFile(t)}}}startWith(e,t){return!!e&&e.substr(0,t.length)===t}withContent(){return!!(this.consumer().sourcesContent&&this.consumer().sourcesContent.length>0)}}e.exports=h,h.default=h},540:(e,t,i)=>{"use strict";let n=i(7744),s=i(427),r=i(2900),o=i(4539);class a{constructor(e=[]){this.version="8.4.31",this.plugins=this.normalize(e)}normalize(e){let t=[];for(let i of e)if(!0===i.postcss?i=i():i.postcss&&(i=i.postcss),"object"==typeof i&&Array.isArray(i.plugins))t=t.concat(i.plugins);else if("object"==typeof i&&i.postcssPlugin)t.push(i);else if("function"==typeof i)t.push(i);else if("object"!=typeof i||!i.parse&&!i.stringify)throw new Error(i+" is not a PostCSS plugin");return t}process(e,t={}){return 0===this.plugins.length&&void 0===t.parser&&void 0===t.stringifier&&void 0===t.syntax?new n(this,e,t):new s(this,e,t)}use(e){return this.plugins=this.plugins.concat(this.normalize([e])),this}}e.exports=a,a.default=a,o.registerProcessor(a),r.registerProcessor(a)},165:(e,t,i)=>{"use strict";let n=i(860);class s{constructor(e,t,i){this.processor=e,this.messages=[],this.root=t,this.opts=i,this.css=void 0,this.map=void 0}toString(){return this.css}warn(e,t={}){t.plugin||this.lastPlugin&&this.lastPlugin.postcssPlugin&&(t.plugin=this.lastPlugin.postcssPlugin);let i=new n(e,t);return this.messages.push(i),i}warnings(){return this.messages.filter((e=>"warning"===e.type))}get content(){return this.css}}e.exports=s,s.default=s},4539:(e,t,i)=>{"use strict";let n,s,r=i(9930);class o extends r{constructor(e){super(e),this.type="root",this.nodes||(this.nodes=[])}normalize(e,t,i){let n=super.normalize(e);if(t)if("prepend"===i)this.nodes.length>1?t.raws.before=this.nodes[1].raws.before:delete t.raws.before;else if(this.first!==t)for(let e of n)e.raws.before=t.raws.before;return n}removeChild(e,t){let i=this.index(e);return!t&&0===i&&this.nodes.length>1&&(this.nodes[1].raws.before=this.nodes[i].raws.before),super.removeChild(e)}toResult(e={}){return new n(new s,this,e).stringify()}}o.registerLazyResult=e=>{n=e},o.registerProcessor=e=>{s=e},e.exports=o,o.default=o,r.registerRoot(o)},4146:(e,t,i)=>{"use strict";let n=i(9930),s=i(6065);class r extends n{constructor(e){super(e),this.type="rule",this.nodes||(this.nodes=[])}get selectors(){return s.comma(this.selector)}set selectors(e){let t=this.selector?this.selector.match(/,\s*/):null,i=t?t[0]:","+this.raw("between","beforeOpen");this.selector=e.join(i)}}e.exports=r,r.default=r,n.registerRule(r)},9906:e=>{"use strict";const t={after:"\n",beforeClose:"\n",beforeComment:"\n",beforeDecl:"\n",beforeOpen:" ",beforeRule:"\n",colon:": ",commentLeft:" ",commentRight:" ",emptyBody:"",indent:" ",semicolon:!1};class i{constructor(e){this.builder=e}atrule(e,t){let i="@"+e.name,n=e.params?this.rawValue(e,"params"):"";if(void 0!==e.raws.afterName?i+=e.raws.afterName:n&&(i+=" "),e.nodes)this.block(e,i+n);else{let s=(e.raws.between||"")+(t?";":"");this.builder(i+n+s,e)}}beforeAfter(e,t){let i;i="decl"===e.type?this.raw(e,null,"beforeDecl"):"comment"===e.type?this.raw(e,null,"beforeComment"):"before"===t?this.raw(e,null,"beforeRule"):this.raw(e,null,"beforeClose");let n=e.parent,s=0;for(;n&&"root"!==n.type;)s+=1,n=n.parent;if(i.includes("\n")){let t=this.raw(e,null,"indent");if(t.length)for(let e=0;e0&&"comment"===e.nodes[t].type;)t-=1;let i=this.raw(e,"semicolon");for(let n=0;n{if(s=e.raws[i],void 0!==s)return!1}))}var a;return void 0===s&&(s=t[n]),o.rawCache[n]=s,s}rawBeforeClose(e){let t;return e.walk((e=>{if(e.nodes&&e.nodes.length>0&&void 0!==e.raws.after)return t=e.raws.after,t.includes("\n")&&(t=t.replace(/[^\n]+$/,"")),!1})),t&&(t=t.replace(/\S/g,"")),t}rawBeforeComment(e,t){let i;return e.walkComments((e=>{if(void 0!==e.raws.before)return i=e.raws.before,i.includes("\n")&&(i=i.replace(/[^\n]+$/,"")),!1})),void 0===i?i=this.raw(t,null,"beforeDecl"):i&&(i=i.replace(/\S/g,"")),i}rawBeforeDecl(e,t){let i;return e.walkDecls((e=>{if(void 0!==e.raws.before)return i=e.raws.before,i.includes("\n")&&(i=i.replace(/[^\n]+$/,"")),!1})),void 0===i?i=this.raw(t,null,"beforeRule"):i&&(i=i.replace(/\S/g,"")),i}rawBeforeOpen(e){let t;return e.walk((e=>{if("decl"!==e.type&&(t=e.raws.between,void 0!==t))return!1})),t}rawBeforeRule(e){let t;return e.walk((i=>{if(i.nodes&&(i.parent!==e||e.first!==i)&&void 0!==i.raws.before)return t=i.raws.before,t.includes("\n")&&(t=t.replace(/[^\n]+$/,"")),!1})),t&&(t=t.replace(/\S/g,"")),t}rawColon(e){let t;return e.walkDecls((e=>{if(void 0!==e.raws.between)return t=e.raws.between.replace(/[^\s:]/g,""),!1})),t}rawEmptyBody(e){let t;return e.walk((e=>{if(e.nodes&&0===e.nodes.length&&(t=e.raws.after,void 0!==t))return!1})),t}rawIndent(e){if(e.raws.indent)return e.raws.indent;let t;return e.walk((i=>{let n=i.parent;if(n&&n!==e&&n.parent&&n.parent===e&&void 0!==i.raws.before){let e=i.raws.before.split("\n");return t=e[e.length-1],t=t.replace(/\S/g,""),!1}})),t}rawSemicolon(e){let t;return e.walk((e=>{if(e.nodes&&e.nodes.length&&"decl"===e.last.type&&(t=e.raws.semicolon,void 0!==t))return!1})),t}rawValue(e,t){let i=e[t],n=e.raws[t];return n&&n.value===i?n.raw:i}root(e){this.body(e),e.raws.after&&this.builder(e.raws.after)}rule(e){this.block(e,this.rawValue(e,"selector")),e.raws.ownSemicolon&&this.builder(e.raws.ownSemicolon,e,"end")}stringify(e,t){if(!this[e.type])throw new Error("Unknown AST node type "+e.type+". Maybe you need to change PostCSS stringifier.");this[e.type](e,t)}}e.exports=i,i.default=i},9573:(e,t,i)=>{"use strict";let n=i(9906);function s(e,t){new n(t).stringify(e)}e.exports=s,s.default=s},2450:e=>{"use strict";e.exports.isClean=Symbol("isClean"),e.exports.my=Symbol("my")},9985:e=>{"use strict";const t="'".charCodeAt(0),i='"'.charCodeAt(0),n="\\".charCodeAt(0),s="/".charCodeAt(0),r="\n".charCodeAt(0),o=" ".charCodeAt(0),a="\f".charCodeAt(0),l="\t".charCodeAt(0),h="\r".charCodeAt(0),c="[".charCodeAt(0),d="]".charCodeAt(0),u="(".charCodeAt(0),p=")".charCodeAt(0),f="{".charCodeAt(0),m="}".charCodeAt(0),g=";".charCodeAt(0),v="*".charCodeAt(0),O=":".charCodeAt(0),b="@".charCodeAt(0),_=/[\t\n\f\r "#'()/;[\\\]{}]/g,y=/[\t\n\f\r !"#'():;@[\\\]{}]|\/(?=\*)/g,w=/.[\r\n"'(/\\]/,x=/[\da-f]/i;e.exports=function(e,S={}){let k,T,C,P,M,E,A,R,D,I,q=e.css.valueOf(),L=S.ignoreErrors,N=q.length,B=0,$=[],Q=[];function z(t){throw e.error("Unclosed "+t,B)}return{back:function(e){Q.push(e)},endOfFile:function(){return 0===Q.length&&B>=N},nextToken:function(e){if(Q.length)return Q.pop();if(B>=N)return;let S=!!e&&e.ignoreUnclosed;switch(k=q.charCodeAt(B),k){case r:case o:case l:case h:case a:T=B;do{T+=1,k=q.charCodeAt(T)}while(k===o||k===r||k===l||k===h||k===a);I=["space",q.slice(B,T)],B=T-1;break;case c:case d:case f:case m:case O:case g:case p:{let e=String.fromCharCode(k);I=[e,e,B];break}case u:if(R=$.length?$.pop()[1]:"",D=q.charCodeAt(B+1),"url"===R&&D!==t&&D!==i&&D!==o&&D!==r&&D!==l&&D!==a&&D!==h){T=B;do{if(E=!1,T=q.indexOf(")",T+1),-1===T){if(L||S){T=B;break}z("bracket")}for(A=T;q.charCodeAt(A-1)===n;)A-=1,E=!E}while(E);I=["brackets",q.slice(B,T+1),B,T],B=T}else T=q.indexOf(")",B+1),P=q.slice(B,T+1),-1===T||w.test(P)?I=["(","(",B]:(I=["brackets",P,B,T],B=T);break;case t:case i:C=k===t?"'":'"',T=B;do{if(E=!1,T=q.indexOf(C,T+1),-1===T){if(L||S){T=B+1;break}z("string")}for(A=T;q.charCodeAt(A-1)===n;)A-=1,E=!E}while(E);I=["string",q.slice(B,T+1),B,T],B=T;break;case b:_.lastIndex=B+1,_.test(q),T=0===_.lastIndex?q.length-1:_.lastIndex-2,I=["at-word",q.slice(B,T+1),B,T],B=T;break;case n:for(T=B,M=!0;q.charCodeAt(T+1)===n;)T+=1,M=!M;if(k=q.charCodeAt(T+1),M&&k!==s&&k!==o&&k!==r&&k!==l&&k!==h&&k!==a&&(T+=1,x.test(q.charAt(T)))){for(;x.test(q.charAt(T+1));)T+=1;q.charCodeAt(T+1)===o&&(T+=1)}I=["word",q.slice(B,T+1),B,T],B=T;break;default:k===s&&q.charCodeAt(B+1)===v?(T=q.indexOf("*/",B+2)+1,0===T&&(L||S?T=q.length:z("comment")),I=["comment",q.slice(B,T+1),B,T],B=T):(y.lastIndex=B+1,y.test(q),T=0===y.lastIndex?q.length-1:y.lastIndex-2,I=["word",q.slice(B,T+1),B,T],$.push(I),B=T)}return B++,I},position:function(){return B}}}},5411:e=>{"use strict";let t={};e.exports=function(e){t[e]||(t[e]=!0,"undefined"!=typeof console&&console.warn&&console.warn(e))}},860:e=>{"use strict";class t{constructor(e,t={}){if(this.type="warning",this.text=e,t.node&&t.node.source){let e=t.node.rangeBy(t);this.line=e.start.line,this.column=e.start.column,this.endLine=e.end.line,this.endColumn=e.end.column}for(let e in t)this[e]=t[e]}toString(){return this.node?this.node.error(this.text,{index:this.index,plugin:this.plugin,word:this.word}).message:this.plugin?this.plugin+": "+this.text:this.text}}e.exports=t,t.default=t},8878:(e,t)=>{"use strict";var i=Object.prototype.hasOwnProperty;function n(e){try{return decodeURIComponent(e.replace(/\+/g," "))}catch(e){return null}}function s(e){try{return encodeURIComponent(e)}catch(e){return null}}t.stringify=function(e,t){t=t||"";var n,r,o=[];for(r in"string"!=typeof t&&(t="?"),e)if(i.call(e,r)){if((n=e[r])||null!=n&&!isNaN(n)||(n=""),r=s(r),n=s(n),null===r||null===n)continue;o.push(r+"="+n)}return o.length?t+o.join("&"):""},t.parse=function(e){for(var t,i=/([^=?#&]+)=?([^&]*)/g,s={};t=i.exec(e);){var r=n(t[1]),o=n(t[2]);null===r||null===o||r in s||(s[r]=o)}return s}},1384:e=>{"use strict";e.exports=function(e,t){if(t=t.split(":")[0],!(e=+e))return!1;switch(t){case"http":case"ws":return 80!==e;case"https":case"wss":return 443!==e;case"ftp":return 21!==e;case"gopher":return 70!==e;case"file":return!1}return 0!==e}},1622:(e,t,i)=>{const n=i(1659),s=i(3419),{isPlainObject:r}=i(3056),o=i(2454),a=i(9382),{parse:l}=i(5356),h=["img","audio","video","picture","svg","object","map","iframe","embed"],c=["script","style"];function d(e,t){e&&Object.keys(e).forEach((function(i){t(e[i],i)}))}function u(e,t){return{}.hasOwnProperty.call(e,t)}function p(e,t){const i=[];return d(e,(function(e){t(e)&&i.push(e)})),i}e.exports=m;const f=/^[^\0\t\n\f\r /<=>]+$/;function m(e,t,i){if(null==e)return"";let v="",O="";function b(e,t){const i=this;this.tag=e,this.attribs=t||{},this.tagPosition=v.length,this.text="",this.mediaChildren=[],this.updateParentNodeText=function(){M.length&&(M[M.length-1].text+=i.text)},this.updateParentNodeMediaChildren=function(){M.length&&h.includes(this.tag)&&M[M.length-1].mediaChildren.push(this.tag)}}(t=Object.assign({},m.defaults,t)).parser=Object.assign({},g,t.parser),c.forEach((function(e){!1!==t.allowedTags&&(t.allowedTags||[]).indexOf(e)>-1&&!t.allowVulnerableTags&&console.warn(`\n\n⚠️ Your \`allowedTags\` option includes, \`${e}\`, which is inherently\nvulnerable to XSS attacks. Please remove it from \`allowedTags\`.\nOr, to disable this warning, add the \`allowVulnerableTags\` option\nand ensure you are accounting for this risk.\n\n`)}));const _=t.nonTextTags||["script","style","textarea","option"];let y,w;t.allowedAttributes&&(y={},w={},d(t.allowedAttributes,(function(e,t){y[t]=[];const i=[];e.forEach((function(e){"string"==typeof e&&e.indexOf("*")>=0?i.push(s(e).replace(/\\\*/g,".*")):y[t].push(e)})),i.length&&(w[t]=new RegExp("^("+i.join("|")+")$"))})));const x={},S={},k={};d(t.allowedClasses,(function(e,t){y&&(u(y,t)||(y[t]=[]),y[t].push("class")),x[t]=[],k[t]=[];const i=[];e.forEach((function(e){"string"==typeof e&&e.indexOf("*")>=0?i.push(s(e).replace(/\\\*/g,".*")):e instanceof RegExp?k[t].push(e):x[t].push(e)})),i.length&&(S[t]=new RegExp("^("+i.join("|")+")$"))}));const T={};let C,P,M,E,A,R,D;d(t.transformTags,(function(e,t){let i;"function"==typeof e?i=e:"string"==typeof e&&(i=m.simpleTransform(e)),"*"===t?C=i:T[t]=i}));let I=!1;L();const q=new n.Parser({onopentag:function(e,i){if(t.enforceHtmlBoundary&&"html"===e&&L(),R)return void D++;const n=new b(e,i);M.push(n);let s=!1;const h=!!n.text;let c;if(u(T,e)&&(c=T[e](e,i),n.attribs=i=c.attribs,void 0!==c.text&&(n.innerText=c.text),e!==c.tagName&&(n.name=e=c.tagName,A[P]=c.tagName)),C&&(c=C(e,i),n.attribs=i=c.attribs,e!==c.tagName&&(n.name=e=c.tagName,A[P]=c.tagName)),(!1!==t.allowedTags&&-1===(t.allowedTags||[]).indexOf(e)||"recursiveEscape"===t.disallowedTagsMode&&!function(e){for(const t in e)if(u(e,t))return!1;return!0}(E)||null!=t.nestingLimit&&P>=t.nestingLimit)&&(s=!0,E[P]=!0,"discard"===t.disallowedTagsMode&&-1!==_.indexOf(e)&&(R=!0,D=1),E[P]=!0),P++,s){if("discard"===t.disallowedTagsMode)return;O=v,v=""}v+="<"+e,"script"===e&&(t.allowedScriptHostnames||t.allowedScriptDomains)&&(n.innerText=""),(!y||u(y,e)||y["*"])&&d(i,(function(i,s){if(!f.test(s))return void delete n.attribs[s];let h=!1;if(!y||u(y,e)&&-1!==y[e].indexOf(s)||y["*"]&&-1!==y["*"].indexOf(s)||u(w,e)&&w[e].test(s)||w["*"]&&w["*"].test(s))h=!0;else if(y&&y[e])for(const t of y[e])if(r(t)&&t.name&&t.name===s){h=!0;let e="";if(!0===t.multiple){const n=i.split(" ");for(const i of n)-1!==t.values.indexOf(i)&&(""===e?e=i:e+=" "+i)}else t.values.indexOf(i)>=0&&(e=i);i=e}if(h){if(-1!==t.allowedSchemesAppliedToAttributes.indexOf(s)&&B(e,i))return void delete n.attribs[s];if("script"===e&&"src"===s){let e=!0;try{const n=$(i);if(t.allowedScriptHostnames||t.allowedScriptDomains){const i=(t.allowedScriptHostnames||[]).find((function(e){return e===n.url.hostname})),s=(t.allowedScriptDomains||[]).find((function(e){return n.url.hostname===e||n.url.hostname.endsWith(`.${e}`)}));e=i||s}}catch(t){e=!1}if(!e)return void delete n.attribs[s]}if("iframe"===e&&"src"===s){let e=!0;try{const n=$(i);if(n.isRelativeUrl)e=u(t,"allowIframeRelativeUrls")?t.allowIframeRelativeUrls:!t.allowedIframeHostnames&&!t.allowedIframeDomains;else if(t.allowedIframeHostnames||t.allowedIframeDomains){const i=(t.allowedIframeHostnames||[]).find((function(e){return e===n.url.hostname})),s=(t.allowedIframeDomains||[]).find((function(e){return n.url.hostname===e||n.url.hostname.endsWith(`.${e}`)}));e=i||s}}catch(t){e=!1}if(!e)return void delete n.attribs[s]}if("srcset"===s)try{let e=a(i);if(e.forEach((function(e){B("srcset",e.url)&&(e.evil=!0)})),e=p(e,(function(e){return!e.evil})),!e.length)return void delete n.attribs[s];i=p(e,(function(e){return!e.evil})).map((function(e){if(!e.url)throw new Error("URL missing");return e.url+(e.w?` ${e.w}w`:"")+(e.h?` ${e.h}h`:"")+(e.d?` ${e.d}x`:"")})).join(", "),n.attribs[s]=i}catch(e){return void delete n.attribs[s]}if("class"===s){const t=x[e],r=x["*"],a=S[e],l=k[e],h=[a,S["*"]].concat(l).filter((function(e){return e}));if(!(c=i,d=t&&r?o(t,r):t||r,m=h,i=d?(c=c.split(/\s+/)).filter((function(e){return-1!==d.indexOf(e)||m.some((function(t){return t.test(e)}))})).join(" "):c).length)return void delete n.attribs[s]}if("style"===s)try{if(i=function(e){return e.nodes[0].nodes.reduce((function(e,t){return e.push(`${t.prop}:${t.value}${t.important?" !important":""}`),e}),[]).join(";")}(function(e,t){if(!t)return e;const i=e.nodes[0];let n;return n=t[i.selector]&&t["*"]?o(t[i.selector],t["*"]):t[i.selector]||t["*"],n&&(e.nodes[0].nodes=i.nodes.reduce(function(e){return function(t,i){return u(e,i.prop)&&e[i.prop].some((function(e){return e.test(i.value)}))&&t.push(i),t}}(n),[])),e}(l(e+" {"+i+"}"),t.allowedStyles)),0===i.length)return void delete n.attribs[s]}catch(e){return void delete n.attribs[s]}v+=" "+s,i&&i.length&&(v+='="'+N(i,!0)+'"')}else delete n.attribs[s];var c,d,m})),-1!==t.selfClosing.indexOf(e)?v+=" />":(v+=">",!n.innerText||h||t.textFilter||(v+=N(n.innerText),I=!0)),s&&(v=O+N(v),O="")},ontext:function(e){if(R)return;const i=M[M.length-1];let n;if(i&&(n=i.tag,e=void 0!==i.innerText?i.innerText:e),"discard"!==t.disallowedTagsMode||"script"!==n&&"style"!==n){const i=N(e,!1);t.textFilter&&!I?v+=t.textFilter(i,n):I||(v+=i)}else v+=e;M.length&&(M[M.length-1].text+=e)},onclosetag:function(e){if(R){if(D--,D)return;R=!1}const i=M.pop();if(!i)return;if(i.tag!==e)return void M.push(i);R=!!t.enforceHtmlBoundary&&"html"===e,P--;const n=E[P];if(n){if(delete E[P],"discard"===t.disallowedTagsMode)return void i.updateParentNodeText();O=v,v=""}A[P]&&(e=A[P],delete A[P]),t.exclusiveFilter&&t.exclusiveFilter(i)?v=v.substr(0,i.tagPosition):(i.updateParentNodeMediaChildren(),i.updateParentNodeText(),-1===t.selfClosing.indexOf(e)?(v+="",n&&(v=O+N(v),O=""),I=!1):n&&(v=O,O=""))}},t.parser);return q.write(e),q.end(),v;function L(){v="",P=0,M=[],E={},A={},R=!1,D=0}function N(e,i){return"string"!=typeof e&&(e+=""),t.parser.decodeEntities&&(e=e.replace(/&/g,"&").replace(//g,">"),i&&(e=e.replace(/"/g,"""))),e=e.replace(/&(?![a-zA-Z0-9#]{1,20};)/g,"&").replace(//g,">"),i&&(e=e.replace(/"/g,""")),e}function B(e,i){for(i=i.replace(/[\x00-\x20]+/g,"");;){const e=i.indexOf("\x3c!--");if(-1===e)break;const t=i.indexOf("--\x3e",e+4);if(-1===t)break;i=i.substring(0,e)+i.substring(t+3)}const n=i.match(/^([a-zA-Z][a-zA-Z0-9.\-+]*):/);if(!n)return!!i.match(/^[/\\]{2}/)&&!t.allowProtocolRelative;const s=n[1].toLowerCase();return u(t.allowedSchemesByTag,e)?-1===t.allowedSchemesByTag[e].indexOf(s):!t.allowedSchemes||-1===t.allowedSchemes.indexOf(s)}function $(e){if((e=e.replace(/^(\w+:)?\s*[\\/]\s*[\\/]/,"$1//")).startsWith("relative:"))throw new Error("relative: exploit attempt");let t="relative://relative-site";for(let e=0;e<100;e++)t+=`/${e}`;const i=new URL(e,t);return{isRelativeUrl:i&&"relative-site"===i.hostname&&"relative:"===i.protocol,url:i}}}const g={decodeEntities:!0};m.defaults={allowedTags:["address","article","aside","footer","header","h1","h2","h3","h4","h5","h6","hgroup","main","nav","section","blockquote","dd","div","dl","dt","figcaption","figure","hr","li","main","ol","p","pre","ul","a","abbr","b","bdi","bdo","br","cite","code","data","dfn","em","i","kbd","mark","q","rb","rp","rt","rtc","ruby","s","samp","small","span","strong","sub","sup","time","u","var","wbr","caption","col","colgroup","table","tbody","td","tfoot","th","thead","tr"],disallowedTagsMode:"discard",allowedAttributes:{a:["href","name","target"],img:["src","srcset","alt","title","width","height","loading"]},selfClosing:["img","br","hr","area","base","basefont","input","link","meta"],allowedSchemes:["http","https","ftp","mailto","tel"],allowedSchemesByTag:{},allowedSchemesAppliedToAttributes:["href","src","cite"],allowProtocolRelative:!0,enforceHtmlBoundary:!1},m.simpleTransform=function(e,t,i){return i=void 0===i||i,t=t||{},function(n,s){let r;if(i)for(r in t)s[r]=t[r];else s=t;return{tagName:e,attribs:s}}}},2296:(e,t,i)=>{"use strict";var n=i(1384),s=i(8878),r=/^[\x00-\x20\u00a0\u1680\u2000-\u200a\u2028\u2029\u202f\u205f\u3000\ufeff]+/,o=/[\n\r\t]/g,a=/^[A-Za-z][A-Za-z0-9+-.]*:\/\//,l=/:\d+$/,h=/^([a-z][a-z0-9.+-]*:)?(\/\/)?([\\/]+)?([\S\s]*)/i,c=/^[a-zA-Z]:/;function d(e){return(e||"").toString().replace(r,"")}var u=[["#","hash"],["?","query"],function(e,t){return m(t.protocol)?e.replace(/\\/g,"/"):e},["/","pathname"],["@","auth",1],[NaN,"host",void 0,1,1],[/:(\d*)$/,"port",void 0,1],[NaN,"hostname",void 0,1,1]],p={hash:1,query:1};function f(e){var t,n=("undefined"!=typeof window?window:void 0!==i.g?i.g:"undefined"!=typeof self?self:{}).location||{},s={},r=typeof(e=e||n);if("blob:"===e.protocol)s=new v(unescape(e.pathname),{});else if("string"===r)for(t in s=new v(e,{}),p)delete s[t];else if("object"===r){for(t in e)t in p||(s[t]=e[t]);void 0===s.slashes&&(s.slashes=a.test(e.href))}return s}function m(e){return"file:"===e||"ftp:"===e||"http:"===e||"https:"===e||"ws:"===e||"wss:"===e}function g(e,t){e=(e=d(e)).replace(o,""),t=t||{};var i,n=h.exec(e),s=n[1]?n[1].toLowerCase():"",r=!!n[2],a=!!n[3],l=0;return r?a?(i=n[2]+n[3]+n[4],l=n[2].length+n[3].length):(i=n[2]+n[4],l=n[2].length):a?(i=n[3]+n[4],l=n[3].length):i=n[4],"file:"===s?l>=2&&(i=i.slice(2)):m(s)?i=n[4]:s?r&&(i=i.slice(2)):l>=2&&m(t.protocol)&&(i=n[4]),{protocol:s,slashes:r||m(s),slashesCount:l,rest:i}}function v(e,t,i){if(e=(e=d(e)).replace(o,""),!(this instanceof v))return new v(e,t,i);var r,a,l,h,p,O,b=u.slice(),_=typeof t,y=this,w=0;for("object"!==_&&"string"!==_&&(i=t,t=null),i&&"function"!=typeof i&&(i=s.parse),r=!(a=g(e||"",t=f(t))).protocol&&!a.slashes,y.slashes=a.slashes||r&&t.slashes,y.protocol=a.protocol||t.protocol||"",e=a.rest,("file:"===a.protocol&&(2!==a.slashesCount||c.test(e))||!a.slashes&&(a.protocol||a.slashesCount<2||!m(y.protocol)))&&(b[3]=[/(.*)/,"pathname"]);w{},1336:()=>{},2666:()=>{},9059:()=>{},415:()=>{},8845:e=>{e.exports={nanoid:(e=21)=>{let t="",i=e;for(;i--;)t+="useandom-26T198340PX75pxJACKVERYMINDBUSHWOLF_GQZbfghjklqvwyzrict"[64*Math.random()|0];return t},customAlphabet:(e,t=21)=>(i=t)=>{let n="",s=i;for(;s--;)n+=e[Math.random()*e.length|0];return n}}},6399:e=>{"use strict";e.exports=JSON.parse('{"0":65533,"128":8364,"130":8218,"131":402,"132":8222,"133":8230,"134":8224,"135":8225,"136":710,"137":8240,"138":352,"139":8249,"140":338,"142":381,"145":8216,"146":8217,"147":8220,"148":8221,"149":8226,"150":8211,"151":8212,"152":732,"153":8482,"154":353,"155":8250,"156":339,"158":382,"159":376}')},2810:e=>{"use strict";e.exports=JSON.parse('{"Aacute":"Á","aacute":"á","Abreve":"Ă","abreve":"ă","ac":"∾","acd":"∿","acE":"∾̳","Acirc":"Â","acirc":"â","acute":"´","Acy":"А","acy":"а","AElig":"Æ","aelig":"æ","af":"⁡","Afr":"𝔄","afr":"𝔞","Agrave":"À","agrave":"à","alefsym":"ℵ","aleph":"ℵ","Alpha":"Α","alpha":"α","Amacr":"Ā","amacr":"ā","amalg":"⨿","amp":"&","AMP":"&","andand":"⩕","And":"⩓","and":"∧","andd":"⩜","andslope":"⩘","andv":"⩚","ang":"∠","ange":"⦤","angle":"∠","angmsdaa":"⦨","angmsdab":"⦩","angmsdac":"⦪","angmsdad":"⦫","angmsdae":"⦬","angmsdaf":"⦭","angmsdag":"⦮","angmsdah":"⦯","angmsd":"∡","angrt":"∟","angrtvb":"⊾","angrtvbd":"⦝","angsph":"∢","angst":"Å","angzarr":"⍼","Aogon":"Ą","aogon":"ą","Aopf":"𝔸","aopf":"𝕒","apacir":"⩯","ap":"≈","apE":"⩰","ape":"≊","apid":"≋","apos":"\'","ApplyFunction":"⁡","approx":"≈","approxeq":"≊","Aring":"Å","aring":"å","Ascr":"𝒜","ascr":"𝒶","Assign":"≔","ast":"*","asymp":"≈","asympeq":"≍","Atilde":"Ã","atilde":"ã","Auml":"Ä","auml":"ä","awconint":"∳","awint":"⨑","backcong":"≌","backepsilon":"϶","backprime":"‵","backsim":"∽","backsimeq":"⋍","Backslash":"∖","Barv":"⫧","barvee":"⊽","barwed":"⌅","Barwed":"⌆","barwedge":"⌅","bbrk":"⎵","bbrktbrk":"⎶","bcong":"≌","Bcy":"Б","bcy":"б","bdquo":"„","becaus":"∵","because":"∵","Because":"∵","bemptyv":"⦰","bepsi":"϶","bernou":"ℬ","Bernoullis":"ℬ","Beta":"Β","beta":"β","beth":"ℶ","between":"≬","Bfr":"𝔅","bfr":"𝔟","bigcap":"⋂","bigcirc":"◯","bigcup":"⋃","bigodot":"⨀","bigoplus":"⨁","bigotimes":"⨂","bigsqcup":"⨆","bigstar":"★","bigtriangledown":"▽","bigtriangleup":"△","biguplus":"⨄","bigvee":"⋁","bigwedge":"⋀","bkarow":"⤍","blacklozenge":"⧫","blacksquare":"▪","blacktriangle":"▴","blacktriangledown":"▾","blacktriangleleft":"◂","blacktriangleright":"▸","blank":"␣","blk12":"▒","blk14":"░","blk34":"▓","block":"█","bne":"=⃥","bnequiv":"≡⃥","bNot":"⫭","bnot":"⌐","Bopf":"𝔹","bopf":"𝕓","bot":"⊥","bottom":"⊥","bowtie":"⋈","boxbox":"⧉","boxdl":"┐","boxdL":"╕","boxDl":"╖","boxDL":"╗","boxdr":"┌","boxdR":"╒","boxDr":"╓","boxDR":"╔","boxh":"─","boxH":"═","boxhd":"┬","boxHd":"╤","boxhD":"╥","boxHD":"╦","boxhu":"┴","boxHu":"╧","boxhU":"╨","boxHU":"╩","boxminus":"⊟","boxplus":"⊞","boxtimes":"⊠","boxul":"┘","boxuL":"╛","boxUl":"╜","boxUL":"╝","boxur":"└","boxuR":"╘","boxUr":"╙","boxUR":"╚","boxv":"│","boxV":"║","boxvh":"┼","boxvH":"╪","boxVh":"╫","boxVH":"╬","boxvl":"┤","boxvL":"╡","boxVl":"╢","boxVL":"╣","boxvr":"├","boxvR":"╞","boxVr":"╟","boxVR":"╠","bprime":"‵","breve":"˘","Breve":"˘","brvbar":"¦","bscr":"𝒷","Bscr":"ℬ","bsemi":"⁏","bsim":"∽","bsime":"⋍","bsolb":"⧅","bsol":"\\\\","bsolhsub":"⟈","bull":"•","bullet":"•","bump":"≎","bumpE":"⪮","bumpe":"≏","Bumpeq":"≎","bumpeq":"≏","Cacute":"Ć","cacute":"ć","capand":"⩄","capbrcup":"⩉","capcap":"⩋","cap":"∩","Cap":"⋒","capcup":"⩇","capdot":"⩀","CapitalDifferentialD":"ⅅ","caps":"∩︀","caret":"⁁","caron":"ˇ","Cayleys":"ℭ","ccaps":"⩍","Ccaron":"Č","ccaron":"č","Ccedil":"Ç","ccedil":"ç","Ccirc":"Ĉ","ccirc":"ĉ","Cconint":"∰","ccups":"⩌","ccupssm":"⩐","Cdot":"Ċ","cdot":"ċ","cedil":"¸","Cedilla":"¸","cemptyv":"⦲","cent":"¢","centerdot":"·","CenterDot":"·","cfr":"𝔠","Cfr":"ℭ","CHcy":"Ч","chcy":"ч","check":"✓","checkmark":"✓","Chi":"Χ","chi":"χ","circ":"ˆ","circeq":"≗","circlearrowleft":"↺","circlearrowright":"↻","circledast":"⊛","circledcirc":"⊚","circleddash":"⊝","CircleDot":"⊙","circledR":"®","circledS":"Ⓢ","CircleMinus":"⊖","CirclePlus":"⊕","CircleTimes":"⊗","cir":"○","cirE":"⧃","cire":"≗","cirfnint":"⨐","cirmid":"⫯","cirscir":"⧂","ClockwiseContourIntegral":"∲","CloseCurlyDoubleQuote":"”","CloseCurlyQuote":"’","clubs":"♣","clubsuit":"♣","colon":":","Colon":"∷","Colone":"⩴","colone":"≔","coloneq":"≔","comma":",","commat":"@","comp":"∁","compfn":"∘","complement":"∁","complexes":"ℂ","cong":"≅","congdot":"⩭","Congruent":"≡","conint":"∮","Conint":"∯","ContourIntegral":"∮","copf":"𝕔","Copf":"ℂ","coprod":"∐","Coproduct":"∐","copy":"©","COPY":"©","copysr":"℗","CounterClockwiseContourIntegral":"∳","crarr":"↵","cross":"✗","Cross":"⨯","Cscr":"𝒞","cscr":"𝒸","csub":"⫏","csube":"⫑","csup":"⫐","csupe":"⫒","ctdot":"⋯","cudarrl":"⤸","cudarrr":"⤵","cuepr":"⋞","cuesc":"⋟","cularr":"↶","cularrp":"⤽","cupbrcap":"⩈","cupcap":"⩆","CupCap":"≍","cup":"∪","Cup":"⋓","cupcup":"⩊","cupdot":"⊍","cupor":"⩅","cups":"∪︀","curarr":"↷","curarrm":"⤼","curlyeqprec":"⋞","curlyeqsucc":"⋟","curlyvee":"⋎","curlywedge":"⋏","curren":"¤","curvearrowleft":"↶","curvearrowright":"↷","cuvee":"⋎","cuwed":"⋏","cwconint":"∲","cwint":"∱","cylcty":"⌭","dagger":"†","Dagger":"‡","daleth":"ℸ","darr":"↓","Darr":"↡","dArr":"⇓","dash":"‐","Dashv":"⫤","dashv":"⊣","dbkarow":"⤏","dblac":"˝","Dcaron":"Ď","dcaron":"ď","Dcy":"Д","dcy":"д","ddagger":"‡","ddarr":"⇊","DD":"ⅅ","dd":"ⅆ","DDotrahd":"⤑","ddotseq":"⩷","deg":"°","Del":"∇","Delta":"Δ","delta":"δ","demptyv":"⦱","dfisht":"⥿","Dfr":"𝔇","dfr":"𝔡","dHar":"⥥","dharl":"⇃","dharr":"⇂","DiacriticalAcute":"´","DiacriticalDot":"˙","DiacriticalDoubleAcute":"˝","DiacriticalGrave":"`","DiacriticalTilde":"˜","diam":"⋄","diamond":"⋄","Diamond":"⋄","diamondsuit":"♦","diams":"♦","die":"¨","DifferentialD":"ⅆ","digamma":"ϝ","disin":"⋲","div":"÷","divide":"÷","divideontimes":"⋇","divonx":"⋇","DJcy":"Ђ","djcy":"ђ","dlcorn":"⌞","dlcrop":"⌍","dollar":"$","Dopf":"𝔻","dopf":"𝕕","Dot":"¨","dot":"˙","DotDot":"⃜","doteq":"≐","doteqdot":"≑","DotEqual":"≐","dotminus":"∸","dotplus":"∔","dotsquare":"⊡","doublebarwedge":"⌆","DoubleContourIntegral":"∯","DoubleDot":"¨","DoubleDownArrow":"⇓","DoubleLeftArrow":"⇐","DoubleLeftRightArrow":"⇔","DoubleLeftTee":"⫤","DoubleLongLeftArrow":"⟸","DoubleLongLeftRightArrow":"⟺","DoubleLongRightArrow":"⟹","DoubleRightArrow":"⇒","DoubleRightTee":"⊨","DoubleUpArrow":"⇑","DoubleUpDownArrow":"⇕","DoubleVerticalBar":"∥","DownArrowBar":"⤓","downarrow":"↓","DownArrow":"↓","Downarrow":"⇓","DownArrowUpArrow":"⇵","DownBreve":"̑","downdownarrows":"⇊","downharpoonleft":"⇃","downharpoonright":"⇂","DownLeftRightVector":"⥐","DownLeftTeeVector":"⥞","DownLeftVectorBar":"⥖","DownLeftVector":"↽","DownRightTeeVector":"⥟","DownRightVectorBar":"⥗","DownRightVector":"⇁","DownTeeArrow":"↧","DownTee":"⊤","drbkarow":"⤐","drcorn":"⌟","drcrop":"⌌","Dscr":"𝒟","dscr":"𝒹","DScy":"Ѕ","dscy":"ѕ","dsol":"⧶","Dstrok":"Đ","dstrok":"đ","dtdot":"⋱","dtri":"▿","dtrif":"▾","duarr":"⇵","duhar":"⥯","dwangle":"⦦","DZcy":"Џ","dzcy":"џ","dzigrarr":"⟿","Eacute":"É","eacute":"é","easter":"⩮","Ecaron":"Ě","ecaron":"ě","Ecirc":"Ê","ecirc":"ê","ecir":"≖","ecolon":"≕","Ecy":"Э","ecy":"э","eDDot":"⩷","Edot":"Ė","edot":"ė","eDot":"≑","ee":"ⅇ","efDot":"≒","Efr":"𝔈","efr":"𝔢","eg":"⪚","Egrave":"È","egrave":"è","egs":"⪖","egsdot":"⪘","el":"⪙","Element":"∈","elinters":"⏧","ell":"ℓ","els":"⪕","elsdot":"⪗","Emacr":"Ē","emacr":"ē","empty":"∅","emptyset":"∅","EmptySmallSquare":"◻","emptyv":"∅","EmptyVerySmallSquare":"▫","emsp13":" ","emsp14":" ","emsp":" ","ENG":"Ŋ","eng":"ŋ","ensp":" ","Eogon":"Ę","eogon":"ę","Eopf":"𝔼","eopf":"𝕖","epar":"⋕","eparsl":"⧣","eplus":"⩱","epsi":"ε","Epsilon":"Ε","epsilon":"ε","epsiv":"ϵ","eqcirc":"≖","eqcolon":"≕","eqsim":"≂","eqslantgtr":"⪖","eqslantless":"⪕","Equal":"⩵","equals":"=","EqualTilde":"≂","equest":"≟","Equilibrium":"⇌","equiv":"≡","equivDD":"⩸","eqvparsl":"⧥","erarr":"⥱","erDot":"≓","escr":"ℯ","Escr":"ℰ","esdot":"≐","Esim":"⩳","esim":"≂","Eta":"Η","eta":"η","ETH":"Ð","eth":"ð","Euml":"Ë","euml":"ë","euro":"€","excl":"!","exist":"∃","Exists":"∃","expectation":"ℰ","exponentiale":"ⅇ","ExponentialE":"ⅇ","fallingdotseq":"≒","Fcy":"Ф","fcy":"ф","female":"♀","ffilig":"ffi","fflig":"ff","ffllig":"ffl","Ffr":"𝔉","ffr":"𝔣","filig":"fi","FilledSmallSquare":"◼","FilledVerySmallSquare":"▪","fjlig":"fj","flat":"♭","fllig":"fl","fltns":"▱","fnof":"ƒ","Fopf":"𝔽","fopf":"𝕗","forall":"∀","ForAll":"∀","fork":"⋔","forkv":"⫙","Fouriertrf":"ℱ","fpartint":"⨍","frac12":"½","frac13":"⅓","frac14":"¼","frac15":"⅕","frac16":"⅙","frac18":"⅛","frac23":"⅔","frac25":"⅖","frac34":"¾","frac35":"⅗","frac38":"⅜","frac45":"⅘","frac56":"⅚","frac58":"⅝","frac78":"⅞","frasl":"⁄","frown":"⌢","fscr":"𝒻","Fscr":"ℱ","gacute":"ǵ","Gamma":"Γ","gamma":"γ","Gammad":"Ϝ","gammad":"ϝ","gap":"⪆","Gbreve":"Ğ","gbreve":"ğ","Gcedil":"Ģ","Gcirc":"Ĝ","gcirc":"ĝ","Gcy":"Г","gcy":"г","Gdot":"Ġ","gdot":"ġ","ge":"≥","gE":"≧","gEl":"⪌","gel":"⋛","geq":"≥","geqq":"≧","geqslant":"⩾","gescc":"⪩","ges":"⩾","gesdot":"⪀","gesdoto":"⪂","gesdotol":"⪄","gesl":"⋛︀","gesles":"⪔","Gfr":"𝔊","gfr":"𝔤","gg":"≫","Gg":"⋙","ggg":"⋙","gimel":"ℷ","GJcy":"Ѓ","gjcy":"ѓ","gla":"⪥","gl":"≷","glE":"⪒","glj":"⪤","gnap":"⪊","gnapprox":"⪊","gne":"⪈","gnE":"≩","gneq":"⪈","gneqq":"≩","gnsim":"⋧","Gopf":"𝔾","gopf":"𝕘","grave":"`","GreaterEqual":"≥","GreaterEqualLess":"⋛","GreaterFullEqual":"≧","GreaterGreater":"⪢","GreaterLess":"≷","GreaterSlantEqual":"⩾","GreaterTilde":"≳","Gscr":"𝒢","gscr":"ℊ","gsim":"≳","gsime":"⪎","gsiml":"⪐","gtcc":"⪧","gtcir":"⩺","gt":">","GT":">","Gt":"≫","gtdot":"⋗","gtlPar":"⦕","gtquest":"⩼","gtrapprox":"⪆","gtrarr":"⥸","gtrdot":"⋗","gtreqless":"⋛","gtreqqless":"⪌","gtrless":"≷","gtrsim":"≳","gvertneqq":"≩︀","gvnE":"≩︀","Hacek":"ˇ","hairsp":" ","half":"½","hamilt":"ℋ","HARDcy":"Ъ","hardcy":"ъ","harrcir":"⥈","harr":"↔","hArr":"⇔","harrw":"↭","Hat":"^","hbar":"ℏ","Hcirc":"Ĥ","hcirc":"ĥ","hearts":"♥","heartsuit":"♥","hellip":"…","hercon":"⊹","hfr":"𝔥","Hfr":"ℌ","HilbertSpace":"ℋ","hksearow":"⤥","hkswarow":"⤦","hoarr":"⇿","homtht":"∻","hookleftarrow":"↩","hookrightarrow":"↪","hopf":"𝕙","Hopf":"ℍ","horbar":"―","HorizontalLine":"─","hscr":"𝒽","Hscr":"ℋ","hslash":"ℏ","Hstrok":"Ħ","hstrok":"ħ","HumpDownHump":"≎","HumpEqual":"≏","hybull":"⁃","hyphen":"‐","Iacute":"Í","iacute":"í","ic":"⁣","Icirc":"Î","icirc":"î","Icy":"И","icy":"и","Idot":"İ","IEcy":"Е","iecy":"е","iexcl":"¡","iff":"⇔","ifr":"𝔦","Ifr":"ℑ","Igrave":"Ì","igrave":"ì","ii":"ⅈ","iiiint":"⨌","iiint":"∭","iinfin":"⧜","iiota":"℩","IJlig":"IJ","ijlig":"ij","Imacr":"Ī","imacr":"ī","image":"ℑ","ImaginaryI":"ⅈ","imagline":"ℐ","imagpart":"ℑ","imath":"ı","Im":"ℑ","imof":"⊷","imped":"Ƶ","Implies":"⇒","incare":"℅","in":"∈","infin":"∞","infintie":"⧝","inodot":"ı","intcal":"⊺","int":"∫","Int":"∬","integers":"ℤ","Integral":"∫","intercal":"⊺","Intersection":"⋂","intlarhk":"⨗","intprod":"⨼","InvisibleComma":"⁣","InvisibleTimes":"⁢","IOcy":"Ё","iocy":"ё","Iogon":"Į","iogon":"į","Iopf":"𝕀","iopf":"𝕚","Iota":"Ι","iota":"ι","iprod":"⨼","iquest":"¿","iscr":"𝒾","Iscr":"ℐ","isin":"∈","isindot":"⋵","isinE":"⋹","isins":"⋴","isinsv":"⋳","isinv":"∈","it":"⁢","Itilde":"Ĩ","itilde":"ĩ","Iukcy":"І","iukcy":"і","Iuml":"Ï","iuml":"ï","Jcirc":"Ĵ","jcirc":"ĵ","Jcy":"Й","jcy":"й","Jfr":"𝔍","jfr":"𝔧","jmath":"ȷ","Jopf":"𝕁","jopf":"𝕛","Jscr":"𝒥","jscr":"𝒿","Jsercy":"Ј","jsercy":"ј","Jukcy":"Є","jukcy":"є","Kappa":"Κ","kappa":"κ","kappav":"ϰ","Kcedil":"Ķ","kcedil":"ķ","Kcy":"К","kcy":"к","Kfr":"𝔎","kfr":"𝔨","kgreen":"ĸ","KHcy":"Х","khcy":"х","KJcy":"Ќ","kjcy":"ќ","Kopf":"𝕂","kopf":"𝕜","Kscr":"𝒦","kscr":"𝓀","lAarr":"⇚","Lacute":"Ĺ","lacute":"ĺ","laemptyv":"⦴","lagran":"ℒ","Lambda":"Λ","lambda":"λ","lang":"⟨","Lang":"⟪","langd":"⦑","langle":"⟨","lap":"⪅","Laplacetrf":"ℒ","laquo":"«","larrb":"⇤","larrbfs":"⤟","larr":"←","Larr":"↞","lArr":"⇐","larrfs":"⤝","larrhk":"↩","larrlp":"↫","larrpl":"⤹","larrsim":"⥳","larrtl":"↢","latail":"⤙","lAtail":"⤛","lat":"⪫","late":"⪭","lates":"⪭︀","lbarr":"⤌","lBarr":"⤎","lbbrk":"❲","lbrace":"{","lbrack":"[","lbrke":"⦋","lbrksld":"⦏","lbrkslu":"⦍","Lcaron":"Ľ","lcaron":"ľ","Lcedil":"Ļ","lcedil":"ļ","lceil":"⌈","lcub":"{","Lcy":"Л","lcy":"л","ldca":"⤶","ldquo":"“","ldquor":"„","ldrdhar":"⥧","ldrushar":"⥋","ldsh":"↲","le":"≤","lE":"≦","LeftAngleBracket":"⟨","LeftArrowBar":"⇤","leftarrow":"←","LeftArrow":"←","Leftarrow":"⇐","LeftArrowRightArrow":"⇆","leftarrowtail":"↢","LeftCeiling":"⌈","LeftDoubleBracket":"⟦","LeftDownTeeVector":"⥡","LeftDownVectorBar":"⥙","LeftDownVector":"⇃","LeftFloor":"⌊","leftharpoondown":"↽","leftharpoonup":"↼","leftleftarrows":"⇇","leftrightarrow":"↔","LeftRightArrow":"↔","Leftrightarrow":"⇔","leftrightarrows":"⇆","leftrightharpoons":"⇋","leftrightsquigarrow":"↭","LeftRightVector":"⥎","LeftTeeArrow":"↤","LeftTee":"⊣","LeftTeeVector":"⥚","leftthreetimes":"⋋","LeftTriangleBar":"⧏","LeftTriangle":"⊲","LeftTriangleEqual":"⊴","LeftUpDownVector":"⥑","LeftUpTeeVector":"⥠","LeftUpVectorBar":"⥘","LeftUpVector":"↿","LeftVectorBar":"⥒","LeftVector":"↼","lEg":"⪋","leg":"⋚","leq":"≤","leqq":"≦","leqslant":"⩽","lescc":"⪨","les":"⩽","lesdot":"⩿","lesdoto":"⪁","lesdotor":"⪃","lesg":"⋚︀","lesges":"⪓","lessapprox":"⪅","lessdot":"⋖","lesseqgtr":"⋚","lesseqqgtr":"⪋","LessEqualGreater":"⋚","LessFullEqual":"≦","LessGreater":"≶","lessgtr":"≶","LessLess":"⪡","lesssim":"≲","LessSlantEqual":"⩽","LessTilde":"≲","lfisht":"⥼","lfloor":"⌊","Lfr":"𝔏","lfr":"𝔩","lg":"≶","lgE":"⪑","lHar":"⥢","lhard":"↽","lharu":"↼","lharul":"⥪","lhblk":"▄","LJcy":"Љ","ljcy":"љ","llarr":"⇇","ll":"≪","Ll":"⋘","llcorner":"⌞","Lleftarrow":"⇚","llhard":"⥫","lltri":"◺","Lmidot":"Ŀ","lmidot":"ŀ","lmoustache":"⎰","lmoust":"⎰","lnap":"⪉","lnapprox":"⪉","lne":"⪇","lnE":"≨","lneq":"⪇","lneqq":"≨","lnsim":"⋦","loang":"⟬","loarr":"⇽","lobrk":"⟦","longleftarrow":"⟵","LongLeftArrow":"⟵","Longleftarrow":"⟸","longleftrightarrow":"⟷","LongLeftRightArrow":"⟷","Longleftrightarrow":"⟺","longmapsto":"⟼","longrightarrow":"⟶","LongRightArrow":"⟶","Longrightarrow":"⟹","looparrowleft":"↫","looparrowright":"↬","lopar":"⦅","Lopf":"𝕃","lopf":"𝕝","loplus":"⨭","lotimes":"⨴","lowast":"∗","lowbar":"_","LowerLeftArrow":"↙","LowerRightArrow":"↘","loz":"◊","lozenge":"◊","lozf":"⧫","lpar":"(","lparlt":"⦓","lrarr":"⇆","lrcorner":"⌟","lrhar":"⇋","lrhard":"⥭","lrm":"‎","lrtri":"⊿","lsaquo":"‹","lscr":"𝓁","Lscr":"ℒ","lsh":"↰","Lsh":"↰","lsim":"≲","lsime":"⪍","lsimg":"⪏","lsqb":"[","lsquo":"‘","lsquor":"‚","Lstrok":"Ł","lstrok":"ł","ltcc":"⪦","ltcir":"⩹","lt":"<","LT":"<","Lt":"≪","ltdot":"⋖","lthree":"⋋","ltimes":"⋉","ltlarr":"⥶","ltquest":"⩻","ltri":"◃","ltrie":"⊴","ltrif":"◂","ltrPar":"⦖","lurdshar":"⥊","luruhar":"⥦","lvertneqq":"≨︀","lvnE":"≨︀","macr":"¯","male":"♂","malt":"✠","maltese":"✠","Map":"⤅","map":"↦","mapsto":"↦","mapstodown":"↧","mapstoleft":"↤","mapstoup":"↥","marker":"▮","mcomma":"⨩","Mcy":"М","mcy":"м","mdash":"—","mDDot":"∺","measuredangle":"∡","MediumSpace":" ","Mellintrf":"ℳ","Mfr":"𝔐","mfr":"𝔪","mho":"℧","micro":"µ","midast":"*","midcir":"⫰","mid":"∣","middot":"·","minusb":"⊟","minus":"−","minusd":"∸","minusdu":"⨪","MinusPlus":"∓","mlcp":"⫛","mldr":"…","mnplus":"∓","models":"⊧","Mopf":"𝕄","mopf":"𝕞","mp":"∓","mscr":"𝓂","Mscr":"ℳ","mstpos":"∾","Mu":"Μ","mu":"μ","multimap":"⊸","mumap":"⊸","nabla":"∇","Nacute":"Ń","nacute":"ń","nang":"∠⃒","nap":"≉","napE":"⩰̸","napid":"≋̸","napos":"ʼn","napprox":"≉","natural":"♮","naturals":"ℕ","natur":"♮","nbsp":" ","nbump":"≎̸","nbumpe":"≏̸","ncap":"⩃","Ncaron":"Ň","ncaron":"ň","Ncedil":"Ņ","ncedil":"ņ","ncong":"≇","ncongdot":"⩭̸","ncup":"⩂","Ncy":"Н","ncy":"н","ndash":"–","nearhk":"⤤","nearr":"↗","neArr":"⇗","nearrow":"↗","ne":"≠","nedot":"≐̸","NegativeMediumSpace":"​","NegativeThickSpace":"​","NegativeThinSpace":"​","NegativeVeryThinSpace":"​","nequiv":"≢","nesear":"⤨","nesim":"≂̸","NestedGreaterGreater":"≫","NestedLessLess":"≪","NewLine":"\\n","nexist":"∄","nexists":"∄","Nfr":"𝔑","nfr":"𝔫","ngE":"≧̸","nge":"≱","ngeq":"≱","ngeqq":"≧̸","ngeqslant":"⩾̸","nges":"⩾̸","nGg":"⋙̸","ngsim":"≵","nGt":"≫⃒","ngt":"≯","ngtr":"≯","nGtv":"≫̸","nharr":"↮","nhArr":"⇎","nhpar":"⫲","ni":"∋","nis":"⋼","nisd":"⋺","niv":"∋","NJcy":"Њ","njcy":"њ","nlarr":"↚","nlArr":"⇍","nldr":"‥","nlE":"≦̸","nle":"≰","nleftarrow":"↚","nLeftarrow":"⇍","nleftrightarrow":"↮","nLeftrightarrow":"⇎","nleq":"≰","nleqq":"≦̸","nleqslant":"⩽̸","nles":"⩽̸","nless":"≮","nLl":"⋘̸","nlsim":"≴","nLt":"≪⃒","nlt":"≮","nltri":"⋪","nltrie":"⋬","nLtv":"≪̸","nmid":"∤","NoBreak":"⁠","NonBreakingSpace":" ","nopf":"𝕟","Nopf":"ℕ","Not":"⫬","not":"¬","NotCongruent":"≢","NotCupCap":"≭","NotDoubleVerticalBar":"∦","NotElement":"∉","NotEqual":"≠","NotEqualTilde":"≂̸","NotExists":"∄","NotGreater":"≯","NotGreaterEqual":"≱","NotGreaterFullEqual":"≧̸","NotGreaterGreater":"≫̸","NotGreaterLess":"≹","NotGreaterSlantEqual":"⩾̸","NotGreaterTilde":"≵","NotHumpDownHump":"≎̸","NotHumpEqual":"≏̸","notin":"∉","notindot":"⋵̸","notinE":"⋹̸","notinva":"∉","notinvb":"⋷","notinvc":"⋶","NotLeftTriangleBar":"⧏̸","NotLeftTriangle":"⋪","NotLeftTriangleEqual":"⋬","NotLess":"≮","NotLessEqual":"≰","NotLessGreater":"≸","NotLessLess":"≪̸","NotLessSlantEqual":"⩽̸","NotLessTilde":"≴","NotNestedGreaterGreater":"⪢̸","NotNestedLessLess":"⪡̸","notni":"∌","notniva":"∌","notnivb":"⋾","notnivc":"⋽","NotPrecedes":"⊀","NotPrecedesEqual":"⪯̸","NotPrecedesSlantEqual":"⋠","NotReverseElement":"∌","NotRightTriangleBar":"⧐̸","NotRightTriangle":"⋫","NotRightTriangleEqual":"⋭","NotSquareSubset":"⊏̸","NotSquareSubsetEqual":"⋢","NotSquareSuperset":"⊐̸","NotSquareSupersetEqual":"⋣","NotSubset":"⊂⃒","NotSubsetEqual":"⊈","NotSucceeds":"⊁","NotSucceedsEqual":"⪰̸","NotSucceedsSlantEqual":"⋡","NotSucceedsTilde":"≿̸","NotSuperset":"⊃⃒","NotSupersetEqual":"⊉","NotTilde":"≁","NotTildeEqual":"≄","NotTildeFullEqual":"≇","NotTildeTilde":"≉","NotVerticalBar":"∤","nparallel":"∦","npar":"∦","nparsl":"⫽⃥","npart":"∂̸","npolint":"⨔","npr":"⊀","nprcue":"⋠","nprec":"⊀","npreceq":"⪯̸","npre":"⪯̸","nrarrc":"⤳̸","nrarr":"↛","nrArr":"⇏","nrarrw":"↝̸","nrightarrow":"↛","nRightarrow":"⇏","nrtri":"⋫","nrtrie":"⋭","nsc":"⊁","nsccue":"⋡","nsce":"⪰̸","Nscr":"𝒩","nscr":"𝓃","nshortmid":"∤","nshortparallel":"∦","nsim":"≁","nsime":"≄","nsimeq":"≄","nsmid":"∤","nspar":"∦","nsqsube":"⋢","nsqsupe":"⋣","nsub":"⊄","nsubE":"⫅̸","nsube":"⊈","nsubset":"⊂⃒","nsubseteq":"⊈","nsubseteqq":"⫅̸","nsucc":"⊁","nsucceq":"⪰̸","nsup":"⊅","nsupE":"⫆̸","nsupe":"⊉","nsupset":"⊃⃒","nsupseteq":"⊉","nsupseteqq":"⫆̸","ntgl":"≹","Ntilde":"Ñ","ntilde":"ñ","ntlg":"≸","ntriangleleft":"⋪","ntrianglelefteq":"⋬","ntriangleright":"⋫","ntrianglerighteq":"⋭","Nu":"Ν","nu":"ν","num":"#","numero":"№","numsp":" ","nvap":"≍⃒","nvdash":"⊬","nvDash":"⊭","nVdash":"⊮","nVDash":"⊯","nvge":"≥⃒","nvgt":">⃒","nvHarr":"⤄","nvinfin":"⧞","nvlArr":"⤂","nvle":"≤⃒","nvlt":"<⃒","nvltrie":"⊴⃒","nvrArr":"⤃","nvrtrie":"⊵⃒","nvsim":"∼⃒","nwarhk":"⤣","nwarr":"↖","nwArr":"⇖","nwarrow":"↖","nwnear":"⤧","Oacute":"Ó","oacute":"ó","oast":"⊛","Ocirc":"Ô","ocirc":"ô","ocir":"⊚","Ocy":"О","ocy":"о","odash":"⊝","Odblac":"Ő","odblac":"ő","odiv":"⨸","odot":"⊙","odsold":"⦼","OElig":"Œ","oelig":"œ","ofcir":"⦿","Ofr":"𝔒","ofr":"𝔬","ogon":"˛","Ograve":"Ò","ograve":"ò","ogt":"⧁","ohbar":"⦵","ohm":"Ω","oint":"∮","olarr":"↺","olcir":"⦾","olcross":"⦻","oline":"‾","olt":"⧀","Omacr":"Ō","omacr":"ō","Omega":"Ω","omega":"ω","Omicron":"Ο","omicron":"ο","omid":"⦶","ominus":"⊖","Oopf":"𝕆","oopf":"𝕠","opar":"⦷","OpenCurlyDoubleQuote":"“","OpenCurlyQuote":"‘","operp":"⦹","oplus":"⊕","orarr":"↻","Or":"⩔","or":"∨","ord":"⩝","order":"ℴ","orderof":"ℴ","ordf":"ª","ordm":"º","origof":"⊶","oror":"⩖","orslope":"⩗","orv":"⩛","oS":"Ⓢ","Oscr":"𝒪","oscr":"ℴ","Oslash":"Ø","oslash":"ø","osol":"⊘","Otilde":"Õ","otilde":"õ","otimesas":"⨶","Otimes":"⨷","otimes":"⊗","Ouml":"Ö","ouml":"ö","ovbar":"⌽","OverBar":"‾","OverBrace":"⏞","OverBracket":"⎴","OverParenthesis":"⏜","para":"¶","parallel":"∥","par":"∥","parsim":"⫳","parsl":"⫽","part":"∂","PartialD":"∂","Pcy":"П","pcy":"п","percnt":"%","period":".","permil":"‰","perp":"⊥","pertenk":"‱","Pfr":"𝔓","pfr":"𝔭","Phi":"Φ","phi":"φ","phiv":"ϕ","phmmat":"ℳ","phone":"☎","Pi":"Π","pi":"π","pitchfork":"⋔","piv":"ϖ","planck":"ℏ","planckh":"ℎ","plankv":"ℏ","plusacir":"⨣","plusb":"⊞","pluscir":"⨢","plus":"+","plusdo":"∔","plusdu":"⨥","pluse":"⩲","PlusMinus":"±","plusmn":"±","plussim":"⨦","plustwo":"⨧","pm":"±","Poincareplane":"ℌ","pointint":"⨕","popf":"𝕡","Popf":"ℙ","pound":"£","prap":"⪷","Pr":"⪻","pr":"≺","prcue":"≼","precapprox":"⪷","prec":"≺","preccurlyeq":"≼","Precedes":"≺","PrecedesEqual":"⪯","PrecedesSlantEqual":"≼","PrecedesTilde":"≾","preceq":"⪯","precnapprox":"⪹","precneqq":"⪵","precnsim":"⋨","pre":"⪯","prE":"⪳","precsim":"≾","prime":"′","Prime":"″","primes":"ℙ","prnap":"⪹","prnE":"⪵","prnsim":"⋨","prod":"∏","Product":"∏","profalar":"⌮","profline":"⌒","profsurf":"⌓","prop":"∝","Proportional":"∝","Proportion":"∷","propto":"∝","prsim":"≾","prurel":"⊰","Pscr":"𝒫","pscr":"𝓅","Psi":"Ψ","psi":"ψ","puncsp":" ","Qfr":"𝔔","qfr":"𝔮","qint":"⨌","qopf":"𝕢","Qopf":"ℚ","qprime":"⁗","Qscr":"𝒬","qscr":"𝓆","quaternions":"ℍ","quatint":"⨖","quest":"?","questeq":"≟","quot":"\\"","QUOT":"\\"","rAarr":"⇛","race":"∽̱","Racute":"Ŕ","racute":"ŕ","radic":"√","raemptyv":"⦳","rang":"⟩","Rang":"⟫","rangd":"⦒","range":"⦥","rangle":"⟩","raquo":"»","rarrap":"⥵","rarrb":"⇥","rarrbfs":"⤠","rarrc":"⤳","rarr":"→","Rarr":"↠","rArr":"⇒","rarrfs":"⤞","rarrhk":"↪","rarrlp":"↬","rarrpl":"⥅","rarrsim":"⥴","Rarrtl":"⤖","rarrtl":"↣","rarrw":"↝","ratail":"⤚","rAtail":"⤜","ratio":"∶","rationals":"ℚ","rbarr":"⤍","rBarr":"⤏","RBarr":"⤐","rbbrk":"❳","rbrace":"}","rbrack":"]","rbrke":"⦌","rbrksld":"⦎","rbrkslu":"⦐","Rcaron":"Ř","rcaron":"ř","Rcedil":"Ŗ","rcedil":"ŗ","rceil":"⌉","rcub":"}","Rcy":"Р","rcy":"р","rdca":"⤷","rdldhar":"⥩","rdquo":"”","rdquor":"”","rdsh":"↳","real":"ℜ","realine":"ℛ","realpart":"ℜ","reals":"ℝ","Re":"ℜ","rect":"▭","reg":"®","REG":"®","ReverseElement":"∋","ReverseEquilibrium":"⇋","ReverseUpEquilibrium":"⥯","rfisht":"⥽","rfloor":"⌋","rfr":"𝔯","Rfr":"ℜ","rHar":"⥤","rhard":"⇁","rharu":"⇀","rharul":"⥬","Rho":"Ρ","rho":"ρ","rhov":"ϱ","RightAngleBracket":"⟩","RightArrowBar":"⇥","rightarrow":"→","RightArrow":"→","Rightarrow":"⇒","RightArrowLeftArrow":"⇄","rightarrowtail":"↣","RightCeiling":"⌉","RightDoubleBracket":"⟧","RightDownTeeVector":"⥝","RightDownVectorBar":"⥕","RightDownVector":"⇂","RightFloor":"⌋","rightharpoondown":"⇁","rightharpoonup":"⇀","rightleftarrows":"⇄","rightleftharpoons":"⇌","rightrightarrows":"⇉","rightsquigarrow":"↝","RightTeeArrow":"↦","RightTee":"⊢","RightTeeVector":"⥛","rightthreetimes":"⋌","RightTriangleBar":"⧐","RightTriangle":"⊳","RightTriangleEqual":"⊵","RightUpDownVector":"⥏","RightUpTeeVector":"⥜","RightUpVectorBar":"⥔","RightUpVector":"↾","RightVectorBar":"⥓","RightVector":"⇀","ring":"˚","risingdotseq":"≓","rlarr":"⇄","rlhar":"⇌","rlm":"‏","rmoustache":"⎱","rmoust":"⎱","rnmid":"⫮","roang":"⟭","roarr":"⇾","robrk":"⟧","ropar":"⦆","ropf":"𝕣","Ropf":"ℝ","roplus":"⨮","rotimes":"⨵","RoundImplies":"⥰","rpar":")","rpargt":"⦔","rppolint":"⨒","rrarr":"⇉","Rrightarrow":"⇛","rsaquo":"›","rscr":"𝓇","Rscr":"ℛ","rsh":"↱","Rsh":"↱","rsqb":"]","rsquo":"’","rsquor":"’","rthree":"⋌","rtimes":"⋊","rtri":"▹","rtrie":"⊵","rtrif":"▸","rtriltri":"⧎","RuleDelayed":"⧴","ruluhar":"⥨","rx":"℞","Sacute":"Ś","sacute":"ś","sbquo":"‚","scap":"⪸","Scaron":"Š","scaron":"š","Sc":"⪼","sc":"≻","sccue":"≽","sce":"⪰","scE":"⪴","Scedil":"Ş","scedil":"ş","Scirc":"Ŝ","scirc":"ŝ","scnap":"⪺","scnE":"⪶","scnsim":"⋩","scpolint":"⨓","scsim":"≿","Scy":"С","scy":"с","sdotb":"⊡","sdot":"⋅","sdote":"⩦","searhk":"⤥","searr":"↘","seArr":"⇘","searrow":"↘","sect":"§","semi":";","seswar":"⤩","setminus":"∖","setmn":"∖","sext":"✶","Sfr":"𝔖","sfr":"𝔰","sfrown":"⌢","sharp":"♯","SHCHcy":"Щ","shchcy":"щ","SHcy":"Ш","shcy":"ш","ShortDownArrow":"↓","ShortLeftArrow":"←","shortmid":"∣","shortparallel":"∥","ShortRightArrow":"→","ShortUpArrow":"↑","shy":"­","Sigma":"Σ","sigma":"σ","sigmaf":"ς","sigmav":"ς","sim":"∼","simdot":"⩪","sime":"≃","simeq":"≃","simg":"⪞","simgE":"⪠","siml":"⪝","simlE":"⪟","simne":"≆","simplus":"⨤","simrarr":"⥲","slarr":"←","SmallCircle":"∘","smallsetminus":"∖","smashp":"⨳","smeparsl":"⧤","smid":"∣","smile":"⌣","smt":"⪪","smte":"⪬","smtes":"⪬︀","SOFTcy":"Ь","softcy":"ь","solbar":"⌿","solb":"⧄","sol":"/","Sopf":"𝕊","sopf":"𝕤","spades":"♠","spadesuit":"♠","spar":"∥","sqcap":"⊓","sqcaps":"⊓︀","sqcup":"⊔","sqcups":"⊔︀","Sqrt":"√","sqsub":"⊏","sqsube":"⊑","sqsubset":"⊏","sqsubseteq":"⊑","sqsup":"⊐","sqsupe":"⊒","sqsupset":"⊐","sqsupseteq":"⊒","square":"□","Square":"□","SquareIntersection":"⊓","SquareSubset":"⊏","SquareSubsetEqual":"⊑","SquareSuperset":"⊐","SquareSupersetEqual":"⊒","SquareUnion":"⊔","squarf":"▪","squ":"□","squf":"▪","srarr":"→","Sscr":"𝒮","sscr":"𝓈","ssetmn":"∖","ssmile":"⌣","sstarf":"⋆","Star":"⋆","star":"☆","starf":"★","straightepsilon":"ϵ","straightphi":"ϕ","strns":"¯","sub":"⊂","Sub":"⋐","subdot":"⪽","subE":"⫅","sube":"⊆","subedot":"⫃","submult":"⫁","subnE":"⫋","subne":"⊊","subplus":"⪿","subrarr":"⥹","subset":"⊂","Subset":"⋐","subseteq":"⊆","subseteqq":"⫅","SubsetEqual":"⊆","subsetneq":"⊊","subsetneqq":"⫋","subsim":"⫇","subsub":"⫕","subsup":"⫓","succapprox":"⪸","succ":"≻","succcurlyeq":"≽","Succeeds":"≻","SucceedsEqual":"⪰","SucceedsSlantEqual":"≽","SucceedsTilde":"≿","succeq":"⪰","succnapprox":"⪺","succneqq":"⪶","succnsim":"⋩","succsim":"≿","SuchThat":"∋","sum":"∑","Sum":"∑","sung":"♪","sup1":"¹","sup2":"²","sup3":"³","sup":"⊃","Sup":"⋑","supdot":"⪾","supdsub":"⫘","supE":"⫆","supe":"⊇","supedot":"⫄","Superset":"⊃","SupersetEqual":"⊇","suphsol":"⟉","suphsub":"⫗","suplarr":"⥻","supmult":"⫂","supnE":"⫌","supne":"⊋","supplus":"⫀","supset":"⊃","Supset":"⋑","supseteq":"⊇","supseteqq":"⫆","supsetneq":"⊋","supsetneqq":"⫌","supsim":"⫈","supsub":"⫔","supsup":"⫖","swarhk":"⤦","swarr":"↙","swArr":"⇙","swarrow":"↙","swnwar":"⤪","szlig":"ß","Tab":"\\t","target":"⌖","Tau":"Τ","tau":"τ","tbrk":"⎴","Tcaron":"Ť","tcaron":"ť","Tcedil":"Ţ","tcedil":"ţ","Tcy":"Т","tcy":"т","tdot":"⃛","telrec":"⌕","Tfr":"𝔗","tfr":"𝔱","there4":"∴","therefore":"∴","Therefore":"∴","Theta":"Θ","theta":"θ","thetasym":"ϑ","thetav":"ϑ","thickapprox":"≈","thicksim":"∼","ThickSpace":"  ","ThinSpace":" ","thinsp":" ","thkap":"≈","thksim":"∼","THORN":"Þ","thorn":"þ","tilde":"˜","Tilde":"∼","TildeEqual":"≃","TildeFullEqual":"≅","TildeTilde":"≈","timesbar":"⨱","timesb":"⊠","times":"×","timesd":"⨰","tint":"∭","toea":"⤨","topbot":"⌶","topcir":"⫱","top":"⊤","Topf":"𝕋","topf":"𝕥","topfork":"⫚","tosa":"⤩","tprime":"‴","trade":"™","TRADE":"™","triangle":"▵","triangledown":"▿","triangleleft":"◃","trianglelefteq":"⊴","triangleq":"≜","triangleright":"▹","trianglerighteq":"⊵","tridot":"◬","trie":"≜","triminus":"⨺","TripleDot":"⃛","triplus":"⨹","trisb":"⧍","tritime":"⨻","trpezium":"⏢","Tscr":"𝒯","tscr":"𝓉","TScy":"Ц","tscy":"ц","TSHcy":"Ћ","tshcy":"ћ","Tstrok":"Ŧ","tstrok":"ŧ","twixt":"≬","twoheadleftarrow":"↞","twoheadrightarrow":"↠","Uacute":"Ú","uacute":"ú","uarr":"↑","Uarr":"↟","uArr":"⇑","Uarrocir":"⥉","Ubrcy":"Ў","ubrcy":"ў","Ubreve":"Ŭ","ubreve":"ŭ","Ucirc":"Û","ucirc":"û","Ucy":"У","ucy":"у","udarr":"⇅","Udblac":"Ű","udblac":"ű","udhar":"⥮","ufisht":"⥾","Ufr":"𝔘","ufr":"𝔲","Ugrave":"Ù","ugrave":"ù","uHar":"⥣","uharl":"↿","uharr":"↾","uhblk":"▀","ulcorn":"⌜","ulcorner":"⌜","ulcrop":"⌏","ultri":"◸","Umacr":"Ū","umacr":"ū","uml":"¨","UnderBar":"_","UnderBrace":"⏟","UnderBracket":"⎵","UnderParenthesis":"⏝","Union":"⋃","UnionPlus":"⊎","Uogon":"Ų","uogon":"ų","Uopf":"𝕌","uopf":"𝕦","UpArrowBar":"⤒","uparrow":"↑","UpArrow":"↑","Uparrow":"⇑","UpArrowDownArrow":"⇅","updownarrow":"↕","UpDownArrow":"↕","Updownarrow":"⇕","UpEquilibrium":"⥮","upharpoonleft":"↿","upharpoonright":"↾","uplus":"⊎","UpperLeftArrow":"↖","UpperRightArrow":"↗","upsi":"υ","Upsi":"ϒ","upsih":"ϒ","Upsilon":"Υ","upsilon":"υ","UpTeeArrow":"↥","UpTee":"⊥","upuparrows":"⇈","urcorn":"⌝","urcorner":"⌝","urcrop":"⌎","Uring":"Ů","uring":"ů","urtri":"◹","Uscr":"𝒰","uscr":"𝓊","utdot":"⋰","Utilde":"Ũ","utilde":"ũ","utri":"▵","utrif":"▴","uuarr":"⇈","Uuml":"Ü","uuml":"ü","uwangle":"⦧","vangrt":"⦜","varepsilon":"ϵ","varkappa":"ϰ","varnothing":"∅","varphi":"ϕ","varpi":"ϖ","varpropto":"∝","varr":"↕","vArr":"⇕","varrho":"ϱ","varsigma":"ς","varsubsetneq":"⊊︀","varsubsetneqq":"⫋︀","varsupsetneq":"⊋︀","varsupsetneqq":"⫌︀","vartheta":"ϑ","vartriangleleft":"⊲","vartriangleright":"⊳","vBar":"⫨","Vbar":"⫫","vBarv":"⫩","Vcy":"В","vcy":"в","vdash":"⊢","vDash":"⊨","Vdash":"⊩","VDash":"⊫","Vdashl":"⫦","veebar":"⊻","vee":"∨","Vee":"⋁","veeeq":"≚","vellip":"⋮","verbar":"|","Verbar":"‖","vert":"|","Vert":"‖","VerticalBar":"∣","VerticalLine":"|","VerticalSeparator":"❘","VerticalTilde":"≀","VeryThinSpace":" ","Vfr":"𝔙","vfr":"𝔳","vltri":"⊲","vnsub":"⊂⃒","vnsup":"⊃⃒","Vopf":"𝕍","vopf":"𝕧","vprop":"∝","vrtri":"⊳","Vscr":"𝒱","vscr":"𝓋","vsubnE":"⫋︀","vsubne":"⊊︀","vsupnE":"⫌︀","vsupne":"⊋︀","Vvdash":"⊪","vzigzag":"⦚","Wcirc":"Ŵ","wcirc":"ŵ","wedbar":"⩟","wedge":"∧","Wedge":"⋀","wedgeq":"≙","weierp":"℘","Wfr":"𝔚","wfr":"𝔴","Wopf":"𝕎","wopf":"𝕨","wp":"℘","wr":"≀","wreath":"≀","Wscr":"𝒲","wscr":"𝓌","xcap":"⋂","xcirc":"◯","xcup":"⋃","xdtri":"▽","Xfr":"𝔛","xfr":"𝔵","xharr":"⟷","xhArr":"⟺","Xi":"Ξ","xi":"ξ","xlarr":"⟵","xlArr":"⟸","xmap":"⟼","xnis":"⋻","xodot":"⨀","Xopf":"𝕏","xopf":"𝕩","xoplus":"⨁","xotime":"⨂","xrarr":"⟶","xrArr":"⟹","Xscr":"𝒳","xscr":"𝓍","xsqcup":"⨆","xuplus":"⨄","xutri":"△","xvee":"⋁","xwedge":"⋀","Yacute":"Ý","yacute":"ý","YAcy":"Я","yacy":"я","Ycirc":"Ŷ","ycirc":"ŷ","Ycy":"Ы","ycy":"ы","yen":"¥","Yfr":"𝔜","yfr":"𝔶","YIcy":"Ї","yicy":"ї","Yopf":"𝕐","yopf":"𝕪","Yscr":"𝒴","yscr":"𝓎","YUcy":"Ю","yucy":"ю","yuml":"ÿ","Yuml":"Ÿ","Zacute":"Ź","zacute":"ź","Zcaron":"Ž","zcaron":"ž","Zcy":"З","zcy":"з","Zdot":"Ż","zdot":"ż","zeetrf":"ℨ","ZeroWidthSpace":"​","Zeta":"Ζ","zeta":"ζ","zfr":"𝔷","Zfr":"ℨ","ZHcy":"Ж","zhcy":"ж","zigrarr":"⇝","zopf":"𝕫","Zopf":"ℤ","Zscr":"𝒵","zscr":"𝓏","zwj":"‍","zwnj":"‌"}')},2836:e=>{"use strict";e.exports=JSON.parse('{"Aacute":"Á","aacute":"á","Acirc":"Â","acirc":"â","acute":"´","AElig":"Æ","aelig":"æ","Agrave":"À","agrave":"à","amp":"&","AMP":"&","Aring":"Å","aring":"å","Atilde":"Ã","atilde":"ã","Auml":"Ä","auml":"ä","brvbar":"¦","Ccedil":"Ç","ccedil":"ç","cedil":"¸","cent":"¢","copy":"©","COPY":"©","curren":"¤","deg":"°","divide":"÷","Eacute":"É","eacute":"é","Ecirc":"Ê","ecirc":"ê","Egrave":"È","egrave":"è","ETH":"Ð","eth":"ð","Euml":"Ë","euml":"ë","frac12":"½","frac14":"¼","frac34":"¾","gt":">","GT":">","Iacute":"Í","iacute":"í","Icirc":"Î","icirc":"î","iexcl":"¡","Igrave":"Ì","igrave":"ì","iquest":"¿","Iuml":"Ï","iuml":"ï","laquo":"«","lt":"<","LT":"<","macr":"¯","micro":"µ","middot":"·","nbsp":" ","not":"¬","Ntilde":"Ñ","ntilde":"ñ","Oacute":"Ó","oacute":"ó","Ocirc":"Ô","ocirc":"ô","Ograve":"Ò","ograve":"ò","ordf":"ª","ordm":"º","Oslash":"Ø","oslash":"ø","Otilde":"Õ","otilde":"õ","Ouml":"Ö","ouml":"ö","para":"¶","plusmn":"±","pound":"£","quot":"\\"","QUOT":"\\"","raquo":"»","reg":"®","REG":"®","sect":"§","shy":"­","sup1":"¹","sup2":"²","sup3":"³","szlig":"ß","THORN":"Þ","thorn":"þ","times":"×","Uacute":"Ú","uacute":"ú","Ucirc":"Û","ucirc":"û","Ugrave":"Ù","ugrave":"ù","uml":"¨","Uuml":"Ü","uuml":"ü","Yacute":"Ý","yacute":"ý","yen":"¥","yuml":"ÿ"}')},8689:e=>{"use strict";e.exports=JSON.parse('{"amp":"&","apos":"\'","gt":">","lt":"<","quot":"\\""}')}},__webpack_module_cache__={};function __webpack_require__(e){var t=__webpack_module_cache__[e];if(void 0!==t)return t.exports;var i=__webpack_module_cache__[e]={exports:{}};return __webpack_modules__[e].call(i.exports,i,i.exports,__webpack_require__),i.exports}__webpack_require__.n=e=>{var t=e&&e.__esModule?()=>e.default:()=>e;return __webpack_require__.d(t,{a:t}),t},__webpack_require__.d=(e,t)=>{for(var i in t)__webpack_require__.o(t,i)&&!__webpack_require__.o(e,i)&&Object.defineProperty(e,i,{enumerable:!0,get:t[i]})},__webpack_require__.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(e){if("object"==typeof window)return window}}(),__webpack_require__.o=(e,t)=>Object.prototype.hasOwnProperty.call(e,t),__webpack_require__.r=e=>{"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})};var __webpack_exports__={};(()=>{"use strict";class e{lineAt(e){if(e<0||e>this.length)throw new RangeError(`Invalid position ${e} in document of length ${this.length}`);return this.lineInner(e,!1,1,0)}line(e){if(e<1||e>this.lines)throw new RangeError(`Invalid line number ${e} in ${this.lines}-line document`);return this.lineInner(e,!0,1,0)}replace(e,t,n){let s=[];return this.decompose(0,e,s,2),n.length&&n.decompose(0,n.length,s,3),this.decompose(t,this.length,s,1),i.from(s,this.length-(t-e)+n.length)}append(e){return this.replace(this.length,this.length,e)}slice(e,t=this.length){let n=[];return this.decompose(e,t,n,0),i.from(n,t-e)}eq(e){if(e==this)return!0;if(e.length!=this.length||e.lines!=this.lines)return!1;let t=this.scanIdentical(e,1),i=this.length-this.scanIdentical(e,-1),n=new r(this),s=new r(e);for(let e=t,r=t;;){if(n.next(e),s.next(e),e=0,n.lineBreak!=s.lineBreak||n.done!=s.done||n.value!=s.value)return!1;if(r+=n.value.length,n.done||r>=i)return!0}}iter(e=1){return new r(this,e)}iterRange(e,t=this.length){return new o(this,e,t)}iterLines(e,t){let i;if(null==e)i=this.iter();else{null==t&&(t=this.lines+1);let n=this.line(e).from;i=this.iterRange(n,Math.max(n,t==this.lines+1?this.length:t<=1?0:this.line(t-1).to))}return new a(i)}toString(){return this.sliceString(0)}toJSON(){let e=[];return this.flatten(e),e}constructor(){}static of(n){if(0==n.length)throw new RangeError("A document must have at least one line");return 1!=n.length||n[0]?n.length<=32?new t(n):i.from(t.split(n,[])):e.empty}}class t extends e{constructor(e,t=function(e){let t=-1;for(let i of e)t+=i.length+1;return t}(e)){super(),this.text=e,this.length=t}get lines(){return this.text.length}get children(){return null}lineInner(e,t,i,n){for(let s=0;;s++){let r=this.text[s],o=n+r.length;if((t?i:o)>=e)return new l(n,o,i,r);n=o+1,i++}}decompose(e,i,r,o){let a=e<=0&&i>=this.length?this:new t(s(this.text,e,i),Math.min(i,this.length)-Math.max(0,e));if(1&o){let e=r.pop(),i=n(a.text,e.text.slice(),0,a.length);if(i.length<=32)r.push(new t(i,e.length+a.length));else{let e=i.length>>1;r.push(new t(i.slice(0,e)),new t(i.slice(e)))}}else r.push(a)}replace(e,r,o){if(!(o instanceof t))return super.replace(e,r,o);let a=n(this.text,n(o.text,s(this.text,0,e)),r),l=this.length+o.length-(r-e);return a.length<=32?new t(a,l):i.from(t.split(a,[]),l)}sliceString(e,t=this.length,i="\n"){let n="";for(let s=0,r=0;s<=t&&re&&r&&(n+=i),es&&(n+=o.slice(Math.max(0,e-s),t-s)),s=a+1}return n}flatten(e){for(let t of this.text)e.push(t)}scanIdentical(){return 0}static split(e,i){let n=[],s=-1;for(let r of e)n.push(r),s+=r.length+1,32==n.length&&(i.push(new t(n,s)),n=[],s=-1);return s>-1&&i.push(new t(n,s)),i}}class i extends e{constructor(e,t){super(),this.children=e,this.length=t,this.lines=0;for(let t of e)this.lines+=t.lines}lineInner(e,t,i,n){for(let s=0;;s++){let r=this.children[s],o=n+r.length,a=i+r.lines-1;if((t?a:o)>=e)return r.lineInner(e,t,i,n);n=o+1,i=a+1}}decompose(e,t,i,n){for(let s=0,r=0;r<=t&&s=r){let s=n&((r<=e?1:0)|(a>=t?2:0));r>=e&&a<=t&&!s?i.push(o):o.decompose(e-r,t-r,i,s)}r=a+1}}replace(e,t,n){if(n.lines=r&&t<=a){let l=o.replace(e-r,t-r,n),h=this.lines-o.lines+l.lines;if(l.lines>4&&l.lines>h>>6){let r=this.children.slice();return r[s]=l,new i(r,this.length-(t-e)+n.length)}return super.replace(r,a,l)}r=a+1}return super.replace(e,t,n)}sliceString(e,t=this.length,i="\n"){let n="";for(let s=0,r=0;se&&s&&(n+=i),er&&(n+=o.sliceString(e-r,t-r,i)),r=a+1}return n}flatten(e){for(let t of this.children)t.flatten(e)}scanIdentical(e,t){if(!(e instanceof i))return 0;let n=0,[s,r,o,a]=t>0?[0,0,this.children.length,e.children.length]:[this.children.length-1,e.children.length-1,-1,-1];for(;;s+=t,r+=t){if(s==o||r==a)return n;let i=this.children[s],l=e.children[r];if(i!=l)return n+i.scanIdentical(l,t);n+=i.length+1}}static from(e,n=e.reduce(((e,t)=>e+t.length+1),-1)){let s=0;for(let t of e)s+=t.lines;if(s<32){let i=[];for(let t of e)t.flatten(i);return new t(i,n)}let r=Math.max(32,s>>5),o=r<<1,a=r>>1,l=[],h=0,c=-1,d=[];function u(e){let n;if(e.lines>o&&e instanceof i)for(let t of e.children)u(t);else e.lines>a&&(h>a||!h)?(p(),l.push(e)):e instanceof t&&h&&(n=d[d.length-1])instanceof t&&e.lines+n.lines<=32?(h+=e.lines,c+=e.length+1,d[d.length-1]=new t(n.text.concat(e.text),n.length+1+e.length)):(h+e.lines>r&&p(),h+=e.lines,c+=e.length+1,d.push(e))}function p(){0!=h&&(l.push(1==d.length?d[0]:i.from(d,c)),c=-1,h=d.length=0)}for(let t of e)u(t);return p(),1==l.length?l[0]:new i(l,n)}}function n(e,t,i=0,n=1e9){for(let s=0,r=0,o=!0;r=i&&(l>n&&(a=a.slice(0,n-s)),s0?1:(e instanceof t?e.text.length:e.children.length)<<1]}nextInner(e,i){for(this.done=this.lineBreak=!1;;){let n=this.nodes.length-1,s=this.nodes[n],r=this.offsets[n],o=r>>1,a=s instanceof t?s.text.length:s.children.length;if(o==(i>0?a:0)){if(0==n)return this.done=!0,this.value="",this;i>0&&this.offsets[n-1]++,this.nodes.pop(),this.offsets.pop()}else if((1&r)==(i>0?0:1)){if(this.offsets[n]+=i,0==e)return this.lineBreak=!0,this.value="\n",this;e--}else if(s instanceof t){let t=s.text[o+(i<0?-1:0)];if(this.offsets[n]+=i,t.length>Math.max(0,e))return this.value=0==e?t:i>0?t.slice(e):t.slice(0,t.length-e),this;e-=t.length}else{let r=s.children[o+(i<0?-1:0)];e>r.length?(e-=r.length,this.offsets[n]+=i):(i<0&&this.offsets[n]--,this.nodes.push(r),this.offsets.push(i>0?1:(r instanceof t?r.text.length:r.children.length)<<1))}}}next(e=0){return e<0&&(this.nextInner(-e,-this.dir),e=this.value.length),this.nextInner(e,this.dir)}}class o{constructor(e,t,i){this.value="",this.done=!1,this.cursor=new r(e,t>i?-1:1),this.pos=t>i?e.length:0,this.from=Math.min(t,i),this.to=Math.max(t,i)}nextInner(e,t){if(t<0?this.pos<=this.from:this.pos>=this.to)return this.value="",this.done=!0,this;e+=Math.max(0,t<0?this.pos-this.to:this.from-this.pos);let i=t<0?this.pos-this.from:this.to-this.pos;e>i&&(e=i),i-=e;let{value:n}=this.cursor.next(e);return this.pos+=(n.length+e)*t,this.value=n.length<=i?n:t<0?n.slice(n.length-i):n.slice(0,i),this.done=!this.value,this}next(e=0){return e<0?e=Math.max(e,this.from-this.pos):e>0&&(e=Math.min(e,this.to-this.pos)),this.nextInner(e,this.cursor.dir)}get lineBreak(){return this.cursor.lineBreak&&""!=this.value}}class a{constructor(e){this.inner=e,this.afterBreak=!0,this.value="",this.done=!1}next(e=0){let{done:t,lineBreak:i,value:n}=this.inner.next(e);return t?(this.done=!0,this.value=""):i?this.afterBreak?this.value="":(this.afterBreak=!0,this.next()):(this.value=n,this.afterBreak=!1),this}get lineBreak(){return!1}}"undefined"!=typeof Symbol&&(e.prototype[Symbol.iterator]=function(){return this.iter()},r.prototype[Symbol.iterator]=o.prototype[Symbol.iterator]=a.prototype[Symbol.iterator]=function(){return this});class l{constructor(e,t,i,n){this.from=e,this.to=t,this.number=i,this.text=n}get length(){return this.to-this.from}}let h="lc,34,7n,7,7b,19,,,,2,,2,,,20,b,1c,l,g,,2t,7,2,6,2,2,,4,z,,u,r,2j,b,1m,9,9,,o,4,,9,,3,,5,17,3,3b,f,,w,1j,,,,4,8,4,,3,7,a,2,t,,1m,,,,2,4,8,,9,,a,2,q,,2,2,1l,,4,2,4,2,2,3,3,,u,2,3,,b,2,1l,,4,5,,2,4,,k,2,m,6,,,1m,,,2,,4,8,,7,3,a,2,u,,1n,,,,c,,9,,14,,3,,1l,3,5,3,,4,7,2,b,2,t,,1m,,2,,2,,3,,5,2,7,2,b,2,s,2,1l,2,,,2,4,8,,9,,a,2,t,,20,,4,,2,3,,,8,,29,,2,7,c,8,2q,,2,9,b,6,22,2,r,,,,,,1j,e,,5,,2,5,b,,10,9,,2u,4,,6,,2,2,2,p,2,4,3,g,4,d,,2,2,6,,f,,jj,3,qa,3,t,3,t,2,u,2,1s,2,,7,8,,2,b,9,,19,3,3b,2,y,,3a,3,4,2,9,,6,3,63,2,2,,1m,,,7,,,,,2,8,6,a,2,,1c,h,1r,4,1c,7,,,5,,14,9,c,2,w,4,2,2,,3,1k,,,2,3,,,3,1m,8,2,2,48,3,,d,,7,4,,6,,3,2,5i,1m,,5,ek,,5f,x,2da,3,3x,,2o,w,fe,6,2x,2,n9w,4,,a,w,2,28,2,7k,,3,,4,,p,2,5,,47,2,q,i,d,,12,8,p,b,1a,3,1c,,2,4,2,2,13,,1v,6,2,2,2,2,c,,8,,1b,,1f,,,3,2,2,5,2,,,16,2,8,,6m,,2,,4,,fn4,,kh,g,g,g,a6,2,gt,,6a,,45,5,1ae,3,,2,5,4,14,3,4,,4l,2,fx,4,ar,2,49,b,4w,,1i,f,1k,3,1d,4,2,2,1x,3,10,5,,8,1q,,c,2,1g,9,a,4,2,,2n,3,2,,,2,6,,4g,,3,8,l,2,1l,2,,,,,m,,e,7,3,5,5f,8,2,3,,,n,,29,,2,6,,,2,,,2,,2,6j,,2,4,6,2,,2,r,2,2d,8,2,,,2,2y,,,,2,6,,,2t,3,2,4,,5,77,9,,2,6t,,a,2,,,4,,40,4,2,2,4,,w,a,14,6,2,4,8,,9,6,2,3,1a,d,,2,ba,7,,6,,,2a,m,2,7,,2,,2,3e,6,3,,,2,,7,,,20,2,3,,,,9n,2,f0b,5,1n,7,t4,,1r,4,29,,f5k,2,43q,,,3,4,5,8,8,2,7,u,4,44,3,1iz,1j,4,1e,8,,e,,m,5,,f,11s,7,,h,2,7,,2,,5,79,7,c5,4,15s,7,31,7,240,5,gx7k,2o,3k,6o".split(",").map((e=>e?parseInt(e,36):1));for(let e=1;ee)return h[t-1]<=e;return!1}function d(e){return e>=127462&&e<=127487}const u=8205;function p(e,t,i=!0,n=!0){return(i?f:m)(e,t,n)}function f(e,t,i){if(t==e.length)return t;t&&g(e.charCodeAt(t))&&v(e.charCodeAt(t-1))&&t--;let n=O(e,t);for(t+=_(n);t=0&&d(O(e,n));)i++,n-=2;if(i%2==0)break;t+=2}}}return t}function m(e,t,i){for(;t>0;){let n=f(e,t-2,i);if(n=56320&&e<57344}function v(e){return e>=55296&&e<56320}function O(e,t){let i=e.charCodeAt(t);if(!v(i)||t+1==e.length)return i;let n=e.charCodeAt(t+1);return g(n)?n-56320+(i-55296<<10)+65536:i}function b(e){return e<=65535?String.fromCharCode(e):(e-=65536,String.fromCharCode(55296+(e>>10),56320+(1023&e)))}function _(e){return e<65536?1:2}const y=/\r\n?|\n/;var w=function(e){return e[e.Simple=0]="Simple",e[e.TrackDel=1]="TrackDel",e[e.TrackBefore=2]="TrackBefore",e[e.TrackAfter=3]="TrackAfter",e}(w||(w={}));class x{constructor(e){this.sections=e}get length(){let e=0;for(let t=0;te)return s+(e-n);s+=o}else{if(i!=w.Simple&&l>=e&&(i==w.TrackDel&&ne||i==w.TrackBefore&&ne))return null;if(l>e||l==e&&t<0&&!o)return e==n||t<0?s:s+a;s+=a}n=l}if(e>n)throw new RangeError(`Position ${e} is out of range for changeset of length ${n}`);return s}touchesRange(e,t=e){for(let i=0,n=0;i=0&&n<=t&&s>=e)return!(nt)||"cover";n=s}return!1}toString(){let e="";for(let t=0;t=0?":"+n:"")}return e}toJSON(){return this.sections}static fromJSON(e){if(!Array.isArray(e)||e.length%2||e.some((e=>"number"!=typeof e)))throw new RangeError("Invalid JSON representation of ChangeDesc");return new x(e)}static create(e){return new x(e)}}class S extends x{constructor(e,t){super(e),this.inserted=t}apply(e){if(this.length!=e.length)throw new RangeError("Applying change set to a document with the wrong length");return C(this,((t,i,n,s,r)=>e=e.replace(n,n+(i-t),r)),!1),e}mapDesc(e,t=!1){return P(this,e,t,!0)}invert(t){let i=this.sections.slice(),n=[];for(let s=0,r=0;s=0){i[s]=a,i[s+1]=o;let l=s>>1;for(;n.length0&&T(i,t,s.text),s.forward(e),o+=e}let l=e[r++];for(;o>1].toJSON()))}return e}static of(t,i,n){let s=[],r=[],o=0,a=null;function l(e=!1){if(!e&&!s.length)return;oa||t<0||a>i)throw new RangeError(`Invalid change range ${t} to ${a} (in doc of length ${i})`);let d=c?"string"==typeof c?e.of(c.split(n||y)):c:e.empty,u=d.length;if(t==a&&0==u)return;to&&k(s,t-o,-1),k(s,a-t,u),T(r,s,d),o=a}}(t),l(!a),a}static empty(e){return new S(e?[e,-1]:[],[])}static fromJSON(t){if(!Array.isArray(t))throw new RangeError("Invalid JSON representation of ChangeSet");let i=[],n=[];for(let s=0;st&&"string"!=typeof e)))throw new RangeError("Invalid JSON representation of ChangeSet");if(1==r.length)i.push(r[0],0);else{for(;n.length=0&&i<=0&&i==e[s+1]?e[s]+=t:0==t&&0==e[s]?e[s+1]+=i:n?(e[s]+=t,e[s+1]+=i):e.push(t,i)}function T(t,i,n){if(0==n.length)return;let s=i.length-2>>1;if(s>1])),!(n||a==t.sections.length||t.sections[a+1]<0);)l=t.sections[a++],h=t.sections[a++];i(r,c,o,d,u),r=c,o=d}}}function P(e,t,i,n=!1){let s=[],r=n?[]:null,o=new E(e),a=new E(t);for(let e=-1;;)if(-1==o.ins&&-1==a.ins){let e=Math.min(o.len,a.len);k(s,e,-1),o.forward(e),a.forward(e)}else if(a.ins>=0&&(o.ins<0||e==o.i||0==o.off&&(a.len=0&&e=0)){if(o.done&&a.done)return r?S.createSet(s,r):x.create(s);throw new Error("Mismatched change set lengths")}{let t=0,i=o.len;for(;i;)if(-1==a.ins){let e=Math.min(i,a.len);t+=e,i-=e,a.forward(e)}else{if(!(0==a.ins&&a.lent||o.ins>=0&&o.len>t)&&(e||n.length>i),r.forward2(t),o.forward(t)}}else k(n,0,o.ins,e),s&&T(s,n,o.text),o.next()}}class E{constructor(e){this.set=e,this.i=0,this.next()}next(){let{sections:e}=this.set;this.i>1;return i>=t.length?e.empty:t[i]}textBit(t){let{inserted:i}=this.set,n=this.i-2>>1;return n>=i.length&&!t?e.empty:i[n].slice(this.off,null==t?void 0:this.off+t)}forward(e){e==this.len?this.next():(this.len-=e,this.off+=e)}forward2(e){-1==this.ins?this.forward(e):e==this.ins?this.next():(this.ins-=e,this.off+=e)}}class A{constructor(e,t,i){this.from=e,this.to=t,this.flags=i}get anchor(){return 32&this.flags?this.to:this.from}get head(){return 32&this.flags?this.from:this.to}get empty(){return this.from==this.to}get assoc(){return 8&this.flags?-1:16&this.flags?1:0}get bidiLevel(){let e=7&this.flags;return 7==e?null:e}get goalColumn(){let e=this.flags>>6;return 16777215==e?void 0:e}map(e,t=-1){let i,n;return this.empty?i=n=e.mapPos(this.from,t):(i=e.mapPos(this.from,1),n=e.mapPos(this.to,-1)),i==this.from&&n==this.to?this:new A(i,n,this.flags)}extend(e,t=e){if(e<=this.anchor&&t>=this.anchor)return R.range(e,t);let i=Math.abs(e-this.anchor)>Math.abs(t-this.anchor)?e:t;return R.range(this.anchor,i)}eq(e){return this.anchor==e.anchor&&this.head==e.head}toJSON(){return{anchor:this.anchor,head:this.head}}static fromJSON(e){if(!e||"number"!=typeof e.anchor||"number"!=typeof e.head)throw new RangeError("Invalid JSON representation for SelectionRange");return R.range(e.anchor,e.head)}static create(e,t,i){return new A(e,t,i)}}class R{constructor(e,t){this.ranges=e,this.mainIndex=t}map(e,t=-1){return e.empty?this:R.create(this.ranges.map((i=>i.map(e,t))),this.mainIndex)}eq(e){if(this.ranges.length!=e.ranges.length||this.mainIndex!=e.mainIndex)return!1;for(let t=0;te.toJSON())),main:this.mainIndex}}static fromJSON(e){if(!e||!Array.isArray(e.ranges)||"number"!=typeof e.main||e.main>=e.ranges.length)throw new RangeError("Invalid JSON representation for EditorSelection");return new R(e.ranges.map((e=>A.fromJSON(e))),e.main)}static single(e,t=e){return new R([R.range(e,t)],0)}static create(e,t=0){if(0==e.length)throw new RangeError("A selection needs at least one range");for(let i=0,n=0;ne?8:0)|s)}static normalized(e,t=0){let i=e[t];e.sort(((e,t)=>e.from-t.from)),t=e.indexOf(i);for(let i=1;in.head?R.range(o,r):R.range(r,o))}}return new R(e,t)}}function D(e,t){for(let i of e.ranges)if(i.to>t)throw new RangeError("Selection points outside of document")}let I=0;class q{constructor(e,t,i,n,s){this.combine=e,this.compareInput=t,this.compare=i,this.isStatic=n,this.id=I++,this.default=e([]),this.extensions="function"==typeof s?s(this):s}get reader(){return this}static define(e={}){return new q(e.combine||(e=>e),e.compareInput||((e,t)=>e===t),e.compare||(e.combine?(e,t)=>e===t:L),!!e.static,e.enables)}of(e){return new N([],this,0,e)}compute(e,t){if(this.isStatic)throw new Error("Can't compute a static facet");return new N(e,this,1,t)}computeN(e,t){if(this.isStatic)throw new Error("Can't compute a static facet");return new N(e,this,2,t)}from(e,t){return t||(t=e=>e),this.compute([e],(i=>t(i.field(e))))}}function L(e,t){return e==t||e.length==t.length&&e.every(((e,i)=>e===t[i]))}class N{constructor(e,t,i,n){this.dependencies=e,this.facet=t,this.type=i,this.value=n,this.id=I++}dynamicSlot(e){var t;let i=this.value,n=this.facet.compareInput,s=this.id,r=e[s]>>1,o=2==this.type,a=!1,l=!1,h=[];for(let i of this.dependencies)"doc"==i?a=!0:"selection"==i?l=!0:0==(1&(null!==(t=e[i.id])&&void 0!==t?t:1))&&h.push(e[i.id]);return{create:e=>(e.values[r]=i(e),1),update(e,t){if(a&&t.docChanged||l&&(t.docChanged||t.selection)||$(e,h)){let t=i(e);if(o?!B(t,e.values[r],n):!n(t,e.values[r]))return e.values[r]=t,1}return 0},reconfigure:(e,t)=>{let a,l=t.config.address[s];if(null!=l){let s=G(t,l);if(this.dependencies.every((i=>i instanceof q?t.facet(i)===e.facet(i):!(i instanceof j)||t.field(i,!1)==e.field(i,!1)))||(o?B(a=i(e),s,n):n(a=i(e),s)))return e.values[r]=s,0}else a=i(e);return e.values[r]=a,1}}}}function B(e,t,i){if(e.length!=t.length)return!1;for(let n=0;ne[t.id])),s=i.map((e=>e.type)),r=n.filter((e=>!(1&e))),o=e[t.id]>>1;function a(e){let i=[];for(let t=0;te===t),e);return e.provide&&(t.provides=e.provide(t)),t}create(e){let t=e.facet(z).find((e=>e.field==this));return((null==t?void 0:t.create)||this.createF)(e)}slot(e){let t=e[this.id]>>1;return{create:e=>(e.values[t]=this.create(e),1),update:(e,i)=>{let n=e.values[t],s=this.updateF(n,i);return this.compareF(n,s)?0:(e.values[t]=s,1)},reconfigure:(e,i)=>null!=i.config.address[this.id]?(e.values[t]=i.field(this),0):(e.values[t]=this.create(e),1)}}init(e){return[this,z.of({field:this,create:e})]}get extension(){return this}}function W(e){return t=>new U(t,e)}const V={highest:W(0),high:W(1),default:W(2),low:W(3),lowest:W(4)};class U{constructor(e,t){this.inner=e,this.prec=t}}class F{of(e){return new H(this,e)}reconfigure(e){return F.reconfigure.of({compartment:this,extension:e})}get(e){return e.config.compartments.get(this)}}class H{constructor(e,t){this.compartment=e,this.inner=t}}class X{constructor(e,t,i,n,s,r){for(this.base=e,this.compartments=t,this.dynamicSlots=i,this.address=n,this.staticValues=s,this.facets=r,this.statusTemplate=[];this.statusTemplate.length>1]}static resolve(e,t,i){let n=[],s=Object.create(null),r=new Map;for(let i of function(e,t,i){let n=[[],[],[],[],[]],s=new Map;return function e(r,o){let a=s.get(r);if(null!=a){if(a<=o)return;let e=n[a].indexOf(r);e>-1&&n[a].splice(e,1),r instanceof H&&i.delete(r.compartment)}if(s.set(r,o),Array.isArray(r))for(let t of r)e(t,o);else if(r instanceof H){if(i.has(r.compartment))throw new RangeError("Duplicate use of compartment in extensions");let n=t.get(r.compartment)||r.inner;i.set(r.compartment,n),e(n,o)}else if(r instanceof U)e(r.inner,r.prec);else if(r instanceof j)n[o].push(r),r.provides&&e(r.provides,o);else if(r instanceof N)n[o].push(r),r.facet.extensions&&e(r.facet.extensions,2);else{let t=r.extension;if(!t)throw new Error(`Unrecognized extension value in extension set (${r}). This sometimes happens because multiple instances of @codemirror/state are loaded, breaking instanceof checks.`);e(t,o)}}(e,2),n.reduce(((e,t)=>e.concat(t)))}(e,t,r))i instanceof j?n.push(i):(s[i.facet.id]||(s[i.facet.id]=[])).push(i);let o=Object.create(null),a=[],l=[];for(let e of n)o[e.id]=l.length<<1,l.push((t=>e.slot(t)));let h=null==i?void 0:i.config.facets;for(let e in s){let t=s[e],n=t[0].facet,r=h&&h[e]||[];if(t.every((e=>0==e.type)))if(o[n.id]=a.length<<1|1,L(r,t))a.push(i.facet(n));else{let e=n.combine(t.map((e=>e.value)));a.push(i&&n.compare(e,i.facet(n))?i.facet(n):e)}else{for(let e of t)0==e.type?(o[e.id]=a.length<<1|1,a.push(e.value)):(o[e.id]=l.length<<1,l.push((t=>e.dynamicSlot(t))));o[n.id]=l.length<<1,l.push((e=>Q(e,n,t)))}}let c=l.map((e=>e(o)));return new X(e,r,c,o,a,s)}}function Y(e,t){if(1&t)return 2;let i=t>>1,n=e.status[i];if(4==n)throw new Error("Cyclic dependency between fields and/or facets");if(2&n)return n;e.status[i]=4;let s=e.computeSlot(e,e.config.dynamicSlots[i]);return e.status[i]=2|s}function G(e,t){return 1&t?e.config.staticValues[t>>1]:e.values[t>>1]}const Z=q.define(),K=q.define({combine:e=>e.some((e=>e)),static:!0}),J=q.define({combine:e=>e.length?e[0]:void 0,static:!0}),ee=q.define(),te=q.define(),ie=q.define(),ne=q.define({combine:e=>!!e.length&&e[0]});class se{constructor(e,t){this.type=e,this.value=t}static define(){return new re}}class re{of(e){return new se(this,e)}}class oe{constructor(e){this.map=e}of(e){return new ae(this,e)}}class ae{constructor(e,t){this.type=e,this.value=t}map(e){let t=this.type.map(this.value,e);return void 0===t?void 0:t==this.value?this:new ae(this.type,t)}is(e){return this.type==e}static define(e={}){return new oe(e.map||(e=>e))}static mapEffects(e,t){if(!e.length)return e;let i=[];for(let n of e){let e=n.map(t);e&&i.push(e)}return i}}ae.reconfigure=ae.define(),ae.appendConfig=ae.define();class le{constructor(e,t,i,n,s,r){this.startState=e,this.changes=t,this.selection=i,this.effects=n,this.annotations=s,this.scrollIntoView=r,this._doc=null,this._state=null,i&&D(i,t.newLength),s.some((e=>e.type==le.time))||(this.annotations=s.concat(le.time.of(Date.now())))}static create(e,t,i,n,s,r){return new le(e,t,i,n,s,r)}get newDoc(){return this._doc||(this._doc=this.changes.apply(this.startState.doc))}get newSelection(){return this.selection||this.startState.selection.map(this.changes)}get state(){return this._state||this.startState.applyTransaction(this),this._state}annotation(e){for(let t of this.annotations)if(t.type==e)return t.value}get docChanged(){return!this.changes.empty}get reconfigured(){return this.startState.config!=this.state.config}isUserEvent(e){let t=this.annotation(le.userEvent);return!(!t||!(t==e||t.length>e.length&&t.slice(0,e.length)==e&&"."==t[e.length]))}}function he(e,t){let i=[];for(let n=0,s=0;;){let r,o;if(n=e[n]))r=e[n++],o=e[n++];else{if(!(s=0;s--){let r=i[s](e);r&&Object.keys(r).length&&(n=ce(n,de(t,r,e.changes.newLength),!0))}return n==e?e:le.create(t,e.changes,e.selection,n.effects,n.annotations,n.scrollIntoView)}(i?function(e){let t=e.startState,i=!0;for(let n of t.facet(ee)){let t=n(e);if(!1===t){i=!1;break}Array.isArray(t)&&(i=!0===i?t:he(i,t))}if(!0!==i){let n,s;if(!1===i)s=e.changes.invertedDesc,n=S.empty(t.doc.length);else{let t=e.changes.filter(i);n=t.changes,s=t.filtered.mapDesc(t.changes).invertedDesc}e=le.create(t,n,e.selection&&e.selection.map(s),ae.mapEffects(e.effects,s),e.annotations,e.scrollIntoView)}let n=t.facet(te);for(let i=n.length-1;i>=0;i--){let s=n[i](e);e=s instanceof le?s:Array.isArray(s)&&1==s.length&&s[0]instanceof le?s[0]:ue(t,fe(s),!1)}return e}(s):s)}le.time=se.define(),le.userEvent=se.define(),le.addToHistory=se.define(),le.remote=se.define();const pe=[];function fe(e){return null==e?pe:Array.isArray(e)?e:[e]}var me=function(e){return e[e.Word=0]="Word",e[e.Space=1]="Space",e[e.Other=2]="Other",e}(me||(me={}));const ge=/[\u00df\u0587\u0590-\u05f4\u0600-\u06ff\u3040-\u309f\u30a0-\u30ff\u3400-\u4db5\u4e00-\u9fcc\uac00-\ud7af]/;let ve;try{ve=new RegExp("[\\p{Alphabetic}\\p{Number}_]","u")}catch(e){}class Oe{constructor(e,t,i,n,s,r){this.config=e,this.doc=t,this.selection=i,this.values=n,this.status=e.statusTemplate.slice(),this.computeSlot=s,r&&(r._state=this);for(let e=0;es.set(t,e))),i=null),s.set(t.value.compartment,t.value.extension)):t.is(ae.reconfigure)?(i=null,n=t.value):t.is(ae.appendConfig)&&(i=null,n=fe(n).concat(t.value));i?t=e.startState.values.slice():(i=X.resolve(n,s,this),t=new Oe(i,this.doc,this.selection,i.dynamicSlots.map((()=>null)),((e,t)=>t.reconfigure(e,this)),null).values),new Oe(i,e.newDoc,e.newSelection,t,((t,i)=>i.update(t,e)),e)}replaceSelection(e){return"string"==typeof e&&(e=this.toText(e)),this.changeByRange((t=>({changes:{from:t.from,to:t.to,insert:e},range:R.cursor(t.from+e.length)})))}changeByRange(e){let t=this.selection,i=e(t.ranges[0]),n=this.changes(i.changes),s=[i.range],r=fe(i.effects);for(let i=1;is.spec.fromJSON(r,e))))}return Oe.create({doc:e.doc,selection:R.fromJSON(e.selection),extensions:t.extensions?n.concat([t.extensions]):n})}static create(t={}){let i=X.resolve(t.extensions||[],new Map),n=t.doc instanceof e?t.doc:e.of((t.doc||"").split(i.staticFacet(Oe.lineSeparator)||y)),s=t.selection?t.selection instanceof R?t.selection:R.single(t.selection.anchor,t.selection.head):R.single(0);return D(s,n.length),i.staticFacet(K)||(s=s.asSingle()),new Oe(i,n,s,i.dynamicSlots.map((()=>null)),((e,t)=>t.create(e)),null)}get tabSize(){return this.facet(Oe.tabSize)}get lineBreak(){return this.facet(Oe.lineSeparator)||"\n"}get readOnly(){return this.facet(ne)}phrase(e,...t){for(let t of this.facet(Oe.phrases))if(Object.prototype.hasOwnProperty.call(t,e)){e=t[e];break}return t.length&&(e=e.replace(/\$(\$|\d*)/g,((e,i)=>{if("$"==i)return"$";let n=+(i||1);return!n||n>t.length?e:t[n-1]}))),e}languageDataAt(e,t,i=-1){let n=[];for(let s of this.facet(Z))for(let r of s(this,t,i))Object.prototype.hasOwnProperty.call(r,e)&&n.push(r[e]);return n}charCategorizer(e){return t=this.languageDataAt("wordChars",e).join(""),e=>{if(!/\S/.test(e))return me.Space;if(function(e){if(ve)return ve.test(e);for(let t=0;t"€"&&(i.toUpperCase()!=i.toLowerCase()||ge.test(i)))return!0}return!1}(e))return me.Word;for(let i=0;i-1)return me.Word;return me.Other};var t}wordAt(e){let{text:t,from:i,length:n}=this.doc.lineAt(e),s=this.charCategorizer(e),r=e-i,o=e-i;for(;r>0;){let e=p(t,r,!1);if(s(t.slice(e,r))!=me.Word)break;r=e}for(;oe.length?e[0]:4}),Oe.lineSeparator=J,Oe.readOnly=ne,Oe.phrases=q.define({compare(e,t){let i=Object.keys(e),n=Object.keys(t);return i.length==n.length&&i.every((i=>e[i]==t[i]))}}),Oe.languageData=Z,Oe.changeFilter=ee,Oe.transactionFilter=te,Oe.transactionExtender=ie,F.reconfigure=ae.define();class _e{eq(e){return this==e}range(e,t=e){return ye.create(e,t,this)}}_e.prototype.startSide=_e.prototype.endSide=0,_e.prototype.point=!1,_e.prototype.mapMode=w.TrackDel;class ye{constructor(e,t,i){this.from=e,this.to=t,this.value=i}static create(e,t,i){return new ye(e,t,i)}}function we(e,t){return e.from-t.from||e.value.startSide-t.value.startSide}class xe{constructor(e,t,i,n){this.from=e,this.to=t,this.value=i,this.maxPoint=n}get length(){return this.to[this.to.length-1]}findIndex(e,t,i,n=0){let s=i?this.to:this.from;for(let r=n,o=s.length;;){if(r==o)return r;let n=r+o>>1,a=s[n]-e||(i?this.value[n].endSide:this.value[n].startSide)-t;if(n==r)return a>=0?r:o;a>=0?o=n:r=n+1}}between(e,t,i,n){for(let s=this.findIndex(t,-1e9,!0),r=this.findIndex(i,1e9,!1,s);sh||l==h&&c.startSide>0&&c.endSide<=0)continue;(h-l||c.endSide-c.startSide)<0||(r<0&&(r=l),c.point&&(o=Math.max(o,h-l)),i.push(c),n.push(l-r),s.push(h-r))}return{mapped:i.length?new xe(n,s,i,o):null,pos:r}}}class Se{constructor(e,t,i,n){this.chunkPos=e,this.chunk=t,this.nextLayer=i,this.maxPoint=n}static create(e,t,i,n){return new Se(e,t,i,n)}get length(){let e=this.chunk.length-1;return e<0?0:Math.max(this.chunkEnd(e),this.nextLayer.length)}get size(){if(this.isEmpty)return 0;let e=this.nextLayer.size;for(let t of this.chunk)e+=t.value.length;return e}chunkEnd(e){return this.chunkPos[e]+this.chunk[e].length}update(e){let{add:t=[],sort:i=!1,filterFrom:n=0,filterTo:s=this.length}=e,r=e.filter;if(0==t.length&&!r)return this;if(i&&(t=t.slice().sort(we)),this.isEmpty)return t.length?Se.of(t):this;let o=new Ce(this,null,-1).goto(0),a=0,l=[],h=new ke;for(;o.value||a=0){let e=t[a++];h.addInner(e.from,e.to,e.value)||l.push(e)}else 1==o.rangeIndex&&o.chunkIndexthis.chunkEnd(o.chunkIndex)||so.to||s=s&&e<=s+r.length&&!1===r.between(s,e-s,t-s,i))return}this.nextLayer.between(e,t,i)}}iter(e=0){return Pe.from([this]).goto(e)}get isEmpty(){return this.nextLayer==this}static iter(e,t=0){return Pe.from(e).goto(t)}static compare(e,t,i,n,s=-1){let r=e.filter((e=>e.maxPoint>0||!e.isEmpty&&e.maxPoint>=s)),o=t.filter((e=>e.maxPoint>0||!e.isEmpty&&e.maxPoint>=s)),a=Te(r,o,i),l=new Ee(r,a,s),h=new Ee(o,a,s);i.iterGaps(((e,t,i)=>Ae(l,e,h,t,i,n))),i.empty&&0==i.length&&Ae(l,0,h,0,0,n)}static eq(e,t,i=0,n){null==n&&(n=999999999);let s=e.filter((e=>!e.isEmpty&&t.indexOf(e)<0)),r=t.filter((t=>!t.isEmpty&&e.indexOf(t)<0));if(s.length!=r.length)return!1;if(!s.length)return!0;let o=Te(s,r),a=new Ee(s,o,0).goto(i),l=new Ee(r,o,0).goto(i);for(;;){if(a.to!=l.to||!Re(a.active,l.active)||a.point&&(!l.point||!a.point.eq(l.point)))return!1;if(a.to>n)return!0;a.next(),l.next()}}static spans(e,t,i,n,s=-1){let r=new Ee(e,null,s).goto(t),o=t,a=r.openStart;for(;;){let e=Math.min(r.to,i);if(r.point){let i=r.activeForPoint(r.to),s=r.pointFromo&&(n.span(o,e,r.active,a),a=r.openEnd(e));if(r.to>i)return a+(r.point&&r.to>i?1:0);o=r.to,r.next()}}static of(e,t=!1){let i=new ke;for(let n of e instanceof ye?[e]:t?function(e){if(e.length>1)for(let t=e[0],i=1;i0)return e.slice().sort(we);t=n}return e}(e):e)i.add(n.from,n.to,n.value);return i.finish()}}Se.empty=new Se([],[],null,-1),Se.empty.nextLayer=Se.empty;class ke{finishChunk(e){this.chunks.push(new xe(this.from,this.to,this.value,this.maxPoint)),this.chunkPos.push(this.chunkStart),this.chunkStart=-1,this.setMaxPoint=Math.max(this.setMaxPoint,this.maxPoint),this.maxPoint=-1,e&&(this.from=[],this.to=[],this.value=[])}constructor(){this.chunks=[],this.chunkPos=[],this.chunkStart=-1,this.last=null,this.lastFrom=-1e9,this.lastTo=-1e9,this.from=[],this.to=[],this.value=[],this.maxPoint=-1,this.setMaxPoint=-1,this.nextLayer=null}add(e,t,i){this.addInner(e,t,i)||(this.nextLayer||(this.nextLayer=new ke)).add(e,t,i)}addInner(e,t,i){let n=e-this.lastTo||i.startSide-this.last.endSide;if(n<=0&&(e-this.lastFrom||i.startSide-this.last.startSide)<0)throw new Error("Ranges must be added sorted by `from` position and `startSide`");return!(n<0||(250==this.from.length&&this.finishChunk(!0),this.chunkStart<0&&(this.chunkStart=e),this.from.push(e-this.chunkStart),this.to.push(t-this.chunkStart),this.last=i,this.lastFrom=e,this.lastTo=t,this.value.push(i),i.point&&(this.maxPoint=Math.max(this.maxPoint,t-e)),0))}addChunk(e,t){if((e-this.lastTo||t.value[0].startSide-this.last.endSide)<0)return!1;this.from.length&&this.finishChunk(!0),this.setMaxPoint=Math.max(this.setMaxPoint,t.maxPoint),this.chunks.push(t),this.chunkPos.push(e);let i=t.value.length-1;return this.last=t.value[i],this.lastFrom=t.from[i]+e,this.lastTo=t.to[i]+e,!0}finish(){return this.finishInner(Se.empty)}finishInner(e){if(this.from.length&&this.finishChunk(!1),0==this.chunks.length)return e;let t=Se.create(this.chunkPos,this.chunks,this.nextLayer?this.nextLayer.finishInner(e):e,this.setMaxPoint);return this.from=null,t}}function Te(e,t,i){let n=new Map;for(let t of e)for(let e=0;e=this.minPoint)break}}}setRangeIndex(e){if(e==this.layer.chunk[this.chunkIndex].value.length){if(this.chunkIndex++,this.skip)for(;this.chunkIndex=i&&n.push(new Ce(r,t,i,s));return 1==n.length?n[0]:new Pe(n)}get startSide(){return this.value?this.value.startSide:0}goto(e,t=-1e9){for(let i of this.heap)i.goto(e,t);for(let e=this.heap.length>>1;e>=0;e--)Me(this.heap,e);return this.next(),this}forward(e,t){for(let i of this.heap)i.forward(e,t);for(let e=this.heap.length>>1;e>=0;e--)Me(this.heap,e);(this.to-e||this.value.endSide-t)<0&&this.next()}next(){if(0==this.heap.length)this.from=this.to=1e9,this.value=null,this.rank=-1;else{let e=this.heap[0];this.from=e.from,this.to=e.to,this.value=e.value,this.rank=e.rank,e.value&&e.next(),Me(this.heap,0)}}}function Me(e,t){for(let i=e[t];;){let n=1+(t<<1);if(n>=e.length)break;let s=e[n];if(n+1=0&&(s=e[n+1],n++),i.compare(s)<0)break;e[n]=i,e[t]=s,t=n}}class Ee{constructor(e,t,i){this.minPoint=i,this.active=[],this.activeTo=[],this.activeRank=[],this.minActive=-1,this.point=null,this.pointFrom=0,this.pointRank=0,this.to=-1e9,this.endSide=0,this.openStart=-1,this.cursor=Pe.from(e,t,i)}goto(e,t=-1e9){return this.cursor.goto(e,t),this.active.length=this.activeTo.length=this.activeRank.length=0,this.minActive=-1,this.to=e,this.endSide=t,this.openStart=-1,this.next(),this}forward(e,t){for(;this.minActive>-1&&(this.activeTo[this.minActive]-e||this.active[this.minActive].endSide-t)<0;)this.removeActive(this.minActive);this.cursor.forward(e,t)}removeActive(e){De(this.active,e),De(this.activeTo,e),De(this.activeRank,e),this.minActive=qe(this.active,this.activeTo)}addActive(e){let t=0,{value:i,to:n,rank:s}=this.cursor;for(;t-1&&(this.activeTo[n]-this.cursor.from||this.active[n].endSide-this.cursor.startSide)<0){if(this.activeTo[n]>e){this.to=this.activeTo[n],this.endSide=this.active[n].endSide;break}this.removeActive(n),i&&De(i,n)}else{if(!this.cursor.value){this.to=this.endSide=1e9;break}if(this.cursor.from>e){this.to=this.cursor.from,this.endSide=this.cursor.startSide;break}{let e=this.cursor.value;if(e.point){if(!(t&&this.cursor.to==this.to&&this.cursor.from=0&&i[t]=0&&!(this.activeRank[i]e||this.activeTo[i]==e&&this.active[i].endSide>=this.point.endSide)&&t.push(this.active[i]);return t.reverse()}openEnd(e){let t=0;for(let i=this.activeTo.length-1;i>=0&&this.activeTo[i]>e;i--)t++;return t}}function Ae(e,t,i,n,s,r){e.goto(t),i.goto(n);let o=n+s,a=n,l=n-t;for(;;){let t=e.to+l-i.to||e.endSide-i.endSide,n=t<0?e.to+l:i.to,s=Math.min(n,o);if(e.point||i.point?e.point&&i.point&&(e.point==i.point||e.point.eq(i.point))&&Re(e.activeForPoint(e.to),i.activeForPoint(i.to))||r.comparePoint(a,s,e.point,i.point):s>a&&!Re(e.active,i.active)&&r.compareRange(a,s,e.active,i.active),n>o)break;a=n,t<=0&&e.next(),t>=0&&i.next()}}function Re(e,t){if(e.length!=t.length)return!1;for(let i=0;i=t;i--)e[i+1]=e[i];e[t]=i}function qe(e,t){let i=-1,n=1e9;for(let s=0;s=t)return n;if(n==e.length)break;s+=9==e.charCodeAt(n)?i-s%i:1,n=p(e,n)}return!0===n?-1:e.length}const Be="undefined"==typeof Symbol?"__ͼ":Symbol.for("ͼ"),$e="undefined"==typeof Symbol?"__styleSet"+Math.floor(1e8*Math.random()):Symbol("styleSet"),Qe="undefined"!=typeof globalThis?globalThis:"undefined"!=typeof window?window:{};class ze{constructor(e,t){this.rules=[];let{finish:i}=t||{};function n(e){return/^@/.test(e)?[e]:e.split(/,\s*/)}function s(e,t,r,o){let a=[],l=/^@(\w+)\b/.exec(e[0]),h=l&&"keyframes"==l[1];if(l&&null==t)return r.push(e[0]+";");for(let i in t){let o=t[i];if(/&/.test(i))s(i.split(/,\s*/).map((t=>e.map((e=>t.replace(/&/,e))))).reduce(((e,t)=>e.concat(t))),o,r);else if(o&&"object"==typeof o){if(!l)throw new RangeError("The value of a property ("+i+") should be a primitive value.");s(n(i),o,a,h)}else null!=o&&a.push(i.replace(/_.*/,"").replace(/[A-Z]/g,(e=>"-"+e.toLowerCase()))+": "+o+";")}(a.length||h)&&r.push((!i||l||o?e:e.map(i)).join(", ")+" {"+a.join(" ")+"}")}for(let t in e)s(n(t),e[t],this.rules)}getRules(){return this.rules.join("\n")}static newName(){let e=Qe[Be]||1;return Qe[Be]=e+1,"ͼ"+e.toString(36)}static mount(e,t,i){let n=e[$e],s=i&&i.nonce;n?s&&n.setNonce(s):n=new We(e,s),n.mount(Array.isArray(t)?t:[t])}}let je=new Map;class We{constructor(e,t){let i=e.ownerDocument||e,n=i.defaultView;if(!e.head&&e.adoptedStyleSheets&&n.CSSStyleSheet){let t=je.get(i);if(t)return e.adoptedStyleSheets=[t.sheet,...e.adoptedStyleSheets],e[$e]=t;this.sheet=new n.CSSStyleSheet,e.adoptedStyleSheets=[this.sheet,...e.adoptedStyleSheets],je.set(i,this)}else{this.styleTag=i.createElement("style"),t&&this.styleTag.setAttribute("nonce",t);let n=e.head||e;n.insertBefore(this.styleTag,n.firstChild)}this.modules=[],e[$e]=this}mount(e){let t=this.sheet,i=0,n=0;for(let s=0;s-1&&(this.modules.splice(o,1),n--,o=-1),-1==o){if(this.modules.splice(n++,0,r),t)for(let e=0;e",191:"?",192:"~",219:"{",220:"|",221:"}",222:'"'},Fe="undefined"!=typeof navigator&&/Mac/.test(navigator.platform),He="undefined"!=typeof navigator&&/MSIE \d|Trident\/(?:[7-9]|\d{2,})\..*rv:(\d+)/.exec(navigator.userAgent),Xe=0;Xe<10;Xe++)Ve[48+Xe]=Ve[96+Xe]=String(Xe);for(Xe=1;Xe<=24;Xe++)Ve[Xe+111]="F"+Xe;for(Xe=65;Xe<=90;Xe++)Ve[Xe]=String.fromCharCode(Xe+32),Ue[Xe]=String.fromCharCode(Xe);for(var Ye in Ve)Ue.hasOwnProperty(Ye)||(Ue[Ye]=Ve[Ye]);function Ge(e){let t;return t=11==e.nodeType?e.getSelection?e:e.ownerDocument:e,t.getSelection()}function Ze(e,t){return!!t&&(e==t||e.contains(1!=t.nodeType?t.parentNode:t))}function Ke(e,t){if(!t.anchorNode)return!1;try{return Ze(e,t.anchorNode)}catch(e){return!1}}function Je(e){return 3==e.nodeType?ct(e,0,e.nodeValue.length).getClientRects():1==e.nodeType?e.getClientRects():[]}function et(e,t,i,n){return!!i&&(it(e,t,i,n,-1)||it(e,t,i,n,1))}function tt(e){for(var t=0;;t++)if(!(e=e.previousSibling))return t}function it(e,t,i,n,s){for(;;){if(e==i&&t==n)return!0;if(t==(s<0?0:nt(e))){if("DIV"==e.nodeName)return!1;let i=e.parentNode;if(!i||1!=i.nodeType)return!1;t=tt(e)+(s<0?0:1),e=i}else{if(1!=e.nodeType)return!1;if(1==(e=e.childNodes[t+(s<0?-1:0)]).nodeType&&"false"==e.contentEditable)return!1;t=s<0?nt(e):0}}}function nt(e){return 3==e.nodeType?e.nodeValue.length:e.childNodes.length}function st(e,t){let i=t?e.left:e.right;return{left:i,right:i,top:e.top,bottom:e.bottom}}function rt(e){return{left:0,right:e.innerWidth,top:0,bottom:e.innerHeight}}class ot{constructor(){this.anchorNode=null,this.anchorOffset=0,this.focusNode=null,this.focusOffset=0}eq(e){return this.anchorNode==e.anchorNode&&this.anchorOffset==e.anchorOffset&&this.focusNode==e.focusNode&&this.focusOffset==e.focusOffset}setRange(e){let{anchorNode:t,focusNode:i}=e;this.set(t,Math.min(e.anchorOffset,t?nt(t):0),i,Math.min(e.focusOffset,i?nt(i):0))}set(e,t,i,n){this.anchorNode=e,this.anchorOffset=t,this.focusNode=i,this.focusOffset=n}}let at,lt=null;function ht(e){if(e.setActive)return e.setActive();if(lt)return e.focus(lt);let t=[];for(let i=e;i&&(t.push(i,i.scrollTop,i.scrollLeft),i!=i.ownerDocument);i=i.parentNode);if(e.focus(null==lt?{get preventScroll(){return lt={preventScroll:!0},!0}}:void 0),!lt){lt=!1;for(let e=0;eMath.max(1,e.scrollHeight-e.clientHeight-4)}class ft{constructor(e,t,i=!0){this.node=e,this.offset=t,this.precise=i}static before(e,t){return new ft(e.parentNode,tt(e),t)}static after(e,t){return new ft(e.parentNode,tt(e)+1,t)}}const mt=[];class gt{constructor(){this.parent=null,this.dom=null,this.flags=2}get overrideDOMText(){return null}get posAtStart(){return this.parent?this.parent.posBefore(this):0}get posAtEnd(){return this.posAtStart+this.length}posBefore(e){let t=this.posAtStart;for(let i of this.children){if(i==e)return t;t+=i.length+i.breakAfter}throw new RangeError("Invalid child in posBefore")}posAfter(e){return this.posBefore(e)+e.length}sync(e,t){if(2&this.flags){let i,n=this.dom,s=null;for(let r of this.children){if(7&r.flags){if(!r.dom&&(i=s?s.nextSibling:n.firstChild)){let e=gt.get(i);(!e||!e.parent&&e.canReuseDOM(r))&&r.reuseDOM(i)}r.sync(e,t),r.flags&=-8}if(i=s?s.nextSibling:n.firstChild,t&&!t.written&&t.node==n&&i!=r.dom&&(t.written=!0),r.dom.parentNode==n)for(;i&&i!=r.dom;)i=vt(i);else n.insertBefore(r.dom,i);s=r.dom}for(i=s?s.nextSibling:n.firstChild,i&&t&&t.node==n&&(t.written=!0);i;)i=vt(i)}else if(1&this.flags)for(let i of this.children)7&i.flags&&(i.sync(e,t),i.flags&=-8)}reuseDOM(e){}localPosFromDOM(e,t){let i;if(e==this.dom)i=this.dom.childNodes[t];else{let n=0==nt(e)?0:0==t?-1:1;for(;;){let t=e.parentNode;if(t==this.dom)break;0==n&&t.firstChild!=t.lastChild&&(n=e==t.firstChild?-1:1),e=t}i=n<0?e:e.nextSibling}if(i==this.dom.firstChild)return 0;for(;i&&!gt.get(i);)i=i.nextSibling;if(!i)return this.length;for(let e=0,t=0;;e++){let n=this.children[e];if(n.dom==i)return t;t+=n.length+n.breakAfter}}domBoundsAround(e,t,i=0){let n=-1,s=-1,r=-1,o=-1;for(let a=0,l=i,h=i;at)return i.domBoundsAround(e,t,l);if(c>=e&&-1==n&&(n=a,s=l),l>t&&i.dom.parentNode==this.dom){r=a,o=h;break}h=c,l=c+i.breakAfter}return{from:s,to:o<0?i+this.length:o,startDOM:(n?this.children[n-1].dom.nextSibling:null)||this.dom.firstChild,endDOM:r=0?this.children[r].dom:null}}markDirty(e=!1){this.flags|=2,this.markParentsDirty(e)}markParentsDirty(e){for(let t=this.parent;t;t=t.parent){if(e&&(t.flags|=2),1&t.flags)return;t.flags|=1,e=!1}}setParent(e){this.parent!=e&&(this.parent=e,7&this.flags&&this.markParentsDirty(!0))}setDOM(e){this.dom!=e&&(this.dom&&(this.dom.cmView=null),this.dom=e,e.cmView=this)}get rootView(){for(let e=this;;){let t=e.parent;if(!t)return e;e=t}}replaceChildren(e,t,i=mt){this.markDirty();for(let i=e;ithis.pos||e==this.pos&&(t>0||0==this.i||this.children[this.i-1].breakAfter))return this.off=e-this.pos,this;let i=this.children[--this.i];this.pos-=i.length+i.breakAfter}}}function bt(e,t,i,n,s,r,o,a,l){let{children:h}=e,c=h.length?h[t]:null,d=r.length?r[r.length-1]:null,u=d?d.breakAfter:o;if(!(t==n&&c&&!o&&!u&&r.length<2&&c.merge(i,s,r.length?d:null,0==i,a,l))){if(n0&&(!o&&r.length&&c.merge(i,c.length,r[0],!1,a,0)?c.breakAfter=r.shift().breakAfter:(i2);var Rt={mac:At||/Mac/.test(yt.platform),windows:/Win/.test(yt.platform),linux:/Linux|X11/.test(yt.platform),ie:Tt,ie_version:St?wt.documentMode||6:kt?+kt[1]:xt?+xt[1]:0,gecko:Ct,gecko_version:Ct?+(/Firefox\/(\d+)/.exec(yt.userAgent)||[0,0])[1]:0,chrome:!!Pt,chrome_version:Pt?+Pt[1]:0,ios:At,android:/Android\b/.test(yt.userAgent),webkit:Mt,safari:Et,webkit_version:Mt?+(/\bAppleWebKit\/(\d+)/.exec(navigator.userAgent)||[0,0])[1]:0,tabSize:null!=wt.documentElement.style.tabSize?"tab-size":"-moz-tab-size"};class Dt extends gt{constructor(e){super(),this.text=e}get length(){return this.text.length}createDOM(e){this.setDOM(e||document.createTextNode(this.text))}sync(e,t){this.dom||this.createDOM(),this.dom.nodeValue!=this.text&&(t&&t.node==this.dom&&(t.written=!0),this.dom.nodeValue=this.text)}reuseDOM(e){3==e.nodeType&&this.createDOM(e)}merge(e,t,i){return!(8&this.flags||i&&(!(i instanceof Dt)||this.length-(t-e)+i.length>256||8&i.flags)||(this.text=this.text.slice(0,e)+(i?i.text:"")+this.text.slice(t),this.markDirty(),0))}split(e){let t=new Dt(this.text.slice(e));return this.text=this.text.slice(0,e),this.markDirty(),t.flags|=8&this.flags,t}localPosFromDOM(e,t){return e==this.dom?t:t?this.text.length:0}domAtPos(e){return new ft(this.dom,e)}domBoundsAround(e,t,i){return{from:i,to:i+this.length,startDOM:this.dom,endDOM:this.dom.nextSibling}}coordsAt(e,t){return function(e,t,i){let n=e.nodeValue.length;t>n&&(t=n);let s=t,r=t,o=0;0==t&&i<0||t==n&&i>=0?Rt.chrome||Rt.gecko||(t?(s--,o=1):r=0)?0:a.length-1];return Rt.safari&&!o&&0==l.width&&(l=Array.prototype.find.call(a,(e=>e.width))||l),o?st(l,o<0):l||null}(this.dom,e,t)}}class It extends gt{constructor(e,t=[],i=0){super(),this.mark=e,this.children=t,this.length=i;for(let e of t)e.setParent(this)}setAttrs(e){if(ut(e),this.mark.class&&(e.className=this.mark.class),this.mark.attrs)for(let t in this.mark.attrs)e.setAttribute(t,this.mark.attrs[t]);return e}canReuseDOM(e){return super.canReuseDOM(e)&&!(8&(this.flags|e.flags))}reuseDOM(e){e.nodeName==this.mark.tagName.toUpperCase()&&(this.setDOM(e),this.flags|=6)}sync(e,t){this.dom?4&this.flags&&this.setAttrs(this.dom):this.setDOM(this.setAttrs(document.createElement(this.mark.tagName))),super.sync(e,t)}merge(e,t,i,n,s,r){return!(i&&(!(i instanceof It&&i.mark.eq(this.mark))||e&&s<=0||te&&t.push(i=e&&(n=s),i=o,s++}let r=this.length-e;return this.length=e,n>-1&&(this.children.length=n,this.markDirty()),new It(this.mark,t,r)}domAtPos(e){return Nt(this,e)}coordsAt(e,t){return $t(this,e,t)}}class qt extends gt{static create(e,t,i){return new qt(e,t,i)}constructor(e,t,i){super(),this.widget=e,this.length=t,this.side=i,this.prevWidget=null}split(e){let t=qt.create(this.widget,this.length-e,this.side);return this.length-=e,t}sync(e){this.dom&&this.widget.updateDOM(this.dom,e)||(this.dom&&this.prevWidget&&this.prevWidget.destroy(this.dom),this.prevWidget=null,this.setDOM(this.widget.toDOM(e)),this.dom.contentEditable="false")}getSide(){return this.side}merge(e,t,i,n,s,r){return!(i&&(!(i instanceof qt&&this.widget.compare(i.widget))||e>0&&s<=0||t0)?ft.before(this.dom):ft.after(this.dom,e==this.length)}domBoundsAround(){return null}coordsAt(e,t){let i=this.widget.coordsAt(this.dom,e,t);if(i)return i;let n=this.dom.getClientRects(),s=null;if(!n.length)return null;let r=this.side?this.side<0:e>0;for(let t=r?n.length-1:0;s=n[t],!(e>0?0==t:t==n.length-1||s.top0?ft.before(this.dom):ft.after(this.dom)}localPosFromDOM(){return 0}domBoundsAround(){return null}coordsAt(e){return this.dom.getBoundingClientRect()}get overrideDOMText(){return e.empty}get isHidden(){return!0}}function Nt(e,t){let i=e.dom,{children:n}=e,s=0;for(let e=0;se&&t0;e--){let t=n[e-1];if(t.dom.parentNode==i)return t.domAtPos(t.length)}for(let e=s;e0&&t instanceof It&&s.length&&(n=s[s.length-1])instanceof It&&n.mark.eq(t.mark)?Bt(n,t.children[0],i-1):(s.push(t),t.setParent(e)),e.length+=t.length}function $t(e,t,i){let n=null,s=-1,r=null,o=-1;!function e(t,a){for(let l=0,h=0;l=a&&(c.children.length?e(c,a-h):(!r||r.isHidden&&i>0)&&(d>a||h==d&&c.getSide()>0)?(r=c,o=a-h):(h-1?1:0)!=s.length-(i&&s.indexOf(i)>-1?1:0))return!1;for(let r of n)if(r!=i&&(-1==s.indexOf(r)||e[r]!==t[r]))return!1;return!0}function Wt(e,t,i){let n=!1;if(t)for(let s in t)i&&s in i||(n=!0,"style"==s?e.style.cssText="":e.removeAttribute(s));if(i)for(let s in i)t&&t[s]==i[s]||(n=!0,"style"==s?e.style.cssText=i[s]:e.setAttribute(s,i[s]));return n}function Vt(e){let t=Object.create(null);for(let i=0;i0&&0==this.children[i-1].length;)this.children[--i].destroy();return this.children.length=i,this.markDirty(),this.length=e,t}transferDOM(e){this.dom&&(this.markDirty(),e.setDOM(this.dom),e.prevAttrs=void 0===this.prevAttrs?this.attrs:this.prevAttrs,this.prevAttrs=void 0,this.dom=null)}setDeco(e){jt(this.attrs,e)||(this.dom&&(this.prevAttrs=this.attrs,this.markDirty()),this.attrs=e)}append(e,t){Bt(this,e,t)}addLineDeco(e){let t=e.spec.attributes,i=e.spec.class;t&&(this.attrs=Qt(t,this.attrs||{})),i&&(this.attrs=Qt({class:i},this.attrs||{}))}domAtPos(e){return Nt(this,e)}reuseDOM(e){"DIV"==e.nodeName&&(this.setDOM(e),this.flags|=6)}sync(e,t){var i;this.dom?4&this.flags&&(ut(this.dom),this.dom.className="cm-line",this.prevAttrs=this.attrs?null:void 0):(this.setDOM(document.createElement("div")),this.dom.className="cm-line",this.prevAttrs=this.attrs?null:void 0),void 0!==this.prevAttrs&&(Wt(this.dom,this.prevAttrs,this.attrs),this.dom.classList.add("cm-line"),this.prevAttrs=void 0),super.sync(e,t);let n=this.dom.lastChild;for(;n&>.get(n)instanceof It;)n=n.lastChild;if(!(n&&this.length&&("BR"==n.nodeName||0!=(null===(i=gt.get(n))||void 0===i?void 0:i.isEditable)||Rt.ios&&this.children.some((e=>e instanceof Dt))))){let e=document.createElement("BR");e.cmIgnore=!0,this.dom.appendChild(e)}}measureTextSize(){if(0==this.children.length||this.length>20)return null;let e,t=0;for(let i of this.children){if(!(i instanceof Dt)||/[^ -~]/.test(i.text))return null;let n=Je(i.dom);if(1!=n.length)return null;t+=n[0].width,e=n[0].height}return t?{lineHeight:this.dom.getBoundingClientRect().height,charWidth:t/this.length,textHeight:e}:null}coordsAt(e,t){let i=$t(this,e,t);if(!this.children.length&&i&&this.parent){let{heightOracle:e}=this.parent.view.viewState,t=i.bottom-i.top;if(Math.abs(t-e.lineHeight)<2&&e.textHeight=t){if(s instanceof Ut)return s;if(r>t)break}n=r+s.breakAfter}return null}}class Ft extends gt{constructor(e,t,i){super(),this.widget=e,this.length=t,this.deco=i,this.breakAfter=0,this.prevWidget=null}merge(e,t,i,n,s,r){return!(i&&(!(i instanceof Ft&&this.widget.compare(i.widget))||e>0&&s<=0||t0)}}class Ht{eq(e){return!1}updateDOM(e,t){return!1}compare(e){return this==e||this.constructor==e.constructor&&this.eq(e)}get estimatedHeight(){return-1}get lineBreaks(){return 0}ignoreEvent(e){return!0}coordsAt(e,t,i){return null}get isHidden(){return!1}destroy(e){}}var Xt=function(e){return e[e.Text=0]="Text",e[e.WidgetBefore=1]="WidgetBefore",e[e.WidgetAfter=2]="WidgetAfter",e[e.WidgetRange=3]="WidgetRange",e}(Xt||(Xt={}));class Yt extends _e{constructor(e,t,i,n){super(),this.startSide=e,this.endSide=t,this.widget=i,this.spec=n}get heightRelevant(){return!1}static mark(e){return new Gt(e)}static widget(e){let t=Math.max(-1e4,Math.min(1e4,e.side||0)),i=!!e.block;return t+=i&&!e.inlineOrder?t>0?3e8:-4e8:t>0?1e8:-1e8,new Kt(e,t,t,i,e.widget||null,!1)}static replace(e){let t,i,n=!!e.block;if(e.isBlockGap)t=-5e8,i=4e8;else{let{start:s,end:r}=Jt(e,n);t=(s?n?-3e8:-1:5e8)-1,i=1+(r?n?2e8:1:-6e8)}return new Kt(e,t,i,n,e.widget||null,!0)}static line(e){return new Zt(e)}static set(e,t=!1){return Se.of(e,t)}hasHeight(){return!!this.widget&&this.widget.estimatedHeight>-1}}Yt.none=Se.empty;class Gt extends Yt{constructor(e){let{start:t,end:i}=Jt(e);super(t?-1:5e8,i?1:-6e8,null,e),this.tagName=e.tagName||"span",this.class=e.class||"",this.attrs=e.attributes||null}eq(e){var t,i;return this==e||e instanceof Gt&&this.tagName==e.tagName&&(this.class||(null===(t=this.attrs)||void 0===t?void 0:t.class))==(e.class||(null===(i=e.attrs)||void 0===i?void 0:i.class))&&jt(this.attrs,e.attrs,"class")}range(e,t=e){if(e>=t)throw new RangeError("Mark decorations may not be empty");return super.range(e,t)}}Gt.prototype.point=!1;class Zt extends Yt{constructor(e){super(-2e8,-2e8,null,e)}eq(e){return e instanceof Zt&&this.spec.class==e.spec.class&&jt(this.spec.attributes,e.spec.attributes)}range(e,t=e){if(t!=e)throw new RangeError("Line decoration ranges must be zero-length");return super.range(e,t)}}Zt.prototype.mapMode=w.TrackBefore,Zt.prototype.point=!0;class Kt extends Yt{constructor(e,t,i,n,s,r){super(t,i,s,e),this.block=n,this.isReplace=r,this.mapMode=n?t<=0?w.TrackBefore:w.TrackAfter:w.TrackDel}get type(){return this.startSide!=this.endSide?Xt.WidgetRange:this.startSide<=0?Xt.WidgetBefore:Xt.WidgetAfter}get heightRelevant(){return this.block||!!this.widget&&(this.widget.estimatedHeight>=5||this.widget.lineBreaks>0)}eq(e){return e instanceof Kt&&((t=this.widget)==(i=e.widget)||!!(t&&i&&t.compare(i)))&&this.block==e.block&&this.startSide==e.startSide&&this.endSide==e.endSide;var t,i}range(e,t=e){if(this.isReplace&&(e>t||e==t&&this.startSide>0&&this.endSide<=0))throw new RangeError("Invalid range for replacement decoration");if(!this.isReplace&&t!=e)throw new RangeError("Widget decorations can only have zero-length ranges");return super.range(e,t)}}function Jt(e,t=!1){let{inclusiveStart:i,inclusiveEnd:n}=e;return null==i&&(i=e.inclusive),null==n&&(n=e.inclusive),{start:null!=i?i:t,end:null!=n?n:t}}function ei(e,t,i,n=0){let s=i.length-1;s>=0&&i[s]+n>=e?i[s]=Math.max(i[s],t):i.push(e,t)}Kt.prototype.point=!0;class ti{constructor(e,t,i,n){this.doc=e,this.pos=t,this.end=i,this.disallowBlockEffectsFor=n,this.content=[],this.curLine=null,this.breakAtStart=0,this.pendingBuffer=0,this.bufferMarks=[],this.atCursorPos=!0,this.openStart=-1,this.openEnd=-1,this.text="",this.textOff=0,this.cursor=e.iter(),this.skip=t}posCovered(){if(0==this.content.length)return!this.breakAtStart&&this.doc.lineAt(this.pos).from!=this.pos;let e=this.content[this.content.length-1];return!(e.breakAfter||e instanceof Ft&&e.deco.endSide<0)}getLine(){return this.curLine||(this.content.push(this.curLine=new Ut),this.atCursorPos=!0),this.curLine}flushBuffer(e=this.bufferMarks){this.pendingBuffer&&(this.curLine.append(ii(new Lt(-1),e),e.length),this.pendingBuffer=0)}addBlockWidget(e){this.flushBuffer(),this.curLine=null,this.content.push(e)}finish(e){this.pendingBuffer&&e<=this.bufferMarks.length?this.flushBuffer():this.pendingBuffer=0,this.posCovered()||e&&this.content.length&&this.content[this.content.length-1]instanceof Ft||this.getLine()}buildText(e,t,i){for(;e>0;){if(this.textOff==this.text.length){let{value:t,lineBreak:i,done:n}=this.cursor.next(this.skip);if(this.skip=0,n)throw new Error("Ran out of text content when drawing inline views");if(i){this.posCovered()||this.getLine(),this.content.length?this.content[this.content.length-1].breakAfter=1:this.breakAtStart=1,this.flushBuffer(),this.curLine=null,this.atCursorPos=!0,e--;continue}this.text=t,this.textOff=0}let n=Math.min(this.text.length-this.textOff,e,512);this.flushBuffer(t.slice(t.length-i)),this.getLine().append(ii(new Dt(this.text.slice(this.textOff,this.textOff+n)),t),i),this.atCursorPos=!0,this.textOff+=n,e-=n,i=0}}span(e,t,i,n){this.buildText(t-e,i,n),this.pos=t,this.openStart<0&&(this.openStart=n)}point(e,t,i,n,s,r){if(this.disallowBlockEffectsFor[r]&&i instanceof Kt){if(i.block)throw new RangeError("Block decorations may not be specified via plugins");if(t>this.doc.lineAt(this.pos).to)throw new RangeError("Decorations that replace line breaks may not be specified via plugins")}let o=t-e;if(i instanceof Kt)if(i.block)i.startSide>0&&!this.posCovered()&&this.getLine(),this.addBlockWidget(new Ft(i.widget||new ni("div"),o,i));else{let r=qt.create(i.widget||new ni("span"),o,o?0:i.startSide),a=this.atCursorPos&&!r.isEditable&&s<=n.length&&(e0),l=!r.isEditable&&(en.length||i.startSide<=0),h=this.getLine();2!=this.pendingBuffer||a||r.isEditable||(this.pendingBuffer=0),this.flushBuffer(n),a&&(h.append(ii(new Lt(1),n),s),s=n.length+Math.max(0,s-n.length)),h.append(ii(r,n),s),this.atCursorPos=l,this.pendingBuffer=l?en.length?1:2:0,this.pendingBuffer&&(this.bufferMarks=n.slice())}else this.doc.lineAt(this.pos).from==this.pos&&this.getLine().addLineDeco(i);o&&(this.textOff+o<=this.text.length?this.textOff+=o:(this.skip+=o-(this.text.length-this.textOff),this.text="",this.textOff=0),this.pos=t),this.openStart<0&&(this.openStart=s)}static build(e,t,i,n,s){let r=new ti(e,t,i,s);return r.openEnd=Se.spans(n,t,i,r),r.openStart<0&&(r.openStart=r.openEnd),r.finish(r.openEnd),r}}function ii(e,t){for(let i of t)e=new It(i,[e],e.length);return e}class ni extends Ht{constructor(e){super(),this.tag=e}eq(e){return e.tag==this.tag}toDOM(){return document.createElement(this.tag)}updateDOM(e){return e.nodeName.toLowerCase()==this.tag}get isHidden(){return!0}}const si=q.define(),ri=q.define(),oi=q.define(),ai=q.define(),li=q.define(),hi=q.define(),ci=q.define(),di=q.define({combine:e=>e.some((e=>e))}),ui=q.define({combine:e=>e.some((e=>e))});class pi{constructor(e,t="nearest",i="nearest",n=5,s=5){this.range=e,this.y=t,this.x=i,this.yMargin=n,this.xMargin=s}map(e){return e.empty?this:new pi(this.range.map(e),this.y,this.x,this.yMargin,this.xMargin)}}const fi=ae.define({map:(e,t)=>e.map(t)});function mi(e,t,i){let n=e.facet(ai);n.length?n[0](t):window.onerror?window.onerror(String(t),i,void 0,void 0,t):i?console.error(i+":",t):console.error(t)}const gi=q.define({combine:e=>!e.length||e[0]});let vi=0;const Oi=q.define();class bi{constructor(e,t,i,n,s){this.id=e,this.create=t,this.domEventHandlers=i,this.domEventObservers=n,this.extension=s(this)}static define(e,t){const{eventHandlers:i,eventObservers:n,provide:s,decorations:r}=t||{};return new bi(vi++,e,i,n,(e=>{let t=[Oi.of(e)];return r&&t.push(xi.of((t=>{let i=t.plugin(e);return i?r(i):Yt.none}))),s&&t.push(s(e)),t}))}static fromClass(e,t){return bi.define((t=>new e(t)),t)}}class _i{constructor(e){this.spec=e,this.mustUpdate=null,this.value=null}update(e){if(this.value){if(this.mustUpdate){let e=this.mustUpdate;if(this.mustUpdate=null,this.value.update)try{this.value.update(e)}catch(t){if(mi(e.state,t,"CodeMirror plugin crashed"),this.value.destroy)try{this.value.destroy()}catch(e){}this.deactivate()}}}else if(this.spec)try{this.value=this.spec.create(e)}catch(t){mi(e.state,t,"CodeMirror plugin crashed"),this.deactivate()}return this}destroy(e){var t;if(null===(t=this.value)||void 0===t?void 0:t.destroy)try{this.value.destroy()}catch(t){mi(e.state,t,"CodeMirror plugin crashed")}}deactivate(){this.spec=this.value=null}}const yi=q.define(),wi=q.define(),xi=q.define(),Si=q.define(),ki=q.define();function Ti(e,t,i){let n=e.state.facet(ki);if(!n.length)return n;let s=n.map((t=>t instanceof Function?t(e):t)),r=[];return Se.spans(s,t,i,{point(){},span(e,t,i,n){let s=r;for(let r=i.length-1;r>=0;r--,n--){let o,a=i[r].spec.bidiIsolate;if(null!=a)if(n>0&&s.length&&(o=s[s.length-1]).to==e&&o.direction==a)o.to=t,s=o.inner;else{let i={from:e,to:t,direction:a,inner:[]};s.push(i),s=i.inner}}}}),r}const Ci=q.define();function Pi(e){let t=0,i=0,n=0,s=0;for(let r of e.state.facet(Ci)){let o=r(e);o&&(null!=o.left&&(t=Math.max(t,o.left)),null!=o.right&&(i=Math.max(i,o.right)),null!=o.top&&(n=Math.max(n,o.top)),null!=o.bottom&&(s=Math.max(s,o.bottom)))}return{left:t,right:i,top:n,bottom:s}}const Mi=q.define();class Ei{constructor(e,t,i,n){this.fromA=e,this.toA=t,this.fromB=i,this.toB=n}join(e){return new Ei(Math.min(this.fromA,e.fromA),Math.max(this.toA,e.toA),Math.min(this.fromB,e.fromB),Math.max(this.toB,e.toB))}addToSet(e){let t=e.length,i=this;for(;t>0;t--){let n=e[t-1];if(!(n.fromA>i.toA)){if(n.toAh)break;s+=2}if(!a)return i;new Ei(a.fromA,a.toA,a.fromB,a.toB).addToSet(i),r=a.toA,o=a.toB}}}class Ai{constructor(e,t,i){this.view=e,this.state=t,this.transactions=i,this.flags=0,this.startState=e.state,this.changes=S.empty(this.startState.doc.length);for(let e of i)this.changes=this.changes.compose(e.changes);let n=[];this.changes.iterChangedRanges(((e,t,i,s)=>n.push(new Ei(e,t,i,s)))),this.changedRanges=n}static create(e,t,i){return new Ai(e,t,i)}get viewportChanged(){return(4&this.flags)>0}get heightChanged(){return(2&this.flags)>0}get geometryChanged(){return this.docChanged||(10&this.flags)>0}get focusChanged(){return(1&this.flags)>0}get docChanged(){return!this.changes.empty}get selectionSet(){return this.transactions.some((e=>e.selection))}get empty(){return 0==this.flags&&0==this.transactions.length}}var Ri=function(e){return e[e.LTR=0]="LTR",e[e.RTL=1]="RTL",e}(Ri||(Ri={}));const Di=Ri.LTR,Ii=Ri.RTL;function qi(e){let t=[];for(let i=0;i=t){if(o.level==i)return r;(s<0||(0!=n?n<0?o.fromt:e[s].level>o.level))&&(s=r)}}if(s<0)throw new RangeError("Index out of range");return s}}function ji(e,t){if(e.length!=t.length)return!1;for(let i=0;il&&o.push(new zi(l,f.from,u)),Ui(e,f.direction==Di!=!(u%2)?n+1:n,s,f.inner,f.from,f.to,o),l=f.to),p=f.to}else{if(p==i||(t?Wi[p]!=a:Wi[p]==a))break;p++}d?Vi(e,l,p,n+1,s,d,o):lt;){let i=!0,c=!1;if(!h||l>r[h-1].to){let e=Wi[l-1];e!=a&&(i=!1,c=16==e)}let d=i||1!=a?null:[],u=i?n:n+1,p=l;e:for(;;)if(h&&p==r[h-1].to){if(c)break e;let f=r[--h];if(!i)for(let e=f.from,i=h;;){if(e==t)break e;if(!i||r[i-1].to!=e){if(Wi[e-1]==a)break e;break}e=r[--i].from}d?d.push(f):(f.to=0;e-=3)if($i[e+1]==-i){let t=$i[e+2],i=2&t?s:4&t?1&t?r:s:0;i&&(Wi[o]=Wi[$i[e]]=i),a=e;break}}else{if(189==$i.length)break;$i[a++]=o,$i[a++]=t,$i[a++]=l}else if(2==(n=Wi[o])||1==n){let e=n==s;l=e?0:1;for(let t=a-3;t>=0;t-=3){let i=$i[t+2];if(2&i)break;if(e)$i[t+2]|=2;else{if(4&i)break;$i[t+2]|=4}}}}}(e,s,r,n,a),function(e,t,i,n){for(let s=0,r=n;s<=i.length;s++){let o=s?i[s-1].to:e,a=sl;)t==r&&(t=i[--n].from,r=n?i[n-1].to:e),Wi[--t]=c;l=o}else r=o,l++}}}(s,r,n,a),Vi(e,s,r,t,i,n,o)}function Fi(e){return[new zi(0,e,0)]}let Hi="";function Xi(e,t,i,n,s){var r;let o=n.head-e.from,a=-1;if(0==o){if(!s||!e.length)return null;t[0].level!=i&&(o=t[0].side(!1,i),a=0)}else if(o==e.length){if(s)return null;let e=t[t.length-1];e.level!=i&&(o=e.side(!0,i),a=t.length-1)}a<0&&(a=zi.find(t,o,null!==(r=n.bidiLevel)&&void 0!==r?r:-1,n.assoc));let l=t[a];o==l.side(s,i)&&(l=t[a+=s?1:-1],o=l.side(!s,i));let h=s==(l.dir==i),c=p(e.text,o,h);if(Hi=e.text.slice(Math.min(o,c),Math.max(o,c)),c!=l.side(s,i))return R.cursor(c+e.from,h?-1:1,l.level);let d=a==(s?t.length-1:0)?null:t[a+(s?1:-1)];return d||l.level==i?d&&d.level0&&i.length&&(i.every((({fromA:e,toA:t})=>tthis.minWidthTo))?(this.minWidthFrom=e.changes.mapPos(this.minWidthFrom,1),this.minWidthTo=e.changes.mapPos(this.minWidthTo,1)):this.minWidth=this.minWidthFrom=this.minWidthTo=0);let n=-1;this.view.inputState.composing>=0&&((null===(t=this.domChanged)||void 0===t?void 0:t.newSel)?n=this.domChanged.newSel.head:function(e,t){let i=!1;return t&&e.iterChangedRanges(((e,n)=>{et.from&&(i=!0)})),i}(e.changes,this.hasComposition)||e.selectionSet||(n=e.state.selection.main.head));let s=n>-1?function(e,t,i){let n=Zi(e,i);if(!n)return null;let{node:s,from:r,to:o}=n,a=s.nodeValue;if(/[\n\r]/.test(a))return null;if(e.state.doc.sliceString(n.from,n.to)!=a)return null;let l=t.invertedDesc,h=new Ei(l.mapPos(r),l.mapPos(o),r,o),c=[];for(let t=s.parentNode;;t=t.parentNode){let i=gt.get(t);if(i instanceof It)c.push({node:t,deco:i.mark});else{if(i instanceof Ut||"DIV"==t.nodeName&&t.parentNode==e.contentDOM)return{range:h,text:s,marks:c,line:t};if(t==e.contentDOM)return null;c.push({node:t,deco:new Gt({inclusive:!0,attributes:Vt(t),tagName:t.tagName.toLowerCase()})})}}}(this.view,e.changes,n):null;if(this.domChanged=null,this.hasComposition){this.markedForComposition.clear();let{from:t,to:n}=this.hasComposition;i=new Ei(t,n,e.changes.mapPos(t,-1),e.changes.mapPos(n,1)).addToSet(i.slice())}this.hasComposition=s?{from:s.range.fromB,to:s.range.toB}:null,(Rt.ie||Rt.chrome)&&!s&&e&&e.state.doc.lines!=e.startState.doc.lines&&(this.forceSelection=!0);let r=function(e,t,i){let n=new Ji;return Se.compare(e,t,i,n),n.changes}(this.decorations,this.updateDeco(),e.changes);return i=Ei.extendWithRanges(i,r),!!(7&this.flags||0!=i.length)&&(this.updateInner(i,e.startState.doc.length,s),e.transactions.length&&(this.lastUpdate=Date.now()),!0)}updateInner(e,t,i){this.view.viewState.mustMeasureContent=!0,this.updateChildren(e,t,i);let{observer:n}=this.view;n.ignore((()=>{this.dom.style.height=this.view.viewState.contentHeight/this.view.scaleY+"px",this.dom.style.flexBasis=this.minWidth?this.minWidth+"px":"";let e=Rt.chrome||Rt.ios?{node:n.selectionRange.focusNode,written:!1}:void 0;this.sync(this.view,e),this.flags&=-8,e&&(e.written||n.selectionRange.focusNode!=e.node)&&(this.forceSelection=!0),this.dom.style.height=""})),this.markedForComposition.forEach((e=>e.flags&=-9));let s=[];if(this.view.viewport.from||this.view.viewport.to=0?n[e]:null;if(!t)break;let r,o,a,l,{fromA:h,toA:c,fromB:d,toB:u}=t;if(i&&i.range.fromBd){let e=ti.build(this.view.state.doc,d,i.range.fromB,this.decorations,this.dynamicDecorationMap),t=ti.build(this.view.state.doc,i.range.toB,u,this.decorations,this.dynamicDecorationMap);o=e.breakAtStart,a=e.openStart,l=t.openEnd;let n=this.compositionView(i);t.breakAtStart?n.breakAfter=1:t.content.length&&n.merge(n.length,n.length,t.content[0],!1,t.openStart,0)&&(n.breakAfter=t.content[0].breakAfter,t.content.shift()),e.content.length&&n.merge(0,0,e.content[e.content.length-1],!0,0,e.openEnd)&&e.content.pop(),r=e.content.concat(n).concat(t.content)}else({content:r,breakAtStart:o,openStart:a,openEnd:l}=ti.build(this.view.state.doc,d,u,this.decorations,this.dynamicDecorationMap));let{i:p,off:f}=s.findPos(c,1),{i:m,off:g}=s.findPos(h,-1);bt(this,m,g,p,f,r,o,a,l)}i&&this.fixCompositionDOM(i)}compositionView(e){let t=new Dt(e.text.nodeValue);t.flags|=8;for(let{deco:i}of e.marks)t=new It(i,[t],t.length);let i=new Ut;return i.append(t,0),i}fixCompositionDOM(e){let t=(e,t)=>{t.flags|=8|(t.children.some((e=>7&e.flags))?1:0),this.markedForComposition.add(t);let i=gt.get(e);i&&i!=t&&(i.dom=null),t.setDOM(e)},i=this.childPos(e.range.fromB,1),n=this.children[i.i];t(e.line,n);for(let s=e.marks.length-1;s>=-1;s--)i=n.childPos(i.off,1),n=n.children[i.i],t(s>=0?e.marks[s].node:e.text,n)}updateSelection(e=!1,t=!1){!e&&this.view.observer.selectionRange.focusNode||this.view.observer.readSelectionRange();let i=this.view.root.activeElement,n=i==this.dom,s=!n&&Ke(this.dom,this.view.observer.selectionRange)&&!(i&&this.dom.contains(i));if(!(n||t||s))return;let r=this.forceSelection;this.forceSelection=!1;let o=this.view.state.selection.main,a=this.moveToLine(this.domAtPos(o.anchor)),l=o.empty?a:this.moveToLine(this.domAtPos(o.head));if(Rt.gecko&&o.empty&&!this.hasComposition&&1==(h=a).node.nodeType&&h.node.firstChild&&(0==h.offset||"false"==h.node.childNodes[h.offset-1].contentEditable)&&(h.offset==h.node.childNodes.length||"false"==h.node.childNodes[h.offset].contentEditable)){let e=document.createTextNode("");this.view.observer.ignore((()=>a.node.insertBefore(e,a.node.childNodes[a.offset]||null))),a=l=new ft(e,0),r=!0}var h;let c=this.view.observer.selectionRange;!r&&c.focusNode&&et(a.node,a.offset,c.anchorNode,c.anchorOffset)&&et(l.node,l.offset,c.focusNode,c.focusOffset)||(this.view.observer.ignore((()=>{Rt.android&&Rt.chrome&&this.dom.contains(c.focusNode)&&function(e,t){for(let i=e;i&&i!=t;i=i.assignedSlot||i.parentNode)if(1==i.nodeType&&"false"==i.contentEditable)return!0;return!1}(c.focusNode,this.dom)&&(this.dom.blur(),this.dom.focus({preventScroll:!0}));let e=Ge(this.view.root);if(e)if(o.empty){if(Rt.gecko){let e=(t=a.node,n=a.offset,1!=t.nodeType?0:(n&&"false"==t.childNodes[n-1].contentEditable?1:0)|(no.head&&([a,l]=[l,a]),t.setEnd(l.node,l.offset),t.setStart(a.node,a.offset),e.removeAllRanges(),e.addRange(t)}var t,n;s&&this.view.root.activeElement==this.dom&&(this.dom.blur(),i&&i.focus())})),this.view.observer.setSelectionRange(a,l)),this.impreciseAnchor=a.precise?null:new ft(c.anchorNode,c.anchorOffset),this.impreciseHead=l.precise?null:new ft(c.focusNode,c.focusOffset)}enforceCursorAssoc(){if(this.hasComposition)return;let{view:e}=this,t=e.state.selection.main,i=Ge(e.root),{anchorNode:n,anchorOffset:s}=e.observer.selectionRange;if(!(i&&t.empty&&t.assoc&&i.modify))return;let r=Ut.find(this,t.head);if(!r)return;let o=r.posAtStart;if(t.head==o||t.head==o+r.length)return;let a=this.coordsAt(t.head,-1),l=this.coordsAt(t.head,1);if(!a||!l||a.bottom>l.top)return;let h=this.domAtPos(t.head+t.assoc);i.collapse(h.node,h.offset),i.modify("move",t.assoc<0?"forward":"backward","lineboundary"),e.observer.readSelectionRange();let c=e.observer.selectionRange;e.docView.posFromDOM(c.anchorNode,c.anchorOffset)!=t.from&&i.collapse(n,s)}moveToLine(e){let t,i=this.dom;if(e.node!=i)return e;for(let n=e.offset;!t&&n=0;n--){let e=gt.get(i.childNodes[n]);e instanceof Ut&&(t=e.domAtPos(e.length))}return t?new ft(t.node,t.offset,!0):e}nearest(e){for(let t=e;t;){let e=gt.get(t);if(e&&e.rootView==this)return e;t=t.parentNode}return null}posFromDOM(e,t){let i=this.nearest(e);if(!i)throw new RangeError("Trying to find position for a DOM position outside of the document");return i.localPosFromDOM(e,t)+i.posAtStart}domAtPos(e){let{i:t,off:i}=this.childCursor().findPos(e,-1);for(;t=0;r--){let o=this.children[r],a=s-o.breakAfter,l=a-o.length;if(ae||o.covers(1))&&(!i||o instanceof Ut&&!(i instanceof Ut&&t>=0))&&(i=o,n=l),s=l}return i?i.coordsAt(e-n,t):null}coordsForChar(e){let{i:t,off:i}=this.childPos(e,1),n=this.children[t];if(!(n instanceof Ut))return null;for(;n.children.length;){let{i:e,off:t}=n.childPos(i,1);for(;;e++){if(e==n.children.length)return null;if((n=n.children[e]).length)break}i=t}if(!(n instanceof Dt))return null;let s=p(n.text,i);if(s==i)return null;let r=ct(n.dom,i,s).getClientRects();for(let e=0;eMath.max(this.view.scrollDOM.clientWidth,this.minWidth)+1,o=-1,a=this.view.textDirection==Ri.LTR;for(let e=0,l=0;ln)break;if(e>=i){let i=h.dom.getBoundingClientRect();if(t.push(i.height),r){let t=h.dom.lastChild,n=t?Je(t):[];if(n.length){let t=n[n.length-1],r=a?t.right-i.left:i.right-t.left;r>o&&(o=r,this.minWidth=s,this.minWidthFrom=e,this.minWidthTo=c)}}}e=c+h.breakAfter}return t}textDirectionAt(e){let{i:t}=this.childPos(e,1);return"rtl"==getComputedStyle(this.children[t].dom).direction?Ri.RTL:Ri.LTR}measureTextSize(){for(let e of this.children)if(e instanceof Ut){let t=e.measureTextSize();if(t)return t}let e,t,i,n=document.createElement("div");return n.className="cm-line",n.style.width="99999px",n.style.position="absolute",n.textContent="abc def ghi jkl mno pqr stu",this.view.observer.ignore((()=>{this.dom.appendChild(n);let s=Je(n.firstChild)[0];e=n.getBoundingClientRect().height,t=s?s.width/27:7,i=s?s.height:e,n.remove()})),{lineHeight:e,charWidth:t,textHeight:i}}childCursor(e=this.length){let t=this.children.length;return t&&(e-=this.children[--t].length),new Ot(this.children,e,t)}computeBlockGapDeco(){let e=[],t=this.view.viewState;for(let i=0,n=0;;n++){let s=n==t.viewports.length?null:t.viewports[n],r=s?s.from-1:this.length;if(r>i){let n=(t.lineBlockAt(r).bottom-t.lineBlockAt(i).top)/this.view.scaleY;e.push(Yt.replace({widget:new Gi(n),block:!0,inclusive:!0,isBlockGap:!0}).range(i,r))}if(!s)break;i=s.to+1}return Yt.set(e)}updateDeco(){let e=this.view.state.facet(xi).map(((e,t)=>(this.dynamicDecorationMap[t]="function"==typeof e)?e(this.view):e));for(let t=e.length;ti.anchor?-1:1);if(!n)return;!i.empty&&(t=this.coordsAt(i.anchor,i.anchor>i.head?-1:1))&&(n={left:Math.min(n.left,t.left),top:Math.min(n.top,t.top),right:Math.max(n.right,t.right),bottom:Math.max(n.bottom,t.bottom)});let s=Pi(this.view),r={left:n.left-s.left,top:n.top-s.top,right:n.right+s.right,bottom:n.bottom+s.bottom};!function(e,t,i,n,s,r,o,a){let l=e.ownerDocument,h=l.defaultView||window;for(let c=e,d=!1;c&&!d;)if(1==c.nodeType){let e,u=c==l.body,p=1,f=1;if(u)e=rt(h);else{if(/^(fixed|sticky)$/.test(getComputedStyle(c).position)&&(d=!0),c.scrollHeight<=c.clientHeight&&c.scrollWidth<=c.clientWidth){c=c.assignedSlot||c.parentNode;continue}let t=c.getBoundingClientRect();p=t.width/c.offsetWidth,f=t.height/c.offsetHeight,e={left:t.left,right:t.left+c.clientWidth*p,top:t.top,bottom:t.top+c.clientHeight*f}}let m=0,g=0;if("nearest"==s)t.top0&&t.bottom>e.bottom+g&&(g=t.bottom-e.bottom+g+o)):t.bottom>e.bottom&&(g=t.bottom-e.bottom+o,i<0&&t.top-g0&&t.right>e.right+m&&(m=t.right-e.right+m+r)):t.right>e.right&&(m=t.right-e.right+r,i<0&&t.left0))break;i=i.childNodes[n-1],n=nt(i)}if(i>=0)for(let n=e,s=t;;){if(3==n.nodeType)return{node:n,offset:s};if(!(1==n.nodeType&&s=0))break;n=n.childNodes[s],s=0}return null}let Ji=class{constructor(){this.changes=[]}compareRange(e,t){ei(e,t,this.changes)}comparePoint(e,t){ei(e,t,this.changes)}};function en(e,t){return t.left>e?t.left-e:Math.max(0,e-t.right)}function tn(e,t){return t.top>e?t.top-e:Math.max(0,e-t.bottom)}function nn(e,t){return e.topt.top+1}function sn(e,t){return te.bottom?{top:e.top,left:e.left,right:e.right,bottom:t}:e}function on(e,t,i){let n,s,r,o,a,l,h,c,d=!1;for(let u=e.firstChild;u;u=u.nextSibling){let e=Je(u);for(let p=0;pg||o==g&&r>m){n=u,s=f,r=m,o=g;let a=g?i0?p0)}0==m?i>f.bottom&&(!h||h.bottomf.top)&&(l=u,c=f):h&&nn(h,f)?h=rn(h,f.bottom):c&&nn(c,f)&&(c=sn(c,f.top))}}if(h&&h.bottom>=i?(n=a,s=h):c&&c.top<=i&&(n=l,s=c),!n)return{node:e,offset:0};let u=Math.max(s.left,Math.min(s.right,t));return 3==n.nodeType?an(n,u,i):d&&"false"!=n.contentEditable?on(n,u,i):{node:e,offset:Array.prototype.indexOf.call(e.childNodes,n)+(t>=(s.left+s.right)/2?1:0)}}function an(e,t,i){let n=e.nodeValue.length,s=-1,r=1e9,o=0;for(let a=0;ai?h.top-i:i-h.bottom)-1;if(h.left-1<=t&&h.right+1>=t&&c=(h.left+h.right)/2,n=i;if((Rt.chrome||Rt.gecko)&&ct(e,a).getBoundingClientRect().left==h.right&&(n=!i),c<=0)return{node:e,offset:a+(n?1:0)};s=a+(n?1:0),r=c}}}return{node:e,offset:s>-1?s:o>0?e.nodeValue.length:0}}function ln(e,t,i,n=-1){var s,r;let o,a=e.contentDOM.getBoundingClientRect(),l=a.top+e.viewState.paddingTop,{docHeight:h}=e.viewState,{x:c,y:d}=t,u=d-l;if(u<0)return 0;if(u>h)return e.state.doc.length;for(let t=e.viewState.heightOracle.textHeight/2,s=!1;o=e.elementAtHeight(u),o.type!=Xt.Text;)for(;u=n>0?o.bottom+t:o.top-t,!(u>=0&&u<=h);){if(s)return i?null:0;s=!0,n=-n}d=l+u;let p=o.from;if(pe.viewport.to)return e.viewport.to==e.state.doc.length?e.state.doc.length:i?null:hn(e,a,o,c,d);let f=e.dom.ownerDocument,m=e.root.elementFromPoint?e.root:f,g=m.elementFromPoint(c,d);g&&!e.contentDOM.contains(g)&&(g=null),g||(c=Math.max(a.left+1,Math.min(a.right-1,c)),g=m.elementFromPoint(c,d),g&&!e.contentDOM.contains(g)&&(g=null));let v,O=-1;if(g&&0!=(null===(s=e.docView.nearest(g))||void 0===s?void 0:s.isEditable))if(f.caretPositionFromPoint){let e=f.caretPositionFromPoint(c,d);e&&({offsetNode:v,offset:O}=e)}else if(f.caretRangeFromPoint){let t=f.caretRangeFromPoint(c,d);t&&(({startContainer:v,startOffset:O}=t),(!e.contentDOM.contains(v)||Rt.safari&&function(e,t,i){let n;if(3!=e.nodeType||t!=(n=e.nodeValue.length))return!1;for(let t=e.nextSibling;t;t=t.nextSibling)if(1!=t.nodeType||"BR"!=t.nodeName)return!1;return ct(e,n-1,n).getBoundingClientRect().left>i}(v,O,c)||Rt.chrome&&function(e,t,i){if(0!=t)return!1;for(let t=e;;){let e=t.parentNode;if(!e||1!=e.nodeType||e.firstChild!=t)return!1;if(e.classList.contains("cm-line"))break;t=e}return i-(1==e.nodeType?e.getBoundingClientRect():ct(e,0,Math.max(e.nodeValue.length,1)).getBoundingClientRect()).left>5}(v,O,c))&&(v=void 0))}if(!v||!e.docView.dom.contains(v)){let t=Ut.find(e.docView,p);if(!t)return u>o.top+o.height/2?o.to:o.from;({node:v,offset:O}=on(t.dom,c,d))}let b=e.docView.nearest(v);if(!b)return null;if(b.isWidget&&1==(null===(r=b.dom)||void 0===r?void 0:r.nodeType)){let e=b.dom.getBoundingClientRect();return t.y1.5*e.defaultLineHeight){let t=e.viewState.heightOracle.textHeight;r+=Math.floor((s-i.top-.5*(e.defaultLineHeight-t))/t)*e.viewState.heightOracle.lineLength}let o=e.state.sliceDoc(i.from,i.to);return i.from+Ne(o,r,e.state.tabSize)}function cn(e,t){let i=e.lineBlockAt(t);if(Array.isArray(i.type))for(let e of i.type)if(e.to>t||e.to==t&&(e.to==i.to||e.type==Xt.Text))return e;return i}function dn(e,t,i,n){let s=e.state.doc.lineAt(t.head),r=e.bidiSpans(s),o=e.textDirectionAt(s.from);for(let a=t,l=null;;){let t=Xi(s,r,o,a,i),h=Hi;if(!t){if(s.number==(i?e.state.doc.lines:1))return a;h="\n",s=e.state.doc.line(s.number+(i?1:-1)),r=e.bidiSpans(s),t=R.cursor(i?s.from:s.to)}if(l){if(!l(h))return a}else{if(!n)return t;l=n(h)}a=t}}function un(e,t,i){for(;;){let n=0;for(let s of e)s.between(t-1,t+1,((e,s,r)=>{if(t>e&&tt(e))),i.from,t.head>i.from?-1:1);return n==i.from?i:R.cursor(n,nnull)),Rt.gecko&&function(e){zn.has(e)||(zn.add(e),e.addEventListener("copy",(()=>{})),e.addEventListener("cut",(()=>{})))}(e.contentDOM.ownerDocument)}handleEvent(e){(function(e,t){if(!t.bubbles)return!0;if(t.defaultPrevented)return!1;for(let i,n=t.target;n!=e.contentDOM;n=n.parentNode)if(!n||11==n.nodeType||(i=gt.get(n))&&i.ignoreEvent(t))return!1;return!0})(this.view,e)&&!this.ignoreDuringComposition(e)&&("keydown"==e.type&&this.keydown(e)||this.runHandlers(e.type,e))}runHandlers(e,t){let i=this.handlers[e];if(i){for(let e of i.observers)e(this.view,t);for(let e of i.handlers){if(t.defaultPrevented)break;if(e(this.view,t)){t.preventDefault();break}}}}ensureHandlers(e){let t=gn(e),i=this.handlers,n=this.view.contentDOM;for(let e in t)if("scroll"!=e){let s=!t[e].handlers.length,r=i[e];r&&s!=!r.handlers.length&&(n.removeEventListener(e,this.handleEvent),r=null),r||n.addEventListener(e,this.handleEvent,{passive:s})}for(let e in i)"scroll"==e||t[e]||n.removeEventListener(e,this.handleEvent);this.handlers=t}keydown(e){if(this.lastKeyCode=e.keyCode,this.lastKeyTime=Date.now(),9==e.keyCode&&Date.now()t.keyCode==e.keyCode)))&&!e.ctrlKey||On.indexOf(e.key)>-1&&e.ctrlKey&&!e.shiftKey)?(229!=e.keyCode&&this.view.observer.forceFlush(),!1):(this.pendingIOSKey=t||e,setTimeout((()=>this.flushIOSKey()),250),!0)}flushIOSKey(){let e=this.pendingIOSKey;return!!e&&(this.pendingIOSKey=void 0,dt(this.view.contentDOM,e.key,e.keyCode))}ignoreDuringComposition(e){return!!/^key/.test(e.type)&&(this.composing>0||!!(Rt.safari&&!Rt.ios&&this.compositionPendingKey&&Date.now()-this.compositionEndedAt<100)&&(this.compositionPendingKey=!1,!0))}startMouseSelection(e){this.mouseSelection&&this.mouseSelection.destroy(),this.mouseSelection=e}update(e){this.mouseSelection&&this.mouseSelection.update(e),e.transactions.length&&(this.lastKeyCode=this.lastSelectionTime=0)}destroy(){this.mouseSelection&&this.mouseSelection.destroy()}}function mn(e,t){return(i,n)=>{try{return t.call(e,n,i)}catch(e){mi(i.state,e)}}}function gn(e){let t=Object.create(null);function i(e){return t[e]||(t[e]={observers:[],handlers:[]})}for(let t of e){let e=t.spec;if(e&&e.domEventHandlers)for(let n in e.domEventHandlers){let s=e.domEventHandlers[n];s&&i(n).handlers.push(mn(t.value,s))}if(e&&e.domEventObservers)for(let n in e.domEventObservers){let s=e.domEventObservers[n];s&&i(n).observers.push(mn(t.value,s))}}for(let e in wn)i(e).handlers.push(wn[e]);for(let e in xn)i(e).observers.push(xn[e]);return t}const vn=[{key:"Backspace",keyCode:8,inputType:"deleteContentBackward"},{key:"Enter",keyCode:13,inputType:"insertParagraph"},{key:"Enter",keyCode:13,inputType:"insertLineBreak"},{key:"Delete",keyCode:46,inputType:"deleteContentForward"}],On="dthko",bn=[16,17,18,20,91,92,224,225];function _n(e){return.7*Math.max(0,e)+8}class yn{constructor(e,t,i,n){this.view=e,this.startEvent=t,this.style=i,this.mustSelect=n,this.scrollSpeed={x:0,y:0},this.scrolling=-1,this.lastEvent=t,this.scrollParent=function(e){let t=e.ownerDocument;for(let i=e.parentNode;i&&i!=t.body;)if(1==i.nodeType){if(i.scrollHeight>i.clientHeight||i.scrollWidth>i.clientWidth)return i;i=i.assignedSlot||i.parentNode}else{if(11!=i.nodeType)break;i=i.host}return null}(e.contentDOM),this.atoms=e.state.facet(Si).map((t=>t(e)));let s=e.contentDOM.ownerDocument;s.addEventListener("mousemove",this.move=this.move.bind(this)),s.addEventListener("mouseup",this.up=this.up.bind(this)),this.extend=t.shiftKey,this.multiple=e.state.facet(Oe.allowMultipleSelections)&&function(e,t){let i=e.state.facet(si);return i.length?i[0](t):Rt.mac?t.metaKey:t.ctrlKey}(e,t),this.dragging=!(!function(e,t){let{main:i}=e.state.selection;if(i.empty)return!1;let n=Ge(e.root);if(!n||0==n.rangeCount)return!0;let s=n.getRangeAt(0).getClientRects();for(let e=0;e=t.clientX&&i.top<=t.clientY&&i.bottom>=t.clientY)return!0}return!1}(e,t)||1!=qn(t))&&null}start(e){!1===this.dragging&&this.select(e)}move(e){var t,i,n;if(0==e.buttons)return this.destroy();if(this.dragging||null==this.dragging&&(i=this.startEvent,n=e,Math.max(Math.abs(i.clientX-n.clientX),Math.abs(i.clientY-n.clientY))<10))return;this.select(this.lastEvent=e);let s=0,r=0,o=(null===(t=this.scrollParent)||void 0===t?void 0:t.getBoundingClientRect())||{left:0,top:0,right:this.view.win.innerWidth,bottom:this.view.win.innerHeight},a=Pi(this.view);e.clientX-a.left<=o.left+6?s=-_n(o.left-e.clientX):e.clientX+a.right>=o.right-6&&(s=_n(e.clientX-o.right)),e.clientY-a.top<=o.top+6?r=-_n(o.top-e.clientY):e.clientY+a.bottom>=o.bottom-6&&(r=_n(e.clientY-o.bottom)),this.setScrollSpeed(s,r)}up(e){null==this.dragging&&this.select(this.lastEvent),this.dragging||e.preventDefault(),this.destroy()}destroy(){this.setScrollSpeed(0,0);let e=this.view.contentDOM.ownerDocument;e.removeEventListener("mousemove",this.move),e.removeEventListener("mouseup",this.up),this.view.inputState.mouseSelection=null}setScrollSpeed(e,t){this.scrollSpeed={x:e,y:t},e||t?this.scrolling<0&&(this.scrolling=setInterval((()=>this.scroll()),50)):this.scrolling>-1&&(clearInterval(this.scrolling),this.scrolling=-1)}scroll(){this.scrollParent?(this.scrollParent.scrollLeft+=this.scrollSpeed.x,this.scrollParent.scrollTop+=this.scrollSpeed.y):this.view.win.scrollBy(this.scrollSpeed.x,this.scrollSpeed.y),!1===this.dragging&&this.select(this.lastEvent)}skipAtoms(e){let t=null;for(let i=0;ithis.select(this.lastEvent)),20)}}const wn=Object.create(null),xn=Object.create(null),Sn=Rt.ie&&Rt.ie_version<15||Rt.ios&&Rt.webkit_version<604;function kn(e,t){let i,{state:n}=e,s=1,r=n.toText(t),o=r.lines==n.selection.ranges.length;if(null!=Nn&&n.selection.ranges.every((e=>e.empty))&&Nn==r.toString()){let e=-1;i=n.changeByRange((i=>{let a=n.doc.lineAt(i.from);if(a.from==e)return{range:i};e=a.from;let l=n.toText((o?r.line(s++).text:t)+n.lineBreak);return{changes:{from:a.from,insert:l},range:R.cursor(i.from+l.length)}}))}else i=o?n.changeByRange((e=>{let t=r.line(s++);return{changes:{from:e.from,to:e.to,insert:t.text},range:R.cursor(e.from+t.length)}})):n.replaceSelection(r);e.dispatch(i,{userEvent:"input.paste",scrollIntoView:!0})}function Tn(e,t,i,n){if(1==n)return R.cursor(t,i);if(2==n)return function(e,t,i=1){let n=e.charCategorizer(t),s=e.doc.lineAt(t),r=t-s.from;if(0==s.length)return R.cursor(t);0==r?i=1:r==s.length&&(i=-1);let o=r,a=r;i<0?o=p(s.text,r,!1):a=p(s.text,r);let l=n(s.text.slice(o,a));for(;o>0;){let e=p(s.text,o,!1);if(n(s.text.slice(e,o))!=l)break;o=e}for(;a{e.inputState.lastScrollTop=e.scrollDOM.scrollTop,e.inputState.lastScrollLeft=e.scrollDOM.scrollLeft},wn.keydown=(e,t)=>(e.inputState.setSelectionOrigin("select"),27==t.keyCode&&(e.inputState.lastEscPress=Date.now()),!1),xn.touchstart=(e,t)=>{e.inputState.lastTouchTime=Date.now(),e.inputState.setSelectionOrigin("select.pointer")},xn.touchmove=e=>{e.inputState.setSelectionOrigin("select.pointer")},wn.mousedown=(e,t)=>{if(e.observer.flush(),e.inputState.lastTouchTime>Date.now()-2e3)return!1;let i=null;for(let n of e.state.facet(oi))if(i=n(e,t),i)break;if(i||0!=t.button||(i=function(e,t){let i=En(e,t),n=qn(t),s=e.state.selection;return{update(e){e.docChanged&&(i.pos=e.changes.mapPos(i.pos),s=s.map(e.changes))},get(t,r,o){let a,l=En(e,t),h=Tn(e,l.pos,l.bias,n);if(i.pos!=l.pos&&!r){let t=Tn(e,i.pos,i.bias,n),s=Math.min(t.from,h.from),r=Math.max(t.to,h.to);h=s1&&(a=function(e,t){for(let i=0;i=t)return R.create(e.ranges.slice(0,i).concat(e.ranges.slice(i+1)),e.mainIndex==i?0:e.mainIndex-(e.mainIndex>i?1:0))}return null}(s,l.pos))?a:o?s.addRange(h):R.create([h])}}}(e,t)),i){let n=!e.hasFocus;e.inputState.startMouseSelection(new yn(e,t,i,n)),n&&e.observer.ignore((()=>ht(e.contentDOM)));let s=e.inputState.mouseSelection;if(s)return s.start(t),!1===s.dragging}return!1};let Cn=(e,t)=>e>=t.top&&e<=t.bottom,Pn=(e,t,i)=>Cn(t,i)&&e>=i.left&&e<=i.right;function Mn(e,t,i,n){let s=Ut.find(e.docView,t);if(!s)return 1;let r=t-s.posAtStart;if(0==r)return 1;if(r==s.length)return-1;let o=s.coordsAt(r,-1);if(o&&Pn(i,n,o))return-1;let a=s.coordsAt(r,1);return a&&Pn(i,n,a)?1:o&&Cn(n,o)?-1:1}function En(e,t){let i=e.posAtCoords({x:t.clientX,y:t.clientY},!1);return{pos:i,bias:Mn(e,i,t.clientX,t.clientY)}}const An=Rt.ie&&Rt.ie_version<=11;let Rn=null,Dn=0,In=0;function qn(e){if(!An)return e.detail;let t=Rn,i=In;return Rn=e,In=Date.now(),Dn=!t||i>Date.now()-400&&Math.abs(t.clientX-e.clientX)<2&&Math.abs(t.clientY-e.clientY)<2?(Dn+1)%3:1}function Ln(e,t,i,n){if(!i)return;let s=e.posAtCoords({x:t.clientX,y:t.clientY},!1),{mouseSelection:r}=e.inputState,o=n&&r&&r.dragging&&function(e,t){let i=e.state.facet(ri);return i.length?i[0](t):Rt.mac?!t.altKey:!t.ctrlKey}(e,t)?{from:r.dragging.from,to:r.dragging.to}:null,a={from:s,insert:i},l=e.state.changes(o?[o,a]:a);e.focus(),e.dispatch({changes:l,selection:{anchor:l.mapPos(s,-1),head:l.mapPos(s,1)},userEvent:o?"move.drop":"input.drop"})}wn.dragstart=(e,t)=>{let{selection:{main:i}}=e.state,{mouseSelection:n}=e.inputState;return n&&(n.dragging=i),t.dataTransfer&&(t.dataTransfer.setData("Text",e.state.sliceDoc(i.from,i.to)),t.dataTransfer.effectAllowed="copyMove"),!1},wn.drop=(e,t)=>{if(!t.dataTransfer)return!1;if(e.state.readOnly)return!0;let i=t.dataTransfer.files;if(i&&i.length){let n=Array(i.length),s=0,r=()=>{++s==i.length&&Ln(e,t,n.filter((e=>null!=e)).join(e.state.lineBreak),!1)};for(let e=0;e{/[\x00-\x08\x0e-\x1f]{2}/.test(t.result)||(n[e]=t.result),r()},t.readAsText(i[e])}return!0}{let i=t.dataTransfer.getData("Text");if(i)return Ln(e,t,i,!0),!0}return!1},wn.paste=(e,t)=>{if(e.state.readOnly)return!0;e.observer.flush();let i=Sn?null:t.clipboardData;return i?(kn(e,i.getData("text/plain")||i.getData("text/uri-text")),!0):(function(e){let t=e.dom.parentNode;if(!t)return;let i=t.appendChild(document.createElement("textarea"));i.style.cssText="position: fixed; left: -10000px; top: 10px",i.focus(),setTimeout((()=>{e.focus(),i.remove(),kn(e,i.value)}),50)}(e),!1)};let Nn=null;wn.copy=wn.cut=(e,t)=>{let{text:i,ranges:n,linewise:s}=function(e){let t=[],i=[],n=!1;for(let n of e.selection.ranges)n.empty||(t.push(e.sliceDoc(n.from,n.to)),i.push(n));if(!t.length){let s=-1;for(let{from:n}of e.selection.ranges){let r=e.doc.lineAt(n);r.number>s&&(t.push(r.text),i.push({from:r.from,to:Math.min(e.doc.length,r.to+1)})),s=r.number}n=!0}return{text:t.join(e.lineBreak),ranges:i,linewise:n}}(e.state);if(!i&&!s)return!1;Nn=s?i:null,"cut"!=t.type||e.state.readOnly||e.dispatch({changes:n,scrollIntoView:!0,userEvent:"delete.cut"});let r=Sn?null:t.clipboardData;return r?(r.clearData(),r.setData("text/plain",i),!0):(function(e,t){let i=e.dom.parentNode;if(!i)return;let n=i.appendChild(document.createElement("textarea"));n.style.cssText="position: fixed; left: -10000px; top: 10px",n.value=t,n.focus(),n.selectionEnd=t.length,n.selectionStart=0,setTimeout((()=>{n.remove(),e.focus()}),50)}(e,i),!1)};const Bn=se.define();function $n(e,t){let i=[];for(let n of e.facet(ci)){let s=n(e,t);s&&i.push(s)}return i?e.update({effects:i,annotations:Bn.of(!0)}):null}function Qn(e){setTimeout((()=>{let t=e.hasFocus;if(t!=e.inputState.notifiedFocused){let i=$n(e.state,t);i?e.dispatch(i):e.update([])}}),10)}xn.focus=e=>{e.inputState.lastFocusTime=Date.now(),e.scrollDOM.scrollTop||!e.inputState.lastScrollTop&&!e.inputState.lastScrollLeft||(e.scrollDOM.scrollTop=e.inputState.lastScrollTop,e.scrollDOM.scrollLeft=e.inputState.lastScrollLeft),Qn(e)},xn.blur=e=>{e.observer.clearSelectionRange(),Qn(e)},xn.compositionstart=xn.compositionupdate=e=>{null==e.inputState.compositionFirstChange&&(e.inputState.compositionFirstChange=!0),e.inputState.composing<0&&(e.inputState.composing=0)},xn.compositionend=e=>{e.inputState.composing=-1,e.inputState.compositionEndedAt=Date.now(),e.inputState.compositionPendingKey=!0,e.inputState.compositionPendingChange=e.observer.pendingRecords().length>0,e.inputState.compositionFirstChange=null,Rt.chrome&&Rt.android?e.observer.flushSoon():e.inputState.compositionPendingChange?Promise.resolve().then((()=>e.observer.flush())):setTimeout((()=>{e.inputState.composing<0&&e.docView.hasComposition&&e.update([])}),50)},xn.contextmenu=e=>{e.inputState.lastContextMenu=Date.now()},wn.beforeinput=(e,t)=>{var i;let n;if(Rt.chrome&&Rt.android&&(n=vn.find((e=>e.inputType==t.inputType)))&&(e.observer.delayAndroidKey(n.key,n.keyCode),"Backspace"==n.key||"Delete"==n.key)){let t=(null===(i=window.visualViewport)||void 0===i?void 0:i.height)||0;setTimeout((()=>{var i;((null===(i=window.visualViewport)||void 0===i?void 0:i.height)||0)>t+10&&e.hasFocus&&(e.contentDOM.blur(),e.focus())}),100)}return!1};const zn=new Set,jn=["pre-wrap","normal","pre-line","break-spaces"];class Wn{constructor(t){this.lineWrapping=t,this.doc=e.empty,this.heightSamples={},this.lineHeight=14,this.charWidth=7,this.textHeight=14,this.lineLength=30,this.heightChanged=!1}heightForGap(e,t){let i=this.doc.lineAt(t).number-this.doc.lineAt(e).number+1;return this.lineWrapping&&(i+=Math.max(0,Math.ceil((t-e-i*this.lineLength*.5)/this.lineLength))),this.lineHeight*i}heightForLine(e){return this.lineWrapping?(1+Math.max(0,Math.ceil((e-this.lineLength)/(this.lineLength-5))))*this.lineHeight:this.lineHeight}setDoc(e){return this.doc=e,this}mustRefreshForWrapping(e){return jn.indexOf(e)>-1!=this.lineWrapping}mustRefreshForHeights(e){let t=!1;for(let i=0;i-1,a=Math.round(t)!=Math.round(this.lineHeight)||this.lineWrapping!=o;if(this.lineWrapping=o,this.lineHeight=t,this.charWidth=i,this.textHeight=n,this.lineLength=s,a){this.heightSamples={};for(let e=0;e0}set outdated(e){this.flags=(e?2:0)|-3&this.flags}setHeight(e,t){this.height!=t&&(Math.abs(this.height-t)>Hn&&(e.heightChanged=!0),this.height=t)}replace(e,t,i){return Xn.of(i)}decomposeLeft(e,t){t.push(this)}decomposeRight(e,t){t.push(this)}applyChanges(e,t,i,n){let s=this,r=i.doc;for(let o=n.length-1;o>=0;o--){let{fromA:a,toA:l,fromB:h,toB:c}=n[o],d=s.lineAt(a,Fn.ByPosNoHeight,i.setDoc(t),0,0),u=d.to>=l?d:s.lineAt(l,Fn.ByPosNoHeight,i,0,0);for(c+=u.to-l,l=u.to;o>0&&d.from<=n[o-1].toA;)a=n[o-1].fromA,h=n[o-1].fromB,o--,a2*s){let s=e[t-1];s.break?e.splice(--t,1,s.left,null,s.right):e.splice(--t,1,s.left,s.right),i+=1+s.break,n-=s.size}else{if(!(s>2*n))break;{let t=e[i];t.break?e.splice(i,1,t.left,null,t.right):e.splice(i,1,t.left,t.right),i+=2+t.break,s-=t.size}}else if(n=s&&r(this.blockAt(0,i,n,s))}updateHeight(e,t=0,i=!1,n){return n&&n.from<=t&&n.more&&this.setHeight(e,n.heights[n.index++]),this.outdated=!1,this}toString(){return`block(${this.length})`}}class Gn extends Yn{constructor(e,t){super(e,t,null),this.collapsed=0,this.widgetHeight=0,this.breaks=0}blockAt(e,t,i,n){return new Un(n,this.length,i,this.height,this.breaks)}replace(e,t,i){let n=i[0];return 1==i.length&&(n instanceof Gn||n instanceof Zn&&4&n.flags)&&Math.abs(this.length-n.length)<10?(n instanceof Zn?n=new Gn(n.length,this.height):n.height=this.height,this.outdated||(n.outdated=!1),n):Xn.of(i)}updateHeight(e,t=0,i=!1,n){return n&&n.from<=t&&n.more?this.setHeight(e,n.heights[n.index++]):(i||this.outdated)&&this.setHeight(e,Math.max(this.widgetHeight,e.heightForLine(this.length-this.collapsed))+this.breaks*e.lineHeight),this.outdated=!1,this}toString(){return`line(${this.length}${this.collapsed?-this.collapsed:""}${this.widgetHeight?":"+this.widgetHeight:""})`}}class Zn extends Xn{constructor(e){super(e,0)}heightMetrics(e,t){let i,n=e.doc.lineAt(t).number,s=e.doc.lineAt(t+this.length).number,r=s-n+1,o=0;if(e.lineWrapping){let t=Math.min(this.height,e.lineHeight*r);i=t/r,this.length>r+1&&(o=(this.height-t)/(this.length-r-1))}else i=this.height/r;return{firstLine:n,lastLine:s,perLine:i,perChar:o}}blockAt(e,t,i,n){let{firstLine:s,lastLine:r,perLine:o,perChar:a}=this.heightMetrics(t,n);if(t.lineWrapping){let s=n+Math.round(Math.max(0,Math.min(1,(e-i)/this.height))*this.length),r=t.doc.lineAt(s),l=o+r.length*a,h=Math.max(i,e-l/2);return new Un(r.from,r.length,h,l,0)}{let n=Math.max(0,Math.min(r-s,Math.floor((e-i)/o))),{from:a,length:l}=t.doc.line(s+n);return new Un(a,l,i+o*n,o,0)}}lineAt(e,t,i,n,s){if(t==Fn.ByHeight)return this.blockAt(e,i,n,s);if(t==Fn.ByPosNoHeight){let{from:t,to:n}=i.doc.lineAt(e);return new Un(t,n-t,0,0,0)}let{firstLine:r,perLine:o,perChar:a}=this.heightMetrics(i,s),l=i.doc.lineAt(e),h=o+l.length*a,c=l.number-r,d=n+o*c+a*(l.from-s-c);return new Un(l.from,l.length,Math.max(n,Math.min(d,n+this.height-h)),h,0)}forEachLine(e,t,i,n,s,r){e=Math.max(e,s),t=Math.min(t,s+this.length);let{firstLine:o,perLine:a,perChar:l}=this.heightMetrics(i,s);for(let h=e,c=n;h<=t;){let t=i.doc.lineAt(h);if(h==e){let i=t.number-o;c+=a*i+l*(e-s-i)}let n=a+l*t.length;r(new Un(t.from,t.length,c,n,0)),c+=n,h=t.to+1}}replace(e,t,i){let n=this.length-t;if(n>0){let e=i[i.length-1];e instanceof Zn?i[i.length-1]=new Zn(e.length+n):i.push(null,new Zn(n-1))}if(e>0){let t=i[0];t instanceof Zn?i[0]=new Zn(e+t.length):i.unshift(new Zn(e-1),null)}return Xn.of(i)}decomposeLeft(e,t){t.push(new Zn(e-1),null)}decomposeRight(e,t){t.push(null,new Zn(this.length-e-1))}updateHeight(e,t=0,i=!1,n){let s=t+this.length;if(n&&n.from<=t+this.length&&n.more){let i=[],r=Math.max(t,n.from),o=-1;for(n.from>t&&i.push(new Zn(n.from-t-1).updateHeight(e,t));r<=s&&n.more;){let t=e.doc.lineAt(r).length;i.length&&i.push(null);let s=n.heights[n.index++];-1==o?o=s:Math.abs(s-o)>=Hn&&(o=-2);let a=new Gn(t,s);a.outdated=!1,i.push(a),r+=t+1}r<=s&&i.push(null,new Zn(s-r).updateHeight(e,r));let a=Xn.of(i);return(o<0||Math.abs(a.height-this.height)>=Hn||Math.abs(o-this.heightMetrics(e,t).perLine)>=Hn)&&(e.heightChanged=!0),a}return(i||this.outdated)&&(this.setHeight(e,e.heightForGap(t,t+this.length)),this.outdated=!1),this}toString(){return`gap(${this.length})`}}class Kn extends Xn{constructor(e,t,i){super(e.length+t+i.length,e.height+i.height,t|(e.outdated||i.outdated?2:0)),this.left=e,this.right=i,this.size=e.size+i.size}get break(){return 1&this.flags}blockAt(e,t,i,n){let s=i+this.left.height;return eo))return l;let h=t==Fn.ByPosNoHeight?Fn.ByPosNoHeight:Fn.ByPos;return a?l.join(this.right.lineAt(o,h,i,r,o)):this.left.lineAt(o,h,i,n,s).join(l)}forEachLine(e,t,i,n,s,r){let o=n+this.left.height,a=s+this.left.length+this.break;if(this.break)e=a&&this.right.forEachLine(e,t,i,o,a,r);else{let l=this.lineAt(a,Fn.ByPos,i,n,s);e=e&&l.from<=t&&r(l),t>l.to&&this.right.forEachLine(l.to+1,t,i,o,a,r)}}replace(e,t,i){let n=this.left.length+this.break;if(tthis.left.length)return this.balanced(this.left,this.right.replace(e-n,t-n,i));let s=[];e>0&&this.decomposeLeft(e,s);let r=s.length;for(let e of i)s.push(e);if(e>0&&Jn(s,r-1),t=i&&t.push(null)),e>i&&this.right.decomposeLeft(e-i,t)}decomposeRight(e,t){let i=this.left.length,n=i+this.break;if(e>=n)return this.right.decomposeRight(e-n,t);e2*t.size||t.size>2*e.size?Xn.of(this.break?[e,null,t]:[e,t]):(this.left=e,this.right=t,this.height=e.height+t.height,this.outdated=e.outdated||t.outdated,this.size=e.size+t.size,this.length=e.length+this.break+t.length,this)}updateHeight(e,t=0,i=!1,n){let{left:s,right:r}=this,o=t+s.length+this.break,a=null;return n&&n.from<=t+s.length&&n.more?a=s=s.updateHeight(e,t,i,n):s.updateHeight(e,t,i),n&&n.from<=o+r.length&&n.more?a=r=r.updateHeight(e,o,i,n):r.updateHeight(e,o,i),a?this.balanced(s,r):(this.height=this.left.height+this.right.height,this.outdated=!1,this)}toString(){return this.left+(this.break?" ":"-")+this.right}}function Jn(e,t){let i,n;null==e[t]&&(i=e[t-1])instanceof Zn&&(n=e[t+1])instanceof Zn&&e.splice(t-1,3,new Zn(i.length+1+n.length))}class es{constructor(e,t){this.pos=e,this.oracle=t,this.nodes=[],this.lineStart=-1,this.lineEnd=-1,this.covering=null,this.writtenTo=e}get isCovered(){return this.covering&&this.nodes[this.nodes.length-1]==this.covering}span(e,t){if(this.lineStart>-1){let e=Math.min(t,this.lineEnd),i=this.nodes[this.nodes.length-1];i instanceof Gn?i.length+=e-this.pos:(e>this.pos||!this.isCovered)&&this.nodes.push(new Gn(e-this.pos,-1)),this.writtenTo=e,t>e&&(this.nodes.push(null),this.writtenTo++,this.lineStart=-1)}this.pos=t}point(e,t,i){if(e=5)&&this.addLineDeco(n,s,r)}else t>e&&this.span(e,t);this.lineEnd>-1&&this.lineEnd-1)return;let{from:e,to:t}=this.oracle.doc.lineAt(this.pos);this.lineStart=e,this.lineEnd=t,this.writtenToe&&this.nodes.push(new Gn(this.pos-e,-1)),this.writtenTo=this.pos}blankContent(e,t){let i=new Zn(t-e);return this.oracle.doc.lineAt(e).to==t&&(i.flags|=4),i}ensureLine(){this.enterLine();let e=this.nodes.length?this.nodes[this.nodes.length-1]:null;if(e instanceof Gn)return e;let t=new Gn(0,-1);return this.nodes.push(t),t}addBlock(e){this.enterLine();let t=e.deco;t&&t.startSide>0&&!this.isCovered&&this.ensureLine(),this.nodes.push(e),this.writtenTo=this.pos=this.pos+e.length,t&&t.endSide>0&&(this.covering=e)}addLineDeco(e,t,i){let n=this.ensureLine();n.length+=i,n.collapsed+=i,n.widgetHeight=Math.max(n.widgetHeight,e),n.breaks+=t,this.writtenTo=this.pos=this.pos+i}finish(e){let t=0==this.nodes.length?null:this.nodes[this.nodes.length-1];!(this.lineStart>-1)||t instanceof Gn||this.isCovered?(this.writtenToi.clientHeight||i.scrollWidth>i.clientWidth)&&"visible"!=n.overflow){let n=i.getBoundingClientRect();r=Math.max(r,n.left),o=Math.min(o,n.right),a=Math.max(a,n.top),l=t==e.parentNode?n.bottom:Math.min(l,n.bottom)}t="absolute"==n.position||"fixed"==n.position?i.offsetParent:i.parentNode}else{if(11!=t.nodeType)break;t=t.host}return{left:r-i.left,right:Math.max(r,o)-i.left,top:a-(i.top+t),bottom:Math.max(a,l)-(i.top+t)}}function ns(e,t){let i=e.getBoundingClientRect();return{left:0,right:i.right-i.left,top:t,bottom:i.bottom-(i.top+t)}}class ss{constructor(e,t,i){this.from=e,this.to=t,this.size=i}static same(e,t){if(e.length!=t.length)return!1;for(let i=0;i"function"!=typeof e&&"cm-lineWrapping"==e.class));this.heightOracle=new Wn(i),this.stateDeco=t.facet(xi).filter((e=>"function"!=typeof e)),this.heightMap=Xn.empty().applyChanges(this.stateDeco,e.empty,this.heightOracle.setDoc(t.doc),[new Ei(0,0,0,t.doc.length)]),this.viewport=this.getViewport(0,null),this.updateViewportLines(),this.updateForViewport(),this.lineGaps=this.ensureLineGaps([]),this.lineGapDeco=Yt.set(this.lineGaps.map((e=>e.draw(this,!1)))),this.computeVisibleRanges()}updateForViewport(){let e=[this.viewport],{main:t}=this.state.selection;for(let i=0;i<=1;i++){let n=i?t.head:t.anchor;if(!e.some((({from:e,to:t})=>n>=e&&n<=t))){let{from:t,to:i}=this.lineBlockAt(n);e.push(new as(t,i))}}this.viewports=e.sort(((e,t)=>e.from-t.from)),this.scaler=this.heightMap.height<=7e6?ds:new us(this.heightOracle,this.heightMap,this.viewports)}updateViewportLines(){this.viewportLines=[],this.heightMap.forEachLine(this.viewport.from,this.viewport.to,this.heightOracle.setDoc(this.state.doc),0,0,(e=>{this.viewportLines.push(1==this.scaler.scale?e:ps(e,this.scaler))}))}update(e,t=null){this.state=e.state;let i=this.stateDeco;this.stateDeco=this.state.facet(xi).filter((e=>"function"!=typeof e));let n=e.changedRanges,s=Ei.extendWithRanges(n,function(e,t,i){let n=new ts;return Se.compare(e,t,i,n,0),n.changes}(i,this.stateDeco,e?e.changes:S.empty(this.state.doc.length))),r=this.heightMap.height,o=this.scrolledToBottom?null:this.scrollAnchorAt(this.scrollTop);this.heightMap=this.heightMap.applyChanges(this.stateDeco,e.startState.doc,this.heightOracle.setDoc(this.state.doc),s),this.heightMap.height!=r&&(e.flags|=2),o?(this.scrollAnchorPos=e.changes.mapPos(o.from,-1),this.scrollAnchorHeight=o.top):(this.scrollAnchorPos=-1,this.scrollAnchorHeight=this.heightMap.height);let a=s.length?this.mapViewport(this.viewport,e.changes):this.viewport;(t&&(t.range.heada.to)||!this.viewportIsAppropriate(a))&&(a=this.getViewport(0,t));let l=!e.changes.empty||2&e.flags||a.from!=this.viewport.from||a.to!=this.viewport.to;this.viewport=a,this.updateForViewport(),l&&this.updateViewportLines(),(this.lineGaps.length||this.viewport.to-this.viewport.from>4e3)&&this.updateLineGaps(this.ensureLineGaps(this.mapLineGaps(this.lineGaps,e.changes))),e.flags|=this.computeVisibleRanges(),t&&(this.scrollTarget=t),!this.mustEnforceCursorAssoc&&e.selectionSet&&e.view.lineWrapping&&e.state.selection.main.empty&&e.state.selection.main.assoc&&!e.state.facet(ui)&&(this.mustEnforceCursorAssoc=!0)}measure(t){let i=t.contentDOM,n=window.getComputedStyle(i),s=this.heightOracle,r=n.whiteSpace;this.defaultTextDirection="rtl"==n.direction?Ri.RTL:Ri.LTR;let o=this.heightOracle.mustRefreshForWrapping(r),a=i.getBoundingClientRect(),l=o||this.mustMeasureContent||this.contentDOMHeight!=a.height;this.contentDOMHeight=a.height,this.mustMeasureContent=!1;let h=0,c=0;if(a.width&&a.height){let e=a.width/i.offsetWidth,t=a.height/i.offsetHeight;(e>.995&&e<1.005||!isFinite(e)||Math.abs(a.width-i.offsetWidth)<1)&&(e=1),(t>.995&&t<1.005||!isFinite(t)||Math.abs(a.height-i.offsetHeight)<1)&&(t=1),this.scaleX==e&&this.scaleY==t||(this.scaleX=e,this.scaleY=t,h|=8,o=l=!0)}let d=(parseInt(n.paddingTop)||0)*this.scaleY,u=(parseInt(n.paddingBottom)||0)*this.scaleY;this.paddingTop==d&&this.paddingBottom==u||(this.paddingTop=d,this.paddingBottom=u,h|=10),this.editorWidth!=t.scrollDOM.clientWidth&&(s.lineWrapping&&(l=!0),this.editorWidth=t.scrollDOM.clientWidth,h|=8);let p=t.scrollDOM.scrollTop*this.scaleY;this.scrollTop!=p&&(this.scrollAnchorHeight=-1,this.scrollTop=p),this.scrolledToBottom=pt(t.scrollDOM);let f=(this.printing?ns:is)(i,this.paddingTop),m=f.top-this.pixelViewport.top,g=f.bottom-this.pixelViewport.bottom;this.pixelViewport=f;let v=this.pixelViewport.bottom>this.pixelViewport.top&&this.pixelViewport.right>this.pixelViewport.left;if(v!=this.inView&&(this.inView=v,v&&(l=!0)),!this.inView&&!this.scrollTarget)return 0;let O=a.width;if(this.contentDOMWidth==O&&this.editorHeight==t.scrollDOM.clientHeight||(this.contentDOMWidth=a.width,this.editorHeight=t.scrollDOM.clientHeight,h|=8),l){let i=t.docView.measureVisibleLineHeights(this.viewport);if(s.mustRefreshForHeights(i)&&(o=!0),o||s.lineWrapping&&Math.abs(O-this.contentDOMWidth)>s.charWidth){let{lineHeight:e,charWidth:n,textHeight:a}=t.docView.measureTextSize();o=e>0&&s.refresh(r,e,n,a,O/n,i),o&&(t.docView.minWidth=0,h|=8)}m>0&&g>0?c=Math.max(m,g):m<0&&g<0&&(c=Math.min(m,g)),s.heightChanged=!1;for(let n of this.viewports){let r=n.from==this.viewport.from?i:t.docView.measureVisibleLineHeights(n);this.heightMap=(o?Xn.empty().applyChanges(this.stateDeco,e.empty,this.heightOracle,[new Ei(0,0,0,t.state.doc.length)]):this.heightMap).updateHeight(s,0,o,new Vn(n.from,r))}s.heightChanged&&(h|=2)}let b=!this.viewportIsAppropriate(this.viewport,c)||this.scrollTarget&&(this.scrollTarget.range.headthis.viewport.to);return b&&(this.viewport=this.getViewport(c,this.scrollTarget)),this.updateForViewport(),(2&h||b)&&this.updateViewportLines(),(this.lineGaps.length||this.viewport.to-this.viewport.from>4e3)&&this.updateLineGaps(this.ensureLineGaps(o?[]:this.lineGaps,t)),h|=this.computeVisibleRanges(),this.mustEnforceCursorAssoc&&(this.mustEnforceCursorAssoc=!1,t.docView.enforceCursorAssoc()),h}get visibleTop(){return this.scaler.fromDOM(this.pixelViewport.top)}get visibleBottom(){return this.scaler.fromDOM(this.pixelViewport.bottom)}getViewport(e,t){let i=.5-Math.max(-.5,Math.min(.5,e/1e3/2)),n=this.heightMap,s=this.heightOracle,{visibleTop:r,visibleBottom:o}=this,a=new as(n.lineAt(r-1e3*i,Fn.ByHeight,s,0,0).from,n.lineAt(o+1e3*(1-i),Fn.ByHeight,s,0,0).to);if(t){let{head:e}=t.range;if(ea.to){let i,r=Math.min(this.editorHeight,this.pixelViewport.bottom-this.pixelViewport.top),o=n.lineAt(e,Fn.ByPos,s,0,0);i="center"==t.y?(o.top+o.bottom)/2-r/2:"start"==t.y||"nearest"==t.y&&e=o+Math.max(10,Math.min(i,250)))&&n>r-2e3&&s>1,r=n<<1;if(this.defaultTextDirection!=Ri.LTR&&!i)return[];let o=[],a=(n,r,l,h)=>{if(r-nn&&ee.from>=l.from&&e.to<=l.to&&Math.abs(e.from-n)e.fromt))));if(!u){if(re.from<=r&&e.to>=r))){let e=t.moveToLineBoundary(R.cursor(r),!1,!0).head;e>n&&(r=e)}u=new ss(n,r,this.gapSize(l,n,r,h))}o.push(u)};for(let e of this.viewportLines){if(e.lengthe.from&&a(e.from,s,e,t),oe.draw(this,this.heightOracle.lineWrapping)))))}computeVisibleRanges(){let e=this.stateDeco;this.lineGaps.length&&(e=e.concat(this.lineGapDeco));let t=[];Se.spans(e,this.viewport.from,this.viewport.to,{span(e,i){t.push({from:e,to:i})},point(){}},20);let i=t.length!=this.visibleRanges.length||this.visibleRanges.some(((e,i)=>e.from!=t[i].from||e.to!=t[i].to));return this.visibleRanges=t,i?4:0}lineBlockAt(e){return e>=this.viewport.from&&e<=this.viewport.to&&this.viewportLines.find((t=>t.from<=e&&t.to>=e))||ps(this.heightMap.lineAt(e,Fn.ByPos,this.heightOracle,0,0),this.scaler)}lineBlockAtHeight(e){return ps(this.heightMap.lineAt(this.scaler.fromDOM(e),Fn.ByHeight,this.heightOracle,0,0),this.scaler)}scrollAnchorAt(e){let t=this.lineBlockAtHeight(e+8);return t.from>=this.viewport.from||this.viewportLines[0].top-e>200?t:this.viewportLines[0]}elementAtHeight(e){return ps(this.heightMap.blockAt(this.scaler.fromDOM(e),this.heightOracle,0,0),this.scaler)}get docHeight(){return this.scaler.toDOM(this.heightMap.height)}get contentHeight(){return this.docHeight+this.paddingTop+this.paddingBottom}}class as{constructor(e,t){this.from=e,this.to=t}}function ls(e,t,i){let n=[],s=e,r=0;return Se.spans(i,e,t,{span(){},point(e,t){e>s&&(n.push({from:s,to:e}),r+=e-s),s=t}},20),s=1)return t[t.length-1].to;let n=Math.floor(e*i);for(let e=0;;e++){let{from:i,to:s}=t[e],r=s-i;if(n<=r)return i+n;n-=r}}function cs(e,t){let i=0;for(let{from:n,to:s}of e.ranges){if(t<=s){i+=t-n;break}i+=s-n}return i/e.total}const ds={toDOM:e=>e,fromDOM:e=>e,scale:1};class us{constructor(e,t,i){let n=0,s=0,r=0;this.viewports=i.map((({from:i,to:s})=>{let r=t.lineAt(i,Fn.ByPos,e,0,0).top,o=t.lineAt(s,Fn.ByPos,e,0,0).bottom;return n+=o-r,{from:i,to:s,top:r,bottom:o,domTop:0,domBottom:0}})),this.scale=(7e6-n)/(t.height-n);for(let e of this.viewports)e.domTop=r+(e.top-s)*this.scale,r=e.domBottom=e.domTop+(e.bottom-e.top),s=e.bottom}toDOM(e){for(let t=0,i=0,n=0;;t++){let s=tps(e,t))):e._content)}const fs=q.define({combine:e=>e.join(" ")}),ms=q.define({combine:e=>e.indexOf(!0)>-1}),gs=ze.newName(),vs=ze.newName(),Os=ze.newName(),bs={"&light":"."+vs,"&dark":"."+Os};function _s(e,t,i){return new ze(t,{finish:t=>/&/.test(t)?t.replace(/&\w*/,(t=>{if("&"==t)return e;if(!i||!i[t])throw new RangeError(`Unsupported selector: ${t}`);return i[t]})):e+" "+t})}const ys=_s("."+gs,{"&":{position:"relative !important",boxSizing:"border-box","&.cm-focused":{outline:"1px dotted #212121"},display:"flex !important",flexDirection:"column"},".cm-scroller":{display:"flex !important",alignItems:"flex-start !important",fontFamily:"monospace",lineHeight:1.4,height:"100%",overflowX:"auto",position:"relative",zIndex:0},".cm-content":{margin:0,flexGrow:2,flexShrink:0,display:"block",whiteSpace:"pre",wordWrap:"normal",boxSizing:"border-box",minHeight:"100%",padding:"4px 0",outline:"none","&[contenteditable=true]":{WebkitUserModify:"read-write-plaintext-only"}},".cm-lineWrapping":{whiteSpace_fallback:"pre-wrap",whiteSpace:"break-spaces",wordBreak:"break-word",overflowWrap:"anywhere",flexShrink:1},"&light .cm-content":{caretColor:"black"},"&dark .cm-content":{caretColor:"white"},".cm-line":{display:"block",padding:"0 2px 0 6px"},".cm-layer":{position:"absolute",left:0,top:0,contain:"size style","& > *":{position:"absolute"}},"&light .cm-selectionBackground":{background:"#d9d9d9"},"&dark .cm-selectionBackground":{background:"#222"},"&light.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground":{background:"#d7d4f0"},"&dark.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground":{background:"#233"},".cm-cursorLayer":{pointerEvents:"none"},"&.cm-focused > .cm-scroller > .cm-cursorLayer":{animation:"steps(1) cm-blink 1.2s infinite"},"@keyframes cm-blink":{"0%":{},"50%":{opacity:0},"100%":{}},"@keyframes cm-blink2":{"0%":{},"50%":{opacity:0},"100%":{}},".cm-cursor, .cm-dropCursor":{borderLeft:"1.2px solid black",marginLeft:"-0.6px",pointerEvents:"none"},".cm-cursor":{display:"none"},"&dark .cm-cursor":{borderLeftColor:"#444"},".cm-dropCursor":{position:"absolute"},"&.cm-focused > .cm-scroller > .cm-cursorLayer .cm-cursor":{display:"block"},"&light .cm-activeLine":{backgroundColor:"#cceeff44"},"&dark .cm-activeLine":{backgroundColor:"#99eeff33"},"&light .cm-specialChar":{color:"red"},"&dark .cm-specialChar":{color:"#f78"},".cm-gutters":{flexShrink:0,display:"flex",height:"100%",boxSizing:"border-box",insetInlineStart:0,zIndex:200},"&light .cm-gutters":{backgroundColor:"#f5f5f5",color:"#6c6c6c",borderRight:"1px solid #ddd"},"&dark .cm-gutters":{backgroundColor:"#333338",color:"#ccc"},".cm-gutter":{display:"flex !important",flexDirection:"column",flexShrink:0,boxSizing:"border-box",minHeight:"100%",overflow:"hidden"},".cm-gutterElement":{boxSizing:"border-box"},".cm-lineNumbers .cm-gutterElement":{padding:"0 3px 0 5px",minWidth:"20px",textAlign:"right",whiteSpace:"nowrap"},"&light .cm-activeLineGutter":{backgroundColor:"#e2f2ff"},"&dark .cm-activeLineGutter":{backgroundColor:"#222227"},".cm-panels":{boxSizing:"border-box",position:"sticky",left:0,right:0},"&light .cm-panels":{backgroundColor:"#f5f5f5",color:"black"},"&light .cm-panels-top":{borderBottom:"1px solid #ddd"},"&light .cm-panels-bottom":{borderTop:"1px solid #ddd"},"&dark .cm-panels":{backgroundColor:"#333338",color:"white"},".cm-tab":{display:"inline-block",overflow:"hidden",verticalAlign:"bottom"},".cm-widgetBuffer":{verticalAlign:"text-top",height:"1em",width:0,display:"inline"},".cm-placeholder":{color:"#888",display:"inline-block",verticalAlign:"top"},".cm-highlightSpace:before":{content:"attr(data-display)",position:"absolute",pointerEvents:"none",color:"#888"},".cm-highlightTab":{backgroundImage:'url(\'data:image/svg+xml,\')',backgroundSize:"auto 100%",backgroundPosition:"right 90%",backgroundRepeat:"no-repeat"},".cm-trailingSpace":{backgroundColor:"#ff332255"},".cm-button":{verticalAlign:"middle",color:"inherit",fontSize:"70%",padding:".2em 1em",borderRadius:"1px"},"&light .cm-button":{backgroundImage:"linear-gradient(#eff1f5, #d9d9df)",border:"1px solid #888","&:active":{backgroundImage:"linear-gradient(#b4b4b4, #d0d3d6)"}},"&dark .cm-button":{backgroundImage:"linear-gradient(#393939, #111)",border:"1px solid #888","&:active":{backgroundImage:"linear-gradient(#111, #333)"}},".cm-textfield":{verticalAlign:"middle",color:"inherit",fontSize:"70%",border:"1px solid silver",padding:".2em .5em"},"&light .cm-textfield":{backgroundColor:"white"},"&dark .cm-textfield":{border:"1px solid #555",backgroundColor:"inherit"}},bs),ws="￿";class xs{constructor(e,t){this.points=e,this.text="",this.lineSeparator=t.facet(Oe.lineSeparator)}append(e){this.text+=e}lineBreak(){this.text+=ws}readRange(e,t){if(!e)return this;let i=e.parentNode;for(let n=e;;){this.findPointBefore(i,n);let e=this.text.length;this.readNode(n);let s=n.nextSibling;if(s==t)break;let r=gt.get(n),o=gt.get(s);(r&&o?r.breakAfter:(r?r.breakAfter:ks(n))||ks(s)&&("BR"!=n.nodeName||n.cmIgnore)&&this.text.length>e)&&this.lineBreak(),n=s}return this.findPointBefore(i,t),this}readTextNode(e){let t=e.nodeValue;for(let i of this.points)i.node==e&&(i.pos=this.text.length+Math.min(i.offset,t.length));for(let i=0,n=this.lineSeparator?null:/\r\n?|\n/g;;){let s,r=-1,o=1;if(this.lineSeparator?(r=t.indexOf(this.lineSeparator,i),o=this.lineSeparator.length):(s=n.exec(t))&&(r=s.index,o=s[0].length),this.append(t.slice(i,r<0?t.length:r)),r<0)break;if(this.lineBreak(),o>1)for(let t of this.points)t.node==e&&t.pos>this.text.length&&(t.pos-=o-1);i=r+o}}readNode(e){if(e.cmIgnore)return;let t=gt.get(e),i=t&&t.overrideDOMText;if(null!=i){this.findPointInside(e,i.length);for(let e=i.iter();!e.next().done;)e.lineBreak?this.lineBreak():this.append(e.value)}else 3==e.nodeType?this.readTextNode(e):"BR"==e.nodeName?e.nextSibling&&this.lineBreak():1==e.nodeType&&this.readRange(e.firstChild,null)}findPointBefore(e,t){for(let i of this.points)i.node==e&&e.childNodes[i.offset]==t&&(i.pos=this.text.length)}findPointInside(e,t){for(let i of this.points)(3==e.nodeType?i.node==e:e.contains(i.node))&&(i.pos=this.text.length+(Ss(e,i.node,i.offset)?t:0))}}function Ss(e,t,i){for(;;){if(!t||i-1)this.newSel=null;else if(t>-1&&(this.bounds=e.docView.domBoundsAround(t,i,0))){let t=s||r?[]:function(e){let t=[];if(e.root.activeElement!=e.contentDOM)return t;let{anchorNode:i,anchorOffset:n,focusNode:s,focusOffset:r}=e.observer.selectionRange;return i&&(t.push(new Ts(i,n)),s==i&&r==n||t.push(new Ts(s,r))),t}(e),i=new xs(t,e.state);i.readRange(this.bounds.startDOM,this.bounds.endDOM),this.text=i.text,this.newSel=function(e,t){if(0==e.length)return null;let i=e[0].pos,n=2==e.length?e[1].pos:i;return i>-1&&n>-1?R.single(i+t,n+t):null}(t,this.bounds.from)}else{let t=e.observer.selectionRange,i=s&&s.node==t.focusNode&&s.offset==t.focusOffset||!Ze(e.contentDOM,t.focusNode)?e.state.selection.main.head:e.docView.posFromDOM(t.focusNode,t.focusOffset),n=r&&r.node==t.anchorNode&&r.offset==t.anchorOffset||!Ze(e.contentDOM,t.anchorNode)?e.state.selection.main.anchor:e.docView.posFromDOM(t.anchorNode,t.anchorOffset);this.newSel=R.single(n,i)}}}function Ps(t,i){let n,{newSel:s}=i,r=t.state.selection.main,o=t.inputState.lastKeyTime>Date.now()-100?t.inputState.lastKeyCode:-1;if(i.bounds){let{from:s,to:a}=i.bounds,l=r.from,h=null;(8===o||Rt.android&&i.text.length0&&a>0&&e.charCodeAt(o-1)==t.charCodeAt(a-1);)o--,a--;return"end"==n&&(i-=o+Math.max(0,r-Math.min(o,a))-r),o=o?r-i:0,a=r+(a-o),o=r):a=a?r-i:0,o=r+(o-a),a=r),{from:r,toA:o,toB:a}}(t.state.doc.sliceString(s,a,ws),i.text,l-s,h);c&&(Rt.chrome&&13==o&&c.toB==c.from+2&&i.text.slice(c.from,c.toB)==ws+ws&&c.toB--,n={from:s+c.from,to:s+c.toA,insert:e.of(i.text.slice(c.from,c.toB).split(ws))})}else s&&(!t.hasFocus&&t.state.facet(gi)||s.main.eq(r))&&(s=null);if(!n&&!s)return!1;if(!n&&i.typeOver&&!r.empty&&s&&s.main.empty?n={from:r.from,to:r.to,insert:t.state.doc.slice(r.from,r.to)}:n&&n.from>=r.from&&n.to<=r.to&&(n.from!=r.from||n.to!=r.to)&&r.to-r.from-(n.to-n.from)<=4?n={from:r.from,to:r.to,insert:t.state.doc.slice(r.from,n.from).append(n.insert).append(t.state.doc.slice(n.to,r.to))}:(Rt.mac||Rt.android)&&n&&n.from==n.to&&n.from==r.head-1&&/^\. ?$/.test(n.insert.toString())&&"off"==t.contentDOM.getAttribute("autocorrect")?(s&&2==n.insert.length&&(s=R.single(s.main.anchor-1,s.main.head-1)),n={from:r.from,to:r.to,insert:e.of([" "])}):Rt.chrome&&n&&n.from==n.to&&n.from==r.head&&"\n "==n.insert.toString()&&t.lineWrapping&&(s&&(s=R.single(s.main.anchor-1,s.main.head-1)),n={from:r.from,to:r.to,insert:e.of([" "])}),n){if(Rt.ios&&t.inputState.flushIOSKey())return!0;if(Rt.android&&(n.from==r.from&&n.to==r.to&&1==n.insert.length&&2==n.insert.lines&&dt(t.contentDOM,"Enter",13)||(n.from==r.from-1&&n.to==r.to&&0==n.insert.length||8==o&&n.insert.lengthr.head)&&dt(t.contentDOM,"Backspace",8)||n.from==r.from&&n.to==r.to+1&&0==n.insert.length&&dt(t.contentDOM,"Delete",46)))return!0;let e,i=n.insert.toString();t.inputState.composing>=0&&t.inputState.composing++;let a=()=>e||(e=function(e,t,i){let n,s=e.state,r=s.selection.main;if(t.from>=r.from&&t.to<=r.to&&t.to-t.from>=(r.to-r.from)/3&&(!i||i.main.empty&&i.main.from==t.from+t.insert.length)&&e.inputState.composing<0){let i=r.fromt.to?s.sliceDoc(t.to,r.to):"";n=s.replaceSelection(e.state.toText(i+t.insert.sliceString(0,void 0,e.state.lineBreak)+o))}else{let o=s.changes(t),a=i&&i.main.to<=o.newLength?i.main:void 0;if(s.selection.ranges.length>1&&e.inputState.composing>=0&&t.to<=r.to&&t.to>=r.to-10){let l,h=e.state.sliceDoc(t.from,t.to),c=i&&Zi(e,i.main.head);if(c){let e=t.insert.length-(t.to-t.from);l={from:c.from,to:c.to-e}}else l=e.state.doc.lineAt(r.head);let d=r.to-t.to,u=r.to-r.from;n=s.changeByRange((i=>{if(i.from==r.from&&i.to==r.to)return{changes:o,range:a||i.map(o)};let n=i.to-d,c=n-h.length;if(i.to-i.from!=u||e.state.sliceDoc(c,n)!=h||i.to>=l.from&&i.from<=l.to)return{range:i};let p=s.changes({from:c,to:n,insert:t.insert}),f=i.to-r.to;return{changes:p,range:a?R.range(Math.max(0,a.anchor+f),Math.max(0,a.head+f)):i.map(p)}}))}else n={changes:o,selection:a&&s.selection.replaceRange(a)}}let o="input.type";return(e.composing||e.inputState.compositionPendingChange&&e.inputState.compositionEndedAt>Date.now()-50)&&(e.inputState.compositionPendingChange=!1,o+=".compose",e.inputState.compositionFirstChange&&(o+=".start",e.inputState.compositionFirstChange=!1)),s.update(n,{userEvent:o,scrollIntoView:!0})}(t,n,s));return t.state.facet(hi).some((e=>e(t,n.from,n.to,i,a)))||t.dispatch(a()),!0}if(s&&!s.main.eq(r)){let e=!1,i="select";return t.inputState.lastSelectionTime>Date.now()-50&&("select"==t.inputState.lastSelectionOrigin&&(e=!0),i=t.inputState.lastSelectionOrigin),t.dispatch({selection:s,scrollIntoView:e,userEvent:i}),!0}return!1}const Ms={childList:!0,characterData:!0,subtree:!0,attributes:!0,characterDataOldValue:!0},Es=Rt.ie&&Rt.ie_version<=11;class As{constructor(e){this.view=e,this.active=!1,this.selectionRange=new ot,this.selectionChanged=!1,this.delayedFlush=-1,this.resizeTimeout=-1,this.queue=[],this.delayedAndroidKey=null,this.flushingAndroidKey=-1,this.lastChange=0,this.scrollTargets=[],this.intersection=null,this.resizeScroll=null,this.intersecting=!1,this.gapIntersection=null,this.gaps=[],this.parentCheck=-1,this.dom=e.contentDOM,this.observer=new MutationObserver((t=>{for(let e of t)this.queue.push(e);(Rt.ie&&Rt.ie_version<=11||Rt.ios&&e.composing)&&t.some((e=>"childList"==e.type&&e.removedNodes.length||"characterData"==e.type&&e.oldValue.length>e.target.nodeValue.length))?this.flushSoon():this.flush()})),Es&&(this.onCharData=e=>{this.queue.push({target:e.target,type:"characterData",oldValue:e.prevValue}),this.flushSoon()}),this.onSelectionChange=this.onSelectionChange.bind(this),this.onResize=this.onResize.bind(this),this.onPrint=this.onPrint.bind(this),this.onScroll=this.onScroll.bind(this),"function"==typeof ResizeObserver&&(this.resizeScroll=new ResizeObserver((()=>{var e;(null===(e=this.view.docView)||void 0===e?void 0:e.lastUpdate){this.parentCheck<0&&(this.parentCheck=setTimeout(this.listenForScroll.bind(this),1e3)),e.length>0&&e[e.length-1].intersectionRatio>0!=this.intersecting&&(this.intersecting=!this.intersecting,this.intersecting!=this.view.inView&&this.onScrollChanged(document.createEvent("Event")))}),{threshold:[0,.001]}),this.intersection.observe(this.dom),this.gapIntersection=new IntersectionObserver((e=>{e.length>0&&e[e.length-1].intersectionRatio>0&&this.onScrollChanged(document.createEvent("Event"))}),{})),this.listenForScroll(),this.readSelectionRange()}onScrollChanged(e){this.view.inputState.runHandlers("scroll",e),this.intersecting&&this.view.measure()}onScroll(e){this.intersecting&&this.flush(!1),this.onScrollChanged(e)}onResize(){this.resizeTimeout<0&&(this.resizeTimeout=setTimeout((()=>{this.resizeTimeout=-1,this.view.requestMeasure()}),50))}onPrint(){this.view.viewState.printing=!0,this.view.measure(),setTimeout((()=>{this.view.viewState.printing=!1,this.view.requestMeasure()}),500)}updateGaps(e){if(this.gapIntersection&&(e.length!=this.gaps.length||this.gaps.some(((t,i)=>t!=e[i])))){this.gapIntersection.disconnect();for(let t of e)this.gapIntersection.observe(t);this.gaps=e}}onSelectionChange(e){let t=this.selectionChanged;if(!this.readSelectionRange()||this.delayedAndroidKey)return;let{view:i}=this,n=this.selectionRange;if(i.state.facet(gi)?i.root.activeElement!=this.dom:!Ke(i.dom,n))return;let s=n.anchorNode&&i.docView.nearest(n.anchorNode);s&&s.ignoreEvent(e)?t||(this.selectionChanged=!1):(Rt.ie&&Rt.ie_version<=11||Rt.android&&Rt.chrome)&&!i.state.selection.main.empty&&n.focusNode&&et(n.focusNode,n.focusOffset,n.anchorNode,n.anchorOffset)?this.flushSoon():this.flush(!1)}readSelectionRange(){let{view:e}=this,t=Rt.safari&&11==e.root.nodeType&&function(e){let t=e.activeElement;for(;t&&t.shadowRoot;)t=t.shadowRoot.activeElement;return t}(this.dom.ownerDocument)==this.dom&&function(e){let t=null;function i(e){e.preventDefault(),e.stopImmediatePropagation(),t=e.getTargetRanges()[0]}if(e.contentDOM.addEventListener("beforeinput",i,!0),e.dom.ownerDocument.execCommand("indent"),e.contentDOM.removeEventListener("beforeinput",i,!0),!t)return null;let n=t.startContainer,s=t.startOffset,r=t.endContainer,o=t.endOffset,a=e.docView.domAtPos(e.state.selection.main.anchor);return et(a.node,a.offset,r,o)&&([n,s,r,o]=[r,o,n,s]),{anchorNode:n,anchorOffset:s,focusNode:r,focusOffset:o}}(this.view)||Ge(e.root);if(!t||this.selectionRange.eq(t))return!1;let i=Ke(this.dom,t);return i&&!this.selectionChanged&&e.inputState.lastFocusTime>Date.now()-200&&e.inputState.lastTouchTime{let e=this.delayedAndroidKey;e&&(this.clearDelayedAndroidKey(),this.view.inputState.lastKeyCode=e.keyCode,this.view.inputState.lastKeyTime=Date.now(),!this.flush()&&e.force&&dt(this.dom,e.key,e.keyCode))};this.flushingAndroidKey=this.view.win.requestAnimationFrame(e)}this.delayedAndroidKey&&"Enter"!=e||(this.delayedAndroidKey={key:e,keyCode:t,force:this.lastChange{this.delayedFlush=-1,this.flush()})))}forceFlush(){this.delayedFlush>=0&&(this.view.win.cancelAnimationFrame(this.delayedFlush),this.delayedFlush=-1),this.flush()}pendingRecords(){for(let e of this.observer.takeRecords())this.queue.push(e);return this.queue}processRecords(){let e=this.pendingRecords();e.length&&(this.queue=[]);let t=-1,i=-1,n=!1;for(let s of e){let e=this.readMutation(s);e&&(e.typeOver&&(n=!0),-1==t?({from:t,to:i}=e):(t=Math.min(e.from,t),i=Math.max(e.to,i)))}return{from:t,to:i,typeOver:n}}readChange(){let{from:e,to:t,typeOver:i}=this.processRecords(),n=this.selectionChanged&&Ke(this.dom,this.selectionRange);if(e<0&&!n)return null;e>-1&&(this.lastChange=Date.now()),this.view.inputState.lastFocusTime=0,this.selectionChanged=!1;let s=new Cs(this.view,e,t,i);return this.view.docView.domChanged={newSel:s.newSel?s.newSel.main:null},s}flush(e=!0){if(this.delayedFlush>=0||this.delayedAndroidKey)return!1;e&&this.readSelectionRange();let t=this.readChange();if(!t)return this.view.requestMeasure(),!1;let i=this.view.state,n=Ps(this.view,t);return this.view.state==i&&this.view.update([]),n}readMutation(e){let t=this.view.docView.nearest(e.target);if(!t||t.ignoreMutation(e))return null;if(t.markDirty("attributes"==e.type),"attributes"==e.type&&(t.flags|=4),"childList"==e.type){let i=Rs(t,e.previousSibling||e.target.previousSibling,-1),n=Rs(t,e.nextSibling||e.target.nextSibling,1);return{from:i?t.posAfter(i):t.posAtStart,to:n?t.posBefore(n):t.posAtEnd,typeOver:!1}}return"characterData"==e.type?{from:t.posAtStart,to:t.posAtEnd,typeOver:e.target.nodeValue==e.oldValue}:null}setWindow(e){e!=this.win&&(this.removeWindowListeners(this.win),this.win=e,this.addWindowListeners(this.win))}addWindowListeners(e){e.addEventListener("resize",this.onResize),e.addEventListener("beforeprint",this.onPrint),e.addEventListener("scroll",this.onScroll),e.document.addEventListener("selectionchange",this.onSelectionChange)}removeWindowListeners(e){e.removeEventListener("scroll",this.onScroll),e.removeEventListener("resize",this.onResize),e.removeEventListener("beforeprint",this.onPrint),e.document.removeEventListener("selectionchange",this.onSelectionChange)}destroy(){var e,t,i;this.stop(),null===(e=this.intersection)||void 0===e||e.disconnect(),null===(t=this.gapIntersection)||void 0===t||t.disconnect(),null===(i=this.resizeScroll)||void 0===i||i.disconnect();for(let e of this.scrollTargets)e.removeEventListener("scroll",this.onScroll);this.removeWindowListeners(this.win),clearTimeout(this.parentCheck),clearTimeout(this.resizeTimeout),this.win.cancelAnimationFrame(this.delayedFlush),this.win.cancelAnimationFrame(this.flushingAndroidKey)}}function Rs(e,t,i){for(;t;){let n=gt.get(t);if(n&&n.parent==e)return n;let s=t.parentNode;t=s!=e.dom?s:i>0?t.nextSibling:t.previousSibling}return null}class Ds{get state(){return this.viewState.state}get viewport(){return this.viewState.viewport}get visibleRanges(){return this.viewState.visibleRanges}get inView(){return this.viewState.inView}get composing(){return this.inputState.composing>0}get compositionStarted(){return this.inputState.composing>=0}get root(){return this._root}get win(){return this.dom.ownerDocument.defaultView||window}constructor(e={}){this.plugins=[],this.pluginMap=new Map,this.editorAttrs={},this.contentAttrs={},this.bidiCache=[],this.destroyed=!1,this.updateState=2,this.measureScheduled=-1,this.measureRequests=[],this.contentDOM=document.createElement("div"),this.scrollDOM=document.createElement("div"),this.scrollDOM.tabIndex=-1,this.scrollDOM.className="cm-scroller",this.scrollDOM.appendChild(this.contentDOM),this.announceDOM=document.createElement("div"),this.announceDOM.style.cssText="position: fixed; top: -10000px",this.announceDOM.setAttribute("aria-live","polite"),this.dom=document.createElement("div"),this.dom.appendChild(this.announceDOM),this.dom.appendChild(this.scrollDOM);let{dispatch:t}=e;this.dispatchTransactions=e.dispatchTransactions||t&&(e=>e.forEach((e=>t(e,this))))||(e=>this.update(e)),this.dispatch=this.dispatch.bind(this),this._root=e.root||function(e){for(;e;){if(e&&(9==e.nodeType||11==e.nodeType&&e.host))return e;e=e.assignedSlot||e.parentNode}return null}(e.parent)||document,this.viewState=new os(e.state||Oe.create(e)),this.plugins=this.state.facet(Oi).map((e=>new _i(e)));for(let e of this.plugins)e.update(this);this.observer=new As(this),this.inputState=new fn(this),this.inputState.ensureHandlers(this.plugins),this.docView=new Yi(this),this.mountStyles(),this.updateAttrs(),this.updateState=0,this.requestMeasure(),e.parent&&e.parent.appendChild(this.dom)}dispatch(...e){let t=1==e.length&&e[0]instanceof le?e:1==e.length&&Array.isArray(e[0])?e[0]:[this.state.update(...e)];this.dispatchTransactions(t,this)}update(e){if(0!=this.updateState)throw new Error("Calls to EditorView.update are not allowed while an update is in progress");let t,i=!1,n=!1,s=this.state;for(let t of e){if(t.startState!=s)throw new RangeError("Trying to update state with a transaction that doesn't start from the previous state.");s=t.state}if(this.destroyed)return void(this.viewState.state=s);let r=this.hasFocus,o=0,a=null;e.some((e=>e.annotation(Bn)))?(this.inputState.notifiedFocused=r,o=1):r!=this.inputState.notifiedFocused&&(this.inputState.notifiedFocused=r,a=$n(s,r),a||(o=1));let l=this.observer.delayedAndroidKey,h=null;if(l?(this.observer.clearDelayedAndroidKey(),h=this.observer.readChange(),(h&&!this.state.doc.eq(s.doc)||!this.state.selection.eq(s.selection))&&(h=null)):this.observer.clear(),s.facet(Oe.phrases)!=this.state.facet(Oe.phrases))return this.setState(s);t=Ai.create(this,s,e),t.flags|=o;let c=this.viewState.scrollTarget;try{this.updateState=2;for(let t of e){if(c&&(c=c.map(t.changes)),t.scrollIntoView){let{main:e}=t.state.selection;c=new pi(e.empty?e:R.cursor(e.head,e.head>e.anchor?-1:1))}for(let e of t.effects)e.is(fi)&&(c=e.value)}this.viewState.update(t,c),this.bidiCache=Ls.update(this.bidiCache,t.changes),t.empty||(this.updatePlugins(t),this.inputState.update(t)),i=this.docView.update(t),this.state.facet(Mi)!=this.styleModules&&this.mountStyles(),n=this.updateAttrs(),this.showAnnouncements(e),this.docView.updateSelection(i,e.some((e=>e.isUserEvent("select.pointer"))))}finally{this.updateState=0}if(t.startState.facet(fs)!=t.state.facet(fs)&&(this.viewState.mustMeasureContent=!0),(i||n||c||this.viewState.mustEnforceCursorAssoc||this.viewState.mustMeasureContent)&&this.requestMeasure(),!t.empty)for(let e of this.state.facet(li))e(t);(a||h)&&Promise.resolve().then((()=>{a&&this.state==a.startState&&this.dispatch(a),h&&!Ps(this,h)&&l.force&&dt(this.contentDOM,l.key,l.keyCode)}))}setState(e){if(0!=this.updateState)throw new Error("Calls to EditorView.setState are not allowed while an update is in progress");if(this.destroyed)return void(this.viewState.state=e);this.updateState=2;let t=this.hasFocus;try{for(let e of this.plugins)e.destroy(this);this.viewState=new os(e),this.plugins=e.facet(Oi).map((e=>new _i(e))),this.pluginMap.clear();for(let e of this.plugins)e.update(this);this.docView=new Yi(this),this.inputState.ensureHandlers(this.plugins),this.mountStyles(),this.updateAttrs(),this.bidiCache=[]}finally{this.updateState=0}t&&this.focus(),this.requestMeasure()}updatePlugins(e){let t=e.startState.facet(Oi),i=e.state.facet(Oi);if(t!=i){let n=[];for(let s of i){let i=t.indexOf(s);if(i<0)n.push(new _i(s));else{let t=this.plugins[i];t.mustUpdate=e,n.push(t)}}for(let t of this.plugins)t.mustUpdate!=e&&t.destroy(this);this.plugins=n,this.pluginMap.clear()}else for(let t of this.plugins)t.mustUpdate=e;for(let e=0;e-1&&this.win.cancelAnimationFrame(this.measureScheduled),this.observer.delayedAndroidKey)return this.measureScheduled=-1,void this.requestMeasure();this.measureScheduled=0,e&&this.observer.forceFlush();let t=null,i=this.scrollDOM,n=i.scrollTop*this.scaleY,{scrollAnchorPos:s,scrollAnchorHeight:r}=this.viewState;Math.abs(n-this.viewState.scrollTop)>1&&(r=-1),this.viewState.scrollAnchorHeight=-1;try{for(let e=0;;e++){if(r<0)if(pt(i))s=-1,r=this.viewState.heightMap.height;else{let e=this.viewState.scrollAnchorAt(n);s=e.from,r=e.top}this.updateState=1;let o=this.viewState.measure(this);if(!o&&!this.measureRequests.length&&null==this.viewState.scrollTarget)break;if(e>5){console.warn(this.measureRequests.length?"Measure loop restarted more than 5 times":"Viewport failed to stabilize");break}let a=[];4&o||([this.measureRequests,a]=[a,this.measureRequests]);let l=a.map((e=>{try{return e.read(this)}catch(e){return mi(this.state,e),qs}})),h=Ai.create(this,this.state,[]),c=!1;h.flags|=o,t?t.flags|=o:t=h,this.updateState=2,h.empty||(this.updatePlugins(h),this.inputState.update(h),this.updateAttrs(),c=this.docView.update(h));for(let e=0;e1||e<-1){n+=e,i.scrollTop=n/this.scaleY,r=-1;continue}}}break}}}finally{this.updateState=0,this.measureScheduled=-1}if(t&&!t.empty)for(let e of this.state.facet(li))e(t)}get themeClasses(){return gs+" "+(this.state.facet(ms)?Os:vs)+" "+this.state.facet(fs)}updateAttrs(){let e=Ns(this,yi,{class:"cm-editor"+(this.hasFocus?" cm-focused ":" ")+this.themeClasses}),t={spellcheck:"false",autocorrect:"off",autocapitalize:"off",translate:"no",contenteditable:this.state.facet(gi)?"true":"false",class:"cm-content",style:`${Rt.tabSize}: ${this.state.tabSize}`,role:"textbox","aria-multiline":"true"};this.state.readOnly&&(t["aria-readonly"]="true"),Ns(this,wi,t);let i=this.observer.ignore((()=>{let i=Wt(this.contentDOM,this.contentAttrs,t),n=Wt(this.dom,this.editorAttrs,e);return i||n}));return this.editorAttrs=e,this.contentAttrs=t,i}showAnnouncements(e){let t=!0;for(let i of e)for(let e of i.effects)e.is(Ds.announce)&&(t&&(this.announceDOM.textContent=""),t=!1,this.announceDOM.appendChild(document.createElement("div")).textContent=e.value)}mountStyles(){this.styleModules=this.state.facet(Mi);let e=this.state.facet(Ds.cspNonce);ze.mount(this.root,this.styleModules.concat(ys).reverse(),e?{nonce:e}:void 0)}readMeasured(){if(2==this.updateState)throw new Error("Reading the editor layout isn't allowed during an update");0==this.updateState&&this.measureScheduled>-1&&this.measure(!1)}requestMeasure(e){if(this.measureScheduled<0&&(this.measureScheduled=this.win.requestAnimationFrame((()=>this.measure()))),e){if(this.measureRequests.indexOf(e)>-1)return;if(null!=e.key)for(let t=0;tt.spec==e))||null),t&&t.update(this).value}get documentTop(){return this.contentDOM.getBoundingClientRect().top+this.viewState.paddingTop}get documentPadding(){return{top:this.viewState.paddingTop,bottom:this.viewState.paddingBottom}}get scaleX(){return this.viewState.scaleX}get scaleY(){return this.viewState.scaleY}elementAtHeight(e){return this.readMeasured(),this.viewState.elementAtHeight(e)}lineBlockAtHeight(e){return this.readMeasured(),this.viewState.lineBlockAtHeight(e)}get viewportLineBlocks(){return this.viewState.viewportLines}lineBlockAt(e){return this.viewState.lineBlockAt(e)}get contentHeight(){return this.viewState.contentHeight}moveByChar(e,t,i){return pn(this,e,dn(this,e,t,i))}moveByGroup(e,t){return pn(this,e,dn(this,e,t,(t=>function(e,t,i){let n=e.state.charCategorizer(t),s=n(i);return e=>{let t=n(e);return s==me.Space&&(s=t),s==t}}(this,e.head,t))))}moveToLineBoundary(e,t,i=!0){return function(e,t,i,n){let s=cn(e,t.head),r=n&&s.type==Xt.Text&&(e.lineWrapping||s.widgetLineBreaks)?e.coordsAtPos(t.assoc<0&&t.head>s.from?t.head-1:t.head):null;if(r){let t=e.dom.getBoundingClientRect(),n=e.textDirectionAt(s.from),o=e.posAtCoords({x:i==(n==Ri.LTR)?t.right-1:t.left+1,y:(r.top+r.bottom)/2});if(null!=o)return R.cursor(o,i?-1:1)}return R.cursor(i?s.to:s.from,i?-1:1)}(this,e,t,i)}moveVertically(e,t,i){return pn(this,e,function(e,t,i,n){let s=t.head,r=i?1:-1;if(s==(i?e.state.doc.length:0))return R.cursor(s,t.assoc);let o,a=t.goalColumn,l=e.contentDOM.getBoundingClientRect(),h=e.coordsAtPos(s,t.assoc||-1),c=e.documentTop;if(h)null==a&&(a=h.left-l.left),o=r<0?h.top:h.bottom;else{let t=e.viewState.lineBlockAt(s);null==a&&(a=Math.min(l.right-l.left,e.defaultCharacterWidth*(s-t.from))),o=(r<0?t.top:t.bottom)+c}let d=l.left+a,u=null!=n?n:e.viewState.heightOracle.textHeight>>1;for(let t=0;;t+=10){let i=o+(u+t)*r,n=ln(e,{x:d,y:i},!1,r);if(il.bottom||(r<0?ns)){let t=e.docView.coordsForChar(n),s=!t||i0)}coordsForChar(e){return this.readMeasured(),this.docView.coordsForChar(e)}get defaultCharacterWidth(){return this.viewState.heightOracle.charWidth}get defaultLineHeight(){return this.viewState.heightOracle.lineHeight}get textDirection(){return this.viewState.defaultTextDirection}textDirectionAt(e){return!this.state.facet(di)||ethis.viewport.to?this.textDirection:(this.readMeasured(),this.docView.textDirectionAt(e))}get lineWrapping(){return this.viewState.heightOracle.lineWrapping}bidiSpans(e){if(e.length>Is)return Fi(e.length);let t,i=this.textDirectionAt(e.from);for(let n of this.bidiCache)if(n.from==e.from&&n.dir==i&&(n.fresh||ji(n.isolates,t=Ti(this,e.from,e.to))))return n.order;t||(t=Ti(this,e.from,e.to));let n=function(e,t,i){if(!e)return[new zi(0,0,t==Ii?1:0)];if(t==Di&&!i.length&&!Qi.test(e))return Fi(e.length);if(i.length)for(;e.length>Wi.length;)Wi[Wi.length]=256;let n=[],s=t==Di?0:1;return Ui(e,s,s,i,0,e.length,n),n}(e.text,i,t);return this.bidiCache.push(new Ls(e.from,e.to,i,t,!0,n)),n}get hasFocus(){var e;return(this.dom.ownerDocument.hasFocus()||Rt.safari&&(null===(e=this.inputState)||void 0===e?void 0:e.lastContextMenu)>Date.now()-3e4)&&this.root.activeElement==this.contentDOM}focus(){this.observer.ignore((()=>{ht(this.contentDOM),this.docView.updateSelection()}))}setRoot(e){this._root!=e&&(this._root=e,this.observer.setWindow((9==e.nodeType?e:e.ownerDocument).defaultView||window),this.mountStyles())}destroy(){for(let e of this.plugins)e.destroy(this);this.plugins=[],this.inputState.destroy(),this.dom.remove(),this.observer.destroy(),this.measureScheduled>-1&&this.win.cancelAnimationFrame(this.measureScheduled),this.destroyed=!0}static scrollIntoView(e,t={}){return fi.of(new pi("number"==typeof e?R.cursor(e):e,t.y,t.x,t.yMargin,t.xMargin))}static domEventHandlers(e){return bi.define((()=>({})),{eventHandlers:e})}static domEventObservers(e){return bi.define((()=>({})),{eventObservers:e})}static theme(e,t){let i=ze.newName(),n=[fs.of(i),Mi.of(_s(`.${i}`,e))];return t&&t.dark&&n.push(ms.of(!0)),n}static baseTheme(e){return V.lowest(Mi.of(_s("."+gs,e,bs)))}static findFromDOM(e){var t;let i=e.querySelector(".cm-content"),n=i&>.get(i)||gt.get(e);return(null===(t=null==n?void 0:n.rootView)||void 0===t?void 0:t.view)||null}}Ds.styleModule=Mi,Ds.inputHandler=hi,Ds.focusChangeEffect=ci,Ds.perLineTextDirection=di,Ds.exceptionSink=ai,Ds.updateListener=li,Ds.editable=gi,Ds.mouseSelectionStyle=oi,Ds.dragMovesSelection=ri,Ds.clickAddsSelectionRange=si,Ds.decorations=xi,Ds.atomicRanges=Si,Ds.bidiIsolatedRanges=ki,Ds.scrollMargins=Ci,Ds.darkTheme=ms,Ds.cspNonce=q.define({combine:e=>e.length?e[0]:""}),Ds.contentAttributes=wi,Ds.editorAttributes=yi,Ds.lineWrapping=Ds.contentAttributes.of({class:"cm-lineWrapping"}),Ds.announce=ae.define();const Is=4096,qs={};class Ls{constructor(e,t,i,n,s,r){this.from=e,this.to=t,this.dir=i,this.isolates=n,this.fresh=s,this.order=r}static update(e,t){if(t.empty&&!e.some((e=>e.fresh)))return e;let i=[],n=e.length?e[e.length-1].dir:Ri.LTR;for(let s=Math.max(0,e.length-10);s=0;s--){let t=n[s],r="function"==typeof t?t(e):t;r&&Qt(r,i)}return i}const Bs=Rt.mac?"mac":Rt.windows?"win":Rt.linux?"linux":"key";function $s(e,t,i){return t.altKey&&(e="Alt-"+e),t.ctrlKey&&(e="Ctrl-"+e),t.metaKey&&(e="Meta-"+e),!1!==i&&t.shiftKey&&(e="Shift-"+e),e}const Qs=V.default(Ds.domEventHandlers({keydown:(e,t)=>Fs(Ws(t.state),e,t,"editor")})),zs=q.define({enables:Qs}),js=new WeakMap;function Ws(e){let t=e.facet(zs),i=js.get(t);return i||js.set(t,i=function(e,t=Bs){let i=Object.create(null),n=Object.create(null),s=(e,t)=>{let i=n[e];if(null==i)n[e]=t;else if(i!=t)throw new Error("Key binding "+e+" is used both as a regular binding and as a multi-stroke prefix")},r=(e,n,r,o,a)=>{var l,h;let c=i[e]||(i[e]=Object.create(null)),d=n.split(/ (?!$)/).map((e=>function(e,t){const i=e.split(/-(?!$)/);let n,s,r,o,a=i[i.length-1];"Space"==a&&(a=" ");for(let e=0;e{let n=Vs={view:t,prefix:i,scope:e};return setTimeout((()=>{Vs==n&&(Vs=null)}),Us),!0}]})}let u=d.join(" ");s(u,!1);let p=c[u]||(c[u]={preventDefault:!1,stopPropagation:!1,run:(null===(h=null===(l=c._any)||void 0===l?void 0:l.run)||void 0===h?void 0:h.slice())||[]});r&&p.run.push(r),o&&(p.preventDefault=!0),a&&(p.stopPropagation=!0)};for(let n of e){let e=n.scope?n.scope.split(" "):["editor"];if(n.any)for(let t of e){let e=i[t]||(i[t]=Object.create(null));e._any||(e._any={preventDefault:!1,stopPropagation:!1,run:[]});for(let t in e)e[t].run.push(n.any)}let s=n[t]||n.key;if(s)for(let t of e)r(t,s,n.run,n.preventDefault,n.stopPropagation),n.shift&&r(t,"Shift-"+s,n.shift,n.preventDefault,n.stopPropagation)}return i}(t.reduce(((e,t)=>e.concat(t)),[]))),i}let Vs=null;const Us=4e3;function Fs(e,t,i,n){let s=function(e){var t=!(Fe&&e.metaKey&&e.shiftKey&&!e.ctrlKey&&!e.altKey||He&&e.shiftKey&&e.key&&1==e.key.length||"Unidentified"==e.key)&&e.key||(e.shiftKey?Ue:Ve)[e.keyCode]||e.key||"Unidentified";return"Esc"==t&&(t="Escape"),"Del"==t&&(t="Delete"),"Left"==t&&(t="ArrowLeft"),"Up"==t&&(t="ArrowUp"),"Right"==t&&(t="ArrowRight"),"Down"==t&&(t="ArrowDown"),t}(t),r=_(O(s,0))==s.length&&" "!=s,o="",a=!1,l=!1,h=!1;Vs&&Vs.view==i&&Vs.scope==n&&(o=Vs.prefix+" ",bn.indexOf(t.keyCode)<0&&(l=!0,Vs=null));let c,d,u=new Set,p=e=>{if(e){for(let n of e.run)if(!u.has(n)&&(u.add(n),n(i,t)))return e.stopPropagation&&(h=!0),!0;e.preventDefault&&(e.stopPropagation&&(h=!0),l=!0)}return!1},f=e[n];return f&&(p(f[o+$s(s,t,!r)])?a=!0:r&&(t.altKey||t.metaKey||t.ctrlKey)&&!(Rt.windows&&t.ctrlKey&&t.altKey)&&(c=Ve[t.keyCode])&&c!=s?(p(f[o+$s(c,t,!0)])||t.shiftKey&&(d=Ue[t.keyCode])!=s&&d!=c&&p(f[o+$s(d,t,!1)]))&&(a=!0):r&&t.shiftKey&&p(f[o+$s(s,t,!0)])&&(a=!0),!a&&p(f._any)&&(a=!0)),l&&(a=!0),a&&h&&t.stopPropagation(),a}class Hs{constructor(e,t,i,n,s){this.className=e,this.left=t,this.top=i,this.width=n,this.height=s}draw(){let e=document.createElement("div");return e.className=this.className,this.adjust(e),e}update(e,t){return t.className==this.className&&(this.adjust(e),!0)}adjust(e){e.style.left=this.left+"px",e.style.top=this.top+"px",null!=this.width&&(e.style.width=this.width+"px"),e.style.height=this.height+"px"}eq(e){return this.left==e.left&&this.top==e.top&&this.width==e.width&&this.height==e.height&&this.className==e.className}static forRange(e,t,i){if(i.empty){let n=e.coordsAtPos(i.head,i.assoc||1);if(!n)return[];let s=Xs(e);return[new Hs(t,n.left-s.left,n.top-s.top,null,n.bottom-n.top)]}return function(e,t,i){if(i.to<=e.viewport.from||i.from>=e.viewport.to)return[];let n=Math.max(i.from,e.viewport.from),s=Math.min(i.to,e.viewport.to),r=e.textDirection==Ri.LTR,o=e.contentDOM,a=o.getBoundingClientRect(),l=Xs(e),h=o.querySelector(".cm-line"),c=h&&window.getComputedStyle(h),d=a.left+(c?parseInt(c.paddingLeft)+Math.min(0,parseInt(c.textIndent)):0),u=a.right-(c?parseInt(c.paddingRight):0),p=cn(e,n),f=cn(e,s),m=p.type==Xt.Text?p:null,g=f.type==Xt.Text?f:null;if(m&&(e.lineWrapping||p.widgetLineBreaks)&&(m=Ys(e,n,m)),g&&(e.lineWrapping||f.widgetLineBreaks)&&(g=Ys(e,s,g)),m&&g&&m.from==g.from)return O(b(i.from,i.to,m));{let t=m?b(i.from,null,m):_(p,!1),n=g?b(null,i.to,g):_(f,!0),s=[];return(m||p).to<(g||f).from-(m&&g?1:0)||p.widgetLineBreaks>1&&t.bottom+e.defaultLineHeight/2h&&n.from=r)break;a>s&&l(Math.max(e,s),null==t&&e<=h,Math.min(a,r),null==i&&a>=c,o.dir)}if(s=n.to+1,s>=r)break}return 0==a.length&&l(h,null==t,c,null==i,e.textDirection),{top:s,bottom:o,horizontal:a}}function _(e,t){let i=a.top+(t?e.top:e.bottom);return{top:i,bottom:i,horizontal:[]}}}(e,t,i)}}function Xs(e){let t=e.scrollDOM.getBoundingClientRect();return{left:(e.textDirection==Ri.LTR?t.left:t.right-e.scrollDOM.clientWidth*e.scaleX)-e.scrollDOM.scrollLeft*e.scaleX,top:t.top-e.scrollDOM.scrollTop*e.scaleY}}function Ys(e,t,i){let n=R.cursor(t);return{from:Math.max(i.from,e.moveToLineBoundary(n,!1,!0).from),to:Math.min(i.to,e.moveToLineBoundary(n,!0,!0).from),type:Xt.Text}}class Gs{constructor(e,t){this.view=e,this.layer=t,this.drawn=[],this.scaleX=1,this.scaleY=1,this.measureReq={read:this.measure.bind(this),write:this.draw.bind(this)},this.dom=e.scrollDOM.appendChild(document.createElement("div")),this.dom.classList.add("cm-layer"),t.above&&this.dom.classList.add("cm-layer-above"),t.class&&this.dom.classList.add(t.class),this.scale(),this.dom.setAttribute("aria-hidden","true"),this.setOrder(e.state),e.requestMeasure(this.measureReq),t.mount&&t.mount(this.dom,e)}update(e){e.startState.facet(Zs)!=e.state.facet(Zs)&&this.setOrder(e.state),(this.layer.update(e,this.dom)||e.geometryChanged)&&(this.scale(),e.view.requestMeasure(this.measureReq))}setOrder(e){let t=0,i=e.facet(Zs);for(;t{return i=e,n=this.drawn[t],!(i.constructor==n.constructor&&i.eq(n));var i,n}))){let t=this.dom.firstChild,i=0;for(let n of e)n.update&&t&&n.constructor&&this.drawn[i].constructor&&n.update(t,this.drawn[i])?(t=t.nextSibling,i++):this.dom.insertBefore(n.draw(),t);for(;t;){let e=t.nextSibling;t.remove(),t=e}this.drawn=e}}destroy(){this.layer.destroy&&this.layer.destroy(this.dom,this.view),this.dom.remove()}}const Zs=q.define();function Ks(e){return[bi.define((t=>new Gs(t,e))),Zs.of(e)]}const Js=!Rt.ios,er=q.define({combine:e=>be(e,{cursorBlinkRate:1200,drawRangeCursor:!0},{cursorBlinkRate:(e,t)=>Math.min(e,t),drawRangeCursor:(e,t)=>e||t})});function tr(e={}){return[er.of(e),nr,rr,ar,ui.of(!0)]}function ir(e){return e.startState.facet(er)!=e.state.facet(er)}const nr=Ks({above:!0,markers(e){let{state:t}=e,i=t.facet(er),n=[];for(let s of t.selection.ranges){let r=s==t.selection.main;if(s.empty?!r||Js:i.drawRangeCursor){let t=r?"cm-cursor cm-cursor-primary":"cm-cursor cm-cursor-secondary",i=s.empty?s:R.cursor(s.head,s.head>s.anchor?-1:1);for(let s of Hs.forRange(e,t,i))n.push(s)}}return n},update(e,t){e.transactions.some((e=>e.selection))&&(t.style.animationName="cm-blink"==t.style.animationName?"cm-blink2":"cm-blink");let i=ir(e);return i&&sr(e.state,t),e.docChanged||e.selectionSet||i},mount(e,t){sr(t.state,e)},class:"cm-cursorLayer"});function sr(e,t){t.style.animationDuration=e.facet(er).cursorBlinkRate+"ms"}const rr=Ks({above:!1,markers:e=>e.state.selection.ranges.map((t=>t.empty?[]:Hs.forRange(e,"cm-selectionBackground",t))).reduce(((e,t)=>e.concat(t))),update:(e,t)=>e.docChanged||e.selectionSet||e.viewportChanged||ir(e),class:"cm-selectionLayer"}),or={".cm-line":{"& ::selection":{backgroundColor:"transparent !important"},"&::selection":{backgroundColor:"transparent !important"}}};Js&&(or[".cm-line"].caretColor="transparent !important");const ar=V.highest(Ds.theme(or)),lr=ae.define({map:(e,t)=>null==e?null:t.mapPos(e)}),hr=j.define({create:()=>null,update:(e,t)=>(null!=e&&(e=t.changes.mapPos(e)),t.effects.reduce(((e,t)=>t.is(lr)?t.value:e),e))}),cr=bi.fromClass(class{constructor(e){this.view=e,this.cursor=null,this.measureReq={read:this.readPos.bind(this),write:this.drawCursor.bind(this)}}update(e){var t;let i=e.state.field(hr);null==i?null!=this.cursor&&(null===(t=this.cursor)||void 0===t||t.remove(),this.cursor=null):(this.cursor||(this.cursor=this.view.scrollDOM.appendChild(document.createElement("div")),this.cursor.className="cm-dropCursor"),(e.startState.field(hr)!=i||e.docChanged||e.geometryChanged)&&this.view.requestMeasure(this.measureReq))}readPos(){let{view:e}=this,t=e.state.field(hr),i=null!=t&&e.coordsAtPos(t);if(!i)return null;let n=e.scrollDOM.getBoundingClientRect();return{left:i.left-n.left+e.scrollDOM.scrollLeft*e.scaleX,top:i.top-n.top+e.scrollDOM.scrollTop*e.scaleY,height:i.bottom-i.top}}drawCursor(e){if(this.cursor){let{scaleX:t,scaleY:i}=this.view;e?(this.cursor.style.left=e.left/t+"px",this.cursor.style.top=e.top/i+"px",this.cursor.style.height=e.height/i+"px"):this.cursor.style.left="-100000px"}}destroy(){this.cursor&&this.cursor.remove()}setDropPos(e){this.view.state.field(hr)!=e&&this.view.dispatch({effects:lr.of(e)})}},{eventObservers:{dragover(e){this.setDropPos(this.view.posAtCoords({x:e.clientX,y:e.clientY}))},dragleave(e){e.target!=this.view.contentDOM&&this.view.contentDOM.contains(e.relatedTarget)||this.setDropPos(null)},dragend(){this.setDropPos(null)},drop(){this.setDropPos(null)}}});function dr(e,t,i,n,s){t.lastIndex=0;for(let r,o=e.iterRange(i,n),a=i;!o.next().done;a+=o.value.length)if(!o.lineBreak)for(;r=t.exec(o.value);)s(a+r.index,r)}class ur{constructor(e){const{regexp:t,decoration:i,decorate:n,boundary:s,maxLength:r=1e3}=e;if(!t.global)throw new RangeError("The regular expression given to MatchDecorator should have its 'g' flag set");if(this.regexp=t,n)this.addMatch=(e,t,i,s)=>n(s,i,i+e[0].length,e,t);else if("function"==typeof i)this.addMatch=(e,t,n,s)=>{let r=i(e,t,n);r&&s(n,n+e[0].length,r)};else{if(!i)throw new RangeError("Either 'decorate' or 'decoration' should be provided to MatchDecorator");this.addMatch=(e,t,n,s)=>s(n,n+e[0].length,i)}this.boundary=s,this.maxLength=r}createDeco(e){let t=new ke,i=t.add.bind(t);for(let{from:t,to:n}of function(e,t){let i=e.visibleRanges;if(1==i.length&&i[0].from==e.viewport.from&&i[0].to==e.viewport.to)return i;let n=[];for(let{from:s,to:r}of i)s=Math.max(e.state.doc.lineAt(s).from,s-t),r=Math.min(e.state.doc.lineAt(r).to,r+t),n.length&&n[n.length-1].to>=s?n[n.length-1].to=r:n.push({from:s,to:r});return n}(e,this.maxLength))dr(e.state.doc,this.regexp,t,n,((t,n)=>this.addMatch(n,e,t,i)));return t.finish()}updateDeco(e,t){let i=1e9,n=-1;return e.docChanged&&e.changes.iterChanges(((t,s,r,o)=>{o>e.view.viewport.from&&r1e3?this.createDeco(e.view):n>-1?this.updateRange(e.view,t.map(e.changes),i,n):t}updateRange(e,t,i,n){for(let s of e.visibleRanges){let r=Math.max(s.from,i),o=Math.min(s.to,n);if(o>r){let i=e.state.doc.lineAt(r),n=i.toi.from;r--)if(this.boundary.test(i.text[r-1-i.from])){a=r;break}for(;oc.push(i.range(e,t));if(i==n)for(this.regexp.lastIndex=a-i.from;(h=this.regexp.exec(i.text))&&h.indexthis.addMatch(i,e,t,d)));t=t.update({filterFrom:a,filterTo:l,filter:(e,t)=>el,add:c})}}return t}}const pr=null!=/x/.unicode?"gu":"g",fr=new RegExp("[\0-\b\n--Ÿ­؜​‎‏\u2028\u2029‭‮⁦⁧⁩\ufeff-]",pr),mr={0:"null",7:"bell",8:"backspace",10:"newline",11:"vertical tab",13:"carriage return",27:"escape",8203:"zero width space",8204:"zero width non-joiner",8205:"zero width joiner",8206:"left-to-right mark",8207:"right-to-left mark",8232:"line separator",8237:"left-to-right override",8238:"right-to-left override",8294:"left-to-right isolate",8295:"right-to-left isolate",8297:"pop directional isolate",8233:"paragraph separator",65279:"zero width no-break space",65532:"object replacement"};let gr=null;const vr=q.define({combine(e){let t=be(e,{render:null,specialChars:fr,addSpecialChars:null});return(t.replaceTabs=!function(){var e;if(null==gr&&"undefined"!=typeof document&&document.body){let t=document.body.style;gr=null!=(null!==(e=t.tabSize)&&void 0!==e?e:t.MozTabSize)}return gr||!1}())&&(t.specialChars=new RegExp("\t|"+t.specialChars.source,pr)),t.addSpecialChars&&(t.specialChars=new RegExp(t.specialChars.source+"|"+t.addSpecialChars.source,pr)),t}});function Or(e={}){return[vr.of(e),br||(br=bi.fromClass(class{constructor(e){this.view=e,this.decorations=Yt.none,this.decorationCache=Object.create(null),this.decorator=this.makeDecorator(e.state.facet(vr)),this.decorations=this.decorator.createDeco(e)}makeDecorator(e){return new ur({regexp:e.specialChars,decoration:(t,i,n)=>{let{doc:s}=i.state,r=O(t[0],0);if(9==r){let e=s.lineAt(n),t=i.state.tabSize,r=Le(e.text,t,n-e.from);return Yt.replace({widget:new yr((t-r%t)*this.view.defaultCharacterWidth/this.view.scaleX)})}return this.decorationCache[r]||(this.decorationCache[r]=Yt.replace({widget:new _r(e,r)}))},boundary:e.replaceTabs?void 0:/[^]/})}update(e){let t=e.state.facet(vr);e.startState.facet(vr)!=t?(this.decorator=this.makeDecorator(t),this.decorations=this.decorator.createDeco(e.view)):this.decorations=this.decorator.updateDeco(e,this.decorations)}},{decorations:e=>e.decorations}))]}let br=null;class _r extends Ht{constructor(e,t){super(),this.options=e,this.code=t}eq(e){return e.code==this.code}toDOM(e){let t=function(e){return e>=32?"•":10==e?"␤":String.fromCharCode(9216+e)}(this.code),i=e.state.phrase("Control character")+" "+(mr[this.code]||"0x"+this.code.toString(16)),n=this.options.render&&this.options.render(this.code,i,t);if(n)return n;let s=document.createElement("span");return s.textContent=t,s.title=i,s.setAttribute("aria-label",i),s.className="cm-specialChar",s}ignoreEvent(){return!1}}class yr extends Ht{constructor(e){super(),this.width=e}eq(e){return e.width==this.width}toDOM(){let e=document.createElement("span");return e.textContent="\t",e.className="cm-tab",e.style.width=this.width+"px",e}ignoreEvent(){return!1}}const wr=Yt.line({class:"cm-activeLine"}),xr=bi.fromClass(class{constructor(e){this.decorations=this.getDeco(e)}update(e){(e.docChanged||e.selectionSet)&&(this.decorations=this.getDeco(e.view))}getDeco(e){let t=-1,i=[];for(let n of e.state.selection.ranges){let s=e.lineBlockAt(n.head);s.from>t&&(i.push(wr.range(s.from)),t=s.from)}return Yt.set(i)}},{decorations:e=>e.decorations}),Sr=2e3;function kr(e,t){let i=e.posAtCoords({x:t.clientX,y:t.clientY},!1),n=e.state.doc.lineAt(i),s=i-n.from,r=s>Sr?-1:s==n.length?function(e,t){let i=e.coordsAtPos(e.viewport.from);return i?Math.round(Math.abs((i.left-t)/e.defaultCharacterWidth)):-1}(e,t.clientX):Le(n.text,e.state.tabSize,i-n.from);return{line:n.number,col:r,off:s}}function Tr(e){let t=(null==e?void 0:e.eventFilter)||(e=>e.altKey&&0==e.button);return Ds.mouseSelectionStyle.of(((e,i)=>t(i)?function(e,t){let i=kr(e,t),n=e.state.selection;return i?{update(e){if(e.docChanged){let t=e.changes.mapPos(e.startState.doc.line(i.line).from),s=e.state.doc.lineAt(t);i={line:s.number,col:i.col,off:Math.min(i.off,s.length)},n=n.map(e.changes)}},get(t,s,r){let o=kr(e,t);if(!o)return n;let a=function(e,t,i){let n=Math.min(t.line,i.line),s=Math.max(t.line,i.line),r=[];if(t.off>Sr||i.off>Sr||t.col<0||i.col<0){let o=Math.min(t.off,i.off),a=Math.max(t.off,i.off);for(let t=n;t<=s;t++){let i=e.doc.line(t);i.length<=a&&r.push(R.range(i.from+o,i.to+a))}}else{let o=Math.min(t.col,i.col),a=Math.max(t.col,i.col);for(let t=n;t<=s;t++){let i=e.doc.line(t),n=Ne(i.text,o,e.tabSize,!0);if(n<0)r.push(R.cursor(i.to));else{let t=Ne(i.text,a,e.tabSize);r.push(R.range(i.from+n,i.from+t))}}}return r}(e.state,i,o);return a.length?r?R.create(a.concat(n.ranges)):R.create(a):n}}:null}(e,i):null))}const Cr={Alt:[18,e=>!!e.altKey],Control:[17,e=>!!e.ctrlKey],Shift:[16,e=>!!e.shiftKey],Meta:[91,e=>!!e.metaKey]},Pr={style:"cursor: crosshair"};function Mr(e={}){let[t,i]=Cr[e.key||"Alt"],n=bi.fromClass(class{constructor(e){this.view=e,this.isDown=!1}set(e){this.isDown!=e&&(this.isDown=e,this.view.update([]))}},{eventObservers:{keydown(e){this.set(e.keyCode==t||i(e))},keyup(e){e.keyCode!=t&&i(e)||this.set(!1)},mousemove(e){this.set(i(e))}}});return[n,Ds.contentAttributes.of((e=>{var t;return(null===(t=e.plugin(n))||void 0===t?void 0:t.isDown)?Pr:null}))]}const Er="-10000px";class Ar{constructor(e,t,i){this.facet=t,this.createTooltipView=i,this.input=e.state.facet(t),this.tooltips=this.input.filter((e=>e)),this.tooltipViews=this.tooltips.map(i)}update(e,t){var i;let n=e.state.facet(this.facet),s=n.filter((e=>e));if(n===this.input){for(let t of this.tooltipViews)t.update&&t.update(e);return!1}let r=[],o=t?[]:null;for(let i=0;it[i]=e)),t.length=o.length),this.input=n,this.tooltips=s,this.tooltipViews=r,!0}}function Rr(e){let{win:t}=e;return{top:0,left:0,bottom:t.innerHeight,right:t.innerWidth}}const Dr=q.define({combine:e=>{var t,i,n;return{position:Rt.ios?"absolute":(null===(t=e.find((e=>e.position)))||void 0===t?void 0:t.position)||"fixed",parent:(null===(i=e.find((e=>e.parent)))||void 0===i?void 0:i.parent)||null,tooltipSpace:(null===(n=e.find((e=>e.tooltipSpace)))||void 0===n?void 0:n.tooltipSpace)||Rr}}}),Ir=new WeakMap,qr=bi.fromClass(class{constructor(e){this.view=e,this.above=[],this.inView=!0,this.madeAbsolute=!1,this.lastTransaction=0,this.measureTimeout=-1;let t=e.state.facet(Dr);this.position=t.position,this.parent=t.parent,this.classes=e.themeClasses,this.createContainer(),this.measureReq={read:this.readMeasure.bind(this),write:this.writeMeasure.bind(this),key:this},this.manager=new Ar(e,Br,(e=>this.createTooltip(e))),this.intersectionObserver="function"==typeof IntersectionObserver?new IntersectionObserver((e=>{Date.now()>this.lastTransaction-50&&e.length>0&&e[e.length-1].intersectionRatio<1&&this.measureSoon()}),{threshold:[1]}):null,this.observeIntersection(),e.win.addEventListener("resize",this.measureSoon=this.measureSoon.bind(this)),this.maybeMeasure()}createContainer(){this.parent?(this.container=document.createElement("div"),this.container.style.position="relative",this.container.className=this.view.themeClasses,this.parent.appendChild(this.container)):this.container=this.view.dom}observeIntersection(){if(this.intersectionObserver){this.intersectionObserver.disconnect();for(let e of this.manager.tooltipViews)this.intersectionObserver.observe(e.dom)}}measureSoon(){this.measureTimeout<0&&(this.measureTimeout=setTimeout((()=>{this.measureTimeout=-1,this.maybeMeasure()}),50))}update(e){e.transactions.length&&(this.lastTransaction=Date.now());let t=this.manager.update(e,this.above);t&&this.observeIntersection();let i=t||e.geometryChanged,n=e.state.facet(Dr);if(n.position!=this.position&&!this.madeAbsolute){this.position=n.position;for(let e of this.manager.tooltipViews)e.dom.style.position=this.position;i=!0}if(n.parent!=this.parent){this.parent&&this.container.remove(),this.parent=n.parent,this.createContainer();for(let e of this.manager.tooltipViews)this.container.appendChild(e.dom);i=!0}else this.parent&&this.view.themeClasses!=this.classes&&(this.classes=this.container.className=this.view.themeClasses);i&&this.maybeMeasure()}createTooltip(e){let t=e.create(this.view);if(t.dom.classList.add("cm-tooltip"),e.arrow&&!t.dom.querySelector(".cm-tooltip > .cm-tooltip-arrow")){let e=document.createElement("div");e.className="cm-tooltip-arrow",t.dom.appendChild(e)}return t.dom.style.position=this.position,t.dom.style.top=Er,t.dom.style.left="0px",this.container.appendChild(t.dom),t.mount&&t.mount(this.view),t}destroy(){var e,t;this.view.win.removeEventListener("resize",this.measureSoon);for(let t of this.manager.tooltipViews)t.dom.remove(),null===(e=t.destroy)||void 0===e||e.call(t);this.parent&&this.container.remove(),null===(t=this.intersectionObserver)||void 0===t||t.disconnect(),clearTimeout(this.measureTimeout)}readMeasure(){let e=this.view.dom.getBoundingClientRect(),t=1,i=1,n=!1;if("fixed"==this.position&&this.manager.tooltipViews.length){let{dom:e}=this.manager.tooltipViews[0];if(Rt.gecko)n=e.offsetParent!=this.container.ownerDocument.body;else if(1!=this.view.scaleX||1!=this.view.scaleY)n=!0;else if(e.style.top==Er&&"0px"==e.style.left){let t=e.getBoundingClientRect();n=Math.abs(t.top+1e4)>1||Math.abs(t.left)>1}}if(n||"absolute"==this.position)if(this.parent){let e=this.parent.getBoundingClientRect();e.width&&e.height&&(t=e.width/this.parent.offsetWidth,i=e.height/this.parent.offsetHeight)}else({scaleX:t,scaleY:i}=this.view.viewState);return{editor:e,parent:this.parent?this.container.getBoundingClientRect():e,pos:this.manager.tooltips.map(((e,t)=>{let i=this.manager.tooltipViews[t];return i.getCoords?i.getCoords(e.pos):this.view.coordsAtPos(e.pos)})),size:this.manager.tooltipViews.map((({dom:e})=>e.getBoundingClientRect())),space:this.view.state.facet(Dr).tooltipSpace(this.view),scaleX:t,scaleY:i,makeAbsolute:n}}writeMeasure(e){var t;if(e.makeAbsolute){this.madeAbsolute=!0,this.position="absolute";for(let e of this.manager.tooltipViews)e.dom.style.position="absolute"}let{editor:i,space:n,scaleX:s,scaleY:r}=e,o=[];for(let a=0;a=Math.min(i.bottom,n.bottom)||d.rightMath.min(i.right,n.right)+.1){c.style.top=Er;continue}let p=l.arrow?h.dom.querySelector(".cm-tooltip-arrow"):null,f=p?7:0,m=u.right-u.left,g=null!==(t=Ir.get(h))&&void 0!==t?t:u.bottom-u.top,v=h.offset||Nr,O=this.view.textDirection==Ri.LTR,b=u.width>n.right-n.left?O?n.left:n.right-u.width:O?Math.min(d.left-(p?14:0)+v.x,n.right-m):Math.max(n.left,d.left-m+(p?14:0)-v.x),_=this.above[a];!l.strictSide&&(_?d.top-(u.bottom-u.top)-v.yn.bottom)&&_==n.bottom-d.bottom>d.top-n.top&&(_=this.above[a]=!_);let y=(_?d.top-n.top:n.bottom-d.bottom)-f;if(yb&&e.topw&&(w=_?e.top-g-2-f:e.bottom+f+2);if("absolute"==this.position?(c.style.top=(w-e.parent.top)/r+"px",c.style.left=(b-e.parent.left)/s+"px"):(c.style.top=w/r+"px",c.style.left=b/s+"px"),p){let e=d.left+(O?v.x:-v.x)-(b+14-7);p.style.left=e/s+"px"}!0!==h.overlap&&o.push({left:b,top:w,right:x,bottom:w+g}),c.classList.toggle("cm-tooltip-above",_),c.classList.toggle("cm-tooltip-below",!_),h.positioned&&h.positioned(e.space)}}maybeMeasure(){if(this.manager.tooltips.length&&(this.view.inView&&this.view.requestMeasure(this.measureReq),this.inView!=this.view.inView&&(this.inView=this.view.inView,!this.inView)))for(let e of this.manager.tooltipViews)e.dom.style.top=Er}},{eventObservers:{scroll(){this.maybeMeasure()}}}),Lr=Ds.baseTheme({".cm-tooltip":{zIndex:100,boxSizing:"border-box"},"&light .cm-tooltip":{border:"1px solid #bbb",backgroundColor:"#f5f5f5"},"&light .cm-tooltip-section:not(:first-child)":{borderTop:"1px solid #bbb"},"&dark .cm-tooltip":{backgroundColor:"#333338",color:"white"},".cm-tooltip-arrow":{height:"7px",width:"14px",position:"absolute",zIndex:-1,overflow:"hidden","&:before, &:after":{content:"''",position:"absolute",width:0,height:0,borderLeft:"7px solid transparent",borderRight:"7px solid transparent"},".cm-tooltip-above &":{bottom:"-7px","&:before":{borderTop:"7px solid #bbb"},"&:after":{borderTop:"7px solid #f5f5f5",bottom:"1px"}},".cm-tooltip-below &":{top:"-7px","&:before":{borderBottom:"7px solid #bbb"},"&:after":{borderBottom:"7px solid #f5f5f5",top:"1px"}}},"&dark .cm-tooltip .cm-tooltip-arrow":{"&:before":{borderTopColor:"#333338",borderBottomColor:"#333338"},"&:after":{borderTopColor:"transparent",borderBottomColor:"transparent"}}}),Nr={x:0,y:0},Br=q.define({enables:[qr,Lr]}),$r=q.define();class Qr{static create(e){return new Qr(e)}constructor(e){this.view=e,this.mounted=!1,this.dom=document.createElement("div"),this.dom.classList.add("cm-tooltip-hover"),this.manager=new Ar(e,$r,(e=>this.createHostedView(e)))}createHostedView(e){let t=e.create(this.view);return t.dom.classList.add("cm-tooltip-section"),this.dom.appendChild(t.dom),this.mounted&&t.mount&&t.mount(this.view),t}mount(e){for(let t of this.manager.tooltipViews)t.mount&&t.mount(e);this.mounted=!0}positioned(e){for(let t of this.manager.tooltipViews)t.positioned&&t.positioned(e)}update(e){this.manager.update(e)}destroy(){var e;for(let t of this.manager.tooltipViews)null===(e=t.destroy)||void 0===e||e.call(t)}passProp(e){let t;for(let i of this.manager.tooltipViews){let n=i[e];if(void 0!==n)if(void 0===t)t=n;else if(t!==n)return}return t}get offset(){return this.passProp("offset")}get getCoords(){return this.passProp("getCoords")}get overlap(){return this.passProp("overlap")}get resize(){return this.passProp("resize")}}const zr=Br.compute([$r],(e=>{let t=e.facet($r).filter((e=>e));return 0===t.length?null:{pos:Math.min(...t.map((e=>e.pos))),end:Math.max(...t.filter((e=>null!=e.end)).map((e=>e.end))),create:Qr.create,above:t[0].above,arrow:t.some((e=>e.arrow))}}));class jr{constructor(e,t,i,n,s){this.view=e,this.source=t,this.field=i,this.setHover=n,this.hoverTime=s,this.hoverTimeout=-1,this.restartTimeout=-1,this.pending=null,this.lastMove={x:0,y:0,target:e.dom,time:0},this.checkHover=this.checkHover.bind(this),e.dom.addEventListener("mouseleave",this.mouseleave=this.mouseleave.bind(this)),e.dom.addEventListener("mousemove",this.mousemove=this.mousemove.bind(this))}update(){this.pending&&(this.pending=null,clearTimeout(this.restartTimeout),this.restartTimeout=setTimeout((()=>this.startHover()),20))}get active(){return this.view.state.field(this.field)}checkHover(){if(this.hoverTimeout=-1,this.active)return;let e=Date.now()-this.lastMove.time;ei.bottom||t.xi.right+e.defaultCharacterWidth)return;let r=e.bidiSpans(e.state.doc.lineAt(n)).find((e=>e.from<=n&&e.to>=n)),o=r&&r.dir==Ri.RTL?-1:1;s=t.x{this.pending==t&&(this.pending=null,i&&e.dispatch({effects:this.setHover.of(i)}))}),(t=>mi(e.state,t,"hover tooltip")))}else r&&e.dispatch({effects:this.setHover.of(r)})}mousemove(e){var t;this.lastMove={x:e.clientX,y:e.clientY,target:e.target,time:Date.now()},this.hoverTimeout<0&&(this.hoverTimeout=setTimeout(this.checkHover,this.hoverTime));let i=this.active;if(i&&!Wr(this.lastMove.target)||this.pending){let{pos:n}=i||this.pending,s=null!==(t=null==i?void 0:i.end)&&void 0!==t?t:n;(n==s?this.view.posAtCoords(this.lastMove)==n:function(e,t,i,n,s,r){let o=e.scrollDOM.getBoundingClientRect(),a=e.documentTop+e.documentPadding.top+e.contentHeight;if(o.left>n||o.rights||Math.min(o.bottom,a)=t&&l<=i}(this.view,n,s,e.clientX,e.clientY))||(this.view.dispatch({effects:this.setHover.of(null)}),this.pending=null)}}mouseleave(e){clearTimeout(this.hoverTimeout),this.hoverTimeout=-1,this.active&&!Wr(e.relatedTarget)&&this.view.dispatch({effects:this.setHover.of(null)})}destroy(){clearTimeout(this.hoverTimeout),this.view.dom.removeEventListener("mouseleave",this.mouseleave),this.view.dom.removeEventListener("mousemove",this.mousemove)}}function Wr(e){for(let t=e;t;t=t.parentNode)if(1==t.nodeType&&t.classList.contains("cm-tooltip"))return!0;return!1}function Vr(e,t={}){let i=ae.define(),n=j.define({create:()=>null,update(e,n){if(e&&(t.hideOnChange&&(n.docChanged||n.selection)||t.hideOn&&t.hideOn(n,e)))return null;if(e&&n.docChanged){let t=n.changes.mapPos(e.pos,-1,w.TrackDel);if(null==t)return null;let i=Object.assign(Object.create(null),e);i.pos=t,null!=e.end&&(i.end=n.changes.mapPos(e.end)),e=i}for(let t of n.effects)t.is(i)&&(e=t.value),t.is(Fr)&&(e=null);return e},provide:e=>$r.from(e)});return[n,bi.define((s=>new jr(s,e,n,i,t.hoverTime||300))),zr]}function Ur(e,t){let i=e.plugin(qr);if(!i)return null;let n=i.manager.tooltips.indexOf(t);return n<0?null:i.manager.tooltipViews[n]}const Fr=ae.define(),Hr=q.define({combine(e){let t,i;for(let n of e)t=t||n.topContainer,i=i||n.bottomContainer;return{topContainer:t,bottomContainer:i}}});function Xr(e,t){let i=e.plugin(Yr),n=i?i.specs.indexOf(t):-1;return n>-1?i.panels[n]:null}const Yr=bi.fromClass(class{constructor(e){this.input=e.state.facet(Kr),this.specs=this.input.filter((e=>e)),this.panels=this.specs.map((t=>t(e)));let t=e.state.facet(Hr);this.top=new Gr(e,!0,t.topContainer),this.bottom=new Gr(e,!1,t.bottomContainer),this.top.sync(this.panels.filter((e=>e.top))),this.bottom.sync(this.panels.filter((e=>!e.top)));for(let e of this.panels)e.dom.classList.add("cm-panel"),e.mount&&e.mount()}update(e){let t=e.state.facet(Hr);this.top.container!=t.topContainer&&(this.top.sync([]),this.top=new Gr(e.view,!0,t.topContainer)),this.bottom.container!=t.bottomContainer&&(this.bottom.sync([]),this.bottom=new Gr(e.view,!1,t.bottomContainer)),this.top.syncClasses(),this.bottom.syncClasses();let i=e.state.facet(Kr);if(i!=this.input){let t=i.filter((e=>e)),n=[],s=[],r=[],o=[];for(let i of t){let t,a=this.specs.indexOf(i);a<0?(t=i(e.view),o.push(t)):(t=this.panels[a],t.update&&t.update(e)),n.push(t),(t.top?s:r).push(t)}this.specs=t,this.panels=n,this.top.sync(s),this.bottom.sync(r);for(let e of o)e.dom.classList.add("cm-panel"),e.mount&&e.mount()}else for(let t of this.panels)t.update&&t.update(e)}destroy(){this.top.sync([]),this.bottom.sync([])}},{provide:e=>Ds.scrollMargins.of((t=>{let i=t.plugin(e);return i&&{top:i.top.scrollMargin(),bottom:i.bottom.scrollMargin()}}))});class Gr{constructor(e,t,i){this.view=e,this.top=t,this.container=i,this.dom=void 0,this.classes="",this.panels=[],this.syncClasses()}sync(e){for(let t of this.panels)t.destroy&&e.indexOf(t)<0&&t.destroy();this.panels=e,this.syncDOM()}syncDOM(){if(0==this.panels.length)return void(this.dom&&(this.dom.remove(),this.dom=void 0));if(!this.dom){this.dom=document.createElement("div"),this.dom.className=this.top?"cm-panels cm-panels-top":"cm-panels cm-panels-bottom",this.dom.style[this.top?"top":"bottom"]="0";let e=this.container||this.view.dom;e.insertBefore(this.dom,this.top?e.firstChild:null)}let e=this.dom.firstChild;for(let t of this.panels)if(t.dom.parentNode==this.dom){for(;e!=t.dom;)e=Zr(e);e=e.nextSibling}else this.dom.insertBefore(t.dom,e);for(;e;)e=Zr(e)}scrollMargin(){return!this.dom||this.container?0:Math.max(0,this.top?this.dom.getBoundingClientRect().bottom-Math.max(0,this.view.scrollDOM.getBoundingClientRect().top):Math.min(innerHeight,this.view.scrollDOM.getBoundingClientRect().bottom)-this.dom.getBoundingClientRect().top)}syncClasses(){if(this.container&&this.classes!=this.view.themeClasses){for(let e of this.classes.split(" "))e&&this.container.classList.remove(e);for(let e of(this.classes=this.view.themeClasses).split(" "))e&&this.container.classList.add(e)}}}function Zr(e){let t=e.nextSibling;return e.remove(),t}const Kr=q.define({enables:Yr});class Jr extends _e{compare(e){return this==e||this.constructor==e.constructor&&this.eq(e)}eq(e){return!1}destroy(e){}}Jr.prototype.elementClass="",Jr.prototype.toDOM=void 0,Jr.prototype.mapMode=w.TrackBefore,Jr.prototype.startSide=Jr.prototype.endSide=-1,Jr.prototype.point=!0;const eo=q.define(),to={class:"",renderEmptyElements:!1,elementStyle:"",markers:()=>Se.empty,lineMarker:()=>null,widgetMarker:()=>null,lineMarkerChange:null,initialSpacer:null,updateSpacer:null,domEventHandlers:{}},io=q.define();function no(e){return[ro(),io.of(Object.assign(Object.assign({},to),e))]}const so=q.define({combine:e=>e.some((e=>e))});function ro(e){let t=[oo];return e&&!1===e.fixed&&t.push(so.of(!0)),t}const oo=bi.fromClass(class{constructor(e){this.view=e,this.prevViewport=e.viewport,this.dom=document.createElement("div"),this.dom.className="cm-gutters",this.dom.setAttribute("aria-hidden","true"),this.dom.style.minHeight=this.view.contentHeight/this.view.scaleY+"px",this.gutters=e.state.facet(io).map((t=>new co(e,t)));for(let e of this.gutters)this.dom.appendChild(e.dom);this.fixed=!e.state.facet(so),this.fixed&&(this.dom.style.position="sticky"),this.syncGutters(!1),e.scrollDOM.insertBefore(this.dom,e.contentDOM)}update(e){if(this.updateGutters(e)){let t=this.prevViewport,i=e.view.viewport,n=Math.min(t.to,i.to)-Math.max(t.from,i.from);this.syncGutters(n<.8*(i.to-i.from))}e.geometryChanged&&(this.dom.style.minHeight=this.view.contentHeight+"px"),this.view.state.facet(so)!=!this.fixed&&(this.fixed=!this.fixed,this.dom.style.position=this.fixed?"sticky":""),this.prevViewport=e.view.viewport}syncGutters(e){let t=this.dom.nextSibling;e&&this.dom.remove();let i=Se.iter(this.view.state.facet(eo),this.view.viewport.from),n=[],s=this.gutters.map((e=>new ho(e,this.view.viewport,-this.view.documentPadding.top)));for(let e of this.view.viewportLineBlocks)if(n.length&&(n=[]),Array.isArray(e.type)){let t=!0;for(let r of e.type)if(r.type==Xt.Text&&t){lo(i,n,r.from);for(let e of s)e.line(this.view,r,n);t=!1}else if(r.widget)for(let e of s)e.widget(this.view,r)}else if(e.type==Xt.Text){lo(i,n,e.from);for(let t of s)t.line(this.view,e,n)}else if(e.widget)for(let t of s)t.widget(this.view,e);for(let e of s)e.finish();e&&this.view.scrollDOM.insertBefore(this.dom,t)}updateGutters(e){let t=e.startState.facet(io),i=e.state.facet(io),n=e.docChanged||e.heightChanged||e.viewportChanged||!Se.eq(e.startState.facet(eo),e.state.facet(eo),e.view.viewport.from,e.view.viewport.to);if(t==i)for(let t of this.gutters)t.update(e)&&(n=!0);else{n=!0;let s=[];for(let n of i){let i=t.indexOf(n);i<0?s.push(new co(this.view,n)):(this.gutters[i].update(e),s.push(this.gutters[i]))}for(let e of this.gutters)e.dom.remove(),s.indexOf(e)<0&&e.destroy();for(let e of s)this.dom.appendChild(e.dom);this.gutters=s}return n}destroy(){for(let e of this.gutters)e.destroy();this.dom.remove()}},{provide:e=>Ds.scrollMargins.of((t=>{let i=t.plugin(e);return i&&0!=i.gutters.length&&i.fixed?t.textDirection==Ri.LTR?{left:i.dom.offsetWidth*t.scaleX}:{right:i.dom.offsetWidth*t.scaleX}:null}))});function ao(e){return Array.isArray(e)?e:[e]}function lo(e,t,i){for(;e.value&&e.from<=i;)e.from==i&&t.push(e.value),e.next()}class ho{constructor(e,t,i){this.gutter=e,this.height=i,this.i=0,this.cursor=Se.iter(e.markers,t.from)}addElement(e,t,i){let{gutter:n}=this,s=(t.top-this.height)/e.scaleY,r=t.height/e.scaleY;if(this.i==n.elements.length){let t=new uo(e,r,s,i);n.elements.push(t),n.dom.appendChild(t.dom)}else n.elements[this.i].update(e,r,s,i);this.height=t.bottom,this.i++}line(e,t,i){let n=[];lo(this.cursor,n,t.from),i.length&&(n=n.concat(i));let s=this.gutter.config.lineMarker(e,t,n);s&&n.unshift(s);let r=this.gutter;(0!=n.length||r.config.renderEmptyElements)&&this.addElement(e,t,n)}widget(e,t){let i=this.gutter.config.widgetMarker(e,t.widget,t);i&&this.addElement(e,t,[i])}finish(){let e=this.gutter;for(;e.elements.length>this.i;){let t=e.elements.pop();e.dom.removeChild(t.dom),t.destroy()}}}class co{constructor(e,t){this.view=e,this.config=t,this.elements=[],this.spacer=null,this.dom=document.createElement("div"),this.dom.className="cm-gutter"+(this.config.class?" "+this.config.class:"");for(let i in t.domEventHandlers)this.dom.addEventListener(i,(n=>{let s,r=n.target;if(r!=this.dom&&this.dom.contains(r)){for(;r.parentNode!=this.dom;)r=r.parentNode;let e=r.getBoundingClientRect();s=(e.top+e.bottom)/2}else s=n.clientY;let o=e.lineBlockAtHeight(s-e.documentTop);t.domEventHandlers[i](e,o,n)&&n.preventDefault()}));this.markers=ao(t.markers(e)),t.initialSpacer&&(this.spacer=new uo(e,0,0,[t.initialSpacer(e)]),this.dom.appendChild(this.spacer.dom),this.spacer.dom.style.cssText+="visibility: hidden; pointer-events: none")}update(e){let t=this.markers;if(this.markers=ao(this.config.markers(e.view)),this.spacer&&this.config.updateSpacer){let t=this.config.updateSpacer(this.spacer.markers[0],e);t!=this.spacer.markers[0]&&this.spacer.update(e.view,0,0,[t])}let i=e.view.viewport;return!Se.eq(this.markers,t,i.from,i.to)||!!this.config.lineMarkerChange&&this.config.lineMarkerChange(e)}destroy(){for(let e of this.elements)e.destroy()}}class uo{constructor(e,t,i,n){this.height=-1,this.above=0,this.markers=[],this.dom=document.createElement("div"),this.dom.className="cm-gutterElement",this.update(e,t,i,n)}update(e,t,i,n){this.height!=t&&(this.height=t,this.dom.style.height=t+"px"),this.above!=i&&(this.dom.style.marginTop=(this.above=i)?i+"px":""),function(e,t){if(e.length!=t.length)return!1;for(let i=0;ibe(e,{formatNumber:String,domEventHandlers:{}},{domEventHandlers(e,t){let i=Object.assign({},e);for(let e in t){let n=i[e],s=t[e];i[e]=n?(e,t,i)=>n(e,t,i)||s(e,t,i):s}return i}})});class mo extends Jr{constructor(e){super(),this.number=e}eq(e){return this.number==e.number}toDOM(){return document.createTextNode(this.number)}}function go(e,t){return e.state.facet(fo).formatNumber(t,e.state)}const vo=io.compute([fo],(e=>({class:"cm-lineNumbers",renderEmptyElements:!1,markers:e=>e.state.facet(po),lineMarker:(e,t,i)=>i.some((e=>e.toDOM))?null:new mo(go(e,e.state.doc.lineAt(t.from).number)),widgetMarker:()=>null,lineMarkerChange:e=>e.startState.facet(fo)!=e.state.facet(fo),initialSpacer:e=>new mo(go(e,bo(e.state.doc.lines))),updateSpacer(e,t){let i=go(t.view,bo(t.view.state.doc.lines));return i==e.number?e:new mo(i)},domEventHandlers:e.facet(fo).domEventHandlers})));function Oo(e={}){return[fo.of(e),ro(),vo]}function bo(e){let t=9;for(;t{let t=[],i=-1;for(let n of e.selection.ranges){let s=e.doc.lineAt(n.head).from;s>i&&(i=s,t.push(_o.range(s)))}return Se.of(t)})),wo=1024;let xo=0;class So{constructor(e,t){this.from=e,this.to=t}}class ko{constructor(e={}){this.id=xo++,this.perNode=!!e.perNode,this.deserialize=e.deserialize||(()=>{throw new Error("This node type doesn't define a deserialize function")})}add(e){if(this.perNode)throw new RangeError("Can't add per-node props to node types");return"function"!=typeof e&&(e=Po.match(e)),t=>{let i=e(t);return void 0===i?null:[this,i]}}}ko.closedBy=new ko({deserialize:e=>e.split(" ")}),ko.openedBy=new ko({deserialize:e=>e.split(" ")}),ko.group=new ko({deserialize:e=>e.split(" ")}),ko.contextHash=new ko({perNode:!0}),ko.lookAhead=new ko({perNode:!0}),ko.mounted=new ko({perNode:!0});class To{constructor(e,t,i){this.tree=e,this.overlay=t,this.parser=i}static get(e){return e&&e.props&&e.props[ko.mounted.id]}}const Co=Object.create(null);class Po{constructor(e,t,i,n=0){this.name=e,this.props=t,this.id=i,this.flags=n}static define(e){let t=e.props&&e.props.length?Object.create(null):Co,i=(e.top?1:0)|(e.skipped?2:0)|(e.error?4:0)|(null==e.name?8:0),n=new Po(e.name||"",t,e.id,i);if(e.props)for(let i of e.props)if(Array.isArray(i)||(i=i(n)),i){if(i[0].perNode)throw new RangeError("Can't store a per-node prop on a node type");t[i[0].id]=i[1]}return n}prop(e){return this.props[e.id]}get isTop(){return(1&this.flags)>0}get isSkipped(){return(2&this.flags)>0}get isError(){return(4&this.flags)>0}get isAnonymous(){return(8&this.flags)>0}is(e){if("string"==typeof e){if(this.name==e)return!0;let t=this.prop(ko.group);return!!t&&t.indexOf(e)>-1}return this.id==e}static match(e){let t=Object.create(null);for(let i in e)for(let n of i.split(" "))t[n]=e[i];return e=>{for(let i=e.prop(ko.group),n=-1;n<(i?i.length:0);n++){let s=t[n<0?e.name:i[n]];if(s)return s}}}}Po.none=new Po("",Object.create(null),0,8);class Mo{constructor(e){this.types=e;for(let t=0;t=t){let o=new $o(r.tree,r.overlay[0].from+e.from,0,null);(s||(s=[n])).push(No(o,t,i,!1))}}return s?Vo(s):n}(this,e,t)}iterate(e){let{enter:t,leave:i,from:n=0,to:s=this.length}=e,r=e.mode||0,o=(r&Ro.IncludeAnonymous)>0;for(let e=this.cursor(r|Ro.IncludeAnonymous);;){let r=!1;if(e.from<=s&&e.to>=n&&(!o&&e.type.isAnonymous||!1!==t(e))){if(e.firstChild())continue;r=!0}for(;r&&i&&(o||!e.type.isAnonymous)&&i(e),!e.nextSibling();){if(!e.parent())return;r=!0}}}prop(e){return e.perNode?this.props?this.props[e.id]:void 0:this.type.prop(e)}get propValues(){let e=[];if(this.props)for(let t in this.props)e.push([+t,this.props[t]]);return e}balance(e={}){return this.children.length<=8?this:Go(Po.none,this.children,this.positions,0,this.children.length,0,this.length,((e,t,i)=>new Do(this.type,e,t,i,this.propValues)),e.makeTree||((e,t,i)=>new Do(Po.none,e,t,i)))}static build(e){return function(e){var t;let{buffer:i,nodeSet:n,maxBufferLength:s=wo,reused:r=[],minRepeatType:o=n.types.length}=e,a=Array.isArray(i)?new Io(i,i.length):i,l=n.types,h=0,c=0;function d(e,t,i,m,g){let{id:v,start:O,end:b,size:_}=a,y=c;for(;_<0;){if(a.next(),-1==_){let t=r[v];return i.push(t),void m.push(O-e)}if(-3==_)return void(h=v);if(-4==_)return void(c=v);throw new RangeError(`Unrecognized record size: ${_}`)}let w,x,S=l[v],k=O-e;if(b-O<=s&&(x=function(e,t){let i=a.fork(),n=0,r=0,l=0,h=i.end-s,c={size:0,start:0,skip:0};e:for(let s=i.pos-e;i.pos>s;){let e=i.size;if(i.id==t&&e>=0){c.size=n,c.start=r,c.skip=l,l+=4,n+=4,i.next();continue}let a=i.pos-e;if(e<0||a=o?4:0,u=i.start;for(i.next();i.pos>a;){if(i.size<0){if(-3!=i.size)break e;d+=4}else i.id>=o&&(d+=4);i.next()}r=u,n+=e,l+=d}return(t<0||n==e)&&(c.size=n,c.start=r,c.skip=l),c.size>4?c:void 0}(a.pos-t,g))){let t=new Uint16Array(x.size-x.skip),i=a.pos-x.size,s=t.length;for(;a.pos>i;)s=f(x.start,t,s);w=new qo(t,b-x.start,n),k=x.start-e}else{let e=a.pos-_;a.next();let t=[],i=[],n=v>=o?v:-1,r=0,l=b;for(;a.pos>e;)n>=0&&a.id==n&&a.size>=0?(a.end<=l-s&&(u(t,i,O,r,a.end,l,n,y),r=t.length,l=a.end),a.next()):d(O,e,t,i,n);if(n>=0&&r>0&&r-1&&r>0){let e=function(e){return(t,i,n)=>{let s,r,o=0,a=t.length-1;if(a>=0&&(s=t[a])instanceof Do){if(!a&&s.type==e&&s.length==n)return s;(r=s.prop(ko.lookAhead))&&(o=i[a]+s.length+r)}return p(e,t,i,n,o)}}(S);w=Go(S,t,i,0,t.length,0,b-O,e,e)}else w=p(S,t,i,b-O,y-b)}i.push(w),m.push(k)}function u(e,t,i,s,r,o,a,l){let h=[],c=[];for(;e.length>s;)h.push(e.pop()),c.push(t.pop()+i-r);e.push(p(n.types[a],h,c,o-r,l-o)),t.push(r-i)}function p(e,t,i,n,s=0,r){if(h){let e=[ko.contextHash,h];r=r?[e].concat(r):[e]}if(s>25){let e=[ko.lookAhead,s];r=r?[e].concat(r):[e]}return new Do(e,t,i,n,r)}function f(e,t,i){let{id:n,start:s,end:r,size:l}=a;if(a.next(),l>=0&&n4){let n=a.pos-(l-4);for(;a.pos>n;)i=f(e,t,i)}t[--i]=o,t[--i]=r-e,t[--i]=s-e,t[--i]=n}else-3==l?h=n:-4==l&&(c=n);return i}let m=[],g=[];for(;a.pos>0;)d(e.start||0,e.bufferStart||0,m,g,-1);let v=null!==(t=e.length)&&void 0!==t?t:m.length?g[0]+m[0].length:0;return new Do(l[e.topID],m.reverse(),g.reverse(),v)}(e)}}Do.empty=new Do(Po.none,[],[],0);class Io{constructor(e,t){this.buffer=e,this.index=t}get id(){return this.buffer[this.index-4]}get start(){return this.buffer[this.index-3]}get end(){return this.buffer[this.index-2]}get size(){return this.buffer[this.index-1]}get pos(){return this.index}next(){this.index-=4}fork(){return new Io(this.buffer,this.index)}}class qo{constructor(e,t,i){this.buffer=e,this.length=t,this.set=i}get type(){return Po.none}toString(){let e=[];for(let t=0;t0));a=r[a+3]);return o}slice(e,t,i){let n=this.buffer,s=new Uint16Array(t-e),r=0;for(let o=e,a=0;o=t&&it;case 1:return i<=t&&n>t;case 2:return n>t;case 4:return!0}}function No(e,t,i,n){for(var s;e.from==e.to||(i<1?e.from>=t:e.from>t)||(i>-1?e.to<=t:e.to0?o.length:-1;e!=l;e+=t){let l=o[e],h=a[e]+r.from;if(Lo(n,i,h,h+l.length))if(l instanceof qo){if(s&Ro.ExcludeBuffers)continue;let o=l.findChild(0,l.buffer.length,t,i-h,n);if(o>-1)return new Wo(new jo(r,l,e,h),null,o)}else if(s&Ro.IncludeAnonymous||!l.type.isAnonymous||Ho(l)){let o;if(!(s&Ro.IgnoreMounts)&&(o=To.get(l))&&!o.overlay)return new $o(o.tree,h,e,r);let a=new $o(l,h,e,r);return s&Ro.IncludeAnonymous||!a.type.isAnonymous?a:a.nextChild(t<0?l.children.length-1:0,t,i,n)}}if(s&Ro.IncludeAnonymous||!r.type.isAnonymous)return null;if(e=r.index>=0?r.index+t:t<0?-1:r._parent._tree.children.length,r=r._parent,!r)return null}}get firstChild(){return this.nextChild(0,1,0,4)}get lastChild(){return this.nextChild(this._tree.children.length-1,-1,0,4)}childAfter(e){return this.nextChild(0,1,e,2)}childBefore(e){return this.nextChild(this._tree.children.length-1,-1,e,-2)}enter(e,t,i=0){let n;if(!(i&Ro.IgnoreOverlays)&&(n=To.get(this._tree))&&n.overlay){let i=e-this.from;for(let{from:e,to:s}of n.overlay)if((t>0?e<=i:e=i:s>i))return new $o(n.tree,n.overlay[0].from+this.from,-1,this)}return this.nextChild(0,1,e,t,i)}nextSignificantParent(){let e=this;for(;e.type.isAnonymous&&e._parent;)e=e._parent;return e}get parent(){return this._parent?this._parent.nextSignificantParent():null}get nextSibling(){return this._parent&&this.index>=0?this._parent.nextChild(this.index+1,1,0,4):null}get prevSibling(){return this._parent&&this.index>=0?this._parent.nextChild(this.index-1,-1,0,4):null}get tree(){return this._tree}toTree(){return this._tree}toString(){return this._tree.toString()}}function Qo(e,t,i,n){let s=e.cursor(),r=[];if(!s.firstChild())return r;if(null!=i)for(;!s.type.is(i);)if(!s.nextSibling())return r;for(;;){if(null!=n&&s.type.is(n))return r;if(s.type.is(t)&&r.push(s.node),!s.nextSibling())return null==n?r:[]}}function zo(e,t,i=t.length-1){for(let n=e.parent;i>=0;n=n.parent){if(!n)return!1;if(!n.type.isAnonymous){if(t[i]&&t[i]!=n.name)return!1;i--}}return!0}class jo{constructor(e,t,i,n){this.parent=e,this.buffer=t,this.index=i,this.start=n}}class Wo extends Bo{get name(){return this.type.name}get from(){return this.context.start+this.context.buffer.buffer[this.index+1]}get to(){return this.context.start+this.context.buffer.buffer[this.index+2]}constructor(e,t,i){super(),this.context=e,this._parent=t,this.index=i,this.type=e.buffer.set.types[e.buffer.buffer[i]]}child(e,t,i){let{buffer:n}=this.context,s=n.findChild(this.index+4,n.buffer[this.index+3],e,t-this.context.start,i);return s<0?null:new Wo(this.context,this,s)}get firstChild(){return this.child(1,0,4)}get lastChild(){return this.child(-1,0,4)}childAfter(e){return this.child(1,e,2)}childBefore(e){return this.child(-1,e,-2)}enter(e,t,i=0){if(i&Ro.ExcludeBuffers)return null;let{buffer:n}=this.context,s=n.findChild(this.index+4,n.buffer[this.index+3],t>0?1:-1,e-this.context.start,t);return s<0?null:new Wo(this.context,this,s)}get parent(){return this._parent||this.context.parent.nextSignificantParent()}externalSibling(e){return this._parent?null:this.context.parent.nextChild(this.context.index+e,e,0,4)}get nextSibling(){let{buffer:e}=this.context,t=e.buffer[this.index+3];return t<(this._parent?e.buffer[this._parent.index+3]:e.buffer.length)?new Wo(this.context,this._parent,t):this.externalSibling(1)}get prevSibling(){let{buffer:e}=this.context,t=this._parent?this._parent.index+4:0;return this.index==t?this.externalSibling(-1):new Wo(this.context,this._parent,e.findChild(t,this.index,-1,0,4))}get tree(){return null}toTree(){let e=[],t=[],{buffer:i}=this.context,n=this.index+4,s=i.buffer[this.index+3];if(s>n){let r=i.buffer[this.index+1];e.push(i.slice(n,s,r)),t.push(0)}return new Do(this.type,e,t,this.to-this.from)}toString(){return this.context.buffer.childString(this.index)}}function Vo(e){if(!e.length)return null;if(1==e.length)return e[0];let t=0,i=e[0];for(let n=1;ni.from||s.to0){if(this.index-1)for(let n=t+e,s=e<0?-1:i._tree.children.length;n!=s;n+=e){let e=i._tree.children[n];if(this.mode&Ro.IncludeAnonymous||e instanceof qo||!e.type.isAnonymous||Ho(e))return!1}return!0}move(e,t){if(t&&this.enterChild(e,0,4))return!0;for(;;){if(this.sibling(e))return!0;if(this.atLastNode(e)||!this.parent())return!1}}next(e=!0){return this.move(1,e)}prev(e=!0){return this.move(-1,e)}moveTo(e,t=0){for(;(this.from==this.to||(t<1?this.from>=e:this.from>e)||(t>-1?this.to<=e:this.to=0;){for(let r=e;r;r=r._parent)if(r.index==n){if(n==this.index)return r;t=r,i=s+1;break e}n=this.stack[--s]}for(let e=i;e=0;s--){if(s<0)return zo(this.node,e,n);let r=i[t.buffer[this.stack[s]]];if(!r.isAnonymous){if(e[n]&&e[n]!=r.name)return!1;n--}}return!0}}function Ho(e){return e.children.some((e=>e instanceof qo||!e.type.isAnonymous||Ho(e)))}const Xo=new WeakMap;function Yo(e,t){if(!e.isAnonymous||t instanceof qo||t.type!=e)return 1;let i=Xo.get(t);if(null==i){i=1;for(let n of t.children){if(n.type!=e||!(n instanceof Do)){i=1;break}i+=Yo(e,n)}Xo.set(t,i)}return i}function Go(e,t,i,n,s,r,o,a,l){let h=0;for(let i=n;i=c)break;f+=t}if(h==s+1){if(f>c){let e=i[s];t(e.children,e.positions,0,e.children.length,n[s]+a);continue}d.push(i[s])}else{let t=n[h-1]+i[h-1].length-p;d.push(Go(e,i,n,s,h,p,t,null,l))}u.push(p+a-r)}}(t,i,n,s,0),(a||l)(d,u,o)}class Zo{constructor(){this.map=new WeakMap}setBuffer(e,t,i){let n=this.map.get(e);n||this.map.set(e,n=new Map),n.set(t,i)}getBuffer(e,t){let i=this.map.get(e);return i&&i.get(t)}set(e,t){e instanceof Wo?this.setBuffer(e.context.buffer,e.index,t):e instanceof $o&&this.map.set(e.tree,t)}get(e){return e instanceof Wo?this.getBuffer(e.context.buffer,e.index):e instanceof $o?this.map.get(e.tree):void 0}cursorSet(e,t){e.buffer?this.setBuffer(e.buffer.buffer,e.index,t):this.map.set(e.tree,t)}cursorGet(e){return e.buffer?this.getBuffer(e.buffer.buffer,e.index):this.map.get(e.tree)}}class Ko{constructor(e,t,i,n,s=!1,r=!1){this.from=e,this.to=t,this.tree=i,this.offset=n,this.open=(s?1:0)|(r?2:0)}get openStart(){return(1&this.open)>0}get openEnd(){return(2&this.open)>0}static addTree(e,t=[],i=!1){let n=[new Ko(0,e.length,e,0,!1,i)];for(let i of t)i.to>e.length&&n.push(i);return n}static applyChanges(e,t,i=128){if(!t.length)return e;let n=[],s=1,r=e.length?e[0]:null;for(let o=0,a=0,l=0;;o++){let h=o=i)for(;r&&r.from=t.from||c<=t.to||l){let e=Math.max(t.from,a)-l,i=Math.min(t.to,c)-l;t=e>=i?null:new Ko(e,i,t.tree,t.offset+l,o>0,!!h)}if(t&&n.push(t),r.to>c)break;r=snew So(e.from,e.to))):[new So(0,0)]:[new So(0,e.length)],this.createParse(e,t||[],i)}parse(e,t,i){let n=this.startParse(e,t,i);for(;;){let e=n.advance();if(e)return e}}}class ea{constructor(e){this.string=e}get length(){return this.string.length}chunk(e){return this.string.slice(e)}get lineChunks(){return!1}read(e,t){return this.string.slice(e,t)}}new ko({perNode:!0});let ta=0;class ia{constructor(e,t,i){this.set=e,this.base=t,this.modified=i,this.id=ta++}static define(e){if(null==e?void 0:e.base)throw new Error("Can not derive from a modified tag");let t=new ia([],null,[]);if(t.set.push(t),e)for(let i of e.set)t.set.push(i);return t}static defineModifier(){let e=new sa;return t=>t.modified.indexOf(e)>-1?t:sa.get(t.base||t,t.modified.concat(e).sort(((e,t)=>e.id-t.id)))}}let na=0;class sa{constructor(){this.instances=[],this.id=na++}static get(e,t){if(!t.length)return e;let i=t[0].instances.find((i=>{return i.base==e&&(n=t,s=i.modified,n.length==s.length&&n.every(((e,t)=>e==s[t])));var n,s}));if(i)return i;let n=[],s=new ia(n,e,t);for(let e of t)e.instances.push(s);let r=function(e){let t=[[]];for(let i=0;it.length-e.length))}(t);for(let t of e.set)if(!t.modified.length)for(let e of r)n.push(sa.get(t,e));return s}}function ra(e){let t=Object.create(null);for(let i in e){let n=e[i];Array.isArray(n)||(n=[n]);for(let e of i.split(" "))if(e){let i=[],s=2,r=e;for(let t=0;;){if("..."==r&&t>0&&t+3==e.length){s=1;break}let n=/^"(?:[^"\\]|\\.)*?"|[^\/!]+/.exec(r);if(!n)throw new RangeError("Invalid path: "+e);if(i.push("*"==n[0]?"":'"'==n[0][0]?JSON.parse(n[0]):n[0]),t+=n[0].length,t==e.length)break;let o=e[t++];if(t==e.length&&"!"==o){s=0;break}if("/"!=o)throw new RangeError("Invalid path: "+e);r=e.slice(t)}let o=i.length-1,a=i[o];if(!a)throw new RangeError("Invalid path: "+e);let l=new aa(n,s,o>0?i.slice(0,o):null);t[a]=l.sort(t[a])}}return oa.add(t)}const oa=new ko;class aa{constructor(e,t,i,n){this.tags=e,this.mode=t,this.context=i,this.next=n}get opaque(){return 0==this.mode}get inherit(){return 1==this.mode}sort(e){return!e||e.depth{let t=s;for(let n of e)for(let e of n.set){let n=i[e.id];if(n){t=t?t+" "+n:n;break}}return t},scope:n}}function ha(e,t,i,n=0,s=e.length){let r=new ca(n,Array.isArray(t)?t:[t],i);r.highlightRange(e.cursor(),n,s,"",r.highlighters),r.flush(s)}aa.empty=new aa([],2,null);class ca{constructor(e,t,i){this.at=e,this.highlighters=t,this.span=i,this.class=""}startSpan(e,t){t!=this.class&&(this.flush(e),e>this.at&&(this.at=e),this.class=t)}flush(e){e>this.at&&this.class&&this.span(this.at,e,this.class)}highlightRange(e,t,i,n,s){let{type:r,from:o,to:a}=e;if(o>=i||a<=t)return;r.isTop&&(s=this.highlighters.filter((e=>!e.scope||e.scope(r))));let l=n,h=function(e){let t=e.type.prop(oa);for(;t&&t.context&&!e.matchContext(t.context);)t=t.next;return t||null}(e)||aa.empty,c=function(e,t){let i=null;for(let n of e){let e=n.style(t);e&&(i=i?i+" "+e:e)}return i}(s,h.tags);if(c&&(l&&(l+=" "),l+=c,1==h.mode&&(n+=(n?" ":"")+c)),this.startSpan(Math.max(t,o),l),h.opaque)return;let d=e.tree&&e.tree.prop(ko.mounted);if(d&&d.overlay){let r=e.node.enter(d.overlay[0].from+o,1),h=this.highlighters.filter((e=>!e.scope||e.scope(d.tree.type))),c=e.firstChild();for(let u=0,p=o;;u++){let f=u=m)&&e.nextSibling()););if(!f||m>i)break;p=f.to+o,p>t&&(this.highlightRange(r.cursor(),Math.max(t,f.from+o),Math.min(i,p),"",h),this.startSpan(Math.min(i,p),l))}c&&e.parent()}else if(e.firstChild()){d&&(n="");do{if(!(e.to<=t)){if(e.from>=i)break;this.highlightRange(e,t,i,n,s),this.startSpan(Math.min(i,e.to),l)}}while(e.nextSibling());e.parent()}}}const da=ia.define,ua=da(),pa=da(),fa=da(pa),ma=da(pa),ga=da(),va=da(ga),Oa=da(ga),ba=da(),_a=da(ba),ya=da(),wa=da(),xa=da(),Sa=da(xa),ka=da(),Ta={comment:ua,lineComment:da(ua),blockComment:da(ua),docComment:da(ua),name:pa,variableName:da(pa),typeName:fa,tagName:da(fa),propertyName:ma,attributeName:da(ma),className:da(pa),labelName:da(pa),namespace:da(pa),macroName:da(pa),literal:ga,string:va,docString:da(va),character:da(va),attributeValue:da(va),number:Oa,integer:da(Oa),float:da(Oa),bool:da(ga),regexp:da(ga),escape:da(ga),color:da(ga),url:da(ga),keyword:ya,self:da(ya),null:da(ya),atom:da(ya),unit:da(ya),modifier:da(ya),operatorKeyword:da(ya),controlKeyword:da(ya),definitionKeyword:da(ya),moduleKeyword:da(ya),operator:wa,derefOperator:da(wa),arithmeticOperator:da(wa),logicOperator:da(wa),bitwiseOperator:da(wa),compareOperator:da(wa),updateOperator:da(wa),definitionOperator:da(wa),typeOperator:da(wa),controlOperator:da(wa),punctuation:xa,separator:da(xa),bracket:Sa,angleBracket:da(Sa),squareBracket:da(Sa),paren:da(Sa),brace:da(Sa),content:ba,heading:_a,heading1:da(_a),heading2:da(_a),heading3:da(_a),heading4:da(_a),heading5:da(_a),heading6:da(_a),contentSeparator:da(ba),list:da(ba),quote:da(ba),emphasis:da(ba),strong:da(ba),link:da(ba),monospace:da(ba),strikethrough:da(ba),inserted:da(),deleted:da(),changed:da(),invalid:da(),meta:ka,documentMeta:da(ka),annotation:da(ka),processingInstruction:da(ka),definition:ia.defineModifier(),constant:ia.defineModifier(),function:ia.defineModifier(),standard:ia.defineModifier(),local:ia.defineModifier(),special:ia.defineModifier()};var Ca;la([{tag:Ta.link,class:"tok-link"},{tag:Ta.heading,class:"tok-heading"},{tag:Ta.emphasis,class:"tok-emphasis"},{tag:Ta.strong,class:"tok-strong"},{tag:Ta.keyword,class:"tok-keyword"},{tag:Ta.atom,class:"tok-atom"},{tag:Ta.bool,class:"tok-bool"},{tag:Ta.url,class:"tok-url"},{tag:Ta.labelName,class:"tok-labelName"},{tag:Ta.inserted,class:"tok-inserted"},{tag:Ta.deleted,class:"tok-deleted"},{tag:Ta.literal,class:"tok-literal"},{tag:Ta.string,class:"tok-string"},{tag:Ta.number,class:"tok-number"},{tag:[Ta.regexp,Ta.escape,Ta.special(Ta.string)],class:"tok-string2"},{tag:Ta.variableName,class:"tok-variableName"},{tag:Ta.local(Ta.variableName),class:"tok-variableName tok-local"},{tag:Ta.definition(Ta.variableName),class:"tok-variableName tok-definition"},{tag:Ta.special(Ta.variableName),class:"tok-variableName2"},{tag:Ta.definition(Ta.propertyName),class:"tok-propertyName tok-definition"},{tag:Ta.typeName,class:"tok-typeName"},{tag:Ta.namespace,class:"tok-namespace"},{tag:Ta.className,class:"tok-className"},{tag:Ta.macroName,class:"tok-macroName"},{tag:Ta.propertyName,class:"tok-propertyName"},{tag:Ta.operator,class:"tok-operator"},{tag:Ta.comment,class:"tok-comment"},{tag:Ta.meta,class:"tok-meta"},{tag:Ta.invalid,class:"tok-invalid"},{tag:Ta.punctuation,class:"tok-punctuation"}]);const Pa=new ko;const Ma=new ko;class Ea{constructor(e,t,i=[],n=""){this.data=e,this.name=n,Oe.prototype.hasOwnProperty("tree")||Object.defineProperty(Oe.prototype,"tree",{get(){return Da(this)}}),this.parser=t,this.extension=[ja.of(this),Oe.languageData.of(((e,t,i)=>{let n=Aa(e,t,i),s=n.type.prop(Pa);if(!s)return[];let r=e.facet(s),o=n.type.prop(Ma);if(o){let s=n.resolve(t-n.from,i);for(let t of o)if(t.test(s,e)){let i=e.facet(t.facet);return"replace"==t.type?i:i.concat(r)}}return r}))].concat(i)}isActiveAt(e,t,i=-1){return Aa(e,t,i).type.prop(Pa)==this.data}findRegions(e){let t=e.facet(ja);if((null==t?void 0:t.data)==this.data)return[{from:0,to:e.doc.length}];if(!t||!t.allowsNesting)return[];let i=[],n=(e,t)=>{if(e.prop(Pa)==this.data)return void i.push({from:t,to:t+e.length});let s=e.prop(ko.mounted);if(s){if(s.tree.prop(Pa)==this.data){if(s.overlay)for(let e of s.overlay)i.push({from:e.from+t,to:e.to+t});else i.push({from:t,to:t+e.length});return}if(s.overlay){let e=i.length;if(n(s.tree,s.overlay[0].from+t),i.length>e)return}}for(let i=0;ie.concat(i):void 0}));var i;return new Ra(t,e.parser.configure({props:[Pa.add((e=>e.isTop?t:void 0))]}),e.name)}configure(e,t){return new Ra(this.data,this.parser.configure(e),t||this.name)}get allowsNesting(){return this.parser.hasWrappers()}}function Da(e){let t=e.field(Ea.state,!1);return t?t.tree:Do.empty}class Ia{constructor(e){this.doc=e,this.cursorPos=0,this.string="",this.cursor=e.iter()}get length(){return this.doc.length}syncTo(e){return this.string=this.cursor.next(e-this.cursorPos).value,this.cursorPos=e+this.string.length,this.cursorPos-this.string.length}chunk(e){return this.syncTo(e),this.string}get lineChunks(){return!0}read(e,t){let i=this.cursorPos-this.string.length;return e=this.cursorPos?this.doc.sliceString(e,t):this.string.slice(e-i,t-i)}}let qa=null;class La{constructor(e,t,i=[],n,s,r,o,a){this.parser=e,this.state=t,this.fragments=i,this.tree=n,this.treeLen=s,this.viewport=r,this.skipped=o,this.scheduleOn=a,this.parse=null,this.tempSkipped=[]}static create(e,t,i){return new La(e,t,[],Do.empty,0,i,[],null)}startParse(){return this.parser.startParse(new Ia(this.state.doc),this.fragments)}work(e,t){return null!=t&&t>=this.state.doc.length&&(t=void 0),this.tree!=Do.empty&&this.isDone(null!=t?t:this.state.doc.length)?(this.takeTree(),!0):this.withContext((()=>{var i;if("number"==typeof e){let t=Date.now()+e;e=()=>Date.now()>t}for(this.parse||(this.parse=this.startParse()),null!=t&&(null==this.parse.stoppedAt||this.parse.stoppedAt>t)&&t=this.treeLen&&((null==this.parse.stoppedAt||this.parse.stoppedAt>e)&&this.parse.stopAt(e),this.withContext((()=>{for(;!(t=this.parse.advance()););})),this.treeLen=e,this.tree=t,this.fragments=this.withoutTempSkipped(Ko.addTree(this.tree,this.fragments,!0)),this.parse=null)}withContext(e){let t=qa;qa=this;try{return e()}finally{qa=t}}withoutTempSkipped(e){for(let t;t=this.tempSkipped.pop();)e=Na(e,t.from,t.to);return e}changes(e,t){let{fragments:i,tree:n,treeLen:s,viewport:r,skipped:o}=this;if(this.takeTree(),!e.empty){let t=[];if(e.iterChangedRanges(((e,i,n,s)=>t.push({fromA:e,toA:i,fromB:n,toB:s}))),i=Ko.applyChanges(i,t),n=Do.empty,s=0,r={from:e.mapPos(r.from,-1),to:e.mapPos(r.to,1)},this.skipped.length){o=[];for(let t of this.skipped){let i=e.mapPos(t.from,1),n=e.mapPos(t.to,-1);ie.from&&(this.fragments=Na(this.fragments,i,n),this.skipped.splice(t--,1))}return!(this.skipped.length>=t||(this.reset(),0))}reset(){this.parse&&(this.takeTree(),this.parse=null)}skipUntilInView(e,t){this.skipped.push({from:e,to:t})}static getSkippingParser(e){return new class extends Jo{createParse(t,i,n){let s=n[0].from,r=n[n.length-1].to;return{parsedPos:s,advance(){let t=qa;if(t){for(let e of n)t.tempSkipped.push(e);e&&(t.scheduleOn=t.scheduleOn?Promise.all([t.scheduleOn,e]):e)}return this.parsedPos=r,new Do(Po.none,[],[],r-s)},stoppedAt:null,stopAt(){}}}}}isDone(e){e=Math.min(e,this.state.doc.length);let t=this.fragments;return this.treeLen>=e&&t.length&&0==t[0].from&&t[0].to>=e}static get(){return qa}}function Na(e,t,i){return Ko.applyChanges(e,[{fromA:t,toA:i,fromB:t,toB:i}])}class Ba{constructor(e){this.context=e,this.tree=e.tree}apply(e){if(!e.docChanged&&this.tree==this.context.tree)return this;let t=this.context.changes(e.changes,e.state),i=this.context.treeLen==e.startState.doc.length?void 0:Math.max(e.changes.mapPos(this.context.treeLen),t.viewport.to);return t.work(20,i)||t.takeTree(),new Ba(t)}static init(e){let t=Math.min(3e3,e.doc.length),i=La.create(e.facet(ja).parser,e,{from:0,to:t});return i.work(20,t)||i.takeTree(),new Ba(i)}}Ea.state=j.define({create:Ba.init,update(e,t){for(let e of t.effects)if(e.is(Ea.setState))return e.value;return t.startState.facet(ja)!=t.state.facet(ja)?Ba.init(t.state):e.apply(t)}});let $a=e=>{let t=setTimeout((()=>e()),500);return()=>clearTimeout(t)};"undefined"!=typeof requestIdleCallback&&($a=e=>{let t=-1,i=setTimeout((()=>{t=requestIdleCallback(e,{timeout:400})}),100);return()=>t<0?clearTimeout(i):cancelIdleCallback(t)});const Qa="undefined"!=typeof navigator&&(null===(Ca=navigator.scheduling)||void 0===Ca?void 0:Ca.isInputPending)?()=>navigator.scheduling.isInputPending():null,za=bi.fromClass(class{constructor(e){this.view=e,this.working=null,this.workScheduled=0,this.chunkEnd=-1,this.chunkBudget=-1,this.work=this.work.bind(this),this.scheduleWork()}update(e){let t=this.view.state.field(Ea.state).context;(t.updateViewport(e.view.viewport)||this.view.viewport.to>t.treeLen)&&this.scheduleWork(),(e.docChanged||e.selectionSet)&&(this.view.hasFocus&&(this.chunkBudget+=50),this.scheduleWork()),this.checkAsyncSchedule(t)}scheduleWork(){if(this.working)return;let{state:e}=this.view,t=e.field(Ea.state);t.tree==t.context.tree&&t.context.isDone(e.doc.length)||(this.working=$a(this.work))}work(e){this.working=null;let t=Date.now();if(this.chunkEndn+1e3,a=s.context.work((()=>Qa&&Qa()||Date.now()>r),n+(o?0:1e5));this.chunkBudget-=Date.now()-t,(a||this.chunkBudget<=0)&&(s.context.takeTree(),this.view.dispatch({effects:Ea.setState.of(new Ba(s.context))})),this.chunkBudget>0&&(!a||o)&&this.scheduleWork(),this.checkAsyncSchedule(s.context)}checkAsyncSchedule(e){e.scheduleOn&&(this.workScheduled++,e.scheduleOn.then((()=>this.scheduleWork())).catch((e=>mi(this.view.state,e))).then((()=>this.workScheduled--)),e.scheduleOn=null)}destroy(){this.working&&this.working()}isWorking(){return!!(this.working||this.workScheduled>0)}},{eventHandlers:{focus(){this.scheduleWork()}}}),ja=q.define({combine:e=>e.length?e[0]:null,enables:e=>[Ea.state,za,Ds.contentAttributes.compute([e],(t=>{let i=t.facet(e);return i&&i.name?{"data-language":i.name}:{}}))]});class Wa{constructor(e,t=[]){this.language=e,this.support=t,this.extension=[e,t]}}const Va=q.define(),Ua=q.define({combine:e=>{if(!e.length)return" ";let t=e[0];if(!t||/\S/.test(t)||Array.from(t).some((e=>e!=t[0])))throw new Error("Invalid indent unit: "+JSON.stringify(e[0]));return t}});function Fa(e){let t=e.facet(Ua);return 9==t.charCodeAt(0)?e.tabSize*t.length:t.length}function Ha(e,t){let i="",n=e.tabSize,s=e.facet(Ua)[0];if("\t"==s){for(;t>=n;)i+="\t",t-=n;s=" "}for(let e=0;e=t?function(e,t,i){let n=t.resolveStack(i),s=n.node.enterUnfinishedNodesBefore(i);if(s!=n.node){let e=[];for(let t=s;t!=n.node;t=t.parent)e.push(t);for(let t=e.length-1;t>=0;t--)n={node:e[t],next:n}}return Za(n,e,i)}(e,i,t):null}class Ya{constructor(e,t={}){this.state=e,this.options=t,this.unit=Fa(e)}lineAt(e,t=1){let i=this.state.doc.lineAt(e),{simulateBreak:n,simulateDoubleBreak:s}=this.options;return null!=n&&n>=i.from&&n<=i.to?s&&n==e?{text:"",from:e}:(t<0?n-1&&(s+=r-this.countColumn(i,i.search(/\S|$/))),s}countColumn(e,t=e.length){return Le(e,this.state.tabSize,t)}lineIndent(e,t=1){let{text:i,from:n}=this.lineAt(e,t),s=this.options.overrideIndentation;if(s){let e=s(n);if(e>-1)return e}return this.countColumn(i,i.search(/\S|$/))}get simulatedBreak(){return this.options.simulateBreak||null}}const Ga=new ko;function Za(e,t,i){for(let n=e;n;n=n.next){let e=Ka(n.node);if(e)return e(el.create(t,i,n))}return 0}function Ka(e){let t=e.type.prop(Ga);if(t)return t;let i,n=e.firstChild;if(n&&(i=n.type.prop(ko.closedBy))){let t=e.lastChild,n=t&&i.indexOf(t.name)>-1;return e=>nl(e,!0,1,void 0,n&&!function(e){return e.pos==e.options.simulateBreak&&e.options.simulateDoubleBreak}(e)?t.from:void 0)}return null==e.parent?Ja:null}function Ja(){return 0}class el extends Ya{constructor(e,t,i){super(e.state,e.options),this.base=e,this.pos=t,this.context=i}get node(){return this.context.node}static create(e,t,i){return new el(e,t,i)}get textAfter(){return this.textAfterPos(this.pos)}get baseIndent(){return this.baseIndentFor(this.node)}baseIndentFor(e){let t=this.state.doc.lineAt(e.from);for(;;){let i=e.resolve(t.from);for(;i.parent&&i.parent.from==i.from;)i=i.parent;if(tl(i,e))break;t=this.state.doc.lineAt(i.from)}return this.lineIndent(t.from)}continue(){return Za(this.context.next,this.base,this.pos)}}function tl(e,t){for(let i=t;i;i=i.parent)if(e==i)return!0;return!1}function il({closing:e,align:t=!0,units:i=1}){return n=>nl(n,t,i,e)}function nl(e,t,i,n,s){let r=e.textAfter,o=r.match(/^\s*/)[0].length,a=n&&r.slice(o,o+n.length)==n||s==e.pos+o,l=t?function(e){let t=e.node,i=t.childAfter(t.from),n=t.lastChild;if(!i)return null;let s=e.options.simulateBreak,r=e.state.doc.lineAt(i.from),o=null==s||s<=r.from?r.to:Math.min(r.to,s);for(let e=i.to;;){let s=t.childAfter(e);if(!s||s==n)return null;if(!s.type.isSkipped)return s.fromi)continue;if(s&&o.from=t&&n.to>i&&(s=n)}}return s}(e,t,i)}function ll(e,t){let i=t.mapPos(e.from,1),n=t.mapPos(e.to,-1);return i>=n?void 0:{from:i,to:n}}const hl=ae.define({map:ll}),cl=ae.define({map:ll});function dl(e){let t=[];for(let{head:i}of e.state.selection.ranges)t.some((e=>e.from<=i&&e.to>=i))||t.push(e.lineBlockAt(i));return t}const ul=j.define({create:()=>Yt.none,update(e,t){e=e.map(t.changes);for(let i of t.effects)if(i.is(hl)&&!fl(e,i.value.from,i.value.to)){let{preparePlaceholder:n}=t.state.facet(bl),s=n?Yt.replace({widget:new xl(n(t.state,i.value))}):wl;e=e.update({add:[s.range(i.value.from,i.value.to)]})}else i.is(cl)&&(e=e.update({filter:(e,t)=>i.value.from!=e||i.value.to!=t,filterFrom:i.value.from,filterTo:i.value.to}));if(t.selection){let i=!1,{head:n}=t.selection.main;e.between(n,n,((e,t)=>{en&&(i=!0)})),i&&(e=e.update({filterFrom:n,filterTo:n,filter:(e,t)=>t<=n||e>=n}))}return e},provide:e=>Ds.decorations.from(e),toJSON(e,t){let i=[];return e.between(0,t.doc.length,((e,t)=>{i.push(e,t)})),i},fromJSON(e){if(!Array.isArray(e)||e.length%2)throw new RangeError("Invalid JSON for fold state");let t=[];for(let i=0;i{(!s||s.from>e)&&(s={from:e,to:t})})),s}function fl(e,t,i){let n=!1;return e.between(t,t,((e,s)=>{e==t&&s==i&&(n=!0)})),n}function ml(e,t){return e.field(ul,!1)?t:t.concat(ae.appendConfig.of(_l()))}function gl(e,t,i=!0){let n=e.state.doc.lineAt(t.from).number,s=e.state.doc.lineAt(t.to).number;return Ds.announce.of(`${e.state.phrase(i?"Folded lines":"Unfolded lines")} ${n} ${e.state.phrase("to")} ${s}.`)}const vl=[{key:"Ctrl-Shift-[",mac:"Cmd-Alt-[",run:e=>{for(let t of dl(e)){let i=al(e.state,t.from,t.to);if(i)return e.dispatch({effects:ml(e.state,[hl.of(i),gl(e,i)])}),!0}return!1}},{key:"Ctrl-Shift-]",mac:"Cmd-Alt-]",run:e=>{if(!e.state.field(ul,!1))return!1;let t=[];for(let i of dl(e)){let n=pl(e.state,i.from,i.to);n&&t.push(cl.of(n),gl(e,n,!1))}return t.length&&e.dispatch({effects:t}),t.length>0}},{key:"Ctrl-Alt-[",run:e=>{let{state:t}=e,i=[];for(let n=0;n{let t=e.state.field(ul,!1);if(!t||!t.size)return!1;let i=[];return t.between(0,e.state.doc.length,((e,t)=>{i.push(cl.of({from:e,to:t}))})),e.dispatch({effects:i}),!0}}],Ol={placeholderDOM:null,preparePlaceholder:null,placeholderText:"…"},bl=q.define({combine:e=>be(e,Ol)});function _l(e){let t=[ul,Cl];return e&&t.push(bl.of(e)),t}function yl(e,t){let{state:i}=e,n=i.facet(bl),s=t=>{let i=e.lineBlockAt(e.posAtDOM(t.target)),n=pl(e.state,i.from,i.to);n&&e.dispatch({effects:cl.of(n)}),t.preventDefault()};if(n.placeholderDOM)return n.placeholderDOM(e,s,t);let r=document.createElement("span");return r.textContent=n.placeholderText,r.setAttribute("aria-label",i.phrase("folded code")),r.title=i.phrase("unfold"),r.className="cm-foldPlaceholder",r.onclick=s,r}const wl=Yt.replace({widget:new class extends Ht{toDOM(e){return yl(e,null)}}});class xl extends Ht{constructor(e){super(),this.value=e}eq(e){return this.value==e.value}toDOM(e){return yl(e,this.value)}}const Sl={openText:"⌄",closedText:"›",markerDOM:null,domEventHandlers:{},foldingChanged:()=>!1};class kl extends Jr{constructor(e,t){super(),this.config=e,this.open=t}eq(e){return this.config==e.config&&this.open==e.open}toDOM(e){if(this.config.markerDOM)return this.config.markerDOM(this.open);let t=document.createElement("span");return t.textContent=this.open?this.config.openText:this.config.closedText,t.title=e.state.phrase(this.open?"Fold line":"Unfold line"),t}}function Tl(e={}){let t=Object.assign(Object.assign({},Sl),e),i=new kl(t,!0),n=new kl(t,!1),s=bi.fromClass(class{constructor(e){this.from=e.viewport.from,this.markers=this.buildMarkers(e)}update(e){(e.docChanged||e.viewportChanged||e.startState.facet(ja)!=e.state.facet(ja)||e.startState.field(ul,!1)!=e.state.field(ul,!1)||Da(e.startState)!=Da(e.state)||t.foldingChanged(e))&&(this.markers=this.buildMarkers(e.view))}buildMarkers(e){let t=new ke;for(let s of e.viewportLineBlocks){let r=pl(e.state,s.from,s.to)?n:al(e.state,s.from,s.to)?i:null;r&&t.add(s.from,s.from,r)}return t.finish()}}),{domEventHandlers:r}=t;return[s,no({class:"cm-foldGutter",markers(e){var t;return(null===(t=e.plugin(s))||void 0===t?void 0:t.markers)||Se.empty},initialSpacer:()=>new kl(t,!1),domEventHandlers:Object.assign(Object.assign({},r),{click:(e,t,i)=>{if(r.click&&r.click(e,t,i))return!0;let n=pl(e.state,t.from,t.to);if(n)return e.dispatch({effects:cl.of(n)}),!0;let s=al(e.state,t.from,t.to);return!!s&&(e.dispatch({effects:hl.of(s)}),!0)}})}),_l()]}const Cl=Ds.baseTheme({".cm-foldPlaceholder":{backgroundColor:"#eee",border:"1px solid #ddd",color:"#888",borderRadius:".2em",margin:"0 1px",padding:"0 1px",cursor:"pointer"},".cm-foldGutter span":{padding:"0 1px",cursor:"pointer"}});class Pl{constructor(e,t){let i;function n(e){let t=ze.newName();return(i||(i=Object.create(null)))["."+t]=e,t}this.specs=e;const s="string"==typeof t.all?t.all:t.all?n(t.all):void 0,r=t.scope;this.scope=r instanceof Ea?e=>e.prop(Pa)==r.data:r?e=>e==r:void 0,this.style=la(e.map((e=>({tag:e.tag,class:e.class||n(Object.assign({},e,{tag:null}))}))),{all:s}).style,this.module=i?new ze(i):null,this.themeType=t.themeType}static define(e,t){return new Pl(e,t||{})}}const Ml=q.define(),El=q.define({combine:e=>e.length?[e[0]]:null});function Al(e){let t=e.facet(Ml);return t.length?t:e.facet(El)}function Rl(e,t){let i,n=[Il];return e instanceof Pl&&(e.module&&n.push(Ds.styleModule.of(e.module)),i=e.themeType),(null==t?void 0:t.fallback)?n.push(El.of(e)):i?n.push(Ml.computeN([Ds.darkTheme],(t=>t.facet(Ds.darkTheme)==("dark"==i)?[e]:[]))):n.push(Ml.of(e)),n}class Dl{constructor(e){this.markCache=Object.create(null),this.tree=Da(e.state),this.decorations=this.buildDeco(e,Al(e.state))}update(e){let t=Da(e.state),i=Al(e.state),n=i!=Al(e.startState);t.length{i.add(e,t,this.markCache[n]||(this.markCache[n]=Yt.mark({class:n})))}),n,s);return i.finish()}}const Il=V.high(bi.fromClass(Dl,{decorations:e=>e.decorations})),ql=Pl.define([{tag:Ta.meta,color:"#404740"},{tag:Ta.link,textDecoration:"underline"},{tag:Ta.heading,textDecoration:"underline",fontWeight:"bold"},{tag:Ta.emphasis,fontStyle:"italic"},{tag:Ta.strong,fontWeight:"bold"},{tag:Ta.strikethrough,textDecoration:"line-through"},{tag:Ta.keyword,color:"#708"},{tag:[Ta.atom,Ta.bool,Ta.url,Ta.contentSeparator,Ta.labelName],color:"#219"},{tag:[Ta.literal,Ta.inserted],color:"#164"},{tag:[Ta.string,Ta.deleted],color:"#a11"},{tag:[Ta.regexp,Ta.escape,Ta.special(Ta.string)],color:"#e40"},{tag:Ta.definition(Ta.variableName),color:"#00f"},{tag:Ta.local(Ta.variableName),color:"#30a"},{tag:[Ta.typeName,Ta.namespace],color:"#085"},{tag:Ta.className,color:"#167"},{tag:[Ta.special(Ta.variableName),Ta.macroName],color:"#256"},{tag:Ta.definition(Ta.propertyName),color:"#00c"},{tag:Ta.comment,color:"#940"},{tag:Ta.invalid,color:"#f00"}]),Ll=Ds.baseTheme({"&.cm-focused .cm-matchingBracket":{backgroundColor:"#328c8252"},"&.cm-focused .cm-nonmatchingBracket":{backgroundColor:"#bb555544"}}),Nl=1e4,Bl="()[]{}",$l=q.define({combine:e=>be(e,{afterCursor:!0,brackets:Bl,maxScanDistance:Nl,renderMatch:jl})}),Ql=Yt.mark({class:"cm-matchingBracket"}),zl=Yt.mark({class:"cm-nonmatchingBracket"});function jl(e){let t=[],i=e.matched?Ql:zl;return t.push(i.range(e.start.from,e.start.to)),e.end&&t.push(i.range(e.end.from,e.end.to)),t}const Wl=j.define({create:()=>Yt.none,update(e,t){if(!t.docChanged&&!t.selection)return e;let i=[],n=t.state.facet($l);for(let e of t.state.selection.ranges){if(!e.empty)continue;let s=Yl(t.state,e.head,-1,n)||e.head>0&&Yl(t.state,e.head-1,1,n)||n.afterCursor&&(Yl(t.state,e.head,1,n)||e.headDs.decorations.from(e)}),Vl=[Wl,Ll];function Ul(e={}){return[$l.of(e),Vl]}const Fl=new ko;function Hl(e,t,i){let n=e.prop(t<0?ko.openedBy:ko.closedBy);if(n)return n;if(1==e.name.length){let n=i.indexOf(e.name);if(n>-1&&n%2==(t<0?1:0))return[i[n+t]]}return null}function Xl(e){let t=e.type.prop(Fl);return t?t(e.node):e}function Yl(e,t,i,n={}){let s=n.maxScanDistance||Nl,r=n.brackets||Bl,o=Da(e),a=o.resolveInner(t,i);for(let e=a;e;e=e.parent){let n=Hl(e.type,i,r);if(n&&e.from0?t>=s.from&&ts.from&&t<=s.to))return Gl(0,0,i,e,s,n,r)}}return function(e,t,i,n,s,r,o){let a=i<0?e.sliceDoc(t-1,t):e.sliceDoc(t,t+1),l=o.indexOf(a);if(l<0||l%2==0!=i>0)return null;let h={from:i<0?t-1:t,to:i>0?t+1:t},c=e.doc.iterRange(t,i>0?e.doc.length:0),d=0;for(let e=0;!c.next().done&&e<=r;){let r=c.value;i<0&&(e+=r.length);let a=t+e*i;for(let e=i>0?0:r.length-1,t=i>0?r.length:-1;e!=t;e+=i){let t=o.indexOf(r[e]);if(!(t<0||n.resolveInner(a+e,1).type!=s))if(t%2==0==i>0)d++;else{if(1==d)return{start:h,end:{from:a+e,to:a+e+1},matched:t>>1==l>>1};d--}}i>0&&(e+=r.length)}return c.done?{start:h,matched:!1}:null}(e,t,i,o,a.type,s,r)}function Gl(e,t,i,n,s,r,o){let a=n.parent,l={from:s.from,to:s.to},h=0,c=null==a?void 0:a.cursor();if(c&&(i<0?c.childBefore(n.from):c.childAfter(n.to)))do{if(i<0?c.to<=n.from:c.from>=n.to){if(0==h&&r.indexOf(c.type.name)>-1&&c.from-1||(Jl.push(e),console.warn(t))}function ih(e,t){let i=[];for(let n of t.split(" ")){let t=[];for(let i of n.split(".")){let n=e[i]||Ta[i];n?"function"==typeof n?t.length?t=t.map(n):th(i,`Modifier ${i} used at start of tag`):t.length?th(i,`Tag ${i} used as modifier`):t=Array.isArray(n)?n:[n]:th(i,`Unknown highlighting tag ${i}`)}for(let e of t)i.push(e)}if(!i.length)return 0;let n=t.replace(/ /g,"_"),s=Po.define({id:Kl.length,name:n,props:[ra({[n]:i})]});return Kl.push(s),s.id}function nh(e,t){return({state:i,dispatch:n})=>{if(i.readOnly)return!1;let s=e(t,i);return!!s&&(n(i.update(s)),!0)}}const sh=nh(ch,0),rh=nh(hh,0),oh=nh(((e,t)=>hh(e,t,function(e){let t=[];for(let i of e.selection.ranges){let n=e.doc.lineAt(i.from),s=i.to<=n.to?n:e.doc.lineAt(i.to),r=t.length-1;r>=0&&t[r].to>n.from?t[r].to=s.to:t.push({from:n.from+/^\s*/.exec(n.text)[0].length,to:s.to})}return t}(t))),0);function ah(e,t){let i=e.languageDataAt("commentTokens",t);return i.length?i[0]:{}}const lh=50;function hh(e,t,i=t.selection.ranges){let n=i.map((e=>ah(t,e.from).block));if(!n.every((e=>e)))return null;let s=i.map(((e,i)=>function(e,{open:t,close:i},n,s){let r,o,a=e.sliceDoc(n-lh,n),l=e.sliceDoc(s,s+lh),h=/\s*$/.exec(a)[0].length,c=/^\s*/.exec(l)[0].length,d=a.length-h;if(a.slice(d-t.length,d)==t&&l.slice(c,c+i.length)==i)return{open:{pos:n-h,margin:h&&1},close:{pos:s+c,margin:c&&1}};s-n<=2*lh?r=o=e.sliceDoc(n,s):(r=e.sliceDoc(n,n+lh),o=e.sliceDoc(s-lh,s));let u=/^\s*/.exec(r)[0].length,p=/\s*$/.exec(o)[0].length,f=o.length-p-i.length;return r.slice(u,u+t.length)==t&&o.slice(f,f+i.length)==i?{open:{pos:n+u+t.length,margin:/\s/.test(r.charAt(u+t.length))?1:0},close:{pos:s-p-i.length,margin:/\s/.test(o.charAt(f-1))?1:0}}:null}(t,n[i],e.from,e.to)));if(2!=e&&!s.every((e=>e)))return{changes:t.changes(i.map(((e,t)=>s[t]?[]:[{from:e.from,insert:n[t].open+" "},{from:e.to,insert:" "+n[t].close}])))};if(1!=e&&s.some((e=>e))){let e=[];for(let t,i=0;is&&(e==r||r>l.from)){s=l.from;let e=/^\s*/.exec(l.text)[0].length,t=e==l.length,i=l.text.slice(e,e+a.length)==a?e:-1;ee.comment<0&&(!e.empty||e.single)))){let e=[];for(let{line:t,token:i,indent:s,empty:r,single:o}of n)!o&&r||e.push({from:t.from+s,insert:i+" "});let i=t.changes(e);return{changes:i,selection:t.selection.map(i,1)}}if(1!=e&&n.some((e=>e.comment>=0))){let e=[];for(let{line:t,comment:i,token:s}of n)if(i>=0){let n=t.from+i,r=n+s.length;" "==t.text[r-t.from]&&r++,e.push({from:n,to:r})}return{changes:e}}return null}const dh=se.define(),uh=se.define(),ph=q.define(),fh=q.define({combine:e=>be(e,{minDepth:100,newGroupDelay:500,joinToEvent:(e,t)=>t},{minDepth:Math.max,newGroupDelay:Math.min,joinToEvent:(e,t)=>(i,n)=>e(i,n)||t(i,n)})}),mh=j.define({create:()=>Rh.empty,update(e,t){let i=t.state.facet(fh),n=t.annotation(dh);if(n){let s=t.docChanged?R.single(function(e){let t=0;return e.iterChangedRanges(((e,i)=>t=i)),t}(t.changes)):void 0,r=wh.fromTransaction(t,s),o=n.side,a=0==o?e.undone:e.done;return a=r?xh(a,a.length,i.minDepth,r):Ch(a,t.startState.selection),new Rh(0==o?n.rest:a,0==o?a:n.rest)}let s=t.annotation(uh);if("full"!=s&&"before"!=s||(e=e.isolate()),!1===t.annotation(le.addToHistory))return t.changes.empty?e:e.addMapping(t.changes.desc);let r=wh.fromTransaction(t),o=t.annotation(le.time),a=t.annotation(le.userEvent);return r?e=e.addChanges(r,o,a,i,t):t.selection&&(e=e.addSelection(t.startState.selection,o,a,i.newGroupDelay)),"full"!=s&&"after"!=s||(e=e.isolate()),e},toJSON:e=>({done:e.done.map((e=>e.toJSON())),undone:e.undone.map((e=>e.toJSON()))}),fromJSON:e=>new Rh(e.done.map(wh.fromJSON),e.undone.map(wh.fromJSON))});function gh(e={}){return[mh,fh.of(e),Ds.domEventHandlers({beforeinput(e,t){let i="historyUndo"==e.inputType?Oh:"historyRedo"==e.inputType?bh:null;return!!i&&(e.preventDefault(),i(t))}})]}function vh(e,t){return function({state:i,dispatch:n}){if(!t&&i.readOnly)return!1;let s=i.field(mh,!1);if(!s)return!1;let r=s.pop(e,i,t);return!!r&&(n(r),!0)}}const Oh=vh(0,!1),bh=vh(1,!1),_h=vh(0,!0),yh=vh(1,!0);class wh{constructor(e,t,i,n,s){this.changes=e,this.effects=t,this.mapped=i,this.startSelection=n,this.selectionsAfter=s}setSelAfter(e){return new wh(this.changes,this.effects,this.mapped,this.startSelection,e)}toJSON(){var e,t,i;return{changes:null===(e=this.changes)||void 0===e?void 0:e.toJSON(),mapped:null===(t=this.mapped)||void 0===t?void 0:t.toJSON(),startSelection:null===(i=this.startSelection)||void 0===i?void 0:i.toJSON(),selectionsAfter:this.selectionsAfter.map((e=>e.toJSON()))}}static fromJSON(e){return new wh(e.changes&&S.fromJSON(e.changes),[],e.mapped&&x.fromJSON(e.mapped),e.startSelection&&R.fromJSON(e.startSelection),e.selectionsAfter.map(R.fromJSON))}static fromTransaction(e,t){let i=kh;for(let t of e.startState.facet(ph)){let n=t(e);n.length&&(i=i.concat(n))}return!i.length&&e.changes.empty?null:new wh(e.changes.invert(e.startState.doc),i,void 0,t||e.startState.selection,kh)}static selection(e){return new wh(void 0,kh,void 0,void 0,e)}}function xh(e,t,i,n){let s=t+1>i+20?t-i-1:0,r=e.slice(s,t);return r.push(n),r}function Sh(e,t){return e.length?t.length?e.concat(t):e:t}const kh=[],Th=200;function Ch(e,t){if(e.length){let i=e[e.length-1],n=i.selectionsAfter.slice(Math.max(0,i.selectionsAfter.length-Th));return n.length&&n[n.length-1].eq(t)?e:(n.push(t),xh(e,e.length-1,1e9,i.setSelAfter(n)))}return[wh.selection([t])]}function Ph(e){let t=e[e.length-1],i=e.slice();return i[e.length-1]=t.setSelAfter(t.selectionsAfter.slice(0,t.selectionsAfter.length-1)),i}function Mh(e,t){if(!e.length)return e;let i=e.length,n=kh;for(;i;){let s=Eh(e[i-1],t,n);if(s.changes&&!s.changes.empty||s.effects.length){let t=e.slice(0,i);return t[i-1]=s,t}t=s.mapped,i--,n=s.selectionsAfter}return n.length?[wh.selection(n)]:kh}function Eh(e,t,i){let n=Sh(e.selectionsAfter.length?e.selectionsAfter.map((e=>e.map(t))):kh,i);if(!e.changes)return wh.selection(n);let s=e.changes.map(t),r=t.mapDesc(e.changes,!0),o=e.mapped?e.mapped.composeDesc(r):r;return new wh(s,ae.mapEffects(e.effects,t),o,e.startSelection.map(r),n)}const Ah=/^(input\.type|delete)($|\.)/;class Rh{constructor(e,t,i=0,n=void 0){this.done=e,this.undone=t,this.prevTime=i,this.prevUserEvent=n}isolate(){return this.prevTime?new Rh(this.done,this.undone):this}addChanges(e,t,i,n,s){let r=this.done,o=r[r.length-1];return r=o&&o.changes&&!o.changes.empty&&e.changes&&(!i||Ah.test(i))&&(!o.selectionsAfter.length&&t-this.prevTimei.push(e,t))),t.iterChangedRanges(((e,t,s,r)=>{for(let e=0;e=t&&s<=o&&(n=!0)}})),n}(o.changes,e.changes))||"input.type.compose"==i)?xh(r,r.length-1,n.minDepth,new wh(e.changes.compose(o.changes),Sh(e.effects,o.effects),o.mapped,o.startSelection,kh)):xh(r,r.length,n.minDepth,e),new Rh(r,kh,t,i)}addSelection(e,t,i,n){let s=this.done.length?this.done[this.done.length-1].selectionsAfter:kh;return s.length>0&&t-this.prevTimee.empty!=o.ranges[t].empty)).length)?this:new Rh(Ch(this.done,e),this.undone,t,i);var r,o}addMapping(e){return new Rh(Mh(this.done,e),Mh(this.undone,e),this.prevTime,this.prevUserEvent)}pop(e,t,i){let n=0==e?this.done:this.undone;if(0==n.length)return null;let s=n[n.length-1];if(i&&s.selectionsAfter.length)return t.update({selection:s.selectionsAfter[s.selectionsAfter.length-1],annotations:dh.of({side:e,rest:Ph(n)}),userEvent:0==e?"select.undo":"select.redo",scrollIntoView:!0});if(s.changes){let i=1==n.length?kh:n.slice(0,n.length-1);return s.mapped&&(i=Mh(i,s.mapped)),t.update({changes:s.changes,selection:s.startSelection,effects:s.effects,annotations:dh.of({side:e,rest:i}),filter:!1,userEvent:0==e?"undo":"redo",scrollIntoView:!0})}return null}}Rh.empty=new Rh(kh,kh);const Dh=[{key:"Mod-z",run:Oh,preventDefault:!0},{key:"Mod-y",mac:"Mod-Shift-z",run:bh,preventDefault:!0},{linux:"Ctrl-Shift-z",run:bh,preventDefault:!0},{key:"Mod-u",run:_h,preventDefault:!0},{key:"Alt-u",mac:"Mod-Shift-u",run:yh,preventDefault:!0}];function Ih(e,t){return R.create(e.ranges.map(t),e.mainIndex)}function qh(e,t){return e.update({selection:t,scrollIntoView:!0,userEvent:"select"})}function Lh({state:e,dispatch:t},i){let n=Ih(e.selection,i);return!n.eq(e.selection)&&(t(qh(e,n)),!0)}function Nh(e,t){return R.cursor(t?e.to:e.from)}function Bh(e,t){return Lh(e,(i=>i.empty?e.moveByChar(i,t):Nh(i,t)))}function $h(e){return e.textDirectionAt(e.state.selection.main.head)==Ri.LTR}const Qh=e=>Bh(e,!$h(e)),zh=e=>Bh(e,$h(e));function jh(e,t){return Lh(e,(i=>i.empty?e.moveByGroup(i,t):Nh(i,t)))}function Wh(e,t,i){if(t.type.prop(i))return!0;let n=t.to-t.from;return n&&(n>2||/[^\s,.;:]/.test(e.sliceDoc(t.from,t.to)))||t.firstChild}function Vh(e,t,i){let n,s,r=Da(e).resolveInner(t.head),o=i?ko.closedBy:ko.openedBy;for(let n=t.head;;){let t=i?r.childAfter(n):r.childBefore(n);if(!t)break;Wh(e,t,o)?r=t:n=i?t.to:t.from}return s=r.type.prop(o)&&(n=i?Yl(e,r.from,1):Yl(e,r.to,-1))&&n.matched?i?n.end.to:n.end.from:i?r.to:r.from,R.cursor(s,i?-1:1)}function Uh(e,t){return Lh(e,(i=>{if(!i.empty)return Nh(i,t);let n=e.moveVertically(i,t);return n.head!=i.head?n:e.moveToLineBoundary(i,t)}))}"undefined"!=typeof Intl&&Intl.Segmenter;const Fh=e=>Uh(e,!1),Hh=e=>Uh(e,!0);function Xh(e){let t,i=e.scrollDOM.clientHeighti.empty?e.moveVertically(i,t,n.height):Nh(i,t)));if(r.eq(s.selection))return!1;if(n.selfScroll){let t=e.coordsAtPos(s.selection.main.head),o=e.scrollDOM.getBoundingClientRect(),a=o.top+n.marginTop,l=o.bottom-n.marginBottom;t&&t.top>a&&t.bottomYh(e,!1),Zh=e=>Yh(e,!0);function Kh(e,t,i){let n=e.lineBlockAt(t.head),s=e.moveToLineBoundary(t,i);if(s.head==t.head&&s.head!=(i?n.to:n.from)&&(s=e.moveToLineBoundary(t,i,!1)),!i&&s.head==n.from&&n.length){let i=/^\s*/.exec(e.state.sliceDoc(n.from,Math.min(n.from+100,n.to)))[0].length;i&&t.head!=n.from+i&&(s=R.cursor(n.from+i))}return s}function Jh(e,t){let i=Ih(e.state.selection,(e=>{let i=t(e);return R.range(e.anchor,i.head,i.goalColumn,i.bidiLevel||void 0)}));return!i.eq(e.state.selection)&&(e.dispatch(qh(e.state,i)),!0)}function ec(e,t){return Jh(e,(i=>e.moveByChar(i,t)))}const tc=e=>ec(e,!$h(e)),ic=e=>ec(e,$h(e));function nc(e,t){return Jh(e,(i=>e.moveByGroup(i,t)))}function sc(e,t){return Jh(e,(i=>e.moveVertically(i,t)))}const rc=e=>sc(e,!1),oc=e=>sc(e,!0);function ac(e,t){return Jh(e,(i=>e.moveVertically(i,t,Xh(e).height)))}const lc=e=>ac(e,!1),hc=e=>ac(e,!0),cc=({state:e,dispatch:t})=>(t(qh(e,{anchor:0})),!0),dc=({state:e,dispatch:t})=>(t(qh(e,{anchor:e.doc.length})),!0),uc=({state:e,dispatch:t})=>(t(qh(e,{anchor:e.selection.main.anchor,head:0})),!0),pc=({state:e,dispatch:t})=>(t(qh(e,{anchor:e.selection.main.anchor,head:e.doc.length})),!0);function fc(e,t){if(e.state.readOnly)return!1;let i="delete.selection",{state:n}=e,s=n.changeByRange((n=>{let{from:s,to:r}=n;if(s==r){let o=t(n);os&&(i="delete.forward",o=mc(e,o,!0)),s=Math.min(s,o),r=Math.max(r,o)}else s=mc(e,s,!1),r=mc(e,r,!0);return s==r?{range:n}:{changes:{from:s,to:r},range:R.cursor(s,st(e))))n.between(t,t,((e,n)=>{et&&(t=i?n:e)}));return t}const gc=(e,t)=>fc(e,(i=>{let n,s,r=i.from,{state:o}=e,a=o.doc.lineAt(r);if(!t&&r>a.from&&rgc(e,!1),Oc=e=>gc(e,!0),bc=(e,t)=>fc(e,(i=>{let n=i.head,{state:s}=e,r=s.doc.lineAt(n),o=s.charCategorizer(n);for(let e=null;;){if(n==(t?r.to:r.from)){n==i.head&&r.number!=(t?s.doc.lines:1)&&(n+=t?1:-1);break}let a=p(r.text,n-r.from,t)+r.from,l=r.text.slice(Math.min(n,a)-r.from,Math.max(n,a)-r.from),h=o(l);if(null!=e&&h!=e)break;" "==l&&n==i.head||(e=h),n=a}return n})),_c=e=>bc(e,!1);function yc(e){let t=[],i=-1;for(let n of e.selection.ranges){let s=e.doc.lineAt(n.from),r=e.doc.lineAt(n.to);if(n.empty||n.to!=r.from||(r=e.doc.lineAt(n.to-1)),i>=s.number){let e=t[t.length-1];e.to=r.to,e.ranges.push(n)}else t.push({from:s.from,to:r.to,ranges:[n]});i=r.number+1}return t}function wc(e,t,i){if(e.readOnly)return!1;let n=[],s=[];for(let t of yc(e)){if(i?t.to==e.doc.length:0==t.from)continue;let r=e.doc.lineAt(i?t.to+1:t.from-1),o=r.length+1;if(i){n.push({from:t.to,to:r.to},{from:t.from,insert:r.text+e.lineBreak});for(let i of t.ranges)s.push(R.range(Math.min(e.doc.length,i.anchor+o),Math.min(e.doc.length,i.head+o)))}else{n.push({from:r.from,to:t.from},{from:t.to,insert:e.lineBreak+r.text});for(let e of t.ranges)s.push(R.range(e.anchor-o,e.head-o))}}return!!n.length&&(t(e.update({changes:n,scrollIntoView:!0,selection:R.create(s,e.selection.mainIndex),userEvent:"move.line"})),!0)}function xc(e,t,i){if(e.readOnly)return!1;let n=[];for(let t of yc(e))i?n.push({from:t.from,insert:e.doc.slice(t.from,t.to)+e.lineBreak}):n.push({from:t.to,insert:e.lineBreak+e.doc.slice(t.from,t.to)});return t(e.update({changes:n,scrollIntoView:!0,userEvent:"input.copyline"})),!0}const Sc=kc(!1);function kc(t){return({state:i,dispatch:n})=>{if(i.readOnly)return!1;let s=i.changeByRange((n=>{let{from:s,to:r}=n,o=i.doc.lineAt(s),a=!t&&s==r&&function(e,t){if(/\(\)|\[\]|\{\}/.test(e.sliceDoc(t-1,t+1)))return{from:t,to:t};let i,n=Da(e).resolveInner(t),s=n.childBefore(t),r=n.childAfter(t);return s&&r&&s.to<=t&&r.from>=t&&(i=s.type.prop(ko.closedBy))&&i.indexOf(r.name)>-1&&e.doc.lineAt(s.to).from==e.doc.lineAt(r.from).from&&!/\S/.test(e.sliceDoc(s.to,r.from))?{from:s.to,to:r.from}:null}(i,s);t&&(s=r=(r<=o.to?o:i.doc.lineAt(r)).to);let l=new Ya(i,{simulateBreak:s,simulateDoubleBreak:!!a}),h=Xa(l,s);for(null==h&&(h=Le(/^\s*/.exec(i.doc.lineAt(s).text)[0],i.tabSize));ro.from&&s{let s=[];for(let r=n.from;r<=n.to;){let o=e.doc.lineAt(r);o.number>i&&(n.empty||n.to>o.from)&&(t(o,s,n),i=o.number),r=o.to+1}let r=e.changes(s);return{changes:s,range:R.range(r.mapPos(n.anchor,1),r.mapPos(n.head,1))}}))}const Cc=[{key:"Alt-ArrowLeft",mac:"Ctrl-ArrowLeft",run:e=>Lh(e,(t=>Vh(e.state,t,!$h(e)))),shift:e=>Jh(e,(t=>Vh(e.state,t,!$h(e))))},{key:"Alt-ArrowRight",mac:"Ctrl-ArrowRight",run:e=>Lh(e,(t=>Vh(e.state,t,$h(e)))),shift:e=>Jh(e,(t=>Vh(e.state,t,$h(e))))},{key:"Alt-ArrowUp",run:({state:e,dispatch:t})=>wc(e,t,!1)},{key:"Shift-Alt-ArrowUp",run:({state:e,dispatch:t})=>xc(e,t,!1)},{key:"Alt-ArrowDown",run:({state:e,dispatch:t})=>wc(e,t,!0)},{key:"Shift-Alt-ArrowDown",run:({state:e,dispatch:t})=>xc(e,t,!0)},{key:"Escape",run:({state:e,dispatch:t})=>{let i=e.selection,n=null;return i.ranges.length>1?n=R.create([i.main]):i.main.empty||(n=R.create([R.cursor(i.main.head)])),!!n&&(t(qh(e,n)),!0)}},{key:"Mod-Enter",run:kc(!0)},{key:"Alt-l",mac:"Ctrl-l",run:({state:e,dispatch:t})=>{let i=yc(e).map((({from:t,to:i})=>R.range(t,Math.min(i+1,e.doc.length))));return t(e.update({selection:R.create(i),userEvent:"select"})),!0}},{key:"Mod-i",run:({state:e,dispatch:t})=>{let i=Ih(e.selection,(t=>{var i;for(let n=Da(e).resolveStack(t.from,1);n;n=n.next){let{node:e}=n;if((e.from=t.to||e.to>t.to&&e.from<=t.from)&&(null===(i=e.parent)||void 0===i?void 0:i.parent))return R.range(e.to,e.from)}return t}));return t(qh(e,i)),!0},preventDefault:!0},{key:"Mod-[",run:({state:e,dispatch:t})=>!e.readOnly&&(t(e.update(Tc(e,((t,i)=>{let n=/^\s*/.exec(t.text)[0];if(!n)return;let s=Le(n,e.tabSize),r=0,o=Ha(e,Math.max(0,s-Fa(e)));for(;r!e.readOnly&&(t(e.update(Tc(e,((t,i)=>{i.push({from:t.from,insert:e.facet(Ua)})})),{userEvent:"input.indent"})),!0)},{key:"Mod-Alt-\\",run:({state:e,dispatch:t})=>{if(e.readOnly)return!1;let i=Object.create(null),n=new Ya(e,{overrideIndentation:e=>{let t=i[e];return null==t?-1:t}}),s=Tc(e,((t,s,r)=>{let o=Xa(n,t.from);if(null==o)return;/\S/.test(t.text)||(o=0);let a=/^\s*/.exec(t.text)[0],l=Ha(e,o);(a!=l||r.from{if(e.state.readOnly)return!1;let{state:t}=e,i=t.changes(yc(t).map((({from:e,to:i})=>(e>0?e--:ie.moveVertically(t,!0))).map(i);return e.dispatch({changes:i,selection:n,scrollIntoView:!0,userEvent:"delete.line"}),!0}},{key:"Shift-Mod-\\",run:({state:e,dispatch:t})=>function(e,t,i){let n=!1,s=Ih(e.selection,(t=>{let s=Yl(e,t.head,-1)||Yl(e,t.head,1)||t.head>0&&Yl(e,t.head-1,1)||t.head{let{state:t}=e,i=t.doc.lineAt(t.selection.main.from),n=ah(e.state,i.from);return n.line?sh(e):!!n.block&&oh(e)}},{key:"Alt-A",run:rh}].concat([{key:"ArrowLeft",run:Qh,shift:tc,preventDefault:!0},{key:"Mod-ArrowLeft",mac:"Alt-ArrowLeft",run:e=>jh(e,!$h(e)),shift:e=>nc(e,!$h(e)),preventDefault:!0},{mac:"Cmd-ArrowLeft",run:e=>Lh(e,(t=>Kh(e,t,!$h(e)))),shift:e=>Jh(e,(t=>Kh(e,t,!$h(e)))),preventDefault:!0},{key:"ArrowRight",run:zh,shift:ic,preventDefault:!0},{key:"Mod-ArrowRight",mac:"Alt-ArrowRight",run:e=>jh(e,$h(e)),shift:e=>nc(e,$h(e)),preventDefault:!0},{mac:"Cmd-ArrowRight",run:e=>Lh(e,(t=>Kh(e,t,$h(e)))),shift:e=>Jh(e,(t=>Kh(e,t,$h(e)))),preventDefault:!0},{key:"ArrowUp",run:Fh,shift:rc,preventDefault:!0},{mac:"Cmd-ArrowUp",run:cc,shift:uc},{mac:"Ctrl-ArrowUp",run:Gh,shift:lc},{key:"ArrowDown",run:Hh,shift:oc,preventDefault:!0},{mac:"Cmd-ArrowDown",run:dc,shift:pc},{mac:"Ctrl-ArrowDown",run:Zh,shift:hc},{key:"PageUp",run:Gh,shift:lc},{key:"PageDown",run:Zh,shift:hc},{key:"Home",run:e=>Lh(e,(t=>Kh(e,t,!1))),shift:e=>Jh(e,(t=>Kh(e,t,!1))),preventDefault:!0},{key:"Mod-Home",run:cc,shift:uc},{key:"End",run:e=>Lh(e,(t=>Kh(e,t,!0))),shift:e=>Jh(e,(t=>Kh(e,t,!0))),preventDefault:!0},{key:"Mod-End",run:dc,shift:pc},{key:"Enter",run:Sc},{key:"Mod-a",run:({state:e,dispatch:t})=>(t(e.update({selection:{anchor:0,head:e.doc.length},userEvent:"select"})),!0)},{key:"Backspace",run:vc,shift:vc},{key:"Delete",run:Oc},{key:"Mod-Backspace",mac:"Alt-Backspace",run:_c},{key:"Mod-Delete",mac:"Alt-Delete",run:e=>bc(e,!0)},{mac:"Mod-Backspace",run:e=>fc(e,(t=>{let i=e.moveToLineBoundary(t,!1).head;return t.head>i?i:Math.max(0,t.head-1)}))},{mac:"Mod-Delete",run:e=>fc(e,(t=>{let i=e.moveToLineBoundary(t,!0).head;return t.headLh(e,(t=>R.cursor(e.lineBlockAt(t.head).from,1))),shift:e=>Jh(e,(t=>R.cursor(e.lineBlockAt(t.head).from)))},{key:"Ctrl-e",run:e=>Lh(e,(t=>R.cursor(e.lineBlockAt(t.head).to,-1))),shift:e=>Jh(e,(t=>R.cursor(e.lineBlockAt(t.head).to)))},{key:"Ctrl-d",run:Oc},{key:"Ctrl-h",run:vc},{key:"Ctrl-k",run:e=>fc(e,(t=>{let i=e.lineBlockAt(t.head).to;return t.head{if(t.readOnly)return!1;let n=t.changeByRange((t=>({changes:{from:t.from,to:t.to,insert:e.of(["",""])},range:R.cursor(t.from)})));return i(t.update(n,{scrollIntoView:!0,userEvent:"input"})),!0}},{key:"Ctrl-t",run:({state:e,dispatch:t})=>{if(e.readOnly)return!1;let i=e.changeByRange((t=>{if(!t.empty||0==t.from||t.from==e.doc.length)return{range:t};let i=t.from,n=e.doc.lineAt(i),s=i==n.from?i-1:p(n.text,i-n.from,!1)+n.from,r=i==n.to?i+1:p(n.text,i-n.from,!0)+n.from;return{changes:{from:s,to:r,insert:e.doc.slice(i,r).append(e.doc.slice(s,i))},range:R.cursor(r)}}));return!i.changes.empty&&(t(e.update(i,{scrollIntoView:!0,userEvent:"move.character"})),!0)}},{key:"Ctrl-v",run:Zh}].map((e=>({mac:e.key,run:e.run,shift:e.shift})))));function Pc(){var e=arguments[0];"string"==typeof e&&(e=document.createElement(e));var t=1,i=arguments[1];if(i&&"object"==typeof i&&null==i.nodeType&&!Array.isArray(i)){for(var n in i)if(Object.prototype.hasOwnProperty.call(i,n)){var s=i[n];"string"==typeof s?e.setAttribute(n,s):null!=s&&(e[n]=s)}t++}for(;te.normalize("NFKD"):e=>e;class Ac{constructor(e,t,i=0,n=e.length,s,r){this.test=r,this.value={from:0,to:0},this.done=!1,this.matches=[],this.buffer="",this.bufferPos=0,this.iter=e.iterRange(i,n),this.bufferStart=i,this.normalize=s?e=>s(Ec(e)):Ec,this.query=this.normalize(t)}peek(){if(this.bufferPos==this.buffer.length){if(this.bufferStart+=this.buffer.length,this.iter.next(),this.iter.done)return-1;this.bufferPos=0,this.buffer=this.iter.value}return O(this.buffer,this.bufferPos)}next(){for(;this.matches.length;)this.matches.pop();return this.nextOverlapping()}nextOverlapping(){for(;;){let e=this.peek();if(e<0)return this.done=!0,this;let t=b(e),i=this.bufferStart+this.bufferPos;this.bufferPos+=_(e);let n=this.normalize(t);for(let e=0,s=i;;e++){let r=n.charCodeAt(e),o=this.match(r,s);if(e==n.length-1){if(o)return this.value=o,this;break}s==i&&ethis.to&&(this.curLine=this.curLine.slice(0,this.to-this.curLineStart)),this.iter.next())}nextLine(){this.curLineStart=this.curLineStart+this.curLine.length+1,this.curLineStart>this.to?this.curLine="":this.getLine(0)}next(){for(let e=this.matchPos-this.curLineStart;;){this.re.lastIndex=e;let t=this.matchPos<=this.to&&this.re.exec(this.curLine);if(t){let i=this.curLineStart+t.index,n=i+t[0].length;if(this.matchPos=Bc(this.text,n+(i==n?1:0)),i==this.curLineStart+this.curLine.length&&this.nextLine(),(ithis.value.to)&&(!this.test||this.test(i,n,t)))return this.value={from:i,to:n,match:t},this;e=this.matchPos-this.curLineStart}else{if(!(this.curLineStart+this.curLine.length=i||n.to<=t){let n=new Lc(t,e.sliceString(t,i));return qc.set(e,n),n}if(n.from==t&&n.to==i)return n;let{text:s,from:r}=n;return r>t&&(s=e.sliceString(t,r)+s,r=t),n.to=this.to?this.to:this.text.lineAt(e).to}next(){for(;;){let e=this.re.lastIndex=this.matchPos-this.flat.from,t=this.re.exec(this.flat.text);if(t&&!t[0]&&t.index==e&&(this.re.lastIndex=e+1,t=this.re.exec(this.flat.text)),t){let e=this.flat.from+t.index,i=e+t[0].length;if((this.flat.to>=this.to||t.index+t[0].length<=this.flat.text.length-10)&&(!this.test||this.test(e,i,t)))return this.value={from:e,to:i,match:t},this.matchPos=Bc(this.text,i+(e==i?1:0)),this}if(this.flat.to==this.to)return this.done=!0,this;this.flat=Lc.get(this.text,this.flat.from,this.chunkEnd(this.flat.from+2*this.flat.text.length))}}}function Bc(e,t){if(t>=e.length)return t;let i,n=e.lineAt(t);for(;t=56320&&i<57344;)t++;return t}function $c(e){let t=Pc("input",{class:"cm-textfield",name:"line",value:String(e.state.doc.lineAt(e.state.selection.main.head).number)});function i(){let i=/^([+-])?(\d+)?(:\d+)?(%)?$/.exec(t.value);if(!i)return;let{state:n}=e,s=n.doc.lineAt(n.selection.main.head),[,r,o,a,l]=i,h=a?+a.slice(1):0,c=o?+o:s.number;if(o&&l){let e=c/100;r&&(e=e*("-"==r?-1:1)+s.number/n.doc.lines),c=Math.round(n.doc.lines*e)}else o&&r&&(c=c*("-"==r?-1:1)+s.number);let d=n.doc.line(Math.max(1,Math.min(n.doc.lines,c))),u=R.cursor(d.from+Math.max(0,Math.min(h,d.length)));e.dispatch({effects:[Qc.of(!1),Ds.scrollIntoView(u.from,{y:"center"})],selection:u}),e.focus()}return{dom:Pc("form",{class:"cm-gotoLine",onkeydown:t=>{27==t.keyCode?(t.preventDefault(),e.dispatch({effects:Qc.of(!1)}),e.focus()):13==t.keyCode&&(t.preventDefault(),i())},onsubmit:e=>{e.preventDefault(),i()}},Pc("label",e.state.phrase("Go to line"),": ",t)," ",Pc("button",{class:"cm-button",type:"submit"},e.state.phrase("go")))}}"undefined"!=typeof Symbol&&(Ic.prototype[Symbol.iterator]=Nc.prototype[Symbol.iterator]=function(){return this});const Qc=ae.define(),zc=j.define({create:()=>!0,update(e,t){for(let i of t.effects)i.is(Qc)&&(e=i.value);return e},provide:e=>Kr.from(e,(e=>e?$c:null))}),jc=Ds.baseTheme({".cm-panel.cm-gotoLine":{padding:"2px 6px 4px","& label":{fontSize:"80%"}}}),Wc={highlightWordAroundCursor:!1,minSelectionLength:1,maxMatches:100,wholeWords:!1},Vc=q.define({combine:e=>be(e,Wc,{highlightWordAroundCursor:(e,t)=>e||t,minSelectionLength:Math.min,maxMatches:Math.min})});function Uc(e){let t=[Gc,Yc];return e&&t.push(Vc.of(e)),t}const Fc=Yt.mark({class:"cm-selectionMatch"}),Hc=Yt.mark({class:"cm-selectionMatch cm-selectionMatch-main"});function Xc(e,t,i,n){return!(0!=i&&e(t.sliceDoc(i-1,i))==me.Word||n!=t.doc.length&&e(t.sliceDoc(n,n+1))==me.Word)}const Yc=bi.fromClass(class{constructor(e){this.decorations=this.getDeco(e)}update(e){(e.selectionSet||e.docChanged||e.viewportChanged)&&(this.decorations=this.getDeco(e.view))}getDeco(e){let t=e.state.facet(Vc),{state:i}=e,n=i.selection;if(n.ranges.length>1)return Yt.none;let s,r=n.main,o=null;if(r.empty){if(!t.highlightWordAroundCursor)return Yt.none;let e=i.wordAt(r.head);if(!e)return Yt.none;o=i.charCategorizer(r.head),s=i.sliceDoc(e.from,e.to)}else{let e=r.to-r.from;if(e200)return Yt.none;if(t.wholeWords){if(s=i.sliceDoc(r.from,r.to),o=i.charCategorizer(r.head),!Xc(o,i,r.from,r.to)||!function(e,t,i,n){return e(t.sliceDoc(i,i+1))==me.Word&&e(t.sliceDoc(n-1,n))==me.Word}(o,i,r.from,r.to))return Yt.none}else if(s=i.sliceDoc(r.from,r.to).trim(),!s)return Yt.none}let a=[];for(let n of e.visibleRanges){let e=new Ac(i.doc,s,n.from,n.to);for(;!e.next().done;){let{from:n,to:s}=e.value;if((!o||Xc(o,i,n,s))&&(r.empty&&n<=r.from&&s>=r.to?a.push(Hc.range(n,s)):(n>=r.to||s<=r.from)&&a.push(Fc.range(n,s)),a.length>t.maxMatches))return Yt.none}}return Yt.set(a)}},{decorations:e=>e.decorations}),Gc=Ds.baseTheme({".cm-selectionMatch":{backgroundColor:"#99ff7780"},".cm-searchMatch .cm-selectionMatch":{backgroundColor:"transparent"}}),Zc=q.define({combine:e=>be(e,{top:!1,caseSensitive:!1,literal:!1,regexp:!1,wholeWord:!1,createPanel:e=>new Td(e),scrollToMatch:e=>Ds.scrollIntoView(e)})});class Kc{constructor(e){this.search=e.search,this.caseSensitive=!!e.caseSensitive,this.literal=!!e.literal,this.regexp=!!e.regexp,this.replace=e.replace||"",this.valid=!!this.search&&(!this.regexp||function(e){try{return new RegExp(e,Dc),!0}catch(e){return!1}}(this.search)),this.unquoted=this.unquote(this.search),this.wholeWord=!!e.wholeWord}unquote(e){return this.literal?e:e.replace(/\\([nrt\\])/g,((e,t)=>"n"==t?"\n":"r"==t?"\r":"t"==t?"\t":"\\"))}eq(e){return this.search==e.search&&this.replace==e.replace&&this.caseSensitive==e.caseSensitive&&this.regexp==e.regexp&&this.wholeWord==e.wholeWord}create(){return this.regexp?new rd(this):new td(this)}getCursor(e,t=0,i){let n=e.doc?e:Oe.create({doc:e});return null==i&&(i=n.doc.length),this.regexp?id(this,n,t,i):ed(this,n,t,i)}}class Jc{constructor(e){this.spec=e}}function ed(e,t,i,n){return new Ac(t.doc,e.unquoted,i,n,e.caseSensitive?void 0:e=>e.toLowerCase(),e.wholeWord?function(e,t){return(i,n,s,r)=>((r>i||r+s.length=t)return null;n.push(i.value)}return n}highlight(e,t,i,n){let s=ed(this.spec,e,Math.max(0,t-this.spec.unquoted.length),Math.min(i+this.spec.unquoted.length,e.doc.length));for(;!s.next().done;)n(s.value.from,s.value.to)}}function id(e,t,i,n){return new Ic(t.doc,e.search,{ignoreCase:!e.caseSensitive,test:e.wholeWord?(s=t.charCategorizer(t.selection.main.head),(e,t,i)=>!i[0].length||(s(nd(i.input,i.index))!=me.Word||s(sd(i.input,i.index))!=me.Word)&&(s(sd(i.input,i.index+i[0].length))!=me.Word||s(nd(i.input,i.index+i[0].length))!=me.Word)):void 0},i,n);var s}function nd(e,t){return e.slice(p(e,t,!1),t)}function sd(e,t){return e.slice(t,p(e,t))}class rd extends Jc{nextMatch(e,t,i){let n=id(this.spec,e,i,e.doc.length).next();return n.done&&(n=id(this.spec,e,0,t).next()),n.done?null:n.value}prevMatchInRange(e,t,i){for(let n=1;;n++){let s=Math.max(t,i-1e4*n),r=id(this.spec,e,s,i),o=null;for(;!r.next().done;)o=r.value;if(o&&(s==t||o.from>s+10))return o;if(s==t)return null}}prevMatch(e,t,i){return this.prevMatchInRange(e,0,t)||this.prevMatchInRange(e,i,e.doc.length)}getReplacement(e){return this.spec.unquote(this.spec.replace.replace(/\$([$&\d+])/g,((t,i)=>"$"==i?"$":"&"==i?e.match[0]:"0"!=i&&+i=t)return null;n.push(i.value)}return n}highlight(e,t,i,n){let s=id(this.spec,e,Math.max(0,t-250),Math.min(i+250,e.doc.length));for(;!s.next().done;)n(s.value.from,s.value.to)}}const od=ae.define(),ad=ae.define(),ld=j.define({create:e=>new hd(_d(e).create(),null),update(e,t){for(let i of t.effects)i.is(od)?e=new hd(i.value.create(),e.panel):i.is(ad)&&(e=new hd(e.query,i.value?bd:null));return e},provide:e=>Kr.from(e,(e=>e.panel))});class hd{constructor(e,t){this.query=e,this.panel=t}}const cd=Yt.mark({class:"cm-searchMatch"}),dd=Yt.mark({class:"cm-searchMatch cm-searchMatch-selected"}),ud=bi.fromClass(class{constructor(e){this.view=e,this.decorations=this.highlight(e.state.field(ld))}update(e){let t=e.state.field(ld);(t!=e.startState.field(ld)||e.docChanged||e.selectionSet||e.viewportChanged)&&(this.decorations=this.highlight(t))}highlight({query:e,panel:t}){if(!t||!e.spec.valid)return Yt.none;let{view:i}=this,n=new ke;for(let t=0,s=i.visibleRanges,r=s.length;ts[t+1].from-500;)a=s[++t].to;e.highlight(i.state,o,a,((e,t)=>{let s=i.state.selection.ranges.some((i=>i.from==e&&i.to==t));n.add(e,t,s?dd:cd)}))}return n.finish()}},{decorations:e=>e.decorations});function pd(e){return t=>{let i=t.state.field(ld,!1);return i&&i.query.spec.valid?e(t,i):xd(t)}}const fd=pd(((e,{query:t})=>{let{to:i}=e.state.selection.main,n=t.nextMatch(e.state,i,i);if(!n)return!1;let s=R.single(n.from,n.to),r=e.state.facet(Zc);return e.dispatch({selection:s,effects:[Ed(e,n),r.scrollToMatch(s.main,e)],userEvent:"select.search"}),wd(e),!0})),md=pd(((e,{query:t})=>{let{state:i}=e,{from:n}=i.selection.main,s=t.prevMatch(i,n,n);if(!s)return!1;let r=R.single(s.from,s.to),o=e.state.facet(Zc);return e.dispatch({selection:r,effects:[Ed(e,s),o.scrollToMatch(r.main,e)],userEvent:"select.search"}),wd(e),!0})),gd=pd(((e,{query:t})=>{let i=t.matchAll(e.state,1e3);return!(!i||!i.length||(e.dispatch({selection:R.create(i.map((e=>R.range(e.from,e.to)))),userEvent:"select.search.matches"}),0))})),vd=pd(((e,{query:t})=>{let{state:i}=e,{from:n,to:s}=i.selection.main;if(i.readOnly)return!1;let r=t.nextMatch(i,n,n);if(!r)return!1;let o,a,l=[],h=[];if(r.from==n&&r.to==s&&(a=i.toText(t.getReplacement(r)),l.push({from:r.from,to:r.to,insert:a}),r=t.nextMatch(i,r.from,r.to),h.push(Ds.announce.of(i.phrase("replaced match on line $",i.doc.lineAt(n).number)+"."))),r){let t=0==l.length||l[0].from>=r.to?0:r.to-r.from-a.length;o=R.single(r.from-t,r.to-t),h.push(Ed(e,r)),h.push(i.facet(Zc).scrollToMatch(o.main,e))}return e.dispatch({changes:l,selection:o,effects:h,userEvent:"input.replace"}),!0})),Od=pd(((e,{query:t})=>{if(e.state.readOnly)return!1;let i=t.matchAll(e.state,1e9).map((e=>{let{from:i,to:n}=e;return{from:i,to:n,insert:t.getReplacement(e)}}));if(!i.length)return!1;let n=e.state.phrase("replaced $ matches",i.length)+".";return e.dispatch({changes:i,effects:Ds.announce.of(n),userEvent:"input.replace.all"}),!0}));function bd(e){return e.state.facet(Zc).createPanel(e)}function _d(e,t){var i,n,s,r,o;let a=e.selection.main,l=a.empty||a.to>a.from+100?"":e.sliceDoc(a.from,a.to);if(t&&!l)return t;let h=e.facet(Zc);return new Kc({search:(null!==(i=null==t?void 0:t.literal)&&void 0!==i?i:h.literal)?l:l.replace(/\n/g,"\\n"),caseSensitive:null!==(n=null==t?void 0:t.caseSensitive)&&void 0!==n?n:h.caseSensitive,literal:null!==(s=null==t?void 0:t.literal)&&void 0!==s?s:h.literal,regexp:null!==(r=null==t?void 0:t.regexp)&&void 0!==r?r:h.regexp,wholeWord:null!==(o=null==t?void 0:t.wholeWord)&&void 0!==o?o:h.wholeWord})}function yd(e){let t=Xr(e,bd);return t&&t.dom.querySelector("[main-field]")}function wd(e){let t=yd(e);t&&t==e.root.activeElement&&t.select()}const xd=e=>{let t=e.state.field(ld,!1);if(t&&t.panel){let i=yd(e);if(i&&i!=e.root.activeElement){let n=_d(e.state,t.query.spec);n.valid&&e.dispatch({effects:od.of(n)}),i.focus(),i.select()}}else e.dispatch({effects:[ad.of(!0),t?od.of(_d(e.state,t.query.spec)):ae.appendConfig.of(Rd)]});return!0},Sd=e=>{let t=e.state.field(ld,!1);if(!t||!t.panel)return!1;let i=Xr(e,bd);return i&&i.dom.contains(e.root.activeElement)&&e.focus(),e.dispatch({effects:ad.of(!1)}),!0},kd=[{key:"Mod-f",run:xd,scope:"editor search-panel"},{key:"F3",run:fd,shift:md,scope:"editor search-panel",preventDefault:!0},{key:"Mod-g",run:fd,shift:md,scope:"editor search-panel",preventDefault:!0},{key:"Escape",run:Sd,scope:"editor search-panel"},{key:"Mod-Shift-l",run:({state:e,dispatch:t})=>{let i=e.selection;if(i.ranges.length>1||i.main.empty)return!1;let{from:n,to:s}=i.main,r=[],o=0;for(let t=new Ac(e.doc,e.sliceDoc(n,s));!t.next().done;){if(r.length>1e3)return!1;t.value.from==n&&(o=r.length),r.push(R.range(t.value.from,t.value.to))}return t(e.update({selection:R.create(r,o),userEvent:"select.search.matches"})),!0}},{key:"Alt-g",run:e=>{let t=Xr(e,$c);if(!t){let i=[Qc.of(!0)];null==e.state.field(zc,!1)&&i.push(ae.appendConfig.of([zc,jc])),e.dispatch({effects:i}),t=Xr(e,$c)}return t&&t.dom.querySelector("input").select(),!0}},{key:"Mod-d",run:({state:e,dispatch:t})=>{let{ranges:i}=e.selection;if(i.some((e=>e.from===e.to)))return(({state:e,dispatch:t})=>{let{selection:i}=e,n=R.create(i.ranges.map((t=>e.wordAt(t.head)||R.cursor(t.head))),i.mainIndex);return!n.eq(i)&&(t(e.update({selection:n})),!0)})({state:e,dispatch:t});let n=e.sliceDoc(i[0].from,i[0].to);if(e.selection.ranges.some((t=>e.sliceDoc(t.from,t.to)!=n)))return!1;let s=function(e,t){let{main:i,ranges:n}=e.selection,s=e.wordAt(i.head),r=s&&s.from==i.from&&s.to==i.to;for(let i=!1,s=new Ac(e.doc,t,n[n.length-1].to);;){if(s.next(),!s.done){if(i&&n.some((e=>e.from==s.value.from)))continue;if(r){let t=e.wordAt(s.value.from);if(!t||t.from!=s.value.from||t.to!=s.value.to)continue}return s.value}if(i)return null;s=new Ac(e.doc,t,0,Math.max(0,n[n.length-1].from-1)),i=!0}}(e,n);return!!s&&(t(e.update({selection:e.selection.addRange(R.range(s.from,s.to),!1),effects:Ds.scrollIntoView(s.to)})),!0)},preventDefault:!0}];class Td{constructor(e){this.view=e;let t=this.query=e.state.field(ld).query.spec;function i(e,t,i){return Pc("button",{class:"cm-button",name:e,onclick:t,type:"button"},i)}this.commit=this.commit.bind(this),this.searchField=Pc("input",{value:t.search,placeholder:Cd(e,"Find"),"aria-label":Cd(e,"Find"),class:"cm-textfield",name:"search",form:"","main-field":"true",onchange:this.commit,onkeyup:this.commit}),this.replaceField=Pc("input",{value:t.replace,placeholder:Cd(e,"Replace"),"aria-label":Cd(e,"Replace"),class:"cm-textfield",name:"replace",form:"",onchange:this.commit,onkeyup:this.commit}),this.caseField=Pc("input",{type:"checkbox",name:"case",form:"",checked:t.caseSensitive,onchange:this.commit}),this.reField=Pc("input",{type:"checkbox",name:"re",form:"",checked:t.regexp,onchange:this.commit}),this.wordField=Pc("input",{type:"checkbox",name:"word",form:"",checked:t.wholeWord,onchange:this.commit}),this.dom=Pc("div",{onkeydown:e=>this.keydown(e),class:"cm-search"},[this.searchField,i("next",(()=>fd(e)),[Cd(e,"next")]),i("prev",(()=>md(e)),[Cd(e,"previous")]),i("select",(()=>gd(e)),[Cd(e,"all")]),Pc("label",null,[this.caseField,Cd(e,"match case")]),Pc("label",null,[this.reField,Cd(e,"regexp")]),Pc("label",null,[this.wordField,Cd(e,"by word")]),...e.state.readOnly?[]:[Pc("br"),this.replaceField,i("replace",(()=>vd(e)),[Cd(e,"replace")]),i("replaceAll",(()=>Od(e)),[Cd(e,"replace all")])],Pc("button",{name:"close",onclick:()=>Sd(e),"aria-label":Cd(e,"close"),type:"button"},["×"])])}commit(){let e=new Kc({search:this.searchField.value,caseSensitive:this.caseField.checked,regexp:this.reField.checked,wholeWord:this.wordField.checked,replace:this.replaceField.value});e.eq(this.query)||(this.query=e,this.view.dispatch({effects:od.of(e)}))}keydown(e){var t,i;i=e,Fs(Ws((t=this.view).state),i,t,"search-panel")?e.preventDefault():13==e.keyCode&&e.target==this.searchField?(e.preventDefault(),(e.shiftKey?md:fd)(this.view)):13==e.keyCode&&e.target==this.replaceField&&(e.preventDefault(),vd(this.view))}update(e){for(let t of e.transactions)for(let e of t.effects)e.is(od)&&!e.value.eq(this.query)&&this.setQuery(e.value)}setQuery(e){this.query=e,this.searchField.value=e.search,this.replaceField.value=e.replace,this.caseField.checked=e.caseSensitive,this.reField.checked=e.regexp,this.wordField.checked=e.wholeWord}mount(){this.searchField.select()}get pos(){return 80}get top(){return this.view.state.facet(Zc).top}}function Cd(e,t){return e.state.phrase(t)}const Pd=30,Md=/[\s\.,:;?!]/;function Ed(e,{from:t,to:i}){let n=e.state.doc.lineAt(t),s=e.state.doc.lineAt(i).to,r=Math.max(n.from,t-Pd),o=Math.min(s,i+Pd),a=e.state.sliceDoc(r,o);if(r!=n.from)for(let e=0;ea.length-Pd;e--)if(!Md.test(a[e-1])&&Md.test(a[e])){a=a.slice(0,e);break}return Ds.announce.of(`${e.state.phrase("current match")}. ${a} ${e.state.phrase("on line")} ${n.number}.`)}const Ad=Ds.baseTheme({".cm-panel.cm-search":{padding:"2px 6px 4px",position:"relative","& [name=close]":{position:"absolute",top:"0",right:"4px",backgroundColor:"inherit",border:"none",font:"inherit",padding:0,margin:0},"& input, & button, & label":{margin:".2em .6em .2em 0"},"& input[type=checkbox]":{marginRight:".2em"},"& label":{fontSize:"80%",whiteSpace:"pre"}},"&light .cm-searchMatch":{backgroundColor:"#ffff0054"},"&dark .cm-searchMatch":{backgroundColor:"#00ffff8a"},"&light .cm-searchMatch-selected":{backgroundColor:"#ff6a0054"},"&dark .cm-searchMatch-selected":{backgroundColor:"#ff00ff8a"}}),Rd=[ld,V.low(ud),Ad];class Dd{constructor(e,t,i){this.state=e,this.pos=t,this.explicit=i,this.abortListeners=[]}tokenBefore(e){let t=Da(this.state).resolveInner(this.pos,-1);for(;t&&e.indexOf(t.name)<0;)t=t.parent;return t?{from:t.from,to:this.pos,text:this.state.sliceDoc(t.from,this.pos),type:t.type}:null}matchBefore(e){let t=this.state.doc.lineAt(this.pos),i=Math.max(t.from,this.pos-250),n=t.text.slice(i-t.from,this.pos-t.from),s=n.search($d(e,!1));return s<0?null:{from:i+s,to:this.pos,text:n.slice(s)}}get aborted(){return null==this.abortListeners}addEventListener(e,t){"abort"==e&&this.abortListeners&&this.abortListeners.push(t)}}function Id(e){let t=Object.keys(e).join(""),i=/\w/.test(t);return i&&(t=t.replace(/\w/g,"")),`[${i?"\\w":""}${t.replace(/[^\w\s]/g,"\\$&")}]`}function qd(e){let t=e.map((e=>"string"==typeof e?{label:e}:e)),[i,n]=t.every((e=>/^\w+$/.test(e.label)))?[/\w*$/,/\w+$/]:function(e){let t=Object.create(null),i=Object.create(null);for(let{label:n}of e){t[n[0]]=!0;for(let e=1;e{let s=e.matchBefore(n);return s||e.explicit?{from:s?s.from:e.pos,options:t,validFor:i}:null}}function Ld(e,t){return i=>{for(let t=Da(i.state).resolveInner(i.pos,-1);t;t=t.parent){if(e.indexOf(t.name)>-1)return null;if(t.type.isTop)break}return t(i)}}class Nd{constructor(e,t,i,n){this.completion=e,this.source=t,this.match=i,this.score=n}}function Bd(e){return e.selection.main.from}function $d(e,t){var i;let{source:n}=e,s=t&&"^"!=n[0],r="$"!=n[n.length-1];return s||r?new RegExp(`${s?"^":""}(?:${n})${r?"$":""}`,null!==(i=e.flags)&&void 0!==i?i:e.ignoreCase?"i":""):e}const Qd=se.define(),zd=new WeakMap;function jd(e){if(!Array.isArray(e))return e;let t=zd.get(e);return t||zd.set(e,t=qd(e)),t}const Wd=ae.define(),Vd=ae.define();class Ud{constructor(e){this.pattern=e,this.chars=[],this.folded=[],this.any=[],this.precise=[],this.byWord=[],this.score=0,this.matched=[];for(let t=0;t=48&&l<=57||l>=97&&l<=122?2:l>=65&&l<=90?1:0:(y=b(l))!=y.toLowerCase()?1:y!=y.toUpperCase()?2:0;(!n||1==w&&m||0==v&&0!=w)&&(t[c]==l||i[c]==l&&(d=!0)?r[c++]=n:r.length&&(g=!1)),v=w,n+=_(l)}return c==a&&0==r[0]&&g?this.result((d?-200:0)-100,r,e):u==a&&0==p?this.ret(-200-e.length+(f==e.length?0:-100),[0,f]):o>-1?this.ret(-700-e.length,[o,o+this.pattern.length]):u==a?this.ret(-900-e.length,[p,f]):c==a?this.result((d?-200:0)-100-700+(g?0:-1100),r,e):2!=t.length&&this.result((n[0]?-700:0)-200-1100,n,e)}result(e,t,i){let n=[],s=0;for(let e of t){let t=e+(this.astral?_(O(i,e)):1);s&&n[s-1]==e?n[s-1]=t:(n[s++]=e,n[s++]=t)}return this.ret(e-i.length,n)}}const Fd=q.define({combine:e=>be(e,{activateOnTyping:!0,selectOnOpen:!0,override:null,closeOnBlur:!0,maxRenderedOptions:100,defaultKeymap:!0,tooltipClass:()=>"",optionClass:()=>"",aboveCursor:!1,icons:!0,addToOptions:[],positionInfo:Xd,compareCompletions:(e,t)=>e.label.localeCompare(t.label),interactionDelay:75,updateSyncTime:100},{defaultKeymap:(e,t)=>e&&t,closeOnBlur:(e,t)=>e&&t,icons:(e,t)=>e&&t,tooltipClass:(e,t)=>i=>Hd(e(i),t(i)),optionClass:(e,t)=>i=>Hd(e(i),t(i)),addToOptions:(e,t)=>e.concat(t)})});function Hd(e,t){return e?t?e+" "+t:e:t}function Xd(e,t,i,n,s,r){let o,a,l=e.textDirection==Ri.RTL,h=l,c=!1,d="top",u=t.left-s.left,p=s.right-t.right,f=n.right-n.left,m=n.bottom-n.top;if(h&&u=m||e>t.top?o=i.bottom-t.top:(d="bottom",o=t.bottom-i.top)}return{style:`${d}: ${o/((t.bottom-t.top)/r.offsetHeight)}px; max-width: ${a/((t.right-t.left)/r.offsetWidth)}px`,class:"cm-completionInfo-"+(c?l?"left-narrow":"right-narrow":h?"left":"right")}}function Yd(e,t,i){if(e<=i)return{from:0,to:e};if(t<0&&(t=0),t<=e>>1){let e=Math.floor(t/i);return{from:e*i,to:(e+1)*i}}let n=Math.floor((e-t)/i);return{from:e-(n+1)*i,to:e-n*i}}class Gd{constructor(e,t,i){this.view=e,this.stateField=t,this.applyCompletion=i,this.info=null,this.infoDestroy=null,this.placeInfoReq={read:()=>this.measureInfo(),write:e=>this.placeInfo(e),key:this},this.space=null,this.currentClass="";let n=e.state.field(t),{options:s,selected:r}=n.open,o=e.state.facet(Fd);this.optionContent=function(e){let t=e.addToOptions.slice();return e.icons&&t.push({render(e){let t=document.createElement("div");return t.classList.add("cm-completionIcon"),e.type&&t.classList.add(...e.type.split(/\s+/g).map((e=>"cm-completionIcon-"+e))),t.setAttribute("aria-hidden","true"),t},position:20}),t.push({render(e,t,i){let n=document.createElement("span");n.className="cm-completionLabel";let s=e.displayLabel||e.label,r=0;for(let e=0;er&&n.appendChild(document.createTextNode(s.slice(r,t)));let a=n.appendChild(document.createElement("span"));a.appendChild(document.createTextNode(s.slice(t,o))),a.className="cm-completionMatchedText",r=o}return re.position-t.position)).map((e=>e.render))}(o),this.optionClass=o.optionClass,this.tooltipClass=o.tooltipClass,this.range=Yd(s.length,r,o.maxRenderedOptions),this.dom=document.createElement("div"),this.dom.className="cm-tooltip-autocomplete",this.updateTooltipClass(e.state),this.dom.addEventListener("mousedown",(i=>{let{options:n}=e.state.field(t).open;for(let t,s=i.target;s&&s!=this.dom;s=s.parentNode)if("LI"==s.nodeName&&(t=/-(\d+)$/.exec(s.id))&&+t[1]{let i=e.state.field(this.stateField,!1);i&&i.tooltip&&e.state.facet(Fd).closeOnBlur&&t.relatedTarget!=e.contentDOM&&e.dispatch({effects:Vd.of(null)})})),this.showOptions(s,n.id)}mount(){this.updateSel()}showOptions(e,t){this.list&&this.list.remove(),this.list=this.dom.appendChild(this.createListBox(e,t,this.range)),this.list.addEventListener("scroll",(()=>{this.info&&this.view.requestMeasure(this.placeInfoReq)}))}update(e){var t;let i=e.state.field(this.stateField),n=e.startState.field(this.stateField);if(this.updateTooltipClass(e.state),i!=n){let{options:s,selected:r,disabled:o}=i.open;n.open&&n.open.options==s||(this.range=Yd(s.length,r,e.state.facet(Fd).maxRenderedOptions),this.showOptions(s,i.id)),this.updateSel(),o!=(null===(t=n.open)||void 0===t?void 0:t.disabled)&&this.dom.classList.toggle("cm-tooltip-autocomplete-disabled",!!o)}}updateTooltipClass(e){let t=this.tooltipClass(e);if(t!=this.currentClass){for(let e of this.currentClass.split(" "))e&&this.dom.classList.remove(e);for(let e of t.split(" "))e&&this.dom.classList.add(e);this.currentClass=t}}positioned(e){this.space=e,this.info&&this.view.requestMeasure(this.placeInfoReq)}updateSel(){let e=this.view.state.field(this.stateField),t=e.open;if((t.selected>-1&&t.selected=this.range.to)&&(this.range=Yd(t.options.length,t.selected,this.view.state.facet(Fd).maxRenderedOptions),this.showOptions(t.options,e.id)),this.updateSelectedOption(t.selected)){this.destroyInfo();let{completion:i}=t.options[t.selected],{info:n}=i;if(!n)return;let s="string"==typeof n?document.createTextNode(n):n(i);if(!s)return;"then"in s?s.then((t=>{t&&this.view.state.field(this.stateField,!1)==e&&this.addInfoPane(t,i)})).catch((e=>mi(this.view.state,e,"completion info"))):this.addInfoPane(s,i)}}addInfoPane(e,t){this.destroyInfo();let i=this.info=document.createElement("div");if(i.className="cm-tooltip cm-completionInfo",null!=e.nodeType)i.appendChild(e),this.infoDestroy=null;else{let{dom:t,destroy:n}=e;i.appendChild(t),this.infoDestroy=n||null}this.dom.appendChild(i),this.view.requestMeasure(this.placeInfoReq)}updateSelectedOption(e){let t=null;for(let i=this.list.firstChild,n=this.range.from;i;i=i.nextSibling,n++)"LI"==i.nodeName&&i.id?n==e?i.hasAttribute("aria-selected")||(i.setAttribute("aria-selected","true"),t=i):i.hasAttribute("aria-selected")&&i.removeAttribute("aria-selected"):n--;return t&&function(e,t){let i=e.getBoundingClientRect(),n=t.getBoundingClientRect(),s=i.height/e.offsetHeight;n.topi.bottom&&(e.scrollTop+=(n.bottom-i.bottom)/s)}(this.list,t),t}measureInfo(){let e=this.dom.querySelector("[aria-selected]");if(!e||!this.info)return null;let t=this.dom.getBoundingClientRect(),i=this.info.getBoundingClientRect(),n=e.getBoundingClientRect(),s=this.space;if(!s){let e=this.dom.ownerDocument.defaultView||window;s={left:0,top:0,right:e.innerWidth,bottom:e.innerHeight}}return n.top>Math.min(s.bottom,t.bottom)-10||n.bottomi.from||0==i.from)&&(s=e,"string"!=typeof l&&l.header?n.appendChild(l.header(l)):n.appendChild(document.createElement("completion-section")).textContent=e)}const h=n.appendChild(document.createElement("li"));h.id=t+"-"+r,h.setAttribute("role","option");let c=this.optionClass(o);c&&(h.className=c);for(let e of this.optionContent){let t=e(o,this.view.state,a);t&&h.appendChild(t)}}return i.from&&n.classList.add("cm-completionListIncompleteTop"),i.tonew Gd(i,e,t)}function Kd(e){return 100*(e.boost||0)+(e.apply?10:0)+(e.info?5:0)+(e.type?1:0)}class Jd{constructor(e,t,i,n,s,r){this.options=e,this.attrs=t,this.tooltip=i,this.timestamp=n,this.selected=s,this.disabled=r}setSelected(e,t){return e==this.selected||e>=this.options.length?this:new Jd(this.options,iu(t,e),this.tooltip,this.timestamp,e,this.disabled)}static build(e,t,i,n,s){let r=function(e,t){let i=[],n=null,s=e=>{i.push(e);let{section:t}=e.completion;if(t){n||(n=[]);let e="string"==typeof t?t:t.name;n.some((t=>t.name==e))||n.push("string"==typeof t?{name:e}:t)}};for(let n of e)if(n.hasResult()){let e=n.result.getMatch;if(!1===n.result.filter)for(let t of n.result.options)s(new Nd(t,n.source,e?e(t):[],1e9-i.length));else{let i=new Ud(t.sliceDoc(n.from,n.to));for(let t of n.result.options)if(i.match(t.label)){let r=t.displayLabel?e?e(t,i.matched):[]:i.matched;s(new Nd(t,n.source,r,i.score+(t.boost||0)))}}}if(n){let e=Object.create(null),t=0,s=(e,t)=>{var i,n;return(null!==(i=e.rank)&&void 0!==i?i:1e9)-(null!==(n=t.rank)&&void 0!==n?n:1e9)||(e.namet.score-e.score||a(e.completion,t.completion)))){let t=e.completion;!o||o.label!=t.label||o.detail!=t.detail||null!=o.type&&null!=t.type&&o.type!=t.type||o.apply!=t.apply||o.boost!=t.boost?r.push(e):Kd(e.completion)>Kd(o)&&(r[r.length-1]=e),o=e.completion}return r}(e,t);if(!r.length)return n&&e.some((e=>1==e.state))?new Jd(n.options,n.attrs,n.tooltip,n.timestamp,n.selected,!0):null;let o=t.facet(Fd).selectOnOpen?0:-1;if(n&&n.selected!=o&&-1!=n.selected){let e=n.options[n.selected].completion;for(let t=0;tt.hasResult()?Math.min(e,t.from):e),1e8),create:du,above:s.aboveCursor},n?n.timestamp:Date.now(),o,!1)}map(e){return new Jd(this.options,this.attrs,Object.assign(Object.assign({},this.tooltip),{pos:e.mapPos(this.tooltip.pos)}),this.timestamp,this.selected,this.disabled)}}class eu{constructor(e,t,i){this.active=e,this.id=t,this.open=i}static start(){return new eu(nu,"cm-ac-"+Math.floor(2e6*Math.random()).toString(36),null)}update(e){let{state:t}=e,i=t.facet(Fd),n=(i.override||t.languageDataAt("autocomplete",Bd(t)).map(jd)).map((t=>(this.active.find((e=>e.source==t))||new ru(t,this.active.some((e=>0!=e.state))?1:0)).update(e,i)));n.length==this.active.length&&n.every(((e,t)=>e==this.active[t]))&&(n=this.active);let s=this.open;s&&e.docChanged&&(s=s.map(e.changes)),e.selection||n.some((t=>t.hasResult()&&e.changes.touchesRange(t.from,t.to)))||!function(e,t){if(e==t)return!0;for(let i=0,n=0;;){for(;i1==e.state))&&(s=null),!s&&n.every((e=>1!=e.state))&&n.some((e=>e.hasResult()))&&(n=n.map((e=>e.hasResult()?new ru(e.source,0):e)));for(let t of e.effects)t.is(lu)&&(s=s&&s.setSelected(t.value,this.id));return n==this.active&&s==this.open?this:new eu(n,this.id,s)}get tooltip(){return this.open?this.open.tooltip:null}get attrs(){return this.open?this.open.attrs:tu}}const tu={"aria-autocomplete":"list"};function iu(e,t){let i={"aria-autocomplete":"list","aria-haspopup":"listbox","aria-controls":e};return t>-1&&(i["aria-activedescendant"]=e+"-"+t),i}const nu=[];function su(e){return e.isUserEvent("input.type")?"input":e.isUserEvent("delete.backward")?"delete":null}class ru{constructor(e,t,i=-1){this.source=e,this.state=t,this.explicitPos=i}hasResult(){return!1}update(e,t){let i=su(e),n=this;i?n=n.handleUserEvent(e,i,t):e.docChanged?n=n.handleChange(e):e.selection&&0!=n.state&&(n=new ru(n.source,0));for(let t of e.effects)if(t.is(Wd))n=new ru(n.source,1,t.value?Bd(e.state):-1);else if(t.is(Vd))n=new ru(n.source,0);else if(t.is(au))for(let e of t.value)e.source==n.source&&(n=e);return n}handleUserEvent(e,t,i){return"delete"!=t&&i.activateOnTyping?new ru(this.source,1):this.map(e.changes)}handleChange(e){return e.changes.touchesRange(Bd(e.startState))?new ru(this.source,0):this.map(e.changes)}map(e){return e.empty||this.explicitPos<0?this:new ru(this.source,this.state,e.mapPos(this.explicitPos))}}class ou extends ru{constructor(e,t,i,n,s){super(e,2,t),this.result=i,this.from=n,this.to=s}hasResult(){return!0}handleUserEvent(e,t,i){var n;let s=e.changes.mapPos(this.from),r=e.changes.mapPos(this.to,1),o=Bd(e.state);if((this.explicitPos<0?o<=s:or||"delete"==t&&Bd(e.startState)==this.from)return new ru(this.source,"input"==t&&i.activateOnTyping?1:0);let a,l=this.explicitPos<0?-1:e.changes.mapPos(this.explicitPos);return function(e,t,i,n){if(!e)return!1;let s=t.sliceDoc(i,n);return"function"==typeof e?e(s,i,n,t):$d(e,!0).test(s)}(this.result.validFor,e.state,s,r)?new ou(this.source,l,this.result,s,r):this.result.update&&(a=this.result.update(this.result,s,r,new Dd(e.state,o,l>=0)))?new ou(this.source,l,a,a.from,null!==(n=a.to)&&void 0!==n?n:Bd(e.state)):new ru(this.source,1,l)}handleChange(e){return e.changes.touchesRange(this.from,this.to)?new ru(this.source,0):this.map(e.changes)}map(e){return e.empty?this:new ou(this.source,this.explicitPos<0?-1:e.mapPos(this.explicitPos),this.result,e.mapPos(this.from),e.mapPos(this.to,1))}}const au=ae.define({map:(e,t)=>e.map((e=>e.map(t)))}),lu=ae.define(),hu=j.define({create:()=>eu.start(),update:(e,t)=>e.update(t),provide:e=>[Br.from(e,(e=>e.tooltip)),Ds.contentAttributes.from(e,(e=>e.attrs))]});function cu(e,t){const i=t.completion.apply||t.completion.label;let n=e.state.field(hu).active.find((e=>e.source==t.source));return n instanceof ou&&("string"==typeof i?e.dispatch(Object.assign(Object.assign({},function(e,t,i,n){let{main:s}=e.selection,r=i-s.from,o=n-s.from;return Object.assign(Object.assign({},e.changeByRange((a=>a!=s&&i!=n&&e.sliceDoc(a.from+r,a.from+o)!=e.sliceDoc(i,n)?{range:a}:{changes:{from:a.from+r,to:n==s.from?a.to:a.from+o,insert:t},range:R.cursor(a.from+r+t.length)}))),{scrollIntoView:!0,userEvent:"input.complete"})}(e.state,i,n.from,n.to)),{annotations:Qd.of(t.completion)})):i(e,t.completion,n.from,n.to),!0)}const du=Zd(hu,cu);function uu(e,t="option"){return i=>{let n=i.state.field(hu,!1);if(!n||!n.open||n.open.disabled||Date.now()-n.open.timestamp-1?n.open.selected+r*(e?1:-1):e?0:o-1;return a<0?a="page"==t?0:o-1:a>=o&&(a="page"==t?o-1:0),i.dispatch({effects:lu.of(a)}),!0}}class pu{constructor(e,t){this.active=e,this.context=t,this.time=Date.now(),this.updates=[],this.done=void 0}}const fu=bi.fromClass(class{constructor(e){this.view=e,this.debounceUpdate=-1,this.running=[],this.debounceAccept=-1,this.composing=0;for(let t of e.state.field(hu).active)1==t.state&&this.startQuery(t)}update(e){let t=e.state.field(hu);if(!e.selectionSet&&!e.docChanged&&e.startState.field(hu)==t)return;let i=e.transactions.some((e=>(e.selection||e.docChanged)&&!su(e)));for(let t=0;t50&&Date.now()-n.time>1e3){for(let e of n.context.abortListeners)try{e()}catch(e){mi(this.view.state,e)}n.context.abortListeners=null,this.running.splice(t--,1)}else n.updates.push(...e.transactions)}if(this.debounceUpdate>-1&&clearTimeout(this.debounceUpdate),this.debounceUpdate=t.active.some((e=>1==e.state&&!this.running.some((t=>t.active.source==e.source))))?setTimeout((()=>this.startUpdate()),50):-1,0!=this.composing)for(let t of e.transactions)"input"==su(t)?this.composing=2:2==this.composing&&t.selection&&(this.composing=3)}startUpdate(){this.debounceUpdate=-1;let{state:e}=this.view,t=e.field(hu);for(let e of t.active)1!=e.state||this.running.some((t=>t.active.source==e.source))||this.startQuery(e)}startQuery(e){let{state:t}=this.view,i=Bd(t),n=new Dd(t,i,e.explicitPos==i),s=new pu(e,n);this.running.push(s),Promise.resolve(e.source(n)).then((e=>{s.context.aborted||(s.done=e||null,this.scheduleAccept())}),(e=>{this.view.dispatch({effects:Vd.of(null)}),mi(this.view.state,e)}))}scheduleAccept(){this.running.every((e=>void 0!==e.done))?this.accept():this.debounceAccept<0&&(this.debounceAccept=setTimeout((()=>this.accept()),this.view.state.facet(Fd).updateSyncTime))}accept(){var e;this.debounceAccept>-1&&clearTimeout(this.debounceAccept),this.debounceAccept=-1;let t=[],i=this.view.state.facet(Fd);for(let n=0;ne.source==s.active.source));if(r&&1==r.state)if(null==s.done){let e=new ru(s.active.source,0);for(let t of s.updates)e=e.update(t,i);1!=e.state&&t.push(e)}else this.startQuery(r)}t.length&&this.view.dispatch({effects:au.of(t)})}},{eventHandlers:{blur(e){let t=this.view.state.field(hu,!1);if(t&&t.tooltip&&this.view.state.facet(Fd).closeOnBlur){let i=t.open&&Ur(this.view,t.open.tooltip);i&&i.dom.contains(e.relatedTarget)||this.view.dispatch({effects:Vd.of(null)})}},compositionstart(){this.composing=1},compositionend(){3==this.composing&&setTimeout((()=>this.view.dispatch({effects:Wd.of(!1)})),20),this.composing=0}}}),mu=Ds.baseTheme({".cm-tooltip.cm-tooltip-autocomplete":{"& > ul":{fontFamily:"monospace",whiteSpace:"nowrap",overflow:"hidden auto",maxWidth_fallback:"700px",maxWidth:"min(700px, 95vw)",minWidth:"250px",maxHeight:"10em",height:"100%",listStyle:"none",margin:0,padding:0,"& > li, & > completion-section":{padding:"1px 3px",lineHeight:1.2},"& > li":{overflowX:"hidden",textOverflow:"ellipsis",cursor:"pointer"},"& > completion-section":{display:"list-item",borderBottom:"1px solid silver",paddingLeft:"0.5em",opacity:.7}}},"&light .cm-tooltip-autocomplete ul li[aria-selected]":{background:"#17c",color:"white"},"&light .cm-tooltip-autocomplete-disabled ul li[aria-selected]":{background:"#777"},"&dark .cm-tooltip-autocomplete ul li[aria-selected]":{background:"#347",color:"white"},"&dark .cm-tooltip-autocomplete-disabled ul li[aria-selected]":{background:"#444"},".cm-completionListIncompleteTop:before, .cm-completionListIncompleteBottom:after":{content:'"···"',opacity:.5,display:"block",textAlign:"center"},".cm-tooltip.cm-completionInfo":{position:"absolute",padding:"3px 9px",width:"max-content",maxWidth:"400px",boxSizing:"border-box"},".cm-completionInfo.cm-completionInfo-left":{right:"100%"},".cm-completionInfo.cm-completionInfo-right":{left:"100%"},".cm-completionInfo.cm-completionInfo-left-narrow":{right:"30px"},".cm-completionInfo.cm-completionInfo-right-narrow":{left:"30px"},"&light .cm-snippetField":{backgroundColor:"#00000022"},"&dark .cm-snippetField":{backgroundColor:"#ffffff22"},".cm-snippetFieldPosition":{verticalAlign:"text-top",width:0,height:"1.15em",display:"inline-block",margin:"0 -0.7px -.7em",borderLeft:"1.4px dotted #888"},".cm-completionMatchedText":{textDecoration:"underline"},".cm-completionDetail":{marginLeft:"0.5em",fontStyle:"italic"},".cm-completionIcon":{fontSize:"90%",width:".8em",display:"inline-block",textAlign:"center",paddingRight:".6em",opacity:"0.6",boxSizing:"content-box"},".cm-completionIcon-function, .cm-completionIcon-method":{"&:after":{content:"'ƒ'"}},".cm-completionIcon-class":{"&:after":{content:"'○'"}},".cm-completionIcon-interface":{"&:after":{content:"'◌'"}},".cm-completionIcon-variable":{"&:after":{content:"'𝑥'"}},".cm-completionIcon-constant":{"&:after":{content:"'𝐶'"}},".cm-completionIcon-type":{"&:after":{content:"'𝑡'"}},".cm-completionIcon-enum":{"&:after":{content:"'∪'"}},".cm-completionIcon-property":{"&:after":{content:"'□'"}},".cm-completionIcon-keyword":{"&:after":{content:"'🔑︎'"}},".cm-completionIcon-namespace":{"&:after":{content:"'▢'"}},".cm-completionIcon-text":{"&:after":{content:"'abc'",fontSize:"50%",verticalAlign:"middle"}}});class gu{constructor(e,t,i,n){this.field=e,this.line=t,this.from=i,this.to=n}}class vu{constructor(e,t,i){this.field=e,this.from=t,this.to=i}map(e){let t=e.mapPos(this.from,-1,w.TrackDel),i=e.mapPos(this.to,1,w.TrackDel);return null==t||null==i?null:new vu(this.field,t,i)}}class Ou{constructor(e,t){this.lines=e,this.fieldPositions=t}instantiate(e,t){let i=[],n=[t],s=e.doc.lineAt(t),r=/^\s*/.exec(s.text)[0];for(let s of this.lines){if(i.length){let i=r,o=/^\t*/.exec(s)[0].length;for(let t=0;tnew vu(e.field,n[e.line]+e.from,n[e.line]+e.to)));return{text:i,ranges:o}}static parse(e){let t,i=[],n=[],s=[];for(let r of e.split(/\r\n?|\n/)){for(;t=/[#$]\{(?:(\d+)(?::([^}]*))?|([^}]*))\}/.exec(r);){let e=t[1]?+t[1]:null,o=t[2]||t[3]||"",a=-1;for(let t=0;t=a&&e.field++}s.push(new gu(a,n.length,t.index,t.index+o.length)),r=r.slice(0,t.index)+o+r.slice(t.index+t[0].length)}for(let e;e=/\\([{}])/.exec(r);){r=r.slice(0,e.index)+e[1]+r.slice(e.index+e[0].length);for(let t of s)t.line==n.length&&t.from>e.index&&(t.from--,t.to--)}n.push(r)}return new Ou(n,s)}}let bu=Yt.widget({widget:new class extends Ht{toDOM(){let e=document.createElement("span");return e.className="cm-snippetFieldPosition",e}ignoreEvent(){return!1}}}),_u=Yt.mark({class:"cm-snippetField"});class yu{constructor(e,t){this.ranges=e,this.active=t,this.deco=Yt.set(e.map((e=>(e.from==e.to?bu:_u).range(e.from,e.to))))}map(e){let t=[];for(let i of this.ranges){let n=i.map(e);if(!n)return null;t.push(n)}return new yu(t,this.active)}selectionInsideField(e){return e.ranges.every((e=>this.ranges.some((t=>t.field==this.active&&t.from<=e.from&&t.to>=e.to))))}}const wu=ae.define({map:(e,t)=>e&&e.map(t)}),xu=ae.define(),Su=j.define({create:()=>null,update(e,t){for(let i of t.effects){if(i.is(wu))return i.value;if(i.is(xu)&&e)return new yu(e.ranges,i.value)}return e&&t.docChanged&&(e=e.map(t.changes)),e&&t.selection&&!e.selectionInsideField(t.selection)&&(e=null),e},provide:e=>Ds.decorations.from(e,(e=>e?e.deco:Yt.none))});function ku(e,t){return R.create(e.filter((e=>e.field==t)).map((e=>R.range(e.from,e.to))))}function Tu(t){let i=Ou.parse(t);return(t,n,s,r)=>{let{text:o,ranges:a}=i.instantiate(t.state,s),l={changes:{from:s,to:r,insert:e.of(o)},scrollIntoView:!0,annotations:n?Qd.of(n):void 0};if(a.length&&(l.selection=ku(a,0)),a.length>1){let e=new yu(a,0),i=l.effects=[wu.of(e)];void 0===t.state.field(Su,!1)&&i.push(ae.appendConfig.of([Su,Eu,Ru,mu]))}t.dispatch(t.state.update(l))}}function Cu(e){return({state:t,dispatch:i})=>{let n=t.field(Su,!1);if(!n||e<0&&0==n.active)return!1;let s=n.active+e,r=e>0&&!n.ranges.some((t=>t.field==s+e));return i(t.update({selection:ku(n.ranges,s),effects:wu.of(r?null:new yu(n.ranges,s)),scrollIntoView:!0})),!0}}const Pu=[{key:"Tab",run:Cu(1),shift:Cu(-1)},{key:"Escape",run:({state:e,dispatch:t})=>!!e.field(Su,!1)&&(t(e.update({effects:wu.of(null)})),!0)}],Mu=q.define({combine:e=>e.length?e[0]:Pu}),Eu=V.highest(zs.compute([Mu],(e=>e.facet(Mu))));function Au(e,t){return Object.assign(Object.assign({},t),{apply:Tu(e)})}const Ru=Ds.domEventHandlers({mousedown(e,t){let i,n=t.state.field(Su,!1);if(!n||null==(i=t.posAtCoords({x:e.clientX,y:e.clientY})))return!1;let s=n.ranges.find((e=>e.from<=i&&e.to>=i));return!(!s||s.field==n.active||(t.dispatch({selection:ku(n.ranges,s.field),effects:wu.of(n.ranges.some((e=>e.field>s.field))?new yu(n.ranges,s.field):null),scrollIntoView:!0}),0))}}),Du={brackets:["(","[","{","'",'"'],before:")]}:;>",stringPrefixes:[]},Iu=ae.define({map(e,t){let i=t.mapPos(e,-1,w.TrackAfter);return null==i?void 0:i}}),qu=new class extends _e{};qu.startSide=1,qu.endSide=-1;const Lu=j.define({create:()=>Se.empty,update(e,t){if(t.selection){let i=t.state.doc.lineAt(t.selection.main.head).from,n=t.startState.doc.lineAt(t.startState.selection.main.head).from;i!=t.changes.mapPos(n,-1)&&(e=Se.empty)}e=e.map(t.changes);for(let i of t.effects)i.is(Iu)&&(e=e.update({add:[qu.range(i.value,i.value+1)]}));return e}}),Nu="()[]{}<>";function Bu(e){for(let t=0;t<8;t+=2)if(Nu.charCodeAt(t)==e)return Nu.charAt(t+1);return b(e<128?e:e+1)}function $u(e,t){return e.languageDataAt("closeBrackets",t)[0]||Du}const Qu="object"==typeof navigator&&/Android\b/.test(navigator.userAgent),zu=Ds.inputHandler.of(((e,t,i,n)=>{if((Qu?e.composing:e.compositionStarted)||e.state.readOnly)return!1;let s=e.state.selection.main;if(n.length>2||2==n.length&&1==_(O(n,0))||t!=s.from||i!=s.to)return!1;let r=function(e,t){let i=$u(e,e.selection.main.head),n=i.brackets||Du.brackets;for(let s of n){let r=Bu(O(s,0));if(t==s)return r==s?Hu(e,s,n.indexOf(s+s+s)>-1,i):Uu(e,s,r,i.before||Du.before);if(t==r&&Wu(e,e.selection.main.from))return Fu(e,0,r)}return null}(e.state,n);return!!r&&(e.dispatch(r),!0)})),ju=[{key:"Backspace",run:({state:e,dispatch:t})=>{if(e.readOnly)return!1;let i=$u(e,e.selection.main.head).brackets||Du.brackets,n=null,s=e.changeByRange((t=>{if(t.empty){let n=function(e,t){let i=e.sliceString(t-2,t);return _(O(i,0))==i.length?i:i.slice(1)}(e.doc,t.head);for(let s of i)if(s==n&&Vu(e.doc,t.head)==Bu(O(s,0)))return{changes:{from:t.head-s.length,to:t.head+s.length},range:R.cursor(t.head-s.length)}}return{range:n=t}}));return n||t(e.update(s,{scrollIntoView:!0,userEvent:"delete.backward"})),!n}}];function Wu(e,t){let i=!1;return e.field(Lu).between(0,e.doc.length,(e=>{e==t&&(i=!0)})),i}function Vu(e,t){let i=e.sliceString(t,t+2);return i.slice(0,_(O(i,0)))}function Uu(e,t,i,n){let s=null,r=e.changeByRange((r=>{if(!r.empty)return{changes:[{insert:t,from:r.from},{insert:i,from:r.to}],effects:Iu.of(r.to+t.length),range:R.range(r.anchor+t.length,r.head+t.length)};let o=Vu(e.doc,r.head);return!o||/\s/.test(o)||n.indexOf(o)>-1?{changes:{insert:t+i,from:r.head},effects:Iu.of(r.head+t.length),range:R.cursor(r.head+t.length)}:{range:s=r}}));return s?null:e.update(r,{scrollIntoView:!0,userEvent:"input.type"})}function Fu(e,t,i){let n=null,s=e.changeByRange((t=>t.empty&&Vu(e.doc,t.head)==i?{changes:{from:t.head,to:t.head+i.length,insert:i},range:R.cursor(t.head+i.length)}:n={range:t}));return n?null:e.update(s,{scrollIntoView:!0,userEvent:"input.type"})}function Hu(e,t,i,n){let s=n.stringPrefixes||Du.stringPrefixes,r=null,o=e.changeByRange((n=>{if(!n.empty)return{changes:[{insert:t,from:n.from},{insert:t,from:n.to}],effects:Iu.of(n.to+t.length),range:R.range(n.anchor+t.length,n.head+t.length)};let o,a=n.head,l=Vu(e.doc,a);if(l==t){if(Xu(e,a))return{changes:{insert:t+t,from:a},effects:Iu.of(a+t.length),range:R.cursor(a+t.length)};if(Wu(e,a)){let n=i&&e.sliceDoc(a,a+3*t.length)==t+t+t?t+t+t:t;return{changes:{from:a,to:a+n.length,insert:n},range:R.cursor(a+n.length)}}}else{if(i&&e.sliceDoc(a-2*t.length,a)==t+t&&(o=Yu(e,a-2*t.length,s))>-1&&Xu(e,o))return{changes:{insert:t+t+t+t,from:a},effects:Iu.of(a+t.length),range:R.cursor(a+t.length)};if(e.charCategorizer(a)(l)!=me.Word&&Yu(e,a,s)>-1&&!function(e,t,i,n){let s=Da(e).resolveInner(t,-1),r=n.reduce(((e,t)=>Math.max(e,t.length)),0);for(let o=0;o<5;o++){let o=e.sliceDoc(s.from,Math.min(s.to,s.from+i.length+r)),a=o.indexOf(i);if(!a||a>-1&&n.indexOf(o.slice(0,a))>-1){let t=s.firstChild;for(;t&&t.from==s.from&&t.to-t.from>i.length+a;){if(e.sliceDoc(t.to-i.length,t.to)==i)return!1;t=t.firstChild}return!0}let l=s.to==t&&s.parent;if(!l)break;s=l}return!1}(e,a,t,s))return{changes:{insert:t+t,from:a},effects:Iu.of(a+t.length),range:R.cursor(a+t.length)}}return{range:r=n}}));return r?null:e.update(o,{scrollIntoView:!0,userEvent:"input.type"})}function Xu(e,t){let i=Da(e).resolveInner(t+1);return i.parent&&i.from==t}function Yu(e,t,i){let n=e.charCategorizer(t);if(n(e.sliceDoc(t-1,t))!=me.Word)return t;for(let s of i){let i=t-s.length;if(e.sliceDoc(i,t)==s&&n(e.sliceDoc(i-1,i))!=me.Word)return i}return-1}function Gu(e={}){return[hu,Fd.of(e),fu,Ku,mu]}const Zu=[{key:"Ctrl-Space",run:e=>!!e.state.field(hu,!1)&&(e.dispatch({effects:Wd.of(!0)}),!0)},{key:"Escape",run:e=>{let t=e.state.field(hu,!1);return!(!t||!t.active.some((e=>0!=e.state))||(e.dispatch({effects:Vd.of(null)}),0))}},{key:"ArrowDown",run:uu(!0)},{key:"ArrowUp",run:uu(!1)},{key:"PageDown",run:uu(!0,"page")},{key:"PageUp",run:uu(!1,"page")},{key:"Enter",run:e=>{let t=e.state.field(hu,!1);return!(e.state.readOnly||!t||!t.open||t.open.selected<0||t.open.disabled||Date.now()-t.open.timestampe.facet(Fd).defaultKeymap?[Zu]:[])));class Ju{constructor(e,t,i){this.from=e,this.to=t,this.diagnostic=i}}class ep{constructor(e,t,i){this.diagnostics=e,this.panel=t,this.selected=i}static init(e,t,i){let n=e,s=i.facet(dp).markerFilter;s&&(n=s(n));let r=Yt.set(n.map((e=>e.from==e.to||e.from==e.to-1&&i.doc.lineAt(e.from).to==e.from?Yt.widget({widget:new fp(e),diagnostic:e}).range(e.from):Yt.mark({attributes:{class:"cm-lintRange cm-lintRange-"+e.severity+(e.markClass?" "+e.markClass:"")},diagnostic:e}).range(e.from,e.to))),!0);return new ep(r,t,tp(r))}}function tp(e,t=null,i=0){let n=null;return e.between(i,1e9,((e,i,{spec:s})=>{if(!t||s.diagnostic==t)return n=new Ju(e,i,s.diagnostic),!1})),n}const ip=ae.define(),np=ae.define(),sp=ae.define(),rp=j.define({create:()=>new ep(Yt.none,null,null),update(e,t){if(t.docChanged){let i=e.diagnostics.map(t.changes),n=null;if(e.selected){let s=t.changes.mapPos(e.selected.from,1);n=tp(i,e.selected.diagnostic,s)||tp(i,null,s)}e=new ep(i,e.panel,n)}for(let i of t.effects)i.is(ip)?e=ep.init(i.value,e.panel,t.state):i.is(np)?e=new ep(e.diagnostics,i.value?gp.open:null,e.selected):i.is(sp)&&(e=new ep(e.diagnostics,e.panel,i.value));return e},provide:e=>[Kr.from(e,(e=>e.panel)),Ds.decorations.from(e,(e=>e.diagnostics))]}),op=Yt.mark({class:"cm-lintRange cm-lintRange-active"});function ap(e,t,i){let{diagnostics:n}=e.state.field(rp),s=[],r=2e8,o=0;n.between(t-(i<0?1:0),t+(i>0?1:0),((e,n,{spec:a})=>{t>=e&&t<=n&&(e==n||(t>e||i>0)&&(t({dom:lp(e,s)})}:null}function lp(e,t){return Pc("ul",{class:"cm-tooltip-lint"},t.map((t=>pp(e,t,!1))))}const hp=e=>{let t=e.state.field(rp,!1);return!(!t||!t.panel||(e.dispatch({effects:np.of(!1)}),0))},cp=[{key:"Mod-Shift-m",run:e=>{let t=e.state.field(rp,!1);var i,n;t&&t.panel||e.dispatch({effects:(i=e.state,n=[np.of(!0)],i.field(rp,!1)?n:n.concat(ae.appendConfig.of(bp)))});let s=Xr(e,gp.open);return s&&s.dom.querySelector(".cm-panel-lint ul").focus(),!0},preventDefault:!0},{key:"F8",run:e=>{let t=e.state.field(rp,!1);if(!t)return!1;let i=e.state.selection.main,n=t.diagnostics.iter(i.to+1);return!(!n.value&&(n=t.diagnostics.iter(0),!n.value||n.from==i.from&&n.to==i.to)||(e.dispatch({selection:{anchor:n.from,head:n.to},scrollIntoView:!0}),0))}}],dp=q.define({combine:e=>Object.assign({sources:e.map((e=>e.source))},be(e.map((e=>e.config)),{delay:750,markerFilter:null,tooltipFilter:null,needsRefresh:null},{needsRefresh:(e,t)=>e?t?i=>e(i)||t(i):e:t}))});function up(e){let t=[];if(e)e:for(let{name:i}of e){for(let e=0;ee.toLowerCase()==n.toLowerCase()))){t.push(n);continue e}}t.push("")}return t}function pp(e,t,i){var n;let s=i?up(t.actions):[];return Pc("li",{class:"cm-diagnostic cm-diagnostic-"+t.severity},Pc("span",{class:"cm-diagnosticText"},t.renderMessage?t.renderMessage():t.message),null===(n=t.actions)||void 0===n?void 0:n.map(((i,n)=>{let r=!1,o=n=>{if(n.preventDefault(),r)return;r=!0;let s=tp(e.state.field(rp).diagnostics,t);s&&i.apply(e,s.from,s.to)},{name:a}=i,l=s[n]?a.indexOf(s[n]):-1,h=l<0?a:[a.slice(0,l),Pc("u",a.slice(l,l+1)),a.slice(l+1)];return Pc("button",{type:"button",class:"cm-diagnosticAction",onclick:o,onmousedown:o,"aria-label":` Action: ${a}${l<0?"":` (access key "${s[n]})"`}.`},h)})),t.source&&Pc("div",{class:"cm-diagnosticSource"},t.source))}class fp extends Ht{constructor(e){super(),this.diagnostic=e}eq(e){return e.diagnostic==this.diagnostic}toDOM(){return Pc("span",{class:"cm-lintPoint cm-lintPoint-"+this.diagnostic.severity})}}class mp{constructor(e,t){this.diagnostic=t,this.id="item_"+Math.floor(4294967295*Math.random()).toString(16),this.dom=pp(e,t,!0),this.dom.id=this.id,this.dom.setAttribute("role","option")}}class gp{constructor(e){this.view=e,this.items=[],this.list=Pc("ul",{tabIndex:0,role:"listbox","aria-label":this.view.state.phrase("Diagnostics"),onkeydown:t=>{if(27==t.keyCode)hp(this.view),this.view.focus();else if(38==t.keyCode||33==t.keyCode)this.moveSelection((this.selectedIndex-1+this.items.length)%this.items.length);else if(40==t.keyCode||34==t.keyCode)this.moveSelection((this.selectedIndex+1)%this.items.length);else if(36==t.keyCode)this.moveSelection(0);else if(35==t.keyCode)this.moveSelection(this.items.length-1);else if(13==t.keyCode)this.view.focus();else{if(!(t.keyCode>=65&&t.keyCode<=90&&this.selectedIndex>=0))return;{let{diagnostic:i}=this.items[this.selectedIndex],n=up(i.actions);for(let s=0;s{for(let t=0;thp(this.view)},"×")),this.update()}get selectedIndex(){let e=this.view.state.field(rp).selected;if(!e)return-1;for(let t=0;t{let a,l=-1;for(let e=i;ei&&(this.items.splice(i,l-i),n=!0)),t&&a.diagnostic==t.diagnostic?a.dom.hasAttribute("aria-selected")||(a.dom.setAttribute("aria-selected","true"),s=a):a.dom.hasAttribute("aria-selected")&&a.dom.removeAttribute("aria-selected"),i++}));i({sel:s.dom.getBoundingClientRect(),panel:this.list.getBoundingClientRect()}),write:({sel:e,panel:t})=>{let i=t.height/this.list.offsetHeight;e.topt.bottom&&(this.list.scrollTop+=(e.bottom-t.bottom)/i)}})):this.selectedIndex<0&&this.list.removeAttribute("aria-activedescendant"),n&&this.sync()}sync(){let e=this.list.firstChild;function t(){let t=e;e=t.nextSibling,t.remove()}for(let i of this.items)if(i.dom.parentNode==this.list){for(;e!=i.dom;)t();e=i.dom.nextSibling}else this.list.insertBefore(i.dom,e);for(;e;)t()}moveSelection(e){if(this.selectedIndex<0)return;let t=tp(this.view.state.field(rp).diagnostics,this.items[e].diagnostic);t&&this.view.dispatch({selection:{anchor:t.from,head:t.to},scrollIntoView:!0,effects:sp.of(t)})}static open(e){return new gp(e)}}function vp(e){return function(e,t='viewBox="0 0 40 40"'){return`url('data:image/svg+xml,${encodeURIComponent(e)}')`}(``,'width="6" height="3"')}const Op=Ds.baseTheme({".cm-diagnostic":{padding:"3px 6px 3px 8px",marginLeft:"-1px",display:"block",whiteSpace:"pre-wrap"},".cm-diagnostic-error":{borderLeft:"5px solid #d11"},".cm-diagnostic-warning":{borderLeft:"5px solid orange"},".cm-diagnostic-info":{borderLeft:"5px solid #999"},".cm-diagnostic-hint":{borderLeft:"5px solid #66d"},".cm-diagnosticAction":{font:"inherit",border:"none",padding:"2px 4px",backgroundColor:"#444",color:"white",borderRadius:"3px",marginLeft:"8px",cursor:"pointer"},".cm-diagnosticSource":{fontSize:"70%",opacity:.7},".cm-lintRange":{backgroundPosition:"left bottom",backgroundRepeat:"repeat-x",paddingBottom:"0.7px"},".cm-lintRange-error":{backgroundImage:vp("#d11")},".cm-lintRange-warning":{backgroundImage:vp("orange")},".cm-lintRange-info":{backgroundImage:vp("#999")},".cm-lintRange-hint":{backgroundImage:vp("#66d")},".cm-lintRange-active":{backgroundColor:"#ffdd9980"},".cm-tooltip-lint":{padding:0,margin:0},".cm-lintPoint":{position:"relative","&:after":{content:'""',position:"absolute",bottom:0,left:"-2px",borderLeft:"3px solid transparent",borderRight:"3px solid transparent",borderBottom:"4px solid #d11"}},".cm-lintPoint-warning":{"&:after":{borderBottomColor:"orange"}},".cm-lintPoint-info":{"&:after":{borderBottomColor:"#999"}},".cm-lintPoint-hint":{"&:after":{borderBottomColor:"#66d"}},".cm-panel.cm-panel-lint":{position:"relative","& ul":{maxHeight:"100px",overflowY:"auto","& [aria-selected]":{backgroundColor:"#ddd","& u":{textDecoration:"underline"}},"&:focus [aria-selected]":{background_fallback:"#bdf",backgroundColor:"Highlight",color_fallback:"white",color:"HighlightText"},"& u":{textDecoration:"none"},padding:0,margin:0},"& [name=close]":{position:"absolute",top:"0",right:"2px",background:"inherit",border:"none",font:"inherit",padding:0,margin:0}}}),bp=[rp,Ds.decorations.compute([rp],(e=>{let{selected:t,panel:i}=e.field(rp);return t&&i&&t.from!=t.to?Yt.set([op.range(t.from,t.to)]):Yt.none})),Vr(ap,{hideOn:function(e,t){let i=e.startState.doc.lineAt(t.pos);return!(!e.effects.some((e=>e.is(ip)))&&!e.changes.touchesRange(i.from,i.to))}}),Op],_p=(()=>[Oo(),yo,Or(),gh(),Tl(),tr(),[hr,cr],Oe.allowMultipleSelections.of(!0),Oe.transactionFilter.of((e=>{if(!e.docChanged||!e.isUserEvent("input.type")&&!e.isUserEvent("input.complete"))return e;let t=e.startState.languageDataAt("indentOnInput",e.startState.selection.main.head);if(!t.length)return e;let i=e.newDoc,{head:n}=e.newSelection.main,s=i.lineAt(n);if(n>s.from+200)return e;let r=i.sliceString(s.from,n);if(!t.some((e=>e.test(r))))return e;let{state:o}=e,a=-1,l=[];for(let{head:e}of o.selection.ranges){let t=o.doc.lineAt(e);if(t.from==a)continue;a=t.from;let i=Xa(o,t.from);if(null==i)continue;let n=/^\s*/.exec(t.text)[0],s=Ha(o,i);n!=s&&l.push({from:t.from,to:t.from+n.length,insert:s})}return l.length?[e,{changes:l,sequential:!0}]:e})),Rl(ql,{fallback:!0}),Ul(),[zu,Lu],Gu(),Tr(),Mr(),xr,Uc(),zs.of([...ju,...Cc,...kd,...Dh,...vl,...Zu,...cp])])();class yp{constructor(e,t,i,n,s,r,o,a,l,h=0,c){this.p=e,this.stack=t,this.state=i,this.reducePos=n,this.pos=s,this.score=r,this.buffer=o,this.bufferBase=a,this.curContext=l,this.lookAhead=h,this.parent=c}toString(){return`[${this.stack.filter(((e,t)=>t%3==0)).concat(this.state)}]@${this.pos}${this.score?"!"+this.score:""}`}static start(e,t,i=0){let n=e.parser.context;return new yp(e,[],t,i,i,0,[],0,n?new wp(n,n.start):null,0,null)}get context(){return this.curContext?this.curContext.context:null}pushState(e,t){this.stack.push(this.state,t,this.bufferBase+this.buffer.length),this.state=e}reduce(e){var t;let i=e>>19,n=65535&e,{parser:s}=this.p,r=s.dynamicPrecedence(n);if(r&&(this.score+=r),0==i)return this.pushState(s.getGoto(this.state,n,!0),this.reducePos),n=2e3&&!(null===(t=this.p.parser.nodeSet.types[n])||void 0===t?void 0:t.isAnonymous)&&(a==this.p.lastBigReductionStart?(this.p.bigReductionCount++,this.p.lastBigReductionSize=l):this.p.lastBigReductionSizeo;)this.stack.pop();this.reduceContext(n,a)}storeNode(e,t,i,n=4,s=!1){if(0==e&&(!this.stack.length||this.stack[this.stack.length-1]0&&0==e.buffer[n-4]&&e.buffer[n-1]>-1){if(t==i)return;if(e.buffer[n-2]>=t)return void(e.buffer[n-2]=i)}}if(s&&this.pos!=i){let s=this.buffer.length;if(s>0&&0!=this.buffer[s-4])for(;s>0&&this.buffer[s-2]>i;)this.buffer[s]=this.buffer[s-4],this.buffer[s+1]=this.buffer[s-3],this.buffer[s+2]=this.buffer[s-2],this.buffer[s+3]=this.buffer[s-1],s-=4,n>4&&(n-=4);this.buffer[s]=e,this.buffer[s+1]=t,this.buffer[s+2]=i,this.buffer[s+3]=n}else this.buffer.push(e,t,i,n)}shift(e,t,i,n){if(131072&e)this.pushState(65535&e,this.pos);else if(0==(262144&e)){let s=e,{parser:r}=this.p;(n>this.pos||t<=r.maxNode)&&(this.pos=n,r.stateFlag(s,1)||(this.reducePos=n)),this.pushState(s,i),this.shiftContext(t,i),t<=r.maxNode&&this.buffer.push(t,i,n,4)}else this.pos=n,this.shiftContext(t,i),t<=this.p.parser.maxNode&&this.buffer.push(t,i,n,4)}apply(e,t,i,n){65536&e?this.reduce(e):this.shift(e,t,i,n)}useNode(e,t){let i=this.p.reused.length-1;(i<0||this.p.reused[i]!=e)&&(this.p.reused.push(e),i++);let n=this.pos;this.reducePos=this.pos=n+e.length,this.pushState(t,n),this.buffer.push(i,n,this.reducePos,-1),this.curContext&&this.updateContext(this.curContext.tracker.reuse(this.curContext.context,e,this,this.p.stream.reset(this.pos-e.length)))}split(){let e=this,t=e.buffer.length;for(;t>0&&e.buffer[t-2]>e.reducePos;)t-=4;let i=e.buffer.slice(t),n=e.bufferBase+t;for(;e&&n==e.bufferBase;)e=e.parent;return new yp(this.p,this.stack.slice(),this.state,this.reducePos,this.pos,this.score,i,n,this.curContext,this.lookAhead,e)}recoverByDelete(e,t){let i=e<=this.p.parser.maxNode;i&&this.storeNode(e,this.pos,t,4),this.storeNode(0,this.pos,t,i?8:4),this.pos=this.reducePos=t,this.score-=190}canShift(e){for(let t=new xp(this);;){let i=this.p.parser.stateSlot(t.state,4)||this.p.parser.hasAction(t.state,e);if(0==i)return!1;if(0==(65536&i))return!0;t.reduce(i)}}recoverByInsert(e){if(this.stack.length>=300)return[];let t=this.p.parser.nextStates(this.state);if(t.length>8||this.stack.length>=120){let i=[];for(let n,s=0;s1&t&&e==n))||i.push(t[e],n)}t=i}let i=[];for(let e=0;e>19,n=65535&t,s=this.stack.length-3*i;if(s<0||e.getGoto(this.stack[s],n,!1)<0){let e=this.findForcedReduction();if(null==e)return!1;t=e}this.storeNode(0,this.pos,this.pos,4,!0),this.score-=100}return this.reducePos=this.pos,this.reduce(t),!0}findForcedReduction(){let{parser:e}=this.p,t=[],i=(n,s)=>{if(!t.includes(n))return t.push(n),e.allActions(n,(t=>{if(393216&t);else if(65536&t){let i=(t>>19)-s;if(i>1){let n=65535&t,s=this.stack.length-3*i;if(s>=0&&e.getGoto(this.stack[s],n,!1)>=0)return i<<19|65536|n}}else{let e=i(t,s+1);if(null!=e)return e}}))};return i(this.state,0)}forceAll(){for(;!this.p.parser.stateFlag(this.state,2);)if(!this.forceReduce()){this.storeNode(0,this.pos,this.pos,4,!0);break}return this}get deadEnd(){if(3!=this.stack.length)return!1;let{parser:e}=this.p;return 65535==e.data[e.stateSlot(this.state,1)]&&!e.stateSlot(this.state,4)}restart(){this.storeNode(0,this.pos,this.pos,4,!0),this.state=this.stack[0],this.stack.length=0}sameState(e){if(this.state!=e.state||this.stack.length!=e.stack.length)return!1;for(let t=0;tthis.lookAhead&&(this.emitLookAhead(),this.lookAhead=e)}close(){this.curContext&&this.curContext.tracker.strict&&this.emitContext(),this.lookAhead>0&&this.emitLookAhead()}}class wp{constructor(e,t){this.tracker=e,this.context=t,this.hash=e.strict?e.hash(t):0}}class xp{constructor(e){this.start=e,this.state=e.state,this.stack=e.stack,this.base=this.stack.length}reduce(e){let t=65535&e,i=e>>19;0==i?(this.stack==this.start.stack&&(this.stack=this.stack.slice()),this.stack.push(this.state,0,0),this.base+=3):this.base-=3*(i-1);let n=this.start.p.parser.getGoto(this.stack[this.base-3],t,!0);this.state=n}}class Sp{constructor(e,t,i){this.stack=e,this.pos=t,this.index=i,this.buffer=e.buffer,0==this.index&&this.maybeNext()}static create(e,t=e.bufferBase+e.buffer.length){return new Sp(e,t,t-e.bufferBase)}maybeNext(){let e=this.stack.parent;null!=e&&(this.index=this.stack.bufferBase-e.bufferBase,this.stack=e,this.buffer=e.buffer)}get id(){return this.buffer[this.index-4]}get start(){return this.buffer[this.index-3]}get end(){return this.buffer[this.index-2]}get size(){return this.buffer[this.index-1]}next(){this.index-=4,this.pos-=4,0==this.index&&this.maybeNext()}fork(){return new Sp(this.stack,this.pos,this.index)}}function kp(e,t=Uint16Array){if("string"!=typeof e)return e;let i=null;for(let n=0,s=0;n=92&&t--,t>=34&&t--;let s=t-32;if(s>=46&&(s-=46,i=!0),r+=s,i)break;r*=46}i?i[s++]=r:i=new t(r)}return i}class Tp{constructor(){this.start=-1,this.value=-1,this.end=-1,this.extended=-1,this.lookAhead=0,this.mask=0,this.context=0}}const Cp=new Tp;class Pp{constructor(e,t){this.input=e,this.ranges=t,this.chunk="",this.chunkOff=0,this.chunk2="",this.chunk2Pos=0,this.next=-1,this.token=Cp,this.rangeIndex=0,this.pos=this.chunkPos=t[0].from,this.range=t[0],this.end=t[t.length-1].to,this.readNext()}resolveOffset(e,t){let i=this.range,n=this.rangeIndex,s=this.pos+e;for(;si.to:s>=i.to;){if(n==this.ranges.length-1)return null;let e=this.ranges[++n];s+=e.from-i.to,i=e}return s}clipPos(e){if(e>=this.range.from&&ee)return Math.max(e,t.from);return this.end}peek(e){let t,i,n=this.chunkOff+e;if(n>=0&&n=this.chunk2Pos&&tn.to&&(this.chunk2=this.chunk2.slice(0,n.to-t)),i=this.chunk2.charCodeAt(0)}}return t>=this.token.lookAhead&&(this.token.lookAhead=t+1),i}acceptToken(e,t=0){let i=t?this.resolveOffset(t,-1):this.pos;if(null==i||i=this.chunk2Pos&&this.posthis.range.to?e.slice(0,this.range.to-this.pos):e,this.chunkPos=this.pos,this.chunkOff=0}}readNext(){return this.chunkOff>=this.chunk.length&&(this.getChunk(),this.chunkOff==this.chunk.length)?this.next=-1:this.next=this.chunk.charCodeAt(this.chunkOff)}advance(e=1){for(this.chunkOff+=e;this.pos+e>=this.range.to;){if(this.rangeIndex==this.ranges.length-1)return this.setDone();e-=this.range.to-this.pos,this.range=this.ranges[++this.rangeIndex],this.pos=this.range.from}return this.pos+=e,this.pos>=this.token.lookAhead&&(this.token.lookAhead=this.pos+1),this.readNext()}setDone(){return this.pos=this.chunkPos=this.end,this.range=this.ranges[this.rangeIndex=this.ranges.length-1],this.chunk="",this.next=-1}reset(e,t){if(t?(this.token=t,t.start=e,t.lookAhead=e+1,t.value=t.extended=-1):this.token=Cp,this.pos!=e){if(this.pos=e,e==this.end)return this.setDone(),this;for(;e=this.range.to;)this.range=this.ranges[++this.rangeIndex];e>=this.chunkPos&&e=this.chunkPos&&t<=this.chunkPos+this.chunk.length)return this.chunk.slice(e-this.chunkPos,t-this.chunkPos);if(e>=this.chunk2Pos&&t<=this.chunk2Pos+this.chunk2.length)return this.chunk2.slice(e-this.chunk2Pos,t-this.chunk2Pos);if(e>=this.range.from&&t<=this.range.to)return this.input.read(e,t);let i="";for(let n of this.ranges){if(n.from>=t)break;n.to>e&&(i+=this.input.read(Math.max(n.from,e),Math.min(n.to,t)))}return i}}class Mp{constructor(e,t){this.data=e,this.id=t}token(e,t){let{parser:i}=t.p;!function(e,t,i,n,s,r){let o=0,a=1<0){let i=e[n];if(l.allows(i)&&(-1==t.token.value||t.token.value==i||Rp(i,t.token.value,s,r))){t.acceptToken(i);break}}let n=t.next,h=0,c=e[o+2];if(!(t.next<0&&c>h&&65535==e[i+3*c-3]&&65535==e[i+3*c-3])){for(;h>1,r=i+s+(s<<1),a=e[r],l=e[r+1]||65536;if(n=l)){o=e[r+2],t.advance();continue e}h=s+1}}break}o=e[i+3*c-1]}}(this.data,e,t,this.id,i.data,i.tokenPrecTable)}}Mp.prototype.contextual=Mp.prototype.fallback=Mp.prototype.extend=!1,Mp.prototype.fallback=Mp.prototype.extend=!1;class Ep{constructor(e,t={}){this.token=e,this.contextual=!!t.contextual,this.fallback=!!t.fallback,this.extend=!!t.extend}}function Ap(e,t,i){for(let n,s=t;65535!=(n=e[s]);s++)if(n==i)return s-t;return-1}function Rp(e,t,i,n){let s=Ap(i,n,t);return s<0||Ap(i,n,e)t)&&!n.type.isError)return i<0?Math.max(0,Math.min(n.to-1,t-25)):Math.min(e.length,Math.max(n.from+1,t+25));if(i<0?n.prevSibling():n.nextSibling())break;if(!n.parent())return i<0?0:e.length}}class Lp{constructor(e,t){this.fragments=e,this.nodeSet=t,this.i=0,this.fragment=null,this.safeFrom=-1,this.safeTo=-1,this.trees=[],this.start=[],this.index=[],this.nextFragment()}nextFragment(){let e=this.fragment=this.i==this.fragments.length?null:this.fragments[this.i++];if(e){for(this.safeFrom=e.openStart?qp(e.tree,e.from+e.offset,1)-e.offset:e.from,this.safeTo=e.openEnd?qp(e.tree,e.to+e.offset,-1)-e.offset:e.to;this.trees.length;)this.trees.pop(),this.start.pop(),this.index.pop();this.trees.push(e.tree),this.start.push(-e.offset),this.index.push(0),this.nextStart=this.safeFrom}else this.nextStart=1e9}nodeAt(e){if(ee)return this.nextStart=r,null;if(s instanceof Do){if(r==e){if(r=Math.max(this.safeFrom,e)&&(this.trees.push(s),this.start.push(r),this.index.push(0))}else this.index[t]++,this.nextStart=r+s.length}}}class Np{constructor(e,t){this.stream=t,this.tokens=[],this.mainToken=null,this.actions=[],this.tokens=e.tokenizers.map((e=>new Tp))}getActions(e){let t=0,i=null,{parser:n}=e.p,{tokenizers:s}=n,r=n.stateSlot(e.state,3),o=e.curContext?e.curContext.hash:0,a=0;for(let n=0;nh.end+25&&(a=Math.max(h.lookAhead,a)),0!=h.value)){let n=t;if(h.extended>-1&&(t=this.addActions(e,h.extended,h.end,t)),t=this.addActions(e,h.value,h.end,t),!l.extend&&(i=h,t>n))break}}for(;this.actions.length>t;)this.actions.pop();return a&&e.setLookAhead(a),i||e.pos!=this.stream.end||(i=new Tp,i.value=e.p.parser.eofTerm,i.start=i.end=e.pos,t=this.addActions(e,i.value,i.end,t)),this.mainToken=i,this.actions}getMainToken(e){if(this.mainToken)return this.mainToken;let t=new Tp,{pos:i,p:n}=e;return t.start=i,t.end=Math.min(i+1,n.stream.end),t.value=i==n.stream.end?n.parser.eofTerm:0,t}updateCachedToken(e,t,i){let n=this.stream.clipPos(i.pos);if(t.token(this.stream.reset(n,e),i),e.value>-1){let{parser:t}=i.p;for(let n=0;n=0&&i.p.parser.dialect.allows(s>>1)){0==(1&s)?e.value=s>>1:e.extended=s>>1;break}}}else e.value=0,e.end=this.stream.clipPos(n+1)}putAction(e,t,i,n){for(let t=0;t4*e.bufferLength?new Lp(i,e.nodeSet):null}get parsedPos(){return this.minStackPos}advance(){let e,t,i=this.stacks,n=this.minStackPos,s=this.stacks=[];if(this.bigReductionCount>300&&1==i.length){let[e]=i;for(;e.forceReduce()&&e.stack.length&&e.stack[e.stack.length-2]>=this.lastBigReductionStart;);this.bigReductionCount=this.lastBigReductionSize=0}for(let r=0;rn)s.push(o);else{if(this.advanceStack(o,s,i))continue;{e||(e=[],t=[]),e.push(o);let i=this.tokens.getMainToken(o);t.push(i.value,i.end)}}break}}if(!s.length){let t=e&&function(e){let t=null;for(let i of e){let e=i.p.stoppedAt;(i.pos==i.p.stream.end||null!=e&&i.pos>e)&&i.p.parser.stateFlag(i.state,2)&&(!t||t.scorethis.stoppedAt?e[0]:this.runRecovery(e,t,s);if(i)return Dp&&console.log("Force-finish "+this.stackID(i)),this.stackToTree(i.forceAll())}if(this.recovering){let e=1==this.recovering?1:3*this.recovering;if(s.length>e)for(s.sort(((e,t)=>t.score-e.score));s.length>e;)s.pop();s.some((e=>e.reducePos>n))&&this.recovering--}else if(s.length>1){e:for(let e=0;e500&&n.buffer.length>500){if(!((t.score-n.score||t.buffer.length-n.buffer.length)>0)){s.splice(e--,1);continue e}s.splice(i--,1)}}}s.length>12&&s.splice(12,s.length-12)}this.minStackPos=s[0].pos;for(let e=1;e ":"";if(null!=this.stoppedAt&&n>this.stoppedAt)return e.forceReduce()?e:null;if(this.fragments){let t=e.curContext&&e.curContext.tracker.strict,i=t?e.curContext.hash:0;for(let o=this.fragments.nodeAt(n);o;){let n=this.parser.nodeSet.types[o.type.id]==o.type?s.getGoto(e.state,o.type.id):-1;if(n>-1&&o.length&&(!t||(o.prop(ko.contextHash)||0)==i))return e.useNode(o,n),Dp&&console.log(r+this.stackID(e)+` (via reuse of ${s.getName(o.type.id)})`),!0;if(!(o instanceof Do)||0==o.children.length||o.positions[0]>0)break;let a=o.children[0];if(!(a instanceof Do&&0==o.positions[0]))break;o=a}}let o=s.stateSlot(e.state,4);if(o>0)return e.reduce(o),Dp&&console.log(r+this.stackID(e)+` (via always-reduce ${s.getName(65535&o)})`),!0;if(e.stack.length>=9e3)for(;e.stack.length>6e3&&e.forceReduce(););let a=this.tokens.getActions(e);for(let o=0;on?t.push(u):i.push(u)}return!1}advanceFully(e,t){let i=e.pos;for(;;){if(!this.advanceStack(e,null,null))return!1;if(e.pos>i)return $p(e,t),!0}}runRecovery(e,t,i){let n=null,s=!1;for(let r=0;r ":"";if(o.deadEnd){if(s)continue;if(s=!0,o.restart(),Dp&&console.log(h+this.stackID(o)+" (restarted)"),this.advanceFully(o,i))continue}let c=o.split(),d=h;for(let e=0;c.forceReduce()&&e<10&&(Dp&&console.log(d+this.stackID(c)+" (via force-reduce)"),!this.advanceFully(c,i));e++)Dp&&(d=this.stackID(c)+" -> ");for(let e of o.recoverByInsert(a))Dp&&console.log(h+this.stackID(e)+" (via recover-insert)"),this.advanceFully(e,i);this.stream.end>o.pos?(l==o.pos&&(l++,a=0),o.recoverByDelete(a,l),Dp&&console.log(h+this.stackID(o)+` (via recover-delete ${this.parser.getName(a)})`),$p(o,i)):(!n||n.scoree;class jp extends Jo{constructor(e){if(super(),this.wrappers=[],14!=e.version)throw new RangeError(`Parser version (${e.version}) doesn't match runtime version (14)`);let t=e.nodeNames.split(" ");this.minRepeatTerm=t.length;for(let i=0;ie.topRules[t][1])),n=[];for(let e=0;e=0)s(n,e,t[i++]);else{let r=t[i+-n];for(let o=-n;o>0;o--)s(t[i++],e,r);i++}}}this.nodeSet=new Mo(t.map(((t,s)=>Po.define({name:s>=this.minRepeatTerm?void 0:t,id:s,props:n[s],top:i.indexOf(s)>-1,error:0==s,skipped:e.skippedNodes&&e.skippedNodes.indexOf(s)>-1})))),e.propSources&&(this.nodeSet=this.nodeSet.extend(...e.propSources)),this.strict=!1,this.bufferLength=wo;let r=kp(e.tokenData);this.context=e.context,this.specializerSpecs=e.specialized||[],this.specialized=new Uint16Array(this.specializerSpecs.length);for(let e=0;e"number"==typeof e?new Mp(r,e):e)),this.topRules=e.topRules,this.dialects=e.dialects||{},this.dynamicPrecedences=e.dynamicPrecedences||null,this.tokenPrecTable=e.tokenPrec,this.termNames=e.termNames||null,this.maxNode=this.nodeSet.types.length-1,this.dialect=this.parseDialect(),this.top=this.topRules[Object.keys(this.topRules)[0]]}createParse(e,t,i){let n=new Bp(this,e,t,i);for(let s of this.wrappers)n=s(n,e,t,i);return n}getGoto(e,t,i=!1){let n=this.goto;if(t>=n[0])return-1;for(let s=n[t+1];;){let t=n[s++],r=1&t,o=n[s++];if(r&&i)return o;for(let i=s+(t>>1);s0}validAction(e,t){return!!this.allActions(e,(e=>e==t||null))}allActions(e,t){let i=this.stateSlot(e,4),n=i?t(i):void 0;for(let i=this.stateSlot(e,1);null==n;i+=3){if(65535==this.data[i]){if(1!=this.data[i+1])break;i=Wp(this.data,i+2)}n=t(Wp(this.data,i+1))}return n}nextStates(e){let t=[];for(let i=this.stateSlot(e,1);;i+=3){if(65535==this.data[i]){if(1!=this.data[i+1])break;i=Wp(this.data,i+2)}if(0==(1&this.data[i+2])){let e=this.data[i+1];t.some(((t,i)=>1&i&&t==e))||t.push(this.data[i],e)}}return t}configure(e){let t=Object.assign(Object.create(jp.prototype),this);if(e.props&&(t.nodeSet=this.nodeSet.extend(...e.props)),e.top){let i=this.topRules[e.top];if(!i)throw new RangeError(`Invalid top rule name ${e.top}`);t.top=i}return e.tokenizers&&(t.tokenizers=this.tokenizers.map((t=>{let i=e.tokenizers.find((e=>e.from==t));return i?i.to:t}))),e.specializers&&(t.specializers=this.specializers.slice(),t.specializerSpecs=this.specializerSpecs.map(((i,n)=>{let s=e.specializers.find((e=>e.from==i.external));if(!s)return i;let r=Object.assign(Object.assign({},i),{external:s.to});return t.specializers[n]=Vp(r),r}))),e.contextTracker&&(t.context=e.contextTracker),e.dialect&&(t.dialect=this.parseDialect(e.dialect)),null!=e.strict&&(t.strict=e.strict),e.wrap&&(t.wrappers=t.wrappers.concat(e.wrap)),null!=e.bufferLength&&(t.bufferLength=e.bufferLength),t}hasWrappers(){return this.wrappers.length>0}getName(e){return this.termNames?this.termNames[e]:String(e<=this.maxNode&&this.nodeSet.types[e].name||e)}get eofTerm(){return this.maxNode+1}get topNode(){return this.nodeSet.types[this.top[1]]}dynamicPrecedence(e){let t=this.dynamicPrecedences;return null==t?0:t[e]||0}parseDialect(e){let t=Object.keys(this.dialects),i=t.map((()=>!1));if(e)for(let n of e.split(" ")){let e=t.indexOf(n);e>=0&&(i[e]=!0)}let n=null;for(let e=0;ee.external(i,n)<<1|t}return e.get}const Up=new Set([27,51,52,270,67,133,58,59,251,64,65,74,62,63,154,155,158,115]);function Fp(e){return 10==e||13==e}const Hp=new Ep(((e,t)=>{let i;if(e.next<0)e.acceptToken(206);else if(t.context.depth<0)Fp(e.next)&&e.acceptToken(205,1);else if(((i=e.peek(-1))<0||Fp(i))&&t.canShift(204)){let t=0;for(;32==e.next||9==e.next;)e.advance(),t++;10!=e.next&&13!=e.next&&35!=e.next||e.acceptToken(204,-t)}else Fp(e.next)&&e.acceptToken(203,1)}),{contextual:!0}),Xp=new Ep(((e,t)=>{let i=t.context.depth;if(i<0)return;let n=e.peek(-1);if(10==n||13==n){let t=0,n=0;for(;;){if(32==e.next)t++;else{if(9!=e.next)break;t+=8-t%8}e.advance(),n++}t!=i&&10!=e.next&&13!=e.next&&35!=e.next&&(t0),this.strict=!1!==e.strict}}({start:Gp,reduce:(e,t)=>e.depth<0&&Up.has(t)?e.parent:e,shift:(e,t,i,n)=>201==t?new Yp(e,function(e){let t=0;for(let i=0;ie.hash}),Kp=new Ep((e=>{for(let t=0;t<5;t++){if(e.next!="print".charCodeAt(t))return;e.advance()}if(!/\w/.test(String.fromCharCode(e.next)))for(let t=0;;t++){let i=e.peek(t);if(32!=i&&9!=i)return void(40!=i&&46!=i&&10!=i&&13!=i&&35!=i&&e.acceptToken(1))}}));function Jp(e,t,i,n,s){return new Ep((r=>{let o=r.pos;for(;!(r.next<0);)if(123==r.next){if(123!=r.peek(1)){if(r.pos==o)return void r.acceptToken(n,1);break}r.advance(2)}else if(92==r.next)r.advance(),r.next>=0&&r.advance();else{if(r.next==e&&(1==t||r.peek(1)==e&&r.peek(2)==e)){if(r.pos==o)return void r.acceptToken(s,t);break}r.advance()}r.pos>o&&r.acceptToken(i)}))}const ef=Jp(39,1,207,2,208),tf=Jp(34,1,209,3,210),nf=Jp(39,3,211,4,212),sf=Jp(34,3,213,5,214),rf=ra({'async "*" "**" FormatConversion FormatSpec':Ta.modifier,"for while if elif else try except finally return raise break continue with pass assert await yield match case":Ta.controlKeyword,"in not and or is del":Ta.operatorKeyword,"from def class global nonlocal lambda":Ta.definitionKeyword,import:Ta.moduleKeyword,"with as print":Ta.keyword,Boolean:Ta.bool,None:Ta.null,VariableName:Ta.variableName,"CallExpression/VariableName":Ta.function(Ta.variableName),"FunctionDefinition/VariableName":Ta.function(Ta.definition(Ta.variableName)),"ClassDefinition/VariableName":Ta.definition(Ta.className),PropertyName:Ta.propertyName,"CallExpression/MemberExpression/PropertyName":Ta.function(Ta.propertyName),Comment:Ta.lineComment,Number:Ta.number,String:Ta.string,FormatString:Ta.special(Ta.string),UpdateOp:Ta.updateOperator,"ArithOp!":Ta.arithmeticOperator,BitOp:Ta.bitwiseOperator,CompareOp:Ta.compareOperator,AssignOp:Ta.definitionOperator,Ellipsis:Ta.punctuation,At:Ta.meta,"( )":Ta.paren,"[ ]":Ta.squareBracket,"{ }":Ta.brace,".":Ta.derefOperator,", ;":Ta.separator}),of={__proto__:null,await:48,or:58,and:60,in:64,not:66,is:68,if:74,else:76,lambda:80,yield:98,from:100,async:106,for:108,None:168,True:170,False:170,del:184,pass:188,break:192,continue:196,return:200,raise:208,import:212,as:214,global:218,nonlocal:220,assert:224,type:229,elif:242,while:246,try:252,except:254,finally:256,with:260,def:264,class:274,match:285,case:291},af=jp.deserialize({version:14,states:"#&jO`Q#yOOP$bOSOOO%kQ&nO'#HcOOQS'#Cq'#CqOOQS'#Cr'#CrO'ZQ#xO'#CpO(|Q&nO'#HbOOQS'#Hc'#HcOOQS'#DW'#DWOOQS'#Hb'#HbO)jQ#xO'#DaO)}Q#xO'#DhO*_Q#xO'#DlOOQS'#Dw'#DwO*rO,UO'#DwO*zO7[O'#DwO+SOWO'#DxO+_O`O'#DxO+jOpO'#DxO+uO!bO'#DxO-wQ&nO'#HSOOQS'#HS'#HSO'ZQ#xO'#HRO/ZQ&nO'#HROOQS'#Ee'#EeO/rQ#xO'#EfOOQS'#HQ'#HQO/|Q#xO'#HPOOQV'#HP'#HPO0XQ#xO'#F]OOQS'#Ge'#GeO0^Q#xO'#F[OOQV'#IY'#IYOOQV'#HO'#HOOOQV'#Ft'#FtQ`Q#yOOO'ZQ#xO'#CsO0lQ#xO'#DPO0sQ#xO'#DTO1RQ#xO'#HgO1cQ&nO'#EYO'ZQ#xO'#EZOOQS'#E]'#E]OOQS'#E_'#E_OOQS'#Ea'#EaO1wQ#xO'#EcO2_Q#xO'#EgO0XQ#xO'#EiO2rQ&nO'#EiO0XQ#xO'#ElO/rQ#xO'#EoO0XQ#xO'#EqO/rQ#xO'#EwO/rQ#xO'#EzO2}Q#xO'#E|O3UQ#xO'#FRO3aQ#xO'#E}O/rQ#xO'#FRO0XQ#xO'#FTO0XQ#xO'#FYO3fQ#xO'#F_P3mO#xO'#G}POOO)CBq)CBqOOQS'#Cg'#CgOOQS'#Ch'#ChOOQS'#Ci'#CiOOQS'#Cj'#CjOOQS'#Ck'#CkOOQS'#Cl'#ClOOQS'#Cn'#CnO'ZQ#xO,59QO'ZQ#xO,59QO'ZQ#xO,59QO'ZQ#xO,59QO'ZQ#xO,59QO'ZQ#xO,59QO3xQ#xO'#DqOOQS,5:[,5:[O4]Q#xO'#HqOOQS,5:_,5:_O4jQMlO,5:_O4oQ&nO,59[O0lQ#xO,59dO0lQ#xO,59dO0lQ#xO,59dO7_Q#xO,59dO7dQ#xO,59dO7kQ#xO,59lO7rQ#xO'#HbO8xQ#xO'#HaOOQS'#Ha'#HaOOQS'#D^'#D^O9aQ#xO,59cO'ZQ#xO,59cO9oQ#xO,59cOOQS,59{,59{O9tQ#xO,5:TO'ZQ#xO,5:TOOQS,5:S,5:SO:SQ#xO,5:SO:XQ#xO,5:ZO'ZQ#xO,5:ZO'ZQ#xO,5:XOOQS,5:W,5:WO:jQ#xO,5:WO:oQ#xO,5:YOOOO'#F|'#F|O:tO,UO,5:cOOQS,5:c,5:cOOOO'#F}'#F}O:|O7[O,5:cO;UQ#xO'#DyOOOW'#GO'#GOO;fOWO,5:dOOQS,5:d,5:dO;UQ#xO'#D}OOO`'#GR'#GRO;qO`O,5:dO;UQ#xO'#EOOOOp'#GS'#GSO;|OpO,5:dO;UQ#xO'#EPOOO!b'#GT'#GTOROOQS,5>R,5>RO/rQ#xO'#EUOOQS'#EV'#EVOGZQ#xO'#GWOGkQ#xO,59OOGkQ#xO,59OO)pQ#xO,5:rOGyQ&nO'#HjOOQS,5:u,5:uOOQS,5:},5:}OH^Q#xO,5;ROHoQ#xO,5;TOOQS'#GZ'#GZOH}Q&nO,5;TOI]Q#xO,5;TOIbQ#xO'#IWOOQS,5;W,5;WOIpQ#xO'#ISOOQS,5;Z,5;ZOJRQ#xO,5;]O3aQ#xO,5;cO3aQ#xO,5;fOJZQ&nO'#IZO'ZQ#xO'#IZOJeQ#xO,5;hO2}Q#xO,5;hO/rQ#xO,5;mO0XQ#xO,5;oOJjQ#yO'#ExOKvQ#{O,5;iO! [Q#xO'#I[O3aQ#xO,5;mO! gQ#xO,5;oO! oQ#xO,5;tO! zQ&nO,5;yO'ZQ#xO,5;yPOOO,5=i,5=iP!!ROSO,5=iP!!WO#xO,5=iO!${Q&nO1G.lO!%SQ&nO1G.lO!'sQ&nO1G.lO!'}Q&nO1G.lO!*hQ&nO1G.lO!*{Q&nO1G.lO!+`Q#xO'#HpO!+nQ&nO'#HSO/rQ#xO'#HpO!+xQ#xO'#HoOOQS,5:],5:]O!,QQ#xO,5:]O!,VQ#xO'#HrO!,bQ#xO'#HrO!,uQ#xO,5>]OOQS'#Du'#DuOOQS1G/y1G/yOOQS1G/O1G/OO!-uQ&nO1G/OO!-|Q&nO1G/OO0lQ#xO1G/OO!.iQ#xO1G/WOOQS'#D]'#D]O/rQ#xO,59vOOQS1G.}1G.}O!.pQ#xO1G/gO!/QQ#xO1G/gO!/YQ#xO1G/hO'ZQ#xO'#HiO!/_Q#xO'#HiO!/dQ&nO1G.}O!/tQ#xO,59kO!0zQ#xO,5>XO!1[Q#xO,5>XO!1dQ#xO1G/oO!1iQ&nO1G/oOOQS1G/n1G/nO!1yQ#xO,5>SO!2pQ#xO,5>SO/rQ#xO1G/sO!3_Q#xO1G/uO!3dQ&nO1G/uO!3tQ&nO1G/sOOQS1G/r1G/rOOQS1G/t1G/tOOOO-E9z-E9zOOQS1G/}1G/}OOOO-E9{-E9{O!4UQ#xO'#H|O/rQ#xO'#H|O!4dQ#xO,5:eOOOW-E9|-E9|OOQS1G0O1G0OO!4oQ#xO,5:iOOO`-E:P-E:PO!4zQ#xO,5:jOOOp-E:Q-E:QO!5VQ#xO,5:kOOO!b-E:R-E:ROOQS-E:S-E:SO!5bQ!LUO1G3XO!6RQ&nO1G3XO'ZQ#xO,5oOOQS1G1c1G1cO!7RQ#xO1G1cOOQS'#DX'#DXO/rQ#xO,5>OOOQS,5>O,5>OO!7WQ#xO'#FuO!7cQ#xO,59qO!7kQ#xO1G/ZO!7uQ&nO,5>SOOQS1G3m1G3mOOQS,5:p,5:pO!8fQ#xO'#HROOQS,5UO!9gQ#xO,5>UO/rQ#xO1G0mO/rQ#xO1G0mO0XQ#xO1G0oOOQS-E:X-E:XO!9xQ#xO1G0oO!:TQ#xO1G0oO!:YQ#xO,5>rO!:hQ#xO,5>rO!:vQ#xO,5>nO!;^Q#xO,5>nO!;oQ#xO'#EsO/rQ#xO1G0wO!;zQ#xO1G0wO!uO!BzQ#xO,5>uO!CSQ&nO,5>uO/rQ#xO1G1SO!C^Q#xO1G1SO3aQ#xO1G1XO! gQ#xO1G1ZOOQV,5;d,5;dO!CcQ#zO,5;dO!ChQ#{O1G1TO!F|Q#xO'#GbO3aQ#xO1G1TO3aQ#xO1G1TO!G^Q#xO,5>vO!GkQ#xO,5>vO0XQ#xO,5>vOOQV1G1X1G1XO!GsQ#xO'#FVO!HUQMlO1G1ZO!H^Q#xO1G1ZOOQV1G1`1G1`O3aQ#xO1G1`O!HcQ#xO1G1`O!HkQ#xO'#FaOOQV1G1e1G1eO! zQ&nO1G1ePOOO1G3T1G3TP!HpOSO1G3TOOQS,5>[,5>[OOQS'#Dr'#DrO/rQ#xO,5>[O!HuQ#xO,5>ZO!IYQ#xO,5>ZOOQS1G/w1G/wO!IbQ#xO,5>^O!IrQ#xO,5>^O!IzQ#xO,5>^O!J_Q#xO,5>^O!JoQ#xO,5>^OOQS1G3w1G3wOOQS7+$j7+$jO!7kQ#xO7+$rO!LbQ#xO1G/OO!LiQ#xO1G/OOOQS1G/b1G/bOOQS,5TO'ZQ#xO,5>TOOQS7+$i7+$iO!MVQ#xO7+%RO!M_Q#xO7+%SO!MdQ#xO1G3sOOQS7+%Z7+%ZO!MtQ#xO1G3sO!M|Q#xO7+%ZOOQS,5hO##PQ#xO,5>hO##PQ#xO,5>hO##_O$ISO'#D{O##jO#tO'#H}OOOW1G0P1G0PO##oQ#xO1G0POOO`1G0T1G0TO##wQ#xO1G0TOOOp1G0U1G0UO#$PQ#xO1G0UOOO!b1G0V1G0VO#$XQ#xO1G0VO#$aQ!LUO7+(sO#%QQ&nO1G2]P#%kQ#xO'#GVOOQS,5i,5>iOOOW7+%k7+%kOOO`7+%o7+%oOOOp7+%p7+%pOOO!b7+%q7+%qO#:`Q#xO1G3XO#:yQ#xO1G3XP'ZQ#xO'#FxO/rQ#xO<qO#;mQ#xO,5>qO0XQ#xO,5>qO#pOOQS<sO#sOOQS1G0y1G0yOOQS<xO#DpQ#xO,5>xOOQS,5>x,5>xO#D{Q#xO,5>wO#E^Q#xO,5>wOOQS1G1]1G1]OOQS,5;s,5;sOOQV<XAN>XO#HmQ#xO<eAN>eO/rQ#xO1G2PO#H}Q&nO1G2PP#IXQ#xO'#FyOOQS1G2V1G2VP#IfQ#xO'#GPO#IsQ#xO7+)nO#JZQ#xO,5:hOOOO-E:O-E:OO#JfQ#xO7+(sOOQSAN?_AN?_O#KPQ#xO,5VOOQSANBaANBaOOOO7+%n7+%nOOQS7+'|7+'|O$+jQ#xO<zO$.`Q#xO,5>zO0XQ#xO,5|O$!pQ#xO,5>|OOQS1G1s1G1sO$2WQ&nO,5<_OOQU7+'S7+'SO$$mQ#xO1G/kO$!pQ#xO,5<]O$2_Q#xO,5>}O$2fQ#xO,5>}OOQS1G1v1G1vOOQS7+'V7+'VP$!pQ#xO'#GkO$2nQ#xO1G4hO$2xQ#xO1G4hO$3QQ#xO1G4hOOQS7+%V7+%VO$3`Q#xO1G1wO$3nQ&nO'#FdO$3uQ#xO,5=UOOQS,5=U,5=UO$4TQ#xO1G4iOOQS-E:h-E:hO$!pQ#xO,5=TO$4[Q#xO,5=TO$4aQ#xO7+*SOOQS-E:g-E:gO$4kQ#xO7+*SO$!pQ#xO,5<^P$!pQ#xO'#GjO$4sQ#xO1G2oO$!pQ#xO1G2oP$5RQ#xO'#GiO$5YQ#xO<fPP>i?Z?^PP'a'aPP?vPP'a'aPP'a'a'a'a'a?z@t'aP@wP@}EXHxPH|IYI^IbIf'aPPPIjIs'XP'X'XP'XP'XP'XP'XP'X'X'XP'XPP'XPP'XP'XPIyJVJ_PJfJlPJfPJfJfPPPJfPLzPMTM_MeLzPJfMnPJfPMuM{PNPNe! S! mNPNP! s!!QNPNPNPNP!!f!!l!!o!!t!!w!#R!#X!#e!#w!#}!$X!$_!${!%R!%X!%_!%i!%o!%u!%{!&R!&X!&k!&u!&{!'R!'X!'c!'i!'o!'u!'{!(V!(]!(g!(m!(v!(|!)]!)e!)o!)vPPPPPPPPPPPPPPPPP!)|!*P!*V!*`!*j!*uPPPPPPPPPPPP!/l!1Q!5T!8hPP!8p!9S!9]!:U!9{!:_!:e!:h!:k!:n!:v!;gPPPPPPPPP!;j!;yPPPP!V!>`!?[!?_]jOs#v$w*W,d(TeOTYZ[fistuwy}!O!S!U!V!W!Z!^!h!i!j!k!l!m!n!p!t!u!v!x!y#P#T#X#Y#c#g#j#m#s#v$X$Y$[$^$a$r$t$u$w%O%[%a%h%k%m%p%t%y%{&V&b&d&o&s&|'O'P'W'Z'_'b'i'l'}(O(R(T(U(Y(_(a(e(i(n(o(u(x)V)X)a)d)p)w)y)}*O*S*W*^*b*l*v*y*z*}+T+U+W+Y+]+^+a+d+h+i+l+t+v+w,O,],^,d,l,m,p,z,{,|-O-P-S-U-W-Y-[-^-_-b-y-{.S.V.Y.}/O/o/s0[0z0{0|0}1P1Q1R1S1T1V1Z}!hQ#r$P$b$q$}%r%w%}&O&t'a'x)W)c)|+R+[,[-Z0Y1O!P!iQ#r$P$b$q$}%S%r%w%}&O&t'a'x)W)c)|+R+[,[-Z0Y1O!R!jQ#r$P$b$q$}%S%T%r%w%}&O&t'a'x)W)c)|+R+[,[-Z0Y1O!T!kQ#r$P$b$q$}%S%T%U%r%w%}&O&t'a'x)W)c)|+R+[,[-Z0Y1O!V!lQ#r$P$b$q$}%S%T%U%V%r%w%}&O&t'a'x)W)c)|+R+[,[-Z0Y1O!X!mQ#r$P$b$q$}%S%T%U%V%W%r%w%}&O&t'a'x)W)c)|+R+[,[-Z0Y1O!]!mQ!s#r$P$b$q$}%S%T%U%V%W%X%r%w%}&O&t'a'x)W)c)|+R+[,[-Z0Y1O(TTOTYZ[fistuwy}!O!S!U!V!W!Z!^!h!i!j!k!l!m!n!p!t!u!v!x!y#P#T#X#Y#c#g#j#m#s#v$X$Y$[$^$a$r$t$u$w%O%[%a%h%k%m%p%t%y%{&V&b&d&o&s&|'O'P'W'Z'_'b'i'l'}(O(R(T(U(Y(_(a(e(i(n(o(u(x)V)X)a)d)p)w)y)}*O*S*W*^*b*l*v*y*z*}+T+U+W+Y+]+^+a+d+h+i+l+t+v+w,O,],^,d,l,m,p,z,{,|-O-P-S-U-W-Y-[-^-_-b-y-{.S.V.Y.}/O/o/s0[0z0{0|0}1P1Q1R1S1T1V1Z&iVOYZ[isuw}!O!S!U!V!Z!n!p!t!u!v!x!y#c#g#j#m#s#v$Y$[$^$a$u$w%[%a%h%k%m%t%y%{&V&b&o&s'O'P'W'Z'b'i'l'}(O(R(T(U(Y(a(i(o(u(x)V)X)a)p)w)y*S*W*^*b*l*v*y*z*}+T+U+W+Y+]+^+a+h+i+l+t+w,O,d,l,m,p,z,{,|-O-P-S-U-W-Y-[-^-_-b-y-{.S.V.Y.}/O/s0[0z0{0|0}1P1Q1R1S1V1Z%sXOYZ[isw}!O!S!U!V!Z!n!p#c#g#j#m#s#v$Y$[$^$a$u$w%[%a%k%m%t%y%{&V&b&o&s'O'P'W'Z'b'i'l'}(O(R(T(U(Y(a(i(o(u(x)V)X)a)p)w)y*S*W*^*b*l*v*y*z*}+T+W+Y+]+^+a+h+i+l+t+w,O,d,l,m,p,z,{,|-O-P-S-W-Y-[-^-_-b-y-{.S.V.}/O/s1Q1R1SQ$VvQ/t/SR1W1Y'zeOTYZ[fistuwy}!O!S!U!V!W!Z!^!h!i!j!k!l!m!p!t!u!v!x!y#P#T#X#Y#c#g#j#m#s#v$X$Y$[$^$a$r$t$u$w%O%[%a%h%k%m%p%t%y%{&V&b&d&o&s&|'O'P'W'Z'_'b'i'l'}(R(T(U(Y(_(a(e(i(n(o(u(x)V)X)a)d)p)w)y)}*O*S*W*^*b*l*y*z*}+T+U+W+Y+]+^+a+d+h+i+l+t+v+w,O,],^,d,l,m,p,{,|-O-P-S-U-W-Y-[-^-_-b-y-{.S.V.Y.}/O/o/s0[0z0{0|0}1P1Q1R1S1T1V1ZW#ym!P!Q$hW$Rv&q/S1YQ$j!RQ$n!TQ${![Q$|!]W%Z!n(O*v,zS&p$S$TQ'e$vQ)Y&jQ)h'QU)i'S)j)kU)l'U)m+}W)s'Y,Q-j.dQ*d'nW*e'p,s-}.lQ,P)rS,r*f*gY-d+x-e.a.b/XQ-g+zQ-t,hQ-x,kQ.j-vl.o.R.u.v.x/d/f/k0R0W0]0b0m0r0uQ/W.`Q/l.wQ/x/^Q0T/hU0h0^0k0sX0n0c0o0v0wR&o$R!_!|YZ!U!V!p%a%m%t(R(T(U(a(i)y*y*z*}+T+W+Y,{,|-O-P-S.S.V.}/O/sR%k!{Q#QYQ&W#cQ&Z#gQ&]#jQ&_#mQ&x$^Q&{$aR-`+lT/R.Y0[![!oQ!s#r$P$b$q$}%S%T%U%V%W%X%r%w%}&O&t'a'x)W)c)|+R+[,[-Z0Y1OQ&m#zQ't$|R*p'uR'}%ZQ%d!rR/v/[(SdOTYZ[fistuwy}!O!S!U!V!W!Z!^!h!i!j!k!l!m!n!p!t!u!v!x!y#P#T#X#Y#c#g#j#m#s#v$X$Y$[$^$a$r$t$u$w%O%[%a%h%k%m%p%t%y%{&V&b&d&o&s&|'O'P'W'Z'_'b'i'l'}(O(R(T(U(Y(_(a(e(i(n(o(u(x)V)X)a)d)p)w)y)}*O*S*W*^*b*l*v*y*z*}+T+U+W+Y+]+^+a+d+h+i+l+t+v+w,O,],^,d,l,m,p,z,{,|-O-P-S-U-W-Y-[-^-_-b-y-{.S.V.Y.}/O/o/s0[0z0{0|0}1P1Q1R1S1T1V1ZS#pd#q!P.s.R.u.v.w.x/^/d/f/k0R0W0]0^0b0c0k0m0o0r0s0u0v0w(SdOTYZ[fistuwy}!O!S!U!V!W!Z!^!h!i!j!k!l!m!n!p!t!u!v!x!y#P#T#X#Y#c#g#j#m#s#v$X$Y$[$^$a$r$t$u$w%O%[%a%h%k%m%p%t%y%{&V&b&d&o&s&|'O'P'W'Z'_'b'i'l'}(O(R(T(U(Y(_(a(e(i(n(o(u(x)V)X)a)d)p)w)y)}*O*S*W*^*b*l*v*y*z*}+T+U+W+Y+]+^+a+d+h+i+l+t+v+w,O,],^,d,l,m,p,z,{,|-O-P-S-U-W-Y-[-^-_-b-y-{.S.V.Y.}/O/o/s0[0z0{0|0}1P1Q1R1S1T1V1ZT#pd#qT#d`#ee(|&W&Z&]&_)O)Q)S)U-`._T+m({+nT#ha#iT#kb#lT#nc#oQ$`xQ,P)sR,q*eX$^x$_$`&zQ'[$nQ'r${Q'u$|R*V'eQ)t'YV-i,Q-j.dZlOs$w*W,dXpOs*W,dQ$x!YQ']$oQ'^$pQ'o$zQ's$|Q*T'dQ*['iQ*_'jQ*`'kQ*m'qS*o't'uQ,W)yQ,Y)zQ,Z){Q,_*RS,a*U*nQ,e*YQ,f*ZS,g*]*^Q,w*pQ-l,VQ-m,XQ-o,`S-p,b,cQ-u,iQ-w,jQ.e-nQ.g-qQ.h-sQ.i-tQ/Y.fQ/Z.jQ/p.{R0Z/qWpOs*W,dR#|oQ'q${S*U'e'rR,c*VQ,p*eR-{,qQ*n'qQ,b*UR-q,cZnOos*W,dQ'w$}R*r'xT.P,x.Qu.z.R.u.v.x/^/d/f/k0R0W0]0^0b0k0m0r0s0ut.z.R.u.v.x/^/d/f/k0R0W0]0^0b0k0m0r0s0uQ/l.wX0n0c0o0v0w!P.r.R.u.v.w.x/^/d/f/k0R0W0]0^0b0c0k0m0o0r0s0u0v0wQ/a.qR/}/bg/d.t/e/y0Q0V0e0g0i0t0x0yu.y.R.u.v.x/^/d/f/k0R0W0]0^0b0k0m0r0s0uX/_.o.y/x0hR/z/^V0j0^0k0sR/q.{QsOS$Os,dR,d*WQ&r$UR)_&rS%z#W$WS(p%z(sT(s%}&tQ%n#OQ%u#SW(b%n%u(g(kQ(g%rR(k%wQ&}$bR)e&}Q(v&OQ+_(qT+e(v+_Q(P%]R*w(PS(S%`%aY*{(S*|-Q.W/PU*|(T(U(VU-Q*}+O+PS.W-R-SR/P.XQ#_^R&R#_Q#b_R&T#bQ#e`R&X#eQ(y&US+j(y+kR+k(zQ+n({R-a+nQ#iaR&[#iQ#lbR&^#lQ#ocR&`#oQ#qdR&a#qQ#tgQ&c#rW&f#t&c)b+uQ)b&wR+u1OQ$_xS&y$_&zR&z$`Q'X$lR)q'XQ&k#yR)Z&kQ$h!QR'R$hQ+y)iS-f+y.cR.c-gQ'V$jR)n'VQ,R)tR-k,RQ#wkR&h#wQ)x']R,U)xQ'`$qS*P'`*QR*Q'aQ'h$xR*X'hQ'm$yS*c'm,nR,n*dQ,t*iR.O,tWoOs*W,dR#{oQ.Q,xR.m.Qd/e.t/y0Q0V0e0g0i0t0x0yR0P/eU/].o/x0hR/w/]Q0d0VS0p0d0qR0q0eS0_/y/zR0l0_Q/g.tR0S/gR!`PXrOs*W,dWqOs*W,dR'f$wYkOs$w*W,dR&g#v[xOs#v$w*W,dR&x$^&hQOYZ[isuw}!O!S!U!V!Z!n!p!t!u!v!x!y#c#g#j#m#s#v$Y$[$^$a$u$w%[%a%h%k%m%t%y%{&V&b&o&s'O'P'W'Z'b'i'l'}(O(R(T(U(Y(a(i(o(u(x)V)X)a)p)w)y*S*W*^*b*l*v*y*z*}+T+U+W+Y+]+^+a+h+i+l+t+w,O,d,l,m,p,z,{,|-O-P-S-U-W-Y-[-^-_-b-y-{.S.V.Y.}/O/s0[0z0{0|0}1P1Q1R1S1V1ZQ!sTQ#rfQ$PtU$by%p(eS$q!W$tQ$}!^Q%S!hQ%T!iQ%U!jQ%V!kQ%W!lQ%X!mQ%r#PQ%w#TQ%}#XQ&O#YQ&t$XQ'a$rQ'x%OQ)W&dU)c&|)d+vW)|'_*O,],^Q+R(_Q+[(nQ,[)}Q-Z+dQ0Y/oR1O1TQ#OYQ#SZQ$o!UQ$p!VQ%`!pQ(V%a^(^%m%t(a(i+T+W+Y^*x(R*z-O-P.V/O/sQ+O(TQ+P(UQ,X)yQ,}*yQ-R*}Q.T,{Q.U,|Q.X-SQ.|.SR/r.}[gOs#v$w*W,d!^!{YZ!U!V!p%a%m%t(R(T(U(a(i)y*y*z*}+T+W+Y,{,|-O-P-S.S.V.}/O/sQ#W[Q#uiS$Ww}Q$e!OW$l!S$a'b*SS$y!Z$uW%Y!n(O*v,zY&U#c#g#j#m+l`&e#s&b)V)X)a+t-b1SQ&u$YQ&v$[Q&w$^Q'{%[Q(]%kW(m%y(o+]+aQ(q%{Q(z&VQ)]&oS)`&s1QQ)f'OQ)g'PU)o'W)p,OQ)v'ZQ*]'iY*a'l*b,l,m-yQ*t'}S+Q(Y1RW+c(u+^-W-[W+g(x+i-^-_Q,T)wQ,i*^Q,v*lQ-]+hQ-c+wQ-z,pQ.]-YR.k-{hUOs#s#v$w&b&s(Y)V)X*W,d%Y!zYZ[iw}!O!S!U!V!Z!n!p#c#g#j#m$Y$[$^$a$u%[%a%k%m%t%y%{&V&o'O'P'W'Z'b'i'l'}(O(R(T(U(a(i(o(u(x)a)p)w)y*S*^*b*l*v*y*z*}+T+W+Y+]+^+a+h+i+l+t+w,O,l,m,p,z,{,|-O-P-S-W-Y-[-^-_-b-y-{.S.V.}/O/s1Q1R1SQ$QuW%e!t!x0{1VQ%f!uQ%g!vQ%i!yQ%s0zS(X%h1PQ(Z0|Q([0}Q-T+UQ.[-US/Q.Y0[R1X1ZU$Uv/S1YR)^&q[hOs#v$w*W,da!}Y#c#g#j#m$^$a+lQ#][Q$ZwR$d}Q%o#OQ%v#SQ%|#WQ'{%YQ(h%rQ(l%wQ(t%}Q(w&OQ+`(qQ,y*tQ.Z-TQ/U.[R/u/TQ$cyQ(d%pR+V(eQ/T.YR0f0[R#VZR#[[R%_!nQ%]!nV*u(O*v,z!]!qQ!s#r$P$b$q$}%S%T%U%V%W%X%r%w%}&O&t'a'x)W)c)|+R+[,[-Z0Y1OR%b!pQ&W#cQ&Z#gQ&]#jQ&_#mR-`+lQ(}&WQ)P&ZQ)R&]Q)T&_Q+p)OQ+q)QQ+r)SQ+s)UQ.^-`R/V._Q$m!SQ&{$aQ*R'bR,`*SQ#zmQ$f!PQ$i!QR'T$hQ)h'SR+|)kQ)h'SQ+{)jR+|)kR$k!RR)u'YXqOs*W,dQ$s!WR'c$tQ$z!ZR'd$uR*k'pQ*i'pV-|,s-}.lQ.{.RQ/i.uR/j.vU.t.R.u.vQ/n.xQ/y/^Q0O/dU0Q/f0R0bQ0V/kQ0e0WQ0g0]U0i0^0k0sQ0t0mQ0x0rR0y0uR/m.wR/{/^",nodeNames:"⚠ print { { { { Comment Script AssignStatement * BinaryExpression BitOp BitOp BitOp BitOp ArithOp ArithOp @ ArithOp ** UnaryExpression ArithOp BitOp AwaitExpression await ) ( ParenthesizedExpression BinaryExpression or and CompareOp in not is UnaryExpression ConditionalExpression if else LambdaExpression lambda ParamList VariableName AssignOp , : NamedExpression AssignOp YieldExpression yield from TupleExpression ComprehensionExpression async for LambdaExpression ] [ ArrayExpression ArrayComprehensionExpression } { DictionaryExpression DictionaryComprehensionExpression SetExpression SetComprehensionExpression CallExpression ArgList AssignOp MemberExpression . PropertyName Number String FormatString FormatReplacement FormatConversion FormatSpec FormatReplacement FormatReplacement FormatReplacement FormatReplacement ContinuedString Ellipsis None Boolean TypeDef AssignOp UpdateStatement UpdateOp ExpressionStatement DeleteStatement del PassStatement pass BreakStatement break ContinueStatement continue ReturnStatement return YieldStatement PrintStatement RaiseStatement raise ImportStatement import as ScopeStatement global nonlocal AssertStatement assert TypeDefinition type TypeParamList TypeParam StatementGroup ; IfStatement Body elif WhileStatement while ForStatement TryStatement try except finally WithStatement with FunctionDefinition def ParamList AssignOp TypeDef ClassDefinition class DecoratedStatement Decorator At MatchStatement match MatchBody MatchClause case CapturePattern LiteralPattern ArithOp ArithOp AsPattern OrPattern LogicOp AttributePattern SequencePattern MappingPattern StarPattern ClassPattern PatternArgList KeywordPattern KeywordPattern Guard",maxTerm:283,context:Zp,nodeProps:[["group",-15,8,88,90,91,93,95,97,99,101,102,103,105,108,111,113,"Statement Statement",-22,10,20,23,27,42,51,52,58,59,62,63,64,65,66,69,72,73,74,82,83,84,85,"Expression",-10,117,119,122,124,125,129,131,136,138,141,"Statement",-9,146,147,150,151,153,154,155,156,157,"Pattern"],["openedBy",25,"(",56,"[",60,"{"],["closedBy",26,")",57,"]",61,"}"]],propSources:[rf],skippedNodes:[0,6],repeatNodeCount:38,tokenData:"%-W#sR!`OX%TXY=|Y[%T[]=|]p%Tpq=|qr@_rsDOst!+|tu%Tuv!Nnvw#!|wx#$Wxy#:Uyz#;Yz{#<^{|#>x|}#@S}!O#AW!O!P#Ci!P!Q#N_!Q!R$!y!R![$&w![!]$1e!]!^$3s!^!_$4w!_!`$7c!`!a$8m!a!b%T!b!c$;U!c!d$W!e!h$W#V#Y$Q<%lO$Xc&r!b&jS&mW%p!TOX%TXY=|Y[%T[]=|]p%Tpq=|qr%Trs&Vsw%Twx/Xx#O%T#O#P?d#P#o%T#o#p8^#p#q%T#q#r8^#r;'S%T;'S;=`=v<%lO%T#s?i[&r!bOY%TYZ=|Z]%T]^=|^#o%T#o#p8^#p#q%T#q#r8^#r;'S%T;'S;=`=P;=`<%l8^<%lO%T!q@hd&r!b&jS&mWOr%Trs&Vsw%Twx/Xx!_%T!_!`Av!`#O%T#O#P7o#P#T%T#T#UBz#U#f%T#f#gBz#g#hBz#h#o%T#o#p8^#p#q%T#q#r8^#r;'S%T;'S;=`=v<%lO%T!qBR]oR&r!b&jS&mWOr%Trs&Vsw%Twx/Xx#O%T#O#P7o#P#o%T#o#p8^#p#q%T#q#r8^#r;'S%T;'S;=`=v<%lO%T!qCV]!nR&r!b&jS&mWOr%Trs&Vsw%Twx/Xx#O%T#O#P7o#P#o%T#o#p8^#p#q%T#q#r8^#r;'S%T;'S;=`=v<%lO%T#cDXa&r!b&jS&hsOYE^YZ%TZ]E^]^%T^rE^rs!)|swE^wxGpx#OE^#O#P!!u#P#oE^#o#p!#d#p#qE^#q#r!#d#r;'SE^;'S;=`!)v<%lOE^#cEia&r!b&jS&mW&hsOYE^YZ%TZ]E^]^%T^rE^rsFnswE^wxGpx#OE^#O#P!!u#P#oE^#o#p!#d#p#qE^#q#r!#d#r;'SE^;'S;=`!)v<%lOE^#cFw]&r!b&jS&hsOr%Trs'Vsw%Twx/Xx#O%T#O#P7o#P#o%T#o#p8^#p#q%T#q#r8^#r;'S%T;'S;=`=v<%lO%T#cGya&r!b&mW&hsOYE^YZ%TZ]E^]^%T^rE^rsFnswE^wxIOx#OE^#O#P!!u#P#oE^#o#p!#d#p#qE^#q#r!#d#r;'SE^;'S;=`!)v<%lOE^#cIXa&r!b&mW&hsOYE^YZ%TZ]E^]^%T^rE^rsFnswE^wxJ^x#OE^#O#P!!u#P#oE^#o#p!#d#p#qE^#q#r!#d#r;'SE^;'S;=`!)v<%lOE^#_Jg_&r!b&mW&hsOYJ^YZ1XZ]J^]^1X^rJ^rsKfs#OJ^#O#PL`#P#oJ^#o#pL}#p#qJ^#q#rL}#r;'SJ^;'S;=`!!o<%lOJ^#_KmZ&r!b&hsOr1Xrs2ys#O1X#O#P3q#P#o1X#o#p4`#p#q1X#q#r4`#r;'S1X;'S;=`7i<%lO1X#_LeW&r!bO#oJ^#o#pL}#p#qJ^#q#rL}#r;'SJ^;'S;=`! r;=`<%lL}<%lOJ^{MUZ&mW&hsOYL}YZ4`Z]L}]^4`^rL}rsMws#OL}#O#PNc#P;'SL};'S;=`! l<%lOL}{M|V&hsOr4`rs5ds#O4`#O#P5y#P;'S4`;'S;=`6t<%lO4`{NfRO;'SL};'S;=`No;=`OL}{Nv[&mW&hsOYL}YZ4`Z]L}]^4`^rL}rsMws#OL}#O#PNc#P;'SL};'S;=`! l;=`<%lL}<%lOL}{! oP;=`<%lL}#_! y[&mW&hsOYL}YZ4`Z]L}]^4`^rL}rsMws#OL}#O#PNc#P;'SL};'S;=`! l;=`<%lJ^<%lOL}#_!!rP;=`<%lJ^#c!!zW&r!bO#oE^#o#p!#d#p#qE^#q#r!#d#r;'SE^;'S;=`!(q;=`<%l!#d<%lOE^!P!#m]&jS&mW&hsOY!#dYZ8^Z]!#d]^8^^r!#drs!$fsw!#dwx!%Yx#O!#d#O#P!'Y#P;'S!#d;'S;=`!(k<%lO!#d!P!$mX&jS&hsOr8^rs9rsw8^wx:dx#O8^#O#P;v#P;'S8^;'S;=`^s#O!=U#O#P!@j#P#o!=U#o#p!Ag#p#q!=U#q#r!Ag#r;'S!=U;'S;=`!FQ<%lO!=U#o!>e_U!T&r!bOY!=UYZ1XZ]!=U]^1X^r!=Urs!?ds#O!=U#O#P!@j#P#o!=U#o#p!Ag#p#q!=U#q#r!Ag#r;'S!=U;'S;=`!FQ<%lO!=U#o!?k_U!T&r!bOY!=UYZ1XZ]!=U]^1X^r!=Urs!3`s#O!=U#O#P!@j#P#o!=U#o#p!Ag#p#q!=U#q#r!Ag#r;'S!=U;'S;=`!FQ<%lO!=U#o!@q[U!T&r!bOY!=UYZ1XZ]!=U]^1X^#o!=U#o#p!Ag#p#q!=U#q#r!Ag#r;'S!=U;'S;=`!Ec;=`<%l4`<%lO!=U!]!AnZU!T&mWOY!AgYZ4`Z]!Ag]^4`^r!Agrs!Bas#O!Ag#O#P!DP#P;'S!Ag;'S;=`!E]<%lO!Ag!]!BfZU!TOY!AgYZ4`Z]!Ag]^4`^r!Agrs!CXs#O!Ag#O#P!DP#P;'S!Ag;'S;=`!E]<%lO!Ag!]!C^ZU!TOY!AgYZ4`Z]!Ag]^4`^r!Agrs!4Ys#O!Ag#O#P!DP#P;'S!Ag;'S;=`!E]<%lO!Ag!]!DUWU!TOY!AgYZ4`Z]!Ag]^4`^;'S!Ag;'S;=`!Dn;=`<%l4`<%lO!Ag!]!DsW&mWOr4`rs4zs#O4`#O#P5y#P;'S4`;'S;=`6t;=`<%l!Ag<%lO4`!]!E`P;=`<%l!Ag#o!EhW&mWOr4`rs4zs#O4`#O#P5y#P;'S4`;'S;=`6t;=`<%l!=U<%lO4`#o!FTP;=`<%l!=U#s!F_[U!T&r!bOY!+|YZ%TZ]!+|]^%T^#o!+|#o#p!GT#p#q!+|#q#r!GT#r;'S!+|;'S;=`!Mq;=`<%l8^<%lO!+|!a!G^]U!T&jS&mWOY!GTYZ8^Z]!GT]^8^^r!GTrs!HVsw!GTwx!JVx#O!GT#O#P!LV#P;'S!GT;'S;=`!Mk<%lO!GT!a!H^]U!T&jSOY!GTYZ8^Z]!GT]^8^^r!GTrs!IVsw!GTwx!JVx#O!GT#O#P!LV#P;'S!GT;'S;=`!Mk<%lO!GT!a!I^]U!T&jSOY!GTYZ8^Z]!GT]^8^^r!GTrs!5wsw!GTwx!JVx#O!GT#O#P!LV#P;'S!GT;'S;=`!Mk<%lO!GT!a!J^]U!T&mWOY!GTYZ8^Z]!GT]^8^^r!GTrs!HVsw!GTwx!KVx#O!GT#O#P!LV#P;'S!GT;'S;=`!Mk<%lO!GT!a!K^]U!T&mWOY!GTYZ8^Z]!GT]^8^^r!GTrs!HVsw!GTwx!Agx#O!GT#O#P!LV#P;'S!GT;'S;=`!Mk<%lO!GT!a!L[WU!TOY!GTYZ8^Z]!GT]^8^^;'S!GT;'S;=`!Lt;=`<%l8^<%lO!GT!a!L{Y&jS&mWOr8^rs9Qsw8^wx:dx#O8^#O#P;v#P;'S8^;'S;=`Q<%lO$TP;=`<%l$ei&r!b&jS&mW&g`&SsOr%Trs$@Ssw%Twx$C`x!Q%T!Q![$Q<%lO$Q<%lO$Q<%lO$Q<%lO$Q<%lO$of[e]||-1}],tokenPrec:7372}),lf=new Zo,hf=new Set(["Script","Body","FunctionDefinition","ClassDefinition","LambdaExpression","ForStatement","MatchClause"]);function cf(e){return(t,i,n)=>{if(n)return!1;let s=t.node.getChild("VariableName");return s&&i(s,e),!0}}const df={FunctionDefinition:cf("function"),ClassDefinition:cf("class"),ForStatement(e,t,i){if(i)for(let i=e.node.firstChild;i;i=i.nextSibling)if("VariableName"==i.name)t(i,"variable");else if("in"==i.name)break},ImportStatement(e,t){var i,n;let{node:s}=e,r="from"==(null===(i=s.firstChild)||void 0===i?void 0:i.name);for(let e=s.getChild("import");e;e=e.nextSibling)"VariableName"==e.name&&"as"!=(null===(n=e.nextSibling)||void 0===n?void 0:n.name)&&t(e,r?"variable":"namespace")},AssignStatement(e,t){for(let i=e.node.firstChild;i;i=i.nextSibling)if("VariableName"==i.name)t(i,"variable");else if(":"==i.name||"AssignOp"==i.name)break},ParamList(e,t){for(let i=null,n=e.node.firstChild;n;n=n.nextSibling)"VariableName"!=n.name||i&&/\*|AssignOp/.test(i.name)||t(n,"variable"),i=n},CapturePattern:cf("variable"),AsPattern:cf("variable"),__proto__:null};function uf(e,t){let i=lf.get(t);if(i)return i;let n=[],s=!0;function r(t,i){let s=e.sliceString(t.from,t.to);n.push({label:s,type:i})}return t.cursor(Ro.IncludeAnonymous).iterate((t=>{if(t.name){let e=df[t.name];if(e&&e(t,r,s)||!s&&hf.has(t.name))return!1;s=!1}else if(t.to-t.from>8192){for(let i of uf(e,t.node))n.push(i);return!1}})),lf.set(t,n),n}const pf=/^[\w\xa1-\uffff][\w\d\xa1-\uffff]*$/,ff=["String","FormatString","Comment","PropertyName"];function mf(e){let t=Da(e.state).resolveInner(e.pos,-1);if(ff.indexOf(t.name)>-1)return null;let i="VariableName"==t.name||t.to-t.from<20&&pf.test(e.state.sliceDoc(t.from,t.to));if(!i&&!e.explicit)return null;let n=[];for(let i=t;i;i=i.parent)hf.has(i.name)&&(n=n.concat(uf(e.state.doc,i)));return{options:n,from:i?t.from:e.pos,validFor:pf}}const gf=["__annotations__","__builtins__","__debug__","__doc__","__import__","__name__","__loader__","__package__","__spec__","False","None","True"].map((e=>({label:e,type:"constant"}))).concat(["ArithmeticError","AssertionError","AttributeError","BaseException","BlockingIOError","BrokenPipeError","BufferError","BytesWarning","ChildProcessError","ConnectionAbortedError","ConnectionError","ConnectionRefusedError","ConnectionResetError","DeprecationWarning","EOFError","Ellipsis","EncodingWarning","EnvironmentError","Exception","FileExistsError","FileNotFoundError","FloatingPointError","FutureWarning","GeneratorExit","IOError","ImportError","ImportWarning","IndentationError","IndexError","InterruptedError","IsADirectoryError","KeyError","KeyboardInterrupt","LookupError","MemoryError","ModuleNotFoundError","NameError","NotADirectoryError","NotImplemented","NotImplementedError","OSError","OverflowError","PendingDeprecationWarning","PermissionError","ProcessLookupError","RecursionError","ReferenceError","ResourceWarning","RuntimeError","RuntimeWarning","StopAsyncIteration","StopIteration","SyntaxError","SyntaxWarning","SystemError","SystemExit","TabError","TimeoutError","TypeError","UnboundLocalError","UnicodeDecodeError","UnicodeEncodeError","UnicodeError","UnicodeTranslateError","UnicodeWarning","UserWarning","ValueError","Warning","ZeroDivisionError"].map((e=>({label:e,type:"type"})))).concat(["bool","bytearray","bytes","classmethod","complex","float","frozenset","int","list","map","memoryview","object","range","set","staticmethod","str","super","tuple","type"].map((e=>({label:e,type:"class"})))).concat(["abs","aiter","all","anext","any","ascii","bin","breakpoint","callable","chr","compile","delattr","dict","dir","divmod","enumerate","eval","exec","exit","filter","format","getattr","globals","hasattr","hash","help","hex","id","input","isinstance","issubclass","iter","len","license","locals","max","min","next","oct","open","ord","pow","print","property","quit","repr","reversed","round","setattr","slice","sorted","sum","vars","zip"].map((e=>({label:e,type:"function"})))),vf=[Au("def ${name}(${params}):\n\t${}",{label:"def",detail:"function",type:"keyword"}),Au("for ${name} in ${collection}:\n\t${}",{label:"for",detail:"loop",type:"keyword"}),Au("while ${}:\n\t${}",{label:"while",detail:"loop",type:"keyword"}),Au("try:\n\t${}\nexcept ${error}:\n\t${}",{label:"try",detail:"/ except block",type:"keyword"}),Au("if ${}:\n\t\n",{label:"if",detail:"block",type:"keyword"}),Au("if ${}:\n\t${}\nelse:\n\t${}",{label:"if",detail:"/ else block",type:"keyword"}),Au("class ${name}:\n\tdef __init__(self, ${params}):\n\t\t\t${}",{label:"class",detail:"definition",type:"keyword"}),Au("import ${module}",{label:"import",detail:"statement",type:"keyword"}),Au("from ${module} import ${names}",{label:"from",detail:"import",type:"keyword"})],Of=Ld(ff,qd(gf.concat(vf)));function bf(e,t){let i=e.baseIndentFor(t),n=e.lineAt(e.pos,-1),s=n.from+n.text.length;return/^\s*($|#)/.test(n.text)&&e.node.toi?null:i+e.unit}const _f=Ra.define({name:"python",parser:af.configure({props:[Ga.add({Body:e=>{var t;return null!==(t=bf(e,e.node))&&void 0!==t?t:e.continue()},IfStatement:e=>/^\s*(else:|elif )/.test(e.textAfter)?e.baseIndent:e.continue(),TryStatement:e=>/^\s*(except |finally:|else:)/.test(e.textAfter)?e.baseIndent:e.continue(),"TupleExpression ComprehensionExpression ParamList ArgList ParenthesizedExpression":il({closing:")"}),"DictionaryExpression DictionaryComprehensionExpression SetExpression SetComprehensionExpression":il({closing:"}"}),"ArrayExpression ArrayComprehensionExpression":il({closing:"]"}),"String FormatString":()=>null,Script:e=>{if(e.pos+/\s*/.exec(e.textAfter)[0].length>=e.node.to){let t=null;for(let i=e.node,n=i.to;i=i.lastChild,i&&i.to==n;)"Body"==i.type.name&&(t=i);if(t){let i=bf(e,t);if(null!=i)return i}}return e.continue()}}),rl.add({"ArrayExpression DictionaryExpression SetExpression TupleExpression":function(e){let t=e.firstChild,i=e.lastChild;return t&&t.to({from:e.from+1,to:e.to-(e.to==t.doc.length?0:1)})})]}),languageData:{closeBrackets:{brackets:["(","[","{","'",'"',"'''",'"""'],stringPrefixes:["f","fr","rf","r","u","b","br","rb","F","FR","RF","R","U","B","BR","RB"]},commentTokens:{line:"#"},indentOnInput:/^\s*([\}\]\)]|else:|elif |except |finally:)$/}}),yf="#e06c75",wf="#abb2bf",xf="#7d8799",Sf="#d19a66",kf="#2c313a",Tf="#282c34",Cf="#353a42",Pf="#528bff",Mf=[Ds.theme({"&":{color:wf,backgroundColor:Tf},".cm-content":{caretColor:Pf},".cm-cursor, .cm-dropCursor":{borderLeftColor:Pf},"&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground, .cm-selectionBackground, .cm-content ::selection":{backgroundColor:"#3E4451"},".cm-panels":{backgroundColor:"#21252b",color:wf},".cm-panels.cm-panels-top":{borderBottom:"2px solid black"},".cm-panels.cm-panels-bottom":{borderTop:"2px solid black"},".cm-searchMatch":{backgroundColor:"#72a1ff59",outline:"1px solid #457dff"},".cm-searchMatch.cm-searchMatch-selected":{backgroundColor:"#6199ff2f"},".cm-activeLine":{backgroundColor:"#6699ff0b"},".cm-selectionMatch":{backgroundColor:"#aafe661a"},"&.cm-focused .cm-matchingBracket, &.cm-focused .cm-nonmatchingBracket":{backgroundColor:"#bad0f847"},".cm-gutters":{backgroundColor:Tf,color:xf,border:"none"},".cm-activeLineGutter":{backgroundColor:kf},".cm-foldPlaceholder":{backgroundColor:"transparent",border:"none",color:"#ddd"},".cm-tooltip":{border:"none",backgroundColor:Cf},".cm-tooltip .cm-tooltip-arrow:before":{borderTopColor:"transparent",borderBottomColor:"transparent"},".cm-tooltip .cm-tooltip-arrow:after":{borderTopColor:Cf,borderBottomColor:Cf},".cm-tooltip-autocomplete":{"& > ul > li[aria-selected]":{backgroundColor:kf,color:wf}}},{dark:!0}),Rl(Pl.define([{tag:Ta.keyword,color:"#c678dd"},{tag:[Ta.name,Ta.deleted,Ta.character,Ta.propertyName,Ta.macroName],color:yf},{tag:[Ta.function(Ta.variableName),Ta.labelName],color:"#61afef"},{tag:[Ta.color,Ta.constant(Ta.name),Ta.standard(Ta.name)],color:Sf},{tag:[Ta.definition(Ta.name),Ta.separator],color:wf},{tag:[Ta.typeName,Ta.className,Ta.number,Ta.changed,Ta.annotation,Ta.modifier,Ta.self,Ta.namespace],color:"#e5c07b"},{tag:[Ta.operator,Ta.operatorKeyword,Ta.url,Ta.escape,Ta.regexp,Ta.link,Ta.special(Ta.string)],color:"#56b6c2"},{tag:[Ta.meta,Ta.comment],color:xf},{tag:Ta.strong,fontWeight:"bold"},{tag:Ta.emphasis,fontStyle:"italic"},{tag:Ta.strikethrough,textDecoration:"line-through"},{tag:Ta.link,color:xf,textDecoration:"underline"},{tag:Ta.heading,fontWeight:"bold",color:yf},{tag:[Ta.atom,Ta.bool,Ta.special(Ta.variableName)],color:Sf},{tag:[Ta.processingInstruction,Ta.string,Ta.inserted],color:"#98c379"},{tag:Ta.invalid,color:"#ffffff"}]))];var Ef,Af,Rf,Df,If,qf,Lf,Nf,Bf,$f=__webpack_require__(5247),Qf=__webpack_require__(5895),zf=__webpack_require__(6424),jf=__webpack_require__(7564),Wf=__webpack_require__(3911);!function(e){e.copyText=function(e){const t=document.body,i=n=>{n.preventDefault(),n.stopPropagation(),n.clipboardData.setData("text",e),t.removeEventListener("copy",i,!0)};t.addEventListener("copy",i,!0),document.execCommand("copy")}}(Ef||(Ef={})),(Bf=Af||(Af={})).boxSizing=function(e){let t=window.getComputedStyle(e),i=parseFloat(t.borderTopWidth)||0,n=parseFloat(t.borderLeftWidth)||0,s=parseFloat(t.borderRightWidth)||0,r=parseFloat(t.borderBottomWidth)||0,o=parseFloat(t.paddingTop)||0,a=parseFloat(t.paddingLeft)||0,l=parseFloat(t.paddingRight)||0,h=parseFloat(t.paddingBottom)||0;return{borderTop:i,borderLeft:n,borderRight:s,borderBottom:r,paddingTop:o,paddingLeft:a,paddingRight:l,paddingBottom:h,horizontalSum:n+a+l+s,verticalSum:i+o+h+r}},Bf.sizeLimits=function(e){let t=window.getComputedStyle(e),i=parseFloat(t.minWidth)||0,n=parseFloat(t.minHeight)||0,s=parseFloat(t.maxWidth)||1/0,r=parseFloat(t.maxHeight)||1/0;return s=Math.max(i,s),r=Math.max(n,r),{minWidth:i,minHeight:n,maxWidth:s,maxHeight:r}},Bf.hitTest=function(e,t,i){let n=e.getBoundingClientRect();return t>=n.left&&t=n.top&&i=i.bottom||(n.topi.bottom&&n.height>=i.height?e.scrollTop-=i.top-n.top:(n.topi.height||n.bottom>i.bottom&&n.height{let e=Element.prototype;return e.matches||e.matchesSelector||e.mozMatchesSelector||e.msMatchesSelector||e.oMatchesSelector||e.webkitMatchesSelector||function(e){let t=this,i=t.ownerDocument?t.ownerDocument.querySelectorAll(e):[];return-1!==Array.prototype.indexOf.call(i,t)}})(),e.calculateSingle=function(e){let h=0,c=0,d=0;function u(t){let i=e.match(t);return null!==i&&(e=e.slice(i[0].length),!0)}for(e=(e=e.split(",",1)[0]).replace(l," $1 ");e.length>0;)if(u(t))h++;else if(u(i))c++;else if(u(n))c++;else if(u(r))d++;else if(u(o))c++;else if(u(s))d++;else if(!u(a))return 0;return h=Math.min(h,255),c=Math.min(c,255),d=Math.min(d,255),h<<16|c<<8|d};const t=/^#[^\s\+>~#\.\[:]+/,i=/^\.[^\s\+>~#\.\[:]+/,n=/^\[[^\]]+\]/,s=/^[^\s\+>~#\.\[:]+/,r=/^(::[^\s\+>~#\.\[:]+|:first-line|:first-letter|:before|:after)/,o=/^:[^\s\+>~#\.\[:]+/,a=/^[\s\+>~\*]+/,l=/:not\(([^\)]+)\)/g}(If||(If={}));class Vf{constructor(){this._first=null,this._last=null,this._size=0}get isEmpty(){return 0===this._size}get size(){return this._size}get length(){return this._size}get first(){return this._first?this._first.value:void 0}get last(){return this._last?this._last.value:void 0}get firstNode(){return this._first}get lastNode(){return this._last}*[Symbol.iterator](){let e=this._first;for(;e;)yield e.value,e=e.next}*retro(){let e=this._last;for(;e;)yield e.value,e=e.prev}*nodes(){let e=this._first;for(;e;)yield e,e=e.next}*retroNodes(){let e=this._last;for(;e;)yield e,e=e.prev}assign(e){this.clear();for(const t of e)this.addLast(t)}push(e){this.addLast(e)}pop(){return this.removeLast()}shift(e){this.addFirst(e)}unshift(){return this.removeFirst()}addFirst(e){let t=new qf.LinkedListNode(this,e);return this._first?(t.next=this._first,this._first.prev=t,this._first=t):(this._first=t,this._last=t),this._size++,t}addLast(e){let t=new qf.LinkedListNode(this,e);return this._last?(t.prev=this._last,this._last.next=t,this._last=t):(this._first=t,this._last=t),this._size++,t}insertBefore(e,t){if(!t||t===this._first)return this.addFirst(e);if(!(t instanceof qf.LinkedListNode)||t.list!==this)throw new Error("Reference node is not owned by the list.");let i=new qf.LinkedListNode(this,e),n=t,s=n.prev;return i.next=n,i.prev=s,n.prev=i,s.next=i,this._size++,i}insertAfter(e,t){if(!t||t===this._last)return this.addLast(e);if(!(t instanceof qf.LinkedListNode)||t.list!==this)throw new Error("Reference node is not owned by the list.");let i=new qf.LinkedListNode(this,e),n=t,s=n.next;return i.next=s,i.prev=n,n.next=i,s.prev=i,this._size++,i}removeFirst(){let e=this._first;if(e)return e===this._last?(this._first=null,this._last=null):(this._first=e.next,this._first.prev=null),e.list=null,e.next=null,e.prev=null,this._size--,e.value}removeLast(){let e=this._last;if(e)return e===this._first?(this._first=null,this._last=null):(this._last=e.prev,this._last.next=null),e.list=null,e.next=null,e.prev=null,this._size--,e.value}removeNode(e){if(!(e instanceof qf.LinkedListNode)||e.list!==this)throw new Error("Node is not owned by the list.");let t=e;t===this._first&&t===this._last?(this._first=null,this._last=null):t===this._first?(this._first=t.next,this._first.prev=null):t===this._last?(this._last=t.prev,this._last.next=null):(t.next.prev=t.prev,t.prev.next=t.next),t.list=null,t.next=null,t.prev=null,this._size--}clear(){let e=this._first;for(;e;){let t=e.next;e.list=null,e.prev=null,e.next=null,e=t}this._first=null,this._last=null,this._size=0}}!function(e){e.from=function(t){let i=new e;return i.assign(t),i}}(Vf||(Vf={})),function(e){e.LinkedListNode=class{constructor(e,t){this.list=null,this.next=null,this.prev=null,this.list=e,this.value=t}}}(qf||(qf={}));class Uf{constructor(e){this.type=e}get isConflatable(){return!1}conflate(e){return!1}}class Ff extends Uf{get isConflatable(){return!0}conflate(e){return!0}}!function(e){let t=null;const i=(n=Promise.resolve(),e=>{let t=!1;return n.then((()=>!t&&e())),()=>{t=!0}});var n;function s(e,t){let i=o.get(e);if(!i||0===i.length)return void c(e,t);let n=(0,jf.yW)((0,jf.kh)(i),(i=>!i||function(e,t,i){let n=!0;try{n="function"==typeof e?e(t,i):e.messageHook(t,i)}catch(e){l(e)}return n}(i,e,t)));n&&c(e,t)}e.sendMessage=s,e.postMessage=function(e,t){t.isConflatable&&(0,jf.G)(r,(i=>i.handler===e&&!!i.msg&&i.msg.type===t.type&&!!i.msg.isConflatable&&i.msg.conflate(t)))||d(e,t)},e.installMessageHook=function(e,t){let i=o.get(e);i&&-1!==i.indexOf(t)||(i?i.push(t):o.set(e,[t]))},e.removeMessageHook=function(e,t){let i=o.get(e);if(!i)return;let n=i.indexOf(t);-1!==n&&(i[n]=null,p(i))},e.clearData=function(e){let t=o.get(e);t&&t.length>0&&(jf.RO.fill(t,null),p(t));for(const t of r)t.handler===e&&(t.handler=null,t.msg=null)},e.flush=function(){h||null===t||(t(),t=null,h=!0,u(),h=!1)},e.getExceptionHandler=function(){return l},e.setExceptionHandler=function(e){let t=l;return l=e,t};const r=new Vf,o=new WeakMap,a=new Set;let l=e=>{console.error(e)},h=!1;function c(e,t){try{e.processMessage(t)}catch(e){l(e)}}function d(e,n){r.addLast({handler:e,msg:n}),null===t&&(t=i(u))}function u(){if(t=null,r.isEmpty)return;let e={handler:null,msg:null};for(r.addLast(e);;){let t=r.removeFirst();if(t===e)return;t.handler&&t.msg&&s(t.handler,t.msg)}}function p(e){0===a.size&&i(f),a.add(e)}function f(){a.forEach(m),a.clear()}function m(e){jf.RO.removeAllWhere(e,g)}function g(e){return null===e}}(Lf||(Lf={}));var Hf,Xf=__webpack_require__(4050),Yf=__webpack_require__(1122);class Gf{constructor(e){this._onScrollFrame=()=>{if(!this._scrollTarget)return;let{element:e,edge:t,distance:i}=this._scrollTarget,n=Hf.SCROLL_EDGE_SIZE-i,s=Math.pow(n/Hf.SCROLL_EDGE_SIZE,2),r=Math.max(1,Math.round(s*Hf.SCROLL_EDGE_SIZE));switch(t){case"top":e.scrollTop-=r;break;case"left":e.scrollLeft-=r;break;case"right":e.scrollLeft+=r;break;case"bottom":e.scrollTop+=r}requestAnimationFrame(this._onScrollFrame)},this._disposed=!1,this._dropAction="none",this._override=null,this._currentTarget=null,this._currentElement=null,this._promise=null,this._scrollTarget=null,this._resolve=null,this.document=e.document||document,this.mimeData=e.mimeData,this.dragImage=e.dragImage||null,this.proposedAction=e.proposedAction||"copy",this.supportedActions=e.supportedActions||"all",this.source=e.source||null}dispose(){if(!this._disposed){if(this._disposed=!0,this._currentTarget){let e=new PointerEvent("pointerup",{bubbles:!0,cancelable:!0,clientX:-1,clientY:-1});Hf.dispatchDragLeave(this,this._currentTarget,null,e)}this._finalize("none")}}get isDisposed(){return this._disposed}start(e,t){if(this._disposed)return Promise.resolve("none");if(this._promise)return this._promise;this._addListeners(),this._attachDragImage(e,t),this._promise=new Promise((e=>{this._resolve=e}));let i=new PointerEvent("pointermove",{bubbles:!0,cancelable:!0,clientX:e,clientY:t});return document.dispatchEvent(i),this._promise}handleEvent(e){switch(e.type){case"pointermove":this._evtPointerMove(e);break;case"pointerup":this._evtPointerUp(e);break;case"keydown":this._evtKeyDown(e);break;default:e.preventDefault(),e.stopPropagation()}}moveDragImage(e,t){this.dragImage&&(this.dragImage.style.transform=`translate(${e}px, ${t}px)`)}_evtPointerMove(e){e.preventDefault(),e.stopPropagation(),this._updateCurrentTarget(e),this._updateDragScroll(e),this.moveDragImage(e.clientX,e.clientY)}_evtPointerUp(e){if(e.preventDefault(),e.stopPropagation(),0!==e.button)return;if(this._updateCurrentTarget(e),!this._currentTarget)return void this._finalize("none");if("none"===this._dropAction)return Hf.dispatchDragLeave(this,this._currentTarget,null,e),void this._finalize("none");let t=Hf.dispatchDrop(this,this._currentTarget,e);this._finalize(t)}_evtKeyDown(e){e.preventDefault(),e.stopPropagation(),27===e.keyCode&&this.dispose()}_addListeners(){document.addEventListener("pointerdown",this,!0),document.addEventListener("pointermove",this,!0),document.addEventListener("pointerup",this,!0),document.addEventListener("pointerenter",this,!0),document.addEventListener("pointerleave",this,!0),document.addEventListener("pointerover",this,!0),document.addEventListener("pointerout",this,!0),document.addEventListener("keydown",this,!0),document.addEventListener("keyup",this,!0),document.addEventListener("keypress",this,!0),document.addEventListener("contextmenu",this,!0)}_removeListeners(){document.removeEventListener("pointerdown",this,!0),document.removeEventListener("pointermove",this,!0),document.removeEventListener("pointerup",this,!0),document.removeEventListener("pointerenter",this,!0),document.removeEventListener("pointerleave",this,!0),document.removeEventListener("pointerover",this,!0),document.removeEventListener("pointerout",this,!0),document.removeEventListener("keydown",this,!0),document.removeEventListener("keyup",this,!0),document.removeEventListener("keypress",this,!0),document.removeEventListener("contextmenu",this,!0)}_updateDragScroll(e){let t=Hf.findScrollTarget(e);(this._scrollTarget||t)&&(this._scrollTarget||setTimeout(this._onScrollFrame,500),this._scrollTarget=t)}_updateCurrentTarget(e){let t=this._currentTarget,i=this._currentTarget,n=this._currentElement,s=Hf.findElementBehidBackdrop(e,this.document);this._currentElement=s,s!==n&&s!==i&&Hf.dispatchDragExit(this,i,s,e),s!==n&&s!==i&&(i=Hf.dispatchDragEnter(this,s,i,e)),i!==t&&(this._currentTarget=i,Hf.dispatchDragLeave(this,t,i,e));let r=Hf.dispatchDragOver(this,i,e);this._setDropAction(r)}_attachDragImage(e,t){if(!this.dragImage)return;this.dragImage.classList.add("lm-mod-drag-image");let i=this.dragImage.style;i.pointerEvents="none",i.position="fixed",i.transform=`translate(${e}px, ${t}px)`,(this.document instanceof Document?this.document.body:this.document.firstElementChild).appendChild(this.dragImage)}_detachDragImage(){if(!this.dragImage)return;let e=this.dragImage.parentNode;e&&e.removeChild(this.dragImage)}_setDropAction(e){if(e=Hf.validateAction(e,this.supportedActions),!this._override||this._dropAction!==e)switch(e){case"none":this._dropAction=e,this._override=Gf.overrideCursor("no-drop",this.document);break;case"copy":this._dropAction=e,this._override=Gf.overrideCursor("copy",this.document);break;case"link":this._dropAction=e,this._override=Gf.overrideCursor("alias",this.document);break;case"move":this._dropAction=e,this._override=Gf.overrideCursor("move",this.document)}}_finalize(e){let t=this._resolve;this._removeListeners(),this._detachDragImage(),this._override&&(this._override.dispose(),this._override=null),this.mimeData.clear(),this._disposed=!0,this._dropAction="none",this._currentTarget=null,this._currentElement=null,this._scrollTarget=null,this._promise=null,this._resolve=null,t&&t(e)}}function Zf(){return em.keyboardLayout}!function(e){class t extends DragEvent{constructor(e,t){super(t.type,{bubbles:!0,cancelable:!0,altKey:e.altKey,button:e.button,clientX:e.clientX,clientY:e.clientY,ctrlKey:e.ctrlKey,detail:0,metaKey:e.metaKey,relatedTarget:t.related,screenX:e.screenX,screenY:e.screenY,shiftKey:e.shiftKey,view:window});const{drag:i}=t;this.dropAction="none",this.mimeData=i.mimeData,this.proposedAction=i.proposedAction,this.supportedActions=i.supportedActions,this.source=i.source}}e.Event=t,e.overrideCursor=function(e,t=document){return Hf.overrideCursor(e,t)}}(Gf||(Gf={})),function(e){function t(t,n=document){if(i&&t==i.event)return i.element;e.cursorBackdrop.style.zIndex="-1000";const s=n.elementFromPoint(t.clientX,t.clientY);return e.cursorBackdrop.style.zIndex="",i={event:t,element:s},s}e.SCROLL_EDGE_SIZE=20,e.validateAction=function(e,t){return n[e]&s[t]?e:"none"},e.findElementBehidBackdrop=t;let i=null;e.findScrollTarget=function(i){let n=i.clientX,s=i.clientY,r=t(i);for(;r;r=r.parentElement){if(!r.hasAttribute("data-lm-dragscroll"))continue;let t=0,i=0;r===document.body&&(t=window.pageXOffset,i=window.pageYOffset);let o=r.getBoundingClientRect(),a=o.top+i,l=o.left+t,h=l+o.width,c=a+o.height;if(n=h||s=c)continue;let d,u=n-l+1,p=s-a+1,f=h-n,m=c-s,g=Math.min(u,p,f,m);if(g>e.SCROLL_EDGE_SIZE)continue;switch(g){case m:d="bottom";break;case p:d="top";break;case f:d="right";break;case u:d="left";break;default:throw"unreachable"}let v,O=r.scrollWidth-r.clientWidth,b=r.scrollHeight-r.clientHeight;switch(d){case"top":v=b>0&&r.scrollTop>0;break;case"left":v=O>0&&r.scrollLeft>0;break;case"right":v=O>0&&r.scrollLeft0&&r.scrollTop{n===o&&e.cursorBackdrop.isConnected&&(document.removeEventListener("pointermove",r,!0),s.removeChild(e.cursorBackdrop))}))};let o=0;e.cursorBackdrop=function(){const e=document.createElement("div");return e.classList.add("lm-cursor-backdrop"),e}()}(Hf||(Hf={}));class Kf{constructor(e,t,i=[]){this.name=e,this._codes=t,this._keys=Kf.extractKeys(t),this._modifierKeys=Kf.convertToKeySet(i)}keys(){return Object.keys(this._keys)}isValidKey(e){return e in this._keys}isModifierKey(e){return e in this._modifierKeys}keyForKeydownEvent(e){return this._codes[e.keyCode]||""}}!function(e){e.extractKeys=function(e){let t=Object.create(null);for(let i in e)t[e[i]]=!0;return t},e.convertToKeySet=function(e){let t=Object(null);for(let i=0,n=e.length;i{this._commands.delete(e),this._commandChanged.emit({id:e,type:"removed"})}))}notifyCommandChanged(e){if(void 0!==e&&!this._commands.has(e))throw new Error(`Command '${e}' is not registered.`);this._commandChanged.emit({id:e,type:e?"changed":"many-changed"})}describedBy(e,t=Wf.JSONExt.emptyObject){var i;let n=this._commands.get(e);return Promise.resolve(null!==(i=null==n?void 0:n.describedBy.call(void 0,t))&&void 0!==i?i:{args:null})}label(e,t=Wf.JSONExt.emptyObject){var i;let n=this._commands.get(e);return null!==(i=null==n?void 0:n.label.call(void 0,t))&&void 0!==i?i:""}mnemonic(e,t=Wf.JSONExt.emptyObject){let i=this._commands.get(e);return i?i.mnemonic.call(void 0,t):-1}icon(e,t=Wf.JSONExt.emptyObject){var i;return null===(i=this._commands.get(e))||void 0===i?void 0:i.icon.call(void 0,t)}iconClass(e,t=Wf.JSONExt.emptyObject){let i=this._commands.get(e);return i?i.iconClass.call(void 0,t):""}iconLabel(e,t=Wf.JSONExt.emptyObject){let i=this._commands.get(e);return i?i.iconLabel.call(void 0,t):""}caption(e,t=Wf.JSONExt.emptyObject){let i=this._commands.get(e);return i?i.caption.call(void 0,t):""}usage(e,t=Wf.JSONExt.emptyObject){let i=this._commands.get(e);return i?i.usage.call(void 0,t):""}className(e,t=Wf.JSONExt.emptyObject){let i=this._commands.get(e);return i?i.className.call(void 0,t):""}dataset(e,t=Wf.JSONExt.emptyObject){let i=this._commands.get(e);return i?i.dataset.call(void 0,t):{}}isEnabled(e,t=Wf.JSONExt.emptyObject){let i=this._commands.get(e);return!!i&&i.isEnabled.call(void 0,t)}isToggled(e,t=Wf.JSONExt.emptyObject){let i=this._commands.get(e);return!!i&&i.isToggled.call(void 0,t)}isToggleable(e,t=Wf.JSONExt.emptyObject){let i=this._commands.get(e);return!!i&&i.isToggleable}isVisible(e,t=Wf.JSONExt.emptyObject){let i=this._commands.get(e);return!!i&&i.isVisible.call(void 0,t)}execute(e,t=Wf.JSONExt.emptyObject){let i,n=this._commands.get(e);if(!n)return Promise.reject(new Error(`Command '${e}' not registered.`));try{i=n.execute.call(void 0,t)}catch(e){i=Promise.reject(e)}let s=Promise.resolve(i);return this._commandExecuted.emit({id:e,args:t,result:s}),s}addKeyBinding(e){let t=tm.createKeyBinding(e);return this._keyBindings.push(t),this._keyBindingChanged.emit({binding:t,type:"added"}),new Yf.DisposableDelegate((()=>{jf.RO.removeFirstOf(this._keyBindings,t),this._keyBindingChanged.emit({binding:t,type:"removed"})}))}processKeydownEvent(e){if(this._replaying||lm.isModifierKeyPressed(e))return;let t=lm.keystrokeForKeydownEvent(e);if(!t)return this._replayKeydownEvents(),void this._clearPendingState();this._keystrokes.push(t);let{exact:i,partial:n}=tm.matchKeyBinding(this._keyBindings,this._keystrokes,e);return i||n?(e.preventDefault(),e.stopPropagation(),i&&!n?(this._executeKeyBinding(i),void this._clearPendingState()):(i&&(this._exactKeyMatch=i),this._keydownEvents.push(e),void this._startTimer())):(this._replayKeydownEvents(),void this._clearPendingState())}_startTimer(){this._clearTimer(),this._timerID=window.setTimeout((()=>{this._onPendingTimeout()}),tm.CHORD_TIMEOUT)}_clearTimer(){0!==this._timerID&&(clearTimeout(this._timerID),this._timerID=0)}_replayKeydownEvents(){0!==this._keydownEvents.length&&(this._replaying=!0,this._keydownEvents.forEach(tm.replayKeyEvent),this._replaying=!1)}_executeKeyBinding(e){let{command:t,args:i}=e;if(this.hasCommand(t)&&this.isEnabled(t,i))this.execute(t,i);else{let i=this.hasCommand(t)?"enabled":"registered",n=`Cannot execute key binding '${e.keys.join(", ")}':`,s=`command '${t}' is not ${i}.`;console.warn(`${n} ${s}`)}}_clearPendingState(){this._clearTimer(),this._exactKeyMatch=null,this._keystrokes.length=0,this._keydownEvents.length=0}_onPendingTimeout(){this._timerID=0,this._exactKeyMatch?this._executeKeyBinding(this._exactKeyMatch):this._replayKeydownEvents(),this._clearPendingState()}}!function(e){function t(e){let t="",i=!1,n=!1,s=!1,r=!1;for(let o of e.split(/\s+/))"Accel"===o?Rf.IS_MAC?n=!0:s=!0:"Alt"===o?i=!0:"Cmd"===o?n=!0:"Ctrl"===o?s=!0:"Shift"===o?r=!0:o.length>0&&(t=o);return{cmd:n,ctrl:s,alt:i,shift:r,key:t}}function i(e){let i="",n=t(e);return n.ctrl&&(i+="Ctrl "),n.alt&&(i+="Alt "),n.shift&&(i+="Shift "),n.cmd&&Rf.IS_MAC&&(i+="Cmd "),i+n.key}e.parseKeystroke=t,e.normalizeKeystroke=i,e.normalizeKeys=function(e){let t;return t=Rf.IS_WIN?e.winKeys||e.keys:Rf.IS_MAC?e.macKeys||e.keys:e.linuxKeys||e.keys,t.map(i)},e.formatKeystroke=function(e){return"string"==typeof e?i(e):e.map(i).join(", ");function i(e){let i=[],n=Rf.IS_MAC?" ":"+",s=t(e);return s.ctrl&&i.push("Ctrl"),s.alt&&i.push("Alt"),s.shift&&i.push("Shift"),Rf.IS_MAC&&s.cmd&&i.push("Cmd"),i.push(s.key),i.map(tm.formatKey).join(n)}},e.isModifierKeyPressed=function(e){let t=Zf(),i=t.keyForKeydownEvent(e);return t.isModifierKey(i)},e.keystrokeForKeydownEvent=function(e){let t=Zf(),i=t.keyForKeydownEvent(e);if(!i||t.isModifierKey(i))return"";let n=[];return e.ctrlKey&&n.push("Ctrl"),e.altKey&&n.push("Alt"),e.shiftKey&&n.push("Shift"),e.metaKey&&Rf.IS_MAC&&n.push("Cmd"),n.push(i),n.join(" ")}}(lm||(lm={})),function(e){e.CHORD_TIMEOUT=1e3,e.createCommand=function(e){return{execute:e.execute,describedBy:h("function"==typeof e.describedBy?e.describedBy:{args:null,...e.describedBy},(()=>({args:null}))),label:h(e.label,n),mnemonic:h(e.mnemonic,s),icon:h(e.icon,l),iconClass:h(e.iconClass,n),iconLabel:h(e.iconLabel,n),caption:h(e.caption,n),usage:h(e.usage,n),className:h(e.className,n),dataset:h(e.dataset,a),isEnabled:e.isEnabled||r,isToggled:e.isToggled||o,isToggleable:e.isToggleable||!!e.isToggled,isVisible:e.isVisible||r}},e.createKeyBinding=function(e){return{keys:lm.normalizeKeys(e),selector:c(e),command:e.command,args:e.args||Wf.JSONExt.emptyObject}},e.matchKeyBinding=function(e,t,i){let n=null,s=!1,r=1/0,o=0;for(let a=0,l=e.length;ar)continue;let p=Df.calculateSpecificity(l.selector);(!n||c=o)&&(n=l,r=c,o=p)}return{exact:n,partial:s}},e.replayKeyEvent=function(e){e.target.dispatchEvent(function(e){let t=document.createEvent("Event"),i=e.bubbles||!0,n=e.cancelable||!0;return t.initEvent(e.type||"keydown",i,n),t.key=e.key||"",t.keyCode=e.keyCode||0,t.which=e.keyCode||0,t.ctrlKey=e.ctrlKey||!1,t.altKey=e.altKey||!1,t.shiftKey=e.shiftKey||!1,t.metaKey=e.metaKey||!1,t.view=e.view||window,t}(e))},e.formatKey=function(e){return Rf.IS_MAC?t.hasOwnProperty(e)?t[e]:e:i.hasOwnProperty(e)?i[e]:e};const t={Backspace:"⌫",Tab:"⇥",Enter:"⏎",Shift:"⇧",Ctrl:"⌃",Alt:"⌥",Escape:"⎋",PageUp:"⇞",PageDown:"⇟",End:"↘",Home:"↖",ArrowLeft:"←",ArrowUp:"↑",ArrowRight:"→",ArrowDown:"↓",Delete:"⌦",Cmd:"⌘"},i={Escape:"Esc",PageUp:"Page Up",PageDown:"Page Down",ArrowLeft:"Left",ArrowUp:"Up",ArrowRight:"Right",ArrowDown:"Down",Delete:"Del"},n=()=>"",s=()=>-1,r=()=>!0,o=()=>!1,a=()=>({}),l=()=>{};function h(e,t){return void 0===e?t:"function"==typeof e?e:()=>e}function c(e){if(-1!==e.selector.indexOf(","))throw new Error(`Selector cannot contain commas: ${e.selector}`);if(!Df.isValid(e.selector))throw new Error(`Invalid selector: ${e.selector}`);return e.selector}function d(e,t){if(e.lengtht.length?2:1}function u(e,t){let i=t.target,n=t.currentTarget;for(let t=0;null!==i;i=i.parentElement,++t){if(i.hasAttribute("data-lm-suppress-shortcuts"))return-1;if(Df.matches(i,e))return t;if(i===n)return-1}return-1}}(tm||(tm={}));class hm{constructor(e){this.type="text",this.content=e}}class cm{constructor(e,t,i,n){this.type="element",this.tag=e,this.attrs=t,this.children=i,this.renderer=n}}function dm(e){let t,i={},n=[];for(let e=1,r=arguments.length;e=n;--r){const n=t[r],o=s?e.lastChild:e.childNodes[r];"text"===n.type||(n.renderer&&n.renderer.unrender?n.renderer.unrender(o,{attrs:n.attrs,children:n.children}):i(o,n.children,0,!1)),s&&e.removeChild(o)}}e.hostMap=new WeakMap,e.asContentArray=function(e){return e?e instanceof Array?e:[e]:[]},e.createDOMNode=t,e.updateContent=function e(n,r,o){if(r===o)return;let a=function(e,t){let i=e.firstChild,n=Object.create(null);for(let e of t)"element"===e.type&&e.attrs.key&&(n[e.attrs.key]={vNode:e,element:i}),i=i.nextSibling;return n}(n,r),l=r.slice(),h=n.firstChild,c=o.length;for(let i=0;i=l.length){t(o[i],n);continue}let r=l[i],c=o[i];if(r===c){h=h.nextSibling;continue}if("text"===r.type&&"text"===c.type){h.textContent!==c.content&&(h.textContent=c.content),h=h.nextSibling;continue}if("text"===r.type||"text"===c.type){jf.RO.insert(l,i,c),t(c,n,h);continue}if(!r.renderer!=!c.renderer){jf.RO.insert(l,i,c),t(c,n,h);continue}let d=c.attrs.key;if(d&&d in a){let e=a[d];e.vNode!==r&&(jf.RO.move(l,l.indexOf(e.vNode,i+1),i),n.insertBefore(e.element,h),r=e.vNode,h=e.element)}if(r===c){h=h.nextSibling;continue}let u=r.attrs.key;u&&u!==d?(jf.RO.insert(l,i,c),t(c,n,h)):r.tag===c.tag?(s(h,r.attrs,c.attrs),c.renderer?c.renderer.render(h,{attrs:c.attrs,children:c.children}):e(h,r.children,c.children),h=h.nextSibling):(jf.RO.insert(l,i,c),t(c,n,h))}i(n,l,c,!0)};const n={key:!0,className:!0,htmlFor:!0,dataset:!0,style:!0};function s(e,t,i){if(t===i)return;let s;for(s in t)s in n||s in i||("on"===s.substr(0,2)?e[s]=null:e.removeAttribute(s));for(s in i)s in n||t[s]===i[s]||("on"===s.substr(0,2)?e[s]=i[s]:e.setAttribute(s,i[s]));t.className!==i.className&&(void 0!==i.className?e.setAttribute("class",i.className):e.removeAttribute("class")),t.htmlFor!==i.htmlFor&&(void 0!==i.htmlFor?e.setAttribute("for",i.htmlFor):e.removeAttribute("for")),t.dataset!==i.dataset&&function(e,t,i){for(let n in t)n in i||e.removeAttribute(`data-${n}`);for(let n in i)t[n]!==i[n]&&e.setAttribute(`data-${n}`,i[n])}(e,t.dataset||{},i.dataset||{}),t.style!==i.style&&function(e,t,i){let n,s=e.style;for(n in t)n in i||(s[n]="");for(n in i)t[n]!==i[n]&&(s[n]=i[n])}(e,t.style||{},i.style||{})}}(nm||(nm={}));class um{constructor(){this.sizeHint=0,this.minSize=0,this.maxSize=1/0,this.stretch=1,this.size=0,this.done=!1}}!function(e){e.calc=function(e,t){let i=e.length;if(0===i)return t;let n=0,s=0,r=0,o=0,a=0;for(let t=0;t0&&(o+=i.stretch,a++)}if(t===r)return 0;if(t<=n){for(let t=0;t=s){for(let t=0;t0&&n>l;){let t=n,s=o;for(let r=0;r0&&n>l;){let t=n/h;for(let s=0;s0&&n>l;){let t=n,s=o;for(let r=0;r=i.maxSize?(n-=i.maxSize-i.size,o-=i.stretch,i.size=i.maxSize,i.done=!0,h--,a--):(n-=l,i.size+=l)}}for(;h>0&&n>l;){let t=n/h;for(let s=0;s=i.maxSize?(n-=i.maxSize-i.size,i.size=i.maxSize,i.done=!0,h--):(n-=t,i.size+=t))}}}return 0},e.adjust=function(e,t,i){0!==e.length&&0!==i&&(i>0?function(e,t,i){let n=0;for(let i=0;i<=t;++i){let t=e[i];n+=t.maxSize-t.size}let s=0;for(let i=t+1,n=e.length;i=0&&r>0;--i){let t=e[i],n=t.maxSize-t.size;n>=r?(t.sizeHint=t.size+r,r=0):(t.sizeHint=t.size+n,r-=n)}let o=i;for(let i=t+1,n=e.length;i0;++i){let t=e[i],n=t.size-t.minSize;n>=o?(t.sizeHint=t.size-o,o=0):(t.sizeHint=t.size-n,o-=n)}}(e,t,i):function(e,t,i){let n=0;for(let i=t+1,s=e.length;i0;++i){let t=e[i],n=t.maxSize-t.size;n>=r?(t.sizeHint=t.size+r,r=0):(t.sizeHint=t.size+n,r-=n)}let o=i;for(let i=t;i>=0&&o>0;--i){let t=e[i],n=t.size-t.minSize;n>=o?(t.sizeHint=t.size-o,o=0):(t.sizeHint=t.size-n,o-=n)}}(e,t,-i))}}(sm||(sm={}));class pm{constructor(e){this._label="",this._caption="",this._mnemonic=-1,this._icon=void 0,this._iconClass="",this._iconLabel="",this._className="",this._closable=!1,this._changed=new zf.Signal(this),this._isDisposed=!1,this.owner=e.owner,void 0!==e.label&&(this._label=e.label),void 0!==e.mnemonic&&(this._mnemonic=e.mnemonic),void 0!==e.icon&&(this._icon=e.icon),void 0!==e.iconClass&&(this._iconClass=e.iconClass),void 0!==e.iconLabel&&(this._iconLabel=e.iconLabel),void 0!==e.caption&&(this._caption=e.caption),void 0!==e.className&&(this._className=e.className),void 0!==e.closable&&(this._closable=e.closable),this._dataset=e.dataset||{}}get changed(){return this._changed}get label(){return this._label}set label(e){this._label!==e&&(this._label=e,this._changed.emit(void 0))}get mnemonic(){return this._mnemonic}set mnemonic(e){this._mnemonic!==e&&(this._mnemonic=e,this._changed.emit(void 0))}get icon(){return this._icon}set icon(e){this._icon!==e&&(this._icon=e,this._changed.emit(void 0))}get iconClass(){return this._iconClass}set iconClass(e){this._iconClass!==e&&(this._iconClass=e,this._changed.emit(void 0))}get iconLabel(){return this._iconLabel}set iconLabel(e){this._iconLabel!==e&&(this._iconLabel=e,this._changed.emit(void 0))}get caption(){return this._caption}set caption(e){this._caption!==e&&(this._caption=e,this._changed.emit(void 0))}get className(){return this._className}set className(e){this._className!==e&&(this._className=e,this._changed.emit(void 0))}get closable(){return this._closable}set closable(e){this._closable!==e&&(this._closable=e,this._changed.emit(void 0))}get dataset(){return this._dataset}set dataset(e){this._dataset!==e&&(this._dataset=e,this._changed.emit(void 0))}get isDisposed(){return this._isDisposed}dispose(){this.isDisposed||(this._isDisposed=!0,zf.Signal.clearData(this))}}class fm{constructor(e={}){this._flags=0,this._layout=null,this._parent=null,this._disposed=new zf.Signal(this),this._hiddenMode=fm.HiddenMode.Display,this.node=rm.createNode(e),this.addClass("lm-Widget")}dispose(){this.isDisposed||(this.setFlag(fm.Flag.IsDisposed),this._disposed.emit(void 0),this.parent?this.parent=null:this.isAttached&&fm.detach(this),this._layout&&(this._layout.dispose(),this._layout=null),this.title.dispose(),zf.Signal.clearData(this),Lf.clearData(this),Xf.AttachedProperty.clearData(this))}get disposed(){return this._disposed}get isDisposed(){return this.testFlag(fm.Flag.IsDisposed)}get isAttached(){return this.testFlag(fm.Flag.IsAttached)}get isHidden(){return this.testFlag(fm.Flag.IsHidden)}get isVisible(){return this.testFlag(fm.Flag.IsVisible)}get title(){return rm.titleProperty.get(this)}get id(){return this.node.id}set id(e){this.node.id=e}get dataset(){return this.node.dataset}get hiddenMode(){return this._hiddenMode}set hiddenMode(e){this._hiddenMode!==e&&(this.isHidden&&this._toggleHidden(!1),e==fm.HiddenMode.Scale?this.node.style.willChange="transform":this.node.style.willChange="auto",this._hiddenMode=e,this.isHidden&&this._toggleHidden(!0))}get parent(){return this._parent}set parent(e){if(this._parent!==e){if(e&&this.contains(e))throw new Error("Invalid parent widget.");if(this._parent&&!this._parent.isDisposed){let e=new fm.ChildMessage("child-removed",this);Lf.sendMessage(this._parent,e)}if(this._parent=e,this._parent&&!this._parent.isDisposed){let e=new fm.ChildMessage("child-added",this);Lf.sendMessage(this._parent,e)}this.isDisposed||Lf.sendMessage(this,fm.Msg.ParentChanged)}}get layout(){return this._layout}set layout(e){if(this._layout!==e){if(this.testFlag(fm.Flag.DisallowLayout))throw new Error("Cannot set widget layout.");if(this._layout)throw new Error("Cannot change widget layout.");if(e.parent)throw new Error("Cannot change layout parent.");this._layout=e,e.parent=this}}*children(){this._layout&&(yield*this._layout)}contains(e){for(let t=e;t;t=t._parent)if(t===this)return!0;return!1}hasClass(e){return this.node.classList.contains(e)}addClass(e){this.node.classList.add(e)}removeClass(e){this.node.classList.remove(e)}toggleClass(e,t){return!0===t?(this.node.classList.add(e),!0):!1===t?(this.node.classList.remove(e),!1):this.node.classList.toggle(e)}update(){Lf.postMessage(this,fm.Msg.UpdateRequest)}fit(){Lf.postMessage(this,fm.Msg.FitRequest)}activate(){Lf.postMessage(this,fm.Msg.ActivateRequest)}close(){Lf.sendMessage(this,fm.Msg.CloseRequest)}show(){if(this.testFlag(fm.Flag.IsHidden)&&(!this.isAttached||this.parent&&!this.parent.isVisible||Lf.sendMessage(this,fm.Msg.BeforeShow),this.clearFlag(fm.Flag.IsHidden),this._toggleHidden(!1),!this.isAttached||this.parent&&!this.parent.isVisible||Lf.sendMessage(this,fm.Msg.AfterShow),this.parent)){let e=new fm.ChildMessage("child-shown",this);Lf.sendMessage(this.parent,e)}}hide(){if(!this.testFlag(fm.Flag.IsHidden)&&(!this.isAttached||this.parent&&!this.parent.isVisible||Lf.sendMessage(this,fm.Msg.BeforeHide),this.setFlag(fm.Flag.IsHidden),this._toggleHidden(!0),!this.isAttached||this.parent&&!this.parent.isVisible||Lf.sendMessage(this,fm.Msg.AfterHide),this.parent)){let e=new fm.ChildMessage("child-hidden",this);Lf.sendMessage(this.parent,e)}}setHidden(e){e?this.hide():this.show()}testFlag(e){return 0!=(this._flags&e)}setFlag(e){this._flags|=e}clearFlag(e){this._flags&=~e}processMessage(e){switch(e.type){case"resize":this.notifyLayout(e),this.onResize(e);break;case"update-request":this.notifyLayout(e),this.onUpdateRequest(e);break;case"fit-request":this.notifyLayout(e),this.onFitRequest(e);break;case"before-show":this.notifyLayout(e),this.onBeforeShow(e);break;case"after-show":this.setFlag(fm.Flag.IsVisible),this.notifyLayout(e),this.onAfterShow(e);break;case"before-hide":this.notifyLayout(e),this.onBeforeHide(e);break;case"after-hide":this.clearFlag(fm.Flag.IsVisible),this.notifyLayout(e),this.onAfterHide(e);break;case"before-attach":this.notifyLayout(e),this.onBeforeAttach(e);break;case"after-attach":this.isHidden||this.parent&&!this.parent.isVisible||this.setFlag(fm.Flag.IsVisible),this.setFlag(fm.Flag.IsAttached),this.notifyLayout(e),this.onAfterAttach(e);break;case"before-detach":this.notifyLayout(e),this.onBeforeDetach(e);break;case"after-detach":this.clearFlag(fm.Flag.IsVisible),this.clearFlag(fm.Flag.IsAttached),this.notifyLayout(e),this.onAfterDetach(e);break;case"activate-request":this.notifyLayout(e),this.onActivateRequest(e);break;case"close-request":this.notifyLayout(e),this.onCloseRequest(e);break;case"child-added":this.notifyLayout(e),this.onChildAdded(e);break;case"child-removed":this.notifyLayout(e),this.onChildRemoved(e);break;default:this.notifyLayout(e)}}notifyLayout(e){this._layout&&this._layout.processParentMessage(e)}onCloseRequest(e){this.parent?this.parent=null:this.isAttached&&fm.detach(this)}onResize(e){}onUpdateRequest(e){}onFitRequest(e){}onActivateRequest(e){}onBeforeShow(e){}onAfterShow(e){}onBeforeHide(e){}onAfterHide(e){}onBeforeAttach(e){}onAfterAttach(e){}onBeforeDetach(e){}onAfterDetach(e){}onChildAdded(e){}onChildRemoved(e){}_toggleHidden(e){if(e)switch(this._hiddenMode){case fm.HiddenMode.Display:this.addClass("lm-mod-hidden");break;case fm.HiddenMode.Scale:this.node.style.transform="scale(0)",this.node.setAttribute("aria-hidden","true");break;case fm.HiddenMode.ContentVisibility:this.node.style.contentVisibility="hidden",this.node.style.zIndex="-1"}else switch(this._hiddenMode){case fm.HiddenMode.Display:this.removeClass("lm-mod-hidden");break;case fm.HiddenMode.Scale:this.node.style.transform="",this.node.removeAttribute("aria-hidden");break;case fm.HiddenMode.ContentVisibility:this.node.style.contentVisibility="",this.node.style.zIndex=""}}}!function(e){var t,i,n;(t=e.HiddenMode||(e.HiddenMode={}))[t.Display=0]="Display",t[t.Scale=1]="Scale",t[t.ContentVisibility=2]="ContentVisibility",(i=e.Flag||(e.Flag={}))[i.IsDisposed=1]="IsDisposed",i[i.IsAttached=2]="IsAttached",i[i.IsHidden=4]="IsHidden",i[i.IsVisible=8]="IsVisible",i[i.DisallowLayout=16]="DisallowLayout",(n=e.Msg||(e.Msg={})).BeforeShow=new Uf("before-show"),n.AfterShow=new Uf("after-show"),n.BeforeHide=new Uf("before-hide"),n.AfterHide=new Uf("after-hide"),n.BeforeAttach=new Uf("before-attach"),n.AfterAttach=new Uf("after-attach"),n.BeforeDetach=new Uf("before-detach"),n.AfterDetach=new Uf("after-detach"),n.ParentChanged=new Uf("parent-changed"),n.UpdateRequest=new Ff("update-request"),n.FitRequest=new Ff("fit-request"),n.ActivateRequest=new Ff("activate-request"),n.CloseRequest=new Ff("close-request"),e.ChildMessage=class extends Uf{constructor(e,t){super(e),this.child=t}};class s extends Uf{constructor(e,t){super("resize"),this.width=e,this.height=t}}e.ResizeMessage=s,function(e){e.UnknownSize=new e(-1,-1)}(s=e.ResizeMessage||(e.ResizeMessage={})),e.attach=function(t,i,n=null){if(t.parent)throw new Error("Cannot attach a child widget.");if(t.isAttached||t.node.isConnected)throw new Error("Widget is already attached.");if(!i.isConnected)throw new Error("Host is not attached.");Lf.sendMessage(t,e.Msg.BeforeAttach),i.insertBefore(t.node,n),Lf.sendMessage(t,e.Msg.AfterAttach)},e.detach=function(t){if(t.parent)throw new Error("Cannot detach a child widget.");if(!t.isAttached||!t.node.isConnected)throw new Error("Widget is not attached.");Lf.sendMessage(t,e.Msg.BeforeDetach),t.node.parentNode.removeChild(t.node),Lf.sendMessage(t,e.Msg.AfterDetach)}}(fm||(fm={})),function(e){e.titleProperty=new Xf.AttachedProperty({name:"title",create:e=>new pm({owner:e})}),e.createNode=function(e){return e.node||document.createElement(e.tag||"div")}}(rm||(rm={}));class mm{constructor(e={}){this._disposed=!1,this._parent=null,this._fitPolicy=e.fitPolicy||"set-min-size"}dispose(){this._parent=null,this._disposed=!0,zf.Signal.clearData(this),Xf.AttachedProperty.clearData(this)}get isDisposed(){return this._disposed}get parent(){return this._parent}set parent(e){if(this._parent!==e){if(this._parent)throw new Error("Cannot change parent widget.");if(e.layout!==this)throw new Error("Invalid parent widget.");this._parent=e,this.init()}}get fitPolicy(){return this._fitPolicy}set fitPolicy(e){if(this._fitPolicy!==e&&(this._fitPolicy=e,this._parent)){let e=this._parent.node.style;e.minWidth="",e.minHeight="",e.maxWidth="",e.maxHeight="",this._parent.fit()}}processParentMessage(e){switch(e.type){case"resize":this.onResize(e);break;case"update-request":this.onUpdateRequest(e);break;case"fit-request":this.onFitRequest(e);break;case"before-show":this.onBeforeShow(e);break;case"after-show":this.onAfterShow(e);break;case"before-hide":this.onBeforeHide(e);break;case"after-hide":this.onAfterHide(e);break;case"before-attach":this.onBeforeAttach(e);break;case"after-attach":this.onAfterAttach(e);break;case"before-detach":this.onBeforeDetach(e);break;case"after-detach":this.onAfterDetach(e);break;case"child-removed":this.onChildRemoved(e);break;case"child-shown":this.onChildShown(e);break;case"child-hidden":this.onChildHidden(e)}}init(){for(const e of this)e.parent=this.parent}onResize(e){for(const e of this)Lf.sendMessage(e,fm.ResizeMessage.UnknownSize)}onUpdateRequest(e){for(const e of this)Lf.sendMessage(e,fm.ResizeMessage.UnknownSize)}onBeforeAttach(e){for(const t of this)Lf.sendMessage(t,e)}onAfterAttach(e){for(const t of this)Lf.sendMessage(t,e)}onBeforeDetach(e){for(const t of this)Lf.sendMessage(t,e)}onAfterDetach(e){for(const t of this)Lf.sendMessage(t,e)}onBeforeShow(e){for(const t of this)t.isHidden||Lf.sendMessage(t,e)}onAfterShow(e){for(const t of this)t.isHidden||Lf.sendMessage(t,e)}onBeforeHide(e){for(const t of this)t.isHidden||Lf.sendMessage(t,e)}onAfterHide(e){for(const t of this)t.isHidden||Lf.sendMessage(t,e)}onChildRemoved(e){this.removeWidget(e.child)}onFitRequest(e){}onChildShown(e){}onChildHidden(e){}}!function(e){e.getHorizontalAlignment=function(e){return om.horizontalAlignmentProperty.get(e)},e.setHorizontalAlignment=function(e,t){om.horizontalAlignmentProperty.set(e,t)},e.getVerticalAlignment=function(e){return om.verticalAlignmentProperty.get(e)},e.setVerticalAlignment=function(e,t){om.verticalAlignmentProperty.set(e,t)}}(mm||(mm={}));class gm{constructor(e){this._top=NaN,this._left=NaN,this._width=NaN,this._height=NaN,this._minWidth=0,this._minHeight=0,this._maxWidth=1/0,this._maxHeight=1/0,this._disposed=!1,this.widget=e,this.widget.node.style.position="absolute",this.widget.node.style.contain="strict"}dispose(){if(this._disposed)return;this._disposed=!0;let e=this.widget.node.style;e.position="",e.top="",e.left="",e.width="",e.height="",e.contain=""}get minWidth(){return this._minWidth}get minHeight(){return this._minHeight}get maxWidth(){return this._maxWidth}get maxHeight(){return this._maxHeight}get isDisposed(){return this._disposed}get isHidden(){return this.widget.isHidden}get isVisible(){return this.widget.isVisible}get isAttached(){return this.widget.isAttached}fit(){let e=Af.sizeLimits(this.widget.node);this._minWidth=e.minWidth,this._minHeight=e.minHeight,this._maxWidth=e.maxWidth,this._maxHeight=e.maxHeight}update(e,t,i,n){let s=Math.max(this._minWidth,Math.min(i,this._maxWidth)),r=Math.max(this._minHeight,Math.min(n,this._maxHeight));if(s"center",changed:t}),e.verticalAlignmentProperty=new Xf.AttachedProperty({name:"verticalAlignment",create:()=>"top",changed:t})}(om||(om={}));class vm extends mm{constructor(){super(...arguments),this._widgets=[]}dispose(){for(;this._widgets.length>0;)this._widgets.pop().dispose();super.dispose()}get widgets(){return this._widgets}*[Symbol.iterator](){yield*this._widgets}addWidget(e){this.insertWidget(this._widgets.length,e)}insertWidget(e,t){t.parent=this.parent;let i=this._widgets.indexOf(t),n=Math.max(0,Math.min(e,this._widgets.length));if(-1===i)return jf.RO.insert(this._widgets,n,t),void(this.parent&&this.attachWidget(n,t));n===this._widgets.length&&n--,i!==n&&(jf.RO.move(this._widgets,i,n),this.parent&&this.moveWidget(i,n,t))}removeWidget(e){this.removeWidgetAt(this._widgets.indexOf(e))}removeWidgetAt(e){let t=jf.RO.removeAt(this._widgets,e);t&&this.parent&&this.detachWidget(e,t)}init(){super.init();let e=0;for(const t of this)this.attachWidget(e++,t)}attachWidget(e,t){let i=this.parent.node.children[e];this.parent.isAttached&&Lf.sendMessage(t,fm.Msg.BeforeAttach),this.parent.node.insertBefore(t.node,i),this.parent.isAttached&&Lf.sendMessage(t,fm.Msg.AfterAttach)}moveWidget(e,t,i){this.parent.isAttached&&Lf.sendMessage(i,fm.Msg.BeforeDetach),this.parent.node.removeChild(i.node),this.parent.isAttached&&Lf.sendMessage(i,fm.Msg.AfterDetach);let n=this.parent.node.children[t];this.parent.isAttached&&Lf.sendMessage(i,fm.Msg.BeforeAttach),this.parent.node.insertBefore(i.node,n),this.parent.isAttached&&Lf.sendMessage(i,fm.Msg.AfterAttach)}detachWidget(e,t){this.parent.isAttached&&Lf.sendMessage(t,fm.Msg.BeforeDetach),this.parent.node.removeChild(t.node),this.parent.isAttached&&Lf.sendMessage(t,fm.Msg.AfterDetach)}}!function(e){e.clampDimension=function(e){return Math.max(0,Math.floor(e))}}(am||(am={}));var Om,bm,_m,ym,wm,xm,Sm,km,Tm,Cm,Pm=am;class Mm extends vm{constructor(e){super(),this.widgetOffset=0,this._fixed=0,this._spacing=4,this._dirty=!1,this._hasNormedSizes=!1,this._sizers=[],this._items=[],this._handles=[],this._box=null,this._alignment="start",this._orientation="horizontal",this.renderer=e.renderer,void 0!==e.orientation&&(this._orientation=e.orientation),void 0!==e.alignment&&(this._alignment=e.alignment),void 0!==e.spacing&&(this._spacing=am.clampDimension(e.spacing))}dispose(){for(const e of this._items)e.dispose();this._box=null,this._items.length=0,this._sizers.length=0,this._handles.length=0,super.dispose()}get orientation(){return this._orientation}set orientation(e){this._orientation!==e&&(this._orientation=e,this.parent&&(this.parent.dataset.orientation=e,this.parent.fit()))}get alignment(){return this._alignment}set alignment(e){this._alignment!==e&&(this._alignment=e,this.parent&&(this.parent.dataset.alignment=e,this.parent.update()))}get spacing(){return this._spacing}set spacing(e){e=am.clampDimension(e),this._spacing!==e&&(this._spacing=e,this.parent&&this.parent.fit())}get handles(){return this._handles}absoluteSizes(){return this._sizers.map((e=>e.size))}relativeSizes(){return Om.normalize(this._sizers.map((e=>e.size)))}setRelativeSizes(e,t=!0){let i=this._sizers.length,n=e.slice(0,i);for(;n.length0&&(e.sizeHint=e.size);sm.adjust(this._sizers,e,i),this.parent&&this.parent.update()}}init(){this.parent.dataset.orientation=this.orientation,this.parent.dataset.alignment=this.alignment,super.init()}attachWidget(e,t){let i=new gm(t),n=Om.createHandle(this.renderer),s=Om.averageSize(this._sizers),r=Om.createSizer(s);jf.RO.insert(this._items,e,i),jf.RO.insert(this._sizers,e,r),jf.RO.insert(this._handles,e,n),this.parent.isAttached&&Lf.sendMessage(t,fm.Msg.BeforeAttach),this.parent.node.appendChild(t.node),this.parent.node.appendChild(n),this.parent.isAttached&&Lf.sendMessage(t,fm.Msg.AfterAttach),this.parent.fit()}moveWidget(e,t,i){jf.RO.move(this._items,e,t),jf.RO.move(this._sizers,e,t),jf.RO.move(this._handles,e,t),this.parent.fit()}detachWidget(e,t){let i=jf.RO.removeAt(this._items,e),n=jf.RO.removeAt(this._handles,e);jf.RO.removeAt(this._sizers,e),this.parent.isAttached&&Lf.sendMessage(t,fm.Msg.BeforeDetach),this.parent.node.removeChild(t.node),this.parent.node.removeChild(n),this.parent.isAttached&&Lf.sendMessage(t,fm.Msg.AfterDetach),i.dispose(),this.parent.fit()}onBeforeShow(e){super.onBeforeShow(e),this.parent.update()}onBeforeAttach(e){super.onBeforeAttach(e),this.parent.fit()}onChildShown(e){this.parent.fit()}onChildHidden(e){this.parent.fit()}onResize(e){this.parent.isVisible&&this._update(e.width,e.height)}onUpdateRequest(e){this.parent.isVisible&&this._update(-1,-1)}onFitRequest(e){this.parent.isAttached&&this._fit()}updateItemPosition(e,t,i,n,s,r,o){const a=this._items[e];if(a.isHidden)return;let l=this._handles[e].style;t?(i+=this.widgetOffset,a.update(i,n,o,s),i+=o,l.top=`${n}px`,l.left=`${i}px`,l.width=`${this._spacing}px`,l.height=`${s}px`):(n+=this.widgetOffset,a.update(i,n,r,o),n+=o,l.top=`${n}px`,l.left=`${i}px`,l.width=`${r}px`,l.height=`${this._spacing}px`)}_fit(){let e=0,t=-1;for(let i=0,n=this._items.length;i0&&(r.sizeHint=r.size),t.isHidden?(r.minSize=0,r.maxSize=0):(t.fit(),r.stretch=Mm.getStretch(t.widget),i?(r.minSize=t.minWidth,r.maxSize=t.maxWidth,n+=t.minWidth,s=Math.max(s,t.minHeight)):(r.minSize=t.minHeight,r.maxSize=t.maxHeight,s+=t.minHeight,n=Math.max(n,t.minWidth)))}let r=this._box=Af.boxSizing(this.parent.node);n+=r.horizontalSum,s+=r.verticalSum;let o=this.parent.node.style;o.minWidth=`${n}px`,o.minHeight=`${s}px`,this._dirty=!0,this.parent.parent&&Lf.sendMessage(this.parent.parent,fm.Msg.FitRequest),this._dirty&&Lf.sendMessage(this.parent,fm.Msg.UpdateRequest)}_update(e,t){this._dirty=!1;let i=0;for(let e=0,t=this._items.length;e0){let e;if(e=h?Math.max(0,r-this._fixed):Math.max(0,o-this._fixed),this._hasNormedSizes){for(let t of this._sizers)t.sizeHint*=e;this._hasNormedSizes=!1}let t=sm.calc(this._sizers,e);if(t>0)switch(this._alignment){case"start":break;case"center":a=0,l=t/2;break;case"end":a=0,l=t;break;case"justify":a=t/i,l=0;break;default:throw"unreachable"}}for(let e=0,t=this._items.length;e0,coerce:(e,t)=>Math.max(0,Math.floor(t)),changed:function(e){e.parent&&e.parent.layout instanceof Mm&&e.parent.fit()}}),e.createSizer=function(e){let t=new um;return t.sizeHint=Math.floor(e),t},e.createHandle=function(e){let t=e.createHandle();return t.style.position="absolute",t.style.contain="style",t},e.averageSize=function(e){return e.reduce(((e,t)=>e+t.size),0)/e.length||0},e.normalize=function(e){let t=e.length;if(0===t)return[];let i=e.reduce(((e,t)=>e+Math.abs(t)),0);return 0===i?e.map((e=>1/t)):e.map((e=>e/i))}}(Om||(Om={}));class Em extends Mm{constructor(e){super({...e,orientation:e.orientation||"vertical"}),this._titles=[],this.titleSpace=e.titleSpace||22}get titleSpace(){return this.widgetOffset}set titleSpace(e){e=Pm.clampDimension(e),this.widgetOffset!==e&&(this.widgetOffset=e,this.parent&&this.parent.fit())}get titles(){return this._titles}dispose(){this.isDisposed||(this._titles.length=0,super.dispose())}updateTitle(e,t){const i=this._titles[e],n=i.classList.contains("lm-mod-expanded"),s=bm.createTitle(this.renderer,t.title,n);this._titles[e]=s,this.parent.node.replaceChild(s,i)}insertWidget(e,t){t.id||(t.id=`id-${Wf.UUID.uuid4()}`),super.insertWidget(e,t)}attachWidget(e,t){const i=bm.createTitle(this.renderer,t.title);jf.RO.insert(this._titles,e,i),this.parent.node.appendChild(i),t.node.setAttribute("role","region"),t.node.setAttribute("aria-labelledby",i.id),super.attachWidget(e,t)}moveWidget(e,t,i){jf.RO.move(this._titles,e,t),super.moveWidget(e,t,i)}detachWidget(e,t){const i=jf.RO.removeAt(this._titles,e);this.parent.node.removeChild(i),super.detachWidget(e,t)}updateItemPosition(e,t,i,n,s,r,o){const a=this._titles[e].style;a.top=`${n}px`,a.left=`${i}px`,a.height=`${this.widgetOffset}px`,a.width=t?`${s}px`:`${r}px`,super.updateItemPosition(e,t,i,n,s,r,o)}}!function(e){e.createTitle=function(e,t,i=!0){const n=e.createSectionTitle(t);return n.style.position="absolute",n.style.contain="strict",n.setAttribute("aria-label",`${t.label} Section`),n.setAttribute("aria-expanded",i?"true":"false"),n.setAttribute("aria-controls",t.owner.id),i&&n.classList.add("lm-mod-expanded"),n}}(bm||(bm={}));class Am extends fm{constructor(e={}){super(),this.addClass("lm-Panel"),this.layout=_m.createLayout(e)}get widgets(){return this.layout.widgets}addWidget(e){this.layout.addWidget(e)}insertWidget(e,t){this.layout.insertWidget(e,t)}}!function(e){e.createLayout=function(e){return e.layout||new vm}}(_m||(_m={}));class Rm extends Am{constructor(e={}){super({layout:ym.createLayout(e)}),this._handleMoved=new zf.Signal(this),this._pressData=null,this.addClass("lm-SplitPanel")}dispose(){this._releaseMouse(),super.dispose()}get orientation(){return this.layout.orientation}set orientation(e){this.layout.orientation=e}get alignment(){return this.layout.alignment}set alignment(e){this.layout.alignment=e}get spacing(){return this.layout.spacing}set spacing(e){this.layout.spacing=e}get renderer(){return this.layout.renderer}get handleMoved(){return this._handleMoved}get handles(){return this.layout.handles}relativeSizes(){return this.layout.relativeSizes()}setRelativeSizes(e,t=!0){this.layout.setRelativeSizes(e,t)}handleEvent(e){switch(e.type){case"pointerdown":this._evtPointerDown(e);break;case"pointermove":this._evtPointerMove(e);break;case"pointerup":this._evtPointerUp(e);break;case"keydown":this._evtKeyDown(e);break;case"contextmenu":e.preventDefault(),e.stopPropagation()}}onBeforeAttach(e){this.node.addEventListener("pointerdown",this)}onAfterDetach(e){this.node.removeEventListener("pointerdown",this),this._releaseMouse()}onChildAdded(e){e.child.addClass("lm-SplitPanel-child"),this._releaseMouse()}onChildRemoved(e){e.child.removeClass("lm-SplitPanel-child"),this._releaseMouse()}_evtKeyDown(e){this._pressData&&(e.preventDefault(),e.stopPropagation()),27===e.keyCode&&this._releaseMouse()}_evtPointerDown(e){if(0!==e.button)return;let t,i=this.layout,n=jf.RO.findFirstIndex(i.handles,(t=>t.contains(e.target)));if(-1===n)return;e.preventDefault(),e.stopPropagation(),document.addEventListener("pointerup",this,!0),document.addEventListener("pointermove",this,!0),document.addEventListener("keydown",this,!0),document.addEventListener("contextmenu",this,!0);let s=i.handles[n],r=s.getBoundingClientRect();t="horizontal"===i.orientation?e.clientX-r.left:e.clientY-r.top;let o=window.getComputedStyle(s),a=Gf.overrideCursor(o.cursor);this._pressData={index:n,delta:t,override:a}}_evtPointerMove(e){let t;e.preventDefault(),e.stopPropagation();let i=this.layout,n=this.node.getBoundingClientRect();t="horizontal"===i.orientation?e.clientX-n.left-this._pressData.delta:e.clientY-n.top-this._pressData.delta,i.moveHandle(this._pressData.index,t)}_evtPointerUp(e){0===e.button&&(e.preventDefault(),e.stopPropagation(),this._releaseMouse())}_releaseMouse(){this._pressData&&(this._pressData.override.dispose(),this._pressData=null,this._handleMoved.emit(),document.removeEventListener("keydown",this,!0),document.removeEventListener("pointerup",this,!0),document.removeEventListener("pointermove",this,!0),document.removeEventListener("contextmenu",this,!0))}}!function(e){class t{createHandle(){let e=document.createElement("div");return e.className="lm-SplitPanel-handle",e}}e.Renderer=t,e.defaultRenderer=new t,e.getStretch=function(e){return Mm.getStretch(e)},e.setStretch=function(e,t){Mm.setStretch(e,t)}}(Rm||(Rm={})),function(e){e.createLayout=function(e){return e.layout||new Mm({renderer:e.renderer||Rm.defaultRenderer,orientation:e.orientation,alignment:e.alignment,spacing:e.spacing})}}(ym||(ym={}));class Dm extends Rm{constructor(e={}){super({...e,layout:wm.createLayout(e)}),this._widgetSizesCache=new WeakMap,this._expansionToggled=new zf.Signal(this),this.addClass("lm-AccordionPanel")}get renderer(){return this.layout.renderer}get titleSpace(){return this.layout.titleSpace}set titleSpace(e){this.layout.titleSpace=e}get titles(){return this.layout.titles}get expansionToggled(){return this._expansionToggled}addWidget(e){super.addWidget(e),e.title.changed.connect(this._onTitleChanged,this)}collapse(e){const t=this.layout.widgets[e];t&&!t.isHidden&&this._toggleExpansion(e)}expand(e){const t=this.layout.widgets[e];t&&t.isHidden&&this._toggleExpansion(e)}insertWidget(e,t){super.insertWidget(e,t),t.title.changed.connect(this._onTitleChanged,this)}handleEvent(e){switch(super.handleEvent(e),e.type){case"click":this._evtClick(e);break;case"keydown":this._eventKeyDown(e)}}onBeforeAttach(e){this.node.addEventListener("click",this),this.node.addEventListener("keydown",this),super.onBeforeAttach(e)}onAfterDetach(e){super.onAfterDetach(e),this.node.removeEventListener("click",this),this.node.removeEventListener("keydown",this)}_onTitleChanged(e){const t=jf.RO.findFirstIndex(this.widgets,(t=>t.contains(e.owner)));t>=0&&(this.layout.updateTitle(t,e.owner),this.update())}_computeWidgetSize(e){const t=this.layout,i=t.widgets[e];if(!i)return;const n=i.isHidden,s=t.absoluteSizes(),r=(n?-1:1)*this.spacing,o=s.reduce(((e,t)=>e+t));let a=[...s];if(n){const t=this._widgetSizesCache.get(i);if(!t)return;a[e]+=t;const n=a.map((e=>e-t>0)).lastIndexOf(!0);-1===n?a.forEach(((i,n)=>{n!==e&&(a[n]-=s[n]/o*(t-r))})):a[n]-=t-r}else{const t=s[e];this._widgetSizesCache.set(i,t),a[e]=0;const n=a.map((e=>e>0)).lastIndexOf(!0);if(-1===n)return;a[n]=s[n]+t+r}return a.map((e=>e/(o+r)))}_evtClick(e){const t=e.target;if(t){const i=jf.RO.findFirstIndex(this.titles,(e=>e.contains(t)));i>=0&&(e.preventDefault(),e.stopPropagation(),this._toggleExpansion(i))}}_eventKeyDown(e){if(e.defaultPrevented)return;const t=e.target;let i=!1;if(t){const n=jf.RO.findFirstIndex(this.titles,(e=>e.contains(t)));if(n>=0){const s=e.keyCode.toString();if(e.key.match(/Space|Enter/)||s.match(/13|32/))t.click(),i=!0;else if("horizontal"===this.orientation?e.key.match(/ArrowLeft|ArrowRight/)||s.match(/37|39/):e.key.match(/ArrowUp|ArrowDown/)||s.match(/38|40/)){const t=e.key.match(/ArrowLeft|ArrowUp/)||s.match(/37|38/)?-1:1,r=this.titles.length,o=(n+r+t)%r;this.titles[o].focus(),i=!0}else"End"===e.key||"35"===s?(this.titles[this.titles.length-1].focus(),i=!0):"Home"!==e.key&&"36"!==s||(this.titles[0].focus(),i=!0)}i&&e.preventDefault()}}_toggleExpansion(e){const t=this.titles[e],i=this.layout.widgets[e],n=this._computeWidgetSize(e);n&&this.setRelativeSizes(n,!1),i.isHidden?(t.classList.add("lm-mod-expanded"),t.setAttribute("aria-expanded","true"),i.show()):(t.classList.remove("lm-mod-expanded"),t.setAttribute("aria-expanded","false"),i.hide()),this._expansionToggled.emit(e)}}!function(e){class t extends Rm.Renderer{constructor(){super(),this.titleClassName="lm-AccordionPanel-title",this._titleID=0,this._titleKeys=new WeakMap,this._uuid=++t._nInstance}createCollapseIcon(e){return document.createElement("span")}createSectionTitle(e){const t=document.createElement("h3");t.setAttribute("tabindex","0"),t.id=this.createTitleKey(e),t.className=this.titleClassName;for(const i in e.dataset)t.dataset[i]=e.dataset[i];t.appendChild(this.createCollapseIcon(e)).className="lm-AccordionPanel-titleCollapser";const i=t.appendChild(document.createElement("span"));return i.className="lm-AccordionPanel-titleLabel",i.textContent=e.label,i.title=e.caption||e.label,t}createTitleKey(e){let t=this._titleKeys.get(e);return void 0===t&&(t=`title-key-${this._uuid}-${this._titleID++}`,this._titleKeys.set(e,t)),t}}t._nInstance=0,e.Renderer=t,e.defaultRenderer=new t}(Dm||(Dm={})),function(e){e.createLayout=function(e){return e.layout||new Em({renderer:e.renderer||Dm.defaultRenderer,orientation:e.orientation,alignment:e.alignment,spacing:e.spacing,titleSpace:e.titleSpace})}}(wm||(wm={}));class Im extends vm{constructor(e={}){super(),this._fixed=0,this._spacing=4,this._dirty=!1,this._sizers=[],this._items=[],this._box=null,this._alignment="start",this._direction="top-to-bottom",void 0!==e.direction&&(this._direction=e.direction),void 0!==e.alignment&&(this._alignment=e.alignment),void 0!==e.spacing&&(this._spacing=Pm.clampDimension(e.spacing))}dispose(){for(const e of this._items)e.dispose();this._box=null,this._items.length=0,this._sizers.length=0,super.dispose()}get direction(){return this._direction}set direction(e){this._direction!==e&&(this._direction=e,this.parent&&(this.parent.dataset.direction=e,this.parent.fit()))}get alignment(){return this._alignment}set alignment(e){this._alignment!==e&&(this._alignment=e,this.parent&&(this.parent.dataset.alignment=e,this.parent.update()))}get spacing(){return this._spacing}set spacing(e){e=Pm.clampDimension(e),this._spacing!==e&&(this._spacing=e,this.parent&&this.parent.fit())}init(){this.parent.dataset.direction=this.direction,this.parent.dataset.alignment=this.alignment,super.init()}attachWidget(e,t){jf.RO.insert(this._items,e,new gm(t)),jf.RO.insert(this._sizers,e,new um),this.parent.isAttached&&Lf.sendMessage(t,fm.Msg.BeforeAttach),this.parent.node.appendChild(t.node),this.parent.isAttached&&Lf.sendMessage(t,fm.Msg.AfterAttach),this.parent.fit()}moveWidget(e,t,i){jf.RO.move(this._items,e,t),jf.RO.move(this._sizers,e,t),this.parent.update()}detachWidget(e,t){let i=jf.RO.removeAt(this._items,e);jf.RO.removeAt(this._sizers,e),this.parent.isAttached&&Lf.sendMessage(t,fm.Msg.BeforeDetach),this.parent.node.removeChild(t.node),this.parent.isAttached&&Lf.sendMessage(t,fm.Msg.AfterDetach),i.dispose(),this.parent.fit()}onBeforeShow(e){super.onBeforeShow(e),this.parent.update()}onBeforeAttach(e){super.onBeforeAttach(e),this.parent.fit()}onChildShown(e){this.parent.fit()}onChildHidden(e){this.parent.fit()}onResize(e){this.parent.isVisible&&this._update(e.width,e.height)}onUpdateRequest(e){this.parent.isVisible&&this._update(-1,-1)}onFitRequest(e){this.parent.isAttached&&this._fit()}_fit(){let e=0;for(let t=0,i=this._items.length;t0)switch(this._alignment){case"start":break;case"center":l=0,h=n/2;break;case"end":l=0,h=n;break;case"justify":l=n/i,h=0;break;default:throw"unreachable"}for(let e=0,t=this._items.length;e0,coerce:(e,t)=>Math.max(0,Math.floor(t)),changed:t}),e.sizeBasisProperty=new Xf.AttachedProperty({name:"sizeBasis",create:()=>0,coerce:(e,t)=>Math.max(0,Math.floor(t)),changed:t}),e.isHorizontal=function(e){return"left-to-right"===e||"right-to-left"===e},e.clampSpacing=function(e){return Math.max(0,Math.floor(e))}}(xm||(xm={}));class qm extends Am{constructor(e={}){super({layout:Sm.createLayout(e)}),this.addClass("lm-BoxPanel")}get direction(){return this.layout.direction}set direction(e){this.layout.direction=e}get alignment(){return this.layout.alignment}set alignment(e){this.layout.alignment=e}get spacing(){return this.layout.spacing}set spacing(e){this.layout.spacing=e}onChildAdded(e){e.child.addClass("lm-BoxPanel-child")}onChildRemoved(e){e.child.removeClass("lm-BoxPanel-child")}}!function(e){e.getStretch=function(e){return Im.getStretch(e)},e.setStretch=function(e,t){Im.setStretch(e,t)},e.getSizeBasis=function(e){return Im.getSizeBasis(e)},e.setSizeBasis=function(e,t){Im.setSizeBasis(e,t)}}(qm||(qm={})),function(e){e.createLayout=function(e){return e.layout||new Im(e)}}(Sm||(Sm={}));class Lm extends fm{constructor(e){super({node:km.createNode()}),this._activeIndex=-1,this._items=[],this._results=null,this.addClass("lm-CommandPalette"),this.setFlag(fm.Flag.DisallowLayout),this.commands=e.commands,this.renderer=e.renderer||Lm.defaultRenderer,this.commands.commandChanged.connect(this._onGenericChange,this),this.commands.keyBindingChanged.connect(this._onGenericChange,this)}dispose(){this._items.length=0,this._results=null,super.dispose()}get searchNode(){return this.node.getElementsByClassName("lm-CommandPalette-search")[0]}get inputNode(){return this.node.getElementsByClassName("lm-CommandPalette-input")[0]}get contentNode(){return this.node.getElementsByClassName("lm-CommandPalette-content")[0]}get items(){return this._items}addItem(e){let t=km.createItem(this.commands,e);return this._items.push(t),this.refresh(),t}addItems(e){const t=e.map((e=>km.createItem(this.commands,e)));return t.forEach((e=>this._items.push(e))),this.refresh(),t}removeItem(e){this.removeItemAt(this._items.indexOf(e))}removeItemAt(e){jf.RO.removeAt(this._items,e)&&this.refresh()}clearItems(){0!==this._items.length&&(this._items.length=0,this.refresh())}refresh(){this._results=null,""!==this.inputNode.value?this.node.getElementsByClassName("lm-close-icon")[0].style.display="inherit":this.node.getElementsByClassName("lm-close-icon")[0].style.display="none",this.update()}handleEvent(e){switch(e.type){case"click":this._evtClick(e);break;case"keydown":this._evtKeyDown(e);break;case"input":this.refresh();break;case"focus":case"blur":this._toggleFocused()}}onBeforeAttach(e){this.node.addEventListener("click",this),this.node.addEventListener("keydown",this),this.node.addEventListener("input",this),this.node.addEventListener("focus",this,!0),this.node.addEventListener("blur",this,!0)}onAfterDetach(e){this.node.removeEventListener("click",this),this.node.removeEventListener("keydown",this),this.node.removeEventListener("input",this),this.node.removeEventListener("focus",this,!0),this.node.removeEventListener("blur",this,!0)}onAfterShow(e){this.update(),super.onAfterShow(e)}onActivateRequest(e){if(this.isAttached){let e=this.inputNode;e.focus(),e.select()}}onUpdateRequest(e){if(this.isHidden)return;let t=this.inputNode.value,i=this.contentNode,n=this._results;if(n||(n=this._results=km.search(this._items,t),this._activeIndex=t?jf.RO.findFirstIndex(n,km.canActivate):-1),!t&&0===n.length)return void im.render(null,i);if(t&&0===n.length){let e=this.renderer.renderEmptyMessage({query:t});return void im.render(e,i)}let s=this.renderer,r=this._activeIndex,o=new Array(n.length);for(let e=0,t=n.length;e=n.length)i.scrollTop=0;else{let e=i.children[r];Af.scrollIntoViewIfNeeded(i,e)}}_evtClick(e){if(0!==e.button)return;if(e.target.classList.contains("lm-close-icon"))return this.inputNode.value="",void this.refresh();let t=jf.RO.findFirstIndex(this.contentNode.children,(t=>t.contains(e.target)));-1!==t&&(e.preventDefault(),e.stopPropagation(),this._execute(t))}_evtKeyDown(e){if(!(e.altKey||e.ctrlKey||e.metaKey||e.shiftKey))switch(e.keyCode){case 13:e.preventDefault(),e.stopPropagation(),this._execute(this._activeIndex);break;case 38:e.preventDefault(),e.stopPropagation(),this._activatePreviousItem();break;case 40:e.preventDefault(),e.stopPropagation(),this._activateNextItem()}}_activateNextItem(){if(!this._results||0===this._results.length)return;let e=this._activeIndex,t=this._results.length,i=ee-t)),h=r.slice(0,l),c=r.slice(l);for(let e=0,t=c.length;ei.command===e&&Wf.JSONExt.deepEqual(i.args,t)))||null}}}(km||(km={}));class Nm extends fm{constructor(e){super({node:Tm.createNode()}),this._childIndex=-1,this._activeIndex=-1,this._openTimerID=0,this._closeTimerID=0,this._items=[],this._childMenu=null,this._parentMenu=null,this._aboutToClose=new zf.Signal(this),this._menuRequested=new zf.Signal(this),this.addClass("lm-Menu"),this.setFlag(fm.Flag.DisallowLayout),this.commands=e.commands,this.renderer=e.renderer||Nm.defaultRenderer}dispose(){this.close(),this._items.length=0,super.dispose()}get aboutToClose(){return this._aboutToClose}get menuRequested(){return this._menuRequested}get parentMenu(){return this._parentMenu}get childMenu(){return this._childMenu}get rootMenu(){let e=this;for(;e._parentMenu;)e=e._parentMenu;return e}get leafMenu(){let e=this;for(;e._childMenu;)e=e._childMenu;return e}get contentNode(){return this.node.getElementsByClassName("lm-Menu-content")[0]}get activeItem(){return this._items[this._activeIndex]||null}set activeItem(e){this.activeIndex=e?this._items.indexOf(e):-1}get activeIndex(){return this._activeIndex}set activeIndex(e){(e<0||e>=this._items.length)&&(e=-1),-1===e||Tm.canActivate(this._items[e])||(e=-1),this._activeIndex!==e&&(this._activeIndex=e,this._activeIndex>=0&&this.contentNode.childNodes[this._activeIndex]&&this.contentNode.childNodes[this._activeIndex].focus(),this.update())}get items(){return this._items}activateNextItem(){let e=this._items.length,t=this._activeIndex,i=t{this.activeIndex=e}})}im.render(r,this.contentNode)}onCloseRequest(e){this._cancelOpenTimer(),this._cancelCloseTimer(),this.activeIndex=-1;let t=this._childMenu;t&&(this._childIndex=-1,this._childMenu=null,t._parentMenu=null,t.close());let i=this._parentMenu;i&&(this._parentMenu=null,i._childIndex=-1,i._childMenu=null,i.activate()),this.isAttached&&this._aboutToClose.emit(void 0),super.onCloseRequest(e)}_evtKeyDown(e){e.preventDefault(),e.stopPropagation();let t=e.keyCode;if(13===t)return void this.triggerActiveItem();if(27===t)return void this.close();if(37===t)return void(this._parentMenu?this.close():this._menuRequested.emit("previous"));if(38===t)return void this.activatePreviousItem();if(39===t){let e=this.activeItem;return void(e&&"submenu"===e.type?this.triggerActiveItem():this.rootMenu._menuRequested.emit("next"))}if(40===t)return void this.activateNextItem();let i=Zf().keyForKeydownEvent(e);if(!i)return;let n=this._activeIndex+1,s=Tm.findMnemonic(this._items,i,n);-1===s.index||s.multiple?-1!==s.index?this.activeIndex=s.index:-1!==s.auto&&(this.activeIndex=s.auto):(this.activeIndex=s.index,this.triggerActiveItem())}_evtMouseUp(e){0===e.button&&(e.preventDefault(),e.stopPropagation(),this.triggerActiveItem())}_evtMouseMove(e){let t=jf.RO.findFirstIndex(this.contentNode.children,(t=>Af.hitTest(t,e.clientX,e.clientY)));if(t===this._activeIndex)return;if(this.activeIndex=t,t=this.activeIndex,t===this._childIndex)return this._cancelOpenTimer(),void this._cancelCloseTimer();-1!==this._childIndex&&this._startCloseTimer(),this._cancelOpenTimer();let i=this.activeItem;i&&"submenu"===i.type&&i.submenu&&this._startOpenTimer()}_evtMouseEnter(e){for(let e=this._parentMenu;e;e=e._parentMenu)e._cancelOpenTimer(),e._cancelCloseTimer(),e.activeIndex=e._childIndex}_evtMouseLeave(e){if(this._cancelOpenTimer(),!this._childMenu)return void(this.activeIndex=-1);let{clientX:t,clientY:i}=e;Af.hitTest(this._childMenu.node,t,i)?this._cancelCloseTimer():(this.activeIndex=-1,this._startCloseTimer())}_evtMouseDown(e){this._parentMenu||(Tm.hitTestMenus(this,e.clientX,e.clientY)?(e.preventDefault(),e.stopPropagation()):this.close())}_openChildMenu(e=!1){let t=this.activeItem;if(!t||"submenu"!==t.type||!t.submenu)return void this._closeChildMenu();let i=t.submenu;if(i===this._childMenu)return;Nm.saveWindowData(),this._closeChildMenu(),this._childMenu=i,this._childIndex=this._activeIndex,i._parentMenu=this,Lf.sendMessage(this,fm.Msg.UpdateRequest);let n=this.contentNode.children[this._activeIndex];Tm.openSubmenu(i,n),e&&(i.activeIndex=-1,i.activateNextItem()),i.activate()}_closeChildMenu(){this._childMenu&&this._childMenu.close()}_startOpenTimer(){0===this._openTimerID&&(this._openTimerID=window.setTimeout((()=>{this._openTimerID=0,this._openChildMenu()}),Tm.TIMER_DELAY))}_startCloseTimer(){0===this._closeTimerID&&(this._closeTimerID=window.setTimeout((()=>{this._closeTimerID=0,this._closeChildMenu()}),Tm.TIMER_DELAY))}_cancelOpenTimer(){0!==this._openTimerID&&(clearTimeout(this._openTimerID),this._openTimerID=0)}_cancelCloseTimer(){0!==this._closeTimerID&&(clearTimeout(this._closeTimerID),this._closeTimerID=0)}static saveWindowData(){Tm.saveWindowData()}}!function(e){class t{renderItem(e){let t=this.createItemClass(e),i=this.createItemDataset(e),n=this.createItemARIA(e);return dm.li({className:t,dataset:i,tabindex:"0",onfocus:e.onfocus,...n},this.renderIcon(e),this.renderLabel(e),this.renderShortcut(e),this.renderSubmenu(e))}renderIcon(e){let t=this.createIconClass(e);return dm.div({className:t},e.item.icon,e.item.iconLabel)}renderLabel(e){let t=this.formatLabel(e);return dm.div({className:"lm-Menu-itemLabel"},t)}renderShortcut(e){let t=this.formatShortcut(e);return dm.div({className:"lm-Menu-itemShortcut"},t)}renderSubmenu(e){return dm.div({className:"lm-Menu-itemSubmenuIcon"})}createItemClass(e){let t="lm-Menu-item";e.item.isEnabled||(t+=" lm-mod-disabled"),e.item.isToggled&&(t+=" lm-mod-toggled"),e.item.isVisible||(t+=" lm-mod-hidden"),e.active&&(t+=" lm-mod-active"),e.collapsed&&(t+=" lm-mod-collapsed");let i=e.item.className;return i&&(t+=` ${i}`),t}createItemDataset(e){let t,{type:i,command:n,dataset:s}=e.item;return t="command"===i?{...s,type:i,command:n}:{...s,type:i},t}createIconClass(e){let t="lm-Menu-itemIcon",i=e.item.iconClass;return i?`${t} ${i}`:t}createItemARIA(e){let t={};switch(e.item.type){case"separator":t.role="presentation";break;case"submenu":t["aria-haspopup"]="true",e.item.isEnabled||(t["aria-disabled"]="true");break;default:e.item.isEnabled||(t["aria-disabled"]="true"),t.role="menuitem"}return t}formatLabel(e){let{label:t,mnemonic:i}=e.item;if(i<0||i>=t.length)return t;let n=t.slice(0,i),s=t.slice(i+1),r=t[i];return[n,dm.span({className:"lm-Menu-itemMnemonic"},r),s]}formatShortcut(e){let t=e.item.keyBinding;return t?lm.formatKeystroke(t.keys):null}}e.Renderer=t,e.defaultRenderer=new t}(Nm||(Nm={})),function(e){e.TIMER_DELAY=300,e.SUBMENU_OVERLAP=3;let t=null,i=0;function n(){return i>0?(i--,t):r()}function s(e){return"separator"!==e.type&&e.isEnabled&&e.isVisible}function r(){return{pageXOffset:window.pageXOffset,pageYOffset:window.pageYOffset,clientWidth:document.documentElement.clientWidth,clientHeight:document.documentElement.clientHeight}}e.saveWindowData=function(){t=r(),i++},e.createNode=function(){let e=document.createElement("div"),t=document.createElement("ul");return t.className="lm-Menu-content",e.appendChild(t),t.setAttribute("role","menu"),e.tabIndex=0,e},e.canActivate=s,e.createItem=function(e,t){return new o(e.commands,t)},e.hitTestMenus=function(e,t,i){for(let n=e;n;n=n.childMenu)if(Af.hitTest(n.node,t,i))return!0;return!1},e.computeCollapsed=function(e){let t=new Array(e.length);jf.RO.fill(t,!1);let i=0,n=e.length;for(;i=0;--s){let i=e[s];if(i.isVisible){if("separator"!==i.type)break;t[s]=!0}}let r=!1;for(;++ia+h&&(t=a+h-f),!r&&i+m>l+c&&(i>l+c?i=l+c-m:i-=m),p.transform=`translate(${Math.max(0,t)}px, ${Math.max(0,i)}px`,p.opacity="1"},e.openSubmenu=function(t,i){const s=n();let r=s.pageXOffset,o=s.pageYOffset,a=s.clientWidth,l=s.clientHeight;Lf.sendMessage(t,fm.Msg.UpdateRequest);let h=l,c=t.node,d=c.style;d.opacity="0",d.maxHeight=`${h}px`,fm.attach(t,document.body);let{width:u,height:p}=c.getBoundingClientRect(),f=Af.boxSizing(t.node),m=i.getBoundingClientRect(),g=m.right-e.SUBMENU_OVERLAP;g+u>r+a&&(g=m.left+e.SUBMENU_OVERLAP-u);let v=m.top-f.borderTop-f.paddingTop;v+p>o+l&&(v=m.bottom+f.borderBottom+f.paddingBottom-p),d.transform=`translate(${Math.max(0,g)}px, ${Math.max(0,v)}px`,d.opacity="1"},e.findMnemonic=function(e,t,i){let n=-1,r=-1,o=!1,a=t.toUpperCase();for(let t=0,l=e.length;t=0&&ui.command===e&&Wf.JSONExt.deepEqual(i.args,t)))||null}return null}}}(Tm||(Tm={})),function(e){function t(e,t){let i=e.rank,n=t.rank;return i!==n?i=this._titles.length)&&(e=-1),this._currentIndex===e)return;let t=this._currentIndex,i=this._titles[t]||null,n=e,s=this._titles[n]||null;this._currentIndex=n,this._previousTitle=i,this.update(),this._currentChanged.emit({previousIndex:t,previousTitle:i,currentIndex:n,currentTitle:s})}get name(){return this._name}set name(e){this._name=e,e?this.contentNode.setAttribute("aria-label",e):this.contentNode.removeAttribute("aria-label")}get orientation(){return this._orientation}set orientation(e){this._orientation!==e&&(this._releaseMouse(),this._orientation=e,this.dataset.orientation=e,this.contentNode.setAttribute("aria-orientation",e))}get addButtonEnabled(){return this._addButtonEnabled}set addButtonEnabled(e){this._addButtonEnabled!==e&&(this._addButtonEnabled=e,e?this.addButtonNode.classList.remove("lm-mod-hidden"):this.addButtonNode.classList.add("lm-mod-hidden"))}get titles(){return this._titles}get contentNode(){return this.node.getElementsByClassName("lm-TabBar-content")[0]}get addButtonNode(){return this.node.getElementsByClassName("lm-TabBar-addButton")[0]}addTab(e){return this.insertTab(this._titles.length,e)}insertTab(e,t){this._releaseMouse();let i=Qm.asTitle(t),n=this._titles.indexOf(i),s=Math.max(0,Math.min(e,this._titles.length));return-1===n?(jf.RO.insert(this._titles,s,i),i.changed.connect(this._onTitleChanged,this),this.update(),this._adjustCurrentForInsert(s,i),i):(s===this._titles.length&&s--,n===s||(jf.RO.move(this._titles,n,s),this.update(),this._adjustCurrentForMove(n,s)),i)}removeTab(e){this.removeTabAt(this._titles.indexOf(e))}removeTabAt(e){this._releaseMouse();let t=jf.RO.removeAt(this._titles,e);t&&(t.changed.disconnect(this._onTitleChanged,this),t===this._previousTitle&&(this._previousTitle=null),this.update(),this._adjustCurrentForRemove(e,t))}clearTabs(){if(0===this._titles.length)return;this._releaseMouse();for(let e of this._titles)e.changed.disconnect(this._onTitleChanged,this);let e=this.currentIndex,t=this.currentTitle;this._currentIndex=-1,this._previousTitle=null,this._titles.length=0,this.update(),-1!==e&&this._currentChanged.emit({previousIndex:e,previousTitle:t,currentIndex:-1,currentTitle:null})}releaseMouse(){this._releaseMouse()}handleEvent(e){switch(e.type){case"pointerdown":this._evtPointerDown(e);break;case"pointermove":this._evtPointerMove(e);break;case"pointerup":this._evtPointerUp(e);break;case"dblclick":this._evtDblClick(e);break;case"keydown":e.eventPhase===Event.CAPTURING_PHASE?this._evtKeyDownCapturing(e):this._evtKeyDown(e);break;case"contextmenu":e.preventDefault(),e.stopPropagation()}}onBeforeAttach(e){this.node.addEventListener("pointerdown",this),this.node.addEventListener("dblclick",this),this.node.addEventListener("keydown",this)}onAfterDetach(e){this.node.removeEventListener("pointerdown",this),this.node.removeEventListener("dblclick",this),this.node.removeEventListener("keydown",this),this._releaseMouse()}onUpdateRequest(e){var t;let i=this._titles,n=this.renderer,s=this.currentTitle,r=new Array(i.length);const o=null!==(t=this._getCurrentTabindex())&&void 0!==t?t:this._currentIndex>-1?this._currentIndex:0;for(let e=0,t=i.length;eAf.hitTest(t,e.clientX,e.clientY)));if(-1===i)return;let n=this.titles[i],s=t[i].querySelector(".lm-TabBar-tabLabel");if(s&&s.contains(e.target)){let e=n.label||"",t=s.innerHTML;s.innerHTML="";let i=document.createElement("input");i.classList.add("lm-TabBar-tabInput"),i.value=e,s.appendChild(i);let r=()=>{i.removeEventListener("blur",r),s.innerHTML=t,this.node.addEventListener("keydown",this)};i.addEventListener("dblclick",(e=>e.stopPropagation())),i.addEventListener("blur",r),i.addEventListener("keydown",(e=>{"Enter"===e.key?(""!==i.value&&(n.label=n.caption=i.value),r()):"Escape"===e.key&&r()})),this.node.removeEventListener("keydown",this),i.select(),i.focus(),s.children.length>0&&s.children[0].focus()}}_evtKeyDownCapturing(e){e.eventPhase===Event.CAPTURING_PHASE&&(e.preventDefault(),e.stopPropagation(),"Escape"===e.key&&this._releaseMouse())}_evtKeyDown(e){var t,i,n;if("Tab"!==e.key&&e.eventPhase!==Event.CAPTURING_PHASE)if("Enter"===e.key||"Spacebar"===e.key||" "===e.key){const t=document.activeElement;if(this.addButtonEnabled&&this.addButtonNode.contains(t))e.preventDefault(),e.stopPropagation(),this._addRequested.emit();else{const i=jf.RO.findFirstIndex(this.contentNode.children,(e=>e.contains(t)));i>=0&&(e.preventDefault(),e.stopPropagation(),this.currentIndex=i)}}else if(Bm.includes(e.key)){const s=[...this.contentNode.children];if(this.addButtonEnabled&&s.push(this.addButtonNode),s.length<=1)return;e.preventDefault(),e.stopPropagation();let r,o=s.indexOf(document.activeElement);-1===o&&(o=this._currentIndex),"ArrowRight"===e.key&&"horizontal"===this._orientation||"ArrowDown"===e.key&&"vertical"===this._orientation?r=null!==(t=s[o+1])&&void 0!==t?t:s[0]:"ArrowLeft"===e.key&&"horizontal"===this._orientation||"ArrowUp"===e.key&&"vertical"===this._orientation?r=null!==(i=s[o-1])&&void 0!==i?i:s[s.length-1]:"Home"===e.key?r=s[0]:"End"===e.key&&(r=s[s.length-1]),r&&(null===(n=s[o])||void 0===n||n.setAttribute("tabindex","-1"),null==r||r.setAttribute("tabindex","0"),r.focus())}}_evtPointerDown(e){if(0!==e.button&&1!==e.button)return;if(this._dragData)return;if(e.target.classList.contains("lm-TabBar-tabInput"))return;let t=this.addButtonEnabled&&this.addButtonNode.contains(e.target),i=this.contentNode.children,n=jf.RO.findFirstIndex(i,(t=>Af.hitTest(t,e.clientX,e.clientY)));if(-1===n&&!t)return;if(e.preventDefault(),e.stopPropagation(),this._dragData={tab:i[n],index:n,pressX:e.clientX,pressY:e.clientY,tabPos:-1,tabSize:-1,tabPressPos:-1,targetIndex:-1,tabLayout:null,contentRect:null,override:null,dragActive:!1,dragAborted:!1,detachRequested:!1},this.document.addEventListener("pointerup",this,!0),1===e.button||t)return;let s=i[n].querySelector(this.renderer.closeIconSelector);s&&s.contains(e.target)||(this.tabsMovable&&(this.document.addEventListener("pointermove",this,!0),this.document.addEventListener("keydown",this,!0),this.document.addEventListener("contextmenu",this,!0)),this.allowDeselect&&this.currentIndex===n?this.currentIndex=-1:this.currentIndex=n,-1!==this.currentIndex&&this._tabActivateRequested.emit({index:this.currentIndex,title:this.currentTitle}))}_evtPointerMove(e){let t=this._dragData;if(!t)return;e.preventDefault(),e.stopPropagation();let i=this.contentNode.children;if(t.dragActive||Qm.dragExceeded(t,e)){if(!t.dragActive){let e=t.tab.getBoundingClientRect();"horizontal"===this._orientation?(t.tabPos=t.tab.offsetLeft,t.tabSize=e.width,t.tabPressPos=t.pressX-e.left):(t.tabPos=t.tab.offsetTop,t.tabSize=e.height,t.tabPressPos=t.pressY-e.top),t.tabPressOffset={x:t.pressX-e.left,y:t.pressY-e.top},t.tabLayout=Qm.snapTabLayout(i,this._orientation),t.contentRect=this.contentNode.getBoundingClientRect(),t.override=Gf.overrideCursor("default"),t.tab.classList.add("lm-mod-dragging"),this.addClass("lm-mod-dragging"),t.dragActive=!0}if(!t.detachRequested&&Qm.detachExceeded(t,e)){t.detachRequested=!0;let n=t.index,s=e.clientX,r=e.clientY,o=i[n],a=this._titles[n];if(this._tabDetachRequested.emit({index:n,title:a,tab:o,clientX:s,clientY:r,offset:t.tabPressOffset}),t.dragAborted)return}Qm.layoutTabs(i,t,e,this._orientation)}}_evtPointerUp(e){if(0!==e.button&&1!==e.button)return;const t=this._dragData;if(!t)return;if(e.preventDefault(),e.stopPropagation(),this.document.removeEventListener("pointermove",this,!0),this.document.removeEventListener("pointerup",this,!0),this.document.removeEventListener("keydown",this,!0),this.document.removeEventListener("contextmenu",this,!0),!t.dragActive){if(this._dragData=null,this.addButtonEnabled&&this.addButtonNode.contains(e.target))return void this._addRequested.emit(void 0);let i=this.contentNode.children,n=jf.RO.findFirstIndex(i,(t=>Af.hitTest(t,e.clientX,e.clientY)));if(n!==t.index)return;let s=this._titles[n];if(!s.closable)return;if(1===e.button)return void this._tabCloseRequested.emit({index:n,title:s});let r=i[n].querySelector(this.renderer.closeIconSelector);return r&&r.contains(e.target)?void this._tabCloseRequested.emit({index:n,title:s}):void 0}if(0!==e.button)return;Qm.finalizeTabPosition(t,this._orientation),t.tab.classList.remove("lm-mod-dragging");let i=Qm.parseTransitionDuration(t.tab);setTimeout((()=>{if(t.dragAborted)return;this._dragData=null,Qm.resetTabPositions(this.contentNode.children,this._orientation),t.override.dispose(),this.removeClass("lm-mod-dragging");let e=t.index,i=t.targetIndex;-1!==i&&e!==i&&(jf.RO.move(this._titles,e,i),this._adjustCurrentForMove(e,i),this._tabMoved.emit({fromIndex:e,toIndex:i,title:this._titles[i]}),Lf.sendMessage(this,fm.Msg.UpdateRequest))}),i)}_releaseMouse(){let e=this._dragData;e&&(this._dragData=null,this.document.removeEventListener("pointermove",this,!0),this.document.removeEventListener("pointerup",this,!0),this.document.removeEventListener("keydown",this,!0),this.document.removeEventListener("contextmenu",this,!0),e.dragAborted=!0,e.dragActive&&(Qm.resetTabPositions(this.contentNode.children,this._orientation),e.override.dispose(),e.tab.classList.remove("lm-mod-dragging"),this.removeClass("lm-mod-dragging")))}_adjustCurrentForInsert(e,t){let i=this.currentTitle,n=this._currentIndex,s=this.insertBehavior;if("select-tab"===s||"select-tab-if-needed"===s&&-1===n)return this._currentIndex=e,this._previousTitle=i,void this._currentChanged.emit({previousIndex:n,previousTitle:i,currentIndex:e,currentTitle:t});n>=e&&this._currentIndex++}_adjustCurrentForMove(e,t){this._currentIndex===e?this._currentIndex=t:this._currentIndex=t?this._currentIndex++:this._currentIndex>e&&this._currentIndex<=t&&this._currentIndex--}_adjustCurrentForRemove(e,t){let i=this._currentIndex,n=this.removeBehavior;if(i===e){if(0===this._titles.length)return this._currentIndex=-1,void this._currentChanged.emit({previousIndex:e,previousTitle:t,currentIndex:-1,currentTitle:null});if("select-tab-after"===n)return this._currentIndex=Math.min(e,this._titles.length-1),void this._currentChanged.emit({previousIndex:e,previousTitle:t,currentIndex:this._currentIndex,currentTitle:this.currentTitle});if("select-tab-before"===n)return this._currentIndex=Math.max(0,e-1),void this._currentChanged.emit({previousIndex:e,previousTitle:t,currentIndex:this._currentIndex,currentTitle:this.currentTitle});if("select-previous-tab"===n)return this._previousTitle?(this._currentIndex=this._titles.indexOf(this._previousTitle),this._previousTitle=null):this._currentIndex=Math.min(e,this._titles.length-1),void this._currentChanged.emit({previousIndex:e,previousTitle:t,currentIndex:this._currentIndex,currentTitle:this.currentTitle});this._currentIndex=-1,this._currentChanged.emit({previousIndex:e,previousTitle:t,currentIndex:-1,currentTitle:null})}else i>e&&this._currentIndex--}_onTitleChanged(e){this.update()}}var Qm,zm,jm,Wm,Vm,Um,Fm,Hm;!function(e){class t{constructor(){this.closeIconSelector=".lm-TabBar-tabCloseIcon",this._tabID=0,this._tabKeys=new WeakMap,this._uuid=++t._nInstance}renderTab(e){let t=e.title.caption,i=this.createTabKey(e),n=i,s=this.createTabStyle(e),r=this.createTabClass(e),o=this.createTabDataset(e),a=this.createTabARIA(e);return e.title.closable?dm.li({id:n,key:i,className:r,title:t,style:s,dataset:o,...a},this.renderIcon(e),this.renderLabel(e),this.renderCloseIcon(e)):dm.li({id:n,key:i,className:r,title:t,style:s,dataset:o,...a},this.renderIcon(e),this.renderLabel(e))}renderIcon(e){const{title:t}=e;let i=this.createIconClass(e);return dm.div({className:i},t.icon,t.iconLabel)}renderLabel(e){return dm.div({className:"lm-TabBar-tabLabel"},e.title.label)}renderCloseIcon(e){return dm.div({className:"lm-TabBar-tabCloseIcon"})}createTabKey(e){let t=this._tabKeys.get(e.title);return void 0===t&&(t=`tab-key-${this._uuid}-${this._tabID++}`,this._tabKeys.set(e.title,t)),t}createTabStyle(e){return{zIndex:`${e.zIndex}`}}createTabClass(e){let t="lm-TabBar-tab";return e.title.className&&(t+=` ${e.title.className}`),e.title.closable&&(t+=" lm-mod-closable"),e.current&&(t+=" lm-mod-current"),t}createTabDataset(e){return e.title.dataset}createTabARIA(e){var t;return{role:"tab","aria-selected":e.current.toString(),tabindex:`${null!==(t=e.tabIndex)&&void 0!==t?t:"-1"}`}}createIconClass(e){let t="lm-TabBar-tabIcon",i=e.title.iconClass;return i?`${t} ${i}`:t}}t._nInstance=0,e.Renderer=t,e.defaultRenderer=new t,e.addButtonSelector=".lm-TabBar-addButton"}($m||($m={})),function(e){e.DRAG_THRESHOLD=5,e.DETACH_THRESHOLD=20,e.createNode=function(){let e=document.createElement("div"),t=document.createElement("ul");t.setAttribute("role","tablist"),t.className="lm-TabBar-content",e.appendChild(t);let i=document.createElement("div");return i.className="lm-TabBar-addButton lm-mod-hidden",i.setAttribute("tabindex","-1"),e.appendChild(i),e},e.asTitle=function(e){return e instanceof pm?e:new pm(e)},e.parseTransitionDuration=function(e){let t=window.getComputedStyle(e);return 1e3*(parseFloat(t.transitionDuration)||0)},e.snapTabLayout=function(e,t){let i=new Array(e.length);for(let n=0,s=e.length;n=e.DRAG_THRESHOLD||s>=e.DRAG_THRESHOLD},e.detachExceeded=function(t,i){let n=t.contentRect;return i.clientX=n.right+e.DETACH_THRESHOLD||i.clientY=n.bottom+e.DETACH_THRESHOLD},e.layoutTabs=function(e,t,i,n){let s,r,o,a;"horizontal"===n?(s=t.pressX,r=i.clientX-t.contentRect.left,o=i.clientX,a=t.contentRect.width):(s=t.pressY,r=i.clientY-t.contentRect.top,o=i.clientY,a=t.contentRect.height);let l=t.index,h=r-t.tabPressPos,c=h+t.tabSize;for(let i=0,r=e.length;i>1);if(it.index&&c>u)r=-t.tabSize-d.margin+"px",l=Math.max(l,i);else if(i===t.index){let e=o-s,i=a-(t.tabPos+t.tabSize);r=`${Math.max(-t.tabPos,Math.min(e,i))}px`}else r="";"horizontal"===n?e[i].style.left=r:e[i].style.top=r}t.targetIndex=l},e.finalizeTabPosition=function(e,t){let i,n;if(i="horizontal"===t?e.contentRect.width:e.contentRect.height,e.targetIndex===e.index)n=0;else if(e.targetIndex>e.index){let t=e.tabLayout[e.targetIndex];n=t.pos+t.size-e.tabSize-e.tabPos}else n=e.tabLayout[e.targetIndex].pos-e.tabPos;let s=i-(e.tabPos+e.tabSize),r=Math.max(-e.tabPos,Math.min(n,s));"horizontal"===t?e.tab.style.left=`${r}px`:e.tab.style.top=`${r}px`},e.resetTabPositions=function(e,t){for(const i of e)"horizontal"===t?i.style.left="":i.style.top=""}}(Qm||(Qm={}));class Xm extends mm{constructor(e){super(),this._spacing=4,this._dirty=!1,this._root=null,this._box=null,this._items=new Map,this.renderer=e.renderer,void 0!==e.spacing&&(this._spacing=Pm.clampDimension(e.spacing)),this._document=e.document||document,this._hiddenMode=void 0!==e.hiddenMode?e.hiddenMode:fm.HiddenMode.Display}dispose(){let e=this[Symbol.iterator]();this._items.forEach((e=>{e.dispose()})),this._box=null,this._root=null,this._items.clear();for(const t of e)t.dispose();super.dispose()}get hiddenMode(){return this._hiddenMode}set hiddenMode(e){if(this._hiddenMode!==e){this._hiddenMode=e;for(const e of this.tabBars())if(e.titles.length>1)for(const t of e.titles)t.owner.hiddenMode=this._hiddenMode}}get spacing(){return this._spacing}set spacing(e){e=Pm.clampDimension(e),this._spacing!==e&&(this._spacing=e,this.parent&&this.parent.fit())}get isEmpty(){return null===this._root}[Symbol.iterator](){return this._root?this._root.iterAllWidgets():(0,jf.cS)()}widgets(){return this._root?this._root.iterUserWidgets():(0,jf.cS)()}selectedWidgets(){return this._root?this._root.iterSelectedWidgets():(0,jf.cS)()}tabBars(){return this._root?this._root.iterTabBars():(0,jf.cS)()}handles(){return this._root?this._root.iterHandles():(0,jf.cS)()}moveHandle(e,t,i){let n=e.classList.contains("lm-mod-hidden");if(!this._root||n)return;let s,r=this._root.findSplitNode(e);r&&(s="horizontal"===r.node.orientation?t-e.offsetLeft:i-e.offsetTop,0!==s&&(r.node.holdSizes(),sm.adjust(r.node.sizers,r.index,s),this.parent&&this.parent.update()))}saveLayout(){return this._root?(this._root.holdAllSizes(),{main:this._root.createConfig()}):{main:null}}restoreLayout(e){let t,i=new Set;t=e.main?zm.normalizeAreaConfig(e.main,i):null;let n=this.widgets(),s=this.tabBars(),r=this.handles();this._root=null;for(const e of n)i.has(e)||(e.parent=null);for(const e of s)e.dispose();for(const e of r)e.parentNode&&e.parentNode.removeChild(e);for(const e of i)e.parent=this.parent;this._root=t?zm.realizeAreaConfig(t,{createTabBar:e=>this._createTabBar(),createHandle:()=>this._createHandle()},this._document):null,this.parent&&(i.forEach((e=>{this.attachWidget(e)})),this.parent.fit())}addWidget(e,t={}){let i=t.ref||null,n=t.mode||"tab-after",s=null;if(this._root&&i&&(s=this._root.findTabNode(i)),i&&!s)throw new Error("Reference widget is not in the layout.");switch(e.parent=this.parent,n){case"tab-after":this._insertTab(e,i,s,!0);break;case"tab-before":this._insertTab(e,i,s,!1);break;case"split-top":this._insertSplit(e,i,s,"vertical",!1);break;case"split-left":this._insertSplit(e,i,s,"horizontal",!1);break;case"split-right":this._insertSplit(e,i,s,"horizontal",!0);break;case"split-bottom":this._insertSplit(e,i,s,"vertical",!0);break;case"merge-top":this._insertSplit(e,i,s,"vertical",!1,!0);break;case"merge-left":this._insertSplit(e,i,s,"horizontal",!1,!0);break;case"merge-right":this._insertSplit(e,i,s,"horizontal",!0,!0);break;case"merge-bottom":this._insertSplit(e,i,s,"vertical",!0,!0)}this.parent&&(this.attachWidget(e),this.parent.fit())}removeWidget(e){this._removeWidget(e),this.parent&&(this.detachWidget(e),this.parent.fit())}hitTestTabAreas(e,t){if(!this._root||!this.parent||!this.parent.isVisible)return null;this._box||(this._box=Af.boxSizing(this.parent.node));let i=this.parent.node.getBoundingClientRect(),n=e-i.left-this._box.borderLeft,s=t-i.top-this._box.borderTop,r=this._root.hitTestTabNodes(n,s);if(!r)return null;let{tabBar:o,top:a,left:l,width:h,height:c}=r,d=this._box.borderLeft+this._box.borderRight,u=this._box.borderTop+this._box.borderBottom;return{tabBar:o,x:n,y:s,top:a,left:l,right:i.width-d-(l+h),bottom:i.height-u-(a+c),width:h,height:c}}init(){super.init();for(const e of this)this.attachWidget(e);for(const e of this.handles())this.parent.node.appendChild(e);this.parent.fit()}attachWidget(e){this.parent.node!==e.node.parentNode&&(this._items.set(e,new gm(e)),this.parent.isAttached&&Lf.sendMessage(e,fm.Msg.BeforeAttach),this.parent.node.appendChild(e.node),this.parent.isAttached&&Lf.sendMessage(e,fm.Msg.AfterAttach))}detachWidget(e){if(this.parent.node!==e.node.parentNode)return;this.parent.isAttached&&Lf.sendMessage(e,fm.Msg.BeforeDetach),this.parent.node.removeChild(e.node),this.parent.isAttached&&Lf.sendMessage(e,fm.Msg.AfterDetach);let t=this._items.get(e);t&&(this._items.delete(e),t.dispose())}onBeforeShow(e){super.onBeforeShow(e),this.parent.update()}onBeforeAttach(e){super.onBeforeAttach(e),this.parent.fit()}onChildShown(e){this.parent.fit()}onChildHidden(e){this.parent.fit()}onResize(e){this.parent.isVisible&&this._update(e.width,e.height)}onUpdateRequest(e){this.parent.isVisible&&this._update(-1,-1)}onFitRequest(e){this.parent.isAttached&&this._fit()}_removeWidget(e){if(!this._root)return;let t=this._root.findTabNode(e);if(!t)return;if(zm.removeAria(e),t.tabBar.titles.length>1)return t.tabBar.removeTab(e.title),void(this._hiddenMode===fm.HiddenMode.Scale&&1==t.tabBar.titles.length&&(t.tabBar.titles[0].owner.hiddenMode=fm.HiddenMode.Display));if(t.tabBar.dispose(),this._root===t)return void(this._root=null);this._root.holdAllSizes();let i=t.parent;t.parent=null;let n=jf.RO.removeFirstOf(i.children,t),s=jf.RO.removeAt(i.handles,n);if(jf.RO.removeAt(i.sizers,n),s.parentNode&&s.parentNode.removeChild(s),i.children.length>1)return void i.syncHandles();let r=i.parent;i.parent=null;let o=i.children[0],a=i.handles[0];if(i.children.length=0,i.handles.length=0,i.sizers.length=0,a.parentNode&&a.parentNode.removeChild(a),this._root===i)return o.parent=null,void(this._root=o);let l=r,h=l.children.indexOf(i);if(o instanceof zm.TabLayoutNode)return o.parent=l,void(l.children[h]=o);let c=jf.RO.removeAt(l.handles,h);jf.RO.removeAt(l.children,h),jf.RO.removeAt(l.sizers,h),c.parentNode&&c.parentNode.removeChild(c);for(let e=0,t=o.children.length;e=i.length)&&(n=0),{type:"tab-area",widgets:i,currentIndex:n}}(t,i):function(t,i){let n=t.orientation,s=[],r=[];for(let o=0,a=t.children.length;o{let l=s(n,i,r),h=t(e.sizes[a]),c=i.createHandle();o.children.push(l),o.handles.push(c),o.sizers.push(h),l.parent=o})),o.syncHandles(),o.normalizeSizes(),o}(r,o,a),l};class i{constructor(e){this.parent=null,this._top=0,this._left=0,this._width=0,this._height=0;let t=new um,i=new um;t.stretch=0,i.stretch=1,this.tabBar=e,this.sizers=[t,i]}get top(){return this._top}get left(){return this._left}get width(){return this._width}get height(){return this._height}*iterAllWidgets(){yield this.tabBar,yield*this.iterUserWidgets()}*iterUserWidgets(){for(const e of this.tabBar.titles)yield e.owner}*iterSelectedWidgets(){let e=this.tabBar.currentTitle;e&&(yield e.owner)}*iterTabBars(){yield this.tabBar}*iterHandles(){}findTabNode(e){return-1!==this.tabBar.titles.indexOf(e.title)?this:null}findSplitNode(e){return null}findFirstTabNode(){return this}hitTestTabNodes(e,t){return e=this._left+this._width||t=this._top+this._height?null:this}createConfig(){return{type:"tab-area",widgets:this.tabBar.titles.map((e=>e.owner)),currentIndex:this.tabBar.currentIndex}}holdAllSizes(){}fit(e,t){let i=0,n=0,s=t.get(this.tabBar),r=this.tabBar.currentTitle,o=r?t.get(r.owner):void 0,[a,l]=this.sizers;return s&&s.fit(),o&&o.fit(),s&&!s.isHidden?(i=Math.max(i,s.minWidth),n+=s.minHeight,a.minSize=s.minHeight,a.maxSize=s.maxHeight):(a.minSize=0,a.maxSize=0),o&&!o.isHidden?(i=Math.max(i,o.minWidth),n+=o.minHeight,l.minSize=o.minHeight,l.maxSize=1/0):(l.minSize=0,l.maxSize=1/0),{minWidth:i,minHeight:n,maxWidth:1/0,maxHeight:1/0}}update(e,t,i,n,s,r){this._top=t,this._left=e,this._width=i,this._height=n;let o=r.get(this.tabBar),a=this.tabBar.currentTitle,l=a?r.get(a.owner):void 0;if(sm.calc(this.sizers,n),o&&!o.isHidden){let n=this.sizers[0].size;o.update(e,t,i,n),t+=n}if(l&&!l.isHidden){let n=this.sizers[1].size;l.update(e,t,i,n)}}}e.TabLayoutNode=i;class n{constructor(e){this.parent=null,this.normalized=!1,this.children=[],this.sizers=[],this.handles=[],this.orientation=e}*iterAllWidgets(){for(const e of this.children)yield*e.iterAllWidgets()}*iterUserWidgets(){for(const e of this.children)yield*e.iterUserWidgets()}*iterSelectedWidgets(){for(const e of this.children)yield*e.iterSelectedWidgets()}*iterTabBars(){for(const e of this.children)yield*e.iterTabBars()}*iterHandles(){yield*this.handles;for(const e of this.children)yield*e.iterHandles()}findTabNode(e){for(let t=0,i=this.children.length;te.createConfig())),sizes:t}}syncHandles(){this.handles.forEach(((e,t)=>{e.setAttribute("data-orientation",this.orientation),t===this.handles.length-1?e.classList.add("lm-mod-hidden"):e.classList.remove("lm-mod-hidden")}))}holdSizes(){for(const e of this.sizers)e.sizeHint=e.size}holdAllSizes(){for(const e of this.children)e.holdAllSizes();this.holdSizes()}normalizeSizes(){let e=this.sizers.length;if(0===e)return;this.holdSizes();let t=this.sizers.reduce(((e,t)=>e+t.sizeHint),0);if(0===t)for(const t of this.sizers)t.size=t.sizeHint=1/e;else for(const e of this.sizers)e.size=e.sizeHint/=t;this.normalized=!0}createNormalizedSizes(){let e=this.sizers.length;if(0===e)return[];let t=this.sizers.map((e=>e.size)),i=t.reduce(((e,t)=>e+t),0);if(0===i)for(let i=t.length-1;i>-1;i--)t[i]=1/e;else for(let e=t.length-1;e>-1;e--)t[e]/=i;return t}fit(e,t){let i="horizontal"===this.orientation,n=Math.max(0,this.children.length-1)*e,s=i?n:0,r=i?0:n;for(let n=0,o=this.children.length;nthis._createTabBar(),createHandle:()=>this._createHandle()};this.layout=new Xm({document:this._document,renderer:t,spacing:e.spacing,hiddenMode:e.hiddenMode}),this.overlay=e.overlay||new Ym.Overlay,this.node.appendChild(this.overlay.node)}dispose(){this._releaseMouse(),this.overlay.hide(0),this._drag&&this._drag.dispose(),super.dispose()}get hiddenMode(){return this.layout.hiddenMode}set hiddenMode(e){this.layout.hiddenMode=e}get layoutModified(){return this._layoutModified}get addRequested(){return this._addRequested}get renderer(){return this.layout.renderer}get spacing(){return this.layout.spacing}set spacing(e){this.layout.spacing=e}get mode(){return this._mode}set mode(e){if(this._mode===e)return;this._mode=e,this.dataset.mode=e;let t=this.layout;switch(e){case"multiple-document":for(const e of t.tabBars())e.show();break;case"single-document":t.restoreLayout(jm.createSingleDocumentConfig(this));break;default:throw"unreachable"}Lf.postMessage(this,jm.LayoutModified)}get tabsMovable(){return this._tabsMovable}set tabsMovable(e){this._tabsMovable=e;for(const t of this.tabBars())t.tabsMovable=e}get tabsConstrained(){return this._tabsConstrained}set tabsConstrained(e){this._tabsConstrained=e}get addButtonEnabled(){return this._addButtonEnabled}set addButtonEnabled(e){this._addButtonEnabled=e;for(const t of this.tabBars())t.addButtonEnabled=e}get isEmpty(){return this.layout.isEmpty}*widgets(){yield*this.layout.widgets()}*selectedWidgets(){yield*this.layout.selectedWidgets()}*tabBars(){yield*this.layout.tabBars()}*handles(){yield*this.layout.handles()}selectWidget(e){let t=(0,jf.sE)(this.tabBars(),(t=>-1!==t.titles.indexOf(e.title)));if(!t)throw new Error("Widget is not contained in the dock panel.");t.currentTitle=e.title}activateWidget(e){this.selectWidget(e),e.activate()}saveLayout(){return this.layout.saveLayout()}restoreLayout(e){this._mode="multiple-document",this.layout.restoreLayout(e),(Rf.IS_EDGE||Rf.IS_IE)&&Lf.flush(),Lf.postMessage(this,jm.LayoutModified)}addWidget(e,t={}){"single-document"===this._mode?this.layout.addWidget(e):this.layout.addWidget(e,t),Lf.postMessage(this,jm.LayoutModified)}processMessage(e){"layout-modified"===e.type?this._layoutModified.emit(void 0):super.processMessage(e)}handleEvent(e){switch(e.type){case"lm-dragenter":this._evtDragEnter(e);break;case"lm-dragleave":this._evtDragLeave(e);break;case"lm-dragover":this._evtDragOver(e);break;case"lm-drop":this._evtDrop(e);break;case"pointerdown":this._evtPointerDown(e);break;case"pointermove":this._evtPointerMove(e);break;case"pointerup":this._evtPointerUp(e);break;case"keydown":this._evtKeyDown(e);break;case"contextmenu":e.preventDefault(),e.stopPropagation()}}onBeforeAttach(e){this.node.addEventListener("lm-dragenter",this),this.node.addEventListener("lm-dragleave",this),this.node.addEventListener("lm-dragover",this),this.node.addEventListener("lm-drop",this),this.node.addEventListener("pointerdown",this)}onAfterDetach(e){this.node.removeEventListener("lm-dragenter",this),this.node.removeEventListener("lm-dragleave",this),this.node.removeEventListener("lm-dragover",this),this.node.removeEventListener("lm-drop",this),this.node.removeEventListener("pointerdown",this),this._releaseMouse()}onChildAdded(e){jm.isGeneratedTabBarProperty.get(e.child)||e.child.addClass("lm-DockPanel-widget")}onChildRemoved(e){jm.isGeneratedTabBarProperty.get(e.child)||(e.child.removeClass("lm-DockPanel-widget"),Lf.postMessage(this,jm.LayoutModified))}_evtDragEnter(e){e.mimeData.hasData("application/vnd.lumino.widget-factory")&&(e.preventDefault(),e.stopPropagation())}_evtDragLeave(e){e.preventDefault(),this._tabsConstrained&&e.source!==this||(e.stopPropagation(),this.overlay.hide(1))}_evtDragOver(e){e.preventDefault(),this._tabsConstrained&&e.source!==this||"invalid"===this._showOverlay(e.clientX,e.clientY)?e.dropAction="none":(e.stopPropagation(),e.dropAction=e.proposedAction)}_evtDrop(e){if(e.preventDefault(),this.overlay.hide(0),"none"===e.proposedAction)return void(e.dropAction="none");let{clientX:t,clientY:i}=e,{zone:n,target:s}=jm.findDropTarget(this,t,i,this._edges);if(this._tabsConstrained&&e.source!==this||"invalid"===n)return void(e.dropAction="none");let r=e.mimeData.getData("application/vnd.lumino.widget-factory");if("function"!=typeof r)return void(e.dropAction="none");let o=r();if(!(o instanceof fm))return void(e.dropAction="none");if(o.contains(this))return void(e.dropAction="none");let a=s?jm.getDropRef(s.tabBar):null;switch(n){case"root-all":this.addWidget(o);break;case"root-top":this.addWidget(o,{mode:"split-top"});break;case"root-left":this.addWidget(o,{mode:"split-left"});break;case"root-right":this.addWidget(o,{mode:"split-right"});break;case"root-bottom":this.addWidget(o,{mode:"split-bottom"});break;case"widget-all":case"widget-tab":this.addWidget(o,{mode:"tab-after",ref:a});break;case"widget-top":this.addWidget(o,{mode:"split-top",ref:a});break;case"widget-left":this.addWidget(o,{mode:"split-left",ref:a});break;case"widget-right":this.addWidget(o,{mode:"split-right",ref:a});break;case"widget-bottom":this.addWidget(o,{mode:"split-bottom",ref:a});break;default:throw"unreachable"}e.dropAction=e.proposedAction,e.stopPropagation(),this.activateWidget(o)}_evtKeyDown(e){e.preventDefault(),e.stopPropagation(),27===e.keyCode&&(this._releaseMouse(),Lf.postMessage(this,jm.LayoutModified))}_evtPointerDown(e){if(0!==e.button)return;let t=this.layout,i=e.target,n=(0,jf.sE)(t.handles(),(e=>e.contains(i)));if(!n)return;e.preventDefault(),e.stopPropagation(),this._document.addEventListener("keydown",this,!0),this._document.addEventListener("pointerup",this,!0),this._document.addEventListener("pointermove",this,!0),this._document.addEventListener("contextmenu",this,!0);let s=n.getBoundingClientRect(),r=e.clientX-s.left,o=e.clientY-s.top,a=window.getComputedStyle(n),l=Gf.overrideCursor(a.cursor,this._document);this._pressData={handle:n,deltaX:r,deltaY:o,override:l}}_evtPointerMove(e){if(!this._pressData)return;e.preventDefault(),e.stopPropagation();let t=this.node.getBoundingClientRect(),i=e.clientX-t.left-this._pressData.deltaX,n=e.clientY-t.top-this._pressData.deltaY;this.layout.moveHandle(this._pressData.handle,i,n)}_evtPointerUp(e){0===e.button&&(e.preventDefault(),e.stopPropagation(),this._releaseMouse(),Lf.postMessage(this,jm.LayoutModified))}_releaseMouse(){this._pressData&&(this._pressData.override.dispose(),this._pressData=null,this._document.removeEventListener("keydown",this,!0),this._document.removeEventListener("pointerup",this,!0),this._document.removeEventListener("pointermove",this,!0),this._document.removeEventListener("contextmenu",this,!0))}_showOverlay(e,t){let i,n,s,r,{zone:o,target:a}=jm.findDropTarget(this,e,t,this._edges);if("invalid"===o)return this.overlay.hide(100),o;let l=Af.boxSizing(this.node),h=this.node.getBoundingClientRect();switch(o){case"root-all":i=l.paddingTop,n=l.paddingLeft,s=l.paddingRight,r=l.paddingBottom;break;case"root-top":i=l.paddingTop,n=l.paddingLeft,s=l.paddingRight,r=h.height*jm.GOLDEN_RATIO;break;case"root-left":i=l.paddingTop,n=l.paddingLeft,s=h.width*jm.GOLDEN_RATIO,r=l.paddingBottom;break;case"root-right":i=l.paddingTop,n=h.width*jm.GOLDEN_RATIO,s=l.paddingRight,r=l.paddingBottom;break;case"root-bottom":i=h.height*jm.GOLDEN_RATIO,n=l.paddingLeft,s=l.paddingRight,r=l.paddingBottom;break;case"widget-all":i=a.top,n=a.left,s=a.right,r=a.bottom;break;case"widget-top":i=a.top,n=a.left,s=a.right,r=a.bottom+a.height/2;break;case"widget-left":i=a.top,n=a.left,s=a.right+a.width/2,r=a.bottom;break;case"widget-right":i=a.top,n=a.left+a.width/2,s=a.right,r=a.bottom;break;case"widget-bottom":i=a.top+a.height/2,n=a.left,s=a.right,r=a.bottom;break;case"widget-tab":{const e=a.tabBar.node.getBoundingClientRect().height;i=a.top,n=a.left,s=a.right,r=a.bottom+a.height-e;break}default:throw"unreachable"}return this.overlay.show({top:i,left:n,right:s,bottom:r}),o}_createTabBar(){let e=this._renderer.createTabBar(this._document);return jm.isGeneratedTabBarProperty.set(e,!0),"single-document"===this._mode&&e.hide(),e.tabsMovable=this._tabsMovable,e.allowDeselect=!1,e.addButtonEnabled=this._addButtonEnabled,e.removeBehavior="select-previous-tab",e.insertBehavior="select-tab-if-needed",e.tabMoved.connect(this._onTabMoved,this),e.currentChanged.connect(this._onCurrentChanged,this),e.tabCloseRequested.connect(this._onTabCloseRequested,this),e.tabDetachRequested.connect(this._onTabDetachRequested,this),e.tabActivateRequested.connect(this._onTabActivateRequested,this),e.addRequested.connect(this._onTabAddRequested,this),e}_createHandle(){return this._renderer.createHandle()}_onTabMoved(){Lf.postMessage(this,jm.LayoutModified)}_onCurrentChanged(e,t){let{previousTitle:i,currentTitle:n}=t;i&&i.owner.hide(),n&&n.owner.show(),(Rf.IS_EDGE||Rf.IS_IE)&&Lf.flush(),Lf.postMessage(this,jm.LayoutModified)}_onTabAddRequested(e){this._addRequested.emit(e)}_onTabActivateRequested(e,t){t.title.owner.activate()}_onTabCloseRequested(e,t){t.title.owner.close()}_onTabDetachRequested(e,t){if(this._drag)return;e.releaseMouse();let{title:i,tab:n,clientX:s,clientY:r,offset:o}=t,a=new Wf.MimeData;a.setData("application/vnd.lumino.widget-factory",(()=>i.owner));let l=n.cloneNode(!0);o&&(l.style.top=`-${o.y}px`,l.style.left=`-${o.x}px`),this._drag=new Gf({document:this._document,mimeData:a,dragImage:l,proposedAction:"move",supportedActions:"move",source:this}),n.classList.add("lm-mod-hidden"),this._drag.start(s,r).then((()=>{this._drag=null,n.classList.remove("lm-mod-hidden")}))}}!function(e){e.Overlay=class{constructor(){this._timer=-1,this._hidden=!0,this.node=document.createElement("div"),this.node.classList.add("lm-DockPanel-overlay"),this.node.classList.add("lm-mod-hidden"),this.node.style.position="absolute",this.node.style.contain="strict"}show(e){let t=this.node.style;t.top=`${e.top}px`,t.left=`${e.left}px`,t.right=`${e.right}px`,t.bottom=`${e.bottom}px`,clearTimeout(this._timer),this._timer=-1,this._hidden&&(this._hidden=!1,this.node.classList.remove("lm-mod-hidden"))}hide(e){if(!this._hidden)return e<=0?(clearTimeout(this._timer),this._timer=-1,this._hidden=!0,void this.node.classList.add("lm-mod-hidden")):void(-1===this._timer&&(this._timer=window.setTimeout((()=>{this._timer=-1,this._hidden=!0,this.node.classList.add("lm-mod-hidden")}),e)))}};class t{createTabBar(e){let t=new $m({document:e});return t.addClass("lm-DockPanel-tabBar"),t}createHandle(){let e=document.createElement("div");return e.className="lm-DockPanel-handle",e}}e.Renderer=t,e.defaultRenderer=new t}(Ym||(Ym={})),function(e){e.GOLDEN_RATIO=.618,e.DEFAULT_EDGES={top:12,right:40,bottom:40,left:40},e.LayoutModified=new Ff("layout-modified"),e.isGeneratedTabBarProperty=new Xf.AttachedProperty({name:"isGeneratedTabBar",create:()=>!1}),e.createSingleDocumentConfig=function(e){if(e.isEmpty)return{main:null};let t=Array.from(e.widgets()),i=e.selectedWidgets().next().value,n=i?t.indexOf(i):-1;return{main:{type:"tab-area",widgets:t,currentIndex:n}}},e.findDropTarget=function(e,t,i,n){if(!Af.hitTest(e.node,t,i))return{zone:"invalid",target:null};let s=e.layout;if(s.isEmpty)return{zone:"root-all",target:null};if("multiple-document"===e.mode){let s=e.node.getBoundingClientRect(),r=t-s.left+1,o=i-s.top+1,a=s.right-t,l=s.bottom-i;switch(Math.min(o,a,l,r)){case o:if(od&&l>d&&a>u&&h>u)return{zone:"widget-all",target:r};switch(o/=d,a/=u,l/=d,h/=u,Math.min(o,a,l,h)){case o:c="widget-left";break;case a:c="widget-top";break;case l:c="widget-right";break;case h:c="widget-bottom";break;default:throw"unreachable"}return{zone:c,target:r}},e.getDropRef=function(e){return 0===e.titles.length?null:e.currentTitle?e.currentTitle.owner:e.titles[e.titles.length-1].owner}}(jm||(jm={}));class Gm{constructor(){this._counter=0,this._widgets=[],this._activeWidget=null,this._currentWidget=null,this._numbers=new Map,this._nodes=new Map,this._activeChanged=new zf.Signal(this),this._currentChanged=new zf.Signal(this)}dispose(){if(!(this._counter<0)){this._counter=-1,zf.Signal.clearData(this);for(const e of this._widgets)e.node.removeEventListener("focus",this,!0),e.node.removeEventListener("blur",this,!0);this._activeWidget=null,this._currentWidget=null,this._nodes.clear(),this._numbers.clear(),this._widgets.length=0}}get currentChanged(){return this._currentChanged}get activeChanged(){return this._activeChanged}get isDisposed(){return this._counter<0}get currentWidget(){return this._currentWidget}get activeWidget(){return this._activeWidget}get widgets(){return this._widgets}focusNumber(e){let t=this._numbers.get(e);return void 0===t?-1:t}has(e){return this._numbers.has(e)}add(e){if(this._numbers.has(e))return;let t=e.node.contains(document.activeElement),i=t?this._counter++:-1;this._widgets.push(e),this._numbers.set(e,i),this._nodes.set(e.node,e),e.node.addEventListener("focus",this,!0),e.node.addEventListener("blur",this,!0),e.disposed.connect(this._onWidgetDisposed,this),t&&this._setWidgets(e,e)}remove(e){if(!this._numbers.has(e))return;if(e.disposed.disconnect(this._onWidgetDisposed,this),e.node.removeEventListener("focus",this,!0),e.node.removeEventListener("blur",this,!0),jf.RO.removeFirstOf(this._widgets,e),this._nodes.delete(e.node),this._numbers.delete(e),this._currentWidget!==e)return;let t=this._widgets.filter((e=>-1!==this._numbers.get(e))),i=(0,jf.Fp)(t,((e,t)=>this._numbers.get(e)-this._numbers.get(t)))||null;this._setWidgets(i,null)}handleEvent(e){switch(e.type){case"focus":this._evtFocus(e);break;case"blur":this._evtBlur(e)}}_setWidgets(e,t){let i=this._currentWidget;this._currentWidget=e;let n=this._activeWidget;this._activeWidget=t,i!==e&&this._currentChanged.emit({oldValue:i,newValue:e}),n!==t&&this._activeChanged.emit({oldValue:n,newValue:t})}_evtFocus(e){let t=this._nodes.get(e.currentTarget);t!==this._currentWidget&&this._numbers.set(t,this._counter++),this._setWidgets(t,t)}_evtBlur(e){let t=this._nodes.get(e.currentTarget),i=e.relatedTarget;i&&(t.node.contains(i)||(0,jf.sE)(this._widgets,(e=>e.node.contains(i))))||this._setWidgets(this._currentWidget,null)}_onWidgetDisposed(e){this.remove(e)}}class Zm extends mm{constructor(e={}){super(e),this._dirty=!1,this._rowSpacing=4,this._columnSpacing=4,this._items=[],this._rowStarts=[],this._columnStarts=[],this._rowSizers=[new um],this._columnSizers=[new um],this._box=null,void 0!==e.rowCount&&Wm.reallocSizers(this._rowSizers,e.rowCount),void 0!==e.columnCount&&Wm.reallocSizers(this._columnSizers,e.columnCount),void 0!==e.rowSpacing&&(this._rowSpacing=Wm.clampValue(e.rowSpacing)),void 0!==e.columnSpacing&&(this._columnSpacing=Wm.clampValue(e.columnSpacing))}dispose(){for(const e of this._items){let t=e.widget;e.dispose(),t.dispose()}this._box=null,this._items.length=0,this._rowStarts.length=0,this._rowSizers.length=0,this._columnStarts.length=0,this._columnSizers.length=0,super.dispose()}get rowCount(){return this._rowSizers.length}set rowCount(e){e!==this.rowCount&&(Wm.reallocSizers(this._rowSizers,e),this.parent&&this.parent.fit())}get columnCount(){return this._columnSizers.length}set columnCount(e){e!==this.columnCount&&(Wm.reallocSizers(this._columnSizers,e),this.parent&&this.parent.fit())}get rowSpacing(){return this._rowSpacing}set rowSpacing(e){e=Wm.clampValue(e),this._rowSpacing!==e&&(this._rowSpacing=e,this.parent&&this.parent.fit())}get columnSpacing(){return this._columnSpacing}set columnSpacing(e){e=Wm.clampValue(e),this._columnSpacing!==e&&(this._columnSpacing=e,this.parent&&this.parent.fit())}rowStretch(e){let t=this._rowSizers[e];return t?t.stretch:-1}setRowStretch(e,t){let i=this._rowSizers[e];i&&(t=Wm.clampValue(t),i.stretch!==t&&(i.stretch=t,this.parent&&this.parent.update()))}columnStretch(e){let t=this._columnSizers[e];return t?t.stretch:-1}setColumnStretch(e,t){let i=this._columnSizers[e];i&&(t=Wm.clampValue(t),i.stretch!==t&&(i.stretch=t,this.parent&&this.parent.update()))}*[Symbol.iterator](){for(const e of this._items)yield e.widget}addWidget(e){-1===jf.RO.findFirstIndex(this._items,(t=>t.widget===e))&&(this._items.push(new gm(e)),this.parent&&this.attachWidget(e))}removeWidget(e){let t=jf.RO.findFirstIndex(this._items,(t=>t.widget===e));if(-1===t)return;let i=jf.RO.removeAt(this._items,t);this.parent&&this.detachWidget(e),i.dispose()}init(){super.init();for(const e of this)this.attachWidget(e)}attachWidget(e){this.parent.isAttached&&Lf.sendMessage(e,fm.Msg.BeforeAttach),this.parent.node.appendChild(e.node),this.parent.isAttached&&Lf.sendMessage(e,fm.Msg.AfterAttach),this.parent.fit()}detachWidget(e){this.parent.isAttached&&Lf.sendMessage(e,fm.Msg.BeforeDetach),this.parent.node.removeChild(e.node),this.parent.isAttached&&Lf.sendMessage(e,fm.Msg.AfterDetach),this.parent.fit()}onBeforeShow(e){super.onBeforeShow(e),this.parent.update()}onBeforeAttach(e){super.onBeforeAttach(e),this.parent.fit()}onChildShown(e){this.parent.fit()}onChildHidden(e){this.parent.fit()}onResize(e){this.parent.isVisible&&this._update(e.width,e.height)}onUpdateRequest(e){this.parent.isVisible&&this._update(-1,-1)}onFitRequest(e){this.parent.isAttached&&this._fit()}_fit(){for(let e=0,t=this.rowCount;e!e.isHidden));for(let t=0,i=e.length;t({row:0,column:0,rowSpan:1,columnSpan:1}),changed:function(e){e.parent&&e.parent.layout instanceof Zm&&e.parent.fit()}}),e.normalizeConfig=function(e){return{row:Math.max(0,Math.floor(e.row||0)),column:Math.max(0,Math.floor(e.column||0)),rowSpan:Math.max(1,Math.floor(e.rowSpan||0)),columnSpan:Math.max(1,Math.floor(e.columnSpan||0))}},e.clampValue=function(e){return Math.max(0,Math.floor(e))},e.rowSpanCmp=function(t,i){let n=e.cellConfigProperty.get(t.widget),s=e.cellConfigProperty.get(i.widget);return n.rowSpan-s.rowSpan},e.columnSpanCmp=function(t,i){let n=e.cellConfigProperty.get(t.widget),s=e.cellConfigProperty.get(i.widget);return n.columnSpan-s.columnSpan},e.reallocSizers=function(e,t){for(t=Math.max(1,Math.floor(t));e.lengtht&&(e.length=t)},e.distributeMin=function(e,t,i,n){if(i=n)return;let r=(n-s)/(i-t+1);for(let n=t;n<=i;++n)e[n].minSize+=r}}(Wm||(Wm={}));class Km extends fm{constructor(e={}){super({node:Vm.createNode()}),this._activeIndex=-1,this._tabFocusIndex=0,this._menus=[],this._childMenu=null,this._overflowMenu=null,this._menuItemSizes=[],this._overflowIndex=-1,this.addClass("lm-MenuBar"),this.setFlag(fm.Flag.DisallowLayout),this.renderer=e.renderer||Km.defaultRenderer,this._forceItemsPosition=e.forceItemsPosition||{forceX:!0,forceY:!0},this._overflowMenuOptions=e.overflowMenuOptions||{isVisible:!0}}dispose(){this._closeChildMenu(),this._menus.length=0,super.dispose()}get childMenu(){return this._childMenu}get overflowIndex(){return this._overflowIndex}get overflowMenu(){return this._overflowMenu}get contentNode(){return this.node.getElementsByClassName("lm-MenuBar-content")[0]}get activeMenu(){return this._menus[this._activeIndex]||null}set activeMenu(e){this.activeIndex=e?this._menus.indexOf(e):-1}get activeIndex(){return this._activeIndex}set activeIndex(e){(e<0||e>=this._menus.length)&&(e=-1),this._activeIndex!==e&&(this._activeIndex=e,-1!==e&&(this._tabFocusIndex=e),this._activeIndex>=0&&this.contentNode.childNodes[this._activeIndex]&&this.contentNode.childNodes[this._activeIndex].focus(),this.update())}get menus(){return this._menus}openActiveMenu(){-1!==this._activeIndex&&(this._openChildMenu(),this._childMenu&&(this._childMenu.activeIndex=-1,this._childMenu.activateNextItem()))}addMenu(e,t=!0){this.insertMenu(this._menus.length,e,t)}insertMenu(e,t,i=!0){this._closeChildMenu();let n=this._menus.indexOf(t),s=Math.max(0,Math.min(e,this._menus.length));if(-1===n)return jf.RO.insert(this._menus,s,t),t.addClass("lm-MenuBar-menu"),t.aboutToClose.connect(this._onMenuAboutToClose,this),t.menuRequested.connect(this._onMenuMenuRequested,this),t.title.changed.connect(this._onTitleChanged,this),void(i&&this.update());s===this._menus.length&&s--,n!==s&&(jf.RO.move(this._menus,n,s),i&&this.update())}removeMenu(e,t=!0){this.removeMenuAt(this._menus.indexOf(e),t)}removeMenuAt(e,t=!0){this._closeChildMenu();let i=jf.RO.removeAt(this._menus,e);i&&(i.aboutToClose.disconnect(this._onMenuAboutToClose,this),i.menuRequested.disconnect(this._onMenuMenuRequested,this),i.title.changed.disconnect(this._onTitleChanged,this),i.removeClass("lm-MenuBar-menu"),t&&this.update())}clearMenus(){if(0!==this._menus.length){this._closeChildMenu();for(let e of this._menus)e.aboutToClose.disconnect(this._onMenuAboutToClose,this),e.menuRequested.disconnect(this._onMenuMenuRequested,this),e.title.changed.disconnect(this._onTitleChanged,this),e.removeClass("lm-MenuBar-menu");this._menus.length=0,this.update()}}handleEvent(e){switch(e.type){case"keydown":this._evtKeyDown(e);break;case"mousedown":this._evtMouseDown(e);break;case"mousemove":this._evtMouseMove(e);break;case"mouseleave":this._evtMouseLeave(e);break;case"contextmenu":e.preventDefault(),e.stopPropagation()}}onBeforeAttach(e){this.node.addEventListener("keydown",this),this.node.addEventListener("mousedown",this),this.node.addEventListener("mousemove",this),this.node.addEventListener("mouseleave",this),this.node.addEventListener("contextmenu",this)}onAfterDetach(e){this.node.removeEventListener("keydown",this),this.node.removeEventListener("mousedown",this),this.node.removeEventListener("mousemove",this),this.node.removeEventListener("mouseleave",this),this.node.removeEventListener("contextmenu",this),this._closeChildMenu()}onActivateRequest(e){this.isAttached&&(this.activeIndex=0)}onResize(e){this.update(),super.onResize(e)}onUpdateRequest(e){var t;let i=this._menus,n=this.renderer,s=this._activeIndex,r=this._tabFocusIndex>=0&&this._tabFocusIndex-1?this._overflowIndex:i.length,a=0,l=!1;o=null!==this._overflowMenu?o-1:o;let h=new Array(o);for(let e=0;e{this.activeIndex=e}}),a+=this._menuItemSizes[e],i[e].title.label===this._overflowMenuOptions.title&&(l=!0,o--);if(this._overflowMenuOptions.isVisible)if(this._overflowIndex>-1&&!l){if(null===this._overflowMenu){const e=null!==(t=this._overflowMenuOptions.title)&&void 0!==t?t:"...";this._overflowMenu=new Nm({commands:new lm}),this._overflowMenu.title.label=e,this._overflowMenu.title.mnemonic=0,this.addMenu(this._overflowMenu,!1)}for(let e=i.length-2;e>=o;e--){const t=this.menus[e];t.title.mnemonic=0,this._overflowMenu.insertItem(0,{type:"submenu",submenu:t}),this.removeMenu(t,!1)}h[o]=n.renderItem({title:this._overflowMenu.title,active:o===s&&0!==i[o].items.length,tabbable:o===r,onfocus:()=>{this.activeIndex=o}}),o++}else if(null!==this._overflowMenu){let e=this._overflowMenu.items,t=this.node.offsetWidth,s=this._overflowMenu.items.length;for(let l=0;lthis._menuItemSizes[s]){let t=e[0].submenu;this._overflowMenu.removeItemAt(0),this.insertMenu(o,t,!1),h[o]=n.renderItem({title:t.title,active:!1,tabbable:o===r,onfocus:()=>{this.activeIndex=o}}),o++}}0===this._overflowMenu.items.length&&(this.removeMenu(this._overflowMenu,!1),h.pop(),this._overflowMenu=null,this._overflowIndex=-1)}im.render(h,this.contentNode),this._updateOverflowIndex()}_updateOverflowIndex(){if(!this._overflowMenuOptions.isVisible)return;const e=this.contentNode.childNodes;let t=this.node.offsetWidth,i=0,n=-1,s=e.length;if(0==this._menuItemSizes.length)for(let r=0;rt&&-1===n&&(n=r)}else for(let e=0;et){n=e;break}this._overflowIndex=n}_evtKeyDown(e){let t=e.keyCode;if(9===t)return void(this.activeIndex=-1);if(e.preventDefault(),e.stopPropagation(),13===t||32===t||38===t||40===t)return void this.openActiveMenu();if(27===t)return this._closeChildMenu(),this.activeIndex=-1,void this.node.blur();if(37===t){let e=this._activeIndex,t=this._menus.length;return void(this.activeIndex=0===e?t-1:e-1)}if(39===t){let e=this._activeIndex,t=this._menus.length;return void(this.activeIndex=e===t-1?0:e+1)}let i=Zf().keyForKeydownEvent(e);if(!i)return;let n=this._activeIndex+1,s=Vm.findMnemonic(this._menus,i,n);-1===s.index||s.multiple?-1!==s.index?this.activeIndex=s.index:-1!==s.auto&&(this.activeIndex=s.auto):(this.activeIndex=s.index,this.openActiveMenu())}_evtMouseDown(e){if(!Af.hitTest(this.node,e.clientX,e.clientY))return;e.preventDefault(),e.stopPropagation(),e.stopImmediatePropagation();let t=jf.RO.findFirstIndex(this.contentNode.children,(t=>Af.hitTest(t,e.clientX,e.clientY)));if(-1!==t){if(0===e.button)if(this._childMenu)this._closeChildMenu(),this.activeIndex=t;else{const e=this._positionForMenu(t);Nm.saveWindowData(),this.activeIndex=t,this._openChildMenu(e)}}else this._closeChildMenu()}_evtMouseMove(e){let t=jf.RO.findFirstIndex(this.contentNode.children,(t=>Af.hitTest(t,e.clientX,e.clientY)));if(t===this._activeIndex)return;if(-1===t&&this._childMenu)return;const i=t>=0&&this._childMenu?this._positionForMenu(t):null;Nm.saveWindowData(),this.activeIndex=t,i&&this._openChildMenu(i)}_positionForMenu(e){let t=this.contentNode.children[e],{left:i,bottom:n}=t.getBoundingClientRect();return{top:n,left:i}}_evtMouseLeave(e){this._childMenu||(this.activeIndex=-1)}_openChildMenu(e={}){let t=this.activeMenu;if(!t)return void this._closeChildMenu();let i=this._childMenu;if(i===t)return;this._childMenu=t,i?i.close():document.addEventListener("mousedown",this,!0),Lf.sendMessage(this,fm.Msg.UpdateRequest);let{left:n,top:s}=e;void 0!==n&&void 0!==s||({left:n,top:s}=this._positionForMenu(this._activeIndex)),i||this.addClass("lm-mod-active"),t.items.length>0&&t.open(n,s,this._forceItemsPosition)}_closeChildMenu(){if(!this._childMenu)return;this.removeClass("lm-mod-active"),document.removeEventListener("mousedown",this,!0);let e=this._childMenu;this._childMenu=null,e.close(),this.activeIndex=-1}_onMenuAboutToClose(e){e===this._childMenu&&(this.removeClass("lm-mod-active"),document.removeEventListener("mousedown",this,!0),this._childMenu=null,this.activeIndex=-1)}_onMenuMenuRequested(e,t){if(e!==this._childMenu)return;let i=this._activeIndex,n=this._menus.length;switch(t){case"next":this.activeIndex=i===n-1?0:i+1;break;case"previous":this.activeIndex=0===i?n-1:i-1}this.openActiveMenu()}_onTitleChanged(){this.update()}}!function(e){class t{renderItem(e){let t=this.createItemClass(e),i=this.createItemDataset(e),n=this.createItemARIA(e);return dm.li({className:t,dataset:i,tabindex:e.tabbable?"0":"-1",onfocus:e.onfocus,...n},this.renderIcon(e),this.renderLabel(e))}renderIcon(e){let t=this.createIconClass(e);return dm.div({className:t},e.title.icon,e.title.iconLabel)}renderLabel(e){let t=this.formatLabel(e);return dm.div({className:"lm-MenuBar-itemLabel"},t)}createItemClass(e){let t="lm-MenuBar-item";return e.title.className&&(t+=` ${e.title.className}`),e.active&&(t+=" lm-mod-active"),t}createItemDataset(e){return e.title.dataset}createItemARIA(e){return{role:"menuitem","aria-haspopup":"true"}}createIconClass(e){let t="lm-MenuBar-itemIcon",i=e.title.iconClass;return i?`${t} ${i}`:t}formatLabel(e){let{label:t,mnemonic:i}=e.title;if(i<0||i>=t.length)return t;let n=t.slice(0,i),s=t.slice(i+1),r=t[i];return[n,dm.span({className:"lm-MenuBar-itemMnemonic"},r),s]}}e.Renderer=t,e.defaultRenderer=new t}(Km||(Km={})),function(e){e.createNode=function(){let e=document.createElement("div"),t=document.createElement("ul");return t.className="lm-MenuBar-content",e.appendChild(t),t.setAttribute("role","menubar"),e},e.findMnemonic=function(e,t,i){let n=-1,s=-1,r=!1,o=t.toUpperCase();for(let t=0,a=e.length;t=0&&c1&&this.widgets.forEach((e=>{e.hiddenMode=this._hiddenMode})))}dispose(){for(const e of this._items)e.dispose();this._box=null,this._items.length=0,super.dispose()}attachWidget(e,t){this._hiddenMode===fm.HiddenMode.Scale&&this._items.length>0?(1===this._items.length&&(this.widgets[0].hiddenMode=fm.HiddenMode.Scale),t.hiddenMode=fm.HiddenMode.Scale):t.hiddenMode=fm.HiddenMode.Display,jf.RO.insert(this._items,e,new gm(t)),this.parent.isAttached&&Lf.sendMessage(t,fm.Msg.BeforeAttach),this.parent.node.appendChild(t.node),this.parent.isAttached&&Lf.sendMessage(t,fm.Msg.AfterAttach),this.parent.fit()}moveWidget(e,t,i){jf.RO.move(this._items,e,t),this.parent.update()}detachWidget(e,t){let i=jf.RO.removeAt(this._items,e);this.parent.isAttached&&Lf.sendMessage(t,fm.Msg.BeforeDetach),this.parent.node.removeChild(t.node),this.parent.isAttached&&Lf.sendMessage(t,fm.Msg.AfterDetach),i.widget.node.style.zIndex="",this._hiddenMode===fm.HiddenMode.Scale&&(t.hiddenMode=fm.HiddenMode.Display,1===this._items.length&&(this._items[0].widget.hiddenMode=fm.HiddenMode.Display)),i.dispose(),this.parent.fit()}onBeforeShow(e){super.onBeforeShow(e),this.parent.update()}onBeforeAttach(e){super.onBeforeAttach(e),this.parent.fit()}onChildShown(e){this.parent.fit()}onChildHidden(e){this.parent.fit()}onResize(e){this.parent.isVisible&&this._update(e.width,e.height)}onUpdateRequest(e){this.parent.isVisible&&this._update(-1,-1)}onFitRequest(e){this.parent.isAttached&&this._fit()}_fit(){let e=0,t=0;for(let i=0,n=this._items.length;i{t.newValue!==this.currentWidget&&(i.current=t.newValue)}),this),i.added.connect(((e,t)=>{this._widgetAdded.emit(t)}),this),i.currentChanged.connect(((e,n)=>{null===n&&t.currentWidget?i.current=t.currentWidget:(this.onCurrentChanged(n),this._currentChanged.emit(n))}),this),i.updated.connect(((e,t)=>{this._widgetUpdated.emit(t)}),this)}get currentChanged(){return this._currentChanged}get currentWidget(){return this._pool.current||null}get restored(){return this._deferred?Promise.resolve():this._pool.restored}get size(){return this._pool.size}get widgetAdded(){return this._widgetAdded}get widgetUpdated(){return this._widgetUpdated}async add(e){this._focusTracker.add(e),await this._pool.add(e),this._focusTracker.activeWidget||(this._pool.current=e)}get isDisposed(){return this._isDisposed}dispose(){this.isDisposed||(this._isDisposed=!0,this._pool.dispose(),this._focusTracker.dispose(),zf.Signal.clearData(this))}find(e){return this._pool.find(e)}forEach(e){return this._pool.forEach(e)}filter(e){return this._pool.filter(e)}inject(e){return this._pool.inject(e)}has(e){return this._pool.has(e)}async restore(e){const t=this._deferred;return t?(this._deferred=null,this._pool.restore(t)):e?this._pool.restore(e):void console.warn("No options provided to restore the tracker.")}defer(e){this._deferred=e}async save(e){return this._pool.save(e)}onCurrentChanged(e){}}function tg(e){return e.replace("-","_")}class ig{constructor(e){e=e||{},this._defaults={domain:"messages",locale:document.documentElement.getAttribute("lang")||"en",pluralFunc:function(e){return{nplurals:2,plural:1!=e?1:0}},contextDelimiter:String.fromCharCode(4),stringsPrefix:""},this._locale=(e.locale||this._defaults.locale).replace("_","-"),this._domain=tg(e.domain||this._defaults.domain),this._contextDelimiter=e.contextDelimiter||this._defaults.contextDelimiter,this._stringsPrefix=e.stringsPrefix||this._defaults.stringsPrefix,this._pluralFuncs={},this._dictionary={},this._pluralForms={},e.messages&&(this._dictionary[this._domain]={},this._dictionary[this._domain][this._locale]=e.messages),e.pluralForms&&(this._pluralForms[this._locale]=e.pluralForms)}setContextDelimiter(e){this._contextDelimiter=e}getContextDelimiter(){return this._contextDelimiter}setLocale(e){this._locale=e.replace("_","-")}getLocale(){return this._locale}setDomain(e){this._domain=tg(e)}getDomain(){return this._domain}setStringsPrefix(e){this._stringsPrefix=e}getStringsPrefix(){return this._stringsPrefix}static strfmt(e,...t){return e.replace(/%%/g,"%% ").replace(/%(\d+)/g,(function(e,i){return t[i-1]})).replace(/%% /g,"%")}loadJSON(e,t){if(!e[""]||!e[""].language||!e[""].pluralForms)throw new Error(`Wrong jsonData, it must have an empty key ("") with "language" and "pluralForms" information: ${e}`);t=tg(t);let i=e[""],n=JSON.parse(JSON.stringify(e));delete n[""],this.setMessages(t||this._defaults.domain,i.language,n,i.pluralForms)}__(e,...t){return this.gettext(e,...t)}_n(e,t,i,...n){return this.ngettext(e,t,i,...n)}_p(e,t,...i){return this.pgettext(e,t,...i)}_np(e,t,i,n,...s){return this.npgettext(e,t,i,n,...s)}gettext(e,...t){return this.dcnpgettext("","",e,"",0,...t)}ngettext(e,t,i,...n){return this.dcnpgettext("","",e,t,i,...n)}pgettext(e,t,...i){return this.dcnpgettext("",e,t,"",0,...i)}npgettext(e,t,i,n,...s){return this.dcnpgettext("",e,t,i,n,...s)}dcnpgettext(e,t,i,n,s,...r){let o;e=tg(e)||this._domain;let a=t?t+this._contextDelimiter+i:i,l={pluralForm:!1},h=!1,c=this._locale,d=this.expandLocale(this._locale);for(let t in d)if(c=d[t],h=this._dictionary[e]&&this._dictionary[e][c]&&this._dictionary[e][c][a],h=n?h&&this._dictionary[e][c][a].length>1:h&&1==this._dictionary[e][c][a].length,h){l.locale=c;break}if(h?o=this._dictionary[e][c][a]:(o=[i],l.pluralFunc=this._defaults.pluralFunc),!n)return this.t(o,s,l,...r);l.pluralForm=!0;let u=h?o:[i,n];return this.t(u,s,l,...r)}expandLocale(e){let t=[e],i=e.lastIndexOf("-");for(;i>0;)e=e.slice(0,i),t.push(e),i=e.lastIndexOf("-");return t}getPluralFunc(e){if(!new RegExp("^\\s*nplurals\\s*=\\s*[0-9]+\\s*;\\s*plural\\s*=\\s*(?:\\s|[-\\?\\|&=!<>+*/%:;n0-9_()])+").test(e))throw new Error(ig.strfmt('The plural form "%1" is not valid',e));return new Function("n","let plural, nplurals; "+e+" return { nplurals: nplurals, plural: (plural === true ? 1 : (plural ? plural : 0)) };")}removeContext(e){return-1!==e.indexOf(this._contextDelimiter)?e.split(this._contextDelimiter)[1]:e}t(e,t,i,...n){if(!i.pluralForm)return this._stringsPrefix+ig.strfmt(this.removeContext(e[0]),...n);let s;return i.pluralFunc?s=i.pluralFunc(t):(this._pluralFuncs[i.locale||""]||(this._pluralFuncs[i.locale||""]=this.getPluralFunc(this._pluralForms[i.locale||""])),s=this._pluralFuncs[i.locale||""](t)),(void 0===!s.plural||s.plural>s.nplurals||e.length<=s.plural)&&(s.plural=0),this._stringsPrefix+ig.strfmt(this.removeContext(e[s.plural]),...[t].concat(n))}setMessages(e,t,i,n){e=tg(e),n&&(this._pluralForms[t]=n),this._dictionary[e]||(this._dictionary[e]={}),this._dictionary[e][t]=i}}const ng=new class{constructor(e){this.languageCode="en",this._languageBundle=e}load(e){return this._languageBundle}}(new class{__(e,...t){return this.gettext(e,...t)}_n(e,t,i,...n){return this.ngettext(e,t,i,...n)}_p(e,t,...i){return this.pgettext(e,t,...i)}_np(e,t,i,n,...s){return this.npgettext(e,t,i,n,...s)}gettext(e,...t){return ig.strfmt(e,...t)}ngettext(e,t,i,...n){return ig.strfmt(1==i?e:t,...[i].concat(n))}pgettext(e,t,...i){return ig.strfmt(t,...i)}npgettext(e,t,i,n,...s){return this.ngettext(t,i,n,...s)}dcnpgettext(e,t,i,n,s,...r){return this.ngettext(i,n,s,...r)}});new Wf.Token("@jupyterlab/translation:ITranslatorConnector","A service to connect to the server translation endpoint."),new Wf.Token("@jupyterlab/translation:ITranslator","A service to translate strings.");const sg="jp-OutputArea-child",rg="jp-OutputArea-output",og="jp-OutputArea-prompt";class ag extends fm{constructor(e){var t,i,n,s;super(),this.outputLengthChanged=new zf.Signal(this),this._onIOPub=e=>{const t=this.model,i=e.header.msg_type;let n;const s=(e.content.transient||{}).display_id;let r;switch(i){case"execute_result":case"display_data":case"stream":case"error":n={...e.content,output_type:i},t.add(n);break;case"clear_output":{const i=e.content.wait;t.clear(i);break}case"update_display_data":if(n={...e.content,output_type:"display_data"},r=this._displayIdMap.get(s),r)for(const e of r)t.set(e,n)}s&&"display_data"===i&&(r=this._displayIdMap.get(s)||[],r.push(t.length-1),this._displayIdMap.set(s,r))},this._onExecuteReply=e=>{const t=this.model,i=e.content;if("ok"!==i.status)return;const n=i&&i.payload;if(!n||!n.length)return;const s=n.filter((e=>"page"===e.source));if(!s.length)return;const r={output_type:"display_data",data:JSON.parse(JSON.stringify(s[0])).data,metadata:{}};t.add(r)},this._displayIdMap=new Map,this._minHeightTimeout=null,this._inputRequested=new zf.Signal(this),this._toggleScrolling=new zf.Signal(this),this._outputTracker=new eg({namespace:Wf.UUID.uuid4()}),this._inputHistoryScope="global",super.layout=new vm,this.addClass("jp-OutputArea"),this.contentFactory=null!==(t=e.contentFactory)&&void 0!==t?t:ag.defaultContentFactory,this.rendermime=e.rendermime,this._maxNumberOutputs=null!==(i=e.maxNumberOutputs)&&void 0!==i?i:1/0,this._translator=null!==(n=e.translator)&&void 0!==n?n:ng,this._inputHistoryScope=null!==(s=e.inputHistoryScope)&&void 0!==s?s:"global";const r=this.model=e.model;for(let e=0;e{$f.KernelMessage.isInputRequestMsg(t)&&this.onInputRequest(t,e)})}get inputRequested(){return this._inputRequested}get maxNumberOutputs(){return this._maxNumberOutputs}set maxNumberOutputs(e){if(e<=0)return void console.warn("OutputArea.maxNumberOutputs must be strictly positive.");const t=this._maxNumberOutputs;this._maxNumberOutputs=e,t{this._toggleScrolling.emit()})),this.node.appendChild(e)}_moveDisplayIdIndices(e,t){this._displayIdMap.forEach((i=>{const n=e+t;for(let s=i.length-1;s>=0;--s){const r=i[s];r>=e&&r=n&&(i[s]-=t)}}))}onStateChanged(e,t){const i=Math.min(this.model.length,this._maxNumberOutputs);if(t){if(t>=this._maxNumberOutputs)return;this._setOutput(t,this.model.get(t))}else for(let e=0;e{this.isDisposed||(this.node.style.minHeight="")}),50)}onInputRequest(e,t){const i=this.contentFactory,n=e.content.prompt,s=e.content.password,r=new Am;r.addClass(sg),r.addClass("jp-OutputArea-stdin-item");const o=i.createOutputPrompt();o.addClass(og),r.addWidget(o);const a=i.createStdin({parent_header:e.header,prompt:n,password:s,future:t,translator:this._translator,inputHistoryScope:this._inputHistoryScope});a.addClass(rg),r.addWidget(a),this.model.length>=this.maxNumberOutputs&&(this.maxNumberOutputs=this.model.length),this.layout.addWidget(r),this._inputRequested.emit(),a.value.then((e=>{this.model.length>=this.maxNumberOutputs&&(this.maxNumberOutputs=this.model.length+1),this.model.add({output_type:"stream",name:"stdin",text:e+"\n"}),r.dispose()}))}_setOutput(e,t){if(e>=this._maxNumberOutputs)return;const i=this.layout.widgets[e],n=i.widgets?i.widgets[1]:i,s=this.rendermime.preferredMimeType(t.data,t.trusted?"any":"ensure");cg.currentPreferredMimetype.get(n)===s&&ag.isIsolated(s,t.metadata)===n instanceof cg.IsolatedRenderer?n.renderModel(t):(this.layout.widgets[e].dispose(),this._insertOutput(e,t))}_insertOutput(e,t){if(e>this._maxNumberOutputs)return;const i=this.layout;if(e===this._maxNumberOutputs){const t=new cg.TrimmedOutputs(this._maxNumberOutputs,(()=>{const e=this._maxNumberOutputs;this._maxNumberOutputs=1/0,this._showTrimmedOutputs(e)}));i.insertWidget(e,this._wrappedOutput(t))}else{let n=this.createOutputItem(t);n?n.toggleClass("jp-OutputArea-executeResult",null!==t.executionCount):n=new fm,this._outputTracker.has(n)||this._outputTracker.add(n),i.insertWidget(e,n)}}get outputTracker(){return this._outputTracker}_showTrimmedOutputs(e){this.widgets[e].dispose();for(let t=e;t{const t=document.createElement("pre"),n=this._translator.load("jupyterlab");t.textContent=n.__("Javascript Error: %1",e.message),i.node.appendChild(t),i.node.className="lm-Widget jp-RenderedText",i.node.setAttribute("data-mime-type","application/vnd.jupyter.stderr")})),i}_wrappedOutput(e,t=null){const i=new cg.OutputPanel;i.addClass(sg);const n=this.contentFactory.createOutputPrompt();return n.executionCount=t,n.addClass(og),i.addWidget(n),e.addClass(rg),i.addWidget(e),i}}!function(e){e.execute=async function(e,t,i,n){var s;let r=!0;n&&Array.isArray(n.tags)&&-1!==n.tags.indexOf("raises-exception")&&(r=!1);const o={code:e,stop_on_error:r},a=null===(s=i.session)||void 0===s?void 0:s.kernel;if(!a)throw new Error("Session has no kernel.");const l=a.requestExecute(o,!1,n);return t.future=l,l.done},e.isIsolated=function(e,t){const i=t[e];return i&&void 0!==i.isolated?!!i.isolated:!!t.isolated};class t{createOutputPrompt(){return new lg}createStdin(e){return new hg(e)}}e.ContentFactory=t,e.defaultContentFactory=new t}(ag||(ag={}));class lg extends fm{constructor(){super(),this._executionCount=null,this.addClass("jp-OutputPrompt")}get executionCount(){return this._executionCount}set executionCount(e){this._executionCount=e,this.node.textContent=null===e?"":`[${e}]:`}}class hg extends fm{static _historyIx(e,t){const i=hg._history.get(e);if(!i)return;const n=i.length;return t<=0?n+t:void 0}static _historyAt(e,t){const i=hg._history.get(e);if(!i)return;const n=i.length,s=hg._historyIx(e,t);return void 0!==s&&s1e3&&i.shift()}static _historySearch(e,t,i,n=!0){const s=hg._history.get(e),r=s.length,o=hg._historyIx(e,i),a=e=>-1!==e.search(t);if(void 0!==o)if(n){if(0===o)return;const e=s.slice(0,o).findLastIndex(a);if(-1!==e)return e-r}else{if(o>=r-1)return;const e=s.slice(o+1).findIndex(a);if(-1!==e)return e-r+o+1}}constructor(e){var t;super({node:cg.createInputWidgetNode(e.prompt,e.password)}),this._promise=new Wf.PromiseDelegate,this.addClass("jp-Stdin"),this._future=e.future,this._historyIndex=0,this._historyKey="session"===e.inputHistoryScope?e.parent_header.session:"",this._historyPat="",this._parentHeader=e.parent_header,this._password=e.password,this._trans=(null!==(t=e.translator)&&void 0!==t?t:ng).load("jupyterlab"),this._value=e.prompt+" ",this._input=this.node.getElementsByTagName("input")[0],this._input.placeholder=this._trans.__("↑↓ for history. Search history with c-↑/c-↓"),hg._history.has(this._historyKey)||hg._history.set(this._historyKey,[])}get value(){return this._promise.promise.then((()=>this._value))}handleEvent(e){const t=this._input;if("keydown"===e.type)if("Enter"===e.key)this.resetSearch(),this._future.sendInputReply({status:"ok",value:t.value},this._parentHeader),this._password?this._value+="········":(this._value+=t.value,hg._historyPush(this._historyKey,t.value)),this._promise.resolve(void 0);else if("Escape"===e.key)this.resetSearch(),t.blur();else if(!e.ctrlKey||"ArrowUp"!==e.key&&"ArrowDown"!==e.key){if("ArrowUp"===e.key){this.resetSearch();const i=hg._historyAt(this._historyKey,this._historyIndex-1);i&&(0===this._historyIndex&&(this._valueCache=t.value),this._setInputValue(i),--this._historyIndex,e.preventDefault())}else if("ArrowDown"===e.key)if(this.resetSearch(),0===this._historyIndex);else if(-1===this._historyIndex)this._setInputValue(this._valueCache),++this._historyIndex;else{const e=hg._historyAt(this._historyKey,this._historyIndex+1);e&&(this._setInputValue(e),++this._historyIndex)}}else{""===this._historyPat&&(this._historyPat=t.value);const i="ArrowUp"===e.key,n=hg._historySearch(this._historyKey,this._historyPat,this._historyIndex,i);if(void 0!==n){const i=hg._historyAt(this._historyKey,n);void 0!==i&&(0===this._historyIndex&&(this._valueCache=t.value),this._setInputValue(i),this._historyIndex=n,e.preventDefault())}}}resetSearch(){this._historyPat=""}onAfterAttach(e){this._input.addEventListener("keydown",this),this._input.focus()}onBeforeDetach(e){this._input.removeEventListener("keydown",this)}_setInputValue(e){this._input.value=e,this._input.setSelectionRange(e.length,e.length)}}var cg,dg,ug,pg,fg;function mg(e){return"execute_result"===e.output_type}function gg(e){return"display_data"===e.output_type}function vg(e){return"stream"===e.output_type}hg._history=new Map,function(e){e.createInputWidgetNode=function(e,t){const i=document.createElement("div"),n=document.createElement("pre");n.className="jp-Stdin-prompt",n.textContent=e;const s=document.createElement("input");return s.className="jp-Stdin-input",t&&(s.type="password"),i.appendChild(n),n.appendChild(s),i},e.IsolatedRenderer=class extends fm{constructor(e){super({node:document.createElement("iframe")}),this.addClass("jp-mod-isolated"),this._wrapped=e;const t=this.node;t.frameBorder="0",t.scrolling="auto",t.addEventListener("load",(()=>{t.contentDocument.open(),t.contentDocument.write(this._wrapped.node.innerHTML),t.contentDocument.close();const e=t.contentDocument.body;t.style.height=`${e.scrollHeight}px`,t.heightChangeObserver=new ResizeObserver((()=>{t.style.height=`${e.scrollHeight}px`})),t.heightChangeObserver.observe(e)}))}renderModel(e){return this._wrapped.renderModel(e)}},e.currentPreferredMimetype=new Xf.AttachedProperty({name:"preferredMimetype",create:e=>""}),e.OutputPanel=class extends Am{constructor(e){super(e)}_onContext(e){this.node.focus()}onAfterAttach(e){super.onAfterAttach(e),this.node.addEventListener("contextmenu",this._onContext.bind(this))}onBeforeDetach(e){super.onAfterDetach(e),this.node.removeEventListener("contextmenu",this._onContext.bind(this))}},e.TrimmedOutputs=class extends fm{constructor(e,t){const i=document.createElement("div"),n=`The first ${e} are displayed`;i.insertAdjacentHTML("afterbegin",`\n
Show more outputs
\n
`),super({node:i}),this._onClick=t,this.addClass("jp-TrimmedOutputs"),this.addClass("jp-RenderedHTMLCommon")}handleEvent(e){"click"===e.type&&this._onClick(e)}onAfterAttach(e){super.onAfterAttach(e),this.node.addEventListener("click",this)}onBeforeDetach(e){super.onBeforeDetach(e),this.node.removeEventListener("click",this)}}}(cg||(cg={}));class Og{constructor(e={}){if(this._array=[],this._isDisposed=!1,this._changed=new zf.Signal(this),e.values)for(const t of e.values)this._array.push(t);this._itemCmp=e.itemCmp||dg.itemCmp}get type(){return"List"}get changed(){return this._changed}get length(){return this._array.length}get isDisposed(){return this._isDisposed}dispose(){this._isDisposed||(this._isDisposed=!0,zf.Signal.clearData(this),this.clear())}[Symbol.iterator](){return this._array[Symbol.iterator]()}get(e){return this._array[e]}set(e,t){const i=this._array[e];if(void 0===t)throw new Error("Cannot set an undefined item");(0,this._itemCmp)(i,t)||(this._array[e]=t,this._changed.emit({type:"set",oldIndex:e,newIndex:e,oldValues:[i],newValues:[t]}))}push(e){const t=this._array.push(e);return this._changed.emit({type:"add",oldIndex:-1,newIndex:this.length-1,oldValues:[],newValues:[e]}),t}insert(e,t){e===this._array.length?this._array.push(t):jf.RO.insert(this._array,e,t),this._changed.emit({type:"add",oldIndex:-2,newIndex:e,oldValues:[],newValues:[t]})}removeValue(e){const t=this._itemCmp,i=jf.RO.findFirstIndex(this._array,(i=>t(i,e)));return this.remove(i),i}remove(e){const t=jf.RO.removeAt(this._array,e);if(void 0!==t)return this._changed.emit({type:"remove",oldIndex:e,newIndex:-1,newValues:[],oldValues:[t]}),t}clear(){const e=this._array.slice();this._array.length=0,this._changed.emit({type:"remove",oldIndex:0,newIndex:0,newValues:[],oldValues:e})}move(e,t){if(this.length<=1||e===t)return;const i=[this._array[e]];jf.RO.move(this._array,e,t),this._changed.emit({type:"move",oldIndex:e,newIndex:t,oldValues:i,newValues:i})}pushAll(e){const t=this.length;for(const t of e)this._array.push(t);return this._changed.emit({type:"add",oldIndex:-1,newIndex:t,oldValues:[],newValues:Array.from(e)}),this.length}insertAll(e,t){const i=e;for(const i of t)jf.RO.insert(this._array,e++,i);this._changed.emit({type:"add",oldIndex:-2,newIndex:i,oldValues:[],newValues:Array.from(t)})}removeRange(e,t){const i=this._array.slice(e,t);for(let i=e;i{e.push(i)})),e}values(){const e=[];return this._map.forEach(((t,i)=>{e.push(t)})),e}delete(e){const t=this._map.get(e);return this._map.delete(e)&&this._changed.emit({type:"remove",key:e,oldValue:t,newValue:void 0}),t}clear(){const e=this.keys();for(let t=0;te.toJSON())))}_add(e){const t=this._trusted;if(e=Wf.JSONExt.deepCopy(e),fg.normalize(e),vg(e)&&this._lastStream&&e.name===this._lastName&&this.shouldCombine({value:e,lastModel:this.list.get(this.length-1)})){this._lastStream+=e.text,this._lastStream=fg.removeOverwrittenChars(this._lastStream),e.text=this._lastStream;const i=this._createItem({value:e,trusted:t}),n=this.length-1,s=this.list.get(n);return this.list.set(n,i),s.dispose(),this.length}vg(e)&&(e.text=fg.removeOverwrittenChars(e.text));const i=this._createItem({value:e,trusted:t});return vg(e)?(this._lastStream=e.text,this._lastName=e.name):this._lastStream="",this.list.push(i)}shouldCombine(e){return!0}_createItem(e){return this.contentFactory.createOutputModel(e)}_onListChanged(e,t){switch(t.type){case"add":t.newValues.forEach((e=>{e.changed.connect(this._onGenericChange,this)}));break;case"remove":t.oldValues.forEach((e=>{e.changed.disconnect(this._onGenericChange,this)}));break;case"set":t.newValues.forEach((e=>{e.changed.connect(this._onGenericChange,this)})),t.oldValues.forEach((e=>{e.changed.disconnect(this._onGenericChange,this)}))}this._changed.emit(t)}_onGenericChange(e){let t,i=null;for(t=0;t-1;){const t=e.match(/^(.*)\r+/m)[1];let i=e.match(/\r+(.*)$/m)[1];i+=t.slice(i.length,t.length),e=e.replace(/\r+.*$/m,"\r").replace(/^.*\r/m,i)}return e}(function(e){let t=e;do{t=(e=t).replace(/[^\n]\x08/gm,"")}while(t.length{const n=e[t],s=e[i];return n.rank!==s.rank?n.rank-s.rank:n.id-s.id}))}}(Pg||(Pg={}));var Rg=__webpack_require__(6145),Dg=__webpack_require__.n(Rg);const Ig=/(\$\$?|\\(?:begin|end)\{[a-z]*\*?\}|\\[{}$]|[{}]|(?:\n\s*)+|@@\d+@@|\\\\(?:\(|\)|\[|\]))/i;function qg(e,t,i,n,s){let r=s.slice(e,t+1).join("").replace(/&/g,"&").replace(//g,">");for(navigator&&"Microsoft Internet Explorer"===navigator.appName&&(r=r.replace(/(%[^\n]*)\n/g,"$1
\n"));t>e;)s[t]="",t--;return s[e]="@@"+n.length+"@@",i&&(r=i(r)),n.push(r),s}function Lg(e){let{host:t,source:i,trusted:n,sanitizer:s,resolver:r,linkHandler:o,shouldTypeset:a,latexTypesetter:l,translator:h}=e;h=h||ng;const c=null==h?void 0:h.load("jupyterlab");let d,u=i;if(!i)return t.textContent="",Promise.resolve(void 0);if(n||(u=`${i}`,i=s.sanitize(i)),t.innerHTML=i,t.getElementsByTagName("script").length>0)if(n)zg.evalInnerHTMLScriptTags(t);else{const e=document.createElement("div"),i=document.createElement("pre");i.textContent=c.__("This HTML output contains inline scripts. Are you sure that you want to run arbitrary Javascript within your JupyterLab session?");const n=document.createElement("button");n.textContent=c.__("Run"),n.onclick=e=>{t.innerHTML=u,zg.evalInnerHTMLScriptTags(t),t.firstChild&&t.removeChild(t.firstChild)},e.appendChild(i),e.appendChild(n),t.insertBefore(e,t.firstChild)}return zg.handleDefaults(t,r),d=r?zg.handleUrls(t,r,o):Promise.resolve(void 0),d.then((()=>{a&&l&&l.typeset(t)}))}async function Ng(e){const{host:t,source:i,markdownParser:n,...s}=e;if(!i)return void(t.textContent="");let r="";if(n){const e=function(e){const t=[];let i,n=null,s=null,r=null,o=0;e.includes("`")||e.includes("~~~")?(e=e.replace(/~/g,"~T").replace(/^(?`{3,}|(~T){3,})[^`\n]*\n([\s\S]*?)^\k`*$/gm,(e=>e.replace(/\$/g,"~D"))).replace(/(^|[^\\])(`+)([^\n]*?[^`\n])\2(?!`)/gm,(e=>e.replace(/\$/g,"~D"))),i=e=>e.replace(/~([TD])/g,((e,t)=>"T"===t?"~":"$"))):i=e=>e;let a=e.replace(/\r\n?/g,"\n").split(Ig);for(let e=1,l=a.length;e{let i=a[t];return"\\\\("===i.substr(0,3)&&"\\\\)"===i.substr(i.length-3)?i="\\("+i.substring(3,i.length-3)+"\\)":"\\\\["===i.substr(0,3)&&"\\\\]"===i.substr(i.length-3)&&(i="\\["+i.substring(3,i.length-3)+"\\]"),i}))}else r=`
${i}
`;var o,a;await Lg({host:t,source:r,...s}),zg.headerAnchors(t)}function Bg(e,t){var i,n;const s=e.cloneNode();s.textContent=null===(i=e.textContent)||void 0===i?void 0:i.slice(0,t);const r=e.cloneNode();return r.textContent=null===(n=e.textContent)||void 0===n?void 0:n.slice(t),{pre:s,post:r}}function*$g(e){var t;let i,n=0;for(let s of e)i=n+((null===(t=s.textContent)||void 0===t?void 0:t.length)||0),yield{node:s,start:n,end:i,isText:s.nodeType===Node.TEXT_NODE},n=i}function Qg(e){var t,i;const{host:n,sanitizer:s,source:r}=e,o=s.sanitize(zg.ansiSpan(r),{allowedTags:["span"]}),a=document.createElement("pre"),l=document.createElement("pre");l.innerHTML=o;const h=l.textContent;if(h){const e=null===(i=null===(t=s.getAutolink)||void 0===t?void 0:t.call(s))||void 0===i||i?function(e){const t="\\u0000-\\u0020\\u007f-\\u009f",i=new RegExp("(?:[a-zA-Z][a-zA-Z0-9+.-]{2,}:\\/\\/|data:|www\\.)[^\\s"+t+'"]{2,}[^\\s'+t+"\"'(){}\\[\\],:;.!?]","ug"),n=[];let s,r=0;for(;null!=(s=i.exec(e));){s.index!==r&&n.push(document.createTextNode(e.slice(r,s.index)));let t=s[0];const i=t.slice(-1),o=-1!==[">","<"].indexOf(i)?t.length-1:t.length,a=document.createElement("a");t=t.slice(0,o),a.href=t.startsWith("www.")?"https://"+t:t,a.rel="noopener",a.target="_blank",a.appendChild(document.createTextNode(t.slice(0,o))),n.push(a),r=s.index+o}return r!==e.length&&n.push(document.createTextNode(e.slice(r,e.length))),n}(h):[document.createTextNode(o)];let n=!1;const r=[],c=Array.from(l.childNodes);for(let t of function*(e,t){var i,n;let s=$g(e),r=$g(t),o=s.next(),a=r.next();for(;!o.done&&!a.done;){let e=o.value,t=a.value;if(e.isText&&e.start<=t.start&&e.end>=t.end)yield[null,t.node],a=r.next();else if(t.isText&&t.start<=e.start&&t.end>=e.end)yield[e.node,null],o=s.next();else if(e.end===t.end&&e.start===t.start)yield[e.node,t.node],o=s.next(),a=r.next();else if(e.end>t.end){let{pre:n,post:s}=Bg(e.node,t.end-e.start);t.starte.end))throw new Error(`Unexpected intersection: ${JSON.stringify(e)} ${JSON.stringify(t)}`);{let{pre:i,post:r}=Bg(t.node,e.end-t.start);e.start{const s=decodeURIComponent(n);return i&&i.handleLink(e,s,r),t.getDownloadUrl(n)})).then((t=>{e.href=t+r})).catch((t=>{e.href=""}))}e.evalInnerHTMLScriptTags=function(e){const t=Array.from(e.getElementsByTagName("script"));for(const e of t){if(!e.parentNode)continue;const t=document.createElement("script"),i=e.attributes;for(let e=0,n=i.length;e{}))},e.headerAnchors=function(e){const t=["h1","h2","h3","h4","h5","h6"];for(const i of t){const t=e.getElementsByTagName(i);for(let e=0;e"),a.push(e),a.push("")):a.push(e)}}function r(e){let t,i,n;const s=e.shift();if(2===s&&e.length>=3){if(t=e.shift(),i=e.shift(),n=e.shift(),[t,i,n].some((e=>e<0||255=1))throw new RangeError("Invalid extended color specification");{const s=e.shift();if(s<0)throw new RangeError("Color index must be >= 0");if(s<16)return s;if(s<232)t=Math.floor((s-16)/36),t=t>0?55+40*t:0,i=Math.floor((s-16)%36/6),i=i>0?55+40*i:0,n=(s-16)%6,n=n>0?55+40*n:0;else{if(!(s<256))throw new RangeError("Color index must be < 256");t=i=n=10*(s-232)+8}}}return[t,i,n]}e.ansiSpan=function(e){const t=/\x1b\[(.*?)([@-~])/g;let i,n=[],o=[],a=!1,l=!1,h=!1;const c=[],d=[];let u=0;for(e=Dg()(e),e+="";i=t.exec(e);){if("m"===i[2]){const e=i[1].split(";");for(let t=0;t]+xmlns=[^>]+svg")<0&&(i=i.replace("new Vg(e)},{safe:!0,mimeTypes:["text/markdown"],defaultRank:60,createRenderer:e=>new Hg(e)},{safe:!0,mimeTypes:["text/latex"],defaultRank:70,createRenderer:e=>new Ug(e)},{safe:!1,mimeTypes:["image/svg+xml"],defaultRank:80,createRenderer:e=>new Xg(e)},{safe:!0,mimeTypes:["image/bmp","image/png","image/jpeg","image/gif","image/webp"],defaultRank:90,createRenderer:e=>new Fg(e)},{safe:!1,mimeTypes:["text/javascript","application/javascript"],defaultRank:110,createRenderer:e=>new Gg(e)},{safe:!0,mimeTypes:["text/plain","application/vnd.jupyter.stdout","application/vnd.jupyter.stderr"],defaultRank:120,createRenderer:e=>new Yg(e)}];var Kg=function(e,t,i,n){return new(i||(i=Promise))((function(s,r){function o(e){try{l(n.next(e))}catch(e){r(e)}}function a(e){try{l(n.throw(e))}catch(e){r(e)}}function l(e){var t;e.done?s(e.value):(t=e.value,t instanceof i?t:new i((function(e){e(t)}))).then(o,a)}l((n=n.apply(e,t||[])).next())}))};const Jg={cell:"manim-binder-cell",input:"manim-binder-input",button:"manim-binder-button",output:"manim-binder-output",wrapper:"manim-binder-wrapper",title:"manim-binder-title",meta:"manim-binder-meta",buttonWrapper:"manim-binder-button-wrapper"};!function(e){let t="ManimCommunity/jupyter_examples",i="main",n=60,s="manim-notebook-kernel",r="python3",o=Jg,a="https://mybinder.org",l=!1,h=null,c=null,d=null,u=null;function p(t){if(void 0!==e){const i=(new Date).getTime()+60*n*1e3,r=JSON.stringify({settings:t,timestamp:i});e.localStorage.setItem(s,r)}const i=$f.ServerConnection.makeSettings(t);return c=new $f.KernelManager({serverSettings:i}),u=new $f.ContentsManager({serverSettings:i}),c.startNew({name:r}).then((e=>e))}function f(e,t="",i=""){const n=document.createElement(e);return n.className=t,n.textContent=i,n}function m(e,t){return Kg(this,void 0,void 0,(function*(){const i=h.requestExecute({code:"from manim import *"});yield i.done,console.log("Import done. Now running code"),e.future=h.requestExecute({code:t}),e.model.add({output_type:"stream",name:"loading",text:"Loading..."}),e.model.clear(!0)}))}function g(n,r){if(h)return n.model.clear(),n.model.add({output_type:"stream",name:"loading",text:"Loading..."}),void m(n,r);const o=a.split("//")[1],c=l?"Reconnecting to":"Launching";n.model.clear(),n.model.add({output_type:"stream",name:"stdout",text:`${c} Docker container on ${o}...`}),new Promise(((n,r)=>function(){if(void 0!==e){const t=e.localStorage.getItem(s);if(t){l=!0;const{settings:i,timestamp:n}=JSON.parse(t);if(n&&(new Date).getTime(){const i=new EventSource(n);i.onerror=e=>{i.close(),t(new Error("Unable to connect to Binder"))};let s=null;i.onmessage=({data:n})=>{const r=JSON.parse(n);if(r.phase&&r.phase!=s&&(s=r.phase.toLowerCase()),"failed"==r.phase)i.close(),t(new Error(r));else if("ready"==r.phase){i.close();const t={baseUrl:r.url,wsUrl:`ws${r.url.slice(4)}`,token:r.token};e(t)}}}))}(t,i,a).then((e=>p(e)))}().then(n).catch(r))).then((e=>{h=e,m(n,r)})).catch((()=>{h=null,void 0!==e&&(l=!1,e.localStorage.removeItem(s)),n.model.clear(),n.model.add({output_type:"stream",name:"failure",text:"Failed to connect to kernel"})}))}e.initManimBinder=function({repo:l,branch:h,storage_expire:c,storage_key:p,kernel_type:m,class_names:v,binder_url:O}={}){t=l||t,i=h||i,n=c||n,s=p||s,r=m||r,o=v||o,a=O||a,function(){const e=document.createElement("style");e.textContent=`\n .${o.wrapper} {\n padding: 10px;\n }\n\n .${o.title} {\n text-align: center;\n display: flex;\n justify-content: space-between;\n }\n\n .${o.meta} {\n font-size: 0.75rem;\n font-weight: 400;\n padding-top: 0.1rem;\n color: #666;\n }\n\n .${o.button} {\n cursor: pointer;\n }\n `,document.head.appendChild(e)}(),[...document.querySelectorAll("[data-manim-binder]")].forEach((t=>function(t){const i=t.getAttribute("data-manim-classname");if(!i)return void console.error("No manim classname provided.");const n=f("div",o.buttonWrapper);t.replaceWith(n);const s=f("button",o.button,"Make interactive");n.appendChild(s),s.addEventListener("click",(s=>{let r=t.textContent||"";r+="\n\n# don't remove below command for run button to work",r+=`\n%manim -qm -v WARNING ${i}`,function(t,i=""){const n=new ag({model:new wg({trusted:!0}),rendermime:new Ag({initialFactories:(d||(d=Zg.filter((t=>!t.mimeTypes.includes("text/latex")||void 0!==e&&e.MathJax))),d)})}),s=f("div",o.wrapper);t.replaceWith(s);const r=f("h4",o.title,"Try out manim!");s.appendChild(r);const l=f("span",o.meta,"Python 3 · via ");r.appendChild(l);const h=f("a","","Binder");h.setAttribute("href",a),l.appendChild(h);const c=f("div",o.cell);s.appendChild(c);const p=f("div",o.input);c.appendChild(p);const m=f("button",o.button,"Run");c.appendChild(m);const v=f("div",o.output);c.appendChild(v),Lf.sendMessage(n,fm.Msg.BeforeAttach),v.appendChild(n.node),Lf.sendMessage(n,fm.Msg.AfterAttach),n.model.changed.connect((()=>{v.querySelectorAll("video").forEach((e=>Kg(this,void 0,void 0,(function*(){console.log("fixing video");const t=e.getAttribute("src");if(!t)return void console.error("no src for the video.");e.style.maxWidth="100%";const i=yield u.get(t);if(!i.mimetype.startsWith("video/"))return void console.error("not a video");const n=atob(i.content),s=new ArrayBuffer(n.length),r=new Uint8Array(s);for(let e=0;e(g(n,O.state.doc.toString()),!0)},{key:"Ctrl-Enter",run:()=>(g(n,O.state.doc.toString()),!0)}]),zs.of([...Cc,...Dh])],parent:p});O.contentDOM.setAttribute("data-enable-grammarly","false"),O.dispatch({changes:{from:0,to:O.state.doc.length,insert:i.trim()}}),m.addEventListener("click",(e=>g(n,O.state.doc.toString())))}(n,r)}))}(t)))}}(window)})()})(); +//# sourceMappingURL=manim-binder.min.js.map diff --git a/docs/source/_static/manim-binder.min.js.LICENSE.txt b/docs/source/_static/manim-binder.min.js.LICENSE.txt new file mode 100644 index 0000000000..fe4c1fe307 --- /dev/null +++ b/docs/source/_static/manim-binder.min.js.LICENSE.txt @@ -0,0 +1,6 @@ +/*! + * is-plain-object + * + * Copyright (c) 2014-2017, Jon Schlinkert. + * Released under the MIT License. + */ diff --git a/docs/source/_static/manim-binder.min.js.map b/docs/source/_static/manim-binder.min.js.map new file mode 100644 index 0000000000..25b36df03d --- /dev/null +++ b/docs/source/_static/manim-binder.min.js.map @@ -0,0 +1 @@ +{"version":3,"file":"manim-binder.min.js","mappings":"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CT,IACA,OACA,UACA,UACA,OACA,UACA,QACA,QACA,IACA,MACA,MACA,MACA,aACA,KACA,SACA,SACA,UACA,SACA,OACA,OACA,MACA,WACA,UACA,UACA,OACA,WACA,KACA,MACA,UACA,MACA,MACA,MACA,KACA,KACA,KACA,WACA,aACA,SACA,OACA,SACA,OACA,KACA,KACA,KACA,KACA,KACA,KACA,SACA,SACA,KACA,IAGA,MACA,QACA,MACA,MACA,QACA,SACA,KACA,MACA,OACA,OACA,QACA,MACA,OACA,KACA,WACA,SACA,SACA,IACA,MACA,WACA,IACA,UACA,IACA,OACA,UACA,SACA,QACA,SACA,OACA,SACA,SACA,MACA,UACA,MACA,QACA,QACA,KACA,WACA,QACA,KACA,QACA,OACA,KACA,QACA,KACA,IACA,KACA,MACA,QACA,OAIJM,kBAAmB,CACf,IAAK,CACD,QACA,MACA,YACA,SACA,KACA,QACA,WACA,UACA,YACA,OACA,aACA,QACA,QACA,aAGJp7D,EAAG,CACC,YACA,SACA,OACA,WACA,OACA,MACA,QACA,WACA,SACA,QAEJ+8J,KAAM,CACF,YACA,MACA,SACA,OACA,SACA,QACA,YAGJ+P,MAAO,CACH,WACA,WACA,OACA,aACA,QACA,UACA,OAEJE,IAAK,CAAC,OACNr8H,WAAY,CAAC,QACbmgD,GAAI,CAAC,SACL7gD,OAAQ,CACJ,YACA,0BACA,6BACA,WACA,OACA,WACA,OACA,SAEJg9H,OAAQ,CAAC,SAAU,SACnB/E,QAAS,CAAC,SACVpgH,IAAK,CAAC,QAAS,OAAQ,UAAW,OAAQ,SAAU,SACpDqlH,SAAU,CAAC,QAAS,OAAQ,UAAW,OAAQ,SAAU,SACzDl9I,QAAS,CACL,UACA,UACA,WACA,OACA,QACA,aACA,QAEJttB,KAAM,CAAC,SACPygG,IAAK,CAAC,OAAQ,YACdxyD,QAAS,CAAC,QACVn0C,IAAK,CAAC,WACNo0C,IAAK,CAAC,SACNC,GAAI,CAAC,WACLC,SAAU,CAAC,YACX6rG,KAAM,CAAC,QAAS,OAAQ,QACxBzr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","sources":["webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+coreutils@6.0.7/node_modules/@jupyterlab/coreutils/lib/activitymonitor.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+coreutils@6.0.7/node_modules/@jupyterlab/coreutils/lib/index.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+coreutils@6.0.7/node_modules/@jupyterlab/coreutils/lib/interfaces.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+coreutils@6.0.7/node_modules/@jupyterlab/coreutils/lib/markdowncodeblocks.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+coreutils@6.0.7/node_modules/@jupyterlab/coreutils/lib/pageconfig.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+coreutils@6.0.7/node_modules/@jupyterlab/coreutils/lib/path.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+coreutils@6.0.7/node_modules/@jupyterlab/coreutils/lib/signal.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+coreutils@6.0.7/node_modules/@jupyterlab/coreutils/lib/text.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+coreutils@6.0.7/node_modules/@jupyterlab/coreutils/lib/time.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+coreutils@6.0.7/node_modules/@jupyterlab/coreutils/lib/url.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/basemanager.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/builder/index.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/config/index.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/contents/index.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/contents/validate.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/event/index.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/index.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/kernel/comm.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/kernel/default.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/kernel/future.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/kernel/index.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/kernel/kernel.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/kernel/manager.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/kernel/messages.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/kernel/restapi.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/kernel/serialize.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/kernel/validate.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/kernelspec/index.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/kernelspec/kernelspec.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/kernelspec/manager.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/kernelspec/restapi.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/kernelspec/validate.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/manager.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/nbconvert/index.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/serverconnection.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/session/default.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/session/index.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/session/manager.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/session/restapi.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/session/session.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/session/validate.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/setting/index.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/shim/ws.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/terminal/default.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/terminal/index.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/terminal/manager.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/terminal/restapi.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/terminal/terminal.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/user/index.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/validate.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+services@7.0.7_react@18.2.0/node_modules/@jupyterlab/services/lib/workspace/index.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+statedb@4.0.7/node_modules/@jupyterlab/statedb/lib/dataconnector.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+statedb@4.0.7/node_modules/@jupyterlab/statedb/lib/index.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+statedb@4.0.7/node_modules/@jupyterlab/statedb/lib/interfaces.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+statedb@4.0.7/node_modules/@jupyterlab/statedb/lib/restorablepool.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+statedb@4.0.7/node_modules/@jupyterlab/statedb/lib/statedb.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+statedb@4.0.7/node_modules/@jupyterlab/statedb/lib/tokens.js","webpack://manim-binder/./node_modules/.pnpm/@lumino+algorithm@2.0.1/node_modules/@lumino/algorithm/dist/index.es6.js","webpack://manim-binder/./node_modules/.pnpm/@lumino+coreutils@2.1.2/node_modules/@lumino/coreutils/dist/index.js","webpack://manim-binder/./node_modules/.pnpm/@lumino+disposable@2.1.2/node_modules/@lumino/disposable/dist/index.es6.js","webpack://manim-binder/./node_modules/.pnpm/@lumino+polling@2.1.2/node_modules/@lumino/polling/dist/index.es6.js","webpack://manim-binder/./node_modules/.pnpm/@lumino+properties@2.0.1/node_modules/@lumino/properties/dist/index.es6.js","webpack://manim-binder/./node_modules/.pnpm/@lumino+signaling@2.1.2/node_modules/@lumino/signaling/dist/index.es6.js","webpack://manim-binder/./node_modules/.pnpm/deepmerge@4.3.1/node_modules/deepmerge/dist/cjs.js","webpack://manim-binder/./node_modules/.pnpm/dom-serializer@1.4.1/node_modules/dom-serializer/lib/foreignNames.js","webpack://manim-binder/./node_modules/.pnpm/dom-serializer@1.4.1/node_modules/dom-serializer/lib/index.js","webpack://manim-binder/./node_modules/.pnpm/domelementtype@2.3.0/node_modules/domelementtype/lib/index.js","webpack://manim-binder/./node_modules/.pnpm/domhandler@4.3.1/node_modules/domhandler/lib/index.js","webpack://manim-binder/./node_modules/.pnpm/domhandler@4.3.1/node_modules/domhandler/lib/node.js","webpack://manim-binder/./node_modules/.pnpm/domutils@2.8.0/node_modules/domutils/lib/feeds.js","webpack://manim-binder/./node_modules/.pnpm/domutils@2.8.0/node_modules/domutils/lib/helpers.js","webpack://manim-binder/./node_modules/.pnpm/domutils@2.8.0/node_modules/domutils/lib/index.js","webpack://manim-binder/./node_modules/.pnpm/domutils@2.8.0/node_modules/domutils/lib/legacy.js","webpack://manim-binder/./node_modules/.pnpm/domutils@2.8.0/node_modules/domutils/lib/manipulation.js","webpack://manim-binder/./node_modules/.pnpm/domutils@2.8.0/node_modules/domutils/lib/querying.js","webpack://manim-binder/./node_modules/.pnpm/domutils@2.8.0/node_modules/domutils/lib/stringify.js","webpack://manim-binder/./node_modules/.pnpm/domutils@2.8.0/node_modules/domutils/lib/traversal.js","webpack://manim-binder/./node_modules/.pnpm/entities@2.2.0/node_modules/entities/lib/decode.js","webpack://manim-binder/./node_modules/.pnpm/entities@2.2.0/node_modules/entities/lib/decode_codepoint.js","webpack://manim-binder/./node_modules/.pnpm/entities@2.2.0/node_modules/entities/lib/encode.js","webpack://manim-binder/./node_modules/.pnpm/entities@2.2.0/node_modules/entities/lib/index.js","webpack://manim-binder/./node_modules/.pnpm/escape-string-regexp@4.0.0/node_modules/escape-string-regexp/index.js","webpack://manim-binder/./node_modules/.pnpm/htmlparser2@6.1.0/node_modules/htmlparser2/lib/FeedHandler.js","webpack://manim-binder/./node_modules/.pnpm/htmlparser2@6.1.0/node_modules/htmlparser2/lib/Parser.js","webpack://manim-binder/./node_modules/.pnpm/htmlparser2@6.1.0/node_modules/htmlparser2/lib/Tokenizer.js","webpack://manim-binder/./node_modules/.pnpm/htmlparser2@6.1.0/node_modules/htmlparser2/lib/index.js","webpack://manim-binder/./node_modules/.pnpm/is-plain-object@5.0.0/node_modules/is-plain-object/dist/is-plain-object.js","webpack://manim-binder/./node_modules/.pnpm/lodash.escape@4.0.1/node_modules/lodash.escape/index.js","webpack://manim-binder/./node_modules/.pnpm/minimist@1.2.8/node_modules/minimist/index.js","webpack://manim-binder/./node_modules/.pnpm/parse-srcset@1.0.2/node_modules/parse-srcset/src/parse-srcset.js","webpack://manim-binder/./node_modules/.pnpm/path-browserify@1.0.1/node_modules/path-browserify/index.js","webpack://manim-binder/./node_modules/.pnpm/picocolors@1.0.0/node_modules/picocolors/picocolors.browser.js","webpack://manim-binder/./node_modules/.pnpm/postcss@8.4.31/node_modules/postcss/lib/at-rule.js","webpack://manim-binder/./node_modules/.pnpm/postcss@8.4.31/node_modules/postcss/lib/comment.js","webpack://manim-binder/./node_modules/.pnpm/postcss@8.4.31/node_modules/postcss/lib/container.js","webpack://manim-binder/./node_modules/.pnpm/postcss@8.4.31/node_modules/postcss/lib/css-syntax-error.js","webpack://manim-binder/./node_modules/.pnpm/postcss@8.4.31/node_modules/postcss/lib/declaration.js","webpack://manim-binder/./node_modules/.pnpm/postcss@8.4.31/node_modules/postcss/lib/document.js","webpack://manim-binder/./node_modules/.pnpm/postcss@8.4.31/node_modules/postcss/lib/fromJSON.js","webpack://manim-binder/./node_modules/.pnpm/postcss@8.4.31/node_modules/postcss/lib/input.js","webpack://manim-binder/./node_modules/.pnpm/postcss@8.4.31/node_modules/postcss/lib/lazy-result.js","webpack://manim-binder/./node_modules/.pnpm/postcss@8.4.31/node_modules/postcss/lib/list.js","webpack://manim-binder/./node_modules/.pnpm/postcss@8.4.31/node_modules/postcss/lib/map-generator.js","webpack://manim-binder/./node_modules/.pnpm/postcss@8.4.31/node_modules/postcss/lib/no-work-result.js","webpack://manim-binder/./node_modules/.pnpm/postcss@8.4.31/node_modules/postcss/lib/node.js","webpack://manim-binder/./node_modules/.pnpm/postcss@8.4.31/node_modules/postcss/lib/parse.js","webpack://manim-binder/./node_modules/.pnpm/postcss@8.4.31/node_modules/postcss/lib/parser.js","webpack://manim-binder/./node_modules/.pnpm/postcss@8.4.31/node_modules/postcss/lib/postcss.js","webpack://manim-binder/./node_modules/.pnpm/postcss@8.4.31/node_modules/postcss/lib/previous-map.js","webpack://manim-binder/./node_modules/.pnpm/postcss@8.4.31/node_modules/postcss/lib/processor.js","webpack://manim-binder/./node_modules/.pnpm/postcss@8.4.31/node_modules/postcss/lib/result.js","webpack://manim-binder/./node_modules/.pnpm/postcss@8.4.31/node_modules/postcss/lib/root.js","webpack://manim-binder/./node_modules/.pnpm/postcss@8.4.31/node_modules/postcss/lib/rule.js","webpack://manim-binder/./node_modules/.pnpm/postcss@8.4.31/node_modules/postcss/lib/stringifier.js","webpack://manim-binder/./node_modules/.pnpm/postcss@8.4.31/node_modules/postcss/lib/stringify.js","webpack://manim-binder/./node_modules/.pnpm/postcss@8.4.31/node_modules/postcss/lib/symbols.js","webpack://manim-binder/./node_modules/.pnpm/postcss@8.4.31/node_modules/postcss/lib/tokenize.js","webpack://manim-binder/./node_modules/.pnpm/postcss@8.4.31/node_modules/postcss/lib/warn-once.js","webpack://manim-binder/./node_modules/.pnpm/postcss@8.4.31/node_modules/postcss/lib/warning.js","webpack://manim-binder/./node_modules/.pnpm/querystringify@2.2.0/node_modules/querystringify/index.js","webpack://manim-binder/./node_modules/.pnpm/requires-port@1.0.0/node_modules/requires-port/index.js","webpack://manim-binder/./node_modules/.pnpm/sanitize-html@2.7.3/node_modules/sanitize-html/index.js","webpack://manim-binder/./node_modules/.pnpm/url-parse@1.5.10/node_modules/url-parse/index.js","webpack://manim-binder/./node_modules/.pnpm/nanoid@3.3.6/node_modules/nanoid/non-secure/index.cjs","webpack://manim-binder/webpack/bootstrap","webpack://manim-binder/webpack/runtime/compat get default export","webpack://manim-binder/webpack/runtime/define property getters","webpack://manim-binder/webpack/runtime/global","webpack://manim-binder/webpack/runtime/hasOwnProperty shorthand","webpack://manim-binder/webpack/runtime/make namespace object","webpack://manim-binder/./node_modules/.pnpm/@codemirror+state@6.3.1/node_modules/@codemirror/state/dist/index.js","webpack://manim-binder/./node_modules/.pnpm/style-mod@4.1.0/node_modules/style-mod/src/style-mod.js","webpack://manim-binder/./node_modules/.pnpm/w3c-keyname@2.2.8/node_modules/w3c-keyname/index.js","webpack://manim-binder/./node_modules/.pnpm/@codemirror+view@6.21.4/node_modules/@codemirror/view/dist/index.js","webpack://manim-binder/./node_modules/.pnpm/@lezer+common@1.1.0/node_modules/@lezer/common/dist/index.js","webpack://manim-binder/./node_modules/.pnpm/@lezer+highlight@1.1.6/node_modules/@lezer/highlight/dist/index.js","webpack://manim-binder/./node_modules/.pnpm/@codemirror+language@6.9.2/node_modules/@codemirror/language/dist/index.js","webpack://manim-binder/./node_modules/.pnpm/@codemirror+commands@6.3.0/node_modules/@codemirror/commands/dist/index.js","webpack://manim-binder/./node_modules/.pnpm/crelt@1.0.6/node_modules/crelt/index.js","webpack://manim-binder/./node_modules/.pnpm/@codemirror+search@6.5.4/node_modules/@codemirror/search/dist/index.js","webpack://manim-binder/./node_modules/.pnpm/@codemirror+autocomplete@6.10.2_@codemirror+language@6.9.2_@codemirror+state@6.3.1_@codemirro_qlo7c5orcxst6mqbb4ug325pdq/node_modules/@codemirror/autocomplete/dist/index.js","webpack://manim-binder/./node_modules/.pnpm/@codemirror+lint@6.4.2/node_modules/@codemirror/lint/dist/index.js","webpack://manim-binder/./node_modules/.pnpm/codemirror@6.0.1_@lezer+common@1.1.0/node_modules/codemirror/dist/index.js","webpack://manim-binder/./node_modules/.pnpm/@lezer+lr@1.3.13/node_modules/@lezer/lr/dist/index.js","webpack://manim-binder/./node_modules/.pnpm/@lezer+python@1.1.9/node_modules/@lezer/python/dist/index.js","webpack://manim-binder/./node_modules/.pnpm/@codemirror+lang-python@6.1.3_@codemirror+state@6.3.1_@codemirror+view@6.21.4_@lezer+common@1.1.0/node_modules/@codemirror/lang-python/dist/index.js","webpack://manim-binder/./node_modules/.pnpm/@codemirror+theme-one-dark@6.1.2/node_modules/@codemirror/theme-one-dark/dist/index.js","webpack://manim-binder/./node_modules/.pnpm/@lumino+domutils@2.0.1/node_modules/@lumino/domutils/dist/index.es6.js","webpack://manim-binder/./node_modules/.pnpm/@lumino+collections@2.0.1/node_modules/@lumino/collections/dist/index.es6.js","webpack://manim-binder/./node_modules/.pnpm/@lumino+messaging@2.0.1/node_modules/@lumino/messaging/dist/index.es6.js","webpack://manim-binder/./node_modules/.pnpm/@lumino+dragdrop@2.1.3/node_modules/@lumino/dragdrop/dist/index.es6.js","webpack://manim-binder/./node_modules/.pnpm/@lumino+keyboard@2.0.1/node_modules/@lumino/keyboard/dist/index.es6.js","webpack://manim-binder/./node_modules/.pnpm/@lumino+commands@2.1.3/node_modules/@lumino/commands/dist/index.es6.js","webpack://manim-binder/./node_modules/.pnpm/@lumino+virtualdom@2.0.1/node_modules/@lumino/virtualdom/dist/index.es6.js","webpack://manim-binder/./node_modules/.pnpm/@lumino+widgets@2.3.0/node_modules/@lumino/widgets/dist/index.es6.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+apputils@4.1.7/node_modules/@jupyterlab/apputils/lib/widgettracker.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+translation@4.0.7_react@18.2.0/node_modules/@jupyterlab/translation/lib/utils.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+translation@4.0.7_react@18.2.0/node_modules/@jupyterlab/translation/lib/gettext.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+translation@4.0.7_react@18.2.0/node_modules/@jupyterlab/translation/lib/base.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+translation@4.0.7_react@18.2.0/node_modules/@jupyterlab/translation/lib/tokens.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+outputarea@4.0.7_react@18.2.0/node_modules/@jupyterlab/outputarea/lib/widget.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+observables@5.0.7/node_modules/@jupyterlab/observables/lib/observablelist.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+observables@5.0.7/node_modules/@jupyterlab/observables/lib/observablemap.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+rendermime@4.0.7_react@18.2.0/node_modules/@jupyterlab/rendermime/lib/outputmodel.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+outputarea@4.0.7_react@18.2.0/node_modules/@jupyterlab/outputarea/lib/model.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+nbformat@4.0.7/node_modules/@jupyterlab/nbformat/lib/index.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+observables@5.0.7/node_modules/@jupyterlab/observables/lib/observablejson.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+apputils@4.1.7/node_modules/@jupyterlab/apputils/lib/sanitizer.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+rendermime@4.0.7_react@18.2.0/node_modules/@jupyterlab/rendermime/lib/mimemodel.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+rendermime@4.0.7_react@18.2.0/node_modules/@jupyterlab/rendermime/lib/registry.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+rendermime@4.0.7_react@18.2.0/node_modules/@jupyterlab/rendermime/lib/latex.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+rendermime@4.0.7_react@18.2.0/node_modules/@jupyterlab/rendermime/lib/renderers.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+rendermime@4.0.7_react@18.2.0/node_modules/@jupyterlab/rendermime/lib/widgets.js","webpack://manim-binder/./node_modules/.pnpm/@jupyterlab+rendermime@4.0.7_react@18.2.0/node_modules/@jupyterlab/rendermime/lib/factories.js","webpack://manim-binder/./src/main.ts"],"sourcesContent":["\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.ActivityMonitor = void 0;\nconst signaling_1 = require(\"@lumino/signaling\");\n/**\n * A class that monitors activity on a signal.\n */\nclass ActivityMonitor {\n /**\n * Construct a new activity monitor.\n */\n constructor(options) {\n this._timer = -1;\n this._timeout = -1;\n this._isDisposed = false;\n this._activityStopped = new signaling_1.Signal(this);\n options.signal.connect(this._onSignalFired, this);\n this._timeout = options.timeout || 1000;\n }\n /**\n * A signal emitted when activity has ceased.\n */\n get activityStopped() {\n return this._activityStopped;\n }\n /**\n * The timeout associated with the monitor, in milliseconds.\n */\n get timeout() {\n return this._timeout;\n }\n set timeout(value) {\n this._timeout = value;\n }\n /**\n * Test whether the monitor has been disposed.\n *\n * #### Notes\n * This is a read-only property.\n */\n get isDisposed() {\n return this._isDisposed;\n }\n /**\n * Dispose of the resources used by the activity monitor.\n */\n dispose() {\n if (this._isDisposed) {\n return;\n }\n this._isDisposed = true;\n signaling_1.Signal.clearData(this);\n }\n /**\n * A signal handler for the monitored signal.\n */\n _onSignalFired(sender, args) {\n clearTimeout(this._timer);\n this._sender = sender;\n this._args = args;\n this._timer = setTimeout(() => {\n this._activityStopped.emit({\n sender: this._sender,\n args: this._args\n });\n }, this._timeout);\n }\n}\nexports.ActivityMonitor = ActivityMonitor;\n//# sourceMappingURL=activitymonitor.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/**\n * @packageDocumentation\n * @module coreutils\n */\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __exportStar = (this && this.__exportStar) || function(m, exports) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n__exportStar(require(\"./activitymonitor\"), exports);\n__exportStar(require(\"./interfaces\"), exports);\n__exportStar(require(\"./markdowncodeblocks\"), exports);\n__exportStar(require(\"./pageconfig\"), exports);\n__exportStar(require(\"./path\"), exports);\n__exportStar(require(\"./signal\"), exports);\n__exportStar(require(\"./text\"), exports);\n__exportStar(require(\"./time\"), exports);\n__exportStar(require(\"./url\"), exports);\n//# sourceMappingURL=index.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\n//# sourceMappingURL=interfaces.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.MarkdownCodeBlocks = void 0;\n/**\n * The namespace for code block functions which help\n * in extract code from markdown text\n */\nvar MarkdownCodeBlocks;\n(function (MarkdownCodeBlocks) {\n MarkdownCodeBlocks.CODE_BLOCK_MARKER = '```';\n const markdownExtensions = [\n '.markdown',\n '.mdown',\n '.mkdn',\n '.md',\n '.mkd',\n '.mdwn',\n '.mdtxt',\n '.mdtext',\n '.text',\n '.txt',\n '.Rmd'\n ];\n class MarkdownCodeBlock {\n constructor(startLine) {\n this.startLine = startLine;\n this.code = '';\n this.endLine = -1;\n }\n }\n MarkdownCodeBlocks.MarkdownCodeBlock = MarkdownCodeBlock;\n /**\n * Check whether the given file extension is a markdown extension\n * @param extension - A file extension\n *\n * @returns true/false depending on whether this is a supported markdown extension\n */\n function isMarkdown(extension) {\n return markdownExtensions.indexOf(extension) > -1;\n }\n MarkdownCodeBlocks.isMarkdown = isMarkdown;\n /**\n * Construct all code snippets from current text\n * (this could be potentially optimized if we can cache and detect differences)\n * @param text - A string to parse codeblocks from\n *\n * @returns An array of MarkdownCodeBlocks.\n */\n function findMarkdownCodeBlocks(text) {\n if (!text || text === '') {\n return [];\n }\n const lines = text.split('\\n');\n const codeBlocks = [];\n let currentBlock = null;\n for (let lineIndex = 0; lineIndex < lines.length; lineIndex++) {\n const line = lines[lineIndex];\n const lineContainsMarker = line.indexOf(MarkdownCodeBlocks.CODE_BLOCK_MARKER) === 0;\n const constructingBlock = currentBlock != null;\n // Skip this line if it is not part of any code block and doesn't contain a marker.\n if (!lineContainsMarker && !constructingBlock) {\n continue;\n }\n // Check if we are already constructing a code block.\n if (!constructingBlock) {\n // Start constructing a new code block.\n currentBlock = new MarkdownCodeBlock(lineIndex);\n // Check whether this is a single line code block of the form ```a = 10```.\n const firstIndex = line.indexOf(MarkdownCodeBlocks.CODE_BLOCK_MARKER);\n const lastIndex = line.lastIndexOf(MarkdownCodeBlocks.CODE_BLOCK_MARKER);\n const isSingleLine = firstIndex !== lastIndex;\n if (isSingleLine) {\n currentBlock.code = line.substring(firstIndex + MarkdownCodeBlocks.CODE_BLOCK_MARKER.length, lastIndex);\n currentBlock.endLine = lineIndex;\n codeBlocks.push(currentBlock);\n currentBlock = null;\n }\n }\n else if (currentBlock) {\n if (lineContainsMarker) {\n // End of block, finish it up.\n currentBlock.endLine = lineIndex - 1;\n codeBlocks.push(currentBlock);\n currentBlock = null;\n }\n else {\n // Append the current line.\n currentBlock.code += line + '\\n';\n }\n }\n }\n return codeBlocks;\n }\n MarkdownCodeBlocks.findMarkdownCodeBlocks = findMarkdownCodeBlocks;\n})(MarkdownCodeBlocks = exports.MarkdownCodeBlocks || (exports.MarkdownCodeBlocks = {}));\n//# sourceMappingURL=markdowncodeblocks.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.PageConfig = void 0;\nconst coreutils_1 = require(\"@lumino/coreutils\");\nconst minimist_1 = __importDefault(require(\"minimist\"));\nconst url_1 = require(\"./url\");\n/**\n * The namespace for `PageConfig` functions.\n */\nvar PageConfig;\n(function (PageConfig) {\n /**\n * Get global configuration data for the Jupyter application.\n *\n * @param name - The name of the configuration option.\n *\n * @returns The config value or an empty string if not found.\n *\n * #### Notes\n * All values are treated as strings.\n * For browser based applications, it is assumed that the page HTML\n * includes a script tag with the id `jupyter-config-data` containing the\n * configuration as valid JSON. In order to support the classic Notebook,\n * we fall back on checking for `body` data of the given `name`.\n *\n * For node applications, it is assumed that the process was launched\n * with a `--jupyter-config-data` option pointing to a JSON settings\n * file.\n */\n function getOption(name) {\n if (configData) {\n return configData[name] || getBodyData(name);\n }\n configData = Object.create(null);\n let found = false;\n // Use script tag if available.\n if (typeof document !== 'undefined' && document) {\n const el = document.getElementById('jupyter-config-data');\n if (el) {\n configData = JSON.parse(el.textContent || '');\n found = true;\n }\n }\n // Otherwise use CLI if given.\n if (!found && typeof process !== 'undefined' && process.argv) {\n try {\n const cli = (0, minimist_1.default)(process.argv.slice(2));\n const path = require('path');\n let fullPath = '';\n if ('jupyter-config-data' in cli) {\n fullPath = path.resolve(cli['jupyter-config-data']);\n }\n else if ('JUPYTER_CONFIG_DATA' in process.env) {\n fullPath = path.resolve(process.env['JUPYTER_CONFIG_DATA']);\n }\n if (fullPath) {\n // Force Webpack to ignore this require.\n // eslint-disable-next-line\n configData = eval('require')(fullPath);\n }\n }\n catch (e) {\n console.error(e);\n }\n }\n if (!coreutils_1.JSONExt.isObject(configData)) {\n configData = Object.create(null);\n }\n else {\n for (const key in configData) {\n // PageConfig expects strings\n if (typeof configData[key] !== 'string') {\n configData[key] = JSON.stringify(configData[key]);\n }\n }\n }\n return configData[name] || getBodyData(name);\n }\n PageConfig.getOption = getOption;\n /**\n * Set global configuration data for the Jupyter application.\n *\n * @param name - The name of the configuration option.\n * @param value - The value to set the option to.\n *\n * @returns The last config value or an empty string if it doesn't exist.\n */\n function setOption(name, value) {\n const last = getOption(name);\n configData[name] = value;\n return last;\n }\n PageConfig.setOption = setOption;\n /**\n * Get the base url for a Jupyter application, or the base url of the page.\n */\n function getBaseUrl() {\n return url_1.URLExt.normalize(getOption('baseUrl') || '/');\n }\n PageConfig.getBaseUrl = getBaseUrl;\n /**\n * Get the tree url for a JupyterLab application.\n */\n function getTreeUrl() {\n return url_1.URLExt.join(getBaseUrl(), getOption('treeUrl'));\n }\n PageConfig.getTreeUrl = getTreeUrl;\n /**\n * Get the base url for sharing links (usually baseUrl)\n */\n function getShareUrl() {\n return url_1.URLExt.normalize(getOption('shareUrl') || getBaseUrl());\n }\n PageConfig.getShareUrl = getShareUrl;\n /**\n * Get the tree url for shareable links.\n * Usually the same as treeUrl,\n * but overrideable e.g. when sharing with JupyterHub.\n */\n function getTreeShareUrl() {\n return url_1.URLExt.normalize(url_1.URLExt.join(getShareUrl(), getOption('treeUrl')));\n }\n PageConfig.getTreeShareUrl = getTreeShareUrl;\n /**\n * Create a new URL given an optional mode and tree path.\n *\n * This is used to create URLS when the mode or tree path change as the user\n * changes mode or the current document in the main area. If fields in\n * options are omitted, the value in PageConfig will be used.\n *\n * @param options - IGetUrlOptions for the new path.\n */\n function getUrl(options) {\n var _a, _b, _c, _d;\n let path = options.toShare ? getShareUrl() : getBaseUrl();\n const mode = (_a = options.mode) !== null && _a !== void 0 ? _a : getOption('mode');\n const workspace = (_b = options.workspace) !== null && _b !== void 0 ? _b : getOption('workspace');\n const labOrDoc = mode === 'single-document' ? 'doc' : 'lab';\n path = url_1.URLExt.join(path, labOrDoc);\n if (workspace !== PageConfig.defaultWorkspace) {\n path = url_1.URLExt.join(path, 'workspaces', encodeURIComponent((_c = getOption('workspace')) !== null && _c !== void 0 ? _c : PageConfig.defaultWorkspace));\n }\n const treePath = (_d = options.treePath) !== null && _d !== void 0 ? _d : getOption('treePath');\n if (treePath) {\n path = url_1.URLExt.join(path, 'tree', url_1.URLExt.encodeParts(treePath));\n }\n return path;\n }\n PageConfig.getUrl = getUrl;\n PageConfig.defaultWorkspace = 'default';\n /**\n * Get the base websocket url for a Jupyter application, or an empty string.\n */\n function getWsUrl(baseUrl) {\n let wsUrl = getOption('wsUrl');\n if (!wsUrl) {\n baseUrl = baseUrl ? url_1.URLExt.normalize(baseUrl) : getBaseUrl();\n if (baseUrl.indexOf('http') !== 0) {\n return '';\n }\n wsUrl = 'ws' + baseUrl.slice(4);\n }\n return url_1.URLExt.normalize(wsUrl);\n }\n PageConfig.getWsUrl = getWsUrl;\n /**\n * Returns the URL converting this notebook to a certain\n * format with nbconvert.\n */\n function getNBConvertURL({ path, format, download }) {\n const notebookPath = url_1.URLExt.encodeParts(path);\n const url = url_1.URLExt.join(getBaseUrl(), 'nbconvert', format, notebookPath);\n if (download) {\n return url + '?download=true';\n }\n return url;\n }\n PageConfig.getNBConvertURL = getNBConvertURL;\n /**\n * Get the authorization token for a Jupyter application.\n */\n function getToken() {\n return getOption('token') || getBodyData('jupyterApiToken');\n }\n PageConfig.getToken = getToken;\n /**\n * Get the Notebook version info [major, minor, patch].\n */\n function getNotebookVersion() {\n const notebookVersion = getOption('notebookVersion');\n if (notebookVersion === '') {\n return [0, 0, 0];\n }\n return JSON.parse(notebookVersion);\n }\n PageConfig.getNotebookVersion = getNotebookVersion;\n /**\n * Private page config data for the Jupyter application.\n */\n let configData = null;\n /**\n * Get a url-encoded item from `body.data` and decode it\n * We should never have any encoded URLs anywhere else in code\n * until we are building an actual request.\n */\n function getBodyData(key) {\n if (typeof document === 'undefined' || !document.body) {\n return '';\n }\n const val = document.body.dataset[key];\n if (typeof val === 'undefined') {\n return '';\n }\n return decodeURIComponent(val);\n }\n /**\n * The namespace for page config `Extension` functions.\n */\n let Extension;\n (function (Extension) {\n /**\n * Populate an array from page config.\n *\n * @param key - The page config key (e.g., `deferredExtensions`).\n *\n * #### Notes\n * This is intended for `deferredExtensions` and `disabledExtensions`.\n */\n function populate(key) {\n try {\n const raw = getOption(key);\n if (raw) {\n return JSON.parse(raw);\n }\n }\n catch (error) {\n console.warn(`Unable to parse ${key}.`, error);\n }\n return [];\n }\n /**\n * The collection of deferred extensions in page config.\n */\n Extension.deferred = populate('deferredExtensions');\n /**\n * The collection of disabled extensions in page config.\n */\n Extension.disabled = populate('disabledExtensions');\n /**\n * Returns whether a plugin is deferred.\n *\n * @param id - The plugin ID.\n */\n function isDeferred(id) {\n // Check for either a full plugin id match or an extension\n // name match.\n const separatorIndex = id.indexOf(':');\n let extName = '';\n if (separatorIndex !== -1) {\n extName = id.slice(0, separatorIndex);\n }\n return Extension.deferred.some(val => val === id || (extName && val === extName));\n }\n Extension.isDeferred = isDeferred;\n /**\n * Returns whether a plugin is disabled.\n *\n * @param id - The plugin ID.\n */\n function isDisabled(id) {\n // Check for either a full plugin id match or an extension\n // name match.\n const separatorIndex = id.indexOf(':');\n let extName = '';\n if (separatorIndex !== -1) {\n extName = id.slice(0, separatorIndex);\n }\n return Extension.disabled.some(val => val === id || (extName && val === extName));\n }\n Extension.isDisabled = isDisabled;\n })(Extension = PageConfig.Extension || (PageConfig.Extension = {}));\n})(PageConfig = exports.PageConfig || (exports.PageConfig = {}));\n//# sourceMappingURL=pageconfig.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.PathExt = void 0;\nconst path_1 = require(\"path\");\n/**\n * The namespace for path-related functions.\n *\n * Note that Jupyter server paths do not start with a leading slash.\n */\nvar PathExt;\n(function (PathExt) {\n /**\n * Join all arguments together and normalize the resulting path.\n * Arguments must be strings. In v0.8, non-string arguments were silently ignored. In v0.10 and up, an exception is thrown.\n *\n * @param paths - The string paths to join.\n */\n function join(...paths) {\n const path = path_1.posix.join(...paths);\n return path === '.' ? '' : removeSlash(path);\n }\n PathExt.join = join;\n /**\n * Return the last portion of a path. Similar to the Unix basename command.\n * Often used to extract the file name from a fully qualified path.\n *\n * @param path - The path to evaluate.\n *\n * @param ext - An extension to remove from the result.\n */\n function basename(path, ext) {\n return path_1.posix.basename(path, ext);\n }\n PathExt.basename = basename;\n /**\n * Get the directory name of a path, similar to the Unix dirname command.\n * When an empty path is given, returns the root path.\n *\n * @param path - The file path.\n */\n function dirname(path) {\n const dir = removeSlash(path_1.posix.dirname(path));\n return dir === '.' ? '' : dir;\n }\n PathExt.dirname = dirname;\n /**\n * Get the extension of the path.\n *\n * @param path - The file path.\n *\n * @returns the extension of the file.\n *\n * #### Notes\n * The extension is the string from the last occurrence of the `.`\n * character to end of string in the last portion of the path, inclusive.\n * If there is no `.` in the last portion of the path, or if the first\n * character of the basename of path [[basename]] is `.`, then an\n * empty string is returned.\n */\n function extname(path) {\n return path_1.posix.extname(path);\n }\n PathExt.extname = extname;\n /**\n * Normalize a string path, reducing '..' and '.' parts.\n * When multiple slashes are found, they're replaced by a single one; when the path contains a trailing slash, it is preserved. On Windows backslashes are used.\n * When an empty path is given, returns the root path.\n *\n * @param path - The string path to normalize.\n */\n function normalize(path) {\n if (path === '') {\n return '';\n }\n return removeSlash(path_1.posix.normalize(path));\n }\n PathExt.normalize = normalize;\n /**\n * Resolve a sequence of paths or path segments into an absolute path.\n * The root path in the application has no leading slash, so it is removed.\n *\n * @param parts - The paths to join.\n *\n * #### Notes\n * The right-most parameter is considered \\{to\\}. Other parameters are considered an array of \\{from\\}.\n *\n * Starting from leftmost \\{from\\} parameter, resolves \\{to\\} to an absolute path.\n *\n * If \\{to\\} isn't already absolute, \\{from\\} arguments are prepended in right to left order, until an absolute path is found. If after using all \\{from\\} paths still no absolute path is found, the current working directory is used as well. The resulting path is normalized, and trailing slashes are removed unless the path gets resolved to the root directory.\n */\n function resolve(...parts) {\n return removeSlash(path_1.posix.resolve(...parts));\n }\n PathExt.resolve = resolve;\n /**\n * Solve the relative path from \\{from\\} to \\{to\\}.\n *\n * @param from - The source path.\n *\n * @param to - The target path.\n *\n * #### Notes\n * If from and to each resolve to the same path (after calling\n * path.resolve() on each), a zero-length string is returned.\n * If a zero-length string is passed as from or to, `/`\n * will be used instead of the zero-length strings.\n */\n function relative(from, to) {\n return removeSlash(path_1.posix.relative(from, to));\n }\n PathExt.relative = relative;\n /**\n * Normalize a file extension to be of the type `'.foo'`.\n *\n * @param extension - the file extension.\n *\n * #### Notes\n * Adds a leading dot if not present and converts to lower case.\n */\n function normalizeExtension(extension) {\n if (extension.length > 0 && extension.indexOf('.') !== 0) {\n extension = `.${extension}`;\n }\n return extension;\n }\n PathExt.normalizeExtension = normalizeExtension;\n /**\n * Remove the leading slash from a path.\n *\n * @param path: the path from which to remove a leading slash.\n */\n function removeSlash(path) {\n if (path.indexOf('/') === 0) {\n path = path.slice(1);\n }\n return path;\n }\n PathExt.removeSlash = removeSlash;\n})(PathExt = exports.PathExt || (exports.PathExt = {}));\n//# sourceMappingURL=path.js.map","\"use strict\";\n/*\n * Copyright (c) Jupyter Development Team.\n * Distributed under the terms of the Modified BSD License.\n */\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.signalToPromise = void 0;\nconst coreutils_1 = require(\"@lumino/coreutils\");\n/**\n * Convert a signal into a promise for the first emitted value.\n *\n * @param signal - The signal we are listening to.\n * @param timeout - Timeout to wait for signal in ms (not timeout if not defined or 0)\n *\n * @returns a Promise that resolves with a `(sender, args)` pair.\n */\nfunction signalToPromise(signal, timeout) {\n const waitForSignal = new coreutils_1.PromiseDelegate();\n function cleanup() {\n signal.disconnect(slot);\n }\n function slot(sender, args) {\n cleanup();\n waitForSignal.resolve([sender, args]);\n }\n signal.connect(slot);\n if ((timeout !== null && timeout !== void 0 ? timeout : 0) > 0) {\n setTimeout(() => {\n cleanup();\n waitForSignal.reject(`Signal not emitted within ${timeout} ms.`);\n }, timeout);\n }\n return waitForSignal.promise;\n}\nexports.signalToPromise = signalToPromise;\n//# sourceMappingURL=signal.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.Text = void 0;\n/**\n * The namespace for text-related functions.\n */\nvar Text;\n(function (Text) {\n // javascript stores text as utf16 and string indices use \"code units\",\n // which stores high-codepoint characters as \"surrogate pairs\",\n // which occupy two indices in the javascript string.\n // We need to translate cursor_pos in the Jupyter protocol (in characters)\n // to js offset (with surrogate pairs taking two spots).\n const HAS_SURROGATES = '𝐚'.length > 1;\n /**\n * Convert a javascript string index into a unicode character offset\n *\n * @param jsIdx - The javascript string index (counting surrogate pairs)\n *\n * @param text - The text in which the offset is calculated\n *\n * @returns The unicode character offset\n */\n function jsIndexToCharIndex(jsIdx, text) {\n if (HAS_SURROGATES) {\n // not using surrogates, nothing to do\n return jsIdx;\n }\n let charIdx = jsIdx;\n for (let i = 0; i + 1 < text.length && i < jsIdx; i++) {\n const charCode = text.charCodeAt(i);\n // check for surrogate pair\n if (charCode >= 0xd800 && charCode <= 0xdbff) {\n const nextCharCode = text.charCodeAt(i + 1);\n if (nextCharCode >= 0xdc00 && nextCharCode <= 0xdfff) {\n charIdx--;\n i++;\n }\n }\n }\n return charIdx;\n }\n Text.jsIndexToCharIndex = jsIndexToCharIndex;\n /**\n * Convert a unicode character offset to a javascript string index.\n *\n * @param charIdx - The index in unicode characters\n *\n * @param text - The text in which the offset is calculated\n *\n * @returns The js-native index\n */\n function charIndexToJsIndex(charIdx, text) {\n if (HAS_SURROGATES) {\n // not using surrogates, nothing to do\n return charIdx;\n }\n let jsIdx = charIdx;\n for (let i = 0; i + 1 < text.length && i < jsIdx; i++) {\n const charCode = text.charCodeAt(i);\n // check for surrogate pair\n if (charCode >= 0xd800 && charCode <= 0xdbff) {\n const nextCharCode = text.charCodeAt(i + 1);\n if (nextCharCode >= 0xdc00 && nextCharCode <= 0xdfff) {\n jsIdx++;\n i++;\n }\n }\n }\n return jsIdx;\n }\n Text.charIndexToJsIndex = charIndexToJsIndex;\n /**\n * Given a 'snake-case', 'snake_case', 'snake:case', or\n * 'snake case' string, will return the camel case version: 'snakeCase'.\n *\n * @param str: the snake-case input string.\n *\n * @param upper: default = false. If true, the first letter of the\n * returned string will be capitalized.\n *\n * @returns the camel case version of the input string.\n */\n function camelCase(str, upper = false) {\n return str.replace(/^(\\w)|[\\s-_:]+(\\w)/g, function (match, p1, p2) {\n if (p2) {\n return p2.toUpperCase();\n }\n else {\n return upper ? p1.toUpperCase() : p1.toLowerCase();\n }\n });\n }\n Text.camelCase = camelCase;\n /**\n * Given a string, title case the words in the string.\n *\n * @param str: the string to title case.\n *\n * @returns the same string, but with each word capitalized.\n */\n function titleCase(str) {\n return (str || '')\n .toLowerCase()\n .split(' ')\n .map(word => word.charAt(0).toUpperCase() + word.slice(1))\n .join(' ');\n }\n Text.titleCase = titleCase;\n})(Text = exports.Text || (exports.Text = {}));\n//# sourceMappingURL=text.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.Time = void 0;\n/**\n * A list of time units with their associated value in milliseconds.\n */\nconst UNITS = [\n { name: 'years', milliseconds: 365 * 24 * 60 * 60 * 1000 },\n { name: 'months', milliseconds: 30 * 24 * 60 * 60 * 1000 },\n { name: 'days', milliseconds: 24 * 60 * 60 * 1000 },\n { name: 'hours', milliseconds: 60 * 60 * 1000 },\n { name: 'minutes', milliseconds: 60 * 1000 },\n { name: 'seconds', milliseconds: 1000 }\n];\n/**\n * The namespace for date functions.\n */\nvar Time;\n(function (Time) {\n /**\n * Convert a timestring to a human readable string (e.g. 'two minutes ago').\n *\n * @param value - The date timestring or date object.\n *\n * @returns A formatted date.\n */\n function formatHuman(value) {\n const lang = document.documentElement.lang || 'en';\n const formatter = new Intl.RelativeTimeFormat(lang, { numeric: 'auto' });\n const delta = new Date(value).getTime() - Date.now();\n for (let unit of UNITS) {\n const amount = Math.ceil(delta / unit.milliseconds);\n if (amount === 0) {\n continue;\n }\n return formatter.format(amount, unit.name);\n }\n return formatter.format(0, 'seconds');\n }\n Time.formatHuman = formatHuman;\n /**\n * Convenient helper to convert a timestring to a date format.\n *\n * @param value - The date timestring or date object.\n *\n * @returns A formatted date.\n */\n function format(value) {\n const lang = document.documentElement.lang || 'en';\n const formatter = new Intl.DateTimeFormat(lang, {\n dateStyle: 'short',\n timeStyle: 'short'\n });\n return formatter.format(new Date(value));\n }\n Time.format = format;\n})(Time = exports.Time || (exports.Time = {}));\n//# sourceMappingURL=time.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { \"default\": mod };\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.URLExt = void 0;\nconst path_1 = require(\"path\");\nconst url_parse_1 = __importDefault(require(\"url-parse\"));\n/**\n * The namespace for URL-related functions.\n */\nvar URLExt;\n(function (URLExt) {\n /**\n * Parse a url into a URL object.\n *\n * @param urlString - The URL string to parse.\n *\n * @returns A URL object.\n */\n function parse(url) {\n if (typeof document !== 'undefined' && document) {\n const a = document.createElement('a');\n a.href = url;\n return a;\n }\n return (0, url_parse_1.default)(url);\n }\n URLExt.parse = parse;\n /**\n * Parse URL and retrieve hostname\n *\n * @param url - The URL string to parse\n *\n * @returns a hostname string value\n */\n function getHostName(url) {\n return (0, url_parse_1.default)(url).hostname;\n }\n URLExt.getHostName = getHostName;\n function normalize(url) {\n return url && parse(url).toString();\n }\n URLExt.normalize = normalize;\n /**\n * Join a sequence of url components and normalizes as in node `path.join`.\n *\n * @param parts - The url components.\n *\n * @returns the joined url.\n */\n function join(...parts) {\n let u = (0, url_parse_1.default)(parts[0], {});\n // Schema-less URL can be only parsed as relative to a base URL\n // see https://github.com/unshiftio/url-parse/issues/219#issuecomment-1002219326\n const isSchemaLess = u.protocol === '' && u.slashes;\n if (isSchemaLess) {\n u = (0, url_parse_1.default)(parts[0], 'https:' + parts[0]);\n }\n const prefix = `${isSchemaLess ? '' : u.protocol}${u.slashes ? '//' : ''}${u.auth}${u.auth ? '@' : ''}${u.host}`;\n // If there was a prefix, then the first path must start at the root.\n const path = path_1.posix.join(`${!!prefix && u.pathname[0] !== '/' ? '/' : ''}${u.pathname}`, ...parts.slice(1));\n return `${prefix}${path === '.' ? '' : path}`;\n }\n URLExt.join = join;\n /**\n * Encode the components of a multi-segment url.\n *\n * @param url - The url to encode.\n *\n * @returns the encoded url.\n *\n * #### Notes\n * Preserves the `'/'` separators.\n * Should not include the base url, since all parts are escaped.\n */\n function encodeParts(url) {\n return join(...url.split('/').map(encodeURIComponent));\n }\n URLExt.encodeParts = encodeParts;\n /**\n * Return a serialized object string suitable for a query.\n *\n * @param object - The source object.\n *\n * @returns an encoded url query.\n *\n * #### Notes\n * Modified version of [stackoverflow](http://stackoverflow.com/a/30707423).\n */\n function objectToQueryString(value) {\n const keys = Object.keys(value).filter(key => key.length > 0);\n if (!keys.length) {\n return '';\n }\n return ('?' +\n keys\n .map(key => {\n const content = encodeURIComponent(String(value[key]));\n return key + (content ? '=' + content : '');\n })\n .join('&'));\n }\n URLExt.objectToQueryString = objectToQueryString;\n /**\n * Return a parsed object that represents the values in a query string.\n */\n function queryStringToObject(value) {\n return value\n .replace(/^\\?/, '')\n .split('&')\n .reduce((acc, val) => {\n const [key, value] = val.split('=');\n if (key.length > 0) {\n acc[key] = decodeURIComponent(value || '');\n }\n return acc;\n }, {});\n }\n URLExt.queryStringToObject = queryStringToObject;\n /**\n * Test whether the url is a local url.\n *\n * #### Notes\n * This function returns `false` for any fully qualified url, including\n * `data:`, `file:`, and `//` protocol URLs.\n */\n function isLocal(url) {\n const { protocol } = parse(url);\n return ((!protocol || url.toLowerCase().indexOf(protocol) !== 0) &&\n url.indexOf('/') !== 0);\n }\n URLExt.isLocal = isLocal;\n})(URLExt = exports.URLExt || (exports.URLExt = {}));\n//# sourceMappingURL=url.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.BaseManager = void 0;\nconst signaling_1 = require(\"@lumino/signaling\");\nconst serverconnection_1 = require(\"./serverconnection\");\nclass BaseManager {\n constructor(options) {\n var _a;\n this._isDisposed = false;\n this._disposed = new signaling_1.Signal(this);\n this.serverSettings =\n (_a = options.serverSettings) !== null && _a !== void 0 ? _a : serverconnection_1.ServerConnection.makeSettings();\n }\n /**\n * A signal emitted when the delegate is disposed.\n */\n get disposed() {\n return this._disposed;\n }\n /**\n * Test whether the delegate has been disposed.\n */\n get isDisposed() {\n return this._isDisposed;\n }\n /**\n * Whether the manager is active.\n */\n get isActive() {\n return true;\n }\n /**\n * Dispose of the delegate and invoke the callback function.\n */\n dispose() {\n if (this.isDisposed) {\n return;\n }\n this._disposed.emit(undefined);\n signaling_1.Signal.clearData(this);\n }\n}\nexports.BaseManager = BaseManager;\n//# sourceMappingURL=basemanager.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.BuildManager = void 0;\nconst coreutils_1 = require(\"@jupyterlab/coreutils\");\nconst serverconnection_1 = require(\"../serverconnection\");\n/**\n * The url for the lab build service.\n */\nconst BUILD_SETTINGS_URL = 'api/build';\n/**\n * The build API service manager.\n */\nclass BuildManager {\n /**\n * Create a new setting manager.\n */\n constructor(options = {}) {\n var _a;\n this._url = '';\n this.serverSettings =\n (_a = options.serverSettings) !== null && _a !== void 0 ? _a : serverconnection_1.ServerConnection.makeSettings();\n const { baseUrl, appUrl } = this.serverSettings;\n this._url = coreutils_1.URLExt.join(baseUrl, appUrl, BUILD_SETTINGS_URL);\n }\n /**\n * Test whether the build service is available.\n */\n get isAvailable() {\n return coreutils_1.PageConfig.getOption('buildAvailable').toLowerCase() === 'true';\n }\n /**\n * Test whether to check build status automatically.\n */\n get shouldCheck() {\n return coreutils_1.PageConfig.getOption('buildCheck').toLowerCase() === 'true';\n }\n /**\n * Get whether the application should be built.\n */\n getStatus() {\n const { _url, serverSettings } = this;\n const promise = serverconnection_1.ServerConnection.makeRequest(_url, {}, serverSettings);\n return promise\n .then(response => {\n if (response.status !== 200) {\n throw new serverconnection_1.ServerConnection.ResponseError(response);\n }\n return response.json();\n })\n .then(data => {\n if (typeof data.status !== 'string') {\n throw new Error('Invalid data');\n }\n if (typeof data.message !== 'string') {\n throw new Error('Invalid data');\n }\n return data;\n });\n }\n /**\n * Build the application.\n */\n build() {\n const { _url, serverSettings } = this;\n const init = { method: 'POST' };\n const promise = serverconnection_1.ServerConnection.makeRequest(_url, init, serverSettings);\n return promise.then(response => {\n if (response.status === 400) {\n throw new serverconnection_1.ServerConnection.ResponseError(response, 'Build aborted');\n }\n if (response.status !== 200) {\n const message = `Build failed with ${response.status}.\n\n If you are experiencing the build failure after installing an extension (or trying to include previously installed extension after updating JupyterLab) please check the extension repository for new installation instructions as many extensions migrated to the prebuilt extensions system which no longer requires rebuilding JupyterLab (but uses a different installation procedure, typically involving a package manager such as 'pip' or 'conda').\n\n If you specifically intended to install a source extension, please run 'jupyter lab build' on the server for full output.`;\n throw new serverconnection_1.ServerConnection.ResponseError(response, message);\n }\n });\n }\n /**\n * Cancel an active build.\n */\n cancel() {\n const { _url, serverSettings } = this;\n const init = { method: 'DELETE' };\n const promise = serverconnection_1.ServerConnection.makeRequest(_url, init, serverSettings);\n return promise.then(response => {\n if (response.status !== 204) {\n throw new serverconnection_1.ServerConnection.ResponseError(response);\n }\n });\n }\n}\nexports.BuildManager = BuildManager;\n//# sourceMappingURL=index.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.ConfigWithDefaults = exports.ConfigSection = void 0;\nconst coreutils_1 = require(\"@jupyterlab/coreutils\");\nconst __1 = require(\"..\");\n/**\n * The url for the config service.\n */\nconst SERVICE_CONFIG_URL = 'api/config';\n/**\n * The namespace for ConfigSection statics.\n */\nvar ConfigSection;\n(function (ConfigSection) {\n /**\n * Create a config section.\n *\n * @returns A Promise that is fulfilled with the config section is loaded.\n */\n function create(options) {\n const section = new DefaultConfigSection(options);\n return section.load().then(() => {\n return section;\n });\n }\n ConfigSection.create = create;\n})(ConfigSection = exports.ConfigSection || (exports.ConfigSection = {}));\n/**\n * Implementation of the Configurable data section.\n */\nclass DefaultConfigSection {\n /**\n * Construct a new config section.\n */\n constructor(options) {\n var _a;\n this._url = 'unknown';\n const settings = (this.serverSettings =\n (_a = options.serverSettings) !== null && _a !== void 0 ? _a : __1.ServerConnection.makeSettings());\n this._url = coreutils_1.URLExt.join(settings.baseUrl, SERVICE_CONFIG_URL, encodeURIComponent(options.name));\n }\n /**\n * Get the data for this section.\n */\n get data() {\n return this._data;\n }\n /**\n * Load the initial data for this section.\n *\n * #### Notes\n * Uses the [Jupyter Notebook API](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter-server/jupyter_server/main/jupyter_server/services/api/api.yaml#!/config).\n *\n * The promise is fulfilled on a valid response and rejected otherwise.\n */\n async load() {\n const response = await __1.ServerConnection.makeRequest(this._url, {}, this.serverSettings);\n if (response.status !== 200) {\n const err = await __1.ServerConnection.ResponseError.create(response);\n throw err;\n }\n this._data = await response.json();\n }\n /**\n * Modify the stored config values.\n *\n * #### Notes\n * Uses the [Jupyter Notebook API](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter-server/jupyter_server/main/jupyter_server/services/api/api.yaml#!/config).\n *\n * The promise is fulfilled on a valid response and rejected otherwise.\n *\n * Updates the local data immediately, sends the change to the server,\n * and updates the local data with the response, and fulfils the promise\n * with that data.\n */\n async update(newdata) {\n this._data = { ...this._data, ...newdata };\n const init = {\n method: 'PATCH',\n body: JSON.stringify(newdata)\n };\n const response = await __1.ServerConnection.makeRequest(this._url, init, this.serverSettings);\n if (response.status !== 200) {\n const err = await __1.ServerConnection.ResponseError.create(response);\n throw err;\n }\n this._data = await response.json();\n return this._data;\n }\n}\n/**\n * Configurable object with defaults.\n */\nclass ConfigWithDefaults {\n /**\n * Create a new config with defaults.\n */\n constructor(options) {\n var _a, _b;\n this._className = '';\n this._section = options.section;\n this._defaults = (_a = options.defaults) !== null && _a !== void 0 ? _a : {};\n this._className = (_b = options.className) !== null && _b !== void 0 ? _b : '';\n }\n /**\n * Get data from the config section or fall back to defaults.\n */\n get(key) {\n const data = this._classData();\n return key in data ? data[key] : this._defaults[key];\n }\n /**\n * Set a config value.\n *\n * #### Notes\n * Uses the [Jupyter Notebook API](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter-server/jupyter_server/main/jupyter_server/services/api/api.yaml#!/config).\n *\n * The promise is fulfilled on a valid response and rejected otherwise.\n *\n * Sends the update to the server, and changes our local copy of the data\n * immediately.\n */\n set(key, value) {\n const d = {};\n d[key] = value;\n if (this._className) {\n const d2 = {};\n d2[this._className] = d;\n return this._section.update(d2);\n }\n else {\n return this._section.update(d);\n }\n }\n /**\n * Get data from the Section with our classname, if available.\n *\n * #### Notes\n * If we have no classname, get all of the data in the Section\n */\n _classData() {\n const data = this._section.data;\n if (this._className && this._className in data) {\n return data[this._className];\n }\n return data;\n }\n}\nexports.ConfigWithDefaults = ConfigWithDefaults;\n//# sourceMappingURL=index.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.Drive = exports.ContentsManager = exports.Contents = void 0;\nconst coreutils_1 = require(\"@jupyterlab/coreutils\");\nconst signaling_1 = require(\"@lumino/signaling\");\nconst __1 = require(\"..\");\nconst validate = __importStar(require(\"./validate\"));\n/**\n * The url for the default drive service.\n */\nconst SERVICE_DRIVE_URL = 'api/contents';\n/**\n * The url for the file access.\n */\nconst FILES_URL = 'files';\n/**\n * A namespace for contents interfaces.\n */\nvar Contents;\n(function (Contents) {\n /**\n * Validates an IModel, throwing an error if it does not pass.\n */\n function validateContentsModel(contents) {\n validate.validateContentsModel(contents);\n }\n Contents.validateContentsModel = validateContentsModel;\n /**\n * Validates an ICheckpointModel, throwing an error if it does not pass.\n */\n function validateCheckpointModel(checkpoint) {\n validate.validateCheckpointModel(checkpoint);\n }\n Contents.validateCheckpointModel = validateCheckpointModel;\n})(Contents = exports.Contents || (exports.Contents = {}));\n/**\n * A contents manager that passes file operations to the server.\n * Multiple servers implementing the `IDrive` interface can be\n * attached to the contents manager, so that the same session can\n * perform file operations on multiple backends.\n *\n * This includes checkpointing with the normal file operations.\n */\nclass ContentsManager {\n /**\n * Construct a new contents manager object.\n *\n * @param options - The options used to initialize the object.\n */\n constructor(options = {}) {\n var _a, _b;\n this._isDisposed = false;\n this._additionalDrives = new Map();\n this._fileChanged = new signaling_1.Signal(this);\n const serverSettings = (this.serverSettings =\n (_a = options.serverSettings) !== null && _a !== void 0 ? _a : __1.ServerConnection.makeSettings());\n this._defaultDrive = (_b = options.defaultDrive) !== null && _b !== void 0 ? _b : new Drive({ serverSettings });\n this._defaultDrive.fileChanged.connect(this._onFileChanged, this);\n }\n /**\n * A signal emitted when a file operation takes place.\n */\n get fileChanged() {\n return this._fileChanged;\n }\n /**\n * Test whether the manager has been disposed.\n */\n get isDisposed() {\n return this._isDisposed;\n }\n /**\n * Dispose of the resources held by the manager.\n */\n dispose() {\n if (this.isDisposed) {\n return;\n }\n this._isDisposed = true;\n signaling_1.Signal.clearData(this);\n }\n /**\n * Add an `IDrive` to the manager.\n */\n addDrive(drive) {\n this._additionalDrives.set(drive.name, drive);\n drive.fileChanged.connect(this._onFileChanged, this);\n }\n /**\n * Given a path, get a shared model factory from the\n * relevant backend. Returns `null` if the backend\n * does not provide one.\n */\n getSharedModelFactory(path) {\n var _a;\n const [drive] = this._driveForPath(path);\n return (_a = drive === null || drive === void 0 ? void 0 : drive.sharedModelFactory) !== null && _a !== void 0 ? _a : null;\n }\n /**\n * Given a path of the form `drive:local/portion/of/it.txt`\n * get the local part of it.\n *\n * @param path: the path.\n *\n * @returns The local part of the path.\n */\n localPath(path) {\n const parts = path.split('/');\n const firstParts = parts[0].split(':');\n if (firstParts.length === 1 || !this._additionalDrives.has(firstParts[0])) {\n return coreutils_1.PathExt.removeSlash(path);\n }\n return coreutils_1.PathExt.join(firstParts.slice(1).join(':'), ...parts.slice(1));\n }\n /**\n * Normalize a global path. Reduces '..' and '.' parts, and removes\n * leading slashes from the local part of the path, while retaining\n * the drive name if it exists.\n *\n * @param path: the path.\n *\n * @returns The normalized path.\n */\n normalize(path) {\n const parts = path.split(':');\n if (parts.length === 1) {\n return coreutils_1.PathExt.normalize(path);\n }\n return `${parts[0]}:${coreutils_1.PathExt.normalize(parts.slice(1).join(':'))}`;\n }\n /**\n * Resolve a global path, starting from the root path. Behaves like\n * posix-path.resolve, with 3 differences:\n * - will never prepend cwd\n * - if root has a drive name, the result is prefixed with \":\"\n * - before adding drive name, leading slashes are removed\n *\n * @param path: the path.\n *\n * @returns The normalized path.\n */\n resolvePath(root, path) {\n const driveName = this.driveName(root);\n const localPath = this.localPath(root);\n const resolved = coreutils_1.PathExt.resolve('/', localPath, path);\n return driveName ? `${driveName}:${resolved}` : resolved;\n }\n /**\n * Given a path of the form `drive:local/portion/of/it.txt`\n * get the name of the drive. If the path is missing\n * a drive portion, returns an empty string.\n *\n * @param path: the path.\n *\n * @returns The drive name for the path, or the empty string.\n */\n driveName(path) {\n const parts = path.split('/');\n const firstParts = parts[0].split(':');\n if (firstParts.length === 1) {\n return '';\n }\n if (this._additionalDrives.has(firstParts[0])) {\n return firstParts[0];\n }\n return '';\n }\n /**\n * Get a file or directory.\n *\n * @param path: The path to the file.\n *\n * @param options: The options used to fetch the file.\n *\n * @returns A promise which resolves with the file content.\n */\n get(path, options) {\n const [drive, localPath] = this._driveForPath(path);\n return drive.get(localPath, options).then(contentsModel => {\n const listing = [];\n if (contentsModel.type === 'directory' && contentsModel.content) {\n for (const item of contentsModel.content) {\n listing.push({ ...item, path: this._toGlobalPath(drive, item.path) });\n }\n return {\n ...contentsModel,\n path: this._toGlobalPath(drive, localPath),\n content: listing,\n serverPath: contentsModel.path\n };\n }\n else {\n return {\n ...contentsModel,\n path: this._toGlobalPath(drive, localPath),\n serverPath: contentsModel.path\n };\n }\n });\n }\n /**\n * Get an encoded download url given a file path.\n *\n * @param path - An absolute POSIX file path on the server.\n *\n * #### Notes\n * It is expected that the path contains no relative paths.\n *\n * The returned URL may include a query parameter.\n */\n getDownloadUrl(path) {\n const [drive, localPath] = this._driveForPath(path);\n return drive.getDownloadUrl(localPath);\n }\n /**\n * Create a new untitled file or directory in the specified directory path.\n *\n * @param options: The options used to create the file.\n *\n * @returns A promise which resolves with the created file content when the\n * file is created.\n */\n newUntitled(options = {}) {\n if (options.path) {\n const globalPath = this.normalize(options.path);\n const [drive, localPath] = this._driveForPath(globalPath);\n return drive\n .newUntitled({ ...options, path: localPath })\n .then(contentsModel => {\n return {\n ...contentsModel,\n path: coreutils_1.PathExt.join(globalPath, contentsModel.name),\n serverPath: contentsModel.path\n };\n });\n }\n else {\n return this._defaultDrive.newUntitled(options);\n }\n }\n /**\n * Delete a file.\n *\n * @param path - The path to the file.\n *\n * @returns A promise which resolves when the file is deleted.\n */\n delete(path) {\n const [drive, localPath] = this._driveForPath(path);\n return drive.delete(localPath);\n }\n /**\n * Rename a file or directory.\n *\n * @param path - The original file path.\n *\n * @param newPath - The new file path.\n *\n * @returns A promise which resolves with the new file contents model when\n * the file is renamed.\n */\n rename(path, newPath) {\n const [drive1, path1] = this._driveForPath(path);\n const [drive2, path2] = this._driveForPath(newPath);\n if (drive1 !== drive2) {\n throw Error('ContentsManager: renaming files must occur within a Drive');\n }\n return drive1.rename(path1, path2).then(contentsModel => {\n return {\n ...contentsModel,\n path: this._toGlobalPath(drive1, path2),\n serverPath: contentsModel.path\n };\n });\n }\n /**\n * Save a file.\n *\n * @param path - The desired file path.\n *\n * @param options - Optional overrides to the model.\n *\n * @returns A promise which resolves with the file content model when the\n * file is saved.\n *\n * #### Notes\n * Ensure that `model.content` is populated for the file.\n */\n save(path, options = {}) {\n const globalPath = this.normalize(path);\n const [drive, localPath] = this._driveForPath(path);\n return drive\n .save(localPath, { ...options, path: localPath })\n .then(contentsModel => {\n return {\n ...contentsModel,\n path: globalPath,\n serverPath: contentsModel.path\n };\n });\n }\n /**\n * Copy a file into a given directory.\n *\n * @param path - The original file path.\n *\n * @param toDir - The destination directory path.\n *\n * @returns A promise which resolves with the new contents model when the\n * file is copied.\n *\n * #### Notes\n * The server will select the name of the copied file.\n */\n copy(fromFile, toDir) {\n const [drive1, path1] = this._driveForPath(fromFile);\n const [drive2, path2] = this._driveForPath(toDir);\n if (drive1 === drive2) {\n return drive1.copy(path1, path2).then(contentsModel => {\n return {\n ...contentsModel,\n path: this._toGlobalPath(drive1, contentsModel.path),\n serverPath: contentsModel.path\n };\n });\n }\n else {\n throw Error('Copying files between drives is not currently implemented');\n }\n }\n /**\n * Create a checkpoint for a file.\n *\n * @param path - The path of the file.\n *\n * @returns A promise which resolves with the new checkpoint model when the\n * checkpoint is created.\n */\n createCheckpoint(path) {\n const [drive, localPath] = this._driveForPath(path);\n return drive.createCheckpoint(localPath);\n }\n /**\n * List available checkpoints for a file.\n *\n * @param path - The path of the file.\n *\n * @returns A promise which resolves with a list of checkpoint models for\n * the file.\n */\n listCheckpoints(path) {\n const [drive, localPath] = this._driveForPath(path);\n return drive.listCheckpoints(localPath);\n }\n /**\n * Restore a file to a known checkpoint state.\n *\n * @param path - The path of the file.\n *\n * @param checkpointID - The id of the checkpoint to restore.\n *\n * @returns A promise which resolves when the checkpoint is restored.\n */\n restoreCheckpoint(path, checkpointID) {\n const [drive, localPath] = this._driveForPath(path);\n return drive.restoreCheckpoint(localPath, checkpointID);\n }\n /**\n * Delete a checkpoint for a file.\n *\n * @param path - The path of the file.\n *\n * @param checkpointID - The id of the checkpoint to delete.\n *\n * @returns A promise which resolves when the checkpoint is deleted.\n */\n deleteCheckpoint(path, checkpointID) {\n const [drive, localPath] = this._driveForPath(path);\n return drive.deleteCheckpoint(localPath, checkpointID);\n }\n /**\n * Given a drive and a local path, construct a fully qualified\n * path. The inverse of `_driveForPath`.\n *\n * @param drive: an `IDrive`.\n *\n * @param localPath: the local path on the drive.\n *\n * @returns the fully qualified path.\n */\n _toGlobalPath(drive, localPath) {\n if (drive === this._defaultDrive) {\n return coreutils_1.PathExt.removeSlash(localPath);\n }\n else {\n return `${drive.name}:${coreutils_1.PathExt.removeSlash(localPath)}`;\n }\n }\n /**\n * Given a path, get the `IDrive to which it refers,\n * where the path satisfies the pattern\n * `'driveName:path/to/file'`. If there is no `driveName`\n * prepended to the path, it returns the default drive.\n *\n * @param path: a path to a file.\n *\n * @returns A tuple containing an `IDrive` object for the path,\n * and a local path for that drive.\n */\n _driveForPath(path) {\n const driveName = this.driveName(path);\n const localPath = this.localPath(path);\n if (driveName) {\n return [this._additionalDrives.get(driveName), localPath];\n }\n else {\n return [this._defaultDrive, localPath];\n }\n }\n /**\n * Respond to fileChanged signals from the drives attached to\n * the manager. This prepends the drive name to the path if necessary,\n * and then forwards the signal.\n */\n _onFileChanged(sender, args) {\n var _a, _b;\n if (sender === this._defaultDrive) {\n this._fileChanged.emit(args);\n }\n else {\n let newValue = null;\n let oldValue = null;\n if ((_a = args.newValue) === null || _a === void 0 ? void 0 : _a.path) {\n newValue = {\n ...args.newValue,\n path: this._toGlobalPath(sender, args.newValue.path)\n };\n }\n if ((_b = args.oldValue) === null || _b === void 0 ? void 0 : _b.path) {\n oldValue = {\n ...args.oldValue,\n path: this._toGlobalPath(sender, args.oldValue.path)\n };\n }\n this._fileChanged.emit({\n type: args.type,\n newValue,\n oldValue\n });\n }\n }\n}\nexports.ContentsManager = ContentsManager;\n/**\n * A default implementation for an `IDrive`, talking to the\n * server using the Jupyter REST API.\n */\nclass Drive {\n /**\n * Construct a new contents manager object.\n *\n * @param options - The options used to initialize the object.\n */\n constructor(options = {}) {\n var _a, _b, _c;\n this._isDisposed = false;\n this._fileChanged = new signaling_1.Signal(this);\n this.name = (_a = options.name) !== null && _a !== void 0 ? _a : 'Default';\n this._apiEndpoint = (_b = options.apiEndpoint) !== null && _b !== void 0 ? _b : SERVICE_DRIVE_URL;\n this.serverSettings =\n (_c = options.serverSettings) !== null && _c !== void 0 ? _c : __1.ServerConnection.makeSettings();\n }\n /**\n * A signal emitted when a file operation takes place.\n */\n get fileChanged() {\n return this._fileChanged;\n }\n /**\n * Test whether the manager has been disposed.\n */\n get isDisposed() {\n return this._isDisposed;\n }\n /**\n * Dispose of the resources held by the manager.\n */\n dispose() {\n if (this.isDisposed) {\n return;\n }\n this._isDisposed = true;\n signaling_1.Signal.clearData(this);\n }\n /**\n * Get a file or directory.\n *\n * @param localPath: The path to the file.\n *\n * @param options: The options used to fetch the file.\n *\n * @returns A promise which resolves with the file content.\n *\n * Uses the [Jupyter Notebook API](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter-server/jupyter_server/main/jupyter_server/services/api/api.yaml#!/contents) and validates the response model.\n */\n async get(localPath, options) {\n let url = this._getUrl(localPath);\n if (options) {\n // The notebook type cannot take an format option.\n if (options.type === 'notebook') {\n delete options['format'];\n }\n const content = options.content ? '1' : '0';\n const params = { ...options, content };\n url += coreutils_1.URLExt.objectToQueryString(params);\n }\n const settings = this.serverSettings;\n const response = await __1.ServerConnection.makeRequest(url, {}, settings);\n if (response.status !== 200) {\n const err = await __1.ServerConnection.ResponseError.create(response);\n throw err;\n }\n const data = await response.json();\n validate.validateContentsModel(data);\n return data;\n }\n /**\n * Get an encoded download url given a file path.\n *\n * @param localPath - An absolute POSIX file path on the server.\n *\n * #### Notes\n * It is expected that the path contains no relative paths.\n *\n * The returned URL may include a query parameter.\n */\n getDownloadUrl(localPath) {\n const baseUrl = this.serverSettings.baseUrl;\n let url = coreutils_1.URLExt.join(baseUrl, FILES_URL, coreutils_1.URLExt.encodeParts(localPath));\n const xsrfTokenMatch = document.cookie.match('\\\\b_xsrf=([^;]*)\\\\b');\n if (xsrfTokenMatch) {\n const fullUrl = new URL(url);\n fullUrl.searchParams.append('_xsrf', xsrfTokenMatch[1]);\n url = fullUrl.toString();\n }\n return Promise.resolve(url);\n }\n /**\n * Create a new untitled file or directory in the specified directory path.\n *\n * @param options: The options used to create the file.\n *\n * @returns A promise which resolves with the created file content when the\n * file is created.\n *\n * #### Notes\n * Uses the [Jupyter Notebook API](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter-server/jupyter_server/main/jupyter_server/services/api/api.yaml#!/contents) and validates the response model.\n */\n async newUntitled(options = {}) {\n var _a;\n let body = '{}';\n if (options) {\n if (options.ext) {\n options.ext = Private.normalizeExtension(options.ext);\n }\n body = JSON.stringify(options);\n }\n const settings = this.serverSettings;\n const url = this._getUrl((_a = options.path) !== null && _a !== void 0 ? _a : '');\n const init = {\n method: 'POST',\n body\n };\n const response = await __1.ServerConnection.makeRequest(url, init, settings);\n if (response.status !== 201) {\n const err = await __1.ServerConnection.ResponseError.create(response);\n throw err;\n }\n const data = await response.json();\n validate.validateContentsModel(data);\n this._fileChanged.emit({\n type: 'new',\n oldValue: null,\n newValue: data\n });\n return data;\n }\n /**\n * Delete a file.\n *\n * @param localPath - The path to the file.\n *\n * @returns A promise which resolves when the file is deleted.\n *\n * #### Notes\n * Uses the [Jupyter Notebook API](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter-server/jupyter_server/main/jupyter_server/services/api/api.yaml#!/contents).\n */\n async delete(localPath) {\n const url = this._getUrl(localPath);\n const settings = this.serverSettings;\n const init = { method: 'DELETE' };\n const response = await __1.ServerConnection.makeRequest(url, init, settings);\n // TODO: update IPEP27 to specify errors more precisely, so\n // that error types can be detected here with certainty.\n if (response.status !== 204) {\n const err = await __1.ServerConnection.ResponseError.create(response);\n throw err;\n }\n this._fileChanged.emit({\n type: 'delete',\n oldValue: { path: localPath },\n newValue: null\n });\n }\n /**\n * Rename a file or directory.\n *\n * @param oldLocalPath - The original file path.\n *\n * @param newLocalPath - The new file path.\n *\n * @returns A promise which resolves with the new file contents model when\n * the file is renamed.\n *\n * #### Notes\n * Uses the [Jupyter Notebook API](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter-server/jupyter_server/main/jupyter_server/services/api/api.yaml#!/contents) and validates the response model.\n */\n async rename(oldLocalPath, newLocalPath) {\n const settings = this.serverSettings;\n const url = this._getUrl(oldLocalPath);\n const init = {\n method: 'PATCH',\n body: JSON.stringify({ path: newLocalPath })\n };\n const response = await __1.ServerConnection.makeRequest(url, init, settings);\n if (response.status !== 200) {\n const err = await __1.ServerConnection.ResponseError.create(response);\n throw err;\n }\n const data = await response.json();\n validate.validateContentsModel(data);\n this._fileChanged.emit({\n type: 'rename',\n oldValue: { path: oldLocalPath },\n newValue: data\n });\n return data;\n }\n /**\n * Save a file.\n *\n * @param localPath - The desired file path.\n *\n * @param options - Optional overrides to the model.\n *\n * @returns A promise which resolves with the file content model when the\n * file is saved.\n *\n * #### Notes\n * Ensure that `model.content` is populated for the file.\n *\n * Uses the [Jupyter Notebook API](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter-server/jupyter_server/main/jupyter_server/services/api/api.yaml#!/contents) and validates the response model.\n */\n async save(localPath, options = {}) {\n const settings = this.serverSettings;\n const url = this._getUrl(localPath);\n const init = {\n method: 'PUT',\n body: JSON.stringify(options)\n };\n const response = await __1.ServerConnection.makeRequest(url, init, settings);\n // will return 200 for an existing file and 201 for a new file\n if (response.status !== 200 && response.status !== 201) {\n const err = await __1.ServerConnection.ResponseError.create(response);\n throw err;\n }\n const data = await response.json();\n validate.validateContentsModel(data);\n this._fileChanged.emit({\n type: 'save',\n oldValue: null,\n newValue: data\n });\n return data;\n }\n /**\n * Copy a file into a given directory.\n *\n * @param localPath - The original file path.\n *\n * @param toDir - The destination directory path.\n *\n * @returns A promise which resolves with the new contents model when the\n * file is copied.\n *\n * #### Notes\n * The server will select the name of the copied file.\n *\n * Uses the [Jupyter Notebook API](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter-server/jupyter_server/main/jupyter_server/services/api/api.yaml#!/contents) and validates the response model.\n */\n async copy(fromFile, toDir) {\n const settings = this.serverSettings;\n const url = this._getUrl(toDir);\n const init = {\n method: 'POST',\n body: JSON.stringify({ copy_from: fromFile })\n };\n const response = await __1.ServerConnection.makeRequest(url, init, settings);\n if (response.status !== 201) {\n const err = await __1.ServerConnection.ResponseError.create(response);\n throw err;\n }\n const data = await response.json();\n validate.validateContentsModel(data);\n this._fileChanged.emit({\n type: 'new',\n oldValue: null,\n newValue: data\n });\n return data;\n }\n /**\n * Create a checkpoint for a file.\n *\n * @param localPath - The path of the file.\n *\n * @returns A promise which resolves with the new checkpoint model when the\n * checkpoint is created.\n *\n * #### Notes\n * Uses the [Jupyter Notebook API](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter-server/jupyter_server/main/jupyter_server/services/api/api.yaml#!/contents) and validates the response model.\n */\n async createCheckpoint(localPath) {\n const url = this._getUrl(localPath, 'checkpoints');\n const init = { method: 'POST' };\n const response = await __1.ServerConnection.makeRequest(url, init, this.serverSettings);\n if (response.status !== 201) {\n const err = await __1.ServerConnection.ResponseError.create(response);\n throw err;\n }\n const data = await response.json();\n validate.validateCheckpointModel(data);\n return data;\n }\n /**\n * List available checkpoints for a file.\n *\n * @param localPath - The path of the file.\n *\n * @returns A promise which resolves with a list of checkpoint models for\n * the file.\n *\n * #### Notes\n * Uses the [Jupyter Notebook API](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter-server/jupyter_server/main/jupyter_server/services/api/api.yaml#!/contents) and validates the response model.\n */\n async listCheckpoints(localPath) {\n const url = this._getUrl(localPath, 'checkpoints');\n const response = await __1.ServerConnection.makeRequest(url, {}, this.serverSettings);\n if (response.status !== 200) {\n const err = await __1.ServerConnection.ResponseError.create(response);\n throw err;\n }\n const data = await response.json();\n if (!Array.isArray(data)) {\n throw new Error('Invalid Checkpoint list');\n }\n for (let i = 0; i < data.length; i++) {\n validate.validateCheckpointModel(data[i]);\n }\n return data;\n }\n /**\n * Restore a file to a known checkpoint state.\n *\n * @param localPath - The path of the file.\n *\n * @param checkpointID - The id of the checkpoint to restore.\n *\n * @returns A promise which resolves when the checkpoint is restored.\n *\n * #### Notes\n * Uses the [Jupyter Notebook API](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter-server/jupyter_server/main/jupyter_server/services/api/api.yaml#!/contents).\n */\n async restoreCheckpoint(localPath, checkpointID) {\n const url = this._getUrl(localPath, 'checkpoints', checkpointID);\n const init = { method: 'POST' };\n const response = await __1.ServerConnection.makeRequest(url, init, this.serverSettings);\n if (response.status !== 204) {\n const err = await __1.ServerConnection.ResponseError.create(response);\n throw err;\n }\n }\n /**\n * Delete a checkpoint for a file.\n *\n * @param localPath - The path of the file.\n *\n * @param checkpointID - The id of the checkpoint to delete.\n *\n * @returns A promise which resolves when the checkpoint is deleted.\n *\n * #### Notes\n * Uses the [Jupyter Notebook API](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter-server/jupyter_server/main/jupyter_server/services/api/api.yaml#!/contents).\n */\n async deleteCheckpoint(localPath, checkpointID) {\n const url = this._getUrl(localPath, 'checkpoints', checkpointID);\n const init = { method: 'DELETE' };\n const response = await __1.ServerConnection.makeRequest(url, init, this.serverSettings);\n if (response.status !== 204) {\n const err = await __1.ServerConnection.ResponseError.create(response);\n throw err;\n }\n }\n /**\n * Get a REST url for a file given a path.\n */\n _getUrl(...args) {\n const parts = args.map(path => coreutils_1.URLExt.encodeParts(path));\n const baseUrl = this.serverSettings.baseUrl;\n return coreutils_1.URLExt.join(baseUrl, this._apiEndpoint, ...parts);\n }\n}\nexports.Drive = Drive;\n/**\n * A namespace for module private data.\n */\nvar Private;\n(function (Private) {\n /**\n * Normalize a file extension to be of the type `'.foo'`.\n *\n * Adds a leading dot if not present and converts to lower case.\n */\n function normalizeExtension(extension) {\n if (extension.length > 0 && extension.indexOf('.') !== 0) {\n extension = `.${extension}`;\n }\n return extension;\n }\n Private.normalizeExtension = normalizeExtension;\n})(Private || (Private = {}));\n//# sourceMappingURL=index.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.validateCheckpointModel = exports.validateContentsModel = void 0;\nconst validate_1 = require(\"../validate\");\n/**\n * Validate an `Contents.IModel` object.\n */\nfunction validateContentsModel(model) {\n (0, validate_1.validateProperty)(model, 'name', 'string');\n (0, validate_1.validateProperty)(model, 'path', 'string');\n (0, validate_1.validateProperty)(model, 'type', 'string');\n (0, validate_1.validateProperty)(model, 'created', 'string');\n (0, validate_1.validateProperty)(model, 'last_modified', 'string');\n (0, validate_1.validateProperty)(model, 'mimetype', 'object');\n (0, validate_1.validateProperty)(model, 'content', 'object');\n (0, validate_1.validateProperty)(model, 'format', 'object');\n}\nexports.validateContentsModel = validateContentsModel;\n/**\n * Validate an `Contents.ICheckpointModel` object.\n */\nfunction validateCheckpointModel(model) {\n (0, validate_1.validateProperty)(model, 'id', 'string');\n (0, validate_1.validateProperty)(model, 'last_modified', 'string');\n}\nexports.validateCheckpointModel = validateCheckpointModel;\n//# sourceMappingURL=validate.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.EventManager = void 0;\nconst coreutils_1 = require(\"@jupyterlab/coreutils\");\nconst polling_1 = require(\"@lumino/polling\");\nconst signaling_1 = require(\"@lumino/signaling\");\nconst serverconnection_1 = require(\"../serverconnection\");\n/**\n * The url for the jupyter-server events service.\n */\nconst SERVICE_EVENTS_URL = 'api/events';\n/**\n * The events API service manager.\n */\nclass EventManager {\n /**\n * Create a new event manager.\n */\n constructor(options = {}) {\n var _a;\n this._socket = null;\n this.serverSettings =\n (_a = options.serverSettings) !== null && _a !== void 0 ? _a : serverconnection_1.ServerConnection.makeSettings();\n // If subscription fails, the poll attempts to reconnect and backs off.\n this._poll = new polling_1.Poll({ factory: () => this._subscribe() });\n this._stream = new signaling_1.Stream(this);\n // Subscribe to the events socket.\n void this._poll.start();\n }\n /**\n * Whether the event manager is disposed.\n */\n get isDisposed() {\n return this._poll.isDisposed;\n }\n /**\n * An event stream that emits and yields each new event.\n */\n get stream() {\n return this._stream;\n }\n /**\n * Dispose the event manager.\n */\n dispose() {\n if (this.isDisposed) {\n return;\n }\n // Clean up poll.\n this._poll.dispose();\n // Clean up socket.\n const socket = this._socket;\n if (socket) {\n this._socket = null;\n socket.onopen = () => undefined;\n socket.onerror = () => undefined;\n socket.onmessage = () => undefined;\n socket.onclose = () => undefined;\n socket.close();\n }\n // Clean up stream.\n signaling_1.Signal.clearData(this);\n this._stream.stop();\n }\n /**\n * Post an event request to be emitted by the event bus.\n */\n async emit(event) {\n const { serverSettings } = this;\n const { baseUrl, token } = serverSettings;\n const { makeRequest, ResponseError } = serverconnection_1.ServerConnection;\n const url = coreutils_1.URLExt.join(baseUrl, SERVICE_EVENTS_URL) +\n (token ? `?token=${token}` : '');\n const init = { body: JSON.stringify(event), method: 'POST' };\n const response = await makeRequest(url, init, serverSettings);\n if (response.status !== 204) {\n throw new ResponseError(response);\n }\n }\n /**\n * Subscribe to event bus emissions.\n */\n _subscribe() {\n return new Promise((_, reject) => {\n if (this.isDisposed) {\n return;\n }\n const { token, WebSocket, wsUrl } = this.serverSettings;\n const url = coreutils_1.URLExt.join(wsUrl, SERVICE_EVENTS_URL, 'subscribe') +\n (token ? `?token=${encodeURIComponent(token)}` : '');\n const socket = (this._socket = new WebSocket(url));\n const stream = this._stream;\n socket.onclose = () => reject(new Error('EventManager socket closed'));\n socket.onmessage = msg => msg.data && stream.emit(JSON.parse(msg.data));\n });\n }\n}\nexports.EventManager = EventManager;\n//# sourceMappingURL=index.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/**\n * @packageDocumentation\n * @module services\n */\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __exportStar = (this && this.__exportStar) || function(m, exports) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n__exportStar(require(\"./basemanager\"), exports);\n__exportStar(require(\"./config\"), exports);\n__exportStar(require(\"./contents\"), exports);\n__exportStar(require(\"./event\"), exports);\n__exportStar(require(\"./kernel\"), exports);\n__exportStar(require(\"./kernelspec\"), exports);\n__exportStar(require(\"./manager\"), exports);\n__exportStar(require(\"./serverconnection\"), exports);\n__exportStar(require(\"./session\"), exports);\n__exportStar(require(\"./setting\"), exports);\n__exportStar(require(\"./terminal\"), exports);\n__exportStar(require(\"./user\"), exports);\n__exportStar(require(\"./workspace\"), exports);\n__exportStar(require(\"./nbconvert\"), exports);\n//# sourceMappingURL=index.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.CommHandler = void 0;\nconst disposable_1 = require(\"@lumino/disposable\");\nconst KernelMessage = __importStar(require(\"./messages\"));\n/**\n * Comm channel handler.\n */\nclass CommHandler extends disposable_1.DisposableDelegate {\n /**\n * Construct a new comm channel.\n */\n constructor(target, id, kernel, disposeCb) {\n super(disposeCb);\n this._target = '';\n this._id = '';\n this._id = id;\n this._target = target;\n this._kernel = kernel;\n }\n /**\n * The unique id for the comm channel.\n */\n get commId() {\n return this._id;\n }\n /**\n * The target name for the comm channel.\n */\n get targetName() {\n return this._target;\n }\n /**\n * Get the callback for a comm close event.\n *\n * #### Notes\n * This is called when the comm is closed from either the server or client.\n *\n * **See also:** [[ICommClose]], [[close]]\n */\n get onClose() {\n return this._onClose;\n }\n /**\n * Set the callback for a comm close event.\n *\n * #### Notes\n * This is called when the comm is closed from either the server or client. If\n * the function returns a promise, and the kernel was closed from the server,\n * kernel message processing will pause until the returned promise is\n * fulfilled.\n *\n * **See also:** [[close]]\n */\n set onClose(cb) {\n this._onClose = cb;\n }\n /**\n * Get the callback for a comm message received event.\n */\n get onMsg() {\n return this._onMsg;\n }\n /**\n * Set the callback for a comm message received event.\n *\n * #### Notes\n * This is called when a comm message is received. If the function returns a\n * promise, kernel message processing will pause until it is fulfilled.\n */\n set onMsg(cb) {\n this._onMsg = cb;\n }\n /**\n * Open a comm with optional data and metadata.\n *\n * #### Notes\n * This sends a `comm_open` message to the server.\n *\n * **See also:** [[ICommOpen]]\n */\n open(data, metadata, buffers = []) {\n if (this.isDisposed || this._kernel.isDisposed) {\n throw new Error('Cannot open');\n }\n const msg = KernelMessage.createMessage({\n msgType: 'comm_open',\n channel: 'shell',\n username: this._kernel.username,\n session: this._kernel.clientId,\n content: {\n comm_id: this._id,\n target_name: this._target,\n data: data !== null && data !== void 0 ? data : {}\n },\n metadata,\n buffers\n });\n return this._kernel.sendShellMessage(msg, false, true);\n }\n /**\n * Send a `comm_msg` message to the kernel.\n *\n * #### Notes\n * This is a no-op if the comm has been closed.\n *\n * **See also:** [[ICommMsg]]\n */\n send(data, metadata, buffers = [], disposeOnDone = true) {\n if (this.isDisposed || this._kernel.isDisposed) {\n throw new Error('Cannot send');\n }\n const msg = KernelMessage.createMessage({\n msgType: 'comm_msg',\n channel: 'shell',\n username: this._kernel.username,\n session: this._kernel.clientId,\n content: {\n comm_id: this._id,\n data: data\n },\n metadata,\n buffers\n });\n return this._kernel.sendShellMessage(msg, false, disposeOnDone);\n }\n /**\n * Close the comm.\n *\n * #### Notes\n * This will send a `comm_close` message to the kernel, and call the\n * `onClose` callback if set.\n *\n * This is a no-op if the comm is already closed.\n *\n * **See also:** [[ICommClose]], [[onClose]]\n */\n close(data, metadata, buffers = []) {\n if (this.isDisposed || this._kernel.isDisposed) {\n throw new Error('Cannot close');\n }\n const msg = KernelMessage.createMessage({\n msgType: 'comm_close',\n channel: 'shell',\n username: this._kernel.username,\n session: this._kernel.clientId,\n content: {\n comm_id: this._id,\n data: data !== null && data !== void 0 ? data : {}\n },\n metadata,\n buffers\n });\n const future = this._kernel.sendShellMessage(msg, false, true);\n const onClose = this._onClose;\n if (onClose) {\n const ioMsg = KernelMessage.createMessage({\n msgType: 'comm_close',\n channel: 'iopub',\n username: this._kernel.username,\n session: this._kernel.clientId,\n content: {\n comm_id: this._id,\n data: data !== null && data !== void 0 ? data : {}\n },\n metadata,\n buffers\n });\n // In the future, we may want to communicate back to the user the possible\n // promise returned from onClose.\n void onClose(ioMsg);\n }\n this.dispose();\n return future;\n }\n}\nexports.CommHandler = CommHandler;\n//# sourceMappingURL=comm.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.KernelConnection = void 0;\nconst coreutils_1 = require(\"@jupyterlab/coreutils\");\nconst coreutils_2 = require(\"@lumino/coreutils\");\nconst signaling_1 = require(\"@lumino/signaling\");\nconst __1 = require(\"..\");\nconst comm_1 = require(\"./comm\");\nconst KernelMessage = __importStar(require(\"./messages\"));\nconst future_1 = require(\"./future\");\nconst serialize_1 = require(\"./serialize\");\nconst validate = __importStar(require(\"./validate\"));\nconst kernelspec_1 = require(\"../kernelspec\");\nconst restapi = __importStar(require(\"./restapi\"));\nconst KERNEL_INFO_TIMEOUT = 3000;\nconst RESTARTING_KERNEL_SESSION = '_RESTARTING_';\nconst STARTING_KERNEL_SESSION = '';\n/**\n * Implementation of the Kernel object.\n *\n * #### Notes\n * Messages from the server are handled in the order they were received and\n * asynchronously. Any message handler can return a promise, and message\n * handling will pause until the promise is fulfilled.\n */\nclass KernelConnection {\n /**\n * Construct a kernel object.\n */\n constructor(options) {\n var _a, _b, _c, _d;\n /**\n * Create the kernel websocket connection and add socket status handlers.\n */\n this._createSocket = (useProtocols = true) => {\n this._errorIfDisposed();\n // Make sure the socket is clear\n this._clearSocket();\n // Update the connection status to reflect opening a new connection.\n this._updateConnectionStatus('connecting');\n const settings = this.serverSettings;\n const partialUrl = coreutils_1.URLExt.join(settings.wsUrl, restapi.KERNEL_SERVICE_URL, encodeURIComponent(this._id));\n // Strip any authentication from the display string.\n const display = partialUrl.replace(/^((?:\\w+:)?\\/\\/)(?:[^@\\/]+@)/, '$1');\n console.debug(`Starting WebSocket: ${display}`);\n let url = coreutils_1.URLExt.join(partialUrl, 'channels?session_id=' + encodeURIComponent(this._clientId));\n // If token authentication is in use.\n const token = settings.token;\n if (settings.appendToken && token !== '') {\n url = url + `&token=${encodeURIComponent(token)}`;\n }\n // Try opening the websocket with our list of subprotocols.\n // If the server doesn't handle subprotocols,\n // the accepted protocol will be ''.\n // But we cannot send '' as a subprotocol, so if connection fails,\n // reconnect without subprotocols.\n const supportedProtocols = useProtocols ? this._supportedProtocols : [];\n this._ws = new settings.WebSocket(url, supportedProtocols);\n // Ensure incoming binary messages are not Blobs\n this._ws.binaryType = 'arraybuffer';\n let alreadyCalledOnclose = false;\n const getKernelModel = async (evt) => {\n var _a, _b;\n if (this._isDisposed) {\n return;\n }\n this._reason = '';\n this._model = undefined;\n try {\n const model = await restapi.getKernelModel(this._id, settings);\n this._model = model;\n if ((model === null || model === void 0 ? void 0 : model.execution_state) === 'dead') {\n this._updateStatus('dead');\n }\n else {\n this._onWSClose(evt);\n }\n }\n catch (err) {\n // Try again, if there is a network failure\n // Handle network errors, as well as cases where we are on a\n // JupyterHub and the server is not running. JupyterHub returns a\n // 503 (<2.0) or 424 (>2.0) in that case.\n if (err instanceof __1.ServerConnection.NetworkError ||\n ((_a = err.response) === null || _a === void 0 ? void 0 : _a.status) === 503 ||\n ((_b = err.response) === null || _b === void 0 ? void 0 : _b.status) === 424) {\n const timeout = Private.getRandomIntInclusive(10, 30) * 1e3;\n setTimeout(getKernelModel, timeout, evt);\n }\n else {\n this._reason = 'Kernel died unexpectedly';\n this._updateStatus('dead');\n }\n }\n return;\n };\n const earlyClose = async (evt) => {\n // If the websocket was closed early, that could mean\n // that the kernel is actually dead. Try getting\n // information about the kernel from the API call,\n // if that fails, then assume the kernel is dead,\n // otherwise just follow the typical websocket closed\n // protocol.\n if (alreadyCalledOnclose) {\n return;\n }\n alreadyCalledOnclose = true;\n await getKernelModel(evt);\n return;\n };\n this._ws.onmessage = this._onWSMessage;\n this._ws.onopen = this._onWSOpen;\n this._ws.onclose = earlyClose;\n this._ws.onerror = earlyClose;\n };\n // Make websocket callbacks arrow functions so they bind `this`.\n /**\n * Handle a websocket open event.\n */\n this._onWSOpen = (evt) => {\n if (this._ws.protocol !== '' &&\n !this._supportedProtocols.includes(this._ws.protocol)) {\n console.log('Server selected unknown kernel wire protocol:', this._ws.protocol);\n this._updateStatus('dead');\n throw new Error(`Unknown kernel wire protocol: ${this._ws.protocol}`);\n }\n // Remember the kernel wire protocol selected by the server.\n this._selectedProtocol = this._ws.protocol;\n this._ws.onclose = this._onWSClose;\n this._ws.onerror = this._onWSClose;\n this._updateConnectionStatus('connected');\n };\n /**\n * Handle a websocket message, validating and routing appropriately.\n */\n this._onWSMessage = (evt) => {\n // Notify immediately if there is an error with the message.\n let msg;\n try {\n msg = (0, serialize_1.deserialize)(evt.data, this._ws.protocol);\n validate.validateMessage(msg);\n }\n catch (error) {\n error.message = `Kernel message validation error: ${error.message}`;\n // We throw the error so that it bubbles up to the top, and displays the right stack.\n throw error;\n }\n // Update the current kernel session id\n this._kernelSession = msg.header.session;\n // Handle the message asynchronously, in the order received.\n this._msgChain = this._msgChain\n .then(() => {\n // Return so that any promises from handling a message are fulfilled\n // before proceeding to the next message.\n return this._handleMessage(msg);\n })\n .catch(error => {\n // Log any errors in handling the message, thus resetting the _msgChain\n // promise so we can process more messages.\n // Ignore the \"Canceled\" errors that are thrown during kernel dispose.\n if (error.message.startsWith('Canceled future for ')) {\n console.error(error);\n }\n });\n // Emit the message receive signal\n this._anyMessage.emit({ msg, direction: 'recv' });\n };\n /**\n * Handle a websocket close event.\n */\n this._onWSClose = (evt) => {\n if (!this.isDisposed) {\n this._reconnect();\n }\n };\n this._id = '';\n this._name = '';\n this._status = 'unknown';\n this._connectionStatus = 'connecting';\n this._kernelSession = '';\n this._isDisposed = false;\n /**\n * Websocket to communicate with kernel.\n */\n this._ws = null;\n this._username = '';\n this._reconnectLimit = 7;\n this._reconnectAttempt = 0;\n this._reconnectTimeout = null;\n this._supportedProtocols = Object.values(KernelMessage.supportedKernelWebSocketProtocols);\n this._selectedProtocol = '';\n this._futures = new Map();\n this._comms = new Map();\n this._targetRegistry = Object.create(null);\n this._info = new coreutils_2.PromiseDelegate();\n this._pendingMessages = [];\n this._statusChanged = new signaling_1.Signal(this);\n this._connectionStatusChanged = new signaling_1.Signal(this);\n this._disposed = new signaling_1.Signal(this);\n this._iopubMessage = new signaling_1.Signal(this);\n this._anyMessage = new signaling_1.Signal(this);\n this._pendingInput = new signaling_1.Signal(this);\n this._unhandledMessage = new signaling_1.Signal(this);\n this._displayIdToParentIds = new Map();\n this._msgIdToDisplayIds = new Map();\n this._msgChain = Promise.resolve();\n this._hasPendingInput = false;\n this._reason = '';\n this._noOp = () => {\n /* no-op */\n };\n this._name = options.model.name;\n this._id = options.model.id;\n this.serverSettings =\n (_a = options.serverSettings) !== null && _a !== void 0 ? _a : __1.ServerConnection.makeSettings();\n this._clientId = (_b = options.clientId) !== null && _b !== void 0 ? _b : coreutils_2.UUID.uuid4();\n this._username = (_c = options.username) !== null && _c !== void 0 ? _c : '';\n this.handleComms = (_d = options.handleComms) !== null && _d !== void 0 ? _d : true;\n this._createSocket();\n }\n get disposed() {\n return this._disposed;\n }\n /**\n * A signal emitted when the kernel status changes.\n */\n get statusChanged() {\n return this._statusChanged;\n }\n /**\n * A signal emitted when the kernel status changes.\n */\n get connectionStatusChanged() {\n return this._connectionStatusChanged;\n }\n /**\n * A signal emitted for iopub kernel messages.\n *\n * #### Notes\n * This signal is emitted after the iopub message is handled asynchronously.\n */\n get iopubMessage() {\n return this._iopubMessage;\n }\n /**\n * A signal emitted for unhandled kernel message.\n *\n * #### Notes\n * This signal is emitted for a message that was not handled. It is emitted\n * during the asynchronous message handling code.\n */\n get unhandledMessage() {\n return this._unhandledMessage;\n }\n /**\n * The kernel model\n */\n get model() {\n return (this._model || {\n id: this.id,\n name: this.name,\n reason: this._reason\n });\n }\n /**\n * A signal emitted for any kernel message.\n *\n * #### Notes\n * This signal is emitted when a message is received, before it is handled\n * asynchronously.\n *\n * This message is emitted when a message is queued for sending (either in\n * the websocket buffer, or our own pending message buffer). The message may\n * actually be sent across the wire at a later time.\n *\n * The message emitted in this signal should not be modified in any way.\n */\n get anyMessage() {\n return this._anyMessage;\n }\n /**\n * A signal emitted when a kernel has pending inputs from the user.\n */\n get pendingInput() {\n return this._pendingInput;\n }\n /**\n * The id of the server-side kernel.\n */\n get id() {\n return this._id;\n }\n /**\n * The name of the server-side kernel.\n */\n get name() {\n return this._name;\n }\n /**\n * The client username.\n */\n get username() {\n return this._username;\n }\n /**\n * The client unique id.\n */\n get clientId() {\n return this._clientId;\n }\n /**\n * The current status of the kernel.\n */\n get status() {\n return this._status;\n }\n /**\n * The current connection status of the kernel connection.\n */\n get connectionStatus() {\n return this._connectionStatus;\n }\n /**\n * Test whether the kernel has been disposed.\n */\n get isDisposed() {\n return this._isDisposed;\n }\n /**\n * The cached kernel info.\n *\n * @returns A promise that resolves to the kernel info.\n */\n get info() {\n return this._info.promise;\n }\n /**\n * The kernel spec.\n *\n * @returns A promise that resolves to the kernel spec.\n */\n get spec() {\n if (this._specPromise) {\n return this._specPromise;\n }\n this._specPromise = kernelspec_1.KernelSpecAPI.getSpecs(this.serverSettings).then(specs => {\n return specs.kernelspecs[this._name];\n });\n return this._specPromise;\n }\n /**\n * Clone the current kernel with a new clientId.\n */\n clone(options = {}) {\n return new KernelConnection({\n model: this.model,\n username: this.username,\n serverSettings: this.serverSettings,\n // handleComms defaults to false since that is safer\n handleComms: false,\n ...options\n });\n }\n /**\n * Dispose of the resources held by the kernel.\n */\n dispose() {\n if (this.isDisposed) {\n return;\n }\n this._isDisposed = true;\n this._disposed.emit();\n this._updateConnectionStatus('disconnected');\n this._clearKernelState();\n this._pendingMessages = [];\n this._clearSocket();\n // Clear Lumino signals\n signaling_1.Signal.clearData(this);\n }\n /**\n * Send a shell message to the kernel.\n *\n * #### Notes\n * Send a message to the kernel's shell channel, yielding a future object\n * for accepting replies.\n *\n * If `expectReply` is given and `true`, the future is disposed when both a\n * shell reply and an idle status message are received. If `expectReply`\n * is not given or is `false`, the future is resolved when an idle status\n * message is received.\n * If `disposeOnDone` is not given or is `true`, the Future is disposed at this point.\n * If `disposeOnDone` is given and `false`, it is up to the caller to dispose of the Future.\n *\n * All replies are validated as valid kernel messages.\n *\n * If the kernel status is `dead`, this will throw an error.\n */\n sendShellMessage(msg, expectReply = false, disposeOnDone = true) {\n return this._sendKernelShellControl(future_1.KernelShellFutureHandler, msg, expectReply, disposeOnDone);\n }\n /**\n * Send a control message to the kernel.\n *\n * #### Notes\n * Send a message to the kernel's control channel, yielding a future object\n * for accepting replies.\n *\n * If `expectReply` is given and `true`, the future is disposed when both a\n * control reply and an idle status message are received. If `expectReply`\n * is not given or is `false`, the future is resolved when an idle status\n * message is received.\n * If `disposeOnDone` is not given or is `true`, the Future is disposed at this point.\n * If `disposeOnDone` is given and `false`, it is up to the caller to dispose of the Future.\n *\n * All replies are validated as valid kernel messages.\n *\n * If the kernel status is `dead`, this will throw an error.\n */\n sendControlMessage(msg, expectReply = false, disposeOnDone = true) {\n return this._sendKernelShellControl(future_1.KernelControlFutureHandler, msg, expectReply, disposeOnDone);\n }\n _sendKernelShellControl(ctor, msg, expectReply = false, disposeOnDone = true) {\n this._sendMessage(msg);\n this._anyMessage.emit({ msg, direction: 'send' });\n const future = new ctor(() => {\n const msgId = msg.header.msg_id;\n this._futures.delete(msgId);\n // Remove stored display id information.\n const displayIds = this._msgIdToDisplayIds.get(msgId);\n if (!displayIds) {\n return;\n }\n displayIds.forEach(displayId => {\n const msgIds = this._displayIdToParentIds.get(displayId);\n if (msgIds) {\n const idx = msgIds.indexOf(msgId);\n if (idx === -1) {\n return;\n }\n if (msgIds.length === 1) {\n this._displayIdToParentIds.delete(displayId);\n }\n else {\n msgIds.splice(idx, 1);\n this._displayIdToParentIds.set(displayId, msgIds);\n }\n }\n });\n this._msgIdToDisplayIds.delete(msgId);\n }, msg, expectReply, disposeOnDone, this);\n this._futures.set(msg.header.msg_id, future);\n return future;\n }\n /**\n * Send a message on the websocket.\n *\n * If queue is true, queue the message for later sending if we cannot send\n * now. Otherwise throw an error.\n *\n * #### Notes\n * As an exception to the queueing, if we are sending a kernel_info_request\n * message while we think the kernel is restarting, we send the message\n * immediately without queueing. This is so that we can trigger a message\n * back, which will then clear the kernel restarting state.\n */\n _sendMessage(msg, queue = true) {\n if (this.status === 'dead') {\n throw new Error('Kernel is dead');\n }\n // If we have a kernel_info_request and we are starting or restarting, send the\n // kernel_info_request immediately if we can, and if not throw an error so\n // we can retry later. On restarting we do this because we must get at least one message\n // from the kernel to reset the kernel session (thus clearing the restart\n // status sentinel).\n if ((this._kernelSession === STARTING_KERNEL_SESSION ||\n this._kernelSession === RESTARTING_KERNEL_SESSION) &&\n KernelMessage.isInfoRequestMsg(msg)) {\n if (this.connectionStatus === 'connected') {\n this._ws.send((0, serialize_1.serialize)(msg, this._ws.protocol));\n return;\n }\n else {\n throw new Error('Could not send message: status is not connected');\n }\n }\n // If there are pending messages, add to the queue so we keep messages in order\n if (queue && this._pendingMessages.length > 0) {\n this._pendingMessages.push(msg);\n return;\n }\n // Send if the ws allows it, otherwise queue the message.\n if (this.connectionStatus === 'connected' &&\n this._kernelSession !== RESTARTING_KERNEL_SESSION) {\n this._ws.send((0, serialize_1.serialize)(msg, this._ws.protocol));\n }\n else if (queue) {\n this._pendingMessages.push(msg);\n }\n else {\n throw new Error('Could not send message');\n }\n }\n /**\n * Interrupt a kernel.\n *\n * #### Notes\n * Uses the [Jupyter Notebook API](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter-server/jupyter_server/main/jupyter_server/services/api/api.yaml#!/kernels).\n *\n * The promise is fulfilled on a valid response and rejected otherwise.\n *\n * It is assumed that the API call does not mutate the kernel id or name.\n *\n * The promise will be rejected if the kernel status is `Dead` or if the\n * request fails or the response is invalid.\n */\n async interrupt() {\n this.hasPendingInput = false;\n if (this.status === 'dead') {\n throw new Error('Kernel is dead');\n }\n return restapi.interruptKernel(this.id, this.serverSettings);\n }\n /**\n * Request a kernel restart.\n *\n * #### Notes\n * Uses the [Jupyter Notebook API](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter-server/jupyter_server/main/jupyter_server/services/api/api.yaml#!/kernels)\n * and validates the response model.\n *\n * Any existing Future or Comm objects are cleared once the kernel has\n * actually be restarted.\n *\n * The promise is fulfilled on a valid server response (after the kernel restarts)\n * and rejected otherwise.\n *\n * It is assumed that the API call does not mutate the kernel id or name.\n *\n * The promise will be rejected if the request fails or the response is\n * invalid.\n */\n async restart() {\n if (this.status === 'dead') {\n throw new Error('Kernel is dead');\n }\n this._updateStatus('restarting');\n this._clearKernelState();\n this._kernelSession = RESTARTING_KERNEL_SESSION;\n await restapi.restartKernel(this.id, this.serverSettings);\n // Reconnect to the kernel to address cases where kernel ports\n // have changed during the restart.\n await this.reconnect();\n this.hasPendingInput = false;\n }\n /**\n * Reconnect to a kernel.\n *\n * #### Notes\n * This may try multiple times to reconnect to a kernel, and will sever any\n * existing connection.\n */\n reconnect() {\n this._errorIfDisposed();\n const result = new coreutils_2.PromiseDelegate();\n // Set up a listener for the connection status changing, which accepts or\n // rejects after the retries are done.\n const fulfill = (sender, status) => {\n if (status === 'connected') {\n result.resolve();\n this.connectionStatusChanged.disconnect(fulfill, this);\n }\n else if (status === 'disconnected') {\n result.reject(new Error('Kernel connection disconnected'));\n this.connectionStatusChanged.disconnect(fulfill, this);\n }\n };\n this.connectionStatusChanged.connect(fulfill, this);\n // Reset the reconnect limit so we start the connection attempts fresh\n this._reconnectAttempt = 0;\n // Start the reconnection process, which will also clear any existing\n // connection.\n this._reconnect();\n // Return the promise that should resolve on connection or reject if the\n // retries don't work.\n return result.promise;\n }\n /**\n * Shutdown a kernel.\n *\n * #### Notes\n * Uses the [Jupyter Notebook API](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter-server/jupyter_server/main/jupyter_server/services/api/api.yaml#!/kernels).\n *\n * The promise is fulfilled on a valid response and rejected otherwise.\n *\n * On a valid response, disposes this kernel connection.\n *\n * If the kernel is already `dead`, disposes this kernel connection without\n * a server request.\n */\n async shutdown() {\n if (this.status !== 'dead') {\n await restapi.shutdownKernel(this.id, this.serverSettings);\n }\n this.handleShutdown();\n }\n /**\n * Handles a kernel shutdown.\n *\n * #### Notes\n * This method should be called if we know from outside information that a\n * kernel is dead (for example, we cannot find the kernel model on the\n * server).\n */\n handleShutdown() {\n this._updateStatus('dead');\n this.dispose();\n }\n /**\n * Send a `kernel_info_request` message.\n *\n * #### Notes\n * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#kernel-info).\n *\n * Fulfills with the `kernel_info_response` content when the shell reply is\n * received and validated.\n */\n async requestKernelInfo() {\n const msg = KernelMessage.createMessage({\n msgType: 'kernel_info_request',\n channel: 'shell',\n username: this._username,\n session: this._clientId,\n content: {}\n });\n let reply;\n try {\n reply = (await Private.handleShellMessage(this, msg));\n }\n catch (e) {\n // If we rejected because the future was disposed, ignore and return.\n if (this.isDisposed) {\n return;\n }\n else {\n throw e;\n }\n }\n this._errorIfDisposed();\n if (!reply) {\n return;\n }\n // Kernels sometimes do not include a status field on kernel_info_reply\n // messages, so set a default for now.\n // See https://github.com/jupyterlab/jupyterlab/issues/6760\n if (reply.content.status === undefined) {\n reply.content.status = 'ok';\n }\n if (reply.content.status !== 'ok') {\n this._info.reject('Kernel info reply errored');\n return reply;\n }\n this._info.resolve(reply.content);\n this._kernelSession = reply.header.session;\n return reply;\n }\n /**\n * Send a `complete_request` message.\n *\n * #### Notes\n * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#completion).\n *\n * Fulfills with the `complete_reply` content when the shell reply is\n * received and validated.\n */\n requestComplete(content) {\n const msg = KernelMessage.createMessage({\n msgType: 'complete_request',\n channel: 'shell',\n username: this._username,\n session: this._clientId,\n content\n });\n return Private.handleShellMessage(this, msg);\n }\n /**\n * Send an `inspect_request` message.\n *\n * #### Notes\n * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#introspection).\n *\n * Fulfills with the `inspect_reply` content when the shell reply is\n * received and validated.\n */\n requestInspect(content) {\n const msg = KernelMessage.createMessage({\n msgType: 'inspect_request',\n channel: 'shell',\n username: this._username,\n session: this._clientId,\n content: content\n });\n return Private.handleShellMessage(this, msg);\n }\n /**\n * Send a `history_request` message.\n *\n * #### Notes\n * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#history).\n *\n * Fulfills with the `history_reply` content when the shell reply is\n * received and validated.\n */\n requestHistory(content) {\n const msg = KernelMessage.createMessage({\n msgType: 'history_request',\n channel: 'shell',\n username: this._username,\n session: this._clientId,\n content\n });\n return Private.handleShellMessage(this, msg);\n }\n /**\n * Send an `execute_request` message.\n *\n * #### Notes\n * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#execute).\n *\n * Future `onReply` is called with the `execute_reply` content when the\n * shell reply is received and validated. The future will resolve when\n * this message is received and the `idle` iopub status is received.\n * The future will also be disposed at this point unless `disposeOnDone`\n * is specified and `false`, in which case it is up to the caller to dispose\n * of the future.\n *\n * **See also:** [[IExecuteReply]]\n */\n requestExecute(content, disposeOnDone = true, metadata) {\n const defaults = {\n silent: false,\n store_history: true,\n user_expressions: {},\n allow_stdin: true,\n stop_on_error: false\n };\n const msg = KernelMessage.createMessage({\n msgType: 'execute_request',\n channel: 'shell',\n username: this._username,\n session: this._clientId,\n content: { ...defaults, ...content },\n metadata\n });\n return this.sendShellMessage(msg, true, disposeOnDone);\n }\n /**\n * Send an experimental `debug_request` message.\n *\n * @hidden\n *\n * #### Notes\n * Debug messages are experimental messages that are not in the official\n * kernel message specification. As such, this function is *NOT* considered\n * part of the public API, and may change without notice.\n */\n requestDebug(content, disposeOnDone = true) {\n const msg = KernelMessage.createMessage({\n msgType: 'debug_request',\n channel: 'control',\n username: this._username,\n session: this._clientId,\n content\n });\n return this.sendControlMessage(msg, true, disposeOnDone);\n }\n /**\n * Send an `is_complete_request` message.\n *\n * #### Notes\n * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#code-completeness).\n *\n * Fulfills with the `is_complete_response` content when the shell reply is\n * received and validated.\n */\n requestIsComplete(content) {\n const msg = KernelMessage.createMessage({\n msgType: 'is_complete_request',\n channel: 'shell',\n username: this._username,\n session: this._clientId,\n content\n });\n return Private.handleShellMessage(this, msg);\n }\n /**\n * Send a `comm_info_request` message.\n *\n * #### Notes\n * Fulfills with the `comm_info_reply` content when the shell reply is\n * received and validated.\n */\n requestCommInfo(content) {\n const msg = KernelMessage.createMessage({\n msgType: 'comm_info_request',\n channel: 'shell',\n username: this._username,\n session: this._clientId,\n content\n });\n return Private.handleShellMessage(this, msg);\n }\n /**\n * Send an `input_reply` message.\n *\n * #### Notes\n * See [Messaging in Jupyter](https://jupyter-client.readthedocs.io/en/latest/messaging.html#messages-on-the-stdin-router-dealer-sockets).\n */\n sendInputReply(content, parent_header) {\n const msg = KernelMessage.createMessage({\n msgType: 'input_reply',\n channel: 'stdin',\n username: this._username,\n session: this._clientId,\n content\n });\n msg.parent_header = parent_header;\n this._sendMessage(msg);\n this._anyMessage.emit({ msg, direction: 'send' });\n this.hasPendingInput = false;\n }\n /**\n * Create a new comm.\n *\n * #### Notes\n * If a client-side comm already exists with the given commId, an error is thrown.\n * If the kernel does not handle comms, an error is thrown.\n */\n createComm(targetName, commId = coreutils_2.UUID.uuid4()) {\n if (!this.handleComms) {\n throw new Error('Comms are disabled on this kernel connection');\n }\n if (this._comms.has(commId)) {\n throw new Error('Comm is already created');\n }\n const comm = new comm_1.CommHandler(targetName, commId, this, () => {\n this._unregisterComm(commId);\n });\n this._comms.set(commId, comm);\n return comm;\n }\n /**\n * Check if a comm exists.\n */\n hasComm(commId) {\n return this._comms.has(commId);\n }\n /**\n * Register a comm target handler.\n *\n * @param targetName - The name of the comm target.\n *\n * @param callback - The callback invoked for a comm open message.\n *\n * @returns A disposable used to unregister the comm target.\n *\n * #### Notes\n * Only one comm target can be registered to a target name at a time, an\n * existing callback for the same target name will be overridden. A registered\n * comm target handler will take precedence over a comm which specifies a\n * `target_module`.\n *\n * If the callback returns a promise, kernel message processing will pause\n * until the returned promise is fulfilled.\n */\n registerCommTarget(targetName, callback) {\n if (!this.handleComms) {\n return;\n }\n this._targetRegistry[targetName] = callback;\n }\n /**\n * Remove a comm target handler.\n *\n * @param targetName - The name of the comm target to remove.\n *\n * @param callback - The callback to remove.\n *\n * #### Notes\n * The comm target is only removed if the callback argument matches.\n */\n removeCommTarget(targetName, callback) {\n if (!this.handleComms) {\n return;\n }\n if (!this.isDisposed && this._targetRegistry[targetName] === callback) {\n delete this._targetRegistry[targetName];\n }\n }\n /**\n * Register an IOPub message hook.\n *\n * @param msg_id - The parent_header message id the hook will intercept.\n *\n * @param hook - The callback invoked for the message.\n *\n * #### Notes\n * The IOPub hook system allows you to preempt the handlers for IOPub\n * messages that are responses to a given message id.\n *\n * The most recently registered hook is run first. A hook can return a\n * boolean or a promise to a boolean, in which case all kernel message\n * processing pauses until the promise is fulfilled. If a hook return value\n * resolves to false, any later hooks will not run and the function will\n * return a promise resolving to false. If a hook throws an error, the error\n * is logged to the console and the next hook is run. If a hook is\n * registered during the hook processing, it will not run until the next\n * message. If a hook is removed during the hook processing, it will be\n * deactivated immediately.\n *\n * See also [[IFuture.registerMessageHook]].\n */\n registerMessageHook(msgId, hook) {\n var _a;\n const future = (_a = this._futures) === null || _a === void 0 ? void 0 : _a.get(msgId);\n if (future) {\n future.registerMessageHook(hook);\n }\n }\n /**\n * Remove an IOPub message hook.\n *\n * @param msg_id - The parent_header message id the hook intercepted.\n *\n * @param hook - The callback invoked for the message.\n *\n */\n removeMessageHook(msgId, hook) {\n var _a;\n const future = (_a = this._futures) === null || _a === void 0 ? void 0 : _a.get(msgId);\n if (future) {\n future.removeMessageHook(hook);\n }\n }\n /**\n * Remove the input guard, if any.\n */\n removeInputGuard() {\n this.hasPendingInput = false;\n }\n /**\n * Handle a message with a display id.\n *\n * @returns Whether the message was handled.\n */\n async _handleDisplayId(displayId, msg) {\n var _a, _b;\n const msgId = msg.parent_header.msg_id;\n let parentIds = this._displayIdToParentIds.get(displayId);\n if (parentIds) {\n // We've seen it before, update existing outputs with same display_id\n // by handling display_data as update_display_data.\n const updateMsg = {\n header: coreutils_2.JSONExt.deepCopy(msg.header),\n parent_header: coreutils_2.JSONExt.deepCopy(msg.parent_header),\n metadata: coreutils_2.JSONExt.deepCopy(msg.metadata),\n content: coreutils_2.JSONExt.deepCopy(msg.content),\n channel: msg.channel,\n buffers: msg.buffers ? msg.buffers.slice() : []\n };\n updateMsg.header.msg_type = 'update_display_data';\n await Promise.all(parentIds.map(async (parentId) => {\n const future = this._futures && this._futures.get(parentId);\n if (future) {\n await future.handleMsg(updateMsg);\n }\n }));\n }\n // We're done here if it's update_display.\n if (msg.header.msg_type === 'update_display_data') {\n // It's an update, don't proceed to the normal display.\n return true;\n }\n // Regular display_data with id, record it for future updating\n // in _displayIdToParentIds for future lookup.\n parentIds = (_a = this._displayIdToParentIds.get(displayId)) !== null && _a !== void 0 ? _a : [];\n if (parentIds.indexOf(msgId) === -1) {\n parentIds.push(msgId);\n }\n this._displayIdToParentIds.set(displayId, parentIds);\n // Add to our map of display ids for this message.\n const displayIds = (_b = this._msgIdToDisplayIds.get(msgId)) !== null && _b !== void 0 ? _b : [];\n if (displayIds.indexOf(msgId) === -1) {\n displayIds.push(msgId);\n }\n this._msgIdToDisplayIds.set(msgId, displayIds);\n // Let the message propagate to the intended recipient.\n return false;\n }\n /**\n * Forcefully clear the socket state.\n *\n * #### Notes\n * This will clear all socket state without calling any handlers and will\n * not update the connection status. If you call this method, you are\n * responsible for updating the connection status as needed and recreating\n * the socket if you plan to reconnect.\n */\n _clearSocket() {\n if (this._ws !== null) {\n // Clear the websocket event handlers and the socket itself.\n this._ws.onopen = this._noOp;\n this._ws.onclose = this._noOp;\n this._ws.onerror = this._noOp;\n this._ws.onmessage = this._noOp;\n this._ws.close();\n this._ws = null;\n }\n }\n /**\n * Handle status iopub messages from the kernel.\n */\n _updateStatus(status) {\n if (this._status === status || this._status === 'dead') {\n return;\n }\n this._status = status;\n Private.logKernelStatus(this);\n this._statusChanged.emit(status);\n if (status === 'dead') {\n this.dispose();\n }\n }\n /**\n * Send pending messages to the kernel.\n */\n _sendPending() {\n // We check to make sure we are still connected each time. For\n // example, if a websocket buffer overflows, it may close, so we should\n // stop sending messages.\n while (this.connectionStatus === 'connected' &&\n this._kernelSession !== RESTARTING_KERNEL_SESSION &&\n this._pendingMessages.length > 0) {\n this._sendMessage(this._pendingMessages[0], false);\n // We shift the message off the queue after the message is sent so that\n // if there is an exception, the message is still pending.\n this._pendingMessages.shift();\n }\n }\n /**\n * Clear the internal state.\n */\n _clearKernelState() {\n this._kernelSession = '';\n this._pendingMessages = [];\n this._futures.forEach(future => {\n future.dispose();\n });\n this._comms.forEach(comm => {\n comm.dispose();\n });\n this._msgChain = Promise.resolve();\n this._futures = new Map();\n this._comms = new Map();\n this._displayIdToParentIds.clear();\n this._msgIdToDisplayIds.clear();\n }\n /**\n * Check to make sure it is okay to proceed to handle a message.\n *\n * #### Notes\n * Because we handle messages asynchronously, before a message is handled the\n * kernel might be disposed or restarted (and have a different session id).\n * This function throws an error in each of these cases. This is meant to be\n * called at the start of an asynchronous message handler to cancel message\n * processing if the message no longer is valid.\n */\n _assertCurrentMessage(msg) {\n this._errorIfDisposed();\n if (msg.header.session !== this._kernelSession) {\n throw new Error(`Canceling handling of old message: ${msg.header.msg_type}`);\n }\n }\n /**\n * Handle a `comm_open` kernel message.\n */\n async _handleCommOpen(msg) {\n this._assertCurrentMessage(msg);\n const content = msg.content;\n const comm = new comm_1.CommHandler(content.target_name, content.comm_id, this, () => {\n this._unregisterComm(content.comm_id);\n });\n this._comms.set(content.comm_id, comm);\n try {\n const target = await Private.loadObject(content.target_name, content.target_module, this._targetRegistry);\n await target(comm, msg);\n }\n catch (e) {\n // Close the comm asynchronously. We cannot block message processing on\n // kernel messages to wait for another kernel message.\n comm.close();\n console.error('Exception opening new comm');\n throw e;\n }\n }\n /**\n * Handle 'comm_close' kernel message.\n */\n async _handleCommClose(msg) {\n this._assertCurrentMessage(msg);\n const content = msg.content;\n const comm = this._comms.get(content.comm_id);\n if (!comm) {\n console.error('Comm not found for comm id ' + content.comm_id);\n return;\n }\n this._unregisterComm(comm.commId);\n const onClose = comm.onClose;\n if (onClose) {\n // tslint:disable-next-line:await-promise\n await onClose(msg);\n }\n comm.dispose();\n }\n /**\n * Handle a 'comm_msg' kernel message.\n */\n async _handleCommMsg(msg) {\n this._assertCurrentMessage(msg);\n const content = msg.content;\n const comm = this._comms.get(content.comm_id);\n if (!comm) {\n return;\n }\n const onMsg = comm.onMsg;\n if (onMsg) {\n // tslint:disable-next-line:await-promise\n await onMsg(msg);\n }\n }\n /**\n * Unregister a comm instance.\n */\n _unregisterComm(commId) {\n this._comms.delete(commId);\n }\n /**\n * Handle connection status changes.\n */\n _updateConnectionStatus(connectionStatus) {\n if (this._connectionStatus === connectionStatus) {\n return;\n }\n this._connectionStatus = connectionStatus;\n // If we are not 'connecting', reset any reconnection attempts.\n if (connectionStatus !== 'connecting') {\n this._reconnectAttempt = 0;\n clearTimeout(this._reconnectTimeout);\n }\n if (this.status !== 'dead') {\n if (connectionStatus === 'connected') {\n let restarting = this._kernelSession === RESTARTING_KERNEL_SESSION;\n // Send a kernel info request to make sure we send at least one\n // message to get kernel status back. Always request kernel info\n // first, to get kernel status back and ensure iopub is fully\n // established. If we are restarting, this message will skip the queue\n // and be sent immediately.\n let p = this.requestKernelInfo();\n // Send any pending messages after the kernelInfo resolves, or after a\n // timeout as a failsafe.\n let sendPendingCalled = false;\n let sendPendingOnce = () => {\n if (sendPendingCalled) {\n return;\n }\n sendPendingCalled = true;\n if (restarting && this._kernelSession === RESTARTING_KERNEL_SESSION) {\n // We were restarting and a message didn't arrive to set the\n // session, but we just assume the restart succeeded and send any\n // pending messages.\n // FIXME: it would be better to retry the kernel_info_request here\n this._kernelSession = '';\n }\n clearTimeout(timeoutHandle);\n if (this._pendingMessages.length > 0) {\n this._sendPending();\n }\n };\n void p.then(sendPendingOnce);\n // FIXME: if sent while zmq subscriptions are not established,\n // kernelInfo may not resolve, so use a timeout to ensure we don't hang forever.\n // It may be preferable to retry kernelInfo rather than give up after one timeout.\n let timeoutHandle = setTimeout(sendPendingOnce, KERNEL_INFO_TIMEOUT);\n }\n else {\n // If the connection is down, then we do not know what is happening\n // with the kernel, so set the status to unknown.\n this._updateStatus('unknown');\n }\n }\n // Notify others that the connection status changed.\n this._connectionStatusChanged.emit(connectionStatus);\n }\n async _handleMessage(msg) {\n var _a, _b;\n let handled = false;\n // Check to see if we have a display_id we need to reroute.\n if (msg.parent_header &&\n msg.channel === 'iopub' &&\n (KernelMessage.isDisplayDataMsg(msg) ||\n KernelMessage.isUpdateDisplayDataMsg(msg) ||\n KernelMessage.isExecuteResultMsg(msg))) {\n // display_data messages may re-route based on their display_id.\n const transient = ((_a = msg.content.transient) !== null && _a !== void 0 ? _a : {});\n const displayId = transient['display_id'];\n if (displayId) {\n handled = await this._handleDisplayId(displayId, msg);\n // The await above may make this message out of date, so check again.\n this._assertCurrentMessage(msg);\n }\n }\n if (!handled && msg.parent_header) {\n const parentHeader = msg.parent_header;\n const future = (_b = this._futures) === null || _b === void 0 ? void 0 : _b.get(parentHeader.msg_id);\n if (future) {\n await future.handleMsg(msg);\n this._assertCurrentMessage(msg);\n }\n else {\n // If the message was sent by us and was not iopub, it is orphaned.\n const owned = parentHeader.session === this.clientId;\n if (msg.channel !== 'iopub' && owned) {\n this._unhandledMessage.emit(msg);\n }\n }\n }\n if (msg.channel === 'iopub') {\n switch (msg.header.msg_type) {\n case 'status': {\n // Updating the status is synchronous, and we call no async user code\n const executionState = msg.content\n .execution_state;\n if (executionState === 'restarting') {\n // The kernel has been auto-restarted by the server. After\n // processing for this message is completely done, we want to\n // handle this restart, so we don't await, but instead schedule\n // the work as a microtask (i.e., in a promise resolution). We\n // schedule this here so that it comes before any microtasks that\n // might be scheduled in the status signal emission below.\n void Promise.resolve().then(async () => {\n this._updateStatus('autorestarting');\n this._clearKernelState();\n // We must reconnect since the kernel connection information may have\n // changed, and the server only refreshes its zmq connection when a new\n // websocket is opened.\n await this.reconnect();\n });\n }\n this._updateStatus(executionState);\n break;\n }\n case 'comm_open':\n if (this.handleComms) {\n await this._handleCommOpen(msg);\n }\n break;\n case 'comm_msg':\n if (this.handleComms) {\n await this._handleCommMsg(msg);\n }\n break;\n case 'comm_close':\n if (this.handleComms) {\n await this._handleCommClose(msg);\n }\n break;\n default:\n break;\n }\n // If the message was a status dead message, we might have disposed ourselves.\n if (!this.isDisposed) {\n this._assertCurrentMessage(msg);\n // the message wouldn't be emitted if we were disposed anyway.\n this._iopubMessage.emit(msg);\n }\n }\n }\n /**\n * Attempt a connection if we have not exhausted connection attempts.\n */\n _reconnect() {\n this._errorIfDisposed();\n // Clear any existing reconnection attempt\n clearTimeout(this._reconnectTimeout);\n // Update the connection status and schedule a possible reconnection.\n if (this._reconnectAttempt < this._reconnectLimit) {\n this._updateConnectionStatus('connecting');\n // The first reconnect attempt should happen immediately, and subsequent\n // attempts should pick a random number in a growing range so that we\n // don't overload the server with synchronized reconnection attempts\n // across multiple kernels.\n const timeout = Private.getRandomIntInclusive(0, 1e3 * (Math.pow(2, this._reconnectAttempt) - 1));\n console.warn(`Connection lost, reconnecting in ${Math.floor(timeout / 1000)} seconds.`);\n // Try reconnection with subprotocols if the server had supported them.\n // Otherwise, try reconnection without subprotocols.\n const useProtocols = this._selectedProtocol !== '' ? true : false;\n this._reconnectTimeout = setTimeout(this._createSocket, timeout, useProtocols);\n this._reconnectAttempt += 1;\n }\n else {\n this._updateConnectionStatus('disconnected');\n }\n // Clear the websocket event handlers and the socket itself.\n this._clearSocket();\n }\n /**\n * Utility function to throw an error if this instance is disposed.\n */\n _errorIfDisposed() {\n if (this.isDisposed) {\n throw new Error('Kernel connection is disposed');\n }\n }\n get hasPendingInput() {\n return this._hasPendingInput;\n }\n set hasPendingInput(value) {\n this._hasPendingInput = value;\n this._pendingInput.emit(value);\n }\n}\nexports.KernelConnection = KernelConnection;\n/**\n * A private namespace for the Kernel.\n */\nvar Private;\n(function (Private) {\n /**\n * Log the current kernel status.\n */\n function logKernelStatus(kernel) {\n switch (kernel.status) {\n case 'idle':\n case 'busy':\n case 'unknown':\n return;\n default:\n console.debug(`Kernel: ${kernel.status} (${kernel.id})`);\n break;\n }\n }\n Private.logKernelStatus = logKernelStatus;\n /**\n * Send a kernel message to the kernel and resolve the reply message.\n */\n async function handleShellMessage(kernel, msg) {\n const future = kernel.sendShellMessage(msg, true);\n return future.done;\n }\n Private.handleShellMessage = handleShellMessage;\n /**\n * Try to load an object from a module or a registry.\n *\n * Try to load an object from a module asynchronously if a module\n * is specified, otherwise tries to load an object from the global\n * registry, if the global registry is provided.\n *\n * #### Notes\n * Loading a module uses requirejs.\n */\n function loadObject(name, moduleName, registry) {\n return new Promise((resolve, reject) => {\n // Try loading the module using require.js\n if (moduleName) {\n if (typeof requirejs === 'undefined') {\n throw new Error('requirejs not found');\n }\n requirejs([moduleName], (mod) => {\n if (mod[name] === void 0) {\n const msg = `Object '${name}' not found in module '${moduleName}'`;\n reject(new Error(msg));\n }\n else {\n resolve(mod[name]);\n }\n }, reject);\n }\n else {\n if (registry === null || registry === void 0 ? void 0 : registry[name]) {\n resolve(registry[name]);\n }\n else {\n reject(new Error(`Object '${name}' not found in registry`));\n }\n }\n });\n }\n Private.loadObject = loadObject;\n /**\n * Get a random integer between min and max, inclusive of both.\n *\n * #### Notes\n * From\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random#Getting_a_random_integer_between_two_values_inclusive\n *\n * From the MDN page: It might be tempting to use Math.round() to accomplish\n * that, but doing so would cause your random numbers to follow a non-uniform\n * distribution, which may not be acceptable for your needs.\n */\n function getRandomIntInclusive(min, max) {\n min = Math.ceil(min);\n max = Math.floor(max);\n return Math.floor(Math.random() * (max - min + 1)) + min;\n }\n Private.getRandomIntInclusive = getRandomIntInclusive;\n})(Private || (Private = {}));\n//# sourceMappingURL=default.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.KernelShellFutureHandler = exports.KernelControlFutureHandler = exports.KernelFutureHandler = void 0;\nconst coreutils_1 = require(\"@lumino/coreutils\");\nconst disposable_1 = require(\"@lumino/disposable\");\nconst KernelMessage = __importStar(require(\"./messages\"));\n/**\n * Implementation of a kernel future.\n *\n * If a reply is expected, the Future is considered done when both a `reply`\n * message and an `idle` iopub status message have been received. Otherwise, it\n * is considered done when the `idle` status is received.\n *\n */\nclass KernelFutureHandler extends disposable_1.DisposableDelegate {\n /**\n * Construct a new KernelFutureHandler.\n */\n constructor(cb, msg, expectReply, disposeOnDone, kernel) {\n super(cb);\n this._status = 0;\n this._stdin = Private.noOp;\n this._iopub = Private.noOp;\n this._reply = Private.noOp;\n this._done = new coreutils_1.PromiseDelegate();\n this._hooks = new Private.HookList();\n this._disposeOnDone = true;\n this._msg = msg;\n if (!expectReply) {\n this._setFlag(Private.KernelFutureFlag.GotReply);\n }\n this._disposeOnDone = disposeOnDone;\n this._kernel = kernel;\n }\n /**\n * Get the original outgoing message.\n */\n get msg() {\n return this._msg;\n }\n /**\n * A promise that resolves when the future is done.\n */\n get done() {\n return this._done.promise;\n }\n /**\n * Get the reply handler.\n */\n get onReply() {\n return this._reply;\n }\n /**\n * Set the reply handler.\n */\n set onReply(cb) {\n this._reply = cb;\n }\n /**\n * Get the iopub handler.\n */\n get onIOPub() {\n return this._iopub;\n }\n /**\n * Set the iopub handler.\n */\n set onIOPub(cb) {\n this._iopub = cb;\n }\n /**\n * Get the stdin handler.\n */\n get onStdin() {\n return this._stdin;\n }\n /**\n * Set the stdin handler.\n */\n set onStdin(cb) {\n this._stdin = cb;\n }\n /**\n * Register hook for IOPub messages.\n *\n * @param hook - The callback invoked for an IOPub message.\n *\n * #### Notes\n * The IOPub hook system allows you to preempt the handlers for IOPub\n * messages handled by the future.\n *\n * The most recently registered hook is run first. A hook can return a\n * boolean or a promise to a boolean, in which case all kernel message\n * processing pauses until the promise is fulfilled. If a hook return value\n * resolves to false, any later hooks will not run and the function will\n * return a promise resolving to false. If a hook throws an error, the error\n * is logged to the console and the next hook is run. If a hook is\n * registered during the hook processing, it will not run until the next\n * message. If a hook is removed during the hook processing, it will be\n * deactivated immediately.\n */\n registerMessageHook(hook) {\n if (this.isDisposed) {\n throw new Error('Kernel future is disposed');\n }\n this._hooks.add(hook);\n }\n /**\n * Remove a hook for IOPub messages.\n *\n * @param hook - The hook to remove.\n *\n * #### Notes\n * If a hook is removed during the hook processing, it will be deactivated immediately.\n */\n removeMessageHook(hook) {\n if (this.isDisposed) {\n return;\n }\n this._hooks.remove(hook);\n }\n /**\n * Send an `input_reply` message.\n */\n sendInputReply(content, parent_header) {\n this._kernel.sendInputReply(content, parent_header);\n }\n /**\n * Dispose and unregister the future.\n */\n dispose() {\n this._stdin = Private.noOp;\n this._iopub = Private.noOp;\n this._reply = Private.noOp;\n this._hooks = null;\n if (!this._testFlag(Private.KernelFutureFlag.IsDone)) {\n // TODO: Uncomment the following logging code, and check for any tests that trigger it.\n // let status = [];\n // if (!this._testFlag(Private.KernelFutureFlag.GotIdle)) {\n // status.push('idle');\n // }\n // if (!this._testFlag(Private.KernelFutureFlag.GotReply)) {\n // status.push('reply');\n // }\n // console.warn(\n // `*************** DISPOSED BEFORE DONE: K${this._kernel.id.slice(\n // 0,\n // 6\n // )} M${this._msg.header.msg_id.slice(0, 6)} missing ${status.join(' ')}`\n // );\n // Reject the `done` promise, but catch its error here in case no one else\n // is waiting for the promise to resolve. This prevents the error from\n // being displayed in the console, but does not prevent it from being\n // caught by a client who is waiting for it.\n this._done.promise.catch(() => {\n /* no-op */\n });\n this._done.reject(new Error(`Canceled future for ${this.msg.header.msg_type} message before replies were done`));\n }\n super.dispose();\n }\n /**\n * Handle an incoming kernel message.\n */\n async handleMsg(msg) {\n switch (msg.channel) {\n case 'control':\n case 'shell':\n if (msg.channel === this.msg.channel &&\n msg.parent_header.msg_id === this.msg.header.msg_id) {\n await this._handleReply(msg);\n }\n break;\n case 'stdin':\n await this._handleStdin(msg);\n break;\n case 'iopub':\n await this._handleIOPub(msg);\n break;\n default:\n break;\n }\n }\n async _handleReply(msg) {\n const reply = this._reply;\n if (reply) {\n // tslint:disable-next-line:await-promise\n await reply(msg);\n }\n this._replyMsg = msg;\n this._setFlag(Private.KernelFutureFlag.GotReply);\n if (this._testFlag(Private.KernelFutureFlag.GotIdle)) {\n this._handleDone();\n }\n }\n async _handleStdin(msg) {\n this._kernel.hasPendingInput = true;\n const stdin = this._stdin;\n if (stdin) {\n // tslint:disable-next-line:await-promise\n await stdin(msg);\n }\n }\n async _handleIOPub(msg) {\n const process = await this._hooks.process(msg);\n const iopub = this._iopub;\n if (process && iopub) {\n // tslint:disable-next-line:await-promise\n await iopub(msg);\n }\n if (KernelMessage.isStatusMsg(msg) &&\n msg.content.execution_state === 'idle') {\n this._setFlag(Private.KernelFutureFlag.GotIdle);\n if (this._testFlag(Private.KernelFutureFlag.GotReply)) {\n this._handleDone();\n }\n }\n }\n _handleDone() {\n if (this._testFlag(Private.KernelFutureFlag.IsDone)) {\n return;\n }\n this._setFlag(Private.KernelFutureFlag.IsDone);\n this._done.resolve(this._replyMsg);\n if (this._disposeOnDone) {\n this.dispose();\n }\n }\n /**\n * Test whether the given future flag is set.\n */\n _testFlag(flag) {\n // tslint:disable-next-line\n return (this._status & flag) !== 0;\n }\n /**\n * Set the given future flag.\n */\n _setFlag(flag) {\n // tslint:disable-next-line\n this._status |= flag;\n }\n}\nexports.KernelFutureHandler = KernelFutureHandler;\nclass KernelControlFutureHandler extends KernelFutureHandler {\n}\nexports.KernelControlFutureHandler = KernelControlFutureHandler;\nclass KernelShellFutureHandler extends KernelFutureHandler {\n}\nexports.KernelShellFutureHandler = KernelShellFutureHandler;\nvar Private;\n(function (Private) {\n /**\n * A no-op function.\n */\n Private.noOp = () => {\n /* no-op */\n };\n /**\n * Defer a computation.\n *\n * #### NOTES\n * We can't just use requestAnimationFrame since it is not available in node.\n * This implementation is from Phosphor:\n * https://github.com/phosphorjs/phosphor/blob/e88e4321289bb1198f3098e7bda40736501f2ed8/tests/test-messaging/src/index.spec.ts#L63\n */\n const defer = (() => {\n const ok = typeof requestAnimationFrame === 'function';\n return ok ? requestAnimationFrame : setImmediate;\n })();\n class HookList {\n constructor() {\n this._hooks = [];\n }\n /**\n * Register a hook.\n *\n * @param hook - The callback to register.\n */\n add(hook) {\n this.remove(hook);\n this._hooks.push(hook);\n }\n /**\n * Remove a hook, if it exists in the hook list.\n *\n * @param hook - The callback to remove.\n */\n remove(hook) {\n const index = this._hooks.indexOf(hook);\n if (index >= 0) {\n this._hooks[index] = null;\n this._scheduleCompact();\n }\n }\n /**\n * Process a message through the hooks.\n *\n * @returns a promise resolving to false if any hook resolved as false,\n * otherwise true\n *\n * #### Notes\n * The most recently registered hook is run first. A hook can return a\n * boolean or a promise to a boolean, in which case processing pauses until\n * the promise is fulfilled. If a hook return value resolves to false, any\n * later hooks will not run and the function will return a promise resolving\n * to false. If a hook throws an error, the error is logged to the console\n * and the next hook is run. If a hook is registered during the hook\n * processing, it will not run until the next message. If a hook is removed\n * during the hook processing, it will be deactivated immediately.\n */\n async process(msg) {\n // Wait until we can start a new process run.\n await this._processing;\n // Start the next process run.\n const processing = new coreutils_1.PromiseDelegate();\n this._processing = processing.promise;\n let continueHandling;\n // Call the end hook (most recently-added) first. Starting at the end also\n // guarantees that hooks added during the processing will not be run in\n // this process run.\n for (let i = this._hooks.length - 1; i >= 0; i--) {\n const hook = this._hooks[i];\n // If the hook has been removed, continue to the next one.\n if (hook === null) {\n continue;\n }\n // Execute the hook and log any errors.\n try {\n // tslint:disable-next-line:await-promise\n continueHandling = await hook(msg);\n }\n catch (err) {\n continueHandling = true;\n console.error(err);\n }\n // If the hook resolved to false, stop processing and return.\n if (continueHandling === false) {\n processing.resolve(undefined);\n return false;\n }\n }\n // All hooks returned true (or errored out), so return true.\n processing.resolve(undefined);\n return true;\n }\n /**\n * Schedule a cleanup of the list, removing any hooks that have been nulled out.\n */\n _scheduleCompact() {\n if (!this._compactScheduled) {\n this._compactScheduled = true;\n // Schedule a compaction in between processing runs. We do the\n // scheduling in an animation frame to rate-limit our compactions. If we\n // need to compact more frequently, we can change this to directly\n // schedule the compaction.\n defer(() => {\n this._processing = this._processing.then(() => {\n this._compactScheduled = false;\n this._compact();\n });\n });\n }\n }\n /**\n * Compact the list, removing any nulls.\n */\n _compact() {\n let numNulls = 0;\n for (let i = 0, len = this._hooks.length; i < len; i++) {\n const hook = this._hooks[i];\n if (this._hooks[i] === null) {\n numNulls++;\n }\n else {\n this._hooks[i - numNulls] = hook;\n }\n }\n this._hooks.length -= numNulls;\n }\n }\n Private.HookList = HookList;\n /**\n * Bit flags for the kernel future state.\n */\n let KernelFutureFlag;\n (function (KernelFutureFlag) {\n KernelFutureFlag[KernelFutureFlag[\"GotReply\"] = 1] = \"GotReply\";\n KernelFutureFlag[KernelFutureFlag[\"GotIdle\"] = 2] = \"GotIdle\";\n KernelFutureFlag[KernelFutureFlag[\"IsDone\"] = 4] = \"IsDone\";\n KernelFutureFlag[KernelFutureFlag[\"DisposeOnDone\"] = 8] = \"DisposeOnDone\";\n })(KernelFutureFlag = Private.KernelFutureFlag || (Private.KernelFutureFlag = {}));\n})(Private || (Private = {}));\n//# sourceMappingURL=future.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nvar __exportStar = (this && this.__exportStar) || function(m, exports) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.KernelConnection = exports.KernelAPI = exports.KernelMessage = exports.Kernel = void 0;\n// Namespace some of our modules for convenience and backwards compatibility.\nconst Kernel = __importStar(require(\"./kernel\"));\nexports.Kernel = Kernel;\nconst KernelMessage = __importStar(require(\"./messages\"));\nexports.KernelMessage = KernelMessage;\nconst KernelAPI = __importStar(require(\"./restapi\"));\nexports.KernelAPI = KernelAPI;\nconst default_1 = require(\"./default\");\nObject.defineProperty(exports, \"KernelConnection\", { enumerable: true, get: function () { return default_1.KernelConnection; } });\n__exportStar(require(\"./manager\"), exports);\n//# sourceMappingURL=index.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\n//# sourceMappingURL=kernel.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.KernelManager = void 0;\nconst polling_1 = require(\"@lumino/polling\");\nconst signaling_1 = require(\"@lumino/signaling\");\nconst __1 = require(\"..\");\nconst basemanager_1 = require(\"../basemanager\");\nconst restapi_1 = require(\"./restapi\");\nconst default_1 = require(\"./default\");\n/**\n * An implementation of a kernel manager.\n */\nclass KernelManager extends basemanager_1.BaseManager {\n /**\n * Construct a new kernel manager.\n *\n * @param options - The default options for kernel.\n */\n constructor(options = {}) {\n var _a;\n super(options);\n this._isReady = false;\n this._kernelConnections = new Set();\n this._models = new Map();\n this._runningChanged = new signaling_1.Signal(this);\n this._connectionFailure = new signaling_1.Signal(this);\n // Start model and specs polling with exponential backoff.\n this._pollModels = new polling_1.Poll({\n auto: false,\n factory: () => this.requestRunning(),\n frequency: {\n interval: 10 * 1000,\n backoff: true,\n max: 300 * 1000\n },\n name: `@jupyterlab/services:KernelManager#models`,\n standby: (_a = options.standby) !== null && _a !== void 0 ? _a : 'when-hidden'\n });\n // Initialize internal data.\n this._ready = (async () => {\n await this._pollModels.start();\n await this._pollModels.tick;\n this._isReady = true;\n })();\n }\n /**\n * Test whether the manager is ready.\n */\n get isReady() {\n return this._isReady;\n }\n /**\n * A promise that fulfills when the manager is ready.\n */\n get ready() {\n return this._ready;\n }\n /**\n * A signal emitted when the running kernels change.\n */\n get runningChanged() {\n return this._runningChanged;\n }\n /**\n * A signal emitted when there is a connection failure.\n */\n get connectionFailure() {\n return this._connectionFailure;\n }\n /**\n * Dispose of the resources used by the manager.\n */\n dispose() {\n if (this.isDisposed) {\n return;\n }\n this._models.clear();\n this._kernelConnections.forEach(x => x.dispose());\n this._pollModels.dispose();\n super.dispose();\n }\n /**\n * Connect to an existing kernel.\n *\n * @returns The new kernel connection.\n *\n * #### Notes\n * This will use the manager's server settings and ignore any server\n * settings passed in the options.\n */\n connectTo(options) {\n var _a;\n const { id } = options.model;\n let handleComms = (_a = options.handleComms) !== null && _a !== void 0 ? _a : true;\n // By default, handle comms only if no other kernel connection is.\n if (options.handleComms === undefined) {\n for (const kc of this._kernelConnections) {\n if (kc.id === id && kc.handleComms) {\n handleComms = false;\n break;\n }\n }\n }\n const kernelConnection = new default_1.KernelConnection({\n handleComms,\n ...options,\n serverSettings: this.serverSettings\n });\n this._onStarted(kernelConnection);\n if (!this._models.has(id)) {\n // We trust the user to connect to an existing kernel, but we verify\n // asynchronously.\n void this.refreshRunning().catch(() => {\n /* no-op */\n });\n }\n return kernelConnection;\n }\n /**\n * Create an iterator over the most recent running kernels.\n *\n * @returns A new iterator over the running kernels.\n */\n running() {\n return this._models.values();\n }\n /**\n * Force a refresh of the running kernels.\n *\n * @returns A promise that resolves when the running list has been refreshed.\n *\n * #### Notes\n * This is not typically meant to be called by the user, since the\n * manager maintains its own internal state.\n */\n async refreshRunning() {\n await this._pollModels.refresh();\n await this._pollModels.tick;\n }\n /**\n * Start a new kernel.\n *\n * @param createOptions - The kernel creation options\n *\n * @param connectOptions - The kernel connection options\n *\n * @returns A promise that resolves with the kernel connection.\n *\n * #### Notes\n * The manager `serverSettings` will be always be used.\n */\n async startNew(createOptions = {}, connectOptions = {}) {\n const model = await (0, restapi_1.startNew)(createOptions, this.serverSettings);\n return this.connectTo({\n ...connectOptions,\n model\n });\n }\n /**\n * Shut down a kernel by id.\n *\n * @param id - The id of the target kernel.\n *\n * @returns A promise that resolves when the operation is complete.\n */\n async shutdown(id) {\n await (0, restapi_1.shutdownKernel)(id, this.serverSettings);\n await this.refreshRunning();\n }\n /**\n * Shut down all kernels.\n *\n * @returns A promise that resolves when all of the kernels are shut down.\n */\n async shutdownAll() {\n // Update the list of models to make sure our list is current.\n await this.refreshRunning();\n // Shut down all models.\n await Promise.all([...this._models.keys()].map(id => (0, restapi_1.shutdownKernel)(id, this.serverSettings)));\n // Update the list of models to clear out our state.\n await this.refreshRunning();\n }\n /**\n * Find a kernel by id.\n *\n * @param id - The id of the target kernel.\n *\n * @returns A promise that resolves with the kernel's model.\n */\n async findById(id) {\n if (this._models.has(id)) {\n return this._models.get(id);\n }\n await this.refreshRunning();\n return this._models.get(id);\n }\n /**\n * Execute a request to the server to poll running kernels and update state.\n */\n async requestRunning() {\n var _a, _b;\n let models;\n try {\n models = await (0, restapi_1.listRunning)(this.serverSettings);\n }\n catch (err) {\n // Handle network errors, as well as cases where we are on a\n // JupyterHub and the server is not running. JupyterHub returns a\n // 503 (<2.0) or 424 (>2.0) in that case.\n if (err instanceof __1.ServerConnection.NetworkError ||\n ((_a = err.response) === null || _a === void 0 ? void 0 : _a.status) === 503 ||\n ((_b = err.response) === null || _b === void 0 ? void 0 : _b.status) === 424) {\n this._connectionFailure.emit(err);\n }\n throw err;\n }\n if (this.isDisposed) {\n return;\n }\n if (this._models.size === models.length &&\n models.every(model => {\n const existing = this._models.get(model.id);\n if (!existing) {\n return false;\n }\n return (existing.connections === model.connections &&\n existing.execution_state === model.execution_state &&\n existing.last_activity === model.last_activity &&\n existing.name === model.name &&\n existing.reason === model.reason &&\n existing.traceback === model.traceback);\n })) {\n // Identical models list (presuming models does not contain duplicate\n // ids), so just return\n return;\n }\n this._models = new Map(models.map(x => [x.id, x]));\n // For any kernel connection to a kernel that doesn't exist, notify it of\n // the shutdown.\n this._kernelConnections.forEach(kc => {\n if (!this._models.has(kc.id)) {\n kc.handleShutdown();\n }\n });\n this._runningChanged.emit(models);\n }\n /**\n * Handle a kernel starting.\n */\n _onStarted(kernelConnection) {\n this._kernelConnections.add(kernelConnection);\n kernelConnection.statusChanged.connect(this._onStatusChanged, this);\n kernelConnection.disposed.connect(this._onDisposed, this);\n }\n _onDisposed(kernelConnection) {\n this._kernelConnections.delete(kernelConnection);\n // A dispose emission could mean the server session is deleted, or that\n // the kernel JS object is disposed and the kernel still exists on the\n // server, so we refresh from the server to make sure we reflect the\n // server state.\n void this.refreshRunning().catch(() => {\n /* no-op */\n });\n }\n _onStatusChanged(kernelConnection, status) {\n if (status === 'dead') {\n // We asynchronously update our list of kernels, which asynchronously\n // will dispose them. We do not want to immediately dispose them because\n // there may be other signal handlers that want to be called.\n void this.refreshRunning().catch(() => {\n /* no-op */\n });\n }\n }\n}\nexports.KernelManager = KernelManager;\n/**\n * The namespace for `KernelManager` class statics.\n */\n(function (KernelManager) {\n /**\n * A no-op kernel manager to be used when starting kernels.\n */\n class NoopManager extends KernelManager {\n constructor() {\n super(...arguments);\n this._readyPromise = new Promise(() => {\n /* no-op */\n });\n }\n /**\n * Whether the manager is active.\n */\n get isActive() {\n return false;\n }\n /**\n * Used for testing.\n */\n get parentReady() {\n return super.ready;\n }\n /**\n * Start a new kernel - throws an error since it is not supported.\n */\n async startNew(createOptions = {}, connectOptions = {}) {\n return Promise.reject(new Error('Not implemented in no-op Kernel Manager'));\n }\n /**\n * Connect to an existing kernel - throws an error since it is not supported.\n */\n connectTo(options) {\n throw new Error('Not implemented in no-op Kernel Manager');\n }\n /**\n * Shut down a kernel by id - throws an error since it is not supported.\n */\n async shutdown(id) {\n return Promise.reject(new Error('Not implemented in no-op Kernel Manager'));\n }\n /**\n * A promise that fulfills when the manager is ready (never).\n */\n get ready() {\n return this.parentReady.then(() => this._readyPromise);\n }\n /**\n * Execute a request to the server to poll running kernels and update state.\n */\n async requestRunning() {\n return Promise.resolve();\n }\n }\n KernelManager.NoopManager = NoopManager;\n})(KernelManager = exports.KernelManager || (exports.KernelManager = {}));\n//# sourceMappingURL=manager.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.supportedKernelWebSocketProtocols = exports.isInputReplyMsg = exports.isInputRequestMsg = exports.isDebugReplyMsg = exports.isDebugRequestMsg = exports.isExecuteReplyMsg = exports.isInfoRequestMsg = exports.isCommMsgMsg = exports.isCommCloseMsg = exports.isCommOpenMsg = exports.isDebugEventMsg = exports.isClearOutputMsg = exports.isStatusMsg = exports.isErrorMsg = exports.isExecuteResultMsg = exports.isExecuteInputMsg = exports.isUpdateDisplayDataMsg = exports.isDisplayDataMsg = exports.isStreamMsg = exports.createMessage = void 0;\nconst coreutils_1 = require(\"@lumino/coreutils\");\nfunction createMessage(options) {\n var _a, _b, _c, _d, _e;\n return {\n buffers: (_a = options.buffers) !== null && _a !== void 0 ? _a : [],\n channel: options.channel,\n content: options.content,\n header: {\n date: new Date().toISOString(),\n msg_id: (_b = options.msgId) !== null && _b !== void 0 ? _b : coreutils_1.UUID.uuid4(),\n msg_type: options.msgType,\n session: options.session,\n username: (_c = options.username) !== null && _c !== void 0 ? _c : '',\n version: '5.2'\n },\n metadata: (_d = options.metadata) !== null && _d !== void 0 ? _d : {},\n parent_header: (_e = options.parentHeader) !== null && _e !== void 0 ? _e : {}\n };\n}\nexports.createMessage = createMessage;\n/**\n * Test whether a kernel message is a `'stream'` message.\n */\nfunction isStreamMsg(msg) {\n return msg.header.msg_type === 'stream';\n}\nexports.isStreamMsg = isStreamMsg;\n/**\n * Test whether a kernel message is an `'display_data'` message.\n */\nfunction isDisplayDataMsg(msg) {\n return msg.header.msg_type === 'display_data';\n}\nexports.isDisplayDataMsg = isDisplayDataMsg;\n/**\n * Test whether a kernel message is an `'update_display_data'` message.\n */\nfunction isUpdateDisplayDataMsg(msg) {\n return msg.header.msg_type === 'update_display_data';\n}\nexports.isUpdateDisplayDataMsg = isUpdateDisplayDataMsg;\n/**\n * Test whether a kernel message is an `'execute_input'` message.\n */\nfunction isExecuteInputMsg(msg) {\n return msg.header.msg_type === 'execute_input';\n}\nexports.isExecuteInputMsg = isExecuteInputMsg;\n/**\n * Test whether a kernel message is an `'execute_result'` message.\n */\nfunction isExecuteResultMsg(msg) {\n return msg.header.msg_type === 'execute_result';\n}\nexports.isExecuteResultMsg = isExecuteResultMsg;\n/**\n * Test whether a kernel message is an `'error'` message.\n */\nfunction isErrorMsg(msg) {\n return msg.header.msg_type === 'error';\n}\nexports.isErrorMsg = isErrorMsg;\n/**\n * Test whether a kernel message is a `'status'` message.\n */\nfunction isStatusMsg(msg) {\n return msg.header.msg_type === 'status';\n}\nexports.isStatusMsg = isStatusMsg;\n/**\n * Test whether a kernel message is a `'clear_output'` message.\n */\nfunction isClearOutputMsg(msg) {\n return msg.header.msg_type === 'clear_output';\n}\nexports.isClearOutputMsg = isClearOutputMsg;\n/**\n * Test whether a kernel message is an experimental `'debug_event'` message.\n *\n * @hidden\n *\n * #### Notes\n * Debug messages are experimental messages that are not in the official\n * kernel message specification. As such, this is *NOT* considered\n * part of the public API, and may change without notice.\n */\nfunction isDebugEventMsg(msg) {\n return msg.header.msg_type === 'debug_event';\n}\nexports.isDebugEventMsg = isDebugEventMsg;\n/**\n * Test whether a kernel message is a `'comm_open'` message.\n */\nfunction isCommOpenMsg(msg) {\n return msg.header.msg_type === 'comm_open';\n}\nexports.isCommOpenMsg = isCommOpenMsg;\n/**\n * Test whether a kernel message is a `'comm_close'` message.\n */\nfunction isCommCloseMsg(msg) {\n return msg.header.msg_type === 'comm_close';\n}\nexports.isCommCloseMsg = isCommCloseMsg;\n/**\n * Test whether a kernel message is a `'comm_msg'` message.\n */\nfunction isCommMsgMsg(msg) {\n return msg.header.msg_type === 'comm_msg';\n}\nexports.isCommMsgMsg = isCommMsgMsg;\n/**\n * Test whether a kernel message is a `'kernel_info_request'` message.\n */\nfunction isInfoRequestMsg(msg) {\n return msg.header.msg_type === 'kernel_info_request';\n}\nexports.isInfoRequestMsg = isInfoRequestMsg;\n/**\n * Test whether a kernel message is an `'execute_reply'` message.\n */\nfunction isExecuteReplyMsg(msg) {\n return msg.header.msg_type === 'execute_reply';\n}\nexports.isExecuteReplyMsg = isExecuteReplyMsg;\n/**\n * Test whether a kernel message is an experimental `'debug_request'` message.\n *\n * @hidden\n *\n * #### Notes\n * Debug messages are experimental messages that are not in the official\n * kernel message specification. As such, this is *NOT* considered\n * part of the public API, and may change without notice.\n */\nfunction isDebugRequestMsg(msg) {\n return msg.header.msg_type === 'debug_request';\n}\nexports.isDebugRequestMsg = isDebugRequestMsg;\n/**\n * Test whether a kernel message is an experimental `'debug_reply'` message.\n *\n * @hidden\n *\n * #### Notes\n * Debug messages are experimental messages that are not in the official\n * kernel message specification. As such, this is *NOT* considered\n * part of the public API, and may change without notice.\n */\nfunction isDebugReplyMsg(msg) {\n return msg.header.msg_type === 'debug_reply';\n}\nexports.isDebugReplyMsg = isDebugReplyMsg;\n/**\n * Test whether a kernel message is an `'input_request'` message.\n */\nfunction isInputRequestMsg(msg) {\n return msg.header.msg_type === 'input_request';\n}\nexports.isInputRequestMsg = isInputRequestMsg;\n/**\n * Test whether a kernel message is an `'input_reply'` message.\n */\nfunction isInputReplyMsg(msg) {\n return msg.header.msg_type === 'input_reply';\n}\nexports.isInputReplyMsg = isInputReplyMsg;\n// ///////////////////////////////////////////////\n// Message (de)serialization\n// ///////////////////////////////////////////////\n/**\n * The list of supported kernel wire protocols over websocket.\n */\nvar supportedKernelWebSocketProtocols;\n(function (supportedKernelWebSocketProtocols) {\n supportedKernelWebSocketProtocols[\"v1KernelWebsocketJupyterOrg\"] = \"v1.kernel.websocket.jupyter.org\";\n})(supportedKernelWebSocketProtocols = exports.supportedKernelWebSocketProtocols || (exports.supportedKernelWebSocketProtocols = {}));\n//# sourceMappingURL=messages.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.getKernelModel = exports.shutdownKernel = exports.interruptKernel = exports.restartKernel = exports.startNew = exports.listRunning = exports.KERNEL_SERVICE_URL = void 0;\nconst serverconnection_1 = require(\"../serverconnection\");\nconst coreutils_1 = require(\"@jupyterlab/coreutils\");\nconst validate_1 = require(\"./validate\");\n/**\n * The url for the kernel service.\n */\nexports.KERNEL_SERVICE_URL = 'api/kernels';\n/**\n * Fetch the running kernels.\n *\n * @param settings - The optional server settings.\n *\n * @returns A promise that resolves with the list of running kernels.\n *\n * #### Notes\n * Uses the [Jupyter Notebook API](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter-server/jupyter_server/main/jupyter_server/services/api/api.yaml#!/kernels) and validates the response model.\n *\n * The promise is fulfilled on a valid response and rejected otherwise.\n */\nasync function listRunning(settings = serverconnection_1.ServerConnection.makeSettings()) {\n const url = coreutils_1.URLExt.join(settings.baseUrl, exports.KERNEL_SERVICE_URL);\n const response = await serverconnection_1.ServerConnection.makeRequest(url, {}, settings);\n if (response.status !== 200) {\n const err = await serverconnection_1.ServerConnection.ResponseError.create(response);\n throw err;\n }\n const data = await response.json();\n (0, validate_1.validateModels)(data);\n return data;\n}\nexports.listRunning = listRunning;\n/**\n * Start a new kernel.\n *\n * @param options - The options used to create the kernel.\n *\n * @returns A promise that resolves with a kernel connection object.\n *\n * #### Notes\n * Uses the [Jupyter Notebook API](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter-server/jupyter_server/main/jupyter_server/services/api/api.yaml#!/kernels) and validates the response model.\n *\n * The promise is fulfilled on a valid response and rejected otherwise.\n */\nasync function startNew(options = {}, settings = serverconnection_1.ServerConnection.makeSettings()) {\n const url = coreutils_1.URLExt.join(settings.baseUrl, exports.KERNEL_SERVICE_URL);\n const init = {\n method: 'POST',\n body: JSON.stringify(options)\n };\n const response = await serverconnection_1.ServerConnection.makeRequest(url, init, settings);\n if (response.status !== 201) {\n const err = await serverconnection_1.ServerConnection.ResponseError.create(response);\n throw err;\n }\n const data = await response.json();\n (0, validate_1.validateModel)(data);\n return data;\n}\nexports.startNew = startNew;\n/**\n * Restart a kernel.\n *\n * #### Notes\n * Uses the [Jupyter Notebook API](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter-server/jupyter_server/main/jupyter_server/services/api/api.yaml#!/kernels) and validates the response model.\n *\n * The promise is fulfilled on a valid response (and thus after a restart) and rejected otherwise.\n */\nasync function restartKernel(id, settings = serverconnection_1.ServerConnection.makeSettings()) {\n const url = coreutils_1.URLExt.join(settings.baseUrl, exports.KERNEL_SERVICE_URL, encodeURIComponent(id), 'restart');\n const init = { method: 'POST' };\n const response = await serverconnection_1.ServerConnection.makeRequest(url, init, settings);\n if (response.status !== 200) {\n const err = await serverconnection_1.ServerConnection.ResponseError.create(response);\n throw err;\n }\n const data = await response.json();\n (0, validate_1.validateModel)(data);\n}\nexports.restartKernel = restartKernel;\n/**\n * Interrupt a kernel.\n *\n * #### Notes\n * Uses the [Jupyter Notebook API](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter-server/jupyter_server/main/jupyter_server/services/api/api.yaml#!/kernels) and validates the response model.\n *\n * The promise is fulfilled on a valid response and rejected otherwise.\n */\nasync function interruptKernel(id, settings = serverconnection_1.ServerConnection.makeSettings()) {\n const url = coreutils_1.URLExt.join(settings.baseUrl, exports.KERNEL_SERVICE_URL, encodeURIComponent(id), 'interrupt');\n const init = { method: 'POST' };\n const response = await serverconnection_1.ServerConnection.makeRequest(url, init, settings);\n if (response.status !== 204) {\n const err = await serverconnection_1.ServerConnection.ResponseError.create(response);\n throw err;\n }\n}\nexports.interruptKernel = interruptKernel;\n/**\n * Shut down a kernel.\n *\n * @param id - The id of the running kernel.\n *\n * @param settings - The server settings for the request.\n *\n * @returns A promise that resolves when the kernel is shut down.\n *\n *\n * #### Notes\n * Uses the [Jupyter Notebook API](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter-server/jupyter_server/main/jupyter_server/services/api/api.yaml#!/kernels) and validates the response model.\n *\n * The promise is fulfilled on a valid response and rejected otherwise.\n */\nasync function shutdownKernel(id, settings = serverconnection_1.ServerConnection.makeSettings()) {\n const url = coreutils_1.URLExt.join(settings.baseUrl, exports.KERNEL_SERVICE_URL, encodeURIComponent(id));\n const init = { method: 'DELETE' };\n const response = await serverconnection_1.ServerConnection.makeRequest(url, init, settings);\n if (response.status === 404) {\n const msg = `The kernel \"${id}\" does not exist on the server`;\n console.warn(msg);\n }\n else if (response.status !== 204) {\n const err = await serverconnection_1.ServerConnection.ResponseError.create(response);\n throw err;\n }\n}\nexports.shutdownKernel = shutdownKernel;\n/**\n * Get a full kernel model from the server by kernel id string.\n *\n * #### Notes\n * Uses the [Jupyter Notebook API](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter-server/jupyter_server/main/jupyter_server/services/api/api.yaml#!/kernels) and validates the response model.\n *\n * The promise is fulfilled on a valid response and rejected otherwise.\n */\nasync function getKernelModel(id, settings = serverconnection_1.ServerConnection.makeSettings()) {\n const url = coreutils_1.URLExt.join(settings.baseUrl, exports.KERNEL_SERVICE_URL, encodeURIComponent(id));\n const response = await serverconnection_1.ServerConnection.makeRequest(url, {}, settings);\n if (response.status === 404) {\n return undefined;\n }\n else if (response.status !== 200) {\n const err = await serverconnection_1.ServerConnection.ResponseError.create(response);\n throw err;\n }\n const data = await response.json();\n (0, validate_1.validateModel)(data);\n return data;\n}\nexports.getKernelModel = getKernelModel;\n//# sourceMappingURL=restapi.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.deserialize = exports.serialize = void 0;\nconst KernelMessage = __importStar(require(\"./messages\"));\n/**\n * Serialize a kernel message for transport.\n */\nfunction serialize(msg, protocol = '') {\n switch (protocol) {\n case KernelMessage.supportedKernelWebSocketProtocols\n .v1KernelWebsocketJupyterOrg:\n return Private.serializeV1KernelWebsocketJupyterOrg(msg);\n default:\n return Private.serializeDefault(msg);\n }\n}\nexports.serialize = serialize;\n/**\n * Deserialize and return the unpacked message.\n */\nfunction deserialize(data, protocol = '') {\n switch (protocol) {\n case KernelMessage.supportedKernelWebSocketProtocols\n .v1KernelWebsocketJupyterOrg:\n return Private.deserializeV1KernelWebsocketJupyterOrg(data);\n default:\n return Private.deserializeDefault(data);\n }\n}\nexports.deserialize = deserialize;\nvar Private;\n(function (Private) {\n /**\n * Deserialize and return the unpacked message.\n * Protocol `v1.kernel.websocket.jupyter.org`\n */\n function deserializeV1KernelWebsocketJupyterOrg(binMsg) {\n let msg;\n const data = new DataView(binMsg);\n const offsetNumber = Number(data.getBigUint64(0, true /* littleEndian */));\n let offsets = [];\n for (let i = 0; i < offsetNumber; i++) {\n // WARNING: we cast our 64-bit unsigned int to a number!\n // so offsets cannot index up to 2**64 bytes\n offsets.push(Number(data.getBigUint64(8 * (i + 1), true /* littleEndian */)));\n }\n const decoder = new TextDecoder('utf8');\n const channel = decoder.decode(binMsg.slice(offsets[0], offsets[1]));\n const header = JSON.parse(decoder.decode(binMsg.slice(offsets[1], offsets[2])));\n const parent_header = JSON.parse(decoder.decode(binMsg.slice(offsets[2], offsets[3])));\n const metadata = JSON.parse(decoder.decode(binMsg.slice(offsets[3], offsets[4])));\n const content = JSON.parse(decoder.decode(binMsg.slice(offsets[4], offsets[5])));\n let buffers = [];\n for (let i = 5; i < offsets.length - 1; i++) {\n buffers.push(new DataView(binMsg.slice(offsets[i], offsets[i + 1])));\n }\n msg = {\n channel,\n header,\n parent_header,\n metadata,\n content,\n buffers\n };\n return msg;\n }\n Private.deserializeV1KernelWebsocketJupyterOrg = deserializeV1KernelWebsocketJupyterOrg;\n /**\n * Serialize a kernel message for transport.\n * Protocol `v1.kernel.websocket.jupyter.org`\n */\n function serializeV1KernelWebsocketJupyterOrg(msg) {\n const header = JSON.stringify(msg.header);\n const parentHeader = msg.parent_header == null ? '{}' : JSON.stringify(msg.parent_header);\n const metadata = JSON.stringify(msg.metadata);\n const content = JSON.stringify(msg.content);\n const buffers = msg.buffers !== undefined ? msg.buffers : [];\n const offsetNumber = 1 + 4 + buffers.length + 1;\n let offsets = [];\n offsets.push(8 * (1 + offsetNumber));\n offsets.push(msg.channel.length + offsets[offsets.length - 1]);\n const encoder = new TextEncoder();\n const channelEncoded = encoder.encode(msg.channel);\n const headerEncoded = encoder.encode(header);\n const parentHeaderEncoded = encoder.encode(parentHeader);\n const metadataEncoded = encoder.encode(metadata);\n const contentEncoded = encoder.encode(content);\n const binMsgNoBuff = new Uint8Array(channelEncoded.length +\n headerEncoded.length +\n parentHeaderEncoded.length +\n metadataEncoded.length +\n contentEncoded.length);\n binMsgNoBuff.set(channelEncoded);\n binMsgNoBuff.set(headerEncoded, channelEncoded.length);\n binMsgNoBuff.set(parentHeaderEncoded, channelEncoded.length + headerEncoded.length);\n binMsgNoBuff.set(metadataEncoded, channelEncoded.length + headerEncoded.length + parentHeaderEncoded.length);\n binMsgNoBuff.set(contentEncoded, channelEncoded.length +\n headerEncoded.length +\n parentHeaderEncoded.length +\n metadataEncoded.length);\n for (let length of [\n headerEncoded.length,\n parentHeaderEncoded.length,\n metadataEncoded.length,\n contentEncoded.length\n ]) {\n offsets.push(length + offsets[offsets.length - 1]);\n }\n let buffersByteLength = 0;\n for (let buffer of buffers) {\n let length = buffer.byteLength;\n offsets.push(length + offsets[offsets.length - 1]);\n buffersByteLength += length;\n }\n const binMsg = new Uint8Array(8 * (1 + offsetNumber) + binMsgNoBuff.byteLength + buffersByteLength);\n const word = new ArrayBuffer(8);\n const data = new DataView(word);\n data.setBigUint64(0, BigInt(offsetNumber), true /* littleEndian */);\n binMsg.set(new Uint8Array(word), 0);\n for (let i = 0; i < offsets.length; i++) {\n data.setBigUint64(0, BigInt(offsets[i]), true /* littleEndian */);\n binMsg.set(new Uint8Array(word), 8 * (i + 1));\n }\n binMsg.set(binMsgNoBuff, offsets[0]);\n for (let i = 0; i < buffers.length; i++) {\n const buffer = buffers[i];\n binMsg.set(new Uint8Array(ArrayBuffer.isView(buffer) ? buffer.buffer : buffer), offsets[5 + i]);\n }\n return binMsg.buffer;\n }\n Private.serializeV1KernelWebsocketJupyterOrg = serializeV1KernelWebsocketJupyterOrg;\n /**\n * Deserialize and return the unpacked message.\n * Default protocol\n *\n * #### Notes\n * Handles JSON blob strings and binary messages.\n */\n function deserializeDefault(data) {\n let value;\n if (typeof data === 'string') {\n value = JSON.parse(data);\n }\n else {\n value = deserializeBinary(data);\n }\n return value;\n }\n Private.deserializeDefault = deserializeDefault;\n /**\n * Serialize a kernel message for transport.\n * Default protocol\n *\n * #### Notes\n * If there is binary content, an `ArrayBuffer` is returned,\n * otherwise the message is converted to a JSON string.\n */\n function serializeDefault(msg) {\n var _a;\n let value;\n if ((_a = msg.buffers) === null || _a === void 0 ? void 0 : _a.length) {\n value = serializeBinary(msg);\n }\n else {\n value = JSON.stringify(msg);\n }\n return value;\n }\n Private.serializeDefault = serializeDefault;\n /**\n * Deserialize a binary message to a Kernel Message.\n */\n function deserializeBinary(buf) {\n const data = new DataView(buf);\n // read the header: 1 + nbufs 32b integers\n const nbufs = data.getUint32(0);\n const offsets = [];\n if (nbufs < 2) {\n throw new Error('Invalid incoming Kernel Message');\n }\n for (let i = 1; i <= nbufs; i++) {\n offsets.push(data.getUint32(i * 4));\n }\n const jsonBytes = new Uint8Array(buf.slice(offsets[0], offsets[1]));\n const msg = JSON.parse(new TextDecoder('utf8').decode(jsonBytes));\n // the remaining chunks are stored as DataViews in msg.buffers\n msg.buffers = [];\n for (let i = 1; i < nbufs; i++) {\n const start = offsets[i];\n const stop = offsets[i + 1] || buf.byteLength;\n msg.buffers.push(new DataView(buf.slice(start, stop)));\n }\n return msg;\n }\n /**\n * Implement the binary serialization protocol.\n *\n * Serialize Kernel message to ArrayBuffer.\n */\n function serializeBinary(msg) {\n const offsets = [];\n const buffers = [];\n const encoder = new TextEncoder();\n let origBuffers = [];\n if (msg.buffers !== undefined) {\n origBuffers = msg.buffers;\n delete msg['buffers'];\n }\n const jsonUtf8 = encoder.encode(JSON.stringify(msg));\n buffers.push(jsonUtf8.buffer);\n for (let i = 0; i < origBuffers.length; i++) {\n // msg.buffers elements could be either views or ArrayBuffers\n // buffers elements are ArrayBuffers\n const b = origBuffers[i];\n buffers.push(ArrayBuffer.isView(b) ? b.buffer : b);\n }\n const nbufs = buffers.length;\n offsets.push(4 * (nbufs + 1));\n for (let i = 0; i + 1 < buffers.length; i++) {\n offsets.push(offsets[offsets.length - 1] + buffers[i].byteLength);\n }\n const msgBuf = new Uint8Array(offsets[offsets.length - 1] + buffers[buffers.length - 1].byteLength);\n // use DataView.setUint32 for network byte-order\n const view = new DataView(msgBuf.buffer);\n // write nbufs to first 4 bytes\n view.setUint32(0, nbufs);\n // write offsets to next 4 * nbufs bytes\n for (let i = 0; i < offsets.length; i++) {\n view.setUint32(4 * (i + 1), offsets[i]);\n }\n // write all the buffers at their respective offsets\n for (let i = 0; i < buffers.length; i++) {\n msgBuf.set(new Uint8Array(buffers[i]), offsets[i]);\n }\n return msgBuf.buffer;\n }\n})(Private || (Private = {}));\n//# sourceMappingURL=serialize.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.validateModels = exports.validateModel = exports.validateMessage = void 0;\nconst validate_1 = require(\"../validate\");\n/**\n * Required fields for `IKernelHeader`.\n */\nconst HEADER_FIELDS = ['username', 'version', 'session', 'msg_id', 'msg_type'];\n/**\n * Required fields and types for contents of various types of `kernel.IMessage`\n * messages on the iopub channel.\n */\nconst IOPUB_CONTENT_FIELDS = {\n stream: { name: 'string', text: 'string' },\n display_data: { data: 'object', metadata: 'object' },\n execute_input: { code: 'string', execution_count: 'number' },\n execute_result: {\n execution_count: 'number',\n data: 'object',\n metadata: 'object'\n },\n error: { ename: 'string', evalue: 'string', traceback: 'object' },\n status: {\n execution_state: [\n 'string',\n ['starting', 'idle', 'busy', 'restarting', 'dead']\n ]\n },\n clear_output: { wait: 'boolean' },\n comm_open: { comm_id: 'string', target_name: 'string', data: 'object' },\n comm_msg: { comm_id: 'string', data: 'object' },\n comm_close: { comm_id: 'string' },\n shutdown_reply: { restart: 'boolean' } // Emitted by the IPython kernel.\n};\n/**\n * Validate the header of a kernel message.\n */\nfunction validateHeader(header) {\n for (let i = 0; i < HEADER_FIELDS.length; i++) {\n (0, validate_1.validateProperty)(header, HEADER_FIELDS[i], 'string');\n }\n}\n/**\n * Validate a kernel message object.\n */\nfunction validateMessage(msg) {\n (0, validate_1.validateProperty)(msg, 'metadata', 'object');\n (0, validate_1.validateProperty)(msg, 'content', 'object');\n (0, validate_1.validateProperty)(msg, 'channel', 'string');\n validateHeader(msg.header);\n if (msg.channel === 'iopub') {\n validateIOPubContent(msg);\n }\n}\nexports.validateMessage = validateMessage;\n/**\n * Validate content an kernel message on the iopub channel.\n */\nfunction validateIOPubContent(msg) {\n if (msg.channel === 'iopub') {\n const fields = IOPUB_CONTENT_FIELDS[msg.header.msg_type];\n // Check for unknown message type.\n if (fields === undefined) {\n return;\n }\n const names = Object.keys(fields);\n const content = msg.content;\n for (let i = 0; i < names.length; i++) {\n let args = fields[names[i]];\n if (!Array.isArray(args)) {\n args = [args];\n }\n (0, validate_1.validateProperty)(content, names[i], ...args);\n }\n }\n}\n/**\n * Validate a `Kernel.IModel` object.\n */\nfunction validateModel(model) {\n (0, validate_1.validateProperty)(model, 'name', 'string');\n (0, validate_1.validateProperty)(model, 'id', 'string');\n}\nexports.validateModel = validateModel;\n/**\n * Validate an array of `IModel` objects.\n */\nfunction validateModels(models) {\n if (!Array.isArray(models)) {\n throw new Error('Invalid kernel list');\n }\n models.forEach(d => validateModel(d));\n}\nexports.validateModels = validateModels;\n//# sourceMappingURL=validate.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nvar __exportStar = (this && this.__exportStar) || function(m, exports) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.KernelSpecAPI = exports.KernelSpec = void 0;\nconst KernelSpec = __importStar(require(\"./kernelspec\"));\nexports.KernelSpec = KernelSpec;\nconst KernelSpecAPI = __importStar(require(\"./restapi\"));\nexports.KernelSpecAPI = KernelSpecAPI;\n__exportStar(require(\"./manager\"), exports);\n//# sourceMappingURL=index.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\n//# sourceMappingURL=kernelspec.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.KernelSpecManager = void 0;\nconst coreutils_1 = require(\"@lumino/coreutils\");\nconst polling_1 = require(\"@lumino/polling\");\nconst signaling_1 = require(\"@lumino/signaling\");\nconst restapi = __importStar(require(\"./restapi\"));\nconst basemanager_1 = require(\"../basemanager\");\n/**\n * An implementation of a kernel spec manager.\n */\nclass KernelSpecManager extends basemanager_1.BaseManager {\n /**\n * Construct a new kernel spec manager.\n *\n * @param options - The default options for kernel.\n */\n constructor(options = {}) {\n var _a;\n super(options);\n this._isReady = false;\n this._connectionFailure = new signaling_1.Signal(this);\n this._specs = null;\n this._specsChanged = new signaling_1.Signal(this);\n // Initialize internal data.\n this._ready = Promise.all([this.requestSpecs()])\n .then(_ => undefined)\n .catch(_ => undefined)\n .then(() => {\n if (this.isDisposed) {\n return;\n }\n this._isReady = true;\n });\n this._pollSpecs = new polling_1.Poll({\n auto: false,\n factory: () => this.requestSpecs(),\n frequency: {\n interval: 61 * 1000,\n backoff: true,\n max: 300 * 1000\n },\n name: `@jupyterlab/services:KernelSpecManager#specs`,\n standby: (_a = options.standby) !== null && _a !== void 0 ? _a : 'when-hidden'\n });\n void this.ready.then(() => {\n void this._pollSpecs.start();\n });\n }\n /**\n * Test whether the manager is ready.\n */\n get isReady() {\n return this._isReady;\n }\n /**\n * A promise that fulfills when the manager is ready.\n */\n get ready() {\n return this._ready;\n }\n /**\n * Get the most recently fetched kernel specs.\n */\n get specs() {\n return this._specs;\n }\n /**\n * A signal emitted when the specs change.\n */\n get specsChanged() {\n return this._specsChanged;\n }\n /**\n * A signal emitted when there is a connection failure.\n */\n get connectionFailure() {\n return this._connectionFailure;\n }\n /**\n * Dispose of the resources used by the manager.\n */\n dispose() {\n this._pollSpecs.dispose();\n super.dispose();\n }\n /**\n * Force a refresh of the specs from the server.\n *\n * @returns A promise that resolves when the specs are fetched.\n *\n * #### Notes\n * This is intended to be called only in response to a user action,\n * since the manager maintains its internal state.\n */\n async refreshSpecs() {\n await this._pollSpecs.refresh();\n await this._pollSpecs.tick;\n }\n /**\n * Execute a request to the server to poll specs and update state.\n */\n async requestSpecs() {\n const specs = await restapi.getSpecs(this.serverSettings);\n if (this.isDisposed) {\n return;\n }\n if (!coreutils_1.JSONExt.deepEqual(specs, this._specs)) {\n this._specs = specs;\n this._specsChanged.emit(specs);\n }\n }\n}\nexports.KernelSpecManager = KernelSpecManager;\n//# sourceMappingURL=manager.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.getSpecs = void 0;\nconst serverconnection_1 = require(\"../serverconnection\");\nconst validate_1 = require(\"./validate\");\nconst coreutils_1 = require(\"@jupyterlab/coreutils\");\n/**\n * The url for the kernelspec service.\n */\nconst KERNELSPEC_SERVICE_URL = 'api/kernelspecs';\n/**\n * Fetch all of the kernel specs.\n *\n * @param settings - The optional server settings.\n * @param useCache - Whether to use the cache. If false, always request.\n *\n * @returns A promise that resolves with the kernel specs.\n *\n * #### Notes\n * Uses the [Jupyter Notebook API](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter-server/jupyter_server/main/jupyter_server/services/api/api.yaml#!/kernelspecs).\n */\nasync function getSpecs(settings = serverconnection_1.ServerConnection.makeSettings()) {\n const url = coreutils_1.URLExt.join(settings.baseUrl, KERNELSPEC_SERVICE_URL);\n const response = await serverconnection_1.ServerConnection.makeRequest(url, {}, settings);\n if (response.status !== 200) {\n const err = await serverconnection_1.ServerConnection.ResponseError.create(response);\n throw err;\n }\n const data = await response.json();\n return (0, validate_1.validateSpecModels)(data);\n}\nexports.getSpecs = getSpecs;\n//# sourceMappingURL=restapi.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.validateSpecModels = exports.validateSpecModel = void 0;\nconst validate_1 = require(\"../validate\");\n/**\n * Validate a server kernelspec model to a client side model.\n */\n// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\nfunction validateSpecModel(data) {\n const spec = data.spec;\n if (!spec) {\n throw new Error('Invalid kernel spec');\n }\n (0, validate_1.validateProperty)(data, 'name', 'string');\n (0, validate_1.validateProperty)(data, 'resources', 'object');\n (0, validate_1.validateProperty)(spec, 'language', 'string');\n (0, validate_1.validateProperty)(spec, 'display_name', 'string');\n (0, validate_1.validateProperty)(spec, 'argv', 'array');\n let metadata = null;\n if (spec.hasOwnProperty('metadata')) {\n (0, validate_1.validateProperty)(spec, 'metadata', 'object');\n metadata = spec.metadata;\n }\n let env = null;\n if (spec.hasOwnProperty('env')) {\n (0, validate_1.validateProperty)(spec, 'env', 'object');\n env = spec.env;\n }\n return {\n name: data.name,\n resources: data.resources,\n language: spec.language,\n display_name: spec.display_name,\n argv: spec.argv,\n metadata,\n env\n };\n}\nexports.validateSpecModel = validateSpecModel;\n/**\n * Validate a `Kernel.ISpecModels` object.\n */\n// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\nfunction validateSpecModels(data) {\n if (!data.hasOwnProperty('kernelspecs')) {\n throw new Error('No kernelspecs found');\n }\n let keys = Object.keys(data.kernelspecs);\n const kernelspecs = Object.create(null);\n let defaultSpec = data.default;\n for (let i = 0; i < keys.length; i++) {\n const ks = data.kernelspecs[keys[i]];\n try {\n kernelspecs[keys[i]] = validateSpecModel(ks);\n }\n catch (err) {\n // Remove the errant kernel spec.\n console.warn(`Removing errant kernel spec: ${keys[i]}`);\n }\n }\n keys = Object.keys(kernelspecs);\n if (!keys.length) {\n throw new Error('No valid kernelspecs found');\n }\n if (!defaultSpec ||\n typeof defaultSpec !== 'string' ||\n !(defaultSpec in kernelspecs)) {\n defaultSpec = keys[0];\n console.warn(`Default kernel not found, using '${keys[0]}'`);\n }\n return {\n default: defaultSpec,\n kernelspecs\n };\n}\nexports.validateSpecModels = validateSpecModels;\n//# sourceMappingURL=validate.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.ServiceManager = void 0;\nconst signaling_1 = require(\"@lumino/signaling\");\nconst builder_1 = require(\"./builder\");\nconst contents_1 = require(\"./contents\");\nconst event_1 = require(\"./event\");\nconst kernel_1 = require(\"./kernel\");\nconst kernelspec_1 = require(\"./kernelspec\");\nconst nbconvert_1 = require(\"./nbconvert\");\nconst serverconnection_1 = require(\"./serverconnection\");\nconst session_1 = require(\"./session\");\nconst setting_1 = require(\"./setting\");\nconst terminal_1 = require(\"./terminal\");\nconst user_1 = require(\"./user\");\nconst workspace_1 = require(\"./workspace\");\n/**\n * A Jupyter services manager.\n */\nclass ServiceManager {\n /**\n * Construct a new services provider.\n */\n constructor(options = {}) {\n var _a, _b;\n this._isDisposed = false;\n this._connectionFailure = new signaling_1.Signal(this);\n this._isReady = false;\n const defaultDrive = options.defaultDrive;\n const serverSettings = (_a = options.serverSettings) !== null && _a !== void 0 ? _a : serverconnection_1.ServerConnection.makeSettings();\n const standby = (_b = options.standby) !== null && _b !== void 0 ? _b : 'when-hidden';\n const normalized = { defaultDrive, serverSettings, standby };\n this.serverSettings = serverSettings;\n this.contents = options.contents || new contents_1.ContentsManager(normalized);\n this.events = options.events || new event_1.EventManager(normalized);\n this.kernels = options.kernels || new kernel_1.KernelManager(normalized);\n this.sessions =\n options.sessions ||\n new session_1.SessionManager({\n ...normalized,\n kernelManager: this.kernels\n });\n this.settings = options.settings || new setting_1.SettingManager(normalized);\n this.terminals = options.terminals || new terminal_1.TerminalManager(normalized);\n this.builder = options.builder || new builder_1.BuildManager(normalized);\n this.workspaces = options.workspaces || new workspace_1.WorkspaceManager(normalized);\n this.nbconvert = options.nbconvert || new nbconvert_1.NbConvertManager(normalized);\n this.kernelspecs = options.kernelspecs || new kernelspec_1.KernelSpecManager(normalized);\n this.user = options.user || new user_1.UserManager(normalized);\n // Proxy all connection failures from the individual service managers.\n this.kernelspecs.connectionFailure.connect(this._onConnectionFailure, this);\n this.sessions.connectionFailure.connect(this._onConnectionFailure, this);\n this.terminals.connectionFailure.connect(this._onConnectionFailure, this);\n // Define promises that need to be resolved before service manager is ready.\n const readyList = [this.sessions.ready, this.kernelspecs.ready];\n if (this.terminals.isAvailable()) {\n readyList.push(this.terminals.ready);\n }\n this._readyPromise = Promise.all(readyList).then(() => {\n this._isReady = true;\n });\n }\n /**\n * A signal emitted when there is a connection failure with the kernel.\n */\n get connectionFailure() {\n return this._connectionFailure;\n }\n /**\n * Test whether the service manager is disposed.\n */\n get isDisposed() {\n return this._isDisposed;\n }\n /**\n * Dispose of the resources used by the manager.\n */\n dispose() {\n if (this.isDisposed) {\n return;\n }\n this._isDisposed = true;\n signaling_1.Signal.clearData(this);\n this.contents.dispose();\n this.events.dispose();\n this.sessions.dispose();\n this.terminals.dispose();\n }\n /**\n * Test whether the manager is ready.\n */\n get isReady() {\n return this._isReady;\n }\n /**\n * A promise that fulfills when the manager is ready.\n */\n get ready() {\n return this._readyPromise;\n }\n _onConnectionFailure(sender, err) {\n this._connectionFailure.emit(err);\n }\n}\nexports.ServiceManager = ServiceManager;\n//# sourceMappingURL=manager.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.NbConvertManager = void 0;\nconst coreutils_1 = require(\"@jupyterlab/coreutils\");\nconst serverconnection_1 = require(\"../serverconnection\");\nconst coreutils_2 = require(\"@lumino/coreutils\");\n/**\n * The url for the lab nbconvert service.\n */\nconst NBCONVERT_SETTINGS_URL = 'api/nbconvert';\n/**\n * The nbconvert API service manager.\n */\nclass NbConvertManager {\n /**\n * Create a new nbconvert manager.\n */\n constructor(options = {}) {\n var _a;\n this._exportFormats = null;\n this.serverSettings =\n (_a = options.serverSettings) !== null && _a !== void 0 ? _a : serverconnection_1.ServerConnection.makeSettings();\n }\n /**\n * Fetch and cache the export formats from the expensive nbconvert handler.\n */\n async fetchExportFormats() {\n this._requestingFormats = new coreutils_2.PromiseDelegate();\n this._exportFormats = null;\n const base = this.serverSettings.baseUrl;\n const url = coreutils_1.URLExt.join(base, NBCONVERT_SETTINGS_URL);\n const { serverSettings } = this;\n const response = await serverconnection_1.ServerConnection.makeRequest(url, {}, serverSettings);\n if (response.status !== 200) {\n const err = await serverconnection_1.ServerConnection.ResponseError.create(response);\n throw err;\n }\n const data = await response.json();\n const exportList = {};\n const keys = Object.keys(data);\n keys.forEach(function (key) {\n const mimeType = data[key].output_mimetype;\n exportList[key] = { output_mimetype: mimeType };\n });\n this._exportFormats = exportList;\n this._requestingFormats.resolve(exportList);\n return exportList;\n }\n /**\n * Get the list of export formats, preferring pre-cached ones.\n */\n async getExportFormats(force = true) {\n if (this._requestingFormats) {\n return this._requestingFormats.promise;\n }\n if (force || !this._exportFormats) {\n return await this.fetchExportFormats();\n }\n return this._exportFormats;\n }\n}\nexports.NbConvertManager = NbConvertManager;\n//# sourceMappingURL=index.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.ServerConnection = void 0;\nconst coreutils_1 = require(\"@jupyterlab/coreutils\");\nlet WEBSOCKET;\nif (typeof window === 'undefined') {\n // Mangle the require statements so it does not get picked up in the\n // browser assets.\n WEBSOCKET = require('ws');\n}\nelse {\n WEBSOCKET = WebSocket;\n}\n/**\n * The namespace for ServerConnection functions.\n *\n * #### Notes\n * This is only intended to manage communication with the Jupyter server.\n *\n * The default values can be used in a JupyterLab or Jupyter Notebook context.\n *\n * We use `token` authentication if available, falling back on an XSRF\n * cookie if one has been provided on the `document`.\n *\n * A content type of `'application/json'` is added when using authentication\n * and there is no body data to allow the server to prevent malicious forms.\n */\nvar ServerConnection;\n(function (ServerConnection) {\n /**\n * Create a settings object given a subset of options.\n *\n * @param options - An optional partial set of options.\n *\n * @returns The full settings object.\n */\n function makeSettings(options) {\n return Private.makeSettings(options);\n }\n ServerConnection.makeSettings = makeSettings;\n /**\n * Make an request to the notebook server.\n *\n * @param url - The url for the request.\n *\n * @param init - The initialization options for the request.\n *\n * @param settings - The server settings to apply to the request.\n *\n * @returns a Promise that resolves with the response.\n *\n * @throws If the url of the request is not a notebook server url.\n *\n * #### Notes\n * The `url` must start with `settings.baseUrl`. The `init` settings are\n * merged with `settings.init`, with `init` taking precedence.\n * The headers in the two objects are not merged.\n * If there is no body data, we set the content type to `application/json`\n * because it is required by the Notebook server.\n */\n function makeRequest(url, init, settings) {\n return Private.handleRequest(url, init, settings);\n }\n ServerConnection.makeRequest = makeRequest;\n /**\n * A wrapped error for a fetch response.\n */\n class ResponseError extends Error {\n /**\n * Create a ResponseError from a response, handling the traceback and message\n * as appropriate.\n *\n * @param response The response object.\n *\n * @returns A promise that resolves with a `ResponseError` object.\n */\n static async create(response) {\n try {\n const data = await response.json();\n const { message, traceback } = data;\n if (traceback) {\n console.error(traceback);\n }\n return new ResponseError(response, message !== null && message !== void 0 ? message : ResponseError._defaultMessage(response), traceback !== null && traceback !== void 0 ? traceback : '');\n }\n catch (e) {\n console.debug(e);\n return new ResponseError(response);\n }\n }\n /**\n * Create a new response error.\n */\n constructor(response, message = ResponseError._defaultMessage(response), traceback = '') {\n super(message);\n this.response = response;\n this.traceback = traceback;\n }\n static _defaultMessage(response) {\n return `Invalid response: ${response.status} ${response.statusText}`;\n }\n }\n ServerConnection.ResponseError = ResponseError;\n /**\n * A wrapped error for a network error.\n */\n class NetworkError extends TypeError {\n /**\n * Create a new network error.\n */\n constructor(original) {\n super(original.message);\n this.stack = original.stack;\n }\n }\n ServerConnection.NetworkError = NetworkError;\n})(ServerConnection = exports.ServerConnection || (exports.ServerConnection = {}));\n/**\n * The namespace for module private data.\n */\nvar Private;\n(function (Private) {\n /**\n * Handle the server connection settings, returning a new value.\n */\n function makeSettings(options = {}) {\n var _a;\n const pageBaseUrl = coreutils_1.PageConfig.getBaseUrl();\n const pageWsUrl = coreutils_1.PageConfig.getWsUrl();\n const baseUrl = coreutils_1.URLExt.normalize(options.baseUrl) || pageBaseUrl;\n let wsUrl = options.wsUrl;\n // Prefer the default wsUrl if we are using the default baseUrl.\n if (!wsUrl && baseUrl === pageBaseUrl) {\n wsUrl = pageWsUrl;\n }\n // Otherwise convert the baseUrl to a wsUrl if possible.\n if (!wsUrl && baseUrl.indexOf('http') === 0) {\n wsUrl = 'ws' + baseUrl.slice(4);\n }\n // Otherwise fall back on the default wsUrl.\n wsUrl = wsUrl !== null && wsUrl !== void 0 ? wsUrl : pageWsUrl;\n return {\n init: { cache: 'no-store', credentials: 'same-origin' },\n fetch,\n Headers,\n Request,\n WebSocket: WEBSOCKET,\n token: coreutils_1.PageConfig.getToken(),\n appUrl: coreutils_1.PageConfig.getOption('appUrl'),\n appendToken: typeof window === 'undefined' ||\n (typeof process !== 'undefined' &&\n ((_a = process === null || process === void 0 ? void 0 : process.env) === null || _a === void 0 ? void 0 : _a.JEST_WORKER_ID) !== undefined) ||\n coreutils_1.URLExt.getHostName(pageBaseUrl) !== coreutils_1.URLExt.getHostName(wsUrl),\n ...options,\n baseUrl,\n wsUrl\n };\n }\n Private.makeSettings = makeSettings;\n /**\n * Handle a request.\n *\n * @param url - The url for the request.\n *\n * @param init - The overrides for the request init.\n *\n * @param settings - The settings object for the request.\n *\n * #### Notes\n * The `url` must start with `settings.baseUrl`. The `init` settings\n * take precedence over `settings.init`.\n */\n function handleRequest(url, init, settings) {\n var _a;\n // Handle notebook server requests.\n if (url.indexOf(settings.baseUrl) !== 0) {\n throw new Error('Can only be used for notebook server requests');\n }\n // Use explicit cache buster when `no-store` is set since\n // not all browsers use it properly.\n const cache = (_a = init.cache) !== null && _a !== void 0 ? _a : settings.init.cache;\n if (cache === 'no-store') {\n // https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest/Using_XMLHttpRequest#Bypassing_the_cache\n url += (/\\?/.test(url) ? '&' : '?') + new Date().getTime();\n }\n const request = new settings.Request(url, { ...settings.init, ...init });\n // Handle authentication. Authentication can be overdetermined by\n // settings token and XSRF token.\n let authenticated = false;\n if (settings.token) {\n authenticated = true;\n request.headers.append('Authorization', `token ${settings.token}`);\n }\n if (typeof document !== 'undefined' && (document === null || document === void 0 ? void 0 : document.cookie)) {\n const xsrfToken = getCookie('_xsrf');\n if (xsrfToken !== undefined) {\n authenticated = true;\n request.headers.append('X-XSRFToken', xsrfToken);\n }\n }\n // Set the content type if there is no given data and we are\n // using an authenticated connection.\n if (!request.headers.has('Content-Type') && authenticated) {\n request.headers.set('Content-Type', 'application/json');\n }\n // Use `call` to avoid a `TypeError` in the browser.\n return settings.fetch.call(null, request).catch((e) => {\n // Convert the TypeError into a more specific error.\n throw new ServerConnection.NetworkError(e);\n });\n // TODO: *this* is probably where we need a system-wide connectionFailure\n // signal we can hook into.\n }\n Private.handleRequest = handleRequest;\n /**\n * Get a cookie from the document.\n */\n function getCookie(name) {\n // From http://www.tornadoweb.org/en/stable/guide/security.html\n const matches = document.cookie.match('\\\\b' + name + '=([^;]*)\\\\b');\n return matches === null || matches === void 0 ? void 0 : matches[1];\n }\n})(Private || (Private = {}));\n//# sourceMappingURL=serverconnection.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.SessionConnection = void 0;\nconst signaling_1 = require(\"@lumino/signaling\");\nconst __1 = require(\"..\");\nconst restapi_1 = require(\"./restapi\");\nconst coreutils_1 = require(\"@lumino/coreutils\");\n/**\n * Session object for accessing the session REST api. The session\n * should be used to start kernels and then shut them down -- for\n * all other kernel operations, the kernel object should be used.\n */\nclass SessionConnection {\n /**\n * Construct a new session.\n */\n constructor(options) {\n var _a, _b, _c, _d;\n this._id = '';\n this._path = '';\n this._name = '';\n this._type = '';\n this._kernel = null;\n this._isDisposed = false;\n this._disposed = new signaling_1.Signal(this);\n this._kernelChanged = new signaling_1.Signal(this);\n this._statusChanged = new signaling_1.Signal(this);\n this._connectionStatusChanged = new signaling_1.Signal(this);\n this._pendingInput = new signaling_1.Signal(this);\n this._iopubMessage = new signaling_1.Signal(this);\n this._unhandledMessage = new signaling_1.Signal(this);\n this._anyMessage = new signaling_1.Signal(this);\n this._propertyChanged = new signaling_1.Signal(this);\n this._id = options.model.id;\n this._name = options.model.name;\n this._path = options.model.path;\n this._type = options.model.type;\n this._username = (_a = options.username) !== null && _a !== void 0 ? _a : '';\n this._clientId = (_b = options.clientId) !== null && _b !== void 0 ? _b : coreutils_1.UUID.uuid4();\n this._connectToKernel = options.connectToKernel;\n this._kernelConnectionOptions = (_c = options.kernelConnectionOptions) !== null && _c !== void 0 ? _c : {};\n this.serverSettings =\n (_d = options.serverSettings) !== null && _d !== void 0 ? _d : __1.ServerConnection.makeSettings();\n this.setupKernel(options.model.kernel);\n }\n /**\n * A signal emitted when the session is disposed.\n */\n get disposed() {\n return this._disposed;\n }\n /**\n * A signal emitted when the kernel changes.\n */\n get kernelChanged() {\n return this._kernelChanged;\n }\n /**\n * A signal proxied from the connection about the kernel status.\n */\n get statusChanged() {\n return this._statusChanged;\n }\n /**\n * A signal proxied from the kernel about the connection status.\n */\n get connectionStatusChanged() {\n return this._connectionStatusChanged;\n }\n /**\n * A signal proxied from the kernel pending input.\n */\n get pendingInput() {\n return this._pendingInput;\n }\n /**\n * A signal proxied from the kernel about iopub kernel messages.\n */\n get iopubMessage() {\n return this._iopubMessage;\n }\n /**\n * A signal proxied from the kernel for an unhandled kernel message.\n */\n get unhandledMessage() {\n return this._unhandledMessage;\n }\n /**\n * A signal proxied from the kernel emitted for any kernel message.\n *\n * #### Notes\n * The behavior is undefined if the message is modified during message\n * handling. As such, it should be treated as read-only.\n */\n get anyMessage() {\n return this._anyMessage;\n }\n /**\n * A signal emitted when a session property changes.\n */\n get propertyChanged() {\n return this._propertyChanged;\n }\n /**\n * Get the session id.\n */\n get id() {\n return this._id;\n }\n /**\n * Get the session kernel connection object.\n *\n * #### Notes\n * This is a read-only property, and can be altered by [changeKernel].\n */\n get kernel() {\n return this._kernel;\n }\n /**\n * Get the session path.\n */\n get path() {\n return this._path;\n }\n /**\n * Get the session type.\n */\n get type() {\n return this._type;\n }\n /**\n * Get the session name.\n */\n get name() {\n return this._name;\n }\n /**\n * Get the model associated with the session.\n */\n get model() {\n return {\n id: this.id,\n kernel: this.kernel && { id: this.kernel.id, name: this.kernel.name },\n path: this._path,\n type: this._type,\n name: this._name\n };\n }\n /**\n * Test whether the session has been disposed.\n */\n get isDisposed() {\n return this._isDisposed;\n }\n /**\n * Update the session based on a session model from the server.\n *\n * #### Notes\n * This only updates this session connection instance. Use `setPath`,\n * `setName`, `setType`, and `changeKernel` to change the session values on\n * the server.\n */\n update(model) {\n const oldModel = this.model;\n this._path = model.path;\n this._name = model.name;\n this._type = model.type;\n if ((this._kernel === null && model.kernel !== null) ||\n (this._kernel !== null && model.kernel === null) ||\n (this._kernel !== null &&\n model.kernel !== null &&\n this._kernel.id !== model.kernel.id)) {\n if (this._kernel !== null) {\n this._kernel.dispose();\n }\n const oldValue = this._kernel || null;\n this.setupKernel(model.kernel);\n const newValue = this._kernel || null;\n this._kernelChanged.emit({ name: 'kernel', oldValue, newValue });\n }\n this._handleModelChange(oldModel);\n }\n /**\n * Dispose of the resources held by the session.\n */\n dispose() {\n if (this.isDisposed) {\n return;\n }\n this._isDisposed = true;\n this._disposed.emit();\n if (this._kernel) {\n this._kernel.dispose();\n const oldValue = this._kernel;\n this._kernel = null;\n const newValue = this._kernel;\n this._kernelChanged.emit({ name: 'kernel', oldValue, newValue });\n }\n signaling_1.Signal.clearData(this);\n }\n /**\n * Change the session path.\n *\n * @param path - The new session path.\n *\n * @returns A promise that resolves when the session has renamed.\n *\n * #### Notes\n * This uses the Jupyter REST API, and the response is validated.\n * The promise is fulfilled on a valid response and rejected otherwise.\n */\n async setPath(path) {\n if (this.isDisposed) {\n throw new Error('Session is disposed');\n }\n await this._patch({ path });\n }\n /**\n * Change the session name.\n */\n async setName(name) {\n if (this.isDisposed) {\n throw new Error('Session is disposed');\n }\n await this._patch({ name });\n }\n /**\n * Change the session type.\n */\n async setType(type) {\n if (this.isDisposed) {\n throw new Error('Session is disposed');\n }\n await this._patch({ type });\n }\n /**\n * Change the kernel.\n *\n * @param options - The name or id of the new kernel.\n *\n * #### Notes\n * This shuts down the existing kernel and creates a new kernel,\n * keeping the existing session ID and session path.\n */\n async changeKernel(options) {\n if (this.isDisposed) {\n throw new Error('Session is disposed');\n }\n await this._patch({ kernel: options });\n return this.kernel;\n }\n /**\n * Kill the kernel and shutdown the session.\n *\n * @returns - The promise fulfilled on a valid response from the server.\n *\n * #### Notes\n * Uses the [Jupyter Notebook API](https://petstore.swagger.io/?url=https://raw.githubusercontent.com/jupyter-server/jupyter_server/main/jupyter_server/services/api/api.yaml#!/sessions), and validates the response.\n * Disposes of the session and emits a [sessionDied] signal on success.\n */\n async shutdown() {\n if (this.isDisposed) {\n throw new Error('Session is disposed');\n }\n await (0, restapi_1.shutdownSession)(this.id, this.serverSettings);\n this.dispose();\n }\n /**\n * Create a new kernel connection and connect to its signals.\n *\n * #### Notes\n * This method is not meant to be subclassed.\n */\n setupKernel(model) {\n if (model === null) {\n this._kernel = null;\n return;\n }\n const kc = this._connectToKernel({\n ...this._kernelConnectionOptions,\n model,\n username: this._username,\n clientId: this._clientId,\n serverSettings: this.serverSettings\n });\n this._kernel = kc;\n kc.statusChanged.connect(this.onKernelStatus, this);\n kc.connectionStatusChanged.connect(this.onKernelConnectionStatus, this);\n kc.pendingInput.connect(this.onPendingInput, this);\n kc.unhandledMessage.connect(this.onUnhandledMessage, this);\n kc.iopubMessage.connect(this.onIOPubMessage, this);\n kc.anyMessage.connect(this.onAnyMessage, this);\n }\n /**\n * Handle to changes in the Kernel status.\n */\n onKernelStatus(sender, state) {\n this._statusChanged.emit(state);\n }\n /**\n * Handle to changes in the Kernel status.\n */\n onKernelConnectionStatus(sender, state) {\n this._connectionStatusChanged.emit(state);\n }\n /**\n * Handle a change in the pendingInput.\n */\n onPendingInput(sender, state) {\n this._pendingInput.emit(state);\n }\n /**\n * Handle iopub kernel messages.\n */\n onIOPubMessage(sender, msg) {\n this._iopubMessage.emit(msg);\n }\n /**\n * Handle unhandled kernel messages.\n */\n onUnhandledMessage(sender, msg) {\n this._unhandledMessage.emit(msg);\n }\n /**\n * Handle any kernel messages.\n */\n onAnyMessage(sender, args) {\n this._anyMessage.emit(args);\n }\n /**\n * Send a PATCH to the server, updating the session path or the kernel.\n */\n async _patch(body) {\n const model = await (0, restapi_1.updateSession)({ ...body, id: this._id }, this.serverSettings);\n this.update(model);\n return model;\n }\n /**\n * Handle a change to the model.\n */\n _handleModelChange(oldModel) {\n if (oldModel.name !== this._name) {\n this._propertyChanged.emit('name');\n }\n if (oldModel.type !== this._type) {\n this._propertyChanged.emit('type');\n }\n if (oldModel.path !== this._path) {\n this._propertyChanged.emit('path');\n }\n }\n}\nexports.SessionConnection = SessionConnection;\n//# sourceMappingURL=default.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nvar __exportStar = (this && this.__exportStar) || function(m, exports) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.SessionAPI = exports.Session = void 0;\nconst Session = __importStar(require(\"./session\"));\nexports.Session = Session;\nconst SessionAPI = __importStar(require(\"./restapi\"));\nexports.SessionAPI = SessionAPI;\n__exportStar(require(\"./manager\"), exports);\n//# sourceMappingURL=index.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.SessionManager = void 0;\nconst polling_1 = require(\"@lumino/polling\");\nconst signaling_1 = require(\"@lumino/signaling\");\nconst serverconnection_1 = require(\"../serverconnection\");\nconst basemanager_1 = require(\"../basemanager\");\nconst default_1 = require(\"./default\");\nconst restapi_1 = require(\"./restapi\");\n/**\n * An implementation of a session manager.\n */\nclass SessionManager extends basemanager_1.BaseManager {\n /**\n * Construct a new session manager.\n *\n * @param options - The default options for each session.\n */\n constructor(options) {\n var _a;\n super(options);\n this._isReady = false;\n this._sessionConnections = new Set();\n this._models = new Map();\n this._runningChanged = new signaling_1.Signal(this);\n this._connectionFailure = new signaling_1.Signal(this);\n // We define these here so they bind `this` correctly\n this._connectToKernel = (options) => {\n return this._kernelManager.connectTo(options);\n };\n this._kernelManager = options.kernelManager;\n // Start model polling with exponential backoff.\n this._pollModels = new polling_1.Poll({\n auto: false,\n factory: () => this.requestRunning(),\n frequency: {\n interval: 10 * 1000,\n backoff: true,\n max: 300 * 1000\n },\n name: `@jupyterlab/services:SessionManager#models`,\n standby: (_a = options.standby) !== null && _a !== void 0 ? _a : 'when-hidden'\n });\n // Initialize internal data.\n this._ready = (async () => {\n await this._pollModels.start();\n await this._pollModels.tick;\n if (this._kernelManager.isActive) {\n await this._kernelManager.ready;\n }\n this._isReady = true;\n })();\n }\n /**\n * Test whether the manager is ready.\n */\n get isReady() {\n return this._isReady;\n }\n /**\n * A promise that fulfills when the manager is ready.\n */\n get ready() {\n return this._ready;\n }\n /**\n * A signal emitted when the running sessions change.\n */\n get runningChanged() {\n return this._runningChanged;\n }\n /**\n * A signal emitted when there is a connection failure.\n */\n get connectionFailure() {\n return this._connectionFailure;\n }\n /**\n * Dispose of the resources used by the manager.\n */\n dispose() {\n if (this.isDisposed) {\n return;\n }\n this._models.clear();\n this._sessionConnections.forEach(x => x.dispose());\n this._pollModels.dispose();\n super.dispose();\n }\n /*\n * Connect to a running session. See also [[connectToSession]].\n */\n connectTo(options) {\n const sessionConnection = new default_1.SessionConnection({\n ...options,\n connectToKernel: this._connectToKernel,\n serverSettings: this.serverSettings\n });\n this._onStarted(sessionConnection);\n if (!this._models.has(options.model.id)) {\n // We trust the user to connect to an existing session, but we verify\n // asynchronously.\n void this.refreshRunning().catch(() => {\n /* no-op */\n });\n }\n return sessionConnection;\n }\n /**\n * Create an iterator over the most recent running sessions.\n *\n * @returns A new iterator over the running sessions.\n */\n running() {\n return this._models.values();\n }\n /**\n * Force a refresh of the running sessions.\n *\n * @returns A promise that with the list of running sessions.\n *\n * #### Notes\n * This is not typically meant to be called by the user, since the\n * manager maintains its own internal state.\n */\n async refreshRunning() {\n await this._pollModels.refresh();\n await this._pollModels.tick;\n }\n /**\n * Start a new session. See also [[startNewSession]].\n *\n * @param createOptions - Options for creating the session\n *\n * @param connectOptions - Options for connecting to the session\n */\n async startNew(createOptions, connectOptions = {}) {\n const model = await (0, restapi_1.startSession)(createOptions, this.serverSettings);\n await this.refreshRunning();\n return this.connectTo({ ...connectOptions, model });\n }\n /**\n * Shut down a session by id.\n */\n async shutdown(id) {\n await (0, restapi_1.shutdownSession)(id, this.serverSettings);\n await this.refreshRunning();\n }\n /**\n * Shut down all sessions.\n *\n * @returns A promise that resolves when all of the kernels are shut down.\n */\n async shutdownAll() {\n // Update the list of models to make sure our list is current.\n await this.refreshRunning();\n // Shut down all models.\n await Promise.all([...this._models.keys()].map(id => (0, restapi_1.shutdownSession)(id, this.serverSettings)));\n // Update the list of models to clear out our state.\n await this.refreshRunning();\n }\n /**\n * Find a session associated with a path and stop it if it is the only session\n * using that kernel.\n *\n * @param path - The path in question.\n *\n * @returns A promise that resolves when the relevant sessions are stopped.\n */\n async stopIfNeeded(path) {\n try {\n const sessions = await (0, restapi_1.listRunning)(this.serverSettings);\n const matches = sessions.filter(value => value.path === path);\n if (matches.length === 1) {\n const id = matches[0].id;\n await this.shutdown(id);\n }\n }\n catch (error) {\n /* Always succeed. */\n }\n }\n /**\n * Find a session by id.\n */\n async findById(id) {\n if (this._models.has(id)) {\n return this._models.get(id);\n }\n await this.refreshRunning();\n return this._models.get(id);\n }\n /**\n * Find a session by path.\n */\n async findByPath(path) {\n for (const m of this._models.values()) {\n if (m.path === path) {\n return m;\n }\n }\n await this.refreshRunning();\n for (const m of this._models.values()) {\n if (m.path === path) {\n return m;\n }\n }\n return undefined;\n }\n /**\n * Execute a request to the server to poll running kernels and update state.\n */\n async requestRunning() {\n var _a, _b;\n let models;\n try {\n models = await (0, restapi_1.listRunning)(this.serverSettings);\n }\n catch (err) {\n // Handle network errors, as well as cases where we are on a\n // JupyterHub and the server is not running. JupyterHub returns a\n // 503 (<2.0) or 424 (>2.0) in that case.\n if (err instanceof serverconnection_1.ServerConnection.NetworkError ||\n ((_a = err.response) === null || _a === void 0 ? void 0 : _a.status) === 503 ||\n ((_b = err.response) === null || _b === void 0 ? void 0 : _b.status) === 424) {\n this._connectionFailure.emit(err);\n }\n throw err;\n }\n if (this.isDisposed) {\n return;\n }\n if (this._models.size === models.length &&\n models.every(model => {\n var _a, _b, _c, _d;\n const existing = this._models.get(model.id);\n if (!existing) {\n return false;\n }\n return (((_a = existing.kernel) === null || _a === void 0 ? void 0 : _a.id) === ((_b = model.kernel) === null || _b === void 0 ? void 0 : _b.id) &&\n ((_c = existing.kernel) === null || _c === void 0 ? void 0 : _c.name) === ((_d = model.kernel) === null || _d === void 0 ? void 0 : _d.name) &&\n existing.name === model.name &&\n existing.path === model.path &&\n existing.type === model.type);\n })) {\n // Identical models list (presuming models does not contain duplicate\n // ids), so just return\n return;\n }\n this._models = new Map(models.map(x => [x.id, x]));\n this._sessionConnections.forEach(sc => {\n if (this._models.has(sc.id)) {\n sc.update(this._models.get(sc.id));\n }\n else {\n sc.dispose();\n }\n });\n this._runningChanged.emit(models);\n }\n /**\n * Handle a session starting.\n */\n _onStarted(sessionConnection) {\n this._sessionConnections.add(sessionConnection);\n sessionConnection.disposed.connect(this._onDisposed, this);\n sessionConnection.propertyChanged.connect(this._onChanged, this);\n sessionConnection.kernelChanged.connect(this._onChanged, this);\n }\n _onDisposed(sessionConnection) {\n this._sessionConnections.delete(sessionConnection);\n // A session termination emission could mean the server session is deleted,\n // or that the session JS object is disposed and the session still exists on\n // the server, so we refresh from the server to make sure we reflect the\n // server state.\n void this.refreshRunning().catch(() => {\n /* no-op */\n });\n }\n _onChanged() {\n void this.refreshRunning().catch(() => {\n /* no-op */\n });\n }\n}\nexports.SessionManager = SessionManager;\n/**\n * The namespace for `SessionManager` class statics.\n */\n(function (SessionManager) {\n /**\n * A no-op session manager to be used when starting sessions is not supported.\n */\n class NoopManager extends SessionManager {\n constructor() {\n super(...arguments);\n this._readyPromise = new Promise(() => {\n /* no-op */\n });\n }\n /**\n * Whether the manager is active.\n */\n get isActive() {\n return false;\n }\n /**\n * Used for testing.\n */\n get parentReady() {\n return super.ready;\n }\n /**\n * Start a new session - throw an error since it is not supported.\n */\n async startNew(createOptions, connectOptions = {}) {\n return Promise.reject(new Error('Not implemented in no-op Session Manager'));\n }\n /*\n * Connect to a running session - throw an error since it is not supported.\n */\n connectTo(options) {\n throw Error('Not implemented in no-op Session Manager');\n }\n /**\n * A promise that fulfills when the manager is ready (never).\n */\n get ready() {\n return this.parentReady.then(() => this._readyPromise);\n }\n /**\n * Shut down a session by id - throw an error since it is not supported.\n */\n async shutdown(id) {\n return Promise.reject(new Error('Not implemented in no-op Session Manager'));\n }\n /**\n * Execute a request to the server to poll running sessions and update state.\n */\n async requestRunning() {\n return Promise.resolve();\n }\n }\n SessionManager.NoopManager = NoopManager;\n})(SessionManager = exports.SessionManager || (exports.SessionManager = {}));\n//# sourceMappingURL=manager.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.updateSession = exports.startSession = exports.getSessionModel = exports.shutdownSession = exports.getSessionUrl = exports.listRunning = exports.SESSION_SERVICE_URL = void 0;\nconst serverconnection_1 = require(\"../serverconnection\");\nconst coreutils_1 = require(\"@jupyterlab/coreutils\");\nconst validate_1 = require(\"./validate\");\n/**\n * The url for the session service.\n */\nexports.SESSION_SERVICE_URL = 'api/sessions';\n/**\n * List the running sessions.\n */\nasync function listRunning(settings = serverconnection_1.ServerConnection.makeSettings()) {\n const url = coreutils_1.URLExt.join(settings.baseUrl, exports.SESSION_SERVICE_URL);\n const response = await serverconnection_1.ServerConnection.makeRequest(url, {}, settings);\n if (response.status !== 200) {\n const err = await serverconnection_1.ServerConnection.ResponseError.create(response);\n throw err;\n }\n const data = await response.json();\n if (!Array.isArray(data)) {\n throw new Error('Invalid Session list');\n }\n data.forEach(m => {\n (0, validate_1.updateLegacySessionModel)(m);\n (0, validate_1.validateModel)(m);\n });\n return data;\n}\nexports.listRunning = listRunning;\n/**\n * Get a session url.\n */\nfunction getSessionUrl(baseUrl, id) {\n return coreutils_1.URLExt.join(baseUrl, exports.SESSION_SERVICE_URL, id);\n}\nexports.getSessionUrl = getSessionUrl;\n/**\n * Shut down a session by id.\n */\nasync function shutdownSession(id, settings = serverconnection_1.ServerConnection.makeSettings()) {\n var _a;\n const url = getSessionUrl(settings.baseUrl, id);\n const init = { method: 'DELETE' };\n const response = await serverconnection_1.ServerConnection.makeRequest(url, init, settings);\n if (response.status === 404) {\n const data = await response.json();\n const msg = (_a = data.message) !== null && _a !== void 0 ? _a : `The session \"${id}\"\" does not exist on the server`;\n console.warn(msg);\n }\n else if (response.status === 410) {\n throw new serverconnection_1.ServerConnection.ResponseError(response, 'The kernel was deleted but the session was not');\n }\n else if (response.status !== 204) {\n const err = await serverconnection_1.ServerConnection.ResponseError.create(response);\n throw err;\n }\n}\nexports.shutdownSession = shutdownSession;\n/**\n * Get a full session model from the server by session id string.\n */\nasync function getSessionModel(id, settings = serverconnection_1.ServerConnection.makeSettings()) {\n const url = getSessionUrl(settings.baseUrl, id);\n const response = await serverconnection_1.ServerConnection.makeRequest(url, {}, settings);\n if (response.status !== 200) {\n const err = await serverconnection_1.ServerConnection.ResponseError.create(response);\n throw err;\n }\n const data = await response.json();\n (0, validate_1.updateLegacySessionModel)(data);\n (0, validate_1.validateModel)(data);\n return data;\n}\nexports.getSessionModel = getSessionModel;\n/**\n * Create a new session, or return an existing session if the session path\n * already exists.\n */\nasync function startSession(options, settings = serverconnection_1.ServerConnection.makeSettings()) {\n const url = coreutils_1.URLExt.join(settings.baseUrl, exports.SESSION_SERVICE_URL);\n const init = {\n method: 'POST',\n body: JSON.stringify(options)\n };\n const response = await serverconnection_1.ServerConnection.makeRequest(url, init, settings);\n if (response.status !== 201) {\n const err = await serverconnection_1.ServerConnection.ResponseError.create(response);\n throw err;\n }\n const data = await response.json();\n (0, validate_1.updateLegacySessionModel)(data);\n (0, validate_1.validateModel)(data);\n return data;\n}\nexports.startSession = startSession;\n/**\n * Send a PATCH to the server, updating the session path or the kernel.\n */\nasync function updateSession(model, settings = serverconnection_1.ServerConnection.makeSettings()) {\n const url = getSessionUrl(settings.baseUrl, model.id);\n const init = {\n method: 'PATCH',\n body: JSON.stringify(model)\n };\n const response = await serverconnection_1.ServerConnection.makeRequest(url, init, settings);\n if (response.status !== 200) {\n const err = await serverconnection_1.ServerConnection.ResponseError.create(response);\n throw err;\n }\n const data = await response.json();\n (0, validate_1.updateLegacySessionModel)(data);\n (0, validate_1.validateModel)(data);\n return data;\n}\nexports.updateSession = updateSession;\n//# sourceMappingURL=restapi.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\n//# sourceMappingURL=session.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.validateModels = exports.updateLegacySessionModel = exports.validateModel = void 0;\nconst validate_1 = require(\"../kernel/validate\");\nconst validate_2 = require(\"../validate\");\n/**\n * Validate an `Session.IModel` object.\n */\n// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\nfunction validateModel(data) {\n (0, validate_2.validateProperty)(data, 'id', 'string');\n (0, validate_2.validateProperty)(data, 'type', 'string');\n (0, validate_2.validateProperty)(data, 'name', 'string');\n (0, validate_2.validateProperty)(data, 'path', 'string');\n (0, validate_2.validateProperty)(data, 'kernel', 'object');\n (0, validate_1.validateModel)(data.kernel);\n}\nexports.validateModel = validateModel;\n/**\n * Update model from legacy session data.\n */\n// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\nfunction updateLegacySessionModel(data) {\n if (data.path === undefined && data.notebook !== undefined) {\n data.path = data.notebook.path;\n data.type = 'notebook';\n data.name = '';\n }\n}\nexports.updateLegacySessionModel = updateLegacySessionModel;\n/**\n * Validate an array of `Session.IModel` objects.\n */\nfunction validateModels(models) {\n if (!Array.isArray(models)) {\n throw new Error('Invalid session list');\n }\n models.forEach(d => validateModel(d));\n}\nexports.validateModels = validateModels;\n//# sourceMappingURL=validate.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.SettingManager = void 0;\nconst coreutils_1 = require(\"@jupyterlab/coreutils\");\nconst statedb_1 = require(\"@jupyterlab/statedb\");\nconst serverconnection_1 = require(\"../serverconnection\");\n/**\n * The url for the lab settings service.\n */\nconst SERVICE_SETTINGS_URL = 'api/settings';\n/**\n * The settings API service manager.\n */\nclass SettingManager extends statedb_1.DataConnector {\n /**\n * Create a new setting manager.\n */\n constructor(options = {}) {\n var _a;\n super();\n this.serverSettings =\n (_a = options.serverSettings) !== null && _a !== void 0 ? _a : serverconnection_1.ServerConnection.makeSettings();\n }\n /**\n * Fetch a plugin's settings.\n *\n * @param id - The plugin's ID.\n *\n * @returns A promise that resolves if successful.\n */\n async fetch(id) {\n if (!id) {\n throw new Error('Plugin `id` parameter is required for settings fetch.');\n }\n const { serverSettings } = this;\n const { baseUrl, appUrl } = serverSettings;\n const { makeRequest, ResponseError } = serverconnection_1.ServerConnection;\n const base = baseUrl + appUrl;\n const url = Private.url(base, id);\n const response = await makeRequest(url, {}, serverSettings);\n if (response.status !== 200) {\n const err = await ResponseError.create(response);\n throw err;\n }\n // Assert what type the server response is returning.\n return response.json();\n }\n /**\n * Fetch the list of all plugin setting bundles.\n *\n * @returns A promise that resolves if successful.\n */\n async list(query) {\n var _a, _b, _c, _d;\n const { serverSettings } = this;\n const { baseUrl, appUrl } = serverSettings;\n const { makeRequest, ResponseError } = serverconnection_1.ServerConnection;\n const base = baseUrl + appUrl;\n const url = Private.url(base, '', query === 'ids');\n const response = await makeRequest(url, {}, serverSettings);\n if (response.status !== 200) {\n throw new ResponseError(response);\n }\n const json = await response.json();\n const ids = (_b = (_a = json === null || json === void 0 ? void 0 : json['settings']) === null || _a === void 0 ? void 0 : _a.map((plugin) => plugin.id)) !== null && _b !== void 0 ? _b : [];\n let values = [];\n if (!query) {\n values =\n (_d = (_c = json === null || json === void 0 ? void 0 : json['settings']) === null || _c === void 0 ? void 0 : _c.map((plugin) => {\n plugin.data = { composite: {}, user: {} };\n return plugin;\n })) !== null && _d !== void 0 ? _d : [];\n }\n return { ids, values };\n }\n /**\n * Save a plugin's settings.\n *\n * @param id - The plugin's ID.\n *\n * @param raw - The user setting values as a raw string of JSON with comments.\n *\n * @returns A promise that resolves if successful.\n */\n async save(id, raw) {\n const { serverSettings } = this;\n const { baseUrl, appUrl } = serverSettings;\n const { makeRequest, ResponseError } = serverconnection_1.ServerConnection;\n const base = baseUrl + appUrl;\n const url = Private.url(base, id);\n // NOTE: 'raw' is JSON5 (not valid JSON), so we encode it as a string in a valid JSON body\n const init = { body: JSON.stringify({ raw }), method: 'PUT' };\n const response = await makeRequest(url, init, serverSettings);\n if (response.status !== 204) {\n throw new ResponseError(response);\n }\n }\n}\nexports.SettingManager = SettingManager;\n/**\n * A namespace for private data.\n */\nvar Private;\n(function (Private) {\n /**\n * Get the url for a plugin's settings.\n */\n function url(base, id, idsOnly) {\n const idsOnlyParam = idsOnly\n ? coreutils_1.URLExt.objectToQueryString({ ids_only: true })\n : '';\n return `${coreutils_1.URLExt.join(base, SERVICE_SETTINGS_URL, id)}${idsOnlyParam}`;\n }\n Private.url = url;\n})(Private || (Private = {}));\n//# sourceMappingURL=index.js.map","\"use strict\";\n/*\n * Copyright (c) Jupyter Development Team.\n * Distributed under the terms of the Modified BSD License.\n */\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.default = WebSocket;\n//# sourceMappingURL=ws.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.TerminalConnection = void 0;\nconst coreutils_1 = require(\"@jupyterlab/coreutils\");\nconst coreutils_2 = require(\"@lumino/coreutils\");\nconst signaling_1 = require(\"@lumino/signaling\");\nconst __1 = require(\"..\");\nconst restapi_1 = require(\"./restapi\");\n/**\n * An implementation of a terminal interface.\n */\nclass TerminalConnection {\n /**\n * Construct a new terminal session.\n */\n constructor(options) {\n var _a;\n /**\n * Create the terminal websocket connection and add socket status handlers.\n *\n * #### Notes\n * You are responsible for updating the connection status as appropriate.\n */\n this._createSocket = () => {\n this._errorIfDisposed();\n // Make sure the socket is clear\n this._clearSocket();\n // Update the connection status to reflect opening a new connection.\n this._updateConnectionStatus('connecting');\n const name = this._name;\n const settings = this.serverSettings;\n let url = coreutils_1.URLExt.join(settings.wsUrl, 'terminals', 'websocket', encodeURIComponent(name));\n // If token authentication is in use.\n const token = settings.token;\n if (settings.appendToken && token !== '') {\n url = url + `?token=${encodeURIComponent(token)}`;\n }\n this._ws = new settings.WebSocket(url);\n this._ws.onmessage = this._onWSMessage;\n this._ws.onclose = this._onWSClose;\n this._ws.onerror = this._onWSClose;\n };\n // Websocket messages events are defined as variables to bind `this`\n this._onWSMessage = (event) => {\n if (this._isDisposed) {\n return;\n }\n const data = JSON.parse(event.data);\n // Handle a disconnect message.\n if (data[0] === 'disconnect') {\n this.dispose();\n }\n if (this._connectionStatus === 'connecting') {\n // After reconnection, ignore all messages until a 'setup' message\n // before we are truly connected. Setting the connection status to\n // connected only then means that if we do not get a setup message\n // before our retry timeout, we will delete the websocket and try again.\n if (data[0] === 'setup') {\n this._updateConnectionStatus('connected');\n }\n return;\n }\n this._messageReceived.emit({\n type: data[0],\n content: data.slice(1)\n });\n };\n this._onWSClose = (event) => {\n console.warn(`Terminal websocket closed: ${event.code}`);\n if (!this.isDisposed) {\n this._reconnect();\n }\n };\n this._connectionStatus = 'connecting';\n this._connectionStatusChanged = new signaling_1.Signal(this);\n this._isDisposed = false;\n this._disposed = new signaling_1.Signal(this);\n this._messageReceived = new signaling_1.Signal(this);\n this._reconnectTimeout = null;\n this._ws = null;\n this._noOp = () => {\n /* no-op */\n };\n this._reconnectLimit = 7;\n this._reconnectAttempt = 0;\n this._pendingMessages = [];\n this._name = options.model.name;\n this.serverSettings =\n (_a = options.serverSettings) !== null && _a !== void 0 ? _a : __1.ServerConnection.makeSettings();\n this._createSocket();\n }\n /**\n * A signal emitted when the session is disposed.\n */\n get disposed() {\n return this._disposed;\n }\n /**\n * A signal emitted when a message is received from the server.\n */\n get messageReceived() {\n return this._messageReceived;\n }\n /**\n * Get the name of the terminal session.\n */\n get name() {\n return this._name;\n }\n /**\n * Get the model for the terminal session.\n */\n get model() {\n return { name: this._name };\n }\n /**\n * Test whether the session is disposed.\n */\n get isDisposed() {\n return this._isDisposed;\n }\n /**\n * Dispose of the resources held by the session.\n */\n dispose() {\n if (this._isDisposed) {\n return;\n }\n this._isDisposed = true;\n this._disposed.emit();\n this._updateConnectionStatus('disconnected');\n this._clearSocket();\n signaling_1.Signal.clearData(this);\n }\n /**\n * Send a message to the terminal session.\n *\n * #### Notes\n * If the connection is down, the message will be queued for sending when\n * the connection comes back up.\n */\n send(message) {\n this._sendMessage(message);\n }\n /**\n * Send a message on the websocket, or possibly queue for later sending.\n *\n * @param queue - whether to queue the message if it cannot be sent\n */\n _sendMessage(message, queue = true) {\n if (this._isDisposed || !message.content) {\n return;\n }\n if (this.connectionStatus === 'connected' && this._ws) {\n const msg = [message.type, ...message.content];\n this._ws.send(JSON.stringify(msg));\n }\n else if (queue) {\n this._pendingMessages.push(message);\n }\n else {\n throw new Error(`Could not send message: ${JSON.stringify(message)}`);\n }\n }\n /**\n * Send pending messages to the kernel.\n */\n _sendPending() {\n // We check to make sure we are still connected each time. For\n // example, if a websocket buffer overflows, it may close, so we should\n // stop sending messages.\n while (this.connectionStatus === 'connected' &&\n this._pendingMessages.length > 0) {\n this._sendMessage(this._pendingMessages[0], false);\n // We shift the message off the queue after the message is sent so that\n // if there is an exception, the message is still pending.\n this._pendingMessages.shift();\n }\n }\n /**\n * Reconnect to a terminal.\n *\n * #### Notes\n * This may try multiple times to reconnect to a terminal, and will sever\n * any existing connection.\n */\n reconnect() {\n this._errorIfDisposed();\n const result = new coreutils_2.PromiseDelegate();\n // Set up a listener for the connection status changing, which accepts or\n // rejects after the retries are done.\n const fulfill = (sender, status) => {\n if (status === 'connected') {\n result.resolve();\n this.connectionStatusChanged.disconnect(fulfill, this);\n }\n else if (status === 'disconnected') {\n result.reject(new Error('Terminal connection disconnected'));\n this.connectionStatusChanged.disconnect(fulfill, this);\n }\n };\n this.connectionStatusChanged.connect(fulfill, this);\n // Reset the reconnect limit so we start the connection attempts fresh\n this._reconnectAttempt = 0;\n // Start the reconnection process, which will also clear any existing\n // connection.\n this._reconnect();\n // Return the promise that should resolve on connection or reject if the\n // retries don't work.\n return result.promise;\n }\n /**\n * Attempt a connection if we have not exhausted connection attempts.\n */\n _reconnect() {\n this._errorIfDisposed();\n // Clear any existing reconnection attempt\n clearTimeout(this._reconnectTimeout);\n // Update the connection status and schedule a possible reconnection.\n if (this._reconnectAttempt < this._reconnectLimit) {\n this._updateConnectionStatus('connecting');\n // The first reconnect attempt should happen immediately, and subsequent\n // attempts should pick a random number in a growing range so that we\n // don't overload the server with synchronized reconnection attempts\n // across multiple kernels.\n const timeout = Private.getRandomIntInclusive(0, 1e3 * (Math.pow(2, this._reconnectAttempt) - 1));\n console.error(`Connection lost, reconnecting in ${Math.floor(timeout / 1000)} seconds.`);\n this._reconnectTimeout = setTimeout(this._createSocket, timeout);\n this._reconnectAttempt += 1;\n }\n else {\n this._updateConnectionStatus('disconnected');\n }\n // Clear the websocket event handlers and the socket itself.\n this._clearSocket();\n }\n /**\n * Forcefully clear the socket state.\n *\n * #### Notes\n * This will clear all socket state without calling any handlers and will\n * not update the connection status. If you call this method, you are\n * responsible for updating the connection status as needed and recreating\n * the socket if you plan to reconnect.\n */\n _clearSocket() {\n if (this._ws !== null) {\n // Clear the websocket event handlers and the socket itself.\n this._ws.onopen = this._noOp;\n this._ws.onclose = this._noOp;\n this._ws.onerror = this._noOp;\n this._ws.onmessage = this._noOp;\n this._ws.close();\n this._ws = null;\n }\n }\n /**\n * Shut down the terminal session.\n */\n async shutdown() {\n await (0, restapi_1.shutdownTerminal)(this.name, this.serverSettings);\n this.dispose();\n }\n /**\n * Clone the current terminal connection.\n */\n clone() {\n return new TerminalConnection(this);\n }\n /**\n * Handle connection status changes.\n */\n _updateConnectionStatus(connectionStatus) {\n if (this._connectionStatus === connectionStatus) {\n return;\n }\n this._connectionStatus = connectionStatus;\n // If we are not 'connecting', stop any reconnection attempts.\n if (connectionStatus !== 'connecting') {\n this._reconnectAttempt = 0;\n clearTimeout(this._reconnectTimeout);\n }\n // Send the pending messages if we just connected.\n if (connectionStatus === 'connected') {\n this._sendPending();\n }\n // Notify others that the connection status changed.\n this._connectionStatusChanged.emit(connectionStatus);\n }\n /**\n * Utility function to throw an error if this instance is disposed.\n */\n _errorIfDisposed() {\n if (this.isDisposed) {\n throw new Error('Terminal connection is disposed');\n }\n }\n /**\n * A signal emitted when the terminal connection status changes.\n */\n get connectionStatusChanged() {\n return this._connectionStatusChanged;\n }\n /**\n * The current connection status of the terminal connection.\n */\n get connectionStatus() {\n return this._connectionStatus;\n }\n}\nexports.TerminalConnection = TerminalConnection;\nvar Private;\n(function (Private) {\n /**\n * Get the url for a terminal.\n */\n function getTermUrl(baseUrl, name) {\n return coreutils_1.URLExt.join(baseUrl, restapi_1.TERMINAL_SERVICE_URL, encodeURIComponent(name));\n }\n Private.getTermUrl = getTermUrl;\n /**\n * Get a random integer between min and max, inclusive of both.\n *\n * #### Notes\n * From\n * https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/random#Getting_a_random_integer_between_two_values_inclusive\n *\n * From the MDN page: It might be tempting to use Math.round() to accomplish\n * that, but doing so would cause your random numbers to follow a non-uniform\n * distribution, which may not be acceptable for your needs.\n */\n function getRandomIntInclusive(min, max) {\n min = Math.ceil(min);\n max = Math.floor(max);\n return Math.floor(Math.random() * (max - min + 1)) + min;\n }\n Private.getRandomIntInclusive = getRandomIntInclusive;\n})(Private || (Private = {}));\n//# sourceMappingURL=default.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nvar __exportStar = (this && this.__exportStar) || function(m, exports) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.TerminalAPI = exports.Terminal = void 0;\nconst Terminal = __importStar(require(\"./terminal\"));\nexports.Terminal = Terminal;\nconst TerminalAPI = __importStar(require(\"./restapi\"));\nexports.TerminalAPI = TerminalAPI;\n__exportStar(require(\"./manager\"), exports);\n//# sourceMappingURL=index.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.TerminalManager = void 0;\nconst polling_1 = require(\"@lumino/polling\");\nconst signaling_1 = require(\"@lumino/signaling\");\nconst __1 = require(\"..\");\nconst basemanager_1 = require(\"../basemanager\");\nconst restapi_1 = require(\"./restapi\");\nconst default_1 = require(\"./default\");\n/**\n * A terminal session manager.\n */\nclass TerminalManager extends basemanager_1.BaseManager {\n /**\n * Construct a new terminal manager.\n */\n constructor(options = {}) {\n var _a;\n super(options);\n this._isReady = false;\n // As an optimization, we unwrap the models to just store the names.\n this._names = [];\n this._terminalConnections = new Set();\n this._runningChanged = new signaling_1.Signal(this);\n this._connectionFailure = new signaling_1.Signal(this);\n // Check if terminals are available\n if (!this.isAvailable()) {\n this._ready = Promise.reject('Terminals unavailable');\n this._ready.catch(_ => undefined);\n return;\n }\n // Start polling with exponential backoff.\n this._pollModels = new polling_1.Poll({\n auto: false,\n factory: () => this.requestRunning(),\n frequency: {\n interval: 10 * 1000,\n backoff: true,\n max: 300 * 1000\n },\n name: `@jupyterlab/services:TerminalManager#models`,\n standby: (_a = options.standby) !== null && _a !== void 0 ? _a : 'when-hidden'\n });\n // Initialize internal data.\n this._ready = (async () => {\n await this._pollModels.start();\n await this._pollModels.tick;\n this._isReady = true;\n })();\n }\n /**\n * Test whether the manager is ready.\n */\n get isReady() {\n return this._isReady;\n }\n /**\n * A promise that fulfills when the manager is ready.\n */\n get ready() {\n return this._ready;\n }\n /**\n * A signal emitted when the running terminals change.\n */\n get runningChanged() {\n return this._runningChanged;\n }\n /**\n * A signal emitted when there is a connection failure.\n */\n get connectionFailure() {\n return this._connectionFailure;\n }\n /**\n * Dispose of the resources used by the manager.\n */\n dispose() {\n if (this.isDisposed) {\n return;\n }\n this._names.length = 0;\n this._terminalConnections.forEach(x => x.dispose());\n this._pollModels.dispose();\n super.dispose();\n }\n /**\n * Whether the terminal service is available.\n */\n isAvailable() {\n return (0, restapi_1.isAvailable)();\n }\n /*\n * Connect to a running terminal.\n *\n * @param options - The options used to connect to the terminal.\n *\n * @returns The new terminal connection instance.\n *\n * #### Notes\n * The manager `serverSettings` will be used.\n */\n connectTo(options) {\n const terminalConnection = new default_1.TerminalConnection({\n ...options,\n serverSettings: this.serverSettings\n });\n this._onStarted(terminalConnection);\n if (!this._names.includes(options.model.name)) {\n // We trust the user to connect to an existing session, but we verify\n // asynchronously.\n void this.refreshRunning().catch(() => {\n /* no-op */\n });\n }\n return terminalConnection;\n }\n /**\n * Create an iterator over the most recent running terminals.\n *\n * @returns A new iterator over the running terminals.\n */\n running() {\n return this._models[Symbol.iterator]();\n }\n /**\n * Force a refresh of the running terminals.\n *\n * @returns A promise that with the list of running terminals.\n *\n * #### Notes\n * This is intended to be called only in response to a user action,\n * since the manager maintains its internal state.\n */\n async refreshRunning() {\n await this._pollModels.refresh();\n await this._pollModels.tick;\n }\n /**\n * Create a new terminal session.\n *\n * @param options - The options used to create the terminal.\n *\n * @returns A promise that resolves with the terminal connection instance.\n *\n * #### Notes\n * The manager `serverSettings` will be used unless overridden in the\n * options.\n */\n async startNew(options) {\n const model = await (0, restapi_1.startNew)(this.serverSettings, options === null || options === void 0 ? void 0 : options.name, options === null || options === void 0 ? void 0 : options.cwd);\n await this.refreshRunning();\n return this.connectTo({ model });\n }\n /**\n * Shut down a terminal session by name.\n */\n async shutdown(name) {\n await (0, restapi_1.shutdownTerminal)(name, this.serverSettings);\n await this.refreshRunning();\n }\n /**\n * Shut down all terminal sessions.\n *\n * @returns A promise that resolves when all of the sessions are shut down.\n */\n async shutdownAll() {\n // Update the list of models to make sure our list is current.\n await this.refreshRunning();\n // Shut down all models.\n await Promise.all(this._names.map(name => (0, restapi_1.shutdownTerminal)(name, this.serverSettings)));\n // Update the list of models to clear out our state.\n await this.refreshRunning();\n }\n /**\n * Execute a request to the server to poll running terminals and update state.\n */\n async requestRunning() {\n var _a, _b;\n let models;\n try {\n models = await (0, restapi_1.listRunning)(this.serverSettings);\n }\n catch (err) {\n // Handle network errors, as well as cases where we are on a\n // JupyterHub and the server is not running. JupyterHub returns a\n // 503 (<2.0) or 424 (>2.0) in that case.\n if (err instanceof __1.ServerConnection.NetworkError ||\n ((_a = err.response) === null || _a === void 0 ? void 0 : _a.status) === 503 ||\n ((_b = err.response) === null || _b === void 0 ? void 0 : _b.status) === 424) {\n this._connectionFailure.emit(err);\n }\n throw err;\n }\n if (this.isDisposed) {\n return;\n }\n const names = models.map(({ name }) => name).sort();\n if (names === this._names) {\n // Identical models list, so just return\n return;\n }\n this._names = names;\n this._terminalConnections.forEach(tc => {\n if (!names.includes(tc.name)) {\n tc.dispose();\n }\n });\n this._runningChanged.emit(this._models);\n }\n /**\n * Handle a session starting.\n */\n _onStarted(terminalConnection) {\n this._terminalConnections.add(terminalConnection);\n terminalConnection.disposed.connect(this._onDisposed, this);\n }\n /**\n * Handle a session terminating.\n */\n _onDisposed(terminalConnection) {\n this._terminalConnections.delete(terminalConnection);\n // Update the running models to make sure we reflect the server state\n void this.refreshRunning().catch(() => {\n /* no-op */\n });\n }\n get _models() {\n return this._names.map(name => {\n return { name };\n });\n }\n}\nexports.TerminalManager = TerminalManager;\n/**\n * The namespace for TerminalManager statics.\n */\n(function (TerminalManager) {\n /**\n * A no-op terminal manager to be used when starting terminals is not supported.\n */\n class NoopManager extends TerminalManager {\n constructor() {\n super(...arguments);\n this._readyPromise = new Promise(() => {\n /* no-op */\n });\n }\n /**\n * Whether the manager is active.\n */\n get isActive() {\n return false;\n }\n /**\n * Used for testing.\n */\n get parentReady() {\n return super.ready;\n }\n /**\n * A promise that fulfills when the manager is ready (never).\n */\n get ready() {\n return this.parentReady.then(() => this._readyPromise);\n }\n /**\n * Create a new terminal session - throw an error since it is not supported.\n *\n */\n async startNew(options) {\n return Promise.reject(new Error('Not implemented in no-op Terminal Manager'));\n }\n /*\n * Connect to a running terminal - throw an error since it is not supported.\n */\n connectTo(options) {\n throw Error('Not implemented in no-op Terminal Manager');\n }\n /**\n * Shut down a session by id - throw an error since it is not supported.\n */\n async shutdown(id) {\n return Promise.reject(new Error('Not implemented in no-op Terminal Manager'));\n }\n /**\n * Execute a request to the server to poll running sessions and update state.\n */\n async requestRunning() {\n return Promise.resolve();\n }\n }\n TerminalManager.NoopManager = NoopManager;\n})(TerminalManager = exports.TerminalManager || (exports.TerminalManager = {}));\n//# sourceMappingURL=manager.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.shutdownTerminal = exports.listRunning = exports.startNew = exports.isAvailable = exports.TERMINAL_SERVICE_URL = void 0;\nconst coreutils_1 = require(\"@jupyterlab/coreutils\");\nconst serverconnection_1 = require(\"../serverconnection\");\n/**\n * The url for the terminal service.\n */\nexports.TERMINAL_SERVICE_URL = 'api/terminals';\n/**\n * Whether the terminal service is available.\n */\nfunction isAvailable() {\n const available = String(coreutils_1.PageConfig.getOption('terminalsAvailable'));\n return available.toLowerCase() === 'true';\n}\nexports.isAvailable = isAvailable;\n/**\n * Start a new terminal session.\n *\n * @param settings - The server settings to use.\n *\n * @param name - The name of the target terminal.\n *\n * @param cwd - The path in which the terminal will start.\n *\n * @returns A promise that resolves with the session model.\n */\nasync function startNew(settings = serverconnection_1.ServerConnection.makeSettings(), name, cwd) {\n Private.errorIfNotAvailable();\n const url = coreutils_1.URLExt.join(settings.baseUrl, exports.TERMINAL_SERVICE_URL);\n const init = {\n method: 'POST',\n body: JSON.stringify({ name, cwd })\n };\n const response = await serverconnection_1.ServerConnection.makeRequest(url, init, settings);\n if (response.status !== 200) {\n const err = await serverconnection_1.ServerConnection.ResponseError.create(response);\n throw err;\n }\n const data = await response.json();\n // TODO: Validate model\n return data;\n}\nexports.startNew = startNew;\n/**\n * List the running terminal sessions.\n *\n * @param settings - The server settings to use.\n *\n * @returns A promise that resolves with the list of running session models.\n */\nasync function listRunning(settings = serverconnection_1.ServerConnection.makeSettings()) {\n Private.errorIfNotAvailable();\n const url = coreutils_1.URLExt.join(settings.baseUrl, exports.TERMINAL_SERVICE_URL);\n const response = await serverconnection_1.ServerConnection.makeRequest(url, {}, settings);\n if (response.status !== 200) {\n const err = await serverconnection_1.ServerConnection.ResponseError.create(response);\n throw err;\n }\n const data = await response.json();\n if (!Array.isArray(data)) {\n throw new Error('Invalid terminal list');\n }\n // TODO: validate each model\n return data;\n}\nexports.listRunning = listRunning;\n/**\n * Shut down a terminal session by name.\n *\n * @param name - The name of the target session.\n *\n * @param settings - The server settings to use.\n *\n * @returns A promise that resolves when the session is shut down.\n */\nasync function shutdownTerminal(name, settings = serverconnection_1.ServerConnection.makeSettings()) {\n var _a;\n Private.errorIfNotAvailable();\n const url = coreutils_1.URLExt.join(settings.baseUrl, exports.TERMINAL_SERVICE_URL, name);\n const init = { method: 'DELETE' };\n const response = await serverconnection_1.ServerConnection.makeRequest(url, init, settings);\n if (response.status === 404) {\n const data = await response.json();\n const msg = (_a = data.message) !== null && _a !== void 0 ? _a : `The terminal session \"${name}\"\" does not exist on the server`;\n console.warn(msg);\n }\n else if (response.status !== 204) {\n const err = await serverconnection_1.ServerConnection.ResponseError.create(response);\n throw err;\n }\n}\nexports.shutdownTerminal = shutdownTerminal;\nvar Private;\n(function (Private) {\n /**\n * Throw an error if terminals are not available.\n */\n function errorIfNotAvailable() {\n if (!isAvailable()) {\n throw new Error('Terminals Unavailable');\n }\n }\n Private.errorIfNotAvailable = errorIfNotAvailable;\n})(Private || (Private = {}));\n//# sourceMappingURL=restapi.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.isAvailable = void 0;\nconst restapi_1 = require(\"./restapi\");\nObject.defineProperty(exports, \"isAvailable\", { enumerable: true, get: function () { return restapi_1.isAvailable; } });\n//# sourceMappingURL=terminal.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.UserManager = void 0;\nconst coreutils_1 = require(\"@jupyterlab/coreutils\");\nconst coreutils_2 = require(\"@lumino/coreutils\");\nconst polling_1 = require(\"@lumino/polling\");\nconst signaling_1 = require(\"@lumino/signaling\");\nconst serverconnection_1 = require(\"../serverconnection\");\nconst basemanager_1 = require(\"../basemanager\");\n/**\n * The url for the lab workspaces service.\n */\nconst SERVICE_USER_URL = 'api/me';\n/**\n * The service's ID.\n * Used to uniquely identify the poll, and\n * the item in local storage.\n */\nconst SERVICE_ID = '@jupyterlab/services:UserManager#user';\n/**\n * The user API service manager.\n */\nclass UserManager extends basemanager_1.BaseManager {\n /**\n * Create a new user manager.\n */\n constructor(options = {}) {\n var _a;\n super(options);\n this._isReady = false;\n this._userChanged = new signaling_1.Signal(this);\n this._connectionFailure = new signaling_1.Signal(this);\n // Initialize internal data.\n this._ready = this.requestUser()\n .then(() => {\n if (this.isDisposed) {\n return;\n }\n this._isReady = true;\n })\n .catch(_ => \n // Return a promise that will never resolve, so user service is never ready\n // This typically occurs when the backend has no user service\n new Promise(() => {\n // no-op\n }));\n this._pollSpecs = new polling_1.Poll({\n auto: false,\n factory: () => this.requestUser(),\n frequency: {\n interval: 61 * 1000,\n backoff: true,\n max: 300 * 1000\n },\n name: SERVICE_ID,\n standby: (_a = options.standby) !== null && _a !== void 0 ? _a : 'when-hidden'\n });\n void this.ready.then(() => {\n void this._pollSpecs.start();\n });\n }\n /**\n * Test whether the manager is ready.\n */\n get isReady() {\n return this._isReady;\n }\n /**\n * A promise that fulfills when the manager is ready.\n */\n get ready() {\n return this._ready;\n }\n /**\n * Get the most recently fetched identity.\n */\n get identity() {\n return this._identity;\n }\n /**\n * Get the most recently fetched permissions.\n */\n get permissions() {\n return this._permissions;\n }\n /**\n * A signal emitted when the user changes.\n */\n get userChanged() {\n return this._userChanged;\n }\n /**\n * A signal emitted when there is a connection failure.\n */\n get connectionFailure() {\n return this._connectionFailure;\n }\n /**\n * Dispose of the resources used by the manager.\n */\n dispose() {\n this._pollSpecs.dispose();\n super.dispose();\n }\n /**\n * Force a refresh of the specs from the server.\n *\n * @returns A promise that resolves when the specs are fetched.\n *\n * #### Notes\n * This is intended to be called only in response to a user action,\n * since the manager maintains its internal state.\n */\n async refreshUser() {\n await this._pollSpecs.refresh();\n await this._pollSpecs.tick;\n }\n /**\n * Execute a request to the server to poll the user and update state.\n */\n async requestUser() {\n if (this.isDisposed) {\n return;\n }\n const { baseUrl } = this.serverSettings;\n const { makeRequest, ResponseError } = serverconnection_1.ServerConnection;\n const url = coreutils_1.URLExt.join(baseUrl, SERVICE_USER_URL);\n const response = await makeRequest(url, {}, this.serverSettings);\n if (response.status !== 200) {\n const err = await ResponseError.create(response);\n throw err;\n }\n const oldUser = {\n identity: this._identity,\n permissions: this._permissions\n };\n const newUser = await response.json();\n const identity = newUser.identity;\n // store the color and initials for the user\n // this info is not provided by the server\n const { localStorage } = window;\n const data = localStorage.getItem(SERVICE_ID);\n if (data && (!identity.initials || !identity.color)) {\n const localUser = JSON.parse(data);\n identity.initials =\n identity.initials ||\n localUser.initials ||\n identity.name.substring(0, 1);\n identity.color =\n identity.color || localUser.color || Private.getRandomColor();\n }\n if (!coreutils_2.JSONExt.deepEqual(newUser, oldUser)) {\n this._identity = identity;\n this._permissions = newUser.permissions;\n localStorage.setItem(SERVICE_ID, JSON.stringify(identity));\n this._userChanged.emit(newUser);\n }\n }\n}\nexports.UserManager = UserManager;\n/**\n * A namespace for module-private functionality.\n *\n * Note: We do not want to export this function\n * to move it to css variables in the Theme.\n */\nvar Private;\n(function (Private) {\n /**\n * Predefined colors for users\n */\n const userColors = [\n 'var(--jp-collaborator-color1)',\n 'var(--jp-collaborator-color2)',\n 'var(--jp-collaborator-color3)',\n 'var(--jp-collaborator-color4)',\n 'var(--jp-collaborator-color5)',\n 'var(--jp-collaborator-color6)',\n 'var(--jp-collaborator-color7)'\n ];\n /**\n * Get a random color from the list of colors.\n */\n Private.getRandomColor = () => userColors[Math.floor(Math.random() * userColors.length)];\n})(Private || (Private = {}));\n//# sourceMappingURL=index.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.validateProperty = void 0;\n/**\n * Validate a property as being on an object, and optionally\n * of a given type and among a given set of values.\n */\nfunction validateProperty(\n// eslint-disable-next-line @typescript-eslint/explicit-module-boundary-types\nobject, name, typeName, values = []) {\n if (!object.hasOwnProperty(name)) {\n throw Error(`Missing property '${name}'`);\n }\n const value = object[name];\n if (typeName !== void 0) {\n let valid = true;\n switch (typeName) {\n case 'array':\n valid = Array.isArray(value);\n break;\n case 'object':\n valid = typeof value !== 'undefined';\n break;\n default:\n valid = typeof value === typeName;\n }\n if (!valid) {\n throw new Error(`Property '${name}' is not of type '${typeName}'`);\n }\n if (values.length > 0) {\n let valid = true;\n switch (typeName) {\n case 'string':\n case 'number':\n case 'boolean':\n valid = values.includes(value);\n break;\n default:\n valid = values.findIndex(v => v === value) >= 0;\n break;\n }\n if (!valid) {\n throw new Error(`Property '${name}' is not one of the valid values ${JSON.stringify(values)}`);\n }\n }\n }\n}\nexports.validateProperty = validateProperty;\n//# sourceMappingURL=validate.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.WorkspaceManager = void 0;\nconst coreutils_1 = require(\"@jupyterlab/coreutils\");\nconst statedb_1 = require(\"@jupyterlab/statedb\");\nconst serverconnection_1 = require(\"../serverconnection\");\n/**\n * The url for the lab workspaces service.\n */\nconst SERVICE_WORKSPACES_URL = 'api/workspaces';\n/**\n * The workspaces API service manager.\n */\nclass WorkspaceManager extends statedb_1.DataConnector {\n /**\n * Create a new workspace manager.\n */\n constructor(options = {}) {\n var _a;\n super();\n this.serverSettings =\n (_a = options.serverSettings) !== null && _a !== void 0 ? _a : serverconnection_1.ServerConnection.makeSettings();\n }\n /**\n * Fetch a workspace.\n *\n * @param id - The workspace's ID.\n *\n * @returns A promise that resolves if successful.\n */\n async fetch(id) {\n const { serverSettings } = this;\n const { baseUrl, appUrl } = serverSettings;\n const { makeRequest, ResponseError } = serverconnection_1.ServerConnection;\n const base = baseUrl + appUrl;\n const url = Private.url(base, id);\n const response = await makeRequest(url, {}, serverSettings);\n if (response.status !== 200) {\n const err = await ResponseError.create(response);\n throw err;\n }\n return response.json();\n }\n /**\n * Fetch the list of workspace IDs that exist on the server.\n *\n * @returns A promise that resolves if successful.\n */\n async list() {\n const { serverSettings } = this;\n const { baseUrl, appUrl } = serverSettings;\n const { makeRequest, ResponseError } = serverconnection_1.ServerConnection;\n const base = baseUrl + appUrl;\n const url = Private.url(base, '');\n const response = await makeRequest(url, {}, serverSettings);\n if (response.status !== 200) {\n const err = await ResponseError.create(response);\n throw err;\n }\n const result = await response.json();\n return result.workspaces;\n }\n /**\n * Remove a workspace from the server.\n *\n * @param id - The workspaces's ID.\n *\n * @returns A promise that resolves if successful.\n */\n async remove(id) {\n const { serverSettings } = this;\n const { baseUrl, appUrl } = serverSettings;\n const { makeRequest, ResponseError } = serverconnection_1.ServerConnection;\n const base = baseUrl + appUrl;\n const url = Private.url(base, id);\n const init = { method: 'DELETE' };\n const response = await makeRequest(url, init, serverSettings);\n if (response.status !== 204) {\n const err = await ResponseError.create(response);\n throw err;\n }\n }\n /**\n * Save a workspace.\n *\n * @param id - The workspace's ID.\n *\n * @param workspace - The workspace being saved.\n *\n * @returns A promise that resolves if successful.\n */\n async save(id, workspace) {\n const { serverSettings } = this;\n const { baseUrl, appUrl } = serverSettings;\n const { makeRequest, ResponseError } = serverconnection_1.ServerConnection;\n const base = baseUrl + appUrl;\n const url = Private.url(base, id);\n const init = { body: JSON.stringify(workspace), method: 'PUT' };\n const response = await makeRequest(url, init, serverSettings);\n if (response.status !== 204) {\n const err = await ResponseError.create(response);\n throw err;\n }\n }\n}\nexports.WorkspaceManager = WorkspaceManager;\n/**\n * A namespace for private data.\n */\nvar Private;\n(function (Private) {\n /**\n * Get the url for a workspace.\n */\n function url(base, id) {\n return coreutils_1.URLExt.join(base, SERVICE_WORKSPACES_URL, id);\n }\n Private.url = url;\n})(Private || (Private = {}));\n//# sourceMappingURL=index.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.DataConnector = void 0;\n/**\n * An abstract class that adheres to the data connector interface.\n *\n * @typeparam T - The basic entity response type a service's connector.\n *\n * @typeparam U - The basic entity request type, which is conventionally the\n * same as the response type but may be different if a service's implementation\n * requires input data to be different from output responses. Defaults to `T`.\n *\n * @typeparam V - The basic token applied to a request, conventionally a string\n * ID or filter, but may be set to a different type when an implementation\n * requires it. Defaults to `string`.\n *\n * @typeparam W - The type of the optional `query` parameter of the `list`\n * method. Defaults to `string`.\n *\n * #### Notes\n * The only abstract method in this class is the `fetch` method, which must be\n * reimplemented by all subclasses. The `remove` and `save` methods have a\n * default implementation that returns a promise that will always reject. This\n * class is a convenience superclass for connectors that only need to `fetch`.\n */\nclass DataConnector {\n /**\n * Retrieve the list of items available from the data connector.\n *\n * @param query - The optional query filter to apply to the connector request.\n *\n * @returns A promise that always rejects with an error.\n *\n * #### Notes\n * Subclasses should reimplement if they support a back-end that can list.\n */\n async list(query) {\n throw new Error('DataConnector#list method has not been implemented.');\n }\n /**\n * Remove a value using the data connector.\n *\n * @param id - The identifier for the data being removed.\n *\n * @returns A promise that always rejects with an error.\n *\n * #### Notes\n * Subclasses should reimplement if they support a back-end that can remove.\n */\n async remove(id) {\n throw new Error('DataConnector#remove method has not been implemented.');\n }\n /**\n * Save a value using the data connector.\n *\n * @param id - The identifier for the data being saved.\n *\n * @param value - The data being saved.\n *\n * @returns A promise that always rejects with an error.\n *\n * #### Notes\n * Subclasses should reimplement if they support a back-end that can save.\n */\n async save(id, value) {\n throw new Error('DataConnector#save method has not been implemented.');\n }\n}\nexports.DataConnector = DataConnector;\n//# sourceMappingURL=dataconnector.js.map","\"use strict\";\n/* -----------------------------------------------------------------------------\n| Copyright (c) Jupyter Development Team.\n| Distributed under the terms of the Modified BSD License.\n|----------------------------------------------------------------------------*/\n/**\n * @packageDocumentation\n * @module statedb\n */\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n var desc = Object.getOwnPropertyDescriptor(m, k);\n if (!desc || (\"get\" in desc ? !m.__esModule : desc.writable || desc.configurable)) {\n desc = { enumerable: true, get: function() { return m[k]; } };\n }\n Object.defineProperty(o, k2, desc);\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __exportStar = (this && this.__exportStar) || function(m, exports) {\n for (var p in m) if (p !== \"default\" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n__exportStar(require(\"./dataconnector\"), exports);\n__exportStar(require(\"./interfaces\"), exports);\n__exportStar(require(\"./restorablepool\"), exports);\n__exportStar(require(\"./statedb\"), exports);\n__exportStar(require(\"./tokens\"), exports);\n//# sourceMappingURL=index.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\n//# sourceMappingURL=interfaces.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.RestorablePool = void 0;\nconst coreutils_1 = require(\"@lumino/coreutils\");\nconst properties_1 = require(\"@lumino/properties\");\nconst signaling_1 = require(\"@lumino/signaling\");\n/**\n * An object pool that supports restoration.\n *\n * @typeparam T - The type of object being tracked.\n */\nclass RestorablePool {\n /**\n * Create a new restorable pool.\n *\n * @param options - The instantiation options for a restorable pool.\n */\n constructor(options) {\n this._added = new signaling_1.Signal(this);\n this._current = null;\n this._currentChanged = new signaling_1.Signal(this);\n this._hasRestored = false;\n this._isDisposed = false;\n this._objects = new Set();\n this._restore = null;\n this._restored = new coreutils_1.PromiseDelegate();\n this._updated = new signaling_1.Signal(this);\n this.namespace = options.namespace;\n }\n /**\n * A signal emitted when an object object is added.\n *\n * #### Notes\n * This signal will only fire when an object is added to the pool.\n * It will not fire if an object injected into the pool.\n */\n get added() {\n return this._added;\n }\n /**\n * The current object.\n *\n * #### Notes\n * The restorable pool does not set `current`. It is intended for client use.\n *\n * If `current` is set to an object that does not exist in the pool, it is a\n * no-op.\n */\n get current() {\n return this._current;\n }\n set current(obj) {\n if (this._current === obj) {\n return;\n }\n if (obj !== null && this._objects.has(obj)) {\n this._current = obj;\n this._currentChanged.emit(this._current);\n }\n }\n /**\n * A signal emitted when the current widget changes.\n */\n get currentChanged() {\n return this._currentChanged;\n }\n /**\n * Test whether the pool is disposed.\n */\n get isDisposed() {\n return this._isDisposed;\n }\n /**\n * A promise resolved when the restorable pool has been restored.\n */\n get restored() {\n return this._restored.promise;\n }\n /**\n * The number of objects held by the pool.\n */\n get size() {\n return this._objects.size;\n }\n /**\n * A signal emitted when an object is updated.\n */\n get updated() {\n return this._updated;\n }\n /**\n * Add a new object to the pool.\n *\n * @param obj - The object object being added.\n *\n * #### Notes\n * The object passed into the pool is added synchronously; its existence in\n * the pool can be checked with the `has()` method. The promise this method\n * returns resolves after the object has been added and saved to an underlying\n * restoration connector, if one is available.\n */\n async add(obj) {\n var _a, _b;\n if (obj.isDisposed) {\n const warning = 'A disposed object cannot be added.';\n console.warn(warning, obj);\n throw new Error(warning);\n }\n if (this._objects.has(obj)) {\n const warning = 'This object already exists in the pool.';\n console.warn(warning, obj);\n throw new Error(warning);\n }\n this._objects.add(obj);\n obj.disposed.connect(this._onInstanceDisposed, this);\n if (Private.injectedProperty.get(obj)) {\n return;\n }\n if (this._restore) {\n const { connector } = this._restore;\n const objName = this._restore.name(obj);\n if (objName) {\n const name = `${this.namespace}:${objName}`;\n const data = (_b = (_a = this._restore).args) === null || _b === void 0 ? void 0 : _b.call(_a, obj);\n Private.nameProperty.set(obj, name);\n await connector.save(name, { data });\n }\n }\n // Emit the added signal.\n this._added.emit(obj);\n }\n /**\n * Dispose of the resources held by the pool.\n *\n * #### Notes\n * Disposing a pool does not affect the underlying data in the data connector,\n * it simply disposes the client-side pool without making any connector calls.\n */\n dispose() {\n if (this.isDisposed) {\n return;\n }\n this._current = null;\n this._isDisposed = true;\n this._objects.clear();\n signaling_1.Signal.clearData(this);\n }\n /**\n * Find the first object in the pool that satisfies a filter function.\n *\n * @param - fn The filter function to call on each object.\n */\n find(fn) {\n const values = this._objects.values();\n for (const value of values) {\n if (fn(value)) {\n return value;\n }\n }\n return undefined;\n }\n /**\n * Iterate through each object in the pool.\n *\n * @param fn - The function to call on each object.\n */\n forEach(fn) {\n this._objects.forEach(fn);\n }\n /**\n * Filter the objects in the pool based on a predicate.\n *\n * @param fn - The function by which to filter.\n */\n filter(fn) {\n const filtered = [];\n this.forEach(obj => {\n if (fn(obj)) {\n filtered.push(obj);\n }\n });\n return filtered;\n }\n /**\n * Inject an object into the restorable pool without the pool handling its\n * restoration lifecycle.\n *\n * @param obj - The object to inject into the pool.\n */\n inject(obj) {\n Private.injectedProperty.set(obj, true);\n return this.add(obj);\n }\n /**\n * Check if this pool has the specified object.\n *\n * @param obj - The object whose existence is being checked.\n */\n has(obj) {\n return this._objects.has(obj);\n }\n /**\n * Restore the objects in this pool's namespace.\n *\n * @param options - The configuration options that describe restoration.\n *\n * @returns A promise that resolves when restoration has completed.\n *\n * #### Notes\n * This function should almost never be invoked by client code. Its primary\n * use case is to be invoked by a layout restorer plugin that handles\n * multiple restorable pools and, when ready, asks them each to restore their\n * respective objects.\n */\n async restore(options) {\n if (this._hasRestored) {\n throw new Error('This pool has already been restored.');\n }\n this._hasRestored = true;\n const { command, connector, registry, when } = options;\n const namespace = this.namespace;\n const promises = when\n ? [connector.list(namespace)].concat(when)\n : [connector.list(namespace)];\n this._restore = options;\n const [saved] = await Promise.all(promises);\n const values = await Promise.all(saved.ids.map(async (id, index) => {\n const value = saved.values[index];\n const args = value && value.data;\n if (args === undefined) {\n return connector.remove(id);\n }\n // Execute the command and if it fails, delete the state restore data.\n return registry\n .execute(command, args)\n .catch(() => connector.remove(id));\n }));\n this._restored.resolve();\n return values;\n }\n /**\n * Save the restore data for a given object.\n *\n * @param obj - The object being saved.\n */\n async save(obj) {\n var _a, _b;\n const injected = Private.injectedProperty.get(obj);\n if (!this._restore || !this.has(obj) || injected) {\n return;\n }\n const { connector } = this._restore;\n const objName = this._restore.name(obj);\n const oldName = Private.nameProperty.get(obj);\n const newName = objName ? `${this.namespace}:${objName}` : '';\n if (oldName && oldName !== newName) {\n await connector.remove(oldName);\n }\n // Set the name property irrespective of whether the new name is null.\n Private.nameProperty.set(obj, newName);\n if (newName) {\n const data = (_b = (_a = this._restore).args) === null || _b === void 0 ? void 0 : _b.call(_a, obj);\n await connector.save(newName, { data });\n }\n if (oldName !== newName) {\n this._updated.emit(obj);\n }\n }\n /**\n * Clean up after disposed objects.\n */\n _onInstanceDisposed(obj) {\n this._objects.delete(obj);\n if (obj === this._current) {\n this._current = null;\n this._currentChanged.emit(this._current);\n }\n if (Private.injectedProperty.get(obj)) {\n return;\n }\n if (!this._restore) {\n return;\n }\n const { connector } = this._restore;\n const name = Private.nameProperty.get(obj);\n if (name) {\n void connector.remove(name);\n }\n }\n}\nexports.RestorablePool = RestorablePool;\n/*\n * A namespace for private data.\n */\nvar Private;\n(function (Private) {\n /**\n * An attached property to indicate whether an object has been injected.\n */\n Private.injectedProperty = new properties_1.AttachedProperty({\n name: 'injected',\n create: () => false\n });\n /**\n * An attached property for an object's ID.\n */\n Private.nameProperty = new properties_1.AttachedProperty({\n name: 'name',\n create: () => ''\n });\n})(Private || (Private = {}));\n//# sourceMappingURL=restorablepool.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.StateDB = void 0;\nconst signaling_1 = require(\"@lumino/signaling\");\n/**\n * The default concrete implementation of a state database.\n */\nclass StateDB {\n /**\n * Create a new state database.\n *\n * @param options - The instantiation options for a state database.\n */\n constructor(options = {}) {\n this._changed = new signaling_1.Signal(this);\n const { connector, transform } = options;\n this._connector = connector || new StateDB.Connector();\n if (!transform) {\n this._ready = Promise.resolve(undefined);\n }\n else {\n this._ready = transform.then(transformation => {\n const { contents, type } = transformation;\n switch (type) {\n case 'cancel':\n return;\n case 'clear':\n return this._clear();\n case 'merge':\n return this._merge(contents || {});\n case 'overwrite':\n return this._overwrite(contents || {});\n default:\n return;\n }\n });\n }\n }\n /**\n * A signal that emits the change type any time a value changes.\n */\n get changed() {\n return this._changed;\n }\n /**\n * Clear the entire database.\n */\n async clear() {\n await this._ready;\n await this._clear();\n }\n /**\n * Retrieve a saved bundle from the database.\n *\n * @param id - The identifier used to retrieve a data bundle.\n *\n * @returns A promise that bears a data payload if available.\n *\n * #### Notes\n * The `id` values of stored items in the state database are formatted:\n * `'namespace:identifier'`, which is the same convention that command\n * identifiers in JupyterLab use as well. While this is not a technical\n * requirement for `fetch()`, `remove()`, and `save()`, it *is* necessary for\n * using the `list(namespace: string)` method.\n *\n * The promise returned by this method may be rejected if an error occurs in\n * retrieving the data. Non-existence of an `id` will succeed with the `value`\n * `undefined`.\n */\n async fetch(id) {\n await this._ready;\n return this._fetch(id);\n }\n /**\n * Retrieve all the saved bundles for a namespace.\n *\n * @param filter - The namespace prefix to retrieve.\n *\n * @returns A promise that bears a collection of payloads for a namespace.\n *\n * #### Notes\n * Namespaces are entirely conventional entities. The `id` values of stored\n * items in the state database are formatted: `'namespace:identifier'`, which\n * is the same convention that command identifiers in JupyterLab use as well.\n *\n * If there are any errors in retrieving the data, they will be logged to the\n * console in order to optimistically return any extant data without failing.\n * This promise will always succeed.\n */\n async list(namespace) {\n await this._ready;\n return this._list(namespace);\n }\n /**\n * Remove a value from the database.\n *\n * @param id - The identifier for the data being removed.\n *\n * @returns A promise that is rejected if remove fails and succeeds otherwise.\n */\n async remove(id) {\n await this._ready;\n await this._remove(id);\n this._changed.emit({ id, type: 'remove' });\n }\n /**\n * Save a value in the database.\n *\n * @param id - The identifier for the data being saved.\n *\n * @param value - The data being saved.\n *\n * @returns A promise that is rejected if saving fails and succeeds otherwise.\n *\n * #### Notes\n * The `id` values of stored items in the state database are formatted:\n * `'namespace:identifier'`, which is the same convention that command\n * identifiers in JupyterLab use as well. While this is not a technical\n * requirement for `fetch()`, `remove()`, and `save()`, it *is* necessary for\n * using the `list(namespace: string)` method.\n */\n async save(id, value) {\n await this._ready;\n await this._save(id, value);\n this._changed.emit({ id, type: 'save' });\n }\n /**\n * Return a serialized copy of the state database's entire contents.\n *\n * @returns A promise that resolves with the database contents as JSON.\n */\n async toJSON() {\n await this._ready;\n const { ids, values } = await this._list();\n return values.reduce((acc, val, idx) => {\n acc[ids[idx]] = val;\n return acc;\n }, {});\n }\n /**\n * Clear the entire database.\n */\n async _clear() {\n await Promise.all((await this._list()).ids.map(id => this._remove(id)));\n }\n /**\n * Fetch a value from the database.\n */\n async _fetch(id) {\n const value = await this._connector.fetch(id);\n if (value) {\n return JSON.parse(value).v;\n }\n }\n /**\n * Fetch a list from the database.\n */\n async _list(namespace = '') {\n const { ids, values } = await this._connector.list(namespace);\n return {\n ids,\n values: values.map(val => JSON.parse(val).v)\n };\n }\n /**\n * Merge data into the state database.\n */\n async _merge(contents) {\n await Promise.all(Object.keys(contents).map(key => contents[key] && this._save(key, contents[key])));\n }\n /**\n * Overwrite the entire database with new contents.\n */\n async _overwrite(contents) {\n await this._clear();\n await this._merge(contents);\n }\n /**\n * Remove a key in the database.\n */\n async _remove(id) {\n return this._connector.remove(id);\n }\n /**\n * Save a key and its value in the database.\n */\n async _save(id, value) {\n return this._connector.save(id, JSON.stringify({ v: value }));\n }\n}\nexports.StateDB = StateDB;\n/**\n * A namespace for StateDB statics.\n */\n(function (StateDB) {\n /**\n * An in-memory string key/value data connector.\n */\n class Connector {\n constructor() {\n this._storage = {};\n }\n /**\n * Retrieve an item from the data connector.\n */\n async fetch(id) {\n return this._storage[id];\n }\n /**\n * Retrieve the list of items available from the data connector.\n *\n * @param namespace - If not empty, only keys whose first token before `:`\n * exactly match `namespace` will be returned, e.g. `foo` in `foo:bar`.\n */\n async list(namespace = '') {\n return Object.keys(this._storage).reduce((acc, val) => {\n if (namespace === '' ? true : namespace === val.split(':')[0]) {\n acc.ids.push(val);\n acc.values.push(this._storage[val]);\n }\n return acc;\n }, { ids: [], values: [] });\n }\n /**\n * Remove a value using the data connector.\n */\n async remove(id) {\n delete this._storage[id];\n }\n /**\n * Save a value using the data connector.\n */\n async save(id, value) {\n this._storage[id] = value;\n }\n }\n StateDB.Connector = Connector;\n})(StateDB = exports.StateDB || (exports.StateDB = {}));\n//# sourceMappingURL=statedb.js.map","\"use strict\";\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.IStateDB = void 0;\nconst coreutils_1 = require(\"@lumino/coreutils\");\n/**\n * The default state database token.\n */\nexports.IStateDB = new coreutils_1.Token('@jupyterlab/coreutils:IStateDB', `A service for the JupyterLab state database.\n Use this if you want to store data that will persist across page loads.\n See \"state database\" for more information.`);\n//# sourceMappingURL=tokens.js.map","// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * The namespace for array-specific algorithms.\n */\nvar ArrayExt;\n(function (ArrayExt) {\n /**\n * Find the index of the first occurrence of a value in an array.\n *\n * @param array - The array-like object to search.\n *\n * @param value - The value to locate in the array. Values are\n * compared using strict `===` equality.\n *\n * @param start - The index of the first element in the range to be\n * searched, inclusive. The default value is `0`. Negative values\n * are taken as an offset from the end of the array.\n *\n * @param stop - The index of the last element in the range to be\n * searched, inclusive. The default value is `-1`. Negative values\n * are taken as an offset from the end of the array.\n *\n * @returns The index of the first occurrence of the value, or `-1`\n * if the value is not found.\n *\n * #### Notes\n * If `stop < start` the search will wrap at the end of the array.\n *\n * #### Complexity\n * Linear.\n *\n * #### Undefined Behavior\n * A `start` or `stop` which is non-integral.\n *\n * #### Example\n * ```typescript\n * import { ArrayExt } from '@lumino/algorithm';\n *\n * let data = ['one', 'two', 'three', 'four', 'one'];\n * ArrayExt.firstIndexOf(data, 'red'); // -1\n * ArrayExt.firstIndexOf(data, 'one'); // 0\n * ArrayExt.firstIndexOf(data, 'one', 1); // 4\n * ArrayExt.firstIndexOf(data, 'two', 2); // -1\n * ArrayExt.firstIndexOf(data, 'two', 2, 1); // 1\n * ```\n */\n function firstIndexOf(array, value, start = 0, stop = -1) {\n let n = array.length;\n if (n === 0) {\n return -1;\n }\n if (start < 0) {\n start = Math.max(0, start + n);\n }\n else {\n start = Math.min(start, n - 1);\n }\n if (stop < 0) {\n stop = Math.max(0, stop + n);\n }\n else {\n stop = Math.min(stop, n - 1);\n }\n let span;\n if (stop < start) {\n span = stop + 1 + (n - start);\n }\n else {\n span = stop - start + 1;\n }\n for (let i = 0; i < span; ++i) {\n let j = (start + i) % n;\n if (array[j] === value) {\n return j;\n }\n }\n return -1;\n }\n ArrayExt.firstIndexOf = firstIndexOf;\n /**\n * Find the index of the last occurrence of a value in an array.\n *\n * @param array - The array-like object to search.\n *\n * @param value - The value to locate in the array. Values are\n * compared using strict `===` equality.\n *\n * @param start - The index of the first element in the range to be\n * searched, inclusive. The default value is `-1`. Negative values\n * are taken as an offset from the end of the array.\n *\n * @param stop - The index of the last element in the range to be\n * searched, inclusive. The default value is `0`. Negative values\n * are taken as an offset from the end of the array.\n *\n * @returns The index of the last occurrence of the value, or `-1`\n * if the value is not found.\n *\n * #### Notes\n * If `start < stop` the search will wrap at the front of the array.\n *\n * #### Complexity\n * Linear.\n *\n * #### Undefined Behavior\n * A `start` or `stop` which is non-integral.\n *\n * #### Example\n * ```typescript\n * import { ArrayExt } from '@lumino/algorithm';\n *\n * let data = ['one', 'two', 'three', 'four', 'one'];\n * ArrayExt.lastIndexOf(data, 'red'); // -1\n * ArrayExt.lastIndexOf(data, 'one'); // 4\n * ArrayExt.lastIndexOf(data, 'one', 1); // 0\n * ArrayExt.lastIndexOf(data, 'two', 0); // -1\n * ArrayExt.lastIndexOf(data, 'two', 0, 1); // 1\n * ```\n */\n function lastIndexOf(array, value, start = -1, stop = 0) {\n let n = array.length;\n if (n === 0) {\n return -1;\n }\n if (start < 0) {\n start = Math.max(0, start + n);\n }\n else {\n start = Math.min(start, n - 1);\n }\n if (stop < 0) {\n stop = Math.max(0, stop + n);\n }\n else {\n stop = Math.min(stop, n - 1);\n }\n let span;\n if (start < stop) {\n span = start + 1 + (n - stop);\n }\n else {\n span = start - stop + 1;\n }\n for (let i = 0; i < span; ++i) {\n let j = (start - i + n) % n;\n if (array[j] === value) {\n return j;\n }\n }\n return -1;\n }\n ArrayExt.lastIndexOf = lastIndexOf;\n /**\n * Find the index of the first value which matches a predicate.\n *\n * @param array - The array-like object to search.\n *\n * @param fn - The predicate function to apply to the values.\n *\n * @param start - The index of the first element in the range to be\n * searched, inclusive. The default value is `0`. Negative values\n * are taken as an offset from the end of the array.\n *\n * @param stop - The index of the last element in the range to be\n * searched, inclusive. The default value is `-1`. Negative values\n * are taken as an offset from the end of the array.\n *\n * @returns The index of the first matching value, or `-1` if no\n * matching value is found.\n *\n * #### Notes\n * If `stop < start` the search will wrap at the end of the array.\n *\n * #### Complexity\n * Linear.\n *\n * #### Undefined Behavior\n * A `start` or `stop` which is non-integral.\n *\n * Modifying the length of the array while searching.\n *\n * #### Example\n * ```typescript\n * import { ArrayExt } from '@lumino/algorithm';\n *\n * function isEven(value: number): boolean {\n * return value % 2 === 0;\n * }\n *\n * let data = [1, 2, 3, 4, 3, 2, 1];\n * ArrayExt.findFirstIndex(data, isEven); // 1\n * ArrayExt.findFirstIndex(data, isEven, 4); // 5\n * ArrayExt.findFirstIndex(data, isEven, 6); // -1\n * ArrayExt.findFirstIndex(data, isEven, 6, 5); // 1\n * ```\n */\n function findFirstIndex(array, fn, start = 0, stop = -1) {\n let n = array.length;\n if (n === 0) {\n return -1;\n }\n if (start < 0) {\n start = Math.max(0, start + n);\n }\n else {\n start = Math.min(start, n - 1);\n }\n if (stop < 0) {\n stop = Math.max(0, stop + n);\n }\n else {\n stop = Math.min(stop, n - 1);\n }\n let span;\n if (stop < start) {\n span = stop + 1 + (n - start);\n }\n else {\n span = stop - start + 1;\n }\n for (let i = 0; i < span; ++i) {\n let j = (start + i) % n;\n if (fn(array[j], j)) {\n return j;\n }\n }\n return -1;\n }\n ArrayExt.findFirstIndex = findFirstIndex;\n /**\n * Find the index of the last value which matches a predicate.\n *\n * @param object - The array-like object to search.\n *\n * @param fn - The predicate function to apply to the values.\n *\n * @param start - The index of the first element in the range to be\n * searched, inclusive. The default value is `-1`. Negative values\n * are taken as an offset from the end of the array.\n *\n * @param stop - The index of the last element in the range to be\n * searched, inclusive. The default value is `0`. Negative values\n * are taken as an offset from the end of the array.\n *\n * @returns The index of the last matching value, or `-1` if no\n * matching value is found.\n *\n * #### Notes\n * If `start < stop` the search will wrap at the front of the array.\n *\n * #### Complexity\n * Linear.\n *\n * #### Undefined Behavior\n * A `start` or `stop` which is non-integral.\n *\n * Modifying the length of the array while searching.\n *\n * #### Example\n * ```typescript\n * import { ArrayExt } from '@lumino/algorithm';\n *\n * function isEven(value: number): boolean {\n * return value % 2 === 0;\n * }\n *\n * let data = [1, 2, 3, 4, 3, 2, 1];\n * ArrayExt.findLastIndex(data, isEven); // 5\n * ArrayExt.findLastIndex(data, isEven, 4); // 3\n * ArrayExt.findLastIndex(data, isEven, 0); // -1\n * ArrayExt.findLastIndex(data, isEven, 0, 1); // 5\n * ```\n */\n function findLastIndex(array, fn, start = -1, stop = 0) {\n let n = array.length;\n if (n === 0) {\n return -1;\n }\n if (start < 0) {\n start = Math.max(0, start + n);\n }\n else {\n start = Math.min(start, n - 1);\n }\n if (stop < 0) {\n stop = Math.max(0, stop + n);\n }\n else {\n stop = Math.min(stop, n - 1);\n }\n let d;\n if (start < stop) {\n d = start + 1 + (n - stop);\n }\n else {\n d = start - stop + 1;\n }\n for (let i = 0; i < d; ++i) {\n let j = (start - i + n) % n;\n if (fn(array[j], j)) {\n return j;\n }\n }\n return -1;\n }\n ArrayExt.findLastIndex = findLastIndex;\n /**\n * Find the first value which matches a predicate.\n *\n * @param array - The array-like object to search.\n *\n * @param fn - The predicate function to apply to the values.\n *\n * @param start - The index of the first element in the range to be\n * searched, inclusive. The default value is `0`. Negative values\n * are taken as an offset from the end of the array.\n *\n * @param stop - The index of the last element in the range to be\n * searched, inclusive. The default value is `-1`. Negative values\n * are taken as an offset from the end of the array.\n *\n * @returns The first matching value, or `undefined` if no matching\n * value is found.\n *\n * #### Notes\n * If `stop < start` the search will wrap at the end of the array.\n *\n * #### Complexity\n * Linear.\n *\n * #### Undefined Behavior\n * A `start` or `stop` which is non-integral.\n *\n * Modifying the length of the array while searching.\n *\n * #### Example\n * ```typescript\n * import { ArrayExt } from '@lumino/algorithm';\n *\n * function isEven(value: number): boolean {\n * return value % 2 === 0;\n * }\n *\n * let data = [1, 2, 3, 4, 3, 2, 1];\n * ArrayExt.findFirstValue(data, isEven); // 2\n * ArrayExt.findFirstValue(data, isEven, 2); // 4\n * ArrayExt.findFirstValue(data, isEven, 6); // undefined\n * ArrayExt.findFirstValue(data, isEven, 6, 5); // 2\n * ```\n */\n function findFirstValue(array, fn, start = 0, stop = -1) {\n let index = findFirstIndex(array, fn, start, stop);\n return index !== -1 ? array[index] : undefined;\n }\n ArrayExt.findFirstValue = findFirstValue;\n /**\n * Find the last value which matches a predicate.\n *\n * @param object - The array-like object to search.\n *\n * @param fn - The predicate function to apply to the values.\n *\n * @param start - The index of the first element in the range to be\n * searched, inclusive. The default value is `-1`. Negative values\n * are taken as an offset from the end of the array.\n *\n * @param stop - The index of the last element in the range to be\n * searched, inclusive. The default value is `0`. Negative values\n * are taken as an offset from the end of the array.\n *\n * @returns The last matching value, or `undefined` if no matching\n * value is found.\n *\n * #### Notes\n * If `start < stop` the search will wrap at the front of the array.\n *\n * #### Complexity\n * Linear.\n *\n * #### Undefined Behavior\n * A `start` or `stop` which is non-integral.\n *\n * Modifying the length of the array while searching.\n *\n * #### Example\n * ```typescript\n * import { ArrayExt } from '@lumino/algorithm';\n *\n * function isEven(value: number): boolean {\n * return value % 2 === 0;\n * }\n *\n * let data = [1, 2, 3, 4, 3, 2, 1];\n * ArrayExt.findLastValue(data, isEven); // 2\n * ArrayExt.findLastValue(data, isEven, 4); // 4\n * ArrayExt.findLastValue(data, isEven, 0); // undefined\n * ArrayExt.findLastValue(data, isEven, 0, 1); // 2\n * ```\n */\n function findLastValue(array, fn, start = -1, stop = 0) {\n let index = findLastIndex(array, fn, start, stop);\n return index !== -1 ? array[index] : undefined;\n }\n ArrayExt.findLastValue = findLastValue;\n /**\n * Find the index of the first element which compares `>=` to a value.\n *\n * @param array - The sorted array-like object to search.\n *\n * @param value - The value to locate in the array.\n *\n * @param fn - The 3-way comparison function to apply to the values.\n * It should return `< 0` if an element is less than a value, `0` if\n * an element is equal to a value, or `> 0` if an element is greater\n * than a value.\n *\n * @param start - The index of the first element in the range to be\n * searched, inclusive. The default value is `0`. Negative values\n * are taken as an offset from the end of the array.\n *\n * @param stop - The index of the last element in the range to be\n * searched, inclusive. The default value is `-1`. Negative values\n * are taken as an offset from the end of the array.\n *\n * @returns The index of the first element which compares `>=` to the\n * value, or `length` if there is no such element. If the computed\n * index for `stop` is less than `start`, then the computed index\n * for `start` is returned.\n *\n * #### Notes\n * The array must already be sorted in ascending order according to\n * the comparison function.\n *\n * #### Complexity\n * Logarithmic.\n *\n * #### Undefined Behavior\n * Searching a range which is not sorted in ascending order.\n *\n * A `start` or `stop` which is non-integral.\n *\n * Modifying the length of the array while searching.\n *\n * #### Example\n * ```typescript\n * import { ArrayExt } from '@lumino/algorithm';\n *\n * function numberCmp(a: number, b: number): number {\n * return a - b;\n * }\n *\n * let data = [0, 3, 4, 7, 7, 9];\n * ArrayExt.lowerBound(data, 0, numberCmp); // 0\n * ArrayExt.lowerBound(data, 6, numberCmp); // 3\n * ArrayExt.lowerBound(data, 7, numberCmp); // 3\n * ArrayExt.lowerBound(data, -1, numberCmp); // 0\n * ArrayExt.lowerBound(data, 10, numberCmp); // 6\n * ```\n */\n function lowerBound(array, value, fn, start = 0, stop = -1) {\n let n = array.length;\n if (n === 0) {\n return 0;\n }\n if (start < 0) {\n start = Math.max(0, start + n);\n }\n else {\n start = Math.min(start, n - 1);\n }\n if (stop < 0) {\n stop = Math.max(0, stop + n);\n }\n else {\n stop = Math.min(stop, n - 1);\n }\n let begin = start;\n let span = stop - start + 1;\n while (span > 0) {\n let half = span >> 1;\n let middle = begin + half;\n if (fn(array[middle], value) < 0) {\n begin = middle + 1;\n span -= half + 1;\n }\n else {\n span = half;\n }\n }\n return begin;\n }\n ArrayExt.lowerBound = lowerBound;\n /**\n * Find the index of the first element which compares `>` than a value.\n *\n * @param array - The sorted array-like object to search.\n *\n * @param value - The value to locate in the array.\n *\n * @param fn - The 3-way comparison function to apply to the values.\n * It should return `< 0` if an element is less than a value, `0` if\n * an element is equal to a value, or `> 0` if an element is greater\n * than a value.\n *\n * @param start - The index of the first element in the range to be\n * searched, inclusive. The default value is `0`. Negative values\n * are taken as an offset from the end of the array.\n *\n * @param stop - The index of the last element in the range to be\n * searched, inclusive. The default value is `-1`. Negative values\n * are taken as an offset from the end of the array.\n *\n * @returns The index of the first element which compares `>` than the\n * value, or `length` if there is no such element. If the computed\n * index for `stop` is less than `start`, then the computed index\n * for `start` is returned.\n *\n * #### Notes\n * The array must already be sorted in ascending order according to\n * the comparison function.\n *\n * #### Complexity\n * Logarithmic.\n *\n * #### Undefined Behavior\n * Searching a range which is not sorted in ascending order.\n *\n * A `start` or `stop` which is non-integral.\n *\n * Modifying the length of the array while searching.\n *\n * #### Example\n * ```typescript\n * import { ArrayExt } from '@lumino/algorithm';\n *\n * function numberCmp(a: number, b: number): number {\n * return a - b;\n * }\n *\n * let data = [0, 3, 4, 7, 7, 9];\n * ArrayExt.upperBound(data, 0, numberCmp); // 1\n * ArrayExt.upperBound(data, 6, numberCmp); // 3\n * ArrayExt.upperBound(data, 7, numberCmp); // 5\n * ArrayExt.upperBound(data, -1, numberCmp); // 0\n * ArrayExt.upperBound(data, 10, numberCmp); // 6\n * ```\n */\n function upperBound(array, value, fn, start = 0, stop = -1) {\n let n = array.length;\n if (n === 0) {\n return 0;\n }\n if (start < 0) {\n start = Math.max(0, start + n);\n }\n else {\n start = Math.min(start, n - 1);\n }\n if (stop < 0) {\n stop = Math.max(0, stop + n);\n }\n else {\n stop = Math.min(stop, n - 1);\n }\n let begin = start;\n let span = stop - start + 1;\n while (span > 0) {\n let half = span >> 1;\n let middle = begin + half;\n if (fn(array[middle], value) > 0) {\n span = half;\n }\n else {\n begin = middle + 1;\n span -= half + 1;\n }\n }\n return begin;\n }\n ArrayExt.upperBound = upperBound;\n /**\n * Test whether two arrays are shallowly equal.\n *\n * @param a - The first array-like object to compare.\n *\n * @param b - The second array-like object to compare.\n *\n * @param fn - The comparison function to apply to the elements. It\n * should return `true` if the elements are \"equal\". The default\n * compares elements using strict `===` equality.\n *\n * @returns Whether the two arrays are shallowly equal.\n *\n * #### Complexity\n * Linear.\n *\n * #### Undefined Behavior\n * Modifying the length of the arrays while comparing.\n *\n * #### Example\n * ```typescript\n * import { ArrayExt } from '@lumino/algorithm';\n *\n * let d1 = [0, 3, 4, 7, 7, 9];\n * let d2 = [0, 3, 4, 7, 7, 9];\n * let d3 = [42];\n * ArrayExt.shallowEqual(d1, d2); // true\n * ArrayExt.shallowEqual(d2, d3); // false\n * ```\n */\n function shallowEqual(a, b, fn) {\n // Check for object identity first.\n if (a === b) {\n return true;\n }\n // Bail early if the lengths are different.\n if (a.length !== b.length) {\n return false;\n }\n // Compare each element for equality.\n for (let i = 0, n = a.length; i < n; ++i) {\n if (fn ? !fn(a[i], b[i]) : a[i] !== b[i]) {\n return false;\n }\n }\n // The array are shallowly equal.\n return true;\n }\n ArrayExt.shallowEqual = shallowEqual;\n /**\n * Create a slice of an array subject to an optional step.\n *\n * @param array - The array-like object of interest.\n *\n * @param options - The options for configuring the slice.\n *\n * @returns A new array with the specified values.\n *\n * @throws An exception if the slice `step` is `0`.\n *\n * #### Complexity\n * Linear.\n *\n * #### Undefined Behavior\n * A `start`, `stop`, or `step` which is non-integral.\n *\n * #### Example\n * ```typescript\n * import { ArrayExt } from '@lumino/algorithm';\n *\n * let data = [0, 3, 4, 7, 7, 9];\n * ArrayExt.slice(data); // [0, 3, 4, 7, 7, 9]\n * ArrayExt.slice(data, { start: 2 }); // [4, 7, 7, 9]\n * ArrayExt.slice(data, { start: 0, stop: 4 }); // [0, 3, 4, 7]\n * ArrayExt.slice(data, { step: 2 }); // [0, 4, 7]\n * ArrayExt.slice(data, { step: -1 }); // [9, 7, 7, 4, 3, 0]\n * ```\n */\n function slice(array, options = {}) {\n // Extract the options.\n let { start, stop, step } = options;\n // Set up the `step` value.\n if (step === undefined) {\n step = 1;\n }\n // Validate the step size.\n if (step === 0) {\n throw new Error('Slice `step` cannot be zero.');\n }\n // Look up the length of the array.\n let n = array.length;\n // Set up the `start` value.\n if (start === undefined) {\n start = step < 0 ? n - 1 : 0;\n }\n else if (start < 0) {\n start = Math.max(start + n, step < 0 ? -1 : 0);\n }\n else if (start >= n) {\n start = step < 0 ? n - 1 : n;\n }\n // Set up the `stop` value.\n if (stop === undefined) {\n stop = step < 0 ? -1 : n;\n }\n else if (stop < 0) {\n stop = Math.max(stop + n, step < 0 ? -1 : 0);\n }\n else if (stop >= n) {\n stop = step < 0 ? n - 1 : n;\n }\n // Compute the slice length.\n let length;\n if ((step < 0 && stop >= start) || (step > 0 && start >= stop)) {\n length = 0;\n }\n else if (step < 0) {\n length = Math.floor((stop - start + 1) / step + 1);\n }\n else {\n length = Math.floor((stop - start - 1) / step + 1);\n }\n // Compute the sliced result.\n let result = [];\n for (let i = 0; i < length; ++i) {\n result[i] = array[start + i * step];\n }\n // Return the result.\n return result;\n }\n ArrayExt.slice = slice;\n /**\n * Move an element in an array from one index to another.\n *\n * @param array - The mutable array-like object of interest.\n *\n * @param fromIndex - The index of the element to move. Negative\n * values are taken as an offset from the end of the array.\n *\n * @param toIndex - The target index of the element. Negative\n * values are taken as an offset from the end of the array.\n *\n * #### Complexity\n * Linear.\n *\n * #### Undefined Behavior\n * A `fromIndex` or `toIndex` which is non-integral.\n *\n * #### Example\n * ```typescript\n * import { ArrayExt } from from '@lumino/algorithm';\n *\n * let data = [0, 1, 2, 3, 4];\n * ArrayExt.move(data, 1, 2); // [0, 2, 1, 3, 4]\n * ArrayExt.move(data, 4, 2); // [0, 2, 4, 1, 3]\n * ```\n */\n function move(array, fromIndex, toIndex) {\n let n = array.length;\n if (n <= 1) {\n return;\n }\n if (fromIndex < 0) {\n fromIndex = Math.max(0, fromIndex + n);\n }\n else {\n fromIndex = Math.min(fromIndex, n - 1);\n }\n if (toIndex < 0) {\n toIndex = Math.max(0, toIndex + n);\n }\n else {\n toIndex = Math.min(toIndex, n - 1);\n }\n if (fromIndex === toIndex) {\n return;\n }\n let value = array[fromIndex];\n let d = fromIndex < toIndex ? 1 : -1;\n for (let i = fromIndex; i !== toIndex; i += d) {\n array[i] = array[i + d];\n }\n array[toIndex] = value;\n }\n ArrayExt.move = move;\n /**\n * Reverse an array in-place.\n *\n * @param array - The mutable array-like object of interest.\n *\n * @param start - The index of the first element in the range to be\n * reversed, inclusive. The default value is `0`. Negative values\n * are taken as an offset from the end of the array.\n *\n * @param stop - The index of the last element in the range to be\n * reversed, inclusive. The default value is `-1`. Negative values\n * are taken as an offset from the end of the array.\n *\n * #### Complexity\n * Linear.\n *\n * #### Undefined Behavior\n * A `start` or `stop` index which is non-integral.\n *\n * #### Example\n * ```typescript\n * import { ArrayExt } from '@lumino/algorithm';\n *\n * let data = [0, 1, 2, 3, 4];\n * ArrayExt.reverse(data, 1, 3); // [0, 3, 2, 1, 4]\n * ArrayExt.reverse(data, 3); // [0, 3, 2, 4, 1]\n * ArrayExt.reverse(data); // [1, 4, 2, 3, 0]\n * ```\n */\n function reverse(array, start = 0, stop = -1) {\n let n = array.length;\n if (n <= 1) {\n return;\n }\n if (start < 0) {\n start = Math.max(0, start + n);\n }\n else {\n start = Math.min(start, n - 1);\n }\n if (stop < 0) {\n stop = Math.max(0, stop + n);\n }\n else {\n stop = Math.min(stop, n - 1);\n }\n while (start < stop) {\n let a = array[start];\n let b = array[stop];\n array[start++] = b;\n array[stop--] = a;\n }\n }\n ArrayExt.reverse = reverse;\n /**\n * Rotate the elements of an array in-place.\n *\n * @param array - The mutable array-like object of interest.\n *\n * @param delta - The amount of rotation to apply to the elements. A\n * positive value will rotate the elements to the left. A negative\n * value will rotate the elements to the right.\n *\n * @param start - The index of the first element in the range to be\n * rotated, inclusive. The default value is `0`. Negative values\n * are taken as an offset from the end of the array.\n *\n * @param stop - The index of the last element in the range to be\n * rotated, inclusive. The default value is `-1`. Negative values\n * are taken as an offset from the end of the array.\n *\n * #### Complexity\n * Linear.\n *\n * #### Undefined Behavior\n * A `delta`, `start`, or `stop` which is non-integral.\n *\n * #### Example\n * ```typescript\n * import { ArrayExt } from '@lumino/algorithm';\n *\n * let data = [0, 1, 2, 3, 4];\n * ArrayExt.rotate(data, 2); // [2, 3, 4, 0, 1]\n * ArrayExt.rotate(data, -2); // [0, 1, 2, 3, 4]\n * ArrayExt.rotate(data, 10); // [0, 1, 2, 3, 4]\n * ArrayExt.rotate(data, 9); // [4, 0, 1, 2, 3]\n * ArrayExt.rotate(data, 2, 1, 3); // [4, 2, 0, 1, 3]\n * ```\n */\n function rotate(array, delta, start = 0, stop = -1) {\n let n = array.length;\n if (n <= 1) {\n return;\n }\n if (start < 0) {\n start = Math.max(0, start + n);\n }\n else {\n start = Math.min(start, n - 1);\n }\n if (stop < 0) {\n stop = Math.max(0, stop + n);\n }\n else {\n stop = Math.min(stop, n - 1);\n }\n if (start >= stop) {\n return;\n }\n let length = stop - start + 1;\n if (delta > 0) {\n delta = delta % length;\n }\n else if (delta < 0) {\n delta = ((delta % length) + length) % length;\n }\n if (delta === 0) {\n return;\n }\n let pivot = start + delta;\n reverse(array, start, pivot - 1);\n reverse(array, pivot, stop);\n reverse(array, start, stop);\n }\n ArrayExt.rotate = rotate;\n /**\n * Fill an array with a static value.\n *\n * @param array - The mutable array-like object to fill.\n *\n * @param value - The static value to use to fill the array.\n *\n * @param start - The index of the first element in the range to be\n * filled, inclusive. The default value is `0`. Negative values\n * are taken as an offset from the end of the array.\n *\n * @param stop - The index of the last element in the range to be\n * filled, inclusive. The default value is `-1`. Negative values\n * are taken as an offset from the end of the array.\n *\n * #### Notes\n * If `stop < start` the fill will wrap at the end of the array.\n *\n * #### Complexity\n * Linear.\n *\n * #### Undefined Behavior\n * A `start` or `stop` which is non-integral.\n *\n * #### Example\n * ```typescript\n * import { ArrayExt } from '@lumino/algorithm';\n *\n * let data = ['one', 'two', 'three', 'four'];\n * ArrayExt.fill(data, 'r'); // ['r', 'r', 'r', 'r']\n * ArrayExt.fill(data, 'g', 1); // ['r', 'g', 'g', 'g']\n * ArrayExt.fill(data, 'b', 2, 3); // ['r', 'g', 'b', 'b']\n * ArrayExt.fill(data, 'z', 3, 1); // ['z', 'z', 'b', 'z']\n * ```\n */\n function fill(array, value, start = 0, stop = -1) {\n let n = array.length;\n if (n === 0) {\n return;\n }\n if (start < 0) {\n start = Math.max(0, start + n);\n }\n else {\n start = Math.min(start, n - 1);\n }\n if (stop < 0) {\n stop = Math.max(0, stop + n);\n }\n else {\n stop = Math.min(stop, n - 1);\n }\n let span;\n if (stop < start) {\n span = stop + 1 + (n - start);\n }\n else {\n span = stop - start + 1;\n }\n for (let i = 0; i < span; ++i) {\n array[(start + i) % n] = value;\n }\n }\n ArrayExt.fill = fill;\n /**\n * Insert a value into an array at a specific index.\n *\n * @param array - The array of interest.\n *\n * @param index - The index at which to insert the value. Negative\n * values are taken as an offset from the end of the array.\n *\n * @param value - The value to set at the specified index.\n *\n * #### Complexity\n * Linear.\n *\n * #### Undefined Behavior\n * An `index` which is non-integral.\n *\n * #### Example\n * ```typescript\n * import { ArrayExt } from '@lumino/algorithm';\n *\n * let data = [0, 1, 2];\n * ArrayExt.insert(data, 0, -1); // [-1, 0, 1, 2]\n * ArrayExt.insert(data, 2, 12); // [-1, 0, 12, 1, 2]\n * ArrayExt.insert(data, -1, 7); // [-1, 0, 12, 1, 7, 2]\n * ArrayExt.insert(data, 6, 19); // [-1, 0, 12, 1, 7, 2, 19]\n * ```\n */\n function insert(array, index, value) {\n let n = array.length;\n if (index < 0) {\n index = Math.max(0, index + n);\n }\n else {\n index = Math.min(index, n);\n }\n for (let i = n; i > index; --i) {\n array[i] = array[i - 1];\n }\n array[index] = value;\n }\n ArrayExt.insert = insert;\n /**\n * Remove and return a value at a specific index in an array.\n *\n * @param array - The array of interest.\n *\n * @param index - The index of the value to remove. Negative values\n * are taken as an offset from the end of the array.\n *\n * @returns The value at the specified index, or `undefined` if the\n * index is out of range.\n *\n * #### Complexity\n * Linear.\n *\n * #### Undefined Behavior\n * An `index` which is non-integral.\n *\n * #### Example\n * ```typescript\n * import { ArrayExt } from '@lumino/algorithm';\n *\n * let data = [0, 12, 23, 39, 14, 12, 75];\n * ArrayExt.removeAt(data, 2); // 23\n * ArrayExt.removeAt(data, -2); // 12\n * ArrayExt.removeAt(data, 10); // undefined;\n * ```\n */\n function removeAt(array, index) {\n let n = array.length;\n if (index < 0) {\n index += n;\n }\n if (index < 0 || index >= n) {\n return undefined;\n }\n let value = array[index];\n for (let i = index + 1; i < n; ++i) {\n array[i - 1] = array[i];\n }\n array.length = n - 1;\n return value;\n }\n ArrayExt.removeAt = removeAt;\n /**\n * Remove the first occurrence of a value from an array.\n *\n * @param array - The array of interest.\n *\n * @param value - The value to remove from the array. Values are\n * compared using strict `===` equality.\n *\n * @param start - The index of the first element in the range to be\n * searched, inclusive. The default value is `0`. Negative values\n * are taken as an offset from the end of the array.\n *\n * @param stop - The index of the last element in the range to be\n * searched, inclusive. The default value is `-1`. Negative values\n * are taken as an offset from the end of the array.\n *\n * @returns The index of the removed value, or `-1` if the value\n * is not contained in the array.\n *\n * #### Notes\n * If `stop < start` the search will wrap at the end of the array.\n *\n * #### Complexity\n * Linear.\n *\n * #### Example\n * ```typescript\n * import { ArrayExt } from '@lumino/algorithm';\n *\n * let data = [0, 12, 23, 39, 14, 12, 75];\n * ArrayExt.removeFirstOf(data, 12); // 1\n * ArrayExt.removeFirstOf(data, 17); // -1\n * ArrayExt.removeFirstOf(data, 39, 3); // -1\n * ArrayExt.removeFirstOf(data, 39, 3, 2); // 2\n * ```\n */\n function removeFirstOf(array, value, start = 0, stop = -1) {\n let index = firstIndexOf(array, value, start, stop);\n if (index !== -1) {\n removeAt(array, index);\n }\n return index;\n }\n ArrayExt.removeFirstOf = removeFirstOf;\n /**\n * Remove the last occurrence of a value from an array.\n *\n * @param array - The array of interest.\n *\n * @param value - The value to remove from the array. Values are\n * compared using strict `===` equality.\n *\n * @param start - The index of the first element in the range to be\n * searched, inclusive. The default value is `-1`. Negative values\n * are taken as an offset from the end of the array.\n *\n * @param stop - The index of the last element in the range to be\n * searched, inclusive. The default value is `0`. Negative values\n * are taken as an offset from the end of the array.\n *\n * @returns The index of the removed value, or `-1` if the value\n * is not contained in the array.\n *\n * #### Notes\n * If `start < stop` the search will wrap at the end of the array.\n *\n * #### Complexity\n * Linear.\n *\n * #### Example\n * ```typescript\n * import { ArrayExt } from '@lumino/algorithm';\n *\n * let data = [0, 12, 23, 39, 14, 12, 75];\n * ArrayExt.removeLastOf(data, 12); // 5\n * ArrayExt.removeLastOf(data, 17); // -1\n * ArrayExt.removeLastOf(data, 39, 2); // -1\n * ArrayExt.removeLastOf(data, 39, 2, 3); // 3\n * ```\n */\n function removeLastOf(array, value, start = -1, stop = 0) {\n let index = lastIndexOf(array, value, start, stop);\n if (index !== -1) {\n removeAt(array, index);\n }\n return index;\n }\n ArrayExt.removeLastOf = removeLastOf;\n /**\n * Remove all occurrences of a value from an array.\n *\n * @param array - The array of interest.\n *\n * @param value - The value to remove from the array. Values are\n * compared using strict `===` equality.\n *\n * @param start - The index of the first element in the range to be\n * searched, inclusive. The default value is `0`. Negative values\n * are taken as an offset from the end of the array.\n *\n * @param stop - The index of the last element in the range to be\n * searched, inclusive. The default value is `-1`. Negative values\n * are taken as an offset from the end of the array.\n *\n * @returns The number of elements removed from the array.\n *\n * #### Notes\n * If `stop < start` the search will conceptually wrap at the end of\n * the array, however the array will be traversed front-to-back.\n *\n * #### Complexity\n * Linear.\n *\n * #### Example\n * ```typescript\n * import { ArrayExt } from '@lumino/algorithm';\n *\n * let data = [14, 12, 23, 39, 14, 12, 19, 14];\n * ArrayExt.removeAllOf(data, 12); // 2\n * ArrayExt.removeAllOf(data, 17); // 0\n * ArrayExt.removeAllOf(data, 14, 1, 4); // 1\n * ```\n */\n function removeAllOf(array, value, start = 0, stop = -1) {\n let n = array.length;\n if (n === 0) {\n return 0;\n }\n if (start < 0) {\n start = Math.max(0, start + n);\n }\n else {\n start = Math.min(start, n - 1);\n }\n if (stop < 0) {\n stop = Math.max(0, stop + n);\n }\n else {\n stop = Math.min(stop, n - 1);\n }\n let count = 0;\n for (let i = 0; i < n; ++i) {\n if (start <= stop && i >= start && i <= stop && array[i] === value) {\n count++;\n }\n else if (stop < start &&\n (i <= stop || i >= start) &&\n array[i] === value) {\n count++;\n }\n else if (count > 0) {\n array[i - count] = array[i];\n }\n }\n if (count > 0) {\n array.length = n - count;\n }\n return count;\n }\n ArrayExt.removeAllOf = removeAllOf;\n /**\n * Remove the first occurrence of a value which matches a predicate.\n *\n * @param array - The array of interest.\n *\n * @param fn - The predicate function to apply to the values.\n *\n * @param start - The index of the first element in the range to be\n * searched, inclusive. The default value is `0`. Negative values\n * are taken as an offset from the end of the array.\n *\n * @param stop - The index of the last element in the range to be\n * searched, inclusive. The default value is `-1`. Negative values\n * are taken as an offset from the end of the array.\n *\n * @returns The removed `{ index, value }`, which will be `-1` and\n * `undefined` if the value is not contained in the array.\n *\n * #### Notes\n * If `stop < start` the search will wrap at the end of the array.\n *\n * #### Complexity\n * Linear.\n *\n * #### Example\n * ```typescript\n * import { ArrayExt } from '@lumino/algorithm';\n *\n * function isEven(value: number): boolean {\n * return value % 2 === 0;\n * }\n *\n * let data = [0, 12, 23, 39, 14, 12, 75];\n * ArrayExt.removeFirstWhere(data, isEven); // { index: 0, value: 0 }\n * ArrayExt.removeFirstWhere(data, isEven, 2); // { index: 3, value: 14 }\n * ArrayExt.removeFirstWhere(data, isEven, 4); // { index: -1, value: undefined }\n * ```\n */\n function removeFirstWhere(array, fn, start = 0, stop = -1) {\n let value;\n let index = findFirstIndex(array, fn, start, stop);\n if (index !== -1) {\n value = removeAt(array, index);\n }\n return { index, value };\n }\n ArrayExt.removeFirstWhere = removeFirstWhere;\n /**\n * Remove the last occurrence of a value which matches a predicate.\n *\n * @param array - The array of interest.\n *\n * @param fn - The predicate function to apply to the values.\n *\n * @param start - The index of the first element in the range to be\n * searched, inclusive. The default value is `-1`. Negative values\n * are taken as an offset from the end of the array.\n *\n * @param stop - The index of the last element in the range to be\n * searched, inclusive. The default value is `0`. Negative values\n * are taken as an offset from the end of the array.\n *\n * @returns The removed `{ index, value }`, which will be `-1` and\n * `undefined` if the value is not contained in the array.\n *\n * #### Notes\n * If `start < stop` the search will wrap at the end of the array.\n *\n * #### Complexity\n * Linear.\n *\n * #### Example\n * ```typescript\n * import { ArrayExt } from '@lumino/algorithm';\n *\n * function isEven(value: number): boolean {\n * return value % 2 === 0;\n * }\n *\n * let data = [0, 12, 23, 39, 14, 12, 75];\n * ArrayExt.removeLastWhere(data, isEven); // { index: 5, value: 12 }\n * ArrayExt.removeLastWhere(data, isEven, 2); // { index: 1, value: 12 }\n * ArrayExt.removeLastWhere(data, isEven, 2, 1); // { index: -1, value: undefined }\n * ```\n */\n function removeLastWhere(array, fn, start = -1, stop = 0) {\n let value;\n let index = findLastIndex(array, fn, start, stop);\n if (index !== -1) {\n value = removeAt(array, index);\n }\n return { index, value };\n }\n ArrayExt.removeLastWhere = removeLastWhere;\n /**\n * Remove all occurrences of values which match a predicate.\n *\n * @param array - The array of interest.\n *\n * @param fn - The predicate function to apply to the values.\n *\n * @param start - The index of the first element in the range to be\n * searched, inclusive. The default value is `0`. Negative values\n * are taken as an offset from the end of the array.\n *\n * @param stop - The index of the last element in the range to be\n * searched, inclusive. The default value is `-1`. Negative values\n * are taken as an offset from the end of the array.\n *\n * @returns The number of elements removed from the array.\n *\n * #### Notes\n * If `stop < start` the search will conceptually wrap at the end of\n * the array, however the array will be traversed front-to-back.\n *\n * #### Complexity\n * Linear.\n *\n * #### Example\n * ```typescript\n * import { ArrayExt } from '@lumino/algorithm';\n *\n * function isEven(value: number): boolean {\n * return value % 2 === 0;\n * }\n *\n * function isNegative(value: number): boolean {\n * return value < 0;\n * }\n *\n * let data = [0, 12, -13, -9, 23, 39, 14, -15, 12, 75];\n * ArrayExt.removeAllWhere(data, isEven); // 4\n * ArrayExt.removeAllWhere(data, isNegative, 0, 3); // 2\n * ```\n */\n function removeAllWhere(array, fn, start = 0, stop = -1) {\n let n = array.length;\n if (n === 0) {\n return 0;\n }\n if (start < 0) {\n start = Math.max(0, start + n);\n }\n else {\n start = Math.min(start, n - 1);\n }\n if (stop < 0) {\n stop = Math.max(0, stop + n);\n }\n else {\n stop = Math.min(stop, n - 1);\n }\n let count = 0;\n for (let i = 0; i < n; ++i) {\n if (start <= stop && i >= start && i <= stop && fn(array[i], i)) {\n count++;\n }\n else if (stop < start && (i <= stop || i >= start) && fn(array[i], i)) {\n count++;\n }\n else if (count > 0) {\n array[i - count] = array[i];\n }\n }\n if (count > 0) {\n array.length = n - count;\n }\n return count;\n }\n ArrayExt.removeAllWhere = removeAllWhere;\n})(ArrayExt || (ArrayExt = {}));\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * Chain together several iterables.\n *\n * @deprecated\n *\n * @param objects - The iterable objects of interest.\n *\n * @returns An iterator which yields the values of the iterables\n * in the order in which they are supplied.\n *\n * #### Example\n * ```typescript\n * import { chain } from '@lumino/algorithm';\n *\n * let data1 = [1, 2, 3];\n * let data2 = [4, 5, 6];\n *\n * let stream = chain(data1, data2);\n *\n * Array.from(stream); // [1, 2, 3, 4, 5, 6]\n * ```\n */\nfunction* chain(...objects) {\n for (const object of objects) {\n yield* object;\n }\n}\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * Create an empty iterator.\n *\n * @returns A new iterator which yields nothing.\n *\n * #### Example\n * ```typescript\n * import { empty } from '@lumino/algorithm';\n *\n * let stream = empty();\n *\n * Array.from(stream); // []\n * ```\n */\n// eslint-disable-next-line require-yield\nfunction* empty() {\n return;\n}\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * Enumerate an iterable object.\n *\n * @param object - The iterable object of interest.\n *\n * @param start - The starting enum value. The default is `0`.\n *\n * @returns An iterator which yields the enumerated values.\n *\n * #### Example\n * ```typescript\n * import { enumerate } from '@lumino/algorithm';\n *\n * let data = ['foo', 'bar', 'baz'];\n *\n * let stream = enumerate(data, 1);\n *\n * Array.from(stream); // [[1, 'foo'], [2, 'bar'], [3, 'baz']]\n * ```\n */\nfunction* enumerate(object, start = 0) {\n for (const value of object) {\n yield [start++, value];\n }\n}\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * Filter an iterable for values which pass a test.\n *\n * @param object - The iterable object of interest.\n *\n * @param fn - The predicate function to invoke for each value.\n *\n * @returns An iterator which yields the values which pass the test.\n *\n * #### Example\n * ```typescript\n * import { filter } from '@lumino/algorithm';\n *\n * let data = [1, 2, 3, 4, 5, 6];\n *\n * let stream = filter(data, value => value % 2 === 0);\n *\n * Array.from(stream); // [2, 4, 6]\n * ```\n */\nfunction* filter(object, fn) {\n let index = 0;\n for (const value of object) {\n if (fn(value, index++)) {\n yield value;\n }\n }\n}\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * Find the first value in an iterable which matches a predicate.\n *\n * @param object - The iterable object to search.\n *\n * @param fn - The predicate function to apply to the values.\n *\n * @returns The first matching value, or `undefined` if no matching\n * value is found.\n *\n * #### Complexity\n * Linear.\n *\n * #### Example\n * ```typescript\n * import { find } from '@lumino/algorithm';\n *\n * interface IAnimal { species: string, name: string };\n *\n * function isCat(value: IAnimal): boolean {\n * return value.species === 'cat';\n * }\n *\n * let data: IAnimal[] = [\n * { species: 'dog', name: 'spot' },\n * { species: 'cat', name: 'fluffy' },\n * { species: 'alligator', name: 'pocho' }\n * ];\n *\n * find(data, isCat).name; // 'fluffy'\n * ```\n */\nfunction find(object, fn) {\n let index = 0;\n for (const value of object) {\n if (fn(value, index++)) {\n return value;\n }\n }\n return undefined;\n}\n/**\n * Find the index of the first value which matches a predicate.\n *\n * @param object - The iterable object to search.\n *\n * @param fn - The predicate function to apply to the values.\n *\n * @returns The index of the first matching value, or `-1` if no\n * matching value is found.\n *\n * #### Complexity\n * Linear.\n *\n * #### Example\n * ```typescript\n * import { findIndex } from '@lumino/algorithm';\n *\n * interface IAnimal { species: string, name: string };\n *\n * function isCat(value: IAnimal): boolean {\n * return value.species === 'cat';\n * }\n *\n * let data: IAnimal[] = [\n * { species: 'dog', name: 'spot' },\n * { species: 'cat', name: 'fluffy' },\n * { species: 'alligator', name: 'pocho' }\n * ];\n *\n * findIndex(data, isCat); // 1\n * ```\n */\nfunction findIndex(object, fn) {\n let index = 0;\n for (const value of object) {\n if (fn(value, index++)) {\n return index - 1;\n }\n }\n return -1;\n}\n/**\n * Find the minimum value in an iterable.\n *\n * @param object - The iterable object to search.\n *\n * @param fn - The 3-way comparison function to apply to the values.\n * It should return `< 0` if the first value is less than the second.\n * `0` if the values are equivalent, or `> 0` if the first value is\n * greater than the second.\n *\n * @returns The minimum value in the iterable. If multiple values are\n * equivalent to the minimum, the left-most value is returned. If\n * the iterable is empty, this returns `undefined`.\n *\n * #### Complexity\n * Linear.\n *\n * #### Example\n * ```typescript\n * import { min } from '@lumino/algorithm';\n *\n * function numberCmp(a: number, b: number): number {\n * return a - b;\n * }\n *\n * min([7, 4, 0, 3, 9, 4], numberCmp); // 0\n * ```\n */\nfunction min(object, fn) {\n let result = undefined;\n for (const value of object) {\n if (result === undefined) {\n result = value;\n continue;\n }\n if (fn(value, result) < 0) {\n result = value;\n }\n }\n return result;\n}\n/**\n * Find the maximum value in an iterable.\n *\n * @param object - The iterable object to search.\n *\n * @param fn - The 3-way comparison function to apply to the values.\n * It should return `< 0` if the first value is less than the second.\n * `0` if the values are equivalent, or `> 0` if the first value is\n * greater than the second.\n *\n * @returns The maximum value in the iterable. If multiple values are\n * equivalent to the maximum, the left-most value is returned. If\n * the iterable is empty, this returns `undefined`.\n *\n * #### Complexity\n * Linear.\n *\n * #### Example\n * ```typescript\n * import { max } from '@lumino/algorithm';\n *\n * function numberCmp(a: number, b: number): number {\n * return a - b;\n * }\n *\n * max([7, 4, 0, 3, 9, 4], numberCmp); // 9\n * ```\n */\nfunction max(object, fn) {\n let result = undefined;\n for (const value of object) {\n if (result === undefined) {\n result = value;\n continue;\n }\n if (fn(value, result) > 0) {\n result = value;\n }\n }\n return result;\n}\n/**\n * Find the minimum and maximum values in an iterable.\n *\n * @param object - The iterable object to search.\n *\n * @param fn - The 3-way comparison function to apply to the values.\n * It should return `< 0` if the first value is less than the second.\n * `0` if the values are equivalent, or `> 0` if the first value is\n * greater than the second.\n *\n * @returns A 2-tuple of the `[min, max]` values in the iterable. If\n * multiple values are equivalent, the left-most values are returned.\n * If the iterable is empty, this returns `undefined`.\n *\n * #### Complexity\n * Linear.\n *\n * #### Example\n * ```typescript\n * import { minmax } from '@lumino/algorithm';\n *\n * function numberCmp(a: number, b: number): number {\n * return a - b;\n * }\n *\n * minmax([7, 4, 0, 3, 9, 4], numberCmp); // [0, 9]\n * ```\n */\nfunction minmax(object, fn) {\n let empty = true;\n let vmin;\n let vmax;\n for (const value of object) {\n if (empty) {\n vmin = value;\n vmax = value;\n empty = false;\n }\n else if (fn(value, vmin) < 0) {\n vmin = value;\n }\n else if (fn(value, vmax) > 0) {\n vmax = value;\n }\n }\n return empty ? undefined : [vmin, vmax];\n}\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * Create an array from an iterable of values.\n *\n * @deprecated\n *\n * @param object - The iterable object of interest.\n *\n * @returns A new array of values from the given object.\n *\n * #### Example\n * ```typescript\n * import { toArray } from '@lumino/algorithm';\n *\n * let stream = [1, 2, 3, 4, 5, 6][Symbol.iterator]();\n *\n * toArray(stream); // [1, 2, 3, 4, 5, 6];\n * ```\n */\nfunction toArray(object) {\n return Array.from(object);\n}\n/**\n * Create an object from an iterable of key/value pairs.\n *\n * @param object - The iterable object of interest.\n *\n * @returns A new object mapping keys to values.\n *\n * #### Example\n * ```typescript\n * import { toObject } from '@lumino/algorithm';\n *\n * let data: [string, number][] = [['one', 1], ['two', 2], ['three', 3]];\n *\n * toObject(data); // { one: 1, two: 2, three: 3 }\n * ```\n */\nfunction toObject(object) {\n const result = {};\n for (const [key, value] of object) {\n result[key] = value;\n }\n return result;\n}\n/**\n * Invoke a function for each value in an iterable.\n *\n * @deprecated\n *\n * @param object - The iterable object of interest.\n *\n * @param fn - The callback function to invoke for each value.\n *\n * #### Notes\n * Iteration can be terminated early by returning `false` from the\n * callback function.\n *\n * #### Complexity\n * Linear.\n *\n * #### Example\n * ```typescript\n * import { each } from '@lumino/algorithm';\n *\n * let data = [5, 7, 0, -2, 9];\n *\n * each(data, value => { console.log(value); });\n * ```\n */\nfunction each(object, fn) {\n let index = 0;\n for (const value of object) {\n if (false === fn(value, index++)) {\n return;\n }\n }\n}\n/**\n * Test whether all values in an iterable satisfy a predicate.\n *\n * @param object - The iterable object of interest.\n *\n * @param fn - The predicate function to invoke for each value.\n *\n * @returns `true` if all values pass the test, `false` otherwise.\n *\n * #### Notes\n * Iteration terminates on the first `false` predicate result.\n *\n * #### Complexity\n * Linear.\n *\n * #### Example\n * ```typescript\n * import { every } from '@lumino/algorithm';\n *\n * let data = [5, 7, 1];\n *\n * every(data, value => value % 2 === 0); // false\n * every(data, value => value % 2 === 1); // true\n * ```\n */\nfunction every(object, fn) {\n let index = 0;\n for (const value of object) {\n if (false === fn(value, index++)) {\n return false;\n }\n }\n return true;\n}\n/**\n * Test whether any value in an iterable satisfies a predicate.\n *\n * @param object - The iterable object of interest.\n *\n * @param fn - The predicate function to invoke for each value.\n *\n * @returns `true` if any value passes the test, `false` otherwise.\n *\n * #### Notes\n * Iteration terminates on the first `true` predicate result.\n *\n * #### Complexity\n * Linear.\n *\n * #### Example\n * ```typescript\n * import { some } from '@lumino/algorithm';\n *\n * let data = [5, 7, 1];\n *\n * some(data, value => value === 7); // true\n * some(data, value => value === 3); // false\n * ```\n */\nfunction some(object, fn) {\n let index = 0;\n for (const value of object) {\n if (fn(value, index++)) {\n return true;\n }\n }\n return false;\n}\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * Transform the values of an iterable with a mapping function.\n *\n * @param object - The iterable object of interest.\n *\n * @param fn - The mapping function to invoke for each value.\n *\n * @returns An iterator which yields the transformed values.\n *\n * #### Example\n * ```typescript\n * import { map } from '@lumino/algorithm';\n *\n * let data = [1, 2, 3];\n *\n * let stream = map(data, value => value * 2);\n *\n * Array.from(stream); // [2, 4, 6]\n * ```\n */\nfunction* map(object, fn) {\n let index = 0;\n for (const value of object) {\n yield fn(value, index++);\n }\n}\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * Create an iterator of evenly spaced values.\n *\n * @param start - The starting value for the range, inclusive.\n *\n * @param stop - The stopping value for the range, exclusive.\n *\n * @param step - The distance between each value.\n *\n * @returns An iterator which produces evenly spaced values.\n *\n * #### Notes\n * In the single argument form of `range(stop)`, `start` defaults to\n * `0` and `step` defaults to `1`.\n *\n * In the two argument form of `range(start, stop)`, `step` defaults\n * to `1`.\n *\n * #### Example\n * ```typescript\n * import { range } from '@lumino/algorithm';\n *\n * let stream = range(2, 4);\n *\n * Array.from(stream); // [2, 3]\n * ```\n */\nfunction* range(start, stop, step) {\n if (stop === undefined) {\n stop = start;\n start = 0;\n step = 1;\n }\n else if (step === undefined) {\n step = 1;\n }\n const length = Private.rangeLength(start, stop, step);\n for (let index = 0; index < length; index++) {\n yield start + step * index;\n }\n}\n/**\n * The namespace for the module implementation details.\n */\nvar Private;\n(function (Private) {\n /**\n * Compute the effective length of a range.\n *\n * @param start - The starting value for the range, inclusive.\n *\n * @param stop - The stopping value for the range, exclusive.\n *\n * @param step - The distance between each value.\n *\n * @returns The number of steps need to traverse the range.\n */\n function rangeLength(start, stop, step) {\n if (step === 0) {\n return Infinity;\n }\n if (start > stop && step > 0) {\n return 0;\n }\n if (start < stop && step < 0) {\n return 0;\n }\n return Math.ceil((stop - start) / step);\n }\n Private.rangeLength = rangeLength;\n})(Private || (Private = {}));\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\nfunction reduce(object, fn, initial) {\n // Setup the iterator and fetch the first value.\n const it = object[Symbol.iterator]();\n let index = 0;\n let first = it.next();\n // An empty iterator and no initial value is an error.\n if (first.done && initial === undefined) {\n throw new TypeError('Reduce of empty iterable with no initial value.');\n }\n // If the iterator is empty, return the initial value.\n if (first.done) {\n return initial;\n }\n // If the iterator has a single item and no initial value, the\n // reducer is not invoked and the first item is the return value.\n let second = it.next();\n if (second.done && initial === undefined) {\n return first.value;\n }\n // If iterator has a single item and an initial value is provided,\n // the reducer is invoked and that result is the return value.\n if (second.done) {\n return fn(initial, first.value, index++);\n }\n // Setup the initial accumlated value.\n let accumulator;\n if (initial === undefined) {\n accumulator = fn(first.value, second.value, index++);\n }\n else {\n accumulator = fn(fn(initial, first.value, index++), second.value, index++);\n }\n // Iterate the rest of the values, updating the accumulator.\n let next;\n while (!(next = it.next()).done) {\n accumulator = fn(accumulator, next.value, index++);\n }\n // Return the final accumulated value.\n return accumulator;\n}\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * Create an iterator which repeats a value a number of times.\n *\n * @deprecated\n *\n * @param value - The value to repeat.\n *\n * @param count - The number of times to repeat the value.\n *\n * @returns A new iterator which repeats the specified value.\n *\n * #### Example\n * ```typescript\n * import { repeat } from '@lumino/algorithm';\n *\n * let stream = repeat(7, 3);\n *\n * Array.from(stream); // [7, 7, 7]\n * ```\n */\nfunction* repeat(value, count) {\n while (0 < count--) {\n yield value;\n }\n}\n/**\n * Create an iterator which yields a value a single time.\n *\n * @deprecated\n *\n * @param value - The value to wrap in an iterator.\n *\n * @returns A new iterator which yields the value a single time.\n *\n * #### Example\n * ```typescript\n * import { once } from '@lumino/algorithm';\n *\n * let stream = once(7);\n *\n * Array.from(stream); // [7]\n * ```\n */\nfunction* once(value) {\n yield value;\n}\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * Create an iterator for a retroable object.\n *\n * @param object - The retroable or array-like object of interest.\n *\n * @returns An iterator which traverses the object's values in reverse.\n *\n * #### Example\n * ```typescript\n * import { retro } from '@lumino/algorithm';\n *\n * let data = [1, 2, 3, 4, 5, 6];\n *\n * let stream = retro(data);\n *\n * Array.from(stream); // [6, 5, 4, 3, 2, 1]\n * ```\n */\nfunction* retro(object) {\n if (typeof object.retro === 'function') {\n yield* object.retro();\n }\n else {\n for (let index = object.length - 1; index > -1; index--) {\n yield object[index];\n }\n }\n}\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * Topologically sort an iterable of edges.\n *\n * @param edges - The iterable object of edges to sort.\n * An edge is represented as a 2-tuple of `[fromNode, toNode]`.\n *\n * @returns The topologically sorted array of nodes.\n *\n * #### Notes\n * If a cycle is present in the graph, the cycle will be ignored and\n * the return value will be only approximately sorted.\n *\n * #### Example\n * ```typescript\n * import { topologicSort } from '@lumino/algorithm';\n *\n * let data = [\n * ['d', 'e'],\n * ['c', 'd'],\n * ['a', 'b'],\n * ['b', 'c']\n * ];\n *\n * topologicSort(data); // ['a', 'b', 'c', 'd', 'e']\n * ```\n */\nfunction topologicSort(edges) {\n // Setup the shared sorting state.\n let sorted = [];\n let visited = new Set();\n let graph = new Map();\n // Add the edges to the graph.\n for (const edge of edges) {\n addEdge(edge);\n }\n // Visit each node in the graph.\n for (const [k] of graph) {\n visit(k);\n }\n // Return the sorted results.\n return sorted;\n // Add an edge to the graph.\n function addEdge(edge) {\n let [fromNode, toNode] = edge;\n let children = graph.get(toNode);\n if (children) {\n children.push(fromNode);\n }\n else {\n graph.set(toNode, [fromNode]);\n }\n }\n // Recursively visit the node.\n function visit(node) {\n if (visited.has(node)) {\n return;\n }\n visited.add(node);\n let children = graph.get(node);\n if (children) {\n for (const child of children) {\n visit(child);\n }\n }\n sorted.push(node);\n }\n}\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * Iterate over an iterable using a stepped increment.\n *\n * @param object - The iterable object of interest.\n *\n * @param step - The distance to step on each iteration. A value\n * of less than `1` will behave the same as a value of `1`.\n *\n * @returns An iterator which traverses the iterable step-wise.\n *\n * #### Example\n * ```typescript\n * import { stride } from '@lumino/algorithm';\n *\n * let data = [1, 2, 3, 4, 5, 6];\n *\n * let stream = stride(data, 2);\n *\n * Array.from(stream); // [1, 3, 5];\n * ```\n */\nfunction* stride(object, step) {\n let count = 0;\n for (const value of object) {\n if (0 === count++ % step) {\n yield value;\n }\n }\n}\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * The namespace for string-specific algorithms.\n */\nvar StringExt;\n(function (StringExt) {\n /**\n * Find the indices of characters in a source text.\n *\n * @param source - The source text which should be searched.\n *\n * @param query - The characters to locate in the source text.\n *\n * @param start - The index to start the search.\n *\n * @returns The matched indices, or `null` if there is no match.\n *\n * #### Complexity\n * Linear on `sourceText`.\n *\n * #### Notes\n * In order for there to be a match, all of the characters in `query`\n * **must** appear in `source` in the order given by `query`.\n *\n * Characters are matched using strict `===` equality.\n */\n function findIndices(source, query, start = 0) {\n let indices = new Array(query.length);\n for (let i = 0, j = start, n = query.length; i < n; ++i, ++j) {\n j = source.indexOf(query[i], j);\n if (j === -1) {\n return null;\n }\n indices[i] = j;\n }\n return indices;\n }\n StringExt.findIndices = findIndices;\n /**\n * A string matcher which uses a sum-of-squares algorithm.\n *\n * @param source - The source text which should be searched.\n *\n * @param query - The characters to locate in the source text.\n *\n * @param start - The index to start the search.\n *\n * @returns The match result, or `null` if there is no match.\n * A lower `score` represents a stronger match.\n *\n * #### Complexity\n * Linear on `sourceText`.\n *\n * #### Notes\n * This scoring algorithm uses a sum-of-squares approach to determine\n * the score. In order for there to be a match, all of the characters\n * in `query` **must** appear in `source` in order. The index of each\n * matching character is squared and added to the score. This means\n * that early and consecutive character matches are preferred, while\n * late matches are heavily penalized.\n */\n function matchSumOfSquares(source, query, start = 0) {\n let indices = findIndices(source, query, start);\n if (!indices) {\n return null;\n }\n let score = 0;\n for (let i = 0, n = indices.length; i < n; ++i) {\n let j = indices[i] - start;\n score += j * j;\n }\n return { score, indices };\n }\n StringExt.matchSumOfSquares = matchSumOfSquares;\n /**\n * A string matcher which uses a sum-of-deltas algorithm.\n *\n * @param source - The source text which should be searched.\n *\n * @param query - The characters to locate in the source text.\n *\n * @param start - The index to start the search.\n *\n * @returns The match result, or `null` if there is no match.\n * A lower `score` represents a stronger match.\n *\n * #### Complexity\n * Linear on `sourceText`.\n *\n * #### Notes\n * This scoring algorithm uses a sum-of-deltas approach to determine\n * the score. In order for there to be a match, all of the characters\n * in `query` **must** appear in `source` in order. The delta between\n * the indices are summed to create the score. This means that groups\n * of matched characters are preferred, while fragmented matches are\n * penalized.\n */\n function matchSumOfDeltas(source, query, start = 0) {\n let indices = findIndices(source, query, start);\n if (!indices) {\n return null;\n }\n let score = 0;\n let last = start - 1;\n for (let i = 0, n = indices.length; i < n; ++i) {\n let j = indices[i];\n score += j - last - 1;\n last = j;\n }\n return { score, indices };\n }\n StringExt.matchSumOfDeltas = matchSumOfDeltas;\n /**\n * Highlight the matched characters of a source text.\n *\n * @param source - The text which should be highlighted.\n *\n * @param indices - The indices of the matched characters. They must\n * appear in increasing order and must be in bounds of the source.\n *\n * @param fn - The function to apply to the matched chunks.\n *\n * @returns An array of unmatched and highlighted chunks.\n */\n function highlight(source, indices, fn) {\n // Set up the result array.\n let result = [];\n // Set up the counter variables.\n let k = 0;\n let last = 0;\n let n = indices.length;\n // Iterator over each index.\n while (k < n) {\n // Set up the chunk indices.\n let i = indices[k];\n let j = indices[k];\n // Advance the right chunk index until it's non-contiguous.\n while (++k < n && indices[k] === j + 1) {\n j++;\n }\n // Extract the unmatched text.\n if (last < i) {\n result.push(source.slice(last, i));\n }\n // Extract and highlight the matched text.\n if (i < j + 1) {\n result.push(fn(source.slice(i, j + 1)));\n }\n // Update the last visited index.\n last = j + 1;\n }\n // Extract any remaining unmatched text.\n if (last < source.length) {\n result.push(source.slice(last));\n }\n // Return the highlighted result.\n return result;\n }\n StringExt.highlight = highlight;\n /**\n * A 3-way string comparison function.\n *\n * @param a - The first string of interest.\n *\n * @param b - The second string of interest.\n *\n * @returns `-1` if `a < b`, else `1` if `a > b`, else `0`.\n */\n function cmp(a, b) {\n return a < b ? -1 : a > b ? 1 : 0;\n }\n StringExt.cmp = cmp;\n})(StringExt || (StringExt = {}));\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * Take a fixed number of items from an iterable.\n *\n * @param object - The iterable object of interest.\n *\n * @param count - The number of items to take from the iterable.\n *\n * @returns An iterator which yields the specified number of items\n * from the source iterable.\n *\n * #### Notes\n * The returned iterator will exhaust early if the source iterable\n * contains an insufficient number of items.\n *\n * #### Example\n * ```typescript\n * import { take } from '@lumino/algorithm';\n *\n * let stream = take([5, 4, 3, 2, 1, 0, -1], 3);\n *\n * Array.from(stream); // [5, 4, 3]\n * ```\n */\nfunction* take(object, count) {\n if (count < 1) {\n return;\n }\n const it = object[Symbol.iterator]();\n let item;\n while (0 < count-- && !(item = it.next()).done) {\n yield item.value;\n }\n}\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * Iterate several iterables in lockstep.\n *\n * @param objects - The iterable objects of interest.\n *\n * @returns An iterator which yields successive tuples of values where\n * each value is taken in turn from the provided iterables. It will\n * be as long as the shortest provided iterable.\n *\n * #### Example\n * ```typescript\n * import { zip } from '@lumino/algorithm';\n *\n * let data1 = [1, 2, 3];\n * let data2 = [4, 5, 6];\n *\n * let stream = zip(data1, data2);\n *\n * Array.from(stream); // [[1, 4], [2, 5], [3, 6]]\n * ```\n */\nfunction* zip(...objects) {\n const iters = objects.map(obj => obj[Symbol.iterator]());\n let tuple = iters.map(it => it.next());\n for (; every(tuple, item => !item.done); tuple = iters.map(it => it.next())) {\n yield tuple.map(item => item.value);\n }\n}\n\nexport { ArrayExt, StringExt, chain, each, empty, enumerate, every, filter, find, findIndex, map, max, min, minmax, once, range, reduce, repeat, retro, some, stride, take, toArray, toObject, topologicSort, zip };\n//# sourceMappingURL=index.es6.js.map\n","(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n typeof define === 'function' && define.amd ? define(['exports'], factory) :\n (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.lumino_coreutils = {}));\n})(this, (function (exports) { 'use strict';\n\n // Copyright (c) Jupyter Development Team.\n // Distributed under the terms of the Modified BSD License.\n /*-----------------------------------------------------------------------------\n | Copyright (c) 2014-2017, PhosphorJS Contributors\n |\n | Distributed under the terms of the BSD 3-Clause License.\n |\n | The full license is in the file LICENSE, distributed with this software.\n |----------------------------------------------------------------------------*/\n /**\n * The namespace for JSON-specific functions.\n */\n exports.JSONExt = void 0;\n (function (JSONExt) {\n /**\n * A shared frozen empty JSONObject\n */\n JSONExt.emptyObject = Object.freeze({});\n /**\n * A shared frozen empty JSONArray\n */\n JSONExt.emptyArray = Object.freeze([]);\n /**\n * Test whether a JSON value is a primitive.\n *\n * @param value - The JSON value of interest.\n *\n * @returns `true` if the value is a primitive,`false` otherwise.\n */\n function isPrimitive(value) {\n return (value === null ||\n typeof value === 'boolean' ||\n typeof value === 'number' ||\n typeof value === 'string');\n }\n JSONExt.isPrimitive = isPrimitive;\n function isArray(value) {\n return Array.isArray(value);\n }\n JSONExt.isArray = isArray;\n function isObject(value) {\n return !isPrimitive(value) && !isArray(value);\n }\n JSONExt.isObject = isObject;\n /**\n * Compare two JSON values for deep equality.\n *\n * @param first - The first JSON value of interest.\n *\n * @param second - The second JSON value of interest.\n *\n * @returns `true` if the values are equivalent, `false` otherwise.\n */\n function deepEqual(first, second) {\n // Check referential and primitive equality first.\n if (first === second) {\n return true;\n }\n // If one is a primitive, the `===` check ruled out the other.\n if (isPrimitive(first) || isPrimitive(second)) {\n return false;\n }\n // Test whether they are arrays.\n let a1 = isArray(first);\n let a2 = isArray(second);\n // Bail if the types are different.\n if (a1 !== a2) {\n return false;\n }\n // If they are both arrays, compare them.\n if (a1 && a2) {\n return deepArrayEqual(first, second);\n }\n // At this point, they must both be objects.\n return deepObjectEqual(first, second);\n }\n JSONExt.deepEqual = deepEqual;\n /**\n * Create a deep copy of a JSON value.\n *\n * @param value - The JSON value to copy.\n *\n * @returns A deep copy of the given JSON value.\n */\n function deepCopy(value) {\n // Do nothing for primitive values.\n if (isPrimitive(value)) {\n return value;\n }\n // Deep copy an array.\n if (isArray(value)) {\n return deepArrayCopy(value);\n }\n // Deep copy an object.\n return deepObjectCopy(value);\n }\n JSONExt.deepCopy = deepCopy;\n /**\n * Compare two JSON arrays for deep equality.\n */\n function deepArrayEqual(first, second) {\n // Check referential equality first.\n if (first === second) {\n return true;\n }\n // Test the arrays for equal length.\n if (first.length !== second.length) {\n return false;\n }\n // Compare the values for equality.\n for (let i = 0, n = first.length; i < n; ++i) {\n if (!deepEqual(first[i], second[i])) {\n return false;\n }\n }\n // At this point, the arrays are equal.\n return true;\n }\n /**\n * Compare two JSON objects for deep equality.\n */\n function deepObjectEqual(first, second) {\n // Check referential equality first.\n if (first === second) {\n return true;\n }\n // Check for the first object's keys in the second object.\n for (let key in first) {\n if (first[key] !== undefined && !(key in second)) {\n return false;\n }\n }\n // Check for the second object's keys in the first object.\n for (let key in second) {\n if (second[key] !== undefined && !(key in first)) {\n return false;\n }\n }\n // Compare the values for equality.\n for (let key in first) {\n // Get the values.\n let firstValue = first[key];\n let secondValue = second[key];\n // If both are undefined, ignore the key.\n if (firstValue === undefined && secondValue === undefined) {\n continue;\n }\n // If only one value is undefined, the objects are not equal.\n if (firstValue === undefined || secondValue === undefined) {\n return false;\n }\n // Compare the values.\n if (!deepEqual(firstValue, secondValue)) {\n return false;\n }\n }\n // At this point, the objects are equal.\n return true;\n }\n /**\n * Create a deep copy of a JSON array.\n */\n function deepArrayCopy(value) {\n let result = new Array(value.length);\n for (let i = 0, n = value.length; i < n; ++i) {\n result[i] = deepCopy(value[i]);\n }\n return result;\n }\n /**\n * Create a deep copy of a JSON object.\n */\n function deepObjectCopy(value) {\n let result = {};\n for (let key in value) {\n // Ignore undefined values.\n let subvalue = value[key];\n if (subvalue === undefined) {\n continue;\n }\n result[key] = deepCopy(subvalue);\n }\n return result;\n }\n })(exports.JSONExt || (exports.JSONExt = {}));\n\n // Copyright (c) Jupyter Development Team.\n // Distributed under the terms of the Modified BSD License.\n /*-----------------------------------------------------------------------------\n | Copyright (c) 2014-2017, PhosphorJS Contributors\n |\n | Distributed under the terms of the BSD 3-Clause License.\n |\n | The full license is in the file LICENSE, distributed with this software.\n |----------------------------------------------------------------------------*/\n /**\n * An object which stores MIME data for general application use.\n *\n * #### Notes\n * This class does not attempt to enforce \"correctness\" of MIME types\n * and their associated data. Since this class is designed to transfer\n * arbitrary data and objects within the same application, it assumes\n * that the user provides correct and accurate data.\n */\n class MimeData {\n constructor() {\n this._types = [];\n this._values = [];\n }\n /**\n * Get an array of the MIME types contained within the dataset.\n *\n * @returns A new array of the MIME types, in order of insertion.\n */\n types() {\n return this._types.slice();\n }\n /**\n * Test whether the dataset has an entry for the given type.\n *\n * @param mime - The MIME type of interest.\n *\n * @returns `true` if the dataset contains a value for the given\n * MIME type, `false` otherwise.\n */\n hasData(mime) {\n return this._types.indexOf(mime) !== -1;\n }\n /**\n * Get the data value for the given MIME type.\n *\n * @param mime - The MIME type of interest.\n *\n * @returns The value for the given MIME type, or `undefined` if\n * the dataset does not contain a value for the type.\n */\n getData(mime) {\n let i = this._types.indexOf(mime);\n return i !== -1 ? this._values[i] : undefined;\n }\n /**\n * Set the data value for the given MIME type.\n *\n * @param mime - The MIME type of interest.\n *\n * @param data - The data value for the given MIME type.\n *\n * #### Notes\n * This will overwrite any previous entry for the MIME type.\n */\n setData(mime, data) {\n this.clearData(mime);\n this._types.push(mime);\n this._values.push(data);\n }\n /**\n * Remove the data entry for the given MIME type.\n *\n * @param mime - The MIME type of interest.\n *\n * #### Notes\n * This is a no-op if there is no entry for the given MIME type.\n */\n clearData(mime) {\n let i = this._types.indexOf(mime);\n if (i !== -1) {\n this._types.splice(i, 1);\n this._values.splice(i, 1);\n }\n }\n /**\n * Remove all data entries from the dataset.\n */\n clear() {\n this._types.length = 0;\n this._values.length = 0;\n }\n }\n\n // Copyright (c) Jupyter Development Team.\n // Distributed under the terms of the Modified BSD License.\n /*-----------------------------------------------------------------------------\n | Copyright (c) 2014-2017, PhosphorJS Contributors\n |\n | Distributed under the terms of the BSD 3-Clause License.\n |\n | The full license is in the file LICENSE, distributed with this software.\n |----------------------------------------------------------------------------*/\n /**\n * A class which wraps a promise into a delegate object.\n *\n * #### Notes\n * This class is useful when the logic to resolve or reject a promise\n * cannot be defined at the point where the promise is created.\n */\n class PromiseDelegate {\n /**\n * Construct a new promise delegate.\n */\n constructor() {\n this.promise = new Promise((resolve, reject) => {\n this._resolve = resolve;\n this._reject = reject;\n });\n }\n /**\n * Resolve the wrapped promise with the given value.\n *\n * @param value - The value to use for resolving the promise.\n */\n resolve(value) {\n let resolve = this._resolve;\n resolve(value);\n }\n /**\n * Reject the wrapped promise with the given value.\n *\n * @reason - The reason for rejecting the promise.\n */\n reject(reason) {\n let reject = this._reject;\n reject(reason);\n }\n }\n\n // Copyright (c) Jupyter Development Team.\n // Distributed under the terms of the Modified BSD License.\n /*-----------------------------------------------------------------------------\n | Copyright (c) 2014-2017, PhosphorJS Contributors\n |\n | Distributed under the terms of the BSD 3-Clause License.\n |\n | The full license is in the file LICENSE, distributed with this software.\n |----------------------------------------------------------------------------*/\n /**\n * A runtime object which captures compile-time type information.\n *\n * #### Notes\n * A token captures the compile-time type of an interface or class in\n * an object which can be used at runtime in a type-safe fashion.\n */\n class Token {\n /**\n * Construct a new token.\n *\n * @param name - A human readable name for the token.\n * @param description - Token purpose description for documentation.\n */\n constructor(name, description) {\n this.name = name;\n this.description = description !== null && description !== void 0 ? description : '';\n this._tokenStructuralPropertyT = null;\n }\n }\n\n // Copyright (c) Jupyter Development Team.\n // Distributed under the terms of the Modified BSD License.\n /*-----------------------------------------------------------------------------\n | Copyright (c) 2014-2017, PhosphorJS Contributors\n |\n | Distributed under the terms of the BSD 3-Clause License.\n |\n | The full license is in the file LICENSE, distributed with this software.\n |----------------------------------------------------------------------------*/\n // Fallback\n function fallbackRandomValues(buffer) {\n let value = 0;\n for (let i = 0, n = buffer.length; i < n; ++i) {\n if (i % 4 === 0) {\n value = (Math.random() * 0xffffffff) >>> 0;\n }\n buffer[i] = value & 0xff;\n value >>>= 8;\n }\n }\n\n // Copyright (c) Jupyter Development Team.\n // Distributed under the terms of the Modified BSD License.\n /*-----------------------------------------------------------------------------\n | Copyright (c) 2014-2017, PhosphorJS Contributors\n |\n | Distributed under the terms of the BSD 3-Clause License.\n |\n | The full license is in the file LICENSE, distributed with this software.\n |----------------------------------------------------------------------------*/\n /**\n * The namespace for random number related functionality.\n */\n exports.Random = void 0;\n (function (Random) {\n /**\n * A function which generates random bytes.\n *\n * @param buffer - The `Uint8Array` to fill with random bytes.\n *\n * #### Notes\n * A cryptographically strong random number generator will be used if\n * available. Otherwise, `Math.random` will be used as a fallback for\n * randomness.\n *\n * The following RNGs are supported, listed in order of precedence:\n * - `window.crypto.getRandomValues`\n * - `window.msCrypto.getRandomValues`\n * - `require('crypto').randomFillSync\n * - `require('crypto').randomBytes\n * - `Math.random`\n */\n Random.getRandomValues = (() => {\n // Look up the crypto module if available.\n const crypto = (typeof window !== 'undefined' && (window.crypto || window.msCrypto)) ||\n null;\n // Modern browsers and IE 11\n if (crypto && typeof crypto.getRandomValues === 'function') {\n return function getRandomValues(buffer) {\n return crypto.getRandomValues(buffer);\n };\n }\n // Fallback\n return fallbackRandomValues;\n })();\n })(exports.Random || (exports.Random = {}));\n\n // Copyright (c) Jupyter Development Team.\n // Distributed under the terms of the Modified BSD License.\n /*-----------------------------------------------------------------------------\n | Copyright (c) 2014-2017, PhosphorJS Contributors\n |\n | Distributed under the terms of the BSD 3-Clause License.\n |\n | The full license is in the file LICENSE, distributed with this software.\n |----------------------------------------------------------------------------*/\n /**\n * A function which creates a function that generates UUID v4 identifiers.\n *\n * @returns A new function that creates a UUID v4 string.\n *\n * #### Notes\n * This implementation complies with RFC 4122.\n *\n * This uses `Random.getRandomValues()` for random bytes, which in\n * turn will use the underlying `crypto` module of the platform if\n * it is available. The fallback for randomness is `Math.random`.\n */\n function uuid4Factory(getRandomValues) {\n // Create a 16 byte array to hold the random values.\n const bytes = new Uint8Array(16);\n // Create a look up table from bytes to hex strings.\n const lut = new Array(256);\n // Pad the single character hex digits with a leading zero.\n for (let i = 0; i < 16; ++i) {\n lut[i] = '0' + i.toString(16);\n }\n // Populate the rest of the hex digits.\n for (let i = 16; i < 256; ++i) {\n lut[i] = i.toString(16);\n }\n // Return a function which generates the UUID.\n return function uuid4() {\n // Get a new batch of random values.\n getRandomValues(bytes);\n // Set the UUID version number to 4.\n bytes[6] = 0x40 | (bytes[6] & 0x0f);\n // Set the clock sequence bit to the RFC spec.\n bytes[8] = 0x80 | (bytes[8] & 0x3f);\n // Assemble the UUID string.\n return (lut[bytes[0]] +\n lut[bytes[1]] +\n lut[bytes[2]] +\n lut[bytes[3]] +\n '-' +\n lut[bytes[4]] +\n lut[bytes[5]] +\n '-' +\n lut[bytes[6]] +\n lut[bytes[7]] +\n '-' +\n lut[bytes[8]] +\n lut[bytes[9]] +\n '-' +\n lut[bytes[10]] +\n lut[bytes[11]] +\n lut[bytes[12]] +\n lut[bytes[13]] +\n lut[bytes[14]] +\n lut[bytes[15]]);\n };\n }\n\n // Copyright (c) Jupyter Development Team.\n // Distributed under the terms of the Modified BSD License.\n /*-----------------------------------------------------------------------------\n | Copyright (c) 2014-2017, PhosphorJS Contributors\n |\n | Distributed under the terms of the BSD 3-Clause License.\n |\n | The full license is in the file LICENSE, distributed with this software.\n |----------------------------------------------------------------------------*/\n /**\n * The namespace for UUID related functionality.\n */\n exports.UUID = void 0;\n (function (UUID) {\n /**\n * A function which generates UUID v4 identifiers.\n *\n * @returns A new UUID v4 string.\n *\n * #### Notes\n * This implementation complies with RFC 4122.\n *\n * This uses `Random.getRandomValues()` for random bytes, which in\n * turn will use the underlying `crypto` module of the platform if\n * it is available. The fallback for randomness is `Math.random`.\n */\n UUID.uuid4 = uuid4Factory(exports.Random.getRandomValues);\n })(exports.UUID || (exports.UUID = {}));\n\n exports.MimeData = MimeData;\n exports.PromiseDelegate = PromiseDelegate;\n exports.Token = Token;\n\n}));\n//# sourceMappingURL=index.js.map\n","import { Signal } from '@lumino/signaling';\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * @packageDocumentation\n * @module disposable\n */\n/**\n * A disposable object which delegates to a callback function.\n */\nclass DisposableDelegate {\n /**\n * Construct a new disposable delegate.\n *\n * @param fn - The callback function to invoke on dispose.\n */\n constructor(fn) {\n this._fn = fn;\n }\n /**\n * Test whether the delegate has been disposed.\n */\n get isDisposed() {\n return !this._fn;\n }\n /**\n * Dispose of the delegate and invoke the callback function.\n */\n dispose() {\n if (!this._fn) {\n return;\n }\n let fn = this._fn;\n this._fn = null;\n fn();\n }\n}\n/**\n * An observable disposable object which delegates to a callback function.\n */\nclass ObservableDisposableDelegate extends DisposableDelegate {\n constructor() {\n super(...arguments);\n this._disposed = new Signal(this);\n }\n /**\n * A signal emitted when the delegate is disposed.\n */\n get disposed() {\n return this._disposed;\n }\n /**\n * Dispose of the delegate and invoke the callback function.\n */\n dispose() {\n if (this.isDisposed) {\n return;\n }\n super.dispose();\n this._disposed.emit(undefined);\n Signal.clearData(this);\n }\n}\n/**\n * An object which manages a collection of disposable items.\n */\nclass DisposableSet {\n constructor() {\n this._isDisposed = false;\n this._items = new Set();\n }\n /**\n * Test whether the set has been disposed.\n */\n get isDisposed() {\n return this._isDisposed;\n }\n /**\n * Dispose of the set and the items it contains.\n *\n * #### Notes\n * Items are disposed in the order they are added to the set.\n */\n dispose() {\n if (this._isDisposed) {\n return;\n }\n this._isDisposed = true;\n this._items.forEach(item => {\n item.dispose();\n });\n this._items.clear();\n }\n /**\n * Test whether the set contains a specific item.\n *\n * @param item - The item of interest.\n *\n * @returns `true` if the set contains the item, `false` otherwise.\n */\n contains(item) {\n return this._items.has(item);\n }\n /**\n * Add a disposable item to the set.\n *\n * @param item - The item to add to the set.\n *\n * #### Notes\n * If the item is already contained in the set, this is a no-op.\n */\n add(item) {\n this._items.add(item);\n }\n /**\n * Remove a disposable item from the set.\n *\n * @param item - The item to remove from the set.\n *\n * #### Notes\n * If the item is not contained in the set, this is a no-op.\n */\n remove(item) {\n this._items.delete(item);\n }\n /**\n * Remove all items from the set.\n */\n clear() {\n this._items.clear();\n }\n}\n/**\n * The namespace for the `DisposableSet` class statics.\n */\n(function (DisposableSet) {\n /**\n * Create a disposable set from an iterable of items.\n *\n * @param items - The iterable object of interest.\n *\n * @returns A new disposable initialized with the given items.\n */\n function from(items) {\n let set = new DisposableSet();\n for (const item of items) {\n set.add(item);\n }\n return set;\n }\n DisposableSet.from = from;\n})(DisposableSet || (DisposableSet = {}));\n/**\n * An observable object which manages a collection of disposable items.\n */\nclass ObservableDisposableSet extends DisposableSet {\n constructor() {\n super(...arguments);\n this._disposed = new Signal(this);\n }\n /**\n * A signal emitted when the set is disposed.\n */\n get disposed() {\n return this._disposed;\n }\n /**\n * Dispose of the set and the items it contains.\n *\n * #### Notes\n * Items are disposed in the order they are added to the set.\n */\n dispose() {\n if (this.isDisposed) {\n return;\n }\n super.dispose();\n this._disposed.emit(undefined);\n Signal.clearData(this);\n }\n}\n/**\n * The namespace for the `ObservableDisposableSet` class statics.\n */\n(function (ObservableDisposableSet) {\n /**\n * Create an observable disposable set from an iterable of items.\n *\n * @param items - The iterable object of interest.\n *\n * @returns A new disposable initialized with the given items.\n */\n function from(items) {\n let set = new ObservableDisposableSet();\n for (const item of items) {\n set.add(item);\n }\n return set;\n }\n ObservableDisposableSet.from = from;\n})(ObservableDisposableSet || (ObservableDisposableSet = {}));\n\nexport { DisposableDelegate, DisposableSet, ObservableDisposableDelegate, ObservableDisposableSet };\n//# sourceMappingURL=index.es6.js.map\n","import { PromiseDelegate, JSONExt } from '@lumino/coreutils';\nimport { Signal } from '@lumino/signaling';\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/**\n * A class that wraps an asynchronous function to poll at a regular interval\n * with exponential increases to the interval length if the poll fails.\n *\n * @typeparam T - The resolved type of the factory's promises.\n * Defaults to `any`.\n *\n * @typeparam U - The rejected type of the factory's promises.\n * Defaults to `any`.\n *\n * @typeparam V - An optional type to extend the phases supported by a poll.\n * Defaults to `standby`, which already exists in the `Phase` type.\n */\nclass Poll {\n /**\n * Instantiate a new poll with exponential backoff in case of failure.\n *\n * @param options - The poll instantiation options.\n */\n constructor(options) {\n var _a;\n this._disposed = new Signal(this);\n this._lingered = 0;\n this._tick = new PromiseDelegate();\n this._ticked = new Signal(this);\n this._factory = options.factory;\n this._linger = (_a = options.linger) !== null && _a !== void 0 ? _a : Private.DEFAULT_LINGER;\n this._standby = options.standby || Private.DEFAULT_STANDBY;\n this._state = { ...Private.DEFAULT_STATE, timestamp: new Date().getTime() };\n // Normalize poll frequency `max` to be the greater of\n // default `max`, `options.frequency.max`, or `options.frequency.interval`.\n const frequency = options.frequency || {};\n const max = Math.max(frequency.interval || 0, frequency.max || 0, Private.DEFAULT_FREQUENCY.max);\n this.frequency = { ...Private.DEFAULT_FREQUENCY, ...frequency, ...{ max } };\n this.name = options.name || Private.DEFAULT_NAME;\n if ('auto' in options ? options.auto : true) {\n setTimeout(() => this.start());\n }\n }\n /**\n * A signal emitted when the poll is disposed.\n */\n get disposed() {\n return this._disposed;\n }\n /**\n * The polling frequency parameters.\n */\n get frequency() {\n return this._frequency;\n }\n set frequency(frequency) {\n if (this.isDisposed || JSONExt.deepEqual(frequency, this.frequency || {})) {\n return;\n }\n let { backoff, interval, max } = frequency;\n interval = Math.round(interval);\n max = Math.round(max);\n if (typeof backoff === 'number' && backoff < 1) {\n throw new Error('Poll backoff growth factor must be at least 1');\n }\n if ((interval < 0 || interval > max) && interval !== Poll.NEVER) {\n throw new Error('Poll interval must be between 0 and max');\n }\n if (max > Poll.MAX_INTERVAL && max !== Poll.NEVER) {\n throw new Error(`Max interval must be less than ${Poll.MAX_INTERVAL}`);\n }\n this._frequency = { backoff, interval, max };\n }\n /**\n * Whether the poll is disposed.\n */\n get isDisposed() {\n return this.state.phase === 'disposed';\n }\n /**\n * Indicates when the poll switches to standby.\n */\n get standby() {\n return this._standby;\n }\n set standby(standby) {\n if (this.isDisposed || this.standby === standby) {\n return;\n }\n this._standby = standby;\n }\n /**\n * The poll state, which is the content of the current poll tick.\n */\n get state() {\n return this._state;\n }\n /**\n * A promise that resolves when the poll next ticks.\n */\n get tick() {\n return this._tick.promise;\n }\n /**\n * A signal emitted when the poll ticks and fires off a new request.\n */\n get ticked() {\n return this._ticked;\n }\n /**\n * Return an async iterator that yields every tick.\n */\n async *[Symbol.asyncIterator]() {\n while (!this.isDisposed) {\n yield this.state;\n await this.tick.catch(() => undefined);\n }\n }\n /**\n * Dispose the poll.\n */\n dispose() {\n if (this.isDisposed) {\n return;\n }\n this._state = {\n ...Private.DISPOSED_STATE,\n timestamp: new Date().getTime()\n };\n this._tick.promise.catch(_ => undefined);\n this._tick.reject(new Error(`Poll (${this.name}) is disposed.`));\n this._disposed.emit(undefined);\n Signal.clearData(this);\n }\n /**\n * Refreshes the poll. Schedules `refreshed` tick if necessary.\n *\n * @returns A promise that resolves after tick is scheduled and never rejects.\n *\n * #### Notes\n * The returned promise resolves after the tick is scheduled, but before\n * the polling action is run. To wait until after the poll action executes,\n * await the `poll.tick` promise: `await poll.refresh(); await poll.tick;`\n */\n refresh() {\n return this.schedule({\n cancel: ({ phase }) => phase === 'refreshed',\n interval: Poll.IMMEDIATE,\n phase: 'refreshed'\n });\n }\n /**\n * Schedule the next poll tick.\n *\n * @param next - The next poll state data to schedule. Defaults to standby.\n *\n * @param next.cancel - Cancels state transition if function returns `true`.\n *\n * @returns A promise that resolves when the next poll state is active.\n *\n * #### Notes\n * This method is not meant to be invoked by user code typically. It is public\n * to allow poll instances to be composed into classes that schedule ticks.\n */\n async schedule(next = {}) {\n if (this.isDisposed) {\n return;\n }\n // Check if the phase transition should be canceled.\n if (next.cancel && next.cancel(this.state)) {\n return;\n }\n // Update poll state.\n const pending = this._tick;\n const scheduled = new PromiseDelegate();\n const state = {\n interval: this.frequency.interval,\n payload: null,\n phase: 'standby',\n timestamp: new Date().getTime(),\n ...next\n };\n this._state = state;\n this._tick = scheduled;\n // Clear the schedule if possible.\n clearTimeout(this._timeout);\n // Emit ticked signal, resolve pending promise, and await its settlement.\n this._ticked.emit(this.state);\n pending.resolve(this);\n await pending.promise;\n if (state.interval === Poll.NEVER) {\n this._timeout = undefined;\n return;\n }\n // Schedule next execution and cache its timeout handle.\n const execute = () => {\n if (this.isDisposed || this.tick !== scheduled.promise) {\n return;\n }\n this._execute();\n };\n // Cache the handle in case it needs to be unscheduled.\n this._timeout = setTimeout(execute, state.interval);\n }\n /**\n * Starts the poll. Schedules `started` tick if necessary.\n *\n * @returns A promise that resolves after tick is scheduled and never rejects.\n */\n start() {\n return this.schedule({\n cancel: ({ phase }) => phase !== 'constructed' && phase !== 'standby' && phase !== 'stopped',\n interval: Poll.IMMEDIATE,\n phase: 'started'\n });\n }\n /**\n * Stops the poll. Schedules `stopped` tick if necessary.\n *\n * @returns A promise that resolves after tick is scheduled and never rejects.\n */\n stop() {\n return this.schedule({\n cancel: ({ phase }) => phase === 'stopped',\n interval: Poll.NEVER,\n phase: 'stopped'\n });\n }\n /**\n * Whether the poll is hidden.\n *\n * #### Notes\n * This property is only relevant in a browser context.\n */\n get hidden() {\n return Private.hidden;\n }\n /**\n * Execute a new poll factory promise or stand by if necessary.\n */\n _execute() {\n let standby = typeof this.standby === 'function' ? this.standby() : this.standby;\n // Check if execution should proceed, linger, or stand by.\n if (standby === 'never') {\n standby = false;\n }\n else if (standby === 'when-hidden') {\n if (this.hidden) {\n standby = ++this._lingered > this._linger;\n }\n else {\n this._lingered = 0;\n standby = false;\n }\n }\n // If in standby mode schedule next tick without calling the factory.\n if (standby) {\n void this.schedule();\n return;\n }\n const pending = this.tick;\n this._factory(this.state)\n .then((resolved) => {\n if (this.isDisposed || this.tick !== pending) {\n return;\n }\n void this.schedule({\n payload: resolved,\n phase: this.state.phase === 'rejected' ? 'reconnected' : 'resolved'\n });\n })\n .catch((rejected) => {\n if (this.isDisposed || this.tick !== pending) {\n return;\n }\n void this.schedule({\n interval: Private.sleep(this.frequency, this.state),\n payload: rejected,\n phase: 'rejected'\n });\n });\n }\n}\n/**\n * A namespace for `Poll` types, interfaces, and statics.\n */\n(function (Poll) {\n /**\n * An interval value in ms that indicates the poll should tick immediately.\n */\n Poll.IMMEDIATE = 0;\n /**\n * Delays are 32-bit integers in many browsers so intervals need to be capped.\n *\n * #### Notes\n * https://developer.mozilla.org/en-US/docs/Web/API/WindowOrWorkerGlobalScope/setTimeout#Maximum_delay_value\n */\n Poll.MAX_INTERVAL = 2147483647;\n /**\n * An interval value that indicates the poll should never tick.\n */\n Poll.NEVER = Infinity;\n})(Poll || (Poll = {}));\n/**\n * A namespace for private module data.\n */\nvar Private;\n(function (Private) {\n /**\n * The default backoff growth rate if `backoff` is `true`.\n */\n Private.DEFAULT_BACKOFF = 3;\n /**\n * The default polling frequency.\n */\n Private.DEFAULT_FREQUENCY = {\n backoff: true,\n interval: 1000,\n max: 30 * 1000\n };\n /**\n * The default number of times to `linger` when a poll is hidden.\n */\n Private.DEFAULT_LINGER = 1;\n /**\n * The default poll name.\n */\n Private.DEFAULT_NAME = 'unknown';\n /**\n * The default poll standby behavior.\n */\n Private.DEFAULT_STANDBY = 'when-hidden';\n /**\n * The first poll tick state's default values superseded in constructor.\n */\n Private.DEFAULT_STATE = {\n interval: Poll.NEVER,\n payload: null,\n phase: 'constructed',\n timestamp: new Date(0).getTime()\n };\n /**\n * The disposed tick state values.\n */\n Private.DISPOSED_STATE = {\n interval: Poll.NEVER,\n payload: null,\n phase: 'disposed',\n timestamp: new Date(0).getTime()\n };\n /**\n * Returns the number of milliseconds to sleep before the next tick.\n *\n * @param frequency - The poll's base frequency.\n * @param last - The poll's last tick.\n */\n function sleep(frequency, last) {\n const { backoff, interval, max } = frequency;\n if (interval === Poll.NEVER) {\n return interval;\n }\n const growth = backoff === true ? Private.DEFAULT_BACKOFF : backoff === false ? 1 : backoff;\n const random = getRandomIntInclusive(interval, last.interval * growth);\n return Math.min(max, random);\n }\n Private.sleep = sleep;\n /**\n * Keep track of whether the document is hidden. This flag is only relevant in\n * a browser context.\n *\n * Listen to `visibilitychange` event to set the `hidden` flag.\n *\n * Listening to `pagehide` is also necessary because Safari support for\n * `visibilitychange` events is partial, cf.\n * https://developer.mozilla.org/docs/Web/API/Document/visibilitychange_event\n */\n Private.hidden = (() => {\n if (typeof document === 'undefined') {\n return false;\n }\n document.addEventListener('visibilitychange', () => {\n Private.hidden = document.visibilityState === 'hidden';\n });\n document.addEventListener('pagehide', () => {\n Private.hidden = document.visibilityState === 'hidden';\n });\n return document.visibilityState === 'hidden';\n })();\n /**\n * Get a random integer between min and max, inclusive of both.\n *\n * #### Notes\n * From\n * https://developer.mozilla.org/docs/Web/JavaScript/Reference/Global_Objects/Math/random#Getting_a_random_integer_between_two_values_inclusive\n *\n * From the MDN page: It might be tempting to use Math.round() to accomplish\n * that, but doing so would cause your random numbers to follow a non-uniform\n * distribution, which may not be acceptable for your needs.\n */\n function getRandomIntInclusive(min, max) {\n min = Math.ceil(min);\n max = Math.floor(max);\n return Math.floor(Math.random() * (max - min + 1)) + min;\n }\n})(Private || (Private = {}));\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/**\n * A base class to implement rate limiters with different invocation strategies.\n *\n * @typeparam T - The resolved type of the underlying function.\n *\n * @typeparam U - The rejected type of the underlying function.\n *\n * @typeparam V - Arguments for the underlying function.\n */\nclass RateLimiter {\n /**\n * Instantiate a rate limiter.\n *\n * @param fn - The function to rate limit.\n *\n * @param limit - The rate limit; defaults to 500ms.\n */\n constructor(fn, limit = 500) {\n /**\n * Arguments for the underlying function.\n */\n this.args = undefined;\n /**\n * A promise that resolves on each successful invocation.\n */\n this.payload = null;\n this.limit = limit;\n this.poll = new Poll({\n auto: false,\n factory: async () => {\n const { args } = this;\n this.args = undefined;\n return fn(...args);\n },\n frequency: { backoff: false, interval: Poll.NEVER, max: Poll.NEVER },\n standby: 'never'\n });\n this.payload = new PromiseDelegate();\n this.poll.ticked.connect((_, state) => {\n const { payload } = this;\n if (state.phase === 'resolved') {\n this.payload = new PromiseDelegate();\n payload.resolve(state.payload);\n return;\n }\n if (state.phase === 'rejected' || state.phase === 'stopped') {\n this.payload = new PromiseDelegate();\n payload.promise.catch(_ => undefined);\n payload.reject(state.payload);\n return;\n }\n }, this);\n }\n /**\n * Whether the rate limiter is disposed.\n */\n get isDisposed() {\n return this.payload === null;\n }\n /**\n * Disposes the rate limiter.\n */\n dispose() {\n if (this.isDisposed) {\n return;\n }\n this.args = undefined;\n this.payload = null;\n this.poll.dispose();\n }\n /**\n * Stop the function if it is mid-flight.\n */\n async stop() {\n return this.poll.stop();\n }\n}\n/**\n * Wraps and debounces a function that can be called multiple times and only\n * executes the underlying function one `interval` after the last invocation.\n *\n * @typeparam T - The resolved type of the underlying function. Defaults to any.\n *\n * @typeparam U - The rejected type of the underlying function. Defaults to any.\n *\n * @typeparam V - Arguments for the underlying function. Defaults to any[].\n */\nclass Debouncer extends RateLimiter {\n /**\n * Invokes the function and only executes after rate limit has elapsed.\n * Each invocation resets the timer.\n */\n invoke(...args) {\n this.args = args;\n void this.poll.schedule({ interval: this.limit, phase: 'invoked' });\n return this.payload.promise;\n }\n}\n/**\n * Wraps and throttles a function that can be called multiple times and only\n * executes the underlying function once per `interval`.\n *\n * @typeparam T - The resolved type of the underlying function. Defaults to any.\n *\n * @typeparam U - The rejected type of the underlying function. Defaults to any.\n *\n * @typeparam V - Arguments for the underlying function. Defaults to any[].\n */\nclass Throttler extends RateLimiter {\n /**\n * Instantiate a throttler.\n *\n * @param fn - The function being throttled.\n *\n * @param options - Throttling configuration or throttling limit in ms.\n *\n * #### Notes\n * The `edge` defaults to `leading`; the `limit` defaults to `500`.\n */\n constructor(fn, options) {\n super(fn, typeof options === 'number' ? options : options && options.limit);\n this._trailing = false;\n if (typeof options !== 'number' && options && options.edge === 'trailing') {\n this._trailing = true;\n }\n this._interval = this._trailing ? this.limit : Poll.IMMEDIATE;\n }\n /**\n * Throttles function invocations if one is currently in flight.\n */\n invoke(...args) {\n const idle = this.poll.state.phase !== 'invoked';\n if (idle || this._trailing) {\n this.args = args;\n }\n if (idle) {\n void this.poll.schedule({ interval: this._interval, phase: 'invoked' });\n }\n return this.payload.promise;\n }\n}\n\nexport { Debouncer, Poll, RateLimiter, Throttler };\n//# sourceMappingURL=index.es6.js.map\n","// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * @packageDocumentation\n * @module properties\n */\n/**\n * A class which attaches a value to an external object.\n *\n * #### Notes\n * Attached properties are used to extend the state of an object with\n * semantic data from an unrelated class. They also encapsulate value\n * creation, coercion, and notification.\n *\n * Because attached property values are stored in a hash table, which\n * in turn is stored in a WeakMap keyed on the owner object, there is\n * non-trivial storage overhead involved in their use. The pattern is\n * therefore best used for the storage of rare data.\n */\nclass AttachedProperty {\n /**\n * Construct a new attached property.\n *\n * @param options - The options for initializing the property.\n */\n constructor(options) {\n this._pid = Private.nextPID();\n this.name = options.name;\n this._create = options.create;\n this._coerce = options.coerce || null;\n this._compare = options.compare || null;\n this._changed = options.changed || null;\n }\n /**\n * Get the current value of the property for a given owner.\n *\n * @param owner - The property owner of interest.\n *\n * @returns The current value of the property.\n *\n * #### Notes\n * If the value has not yet been set, the default value will be\n * computed and assigned as the current value of the property.\n */\n get(owner) {\n let value;\n let map = Private.ensureMap(owner);\n if (this._pid in map) {\n value = map[this._pid];\n }\n else {\n value = map[this._pid] = this._createValue(owner);\n }\n return value;\n }\n /**\n * Set the current value of the property for a given owner.\n *\n * @param owner - The property owner of interest.\n *\n * @param value - The value for the property.\n *\n * #### Notes\n * If the value has not yet been set, the default value will be\n * computed and used as the previous value for the comparison.\n */\n set(owner, value) {\n let oldValue;\n let map = Private.ensureMap(owner);\n if (this._pid in map) {\n oldValue = map[this._pid];\n }\n else {\n oldValue = map[this._pid] = this._createValue(owner);\n }\n let newValue = this._coerceValue(owner, value);\n this._maybeNotify(owner, oldValue, (map[this._pid] = newValue));\n }\n /**\n * Explicitly coerce the current property value for a given owner.\n *\n * @param owner - The property owner of interest.\n *\n * #### Notes\n * If the value has not yet been set, the default value will be\n * computed and used as the previous value for the comparison.\n */\n coerce(owner) {\n let oldValue;\n let map = Private.ensureMap(owner);\n if (this._pid in map) {\n oldValue = map[this._pid];\n }\n else {\n oldValue = map[this._pid] = this._createValue(owner);\n }\n let newValue = this._coerceValue(owner, oldValue);\n this._maybeNotify(owner, oldValue, (map[this._pid] = newValue));\n }\n /**\n * Get or create the default value for the given owner.\n */\n _createValue(owner) {\n let create = this._create;\n return create(owner);\n }\n /**\n * Coerce the value for the given owner.\n */\n _coerceValue(owner, value) {\n let coerce = this._coerce;\n return coerce ? coerce(owner, value) : value;\n }\n /**\n * Compare the old value and new value for equality.\n */\n _compareValue(oldValue, newValue) {\n let compare = this._compare;\n return compare ? compare(oldValue, newValue) : oldValue === newValue;\n }\n /**\n * Run the change notification if the given values are different.\n */\n _maybeNotify(owner, oldValue, newValue) {\n let changed = this._changed;\n if (changed && !this._compareValue(oldValue, newValue)) {\n changed(owner, oldValue, newValue);\n }\n }\n}\n/**\n * The namespace for the `AttachedProperty` class statics.\n */\n(function (AttachedProperty) {\n /**\n * Clear the stored property data for the given owner.\n *\n * @param owner - The property owner of interest.\n *\n * #### Notes\n * This will clear all property values for the owner, but it will\n * **not** run the change notification for any of the properties.\n */\n function clearData(owner) {\n Private.ownerData.delete(owner);\n }\n AttachedProperty.clearData = clearData;\n})(AttachedProperty || (AttachedProperty = {}));\n/**\n * The namespace for the module implementation details.\n */\nvar Private;\n(function (Private) {\n /**\n * A weak mapping of property owner to property map.\n */\n Private.ownerData = new WeakMap();\n /**\n * A function which computes successive unique property ids.\n */\n Private.nextPID = (() => {\n let id = 0;\n return () => {\n let rand = Math.random();\n let stem = `${rand}`.slice(2);\n return `pid-${stem}-${id++}`;\n };\n })();\n /**\n * Lookup the data map for the property owner.\n *\n * This will create the map if one does not already exist.\n */\n function ensureMap(owner) {\n let map = Private.ownerData.get(owner);\n if (map) {\n return map;\n }\n map = Object.create(null);\n Private.ownerData.set(owner, map);\n return map;\n }\n Private.ensureMap = ensureMap;\n})(Private || (Private = {}));\n\nexport { AttachedProperty };\n//# sourceMappingURL=index.es6.js.map\n","import { find, ArrayExt } from '@lumino/algorithm';\nimport { PromiseDelegate } from '@lumino/coreutils';\n\n// Copyright (c) Jupyter Development Team.\n// Distributed under the terms of the Modified BSD License.\n/*-----------------------------------------------------------------------------\n| Copyright (c) 2014-2017, PhosphorJS Contributors\n|\n| Distributed under the terms of the BSD 3-Clause License.\n|\n| The full license is in the file LICENSE, distributed with this software.\n|----------------------------------------------------------------------------*/\n/**\n * @packageDocumentation\n * @module signaling\n */\n/**\n * A concrete implementation of `ISignal`.\n *\n * #### Example\n * ```typescript\n * import { ISignal, Signal } from '@lumino/signaling';\n *\n * class SomeClass {\n *\n * constructor(name: string) {\n * this.name = name;\n * }\n *\n * readonly name: string;\n *\n * get valueChanged: ISignal {\n * return this._valueChanged;\n * }\n *\n * get value(): number {\n * return this._value;\n * }\n *\n * set value(value: number) {\n * if (value === this._value) {\n * return;\n * }\n * this._value = value;\n * this._valueChanged.emit(value);\n * }\n *\n * private _value = 0;\n * private _valueChanged = new Signal(this);\n * }\n *\n * function logger(sender: SomeClass, value: number): void {\n * console.log(sender.name, value);\n * }\n *\n * let m1 = new SomeClass('foo');\n * let m2 = new SomeClass('bar');\n *\n * m1.valueChanged.connect(logger);\n * m2.valueChanged.connect(logger);\n *\n * m1.value = 42; // logs: foo 42\n * m2.value = 17; // logs: bar 17\n * ```\n */\nclass Signal {\n /**\n * Construct a new signal.\n *\n * @param sender - The sender which owns the signal.\n */\n constructor(sender) {\n this.sender = sender;\n }\n /**\n * Connect a slot to the signal.\n *\n * @param slot - The slot to invoke when the signal is emitted.\n *\n * @param thisArg - The `this` context for the slot. If provided,\n * this must be a non-primitive object.\n *\n * @returns `true` if the connection succeeds, `false` otherwise.\n */\n connect(slot, thisArg) {\n return Private.connect(this, slot, thisArg);\n }\n /**\n * Disconnect a slot from the signal.\n *\n * @param slot - The slot to disconnect from the signal.\n *\n * @param thisArg - The `this` context for the slot. If provided,\n * this must be a non-primitive object.\n *\n * @returns `true` if the connection is removed, `false` otherwise.\n */\n disconnect(slot, thisArg) {\n return Private.disconnect(this, slot, thisArg);\n }\n /**\n * Emit the signal and invoke the connected slots.\n *\n * @param args - The args to pass to the connected slots.\n *\n * #### Notes\n * Slots are invoked synchronously in connection order.\n *\n * Exceptions thrown by connected slots will be caught and logged.\n */\n emit(args) {\n Private.emit(this, args);\n }\n}\n/**\n * The namespace for the `Signal` class statics.\n */\n(function (Signal) {\n /**\n * Remove all connections between a sender and receiver.\n *\n * @param sender - The sender object of interest.\n *\n * @param receiver - The receiver object of interest.\n *\n * #### Notes\n * If a `thisArg` is provided when connecting a signal, that object\n * is considered the receiver. Otherwise, the `slot` is considered\n * the receiver.\n */\n function disconnectBetween(sender, receiver) {\n Private.disconnectBetween(sender, receiver);\n }\n Signal.disconnectBetween = disconnectBetween;\n /**\n * Remove all connections where the given object is the sender.\n *\n * @param sender - The sender object of interest.\n */\n function disconnectSender(sender) {\n Private.disconnectSender(sender);\n }\n Signal.disconnectSender = disconnectSender;\n /**\n * Remove all connections where the given object is the receiver.\n *\n * @param receiver - The receiver object of interest.\n *\n * #### Notes\n * If a `thisArg` is provided when connecting a signal, that object\n * is considered the receiver. Otherwise, the `slot` is considered\n * the receiver.\n */\n function disconnectReceiver(receiver) {\n Private.disconnectReceiver(receiver);\n }\n Signal.disconnectReceiver = disconnectReceiver;\n /**\n * Remove all connections where an object is the sender or receiver.\n *\n * @param object - The object of interest.\n *\n * #### Notes\n * If a `thisArg` is provided when connecting a signal, that object\n * is considered the receiver. Otherwise, the `slot` is considered\n * the receiver.\n */\n function disconnectAll(object) {\n Private.disconnectAll(object);\n }\n Signal.disconnectAll = disconnectAll;\n /**\n * Clear all signal data associated with the given object.\n *\n * @param object - The object for which the data should be cleared.\n *\n * #### Notes\n * This removes all signal connections and any other signal data\n * associated with the object.\n */\n function clearData(object) {\n Private.disconnectAll(object);\n }\n Signal.clearData = clearData;\n /**\n * Get the signal exception handler.\n *\n * @returns The current exception handler.\n *\n * #### Notes\n * The default exception handler is `console.error`.\n */\n function getExceptionHandler() {\n return Private.exceptionHandler;\n }\n Signal.getExceptionHandler = getExceptionHandler;\n /**\n * Set the signal exception handler.\n *\n * @param handler - The function to use as the exception handler.\n *\n * @returns The old exception handler.\n *\n * #### Notes\n * The exception handler is invoked when a slot throws an exception.\n */\n function setExceptionHandler(handler) {\n let old = Private.exceptionHandler;\n Private.exceptionHandler = handler;\n return old;\n }\n Signal.setExceptionHandler = setExceptionHandler;\n})(Signal || (Signal = {}));\n/**\n * A concrete implementation of `IStream`.\n *\n * #### Example\n * ```typescript\n * import { IStream, Stream } from '@lumino/signaling';\n *\n * class SomeClass {\n *\n * constructor(name: string) {\n * this.name = name;\n * }\n *\n * readonly name: string;\n *\n * get pings(): IStream {\n * return this._pings;\n * }\n *\n * ping(value: string) {\n * this._pings.emit(value);\n * }\n *\n * private _pings = new Stream(this);\n * }\n *\n * let m1 = new SomeClass('foo');\n *\n * m1.pings.connect((_, value: string) => {\n * console.log('connect', value);\n * });\n *\n * void (async () => {\n * for await (const ping of m1.pings) {\n * console.log('iterator', ping);\n * }\n * })();\n *\n * m1.ping('alpha'); // logs: connect alpha\n * // logs: iterator alpha\n * m1.ping('beta'); // logs: connect beta\n * // logs: iterator beta\n * ```\n */\nclass Stream extends Signal {\n constructor() {\n super(...arguments);\n this._pending = new PromiseDelegate();\n }\n /**\n * Return an async iterator that yields every emission.\n */\n async *[Symbol.asyncIterator]() {\n let pending = this._pending;\n while (true) {\n try {\n const { args, next } = await pending.promise;\n pending = next;\n yield args;\n }\n catch (_) {\n return; // Any promise rejection stops the iterator.\n }\n }\n }\n /**\n * Emit the signal, invoke the connected slots, and yield the emission.\n *\n * @param args - The args to pass to the connected slots.\n */\n emit(args) {\n const pending = this._pending;\n const next = (this._pending = new PromiseDelegate());\n pending.resolve({ args, next });\n super.emit(args);\n }\n /**\n * Stop the stream's async iteration.\n */\n stop() {\n this._pending.promise.catch(() => undefined);\n this._pending.reject('stop');\n this._pending = new PromiseDelegate();\n }\n}\n/**\n * The namespace for the module implementation details.\n */\nvar Private;\n(function (Private) {\n /**\n * The signal exception handler function.\n */\n Private.exceptionHandler = (err) => {\n console.error(err);\n };\n /**\n * Connect a slot to a signal.\n *\n * @param signal - The signal of interest.\n *\n * @param slot - The slot to invoke when the signal is emitted.\n *\n * @param thisArg - The `this` context for the slot. If provided,\n * this must be a non-primitive object.\n *\n * @returns `true` if the connection succeeds, `false` otherwise.\n */\n function connect(signal, slot, thisArg) {\n // Coerce a `null` `thisArg` to `undefined`.\n thisArg = thisArg || undefined;\n // Ensure the sender's array of receivers is created.\n let receivers = receiversForSender.get(signal.sender);\n if (!receivers) {\n receivers = [];\n receiversForSender.set(signal.sender, receivers);\n }\n // Bail if a matching connection already exists.\n if (findConnection(receivers, signal, slot, thisArg)) {\n return false;\n }\n // Choose the best object for the receiver.\n let receiver = thisArg || slot;\n // Ensure the receiver's array of senders is created.\n let senders = sendersForReceiver.get(receiver);\n if (!senders) {\n senders = [];\n sendersForReceiver.set(receiver, senders);\n }\n // Create a new connection and add it to the end of each array.\n let connection = { signal, slot, thisArg };\n receivers.push(connection);\n senders.push(connection);\n // Indicate a successful connection.\n return true;\n }\n Private.connect = connect;\n /**\n * Disconnect a slot from a signal.\n *\n * @param signal - The signal of interest.\n *\n * @param slot - The slot to disconnect from the signal.\n *\n * @param thisArg - The `this` context for the slot. If provided,\n * this must be a non-primitive object.\n *\n * @returns `true` if the connection is removed, `false` otherwise.\n */\n function disconnect(signal, slot, thisArg) {\n // Coerce a `null` `thisArg` to `undefined`.\n thisArg = thisArg || undefined;\n // Lookup the list of receivers, and bail if none exist.\n let receivers = receiversForSender.get(signal.sender);\n if (!receivers || receivers.length === 0) {\n return false;\n }\n // Bail if no matching connection exits.\n let connection = findConnection(receivers, signal, slot, thisArg);\n if (!connection) {\n return false;\n }\n // Choose the best object for the receiver.\n let receiver = thisArg || slot;\n // Lookup the array of senders, which is now known to exist.\n let senders = sendersForReceiver.get(receiver);\n // Clear the connection and schedule cleanup of the arrays.\n connection.signal = null;\n scheduleCleanup(receivers);\n scheduleCleanup(senders);\n // Indicate a successful disconnection.\n return true;\n }\n Private.disconnect = disconnect;\n /**\n * Remove all connections between a sender and receiver.\n *\n * @param sender - The sender object of interest.\n *\n * @param receiver - The receiver object of interest.\n */\n function disconnectBetween(sender, receiver) {\n // If there are no receivers, there is nothing to do.\n let receivers = receiversForSender.get(sender);\n if (!receivers || receivers.length === 0) {\n return;\n }\n // If there are no senders, there is nothing to do.\n let senders = sendersForReceiver.get(receiver);\n if (!senders || senders.length === 0) {\n return;\n }\n // Clear each connection between the sender and receiver.\n for (const connection of senders) {\n // Skip connections which have already been cleared.\n if (!connection.signal) {\n continue;\n }\n // Clear the connection if it matches the sender.\n if (connection.signal.sender === sender) {\n connection.signal = null;\n }\n }\n // Schedule a cleanup of the senders and receivers.\n scheduleCleanup(receivers);\n scheduleCleanup(senders);\n }\n Private.disconnectBetween = disconnectBetween;\n /**\n * Remove all connections where the given object is the sender.\n *\n * @param sender - The sender object of interest.\n */\n function disconnectSender(sender) {\n // If there are no receivers, there is nothing to do.\n let receivers = receiversForSender.get(sender);\n if (!receivers || receivers.length === 0) {\n return;\n }\n // Clear each receiver connection.\n for (const connection of receivers) {\n // Skip connections which have already been cleared.\n if (!connection.signal) {\n continue;\n }\n // Choose the best object for the receiver.\n let receiver = connection.thisArg || connection.slot;\n // Clear the connection.\n connection.signal = null;\n // Cleanup the array of senders, which is now known to exist.\n scheduleCleanup(sendersForReceiver.get(receiver));\n }\n // Schedule a cleanup of the receivers.\n scheduleCleanup(receivers);\n }\n Private.disconnectSender = disconnectSender;\n /**\n * Remove all connections where the given object is the receiver.\n *\n * @param receiver - The receiver object of interest.\n */\n function disconnectReceiver(receiver) {\n // If there are no senders, there is nothing to do.\n let senders = sendersForReceiver.get(receiver);\n if (!senders || senders.length === 0) {\n return;\n }\n // Clear each sender connection.\n for (const connection of senders) {\n // Skip connections which have already been cleared.\n if (!connection.signal) {\n continue;\n }\n // Lookup the sender for the connection.\n let sender = connection.signal.sender;\n // Clear the connection.\n connection.signal = null;\n // Cleanup the array of receivers, which is now known to exist.\n scheduleCleanup(receiversForSender.get(sender));\n }\n // Schedule a cleanup of the list of senders.\n scheduleCleanup(senders);\n }\n Private.disconnectReceiver = disconnectReceiver;\n /**\n * Remove all connections where an object is the sender or receiver.\n *\n * @param object - The object of interest.\n */\n function disconnectAll(object) {\n // Remove all connections where the given object is the sender.\n disconnectSender(object);\n // Remove all connections where the given object is the receiver.\n disconnectReceiver(object);\n }\n Private.disconnectAll = disconnectAll;\n /**\n * Emit a signal and invoke its connected slots.\n *\n * @param signal - The signal of interest.\n *\n * @param args - The args to pass to the connected slots.\n *\n * #### Notes\n * Slots are invoked synchronously in connection order.\n *\n * Exceptions thrown by connected slots will be caught and logged.\n */\n function emit(signal, args) {\n // If there are no receivers, there is nothing to do.\n let receivers = receiversForSender.get(signal.sender);\n if (!receivers || receivers.length === 0) {\n return;\n }\n // Invoke the slots for connections with a matching signal.\n // Any connections added during emission are not invoked.\n for (let i = 0, n = receivers.length; i < n; ++i) {\n let connection = receivers[i];\n if (connection.signal === signal) {\n invokeSlot(connection, args);\n }\n }\n }\n Private.emit = emit;\n /**\n * A weak mapping of sender to array of receiver connections.\n */\n const receiversForSender = new WeakMap();\n /**\n * A weak mapping of receiver to array of sender connections.\n */\n const sendersForReceiver = new WeakMap();\n /**\n * A set of connection arrays which are pending cleanup.\n */\n const dirtySet = new Set();\n /**\n * A function to schedule an event loop callback.\n */\n const schedule = (() => {\n let ok = typeof requestAnimationFrame === 'function';\n return ok ? requestAnimationFrame : setImmediate;\n })();\n /**\n * Find a connection which matches the given parameters.\n */\n function findConnection(connections, signal, slot, thisArg) {\n return find(connections, connection => connection.signal === signal &&\n connection.slot === slot &&\n connection.thisArg === thisArg);\n }\n /**\n * Invoke a slot with the given parameters.\n *\n * The connection is assumed to be valid.\n *\n * Exceptions in the slot will be caught and logged.\n */\n function invokeSlot(connection, args) {\n let { signal, slot, thisArg } = connection;\n try {\n slot.call(thisArg, signal.sender, args);\n }\n catch (err) {\n Private.exceptionHandler(err);\n }\n }\n /**\n * Schedule a cleanup of a connection array.\n *\n * This will add the array to the dirty set and schedule a deferred\n * cleanup of the array contents. On cleanup, any connection with a\n * `null` signal will be removed from the array.\n */\n function scheduleCleanup(array) {\n if (dirtySet.size === 0) {\n schedule(cleanupDirtySet);\n }\n dirtySet.add(array);\n }\n /**\n * Cleanup the connection lists in the dirty set.\n *\n * This function should only be invoked asynchronously, when the\n * stack frame is guaranteed to not be on the path of user code.\n */\n function cleanupDirtySet() {\n dirtySet.forEach(cleanupConnections);\n dirtySet.clear();\n }\n /**\n * Cleanup the dirty connections in a connections array.\n *\n * This will remove any connection with a `null` signal.\n *\n * This function should only be invoked asynchronously, when the\n * stack frame is guaranteed to not be on the path of user code.\n */\n function cleanupConnections(connections) {\n ArrayExt.removeAllWhere(connections, isDeadConnection);\n }\n /**\n * Test whether a connection is dead.\n *\n * A dead connection has a `null` signal.\n */\n function isDeadConnection(connection) {\n return connection.signal === null;\n }\n})(Private || (Private = {}));\n\nexport { Signal, Stream };\n//# sourceMappingURL=index.es6.js.map\n","'use strict';\n\nvar isMergeableObject = function isMergeableObject(value) {\n\treturn isNonNullObject(value)\n\t\t&& !isSpecial(value)\n};\n\nfunction isNonNullObject(value) {\n\treturn !!value && typeof value === 'object'\n}\n\nfunction isSpecial(value) {\n\tvar stringValue = Object.prototype.toString.call(value);\n\n\treturn stringValue === '[object RegExp]'\n\t\t|| stringValue === '[object Date]'\n\t\t|| isReactElement(value)\n}\n\n// see https://github.com/facebook/react/blob/b5ac963fb791d1298e7f396236383bc955f916c1/src/isomorphic/classic/element/ReactElement.js#L21-L25\nvar canUseSymbol = typeof Symbol === 'function' && Symbol.for;\nvar REACT_ELEMENT_TYPE = canUseSymbol ? Symbol.for('react.element') : 0xeac7;\n\nfunction isReactElement(value) {\n\treturn value.$$typeof === REACT_ELEMENT_TYPE\n}\n\nfunction emptyTarget(val) {\n\treturn Array.isArray(val) ? [] : {}\n}\n\nfunction cloneUnlessOtherwiseSpecified(value, options) {\n\treturn (options.clone !== false && options.isMergeableObject(value))\n\t\t? deepmerge(emptyTarget(value), value, options)\n\t\t: value\n}\n\nfunction defaultArrayMerge(target, source, options) {\n\treturn target.concat(source).map(function(element) {\n\t\treturn cloneUnlessOtherwiseSpecified(element, options)\n\t})\n}\n\nfunction getMergeFunction(key, options) {\n\tif (!options.customMerge) {\n\t\treturn deepmerge\n\t}\n\tvar customMerge = options.customMerge(key);\n\treturn typeof customMerge === 'function' ? customMerge : deepmerge\n}\n\nfunction getEnumerableOwnPropertySymbols(target) {\n\treturn Object.getOwnPropertySymbols\n\t\t? Object.getOwnPropertySymbols(target).filter(function(symbol) {\n\t\t\treturn Object.propertyIsEnumerable.call(target, symbol)\n\t\t})\n\t\t: []\n}\n\nfunction getKeys(target) {\n\treturn Object.keys(target).concat(getEnumerableOwnPropertySymbols(target))\n}\n\nfunction propertyIsOnObject(object, property) {\n\ttry {\n\t\treturn property in object\n\t} catch(_) {\n\t\treturn false\n\t}\n}\n\n// Protects from prototype poisoning and unexpected merging up the prototype chain.\nfunction propertyIsUnsafe(target, key) {\n\treturn propertyIsOnObject(target, key) // Properties are safe to merge if they don't exist in the target yet,\n\t\t&& !(Object.hasOwnProperty.call(target, key) // unsafe if they exist up the prototype chain,\n\t\t\t&& Object.propertyIsEnumerable.call(target, key)) // and also unsafe if they're nonenumerable.\n}\n\nfunction mergeObject(target, source, options) {\n\tvar destination = {};\n\tif (options.isMergeableObject(target)) {\n\t\tgetKeys(target).forEach(function(key) {\n\t\t\tdestination[key] = cloneUnlessOtherwiseSpecified(target[key], options);\n\t\t});\n\t}\n\tgetKeys(source).forEach(function(key) {\n\t\tif (propertyIsUnsafe(target, key)) {\n\t\t\treturn\n\t\t}\n\n\t\tif (propertyIsOnObject(target, key) && options.isMergeableObject(source[key])) {\n\t\t\tdestination[key] = getMergeFunction(key, options)(target[key], source[key], options);\n\t\t} else {\n\t\t\tdestination[key] = cloneUnlessOtherwiseSpecified(source[key], options);\n\t\t}\n\t});\n\treturn destination\n}\n\nfunction deepmerge(target, source, options) {\n\toptions = options || {};\n\toptions.arrayMerge = options.arrayMerge || defaultArrayMerge;\n\toptions.isMergeableObject = options.isMergeableObject || isMergeableObject;\n\t// cloneUnlessOtherwiseSpecified is added to `options` so that custom arrayMerge()\n\t// implementations can use it. The caller may not replace it.\n\toptions.cloneUnlessOtherwiseSpecified = cloneUnlessOtherwiseSpecified;\n\n\tvar sourceIsArray = Array.isArray(source);\n\tvar targetIsArray = Array.isArray(target);\n\tvar sourceAndTargetTypesMatch = sourceIsArray === targetIsArray;\n\n\tif (!sourceAndTargetTypesMatch) {\n\t\treturn cloneUnlessOtherwiseSpecified(source, options)\n\t} else if (sourceIsArray) {\n\t\treturn options.arrayMerge(target, source, options)\n\t} else {\n\t\treturn mergeObject(target, source, options)\n\t}\n}\n\ndeepmerge.all = function deepmergeAll(array, options) {\n\tif (!Array.isArray(array)) {\n\t\tthrow new Error('first argument should be an array')\n\t}\n\n\treturn array.reduce(function(prev, next) {\n\t\treturn deepmerge(prev, next, options)\n\t}, {})\n};\n\nvar deepmerge_1 = deepmerge;\n\nmodule.exports = deepmerge_1;\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.attributeNames = exports.elementNames = void 0;\nexports.elementNames = new Map([\n [\"altglyph\", \"altGlyph\"],\n [\"altglyphdef\", \"altGlyphDef\"],\n [\"altglyphitem\", \"altGlyphItem\"],\n [\"animatecolor\", \"animateColor\"],\n [\"animatemotion\", \"animateMotion\"],\n [\"animatetransform\", \"animateTransform\"],\n [\"clippath\", \"clipPath\"],\n [\"feblend\", \"feBlend\"],\n [\"fecolormatrix\", \"feColorMatrix\"],\n [\"fecomponenttransfer\", \"feComponentTransfer\"],\n [\"fecomposite\", \"feComposite\"],\n [\"feconvolvematrix\", \"feConvolveMatrix\"],\n [\"fediffuselighting\", \"feDiffuseLighting\"],\n [\"fedisplacementmap\", \"feDisplacementMap\"],\n [\"fedistantlight\", \"feDistantLight\"],\n [\"fedropshadow\", \"feDropShadow\"],\n [\"feflood\", \"feFlood\"],\n [\"fefunca\", \"feFuncA\"],\n [\"fefuncb\", \"feFuncB\"],\n [\"fefuncg\", \"feFuncG\"],\n [\"fefuncr\", \"feFuncR\"],\n [\"fegaussianblur\", \"feGaussianBlur\"],\n [\"feimage\", \"feImage\"],\n [\"femerge\", \"feMerge\"],\n [\"femergenode\", \"feMergeNode\"],\n [\"femorphology\", \"feMorphology\"],\n [\"feoffset\", \"feOffset\"],\n [\"fepointlight\", \"fePointLight\"],\n [\"fespecularlighting\", \"feSpecularLighting\"],\n [\"fespotlight\", \"feSpotLight\"],\n [\"fetile\", \"feTile\"],\n [\"feturbulence\", \"feTurbulence\"],\n [\"foreignobject\", \"foreignObject\"],\n [\"glyphref\", \"glyphRef\"],\n [\"lineargradient\", \"linearGradient\"],\n [\"radialgradient\", \"radialGradient\"],\n [\"textpath\", \"textPath\"],\n]);\nexports.attributeNames = new Map([\n [\"definitionurl\", \"definitionURL\"],\n [\"attributename\", \"attributeName\"],\n [\"attributetype\", \"attributeType\"],\n [\"basefrequency\", \"baseFrequency\"],\n [\"baseprofile\", \"baseProfile\"],\n [\"calcmode\", \"calcMode\"],\n [\"clippathunits\", \"clipPathUnits\"],\n [\"diffuseconstant\", \"diffuseConstant\"],\n [\"edgemode\", \"edgeMode\"],\n [\"filterunits\", \"filterUnits\"],\n [\"glyphref\", \"glyphRef\"],\n [\"gradienttransform\", \"gradientTransform\"],\n [\"gradientunits\", \"gradientUnits\"],\n [\"kernelmatrix\", \"kernelMatrix\"],\n [\"kernelunitlength\", \"kernelUnitLength\"],\n [\"keypoints\", \"keyPoints\"],\n [\"keysplines\", \"keySplines\"],\n [\"keytimes\", \"keyTimes\"],\n [\"lengthadjust\", \"lengthAdjust\"],\n [\"limitingconeangle\", \"limitingConeAngle\"],\n [\"markerheight\", \"markerHeight\"],\n [\"markerunits\", \"markerUnits\"],\n [\"markerwidth\", \"markerWidth\"],\n [\"maskcontentunits\", \"maskContentUnits\"],\n [\"maskunits\", \"maskUnits\"],\n [\"numoctaves\", \"numOctaves\"],\n [\"pathlength\", \"pathLength\"],\n [\"patterncontentunits\", \"patternContentUnits\"],\n [\"patterntransform\", \"patternTransform\"],\n [\"patternunits\", \"patternUnits\"],\n [\"pointsatx\", \"pointsAtX\"],\n [\"pointsaty\", \"pointsAtY\"],\n [\"pointsatz\", \"pointsAtZ\"],\n [\"preservealpha\", \"preserveAlpha\"],\n [\"preserveaspectratio\", \"preserveAspectRatio\"],\n [\"primitiveunits\", \"primitiveUnits\"],\n [\"refx\", \"refX\"],\n [\"refy\", \"refY\"],\n [\"repeatcount\", \"repeatCount\"],\n [\"repeatdur\", \"repeatDur\"],\n [\"requiredextensions\", \"requiredExtensions\"],\n [\"requiredfeatures\", \"requiredFeatures\"],\n [\"specularconstant\", \"specularConstant\"],\n [\"specularexponent\", \"specularExponent\"],\n [\"spreadmethod\", \"spreadMethod\"],\n [\"startoffset\", \"startOffset\"],\n [\"stddeviation\", \"stdDeviation\"],\n [\"stitchtiles\", \"stitchTiles\"],\n [\"surfacescale\", \"surfaceScale\"],\n [\"systemlanguage\", \"systemLanguage\"],\n [\"tablevalues\", \"tableValues\"],\n [\"targetx\", \"targetX\"],\n [\"targety\", \"targetY\"],\n [\"textlength\", \"textLength\"],\n [\"viewbox\", \"viewBox\"],\n [\"viewtarget\", \"viewTarget\"],\n [\"xchannelselector\", \"xChannelSelector\"],\n [\"ychannelselector\", \"yChannelSelector\"],\n [\"zoomandpan\", \"zoomAndPan\"],\n]);\n","\"use strict\";\nvar __assign = (this && this.__assign) || function () {\n __assign = Object.assign || function(t) {\n for (var s, i = 1, n = arguments.length; i < n; i++) {\n s = arguments[i];\n for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))\n t[p] = s[p];\n }\n return t;\n };\n return __assign.apply(this, arguments);\n};\nvar __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });\n}) : (function(o, m, k, k2) {\n if (k2 === undefined) k2 = k;\n o[k2] = m[k];\n}));\nvar __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {\n Object.defineProperty(o, \"default\", { enumerable: true, value: v });\n}) : function(o, v) {\n o[\"default\"] = v;\n});\nvar __importStar = (this && this.__importStar) || function (mod) {\n if (mod && mod.__esModule) return mod;\n var result = {};\n if (mod != null) for (var k in mod) if (k !== \"default\" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);\n __setModuleDefault(result, mod);\n return result;\n};\nObject.defineProperty(exports, \"__esModule\", { value: true });\n/*\n * Module dependencies\n */\nvar ElementType = __importStar(require(\"domelementtype\"));\nvar entities_1 = require(\"entities\");\n/**\n * Mixed-case SVG and MathML tags & attributes\n * recognized by the HTML parser.\n *\n * @see https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inforeign\n */\nvar foreignNames_1 = require(\"./foreignNames\");\nvar unencodedElements = new Set([\n \"style\",\n \"script\",\n \"xmp\",\n \"iframe\",\n \"noembed\",\n \"noframes\",\n \"plaintext\",\n \"noscript\",\n]);\n/**\n * Format attributes\n */\nfunction formatAttributes(attributes, opts) {\n if (!attributes)\n return;\n return Object.keys(attributes)\n .map(function (key) {\n var _a, _b;\n var value = (_a = attributes[key]) !== null && _a !== void 0 ? _a : \"\";\n if (opts.xmlMode === \"foreign\") {\n /* Fix up mixed-case attribute names */\n key = (_b = foreignNames_1.attributeNames.get(key)) !== null && _b !== void 0 ? _b : key;\n }\n if (!opts.emptyAttrs && !opts.xmlMode && value === \"\") {\n return key;\n }\n return key + \"=\\\"\" + (opts.decodeEntities !== false\n ? entities_1.encodeXML(value)\n : value.replace(/\"/g, \""\")) + \"\\\"\";\n })\n .join(\" \");\n}\n/**\n * Self-enclosing tags\n */\nvar singleTag = new Set([\n \"area\",\n \"base\",\n \"basefont\",\n \"br\",\n \"col\",\n \"command\",\n \"embed\",\n \"frame\",\n \"hr\",\n \"img\",\n \"input\",\n \"isindex\",\n \"keygen\",\n \"link\",\n \"meta\",\n \"param\",\n \"source\",\n \"track\",\n \"wbr\",\n]);\n/**\n * Renders a DOM node or an array of DOM nodes to a string.\n *\n * Can be thought of as the equivalent of the `outerHTML` of the passed node(s).\n *\n * @param node Node to be rendered.\n * @param options Changes serialization behavior\n */\nfunction render(node, options) {\n if (options === void 0) { options = {}; }\n var nodes = \"length\" in node ? node : [node];\n var output = \"\";\n for (var i = 0; i < nodes.length; i++) {\n output += renderNode(nodes[i], options);\n }\n return output;\n}\nexports.default = render;\nfunction renderNode(node, options) {\n switch (node.type) {\n case ElementType.Root:\n return render(node.children, options);\n case ElementType.Directive:\n case ElementType.Doctype:\n return renderDirective(node);\n case ElementType.Comment:\n return renderComment(node);\n case ElementType.CDATA:\n return renderCdata(node);\n case ElementType.Script:\n case ElementType.Style:\n case ElementType.Tag:\n return renderTag(node, options);\n case ElementType.Text:\n return renderText(node, options);\n }\n}\nvar foreignModeIntegrationPoints = new Set([\n \"mi\",\n \"mo\",\n \"mn\",\n \"ms\",\n \"mtext\",\n \"annotation-xml\",\n \"foreignObject\",\n \"desc\",\n \"title\",\n]);\nvar foreignElements = new Set([\"svg\", \"math\"]);\nfunction renderTag(elem, opts) {\n var _a;\n // Handle SVG / MathML in HTML\n if (opts.xmlMode === \"foreign\") {\n /* Fix up mixed-case element names */\n elem.name = (_a = foreignNames_1.elementNames.get(elem.name)) !== null && _a !== void 0 ? _a : elem.name;\n /* Exit foreign mode at integration points */\n if (elem.parent &&\n foreignModeIntegrationPoints.has(elem.parent.name)) {\n opts = __assign(__assign({}, opts), { xmlMode: false });\n }\n }\n if (!opts.xmlMode && foreignElements.has(elem.name)) {\n opts = __assign(__assign({}, opts), { xmlMode: \"foreign\" });\n }\n var tag = \"<\" + elem.name;\n var attribs = formatAttributes(elem.attribs, opts);\n if (attribs) {\n tag += \" \" + attribs;\n }\n if (elem.children.length === 0 &&\n (opts.xmlMode\n ? // In XML mode or foreign mode, and user hasn't explicitly turned off self-closing tags\n opts.selfClosingTags !== false\n : // User explicitly asked for self-closing tags, even in HTML mode\n opts.selfClosingTags && singleTag.has(elem.name))) {\n if (!opts.xmlMode)\n tag += \" \";\n tag += \"/>\";\n }\n else {\n tag += \">\";\n if (elem.children.length > 0) {\n tag += render(elem.children, opts);\n }\n if (opts.xmlMode || !singleTag.has(elem.name)) {\n tag += \"\";\n }\n }\n return tag;\n}\nfunction renderDirective(elem) {\n return \"<\" + elem.data + \">\";\n}\nfunction renderText(elem, opts) {\n var data = elem.data || \"\";\n // If entities weren't decoded, no need to encode them back\n if (opts.decodeEntities !== false &&\n !(!opts.xmlMode &&\n elem.parent &&\n unencodedElements.has(elem.parent.name))) {\n data = entities_1.encodeXML(data);\n }\n return data;\n}\nfunction renderCdata(elem) {\n return \"\";\n}\nfunction renderComment(elem) {\n return \"\";\n}\n","\"use strict\";\nObject.defineProperty(exports, \"__esModule\", { value: true });\nexports.Doctype = exports.CDATA = exports.Tag = exports.Style = exports.Script = exports.Comment = exports.Directive = exports.Text = exports.Root = exports.isTag = exports.ElementType = void 0;\n/** Types of elements found in htmlparser2's DOM */\nvar ElementType;\n(function (ElementType) {\n /** Type for the root element of a document */\n ElementType[\"Root\"] = \"root\";\n /** Type for Text */\n ElementType[\"Text\"] = \"text\";\n /** Type for */\n ElementType[\"Directive\"] = \"directive\";\n /** Type for */\n ElementType[\"Comment\"] = \"comment\";\n /** Type for - -**Thank you for contributing!** diff --git a/docs/source/contributing/docs.rst b/docs/source/contributing/docs.rst new file mode 100644 index 0000000000..aaac806a83 --- /dev/null +++ b/docs/source/contributing/docs.rst @@ -0,0 +1,84 @@ +==================== +Adding Documentation +==================== + +Building the documentation +-------------------------- + +When you clone the Manim repository from GitHub, you can access the +``docs/`` folder which contains the necessary files to build the +documentation. + +To build the docs locally, open a CLI, enter the ``docs/`` folder with the +``cd`` command and execute the following depending on your OS: + +- Windows: ``./make.bat html`` +- macOS and Linux: ``make html`` + +The first time you build the docs, the process will take several +minutes because it needs to generate all the ``.rst`` (reST: +reStructured Text) files from scratch by reading and parsing all the +Manim content. The process becomes much shorter the next time, as it +rebuilds only the parts which have changed. + + +Sphinx library and extensions +----------------------------- + +Manim uses `Sphinx `_ for building the +docs. It also makes use of Sphinx extensions such as: + +- `Autodoc: `_ + imports Manim's Python source code, extracts its docstrings and + generates documentation from them. +- `Autosummary: `_ + a complement to Autodoc which adds a special directive ``autosummary``, + used in Manim to automatically document classes, methods, + attributes, functions, module-level variables and exceptions. + Autosummary makes use of `Jinja templates `_, + which Manim defines for autosummarizing classes and modules + inside ``docs/source/_templates/``. +- `Graphviz extension for Sphinx: `_ + embeds graphs generated by the `Graphviz `_ + module, which must be installed in order to render the + inheritance diagrams in the :doc:`/reference`. +- `Napoleon: `_ + enables Sphinx to read Google style docstrings and, in + particular for Manim, `NumPy style docstrings `_ + - see :doc:`docs/docstrings` for more information. + + +Sphinx theme +------------ + +The theme used for this website is `Furo `_. + + +Custom Sphinx directives +------------------------ + +Manim implements **custom directives** for use with Autodoc and Autosummary, which +are defined in :mod:`~.docbuild`: + +.. currentmodule:: manim.utils.docbuild + +.. autosummary:: + + :toctree: ../reference + autoaliasattr_directive + autocolor_directive + manim_directive + + +Index +----- + +.. toctree:: + :maxdepth: 2 + + docs/admonitions + docs/docstrings + docs/examples + docs/references + docs/typings + docs/types diff --git a/docs/source/contributing/admonitions.rst b/docs/source/contributing/docs/admonitions.rst similarity index 100% rename from docs/source/contributing/admonitions.rst rename to docs/source/contributing/docs/admonitions.rst diff --git a/docs/source/contributing/docstrings.rst b/docs/source/contributing/docs/docstrings.rst similarity index 99% rename from docs/source/contributing/docstrings.rst rename to docs/source/contributing/docs/docstrings.rst index 86ee68f81c..5851f5d1ff 100644 --- a/docs/source/contributing/docstrings.rst +++ b/docs/source/contributing/docs/docstrings.rst @@ -77,8 +77,7 @@ Example: The mobject linked to this instance. """ - def __init__(name: str, id: int, singleton: MyClass, mobj: Mobject = None): - ... + def __init__(name: str, id: int, singleton: MyClass, mobj: Mobject = None): ... 2. The usage of ``Parameters`` on functions to specify how every parameter works and what it does. This should be excluded if diff --git a/docs/source/contributing/examples.rst b/docs/source/contributing/docs/examples.rst similarity index 100% rename from docs/source/contributing/examples.rst rename to docs/source/contributing/docs/examples.rst diff --git a/docs/source/contributing/references.rst b/docs/source/contributing/docs/references.rst similarity index 100% rename from docs/source/contributing/references.rst rename to docs/source/contributing/docs/references.rst diff --git a/docs/source/contributing/docs/types.rst b/docs/source/contributing/docs/types.rst new file mode 100644 index 0000000000..840d29e6c0 --- /dev/null +++ b/docs/source/contributing/docs/types.rst @@ -0,0 +1,153 @@ +=================== +Choosing Type Hints +=================== +In order to provide the best user experience, +it's important that type hints are chosen correctly. +With the large variety of types provided by Manim, choosing +which one to use can be difficult. This guide aims to +aid you in the process of choosing the right type for the scenario. + + +The first step is figuring out which category your type hint fits into. + +Coordinates +----------- +Coordinates encompass two main categories: points, and vectors. + + +Points +~~~~~~ +The purpose of points is pretty straightforward: they represent a point +in space. For example: + +.. code-block:: python + + def print_point2D(coord: Point2DLike) -> None: + x, y = coord + print(f"Point at {x=},{y=}") + + + def print_point3D(coord: Point3DLike) -> None: + x, y, z = coord + print(f"Point at {x=},{y=},{z=}") + + + def print_point_array(coords: Point2DLike_Array | Point3DLike_Array) -> None: + for coord in coords: + if len(coord) == 2: + # it's a Point2DLike + print_point2D(coord) + else: + # it's a Point3DLike + print_point3D(coord) + + def shift_point_up(coord: Point3DLike) -> Point3D: + result = np.asarray(coord) + result += UP + print(f"New point: {result}") + return result + +Notice that the last function, ``shift_point_up()``, accepts a +:class:`~.Point3DLike` as a parameter and returns a :class:`~.Point3D`. A +:class:`~.Point3D` always represents a NumPy array consisting of 3 floats, +whereas a :class:`~.Point3DLike` can represent anything resembling a 3D point: +either a NumPy array or a tuple/list of 3 floats, hence the ``Like`` word. The +same happens with :class:`~.Point2D`, :class:`~.Point2D_Array` and +:class:`~.Point3D_Array`, and their ``Like`` counterparts +:class:`~.Point2DLike`, :class:`~.Point2DLike_Array` and +:class:`~.Point3DLike_Array`. + +The rule for typing functions is: **make parameter types as broad as possible, +and return types as specific as possible.** Therefore, for functions which are +intended to be called by users, **we should always, if possible, accept** +``Like`` **types as parameters and return NumPy, non-** ``Like`` **types.** The +main reason is to be more flexible with users who might want to pass tuples or +lists as arguments rather than NumPy arrays, because it's more convenient. The +last function, ``shift_point_up()``, is an example of it. + +Internal functions which are *not* meant to be called by users may accept +non-``Like`` parameters if necessary. + +Vectors +~~~~~~~ +Vectors share many similarities to points. However, they have a different +connotation. Vectors should be used to represent direction. For example, +consider this slightly contrived function: + +.. code-block:: python + + M = TypeVar("M", bound=Mobject) # allow any mobject + def shift_mobject(mob: M, direction: Vector3D, scale_factor: float = 1) -> M: + return mob.shift(direction * scale_factor) + +Here we see an important example of the difference. ``direction`` should not be +typed as a :class:`~.Point3D`, because it represents a direction along +which to shift a :class:`~.Mobject`, not a position in space. + +As a general rule, if a parameter is called ``direction`` or ``axis``, +it should be type hinted as some form of :class:`~.VectorND`. + +.. warning:: + + This is not always true. For example, as of Manim 0.18.0, the direction + parameter of the :class:`.Vector` Mobject should be + ``Point2DLike | Point3DLike``, as it can also accept ``tuple[float, float]`` + and ``tuple[float, float, float]``. + +Colors +------ +The interface Manim provides for working with colors is :class:`.ManimColor`. +The main color types Manim supports are RGB, RGBA, and HSV. You will want +to add type hints to a function depending on which type it uses. If any color will work, +you will need something like: + +.. code-block:: python + + if TYPE_CHECKING: + from manim.utils.color import ParsableManimColor + + # type hint stuff with ParsableManimColor + + + +Béziers +------- +Manim internally represents a :class:`.Mobject` by a collection of points. In the case of :class:`.VMobject`, +the most commonly used subclass of :class:`.Mobject`, these points represent Bézier curves, +which are a way of representing a curve using a sequence of points. + +.. note:: + + To learn more about Béziers, take a look at https://pomax.github.io/bezierinfo/ + + +Manim supports two different renderers, which each have different representations of +Béziers: Cairo uses cubic Bézier curves, while OpenGL uses quadratic Bézier curves. + +Type hints like :class:`~.typing.BezierPoints` represent a single bezier curve, and :class:`~.typing.BezierPath` +represents multiple Bézier curves. A :class:`~.typing.Spline` is when the Bézier curves in a :class:`~.typing.BezierPath` +forms a single connected curve. Manim also provides more specific type aliases when working with +quadratic or cubic curves, and they are prefixed with their respective type (e.g. :class:`~.typing.CubicBezierPoints`, +is a :class:`~.typing.BezierPoints` consisting of exactly 4 points representing a cubic Bézier curve). + + +Functions +--------- +Throughout the codebase, many different types of functions are used. The most obvious example +is a rate function, which takes in a float and outputs a float (``Callable[[float], float]``). +Another example is for overriding animations. One will often need to map a :class:`.Mobject` +to an overridden :class:`.Animation`, and for that we have the :class:`~.typing.FunctionOverride` type hint. + +:class:`~.typing.PathFuncType` and :class:`~.typing.MappingFunction` are more niche, but are related to moving objects +along a path, or applying functions. If you need to use it, you'll know. + + +Images +------ +There are several representations of images in Manim. The most common is +the representation as a NumPy array of floats representing the pixels of an image. +This is especially common when it comes to the OpenGL renderer. + +This is the use case of the :class:`~.typing.PixelArray` type hint. Sometimes, Manim may use ``PIL.Image.Image``, +which is not the same as :class:`~.typing.PixelArray`. In this case, use the ``PIL.Image.Image`` typehint. +Of course, if a more specific type of image is needed, it can be annotated as such. diff --git a/docs/source/contributing/docs/typings.rst b/docs/source/contributing/docs/typings.rst new file mode 100644 index 0000000000..7cc14068c8 --- /dev/null +++ b/docs/source/contributing/docs/typings.rst @@ -0,0 +1,148 @@ +================== +Typing Conventions +================== + +.. warning:: + This section is still a work in progress. + +Adding type hints to functions and parameters +--------------------------------------------- + +Manim is currently in the process of adding type hints into the library. In this +section, you will find information about the standards used and some general +guidelines. + +If you've never used type hints before, this is a good place to get started: +https://realpython.com/python-type-checking/#hello-types. + +Typing standards +~~~~~~~~~~~~~~~~ + +Manim uses `mypy`_ to type check its codebase. You will find a list of configuration values in the ``mypy.ini`` configuration file. +To be able to use the newest typing features not available in the lowest +supported Python version, make use of `typing_extensions`_. + +To be able to use the new Union syntax (``|``) and builtins subscripting, use +the ``from __future__ import annotations`` import. + +.. _mypy: https://mypy-lang.org/ +.. _typing_extensions: https://pypi.org/project/typing-extensions/ + +Typing guidelines +~~~~~~~~~~~~~~~~~ + +* Manim has a dedicated :mod:`~.typing` module where type aliases are provided. + Most of them may seem redundant, in particular the ones related to ``numpy``. + This is in anticipation of the support for shape type hinting + (`related issue `_). Besides the + pending shape support, using the correct type aliases will help users understand + which shape should be used. + +* For typings of generic collections, check out `this `_ + link. + +* Always use a type hint of ``None`` for functions that does not return + a value (this also applies to ``__init__``), e.g.: + +.. code:: py + + def height(self, value) -> None: + self.scale_to_fit_height(value) + +* For variables representing paths, use the ``StrPath`` or ``StrOrBytesPath`` + type alias defined in the :mod:`~.typing` module. + +* ``*args`` and ``**kwargs`` shouldn't be left untyped (in most cases you can + use ``Any``). + +* Following `PEP 484 `_, + use ``float`` instead of ``int | float``. + +* Use ``x | y`` instead of ``Union[x, y]`` + +* Mobjects have the typehint ``Mobject``, e.g.: + +.. code:: py + + def match_color(self, mobject: "Mobject"): + """Match the color with the color of another :class:`~.Mobject`.""" + return self.set_color(mobject.get_color()) + +* Always parametrize generics (``list[int]`` instead of ``list``, + ``type[Any]`` instead of ``type``, etc.). This also applies to callables. + +.. code:: py + + rate_func: Callable[[float], float] = lambda t: smooth(1 - t) + +* Use ``TypeVar`` when you want to "link" type hints as being the same type. + Consider ``Mobject.copy``, which returns a new instance of the same class. + It would be type-hinted as: + +.. code:: py + + T = TypeVar("T") + + + def copy(self: T) -> T: ... + +* Use ``typing.Iterable`` whenever the function works with *any* iterable, not a specific type. + +* Prefer ``numpy.typing.NDArray`` over ``numpy.ndarray`` + +.. code:: py + + import numpy as np + + if TYPE_CHECKING: + import numpy.typing as npt + + + def foo() -> npt.NDArray[float]: + return np.array([1, 0, 1]) + +* If a method returns ``self``, use ``typing_extensions.Self``. + +.. code:: py + + if TYPE_CHECKING: + from typing_extensions import Self + + + class CustomMobject: + def set_color(self, color: ManimColor) -> Self: + ... + return self + +* If the function returns a container of a specific length each time, consider using ``tuple`` instead of ``list``. + +.. code:: py + + def foo() -> tuple[float, float, float]: + return (0, 0, 0) + +* If a function works with a parameter as long as said parameter has a ``__getitem__``, ``__iter___`` and ``__len__`` method, + the typehint of the parameter should be ``collections.abc.Mapping``. If it also supports ``__setitem__`` and/or ``__delitem__``, it + should be marked as ``collections.abc.MutableMapping``. + +* Typehinting something as ``object`` means that only attributes available on every Python object should be accessed, + like ``__str__`` and so on. On the other hand, literally any attribute can be accessed on a variable with the ``Any`` typehint - + it's more freeing than the ``object`` typehint, and makes mypy stop typechecking the variable. Note that whenever possible, + try to keep typehints as specific as possible. + +* If objects are imported purely for type hint purposes, keep it under an ``if typing.TYPE_CHECKING`` guard, to prevent them from + being imported at runtime (helps library performance). Do not forget to use the ``from __future__ import annotations`` import to avoid having runtime ``NameError`` exceptions. + +.. code:: py + + from typing import TYPE_CHECKING + + if TYPE_CHECKING: + from manim.typing import Vector3D + # type stuff with Vector3D + +Missing Sections for typehints are: +----------------------------------- + +* Mypy and numpy import errors: https://realpython.com/python-type-checking/#running-mypy +* Explain ``mypy.ini`` (see above link) diff --git a/docs/source/contributing/internationalization.rst b/docs/source/contributing/internationalization.rst index e960cae660..2033c8b608 100644 --- a/docs/source/contributing/internationalization.rst +++ b/docs/source/contributing/internationalization.rst @@ -28,7 +28,7 @@ Contributing That being said, improving the documentation and making it more accessible is still highly encouraged. And even if your work gets outdated and requires change, you or someone else can simply adjust the translation. -Your efforts are not in vail! +Your efforts are not in vain! Voting diff --git a/docs/source/contributing/testing.rst b/docs/source/contributing/testing.rst index 7f60a52074..dfc6a225f8 100644 --- a/docs/source/contributing/testing.rst +++ b/docs/source/contributing/testing.rst @@ -5,6 +5,24 @@ If you are adding new features to manim, you should add appropriate tests for th manim from breaking at each change by checking that no other feature has been broken and/or been unintentionally modified. +.. warning:: + + The full tests suite requires Cairo 1.18 in order to run all tests. + However, Cairo 1.18 may not be available from your package manager, + like ``apt``, and it is very likely that you have an older version installed, + e.g., 1.16. If you run tests with a version prior to 1.18, + many tests will be skipped. Those tests are not skipped in the online CI. + + If you want to run all tests locally, you need to install Cairo 1.18 or above. + You can do so by compiling Cairo from source: + + 1. download ``cairo-1.18.0.tar.xz`` from + `here `_. + and uncompress it; + 2. open the INSTALL file and follow the instructions (you might need to install + ``meson`` and ``ninja``); + 3. run the tests suite and verify that the Cairo version is correct. + How Manim tests --------------- @@ -36,8 +54,8 @@ At the moment there are three types of tests: #. Graphical unit tests: Because ``manim`` is a graphics library, we test frames. To do so, we create test scenes that render a specific feature. When pytest runs, it compares the result of the test to the control data, either at 6 fps or just the last frame. If it matches, the tests - pass. If the test and control data differ, the tests fail. You can - use ``--show_diff`` flag with ``pytest`` to visually see the differences. + pass. If the test and control data differ, the tests fail. You can use ``--show_diff`` flag with ``pytest`` to visually + see the differences. The ``extract_frames.py`` script lets you see all the frames of a test. #. Videos format tests: @@ -112,7 +130,6 @@ The ``manim/tests`` directory looks like this: │ └── test_cli_flags.py └── utils ├── commands.py - ├── GraphicalUnitTester.py ├── __init__.py ├── testing_utils.py └── video_tester.py @@ -222,6 +239,15 @@ For the example above, it would be (``-s`` is here to see manim logs, so you can see what's going on). +If you want to see all the control data frames (e.g. to make sure your test is doing what you want), use the +``extract_frames.py`` script. The first parameter is the path to a ``.npz`` file and the second parameter is the +directory you want the frames created. The frames will be named ``frame0.png``, ``frame1.png``, etc. + +.. code-block:: bash + + python scripts/extract_frames.py tests/test_graphical_units/control_data/plot/axes.npz output + + Please make sure to add the control data to git as soon as it is produced with ``git add ``. diff --git a/docs/source/contributing/typings.rst b/docs/source/contributing/typings.rst deleted file mode 100644 index 034f4b6faf..0000000000 --- a/docs/source/contributing/typings.rst +++ /dev/null @@ -1,103 +0,0 @@ -============== -Adding Typings -============== - -Adding type hints to functions and parameters ---------------------------------------------- - -.. warning:: - This section is still a work in progress. - -If you've never used type hints before, this is a good place to get started: -https://realpython.com/python-type-checking/#hello-types. - -When adding type hints to manim, there are some guidelines that should be followed: - -* Coordinates have the typehint ``Sequence[float]``, e.g. - -.. code:: py - - def set_points_as_corners(self, points: Sequence[float]) -> "VMobject": - """Given an array of points, set them as corner of the Vmobject.""" - -* ``**kwargs`` has no typehint - -* Mobjects have the typehint "Mobject", e.g. - -.. code:: py - - def match_color(self, mobject: "Mobject"): - """Match the color with the color of another :class:`~.Mobject`.""" - return self.set_color(mobject.get_color()) - -* Colors have the typehint ``Color``, e.g. - -.. code:: py - - def set_color(self, color: Color = YELLOW_C, family: bool = True): - """Condition is function which takes in one arguments, (x, y, z).""" - -* As ``float`` and ``Union[int, float]`` are the same, use only ``float`` - -* For numpy arrays use the typehint ``np.ndarray`` - -* Functions that does not return a value should get the type hint ``None``. (This annotations help catch the kinds of subtle bugs where you are trying to use a meaningless return value. ) - -.. code:: py - - def height(self, value) -> None: - self.scale_to_fit_height(value) - -* Parameters that are None by default should get the type hint ``Optional`` - -.. code:: py - - def rotate( - self, - angle, - axis=OUT, - about_point: Optional[Sequence[float]] = None, - **kwargs, - ): - pass - - -* The ``__init__()`` method always should have None as its return type. - -* Functions and lambda functions should get the typehint ``Callable`` - -.. code:: py - - rate_func: Callable[[float], float] = lambda t: smooth(1 - t) - - -* Assuming that typical path objects are either Paths or strs, one can use the typehint ``typing.Union[str, pathlib.Path]`` - -.. note:: - As a helper for tool for typesets, you can use `typestring-parser - `_ - which can be accessed by first installing it via ``pip`` - ``pip install typestring-parser`` and - then using ``from typestring_parser import parse``. - -.. doctest:: - :options: +SKIP - - >>> from typestring_parser import parse - >>> parse("int") - - >>> parse("int or str") - typing.Union[int, str] - >>> parse("list of str or str") - typing.Union[typing.List[str], str] - >>> parse("list of (int, str)") - typing.List[typing.Tuple[int, str]] - -Missing Sections for typehints are: ------------------------------------ -* Tools for typehinting -* Link to MyPy -* Mypy and numpy import errors: https://realpython.com/python-type-checking/#running-mypy -* Where to find the alias -* When to use Object and when to use "Object". -* The use of a TypeVar on the type hints for copy(). -* The definition and use of Protocols (like Sized, or Sequence, or Iterable...) diff --git a/docs/source/examples.rst b/docs/source/examples.rst index d787c7111d..00b4299a52 100644 --- a/docs/source/examples.rst +++ b/docs/source/examples.rst @@ -90,11 +90,11 @@ Basic Concepts [[i * 256 / n for i in range(0, n)] for _ in range(0, n)] ) image = ImageMobject(imageArray).scale(2) - image.background_rectangle = SurroundingRectangle(image, GREEN) + image.background_rectangle = SurroundingRectangle(image, color=GREEN) self.add(image, image.background_rectangle) .. manim:: BooleanOperations - :ref_classes: Union Intersection Exclusion + :ref_classes: Union Intersection Exclusion Difference class BooleanOperations(Scene): def construct(self): @@ -341,7 +341,7 @@ Plotting with Manim axes.i2gp(TAU, cos_graph), color=YELLOW, line_func=Line ) line_label = axes.get_graph_label( - cos_graph, "x=2\pi", x_val=TAU, direction=UR, color=WHITE + cos_graph, r"x=2\pi", x_val=TAU, direction=UR, color=WHITE ) plot = VGroup(axes, sin_graph, cos_graph, vert_line) @@ -407,6 +407,64 @@ Plotting with Manim self.add(ax, labels, curve_1, curve_2, line_1, line_2, riemann_area, area) +.. manim:: PolygonOnAxes + :ref_classes: Axes Polygon + + class PolygonOnAxes(Scene): + def get_rectangle_corners(self, bottom_left, top_right): + return [ + (top_right[0], top_right[1]), + (bottom_left[0], top_right[1]), + (bottom_left[0], bottom_left[1]), + (top_right[0], bottom_left[1]), + ] + + def construct(self): + ax = Axes( + x_range=[0, 10], + y_range=[0, 10], + x_length=6, + y_length=6, + axis_config={"include_tip": False}, + ) + + t = ValueTracker(5) + k = 25 + + graph = ax.plot( + lambda x: k / x, + color=YELLOW_D, + x_range=[k / 10, 10.0, 0.01], + use_smoothing=False, + ) + + def get_rectangle(): + polygon = Polygon( + *[ + ax.c2p(*i) + for i in self.get_rectangle_corners( + (0, 0), (t.get_value(), k / t.get_value()) + ) + ] + ) + polygon.stroke_width = 1 + polygon.set_fill(BLUE, opacity=0.5) + polygon.set_stroke(YELLOW_B) + return polygon + + polygon = always_redraw(get_rectangle) + + dot = Dot() + dot.add_updater(lambda x: x.move_to(ax.c2p(t.get_value(), k / t.get_value()))) + dot.set_z_index(10) + + self.add(ax, graph, dot) + self.play(Create(polygon)) + self.play(t.animate.set_value(10)) + self.play(t.animate.set_value(k / 10)) + self.play(t.animate.set_value(5)) + + .. manim:: HeatDiagramPlot :save_last_frame: :ref_modules: manim.mobject.coordinate_systems @@ -424,7 +482,7 @@ Plotting with Manim tips=False, ) labels = ax.get_axis_labels( - x_label=Tex("$\Delta Q$"), y_label=Tex("T[$^\circ C$]") + x_label=Tex(r"$\Delta Q$"), y_label=Tex(r"T[$^\circ C$]") ) x_vals = [0, 8, 38, 39] @@ -609,7 +667,7 @@ Special Camera Settings class ThreeDSurfacePlot(ThreeDScene): def construct(self): - resolution_fa = 42 + resolution_fa = 24 self.set_camera_orientation(phi=75 * DEGREES, theta=-30 * DEGREES) def param_gauss(u, v): @@ -727,8 +785,8 @@ Advanced Projects def add_x_labels(self): x_labels = [ - MathTex("\pi"), MathTex("2 \pi"), - MathTex("3 \pi"), MathTex("4 \pi"), + MathTex(r"\pi"), MathTex(r"2 \pi"), + MathTex(r"3 \pi"), MathTex(r"4 \pi"), ] for i in range(len(x_labels)): diff --git a/docs/source/faq/general.md b/docs/source/faq/general.md new file mode 100644 index 0000000000..8ac092f5f1 --- /dev/null +++ b/docs/source/faq/general.md @@ -0,0 +1,248 @@ +# FAQ: General Usage + +## Why does Manim say that "there are no scenes inside that module"? + +There are two main reasons why this error appears: if you have edited +the file containing your `Scene` class and forgot to save it, or if you +have accidentally passed the name of a wrong file to `manim`, this is +a likely outcome. Check that you have spelled everything correctly. + +Otherwise, you are likely mixing up Manim versions. See {ref}`this FAQ answer ` +for an explanation regarding why there are different versions. Under the +assumption that you are trying to use the `manim` executable from the terminal to run +a scene that has been written for the community version (i.e., there is +`from manim import *`, or more specifically `from manim import Scene`), +then this error indicates that the `manim` executable has been overwritten +by the one provided by `manimgl` (unfortunately, both `manim` and `manimgl` +provide a `manim` executable). + +You can check whether this is the case by running `manim --version`, the output of +the community maintained version starts with `Manim Community v...`. If this is not +the case, you are running `manimgl`. + +You can resolve this by either of the following steps: +- Un- and reinstalling `manim`, +- using the `manimce` executable in place of the `manim` one, +- or replacing the call to the executable with a direct call to the + Python module via `python -m manim`. + +--- + +## No matter what code I put in my file, Manim only renders a black frame! Why? + +If you are using the usual pattern to write a `Scene`, i.e., +```python +class MyAwesomeScene(Scene): + def construct(self): + ... + # your animation code +``` +then double check whether you have spelled `construct` correctly. +If the method containing your code is not called `construct` (or +if you are not calling a different, custom method from `construct`), +Manim will not call your method and simply output a black frame. + +--- + +## What are the default measurements for Manim's scene? + +The scene measures 8 units in height and has a default ratio of 16:9, +which means that it measures {math}`8 \cdot 16 / 9 = 14 + 2/9` units in width. +The origin is in the center of the scene, which means that, for example, the +upper left corner of the scene has coordinates `[-7-1/9, 4, 0]`. + +--- + +## How do I find out which keyword arguments I can pass when creating a `Mobject`? + +Let us consider a specific example, like the {class}`.Circle` class. When looking +at its documentation page, only two specific keyword arguments are listed +(`radius`, and `color`). Besides these concrete arguments, there is also a +catchall `**kwargs` argument which captures all other arguments that are passed +to `Circle`, and passes them on to the base class of {class}`.Circle`, {class}`.Arc`. + +The same holds for {class}`.Arc`: some arguments are explicitly documented, and +there is again a catchall `**kwargs` argument that passes unprocessed arguments +to the next base class -- and so on. + +The most important keyword arguments relevant to styling your mobjects are the +ones that are documented for the base classes {class}`.VMobject` and +{class}`.Mobject`. + +--- + +## Can Manim render a video with transparent background? + +Yes: simply pass the CLI flag `-t` (or its long form `--transparent`). +Note that the default video file format does not support transparency, +which is why Manim will output a `.mov` instead of a `.mp4` when +rendering with a transparent background. Other movie file formats +that support transparency can be obtained by passing +`--format=webm` or `--format=gif`. + +--- + +## I have watched a video where a creator ran command X, but it does not work for me. Why? + +The video you have been watching is likely outdated. If you want to follow +along, you either need to use the same version used in the video, or +modify the code (in many cases it is just a method having been renamed etc.) +accordingly. Check the video description, in some cases creators point out +whether changes need to be applied to the code shown in the video. + +--- + +## When using `Tex` or `MathTex`, some letters are missing. How can I fix this? + +It is possible that you have to (re)build some fonts used by LaTeX. For +some distributions, you can do this manually by running +```bash +fmtutil -sys --all +``` +We recommend consulting the documentation of your LaTeX distribution +for more information. + +--- + +## I want to translate some code from `manimgl` to `manim`, what do I do with `CONFIG` dictionaries? + +The community-maintained version has dropped the use of `CONFIG` dictionaries very +early, with {doc}`version v0.2.0 ` released in +January 2021. + +Before that, Manim's classes basically processed `CONFIG` dictionaries +by mimicking inheritance (to properly process `CONFIG` dictionaries set +by parent classes) and then assigning all of the key-value-pairs in the +dictionary as attributes of the corresponding object. + +In situations where there is not much inheritance going on, +or for any custom setting, you should set these attributes yourself. +For example, for an old-style `Scene` with custom attributes like + +```python +class OldStyle(Scene): + CONFIG = {"a": 1, "b": 2} +``` + +should be written as + +```python +class NewStyle(Scene): + a = 1 + b = 2 +``` + +In situations where values should be properly inherited, the arguments +should be added to the initialization function of the class. An old-style +mobject `Thing` could look like + +```python +class Thing(VMobject): + CONFIG = { + "stroke_color": RED, + "fill_opacity": 0.7, + "my_awesome_argument": 42, + } +``` + +where `stroke_color` and `fill_opacity` are arguments that concern the +parent class of `Thing`, and `my_awesome_argument` is a custom argument +that only concerns `Thing`. A version without `CONFIG` could look like this: + +```python +class Thing(VMobject): + def __init__( + self, stroke_color=RED, fill_opacity=0.7, my_awesome_argument=42, **kwargs + ): + self.my_awesome_argument = my_awesome_argument + super().__init__(stroke_color=stroke_color, fill_opacity=fill_opacity, **kwargs) +``` + +--- + +## My installation does not support converting PDF to SVG, help? + +This is an issue with `dvisvgm`, the tool shipped with LaTeX that +transforms LaTeX output to a `.svg` file that +Manim can parse. + +First, make sure your ``dvisvgm`` version is at least 2.4 by +checking the output of + +```bash +dvisvgm --version +``` + +If you do not know how to update `dvisvgm`, please refer to your +LaTeX distributions documentation (or the documentation of your +operating system, if `dvisvgm` was installed as a system package). + +Second, check whether your ``dvisvgm`` supports PostScript specials. This is +needed to convert from PDF to SVG. Run: + +```bash +dvisvgm -l +``` + +If the output to this command does **not** contain `ps dvips PostScript specials`, +this is a bad sign. In this case, run + +```bash +dvisvgm -h +``` + +If the output does **not** contain `--libgs=filename`, this means your +`dvisvgm` does not currently support PostScript. You must get another binary. + +If, however, `--libgs=filename` appears in the help, that means that your +`dvisvgm` needs the Ghostscript library to support PostScript. Search for +`libgs.so` (on Linux, probably in `/usr/local/lib` or `/usr/lib`) or +`gsdll32.dll` (on 32-bit Windows, probably in `C:\windows\system32`) or +`gsdll64.dll` (on 64-bit Windows, also probably in `C:\windows\system32`) +or `libgsl.dylib` (on MacOS, probably in `/usr/local/lib` or +`/opt/local/lib`). Please look carefully, as the file might be located +elsewhere, e.g. in the directory where Ghostscript is installed. + +When you have found the library, try (on MacOS or Linux) + +```bash +export LIBGS= +dvisvgm -l +``` + +or (on Windows) + +```bat +set LIBGS= +dvisvgm -l +``` + +You should now see `ps dvips PostScript specials` in the output. Refer to +your operating system's documentation to find out how you can set or export the +environment variable ``LIBGS`` automatically whenever you open a shell. + +As a last check, you can run + +```bash +dvisvgm -V1 +``` + +(while still having `LIBGS` set to the correct path, of course.) If `dvisvgm` +can find your Ghostscript installation, it will be shown in the output together +with the version number. + +If you do not have the necessary library on your system, please refer to your +operating system's documentation to find out where you can get it and how you +have to install it. + +If you are unable to solve your problem, check out the +[dvisvgm FAQ](https://dvisvgm.de/FAQ/). + +--- + +## Where can I find more resources for learning Manim? + +In our [Discord server](https://manim.community/discord), we have the community-maintained +`#beginner-resources` channel in which links to helpful learning resources are collected. +You are welcome to join our Discord and take a look yourself! If you have found some +guides or tutorials yourself that are not on our list yet, feel free to add them! diff --git a/docs/source/faq/help.md b/docs/source/faq/help.md new file mode 100644 index 0000000000..c0c7a5e6d1 --- /dev/null +++ b/docs/source/faq/help.md @@ -0,0 +1,121 @@ +# FAQ: Getting Help + +## How do I animate X? Why do I get error Y? Can someone help me? + +Before asking the community, please make sure that the issue you are having +is not already discussed in our {doc}`FAQ section ` sufficiently +well so that you can resolve the problem yourself. You can also try to +use your favorite search engine, if you are lucky you might find a blog post, +a question on [StackOverflow](https://stackoverflow.com/questions/tagged/manim), +or a post in the [r/manim subreddit](https://reddit.com/r/manim). + +If this is not the case, please take a moment to properly prepare your question: +the better you manage to explain what exactly it is you are struggling with, +the more efficient people will be able to help you. Regardless of the platform +you choose in the next step, StackOverflow has a good guide on +[asking good questions](https://stackoverflow.com/help/how-to-ask). + +As soon as you have a good idea of what exactly you want to ask, pick one of the +following communication channels: + +- The community is most active [in our Discord server](https://manim.community/discord/). + Click the link to join, then pick one of the `#manim-help` channels in the sidebar, + and post your question there. If you are comfortable with using Discord, try to search + for your problem using the search function of our server; perhaps people have been + talking about it before! +- We are also monitoring questions on + [StackOverflow](https://stackoverflow.com/questions/tagged/manim) that are tagged + with `manim`. +- Many people are also active in our [r/manim subreddit](https://reddit.com/r/manim), + feel free to post there if you are an avid Redditor -- but be aware that Discord + or StackOverflow might be better choices. +- And finally, you can also start a new [discussion on GitHub](https://github.com/ManimCommunity/manim/discussions) + if you dislike all other options. + +In all of these channels, please make sure to abide by Manim's +{doc}`Code of Conduct ` -- in short, be *excellent* to one another: +be friendly and patient, considerate, and respectful. + +--- + +## What should I do if nobody answers my question? + +Try and see whether your question can be improved: did you include all relevant +information (in case of errors: the full stack trace, the code that you were +rendering, and the command you used to run Manim?). In case you used a very long +example, is it possible to construct a more minimal version that has the same +(faulty) behavior? + +If you posted in one of our help channels on Discord and your question got buried, +you are allowed to ping the `@Manim Helper` role to bring it to the attention of +the volunteers who are willing to take a look. Please refrain from pinging the role +immediately when asking your question for the first time, this is considered impolite. + +You can also try to post your question to a different channel if you feel that you +are not having any success with your initial choice -- but please do not spam your +question in all of our communication channels (and in particular for Discord: +please don't use multiple help channels at once). + +In the end, it is as for most open-source projects: our community members are +volunteers. If you do not receive a quick answer to your question, it may be +because nobody knows the answer, or because your question is not clear enough, +or it could be that everyone who can help you with your problem is busy doing +other things. + +--- + +## The library does not behave as documented, or something broke in a new release. What should I do? + +Sounds like you have found a bug. One of the best ways of contributing to the +development of Manim is by reporting it! + +Check our list of known issues and feature requests +[in our GitHub repository](https://github.com/ManimCommunity/manim/issues). If the +problem you have found is not listed there yet (use the search function; also check +whether there is a corresponding closed issue, it is possible that your problem +has already been resolved and will be fixed with the next release), please consider +the following steps to submit a new issue. + +```{note} +If you are unsure whether or not you should file a new issue for some odd behavior +that you found, feel free to ask the community developers, preferably in one of +our `#manim-dev` channels in [our Discord](https://manim.community/discord/). +``` + +1. Make sure you are running the latest released version of Manim, your problem + might otherwise already be fixed in a more recent version. Check the + {doc}`/changelog` for a full list of changes between Manim releases. + +2. Choose the correct category for your report when + [creating a new issue](https://github.com/ManimCommunity/manim/issues/new/choose). + We have dedicated issue templates for *bug reports*, *feature requests*, and + *installation issues*. If your report falls into one of these + categories, read the issue template carefully! Instructions are given in the + `` sections of the text field. If you want to suggest a new feature + without concrete implementation details, see + {ref}`the instructions given in this answer `. + +3. For bug reports: prepare a minimal example that can be used to illustrate the + issue. Examples with hundreds of lines are very inefficient and tedious to debug. + Your problem needs to be reproducible for others, so please make sure to prepare + a suitable example. + +4. This is mentioned in the bug report template as well, but it is very important: + if you report that some code raises an error, make sure to include the full + terminal output, from the command you used to run the library up to and including + the last line with the error message. Read carefully: if the message mentions + that there is another relevant log file, include this other file as well! + +--- + +(creating-suggestions)= +## I have an idea for a really cool feature that should be implemented, where should I share my idea? + +New suggestions and proposals should be made by +[creating a new discussion](https://github.com/ManimCommunity/manim/discussions/new?category=suggestions-and-proposals) +in the [*Suggestions and Proposals* category](https://github.com/ManimCommunity/manim/discussions/categories/suggestions-and-proposals) +in our GitHub repository. Once the raw idea has been formed into a more concrete, +implementable proposal that is supported by the community, and someone has expressed +interest in working on the new feature, a corresponding +[issue](https://github.com/ManimCommunity/manim/issues) will be created. Do **not** create +issues for suggesting new features directly, they will be closed down. diff --git a/docs/source/faq/index.rst b/docs/source/faq/index.rst new file mode 100644 index 0000000000..e500af73f8 --- /dev/null +++ b/docs/source/faq/index.rst @@ -0,0 +1,9 @@ +Frequently Asked Questions +========================== + +.. toctree:: + :caption: Table of Contents + :maxdepth: 2 + :glob: + + * diff --git a/docs/source/faq/installation.md b/docs/source/faq/installation.md new file mode 100644 index 0000000000..25db9cbad5 --- /dev/null +++ b/docs/source/faq/installation.md @@ -0,0 +1,192 @@ +# FAQ: Installation + +(different-versions)= +## Why are there different versions of Manim? + +Manim was originally created by Grant Sanderson as a personal project and for use +in his YouTube channel, +[3Blue1Brown](https://www.youtube.com/channel/UCYO_jab_esuFRV4b17AJtAw). +As his channel gained popularity, many grew to like the style of his animations and +wanted to use manim for their own projects. However, as manim was only intended for +personal use, it was very difficult for other users to install and use it. + +In late 2019, Grant started working on faster OpenGL rendering in a new branch, +known as the `shaders` branch. In mid-2020, a group of developers forked it into what is +now the community edition; this is the version documented on this website. +In early 2021, Grant merged the shaders branch back into master, making it the default branch in his repository -- and this is what `manimgl` is. +The old version, before merging the `shaders` branch is sometimes referred to as +`ManimCairo` and is, at this point, only useful for one singular purpose: rendering +Grant's old videos locally on your machine. It is still available in his GitHub +repository in form of the `cairo-backend` branch. + +To summarize: +- [**Manim**, or **ManimCE**](https://manim.community) refers to the community + maintained version of the library. This is the version documented on this website; + the package name on PyPI is [`manim`](https://pypi.org/project/manim/). +- [ManimGL](https://github.com/3b1b/manim) is the latest released version of the + version of the library developed by Grant "3b1b" Sanderson. It has more experimental + features and breaking changes between versions are not documented. Check out + its documentation [here](https://3b1b.github.io/manim/index.html); on PyPI the + package name is [`manimgl`](https://pypi.org/project/manimgl/). +- [ManimCairo](https://github.com/3b1b/manim/tree/cairo-backend) is the name that + is sometimes used for the old, pre-OpenGL version of `manimgl`. The latest version + of it is available [on PyPI as `manimlib`](https://pypi.org/project/manimgl/), + but note that if you intend to use it to compile some old project of Grant, + you will likely have to install the exact version from the time the project + was created from source. + +--- + +## Which version should I use? + +We recommend the community maintained version especially for beginners. It has been +developed to be more stable, better tested and documented (!), and quicker to respond +to community contributions. It is also perfectly reasonable to start learning with the +community maintained version and then switch to a different version later on. + +If you do not care so much about documentation or stability, and would like to use +the exact same version that Grant is using, then use ManimGL. + +And as mentioned above, ManimCairo should only be used for (re)rendering old +3Blue1Brown projects (basically 2019 and before). + +--- + +## What are the differences between Manim, ManimGL, ManimCairo? Can I tell for which version a scene was written for? + +You can! The thing that usually gives it away is the `import` statement +at the top of the file; depending on how the code imports Manim you can tell +for which version of the code it was written for: + +- If the code imports from `manim` (i.e., `from manim import *`, `import manim as mn`, etc.), + then the code you are reading is supposed to be run with the community maintained version. +- If the import reads `import manimlib` (or `from manimlib import *`), you are likely + reading a file to be rendered with ManimGL. +- And if the import reads `from manimlib.imports import *`, or perhaps even + `from big_ol_pile_of_manim_imports import *` you are reading a snippet that is + supposed to be rendered with an early, or very early version of ManimCairo, respectively. + +--- + +## How do I know which version of Manim I have installed? + +Assuming you can run `manim` in your terminal and there is some output, check the +first line of the text being produced. If you are using the community maintained +version, the first line of any output will be `Manim Community `. +If it does not say that, you are likely using ManimGL. + +You can also check the list of packages you have installed: if typing `python` +in your terminal spawns the interpreter that corresponds to the Python +installation you use (might also be `py`, or `python3`, depending on your +operating system), running `python -m pip list` will print a list of all +installed packages. Check whether `manim` or `manimgl` appear in that list. + +Similarly, you can use `python -m pip install ` and +`python -m pip uninstall ` to install and uninstall +packages from that list, respectively. + +--- + +## I am following the video guide X to install Manim, but some step fails. What do I do? + +It is only natural that there are many video guides on installing Manim +out there, given that Manim is a library used for creating videos. Unfortunately +however, (YouTube) videos can't be updated easily (without uploading a new one, that is) +when some step in the installation process changes, and so there are many +**severely outdated** resources out there. + +This is why we strongly recommend following our +{doc}`written installation guide
` to guide you through the process. +In case you prefer using a video guide regardless, please check whether the +creator whose guide you have been watching has made a more recent version available, +and otherwise please contact them directly. Asking for help in the community will +likely lead to being suggested to follow our written guide. + +--- + +## Why does ManimPango fail to install when running `pip install manim`? + +This most likely means that pip was not able to use our pre-built wheels +of the `manimpango` dependency. Let us know (via +[Discord](https://www.manim.community/discord/) or by opening a +[new issue on GitHub](https://github.com/ManimCommunity/ManimPango/issues/new)) +which architecture you would like to see supported, and we'll see what we +can do about it. + +To fix errors when installing `manimpango`, you need to make sure you +have all the necessary build requirements. Check out the detailed +instructions given in [the BUILDING section](https://github.com/ManimCommunity/ManimPango#BUILDING) +of [ManimPango's README](https://github.com/ManimCommunity/ManimPango). + +--- + +(not-on-path)= +## I am using Windows and get the error `X is not recognized as an internal or external command, operable program or batch file` + +If you have followed {doc}`our local installation instructions ` and +have not activated the corresponding virtual environment, make sure to use `uv run manim ...` +instead of just `manim` (or activate the virtual environment by following the instructions +printed when running `uv venv`). + +Otherwise there is a problem with the directories where your system is looking for +executables (the `PATH` variable). +If `python` is recognized, you can try running +commands by prepending `python -m`. That is, `manim` becomes `python -m manim`, +and `pip` becomes `python -m pip`. + +Otherwise see +[this StackExchange answer](https://superuser.com/questions/143119/how-do-i-add-python-to-the-windows-path/143121#143121) +to get help with editing the `PATH` variable manually. + +--- + +## I have tried using Chocolatey (`choco install manimce`) to install Manim, but it failed! + +Make sure that you were running the command with administrator permissions, +otherwise there can be problems. If this is not the issue, read Chocolatey's +output carefully, it should mention a `.log` file containing information why +the process failed. + +You are welcome to take this file (and any other input you feel might be +relevant) and submit it to Manim's community to ask for help with +your problem. See the {doc}`FAQ on getting help ` for instructions. + +--- + +## On Windows, when typing `python` or `python3` the Windows store is opened, can I fix this? + +Yes: you can remove these aliases with these steps: + +1. Go to the Windows Setting. +2. Under *Apps and Features* you will find application execution aliases. +3. Within this menu, disable the alias(es) that are causing the issue + (`python` and/or `python3`). + +--- + +## I am using Anaconda and get an `ImportError` mentioning that some Symbol is not found. + +This is because Anaconda environments come with their own preinstalled +version of `cairo` which is not compatible with the version of `pycairo` +required by Manim. Usually it can be fixed by running + +```bash +conda install -c conda-forge pycairo +``` + +--- + +## How can I fix the error that `manimpango/cmanimpango.c` could not be found when trying to install Manim? + +This occasionally happens when your system has to build a wheel for +[ManimPango](https://github.com/ManimCommunity/ManimPango) locally because there +is no compatible version for your architecture available on PyPI. + +Very often, the problem is resolved by installing Cython (e.g., via +`pip3 install Cython`) and then trying to reinstall Manim. If this +does not fix it: + +- Make sure that you have installed all build dependencies mentioned + in [ManimPango's README](https://github.com/ManimCommunity/ManimPango), +- and if you still run into troubles after that, please reach out to + us as described in the {doc}`Getting Help FAQs `. diff --git a/docs/source/internals.rst b/docs/source/faq/internals.md similarity index 71% rename from docs/source/internals.rst rename to docs/source/faq/internals.md index aa83f809ef..08cdcd496f 100644 --- a/docs/source/internals.rst +++ b/docs/source/faq/internals.md @@ -1,8 +1,7 @@ -Internal structure -================== +# Where can I learn more about Manim's internal structure? Efforts to document the internal structure of Manim is ongoing on our -`wiki `_. +[wiki](https://github.com/ManimCommunity/manim/wiki/Developer-documentation-(WIP)). Keep in mind that since this is a work in progress, the information you find may be incomplete, outdated or even wrong. Still, it should serve as a good starting point. diff --git a/docs/source/faq/opengl.md b/docs/source/faq/opengl.md new file mode 100644 index 0000000000..2efb43660c --- /dev/null +++ b/docs/source/faq/opengl.md @@ -0,0 +1,20 @@ +# FAQ: OpenGL rendering + +## Are there any resources on how the OpenGL renderer in the community maintained version can be used? + +Yes. Unfortunately, at this point, the official online documentation does +not contain the relevant base classes like `OpenGLMobject` and `OpenGLVMobject` +or specific OpenGL classes like `OpenGLSurface`, but documentation for some of +them is available in form of docstrings +[in the source code](https://github.com/ManimCommunity/manim/tree/main/manim/mobject/opengl). + +Furthermore, [this user guide by *aquabeam*](https://www.aquabeam.me/manim/opengl_guide/) +can be helpful to get started using the OpenGL renderer. + +--- + +## I am trying to run an interactive scene with `--renderer=opengl` and `Scene.interactive_embed`, but an error (`sqlite3.ProgrammingError`) is raised. How can I fix this? + +This seems to be an issue with a recent IPython release, +in our experience it helps to downgrade the installed `IPython` +package to `8.0.1`: `pip install IPython==8.0.1`. diff --git a/docs/source/guides/add_voiceovers.rst b/docs/source/guides/add_voiceovers.rst new file mode 100644 index 0000000000..5db74f0ea2 --- /dev/null +++ b/docs/source/guides/add_voiceovers.rst @@ -0,0 +1,66 @@ +########################### +Adding Voiceovers to Videos +########################### + +Creating a full-fledged video with voiceovers is a bit more involved than +creating purely visual Manim scenes. One has to use `a video editing +program `__ +to add the voiceovers after the video has been rendered. This process +can be difficult and time-consuming, since it requires a lot of planning +and preparation. + +To ease the process of adding voiceovers to videos, we have created +`Manim Voiceover `__, a plugin +that lets you add voiceovers to scenes directly in Python. To install it, run + +.. code-block:: bash + + pip install "manim-voiceover[azure,gtts]" + +Visit `the installation page `__ +for more details on how to install Manim Voiceover. + +Basic Usage +########### + +Manim Voiceover lets you ... + +- Add voiceovers to Manim videos directly in Python, without having to use a video editor. +- Record voiceovers with your microphone during rendering through a simple command line interface. +- Develop animations with auto-generated AI voices from various free and proprietary services. + +It provides a very simple API that lets you specify your voiceover script +and then record it during rendering: + +.. code-block:: python + + from manim import * + from manim_voiceover import VoiceoverScene + from manim_voiceover.services.recorder import RecorderService + + + # Simply inherit from VoiceoverScene instead of Scene to get all the + # voiceover functionality. + class RecorderExample(VoiceoverScene): + def construct(self): + # You can choose from a multitude of TTS services, + # or in this example, record your own voice: + self.set_speech_service(RecorderService()) + + circle = Circle() + + # Surround animation sections with with-statements: + with self.voiceover(text="This circle is drawn as I speak.") as tracker: + self.play(Create(circle), run_time=tracker.duration) + # The duration of the animation is received from the audio file + # and passed to the tracker automatically. + + # This part will not start playing until the previous voiceover is finished. + with self.voiceover(text="Let's shift it to the left 2 units.") as tracker: + self.play(circle.animate.shift(2 * LEFT), run_time=tracker.duration) + +To get started with Manim Voiceover, +visit the `Quick Start Guide `__. + +Visit the `Example Gallery `__ +to see some examples of Manim Voiceover in action. diff --git a/docs/source/tutorials/configuration.rst b/docs/source/guides/configuration.rst similarity index 83% rename from docs/source/tutorials/configuration.rst rename to docs/source/guides/configuration.rst index be219b1bce..17cdfecc90 100644 --- a/docs/source/tutorials/configuration.rst +++ b/docs/source/guides/configuration.rst @@ -8,7 +8,7 @@ can be configured programmatically via `the ManimConfig class`_, at the time of command invocation via `command-line arguments`_, or at the time the library is first imported via `the config files`_. -The most common, simplest and recommended way to set the configure Manim is +The most common, simplest, and recommended way to configure Manim is via the command-line interface (CLI), which is described directly below. Command-line arguments @@ -21,7 +21,7 @@ It is used with the following arguments: .. program-output:: manim render --help :ellipsis: 9 -However, since manim defaults to the :code:`render` command whenever no command +However, since Manim defaults to the :code:`render` command whenever no command is specified, the following form is far more common and can be used instead: .. code-block:: bash @@ -34,7 +34,7 @@ An example of using the above form is: manim -qm file.py SceneOne -This asks manim to search for a Scene class called :code:`SceneOne` inside the +This asks Manim to search for a Scene class called :code:`SceneOne` inside the file ``file.py`` and render it with medium quality (specified by the ``-qm`` flag). Another frequently used flag is ``-p`` ("preview"), which makes manim @@ -74,7 +74,7 @@ A list of all CLI flags The ManimConfig class ********************* -The most direct way of configuring manim is through the global ``config`` object, +The most direct way of configuring Manim is through the global ``config`` object, which is an instance of :class:`.ManimConfig`. Each property of this class is a config option that can be accessed either with standard attribute syntax or with dict-like syntax: @@ -139,22 +139,22 @@ rendered in our documentation with a reference frame. The config files **************** -As the last example shows, executing manim from the command-line may involve -using many flags at the same time. This may become a nuisance if you must -execute the same script many times in a short time period, for example when -making small incremental tweaks to your scene script. For this reason, manim +As the last example shows, executing Manim from the command line may involve +using many flags simultaneously. This may become a nuisance if you must +execute the same script many times in a short time period, for example, when +making small incremental tweaks to your scene script. For this reason, Manim can also be configured using a configuration file. A configuration file is a file ending with the suffix ``.cfg``. To use a local configuration file when rendering your scene, you must create a -file with name ``manim.cfg`` in the same directory as your scene code. +file with the name ``manim.cfg`` in the same directory as your scene code. -.. warning:: The config file **must** be named ``manim.cfg``. Currently, manim +.. warning:: The config file **must** be named ``manim.cfg``. Currently, Manim does not support config files with any other name. The config file must start with the section header ``[CLI]``. The -configuration options under this header have the same name as the CLI flags, -and serve the same purpose. Take for example the following config file. +configuration options under this header have the same name as the CLI flags +and serve the same purpose. Take, for example, the following config file. .. code-block:: ini @@ -188,8 +188,8 @@ is in the same directory as , Since config files are meant to replace CLI flags, all CLI flags can be set via a config file. Moreover, any config option can be set via a config file, -whether or not it has an associated CLI flag. For a list of all CLI flags and -all config options, see the bottom of this document. +whether or not it has an associated CLI flag. See the bottom of this document +for a list of all CLI flags and config options. Manim will look for a ``manim.cfg`` config file in the same directory as the file being rendered, and **not** in the directory of execution. For example, @@ -215,7 +215,7 @@ As explained in the previous section, a :code:`manim.cfg` config file only affects the scene scripts in its same folder. However, the user may also create a special config file that will apply to all scenes rendered by that user. This is referred to as the **user-wide** config file, and it will apply -regardless of where manim is executed from, and regardless of where the scene +regardless of where Manim is executed from, and regardless of where the scene script is stored. The user-wide config file lives in a special folder, depending on the operating @@ -235,14 +235,14 @@ Here, :code:`UserDirectory` is the user's home folder. .. warning:: Do not store scene scripts in the same folder as the user-wide config file. In this case, the behavior is undefined. -Whenever you use manim from anywhere in the system, manim will look for a +Whenever you use Manim from anywhere in the system, Manim will look for a user-wide config file and read its configuration. Cascading config files ====================== -What happens if you execute manim and it finds both a folder-wide config file +What happens if you execute Manim and it finds both a folder-wide config file and a user-wide config file? Manim will read both files, but if they are incompatible, **the folder-wide file takes precedence**. @@ -280,7 +280,7 @@ executing manim -o myscene -c RED SceneName -There is also a **library-wide** config file that determines manim's default +There is also a **library-wide** config file that determines Manim's default behavior and applies to every user of the library. It has the least precedence, so any config options in the user-wide and any folder-wide files will override the library-wide file. This is referred to as the *cascading* @@ -301,19 +301,19 @@ Order of operations -With so many different ways of configuring manim, it can be difficult to know -when each config option is being set. In fact, this will depend on how manim +With so many different ways of configuring Manim, it can be difficult to know +when each config option is being set. In fact, this will depend on how Manim is being used. -If manim is imported from a module, then the configuration system will follow +If Manim is imported from a module, then the configuration system will follow these steps: 1. The library-wide config file is loaded. -2. The user-wide and folder-wide files are loaded, if they exist. +2. The user-wide and folder-wide files are loaded if they exist. 3. All files found in the previous two steps are parsed in a single :class:`ConfigParser` object, called ``parser``. This is where *cascading* happens. -4. :class:`logging.Logger` is instantiated to create manim's global ``logger`` +4. :class:`logging.Logger` is instantiated to create Manim's global ``logger`` object. It is configured using the "logger" section of the parser, i.e. ``parser['logger']``. 5. :class:`ManimConfig` is instantiated to create the global ``config`` object. @@ -321,7 +321,7 @@ these steps: :meth:`ManimConfig.digest_parser`. 7. Both ``logger`` and ``config`` are exposed to the user. -If manim is being invoked from the command-line, all of the previous steps +If Manim is being invoked from the command line, all of the previous steps happen, and are complemented by: 8. The CLI flags are parsed and fed into ``config`` via @@ -360,7 +360,44 @@ A list of all config options 'progress_bar', 'quality', 'right_side', 'save_as_gif', 'save_last_frame', 'save_pngs', 'scene_names', 'show_in_file_browser', 'sound', 'tex_dir', 'tex_template', 'tex_template_file', 'text_dir', 'top', 'transparent', - 'upto_animation_number', 'use_opengl_renderer', 'use_webgl_renderer', - 'verbosity', 'video_dir', 'webgl_renderer_path', 'window_position', - 'window_monitor', 'window_size', 'write_all', 'write_to_movie', 'enable_wireframe', - 'force_window'] + 'upto_animation_number', 'use_opengl_renderer', 'verbosity', 'video_dir', + 'window_position', 'window_monitor', 'window_size', 'write_all', 'write_to_movie', + 'enable_wireframe', 'force_window'] + + +Accessing CLI command options +***************************** + +Entering ``manim``, or ``manim --help``, will open the main help page. + +.. code:: + + Usage: manim [OPTIONS] COMMAND [ARGS]... + + Animation engine for explanatory math videos. + + Options: + --version Show version and exit. + --help Show this message and exit. + + Commands: + cfg Manages Manim configuration files. + init Sets up a new project in current working directory with default + settings. + + It copies files from templates directory and pastes them in the + current working dir. + new Create a new project or insert a new scene. + plugins Manages Manim plugins. + render Render SCENE(S) from the input FILE. + + See 'manim ' to read about a specific subcommand. + + Made with <3 by Manim Community developers. + +Each of the subcommands has its own help page which can be accessed similarly: + +.. code:: + + manim render + manim render --help diff --git a/docs/source/guides/deep_dive.rst b/docs/source/guides/deep_dive.rst new file mode 100644 index 0000000000..a5dc298d1b --- /dev/null +++ b/docs/source/guides/deep_dive.rst @@ -0,0 +1,1029 @@ +A deep dive into Manim's internals +================================== + +**Author:** `Benjamin Hackl `__ + +.. admonition:: Disclaimer + + This guide reflects the state of the library as of version ``v0.16.0`` + and primarily treats the Cairo renderer. The situation in the latest + version of Manim might be different; in case of substantial deviations + we will add a note below. + +Introduction +------------ + +Manim can be a wonderful library, if it behaves the way you would like it to, +and/or the way you expect it to. Unfortunately, this is not always the case +(as you probably know if you have played with some manimations yourself already). +To understand where things *go wrong*, digging through the library's source code +is sometimes the only option -- but in order to do that, you need to know where +to start digging. + +This article is intended as some sort of life line through the render process. +We aim to give an appropriate amount of detail describing what happens when +Manim reads your scene code and produces the corresponding animation. Throughout +this article, we will focus on the following toy example:: + + from manim import * + + class ToyExample(Scene): + def construct(self): + orange_square = Square(color=ORANGE, fill_opacity=0.5) + blue_circle = Circle(color=BLUE, fill_opacity=0.5) + self.add(orange_square) + self.play(ReplacementTransform(orange_square, blue_circle, run_time=3)) + small_dot = Dot() + small_dot.add_updater(lambda mob: mob.next_to(blue_circle, DOWN)) + self.play(Create(small_dot)) + self.play(blue_circle.animate.shift(RIGHT)) + self.wait() + self.play(FadeOut(blue_circle, small_dot)) + +Before we go into details or even look at the rendered output of this scene, +let us first describe verbally what happens in this *manimation*. In the first +three lines of the ``construct`` method, a :class:`.Square` and a :class:`.Circle` +are initialized, then the square is added to the scene. The first frame of the +rendered output should thus show an orange square. + +Then the actual animations happen: the square first transforms into a circle, +then a :class:`.Dot` is created (Where do you guess the dot is located when +it is first added to the scene? Answering this already requires detailed +knowledge about the render process.). The dot has an updater attached to it, and +as the circle moves right, the dot moves with it. In the end, all mobjects are +faded out. + +Actually rendering the code yields the following video: + +.. manim:: ToyExample + :hide_source: + + class ToyExample(Scene): + def construct(self): + orange_square = Square(color=ORANGE, fill_opacity=0.5) + blue_circle = Circle(color=BLUE, fill_opacity=0.5) + self.add(orange_square) + self.play(ReplacementTransform(orange_square, blue_circle, run_time=3)) + small_dot = Dot() + small_dot.add_updater(lambda mob: mob.next_to(blue_circle, DOWN)) + self.play(Create(small_dot)) + self.play(blue_circle.animate.shift(RIGHT)) + self.wait() + self.play(FadeOut(blue_circle, small_dot)) + + +For this example, the output (fortunately) coincides with our expectations. + +Overview +-------- + +Because there is a lot of information in this article, here is a brief overview +discussing the contents of the following chapters on a very high level. + +- `Preliminaries`_: In this chapter we unravel all the steps that take place + to prepare a scene for rendering; right until the point where the user-overridden + ``construct`` method is ran. This includes a brief discussion on using Manim's CLI + versus other means of rendering (e.g., via Jupyter notebooks, or in your Python + script by calling the :meth:`.Scene.render` method yourself). +- `Mobject Initialization`_: For the second chapter we dive into creating and handling + Mobjects, the basic elements that should be displayed in our scene. + We discuss the :class:`.Mobject` base class, how there are essentially + three different types of Mobjects, and then discuss the most important of them, + vectorized Mobjects. In particular, we describe the internal point data structure + that governs how the mechanism responsible for drawing the vectorized Mobject + to the screen sets the corresponding Bézier curves. We conclude the chapter + with a tour into :meth:`.Scene.add`, the bookkeeping mechanism controlling which + mobjects should be rendered. +- `Animations and the Render Loop`_: And finally, in the last chapter we walk + through the instantiation of :class:`.Animation` objects (the blueprints that + hold information on how Mobjects should be modified when the render loop runs), + followed by a investigation of the infamous :meth:`.Scene.play` call. We will + see that there are three relevant parts in a :meth:`.Scene.play` call; + a part in which the passed animations and keyword arguments are processed + and prepared, followed by the actual "render loop" in which the library + steps through a time line and renders frame by frame. The final part + does some post-processing to save a short video segment ("partial movie file") + and cleanup for the next call to :meth:`.Scene.play`. In the end, after all of + :meth:`.Scene.construct` has been run, the library combines the partial movie + files to one video. + +And with that, let us get *in medias res*. + +Preliminaries +------------- + +Importing the library +^^^^^^^^^^^^^^^^^^^^^ + +Independent of how exactly you are telling your system +to render the scene, i.e., whether you run ``manim -qm -p file_name.py ToyExample``, or +whether you are rendering the scene directly from the Python script via a snippet +like + +:: + + with tempconfig({"quality": "medium_quality", "preview": True}): + scene = ToyExample() + scene.render() + +or whether you are rendering the code in a Jupyter notebook, you are still telling your +python interpreter to import the library. The usual pattern used to do this is + +:: + + from manim import * + +which (while being a debatable strategy in general) imports a lot of classes and +functions shipped with the library and makes them available in your global name space. +I explicitly avoided stating that it imports **all** classes and functions of the +library, because it does not do that: Manim makes use of the practice described +in `Section 6.4.1 of the Python tutorial `__, +and all module members that should be exposed to the user upon running the ``*``-import +are explicitly declared in the ``__all__`` variable of the module. + +Manim also uses this strategy internally: taking a peek at the file that is run when +the import is called, ``__init__.py`` (see +`here `__), +you will notice that most of the code in that module is concerned with importing +members from various different submodules, again using ``*``-imports. + +.. hint:: + + If you would ever contribute a new submodule to Manim, the main + ``__init__.py`` is where it would have to be listed in order to make its + members accessible to users after importing the library. + +In that file, there is one particular import at the beginning of the file however, +namely:: + + from ._config import * + +This initializes Manim's global configuration system, which is used in various places +throughout the library. After the library runs this line, the current configuration +options are set. The code in there takes care of reading the options in your ``.cfg`` +files (all users have at least the global one that is shipped with the library) +as well as correctly handling command line arguments (if you used the CLI to render). + +You can read more about the config system in the +:doc:`corresponding thematic guide `, and if you are interested in learning +more about the internals of the configuration system and how it is initialized, +follow the code flow starting in `the config module's init file +`__. + +Now that the library is imported, we can turn our attention to the next step: +reading your scene code (which is not particularly exciting, Python just creates +a new class ``ToyExample`` based on our code; Manim is virtually not involved +in that step, with the exception that ``ToyExample`` inherits from ``Scene``). + +However, with the ``ToyExample`` class created and ready to go, there is a new +excellent question to answer: how is the code in our ``construct`` method +actually executed? + +Scene instantiation and rendering +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The answer to this question depends on how exactly you are running the code. +To make things a bit clearer, let us first consider the case that you +have created a file ``toy_example.py`` which looks like this:: + + from manim import * + + class ToyExample(Scene): + def construct(self): + orange_square = Square(color=ORANGE, fill_opacity=0.5) + blue_circle = Circle(color=BLUE, fill_opacity=0.5) + self.add(orange_square) + self.play(ReplacementTransform(orange_square, blue_circle, run_time=3)) + small_dot = Dot() + small_dot.add_updater(lambda mob: mob.next_to(blue_circle, DOWN)) + self.play(Create(small_dot)) + self.play(blue_circle.animate.shift(RIGHT)) + self.wait() + self.play(FadeOut(blue_circle, small_dot)) + + with tempconfig({"quality": "medium_quality", "preview": True}): + scene = ToyExample() + scene.render() + +With such a file, the desired scene is rendered by simply running this Python +script via ``python toy_example.py``. Then, as described above, the library +is imported and Python has read and defined the ``ToyExample`` class (but, +read carefully: *no instance of this class has been created yet*). + +At this point, the interpreter is about to enter the ``tempconfig`` context +manager. Even if you have not seen Manim's ``tempconfig`` before, its name +already suggests what it does: it creates a copy of the current state of the +configuration, applies the changes to the key-value pairs in the passed +dictionary, and upon leaving the context the original version of the +configuration is restored. TL;DR: it provides a fancy way of temporarily setting +configuration options. + +Inside the context manager, two things happen: an actual ``ToyExample``-scene +object is instantiated, and the ``render`` method is called. Every way of using +Manim ultimately does something along of these lines, the library always instantiates +the scene object and then calls its ``render`` method. To illustrate that this +really is the case, let us briefly look at the two most common ways of rendering +scenes: + +**Command Line Interface.** When using the CLI and running the command +``manim -qm -p toy_example.py ToyExample`` in your terminal, the actual +entry point is Manim's ``__main__.py`` file (located +`here `__. +Manim uses `Click `__ to implement +the command line interface, and the corresponding code is located in Manim's +``cli`` module (https://github.com/ManimCommunity/manim/tree/main/manim/cli). +The corresponding code creating the scene class and calling its render method +is located `here `__. + +**Jupyter notebooks.** In Jupyter notebooks, the communication with the library +is handled by the ``%%manim`` magic command, which is implemented in the +``manim.utils.ipython_magic`` module. There is +:meth:`some documentation <.ManimMagic.manim>` available for the magic command, +and the code creating the scene class and calling its render method is located +`here `__. + + +Now that we know that either way, a :class:`.Scene` object is created, let us investigate +what Manim does when that happens. When instantiating our scene object + +:: + + scene = ToyExample() + +the ``Scene.__init__`` method is called, given that we did not implement our own initialization +method. Inspecting the corresponding code (see +`here `__) +reveals that ``Scene.__init__`` first sets several attributes of the scene objects that do not +depend on any configuration options set in ``config``. Then the scene inspects the value of +``config.renderer``, and based on its value, either instantiates a ``CairoRenderer`` or an +``OpenGLRenderer`` object and assigns it to its ``renderer`` attribute. + +The scene then asks its renderer to initialize the scene by calling + +:: + + self.renderer.init_scene(self) + +Inspecting both the default Cairo renderer and the OpenGL renderer shows that the ``init_scene`` +method effectively makes the renderer instantiate a :class:`.SceneFileWriter` object, which +basically is Manim's interface to ``libav`` (FFMPEG) and actually writes the movie file. The Cairo +renderer (see the implementation `here `__) does not require any further initialization. The OpenGL renderer +does some additional setup to enable the realtime rendering preview window, which we do not go +into detail further here. + +.. warning:: + + Currently, there is a lot of interplay between a scene and its renderer. This is a flaw + in Manim's current architecture, and we are working on reducing this interdependency to + achieve a less convoluted code flow. + +After the renderer has been instantiated and initialized its file writer, the scene populates +further initial attributes (notable mention: the ``mobjects`` attribute which keeps track +of the mobjects that have been added to the scene). It is then done with its instantiation +and ready to be rendered. + +The rest of this article is concerned with the last line in our toy example script:: + + scene.render() + +This is where the actual magic happens. + +Inspecting the `implementation of the render method `__ +reveals that there are several hooks that can be used for pre- or postprocessing +a scene. Unsurprisingly, :meth:`.Scene.render` describes the full *render cycle* +of a scene. During this life cycle, there are three custom methods whose base +implementation is empty and that can be overwritten to suit your purposes. In +the order they are called, these customizable methods are: + +- :meth:`.Scene.setup`, which is intended for preparing and, well, *setting up* + the scene for your animation (e.g., adding initial mobjects, assigning custom + attributes to your scene class, etc.), +- :meth:`.Scene.construct`, which is the *script* for your screen play and + contains programmatic descriptions of your animations, and +- :meth:`.Scene.tear_down`, which is intended for any operations you might + want to run on the scene after the last frame has already been rendered + (for example, this could run some code that generates a custom thumbnail + for the video based on the state of the objects in the scene -- this + hook is more relevant for situations where Manim is used within other + Python scripts). + +After these three methods are run, the animations have been fully rendered, +and Manim calls :meth:`.CairoRenderer.scene_finished` to gracefully +complete the rendering process. This checks whether any animations have been +played -- and if so, it tells the :class:`.SceneFileWriter` to close the output +file. If not, Manim assumes that a static image should be output +which it then renders using the same strategy by calling the render loop +(see below) once. + +**Back in our toy example,** the call to :meth:`.Scene.render` first +triggers :meth:`.Scene.setup` (which only consists of ``pass``), followed by +a call of :meth:`.Scene.construct`. At this point, our *animation script* +is run, starting with the initialization of ``orange_square``. + + +Mobject Initialization +---------------------- + +Mobjects are, in a nutshell, the Python objects that represent all the +*things* we want to display in our scene. Before we follow our debugger +into the depths of mobject initialization code, it makes sense to +discuss Manim's different types of Mobjects and their basic data +structure. + +What even is a Mobject? +^^^^^^^^^^^^^^^^^^^^^^^ + +:class:`.Mobject` stands for *mathematical object* or *Manim object* +(depends on who you ask 😄). The Python class :class:`.Mobject` is +the base class for all objects that should be displayed on screen. +Looking at the `initialization method +`__ +of :class:`.Mobject`, you will find that not too much happens in there: + +- some initial attribute values are assigned, like ``name`` (which makes the + render logs mention the name of the mobject instead of its type), + ``submobjects`` (initially an empty list), ``color``, and some others. +- Then, two methods related to *points* are called: ``reset_points`` + followed by ``generate_points``, +- and finally, ``init_colors`` is called. + +Digging deeper, you will find that :meth:`.Mobject.reset_points` simply +sets the ``points`` attribute of the mobject to an empty NumPy vector, +while the other two methods, :meth:`.Mobject.generate_points` and +:meth:`.Mobject.init_colors` are just implemented as ``pass``. + +This makes sense: :class:`.Mobject` is not supposed to be used as +an *actual* object that is displayed on screen; in fact the camera +(which we will discuss later in more detail; it is the class that is, +for the Cairo renderer, responsible for "taking a picture" of the +current scene) does not process "pure" :class:`Mobjects <.Mobject>` +in any way, they *cannot* even appear in the rendered output. + +This is where different types of mobjects come into play. Roughly +speaking, the Cairo renderer setup knows three different types of +mobjects that can be rendered: + +- :class:`.ImageMobject`, which represent images that you can display + in your scene, +- :class:`.PMobject`, which are very special mobjects used to represent + point clouds; we will not discuss them further in this guide, +- :class:`.VMobject`, which are *vectorized mobjects*, that is, mobjects + that consist of points that are connected via curves. These are pretty + much everywhere, and we will discuss them in detail in the next section. + +... and what are VMobjects? +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +As just mentioned, :class:`VMobjects <.VMobject>` represent vectorized +mobjects. To render a :class:`.VMobject`, the camera looks at the +``points`` attribute of a :class:`.VMobject` and divides it into sets +of four points each. Each of these sets is then used to construct a +cubic Bézier curve with the first and last entry describing the +end points of the curve ("anchors"), and the second and third entry +describing the control points in between ("handles"). + +.. hint:: + To learn more about Bézier curves, take a look at the excellent + online textbook `A Primer on Bézier curves `__ + by `Pomax `__ -- there is a playground representing + cubic Bézier curves `in §1 `__, + the red and yellow points are "anchors", and the green and blue + points are "handles". + +In contrast to :class:`.Mobject`, :class:`.VMobject` can be displayed +on screen (even though, technically, it is still considered a base class). +To illustrate how points are processed, consider the following short example +of a :class:`.VMobject` with 8 points (and thus made out of 8/4 = 2 cubic +Bézier curves). The resulting :class:`.VMobject` is drawn in green. +The handles are drawn as red dots with a line to their closest anchor. + +.. manim:: VMobjectDemo + :save_last_frame: + + class VMobjectDemo(Scene): + def construct(self): + plane = NumberPlane() + my_vmobject = VMobject(color=GREEN) + my_vmobject.points = [ + np.array([-2, -1, 0]), # start of first curve + np.array([-3, 1, 0]), + np.array([0, 3, 0]), + np.array([1, 3, 0]), # end of first curve + np.array([1, 3, 0]), # start of second curve + np.array([0, 1, 0]), + np.array([4, 3, 0]), + np.array([4, -2, 0]), # end of second curve + ] + handles = [ + Dot(point, color=RED) for point in + [[-3, 1, 0], [0, 3, 0], [0, 1, 0], [4, 3, 0]] + ] + handle_lines = [ + Line( + my_vmobject.points[ind], + my_vmobject.points[ind+1], + color=RED, + stroke_width=2 + ) for ind in range(0, len(my_vmobject.points), 2) + ] + self.add(plane, *handles, *handle_lines, my_vmobject) + + +.. warning:: + Manually setting the points of your :class:`.VMobject` is usually + discouraged; there are specialized methods that can take care of + that for you -- but it might be relevant when implementing your own, + custom :class:`.VMobject`. + + + +Squares and Circles: back to our Toy Example +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +With a basic understanding of different types of mobjects, +and an idea of how vectorized mobjects are built we can now +come back to our toy example and the execution of the +:meth:`.Scene.construct` method. In the first two lines +of our animation script, the ``orange_square`` and the +``blue_circle`` are initialized. + +When creating the orange square by running + +:: + + Square(color=ORANGE, fill_opacity=0.5) + +the initialization method of :class:`.Square`, +``Square.__init__``, is called. `Looking at the +implementation `__, +we can see that the ``side_length`` attribute of the square is set, +and then + +:: + + super().__init__(height=side_length, width=side_length, **kwargs) + +is called. This ``super`` call is the Python way of calling the +initialization function of the parent class. As :class:`.Square` +inherits from :class:`.Rectangle`, the next method called +is ``Rectangle.__init__``. There, only the first three lines +are really relevant for us:: + + super().__init__(UR, UL, DL, DR, color=color, **kwargs) + self.stretch_to_fit_width(width) + self.stretch_to_fit_height(height) + +First, the initialization function of the parent class of +:class:`.Rectangle` -- :class:`.Polygon` -- is called. The +four positional arguments passed are the four corners of +the polygon: ``UR`` is up right (and equal to ``UP + RIGHT``), +``UL`` is up left (and equal to ``UP + LEFT``), and so forth. +Before we follow our debugger deeper, let us observe what +happens with the constructed polygon: the remaining two lines +stretch the polygon to fit the specified width and height +such that a rectangle with the desired measurements is created. + +The initialization function of :class:`.Polygon` is particularly +simple, it only calls the initialization function of its parent +class, :class:`.Polygram`. There, we have almost reached the end +of the chain: :class:`.Polygram` inherits from :class:`.VMobject`, +whose initialization function mainly sets the values of some +attributes (quite similar to ``Mobject.__init__``, but more specific +to the Bézier curves that make up the mobject). + +After calling the initialization function of :class:`.VMobject`, +the constructor of :class:`.Polygram` also does something somewhat +odd: it sets the points (which, you might remember above, should +actually be set in a corresponding ``generate_points`` method +of :class:`.Polygram`). + +.. warning:: + In several instances, the implementation of mobjects does + not really stick to all aspects of Manim's interface. This + is unfortunate, and increasing consistency is something + that we actively work on. Help is welcome! + +Without going too much into detail, :class:`.Polygram` sets its +``points`` attribute via :meth:`.VMobject.start_new_path`, +:meth:`.VMobject.add_points_as_corners`, which take care of +setting the quadruples of anchors and handles appropriately. +After the points are set, Python continues to process the +call stack until it reaches the method that was first called; +the initialization method of :class:`.Square`. After this, +the square is initialized and assigned to the ``orange_square`` +variable. + +The initialization of ``blue_circle`` is similar to the one of +``orange_square``, with the main difference being that the inheritance +chain of :class:`.Circle` is different. Let us briefly follow the trace +of the debugger: + +The implementation of :meth:`.Circle.__init__` immediately calls +the initialization method of :class:`.Arc`, as a circle in Manim +is simply an arc with an angle of :math:`\tau = 2\pi`. When +initializing the arc, some basic attributes are set (like +``Arc.radius``, ``Arc.arc_center``, ``Arc.start_angle``, and +``Arc.angle``), and then the initialization method of its +parent class, :class:`.TipableVMobject`, is called (which is +a rather abstract base class for mobjects which a arrow tip can +be attached to). Note that in contrast to :class:`.Polygram`, +this class does **not** preemptively generate the points of the circle. + +After that, things are less exciting: :class:`.TipableVMobject` again +sets some attributes relevant for adding arrow tips, and afterwards +passes to the initialization method of :class:`.VMobject`. From there, +:class:`.Mobject` is initialized and :meth:`.Mobject.generate_points` +is called, which actually runs the method implemented in +:meth:`.Arc.generate_points`. + +After both our ``orange_square`` and the ``blue_circle`` are initialized, +the square is actually added to the scene. The :meth:`.Scene.add` method +is actually doing a few interesting things, so it is worth to dig a bit +deeper in the next section. + + +Adding Mobjects to the Scene +^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The code in our ``construct`` method that is run next is + +:: + + self.add(orange_square) + +From a high-level point of view, :meth:`.Scene.add` adds the +``orange_square`` to the list of mobjects that should be rendered, +which is stored in the ``mobjects`` attribute of the scene. However, +it does so in a very careful way to avoid the situation that a mobject +is being added to the scene more than once. At a first glance, this +sounds like a simple task -- the problem is that ``Scene.mobjects`` +is not a "flat" list of mobjects, but a list of mobjects which +might contain mobjects themselves, and so on. + +Stepping through the code in :meth:`.Scene.add`, we see that first +it is checked whether we are currently using the OpenGL renderer +(which we are not) -- adding mobjects to the scene works slightly +different (and actually easier!) for the OpenGL renderer. Then, the +code branch for the Cairo renderer is entered and the list of so-called +foreground mobjects (which are rendered on top of all other mobjects) +is added to the list of passed mobjects. This is to ensure that the +foreground mobjects will stay above of the other mobjects, even after +adding the new ones. In our case, the list of foreground mobjects +is actually empty, and nothing changes. + +Next, :meth:`.Scene.restructure_mobjects` is called with the list +of mobjects to be added as the ``to_remove`` argument, which might +sound odd at first. Practically, this ensures that mobjects are not +added twice, as mentioned above: if they were present in the scene +``Scene.mobjects`` list before (even if they were contained as a +child of some other mobject), they are first removed from the list. +The way :meth:`.Scene.restructure_mobjects` works is rather aggressive: +It always operates on a given list of mobjects; in the ``add`` method +two different lists occur: the default one, ``Scene.mobjects`` (no extra +keyword argument is passed), and ``Scene.moving_mobjects`` (which we will +discuss later in more detail). It iterates through all of the members of +the list, and checks whether any of the mobjects passed in ``to_remove`` +are contained as children (in any nesting level). If so, **their parent +mobject is deconstructed** and their siblings are inserted directly +one level higher. Consider the following example:: + + >>> from manim import Scene, Square, Circle, Group + >>> test_scene = Scene() + >>> mob1 = Square() + >>> mob2 = Circle() + >>> mob_group = Group(mob1, mob2) + >>> test_scene.add(mob_group) + + >>> test_scene.mobjects + [Group] + >>> test_scene.restructure_mobjects(to_remove=[mob1]) + + >>> test_scene.mobjects + [Circle] + +Note that the group is disbanded and the circle moves into the +root layer of mobjects in ``test_scene.mobjects``. + +After the mobject list is "restructured", the mobject to be added +are simply appended to ``Scene.mobjects``. In our toy example, +the ``Scene.mobjects`` list is actually empty, so the +``restructure_mobjects`` method does not actually do anything. The +``orange_square`` is simply added to ``Scene.mobjects``, and as +the aforementioned ``Scene.moving_mobjects`` list is, at this point, +also still empty, nothing happens and :meth:`.Scene.add` returns. + +We will hear more about the ``moving_mobject`` list when we discuss +the render loop. Before we do that, let us look at the next line +of code in our toy example, which includes the initialization of +an animation class, +:: + + ReplacementTransform(orange_square, blue_circle, run_time=3) + +Hence it is time to talk about :class:`.Animation`. + + +Animations and the Render Loop +------------------------------ + +Initializing animations +^^^^^^^^^^^^^^^^^^^^^^^ + +Before we follow the trace of the debugger, let us briefly discuss +the general structure of the (abstract) base class :class:`.Animation`. +An animation object holds all the information necessary for the renderer +to generate the corresponding frames. Animations (in the sense of +animation objects) in Manim are *always* tied to a specific mobject; +even in the case of :class:`.AnimationGroup` (which you should actually +think of as an animation on a group of mobjects rather than a group +of animations). Moreover, except for in a particular special case, +the run time of animations is also fixed and known beforehand. + +The initialization of animations actually is not very exciting, +:meth:`.Animation.__init__` merely sets some attributes derived +from the passed keyword arguments and additionally ensures that +the ``Animation.starting_mobject`` and ``Animation.mobject`` +attributes are populated. Once the animation is played, the +``starting_mobject`` attribute holds an unmodified copy of the +mobject the animation is attached to; during the initialization +it is set to a placeholder mobject. The ``mobject`` attribute +is set to the mobject the animation is attached to. + +Animations have a few special methods which are called during the +render loop: + +- :meth:`.Animation.begin`, which is called (as hinted by its name) + at the beginning of every animation, so before the first frame + is rendered. In it, all the required setup for the animation happens. +- :meth:`.Animation.finish` is the counterpart to the ``begin`` method + which is called at the end of the life cycle of the animation (after + the last frame has been rendered). +- :meth:`.Animation.interpolate` is the method that updates the mobject + attached to the animation to the corresponding animation completion + percentage. For example, if in the render loop, + ``some_animation.interpolate(0.5)`` is called, the attached mobject + will be updated to the state where 50% of the animation are completed. + +We will discuss details about these and some further animation methods +once we walk through the actual render loop. For now, we continue with +our toy example and the code that is run when initializing the +:class:`.ReplacementTransform` animation. + +The initialization method of :class:`.ReplacementTransform` only +consists of a call to the constructor of its parent class, +:class:`.Transform`, with the additional keyword argument +``replace_mobject_with_target_in_scene`` set to ``True``. +:class:`.Transform` then sets attributes that control how the +points of the starting mobject are deformed into the points of +the target mobject, and then passes on to the initialization +method of :class:`.Animation`. Other basic properties of the +animation (like its ``run_time``, the ``rate_func``, etc.) are +processed there -- and then the animation object is fully +initialized and ready to be played. + +The ``play`` call: preparing to enter Manim's render loop +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +We are finally there, the render loop is in our reach. Let us +walk through the code that is run when :meth:`.Scene.play` is called. + +.. hint:: + + Recall that this article is specifically about the Cairo renderer. + Up to here, things were more or less the same for the OpenGL renderer + as well; while some base mobjects might be different, the control flow + and lifecycle of mobjects is still more or less the same. There are more + substantial differences when it comes to the rendering loop. + +As you will see when inspecting the method, :meth:`.Scene.play` almost +immediately passes over to the ``play`` method of the renderer, +in our case :class:`.CairoRenderer.play`. The one thing :meth:`.Scene.play` +takes care of is the management of subcaptions that you might have +passed to it (see the the documentation of :meth:`.Scene.play` and +:meth:`.Scene.add_subcaption` for more information). + +.. warning:: + + As has been said before, the communication between scene and renderer + is not in a very clean state at this point, so the following paragraphs + might be confusing if you don't run a debugger and step through the + code yourself a bit. + +Inside :meth:`.CairoRenderer.play`, the renderer first checks whether +it may skip rendering of the current play call. This might happen, for example, +when ``-s`` is passed to the CLI (i.e., only the last frame should be rendered), +or when the ``-n`` flag is passed and the current play call is outside of the +specified render bounds. The "skipping status" is updated in form of the +call to :meth:`.CairoRenderer.update_skipping_status`. + +Next, the renderer asks the scene to process the animations in the play +call so that renderer obtains all of the information it needs. To +be more concrete, :meth:`.Scene.compile_animation_data` is called, +which then takes care of several things: + +- The method processes all animations and the keyword arguments passed + to the initial :meth:`.Scene.play` call. In particular, this means + that it makes sure all arguments passed to the play call are actually + animations (or ``.animate`` syntax calls, which are also assembled to + be actual :class:`.Animation`-objects at that point). It also propagates + any animation-related keyword arguments (like ``run_time``, + or ``rate_func``) passed to :class:`.Scene.play` to each individual + animation. The processed animations are then stored in the ``animations`` + attribute of the scene (which the renderer later reads...). +- It adds all mobjects to which the animations that are played are + bound to to the scene (provided the animation is not an mobject-introducing + animation -- for these, the addition to the scene happens later). +- In case the played animation is a :class:`.Wait` animation (this is the + case in a :meth:`.Scene.wait` call), the method checks whether a static + image should be rendered, or whether the render loop should be processed + as usual (see :meth:`.Scene.should_update_mobjects` for the exact conditions, + basically it checks whether there are any time-dependent updater functions + and so on). +- Finally, the method determines the total run time of the play call (which + at this point is computed as the maximum of the run times of the passed + animations). This is stored in the ``duration`` attribute of the scene. + + +After the animation data has been compiled by the scene, the renderer +continues to prepare for entering the render loop. It now checks the +skipping status which has been determined before. If the renderer can +skip this play call, it does so: it sets the current play call hash (which +we will get back to in a moment) to ``None`` and increases the time of the +renderer by the determined animation run time. + +Otherwise, the renderer checks whether or not Manim's caching system should +be used. The idea of the caching system is simple: for every play call, a +hash value is computed, which is then stored and upon re-rendering the scene, +the hash is generated again and checked against the stored value. If it is the +same, the cached output is reused, otherwise it is fully rerendered again. +We will not go into details of the caching system here; if you would like +to learn more, the :func:`.get_hash_from_play_call` function in the +:mod:`.utils.hashing` module is essentially the entry point to the caching +mechanism. + +In the event that the animation has to be rendered, the renderer asks +its :class:`.SceneFileWriter` to open an output container. The process +is started by a call to ``libav`` and opens a container to which rendered +raw frames can be written. As long as the output is open, the container +can be accessed via the ``output_container`` attribute of the file writer. +With the writing process in place, the renderer then asks the scene +to "begin" the animations. + +First, it literally *begins* all of the animations by calling their +setup methods (:meth:`.Animation._setup_scene`, :meth:`.Animation.begin`). +In doing so, the mobjects that are newly introduced by an animation +(like via :class:`.Create` etc.) are added to the scene. Furthermore, the +animation suspends updater functions being called on its mobject, and +it sets its mobject to the state that corresponds to the first frame +of the animation. + +After this has happened for all animations in the current ``play`` call, +the Cairo renderer determines which of the scene's mobjects can be +painted statically to the background, and which ones have to be +redrawn every frame. It does so by calling +:meth:`.Scene.get_moving_and_static_mobjects`, and the resulting +partition of mobjects is stored in the corresponding ``moving_mobjects`` +and ``static_mobjects`` attributes. + +.. NOTE:: + + The mechanism that determines static and moving mobjects is + specific for the Cairo renderer, the OpenGL renderer works differently. + Basically, moving mobjects are determined by checking whether they, + any of their children, or any of the mobjects "below" them (in the + sense of the order in which mobjects are processed in the scene) + either have an update function attached, or whether they appear + in one of the current animations. See the implementation of + :meth:`.Scene.get_moving_mobjects` for more details. + +Up to this very point, we did not actually render any (partial) +image or movie files from the scene yet. This is, however, about to change. +Before we enter the render loop, let us briefly revisit our toy +example and discuss how the generic :meth:`.Scene.play` call +setup looks like there. + +For the call that plays the :class:`.ReplacementTransform`, there +is no subcaption to be taken care of. The renderer then asks +the scene to compile the animation data: the passed argument +already is an animation (no additional preparations needed), +there is no need for processing any keyword arguments (as +we did not specify any additional ones to ``play``). The +mobject bound to the animation, ``orange_square``, is already +part of the scene (so again, no action taken). Finally, the run +time is extracted (3 seconds long) and stored in +``Scene.duration``. The renderer then checks whether it should +skip (it should not), then whether the animation is already +cached (it is not). The corresponding animation hash value is +determined and passed to the file writer, which then also calls +``libav`` to start the writing process which waits for rendered +frames from the library. + +The scene then ``begin``\ s the animation: for the +:class:`.ReplacementTransform` this means that the animation populates +all of its relevant animation attributes (i.e., compatible copies +of the starting and the target mobject so that it can safely interpolate +between the two). + +The mechanism determining static and moving mobjects considers +all of the scenes mobjects (at this point only the +``orange_square``), and determines that the ``orange_square`` is +bound to an animation that is currently played. As a result, +the square is classified as a "moving mobject". + +Time to render some frames. + + +The render loop (for real this time) +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +As mentioned above, due to the mechanism that determines static and moving +mobjects in the scene, the renderer knows which mobjects it can paint +statically to the background of the scene. Practically, this means that +it partially renders a scene (to produce a background image), and then +when iterating through the time progression of the animation only the +"moving mobjects" are re-painted on top of the static background. + +The renderer calls :meth:`.CairoRenderer.save_static_frame_data`, which +first checks whether there are currently any static mobjects, and if there +are, it updates the frame (only with the static mobjects; more about how +exactly this works in a moment) and then saves a NumPy array representing +the rendered frame in the ``static_image`` attribute. In our toy example, +there are no static mobjects, and so the ``static_image`` attribute is +simply set to ``None``. + +Next, the renderer asks the scene whether the current animation is +a "frozen frame" animation, which would mean that the renderer actually +does not have to repaint the moving mobjects in every frame of the time +progression. It can then just take the latest static frame, and display it +throughout the animation. + +.. NOTE:: + + An animation is considered a "frozen frame" animation if only a + static :class:`.Wait` animation is played. See the description + of :meth:`.Scene.compile_animation_data` above, or the + implementation of :meth:`.Scene.should_update_mobjects` for + more details. + +If this is not the case (just as in our toy example), the renderer +then calls the :meth:`.Scene.play_internal` method, which is the +integral part of the render loop (in which the library steps through +the time progression of the animation and renders the corresponding +frames). + +Within :meth:`.Scene.play_internal`, the following steps are performed: + +- The scene determines the run time of the animations by calling + :meth:`.Scene.get_run_time`. This method basically takes the maximum + ``run_time`` attribute of all of the animations passed to the + :meth:`.Scene.play` call. +- Then the *time progression* is constructed via the (internal) + :meth:`.Scene._get_animation_time_progression` method, which wraps + the actual :meth:`.Scene.get_time_progression` method. The time + progression is a ``tqdm`` `progress bar object `__ + for an iterator over ``np.arange(0, run_time, 1 / config.frame_rate)``. In + other words, the time progression holds the time stamps (relative to the + current animations, so starting at 0 and ending at the total animation run time, + with the step size determined by the render frame rate) of the timeline where + a new animation frame should be rendered. +- Then the scene iterates over the time progression: for each time stamp ``t``, + :meth:`.Scene.update_to_time` is called, which ... + + - ... first computes the time passed since the last update (which might be 0, + especially for the initial call) and references it as ``dt``, + - then (in the order in which the animations are passed to :meth:`.Scene.play`) + calls :meth:`.Animation.update_mobjects` to trigger all updater functions that + are attached to the respective animation except for the "main mobject" of + the animation (that is, for example, for :class:`.Transform` the unmodified + copies of start and target mobject -- see :meth:`.Animation.get_all_mobjects_to_update` + for more details), + - then the relative time progression with respect to the current animation + is computed (``alpha = t / animation.run_time``), which is then used to + update the state of the animation with a call to :meth:`.Animation.interpolate`. + - After all of the passed animations have been processed, the updater functions + of all mobjects in the scene, all meshes, and finally those attached to + the scene itself are run. + +At this point, the internal (Python) state of all mobjects has been updated +to match the currently processed timestamp. If rendering should not be skipped, +then it is now time to *take a picture*! + +.. NOTE:: + + The update of the internal state (iteration over the time progression) happens + *always* once :meth:`.Scene.play_internal` is entered. This ensures that even + if frames do not need to be rendered (because, e.g., the ``-n`` CLI flag has + been passed, something has been cached, or because we might be in a *Section* + with skipped rendering), updater functions still run correctly, and the state + of the first frame that *is* rendered is kept consistent. + +To render an image, the scene calls the corresponding method of its renderer, +:meth:`.CairoRenderer.render` and passes just the list of *moving mobjects* (remember, +the *static mobjects* are assumed to have already been painted statically to +the background of the scene). All of the hard work then happens when the renderer +updates its current frame via a call to :meth:`.CairoRenderer.update_frame`: + +First, the renderer prepares its :class:`.Camera` by checking whether the renderer +has a ``static_image`` different from ``None`` stored already. If so, it sets the +image as the *background image* of the camera via :meth:`.Camera.set_frame_to_background`, +and otherwise it just resets the camera via :meth:`.Camera.reset`. The camera is then +asked to capture the scene with a call to :meth:`.Camera.capture_mobjects`. + +Things get a bit technical here, and at some point it is more efficient to +delve into the implementation -- but here is a summary of what happens once the +camera is asked to capture the scene: + +- First, a flat list of mobjects is created (so submobjects get extracted from + their parents). This list is then processed in groups of the same type of + mobjects (e.g., a batch of vectorized mobjects, followed by a batch of image mobjects, + followed by more vectorized mobjects, etc. -- in many cases there will just be + one batch of vectorized mobjects). +- Depending on the type of the currently processed batch, the camera uses dedicated + *display functions* to convert the :class:`.Mobject` Python object to + a NumPy array stored in the camera's ``pixel_array`` attribute. + The most important example in that context is the display function for + vectorized mobjects, :meth:`.Camera.display_multiple_vectorized_mobjects`, + or the more particular (in case you did not add a background image to your + :class:`.VMobject`), :meth:`.Camera.display_multiple_non_background_colored_vmobjects`. + This method first gets the current Cairo context, and then, for every (vectorized) + mobject in the batch, calls :meth:`.Camera.display_vectorized`. There, + the actual background stroke, fill, and then stroke of the mobject is + drawn onto the context. See :meth:`.Camera.apply_stroke` and + :meth:`.Camera.set_cairo_context_color` for more details -- but it does not get + much deeper than that, in the latter method the actual Bézier curves + determined by the points of the mobject are drawn; this is where the low-level + interaction with Cairo happens. + +After all batches have been processed, the camera has an image representation +of the Scene at the current time stamp in form of a NumPy array stored in its +``pixel_array`` attribute. The renderer then takes this array and passes it to +its :class:`.SceneFileWriter`. This concludes one iteration of the render loop, +and once the time progression has been processed completely, a final bit +of cleanup is performed before the :meth:`.Scene.play_internal` call is completed. + +A TL;DR for the render loop, in the context of our toy example, reads as follows: + +- The scene finds that a 3 second long animation (the :class:`.ReplacementTransform` + changing the orange square to the blue circle) should be played. Given the requested + medium render quality, the frame rate is 30 frames per second, and so the time + progression with steps ``[0, 1/30, 2/30, ..., 89/30]`` is created. +- In the internal render loop, each of these time stamps is processed: + there are no updater functions, so effectively the scene updates the + state of the transformation animation to the desired time stamp (for example, + at time stamp ``t = 45/30``, the animation is completed to a rate of + ``alpha = 0.5``). +- Then the scene asks the renderer to do its job. The renderer asks its camera + to capture the scene, the only mobject that needs to be processed at this point + is the main mobject attached to the transformation; the camera converts the + current state of the mobject to entries in a NumPy array. The renderer passes + this array to the file writer. +- At the end of the loop, 90 frames have been passed to the file writer. + +Completing the render loop +^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The last few steps in the :meth:`.Scene.play_internal` call are not too +exciting: for every animation, the corresponding :meth:`.Animation.finish` +and :meth:`.Animation.clean_up_from_scene` methods are called. + +.. NOTE:: + + Note that as part of :meth:`.Animation.finish`, the :meth:`.Animation.interpolate` + method is called with an argument of 1.0 -- you might have noticed already that + the last frame of an animation can sometimes be a bit off or incomplete. + This is by current design! The last frame rendered in the render loop (and displayed + for a duration of ``1 / frame_rate`` seconds in the rendered video) corresponds to + the state of the animation ``1 / frame_rate`` seconds before it ends. To display + the final frame as well in the video, we would need to append another ``1 / frame_rate`` + seconds to the video -- which would then mean that a 1 second rendered Manim video + would be slightly longer than 1 second. We decided against this at some point. + +In the end, the time progression is closed (which completes the displayed progress bar) +in the terminal. With the closing of the time progression, the +:meth:`.Scene.play_internal` call is completed, and we return to the renderer, +which now orders the :class:`.SceneFileWriter` to close the output container that has +been opened for this animation: a partial movie file is written. + +This pretty much concludes the walkthrough of a :class:`.Scene.play` call, +and actually there is not too much more to say for our toy example either: at +this point, a partial movie file that represents playing the +:class:`.ReplacementTransform` has been written. The initialization of +the :class:`.Dot` happens analogous to the initialization of ``blue_circle``, +which has been discussed above. The :meth:`.Mobject.add_updater` call literally +just attaches a function to the ``updaters`` attribute of the ``small_dot``. And +the remaining :meth:`.Scene.play` and :meth:`.Scene.wait` calls follow the +exact same procedure as discussed in the render loop section above; each such call +produces a corresponding partial movie file. + +Once the :meth:`.Scene.construct` method has been fully processed (and thus all +of the corresponding partial movie files have been written), the +scene calls its cleanup method :meth:`.Scene.tear_down`, and then +asks its renderer to finish the scene. The renderer, in turn, asks +its scene file writer to wrap things up by calling :meth:`.SceneFileWriter.finish`, +which triggers the combination of the partial movie files into the final product. + +And there you go! This is a more or less detailed description of how Manim works +under the hood. While we did not discuss every single line of code in detail +in this walkthrough, it should still give you a fairly good idea of how the general +structural design of the library and at least the Cairo rendering flow in particular +looks like. diff --git a/docs/source/guides/index.rst b/docs/source/guides/index.rst new file mode 100644 index 0000000000..0f0a92b98d --- /dev/null +++ b/docs/source/guides/index.rst @@ -0,0 +1,12 @@ +Thematic Guides +=============== + +.. toctree:: + :caption: Table of Contents + :maxdepth: 2 + :glob: + + configuration + deep_dive + using_text + add_voiceovers diff --git a/docs/source/tutorials/using_text.rst b/docs/source/guides/using_text.rst similarity index 98% rename from docs/source/tutorials/using_text.rst rename to docs/source/guides/using_text.rst index 723438e8c5..a71b29ec81 100644 --- a/docs/source/tutorials/using_text.rst +++ b/docs/source/guides/using_text.rst @@ -1,6 +1,6 @@ -########## -Using Text -########## +########################### +Rendering Text and Formulas +########################### There are two different ways by which you can render **Text** in videos: @@ -50,7 +50,7 @@ For example: ) self.add(text) -.. _Pango library: https://pango.gnome.org +.. _Pango library: https://pango.org Working with :class:`~.Text` ============================ @@ -378,7 +378,7 @@ we have to add it manually. myTemplate = TexTemplate() myTemplate.add_to_preamble(r"\usepackage{mathrsfs}") tex = Tex( - r"$\mathscr{H} \rightarrow \mathbb{H}$}", + r"$\mathscr{H} \rightarrow \mathbb{H}$", tex_template=myTemplate, font_size=144, ) diff --git a/docs/source/index.rst b/docs/source/index.rst index 1e1ac1836f..d88eb9a854 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -3,8 +3,8 @@ You can adapt this file completely to your liking, but it should at least contain the root `toctree` directive. -Manim Community Overview -======================== +Manim Community Edition +======================= Animating technical concepts is traditionally pretty tedious since it can be difficult to make the animations precise enough to convey them accurately. @@ -13,23 +13,99 @@ making it convenient to specify exactly how each one should run. Take a look at the :doc:`Example Gallery <../examples>` for some inspiration on how to create beautiful images and videos with Manim. +First Steps +----------- + +Are you new to Manim and are looking for where to get started? Then you are +in the right place! + +.. note:: + + Please be aware that there are different, incompatible versions of Manim available. + This version, the Community Edition of Manim (`ManimCE `_), + is a separate project maintained by the community, but it was forked from `3b1b/manim `_, + the original Manim created and open-sourced by Grant Sanderson, creator of `3Blue1Brown `_ educational math videos. + Check our :ref:`installation FAQ ` + to learn more! + +- The :doc:`Installation ` section has the latest and + up-to-date installation instructions for Windows, macOS, and Linux. + You can also find information on Manim's docker images and (online) + notebook environments there. +- Want to try the library before installing it? Take a look at our + interactive online playground at https://try.manim.community in the form + of a Jupyter notebook. +- In our :doc:`Tutorials ` section you will find a + collection of resources that will teach you how to use Manim. In particular, + the :doc:`tutorials/quickstart` tutorial teaches you Manim's basics, + and in :doc:`tutorials/building_blocks` the classes used to compose + your animations are described in more detail. + + +Finding Help +------------ + +Are you struggling with installing or using Manim? Don't worry, we've all been +there. Here are some good resources to help you out: + +- Perhaps your problem is one that occurs frequently, then chances are it is + addressed in our :doc:`collection of FAQs `. +- If you are looking for information on some specific class, look for it + in the :doc:`reference manual ` and/or use the search feature + of the documentation. +- Still no luck? Then you are welcome to ask the community for help, together + we usually manage to find a solution for your problem! Consult the + :doc:`FAQ page on getting help ` for instructions. + + +Navigating the Documentation +---------------------------- + +Here are some short summaries for all of the sections in this documentation: + +- The :doc:`Example Gallery ` is a collection of examples (rendered videos + and images together with the code they were generated from) that show a few different, + simple things that you can do with Manim. +- The :doc:`Installation ` section has information on installing Manim. +- In :doc:`Tutorials & Guides ` you can find learning resources: proper + tutorials that guide you through the process of creating a video are in + the :doc:`Tutorial ` section; guides on specific topics are in the + :doc:`Guides ` section, and the answers to frequently asked questions + can be found in the :doc:`FAQ ` section. +- The :doc:`Reference Manual ` contains a comprehensive list of all of Manim's + (documented) modules, classes, and functions. If you are somewhat familiar with Manim's + module structure, feel free to browse the manual directly. If you are searching for + something specific, feel free to use the documentation's search feature in the sidebar. + Many classes and methods come with their own illustrated examples too! +- The :doc:`Plugins ` page documents how to install, write, and distribute + plugins (that is, separate Python packages that extend the feature set of the core library). +- Changes between versions are documented in our :doc:`Changelog `. +- If you are looking into contributing to the development of Manim, you can find information + on how to get involved in our :doc:`Contributing ` section. +- And finally, the :doc:`Code of Conduct ` page has a formal description of + the rules you should abide by when interacting within our community. + +Sharing Your Work +----------------- + We'd love to hear from you and see your manimations `on Twitter `_, `Reddit `_, or `Discord `_. If you're using Manim in a scientific context, instructions on how to cite a particular release can be found `in our README `_. +Index +----- + .. toctree:: :maxdepth: 2 - installation - tutorials examples - changelog + installation + tutorials_guides reference plugins - reporting_bugs - internals + changelog contributing conduct diff --git a/docs/source/installation.rst b/docs/source/installation.rst index 160a167bfd..3c2b4e4c09 100644 --- a/docs/source/installation.rst +++ b/docs/source/installation.rst @@ -8,18 +8,20 @@ require no local installation. Head over to https://try.manim.community to give our interactive tutorial a try. Otherwise, if you intend to use Manim to work on an animation project, -we recommend installing the library locally (either to your system's -Python, or via Docker). +we recommend installing the library locally (preferably to some isolated +virtual Python environment, or a conda-like environment, or via Docker). .. warning:: Note that there are several different versions of Manim. The instructions on this website are **only** for the *community edition*. - Find out more about the :doc:`differences between Manim - versions ` if you are unsure which + Find out more about the :ref:`differences between Manim + versions ` if you are unsure which version you should install. -#. :ref:`Installing Manim to your system's Python ` +#. :ref:`(Recommended) Installing Manim via Python's package manager pip + ` +#. :ref:`Installing Manim to a conda environment ` #. :ref:`Using Manim via Docker ` #. :ref:`Interactive Jupyter notebooks via Binder / Google Colab ` @@ -27,46 +29,48 @@ Python, or via Docker). .. _local-installation: -Installing Manim locally -************************ +Installing Manim locally via pip +******************************** -Manim is a Python library, and it can be -`installed via pip `__. However, -in order for Manim to work properly, some additional system -dependencies need to be installed first. The following pages have -operating system specific instructions for you to follow. +The recommended way of installing Manim is by using Python's package manager +pip. If you already have a Python environment set up, you can simply run +``pip install manim`` to install the library. -Manim requires Python version ``3.7`` or above to run. +Our :doc:`local installation guide ` provides more detailed +instructions, including best practices for setting up a suitable local environment. -.. hint:: +.. toctree:: + :hidden: - Depending on your particular setup, the installation process - might be slightly different. Make sure that you have tried to - follow the steps on the following pages carefully, but in case - you hit a wall we are happy to help: either `join our Discord - `__, or start a new - Discussion `directly on GitHub - `__. + installation/uv -.. toctree:: - :maxdepth: 2 +.. _conda-installation: + +Installing Manim via Conda and related environment managers +*********************************************************** + +Conda is a package manager for Python that allows creating environments +where all your dependencies are stored. Like this, you don't clutter up your PC with +unwanted libraries and you can just delete the environment when you don't need it anymore. +It is a good way to install manim since all dependencies like ``pycairo``, etc. come with it. +Also, the installation steps are the same, no matter if you are +on Windows, Linux, Intel Macs or on Apple Silicon. - installation/windows - installation/macos - installation/linux - installation/troubleshooting +.. NOTE:: -Once Manim is installed locally, you can proceed to our -:doc:`quickstart guide ` which walks you -through rendering a first simple scene. + There are various popular alternatives to Conda like + `mamba `__ / + `micromamba `__, + or `pixi `__. + They all can be used to setup a suitable, isolated environment + for your Manim projects. -As mentioned above, do not worry if there are errors or other -problems: consult our :doc:`troubleshooting -guide ` for help, or get in touch -with the community via `GitHub discussions -`__ or -`Discord `__. +The following pages show how to install Manim in a conda environment: +.. toctree:: + :maxdepth: 2 + + installation/conda .. _docker-installation: @@ -112,6 +116,11 @@ If you're using Visual Studio Code you can install an extension called of the animation inside the editor. The extension can be installed through the `marketplace of VS Code `__. +.. caution:: + + This extension is not officially maintained by the Manim Community. + If you run into issues, please report them to the extension's author. + Installation for developers *************************** diff --git a/docs/source/installation/conda.rst b/docs/source/installation/conda.rst new file mode 100644 index 0000000000..8350bfaeea --- /dev/null +++ b/docs/source/installation/conda.rst @@ -0,0 +1,54 @@ +Conda +===== + +Required Dependencies +--------------------- + +There are several package managers that work with conda packages, +namely `conda `__, +`mamba `__ and `pixi `__. + +After installing your package manager, you can create a new environment and install ``manim`` inside by running + + +.. tab-set:: + + .. tab-item:: conda / mamba + + .. code-block:: bash + + # if you want to use mamba, just replace conda below with mamba + conda create -n my-manim-environment + conda activate my-manim-environment + conda install -c conda-forge manim + + .. tab-item:: pixi + + .. code-block:: bash + + pixi init + pixi add manim + + +Since all dependencies (except LaTeX) are handled by conda, you don't need to worry +about needing to install additional dependencies. + + + +Optional Dependencies +--------------------- + +In order to make use of Manim's interface to LaTeX to, for example, render +equations, LaTeX has to be installed as well. Note that this is an optional +dependency: if you don't intend to use LaTeX, you don't have to install it. + +Recommendations on how to install LaTeX on different operating systems +can be found :doc:`in our local installation guide `. + + +Working with Manim +------------------ + +At this point, you should have a working installation of Manim, head +over to our :doc:`Quickstart Tutorial <../tutorials/quickstart>` to learn +how to make your own *Manimations*! diff --git a/docs/source/installation/docker.rst b/docs/source/installation/docker.rst index 45eab6864b..1e2b16f0e5 100644 --- a/docs/source/installation/docker.rst +++ b/docs/source/installation/docker.rst @@ -45,7 +45,7 @@ modify to your liking. First, run .. code-block:: sh - docker run -it --name my-manim-container -v "/full/path/to/your/directory:/manim" manimcommunity/manim /bin/bash + docker run -it --name my-manim-container -v "/full/path/to/your/directory:/manim" manimcommunity/manim bash to obtain an interactive shell inside your container allowing you diff --git a/docs/source/installation/jupyter.rst b/docs/source/installation/jupyter.rst index e2a61114f6..94a2fcf2c3 100644 --- a/docs/source/installation/jupyter.rst +++ b/docs/source/installation/jupyter.rst @@ -26,7 +26,7 @@ a way that allows them to be shared interactively via Binder as well: .. code-block:: dockerfile - FROM manimcommunity/manim:v0.9.0 + FROM docker.io/manimcommunity/manim:v0.9.0 COPY --chown=manimuser:manimuser . /manim @@ -66,12 +66,12 @@ then execute it. .. code-block:: !sudo apt update - !sudo apt install libcairo2-dev ffmpeg \ + !sudo apt install libcairo2-dev \ texlive texlive-latex-extra texlive-fonts-extra \ texlive-latex-recommended texlive-science \ tipa libpango1.0-dev !pip install manim - !pip install IPython --upgrade + !pip install IPython==8.21.0 You should start to see Colab installing all the dependencies specified in these commands. After the execution has completed, you will be prompted diff --git a/docs/source/installation/linux.rst b/docs/source/installation/linux.rst deleted file mode 100644 index dba8e16c60..0000000000 --- a/docs/source/installation/linux.rst +++ /dev/null @@ -1,149 +0,0 @@ -Linux -===== - -The installation instructions depend on your particular operating -system and package manager. If you happen to know exactly what you are doing, -you can also simply ensure that your system has: - -- a reasonably recent version of Python 3 (3.7–3.10), -- with working Cairo bindings in the form of - `pycairo `__, -- FFmpeg accessible from the command line as ``ffmpeg``, -- and `Pango `__ headers. - -Then, installing Manim is just a matter of running: - -.. code-block:: bash - - pip3 install manim - -.. note:: - - In light of the current efforts of migrating to rendering via OpenGL, - this list might be incomplete. Please `let us know - ` if you - ran into missing dependencies while installing. - -In any case, we have also compiled instructions for several common -combinations of operating systems and package managers below. - -Required Dependencies ---------------------- - -apt – Ubuntu / Mint / Debian -**************************** - -To first update your sources, and then install Cairo, Pango, and FFmpeg -simply run: - -.. code-block:: bash - - sudo apt update - sudo apt install libcairo2-dev libpango1.0-dev ffmpeg - -If you don't have python3-pip installed, install it via: - -.. code-block:: bash - - sudo apt install python3-pip - -Then, to install Manim, run: - -.. code-block:: bash - - pip3 install manim - -Continue by reading the :ref:`optional dependencies ` -section. - -dnf – Fedora / CentOS / RHEL -**************************** - -To install Cairo and Pango: - -.. code-block:: bash - - sudo dnf install cairo-devel pango-devel - -In order to successfully build the ``pycairo`` wheel, you will also -need the Python development headers: - -.. code-block:: bash - - sudo dnf install python3-devel - -FFmpeg is only available via the RPMfusion repository which you have to -configure first – please consult https://rpmfusion.org/Configuration/ for -instructions. Then, install FFmpeg: - -.. code-block:: bash - - sudo dnf install ffmpeg - -At this point you have all required dependencies and can install -Manim by running: - -.. code-block:: bash - - pip3 install manim - -Continue by reading the :ref:`optional dependencies ` -section. - -pacman – Arch / Manjaro -*********************** - -.. tip:: - - Thanks to *groctel*, there is a `dedicated Manim package - on the AUR! ` - -If you don't want to use the packaged version from AUR, here is what -you need to do manually: Update your package sources, then install -Cairo, Pango, and FFmpeg: - -.. code-block:: bash - - sudo pacman -Syu - sudo pacman -S cairo pango ffmpeg - -If you don't have ``python-pip`` installed, get it by running: - -.. code-block:: bash - - sudo pacman -S python-pip - -then simply install Manim via: - -.. code-block:: bash - - pip3 install manim - - -Continue by reading the :ref:`optional dependencies ` -section. - - -.. _linux-optional-dependencies: - -Optional Dependencies ---------------------- - -In order to make use of Manim's interface to LaTeX for, e.g., rendering -equations, LaTeX has to be installed as well. Note that this is an optional -dependency: if you don't intend to use LaTeX, you don't have to install it. - -You can use whichever LaTeX distribution you like or whichever is easiest -to install with your package manager. Usually, -`TeX Live `__ is a good candidate if you don't -care too much about disk space. - -Should you choose to work with some smaller TeX distribution like -`TinyTeX `__ , the full list -of LaTeX packages which Manim interacts with in some way (a subset might -be sufficient for your particular application) is:: - - collection-basic amsmath babel-english cbfonts-fd cm-super ctex doublestroke - dvisvgm everysel fontspec frcursive fundus-calligra gnu-freefont jknapltx - latex-bin mathastext microtype ms physics preview ragged2e relsize rsfs - setspace standalone tipa wasy wasysym xcolor xetex xkeyval diff --git a/docs/source/installation/macos.rst b/docs/source/installation/macos.rst deleted file mode 100644 index 42d43ae27e..0000000000 --- a/docs/source/installation/macos.rst +++ /dev/null @@ -1,100 +0,0 @@ -MacOS -===== - -For the sake of simplicity, the following instructions assume that you have -the popular `package manager Homebrew `__ installed. While -you can certainly also install all dependencies without it, using Homebrew -makes the process much easier. - -If you want to use Homebrew but do not have it installed yet, please -follow `Homebrew's installation instructions `__. - -.. note:: - - For a while after Apple released its new ARM-based processors (the *"M1 chip"*), - the recommended way of installing Manim relied on *Rosetta*, Apple's compatibility - layer between Intel and ARM architectures. This is no longer necessary, Manim can - (and is recommended to) be installed natively. - - -Required Dependencies ---------------------- - -To install all required dependencies for installing Manim (namely: ffmpeg, Python, -and some required Python packages), run: - -.. code-block:: bash - - brew install py3cairo ffmpeg - -On *Apple Silicon* based machines (i.e., devices with the M1 chip or similar; if -you are unsure which processor you have check by opening the Apple menu, select -*About This Mac* and check the entry next to *Chip*), some additional dependencies -are required, namely: - -.. code-block:: bash - - brew install cmake pango scipy - -After all required dependencies are installed, simply run: - -.. code-block:: bash - - pip3 install manim - -to install Manim. - -.. note:: - - A frequent source for installation problems is if ``pip3`` - does not point to the correct Python installation on your system. - To check this, run ``pip3 -V``: for MacOS Intel, the path should - start with ``/usr/local``, and for Apple Silicon with - ``/opt/homebrew``. If this is not the case, you either forgot - to modify your shell profile (``.zprofile``) during the installation - of Homebrew, or did not reload your shell (e.g., by opening a new - terminal) after doing so. It is also possible that some other - software (like Pycharm) changed the ``PATH`` variable – to fix this, - make sure that the Homebrew-related lines in your ``.zprofile`` are - at the very end of the file. - - -Optional Dependencies ---------------------- - -In order to make use of Manim's interface to LaTeX for, e.g., rendering -equations, LaTeX has to be installed as well. Note that this is an optional -dependency: if you don't intend to use LaTeX, you don't have to install it. - -For MacOS, the recommended LaTeX distribution is -`MacTeX `__. You can install it by following -the instructions from the link, or alternatively also via Homebrew by -running: - -.. code-block:: bash - - brew install --cask mactex-no-gui - -.. warning:: - - MacTeX is a *full* LaTeX distribution and will require more than 4GB of - disk space. If this is an issue for you, consider installing a smaller - distribution like - `BasicTeX `__. - -Should you choose to work with some partial TeX distribution, the full list -of LaTeX packages which Manim interacts with in some way (a subset might -be sufficient for your particular application) is:: - - amsmath babel-english cbfonts-fd cm-super ctex doublestroke dvisvgm everysel - fontspec frcursive fundus-calligra gnu-freefont jknapltx latex-bin - mathastext microtype ms physics preview ragged2e relsize rsfs - setspace standalone tipa wasy wasysym xcolor xetex xkeyval - - -Working with Manim ------------------- - -At this point, you should have a working installation of Manim. Head -over to our :doc:`Quickstart Tutorial <../tutorials/quickstart>` to learn -how to make your own *Manimations*! diff --git a/docs/source/installation/troubleshooting.rst b/docs/source/installation/troubleshooting.rst deleted file mode 100644 index 982685e5cd..0000000000 --- a/docs/source/installation/troubleshooting.rst +++ /dev/null @@ -1,299 +0,0 @@ -Troubleshooting -=============== - -Version incompatibility -*********************** - -Confusion and conflict between versions is by far the most common reason -for installation failures. Some signs and errors resulting from this are -as follows: - -- ``There are no scenes in that module`` -- ``ModuleNotFoundError: No module named 'manim'`` -- ``ModuleNotFoundError: No module named 'manimlib'`` -- You followed any tutorial created before October 2020 (because the community edition did not exist before then) -- You cloned a repository on GitHub (installation of the community version for normal use does not require the cloning of any repository) -- Different import statements (explained below) -- You used documentation for multiple versions (such as the readme for 3b1b/manim and this documentation) - -.. note:: - As this is the documentation for the community version, we can - only help with the installation of this library. If you would like to - install other versions of manim, please refer to their documentation. - -Identifying files written for a different version of manim ----------------------------------------------------------- - -There are some distinctive features of different versions of manim that -can help in identifying what version of manim files are written for: - -+--------------+-------------------------+----------------------------+-----------------------------------------+ -| Feature | ManimCE (this version) | ManimGL | ManimCairo | -+==============+=========================+============================+=========================================+ -| Import | ``from manim import *`` | ``from manimlib import *`` | ``from manimlib.imports import *`` | -| statement | | | | -+--------------+-------------------------+----------------------------+-----------------------------------------+ - -If you are a beginner, you should only attempt to run files written for -your version. Files written for a different version of manim will -generally not work without some modification. - -Identifying the version you are running ---------------------------------------- - -The community edition of manim should always state `Manim Community ` -as its first line of any command you run. - -Identifying and removing conflicting versions of manim ------------------------------------------------------- - -Within the system or environment you are using to run manim, run the -following command in the terminal: - -.. code-block:: bash - - pip list - -The correct package for the community edition is simply ``manim``. If -you do not see this package listed, please refer back to our -installation guide to install it. If you see ``manimlib`` or ``manimce`` -(actually an old version of the community edition), you should remove -them with: - -.. code-block:: bash - - pip uninstall - - -If you have cloned a repository from GitHub, you should either remove it -or run manim outside that folder. - -Other errors -************ - -``pip install manim`` fails when installing manimpango? -------------------------------------------------------- -Most likely this means that pip was not able to use our pre-built wheels -of ``manimpango``. Let us know (via our `Discord `_ -or by opening a -`new issue on GitHub `_) -which architecture you would like to see supported, and we'll see what we -can do about it. - -To fix errors when installing ``manimpango``, you need to make sure you -have all the necessary build requirements. Check out the detailed -instructions given in -`the BUILDING section `_ -of the corresponding `GitHub repository `_. - - -(Windows) OSError: dlopen() failed to load a library: pango? ------------------------------------------------------------- - -This should be fixed in Manim's latest version, update -using ``pip install --upgrade manim``. - - - -Some letters are missing from Text/Tex output? ------------------------------------------------------------- - -If you have recently installed TeX you may need to build the fonts it -uses. Which can be done by running: - -.. code-block:: bash - - fmtutil -sys --all - - -.. _dvisvgm-troubleshoot: - -Installation does not support converting PDF to SVG? ----------------------------------------------------- - -First, make sure your ``dvisvgm`` version is at least 2.4: - -.. code-block:: bash - - dvisvgm --version - - -If you do not know how to update ``dvisvgm``, please refer to your operating system's documentation. - -Second, check whether your ``dvisvgm`` supports PostScript specials. This is -needed to convert from PDF to SVG. - -.. code-block:: bash - - dvisvgm -l - - -If the output to this command does **not** contain ``ps dvips PostScript specials``, -this is a bad sign. In this case, run - -.. code-block:: bash - - dvisvgm -h - - -If the output does **not** contain ``--libgs=filename``, this means your -``dvisvgm`` does not currently support PostScript. You must get another binary. - -If, however, ``--libgs=filename`` appears in the help, that means that your -``dvisvgm`` needs the Ghostscript library to support PostScript. Search for -``libgs.so`` (on Linux, probably in ``/usr/local/lib`` or ``/usr/lib``) or -``gsdll32.dll`` (on 32-bit Windows, probably in ``C:\windows\system32``) or -``gsdll64.dll`` (on 64-bit Windows, probably in ``c:\windows\system32`` -- yes -32) or ``libgsl.dylib`` (on Mac OS, probably in ``/usr/local/lib`` or -``/opt/local/lib``). Please look carefully, as the file might be located -elsewhere, e.g. in the directory where Ghostscript is installed. - -As soon as you have found the library, try (on Mac OS or Linux) - -.. code-block:: bash - - export LIBGS= - dvisvgm -l - -or (on Windows) - -.. code-block:: bat - - set LIBGS= - dvisvgm -l - - -You should now see ``ps dvips PostScript specials`` in the output. Refer to -your operating system's documentation to find out how you can set or export the -environment variable ``LIBGS`` automatically whenever you open a shell. - -As a last check, you can run - -.. code-block:: bash - - dvisvgm -V1 - -while still having ``LIBGS`` set to the correct path, of course. If ``dvisvgm`` -can find your Ghostscript installation, it will be shown in the output together -with the version number. - -If you do not have the necessary library on your system, please refer to your -operating system's documentation to find out where you can get it and how you -have to install it. - -If you are unable to solve your problem, check out the `dvisvgm FAQ `_. - -(Windows) ``Python is not recognized as an internal or external command, operable program or batch file.`` ----------------------------------------------------------------------------------------------------------- - -To fix this, you need to add the Python executable to your ``PATH`` environment variable. -Follow the steps in `this StackExchange answer `__. - -``choco install manimce`` failed --------------------------------- - -If ``choco install manimce`` failed, -it is likely being caused by Python not being added to your ``PATH`` variable properly. -Try running the following commands in your terminal: - -1. ``py --version`` -2. ``python --version`` -3. ``py3 --version`` -4. ``python3 --version`` - -Minimally, ``py --version`` and ``python --version`` should return a version. -If none of these commands are recognized, -this means that Python was installed on your system, but was not added to PATH. -See above for directions to add it to your PATH variable. - -If any of these commands opens up the Windows store, -this is likely interfering with the process. -This is because Chocolatey runs a command that calls python or python3, -and opening up the Windows store is not the expected behavior. -See below to fix aliases. - -(Windows) Fix Aliases ---------------------- - -1. Go to the Windows Settings. -2. Under Apps and Features, there are an application execution aliases. -3. Within this menu disable the alias(es) that is causing the issue (``python`` and/or ``python3``). - -``IndexError: List index out of range`` ---------------------------------------- - -Did you install LaTeX using MiKTeX? If so, open the MiKTeX console, -install the ``cm-super`` package, then delete the ``media`` directory and -try to render the scene again. - -Config ------- - -We've dropped the use of CONFIG in the -Community Version :doc:`version 0.2.0<../changelog/0.2.0-changelog>`, released in January 2021. -This means parameters that were previously specified in the -CONFIG dictionary should now be passed directly into the constructor. -Practically, this means that old constructions like: - -.. code-block:: python - - class SomeMobject(Thing): - CONFIG = { - "stroke_color": RED, - "fill_opacity": 0.7, - "radius": 3, - "my_awesome_property": 42, - } - # add methods here - -should now be defined like: - -.. code-block:: python - - class SomeMobject(VMobject): - def __init__( - self, - stroke_color=RED, - fill_opacity=0.7, - radius=3, - my_awesome_property=42, - **kwargs - ): - self.radius = 3 - self.my_awesome_property = 42 - super().__init__( - stroke_color=stroke_color, fill_opacity=fill_opacity, **kwargs - ) # passing arguments into the parent class - # add methods here - -For scenes, this is even easier: - -.. code-block:: python - - class Test(Scene): - CONFIG = {"a": 1, "b": 2} - -becomes: - -.. code-block:: python - - class Test(Scene): - def construct(self): - self.a = 1 - self.b = 2 - -A python command does not work ------------------------------- - -If a python command does not work, -try adding ``python -m`` in front of it. -For example, if ``pip install manim`` does not work, you can try ``python -m pip install manim``. - -undefined symbol ----------------- - -If you are using anaconda, run the following command: - -.. code-block:: bash - - conda install -c conda-forge pycairo diff --git a/docs/source/installation/uv.md b/docs/source/installation/uv.md new file mode 100644 index 0000000000..ab2ccec554 --- /dev/null +++ b/docs/source/installation/uv.md @@ -0,0 +1,331 @@ +# Installing Manim locally + +The standard way of installing Manim is by using +Python's package manager `pip` to install the latest +release from [PyPI](https://pypi.org/project/manim/). + +To make it easier for you to follow best practices when it +comes to setting up a Python project for your Manim animations, +we strongly recommend using a tool for managing Python environments +and dependencies. In particular, +[we strongly recommend using `uv`](https://docs.astral.sh/uv/#getting-started). + +For the two main ways of installing Manim described below, we assume +that `uv` is available; we think it is particularly helpful if you are +new to Python or programming in general. It is not a hard requirement +whatsoever; if you know what you are doing you can just use `pip` to +install Manim directly. + +:::::{admonition} Installing the Python management tool `uv` +:class: seealso + +One way to install `uv` is via the dedicated console installer supporting +all large operating systems. Simply paste the following snippet into +your terminal / PowerShell -- or +[consult `uv`'s documentation](https://docs.astral.sh/uv/#getting-started) +for alternative ways to install the tool. + +::::{tab-set} +:::{tab-item} MacOS and Linux +```bash +curl -LsSf https://astral.sh/uv/install.sh | sh +``` +::: +:::{tab-item} Windows +```powershell +powershell -ExecutionPolicy ByPass -c "irm https://astral.sh/uv/install.ps1 | iex" +``` +::: +:::: + +::::: + +Of course, if you know what you are doing and prefer to setup a virtual +environment yourself, feel free to do so! + +:::{important} +If you run into issues when following our instructions below, do +not worry: check our [installation FAQs]() to +see whether the problem is already addressed there -- and otherwise go and +check [how to contact our community]() to get help. +::: + + + +## Installation + +### Step 1: Installing Python + +We first need to check that an appropriate version of Python is available +on your machine. Open a terminal to run +```bash +uv python install +``` +to install the latest version of Python. If this is successful, continue +to the next step. + +(installation-optional-latex)= +### Step 2 (optional): Installing LaTeX + +[LaTeX](https://en.wikibooks.org/wiki/LaTeX/Mathematics) is a very well-known +and widely used typesetting system allowing you to write formulas like + +\begin{equation*} +\frac{1}{2\pi i} \oint_{\gamma} \frac{f(z)}{(z - z_0)^{n+1}}~dz += \frac{f^{(n)}(z_0)}{n!}. +\end{equation*} + +If rendering plain text is sufficient for your needs and you don't want +to render any typeset formulas, you can technically skip this step. Otherwise +select your operating system from the tab list below and follow the instructions. + +:::::{tab-set} + +::::{tab-item} Windows +For Windows we recommend installing LaTeX via the +[MiKTeX distribution](https://miktex.org). Simply grab +the Windows installer available from their download page, + and run it. +:::: + +::::{tab-item} MacOS +If you are running MacOS, we recommend installing the +[MacTeX distribution](https://www.tug.org/mactex/). The latest +available PKG file can be downloaded from +. +Get it and follow the standard installation procedure. +:::: + +::::{tab-item} Linux +Given the large number of Linux distributions with different ways +of installing packages, we cannot give detailed instructions for +all package managers. + +In general we recommend to install a *TeX Live* distribution +(). For most Linux distributions, +TeX Live has already been packaged such that it can be installed +easily with your system package manager. Search the internet and +your usual OS resources for detailed instructions. + +For example, on Debian-based systems with the package manager `apt`, +a full TeX Live distribution can be installed by running +```bash +sudo apt install texlive-full +``` +For Fedora (managed via `dnf`), the corresponding command is +```bash +sudo dnf install texlive-scheme-full +``` +As soon as LaTeX is installed, continue with actually installing Manim +itself. + +:::: + +::::: + +:::{dropdown} I know what I am doing and I would like to setup a minimal LaTeX installation +You are welcome to use a smaller, more customizable LaTeX distribution like +[TinyTeX](https://yihui.org/tinytex/). Manim overall requires the following +LaTeX packages to be installed in your distribution: +```text +amsmath babel-english cbfonts-fd cm-super count1to ctex doublestroke dvisvgm everysel +fontspec frcursive fundus-calligra gnu-freefont jknapltx latex-bin +mathastext microtype multitoc physics preview prelim2e ragged2e relsize rsfs +setspace standalone tipa wasy wasysym xcolor xetex xkeyval +``` +::: + +### Step 3: Installing Manim + +These steps again differ slightly between different operating systems. Make +sure you select the correct one from the tab list below, then follow +the instructions below. + +::::::{tab-set} + +:::::{tab-item} Windows +The following commands will + +- create a new directory for a Python project, +- and add Manim as a dependency, which installs it into the corresponding + local Python environment. + +The name for the Python project is *manimations*, which you can change +to anything you like. + +```bash +uv init manimations +cd manimations +uv add manim +``` + +Manim is now installed in your local project environment! + +::::: + +:::::{tab-item} MacOS +Before we can install Manim, we need to make sure that the system utilities +`cairo` and `pkg-config` are present. They are needed for the [`pycairo` Python +package](https://pycairo.readthedocs.io/en/latest/), a dependency of Manim. + +The easiest way of installing these utilities is by using [Homebrew](https://brew.sh/), +a fairly popular 3rd party package manager for MacOS. Check whether Homebrew is +already installed by running + +```bash +brew --version +``` + +which will report something along the lines of `Homebrew 4.4.15-54-...` +if it is installed, and a message `command not found: brew` otherwise. In this +case, use the shell installer [as instructed on Homebrew's website](https://brew.sh/), +or get a `.pkg`-installer from +[their GitHub release page](https://github.com/Homebrew/brew/releases). Make sure to +follow the instructions of the installer carefully, especially when prompted to +modify your `.zprofile` to add Homebrew to your system's PATH. + +With Homebrew available, the required utilities can be installed by running + +```bash +brew install cairo pkg-config +``` + +With all of this preparation out of the way, now it is time to actually install +Manim itself! The following commands will + +- create a new directory for a Python project, +- and add Manim as a dependency, which installs it into the corresponding + local Python environment. + +The name for the Python project is *manimations*, which you can change +to anything you like. + +```bash +uv init manimations +cd manimations +uv add manim +``` + +Manim is now installed in your local project environment! + +::::: + +:::::{tab-item} Linux +Practically, the instructions given in the *Windows* tab +also apply for Linux -- however, some additional dependencies are +required as Linux users need to build +[ManimPango](https://github.com/ManimCommunity/ManimPango) +(and potentially [pycairo](https://pycairo.readthedocs.io/en/latest/)) +from source. More specifically, this includes: + +- A C compiler, +- Python's development headers, +- the `pkg-config` tool, +- Pango and its development headers, +- and Cairo and its development headers. + +Instructions for popular systems / package managers are given below. + +::::{tab-set} + +:::{tab-item} Debian-based / apt +```bash +sudo apt update +sudo apt install build-essential python3-dev libcairo2-dev libpango1.0-dev +``` +::: + +:::{tab-item} Fedora / dnf +```bash +sudo dnf install python3-devel pkg-config cairo-devel pango-devel +``` +::: + +:::{tab-item} Arch Linux / pacman +```bash +sudo pacman -Syu base-devel cairo pango +``` +::: + +:::: + +As soon as the required dependencies are installed, you can create +a Python project (feel free to change the name *manimations* used below +to some other name) with a local environment containing Manim by running +```bash +uv init manimations +cd manimations +uv add manim +``` + +::::: + +:::::: + +To verify that your local Python project is setup correctly +and that Manim is available, simply run +```bash +uv run manim checkhealth +``` + +At this point, you can also open your project folder with the +IDE of your choice. All modern Python IDEs (for example VS Code +with the Python extension, or PyCharm) should automatically detect +the local environment created by `uv` such that if you put +```py +import manim +``` +into a new file `my-first-animation.py`, the import is resolved +correctly and autocompletion is available. + +*Happy Manimating!* + + +:::{dropdown} Alternative: Installing Manim as a global `uv`-managed tool +If you have Manim projects in many different directories and you do not +want to setup a local project environment for each of them, you could +also install Manim as a `uv`-managed tool. + +See [`uv`'s documentation for more information](https://docs.astral.sh/uv/concepts/tools/) +on their tool mechanism. + +To install Manim as a global `uv` tool, simply run +```bash +uv tool install manim +``` +after which the `manim` executable will be available on your +global system path, without the need to activate any virtual +environment or prefixing your commands with `uv run`. + +Note that when using this approach, setting up your code editor +to properly resolve `import manim` requires additional work, as +the global tool environment is not automatically detected: the +base path of all tool environments can be determined by running +``` +uv tool dir +``` +which should now contain a directory `manim` in which the appropriate +virtual environment is located. Set the Python interpreter of your IDE +to this environment to make imports properly resolve themselves. +::: + +:::{dropdown} Installing Manim for a different version of Python +In case you would like to use a different version of Python +(for example, due to compatibility issues with other packages), +then `uv` allows you to do so in a fairly straightforward way. + +When initializing the local Python project, simply pass the Python +version you want to use as an argument to the `init` command: +``` +uv init --python 3.12 manimations +cd manimations +uv add manim +``` +To change the version for an existing package, you will need to +edit the `pyproject.toml` file. If you are downgrading the python version, the +`requires-python` entry needs to be updated such that your chosen +version satisfies the requirement. Change the line to, for example +`requires-python = ">=3.12"`. After that, run `uv python pin 3.12` +to pin the python version to `3.12`. Finally, run `uv sync`, and your +environment is updated! +::: diff --git a/docs/source/installation/versions.rst b/docs/source/installation/versions.rst deleted file mode 100644 index 6bad75c0df..0000000000 --- a/docs/source/installation/versions.rst +++ /dev/null @@ -1,49 +0,0 @@ -Differences between Manim Versions -================================== - -While originally a single library, there are now three main versions of manim, -each with their own advantages, disadvantages, and ideal use cases. -It is important to understand these differences in order to select the best version -for your use case and avoid confusion arising from version mismatches. - -A brief history of Manim -************************ - -Manim was originally created by Grant Sanderson as a personal project and for use in his YouTube channel, -`3Blue1Brown `_. As his channel gained popularity, -many grew to like the style of his animations and wanted to use manim for their own projects. -However, as manim was only intended for personal use, -it was very difficult for other users to install and use it. - -In late 2019, Grant started working on faster OpenGL rendering in a new branch, -known as the shaders branch. In mid-2020, a group of developers forked it into what is now the community edition; -this is the version documented on this website. -In early 2021, Grant merged the shaders branch back into master, making it the default branch in his repository. -The old version is still available as the branch ``cairo-backend``. - -The three versions of Manim -*************************** - -There are currently three main versions of manim. They are as follows: - -- **ManimCE**: The community edition of manim. This is the version documented by this website, and is named `manim `_ on pip. -- `ManimGL `_: The current version of manim that is used by 3blue1brown. It supports OpenGL rendering and interactivity, and is named ``manimgl`` on pip. You can find documentation for it `here `_. -- `ManimCairo `_: The old version of manim originally used by 3blue1brown. It is not available on pip. - -Which version to use -******************** -We recommend using the community edition for most purposes, as it has been developed to be more stable, -better tested, quicker to respond to community contributions, and easier for beginners to use. -It also has partial experimental OpenGL support and should have full support shortly (as of April 2021). - -If you would like to use a version with full OpenGL support or render recent 3Blue1Brown videos (2020 onwards), you should use ManimGL. - -If you would like to render old 3Blue1Brown projects (2019 and before), you should use ManimCairo. - -Notes on installation, documentation, and use -********************************************* -If you are a beginner, it is very important that you only use the documentation for your desired version. -Trying to install or learn manim using documentation or guides made for different versions will likely fail and only lead to more confusion. -As many tutorials and guides on the internet are outdated, we do not recommend you follow them. -You should only read tutorials and documentation for other versions once you are aware of the differences between them -and know how to adapt code for your desired version. diff --git a/docs/source/installation/windows.rst b/docs/source/installation/windows.rst deleted file mode 100644 index 37f6c822af..0000000000 --- a/docs/source/installation/windows.rst +++ /dev/null @@ -1,150 +0,0 @@ -Windows -======= - -The easiest way of installing Manim and its dependencies is by using a -package manager like `Chocolatey `__ -or `Scoop `__. If you are not afraid of editing -your System's ``PATH``, a manual installation is also possible. -In fact, if you already have an existing Python -installation (3.7-3.10), it might be the easiest way to get -everything up and running. - -If you choose to use one of the package managers, please follow -their installation instructions -(`for Chocolatey `__, -`for Scoop `__) -to make one of them available on your system. - - -Required Dependencies ---------------------- - -Manim requires a recent version of Python (3.7–3.10) and ``ffmpeg`` -in order to work. - -Chocolatey -********** - -Manim can be installed via Chocolatey simply by running: - -.. code-block:: powershell - - choco install manimce - -That's it, no further steps required. You can continue with installing -the :ref:`optional dependencies ` below. - -Scoop -***** - -While there is no recipe for installing Manim with Scoop directly, -you can install all requirements by running: - -.. code-block:: powershell - - scoop install python ffmpeg - -and then Manim can be installed by running: - -.. code-block:: powershell - - python -m pip install manim - -Manim should now be installed on your system. Continue reading -the :ref:`optional dependencies ` section -below. - -Manual Installation -******************* - -As mentioned above, Manim needs a reasonably recent version of -Python 3 (3.7–3.10) and FFmpeg. - -**Python:** Head over to https://www.python.org, download an installer -for Python (3.7–3.10), and follow its instructions to get Python -installed on your system. - -.. note:: - - We have received reports of problems caused by using the version of - Python that can be installed from the Windows Store. At this point, - we recommend staying away from the Windows Store version. Instead, - install Python directly from the - `official website `__. - -**FFmpeg:** In order to install FFmpeg, you can get a -pre-compiled and ready-to-use version from one of the resources -linked at https://ffmpeg.org/download.html#build-windows, such as -`the version available here -`__ -(recommended), or if you know exactly what you are doing -you can alternatively get the source code -from https://ffmpeg.org/download.html and compile it yourself. - - -After downloading the pre-compiled archive, -`unzip it `__ and, if you like, move the -extracted directory to some more permanent place (e.g., -``C:\Program Files\``). Next, edit the ``PATH`` environment variable: -first, visit ``Control Panel`` > ``System`` > ``System settings`` > -``Environment Variables``, then add the full path to the ``bin`` -directory inside of the (moved) ffmpeg directory to the -``PATH`` variable. Finally, save your changes and exit. - -If you now open a new command line prompt (or PowerShell) and -run ``ffmpeg``, the command should be recognized. - -At this point, you have all the required dependencies and can now -install Manim via - -.. code-block:: powershell - - python -m pip install manim - - -.. _win-optional-dependencies: - -Optional Dependencies ---------------------- - -In order to make use of Manim's interface to LaTeX to, for example, render -equations, LaTeX has to be installed as well. Note that this is an optional -dependency: if you don't intend to use LaTeX, you don't have to install it. - -For Windows, the recommended LaTeX distribution is -`MiKTeX `__. You can install it by using the -installer from the linked MiKTeX site, or by using the package manager -of your choice (Chocolatey: ``choco install miktex.install``, -Scoop: ``scoop install latex``). - -If you are concerned about disk space, there are some alternative, -smaller distributions of LaTeX. - -**Using Chocolatey:** If you used Chocolatey to install manim or are already -a chocolatey user, then you can simply run ``choco install manim-latex``. It -is a dedicated package for Manim based on TinyTeX which contains all the -required packages that Manim interacts with. - -**Manual Installation:** -You can also use `TinyTeX `__ (Chocolatey: ``choco install tinytex``, -Scoop: first ``scoop bucket add r-bucket https://github.com/cderv/r-bucket.git``, -then ``scoop install tinytex``) alternative installation instructions can be found at their website. -Keep in mind that you will have to manage the LaTeX packages installed on your system yourself via ``tlmgr``. -Therefore we only recommend this option if you know what you are doing. - -The full list of LaTeX packages which Manim interacts with in some way -(a subset might be sufficient for your particular application) are:: - - amsmath babel-english cbfonts-fd cm-super ctex doublestroke dvisvgm everysel - fontspec frcursive fundus-calligra gnu-freefont jknapltx latex-bin - mathastext microtype ms physics preview ragged2e relsize rsfs - setspace standalone tipa wasy wasysym xcolor xetex xkeyval - - - -Working with Manim ------------------- - -At this point, you should have a working installation of Manim, head -over to our :doc:`Quickstart Tutorial <../tutorials/quickstart>` to learn -how to make your own *Manimations*! diff --git a/docs/source/plugins.rst b/docs/source/plugins.rst index 2bc3c2743d..a38123693c 100644 --- a/docs/source/plugins.rst +++ b/docs/source/plugins.rst @@ -81,6 +81,7 @@ For specifying multiple plugins, comma-separated values must be used. Creating Plugins **************** + Plugins are intended to extend Manim's core functionality. If you aren't sure whether a feature should be included in Manim's core, feel free to ask over on the `Discord server `_. Visit @@ -95,40 +96,38 @@ The only requirement of manim plugins is that they specify an entry point with the group, ``"manim.plugins"``. This allows Manim to discover plugins available in the user's environment. Everything regarding the plugin's directory structure, build system, and naming are completely up to your -discretion as an author. The aforementioned template plugin is only a model -using Poetry since this is the build system Manim uses. The plugin's `entry -point `_ can be -specified in poetry as: - -.. code-block:: toml - - [tool.poetry.plugins."manim.plugins"] - "name" = "object_reference" - -Here ``name`` is the name of the module of the plugin. +discretion as an author. -Here ``object_reference`` can point to either a function in a module or a module -itself. For example, +The standard way to specify an entry point (see +`the Python packaging guide `__ +for details) is to include the following in your ``pyproject.toml``: .. code-block:: toml - [tool.poetry.plugins."manim.plugins"] - "manim_plugintemplate" = "manim_plugintemplate" + [project.entry-points."manim.plugins"] + "name" = "object_reference" -Here a module is used as ``object_reference``, and when this plugin is enabled, -Manim will look for ``__all__`` keyword defined in ``manim_plugintemplate`` and -everything as a global variable one by one. +.. versionremoved:: 0.18.1 -If ``object_reference`` is a function, Manim calls the function and expects the -function to return a list of modules or functions that need to be defined globally. + Plugins should be imported explicitly to be usable in user code. The plugin + system will probably be refactored in the future to provide a more structured + interface. -For example, +A note on Renderer Compatibility +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -.. code-block:: toml +Depending on which renderer is currently active, custom mobjects +created in your plugin might want to behave differently as the +corresponding mobject base classes are (unfortunately) not fully +compatible. - [tool.poetry.plugins."manim.plugins"] - "manim_plugintemplate" = "manim_awesomeplugin.imports:setup_things" +The currently active renderer can be queried by checking the value +of ``manim.config.renderer``. All possible renderer types are given +by :class:`.constants.RendererType`. The module :mod:`.manim.mobject.utils` +contains utility functions that return the base class for the currently +active renderer. -Here, Manim will call the function ``setup_things`` defined in -``manim_awesomeplugin.imports`` and calls that. It returns a list of function or -modules which will be imported globally. +A simple form of renderer compatibility (by hot-swapping the class +inheritance chain) for Mobjects directly inheriting from +:class:`.Mobject` or :class:`.VMobject` can be achieved by using the +:class:`.mobject.opengl.opengl_compatibility.ConvertToOpenGL` metaclass. diff --git a/docs/source/reference.rst b/docs/source/reference.rst index dec23a6857..5352f83223 100644 --- a/docs/source/reference.rst +++ b/docs/source/reference.rst @@ -3,7 +3,7 @@ Reference Manual This reference manual details modules, functions, and variables included in Manim, describing what they are and what they do. For learning how to use -Manim, see :doc:`tutorials`. For a list of changes since the last release, see +Manim, see :doc:`tutorials/index`. For a list of changes since the last release, see the :doc:`changelog`. .. warning:: The pages linked to here are currently a work in progress. @@ -26,6 +26,7 @@ Animations manim.animation.numbers manim.animation.rotation manim.animation.specialized + manim.animation.speedmodifier manim.animation.transform manim.animation.transform_matching_parts manim.animation.updaters.mobject_update_utils diff --git a/docs/source/reference_index/animations.rst b/docs/source/reference_index/animations.rst index 2afb09180b..a25c61fdd5 100644 --- a/docs/source/reference_index/animations.rst +++ b/docs/source/reference_index/animations.rst @@ -17,6 +17,7 @@ Animations ~animation.numbers ~animation.rotation ~animation.specialized + ~animation.speedmodifier ~animation.transform ~animation.transform_matching_parts ~animation.updaters diff --git a/docs/source/reference_index/mobjects.rst b/docs/source/reference_index/mobjects.rst index cd0f0b72f7..a736738e17 100644 --- a/docs/source/reference_index/mobjects.rst +++ b/docs/source/reference_index/mobjects.rst @@ -18,5 +18,6 @@ Mobjects ~mobject.text ~mobject.three_d ~mobject.types + ~mobject.utils ~mobject.value_tracker ~mobject.vector_field diff --git a/docs/source/reference_index/utilities_misc.rst b/docs/source/reference_index/utilities_misc.rst index 862a0930e0..874a20ef86 100644 --- a/docs/source/reference_index/utilities_misc.rst +++ b/docs/source/reference_index/utilities_misc.rst @@ -9,22 +9,26 @@ Module Index .. autosummary:: :toctree: ../reference - constants ~utils.bezier + cli ~utils.color ~utils.commands ~utils.config_ops - ~utils.deprecation + constants ~utils.debug + ~utils.deprecation + ~utils.docbuild ~utils.hashing - ~utils.ipython_magic ~utils.images + ~utils.ipython_magic ~utils.iterables ~utils.paths ~utils.rate_functions ~utils.simple_functions ~utils.sounds ~utils.space_ops + ~utils.testing ~utils.tex - ~utils.tex_templates ~utils.tex_file_writing + ~utils.tex_templates + typing diff --git a/docs/source/reporting_bugs.rst b/docs/source/reporting_bugs.rst deleted file mode 100644 index f9c21804bf..0000000000 --- a/docs/source/reporting_bugs.rst +++ /dev/null @@ -1,37 +0,0 @@ -Reporting bugs -=============== - -One of the best ways of contributing to Manim is by reporting bugs. If you -have encountered something that you believe is a bug, please follow these -steps: - -1. First of all, make sure you are running the latest version of manim. If - not, update your version and try again. - -2. Search for other users who may have had similar issues in the - past. Search the repository's `issues page `_ (don't forget to search closed - issues), bring it up on our `Discord server `_, use sites like StackOverflow, and exercise - your best Google practices. If you can't find anything helpful, then go to - the next step. - -3. Can reproduce the issue, i.e. that you have some code that - illustrates the bug **every time** (or at least most of the time) it is - executed. - -4. Clarify what behavior you expected, and how the actual behavior - differs from your expectation. - -5. Gather information about your environment, such as your - operating system, python version, and any stack traces that the code may - have generated (if applicable). - -4. Please open an issue only after you have gathered this information. When - submitting an issue, make sure to follow the template (this is the default - text you are shown when first opening the 'New Issue' page). A community - member will (hopefully) respond and start a conversation to address the - issue. - -7. Please give the community a reasonable amount of time before asking again, - or insisting on your issue. Keep in mind that everyone is a volunteer. If - you wait for a reasonable amount of time and you receive no response, feel - free to ask again. diff --git a/docs/source/tutorials.rst b/docs/source/tutorials.rst deleted file mode 100644 index c2407b8afd..0000000000 --- a/docs/source/tutorials.rst +++ /dev/null @@ -1,12 +0,0 @@ -Tutorials -============ - -.. toctree:: - :caption: Table of Contents - :maxdepth: 2 - - tutorials/quickstart - tutorials/building_blocks - tutorials/a_deeper_look - tutorials/configuration - tutorials/using_text diff --git a/docs/source/tutorials/building_blocks.rst b/docs/source/tutorials/building_blocks.rst index f38aedf024..a01874535e 100644 --- a/docs/source/tutorials/building_blocks.rst +++ b/docs/source/tutorials/building_blocks.rst @@ -13,7 +13,7 @@ concepts is implemented in manim as a separate class: the :class:`.Mobject`, :class:`.Animation`, and :class:`.Scene` classes. .. note:: It is recommended that you read the tutorials :doc:`quickstart` and - :doc:`a_deeper_look` before reading this page. + :doc:`output_and_config` before reading this page. ******** @@ -376,13 +376,13 @@ and :meth:`~.Mobject.get_start`. Here is an example of some important coordinate class MobjectExample(Scene): def construct(self): - p1= [-1,-1,0] - p2= [1,-1,0] - p3= [1,1,0] - p4= [-1,1,0] - a = Line(p1,p2).append_points(Line(p2,p3).points).append_points(Line(p3,p4).points) - point_start= a.get_start() - point_end = a.get_end() + p1 = [-1,-1, 0] + p2 = [ 1,-1, 0] + p3 = [ 1, 1, 0] + p4 = [-1, 1, 0] + a = Line(p1,p2).append_points(Line(p2,p3).points).append_points(Line(p3,p4).points) + point_start = a.get_start() + point_end = a.get_end() point_center = a.get_center() self.add(Text(f"a.get_start() = {np.round(point_start,2).tolist()}", font_size=24).to_edge(UR).set_color(YELLOW)) self.add(Text(f"a.get_end() = {np.round(point_end,2).tolist()}", font_size=24).next_to(self.mobjects[-1],DOWN).set_color(RED)) @@ -425,8 +425,8 @@ function of numpy: self.camera.background_color = WHITE m1a = Square().set_color(RED).shift(LEFT) m1b = Circle().set_color(RED).shift(LEFT) - m2a= Square().set_color(BLUE).shift(RIGHT) - m2b= Circle().set_color(BLUE).shift(RIGHT) + m2a = Square().set_color(BLUE).shift(RIGHT) + m2b = Circle().set_color(BLUE).shift(RIGHT) points = m2a.points points = np.roll(points, int(len(points)/4), axis=0) diff --git a/docs/source/tutorials/index.rst b/docs/source/tutorials/index.rst new file mode 100644 index 0000000000..25750d4b17 --- /dev/null +++ b/docs/source/tutorials/index.rst @@ -0,0 +1,10 @@ +Tutorials +========= + +.. toctree:: + :caption: Table of Contents + :maxdepth: 2 + + quickstart + output_and_config + building_blocks diff --git a/docs/source/tutorials/a_deeper_look.rst b/docs/source/tutorials/output_and_config.rst similarity index 90% rename from docs/source/tutorials/a_deeper_look.rst rename to docs/source/tutorials/output_and_config.rst index d70427e343..af7961d873 100644 --- a/docs/source/tutorials/a_deeper_look.rst +++ b/docs/source/tutorials/output_and_config.rst @@ -1,5 +1,5 @@ -A deeper look -============= +Manim's Output Settings +======================= This document will focus on understanding manim's output files and some of the main command-line flags available. @@ -276,24 +276,28 @@ When executing the command manim -pql scene.py SquareToCircle -it was necessary to specify which ``Scene`` class to render. This is because a -single file can contain more than one ``Scene`` class. If your file contains -multiple ``Scene`` classes, and you want to render them all, you can use the -``-a`` flag. +it specifies the scene to render. This is not necessary now. When a single +file contains only one ``Scene`` class, it will just render the ``Scene`` +class. When a single file contains more than one ``Scene`` class, manim will +let you choose a ``Scene`` class. If your file contains multiple ``Scene`` +classes, and you want to render them all, you can use the ``-a`` flag. -As discussed previously, the ``-ql`` specifies low render quality. This does -not look very good, but is very useful for rapid prototyping and testing. The -other options that specify render quality are ``-qm``, ``-qh``, and ``-qk`` for -medium, high, and 4k quality, respectively. +As discussed previously, the ``-ql`` specifies low render quality (854x480 +15FPS). This does not look very good, but is very useful for rapid +prototyping and testing. The other options that specify render quality are +``-qm``, ``-qh``, ``-qp`` and ``-qk`` for medium (1280x720 30FPS), high +(1920x1080 60FPS), 2k (2560x1440 60FPS) and 4k quality (3840x2160 60FPS), +respectively. The ``-p`` flag plays the animation once it is rendered. If you want to open the file browser at the location of the animation instead of playing it, you can use the ``-f`` flag. You can also omit these two flags. Finally, by default manim will output .mp4 files. If you want your animations -in .gif format instead, use the ``-i`` flag. The output files will be in the -same folder as the .mp4 files, and with the same name, but a different file -extension. +in .gif format instead, use the ``--format gif`` flag. The output files will +be in the same folder as the .mp4 files, and with the same name, but a +different file extension. -This was a quick review of some of the most frequent command-line flags. For a -thorough review of all flags available, see :doc:`configuration`. +This was a quick review of some of the most frequent command-line flags. +For a thorough review of all flags available, see the :doc:`thematic guide on +Manim's configuration system `. diff --git a/docs/source/tutorials/quickstart.rst b/docs/source/tutorials/quickstart.rst index 24e257608b..6f419aa029 100644 --- a/docs/source/tutorials/quickstart.rst +++ b/docs/source/tutorials/quickstart.rst @@ -3,12 +3,22 @@ Quickstart ========== .. note:: - Before proceeding, install Manim and make sure it's running properly by - following the steps in :doc:`../installation`. For - information on using Manim with Jupyterlab or Jupyter notebook, go to the - documentation for the - :meth:`IPython magic command `, - ``%%manim``. + + Before proceeding, install Manim and make sure it is running properly by + following the steps in :doc:`../installation`. For + information on using Manim with Jupyterlab or Jupyter notebook, go to the + documentation for the + :meth:`IPython magic command `, + ``%%manim``. + + +.. important:: + + If you installed Manim in the recommended way, using the + Python management tool ``uv``, then you either need to make sure the corresponding + virtual environment is activated (follow the instructions printed on running ``uv venv``), + or you need to remember to prefix the ``manim`` command in the console with ``uv run``; + that is, ``uv run manim ...``. Overview ******** @@ -28,45 +38,38 @@ use to modify ``Mobject``\s. Starting a new project ********************** -Start by creating a new folder. For the purposes of this guide, name the folder ``project``: - -.. code-block:: bash +Start by creating a new folder:: - project/ + manim init project my-project --default -This folder is the root folder for your project. It contains all the files that Manim needs to function, +The ``my-project`` folder is the root folder for your project. It contains all the files that Manim needs to function, as well as any output that your project produces. Animating a circle ****************** -1. Open a text editor, such as Notepad. Copy the following code snippet into the window: +1. Open a text editor, such as Notepad. Open the file ``main.py`` in the ``my-project`` folder. + It should look something like this: -.. code-block:: python - - from manim import * + .. code-block:: python + from manim import * - class CreateCircle(Scene): - def construct(self): - circle = Circle() # create a circle - circle.set_fill(PINK, opacity=0.5) # set the color and transparency - self.play(Create(circle)) # show the circle on screen - -2. Save the code snippet into your project folder with the name ``scene.py``. -.. code-block:: bash + class CreateCircle(Scene): + def construct(self): + circle = Circle() # create a circle + circle.set_fill(PINK, opacity=0.5) # set the color and transparency + self.play(Create(circle)) # show the circle on screen - project/ - └─scene.py -3. Open the command line, navigate to your project folder, and execute -the following command: +2. Open the command line, navigate to your project folder, and execute + the following command: -.. code-block:: bash + .. code-block:: bash - manim -pql scene.py CreateCircle + manim -pql main.py CreateCircle Manim will output rendering information, then create an MP4 file. Your default movie player will play the MP4 file, displaying the following animation. @@ -86,8 +89,8 @@ You just wrote your first Manim scene from scratch. If you get an error message instead, you do not see a video, or if the video output does not look like the preceding animation, it is likely that Manim has not been -installed correctly. Please refer to the :doc:`../installation/troubleshooting` -page for more information. +installed correctly. Please refer to our :doc:`FAQ section ` +for help with the most common issues. *********** @@ -113,7 +116,7 @@ Now let's look at the next two lines: class CreateCircle(Scene): def construct(self): - ... + [...] Most of the time, the code for scripting an animation is entirely contained within the :meth:`~.Scene.construct` method of a :class:`.Scene` class. @@ -268,11 +271,9 @@ and animating those method calls with ``.animate``. self.play(Create(square)) # show the square on screen self.play(square.animate.rotate(PI / 4)) # rotate the square + self.play(Transform(square, circle)) # transform the square into a circle self.play( - ReplacementTransform(square, circle) - ) # transform the square into a circle - self.play( - circle.animate.set_fill(PINK, opacity=0.5) + square.animate.set_fill(PINK, opacity=0.5) ) # color the circle on screen 2. Render ``AnimatedSquareToCircle`` by running the following command in the command line: @@ -293,8 +294,8 @@ The following animation will render: self.play(Create(square)) # show the square on screen self.play(square.animate.rotate(PI / 4)) # rotate the square - self.play(ReplacementTransform(square, circle)) # transform the square into a circle - self.play(circle.animate.set_fill(PINK, opacity=0.5)) # color the circle on screen + self.play(Transform(square, circle)) # transform the square into a circle + self.play(square.animate.set_fill(PINK, opacity=0.5)) # color the circle on screen The first ``self.play`` creates the square. The second animates rotating it 45 degrees. The third transforms the square into a circle, and the last colors the circle pink. @@ -342,12 +343,61 @@ the corners of the square appear to contract slightly as they move into the posi for the first square to transform into the second one. In ``DifferentRotations``, the difference between ``.animate``'s interpretation of rotation and the -``Rotate`` method is far more apparent. The starting and ending states of a ``Mobject`` rotated 360 degrees +``Rotate`` method is far more apparent. The starting and ending states of a ``Mobject`` rotated 180 degrees are the same, so ``.animate`` tries to interpolate two identical objects and the result is the left square. If you find that your own usage of ``.animate`` is causing similar unwanted behavior, consider using conventional animation methods like the right square, which uses ``Rotate``. +``Transform`` vs ``ReplacementTransform`` +***************************************** +The difference between ``Transform`` and ``ReplacementTransform`` is that ``Transform(mob1, mob2)`` transforms the points +(as well as other attributes like color) of ``mob1`` into the points/attributes of ``mob2``. + +``ReplacementTransform(mob1, mob2)`` on the other hand literally replaces ``mob1`` on the scene with ``mob2``. + +The use of ``ReplacementTransform`` or ``Transform`` is mostly up to personal preference. They can be used to accomplish the same effect, as shown below. + +.. code-block:: python + + class TwoTransforms(Scene): + def transform(self): + a = Circle() + b = Square() + c = Triangle() + self.play(Transform(a, b)) + self.play(Transform(a, c)) + self.play(FadeOut(a)) + + def replacement_transform(self): + a = Circle() + b = Square() + c = Triangle() + self.play(ReplacementTransform(a, b)) + self.play(ReplacementTransform(b, c)) + self.play(FadeOut(c)) + + def construct(self): + self.transform() + self.wait(0.5) # wait for 0.5 seconds + self.replacement_transform() + + +However, in some cases it is more beneficial to use ``Transform``, like when you are transforming several mobjects one after the other. +The code below avoids having to keep a reference to the last mobject that was transformed. + +.. manim:: TransformCycle + + class TransformCycle(Scene): + def construct(self): + a = Circle() + t1 = Square() + t2 = Triangle() + self.add(a) + self.wait() + for t in [t1,t2]: + self.play(Transform(a,t)) + ************ You're done! ************ @@ -355,7 +405,7 @@ You're done! With a working installation of Manim and this sample project under your belt, you're ready to start creating animations of your own. To learn more about what Manim is doing under the hood, move on to the next tutorial: -:doc:`a_deeper_look`. For an overview of +:doc:`output_and_config`. For an overview of Manim's features, as well as its configuration and other settings, check out the -other :doc:`../tutorials`. For a list of all available features, refer to the +other :doc:`Tutorials <../tutorials/index>`. For a list of all available features, refer to the :doc:`../reference` page. diff --git a/docs/source/tutorials_guides.rst b/docs/source/tutorials_guides.rst new file mode 100644 index 0000000000..05b318230b --- /dev/null +++ b/docs/source/tutorials_guides.rst @@ -0,0 +1,10 @@ +Tutorials & Guides +================== + +.. toctree:: + :caption: Table of Contents + :maxdepth: 2 + + tutorials/index + guides/index + faq/index diff --git a/example_scenes/advanced_tex_fonts.py b/example_scenes/advanced_tex_fonts.py index 63edb06039..d8d7486ff9 100644 --- a/example_scenes/advanced_tex_fonts.py +++ b/example_scenes/advanced_tex_fonts.py @@ -23,7 +23,8 @@ def FrenchCursive(*tex_strings, **kwargs): class TexFontTemplateManual(Scene): """An example scene that uses a manually defined TexTemplate() object to create - LaTeX output in French Cursive font""" + LaTeX output in French Cursive font + """ def construct(self): self.add(Tex("Tex Font Example").to_edge(UL)) diff --git a/example_scenes/basic.py b/example_scenes/basic.py index f7257ab8f7..6e8c866f49 100644 --- a/example_scenes/basic.py +++ b/example_scenes/basic.py @@ -153,7 +153,7 @@ def construct(self): ], color=PURPLE_B, fill_opacity=1, - stroke_width=0 + stroke_width=0, ).shift(UP + 2 * RIGHT) shapes = VGroup(triangle, square, circle, pentagon, pi) self.play(SpiralIn(shapes, fade_in_fraction=0.9)) @@ -161,4 +161,19 @@ def construct(self): self.play(FadeOut(shapes)) +Triangle.set_default(stroke_width=20) + + +class LineJoints(Scene): + def construct(self): + t1 = Triangle() + t2 = Triangle(joint_type=LineJointType.ROUND) + t3 = Triangle(joint_type=LineJointType.BEVEL) + + grp = VGroup(t1, t2, t3).arrange(RIGHT) + grp.set(width=config.frame_width - 1) + + self.add(grp) + + # See many more examples at https://docs.manim.community/en/stable/examples.html diff --git a/example_scenes/opengl.py b/example_scenes/opengl.py index 729f5a0eb7..baa59899cf 100644 --- a/example_scenes/opengl.py +++ b/example_scenes/opengl.py @@ -1,9 +1,8 @@ -import os from pathlib import Path import manim.utils.opengl as opengl from manim import * -from manim.opengl import * # type: ignore +from manim.opengl import * # Copied from https://3b1b.github.io/manim/getting_started/example_scenes.html#surfaceexample. # Lines that do not yet work with the Community Version are commented. @@ -407,7 +406,7 @@ def construct(self): self.play(Create(square)) self.wait() - # This opens an iPython termnial where you can keep writing + # This opens an iPython terminal where you can keep writing # lines as if they were part of this construct method. # In particular, 'square', 'circle' and 'self' will all be # part of the local namespace in that terminal. @@ -462,7 +461,7 @@ def construct(self): # in whatever you've set as the image directory in # the custom_config.yml file - script_location = Path(os.path.realpath(__file__)).parent + script_location = Path(__file__).resolve().parent day_texture = ( script_location / "assets" / "1280px-Whole_world_-_land_and_oceans.jpg" ) diff --git a/manim/__init__.py b/manim/__init__.py index 2ddf5ac301..a4034ed134 100644 --- a/manim/__init__.py +++ b/manim/__init__.py @@ -1,37 +1,22 @@ #!/usr/bin/env python - - from __future__ import annotations -import pkg_resources +from importlib.metadata import version -__version__: str = pkg_resources.get_distribution(__name__).version +__version__ = version(__name__) -import sys +# isort: off # Importing the config module should be the first thing we do, since other # modules depend on the global config dict for initialization. from ._config import * -# Workaround to set the renderer passed via CLI args *before* importing -# Manim's classes (as long as the metaclass approach for switching -# between OpenGL and cairo rendering is in place, classes depend -# on the value of config.renderer). -for i, arg in enumerate(sys.argv): - if arg.startswith("--renderer"): - if "=" in arg: - _, parsed_renderer = arg.split("=") - else: - parsed_renderer = sys.argv[i + 1] - config.renderer = parsed_renderer - elif arg == "--use_opengl_renderer": - config.renderer = "opengl" - elif arg == "--use_webgl_renderer": - config.renderer = "webgl" - # many scripts depend on this -> has to be loaded first -from .utils.commands import * # isort:skip +from .utils.commands import * + +# isort: on +import numpy as np from .animation.animation import * from .animation.changing import * @@ -44,6 +29,7 @@ from .animation.numbers import * from .animation.rotation import * from .animation.specialized import * +from .animation.speedmodifier import * from .animation.transform import * from .animation.transform_matching_parts import * from .animation.updaters.mobject_update_utils import * @@ -57,6 +43,7 @@ from .mobject.frame import * from .mobject.geometry.arc import * from .mobject.geometry.boolean_ops import * +from .mobject.geometry.labeled import * from .mobject.geometry.line import * from .mobject.geometry.polygram import * from .mobject.geometry.shape_matchers import * diff --git a/manim/__main__.py b/manim/__main__.py index 9905185c09..572053bf08 100644 --- a/manim/__main__.py +++ b/manim/__main__.py @@ -1,52 +1,100 @@ from __future__ import annotations -import sys - import click -from click_default_group import DefaultGroup +import cloup + +from manim import __version__ +from manim._config import cli_ctx_settings, console +from manim.cli.cfg.group import cfg +from manim.cli.checkhealth.commands import checkhealth +from manim.cli.default_group import DefaultGroup +from manim.cli.init.commands import init +from manim.cli.plugins.commands import plugins +from manim.cli.render.commands import render +from manim.constants import EPILOG -from . import __version__, console -from .cli.cfg.group import cfg -from .cli.init.commands import init -from .cli.new.group import new -from .cli.plugins.commands import plugins -from .cli.render.commands import render -from .constants import EPILOG +def show_splash(ctx: click.Context, param: click.Option, value: str | None) -> None: + """When giving a value by console, show an initial message with the Manim + version before executing any other command: ``Manim Community vA.B.C``. -def exit_early(ctx, param, value): + Parameters + ---------- + ctx + The Click context. + param + A Click option. + value + A string value given by console, or None. + """ if value: - sys.exit() + console.print(f"Manim Community [green]v{__version__}[/green]\n") + +def print_version_and_exit( + ctx: click.Context, param: click.Option, value: str | None +) -> None: + """Same as :func:`show_splash`, but also exit when giving a value by + console. -console.print(f"Manim Community [green]v{__version__}[/green]\n") + Parameters + ---------- + ctx + The Click context. + param + A Click option. + value + A string value given by console, or None. + """ + show_splash(ctx, param, value) + if value: + ctx.exit() -@click.group( +@cloup.group( + context_settings=cli_ctx_settings, cls=DefaultGroup, default="render", no_args_is_help=True, - help="Animation engine for explanatory math videos", - epilog=EPILOG, + help="Animation engine for explanatory math videos.", + epilog="See 'manim ' to read about a specific subcommand.\n\n" + "Note: the subcommand 'manim render' is called if no other subcommand " + "is specified. Run 'manim render --help' if you would like to know what the " + f"'-ql' or '-p' flags do, for example.\n\n{EPILOG}", ) -@click.option( +@cloup.option( "--version", is_flag=True, help="Show version and exit.", - callback=exit_early, + callback=print_version_and_exit, is_eager=True, expose_value=False, ) -@click.pass_context -def main(ctx): - """The entry point for manim.""" +@click.option( + "--show-splash/--hide-splash", + is_flag=True, + default=True, + help="Print splash message with version information.", + callback=show_splash, + is_eager=True, + expose_value=False, +) +@cloup.pass_context +def main(ctx: click.Context) -> None: + """The entry point for Manim. + + Parameters + ---------- + ctx + The Click context. + """ pass +main.add_command(checkhealth) main.add_command(cfg) main.add_command(plugins) main.add_command(init) -main.add_command(new) main.add_command(render) if __name__ == "__main__": diff --git a/manim/_config/__init__.py b/manim/_config/__init__.py index 036f54c188..3eed54b481 100644 --- a/manim/_config/__init__.py +++ b/manim/_config/__init__.py @@ -3,8 +3,11 @@ from __future__ import annotations import logging -from contextlib import _GeneratorContextManager, contextmanager +from collections.abc import Generator +from contextlib import contextmanager +from typing import Any +from .cli_colors import parse_cli_ctx from .logger_utils import make_logger from .utils import ManimConfig, ManimFrame, make_config_parser @@ -15,10 +18,10 @@ "config", "frame", "tempconfig", + "cli_ctx_settings", ] parser = make_config_parser() -logger: logging.Logger # The logger can be accessed from anywhere as manim.logger, or as # logging.getLogger("manim"). The console must be accessed as manim.console. @@ -28,17 +31,20 @@ parser["logger"], parser["CLI"]["verbosity"], ) +cli_ctx_settings = parse_cli_ctx(parser["CLI_CTX"]) # TODO: temporary to have a clean terminal output when working with PIL or matplotlib logging.getLogger("PIL").setLevel(logging.INFO) logging.getLogger("matplotlib").setLevel(logging.INFO) config = ManimConfig().digest_parser(parser) +# TODO: to be used in the future - see PR #620 +# https://github.com/ManimCommunity/manim/pull/620 frame = ManimFrame(config) # This has to go here because it needs access to this module's config @contextmanager -def tempconfig(temp: ManimConfig | dict) -> _GeneratorContextManager: +def tempconfig(temp: ManimConfig | dict[str, Any]) -> Generator[None, None, None]: """Context manager that temporarily modifies the global ``config`` object. Inside the ``with`` statement, the modified config will be used. After @@ -46,7 +52,7 @@ def tempconfig(temp: ManimConfig | dict) -> _GeneratorContextManager: Parameters ---------- - temp : Union[:class:`ManimConfig`, :class:`dict`] + temp Object whose keys will be used to temporarily update the global ``config``. @@ -62,7 +68,6 @@ def tempconfig(temp: ManimConfig | dict) -> _GeneratorContextManager: 8.0 >>> with tempconfig({"frame_height": 100.0}): ... print(config["frame_height"]) - ... 100.0 >>> config["frame_height"] 8.0 diff --git a/manim/_config/cli_colors.py b/manim/_config/cli_colors.py new file mode 100644 index 0000000000..5b1d151bdb --- /dev/null +++ b/manim/_config/cli_colors.py @@ -0,0 +1,58 @@ +from __future__ import annotations + +import configparser +from typing import Any + +from cloup import Context, HelpFormatter, HelpTheme, Style + +__all__ = ["parse_cli_ctx"] + + +def parse_cli_ctx(parser: configparser.SectionProxy) -> dict[str, Any]: + formatter_settings: dict[str, str | int] = { + "indent_increment": int(parser["indent_increment"]), + "width": int(parser["width"]), + "col1_max_width": int(parser["col1_max_width"]), + "col2_min_width": int(parser["col2_min_width"]), + "col_spacing": int(parser["col_spacing"]), + "row_sep": parser["row_sep"] if parser["row_sep"] else None, + } + theme_settings = {} + theme_keys = { + "command_help", + "invoked_command", + "heading", + "constraint", + "section_help", + "col1", + "col2", + "epilog", + } + for k, v in parser.items(): + if k in theme_keys and v: + theme_settings.update({k: Style(v)}) + + formatter = {} + theme = parser["theme"] if parser["theme"] else None + if theme is None: + formatter = HelpFormatter.settings( + theme=HelpTheme(**theme_settings), + **formatter_settings, # type: ignore[arg-type] + ) + elif theme.lower() == "dark": + formatter = HelpFormatter.settings( + theme=HelpTheme.dark().with_(**theme_settings), + **formatter_settings, # type: ignore[arg-type] + ) + elif theme.lower() == "light": + formatter = HelpFormatter.settings( + theme=HelpTheme.light().with_(**theme_settings), + **formatter_settings, # type: ignore[arg-type] + ) + + return Context.settings( + align_option_groups=parser["align_option_groups"].lower() == "true", + align_sections=parser["align_sections"].lower() == "true", + show_constraints=True, + formatter_settings=formatter, + ) diff --git a/manim/_config/default.cfg b/manim/_config/default.cfg index eb48df5cde..9155d28dbd 100644 --- a/manim/_config/default.cfg +++ b/manim/_config/default.cfg @@ -93,18 +93,9 @@ tex_dir = {media_dir}/Tex text_dir = {media_dir}/texts partial_movie_dir = {video_dir}/partial_movie_files/{scene_name} -# --renderer [cairo|opengl|webgl] +# --renderer [cairo|opengl] renderer = cairo -# --use_webgl_renderer -use_webgl_renderer = False - -# --webgl_renderer_path -webgl_renderer_path = - -# --use_opengl_renderer -use_opengl_renderer = False - # --enable_gui enable_gui = False @@ -165,6 +156,36 @@ tex_template = # manim will load that plugin if it specified here. plugins = +# CLI Context/Formatter +# Visit the cloup documentation to understand the formatting options available: +# https://cloup.readthedocs.io/en/latest/index.html#a-simple-example +[CLI_CTX] +# CTX settings +align_option_groups = True +align_sections = True +show_constraints = True + +# Formatter settings +indent_increment = 2 +width = 80 +col1_max_width = 30 +col2_min_width = 35 +col_spacing = 2 +row_sep = + +# Dark/Light, or leave empty +theme = + +# Theme Settings - The following options override the theme colors. +command_help = +invoked_command = +heading = +constraint = +section_help = +col1 = +col2 = +epilog = + # Overrides the default output folders, NOT the output file names. Note that # if the custom_folders flag is present, the Tex and text files will not be put # under media_dir, as is the default. @@ -202,5 +223,5 @@ repr_number = green loglevel = ERROR [jupyter] -media_embed = +media_embed = False media_width = 60%% diff --git a/manim/_config/logger_utils.py b/manim/_config/logger_utils.py index de579dcfef..9205635eef 100644 --- a/manim/_config/logger_utils.py +++ b/manim/_config/logger_utils.py @@ -9,14 +9,13 @@ format. """ + from __future__ import annotations import configparser import copy import json import logging -import os -import sys from typing import TYPE_CHECKING from rich import color, errors @@ -26,7 +25,10 @@ from rich.theme import Theme if TYPE_CHECKING: - from manim._config.utils import ManimConfig + from pathlib import Path + +__all__ = ["make_logger", "parse_theme", "set_file_logger", "JSONFormatter"] + HIGHLIGHTED_KEYWORDS = [ # these keywords are highlighted specially "Played", "animations", @@ -50,17 +52,17 @@ def make_logger( - parser: configparser.ConfigParser, + parser: configparser.SectionProxy, verbosity: str, -) -> tuple[logging.Logger, Console]: +) -> tuple[logging.Logger, Console, Console]: """Make the manim logger and console. Parameters ---------- - parser : :class:`configparser.ConfigParser` + parser A parser containing any .cfg files in use. - verbosity : :class:`str` + verbosity The verbosity level of the logger. Returns @@ -84,30 +86,34 @@ def make_logger( theme = parse_theme(parser) console = Console(theme=theme) - # With rich 9.5.0+ we could pass stderr=True instead - error_console = Console(theme=theme, file=sys.stderr) + error_console = Console(theme=theme, stderr=True) # set the rich handler - RichHandler.KEYWORDS = HIGHLIGHTED_KEYWORDS rich_handler = RichHandler( console=console, show_time=parser.getboolean("log_timestamps"), + keywords=HIGHLIGHTED_KEYWORDS, ) # finally, the logger logger = logging.getLogger("manim") logger.addHandler(rich_handler) logger.setLevel(verbosity) + logger.propagate = False + + if not (libav_logger := logging.getLogger()).hasHandlers(): + libav_logger.addHandler(rich_handler) + libav_logger.setLevel(verbosity) return logger, console, error_console -def parse_theme(parser: configparser.ConfigParser) -> Theme: +def parse_theme(parser: configparser.SectionProxy) -> Theme: """Configure the rich style of logger and console output. Parameters ---------- - parser : :class:`configparser.ConfigParser` + parser A parser containing any .cfg files in use. Returns @@ -142,38 +148,26 @@ def parse_theme(parser: configparser.ConfigParser) -> Theme: return custom_theme -def set_file_logger(config: ManimConfig, verbosity: str) -> None: +def set_file_logger(scene_name: str, module_name: str, log_dir: Path) -> None: """Add a file handler to manim logger. The path to the file is built using ``config.log_dir``. Parameters ---------- - config : :class:`ManimConfig` - The global config, used to determine the log file path. - - verbosity : :class:`str` - The verbosity level of the logger. - - Notes - ----- - Calling this function changes the verbosity of all handlers assigned to - manim logger. - + scene_name + The name of the scene, used in the name of the log file. + module_name + The name of the module, used in the name of the log file. + log_dir + Path to the folder where log files are stored. """ # Note: The log file name will be # _.log, gotten from config. So it # can differ from the real name of the scene. would only # appear if scene name was provided when manim was called. - scene_name_suffix = "".join(config["scene_names"]) - scene_file_name = os.path.basename(config["input_file"]).split(".")[0] - log_file_name = ( - f"{scene_file_name}_{scene_name_suffix}.log" - if scene_name_suffix - else f"{scene_file_name}.log" - ) - log_file_path = config.get_dir("log_dir") / log_file_name - log_file_path.parent.mkdir(parents=True, exist_ok=True) + log_file_name = f"{module_name}_{scene_name}.log" + log_file_path = log_dir / log_file_name file_handler = logging.FileHandler(log_file_path, mode="w") file_handler.setFormatter(JSONFormatter()) @@ -182,9 +176,6 @@ def set_file_logger(config: ManimConfig, verbosity: str) -> None: logger.addHandler(file_handler) logger.info("Log file will be saved in %(logpath)s", {"logpath": log_file_path}) - config.verbosity = verbosity - logger.setLevel(verbosity) - class JSONFormatter(logging.Formatter): """A formatter that outputs logs in a custom JSON format. @@ -193,7 +184,7 @@ class JSONFormatter(logging.Formatter): """ - def format(self, record: dict) -> str: + def format(self, record: logging.LogRecord) -> str: """Format the record in a custom JSON format.""" record_c = copy.deepcopy(record) if record_c.args: diff --git a/manim/_config/utils.py b/manim/_config/utils.py index 823d1ad41b..b453b290e2 100644 --- a/manim/_config/utils.py +++ b/manim/_config/utils.py @@ -6,9 +6,10 @@ (e.g. background color, transparency), and general behavior (e.g. writing a movie vs writing a single frame). -See :doc:`/tutorials/configuration` for an introduction to Manim's configuration system. +See :doc:`/guides/configuration` for an introduction to Manim's configuration system. """ + from __future__ import annotations import argparse @@ -19,17 +20,27 @@ import os import re import sys -import typing -from collections.abc import Mapping, MutableMapping +from collections.abc import Iterable, Iterator, Mapping, MutableMapping from pathlib import Path +from typing import TYPE_CHECKING, Any, ClassVar, NoReturn -import colour import numpy as np -from .. import constants -from ..utils.tex import TexTemplate, TexTemplateFromFile -from ..utils.tex_templates import TexTemplateLibrary -from .logger_utils import set_file_logger +from manim import constants +from manim.constants import RendererType +from manim.utils.color import ManimColor +from manim.utils.tex import TexTemplate + +if TYPE_CHECKING: + from enum import EnumMeta + + from typing_extensions import Self + + from manim.typing import StrPath, Vector3D + +__all__ = ["config_file_paths", "make_config_parser", "ManimConfig", "ManimFrame"] + +logger = logging.getLogger("manim") def config_file_paths() -> list[Path]: @@ -75,7 +86,9 @@ def config_file_paths() -> list[Path]: return [library_wide, user_wide, folder_wide] -def make_config_parser(custom_file: str = None) -> configparser.ConfigParser: +def make_config_parser( + custom_file: StrPath | None = None, +) -> configparser.ConfigParser: """Make a :class:`ConfigParser` object and load any ``.cfg`` files. The user-wide file, if it exists, overrides the library-wide file. The @@ -86,7 +99,7 @@ def make_config_parser(custom_file: str = None) -> configparser.ConfigParser: Parameters ---------- - custom_file : :class:`str` + custom_file Path to a custom config file. If used, the folder-wide file in the relevant directory will be ignored, if it exists. If None, the folder-wide file will be used, if it exists. @@ -109,10 +122,10 @@ def make_config_parser(custom_file: str = None) -> configparser.ConfigParser: # read_file() before calling read() for any optional files." # https://docs.python.org/3/library/configparser.html#configparser.ConfigParser.read parser = configparser.ConfigParser() - with open(library_wide) as file: + with library_wide.open() as file: parser.read_file(file) # necessary file - other_files = [user_wide, custom_file if custom_file else folder_wide] + other_files = [user_wide, Path(custom_file) if custom_file else folder_wide] parser.read(other_files) # optional files return parser @@ -151,12 +164,22 @@ class ManimConfig(MutableMapping): Examples -------- + We use a copy of the global configuration object in the following + examples for the sake of demonstration; you can skip these lines + and just import ``config`` directly if you actually want to modify + the configuration: + + .. code-block:: pycon + + >>> from manim import config as global_config + >>> config = global_config.copy() + Each config option allows for dict syntax and attribute syntax. For example, the following two lines are equivalent, .. code-block:: pycon - >>> from manim import config, WHITE + >>> from manim import WHITE >>> config.background_color = WHITE >>> config["background_color"] = WHITE @@ -225,8 +248,7 @@ class ManimConfig(MutableMapping): config.background_color = RED - class MyScene(Scene): - ... + class MyScene(Scene): ... the background color will be set to RED, regardless of the contents of ``manim.cfg`` or the CLI arguments used when invoking manim. @@ -255,7 +277,6 @@ class MyScene(Scene): "input_file", "media_embed", "media_width", - "webgl_renderer_path", "log_dir", "log_to_file", "max_files_cached", @@ -277,12 +298,11 @@ class MyScene(Scene): "scene_names", "show_in_file_browser", "tex_dir", + "tex_template", "tex_template_file", "text_dir", "upto_animation_number", "renderer", - "use_opengl_renderer", - "use_webgl_renderer", "enable_gui", "gui_location", "use_projection_fill_shaders", @@ -298,32 +318,34 @@ class MyScene(Scene): "write_to_movie", "zero_pad", "force_window", + "no_latex_cleanup", + "preview_command", } def __init__(self) -> None: - self._d = {k: None for k in self._OPTS} + self._d: dict[str, Any | None] = dict.fromkeys(self._OPTS) # behave like a dict - def __iter__(self) -> typing.Iterator[str]: + def __iter__(self) -> Iterator[str]: return iter(self._d) def __len__(self) -> int: return len(self._d) - def __contains__(self, key) -> bool: + def __contains__(self, key: object) -> bool: try: self.__getitem__(key) return True except AttributeError: return False - def __getitem__(self, key) -> typing.Any: + def __getitem__(self, key: str) -> Any: return getattr(self, key) - def __setitem__(self, key: str, val: typing.Any) -> None: + def __setitem__(self, key: str, val: Any) -> None: getattr(ManimConfig, key).fset(self, val) # fset is the property's setter - def update(self, obj: ManimConfig | dict) -> None: + def update(self, obj: ManimConfig | dict[str, Any]) -> None: # type: ignore[override] """Digest the options found in another :class:`ManimConfig` or in a dict. Similar to :meth:`dict.update`, replaces the values of this object with @@ -331,7 +353,7 @@ def update(self, obj: ManimConfig | dict) -> None: Parameters ---------- - obj : Union[:class:`ManimConfig`, :class:`dict`] + obj The object to copy values from. Returns @@ -350,9 +372,10 @@ def update(self, obj: ManimConfig | dict) -> None: :meth:`~ManimConfig.digest_parser` """ - if isinstance(obj, ManimConfig): self._d.update(obj._d) + if obj.tex_template: + self.tex_template = obj.tex_template elif isinstance(obj, dict): # First update the underlying _d, then update other properties @@ -365,14 +388,14 @@ def update(self, obj: ManimConfig | dict) -> None: self[k] = v # don't allow to delete anything - def __delitem__(self, key: str): + def __delitem__(self, key: str) -> NoReturn: raise AttributeError("'ManimConfig' object does not support item deletion") - def __delattr__(self, key: str): + def __delattr__(self, key: str) -> NoReturn: raise AttributeError("'ManimConfig' object does not support item deletion") # copy functions - def copy(self) -> ManimConfig: + def copy(self) -> Self: """Deepcopy the contents of this ManimConfig. Returns @@ -391,13 +414,13 @@ def copy(self) -> ManimConfig: """ return copy.deepcopy(self) - def __copy__(self) -> ManimConfig: + def __copy__(self) -> Self: """See ManimConfig.copy().""" return copy.deepcopy(self) - def __deepcopy__(self, memo: dict[str, typing.Any]) -> ManimConfig: + def __deepcopy__(self, memo: dict[str, Any]) -> Self: """See ManimConfig.copy().""" - c = ManimConfig() + c = type(self)() # Deepcopying the underlying dict is enough because all properties # either read directly from it or compute their value on the fly from # values read directly from it. @@ -405,27 +428,52 @@ def __deepcopy__(self, memo: dict[str, typing.Any]) -> ManimConfig: return c # helper type-checking methods - def _set_from_list(self, key: str, val: typing.Any, values: list) -> None: + def _set_from_list(self, key: str, val: Any, values: list[Any]) -> None: """Set ``key`` to ``val`` if ``val`` is contained in ``values``.""" if val in values: self._d[key] = val else: raise ValueError(f"attempted to set {key} to {val}; must be in {values}") - def _set_boolean(self, key: str | int, val: typing.Any) -> None: + def _set_from_enum(self, key: str, enum_value: Any, enum_class: EnumMeta) -> None: + """Set ``key`` to the enum object with value ``enum_value`` in the given + ``enum_class``. + + Tests:: + + >>> from enum import Enum + >>> class Fruit(Enum): + ... APPLE = 1 + ... BANANA = 2 + ... CANTALOUPE = 3 + >>> test_config = ManimConfig() + >>> test_config._set_from_enum("fruit", 1, Fruit) + >>> test_config._d['fruit'] + + >>> test_config._set_from_enum("fruit", Fruit.BANANA, Fruit) + >>> test_config._d['fruit'] + + >>> test_config._set_from_enum("fruit", 42, Fruit) + Traceback (most recent call last): + ... + ValueError: 42 is not a valid Fruit + """ + self._d[key] = enum_class(enum_value) + + def _set_boolean(self, key: str, val: Any) -> None: """Set ``key`` to ``val`` if ``val`` is Boolean.""" if val in [True, False]: self._d[key] = val else: raise ValueError(f"{key} must be boolean") - def _set_tuple(self, key: str, val: tuple) -> None: + def _set_tuple(self, key: str, val: tuple[Any]) -> None: if isinstance(val, tuple): self._d[key] = val else: raise ValueError(f"{key} must be tuple") - def _set_str(self, key: str, val: typing.Any) -> None: + def _set_str(self, key: str, val: Any) -> None: """Set ``key`` to ``val`` if ``val`` is a string.""" if isinstance(val, str): self._d[key] = val @@ -468,7 +516,7 @@ def __repr__(self) -> str: return rep # builders - def digest_parser(self, parser: configparser.ConfigParser) -> ManimConfig: + def digest_parser(self, parser: configparser.ConfigParser) -> Self: """Process the config options present in a :class:`ConfigParser` object. This method processes arbitrary parsers, not only those read from a @@ -477,7 +525,7 @@ def digest_parser(self, parser: configparser.ConfigParser) -> ManimConfig: Parameters ---------- - parser : :class:`ConfigParser` + parser An object reflecting the contents of one or many ``.cfg`` files. In particular, it may reflect the contents of multiple files that have been parsed in a cascading fashion. @@ -536,14 +584,13 @@ def digest_parser(self, parser: configparser.ConfigParser) -> ManimConfig: "disable_caching_warning", "flush_cache", "custom_folders", - "use_opengl_renderer", - "use_webgl_renderer", "enable_gui", "fullscreen", "use_projection_fill_shaders", "use_projection_stroke_shaders", "enable_wireframe", "force_window", + "no_latex_cleanup", ]: setattr(self, key, parser["CLI"].getboolean(key, fallback=False)) @@ -577,7 +624,6 @@ def digest_parser(self, parser: configparser.ConfigParser) -> ManimConfig: "movie_file_extension", "background_color", "renderer", - "webgl_renderer_path", "window_position", ]: setattr(self, key, parser["CLI"].get(key, fallback="", raw=True)) @@ -596,17 +642,19 @@ def digest_parser(self, parser: configparser.ConfigParser) -> ManimConfig: gui_location = tuple( map(int, re.split(r"[;,\-]", parser["CLI"]["gui_location"])), ) - setattr(self, "gui_location", gui_location) + self.gui_location = gui_location window_size = parser["CLI"][ "window_size" ] # if not "default", get a tuple of the position if window_size != "default": window_size = tuple(map(int, re.split(r"[;,\-]", window_size))) - setattr(self, "window_size", window_size) + self.window_size = window_size # plugins - self.plugins = parser["CLI"].get("plugins", fallback="", raw=True).split(",") + plugins = parser["CLI"].get("plugins", fallback="", raw=True) + plugins = [] if plugins == "" else plugins.split(",") + self.plugins = plugins # the next two must be set AFTER digesting pixel_width and pixel_height self["frame_height"] = parser["CLI"].getfloat("frame_height", 8.0) width = parser["CLI"].getfloat("frame_width", None) @@ -622,7 +670,7 @@ def digest_parser(self, parser: configparser.ConfigParser) -> ManimConfig: val = parser["CLI"].get("progress_bar") if val: - setattr(self, "progress_bar", val) + self.progress_bar = val val = parser["ffmpeg"].get("loglevel") if val: @@ -632,11 +680,11 @@ def digest_parser(self, parser: configparser.ConfigParser) -> ManimConfig: val = parser["jupyter"].getboolean("media_embed") except ValueError: val = None - setattr(self, "media_embed", val) + self.media_embed = val val = parser["jupyter"].get("media_width") if val: - setattr(self, "media_width", val) + self.media_width = val val = parser["CLI"].get("quality", fallback="", raw=True) if val: @@ -644,12 +692,12 @@ def digest_parser(self, parser: configparser.ConfigParser) -> ManimConfig: return self - def digest_args(self, args: argparse.Namespace) -> ManimConfig: + def digest_args(self, args: argparse.Namespace) -> Self: """Process the config options present in CLI arguments. Parameters ---------- - args : :class:`argparse.Namespace` + args An object returned by :func:`.main_utils.parse_args()`. Returns @@ -709,8 +757,6 @@ def digest_args(self, args: argparse.Namespace) -> ManimConfig: "verbosity", "renderer", "background_color", - "use_opengl_renderer", - "use_webgl_renderer", "enable_gui", "fullscreen", "use_projection_fill_shaders", @@ -719,6 +765,8 @@ def digest_args(self, args: argparse.Namespace) -> ManimConfig: "enable_wireframe", "force_window", "dry_run", + "no_latex_cleanup", + "preview_command", ]: if hasattr(args, key): attr = getattr(args, key) @@ -749,7 +797,7 @@ def digest_args(self, args: argparse.Namespace) -> ManimConfig: try: self.upto_animation_number = nflag[1] except Exception: - logging.getLogger("manim").info( + logger.info( f"No end scene number specified in -n option. Rendering from {nflag[0]} onwards...", ) @@ -785,19 +833,19 @@ def digest_args(self, args: argparse.Namespace) -> ManimConfig: # Handle --tex_template if args.tex_template: - self.tex_template = TexTemplateFromFile(tex_filename=args.tex_template) + self.tex_template = TexTemplate.from_file(args.tex_template) - if self.renderer == "opengl" and getattr(args, "write_to_movie") is None: + if self.renderer == RendererType.OPENGL and args.write_to_movie is None: # --write_to_movie was not passed on the command line, so don't generate video. self["write_to_movie"] = False # Handle --gui_location flag. - if getattr(args, "gui_location") is not None: + if args.gui_location is not None: self.gui_location = args.gui_location return self - def digest_file(self, filename: str) -> ManimConfig: + def digest_file(self, filename: StrPath) -> Self: """Process the config options present in a ``.cfg`` file. This method processes a single ``.cfg`` file, whereas @@ -806,7 +854,7 @@ def digest_file(self, filename: str) -> ManimConfig: Parameters ---------- - filename : :class:`str` + filename Path to the ``.cfg`` file. Returns @@ -828,345 +876,443 @@ def digest_file(self, filename: str) -> ManimConfig: multiple times. """ - if not os.path.isfile(filename): + if not Path(filename).is_file(): raise FileNotFoundError( errno.ENOENT, "Error: --config_file could not find a valid config file.", - filename, + str(filename), ) - if filename: - return self.digest_parser(make_config_parser(filename)) + return self.digest_parser(make_config_parser(filename)) # config options are properties - preview = property( - lambda self: self._d["preview"] or self._d["enable_gui"], - lambda self, val: self._set_boolean("preview", val), - doc="Whether to play the rendered movie (-p).", - ) - - show_in_file_browser = property( - lambda self: self._d["show_in_file_browser"], - lambda self, val: self._set_boolean("show_in_file_browser", val), - doc="Whether to show the output file in the file browser (-f).", - ) - - progress_bar = property( - lambda self: self._d["progress_bar"], - lambda self, val: self._set_from_list( - "progress_bar", - val, - ["none", "display", "leave"], - ), - doc="Whether to show progress bars while rendering animations.", - ) @property - def log_to_file(self): + def preview(self) -> bool: + """Whether to play the rendered movie (-p).""" + return self._d["preview"] or self._d["enable_gui"] + + @preview.setter + def preview(self, value: bool) -> None: + self._set_boolean("preview", value) + + @property + def show_in_file_browser(self) -> bool: + """Whether to show the output file in the file browser (-f).""" + return self._d["show_in_file_browser"] + + @show_in_file_browser.setter + def show_in_file_browser(self, value: bool) -> None: + self._set_boolean("show_in_file_browser", value) + + @property + def progress_bar(self) -> str: + """Whether to show progress bars while rendering animations.""" + return self._d["progress_bar"] + + @progress_bar.setter + def progress_bar(self, value: str) -> None: + self._set_from_list("progress_bar", value, ["none", "display", "leave"]) + + @property + def log_to_file(self) -> bool: """Whether to save logs to a file.""" return self._d["log_to_file"] @log_to_file.setter - def log_to_file(self, val: str) -> None: - self._set_boolean("log_to_file", val) - if val: - log_dir = self.get_dir("log_dir") - if not os.path.exists(log_dir): - os.makedirs(log_dir) - set_file_logger(self, self["verbosity"]) - - notify_outdated_version = property( - lambda self: self._d["notify_outdated_version"], - lambda self, val: self._set_boolean("notify_outdated_version", val), - doc="Whether to notify if there is a version update available.", - ) - - write_to_movie = property( - lambda self: self._d["write_to_movie"], - lambda self, val: self._set_boolean("write_to_movie", val), - doc="Whether to render the scene to a movie file (-w).", - ) - - save_last_frame = property( - lambda self: self._d["save_last_frame"], - lambda self, val: self._set_boolean("save_last_frame", val), - doc="Whether to save the last frame of the scene as an image file (-s).", - ) - - write_all = property( - lambda self: self._d["write_all"], - lambda self, val: self._set_boolean("write_all", val), - doc="Whether to render all scenes in the input file (-a).", - ) - - save_pngs = property( - lambda self: self._d["save_pngs"], - lambda self, val: self._set_boolean("save_pngs", val), - doc="Whether to save all frames in the scene as images files (-g).", - ) - - save_as_gif = property( - lambda self: self._d["save_as_gif"], - lambda self, val: self._set_boolean("save_as_gif", val), - doc="Whether to save the rendered scene in .gif format (-i).", - ) - - save_sections = property( - lambda self: self._d["save_sections"], - lambda self, val: self._set_boolean("save_sections", val), - doc="Whether to save single videos for each section in addition to the movie file.", - ) - - enable_wireframe = property( - lambda self: self._d["enable_wireframe"], - lambda self, val: self._set_boolean("enable_wireframe", val), - doc="Enable wireframe debugging mode in opengl.", - ) - - force_window = property( - lambda self: self._d["force_window"], - lambda self, val: self._set_boolean("force_window", val), - doc="Set to force window when using the opengl renderer", - ) - - dry_run = property( - lambda self: self._d["dry_run"], - lambda self, val: self._set_boolean("dry_run", val), - doc="Enable dry_run so that no output files are generated and window is disabled.", - ) - - @property - def verbosity(self): + def log_to_file(self, value: bool) -> None: + self._set_boolean("log_to_file", value) + + @property + def notify_outdated_version(self) -> bool: + """Whether to notify if there is a version update available.""" + return self._d["notify_outdated_version"] + + @notify_outdated_version.setter + def notify_outdated_version(self, value: bool) -> None: + self._set_boolean("notify_outdated_version", value) + + @property + def write_to_movie(self) -> bool: + """Whether to render the scene to a movie file (-w).""" + return self._d["write_to_movie"] + + @write_to_movie.setter + def write_to_movie(self, value: bool) -> None: + self._set_boolean("write_to_movie", value) + + @property + def save_last_frame(self) -> bool: + """Whether to save the last frame of the scene as an image file (-s).""" + return self._d["save_last_frame"] + + @save_last_frame.setter + def save_last_frame(self, value: bool) -> None: + self._set_boolean("save_last_frame", value) + + @property + def write_all(self) -> bool: + """Whether to render all scenes in the input file (-a).""" + return self._d["write_all"] + + @write_all.setter + def write_all(self, value: bool) -> None: + self._set_boolean("write_all", value) + + @property + def save_pngs(self) -> bool: + """Whether to save all frames in the scene as images files (-g).""" + return self._d["save_pngs"] + + @save_pngs.setter + def save_pngs(self, value: bool) -> None: + self._set_boolean("save_pngs", value) + + @property + def save_as_gif(self) -> bool: + """Whether to save the rendered scene in .gif format (-i).""" + return self._d["save_as_gif"] + + @save_as_gif.setter + def save_as_gif(self, value: bool) -> None: + self._set_boolean("save_as_gif", value) + + @property + def save_sections(self) -> bool: + """Whether to save single videos for each section in addition to the movie file.""" + return self._d["save_sections"] + + @save_sections.setter + def save_sections(self, value: bool) -> None: + self._set_boolean("save_sections", value) + + @property + def enable_wireframe(self) -> bool: + """Whether to enable wireframe debugging mode in opengl.""" + return self._d["enable_wireframe"] + + @enable_wireframe.setter + def enable_wireframe(self, value: bool) -> None: + self._set_boolean("enable_wireframe", value) + + @property + def force_window(self) -> bool: + """Whether to force window when using the opengl renderer.""" + return self._d["force_window"] + + @force_window.setter + def force_window(self, value: bool) -> None: + self._set_boolean("force_window", value) + + @property + def no_latex_cleanup(self) -> bool: + """Prevents deletion of .aux, .dvi, and .log files produced by Tex and MathTex.""" + return self._d["no_latex_cleanup"] + + @no_latex_cleanup.setter + def no_latex_cleanup(self, value: bool) -> None: + self._set_boolean("no_latex_cleanup", value) + + @property + def preview_command(self) -> str: + return self._d["preview_command"] + + @preview_command.setter + def preview_command(self, value: str) -> None: + self._set_str("preview_command", value) + + @property + def verbosity(self) -> str: """Logger verbosity; "DEBUG", "INFO", "WARNING", "ERROR", or "CRITICAL" (-v).""" return self._d["verbosity"] @verbosity.setter def verbosity(self, val: str) -> None: - """Verbosity level of the logger.""" self._set_from_list( "verbosity", val, ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"], ) - logging.getLogger("manim").setLevel(val) + logger.setLevel(val) @property - def format(self): + def format(self) -> str: """File format; "png", "gif", "mp4", "webm" or "mov".""" return self._d["format"] @format.setter def format(self, val: str) -> None: - """File format the renderer will output.""" self._set_from_list( "format", val, [None, "png", "gif", "mp4", "mov", "webm"], ) + self.resolve_movie_file_extension(self.transparent) if self.format == "webm": - logging.getLogger("manim").warning( + logger.warning( "Output format set as webm, this can be slower than other formats", ) - ffmpeg_loglevel = property( - lambda self: self._d["ffmpeg_loglevel"], - lambda self, val: self._set_from_list( + @property + def ffmpeg_loglevel(self) -> str: + """Verbosity level of ffmpeg (no flag).""" + return self._d["ffmpeg_loglevel"] + + @ffmpeg_loglevel.setter + def ffmpeg_loglevel(self, val: str) -> None: + self._set_from_list( "ffmpeg_loglevel", val, ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"], - ), - doc="Verbosity level of ffmpeg (no flag).", - ) - - media_embed = property( - lambda self: self._d["media_embed"], - lambda self, val: self._d.__setitem__("media_embed", val), - doc="Embed videos in Jupyter notebook", - ) - - media_width = property( - lambda self: self._d["media_width"], - lambda self, val: self._d.__setitem__("media_width", val), - doc="Media width in Jupyter notebook", - ) - - pixel_width = property( - lambda self: self._d["pixel_width"], - lambda self, val: self._set_pos_number("pixel_width", val, False), - doc="Frame width in pixels (--resolution, -r).", - ) - - pixel_height = property( - lambda self: self._d["pixel_height"], - lambda self, val: self._set_pos_number("pixel_height", val, False), - doc="Frame height in pixels (--resolution, -r).", - ) - - aspect_ratio = property( - lambda self: self._d["pixel_width"] / self._d["pixel_height"], - doc="Aspect ratio (width / height) in pixels (--resolution, -r).", - ) - - frame_height = property( - lambda self: self._d["frame_height"], - lambda self, val: self._d.__setitem__("frame_height", val), - doc="Frame height in logical units (no flag).", - ) - - frame_width = property( - lambda self: self._d["frame_width"], - lambda self, val: self._d.__setitem__("frame_width", val), - doc="Frame width in logical units (no flag).", - ) - - frame_y_radius = property( - lambda self: self._d["frame_height"] / 2, - lambda self, val: ( - self._d.__setitem__("frame_y_radius", val) - or self._d.__setitem__("frame_height", 2 * val) - ), - doc="Half the frame height (no flag).", - ) - - frame_x_radius = property( - lambda self: self._d["frame_width"] / 2, - lambda self, val: ( - self._d.__setitem__("frame_x_radius", val) - or self._d.__setitem__("frame_width", 2 * val) - ), - doc="Half the frame width (no flag).", - ) - - top = property( - lambda self: self.frame_y_radius * constants.UP, - doc="Coordinate at the center top of the frame.", - ) - - bottom = property( - lambda self: self.frame_y_radius * constants.DOWN, - doc="Coordinate at the center bottom of the frame.", - ) - - left_side = property( - lambda self: self.frame_x_radius * constants.LEFT, - doc="Coordinate at the middle left of the frame.", - ) - - right_side = property( - lambda self: self.frame_x_radius * constants.RIGHT, - doc="Coordinate at the middle right of the frame.", - ) - - frame_rate = property( - lambda self: self._d["frame_rate"], - lambda self, val: self._d.__setitem__("frame_rate", val), - doc="Frame rate in frames per second.", - ) - - background_color = property( - lambda self: self._d["background_color"], - lambda self, val: self._d.__setitem__("background_color", colour.Color(val)), - doc="Background color of the scene (-c).", - ) - - from_animation_number = property( - lambda self: self._d["from_animation_number"], - lambda self, val: self._d.__setitem__("from_animation_number", val), - doc="Start rendering animations at this number (-n).", - ) - - upto_animation_number = property( - lambda self: self._d["upto_animation_number"], - lambda self, val: self._set_pos_number("upto_animation_number", val, True), - doc="Stop rendering animations at this nmber. Use -1 to avoid skipping (-n).", - ) - - max_files_cached = property( - lambda self: self._d["max_files_cached"], - lambda self, val: self._set_pos_number("max_files_cached", val, True), - doc="Maximum number of files cached. Use -1 for infinity (no flag).", - ) - - window_monitor = property( - lambda self: self._d["window_monitor"], - lambda self, val: self._set_pos_number("window_monitor", val, True), - doc="The monitor on which the scene will be rendered", - ) - flush_cache = property( - lambda self: self._d["flush_cache"], - lambda self, val: self._set_boolean("flush_cache", val), - doc="Whether to delete all the cached partial movie files.", - ) - - disable_caching = property( - lambda self: self._d["disable_caching"], - lambda self, val: self._set_boolean("disable_caching", val), - doc="Whether to use scene caching.", - ) - - disable_caching_warning = property( - lambda self: self._d["disable_caching_warning"], - lambda self, val: self._set_boolean("disable_caching_warning", val), - doc="Whether a warning is raised if there are too much submobjects to hash.", - ) - - movie_file_extension = property( - lambda self: self._d["movie_file_extension"], - lambda self, val: self._set_from_list( - "movie_file_extension", - val, - [".mp4", ".mov", ".webm"], - ), - doc="Either .mp4, .webm or .mov.", - ) - - background_opacity = property( - lambda self: self._d["background_opacity"], - lambda self, val: self._set_between("background_opacity", val, 0, 1), - doc="A number between 0.0 (fully transparent) and 1.0 (fully opaque).", - ) - - frame_size = property( - lambda self: (self._d["pixel_width"], self._d["pixel_height"]), - lambda self, tup: ( - self._d.__setitem__("pixel_width", tup[0]) - or self._d.__setitem__("pixel_height", tup[1]) - ), - doc="Tuple with (pixel width, pixel height) (no flag).", - ) - - @property - def quality(self): + ) + logging.getLogger("libav").setLevel(self.ffmpeg_loglevel) + + @property + def media_embed(self) -> bool: + """Whether to embed videos in Jupyter notebook.""" + return self._d["media_embed"] + + @media_embed.setter + def media_embed(self, value: bool) -> None: + self._set_boolean("media_embed", value) + + @property + def media_width(self) -> str: + """Media width in Jupyter notebook.""" + return self._d["media_width"] + + @media_width.setter + def media_width(self, value: str) -> None: + self._set_str("media_width", value) + + @property + def pixel_width(self) -> int: + """Frame width in pixels (--resolution, -r).""" + return self._d["pixel_width"] + + @pixel_width.setter + def pixel_width(self, value: int) -> None: + self._set_pos_number("pixel_width", value, False) + + @property + def pixel_height(self) -> int: + """Frame height in pixels (--resolution, -r).""" + return self._d["pixel_height"] + + @pixel_height.setter + def pixel_height(self, value: int) -> None: + self._set_pos_number("pixel_height", value, False) + + @property + def aspect_ratio(self) -> int: + """Aspect ratio (width / height) in pixels (--resolution, -r).""" + return self._d["pixel_width"] / self._d["pixel_height"] + + @property + def frame_height(self) -> float: + """Frame height in logical units (no flag).""" + return self._d["frame_height"] + + @frame_height.setter + def frame_height(self, value: float) -> None: + self._d.__setitem__("frame_height", value) + + @property + def frame_width(self) -> float: + """Frame width in logical units (no flag).""" + return self._d["frame_width"] + + @frame_width.setter + def frame_width(self, value: float) -> None: + self._d.__setitem__("frame_width", value) + + @property + def frame_y_radius(self) -> float: + """Half the frame height (no flag).""" + return self._d["frame_height"] / 2 + + @frame_y_radius.setter + def frame_y_radius(self, value: float) -> None: + self._d.__setitem__("frame_y_radius", value) or self._d.__setitem__( + "frame_height", 2 * value + ) + + @property + def frame_x_radius(self) -> float: + """Half the frame width (no flag).""" + return self._d["frame_width"] / 2 + + @frame_x_radius.setter + def frame_x_radius(self, value: float) -> None: + self._d.__setitem__("frame_x_radius", value) or self._d.__setitem__( + "frame_width", 2 * value + ) + + @property + def top(self) -> Vector3D: + """Coordinate at the center top of the frame.""" + return self.frame_y_radius * constants.UP + + @property + def bottom(self) -> Vector3D: + """Coordinate at the center bottom of the frame.""" + return self.frame_y_radius * constants.DOWN + + @property + def left_side(self) -> Vector3D: + """Coordinate at the middle left of the frame.""" + return self.frame_x_radius * constants.LEFT + + @property + def right_side(self) -> Vector3D: + """Coordinate at the middle right of the frame.""" + return self.frame_x_radius * constants.RIGHT + + @property + def frame_rate(self) -> float: + """Frame rate in frames per second.""" + return self._d["frame_rate"] + + @frame_rate.setter + def frame_rate(self, value: float) -> None: + self._d.__setitem__("frame_rate", value) + + # TODO: This was parsed before maybe add ManimColor(val), but results in circular import + @property + def background_color(self) -> ManimColor: + """Background color of the scene (-c).""" + return self._d["background_color"] + + @background_color.setter + def background_color(self, value: Any) -> None: + self._d.__setitem__("background_color", ManimColor(value)) + + @property + def from_animation_number(self) -> int: + """Start rendering animations at this number (-n).""" + return self._d["from_animation_number"] + + @from_animation_number.setter + def from_animation_number(self, value: int) -> None: + self._d.__setitem__("from_animation_number", value) + + @property + def upto_animation_number(self) -> int: + """Stop rendering animations at this number. Use -1 to avoid skipping (-n).""" + return self._d["upto_animation_number"] + + @upto_animation_number.setter + def upto_animation_number(self, value: int) -> None: + self._set_pos_number("upto_animation_number", value, True) + + @property + def max_files_cached(self) -> int: + """Maximum number of files cached. Use -1 for infinity (no flag).""" + return self._d["max_files_cached"] + + @max_files_cached.setter + def max_files_cached(self, value: int) -> None: + self._set_pos_number("max_files_cached", value, True) + + @property + def window_monitor(self) -> int: + """The monitor on which the scene will be rendered.""" + return self._d["window_monitor"] + + @window_monitor.setter + def window_monitor(self, value: int) -> None: + self._set_pos_number("window_monitor", value, True) + + @property + def flush_cache(self) -> bool: + """Whether to delete all the cached partial movie files.""" + return self._d["flush_cache"] + + @flush_cache.setter + def flush_cache(self, value: bool) -> None: + self._set_boolean("flush_cache", value) + + @property + def disable_caching(self) -> bool: + """Whether to use scene caching.""" + return self._d["disable_caching"] + + @disable_caching.setter + def disable_caching(self, value: bool) -> None: + self._set_boolean("disable_caching", value) + + @property + def disable_caching_warning(self) -> bool: + """Whether a warning is raised if there are too much submobjects to hash.""" + return self._d["disable_caching_warning"] + + @disable_caching_warning.setter + def disable_caching_warning(self, value: bool) -> None: + self._set_boolean("disable_caching_warning", value) + + @property + def movie_file_extension(self) -> str: + """Either .mp4, .webm or .mov.""" + return self._d["movie_file_extension"] + + @movie_file_extension.setter + def movie_file_extension(self, value: str) -> None: + self._set_from_list("movie_file_extension", value, [".mp4", ".mov", ".webm"]) + + @property + def background_opacity(self) -> float: + """A number between 0.0 (fully transparent) and 1.0 (fully opaque).""" + return self._d["background_opacity"] + + @background_opacity.setter + def background_opacity(self, value: float) -> None: + self._set_between("background_opacity", value, 0, 1) + if self.background_opacity < 1: + self.resolve_movie_file_extension(is_transparent=True) + + @property + def frame_size(self) -> tuple[int, int]: + """Tuple with (pixel width, pixel height) (no flag).""" + return (self._d["pixel_width"], self._d["pixel_height"]) + + @frame_size.setter + def frame_size(self, value: tuple[int, int]) -> None: + self._d.__setitem__("pixel_width", value[0]) or self._d.__setitem__( + "pixel_height", value[1] + ) + + @property + def quality(self) -> str | None: """Video quality (-q).""" keys = ["pixel_width", "pixel_height", "frame_rate"] q = {k: self[k] for k in keys} for qual in constants.QUALITIES: - if all([q[k] == constants.QUALITIES[qual][k] for k in keys]): + if all(q[k] == constants.QUALITIES[qual][k] for k in keys): return qual return None @quality.setter - def quality(self, qual: str) -> None: - if qual is None: + def quality(self, value: str | None) -> None: + if value is None: return - if qual not in constants.QUALITIES: + if value not in constants.QUALITIES: raise KeyError(f"quality must be one of {list(constants.QUALITIES.keys())}") - q = constants.QUALITIES[qual] + q = constants.QUALITIES[value] self.frame_size = q["pixel_width"], q["pixel_height"] self.frame_rate = q["frame_rate"] @property - def transparent(self): - """Whether the background opacity is 0.0 (-t).""" - return self._d["background_opacity"] == 0.0 + def transparent(self) -> bool: + """Whether the background opacity is less than 1.0 (-t).""" + return self._d["background_opacity"] < 1.0 @transparent.setter - def transparent(self, val: bool) -> None: - self._d["background_opacity"] = float(not val) - self.resolve_movie_file_extension(val) + def transparent(self, value: bool) -> None: + self._d["background_opacity"] = float(not value) + self.resolve_movie_file_extension(value) @property - def dry_run(self): + def dry_run(self) -> bool: """Whether dry run is enabled.""" return self._d["dry_run"] @@ -1180,13 +1326,41 @@ def dry_run(self, val: bool) -> None: self.format = None @property - def renderer(self): - """Renderer: "cairo", "opengl", "webgl""" + def renderer(self) -> RendererType: + """The currently active renderer. + + Populated with one of the available renderers in :class:`.RendererType`. + + Tests:: + + >>> test_config = ManimConfig() + >>> test_config.renderer is None # a new ManimConfig is unpopulated + True + >>> test_config.renderer = 'opengl' + >>> test_config.renderer + + >>> test_config.renderer = 42 + Traceback (most recent call last): + ... + ValueError: 42 is not a valid RendererType + + Check that capitalization of renderer types is irrelevant:: + + >>> test_config.renderer = 'OpenGL' + >>> test_config.renderer = 'cAirO' + """ return self._d["renderer"] @renderer.setter - def renderer(self, val: str) -> None: - """Renderer for animations.""" + def renderer(self, value: str | RendererType) -> None: + """The setter of the renderer property. + + Takes care of switching inheritance bases using the + :class:`.ConvertToOpenGL` metaclass. + """ + if isinstance(value, str): + value = value.lower() + renderer = RendererType(value) try: from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL from manim.mobject.opengl.opengl_mobject import OpenGLMobject @@ -1196,7 +1370,7 @@ def renderer(self, val: str) -> None: from ..mobject.types.vectorized_mobject import VMobject for cls in ConvertToOpenGL._converted_classes: - if val == "opengl": + if renderer == RendererType.OPENGL: conversion_dict = { Mobject: OpenGLMobject, VMobject: OpenGLVMobject, @@ -1218,68 +1392,37 @@ def renderer(self, val: str) -> None: # can just do nothing. pass - self._set_from_list( - "renderer", - val, - ["cairo", "opengl", "webgl"], - ) + self._set_from_enum("renderer", renderer, RendererType) @property - def use_opengl_renderer(self): - """Whether or not to use the OpenGL renderer.""" - return self._d["use_opengl_renderer"] + def media_dir(self) -> str: + """Main output directory. See :meth:`ManimConfig.get_dir`.""" + return self._d["media_dir"] - @use_opengl_renderer.setter - def use_opengl_renderer(self, val: bool) -> None: - self._d["use_opengl_renderer"] = val - if val: - self._set_from_list( - "renderer", - "opengl", - ["cairo", "opengl", "webgl"], - ) + @media_dir.setter + def media_dir(self, value: str | Path) -> None: + self._set_dir("media_dir", value) @property - def use_webgl_renderer(self): - """Whether or not to use WebGL renderer.""" - return self._d["use_webgl_renderer"] + def window_position(self) -> str: + """Set the position of preview window. You can use directions, e.g. UL/DR/ORIGIN/LEFT...or the position(pixel) of the upper left corner of the window, e.g. '960,540'.""" + return self._d["window_position"] - @use_webgl_renderer.setter - def use_webgl_renderer(self, val: bool) -> None: - self._d["use_webgl_renderer"] = val - if val: - self._set_from_list( - "webgl", - "renderer", - ["cairo", "opengl", "webgl"], - ) - self["disable_caching"] = True - - webgl_renderer_path = property( - lambda self: self._d["webgl_renderer_path"], - lambda self, val: self._d.__setitem__("webgl_renderer_path", val), - doc="Path to WebGL renderer.", - ) - - media_dir = property( - lambda self: self._d["media_dir"], - lambda self, val: self._set_dir("media_dir", val), - doc="Main output directory. See :meth:`ManimConfig.get_dir`.", - ) - - window_position = property( - lambda self: self._d["window_position"], - lambda self, val: self._d.__setitem__("window_position", val), - doc="Set the position of preview window. You can use directions, e.g. UL/DR/ORIGIN/LEFT...or the position(pixel) of the upper left corner of the window, e.g. '960,540'", - ) - - window_size = property( - lambda self: self._d["window_size"], - lambda self, val: self._d.__setitem__("window_size", val), - doc="The size of the opengl window. 'default' to automatically scale the window based on the display monitor.", - ) - - def resolve_movie_file_extension(self, is_transparent): + @window_position.setter + def window_position(self, value: str) -> None: + self._d.__setitem__("window_position", value) + + @property + def window_size(self) -> str: + """The size of the opengl window. 'default' to automatically scale the window based on the display monitor.""" + return self._d["window_size"] + + @window_size.setter + def window_size(self, value: str) -> None: + self._d.__setitem__("window_size", value) + + def resolve_movie_file_extension(self, is_transparent: bool) -> None: + prev_file_extension = self.movie_file_extension if is_transparent: self.movie_file_extension = ".webm" if self.format == "webm" else ".mov" elif self.format == "webm": @@ -1288,44 +1431,67 @@ def resolve_movie_file_extension(self, is_transparent): self.movie_file_extension = ".mov" else: self.movie_file_extension = ".mp4" + if self.movie_file_extension != prev_file_extension: + logger.warning( + f"Output format changed to '{self.movie_file_extension}' " + "to support transparency", + ) + + @property + def enable_gui(self) -> bool: + """Enable GUI interaction.""" + return self._d["enable_gui"] + + @enable_gui.setter + def enable_gui(self, value: bool) -> None: + self._set_boolean("enable_gui", value) + + @property + def gui_location(self) -> tuple[Any]: + """Enable GUI interaction.""" + return self._d["gui_location"] + + @gui_location.setter + def gui_location(self, value: tuple[Any]) -> None: + self._set_tuple("gui_location", value) + + @property + def fullscreen(self) -> bool: + """Expand the window to its maximum possible size.""" + return self._d["fullscreen"] + + @fullscreen.setter + def fullscreen(self, value: bool) -> None: + self._set_boolean("fullscreen", value) + + @property + def use_projection_fill_shaders(self) -> bool: + """Use shaders for OpenGLVMobject fill which are compatible with transformation matrices.""" + return self._d["use_projection_fill_shaders"] + + @use_projection_fill_shaders.setter + def use_projection_fill_shaders(self, value: bool) -> None: + self._set_boolean("use_projection_fill_shaders", value) + + @property + def use_projection_stroke_shaders(self) -> bool: + """Use shaders for OpenGLVMobject stroke which are compatible with transformation matrices.""" + return self._d["use_projection_stroke_shaders"] + + @use_projection_stroke_shaders.setter + def use_projection_stroke_shaders(self, value: bool) -> None: + self._set_boolean("use_projection_stroke_shaders", value) - enable_gui = property( - lambda self: self._d["enable_gui"], - lambda self, val: self._set_boolean("enable_gui", val), - doc="Enable GUI interaction.", - ) - - gui_location = property( - lambda self: self._d["gui_location"], - lambda self, val: self._set_tuple("gui_location", val), - doc="Enable GUI interaction.", - ) - - fullscreen = property( - lambda self: self._d["fullscreen"], - lambda self, val: self._set_boolean("fullscreen", val), - doc="Expand the window to its maximum possible size.", - ) - - use_projection_fill_shaders = property( - lambda self: self._d["use_projection_fill_shaders"], - lambda self, val: self._set_boolean("use_projection_fill_shaders", val), - doc="Use shaders for OpenGLVMobject fill which are compatible with transformation matrices.", - ) - - use_projection_stroke_shaders = property( - lambda self: self._d["use_projection_stroke_shaders"], - lambda self, val: self._set_boolean("use_projection_stroke_shaders", val), - doc="Use shaders for OpenGLVMobject stroke which are compatible with transformation matrices.", - ) - - zero_pad = property( - lambda self: self._d["zero_pad"], - lambda self, val: self._set_int_between("zero_pad", val, 0, 9), - doc="PNG zero padding. A number between 0 (no zero padding) and 9 (9 columns minimum).", - ) - - def get_dir(self, key: str, **kwargs: str) -> Path: + @property + def zero_pad(self) -> int: + """PNG zero padding. A number between 0 (no zero padding) and 9 (9 columns minimum).""" + return self._d["zero_pad"] + + @zero_pad.setter + def zero_pad(self, value: int) -> None: + self._set_int_between("zero_pad", value, 0, 9) + + def get_dir(self, key: str, **kwargs: Any) -> Path: """Resolve a config option that stores a directory. Config options that store directories may depend on one another. This @@ -1333,11 +1499,11 @@ def get_dir(self, key: str, **kwargs: str) -> Path: Parameters ---------- - key : :class:`str` + key The config option to be resolved. Must be an option ending in ``'_dir'``, for example ``'media_dir'`` or ``'video_dir'``. - kwargs : :class:`str` + kwargs Any strings to be used when resolving the directory. Returns @@ -1369,7 +1535,8 @@ def get_dir(self, key: str, **kwargs: str) -> Path: .. code-block:: pycon - >>> from manim import config + >>> from manim import config as globalconfig + >>> config = globalconfig.copy() >>> config.tex_dir '{media_dir}/Tex' >>> config.media_dir @@ -1475,131 +1642,167 @@ def get_dir(self, key: str, **kwargs: str) -> Path: ) from exc return Path(path) if path else None - def _set_dir(self, key: str, val: str | Path): + def _set_dir(self, key: str, val: str | Path) -> None: if isinstance(val, Path): self._d.__setitem__(key, str(val)) else: self._d.__setitem__(key, val) - assets_dir = property( - lambda self: self._d["assets_dir"], - lambda self, val: self._set_dir("assets_dir", val), - doc="Directory to locate video assets (no flag).", - ) - - log_dir = property( - lambda self: self._d["log_dir"], - lambda self, val: self._set_dir("log_dir", val), - doc="Directory to place logs. See :meth:`ManimConfig.get_dir`.", - ) - - video_dir = property( - lambda self: self._d["video_dir"], - lambda self, val: self._set_dir("video_dir", val), - doc="Directory to place videos (no flag). See :meth:`ManimConfig.get_dir`.", - ) - - sections_dir = property( - lambda self: self._d["sections_dir"], - lambda self, val: self._set_dir("sections_dir", val), - doc="Directory to place section videos (no flag). See :meth:`ManimConfig.get_dir`.", - ) - - images_dir = property( - lambda self: self._d["images_dir"], - lambda self, val: self._set_dir("images_dir", val), - doc="Directory to place images (no flag). See :meth:`ManimConfig.get_dir`.", - ) - - text_dir = property( - lambda self: self._d["text_dir"], - lambda self, val: self._set_dir("text_dir", val), - doc="Directory to place text (no flag). See :meth:`ManimConfig.get_dir`.", - ) - - tex_dir = property( - lambda self: self._d["tex_dir"], - lambda self, val: self._set_dir("tex_dir", val), - doc="Directory to place tex (no flag). See :meth:`ManimConfig.get_dir`.", - ) - - partial_movie_dir = property( - lambda self: self._d["partial_movie_dir"], - lambda self, val: self._set_dir("partial_movie_dir", val), - doc="Directory to place partial movie files (no flag). See :meth:`ManimConfig.get_dir`.", - ) - - custom_folders = property( - lambda self: self._d["custom_folders"], - lambda self, val: self._set_boolean("custom_folders", val), - doc="Whether to use custom folder output.", - ) - - input_file = property( - lambda self: self._d["input_file"], - lambda self, val: self._set_dir("input_file", val), - doc="Input file name.", - ) - - output_file = property( - lambda self: self._d["output_file"], - lambda self, val: self._set_dir("output_file", val), - doc="Output file name (-o).", - ) - - scene_names = property( - lambda self: self._d["scene_names"], - lambda self, val: self._d.__setitem__("scene_names", val), - doc="Scenes to play from file.", - ) - - @property - def tex_template(self): + @property + def assets_dir(self) -> str: + """Directory to locate video assets (no flag).""" + return self._d["assets_dir"] + + @assets_dir.setter + def assets_dir(self, value: str | Path) -> None: + self._set_dir("assets_dir", value) + + @property + def log_dir(self) -> str: + """Directory to place logs. See :meth:`ManimConfig.get_dir`.""" + return self._d["log_dir"] + + @log_dir.setter + def log_dir(self, value: str | Path) -> None: + self._set_dir("log_dir", value) + + @property + def video_dir(self) -> str: + """Directory to place videos (no flag). See :meth:`ManimConfig.get_dir`.""" + return self._d["video_dir"] + + @video_dir.setter + def video_dir(self, value: str | Path) -> None: + self._set_dir("video_dir", value) + + @property + def sections_dir(self) -> str: + """Directory to place section videos (no flag). See :meth:`ManimConfig.get_dir`.""" + return self._d["sections_dir"] + + @sections_dir.setter + def sections_dir(self, value: str | Path) -> None: + self._set_dir("sections_dir", value) + + @property + def images_dir(self) -> str: + """Directory to place images (no flag). See :meth:`ManimConfig.get_dir`.""" + return self._d["images_dir"] + + @images_dir.setter + def images_dir(self, value: str | Path) -> None: + self._set_dir("images_dir", value) + + @property + def text_dir(self) -> str: + """Directory to place text (no flag). See :meth:`ManimConfig.get_dir`.""" + return self._d["text_dir"] + + @text_dir.setter + def text_dir(self, value: str | Path) -> None: + self._set_dir("text_dir", value) + + @property + def tex_dir(self) -> str: + """Directory to place tex (no flag). See :meth:`ManimConfig.get_dir`.""" + return self._d["tex_dir"] + + @tex_dir.setter + def tex_dir(self, value: str | Path) -> None: + self._set_dir("tex_dir", value) + + @property + def partial_movie_dir(self) -> str: + """Directory to place partial movie files (no flag). See :meth:`ManimConfig.get_dir`.""" + return self._d["partial_movie_dir"] + + @partial_movie_dir.setter + def partial_movie_dir(self, value: str | Path) -> None: + self._set_dir("partial_movie_dir", value) + + @property + def custom_folders(self) -> str: + """Whether to use custom folder output.""" + return self._d["custom_folders"] + + @custom_folders.setter + def custom_folders(self, value: str | Path) -> None: + self._set_dir("custom_folders", value) + + @property + def input_file(self) -> str: + """Input file name.""" + return self._d["input_file"] + + @input_file.setter + def input_file(self, value: str | Path) -> None: + self._set_dir("input_file", value) + + @property + def output_file(self) -> str: + """Output file name (-o).""" + return self._d["output_file"] + + @output_file.setter + def output_file(self, value: str | Path) -> None: + self._set_dir("output_file", value) + + @property + def scene_names(self) -> list[str]: + """Scenes to play from file.""" + return self._d["scene_names"] + + @scene_names.setter + def scene_names(self, value: list[str]) -> None: + self._d.__setitem__("scene_names", value) + + @property + def tex_template(self) -> TexTemplate: """Template used when rendering Tex. See :class:`.TexTemplate`.""" if not hasattr(self, "_tex_template") or not self._tex_template: fn = self._d["tex_template_file"] if fn: - self._tex_template = TexTemplateFromFile(filename=fn) + self._tex_template = TexTemplate.from_file(fn) else: - self._tex_template = TexTemplateLibrary.default.copy() + self._tex_template = TexTemplate() return self._tex_template @tex_template.setter - def tex_template(self, val: TexTemplateFromFile | TexTemplate) -> None: - if isinstance(val, (TexTemplateFromFile, TexTemplate)): + def tex_template(self, val: TexTemplate) -> None: + if isinstance(val, TexTemplate): self._tex_template = val @property - def tex_template_file(self): - """File to read Tex template from (no flag). See :class:`.TexTemplateFromFile`.""" + def tex_template_file(self) -> Path: + """File to read Tex template from (no flag). See :class:`.TexTemplate`.""" return self._d["tex_template_file"] @tex_template_file.setter def tex_template_file(self, val: str) -> None: if val: if not os.access(val, os.R_OK): - logging.getLogger("manim").warning( + logger.warning( f"Custom TeX template {val} not found or not readable.", ) else: self._d["tex_template_file"] = Path(val) - self._tex_template = TexTemplateFromFile(filename=val) else: self._d["tex_template_file"] = val # actually set the falsy value - self._tex_template = TexTemplate() # but don't use it @property - def plugins(self): + def plugins(self) -> list[str]: """List of plugins to enable.""" return self._d["plugins"] @plugins.setter - def plugins(self, value): + def plugins(self, value: list[str]): self._d["plugins"] = value +# TODO: to be used in the future - see PR #620 +# https://github.com/ManimCommunity/manim/pull/620 class ManimFrame(Mapping): - _OPTS: set[str] = { + _OPTS: ClassVar[set[str]] = { "pixel_width", "pixel_height", "aspect_ratio", @@ -1612,7 +1815,7 @@ class ManimFrame(Mapping): "left_side", "right_side", } - _CONSTANTS: dict[str, np.ndarray] = { + _CONSTANTS: ClassVar[dict[str, Vector3D]] = { "UP": np.array((0.0, 1.0, 0.0)), "DOWN": np.array((0.0, -1.0, 0.0)), "RIGHT": np.array((1.0, 0.0, 0.0)), @@ -1629,6 +1832,8 @@ class ManimFrame(Mapping): "DR": np.array((1.0, -1.0, 0.0)), } + _c: ManimConfig + def __init__(self, c: ManimConfig) -> None: if not isinstance(c, ManimConfig): raise TypeError("argument must be instance of 'ManimConfig'") @@ -1637,7 +1842,7 @@ def __init__(self, c: ManimConfig) -> None: self.__dict__["_c"] = c # there are required by parent class Mapping to behave like a dict - def __getitem__(self, key: str | int) -> typing.Any: + def __getitem__(self, key: str | int) -> Any: if key in self._OPTS: return self._c[key] elif key in self._CONSTANTS: @@ -1645,20 +1850,20 @@ def __getitem__(self, key: str | int) -> typing.Any: else: raise KeyError(key) - def __iter__(self) -> typing.Iterable: + def __iter__(self) -> Iterable[str]: return iter(list(self._OPTS) + list(self._CONSTANTS)) def __len__(self) -> int: return len(self._OPTS) # make this truly immutable - def __setattr__(self, attr, val) -> None: + def __setattr__(self, attr: Any, val: Any) -> NoReturn: raise TypeError("'ManimFrame' object does not support item assignment") - def __setitem__(self, key, val) -> None: + def __setitem__(self, key: Any, val: Any) -> NoReturn: raise TypeError("'ManimFrame' object does not support item assignment") - def __delitem__(self, key) -> None: + def __delitem__(self, key: Any) -> NoReturn: raise TypeError("'ManimFrame' object does not support item deletion") diff --git a/manim/animation/animation.py b/manim/animation/animation.py index 2805e04023..491d573740 100644 --- a/manim/animation/animation.py +++ b/manim/animation/animation.py @@ -1,21 +1,25 @@ """Animate mobjects.""" - from __future__ import annotations from manim.mobject.opengl.opengl_mobject import OpenGLMobject from .. import config, logger +from ..constants import RendererType from ..mobject import mobject -from ..mobject.mobject import Mobject +from ..mobject.mobject import Group, Mobject from ..mobject.opengl import opengl_mobject -from ..utils.rate_functions import smooth +from ..utils.rate_functions import linear, smooth -__all__ = ["Animation", "Wait", "override_animation"] +__all__ = ["Animation", "Wait", "Add", "override_animation"] +from collections.abc import Iterable, Sequence from copy import deepcopy -from typing import TYPE_CHECKING, Callable, Iterable, Sequence +from functools import partialmethod +from typing import TYPE_CHECKING, Any, Callable + +from typing_extensions import Self if TYPE_CHECKING: from manim.scene.scene import Scene @@ -49,6 +53,13 @@ class Animation: For example ``rate_func(0.5)`` is the proportion of the animation that is done after half of the animations run time. + + + reverse_rate_function + Reverses the rate function of the animation. Setting ``reverse_rate_function`` + does not have any effect on ``remover`` or ``introducer``. These need to be + set explicitly if an introducer-animation should be turned into a remover one + and vice versa. name The name of the animation. This gets displayed while rendering the animation. Defaults to (). @@ -104,7 +115,7 @@ def __new__( *args, use_override=True, **kwargs, - ): + ) -> Self: if isinstance(mobject, Mobject) and use_override: func = mobject.animation_override_for(cls) if func is not None: @@ -123,6 +134,7 @@ def __init__( lag_ratio: float = DEFAULT_ANIMATION_LAG_RATIO, run_time: float = DEFAULT_ANIMATION_RUN_TIME, rate_func: Callable[[float], float] = smooth, + reverse_rate_function: bool = False, name: str = None, remover: bool = False, # remove a mobject from the screen? suspend_mobject_updating: bool = True, @@ -134,13 +146,14 @@ def __init__( self._typecheck_input(mobject) self.run_time: float = run_time self.rate_func: Callable[[float], float] = rate_func + self.reverse_rate_function: bool = reverse_rate_function self.name: str | None = name self.remover: bool = remover self.introducer: bool = introducer self.suspend_mobject_updating: bool = suspend_mobject_updating self.lag_ratio: float = lag_ratio self._on_finish: Callable[[Scene], None] = _on_finish - if config["renderer"] == "opengl": + if config["renderer"] == RendererType.OPENGL: self.starting_mobject: OpenGLMobject = OpenGLMobject() self.mobject: OpenGLMobject = ( mobject if mobject is not None else OpenGLMobject() @@ -159,6 +172,19 @@ def __init__( ), ) + @property + def run_time(self) -> float: + return self._run_time + + @run_time.setter + def run_time(self, value: float) -> None: + if value < 0: + raise ValueError( + f"The run_time of {self.__class__.__name__} cannot be " + f"negative. The given value was {value}." + ) + self._run_time = value + def _typecheck_input(self, mobject: Mobject | None) -> None: if mobject is None: logger.debug("Animation with empty mobject") @@ -256,7 +282,7 @@ def get_all_mobjects(self) -> Sequence[Mobject]: return self.mobject, self.starting_mobject def get_all_families_zipped(self) -> Iterable[tuple]: - if config["renderer"] == "opengl": + if config["renderer"] == RendererType.OPENGL: return zip(*(mob.get_family() for mob in self.get_all_mobjects())) return zip( *(mob.family_members_with_points() for mob in self.get_all_mobjects()) @@ -361,7 +387,10 @@ def get_sub_alpha(self, alpha: float, index: int, num_submobjects: int) -> float full_length = (num_submobjects - 1) * lag_ratio + 1 value = alpha * full_length lower = index * lag_ratio - return self.rate_func(value - lower) + if self.reverse_rate_function: + return self.rate_func(1 - (value - lower)) + else: + return self.rate_func(value - lower) # Getters and setters def set_run_time(self, run_time: float) -> Animation: @@ -385,6 +414,7 @@ def set_run_time(self, run_time: float) -> Animation: self.run_time = run_time return self + # TODO: is this getter even necessary? def get_run_time(self) -> float: """Get the run time of the animation. @@ -403,9 +433,9 @@ def set_rate_func( Parameters ---------- - run_time - The new time the animation should take in seconds. - + rate_func + The new function defining the animation progress based on the + relative runtime (see :mod:`~.rate_functions`). Returns ------- @@ -444,7 +474,7 @@ def set_name(self, name: str) -> Animation: return self def is_remover(self) -> bool: - """Test if a the animation is a remover. + """Test if the animation is a remover. Returns ------- @@ -454,7 +484,7 @@ def is_remover(self) -> bool: return self.remover def is_introducer(self) -> bool: - """Test if a the animation is an introducer. + """Test if the animation is an introducer. Returns ------- @@ -463,6 +493,52 @@ def is_introducer(self) -> bool: """ return self.introducer + @classmethod + def __init_subclass__(cls, **kwargs) -> None: + super().__init_subclass__(**kwargs) + + cls._original__init__ = cls.__init__ + + @classmethod + def set_default(cls, **kwargs) -> None: + """Sets the default values of keyword arguments. + + If this method is called without any additional keyword + arguments, the original default values of the initialization + method of this class are restored. + + Parameters + ---------- + + kwargs + Passing any keyword argument will update the default + values of the keyword arguments of the initialization + function of this class. + + Examples + -------- + + .. manim:: ChangeDefaultAnimation + + class ChangeDefaultAnimation(Scene): + def construct(self): + Rotate.set_default(run_time=2, rate_func=rate_functions.linear) + Indicate.set_default(color=None) + + S = Square(color=BLUE, fill_color=BLUE, fill_opacity=0.25) + self.add(S) + self.play(Rotate(S, PI)) + self.play(Indicate(S)) + + Rotate.set_default() + Indicate.set_default() + + """ + if kwargs: + cls.__init__ = partialmethod(cls.__init__, **kwargs) + else: + cls.__init__ = cls._original__init__ + def prepare_animation( anim: Animation | mobject._AnimationBuilder, @@ -515,8 +591,8 @@ class Wait(Animation): stop_condition A function without positional arguments that evaluates to a boolean. The function is evaluated after every new frame has been rendered. - Playing the animation only stops after the return value is truthy. - Overrides the specified ``run_time``. + Playing the animation stops after the return value is truthy, or + after the specified ``run_time`` has passed. frozen_frame Controls whether or not the wait animation is static, i.e., corresponds to a frozen frame. If ``False`` is passed, the render loop still @@ -533,6 +609,7 @@ def __init__( run_time: float = 1, stop_condition: Callable[[], bool] | None = None, frozen_frame: bool | None = None, + rate_func: Callable[[float], float] = linear, **kwargs, ): if stop_condition and frozen_frame: @@ -541,7 +618,7 @@ def __init__( self.duration: float = run_time self.stop_condition = stop_condition self.is_static_wait: bool = frozen_frame - super().__init__(None, run_time=run_time, **kwargs) + super().__init__(None, run_time=run_time, rate_func=rate_func, **kwargs) # quick fix to work in opengl setting: self.mobject.shader_wrapper_list = [] @@ -561,6 +638,90 @@ def interpolate(self, alpha: float) -> None: pass +class Add(Animation): + """Add Mobjects to a scene, without animating them in any other way. This + is similar to the :meth:`.Scene.add` method, but :class:`Add` is an + animation which can be grouped into other animations. + + Parameters + ---------- + mobjects + One :class:`~.Mobject` or more to add to a scene. + run_time + The duration of the animation after adding the ``mobjects``. Defaults + to 0, which means this is an instant animation without extra wait time + after adding them. + **kwargs + Additional arguments to pass to the parent :class:`Animation` class. + + Examples + -------- + + .. manim:: DefaultAddScene + + class DefaultAddScene(Scene): + def construct(self): + text_1 = Text("I was added with Add!") + text_2 = Text("Me too!") + text_3 = Text("And me!") + texts = VGroup(text_1, text_2, text_3).arrange(DOWN) + rect = SurroundingRectangle(texts, buff=0.5) + + self.play( + Create(rect, run_time=3.0), + Succession( + Wait(1.0), + # You can Add a Mobject in the middle of an animation... + Add(text_1), + Wait(1.0), + # ...or multiple Mobjects at once! + Add(text_2, text_3), + ), + ) + self.wait() + + .. manim:: AddWithRunTimeScene + + class AddWithRunTimeScene(Scene): + def construct(self): + # A 5x5 grid of circles + circles = VGroup( + *[Circle(radius=0.5) for _ in range(25)] + ).arrange_in_grid(5, 5) + + self.play( + Succession( + # Add a run_time of 0.2 to wait for 0.2 seconds after + # adding the circle, instead of using Wait(0.2) after Add! + *[Add(circle, run_time=0.2) for circle in circles], + rate_func=smooth, + ) + ) + self.wait() + """ + + def __init__( + self, *mobjects: Mobject, run_time: float = 0.0, **kwargs: Any + ) -> None: + mobject = mobjects[0] if len(mobjects) == 1 else Group(*mobjects) + super().__init__(mobject, run_time=run_time, introducer=True, **kwargs) + + def begin(self) -> None: + pass + + def finish(self) -> None: + pass + + def clean_up_from_scene(self, scene: Scene) -> None: + pass + + def update_mobjects(self, dt: float) -> None: + pass + + def interpolate(self, alpha: float) -> None: + pass + + def override_animation( animation_class: type[Animation], ) -> Callable[[Callable], Callable]: diff --git a/manim/animation/changing.py b/manim/animation/changing.py index 501932e9f5..bb11cfc0a4 100644 --- a/manim/animation/changing.py +++ b/manim/animation/changing.py @@ -6,12 +6,16 @@ from typing import Callable -from colour import Color - -from manim._config import config from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL from manim.mobject.types.vectorized_mobject import VGroup, VMobject -from manim.utils.color import BLUE_B, BLUE_D, BLUE_E, GREY_BROWN, WHITE +from manim.utils.color import ( + BLUE_B, + BLUE_D, + BLUE_E, + GREY_BROWN, + WHITE, + ParsableManimColor, +) from manim.utils.rate_functions import smooth @@ -140,7 +144,7 @@ def __init__( self, traced_point_func: Callable, stroke_width: float = 2, - stroke_color: Color = WHITE, + stroke_color: ParsableManimColor | None = WHITE, dissipating_time: float | None = None, **kwargs, ): @@ -158,8 +162,5 @@ def update_path(self, mob, dt): if self.dissipating_time: self.time += dt if self.time - 1 > self.dissipating_time: - if config["renderer"] == "opengl": - nppcc = self.n_points_per_curve - else: - nppcc = self.n_points_per_cubic_curve + nppcc = self.n_points_per_curve self.set_points(self.points[nppcc:]) diff --git a/manim/animation/composition.py b/manim/animation/composition.py index 6a541c97c1..128066ba80 100644 --- a/manim/animation/composition.py +++ b/manim/animation/composition.py @@ -1,25 +1,26 @@ """Tools for displaying multiple animations at once.""" - from __future__ import annotations -from typing import TYPE_CHECKING, Callable, Sequence +import types +from collections.abc import Iterable, Sequence +from typing import TYPE_CHECKING, Callable import numpy as np +from manim._config import config +from manim.animation.animation import Animation, prepare_animation +from manim.constants import RendererType +from manim.mobject.mobject import Group, Mobject from manim.mobject.opengl.opengl_mobject import OpenGLGroup - -from .._config import config -from ..animation.animation import Animation, prepare_animation -from ..mobject.mobject import Group, Mobject -from ..scene.scene import Scene -from ..utils.iterables import remove_list_redundancies -from ..utils.rate_functions import linear +from manim.scene.scene import Scene +from manim.utils.iterables import remove_list_redundancies +from manim.utils.parameter_parsing import flatten_iterable_parameters +from manim.utils.rate_functions import linear if TYPE_CHECKING: from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVGroup - - from ..mobject.types.vectorized_mobject import VGroup + from manim.mobject.types.vectorized_mobject import VGroup __all__ = ["AnimationGroup", "Succession", "LaggedStart", "LaggedStartMap"] @@ -28,32 +29,65 @@ class AnimationGroup(Animation): + """Plays a group or series of :class:`~.Animation`. + + Parameters + ---------- + animations + Sequence of :class:`~.Animation` objects to be played. + group + A group of multiple :class:`~.Mobject`. + run_time + The duration of the animation in seconds. + rate_func + The function defining the animation progress based on the relative + runtime (see :mod:`~.rate_functions`) . + lag_ratio + Defines the delay after which the animation is applied to submobjects. A lag_ratio of + ``n.nn`` means the next animation will play when ``nnn%`` of the current animation has played. + Defaults to 0.0, meaning that all animations will be played together. + + This does not influence the total runtime of the animation. Instead the runtime + of individual animations is adjusted so that the complete animation has the defined + run time. + """ + def __init__( self, - *animations: Animation, + *animations: Animation | Iterable[Animation] | types.GeneratorType[Animation], group: Group | VGroup | OpenGLGroup | OpenGLVGroup = None, run_time: float | None = None, rate_func: Callable[[float], float] = linear, lag_ratio: float = 0, **kwargs, ) -> None: - self.animations = [prepare_animation(anim) for anim in animations] + arg_anim = flatten_iterable_parameters(animations) + self.animations = [prepare_animation(anim) for anim in arg_anim] + self.rate_func = rate_func self.group = group if self.group is None: mobjects = remove_list_redundancies( [anim.mobject for anim in self.animations if not anim.is_introducer()], ) - if config["renderer"] == "opengl": + if config["renderer"] == RendererType.OPENGL: self.group = OpenGLGroup(*mobjects) else: self.group = Group(*mobjects) - super().__init__(self.group, rate_func=rate_func, lag_ratio=lag_ratio, **kwargs) + super().__init__( + self.group, rate_func=self.rate_func, lag_ratio=lag_ratio, **kwargs + ) self.run_time: float = self.init_run_time(run_time) def get_all_mobjects(self) -> Sequence[Mobject]: return list(self.group) def begin(self) -> None: + if not self.animations: + raise ValueError( + f"Trying to play {self} without animations, this is not supported. " + "Please add at least one subanimation." + ) + self.anim_group_time = 0.0 if self.suspend_mobject_updating: self.group.suspend_updating() for anim in self.animations: @@ -66,6 +100,8 @@ def _setup_scene(self, scene) -> None: def finish(self) -> None: for anim in self.animations: anim.finish() + self.anims_begun[:] = True + self.anims_finished[:] = True if self.suspend_mobject_updating: self.group.resume_updating() @@ -77,30 +113,49 @@ def clean_up_from_scene(self, scene: Scene) -> None: anim.clean_up_from_scene(scene) def update_mobjects(self, dt: float) -> None: - for anim in self.animations: + for anim in self.anims_with_timings["anim"][ + self.anims_begun & ~self.anims_finished + ]: anim.update_mobjects(dt) def init_run_time(self, run_time) -> float: + """Calculates the run time of the animation, if different from ``run_time``. + + Parameters + ---------- + run_time + The duration of the animation in seconds. + + Returns + ------- + run_time + The duration of the animation in seconds. + """ self.build_animations_with_timings() - if self.anims_with_timings: - self.max_end_time = np.max([awt[2] for awt in self.anims_with_timings]) - else: - self.max_end_time = 0 + # Note: if lag_ratio < 1, then not necessarily the final animation's + # end time will be the max end time! Therefore we must calculate the + # maximum over all the end times, and not just take the last one. + # Example: if you want to play 2 animations of 10s and 1s with a + # lag_ratio of 0.1, the 1st one will end at t=10 and the 2nd one will + # end at t=2, so the AnimationGroup will end at t=10. + self.max_end_time = max(self.anims_with_timings["end"], default=0) return self.max_end_time if run_time is None else run_time def build_animations_with_timings(self) -> None: - """ - Creates a list of triplets of the form - (anim, start_time, end_time) - """ - self.anims_with_timings = [] - curr_time: float = 0 - for anim in self.animations: - start_time: float = curr_time - end_time: float = start_time + anim.get_run_time() - self.anims_with_timings.append((anim, start_time, end_time)) - # Start time of next animation is based on the lag_ratio - curr_time = (1 - self.lag_ratio) * start_time + self.lag_ratio * end_time + """Creates a list of triplets of the form (anim, start_time, end_time).""" + run_times = np.array([anim.run_time for anim in self.animations]) + num_animations = run_times.shape[0] + dtype = [("anim", "O"), ("start", "f8"), ("end", "f8")] + self.anims_with_timings = np.zeros(num_animations, dtype=dtype) + self.anims_begun = np.zeros(num_animations, dtype=bool) + self.anims_finished = np.zeros(num_animations, dtype=bool) + if num_animations == 0: + return + + lags = run_times[:-1] * self.lag_ratio + self.anims_with_timings["anim"] = self.animations + self.anims_with_timings["start"][1:] = np.add.accumulate(lags) + self.anims_with_timings["end"] = self.anims_with_timings["start"] + run_times def interpolate(self, alpha: float) -> None: # Note, if the run_time of AnimationGroup has been @@ -108,22 +163,80 @@ def interpolate(self, alpha: float) -> None: # times might not correspond to actual times, # e.g. of the surrounding scene. Instead they'd # be a rescaled version. But that's okay! - time = alpha * self.max_end_time - for anim, start_time, end_time in self.anims_with_timings: - anim_time = end_time - start_time - if anim_time == 0: - sub_alpha = 0 - else: - sub_alpha = np.clip((time - start_time) / anim_time, 0, 1) - anim.interpolate(sub_alpha) + anim_group_time = self.rate_func(alpha) * self.max_end_time + time_goes_back = anim_group_time < self.anim_group_time + + # Only update ongoing animations + awt = self.anims_with_timings + new_begun = anim_group_time >= awt["start"] + new_finished = anim_group_time > awt["end"] + to_update = awt[ + (self.anims_begun | new_begun) & (~self.anims_finished | ~new_finished) + ] + + run_times = to_update["end"] - to_update["start"] + with_zero_run_time = run_times == 0 + run_times[with_zero_run_time] = 1 + sub_alphas = (anim_group_time - to_update["start"]) / run_times + if time_goes_back: + sub_alphas[(sub_alphas < 0) | with_zero_run_time] = 0 + else: + sub_alphas[(sub_alphas > 1) | with_zero_run_time] = 1 + + for anim_to_update, sub_alpha in zip(to_update["anim"], sub_alphas): + anim_to_update.interpolate(sub_alpha) + + self.anim_group_time = anim_group_time + self.anims_begun = new_begun + self.anims_finished = new_finished class Succession(AnimationGroup): + """Plays a series of animations in succession. + + Parameters + ---------- + animations + Sequence of :class:`~.Animation` objects to be played. + lag_ratio + Defines the delay after which the animation is applied to submobjects. A lag_ratio of + ``n.nn`` means the next animation will play when ``nnn%`` of the current animation has played. + Defaults to 1.0, meaning that the next animation will begin when 100% of the current + animation has played. + + This does not influence the total runtime of the animation. Instead the runtime + of individual animations is adjusted so that the complete animation has the defined + run time. + + Examples + -------- + .. manim:: SuccessionExample + + class SuccessionExample(Scene): + def construct(self): + dot1 = Dot(point=LEFT * 2 + UP * 2, radius=0.16, color=BLUE) + dot2 = Dot(point=LEFT * 2 + DOWN * 2, radius=0.16, color=MAROON) + dot3 = Dot(point=RIGHT * 2 + DOWN * 2, radius=0.16, color=GREEN) + dot4 = Dot(point=RIGHT * 2 + UP * 2, radius=0.16, color=YELLOW) + self.add(dot1, dot2, dot3, dot4) + + self.play(Succession( + dot1.animate.move_to(dot2), + dot2.animate.move_to(dot3), + dot3.animate.move_to(dot4), + dot4.animate.move_to(dot1) + )) + """ + def __init__(self, *animations: Animation, lag_ratio: float = 1, **kwargs) -> None: super().__init__(*animations, lag_ratio=lag_ratio, **kwargs) def begin(self) -> None: - assert len(self.animations) > 0 + if not self.animations: + raise ValueError( + f"Trying to play {self} without animations, this is not supported. " + "Please add at least one subanimation." + ) self.update_active_animation(0) def finish(self) -> None: @@ -154,26 +267,74 @@ def update_active_animation(self, index: int) -> None: self.active_animation = self.animations[index] self.active_animation._setup_scene(self.scene) self.active_animation.begin() - self.active_start_time = self.anims_with_timings[index][1] - self.active_end_time = self.anims_with_timings[index][2] + self.active_start_time = self.anims_with_timings[index]["start"] + self.active_end_time = self.anims_with_timings[index]["end"] def next_animation(self) -> None: + """Proceeds to the next animation. + + This method is called right when the active animation finishes. + """ if self.active_animation is not None: self.active_animation.finish() self.update_active_animation(self.active_index + 1) def interpolate(self, alpha: float) -> None: - current_time = alpha * self.run_time + current_time = self.rate_func(alpha) * self.max_end_time while self.active_end_time is not None and current_time >= self.active_end_time: self.next_animation() if self.active_animation is not None and self.active_start_time is not None: elapsed = current_time - self.active_start_time - active_run_time = self.active_animation.get_run_time() + active_run_time = self.active_animation.run_time subalpha = elapsed / active_run_time if active_run_time != 0.0 else 1.0 self.active_animation.interpolate(subalpha) class LaggedStart(AnimationGroup): + """Adjusts the timing of a series of :class:`~.Animation` according to ``lag_ratio``. + + Parameters + ---------- + animations + Sequence of :class:`~.Animation` objects to be played. + lag_ratio + Defines the delay after which the animation is applied to submobjects. A lag_ratio of + ``n.nn`` means the next animation will play when ``nnn%`` of the current animation has played. + Defaults to 0.05, meaning that the next animation will begin when 5% of the current + animation has played. + + This does not influence the total runtime of the animation. Instead the runtime + of individual animations is adjusted so that the complete animation has the defined + run time. + + Examples + -------- + .. manim:: LaggedStartExample + + class LaggedStartExample(Scene): + def construct(self): + title = Text("lag_ratio = 0.25").to_edge(UP) + + dot1 = Dot(point=LEFT * 2 + UP, radius=0.16) + dot2 = Dot(point=LEFT * 2, radius=0.16) + dot3 = Dot(point=LEFT * 2 + DOWN, radius=0.16) + line_25 = DashedLine( + start=LEFT + UP * 2, + end=LEFT + DOWN * 2, + color=RED + ) + label = Text("25%", font_size=24).next_to(line_25, UP) + self.add(title, dot1, dot2, dot3, line_25, label) + + self.play(LaggedStart( + dot1.animate.shift(RIGHT * 4), + dot2.animate.shift(RIGHT * 4), + dot3.animate.shift(RIGHT * 4), + lag_ratio=0.25, + run_time=4 + )) + """ + def __init__( self, *animations: Animation, @@ -184,6 +345,43 @@ def __init__( class LaggedStartMap(LaggedStart): + """Plays a series of :class:`~.Animation` while mapping a function to submobjects. + + Parameters + ---------- + AnimationClass + :class:`~.Animation` to apply to mobject. + mobject + :class:`~.Mobject` whose submobjects the animation, and optionally the function, + are to be applied. + arg_creator + Function which will be applied to :class:`~.Mobject`. + run_time + The duration of the animation in seconds. + + Examples + -------- + .. manim:: LaggedStartMapExample + + class LaggedStartMapExample(Scene): + def construct(self): + title = Tex("LaggedStartMap").to_edge(UP, buff=LARGE_BUFF) + dots = VGroup( + *[Dot(radius=0.16) for _ in range(35)] + ).arrange_in_grid(rows=5, cols=7, buff=MED_LARGE_BUFF) + self.add(dots, title) + + # Animate yellow ripple effect + for mob in dots, title: + self.play(LaggedStartMap( + ApplyMethod, mob, + lambda m : (m.set_color, YELLOW), + lag_ratio = 0.1, + rate_func = there_and_back, + run_time = 2 + )) + """ + def __init__( self, AnimationClass: Callable[..., Animation], diff --git a/manim/animation/creation.py b/manim/animation/creation.py index 1b2eddda7e..dc3ec69527 100644 --- a/manim/animation/creation.py +++ b/manim/animation/creation.py @@ -67,30 +67,36 @@ def construct(self): "ShowIncreasingSubsets", "SpiralIn", "AddTextLetterByLetter", + "RemoveTextLetterByLetter", "ShowSubmobjectsOneByOne", "AddTextWordByWord", + "TypeWithCursor", + "UntypeWithCursor", ] import itertools as it -from typing import TYPE_CHECKING, Callable, Iterable, Sequence +from collections.abc import Iterable, Sequence +from typing import TYPE_CHECKING, Callable import numpy as np -from colour import Color if TYPE_CHECKING: from manim.mobject.text.text_mobject import Text + from manim.scene.scene import Scene +from manim.constants import RIGHT, TAU from manim.mobject.opengl.opengl_surface import OpenGLSurface from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject +from manim.utils.color import ManimColor +from .. import config from ..animation.animation import Animation from ..animation.composition import Succession -from ..constants import TAU from ..mobject.mobject import Group, Mobject from ..mobject.types.vectorized_mobject import VMobject from ..utils.bezier import integer_interpolate -from ..utils.rate_functions import double_smooth, linear, smooth +from ..utils.rate_functions import double_smooth, linear class ShowPartial(Animation): @@ -136,7 +142,7 @@ class Create(ShowPartial): Parameters ---------- - mobject : :class:`~.VMobject` + mobject The VMobject to animate. Raises @@ -191,13 +197,13 @@ def construct(self): def __init__( self, mobject: VMobject | OpenGLVMobject, - rate_func: Callable[[float], float] = lambda t: smooth(1 - t), + reverse_rate_function: bool = True, remover: bool = True, **kwargs, ) -> None: super().__init__( mobject, - rate_func=rate_func, + reverse_rate_function=reverse_rate_function, introducer=False, remover=remover, **kwargs, @@ -244,7 +250,9 @@ def __init__( def _typecheck_input(self, vmobject: VMobject | OpenGLVMobject) -> None: if not isinstance(vmobject, (VMobject, OpenGLVMobject)): - raise TypeError("DrawBorderThenFill only works for vectorized Mobjects") + raise TypeError( + f"{self.__class__.__name__} only works for vectorized Mobjects" + ) def begin(self) -> None: self.outline = self.get_outline() @@ -257,7 +265,7 @@ def get_outline(self) -> Mobject: sm.set_stroke(color=self.get_stroke_color(sm), width=self.stroke_width) return outline - def get_stroke_color(self, vmobject: VMobject | OpenGLVMobject) -> Color: + def get_stroke_color(self, vmobject: VMobject | OpenGLVMobject) -> ManimColor: if self.stroke_color: return self.stroke_color elif vmobject.get_stroke_width() > 0: @@ -275,7 +283,7 @@ def interpolate_submobject( alpha: float, ) -> None: # Fixme: not matching the parent class? What is outline doing here? index: int - subalpha: int + subalpha: float index, subalpha = integer_interpolate(0, 2, alpha) if index == 0: submobject.pointwise_become_partial(outline, 0, subalpha) @@ -299,7 +307,16 @@ def construct(self): class ShowWriteReversed(Scene): def construct(self): - self.play(Write(Text("Hello", font_size=144), reverse=True)) + self.play(Write(Text("Hello", font_size=144), reverse=True, remover=False)) + + Tests + ----- + + Check that creating empty :class:`.Write` animations works:: + + >>> from manim import Write, Text + >>> Write(Text('')) + Write(Text('')) """ def __init__( @@ -336,12 +353,9 @@ def _set_default_config_from_length( ) -> tuple[float, float]: length = len(vmobject.family_members_with_points()) if run_time is None: - if length < 15: - run_time = 1 - else: - run_time = 2 + run_time = 1 if length < 15 else 2 if lag_ratio is None: - lag_ratio = min(4.0 / length, 0.2) + lag_ratio = min(4.0 / max(1.0, length), 0.2) return run_time, lag_ratio def reverse_submobjects(self) -> None: @@ -363,7 +377,7 @@ class Unwrite(Write): Parameters ---------- - reverse : :class:`bool` + reverse Set True to have the animation start erasing from the last submobject first. Examples @@ -393,7 +407,6 @@ def __init__( reverse: bool = True, **kwargs, ) -> None: - run_time: float | None = kwargs.pop("run_time", None) lag_ratio: float | None = kwargs.pop("lag_ratio", None) run_time, lag_ratio = self._set_default_config_from_length( @@ -405,7 +418,7 @@ def __init__( vmobject, run_time=run_time, lag_ratio=lag_ratio, - rate_func=lambda t: -rate_func(t) + 1, + reverse_rate_function=True, reverse=reverse, **kwargs, ) @@ -446,7 +459,7 @@ def __init__( fade_in_fraction=0.3, **kwargs, ) -> None: - self.shapes = shapes + self.shapes = shapes.copy() self.scale_factor = scale_factor self.shape_center = shapes.get_center() self.fade_in_fraction = fade_in_fraction @@ -459,18 +472,25 @@ def __init__( shape.move_to(shape.initial_position) shape.save_state() - super().__init__(shapes, **kwargs) + super().__init__(shapes, introducer=True, **kwargs) def interpolate_mobject(self, alpha: float) -> None: - for shape in self.shapes: + alpha = self.rate_func(alpha) + for original_shape, shape in zip(self.shapes, self.mobject): shape.restore() - shape.save_state() - opacity = shape.get_fill_opacity() - new_opacity = min(opacity, alpha * opacity / self.fade_in_fraction) + fill_opacity = original_shape.get_fill_opacity() + stroke_opacity = original_shape.get_stroke_opacity() + new_fill_opacity = min( + fill_opacity, alpha * fill_opacity / self.fade_in_fraction + ) + new_stroke_opacity = min( + stroke_opacity, alpha * stroke_opacity / self.fade_in_fraction + ) shape.shift((shape.final_position - shape.initial_position) * alpha) shape.rotate(TAU * alpha, about_point=self.shape_center) shape.rotate(-TAU * alpha, about_point=shape.get_center_of_mass()) - shape.set_opacity(new_opacity) + shape.set_fill(opacity=new_fill_opacity) + shape.set_stroke(opacity=new_stroke_opacity) class ShowIncreasingSubsets(Animation): @@ -494,6 +514,7 @@ def __init__( group: Mobject, suspend_mobject_updating: bool = False, int_func: Callable[[np.ndarray], np.ndarray] = np.floor, + reverse_rate_function=False, **kwargs, ) -> None: self.all_submobs = list(group.submobjects) @@ -501,17 +522,27 @@ def __init__( for mobj in self.all_submobs: mobj.set_opacity(0) super().__init__( - group, suspend_mobject_updating=suspend_mobject_updating, **kwargs + group, + suspend_mobject_updating=suspend_mobject_updating, + reverse_rate_function=reverse_rate_function, + **kwargs, ) def interpolate_mobject(self, alpha: float) -> None: n_submobs = len(self.all_submobs) - index = int(self.int_func(self.rate_func(alpha) * n_submobs)) + value = ( + 1 - self.rate_func(alpha) + if self.reverse_rate_function + else self.rate_func(alpha) + ) + index = int(self.int_func(value * n_submobs)) self.update_submobject_list(index) def update_submobject_list(self, index: int) -> None: for mobj in self.all_submobs[:index]: mobj.set_opacity(1) + for mobj in self.all_submobs[index:]: + mobj.set_opacity(0) class AddTextLetterByLetter(ShowIncreasingSubsets): @@ -519,7 +550,7 @@ class AddTextLetterByLetter(ShowIncreasingSubsets): Parameters ---------- - time_per_char : :class:`float` + time_per_char Frequency of appearance of the letters. .. tip:: @@ -536,19 +567,69 @@ def __init__( rate_func: Callable[[float], float] = linear, time_per_char: float = 0.1, run_time: float | None = None, + reverse_rate_function=False, + introducer=True, **kwargs, ) -> None: - # time_per_char must be above 0.06, or the animation won't finish self.time_per_char = time_per_char + # Check for empty text using family_members_with_points() + if not text.family_members_with_points(): + raise ValueError( + f"The text mobject {text} does not seem to contain any characters." + ) if run_time is None: - run_time = np.max((0.06, self.time_per_char)) * len(text) + # minimum time per character is 1/frame_rate, otherwise + # the animation does not finish. + run_time = np.max((1 / config.frame_rate, self.time_per_char)) * len(text) + super().__init__( + text, + suspend_mobject_updating=suspend_mobject_updating, + int_func=int_func, + rate_func=rate_func, + run_time=run_time, + reverse_rate_function=reverse_rate_function, + introducer=introducer, + **kwargs, + ) + +class RemoveTextLetterByLetter(AddTextLetterByLetter): + """Remove a :class:`~.Text` letter by letter from the scene. + + Parameters + ---------- + time_per_char + Frequency of appearance of the letters. + + .. tip:: + + This is currently only possible for class:`~.Text` and not for class:`~.MathTex` + + """ + + def __init__( + self, + text: Text, + suspend_mobject_updating: bool = False, + int_func: Callable[[np.ndarray], np.ndarray] = np.ceil, + rate_func: Callable[[float], float] = linear, + time_per_char: float = 0.1, + run_time: float | None = None, + reverse_rate_function=True, + introducer=False, + remover=True, + **kwargs, + ) -> None: super().__init__( text, suspend_mobject_updating=suspend_mobject_updating, int_func=int_func, rate_func=rate_func, + time_per_char=time_per_char, run_time=run_time, + reverse_rate_function=reverse_rate_function, + introducer=introducer, + remover=remover, **kwargs, ) @@ -596,3 +677,176 @@ def __init__( ) ) super().__init__(*anims, **kwargs) + + +class TypeWithCursor(AddTextLetterByLetter): + """Similar to :class:`~.AddTextLetterByLetter` , but with an additional cursor mobject at the end. + + Parameters + ---------- + time_per_char + Frequency of appearance of the letters. + cursor + :class:`~.Mobject` shown after the last added letter. + buff + Controls how far away the cursor is to the right of the last added letter. + keep_cursor_y + If ``True``, the cursor's y-coordinate is set to the center of the ``Text`` and remains the same throughout the animation. Otherwise, it is set to the center of the last added letter. + leave_cursor_on + Whether to show the cursor after the animation. + + .. tip:: + This is currently only possible for class:`~.Text` and not for class:`~.MathTex`. + + + Examples + -------- + + .. manim:: InsertingTextExample + :ref_classes: Blink + + class InsertingTextExample(Scene): + def construct(self): + text = Text("Inserting", color=PURPLE).scale(1.5).to_edge(LEFT) + cursor = Rectangle( + color = GREY_A, + fill_color = GREY_A, + fill_opacity = 1.0, + height = 1.1, + width = 0.5, + ).move_to(text[0]) # Position the cursor + + self.play(TypeWithCursor(text, cursor)) + self.play(Blink(cursor, blinks=2)) + + """ + + def __init__( + self, + text: Text, + cursor: Mobject, + buff: float = 0.1, + keep_cursor_y: bool = True, + leave_cursor_on: bool = True, + time_per_char: float = 0.1, + reverse_rate_function=False, + introducer=True, + **kwargs, + ) -> None: + self.cursor = cursor + self.buff = buff + self.keep_cursor_y = keep_cursor_y + self.leave_cursor_on = leave_cursor_on + super().__init__( + text, + time_per_char=time_per_char, + reverse_rate_function=reverse_rate_function, + introducer=introducer, + **kwargs, + ) + + def begin(self) -> None: + self.y_cursor = self.cursor.get_y() + self.cursor.initial_position = self.mobject.get_center() + if self.keep_cursor_y: + self.cursor.set_y(self.y_cursor) + + self.cursor.set_opacity(0) + self.mobject.add(self.cursor) + super().begin() + + def finish(self) -> None: + if self.leave_cursor_on: + self.cursor.set_opacity(1) + else: + self.cursor.set_opacity(0) + self.mobject.remove(self.cursor) + super().finish() + + def clean_up_from_scene(self, scene: Scene) -> None: + if not self.leave_cursor_on: + scene.remove(self.cursor) + super().clean_up_from_scene(scene) + + def update_submobject_list(self, index: int) -> None: + for mobj in self.all_submobs[:index]: + mobj.set_opacity(1) + + for mobj in self.all_submobs[index:]: + mobj.set_opacity(0) + + if index != 0: + self.cursor.next_to( + self.all_submobs[index - 1], RIGHT, buff=self.buff + ).set_y(self.cursor.initial_position[1]) + else: + self.cursor.move_to(self.all_submobs[0]).set_y( + self.cursor.initial_position[1] + ) + + if self.keep_cursor_y: + self.cursor.set_y(self.y_cursor) + self.cursor.set_opacity(1) + + +class UntypeWithCursor(TypeWithCursor): + """Similar to :class:`~.RemoveTextLetterByLetter` , but with an additional cursor mobject at the end. + + Parameters + ---------- + time_per_char + Frequency of appearance of the letters. + cursor + :class:`~.Mobject` shown after the last added letter. + buff + Controls how far away the cursor is to the right of the last added letter. + keep_cursor_y + If ``True``, the cursor's y-coordinate is set to the center of the ``Text`` and remains the same throughout the animation. Otherwise, it is set to the center of the last added letter. + leave_cursor_on + Whether to show the cursor after the animation. + + .. tip:: + This is currently only possible for class:`~.Text` and not for class:`~.MathTex`. + + + Examples + -------- + + .. manim:: DeletingTextExample + :ref_classes: Blink + + class DeletingTextExample(Scene): + def construct(self): + text = Text("Deleting", color=PURPLE).scale(1.5).to_edge(LEFT) + cursor = Rectangle( + color = GREY_A, + fill_color = GREY_A, + fill_opacity = 1.0, + height = 1.1, + width = 0.5, + ).move_to(text[0]) # Position the cursor + + self.play(UntypeWithCursor(text, cursor)) + self.play(Blink(cursor, blinks=2)) + + """ + + def __init__( + self, + text: Text, + cursor: VMobject | None = None, + time_per_char: float = 0.1, + reverse_rate_function=True, + introducer=False, + remover=True, + **kwargs, + ) -> None: + super().__init__( + text, + cursor=cursor, + time_per_char=time_per_char, + reverse_rate_function=reverse_rate_function, + introducer=introducer, + remover=remover, + **kwargs, + ) diff --git a/manim/animation/fading.py b/manim/animation/fading.py index 33f38a5027..79cd41a516 100644 --- a/manim/animation/fading.py +++ b/manim/animation/fading.py @@ -12,7 +12,6 @@ def construct(self): """ - from __future__ import annotations __all__ = [ @@ -58,10 +57,7 @@ def __init__( ) -> None: if not mobjects: raise ValueError("At least one mobject must be passed.") - if len(mobjects) == 1: - mobject = mobjects[0] - else: - mobject = Group(*mobjects) + mobject = mobjects[0] if len(mobjects) == 1 else Group(*mobjects) self.point_target = False if shift is None: @@ -98,7 +94,7 @@ def _create_faded_mobject(self, fadeIn: bool) -> Mobject: class FadeIn(_Fade): - """Fade in :class:`~.Mobject` s. + r"""Fade in :class:`~.Mobject` s. Parameters ---------- @@ -123,7 +119,7 @@ def construct(self): dot = Dot(UP * 2 + LEFT) self.add(dot) tex = Tex( - "FadeIn with ", "shift ", " or target\\_position", " and scale" + "FadeIn with ", "shift ", r" or target\_position", " and scale" ).scale(1) animations = [ FadeIn(tex[0]), @@ -146,7 +142,7 @@ def create_starting_mobject(self): class FadeOut(_Fade): - """Fade out :class:`~.Mobject` s. + r"""Fade out :class:`~.Mobject` s. Parameters ---------- @@ -170,7 +166,7 @@ def construct(self): dot = Dot(UP * 2 + LEFT) self.add(dot) tex = Tex( - "FadeOut with ", "shift ", " or target\\_position", " and scale" + "FadeOut with ", "shift ", r" or target\_position", " and scale" ).scale(1) animations = [ FadeOut(tex[0]), diff --git a/manim/animation/indication.py b/manim/animation/indication.py index 55bf6b409c..f931491b37 100644 --- a/manim/animation/indication.py +++ b/manim/animation/indication.py @@ -25,27 +25,30 @@ def construct(self): """ +from __future__ import annotations + __all__ = [ "FocusOn", "Indicate", "Flash", "ShowPassingFlash", "ShowPassingFlashWithThinningStrokeWidth", - "ShowCreationThenFadeOut", "ApplyWave", "Circumscribe", "Wiggle", + "Blink", ] -from typing import Callable, Iterable, Optional, Tuple, Type, Union +from collections.abc import Iterable +from typing import Callable import numpy as np -from colour import Color from manim.mobject.geometry.arc import Circle, Dot from manim.mobject.geometry.line import Line from manim.mobject.geometry.polygram import Rectangle from manim.mobject.geometry.shape_matchers import SurroundingRectangle +from manim.scene.scene import Scene from .. import config from ..animation.animation import Animation @@ -54,12 +57,12 @@ def construct(self): from ..animation.fading import FadeIn, FadeOut from ..animation.movement import Homotopy from ..animation.transform import Transform +from ..animation.updaters.update import UpdateFromFunc from ..constants import * from ..mobject.mobject import Mobject from ..mobject.types.vectorized_mobject import VGroup, VMobject from ..utils.bezier import interpolate, inverse_interpolate -from ..utils.color import GREY, YELLOW -from ..utils.deprecation import deprecated +from ..utils.color import GREY, YELLOW, ParsableManimColor from ..utils.rate_functions import smooth, there_and_back, wiggle from ..utils.space_ops import normalize @@ -77,8 +80,6 @@ class FocusOn(Transform): The color of the spotlight. run_time The duration of the animation. - kwargs : Any - Additional arguments to be passed to the :class:`~.Succession` constructor Examples -------- @@ -94,11 +95,11 @@ def construct(self): def __init__( self, - focus_point: Union[np.ndarray, Mobject], + focus_point: np.ndarray | Mobject, opacity: float = 0.2, color: str = GREY, run_time: float = 2, - **kwargs + **kwargs, ) -> None: self.focus_point = focus_point self.color = color @@ -131,8 +132,8 @@ class Indicate(Transform): color The color the mobject temporally takes. rate_func - The function definig the animation progress at every point in time. - kwargs : Any + The function defining the animation progress at every point in time. + kwargs Additional arguments to be passed to the :class:`~.Succession` constructor Examples @@ -148,17 +149,17 @@ def construct(self): def __init__( self, - mobject: "Mobject", + mobject: Mobject, scale_factor: float = 1.2, color: str = YELLOW, - rate_func: Callable[[float, Optional[float]], np.ndarray] = there_and_back, - **kwargs + rate_func: Callable[[float, float | None], np.ndarray] = there_and_back, + **kwargs, ) -> None: self.color = color self.scale_factor = scale_factor super().__init__(mobject, rate_func=rate_func, **kwargs) - def create_target(self) -> "Mobject": + def create_target(self) -> Mobject: target = self.mobject.copy() target.scale(self.scale_factor) target.set_color(self.color) @@ -186,7 +187,7 @@ class Flash(AnimationGroup): The time width used for the flash lines. See :class:`.~ShowPassingFlash` for more details. run_time The duration of the animation. - kwargs : Any + kwargs Additional arguments to be passed to the :class:`~.Succession` constructor Examples @@ -218,7 +219,7 @@ def construct(self): def __init__( self, - point: Union[np.ndarray, Mobject], + point: np.ndarray | Mobject, line_length: float = 0.2, num_lines: int = 12, flash_radius: float = 0.1, @@ -226,7 +227,7 @@ def __init__( color: str = YELLOW, time_width: float = 1, run_time: float = 1.0, - **kwargs + **kwargs, ) -> None: if isinstance(point, Mobject): self.point = point.get_center() @@ -256,7 +257,7 @@ def create_lines(self) -> VGroup: lines.set_stroke(width=self.line_stroke_width) return lines - def create_line_anims(self) -> Iterable["ShowPassingFlash"]: + def create_line_anims(self) -> Iterable[ShowPassingFlash]: return [ ShowPassingFlash( line, @@ -269,7 +270,7 @@ def create_line_anims(self) -> Iterable["ShowPassingFlash"]: class ShowPassingFlash(ShowPartial): - """Show only a sliver of the VMobject each frame. + r"""Show only a sliver of the VMobject each frame. Parameters ---------- @@ -289,7 +290,7 @@ def construct(self): self.add(p, lbl) p = p.copy().set_color(BLUE) for time_width in [0.2, 0.5, 1, 2]: - lbl.become(Tex(r"\\texttt{time\\_width={{%.1f}}}"%time_width)) + lbl.become(Tex(r"\texttt{time\_width={{%.1f}}}"%time_width)) self.play(ShowPassingFlash( p.copy().set_color(BLUE), run_time=2, @@ -302,11 +303,11 @@ def construct(self): """ - def __init__(self, mobject: "VMobject", time_width: float = 0.1, **kwargs) -> None: + def __init__(self, mobject: VMobject, time_width: float = 0.1, **kwargs) -> None: self.time_width = time_width super().__init__(mobject, remover=True, introducer=True, **kwargs) - def _get_bounds(self, alpha: float) -> Tuple[float]: + def _get_bounds(self, alpha: float) -> tuple[float]: tw = self.time_width upper = interpolate(0, 1 + tw, alpha) lower = upper - tw @@ -314,7 +315,7 @@ def _get_bounds(self, alpha: float) -> Tuple[float]: lower = max(lower, 0) return (lower, upper) - def clean_up_from_scene(self, scene: "Scene") -> None: + def clean_up_from_scene(self, scene: Scene) -> None: super().clean_up_from_scene(scene) for submob, start in self.get_all_families_zipped(): submob.pointwise_become_partial(start, 0, 1) @@ -330,7 +331,7 @@ def __init__(self, vmobject, n_segments=10, time_width=0.1, remover=True, **kwar super().__init__( *( ShowPassingFlash( - vmobject.deepcopy().set_stroke(width=stroke_width), + vmobject.copy().set_stroke(width=stroke_width), time_width=time_width, **kwargs, ) @@ -342,16 +343,6 @@ def __init__(self, vmobject, n_segments=10, time_width=0.1, remover=True, **kwar ) -@deprecated( - since="v0.15.0", - until="v0.16.0", - message="Use Create then FadeOut to achieve this effect.", -) -class ShowCreationThenFadeOut(Succession): - def __init__(self, mobject: "Mobject", remover: bool = True, **kwargs) -> None: - super().__init__(Create(mobject), FadeOut(mobject), remover=remover, **kwargs) - - class ApplyWave(Homotopy): """Send a wave through the Mobject distorting it temporarily. @@ -397,14 +388,14 @@ def construct(self): def __init__( self, - mobject: "Mobject", + mobject: Mobject, direction: np.ndarray = UP, amplitude: float = 0.2, wave_func: Callable[[float], float] = smooth, time_width: float = 1, ripples: int = 1, run_time: float = 2, - **kwargs + **kwargs, ) -> None: x_min = mobject.get_left()[0] x_max = mobject.get_right()[0] @@ -415,7 +406,7 @@ def wave(t): # This wave is build up as follows: # The time is split into 2*ripples phases. In every phase the amplitude # either rises to one or goes down to zero. Consecutive ripples will have - # their amplitudes in oppising directions (first ripple from 0 to 1 to 0, + # their amplitudes in opposing directions (first ripple from 0 to 1 to 0, # second from 0 to -1 to 0 and so on). This is how two ripples would be # divided into phases: @@ -454,7 +445,7 @@ def wave(t): return wave_func(t * phases) elif phase == phases - 1: # last ripple. Rising or falling depending on the number of ripples - # The (ripples % 2)-term is used to make this destinction. + # The (ripples % 2)-term is used to make this distinction. t -= phase / phases # Time relative to the phase return (1 - wave_func(t * phases)) * (2 * (ripples % 2) - 1) else: @@ -470,7 +461,7 @@ def homotopy( y: float, z: float, t: float, - ) -> Tuple[float, float, float]: + ) -> tuple[float, float, float]: upper = interpolate(0, 1 + time_width, t) lower = upper - time_width relative_x = inverse_interpolate(x_min, x_max, x) @@ -486,7 +477,7 @@ class Wiggle(Animation): Parameters ---------- - mobject : Mobject + mobject The mobject to wiggle. scale_value The factor by which the mobject will be temporarily scaled. @@ -516,14 +507,14 @@ def construct(self): def __init__( self, - mobject: "Mobject", + mobject: Mobject, scale_value: float = 1.1, rotation_angle: float = 0.01 * TAU, n_wiggles: int = 6, - scale_about_point: Optional[np.ndarray] = None, - rotate_about_point: Optional[np.ndarray] = None, + scale_about_point: np.ndarray | None = None, + rotate_about_point: np.ndarray | None = None, run_time: float = 2, - **kwargs + **kwargs, ) -> None: self.scale_value = scale_value self.rotation_angle = rotation_angle @@ -535,15 +526,17 @@ def __init__( def get_scale_about_point(self) -> np.ndarray: if self.scale_about_point is None: return self.mobject.get_center() + return self.scale_about_point def get_rotate_about_point(self) -> np.ndarray: if self.rotate_about_point is None: return self.mobject.get_center() + return self.rotate_about_point def interpolate_submobject( self, - submobject: "Mobject", - starting_submobject: "Mobject", + submobject: Mobject, + starting_submobject: Mobject, alpha: float, ) -> None: submobject.points[:, :] = starting_submobject.points @@ -558,14 +551,14 @@ def interpolate_submobject( class Circumscribe(Succession): - """Draw a temporary line surrounding the mobject. + r"""Draw a temporary line surrounding the mobject. Parameters ---------- mobject The mobject to be circumscribed. shape - The shape with which to surrond the given mobject. Should be either + The shape with which to surround the given mobject. Should be either :class:`~.Rectangle` or :class:`~.Circle` fade_in Whether to make the surrounding shape to fade in. It will be drawn otherwise. @@ -579,7 +572,7 @@ class Circumscribe(Succession): The color of the surrounding shape. run_time The duration of the entire animation. - kwargs : Any + kwargs Additional arguments to be passed to the :class:`~.Succession` constructor Examples @@ -589,7 +582,7 @@ class Circumscribe(Succession): class UsingCircumscribe(Scene): def construct(self): - lbl = Tex(r"Circum-\\\\scribe").scale(2) + lbl = Tex(r"Circum-\\scribe").scale(2) self.add(lbl) self.play(Circumscribe(lbl)) self.play(Circumscribe(lbl, Circle)) @@ -602,21 +595,21 @@ def construct(self): def __init__( self, mobject: Mobject, - shape: Type = Rectangle, + shape: type = Rectangle, fade_in=False, fade_out=False, time_width=0.3, buff: float = SMALL_BUFF, - color: Color = YELLOW, + color: ParsableManimColor = YELLOW, run_time=1, stroke_width=DEFAULT_STROKE_WIDTH, - **kwargs + **kwargs, ): if shape is Rectangle: frame = SurroundingRectangle( mobject, - color, - buff, + color=color, + buff=buff, stroke_width=stroke_width, ) elif shape is Circle: @@ -652,3 +645,68 @@ def __init__( super().__init__( ShowPassingFlash(frame, time_width, run_time=run_time), **kwargs ) + + +class Blink(Succession): + """Blink the mobject. + + Parameters + ---------- + mobject + The mobject to be blinked. + time_on + The duration that the mobject is shown for one blink. + time_off + The duration that the mobject is hidden for one blink. + blinks + The number of blinks + hide_at_end + Whether to hide the mobject at the end of the animation. + kwargs + Additional arguments to be passed to the :class:`~.Succession` constructor. + + Examples + -------- + + .. manim:: BlinkingExample + + class BlinkingExample(Scene): + def construct(self): + text = Text("Blinking").scale(1.5) + self.add(text) + self.play(Blink(text, blinks=3)) + + """ + + def __init__( + self, + mobject: Mobject, + time_on: float = 0.5, + time_off: float = 0.5, + blinks: int = 1, + hide_at_end: bool = False, + **kwargs, + ): + animations = [ + UpdateFromFunc( + mobject, + update_function=lambda mob: mob.set_opacity(1.0), + run_time=time_on, + ), + UpdateFromFunc( + mobject, + update_function=lambda mob: mob.set_opacity(0.0), + run_time=time_off, + ), + ] * blinks + + if not hide_at_end: + animations.append( + UpdateFromFunc( + mobject, + update_function=lambda mob: mob.set_opacity(1.0), + run_time=time_on, + ), + ) + + super().__init__(*animations, **kwargs) diff --git a/manim/animation/movement.py b/manim/animation/movement.py index 0eb78c7117..b9b185db06 100644 --- a/manim/animation/movement.py +++ b/manim/animation/movement.py @@ -22,6 +22,50 @@ class Homotopy(Animation): + """A Homotopy. + + This is an animation transforming the points of a mobject according + to the specified transformation function. With the parameter :math:`t` + moving from 0 to 1 throughout the animation and :math:`(x, y, z)` + describing the coordinates of the point of a mobject, + the function passed to the ``homotopy`` keyword argument should + transform the tuple :math:`(x, y, z, t)` to :math:`(x', y', z')`, + the coordinates the original point is transformed to at time :math:`t`. + + Parameters + ---------- + homotopy + A function mapping :math:`(x, y, z, t)` to :math:`(x', y', z')`. + mobject + The mobject transformed under the given homotopy. + run_time + The run time of the animation. + apply_function_kwargs + Keyword arguments propagated to :meth:`.Mobject.apply_function`. + kwargs + Further keyword arguments passed to the parent class. + + Examples + -------- + + .. manim:: HomotopyExample + + class HomotopyExample(Scene): + def construct(self): + square = Square() + + def homotopy(x, y, z, t): + if t <= 0.25: + progress = t / 0.25 + return (x, y + progress * 0.2 * np.sin(x), z) + else: + wave_progress = (t - 0.25) / 0.75 + return (x, y + 0.2 * np.sin(x + 10 * wave_progress), z) + + self.play(Homotopy(homotopy, square, rate_func= linear, run_time=2)) + + """ + def __init__( self, homotopy: Callable[[float, float, float, float], tuple[float, float, float]], @@ -30,10 +74,6 @@ def __init__( apply_function_kwargs: dict[str, Any] | None = None, **kwargs, ) -> None: - """ - Homotopy is a function from - (x, y, z, t) to (x', y', z') - """ self.homotopy = homotopy self.apply_function_kwargs = ( apply_function_kwargs if apply_function_kwargs is not None else {} @@ -70,9 +110,7 @@ class ComplexHomotopy(Homotopy): def __init__( self, complex_homotopy: Callable[[complex], float], mobject: Mobject, **kwargs ) -> None: - """ - Complex Homotopy a function Cx[0, 1] to C - """ + """Complex Homotopy a function Cx[0, 1] to C""" def homotopy( x: float, @@ -116,8 +154,7 @@ def interpolate_mobject(self, alpha: float) -> None: class MoveAlongPath(Animation): """Make one mobject move along the path of another mobject. - Example - -------- + .. manim:: MoveAlongPathExample class MoveAlongPathExample(Scene): diff --git a/manim/animation/rotation.py b/manim/animation/rotation.py index faff411c21..7bdd42238a 100644 --- a/manim/animation/rotation.py +++ b/manim/animation/rotation.py @@ -4,7 +4,8 @@ __all__ = ["Rotating", "Rotate"] -from typing import TYPE_CHECKING, Callable, Sequence +from collections.abc import Sequence +from typing import TYPE_CHECKING, Callable import numpy as np @@ -59,7 +60,7 @@ class Rotate(Transform): about_point The rotation center. about_edge - If ``about_point``is ``None``, this argument specifies + If ``about_point`` is ``None``, this argument specifies the direction of the bounding box point to be taken as the rotation center. diff --git a/manim/animation/specialized.py b/manim/animation/specialized.py index 2c9ed5c617..e5f9e96d96 100644 --- a/manim/animation/specialized.py +++ b/manim/animation/specialized.py @@ -2,7 +2,8 @@ __all__ = ["Broadcast"] -from typing import Any, Sequence +from collections.abc import Sequence +from typing import Any from manim.animation.transform import Restore @@ -69,10 +70,7 @@ def __init__( anims = [] # Works by saving the mob that is passed into the animation, scaling it to 0 (or the initial_width) and then restoring the original mob. - if mobject.fill_opacity: - fill_o = True - else: - fill_o = False + fill_o = bool(mobject.fill_opacity) for _ in range(self.n_mobs): mob = mobject.copy() @@ -84,7 +82,7 @@ def __init__( mob.move_to(self.focal_point) mob.save_state() - mob.set_width(self.initial_width) + mob.set(width=self.initial_width) if fill_o: mob.set_opacity(self.initial_opacity) diff --git a/manim/animation/speedmodifier.py b/manim/animation/speedmodifier.py new file mode 100644 index 0000000000..b8ccea66d1 --- /dev/null +++ b/manim/animation/speedmodifier.py @@ -0,0 +1,295 @@ +"""Utilities for modifying the speed at which animations are played.""" + +from __future__ import annotations + +import inspect +import types +from typing import TYPE_CHECKING, Callable + +from numpy import piecewise + +from ..animation.animation import Animation, Wait, prepare_animation +from ..animation.composition import AnimationGroup +from ..mobject.mobject import Mobject, _AnimationBuilder +from ..scene.scene import Scene + +if TYPE_CHECKING: + from ..mobject.mobject import Updater + +__all__ = ["ChangeSpeed"] + + +class ChangeSpeed(Animation): + """Modifies the speed of passed animation. + :class:`AnimationGroup` with different ``lag_ratio`` can also be used + which combines multiple animations into one. + The ``run_time`` of the passed animation is changed to modify the speed. + + Parameters + ---------- + anim + Animation of which the speed is to be modified. + speedinfo + Contains nodes (percentage of ``run_time``) and its corresponding speed factor. + rate_func + Overrides ``rate_func`` of passed animation, applied before changing speed. + + Examples + -------- + + .. manim:: SpeedModifierExample + + class SpeedModifierExample(Scene): + def construct(self): + a = Dot().shift(LEFT * 4) + b = Dot().shift(RIGHT * 4) + self.add(a, b) + self.play( + ChangeSpeed( + AnimationGroup( + a.animate(run_time=1).shift(RIGHT * 8), + b.animate(run_time=1).shift(LEFT * 8), + ), + speedinfo={0.3: 1, 0.4: 0.1, 0.6: 0.1, 1: 1}, + rate_func=linear, + ) + ) + + .. manim:: SpeedModifierUpdaterExample + + class SpeedModifierUpdaterExample(Scene): + def construct(self): + a = Dot().shift(LEFT * 4) + self.add(a) + + ChangeSpeed.add_updater(a, lambda x, dt: x.shift(RIGHT * 4 * dt)) + self.play( + ChangeSpeed( + Wait(2), + speedinfo={0.4: 1, 0.5: 0.2, 0.8: 0.2, 1: 1}, + affects_speed_updaters=True, + ) + ) + + .. manim:: SpeedModifierUpdaterExample2 + + class SpeedModifierUpdaterExample2(Scene): + def construct(self): + a = Dot().shift(LEFT * 4) + self.add(a) + + ChangeSpeed.add_updater(a, lambda x, dt: x.shift(RIGHT * 4 * dt)) + self.wait() + self.play( + ChangeSpeed( + Wait(), + speedinfo={1: 0}, + affects_speed_updaters=True, + ) + ) + + """ + + dt = 0 + is_changing_dt = False + + def __init__( + self, + anim: Animation | _AnimationBuilder, + speedinfo: dict[float, float], + rate_func: Callable[[float], float] | None = None, + affects_speed_updaters: bool = True, + **kwargs, + ) -> None: + if issubclass(type(anim), AnimationGroup): + self.anim = type(anim)( + *map(self.setup, anim.animations), + group=anim.group, + run_time=anim.run_time, + rate_func=anim.rate_func, + lag_ratio=anim.lag_ratio, + ) + else: + self.anim = self.setup(anim) + + if affects_speed_updaters: + assert ChangeSpeed.is_changing_dt is False, ( + "Only one animation at a time can play that changes speed (dt) for ChangeSpeed updaters" + ) + ChangeSpeed.is_changing_dt = True + self.t = 0 + self.affects_speed_updaters = affects_speed_updaters + + self.rate_func = self.anim.rate_func if rate_func is None else rate_func + + # A function where, f(0) = 0, f'(0) = initial speed, f'( f-1(1) ) = final speed + # Following function obtained when conditions applied to vertical parabola + self.speed_modifier = lambda x, init_speed, final_speed: ( + (final_speed**2 - init_speed**2) * x**2 / 4 + init_speed * x + ) + + # f-1(1), returns x for which f(x) = 1 in `speed_modifier` function + self.f_inv_1 = lambda init_speed, final_speed: 2 / (init_speed + final_speed) + + # if speed factors for the starting node (0) and the final node (1) are + # not set, set them to 1 and the penultimate factor, respectively + if 0 not in speedinfo: + speedinfo[0] = 1 + if 1 not in speedinfo: + speedinfo[1] = sorted(speedinfo.items())[-1][1] + + self.speedinfo = dict(sorted(speedinfo.items())) + self.functions = [] + self.conditions = [] + + # Get the time taken by amimation if `run_time` is assumed to be 1 + scaled_total_time = self.get_scaled_total_time() + + prevnode = 0 + init_speed = self.speedinfo[0] + curr_time = 0 + for node, final_speed in list(self.speedinfo.items())[1:]: + dur = node - prevnode + + def condition( + t, + curr_time=curr_time, + init_speed=init_speed, + final_speed=final_speed, + dur=dur, + ): + lower_bound = curr_time / scaled_total_time + upper_bound = ( + curr_time + self.f_inv_1(init_speed, final_speed) * dur + ) / scaled_total_time + return lower_bound <= t <= upper_bound + + self.conditions.append(condition) + + def function( + t, + curr_time=curr_time, + init_speed=init_speed, + final_speed=final_speed, + dur=dur, + prevnode=prevnode, + ): + return ( + self.speed_modifier( + (scaled_total_time * t - curr_time) / dur, + init_speed, + final_speed, + ) + * dur + + prevnode + ) + + self.functions.append(function) + + curr_time += self.f_inv_1(init_speed, final_speed) * dur + prevnode = node + init_speed = final_speed + + def func(t): + if t == 1: + ChangeSpeed.is_changing_dt = False + new_t = piecewise( + self.rate_func(t), + [condition(self.rate_func(t)) for condition in self.conditions], + self.functions, + ) + if self.affects_speed_updaters: + ChangeSpeed.dt = (new_t - self.t) * self.anim.run_time + self.t = new_t + return new_t + + self.anim.set_rate_func(func) + + super().__init__( + self.anim.mobject, + rate_func=self.rate_func, + run_time=scaled_total_time * self.anim.run_time, + **kwargs, + ) + + def setup(self, anim): + if type(anim) is Wait: + anim.interpolate = types.MethodType( + lambda self, alpha: self.rate_func(alpha), anim + ) + return prepare_animation(anim) + + def get_scaled_total_time(self) -> float: + """The time taken by the animation under the assumption that the ``run_time`` is 1.""" + prevnode = 0 + init_speed = self.speedinfo[0] + total_time = 0 + for node, final_speed in list(self.speedinfo.items())[1:]: + dur = node - prevnode + total_time += dur * self.f_inv_1(init_speed, final_speed) + prevnode = node + init_speed = final_speed + return total_time + + @classmethod + def add_updater( + cls, + mobject: Mobject, + update_function: Updater, + index: int | None = None, + call_updater: bool = False, + ): + """This static method can be used to apply speed change to updaters. + + This updater will follow speed and rate function of any :class:`.ChangeSpeed` + animation that is playing with ``affects_speed_updaters=True``. By default, + updater functions added via the usual :meth:`.Mobject.add_updater` method + do not respect the change of animation speed. + + Parameters + ---------- + mobject + The mobject to which the updater should be attached. + update_function + The function that is called whenever a new frame is rendered. + index + The position in the list of the mobject's updaters at which the + function should be inserted. + call_updater + If ``True``, calls the update function when attaching it to the + mobject. + + See also + -------- + :class:`.ChangeSpeed` + :meth:`.Mobject.add_updater` + """ + if "dt" in inspect.signature(update_function).parameters: + mobject.add_updater( + lambda mob, dt: update_function( + mob, ChangeSpeed.dt if ChangeSpeed.is_changing_dt else dt + ), + index=index, + call_updater=call_updater, + ) + else: + mobject.add_updater(update_function, index=index, call_updater=call_updater) + + def interpolate(self, alpha: float) -> None: + self.anim.interpolate(alpha) + + def update_mobjects(self, dt: float) -> None: + self.anim.update_mobjects(dt) + + def finish(self) -> None: + ChangeSpeed.is_changing_dt = False + self.anim.finish() + + def begin(self) -> None: + self.anim.begin() + + def clean_up_from_scene(self, scene: Scene) -> None: + self.anim.clean_up_from_scene(scene) + + def _setup_scene(self, scene) -> None: + self.anim._setup_scene(scene) diff --git a/manim/animation/transform.py b/manim/animation/transform.py index 22d2a65d18..aff109ec71 100644 --- a/manim/animation/transform.py +++ b/manim/animation/transform.py @@ -28,7 +28,8 @@ import inspect import types -from typing import TYPE_CHECKING, Any, Callable, Iterable, Sequence +from collections.abc import Iterable, Sequence +from typing import TYPE_CHECKING, Any, Callable import numpy as np @@ -36,7 +37,13 @@ from .. import config from ..animation.animation import Animation -from ..constants import DEFAULT_POINTWISE_FUNCTION_RUN_TIME, DEGREES, ORIGIN, OUT +from ..constants import ( + DEFAULT_POINTWISE_FUNCTION_RUN_TIME, + DEGREES, + ORIGIN, + OUT, + RendererType, +) from ..mobject.mobject import Group, Mobject from ..utils.paths import path_along_arc, path_along_circles from ..utils.rate_functions import smooth, squish_rate_func @@ -46,6 +53,78 @@ class Transform(Animation): + """A Transform transforms a Mobject into a target Mobject. + + Parameters + ---------- + mobject + The :class:`.Mobject` to be transformed. It will be mutated to become the ``target_mobject``. + target_mobject + The target of the transformation. + path_func + A function defining the path that the points of the ``mobject`` are being moved + along until they match the points of the ``target_mobject``, see :mod:`.utils.paths`. + path_arc + The arc angle (in radians) that the points of ``mobject`` will follow to reach + the points of the target if using a circular path arc, see ``path_arc_centers``. + See also :func:`manim.utils.paths.path_along_arc`. + path_arc_axis + The axis to rotate along if using a circular path arc, see ``path_arc_centers``. + path_arc_centers + The center of the circular arcs along which the points of ``mobject`` are + moved by the transformation. + + If this is set and ``path_func`` is not set, then a ``path_along_circles`` path will be generated + using the ``path_arc`` parameters and stored in ``path_func``. If ``path_func`` is set, this and the + other ``path_arc`` fields are set as attributes, but a ``path_func`` is not generated from it. + replace_mobject_with_target_in_scene + Controls which mobject is replaced when the transformation is complete. + + If set to True, ``mobject`` will be removed from the scene and ``target_mobject`` will + replace it. Otherwise, ``target_mobject`` is never added and ``mobject`` just takes its shape. + + Examples + -------- + + .. manim :: TransformPathArc + + class TransformPathArc(Scene): + def construct(self): + def make_arc_path(start, end, arc_angle): + points = [] + p_fn = path_along_arc(arc_angle) + # alpha animates between 0.0 and 1.0, where 0.0 + # is the beginning of the animation and 1.0 is the end. + for alpha in range(0, 11): + points.append(p_fn(start, end, alpha / 10.0)) + path = VMobject(stroke_color=YELLOW) + path.set_points_smoothly(points) + return path + + left = Circle(stroke_color=BLUE_E, fill_opacity=1.0, radius=0.5).move_to(LEFT * 2) + colors = [TEAL_A, TEAL_B, TEAL_C, TEAL_D, TEAL_E, GREEN_A] + # Positive angles move counter-clockwise, negative angles move clockwise. + examples = [-90, 0, 30, 90, 180, 270] + anims = [] + for idx, angle in enumerate(examples): + left_c = left.copy().shift((3 - idx) * UP) + left_c.fill_color = colors[idx] + right_c = left_c.copy().shift(4 * RIGHT) + path_arc = make_arc_path(left_c.get_center(), right_c.get_center(), + arc_angle=angle * DEGREES) + desc = Text('%d°' % examples[idx]).next_to(left_c, LEFT) + # Make the circles in front of the text in front of the arcs. + self.add( + path_arc.set_z_index(1), + desc.set_z_index(2), + left_c.set_z_index(3), + ) + anims.append(Transform(left_c, right_c, path_arc=angle * DEGREES)) + + self.play(*anims, run_time=2) + self.wait() + """ + def __init__( self, mobject: Mobject | None, @@ -61,14 +140,16 @@ def __init__( self.path_arc_centers: np.ndarray = path_arc_centers self.path_arc: float = path_arc - if self.path_arc_centers is not None: + # path_func is a property a few lines below so it doesn't need to be set in any case + if path_func is not None: + self.path_func: Callable = path_func + elif self.path_arc_centers is not None: self.path_func = path_along_circles( path_arc, self.path_arc_centers, self.path_arc_axis, ) - self.path_func: Callable | None = path_func self.replace_mobject_with_target_in_scene: bool = ( replace_mobject_with_target_in_scene ) @@ -117,7 +198,7 @@ def begin(self) -> None: self.target_copy = self.target_mobject.copy() # Note, this potentially changes the structure # of both mobject and target_mobject - if config["renderer"] == "opengl": + if config.renderer == RendererType.OPENGL: self.mobject.align_data_and_family(self.target_copy) else: self.mobject.align_data(self.target_copy) @@ -131,8 +212,7 @@ def create_target(self) -> Mobject: def clean_up_from_scene(self, scene: Scene) -> None: super().clean_up_from_scene(scene) if self.replace_mobject_with_target_in_scene: - scene.remove(self.mobject) - scene.add(self.target_mobject) + scene.replace(self.mobject, self.target_mobject) def get_all_mobjects(self) -> Sequence[Mobject]: return [ @@ -148,7 +228,7 @@ def get_all_families_zipped(self) -> Iterable[tuple]: # more precise typing? self.starting_mobject, self.target_copy, ] - if config["renderer"] == "opengl": + if config.renderer == RendererType.OPENGL: return zip(*(mob.get_family() for mob in mobs)) return zip(*(mob.family_members_with_points() for mob in mobs)) @@ -218,9 +298,7 @@ def __init__(self, mobject: Mobject, target_mobject: Mobject, **kwargs) -> None: class TransformFromCopy(Transform): - """ - Performs a reversed Transform - """ + """Performs a reversed Transform""" def __init__(self, mobject: Mobject, target_mobject: Mobject, **kwargs) -> None: super().__init__(target_mobject, mobject, **kwargs) @@ -351,7 +429,7 @@ def __init__(self, mobject: Mobject, **kwargs) -> None: def check_validity_of_input(self, mobject: Mobject) -> None: if not hasattr(mobject, "target"): raise ValueError( - "MoveToTarget called on mobject" "without attribute 'target'", + "MoveToTarget called on mobjectwithout attribute 'target'", ) @@ -360,6 +438,11 @@ def __init__(self, mobject, methods): self.methods = methods super().__init__(mobject) + def finish(self) -> None: + for method, method_args, method_kwargs in self.methods: + method.__func__(self.mobject, *method_args, **method_kwargs) + super().finish() + class ApplyMethod(Transform): """Animates a mobject by applying a method. @@ -612,6 +695,37 @@ def _init_path_func(self) -> None: class CyclicReplace(Transform): + """An animation moving mobjects cyclically. + + In particular, this means: the first mobject takes the place + of the second mobject, the second one takes the place of + the third mobject, and so on. The last mobject takes the + place of the first one. + + Parameters + ---------- + mobjects + List of mobjects to be transformed. + path_arc + The angle of the arc (in radians) that the mobjects will follow to reach + their target. + kwargs + Further keyword arguments that are passed to :class:`.Transform`. + + Examples + -------- + .. manim :: CyclicReplaceExample + + class CyclicReplaceExample(Scene): + def construct(self): + group = VGroup(Square(), Circle(), Triangle(), Star()) + group.arrange(RIGHT) + self.add(group) + + for _ in range(4): + self.play(CyclicReplace(*group)) + """ + def __init__( self, *mobjects: Mobject, path_arc: float = 90 * DEGREES, **kwargs ) -> None: @@ -720,7 +834,7 @@ def __init__(self, mobject, target_mobject, stretch=True, dim_to_match=1, **kwar self.stretch = stretch self.dim_to_match = dim_to_match mobject.save_state() - if config["renderer"] == "opengl": + if config.renderer == RendererType.OPENGL: group = OpenGLGroup(mobject, target_mobject.copy()) else: group = Group(mobject, target_mobject.copy()) @@ -744,8 +858,14 @@ def begin(self): self.ghost_to(m0, m1) def ghost_to(self, source, target): - """Replaces the source by the target and sets the opacity to 0.""" - source.replace(target, stretch=self.stretch, dim_to_match=self.dim_to_match) + """Replaces the source by the target and sets the opacity to 0. + + If the provided target has no points, and thus a location of [0, 0, 0] + the source will simply fade out where it currently is. + """ + # mobject.replace() does not work if the target has no points. + if target.get_num_points() or target.submobjects: + source.replace(target, stretch=self.stretch, dim_to_match=self.dim_to_match) source.set_opacity(0) def get_all_mobjects(self) -> Sequence[Mobject]: diff --git a/manim/animation/transform_matching_parts.py b/manim/animation/transform_matching_parts.py index 7cac274777..dbf5dd294e 100644 --- a/manim/animation/transform_matching_parts.py +++ b/manim/animation/transform_matching_parts.py @@ -12,6 +12,7 @@ from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVGroup, OpenGLVMobject from .._config import config +from ..constants import RendererType from ..mobject.mobject import Group, Mobject from ..mobject.types.vectorized_mobject import VGroup, VMobject from .composition import AnimationGroup @@ -75,7 +76,6 @@ def __init__( key_map: dict | None = None, **kwargs, ): - if isinstance(mobject, OpenGLVMobject): group_type = OpenGLVGroup elif isinstance(mobject, OpenGLMobject): @@ -122,6 +122,7 @@ def __init__( fade_source.add(source_map[key]) for key in set(target_map).difference(source_map): fade_target.add(target_map[key]) + fade_target_copy = fade_target.copy() if transform_mismatches: if "replace_mobject_with_target_in_scene" not in kwargs: @@ -132,12 +133,12 @@ def __init__( else: anims.append(FadeOut(fade_source, target_position=fade_target, **kwargs)) anims.append( - FadeIn(fade_target.copy(), target_position=fade_target, **kwargs), + FadeIn(fade_target_copy, target_position=fade_target, **kwargs), ) super().__init__(*anims) - self.to_remove = mobject + self.to_remove = [mobject, fade_target_copy] self.to_add = target_mobject def get_shape_map(self, mobject: Mobject) -> dict: @@ -145,7 +146,7 @@ def get_shape_map(self, mobject: Mobject) -> dict: for sm in self.get_mobject_parts(mobject): key = self.get_mobject_key(sm) if key not in shape_map: - if config["renderer"] == "opengl": + if config["renderer"] == RendererType.OPENGL: shape_map[key] = OpenGLVGroup() else: shape_map[key] = VGroup() @@ -153,10 +154,11 @@ def get_shape_map(self, mobject: Mobject) -> dict: return shape_map def clean_up_from_scene(self, scene: Scene) -> None: + # Interpolate all animations back to 0 to ensure source mobjects remain unchanged. for anim in self.animations: anim.interpolate(0) scene.remove(self.mobject) - scene.remove(self.to_remove) + scene.remove(*self.to_remove) scene.add(self.to_add) @staticmethod @@ -223,7 +225,7 @@ def get_mobject_parts(mobject: Mobject) -> list[Mobject]: def get_mobject_key(mobject: Mobject) -> int: mobject.save_state() mobject.center() - mobject.set_height(1) + mobject.set(height=1) result = hash(np.round(mobject.points, 3).tobytes()) mobject.restore() return result diff --git a/manim/animation/updaters/mobject_update_utils.py b/manim/animation/updaters/mobject_update_utils.py index c039b04b8c..213180f3bd 100644 --- a/manim/animation/updaters/mobject_update_utils.py +++ b/manim/animation/updaters/mobject_update_utils.py @@ -15,20 +15,26 @@ import inspect +from typing import TYPE_CHECKING, Callable import numpy as np from manim.constants import DEGREES, RIGHT from manim.mobject.mobject import Mobject +from manim.opengl import OpenGLMobject +from manim.utils.space_ops import normalize +if TYPE_CHECKING: + from manim.animation.animation import Animation -def assert_is_mobject_method(method): + +def assert_is_mobject_method(method: Callable) -> None: assert inspect.ismethod(method) mobject = method.__self__ - assert isinstance(mobject, Mobject) + assert isinstance(mobject, (Mobject, OpenGLMobject)) -def always(method, *args, **kwargs): +def always(method: Callable, *args, **kwargs) -> Mobject: assert_is_mobject_method(method) mobject = method.__self__ func = method.__func__ @@ -36,7 +42,7 @@ def always(method, *args, **kwargs): return mobject -def f_always(method, *arg_generators, **kwargs): +def f_always(method: Callable[[Mobject], None], *arg_generators, **kwargs) -> Mobject: """ More functional version of always, where instead of taking in args, it takes in functions which output @@ -54,59 +60,175 @@ def updater(mob): return mobject -def always_redraw(func): +def always_redraw(func: Callable[[], Mobject]) -> Mobject: + """Redraw the mobject constructed by a function every frame. + + This function returns a mobject with an attached updater that + continuously regenerates the mobject according to the + specified function. + + Parameters + ---------- + func + A function without (required) input arguments that returns + a mobject. + + Examples + -------- + + .. manim:: TangentAnimation + + class TangentAnimation(Scene): + def construct(self): + ax = Axes() + sine = ax.plot(np.sin, color=RED) + alpha = ValueTracker(0) + point = always_redraw( + lambda: Dot( + sine.point_from_proportion(alpha.get_value()), + color=BLUE + ) + ) + tangent = always_redraw( + lambda: TangentLine( + sine, + alpha=alpha.get_value(), + color=YELLOW, + length=4 + ) + ) + self.add(ax, sine, point, tangent) + self.play(alpha.animate.set_value(1), rate_func=linear, run_time=2) + """ mob = func() - mob.add_updater(lambda m: mob.become(func())) + mob.add_updater(lambda _: mob.become(func())) return mob -def always_shift(mobject, direction=RIGHT, rate=0.1): - def normalize(v): - norm = np.linalg.norm(v) - if norm == 0: - return v - return v / norm - +def always_shift( + mobject: Mobject, direction: np.ndarray[np.float64] = RIGHT, rate: float = 0.1 +) -> Mobject: + """A mobject which is continuously shifted along some direction + at a certain rate. + + Parameters + ---------- + mobject + The mobject to shift. + direction + The direction to shift. The vector is normalized, the specified magnitude + is not relevant. + rate + Length in Manim units which the mobject travels in one + second along the specified direction. + + Examples + -------- + + .. manim:: ShiftingSquare + + class ShiftingSquare(Scene): + def construct(self): + sq = Square().set_fill(opacity=1) + tri = Triangle() + VGroup(sq, tri).arrange(LEFT) + + # construct a square which is continuously + # shifted to the right + always_shift(sq, RIGHT, rate=5) + + self.add(sq) + self.play(tri.animate.set_fill(opacity=1)) + """ mobject.add_updater(lambda m, dt: m.shift(dt * rate * normalize(direction))) return mobject -def always_rotate(mobject, rate=20 * DEGREES, **kwargs): +def always_rotate(mobject: Mobject, rate: float = 20 * DEGREES, **kwargs) -> Mobject: + """A mobject which is continuously rotated at a certain rate. + + Parameters + ---------- + mobject + The mobject to be rotated. + rate + The angle which the mobject is rotated by + over one second. + kwags + Further arguments to be passed to :meth:`.Mobject.rotate`. + + Examples + -------- + + .. manim:: SpinningTriangle + + class SpinningTriangle(Scene): + def construct(self): + tri = Triangle().set_fill(opacity=1).set_z_index(2) + sq = Square().to_edge(LEFT) + + # will keep spinning while there is an animation going on + always_rotate(tri, rate=2*PI, about_point=ORIGIN) + + self.add(tri, sq) + self.play(sq.animate.to_edge(RIGHT), rate_func=linear, run_time=1) + """ mobject.add_updater(lambda m, dt: m.rotate(dt * rate, **kwargs)) return mobject -def turn_animation_into_updater(animation, cycle=False, **kwargs): +def turn_animation_into_updater( + animation: Animation, cycle: bool = False, delay: float = 0, **kwargs +) -> Mobject: """ Add an updater to the animation's mobject which applies the interpolation and update functions of the animation If cycle is True, this repeats over and over. Otherwise, the updater will be popped upon completion + + The ``delay`` parameter is the delay (in seconds) before the animation starts.. + + Examples + -------- + + .. manim:: WelcomeToManim + + class WelcomeToManim(Scene): + def construct(self): + words = Text("Welcome to") + banner = ManimBanner().scale(0.5) + VGroup(words, banner).arrange(DOWN) + + turn_animation_into_updater(Write(words, run_time=0.9)) + self.add(words) + self.wait(0.5) + self.play(banner.expand(), run_time=0.5) """ mobject = animation.mobject animation.suspend_mobject_updating = False animation.begin() - animation.total_time = 0 - - def update(m, dt): - run_time = animation.get_run_time() - time_ratio = animation.total_time / run_time - if cycle: - alpha = time_ratio % 1 - else: - alpha = np.clip(time_ratio, 0, 1) - if alpha >= 1: - animation.finish() - m.remove_updater(update) - return - animation.interpolate(alpha) - animation.update_mobjects(dt) + animation.total_time = -delay + + def update(m: Mobject, dt: float): + if animation.total_time >= 0: + run_time = animation.get_run_time() + time_ratio = animation.total_time / run_time + if cycle: + alpha = time_ratio % 1 + else: + alpha = np.clip(time_ratio, 0, 1) + if alpha >= 1: + animation.finish() + m.remove_updater(update) + return + animation.interpolate(alpha) + animation.update_mobjects(dt) animation.total_time += dt mobject.add_updater(update) return mobject -def cycle_animation(animation, **kwargs): +def cycle_animation(animation: Animation, **kwargs) -> Mobject: return turn_animation_into_updater(animation, cycle=True, **kwargs) diff --git a/manim/camera/camera.py b/manim/camera/camera.py index 81dfa78d0e..af5899c5c5 100644 --- a/manim/camera/camera.py +++ b/manim/camera/camera.py @@ -1,6 +1,5 @@ """A camera converts the mobjects contained in a Scene into an array of pixels.""" - from __future__ import annotations __all__ = ["Camera", "BackgroundColoredVMobjectDisplayer"] @@ -9,9 +8,9 @@ import itertools as it import operator as op import pathlib -import time +from collections.abc import Iterable from functools import reduce -from typing import Any +from typing import Any, Callable import cairo import numpy as np @@ -24,12 +23,27 @@ from ..mobject.types.image_mobject import AbstractImageMobject from ..mobject.types.point_cloud_mobject import PMobject from ..mobject.types.vectorized_mobject import VMobject -from ..utils.color import color_to_int_rgba +from ..utils.color import ManimColor, ParsableManimColor, color_to_int_rgba from ..utils.family import extract_mobject_family_members from ..utils.images import get_full_raster_image_path from ..utils.iterables import list_difference_update from ..utils.space_ops import angle_of_vector +LINE_JOIN_MAP = { + LineJointType.AUTO: None, # TODO: this could be improved + LineJointType.ROUND: cairo.LineJoin.ROUND, + LineJointType.BEVEL: cairo.LineJoin.BEVEL, + LineJointType.MITER: cairo.LineJoin.MITER, +} + + +CAP_STYLE_MAP = { + CapStyleType.AUTO: None, # TODO: this could be improved + CapStyleType.ROUND: cairo.LineCap.ROUND, + CapStyleType.BUTT: cairo.LineCap.BUTT, + CapStyleType.SQUARE: cairo.LineCap.SQUARE, +} + class Camera: """Base camera class. @@ -37,50 +51,46 @@ class Camera: This is the object which takes care of what exactly is displayed on screen at any given moment. - Some important configuration values and local variables to note are: - - background_image : :class:`str`, optional + Parameters + ---------- + background_image The path to an image that should be the background image. - If not set, the background is filled with `self.background_color` - - pixel_height : :class:`int`, optional + If not set, the background is filled with :attr:`self.background_color` + background + What :attr:`background` is set to. By default, ``None``. + pixel_height The height of the scene in pixels. - + pixel_width + The width of the scene in pixels. + kwargs + Additional arguments (``background_color``, ``background_opacity``) + to be set. """ def __init__( self, - background_image=None, - frame_center=ORIGIN, - image_mode="RGBA", - n_channels=4, - pixel_array_dtype="uint8", - z_buff_func=lambda m: np.round(m.get_center()[2], 2), - cairo_line_width_multiple=0.01, - use_z_index=True, - background=None, - pixel_height=None, - pixel_width=None, - frame_height=None, - frame_width=None, - frame_rate=None, + background_image: str | None = None, + frame_center: np.ndarray = ORIGIN, + image_mode: str = "RGBA", + n_channels: int = 4, + pixel_array_dtype: str = "uint8", + cairo_line_width_multiple: float = 0.01, + use_z_index: bool = True, + background: np.ndarray | None = None, + pixel_height: int | None = None, + pixel_width: int | None = None, + frame_height: float | None = None, + frame_width: float | None = None, + frame_rate: float | None = None, + background_color: ParsableManimColor | None = None, + background_opacity: float | None = None, **kwargs, ): - """Initialises the Camera. - - Parameters - ---------- - background : optional - What self.background should be, by default None as will be set later. - **kwargs - Any local variables to be set. - """ self.background_image = background_image self.frame_center = frame_center self.image_mode = image_mode self.n_channels = n_channels self.pixel_array_dtype = pixel_array_dtype - self.z_buff_func = z_buff_func self.cairo_line_width_multiple = cairo_line_width_multiple self.use_z_index = use_z_index self.background = background @@ -105,8 +115,14 @@ def __init__( frame_rate = config["frame_rate"] self.frame_rate = frame_rate - for attr in ["background_color", "background_opacity"]: - setattr(self, f"_{attr}", kwargs.get(attr, config[attr])) + if background_color is None: + self._background_color = ManimColor.parse(config["background_color"]) + else: + self._background_color = ManimColor.parse(background_color) + if background_opacity is None: + self._background_opacity = config["background_opacity"] + else: + self._background_opacity = background_opacity # This one is in the same boat as the above, but it doesn't have the # same name as the corresponding key so it has to be handled on its own @@ -149,7 +165,7 @@ def background_opacity(self, alpha): self._background_opacity = alpha self.init_background() - def type_or_raise(self, mobject): + def type_or_raise(self, mobject: Mobject): """Return the type of mobject, if it is a type that can be rendered. If `mobject` is an instance of a class that inherits from a class that @@ -159,7 +175,7 @@ def type_or_raise(self, mobject): Parameters ---------- - mobject : :class:`~.Mobject` + mobject The object to take the type of. Notes @@ -190,15 +206,15 @@ def type_or_raise(self, mobject): return _type raise TypeError(f"Displaying an object of class {_type} is not supported") - def reset_pixel_shape(self, new_height, new_width): + def reset_pixel_shape(self, new_height: float, new_width: float): """This method resets the height and width of a single pixel to the passed new_height and new_width. Parameters ---------- - new_height : int, float + new_height The new height of the entire scene in pixels - new_width : int, float + new_width The new width of the entire scene in pixels """ self.pixel_width = new_width @@ -207,7 +223,7 @@ def reset_pixel_shape(self, new_height, new_width): self.resize_frame_shape() self.reset() - def resize_frame_shape(self, fixed_dimension=0): + def resize_frame_shape(self, fixed_dimension: int = 0): """ Changes frame_shape to match the aspect ratio of the pixels, where fixed_dimension determines @@ -216,7 +232,7 @@ def resize_frame_shape(self, fixed_dimension=0): Parameters ---------- - fixed_dimension : int + fixed_dimension If 0, height is scaled with respect to width else, width is scaled with respect to height. """ @@ -258,14 +274,14 @@ def init_background(self): ) self.background[:, :] = background_rgba - def get_image(self, pixel_array=None): + def get_image(self, pixel_array: np.ndarray | list | tuple | None = None): """Returns an image from the passed pixel array, or from the current frame if the passed pixel array is none. Parameters ---------- - pixel_array : np.array, list, tuple, optional + pixel_array The pixel array from which to get an image, by default None Returns @@ -277,15 +293,17 @@ def get_image(self, pixel_array=None): pixel_array = self.pixel_array return Image.fromarray(pixel_array, mode=self.image_mode) - def convert_pixel_array(self, pixel_array, convert_from_floats=False): + def convert_pixel_array( + self, pixel_array: np.ndarray | list | tuple, convert_from_floats: bool = False + ): """Converts a pixel array from values that have floats in then to proper RGB values. Parameters ---------- - pixel_array : np.array, list, tuple + pixel_array Pixel array to convert. - convert_from_floats : bool, optional + convert_from_floats Whether or not to convert float values to ints, by default False Returns @@ -302,14 +320,16 @@ def convert_pixel_array(self, pixel_array, convert_from_floats=False): ) return retval - def set_pixel_array(self, pixel_array, convert_from_floats=False): + def set_pixel_array( + self, pixel_array: np.ndarray | list | tuple, convert_from_floats: bool = False + ): """Sets the pixel array of the camera to the passed pixel array. Parameters ---------- - pixel_array : np.array, list, tuple + pixel_array The pixel array to convert and then set as the camera's pixel array. - convert_from_floats : bool, optional + convert_from_floats Whether or not to convert float values to proper RGB values, by default False """ converted_array = self.convert_pixel_array(pixel_array, convert_from_floats) @@ -322,21 +342,25 @@ def set_pixel_array(self, pixel_array, convert_from_floats=False): # Set in place self.pixel_array[:, :, :] = converted_array[:, :, :] - def set_background(self, pixel_array, convert_from_floats=False): + def set_background( + self, pixel_array: np.ndarray | list | tuple, convert_from_floats: bool = False + ): """Sets the background to the passed pixel_array after converting to valid RGB values. Parameters ---------- - pixel_array : np.array, list, tuple + pixel_array The pixel array to set the background to. - convert_from_floats : bool, optional + convert_from_floats Whether or not to convert floats values to proper RGB valid ones, by default False """ self.background = self.convert_pixel_array(pixel_array, convert_from_floats) # TODO, this should live in utils, not as a method of Camera - def make_background_from_func(self, coords_to_colors_func): + def make_background_from_func( + self, coords_to_colors_func: Callable[[np.ndarray], np.ndarray] + ): """ Makes a pixel array for the background by using coords_to_colors_func to determine each pixel's color. Each input pixel's color. Each input to coords_to_colors_func is an (x, y) pair in space (in ordinary space coordinates; not @@ -344,7 +368,7 @@ def make_background_from_func(self, coords_to_colors_func): Parameters ---------- - coords_to_colors_func : function + coords_to_colors_func The function whose input is an (x,y) pair of coordinates and whose return values must be the colors for that point @@ -353,7 +377,6 @@ def make_background_from_func(self, coords_to_colors_func): np.array The pixel array which can then be passed to set_background. """ - logger.info("Starting set_background") coords = self.get_coords_of_all_pixels() new_background = np.apply_along_axis(coords_to_colors_func, 2, coords) @@ -361,7 +384,9 @@ def make_background_from_func(self, coords_to_colors_func): return self.convert_pixel_array(new_background, convert_from_floats=True) - def set_background_from_func(self, coords_to_colors_func): + def set_background_from_func( + self, coords_to_colors_func: Callable[[np.ndarray], np.ndarray] + ): """ Sets the background to a pixel array using coords_to_colors_func to determine each pixel's color. Each input pixel's color. Each input to coords_to_colors_func is an (x, y) pair in space (in ordinary space coordinates; not @@ -369,7 +394,7 @@ def set_background_from_func(self, coords_to_colors_func): Parameters ---------- - coords_to_colors_func : function + coords_to_colors_func The function whose input is an (x,y) pair of coordinates and whose return values must be the colors for that point """ @@ -383,7 +408,7 @@ def reset(self): ------- Camera The camera object after setting the pixel array. - """ "" + """ self.set_pixel_array(self.background) return self @@ -394,20 +419,20 @@ def set_frame_to_background(self, background): def get_mobjects_to_display( self, - mobjects, - include_submobjects=True, - excluded_mobjects=None, + mobjects: Iterable[Mobject], + include_submobjects: bool = True, + excluded_mobjects: list | None = None, ): """Used to get the list of mobjects to display with the camera. Parameters ---------- - mobjects : Mobject + mobjects The Mobjects - include_submobjects : bool, optional + include_submobjects Whether or not to include the submobjects of mobjects, by default True - excluded_mobjects : list, optional + excluded_mobjects Any mobjects to exclude, by default None Returns @@ -427,15 +452,15 @@ def get_mobjects_to_display( use_z_index=self.use_z_index, ) mobjects = list_difference_update(mobjects, all_excluded) - return mobjects + return list(mobjects) - def is_in_frame(self, mobject): + def is_in_frame(self, mobject: Mobject): """Checks whether the passed mobject is in frame or not. Parameters ---------- - mobject : Mobject + mobject The mobject for which the checking needs to be done. Returns @@ -472,7 +497,7 @@ def capture_mobject(self, mobject: Mobject, **kwargs: Any): """ return self.capture_mobjects([mobject], **kwargs) - def capture_mobjects(self, mobjects, **kwargs): + def capture_mobjects(self, mobjects: Iterable[Mobject], **kwargs): """Capture mobjects by printing them on :attr:`pixel_array`. This is the essential function that converts the contents of a Scene @@ -480,10 +505,10 @@ def capture_mobjects(self, mobjects, **kwargs): Parameters ---------- - mobjects : :class:`~.Mobject` + mobjects Mobjects to capture. - kwargs : Any + kwargs Keyword arguments to be passed to :meth:`get_mobjects_to_display`. Notes @@ -507,13 +532,13 @@ def capture_mobjects(self, mobjects, **kwargs): # NOTE: None of the methods below have been mentioned outside of their definitions. Their DocStrings are not as # detailed as possible. - def get_cached_cairo_context(self, pixel_array): + def get_cached_cairo_context(self, pixel_array: np.ndarray): """Returns the cached cairo context of the passed pixel array if it exists, and None if it doesn't. Parameters ---------- - pixel_array : np.array + pixel_array The pixel array to check. Returns @@ -523,19 +548,19 @@ def get_cached_cairo_context(self, pixel_array): """ return self.pixel_array_to_cairo_context.get(id(pixel_array), None) - def cache_cairo_context(self, pixel_array, ctx): + def cache_cairo_context(self, pixel_array: np.ndarray, ctx: cairo.Context): """Caches the passed Pixel array into a Cairo Context Parameters ---------- - pixel_array : np.array + pixel_array The pixel array to cache - ctx : cairo.Context + ctx The context to cache it into. """ self.pixel_array_to_cairo_context[id(pixel_array)] = ctx - def get_cairo_context(self, pixel_array): + def get_cairo_context(self, pixel_array: np.ndarray): """Returns the cairo context for a pixel array after caching it to self.pixel_array_to_cairo_context If that array has already been cached, it returns the @@ -543,7 +568,7 @@ def get_cairo_context(self, pixel_array): Parameters ---------- - pixel_array : np.array + pixel_array The Pixel array to get the cairo context of. Returns @@ -580,14 +605,16 @@ def get_cairo_context(self, pixel_array): self.cache_cairo_context(pixel_array, ctx) return ctx - def display_multiple_vectorized_mobjects(self, vmobjects, pixel_array): + def display_multiple_vectorized_mobjects( + self, vmobjects: list, pixel_array: np.ndarray + ): """Displays multiple VMobjects in the pixel_array Parameters ---------- - vmobjects : list + vmobjects list of VMobjects to display - pixel_array : np.array + pixel_array The pixel array """ if len(vmobjects) == 0: @@ -602,29 +629,31 @@ def display_multiple_vectorized_mobjects(self, vmobjects, pixel_array): pixel_array, ) - def display_multiple_non_background_colored_vmobjects(self, vmobjects, pixel_array): + def display_multiple_non_background_colored_vmobjects( + self, vmobjects: list, pixel_array: np.ndarray + ): """Displays multiple VMobjects in the cairo context, as long as they don't have background colors. Parameters ---------- - vmobjects : list + vmobjects list of the VMobjects - pixel_array : np.ndarray + pixel_array The Pixel array to add the VMobjects to. """ ctx = self.get_cairo_context(pixel_array) for vmobject in vmobjects: self.display_vectorized(vmobject, ctx) - def display_vectorized(self, vmobject, ctx): + def display_vectorized(self, vmobject: VMobject, ctx: cairo.Context): """Displays a VMobject in the cairo context Parameters ---------- - vmobject : VMobject + vmobject The Vectorized Mobject to display - ctx : cairo.Context + ctx The cairo context to use. Returns @@ -638,14 +667,14 @@ def display_vectorized(self, vmobject, ctx): self.apply_stroke(ctx, vmobject) return self - def set_cairo_context_path(self, ctx, vmobject): + def set_cairo_context_path(self, ctx: cairo.Context, vmobject: VMobject): """Sets a path for the cairo context with the vmobject passed Parameters ---------- - ctx : cairo.Context + ctx The cairo context - vmobject : VMobject + vmobject The VMobject Returns @@ -672,16 +701,18 @@ def set_cairo_context_path(self, ctx, vmobject): ctx.close_path() return self - def set_cairo_context_color(self, ctx, rgbas, vmobject): + def set_cairo_context_color( + self, ctx: cairo.Context, rgbas: np.ndarray, vmobject: VMobject + ): """Sets the color of the cairo context Parameters ---------- - ctx : cairo.Context + ctx The cairo context - rgbas : np.ndarray + rgbas The RGBA array with which to color the context. - vmobject : VMobject + vmobject The VMobject with which to set the color. Returns @@ -704,14 +735,14 @@ def set_cairo_context_color(self, ctx, rgbas, vmobject): ctx.set_source(pat) return self - def apply_fill(self, ctx, vmobject): + def apply_fill(self, ctx: cairo.Context, vmobject: VMobject): """Fills the cairo context Parameters ---------- - ctx : cairo.Context + ctx The cairo context - vmobject : VMobject + vmobject The VMobject Returns @@ -723,16 +754,18 @@ def apply_fill(self, ctx, vmobject): ctx.fill_preserve() return self - def apply_stroke(self, ctx, vmobject, background=False): + def apply_stroke( + self, ctx: cairo.Context, vmobject: VMobject, background: bool = False + ): """Applies a stroke to the VMobject in the cairo context. Parameters ---------- - ctx : cairo.Context + ctx The cairo context - vmobject : VMobject + vmobject The VMobject - background : bool, optional + background Whether or not to consider the background when applying this stroke width, by default False @@ -752,21 +785,25 @@ def apply_stroke(self, ctx, vmobject, background=False): ctx.set_line_width( width * self.cairo_line_width_multiple - # This ensures lines have constant width as you zoom in on them. * (self.frame_width / self.frame_width), + # This ensures lines have constant width as you zoom in on them. ) + if vmobject.joint_type != LineJointType.AUTO: + ctx.set_line_join(LINE_JOIN_MAP[vmobject.joint_type]) + if vmobject.cap_style != CapStyleType.AUTO: + ctx.set_line_cap(CAP_STYLE_MAP[vmobject.cap_style]) ctx.stroke_preserve() return self - def get_stroke_rgbas(self, vmobject, background=False): + def get_stroke_rgbas(self, vmobject: VMobject, background: bool = False): """Gets the RGBA array for the stroke of the passed VMobject. Parameters ---------- - vmobject : VMobject + vmobject The VMobject - background : bool, optional + background Whether or not to consider the background when getting the stroke RGBAs, by default False @@ -777,12 +814,12 @@ def get_stroke_rgbas(self, vmobject, background=False): """ return vmobject.get_stroke_rgbas(background) - def get_fill_rgbas(self, vmobject): + def get_fill_rgbas(self, vmobject: VMobject): """Returns the RGBA array of the fill of the passed VMobject Parameters ---------- - vmobject : VMobject + vmobject The VMobject Returns @@ -808,14 +845,16 @@ def get_background_colored_vmobject_displayer(self): setattr(self, bcvd, BackgroundColoredVMobjectDisplayer(self)) return getattr(self, bcvd) - def display_multiple_background_colored_vmobjects(self, cvmobjects, pixel_array): + def display_multiple_background_colored_vmobjects( + self, cvmobjects: list, pixel_array: np.ndarray + ): """Displays multiple vmobjects that have the same color as the background. Parameters ---------- - cvmobjects : list + cvmobjects List of Colored VMobjects - pixel_array : np.array + pixel_array The pixel array. Returns @@ -833,14 +872,16 @@ def display_multiple_background_colored_vmobjects(self, cvmobjects, pixel_array) # NOTE: Out of the following methods, only `transform_points_pre_display` and `points_to_pixel_coords` have been mentioned outside of their definitions. # As a result, the other methods do not have as detailed docstrings as would be preferred. - def display_multiple_point_cloud_mobjects(self, pmobjects, pixel_array): + def display_multiple_point_cloud_mobjects( + self, pmobjects: list, pixel_array: np.ndarray + ): """Displays multiple PMobjects by modifying the passed pixel array. Parameters ---------- - pmobjects : list + pmobjects List of PMobjects - pixel_array : np.array + pixel_array The pixel array to modify. """ for pmobject in pmobjects: @@ -852,20 +893,29 @@ def display_multiple_point_cloud_mobjects(self, pmobjects, pixel_array): pixel_array, ) - def display_point_cloud(self, pmobject, points, rgbas, thickness, pixel_array): - """Displays a PMobject by modifying the Pixel array suitably.. + def display_point_cloud( + self, + pmobject: PMobject, + points: list, + rgbas: np.ndarray, + thickness: float, + pixel_array: np.ndarray, + ): + """Displays a PMobject by modifying the pixel array suitably. + TODO: Write a description for the rgbas argument. + Parameters ---------- - pmobject : PMobject + pmobject Point Cloud Mobject - points : list + points The points to display in the point cloud mobject - rgbas : np.array + rgbas - thickness : int, float + thickness The thickness of each point of the PMobject - pixel_array : np.array + pixel_array The pixel array to modify. """ @@ -896,31 +946,35 @@ def display_point_cloud(self, pmobject, points, rgbas, thickness, pixel_array): new_pa[indices] = rgbas pixel_array[:, :] = new_pa.reshape((ph, pw, rgba_len)) - def display_multiple_image_mobjects(self, image_mobjects, pixel_array): + def display_multiple_image_mobjects( + self, image_mobjects: list, pixel_array: np.ndarray + ): """Displays multiple image mobjects by modifying the passed pixel_array. Parameters ---------- - image_mobjects : list + image_mobjects list of ImageMobjects - pixel_array : np.array + pixel_array The pixel array to modify. """ for image_mobject in image_mobjects: self.display_image_mobject(image_mobject, pixel_array) - def display_image_mobject(self, image_mobject: AbstractImageMobject, pixel_array): + def display_image_mobject( + self, image_mobject: AbstractImageMobject, pixel_array: np.ndarray + ): """Displays an ImageMobject by changing the pixel_array suitably. Parameters ---------- - image_mobject : ImageMobject + image_mobject The imageMobject to display - pixel_array : np.ndarray + pixel_array The Pixel array to put the imagemobject in. """ corner_coords = self.points_to_pixel_coords(image_mobject, image_mobject.points) - ul_coords, ur_coords, dl_coords = corner_coords + ul_coords, ur_coords, dl_coords, _ = corner_coords right_vect = ur_coords - ul_coords down_vect = dl_coords - ul_coords center_coords = ul_coords + (right_vect + down_vect) / 2 @@ -928,8 +982,8 @@ def display_image_mobject(self, image_mobject: AbstractImageMobject, pixel_array sub_image = Image.fromarray(image_mobject.get_pixel_array(), mode="RGBA") # Reshape - pixel_width = max(int(pdist([ul_coords, ur_coords])), 1) - pixel_height = max(int(pdist([ul_coords, dl_coords])), 1) + pixel_width = max(int(pdist([ul_coords, ur_coords]).item()), 1) + pixel_height = max(int(pdist([ul_coords, dl_coords]).item()), 1) sub_image = sub_image.resize( (pixel_width, pixel_height), resample=image_mobject.resampling_algorithm, @@ -966,26 +1020,26 @@ def display_image_mobject(self, image_mobject: AbstractImageMobject, pixel_array # Paint on top of existing pixel array self.overlay_PIL_image(pixel_array, full_image) - def overlay_rgba_array(self, pixel_array, new_array): + def overlay_rgba_array(self, pixel_array: np.ndarray, new_array: np.ndarray): """Overlays an RGBA array on top of the given Pixel array. Parameters ---------- - pixel_array : np.array + pixel_array The original pixel array to modify. - new_array : np.array + new_array The new pixel array to overlay. """ self.overlay_PIL_image(pixel_array, self.get_image(new_array)) - def overlay_PIL_image(self, pixel_array, image): + def overlay_PIL_image(self, pixel_array: np.ndarray, image: Image): """Overlays a PIL image on the passed pixel array. Parameters ---------- - pixel_array : np.ndarray + pixel_array The Pixel array - image : PIL.Image + image The Image to overlay. """ pixel_array[:, :] = np.array( @@ -993,13 +1047,13 @@ def overlay_PIL_image(self, pixel_array, image): dtype="uint8", ) - def adjust_out_of_range_points(self, points): + def adjust_out_of_range_points(self, points: np.ndarray): """If any of the points in the passed array are out of the viable range, they are adjusted suitably. Parameters ---------- - points : np.array + points The points to adjust Returns @@ -1061,13 +1115,13 @@ def points_to_pixel_coords( result[:, 1] = shifted_points[:, 1] * height_mult + height_add return result.astype("int") - def on_screen_pixels(self, pixel_coords): + def on_screen_pixels(self, pixel_coords: np.ndarray): """Returns array of pixels that are on the screen from a given array of pixel_coordinates Parameters ---------- - pixel_coords : np.array + pixel_coords The pixel coords to check. Returns @@ -1085,17 +1139,19 @@ def on_screen_pixels(self, pixel_coords): ], ) - def adjusted_thickness(self, thickness): - """ + def adjusted_thickness(self, thickness: float) -> float: + """Computes the adjusted stroke width for a zoomed camera. Parameters ---------- - thickness : int, float + thickness + The stroke width of a mobject. Returns ------- float - + The adjusted stroke width that reflects zooming in with + the camera. """ # TODO: This seems...unsystematic big_sum = op.add(config["pixel_height"], config["pixel_width"]) @@ -1103,12 +1159,13 @@ def adjusted_thickness(self, thickness): factor = big_sum / this_sum return 1 + (thickness - 1) * factor - def get_thickening_nudges(self, thickness): - """ + def get_thickening_nudges(self, thickness: float): + """Determine a list of vectors used to nudge + two-dimensional pixel coordinates. Parameters ---------- - thickness : int, float + thickness Returns ------- @@ -1119,15 +1176,15 @@ def get_thickening_nudges(self, thickness): _range = list(range(-thickness // 2 + 1, thickness // 2 + 1)) return np.array(list(it.product(_range, _range))) - def thickened_coordinates(self, pixel_coords, thickness): + def thickened_coordinates(self, pixel_coords: np.ndarray, thickness: float): """Returns thickened coordinates for a passed array of pixel coords and a thickness to thicken by. Parameters ---------- - pixel_coords : np.array + pixel_coords Pixel coordinates - thickness : int, float + thickness Thickness Returns @@ -1178,13 +1235,16 @@ def get_coords_of_all_pixels(self): # NOTE: The methods of the following class have not been mentioned outside of their definitions. # Their DocStrings are not as detailed as preferred. class BackgroundColoredVMobjectDisplayer: - def __init__(self, camera): - """ - Parameters - ---------- - camera : Camera - Camera object to use. - """ + """Auxiliary class that handles displaying vectorized mobjects with + a set background image. + + Parameters + ---------- + camera + Camera object to use. + """ + + def __init__(self, camera: Camera): self.camera = camera self.file_name_to_pixel_array_map = {} self.pixel_array = np.array(camera.pixel_array) @@ -1195,22 +1255,22 @@ def reset_pixel_array(self): def resize_background_array( self, - background_array, - new_width, - new_height, - mode="RGBA", + background_array: np.ndarray, + new_width: float, + new_height: float, + mode: str = "RGBA", ): """Resizes the pixel array representing the background. Parameters ---------- - background_array : np.array + background_array The pixel - new_width : int, float + new_width The new width of the background - new_height : int, float + new_height The new height of the background - mode : str, optional + mode The PIL image mode, by default "RGBA" Returns @@ -1223,14 +1283,16 @@ def resize_background_array( resized_image = image.resize((new_width, new_height)) return np.array(resized_image) - def resize_background_array_to_match(self, background_array, pixel_array): + def resize_background_array_to_match( + self, background_array: np.ndarray, pixel_array: np.ndarray + ): """Resizes the background array to match the passed pixel array. Parameters ---------- - background_array : np.array + background_array The prospective pixel array. - pixel_array : np.array + pixel_array The pixel array whose width and height should be matched. Returns @@ -1271,12 +1333,12 @@ def get_background_array(self, image: Image.Image | pathlib.Path | str): self.file_name_to_pixel_array_map[image_key] = back_array return back_array - def display(self, *cvmobjects): + def display(self, *cvmobjects: VMobject): """Displays the colored VMobjects. Parameters ---------- - *cvmobjects : VMobject + *cvmobjects The VMobjects Returns diff --git a/manim/camera/mapping_camera.py b/manim/camera/mapping_camera.py index 34561c3d9c..03f0afc3b4 100644 --- a/manim/camera/mapping_camera.py +++ b/manim/camera/mapping_camera.py @@ -64,6 +64,7 @@ def capture_mobjects(self, mobjects, **kwargs): # TODO: Add optional separator borders between cameras (or perhaps peel this off into a # CameraPlusOverlay class) + # TODO, the classes below should likely be deleted class OldMultiCamera(Camera): def __init__(self, *cameras_with_start_positions, **kwargs): diff --git a/manim/camera/moving_camera.py b/manim/camera/moving_camera.py index c0c2ad3d25..1d01d01e22 100644 --- a/manim/camera/moving_camera.py +++ b/manim/camera/moving_camera.py @@ -8,24 +8,18 @@ from __future__ import annotations -__all__ = ["CameraFrame", "MovingCamera"] +__all__ = ["MovingCamera"] + +import numpy as np from .. import config from ..camera.camera import Camera -from ..constants import DOWN, LEFT, ORIGIN, RIGHT, UP +from ..constants import DOWN, LEFT, RIGHT, UP from ..mobject.frame import ScreenRectangle -from ..mobject.types.vectorized_mobject import VGroup +from ..mobject.mobject import Mobject from ..utils.color import WHITE -# TODO, think about how to incorporate perspective -class CameraFrame(VGroup): - def __init__(self, center=ORIGIN, **kwargs): - super().__init__(center=center, **kwargs) - self.width = config["frame_width"] - self.height = config["frame_height"] - - class MovingCamera(Camera): """ Stays in line with the height, width and position of it's 'frame', which is a Rectangle @@ -95,34 +89,34 @@ def frame_center(self): return self.frame.get_center() @frame_height.setter - def frame_height(self, frame_height): + def frame_height(self, frame_height: float): """Sets the height of the frame in MUnits. Parameters ---------- - frame_height : int, float + frame_height The new frame_height. """ self.frame.stretch_to_fit_height(frame_height) @frame_width.setter - def frame_width(self, frame_width): + def frame_width(self, frame_width: float): """Sets the width of the frame in MUnits. Parameters ---------- - frame_width : int, float + frame_width The new frame_width. """ self.frame.stretch_to_fit_width(frame_width) @frame_center.setter - def frame_center(self, frame_center): + def frame_center(self, frame_center: np.ndarray | list | tuple | Mobject): """Sets the centerpoint of the frame. Parameters ---------- - frame_center : np.array, list, tuple, Mobject + frame_center The point to which the frame must be moved. If is of type mobject, the frame will be moved to the center of that mobject. @@ -175,7 +169,13 @@ def get_mobjects_indicating_movement(self): """ return [self.frame] - def auto_zoom(self, mobjects, margin=0, only_mobjects_in_frame=False): + def auto_zoom( + self, + mobjects: list[Mobject], + margin: float = 0, + only_mobjects_in_frame: bool = False, + animate: bool = True, + ): """Zooms on to a given array of mobjects (or a singular mobject) and automatically resizes to frame all the mobjects. @@ -195,11 +195,14 @@ def auto_zoom(self, mobjects, margin=0, only_mobjects_in_frame=False): only_mobjects_in_frame If set to ``True``, only allows focusing on mobjects that are already in frame. + animate + If set to ``False``, applies the changes instead of returning the corresponding animation + Returns ------- - _AnimationBuilder - Returns an animation that zooms the camera view to a given - list of mobjects. + Union[_AnimationBuilder, ScreenRectangle] + _AnimationBuilder that zooms the camera view to a given list of mobjects + or ScreenRectangle with position and size updated to zoomed position. """ scene_critical_x_left = None @@ -242,8 +245,9 @@ def auto_zoom(self, mobjects, margin=0, only_mobjects_in_frame=False): new_width = abs(scene_critical_x_left - scene_critical_x_right) new_height = abs(scene_critical_y_up - scene_critical_y_down) + m_target = self.frame.animate if animate else self.frame # zoom to fit all mobjects along the side that has the largest size if new_width / self.frame.width > new_height / self.frame.height: - return self.frame.animate.set_x(x).set_y(y).set(width=new_width + margin) + return m_target.set_x(x).set_y(y).set(width=new_width + margin) else: - return self.frame.animate.set_x(x).set_y(y).set(height=new_height + margin) + return m_target.set_x(x).set_y(y).set(height=new_height + margin) diff --git a/manim/camera/multi_camera.py b/manim/camera/multi_camera.py index a9eb74969b..a5202135e9 100644 --- a/manim/camera/multi_camera.py +++ b/manim/camera/multi_camera.py @@ -5,6 +5,8 @@ __all__ = ["MultiCamera"] +from manim.mobject.types.image_mobject import ImageMobject + from ..camera.moving_camera import MovingCamera from ..utils.iterables import list_difference_update @@ -14,7 +16,7 @@ class MultiCamera(MovingCamera): def __init__( self, - image_mobjects_from_cameras=None, + image_mobjects_from_cameras: ImageMobject | None = None, allow_cameras_to_capture_their_own_display=False, **kwargs, ): @@ -22,7 +24,7 @@ def __init__( Parameters ---------- - image_mobjects_from_cameras : ImageMobject + image_mobjects_from_cameras kwargs Any valid keyword arguments of MovingCamera. @@ -36,13 +38,13 @@ def __init__( ) super().__init__(**kwargs) - def add_image_mobject_from_camera(self, image_mobject_from_camera): + def add_image_mobject_from_camera(self, image_mobject_from_camera: ImageMobject): """Adds an ImageMobject that's been obtained from the camera into the list ``self.image_mobject_from_cameras`` Parameters ---------- - image_mobject_from_camera : ImageMobject + image_mobject_from_camera The ImageMobject to add to self.image_mobject_from_cameras """ # A silly method to have right now, but maybe there are things diff --git a/manim/camera/three_d_camera.py b/manim/camera/three_d_camera.py index 863cf03e86..f45854e810 100644 --- a/manim/camera/three_d_camera.py +++ b/manim/camera/three_d_camera.py @@ -5,8 +5,11 @@ __all__ = ["ThreeDCamera"] +from typing import Callable + import numpy as np +from manim.mobject.mobject import Mobject from manim.mobject.three_d.three_d_utils import ( get_3d_vmob_end_corner, get_3d_vmob_end_corner_unit_normal, @@ -43,8 +46,6 @@ def __init__( Parameters ---------- - *args - Any argument of Camera *kwargs Any keyword argument of Camera. """ @@ -84,7 +85,8 @@ def capture_mobjects(self, mobjects, **kwargs): super().capture_mobjects(mobjects, **kwargs) def get_value_trackers(self): - """Returns list of ValueTrackers of phi, theta, focal_distance and gamma + """A list of :class:`ValueTrackers <.ValueTracker>` of phi, theta, focal_distance, + gamma and zoom. Returns ------- @@ -197,52 +199,52 @@ def get_zoom(self): """ return self.zoom_tracker.get_value() - def set_phi(self, value): + def set_phi(self, value: float): """Sets the polar angle i.e the angle between Z_AXIS and Camera through ORIGIN in radians. Parameters ---------- - value : int, float + value The new value of the polar angle in radians. """ self.phi_tracker.set_value(value) - def set_theta(self, value): + def set_theta(self, value: float): """Sets the azimuthal angle i.e the angle that spins the camera around Z_AXIS in radians. Parameters ---------- - value : int, float + value The new value of the azimuthal angle in radians. """ self.theta_tracker.set_value(value) - def set_focal_distance(self, value): + def set_focal_distance(self, value: float): """Sets the focal_distance of the Camera. Parameters ---------- - value : int, float + value The focal_distance of the Camera. """ self.focal_distance_tracker.set_value(value) - def set_gamma(self, value): + def set_gamma(self, value: float): """Sets the angle of rotation of the camera about the vector from the ORIGIN to the Camera. Parameters ---------- - value : int, float + value The new angle of rotation of the camera. """ self.gamma_tracker.set_value(value) - def set_zoom(self, value): + def set_zoom(self, value: float): """Sets the zoom amount of the camera. Parameters ---------- - value : int, float + value The zoom amount of the camera. """ self.zoom_tracker.set_value(value) @@ -284,13 +286,13 @@ def generate_rotation_matrix(self): result = np.dot(matrix, result) return result - def project_points(self, points): + def project_points(self, points: np.ndarray | list): """Applies the current rotation_matrix as a projection matrix to the passed array of points. Parameters ---------- - points : np.array, list + points The list of points to project. Returns @@ -321,13 +323,13 @@ def project_points(self, points): points[:, i] *= factor * zoom return points - def project_point(self, point): + def project_point(self, point: list | np.ndarray): """Applies the current rotation_matrix as a projection matrix to the passed point. Parameters ---------- - point : list, np.array + point The point to project. Returns @@ -357,7 +359,10 @@ def transform_points_pre_display( return self.project_points(points) def add_fixed_orientation_mobjects( - self, *mobjects, use_static_center_func=False, center_func=None + self, + *mobjects: Mobject, + use_static_center_func: bool = False, + center_func: Callable[[], np.ndarray] | None = None, ): """This method allows the mobject to have a fixed orientation, even when the camera moves around. @@ -367,15 +372,16 @@ def add_fixed_orientation_mobjects( Parameters ---------- - *mobjects : Mobject + *mobjects The mobject whose orientation must be fixed. - use_static_center_func : bool, optional + use_static_center_func Whether or not to use the function that takes the mobject's center as centerpoint, by default False - center_func : func, optional + center_func The function which returns the centerpoint with respect to which the mobject will be oriented, by default None """ + # This prevents the computation of mobject.get_center # every single time a projection happens def get_static_center_func(mobject): @@ -392,7 +398,7 @@ def get_static_center_func(mobject): for submob in mobject.get_family(): self.fixed_orientation_mobjects[submob] = func - def add_fixed_in_frame_mobjects(self, *mobjects): + def add_fixed_in_frame_mobjects(self, *mobjects: Mobject): """This method allows the mobject to have a fixed position, even when the camera moves around. E.G If it was passed through this method, at the top of the frame, it @@ -402,34 +408,34 @@ def add_fixed_in_frame_mobjects(self, *mobjects): Parameters ---------- - **mobjects : Mobject + **mobjects The mobject to fix in frame. """ for mobject in extract_mobject_family_members(mobjects): self.fixed_in_frame_mobjects.add(mobject) - def remove_fixed_orientation_mobjects(self, *mobjects): + def remove_fixed_orientation_mobjects(self, *mobjects: Mobject): """If a mobject was fixed in its orientation by passing it through :meth:`.add_fixed_orientation_mobjects`, then this undoes that fixing. The Mobject will no longer have a fixed orientation. Parameters ---------- - mobjects : :class:`Mobject` + mobjects The mobjects whose orientation need not be fixed any longer. """ for mobject in extract_mobject_family_members(mobjects): if mobject in self.fixed_orientation_mobjects: del self.fixed_orientation_mobjects[mobject] - def remove_fixed_in_frame_mobjects(self, *mobjects): + def remove_fixed_in_frame_mobjects(self, *mobjects: Mobject): """If a mobject was fixed in frame by passing it through :meth:`.add_fixed_in_frame_mobjects`, then this undoes that fixing. The Mobject will no longer be fixed in frame. Parameters ---------- - mobjects : :class:`Mobject` + mobjects The mobjects which need not be fixed in frame any longer. """ for mobject in extract_mobject_family_members(mobjects): diff --git a/manim/camera/webgl_camera.py b/manim/camera/webgl_camera.py deleted file mode 100644 index adf4203d2e..0000000000 --- a/manim/camera/webgl_camera.py +++ /dev/null @@ -1,35 +0,0 @@ -from __future__ import annotations - -import copy - -from .camera import Camera - - -class WebGLCamera(Camera): - def __init__(self, **kwargs): - super().__init__(self, **kwargs) - self.serialized_frame = [] - self.pixel_array = None - - def display_multiple_non_background_colored_vmobjects(self, vmobjects, _): - for vmobject in vmobjects: - # TODO: Store a proto instead of JSON. - needs_redraw = False - point_hash = hash(tuple(vmobject.points.flatten())) - if vmobject.point_hash != point_hash: - vmobject.point_hash = point_hash - needs_redraw = True - self.serialized_frame.append( - { - "points": vmobject.points.tolist(), - "style": vmobject.get_style(simple=True), - "id": id(vmobject), - "needs_redraw": needs_redraw, - }, - ) - - def reset(self): - self.serialized_frame = [] - - def set_frame_to_background(self, background): - self.serialized_frame = copy.deepcopy(background) diff --git a/manim/cli/__init__.py b/manim/cli/__init__.py index e69de29bb2..f1aa512e02 100644 --- a/manim/cli/__init__.py +++ b/manim/cli/__init__.py @@ -0,0 +1,17 @@ +"""The Manim CLI, and the available commands for ``manim``. + +This page is a work in progress. Please run ``manim`` or ``manim --help`` in +your terminal to find more information on the following commands. + +Available commands +------------------ + +.. autosummary:: + :toctree: ../reference + + cfg + checkhealth + init + plugins + render +""" diff --git a/manim/cli/cfg/group.py b/manim/cli/cfg/group.py index 3cc5b207d6..13834311ab 100644 --- a/manim/cli/cfg/group.py +++ b/manim/cli/cfg/group.py @@ -5,82 +5,106 @@ group. """ + from __future__ import annotations -import os +import contextlib from ast import literal_eval +from pathlib import Path +from typing import Any, cast -import click +import cloup from rich.errors import StyleSyntaxError from rich.style import Style -from ... import console -from ..._config.utils import config_file_paths, make_config_parser -from ...constants import CONTEXT_SETTINGS, EPILOG -from ...utils.file_ops import guarantee_existence, open_file +from manim._config import cli_ctx_settings, console +from manim._config.utils import config_file_paths, make_config_parser +from manim.constants import EPILOG +from manim.utils.file_ops import guarantee_existence, open_file RICH_COLOUR_INSTRUCTIONS: str = """ [red]The default colour is used by the input statement. If left empty, the default colour will be used.[/red] [magenta] For a full list of styles, visit[/magenta] [green]https://rich.readthedocs.io/en/latest/style.html[/green] """ -RICH_NON_STYLE_ENTRIES: str = ["log.width", "log.height", "log.timestamps"] +RICH_NON_STYLE_ENTRIES: list[str] = ["log.width", "log.height", "log.timestamps"] + +__all__ = [ + "value_from_string", + "value_from_string", + "is_valid_style", + "replace_keys", + "cfg", + "write", + "show", + "export", +] def value_from_string(value: str) -> str | int | bool: - """Extracts the literal of proper datatype from a string. + """Extract the literal of proper datatype from a ``value`` string. + Parameters ---------- - value : :class:`str` + value The value to check get the literal from. Returns ------- - Union[:class:`str`, :class:`int`, :class:`bool`] - Returns the literal of appropriate datatype. + :class:`str` | :class:`int` | :class:`bool` + The literal of appropriate datatype. """ - try: + with contextlib.suppress(SyntaxError, ValueError): value = literal_eval(value) - except (SyntaxError, ValueError): - pass return value -def _is_expected_datatype(value: str, expected: str, style: bool = False) -> bool: - """Checks whether `value` is the same datatype as `expected`, - and checks if it is a valid `style` if `style` is true. +def _is_expected_datatype( + value: str, expected: str, validate_style: bool = False +) -> bool: + """Check whether the literal from ``value`` is the same datatype as the + literal from ``expected``. If ``validate_style`` is ``True``, also check if + the style given by ``value`` is valid, according to ``rich``. Parameters ---------- - value : :class:`str` - The string of the value to check (obtained from reading the user input). - expected : :class:`str` - The string of the literal datatype must be matched by `value`. Obtained from - reading the cfg file. - style : :class:`bool`, optional - Whether or not to confirm if `value` is a style, by default False + value + The string of the value to check, obtained from reading the user input. + expected + The string of the literal datatype which must be matched by ``value``. + This is obtained from reading the ``cfg`` file. + validate_style + Whether or not to confirm if ``value`` is a valid style, according to + ``rich``. Default is ``False``. Returns ------- :class:`bool` - Whether or not `value` matches the datatype of `expected`. + Whether or not the literal from ``value`` matches the datatype of the + literal from ``expected``. """ - value = value_from_string(value) - expected = type(value_from_string(expected)) + value_literal = value_from_string(value) + ExpectedLiteralType = type(value_from_string(expected)) - return isinstance(value, expected) and (is_valid_style(value) if style else True) + return isinstance(value_literal, ExpectedLiteralType) and ( + (isinstance(value_literal, str) and is_valid_style(value_literal)) + if validate_style + else True + ) def is_valid_style(style: str) -> bool: - """Checks whether the entered color is a valid color according to rich + """Checks whether the entered color style is valid, according to ``rich``. + Parameters ---------- - style : :class:`str` + style The style to check whether it is valid. + Returns ------- - Boolean - Returns whether it is valid style or not according to rich. + :class:`bool` + Whether the color style is valid or not, according to ``rich``. """ try: Style.parse(style) @@ -89,16 +113,20 @@ def is_valid_style(style: str) -> bool: return False -def replace_keys(default: dict) -> dict: - """Replaces _ to . and vice versa in a dictionary for rich +def replace_keys(default: dict[str, Any]) -> dict[str, Any]: + """Replace ``_`` with ``.`` and vice versa in a dictionary's keys for + ``rich``. + Parameters ---------- - default : :class:`dict` - The dictionary to check and replace + default + The dictionary whose keys will be checked and replaced. + Returns ------- :class:`dict` - The dictionary which is modified by replacing _ with . and vice versa + The dictionary whose keys are modified by replacing ``_`` with ``.`` + and vice versa. """ for key in default: if "_" in key: @@ -114,29 +142,29 @@ def replace_keys(default: dict) -> dict: return default -@click.group( - context_settings=CONTEXT_SETTINGS, +@cloup.group( + context_settings=cli_ctx_settings, invoke_without_command=True, no_args_is_help=True, epilog=EPILOG, help="Manages Manim configuration files.", ) -@click.pass_context -def cfg(ctx): +@cloup.pass_context +def cfg(ctx: cloup.Context) -> None: """Responsible for the cfg subcommand.""" pass -@cfg.command(context_settings=CONTEXT_SETTINGS, no_args_is_help=True) -@click.option( +@cfg.command(context_settings=cli_ctx_settings, no_args_is_help=True) +@cloup.option( "-l", "--level", - type=click.Choice(["user", "cwd"], case_sensitive=False), + type=cloup.Choice(["user", "cwd"], case_sensitive=False), default="cwd", help="Specify if this config is for user or the working directory.", ) -@click.option("-o", "--open", "openfile", is_flag=True) -def write(level: str = None, openfile: bool = False) -> None: +@cloup.option("-o", "--open", "openfile", is_flag=True) +def write(level: str | None = None, openfile: bool = False) -> None: config_paths = config_file_paths() console.print( "[yellow bold]Manim Configuration File Writer[/yellow bold]", @@ -155,7 +183,7 @@ def write(level: str = None, openfile: bool = False) -> None: action = "save this as" for category in parser: console.print(f"{category}", style="bold green underline") - default = parser[category] + default = cast(dict[str, Any], parser[category]) if category == "logger": console.print(RICH_COLOUR_INSTRUCTIONS) default = replace_keys(default) @@ -185,7 +213,7 @@ def write(level: str = None, openfile: bool = False) -> None: """Not enough values in input. You may have added a new entry to default.cfg, in which case you will have to modify write_cfg_subcmd_input to account for it.""", - ) + ) from None if temp: while temp and not _is_expected_datatype( temp, @@ -231,14 +259,14 @@ def write(level: str = None, openfile: bool = False) -> None: cfg_file_path = config_paths[2] guarantee_existence(config_paths[2].parents[0]) console.print(CWD_CONFIG_MSG) - with open(cfg_file_path, "w") as fp: + with cfg_file_path.open("w") as fp: parser.write(fp) if openfile: open_file(cfg_file_path) -@cfg.command(context_settings=CONTEXT_SETTINGS) -def show(): +@cfg.command(context_settings=cli_ctx_settings) +def show() -> None: parser = make_config_parser() rich_non_style_entries = [a.replace(".", "_") for a in RICH_NON_STYLE_ENTRIES] for category in parser: @@ -255,11 +283,12 @@ def show(): console.print("\n") -@cfg.command(context_settings=CONTEXT_SETTINGS) -@click.option("-d", "--directory", default=os.getcwd()) -@click.pass_context -def export(ctx, directory): - if os.path.abspath(directory) == os.path.abspath(os.getcwd()): +@cfg.command(context_settings=cli_ctx_settings) +@cloup.option("-d", "--directory", default=Path.cwd()) +@cloup.pass_context +def export(ctx: cloup.Context, directory: str) -> None: + directory_path = Path(directory) + if directory_path.absolute == Path.cwd().absolute: console.print( """You are reading the config from the same directory you are exporting to. This means that the exported config will overwrite the config for this directory. @@ -271,13 +300,14 @@ def export(ctx, directory): else: proceed = True if proceed: - if not os.path.isdir(directory): + if not directory_path.is_dir(): console.print(f"Creating folder: {directory}.", style="red bold") - os.mkdir(directory) - with open(os.path.join(directory, "manim.cfg"), "w") as outpath: - ctx.invoke(write) - from_path = os.path.join(os.getcwd(), "manim.cfg") - to_path = os.path.join(directory, "manim.cfg") + directory_path.mkdir(parents=True) + + ctx.invoke(write) + from_path = Path.cwd() / "manim.cfg" + to_path = directory_path / "manim.cfg" + console.print(f"Exported final Config at {from_path} to {to_path}.") else: console.print("Aborted...", style="red bold") diff --git a/manim/grpc/impl/__init__.py b/manim/cli/checkhealth/__init__.py similarity index 100% rename from manim/grpc/impl/__init__.py rename to manim/cli/checkhealth/__init__.py diff --git a/manim/cli/checkhealth/checks.py b/manim/cli/checkhealth/checks.py new file mode 100644 index 0000000000..ec9c07dec7 --- /dev/null +++ b/manim/cli/checkhealth/checks.py @@ -0,0 +1,191 @@ +"""Auxiliary module for the checkhealth subcommand, contains +the actual check implementations. +""" + +from __future__ import annotations + +import os +import shutil +from typing import Callable, Protocol, cast + +__all__ = ["HEALTH_CHECKS"] + + +class HealthCheckFunction(Protocol): + description: str + recommendation: str + skip_on_failed: list[str] + post_fail_fix_hook: Callable[..., object] | None + __name__: str + + def __call__(self) -> bool: ... + + +HEALTH_CHECKS: list[HealthCheckFunction] = [] + + +def healthcheck( + description: str, + recommendation: str, + skip_on_failed: list[HealthCheckFunction | str] | None = None, + post_fail_fix_hook: Callable[..., object] | None = None, +) -> Callable[[Callable[[], bool]], HealthCheckFunction]: + """Decorator used for declaring health checks. + + This decorator attaches some data to a function, which is then added to a + a list containing all checks. + + Parameters + ---------- + description + A brief description of this check, displayed when the ``checkhealth`` + subcommand is run. + recommendation + Help text which is displayed in case the check fails. + skip_on_failed + A list of check functions which, if they fail, cause the current check + to be skipped. + post_fail_fix_hook + A function that is meant to (interactively) help to fix the detected + problem, if possible. This is only called upon explicit confirmation of + the user. + + Returns + ------- + Callable[Callable[[], bool], :class:`HealthCheckFunction`] + A decorator which converts a function into a health check function, as + required by the ``checkhealth`` subcommand. + """ + new_skip_on_failed: list[str] + if skip_on_failed is None: + new_skip_on_failed = [] + else: + new_skip_on_failed = [ + skip.__name__ if callable(skip) else skip for skip in skip_on_failed + ] + + def wrapper(func: Callable[[], bool]) -> HealthCheckFunction: + health_func = cast(HealthCheckFunction, func) + health_func.description = description + health_func.recommendation = recommendation + health_func.skip_on_failed = new_skip_on_failed + health_func.post_fail_fix_hook = post_fail_fix_hook + HEALTH_CHECKS.append(health_func) + return health_func + + return wrapper + + +@healthcheck( + description="Checking whether manim is on your PATH", + recommendation=( + "The command is currently not on your system's PATH.\n\n" + "You can work around this by calling the manim module directly " + "via instead of just .\n\n" + "To fix the PATH issue properly: " + "Usually, the Python package installer pip issues a warning " + "during the installation which contains more information. " + "Consider reinstalling manim via " + "followed by to see the warning again, " + "then consult the internet on how to modify your system's " + "PATH variable." + ), +) +def is_manim_on_path() -> bool: + """Check whether ``manim`` is in ``PATH``. + + Returns + ------- + :class:`bool` + Whether ``manim`` is in ``PATH`` or not. + """ + path_to_manim = shutil.which("manim") + return path_to_manim is not None + + +@healthcheck( + description="Checking whether the executable belongs to manim", + recommendation=( + "The command does not belong to your installed version " + "of this library, it likely belongs to manimgl / manimlib.\n\n" + "Run manim via or via , or uninstall " + "and reinstall manim via to fix this." + ), + skip_on_failed=[is_manim_on_path], +) +def is_manim_executable_associated_to_this_library() -> bool: + """Check whether the ``manim`` executable in ``PATH`` is associated to this + library. To verify this, the executable should look like this: + + .. code-block:: python + + #!/.../python + import sys + from manim.__main__ import main + + if __name__ == "__main__": + sys.exit(main()) + + + Returns + ------- + :class:`bool` + Whether the ``manim`` executable in ``PATH`` is associated to this + library or not. + """ + path_to_manim = shutil.which("manim") + assert path_to_manim is not None + with open(path_to_manim, "rb") as manim_binary: + manim_exec = manim_binary.read() + + # first condition below corresponds to the executable being + # some sort of python script. second condition happens when + # the executable is actually a Windows batch file. + return b"manim.__main__" in manim_exec or b'"%~dp0\\manim"' in manim_exec + + +@healthcheck( + description="Checking whether latex is available", + recommendation=( + "Manim cannot find on your system's PATH. " + "You will not be able to use Tex and MathTex mobjects " + "in your scenes.\n\n" + "Consult our installation instructions " + "at https://docs.manim.community/en/stable/installation.html " + "or search the web for instructions on how to install a " + "LaTeX distribution on your operating system." + ), +) +def is_latex_available() -> bool: + """Check whether ``latex`` is in ``PATH`` and can be executed. + + Returns + ------- + :class:`bool` + Whether ``latex`` is in ``PATH`` and can be executed or not. + """ + path_to_latex = shutil.which("latex") + return path_to_latex is not None and os.access(path_to_latex, os.X_OK) + + +@healthcheck( + description="Checking whether dvisvgm is available", + recommendation=( + "Manim could find , but not on your system's " + "PATH. Make sure your installed LaTeX distribution comes with " + "dvisvgm and consider installing a larger distribution if it " + "does not." + ), + skip_on_failed=[is_latex_available], +) +def is_dvisvgm_available() -> bool: + """Check whether ``dvisvgm`` is in ``PATH`` and can be executed. + + Returns + ------- + :class:`bool` + Whether ``dvisvgm`` is in ``PATH`` and can be executed or not. + """ + path_to_dvisvgm = shutil.which("dvisvgm") + return path_to_dvisvgm is not None and os.access(path_to_dvisvgm, os.X_OK) diff --git a/manim/cli/checkhealth/commands.py b/manim/cli/checkhealth/commands.py new file mode 100644 index 0000000000..3750f63d4f --- /dev/null +++ b/manim/cli/checkhealth/commands.py @@ -0,0 +1,90 @@ +"""A CLI utility helping to diagnose problems with +your Manim installation. + +""" + +from __future__ import annotations + +import sys +import timeit + +import click +import cloup + +from manim.cli.checkhealth.checks import HEALTH_CHECKS, HealthCheckFunction + +__all__ = ["checkhealth"] + + +@cloup.command( + context_settings=None, +) +def checkhealth() -> None: + """This subcommand checks whether Manim is installed correctly + and has access to its required (and optional) system dependencies. + """ + click.echo(f"Python executable: {sys.executable}\n") + click.echo("Checking whether your installation of Manim Community is healthy...") + failed_checks: list[HealthCheckFunction] = [] + + for check in HEALTH_CHECKS: + click.echo(f"- {check.description} ... ", nl=False) + if any( + failed_check.__name__ in check.skip_on_failed + for failed_check in failed_checks + ): + click.secho("SKIPPED", fg="blue") + continue + check_result = check() + if check_result: + click.secho("PASSED", fg="green") + else: + click.secho("FAILED", fg="red") + failed_checks.append(check) + + click.echo() + + if failed_checks: + click.echo( + "There are problems with your installation, " + "here are some recommendations to fix them:" + ) + for ind, failed_check in enumerate(failed_checks): + click.echo(failed_check.recommendation) + if ind + 1 < len(failed_checks): + click.confirm("Continue with next recommendation?") + + else: # no problems detected! + click.echo("No problems detected, your installation seems healthy!") + render_test_scene = click.confirm( + "Would you like to render and preview a test scene?" + ) + if render_test_scene: + import manim as mn + + class CheckHealthDemo(mn.Scene): + def _inner_construct(self) -> None: + banner = mn.ManimBanner().shift(mn.UP * 0.5) + self.play(banner.create()) + self.wait(0.5) + self.play(banner.expand()) + self.wait(0.5) + text_left = mn.Text("All systems operational!") + formula_right = mn.MathTex(r"\oint_{\gamma} f(z)~dz = 0") + text_tex_group = mn.VGroup(text_left, formula_right) + text_tex_group.arrange(mn.RIGHT, buff=1).next_to(banner, mn.DOWN) + self.play(mn.Write(text_tex_group)) + self.wait(0.5) + self.play( + mn.FadeOut(banner, shift=mn.UP), + mn.FadeOut(text_tex_group, shift=mn.DOWN), + ) + + def construct(self) -> None: + self.execution_time = timeit.timeit(self._inner_construct, number=1) + + with mn.tempconfig({"preview": True, "disable_caching": True}): + scene = CheckHealthDemo() + scene.render() + + click.echo(f"Scene rendered in {scene.execution_time:.2f} seconds.") diff --git a/manim/cli/default_group.py b/manim/cli/default_group.py new file mode 100644 index 0000000000..579a3e3a05 --- /dev/null +++ b/manim/cli/default_group.py @@ -0,0 +1,199 @@ +"""``DefaultGroup`` allows a subcommand to act as the main command. + +In particular, this class is what allows ``manim`` to act as ``manim render``. + +.. note:: + This is a vendored version of https://github.com/click-contrib/click-default-group/ + under the BSD 3-Clause "New" or "Revised" License. + + This library isn't used as a dependency, as we need to inherit from + :class:`cloup.Group` instead of :class:`click.Group`. +""" + +from __future__ import annotations + +import warnings +from typing import TYPE_CHECKING, Any, Callable + +import cloup + +from manim.utils.deprecation import deprecated + +__all__ = ["DefaultGroup"] + +if TYPE_CHECKING: + from click import Command, Context + + +class DefaultGroup(cloup.Group): + """Invokes a subcommand marked with ``default=True`` if any subcommand is not + chosen. + + Parameters + ---------- + *args + Positional arguments to forward to :class:`cloup.Group`. + **kwargs + Keyword arguments to forward to :class:`cloup.Group`. The keyword + ``ignore_unknown_options`` must be set to ``False``. + + Attributes + ---------- + default_cmd_name : str | None + The name of the default command, if specified through the ``default`` + keyword argument. Otherwise, this is set to ``None``. + default_if_no_args : bool + Whether to include or not the default command, if no command arguments + are supplied. This can be specified through the ``default_if_no_args`` + keyword argument. Default is ``False``. + """ + + def __init__(self, *args: Any, **kwargs: Any): + # To resolve as the default command. + if not kwargs.get("ignore_unknown_options", True): + raise ValueError("Default group accepts unknown options") + self.ignore_unknown_options = True + self.default_cmd_name: str | None = kwargs.pop("default", None) + self.default_if_no_args: bool = kwargs.pop("default_if_no_args", False) + super().__init__(*args, **kwargs) + + def set_default_command(self, command: Command) -> None: + """Sets a command function as the default command. + + Parameters + ---------- + command + The command to set as default. + """ + cmd_name = command.name + self.add_command(command) + self.default_cmd_name = cmd_name + + def parse_args(self, ctx: Context, args: list[str]) -> list[str]: + """Parses the list of ``args`` by forwarding it to + :meth:`cloup.Group.parse_args`. Before doing so, if + :attr:`default_if_no_args` is set to ``True`` and ``args`` is empty, + this function appends to it the name of the default command specified + by :attr:`default_cmd_name`. + + Parameters + ---------- + ctx + The Click context. + args + A list of arguments. If it's empty and :attr:`default_if_no_args` + is ``True``, append the name of the default command to it. + + Returns + ------- + list[str] + The parsed arguments. + """ + if not args and self.default_if_no_args and self.default_cmd_name: + args.insert(0, self.default_cmd_name) + parsed_args: list[str] = super().parse_args(ctx, args) + return parsed_args + + def get_command(self, ctx: Context, cmd_name: str) -> Command | None: + """Get a command function by its name, by forwarding the arguments to + :meth:`cloup.Group.get_command`. If ``cmd_name`` does not match any of + the command names in :attr:`commands`, attempt to get the default command + instead. + + Parameters + ---------- + ctx + The Click context. + cmd_name + The name of the command to get. + + Returns + ------- + :class:`click.Command` | None + The command, if found. Otherwise, ``None``. + """ + if cmd_name not in self.commands and self.default_cmd_name: + # No command name matched. + ctx.meta["arg0"] = cmd_name + cmd_name = self.default_cmd_name + return super().get_command(ctx, cmd_name) + + def resolve_command( + self, ctx: Context, args: list[str] + ) -> tuple[str | None, Command | None, list[str]]: + """Given a list of ``args`` given by a CLI, find a command which + matches the first element, and return its name (``cmd_name``), the + command function itself (``cmd``) and the rest of the arguments which + shall be passed to the function (``cmd_args``). If not found, return + ``None``, ``None`` and the rest of the arguments. + + After resolving the command, if the Click context given by ``ctx`` + contains an ``arg0`` attribute in its :attr:`click.Context.meta` + dictionary, insert it as the first element of the returned + ``cmd_args``. + + Parameters + ---------- + ctx + The Click context. + cmd_name + The name of the command to get. + + Returns + ------- + cmd_name : str | None + The command name, if found. Otherwise, ``None``. + cmd : :class:`click.Command` | None + The command, if found. Otherwise, ``None``. + cmd_args : list[str] + The rest of the arguments to be passed to ``cmd``. + """ + cmd_name, cmd, args = super().resolve_command(ctx, args) + if "arg0" in ctx.meta: + args.insert(0, ctx.meta["arg0"]) + if cmd is not None: + cmd_name = cmd.name + return cmd_name, cmd, args + + @deprecated + def command( + self, *args: Any, **kwargs: Any + ) -> Callable[[Callable[..., object]], Command]: + """Return a decorator which converts any function into the default + subcommand for this :class:`DefaultGroup`. + + .. warning:: + This method is deprecated. Use the ``default`` parameter of + :class:`DefaultGroup` or :meth:`set_default_command` instead. + + Parameters + ---------- + *args + Positional arguments to pass to :meth:`cloup.Group.command`. + **kwargs + Keyword arguments to pass to :meth:`cloup.Group.command`. + + Returns + ------- + Callable[[Callable[..., object]], click.Command] + A decorator which transforms its input into this + :class:`DefaultGroup`'s default subcommand. + """ + default = kwargs.pop("default", False) + decorator: Callable[[Callable[..., object]], Command] = super().command( + *args, **kwargs + ) + if not default: + return decorator + warnings.warn( + "Use default param of DefaultGroup or set_default_command() instead", + DeprecationWarning, + stacklevel=1, + ) + + def _decorator(f: Callable) -> Command: + cmd = decorator(f) + self.set_default_command(cmd) + return cmd + + return _decorator diff --git a/manim/cli/init/commands.py b/manim/cli/init/commands.py index d619730de2..dd9d64837f 100644 --- a/manim/cli/init/commands.py +++ b/manim/cli/init/commands.py @@ -5,30 +5,199 @@ group. """ + from __future__ import annotations +import configparser from pathlib import Path +from typing import Any import click +import cloup + +from manim._config import console +from manim.constants import CONTEXT_SETTINGS, EPILOG, QUALITIES +from manim.utils.file_ops import ( + add_import_statement, + copy_template_files, + get_template_names, + get_template_path, +) + +CFG_DEFAULTS = { + "frame_rate": 30, + "background_color": "BLACK", + "background_opacity": 1, + "scene_names": "Default", + "resolution": (854, 480), +} + +__all__ = ["select_resolution", "update_cfg", "project", "scene"] + + +def select_resolution() -> tuple[int, int]: + """Prompts input of type click.Choice from user. Presents options from QUALITIES constant. + + Returns + ------- + tuple[int, int] + Tuple containing height and width. + """ + resolution_options: list[tuple[int, int]] = [] + for quality in QUALITIES.items(): + resolution_options.append( + (quality[1]["pixel_height"], quality[1]["pixel_width"]), + ) + resolution_options.pop() + choice = click.prompt( + "\nSelect resolution:\n", + type=cloup.Choice([f"{i[0]}p" for i in resolution_options]), + show_default=False, + default="480p", + ) + matches = [res for res in resolution_options if f"{res[0]}p" == choice] + return matches[0] + -from ...constants import CONTEXT_SETTINGS, EPILOG -from ...utils.file_ops import copy_template_files +def update_cfg(cfg_dict: dict[str, Any], project_cfg_path: Path) -> None: + """Update the ``manim.cfg`` file after reading it from the specified + ``project_cfg_path``. + + Parameters + ---------- + cfg_dict + Values used to update ``manim.cfg`` which is found in + ``project_cfg_path``. + project_cfg_path + Path of the ``manim.cfg`` file. + """ + config = configparser.ConfigParser() + config.read(project_cfg_path) + cli_config = config["CLI"] + for key, value in cfg_dict.items(): + if key == "resolution": + cli_config["pixel_height"] = str(value[0]) + cli_config["pixel_width"] = str(value[1]) + else: + cli_config[key] = str(value) + + with project_cfg_path.open("w") as conf: + config.write(conf) -@click.command( +@cloup.command( context_settings=CONTEXT_SETTINGS, epilog=EPILOG, - short_help="""Sets up a new project in current working directory with default settings.\n -It copies files from templates directory and pastes them in the current working dir. -""", ) -def init(): - """Sets up a new project in current working directory with default settings. +@cloup.argument("project_name", type=cloup.Path(path_type=Path), required=False) +@cloup.option( + "-d", + "--default", + "default_settings", + is_flag=True, + help="Default settings for project creation.", + nargs=1, +) +def project(default_settings: bool, **kwargs: Any) -> None: + """Creates a new project. - It copies files from templates directory and pastes them in the current working dir. + PROJECT_NAME is the name of the folder in which the new project will be initialized. """ - cfg = Path("manim.cfg") - if cfg.exists(): - raise FileExistsError(f"\t{cfg} exists\n") + project_name: Path + if kwargs["project_name"]: + project_name = kwargs["project_name"] + else: + project_name = click.prompt("Project Name", type=Path) + + # in the future when implementing a full template system. Choices are going to be saved in some sort of config file for templates + template_name = click.prompt( + "Template", + type=click.Choice(get_template_names(), False), + default="Default", + ) + + if project_name.is_dir(): + console.print( + f"\nFolder [red]{project_name}[/red] exists. Please type another name\n", + ) else: - copy_template_files() + project_name.mkdir() + new_cfg: dict[str, Any] = {} + new_cfg_path = Path.resolve(project_name / "manim.cfg") + + if not default_settings: + for key, value in CFG_DEFAULTS.items(): + if key == "scene_names": + new_cfg[key] = template_name + "Template" + elif key == "resolution": + new_cfg[key] = select_resolution() + else: + new_cfg[key] = click.prompt(f"\n{key}", default=value) + + console.print("\n", new_cfg) + if click.confirm("Do you want to continue?", default=True, abort=True): + copy_template_files(project_name, template_name) + update_cfg(new_cfg, new_cfg_path) + else: + copy_template_files(project_name, template_name) + update_cfg(CFG_DEFAULTS, new_cfg_path) + + +@cloup.command( + context_settings=CONTEXT_SETTINGS, + no_args_is_help=True, + epilog=EPILOG, +) +@cloup.argument("scene_name", type=str, required=True) +@cloup.argument("file_name", type=str, required=False) +def scene(**kwargs: Any) -> None: + """Inserts a SCENE to an existing FILE or creates a new FILE. + + SCENE is the name of the scene that will be inserted. + + FILE is the name of file in which the SCENE will be inserted. + """ + template_name: str = click.prompt( + "template", + type=click.Choice(get_template_names(), False), + default="Default", + ) + scene = (get_template_path() / f"{template_name}.mtp").resolve().read_text() + scene = scene.replace(template_name + "Template", kwargs["scene_name"], 1) + + if kwargs["file_name"]: + file_name = Path(kwargs["file_name"]) + + if file_name.suffix != ".py": + file_name = file_name.with_suffix(file_name.suffix + ".py") + + if file_name.is_file(): + # file exists so we are going to append new scene to that file + with file_name.open("a") as f: + f.write("\n\n\n" + scene) + else: + # file does not exist so we create a new file, append the scene and prepend the import statement + file_name.write_text("\n\n\n" + scene) + + add_import_statement(file_name) + else: + # file name is not provided so we assume it is main.py + # if main.py does not exist we do not continue + with Path("main.py").open("a") as f: + f.write("\n\n\n" + scene) + + +@cloup.group( + context_settings=CONTEXT_SETTINGS, + invoke_without_command=True, + no_args_is_help=True, + epilog=EPILOG, + help="Create a new project or insert a new scene.", +) +@cloup.pass_context +def init(ctx: cloup.Context) -> None: + pass + + +init.add_command(project) +init.add_command(scene) diff --git a/manim/cli/new/group.py b/manim/cli/new/group.py deleted file mode 100644 index d53bcf4690..0000000000 --- a/manim/cli/new/group.py +++ /dev/null @@ -1,190 +0,0 @@ -from __future__ import annotations - -import configparser -from pathlib import Path - -import click - -from ... import console -from ...constants import CONTEXT_SETTINGS, EPILOG, QUALITIES -from ...utils.file_ops import ( - add_import_statement, - copy_template_files, - get_template_names, - get_template_path, -) - -CFG_DEFAULTS = { - "frame_rate": 30, - "background_color": "BLACK", - "background_opacity": 1, - "scene_names": "Default", - "resolution": (854, 480), -} - - -def select_resolution(): - """Prompts input of type click.Choice from user. Presents options from QUALITIES constant. - - Returns - ------- - :class:`tuple` - Tuple containing height and width. - """ - resolution_options = [] - for quality in QUALITIES.items(): - resolution_options.append( - (quality[1]["pixel_height"], quality[1]["pixel_width"]), - ) - resolution_options.pop() - choice = click.prompt( - "\nSelect resolution:\n", - type=click.Choice([f"{i[0]}p" for i in resolution_options]), - show_default=False, - default="480p", - ) - return [res for res in resolution_options if f"{res[0]}p" == choice][0] - - -def update_cfg(cfg_dict, project_cfg_path): - """Updates the manim.cfg file after reading it from the project_cfg_path. - - Parameters - ---------- - cfg : :class:`dict` - values used to update manim.cfg found project_cfg_path. - project_cfg_path : :class:`Path` - Path of manim.cfg file. - """ - config = configparser.ConfigParser() - config.read(project_cfg_path) - cli_config = config["CLI"] - for key, value in cfg_dict.items(): - if key == "resolution": - cli_config["pixel_height"] = str(value[0]) - cli_config["pixel_width"] = str(value[1]) - else: - cli_config[key] = str(value) - - with open(project_cfg_path, "w") as conf: - config.write(conf) - - -@click.command( - context_settings=CONTEXT_SETTINGS, - epilog=EPILOG, -) -@click.argument("project_name", type=Path, required=False) -@click.option( - "-d", - "--default", - "default_settings", - is_flag=True, - help="Default settings for project creation.", - nargs=1, -) -def project(default_settings, **args): - """Creates a new project. - - PROJECT_NAME is the name of the folder in which the new project will be initialized. - """ - if args["project_name"]: - project_name = args["project_name"] - else: - project_name = click.prompt("Project Name", type=Path) - - # in the future when implementing a full template system. Choices are going to be saved in some sort of config file for templates - template_name = click.prompt( - "Template", - type=click.Choice(get_template_names(), False), - default="Default", - ) - - if project_name.is_dir(): - console.print( - f"\nFolder [red]{project_name}[/red] exists. Please type another name\n", - ) - else: - project_name.mkdir() - new_cfg = {} - new_cfg_path = Path.resolve(project_name / "manim.cfg") - - if not default_settings: - for key, value in CFG_DEFAULTS.items(): - if key == "scene_names": - new_cfg[key] = template_name + "Template" - elif key == "resolution": - new_cfg[key] = select_resolution() - else: - new_cfg[key] = click.prompt(f"\n{key}", default=value) - - console.print("\n", new_cfg) - if click.confirm("Do you want to continue?", default=True, abort=True): - copy_template_files(project_name, template_name) - update_cfg(new_cfg, new_cfg_path) - else: - copy_template_files(project_name, template_name) - update_cfg(CFG_DEFAULTS, new_cfg_path) - - -@click.command( - context_settings=CONTEXT_SETTINGS, - no_args_is_help=True, - epilog=EPILOG, -) -@click.argument("scene_name", type=str, required=True) -@click.argument("file_name", type=str, required=False) -def scene(**args): - """Inserts a SCENE to an existing FILE or creates a new FILE. - - SCENE is the name of the scene that will be inserted. - - FILE is the name of file in which the SCENE will be inserted. - """ - if not Path("main.py").exists(): - raise FileNotFoundError(f"{Path('main.py')} : Not a valid project directory.") - - template_name = click.prompt( - "template", - type=click.Choice(get_template_names(), False), - default="Default", - ) - scene = "" - with open(Path.resolve(get_template_path() / f"{template_name}.mtp")) as f: - scene = f.read() - scene = scene.replace(template_name + "Template", args["scene_name"], 1) - - if args["file_name"]: - file_name = Path(args["file_name"] + ".py") - - if file_name.is_file(): - # file exists so we are going to append new scene to that file - with open(file_name, "a") as f: - f.write("\n\n\n" + scene) - else: - # file does not exist so we create a new file, append the scene and prepend the import statement - with open(file_name, "w") as f: - f.write("\n\n\n" + scene) - - add_import_statement(file_name) - else: - # file name is not provided so we assume it is main.py - # if main.py does not exist we do not continue - with open(Path("main.py"), "a") as f: - f.write("\n\n\n" + scene) - - -@click.group( - context_settings=CONTEXT_SETTINGS, - invoke_without_command=True, - no_args_is_help=True, - epilog=EPILOG, - help="Create a new project or insert a new scene.", -) -@click.pass_context -def new(ctx): - pass - - -new.add_command(project) -new.add_command(scene) diff --git a/manim/cli/plugins/commands.py b/manim/cli/plugins/commands.py index 06c4c42e56..994e074242 100644 --- a/manim/cli/plugins/commands.py +++ b/manim/cli/plugins/commands.py @@ -5,27 +5,40 @@ group. """ + from __future__ import annotations -import click +import cloup + +from manim.constants import CONTEXT_SETTINGS, EPILOG +from manim.plugins.plugins_flags import list_plugins -from ...constants import CONTEXT_SETTINGS, EPILOG -from ...plugins.plugins_flags import list_plugins +__all__ = ["plugins"] -@click.command( +@cloup.command( context_settings=CONTEXT_SETTINGS, no_args_is_help=True, epilog=EPILOG, help="Manages Manim plugins.", ) -@click.option( +@cloup.option( "-l", "--list", "list_available", is_flag=True, help="List available plugins.", ) -def plugins(list_available): +def plugins(list_available: bool) -> None: + """Print a list of all available plugins when calling ``manim plugins -l`` + or ``manim plugins --list``. + + Parameters + ---------- + list_available + If the ``-l`` or ``-list`` option is passed to ``manim plugins``, this + parameter will be set to ``True``, which will print a list of all + available plugins. + """ if list_available: list_plugins() diff --git a/manim/cli/render/commands.py b/manim/cli/render/commands.py index f06344dbec..fde82f4970 100644 --- a/manim/cli/render/commands.py +++ b/manim/cli/render/commands.py @@ -5,100 +5,96 @@ can specify options, and arguments for the render command. """ + from __future__ import annotations +import http.client import json import sys +import urllib.error +import urllib.request +from argparse import Namespace from pathlib import Path +from typing import Any, cast -import click import cloup -import requests -from ... import __version__, config, console, error_console, logger -from ...constants import EPILOG -from ...utils.module_ops import scene_classes_from_file -from .ease_of_access_options import ease_of_access_options -from .global_options import global_options -from .output_options import output_options -from .render_options import render_options +from manim import __version__ +from manim._config import ( + config, + console, + error_console, + logger, + tempconfig, +) +from manim.cli.render.ease_of_access_options import ease_of_access_options +from manim.cli.render.global_options import global_options +from manim.cli.render.output_options import output_options +from manim.cli.render.render_options import render_options +from manim.constants import EPILOG, RendererType +from manim.utils.module_ops import scene_classes_from_file + +__all__ = ["render"] + + +class ClickArgs(Namespace): + def __init__(self, args: dict[str, Any]) -> None: + for name in args: + setattr(self, name, args[name]) + + def _get_kwargs(self) -> list[tuple[str, Any]]: + return list(self.__dict__.items()) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, ClickArgs): + return NotImplemented + return vars(self) == vars(other) + + def __contains__(self, key: str) -> bool: + return key in self.__dict__ + + def __repr__(self) -> str: + return str(self.__dict__) @cloup.command( context_settings=None, + no_args_is_help=True, epilog=EPILOG, ) -@click.argument("file", type=Path, required=True) -@click.argument("scene_names", required=False, nargs=-1) +@cloup.argument("file", type=cloup.Path(path_type=Path), required=True) +@cloup.argument("scene_names", required=False, nargs=-1) @global_options @output_options -@render_options # type: ignore +@render_options @ease_of_access_options -def render( - **args, -): +def render(**kwargs: Any) -> ClickArgs | dict[str, Any]: """Render SCENE(S) from the input FILE. FILE is the file path of the script or a config file. SCENES is an optional list of scenes in the file. """ - - if args["use_opengl_renderer"]: - logger.warning( - "--use_opengl_renderer is deprecated, please use --renderer=opengl instead!", - ) - args["renderer"] = "opengl" - - if args["use_webgl_renderer"]: - logger.warning( - "--use_webgl_renderer is deprecated, please use --renderer=webgl instead!", - ) - args["renderer"] = "webgl" - - if args["use_webgl_renderer"] and args["use_opengl_renderer"]: - logger.warning("You may select only one renderer!") - sys.exit() - - if args["save_as_gif"]: + if kwargs["save_as_gif"]: logger.warning("--save_as_gif is deprecated, please use --format=gif instead!") - args["format"] = "gif" + kwargs["format"] = "gif" - if args["save_pngs"]: + if kwargs["save_pngs"]: logger.warning("--save_pngs is deprecated, please use --format=png instead!") - args["format"] = "png" + kwargs["format"] = "png" - if args["show_in_file_browser"]: + if kwargs["show_in_file_browser"]: logger.warning( "The short form of show_in_file_browser is deprecated and will be moved to support --format.", ) - class ClickArgs: - def __init__(self, args): - for name in args: - setattr(self, name, args[name]) - - def _get_kwargs(self): - return list(self.__dict__.items()) - - def __eq__(self, other): - if not isinstance(other, ClickArgs): - return NotImplemented - return vars(self) == vars(other) - - def __contains__(self, key): - return key in self.__dict__ - - def __repr__(self): - return str(self.__dict__) - - click_args = ClickArgs(args) - if args["jupyter"]: + click_args = ClickArgs(kwargs) + if kwargs["jupyter"]: return click_args config.digest_args(click_args) file = Path(config.input_file) - if config.renderer == "opengl": + if config.renderer == RendererType.OPENGL: from manim.renderer.opengl_renderer import OpenGLRenderer try: @@ -106,8 +102,9 @@ def __repr__(self): keep_running = True while keep_running: for SceneClass in scene_classes_from_file(file): - scene = SceneClass(renderer) - rerun = scene.render() + with tempconfig({}): + scene = SceneClass(renderer) + rerun = scene.render() if rerun or config["write_all"]: renderer.num_plays = 0 continue @@ -120,25 +117,12 @@ def __repr__(self): except Exception: error_console.print_exception() sys.exit(1) - elif config.renderer == "webgl": - try: - from manim.grpc.impl import frame_server_impl - - server = frame_server_impl.get(file) - server.start() - server.wait_for_termination() - except ModuleNotFoundError: - console.print( - "Dependencies for the WebGL render are missing. Run " - "pip install manim[webgl_renderer] to install them.", - ) - error_console.print_exception() - sys.exit(1) else: for SceneClass in scene_classes_from_file(file): try: - scene = SceneClass() - scene.render() + with tempconfig({}): + scene = SceneClass() + scene.render() except Exception: error_console.print_exception() sys.exit(1) @@ -146,13 +130,26 @@ def __repr__(self): if config.notify_outdated_version: manim_info_url = "https://pypi.org/pypi/manim/json" warn_prompt = "Cannot check if latest release of manim is installed" - req_info = {} try: - req_info = requests.get(manim_info_url) - req_info.raise_for_status() - - stable = req_info.json()["info"]["version"] + with urllib.request.urlopen( + urllib.request.Request(manim_info_url), + timeout=10, + ) as response: + response = cast(http.client.HTTPResponse, response) + json_data = json.loads(response.read()) + except urllib.error.HTTPError: + logger.debug("HTTP Error: %s", warn_prompt) + except urllib.error.URLError: + logger.debug("URL Error: %s", warn_prompt) + except json.JSONDecodeError: + logger.debug( + "Error while decoding JSON from %r: %s", manim_info_url, warn_prompt + ) + except Exception: + logger.debug("Something went wrong: %s", warn_prompt) + else: + stable = json_data["info"]["version"] if stable != __version__: console.print( f"You are using manim version [red]v{__version__}[/red], but version [green]v{stable}[/green] is available.", @@ -160,16 +157,5 @@ def __repr__(self): console.print( "You should consider upgrading via [yellow]pip install -U manim[/yellow]", ) - except requests.exceptions.HTTPError: - logger.debug(f"HTTP Error: {warn_prompt}") - except requests.exceptions.ConnectionError: - logger.debug(f"Connection Error: {warn_prompt}") - except requests.exceptions.Timeout: - logger.debug(f"Timed Out: {warn_prompt}") - except json.JSONDecodeError: - logger.debug(warn_prompt) - logger.debug(f"Error decoding JSON from {manim_info_url}") - except Exception: - logger.debug(f"Something went wrong: {warn_prompt}") - return args + return kwargs diff --git a/manim/cli/render/ease_of_access_options.py b/manim/cli/render/ease_of_access_options.py index 15cee6f55f..ac5e78f6a7 100644 --- a/manim/cli/render/ease_of_access_options.py +++ b/manim/cli/render/ease_of_access_options.py @@ -1,7 +1,8 @@ from __future__ import annotations -import click -from cloup import option, option_group +from cloup import Choice, option, option_group + +__all__ = ["ease_of_access_options"] ease_of_access_options = option_group( "Ease of access options", @@ -9,7 +10,7 @@ "--progress_bar", default=None, show_default=False, - type=click.Choice( + type=Choice( ["display", "leave", "none"], case_sensitive=False, ), diff --git a/manim/cli/render/global_options.py b/manim/cli/render/global_options.py index b17e4671c2..32f9547b0c 100644 --- a/manim/cli/render/global_options.py +++ b/manim/cli/render/global_options.py @@ -1,28 +1,59 @@ from __future__ import annotations +import logging import re +import sys from typing import TYPE_CHECKING -import click -from cloup import option, option_group - -from ... import logger +from cloup import Choice, option, option_group if TYPE_CHECKING: - from cloup._option_groups import OptionGroupDecorator + from click import Context, Option + +__all__ = ["global_options"] + +logger = logging.getLogger("manim") + + +def validate_gui_location( + ctx: Context, param: Option, value: str | None +) -> tuple[int, int] | None: + """If the ``value`` string is given, extract from it the GUI location, + which should be in any of these formats: 'x;y', 'x,y' or 'x-y'. + + Parameters + ---------- + ctx + The Click context. + param + A Click option. + value + The optional string which will be parsed. + + Returns + ------- + tuple[int, int] | None + If ``value`` is ``None``, the return value is ``None``. Otherwise, it's + the ``(x, y)`` location for the GUI. + Raises + ------ + ValueError + If ``value`` has an invalid format. + """ + if value is None: + return None -def validate_gui_location(ctx, param, value): - if value: - try: - x_offset, y_offset = map(int, re.split(r"[;,\-]", value)) - return (x_offset, y_offset) - except Exception: - logger.error("GUI location option is invalid.") - exit() + try: + x_offset, y_offset = map(int, re.split(r"[;,\-]", value)) + except Exception: + logger.error("GUI location option is invalid.") + sys.exit() + return (x_offset, y_offset) -global_options: OptionGroupDecorator = option_group( + +global_options = option_group( "Global options", option( "-c", @@ -53,7 +84,7 @@ def validate_gui_location(ctx, param, value): option( "-v", "--verbosity", - type=click.Choice( + type=Choice( ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"], case_sensitive=False, ), @@ -102,4 +133,15 @@ def validate_gui_location(ctx, param, value): help="Renders animations without outputting image or video files and disables the window", default=False, ), + option( + "--no_latex_cleanup", + is_flag=True, + help="Prevents deletion of .aux, .dvi, and .log files produced by Tex and MathTex.", + default=False, + ), + option( + "--preview_command", + help="The command used to preview the output file (for example vlc for video files)", + default="", + ), ) diff --git a/manim/cli/render/output_options.py b/manim/cli/render/output_options.py index 33c60b2883..a7613f1565 100644 --- a/manim/cli/render/output_options.py +++ b/manim/cli/render/output_options.py @@ -1,7 +1,8 @@ from __future__ import annotations -import click -from cloup import option, option_group +from cloup import IntRange, Path, option, option_group + +__all__ = ["output_options"] output_options = option_group( "Output options", @@ -15,7 +16,7 @@ option( "-0", "--zero_pad", - type=click.IntRange(0, 9), + type=IntRange(0, 9), default=None, help="Zero padding for PNG file names.", ), @@ -27,13 +28,13 @@ ), option( "--media_dir", - type=click.Path(), + type=Path(), default=None, help="Path to store rendered videos and latex.", ), option( "--log_dir", - type=click.Path(), + type=Path(), help="Path to store render logs.", default=None, ), diff --git a/manim/cli/render/render_options.py b/manim/cli/render/render_options.py index 4bc67f8336..9a31d36ed4 100644 --- a/manim/cli/render/render_options.py +++ b/manim/cli/render/render_options.py @@ -1,39 +1,105 @@ from __future__ import annotations +import logging import re +import sys +from typing import TYPE_CHECKING -import click -from cloup import option, option_group +from cloup import Choice, option, option_group -from manim.constants import QUALITIES +from manim.constants import QUALITIES, RendererType -from ... import logger +if TYPE_CHECKING: + from click import Context, Option +__all__ = ["render_options"] + +logger = logging.getLogger("manim") + + +def validate_scene_range( + ctx: Context, param: Option, value: str | None +) -> tuple[int] | tuple[int, int] | None: + """If the ``value`` string is given, extract from it the scene range, which + should be in any of these formats: 'start', 'start;end', 'start,end' or + 'start-end'. Otherwise, return ``None``. + + Parameters + ---------- + ctx + The Click context. + param + A Click option. + value + The optional string which will be parsed. + + Returns + ------- + tuple[int] | tuple[int, int] | None + If ``value`` is ``None``, the return value is ``None``. Otherwise, it's + the scene range, given by a tuple which may contain a single value + ``start`` or two values ``start`` and ``end``. + + Raises + ------ + ValueError + If ``value`` has an invalid format. + """ + if value is None: + return None -def validate_scene_range(ctx, param, value): try: start = int(value) return (start,) except Exception: pass - if value: - try: - start, end = map(int, re.split(r"[;,\-]", value)) - return start, end - except Exception: - logger.error("Couldn't determine a range for -n option.") - exit() + try: + start, end = map(int, re.split(r"[;,\-]", value)) + except Exception: + logger.error("Couldn't determine a range for -n option.") + sys.exit() + + return start, end + + +def validate_resolution( + ctx: Context, param: Option, value: str | None +) -> tuple[int, int] | None: + """If the ``value`` string is given, extract from it the resolution, which + should be in any of these formats: 'W;H', 'W,H' or 'W-H'. Otherwise, return + ``None``. + Parameters + ---------- + ctx + The Click context. + param + A Click option. + value + The optional string which will be parsed. -def validate_resolution(ctx, param, value): - if value: - try: - start, end = map(int, re.split(r"[;,\-]", value)) - return (start, end) - except Exception: - logger.error("Resolution option is invalid.") - exit() + Returns + ------- + tuple[int, int] | None + If ``value`` is ``None``, the return value is ``None``. Otherwise, it's + the resolution as a ``(W, H)`` tuple. + + Raises + ------ + ValueError + If ``value`` has an invalid format. + """ + if value is None: + return None + + try: + width, height = map(int, re.split(r"[;,\-]", value)) + except Exception: + logger.error("Resolution option is invalid.") + sys.exit() + + return width, height render_options = option_group( @@ -55,23 +121,29 @@ def validate_resolution(ctx, param, value): ), option( "--format", - type=click.Choice(["png", "gif", "mp4", "webm", "mov"], case_sensitive=False), + type=Choice(["png", "gif", "mp4", "webm", "mov"], case_sensitive=False), + default=None, + ), + option( + "-s", + "--save_last_frame", default=None, + is_flag=True, + help="Render and save only the last frame of a scene as a PNG image.", ), - option("-s", "--save_last_frame", is_flag=True, default=None), option( "-q", "--quality", default=None, - type=click.Choice( - list(reversed([q["flag"] for q in QUALITIES.values() if q["flag"]])), # type: ignore + type=Choice( + list(reversed([q["flag"] for q in QUALITIES.values() if q["flag"]])), case_sensitive=False, ), help="Render quality at the follow resolution framerates, respectively: " + ", ".join( reversed( [ - f'{q["pixel_width"]}x{q["pixel_height"]} {q["frame_rate"]}FPS' + f"{q['pixel_width']}x{q['pixel_height']} {q['frame_rate']}FPS" for q in QUALITIES.values() if q["flag"] ] @@ -83,7 +155,7 @@ def validate_resolution(ctx, param, value): "--resolution", callback=validate_resolution, default=None, - help="Resolution in (W,H) for when 16:9 aspect ratio isn't possible.", + help='Resolution in "W,H" for when 16:9 aspect ratio isn\'t possible.', ), option( "--fps", @@ -95,27 +167,12 @@ def validate_resolution(ctx, param, value): ), option( "--renderer", - type=click.Choice(["cairo", "opengl", "webgl"], case_sensitive=False), + type=Choice( + [renderer_type.value for renderer_type in RendererType], + case_sensitive=False, + ), help="Select a renderer for your Scene.", - default=None, - ), - option( - "--use_opengl_renderer", - is_flag=True, - help="Render scenes using OpenGL (Deprecated).", - default=None, - ), - option( - "--use_webgl_renderer", - is_flag=True, - help="Render scenes using the WebGL frontend (Deprecated).", - default=None, - ), - option( - "--webgl_renderer_path", - default=None, - type=click.Path(), - help="The path to the WebGL frontend.", + default="cairo", ), option( "-g", @@ -137,13 +194,6 @@ def validate_resolution(ctx, param, value): is_flag=True, help="Save section videos in addition to movie file.", ), - option( - "-s", - "--save_last_frame", - default=None, - is_flag=True, - help="Save last frame as png (Deprecated).", - ), option( "-t", "--transparent", diff --git a/manim/communitycolors.py b/manim/communitycolors.py deleted file mode 100644 index c68d16e5ee..0000000000 --- a/manim/communitycolors.py +++ /dev/null @@ -1,9 +0,0 @@ -"""The colormap of manim community""" - -from __future__ import annotations - -LOGO_WHITE = "#ece6e2" -LOGO_GREEN = "#87c2a5" -LOGO_BLUE = "#525893" -LOGO_RED = "#e07a5f" -LOGO_BLACK = "#343434" diff --git a/manim/constants.py b/manim/constants.py index 4f0b8e258b..0a3e00da85 100644 --- a/manim/constants.py +++ b/manim/constants.py @@ -1,14 +1,17 @@ -""" -Constant definitions. -""" +"""Constant definitions.""" from __future__ import annotations +from enum import Enum +from typing import TypedDict + import numpy as np -from PIL import Image +from cloup import Context +from PIL.Image import Resampling + +from manim.typing import Vector3D __all__ = [ - "NOT_SETTING_FONT_MSG", "SCENE_NOT_FOUND_MESSAGE", "CHOOSE_NUMBER_MESSAGE", "INVALID_NUMBER_MESSAGE", @@ -60,171 +63,151 @@ "DEFAULT_POINT_DENSITY_1D", "DEFAULT_STROKE_WIDTH", "DEFAULT_FONT_SIZE", + "SCALE_FACTOR_PER_FONT_POINT", "PI", "TAU", "DEGREES", - "FFMPEG_BIN", - "GIF_FILE_EXTENSION", - "FFMPEG_VERBOSITY_MAP", - "VERBOSITY_CHOICES", - "WEBGL_RENDERER_INFO", "QUALITIES", "DEFAULT_QUALITY", - "DEFAULT_QUALITY_SHORT", "EPILOG", - "HELP_OPTIONS", "CONTEXT_SETTINGS", "SHIFT_VALUE", "CTRL_VALUE", + "RendererType", + "LineJointType", + "CapStyleType", ] # Messages -NOT_SETTING_FONT_MSG: str = """ -You haven't set font. -If you are not using English, this may cause text rendering problem. -You set font like: -text = Text('your text', font='your font') -""" -SCENE_NOT_FOUND_MESSAGE: str = """ + +SCENE_NOT_FOUND_MESSAGE = """ {} is not in the script """ -CHOOSE_NUMBER_MESSAGE: str = """ +CHOOSE_NUMBER_MESSAGE = """ Choose number corresponding to desired scene/arguments. (Use comma separated list for multiple entries) Choice(s): """ -INVALID_NUMBER_MESSAGE: str = "Invalid scene numbers have been specified. Aborting." -NO_SCENE_MESSAGE: str = """ +INVALID_NUMBER_MESSAGE = "Invalid scene numbers have been specified. Aborting." +NO_SCENE_MESSAGE = """ There are no scenes inside that module """ # Pango stuff -NORMAL: str = "NORMAL" -ITALIC: str = "ITALIC" -OBLIQUE: str = "OBLIQUE" -BOLD: str = "BOLD" +NORMAL = "NORMAL" +ITALIC = "ITALIC" +OBLIQUE = "OBLIQUE" +BOLD = "BOLD" # Only for Pango from below -THIN: str = "THIN" -ULTRALIGHT: str = "ULTRALIGHT" -LIGHT: str = "LIGHT" -SEMILIGHT: str = "SEMILIGHT" -BOOK: str = "BOOK" -MEDIUM: str = "MEDIUM" -SEMIBOLD: str = "SEMIBOLD" -ULTRABOLD: str = "ULTRABOLD" -HEAVY: str = "HEAVY" -ULTRAHEAVY: str = "ULTRAHEAVY" +THIN = "THIN" +ULTRALIGHT = "ULTRALIGHT" +LIGHT = "LIGHT" +SEMILIGHT = "SEMILIGHT" +BOOK = "BOOK" +MEDIUM = "MEDIUM" +SEMIBOLD = "SEMIBOLD" +ULTRABOLD = "ULTRABOLD" +HEAVY = "HEAVY" +ULTRAHEAVY = "ULTRAHEAVY" RESAMPLING_ALGORITHMS = { - "nearest": Image.NEAREST, - "none": Image.NEAREST, - "lanczos": Image.LANCZOS, - "antialias": Image.LANCZOS, - "bilinear": Image.BILINEAR, - "linear": Image.BILINEAR, - "bicubic": Image.BICUBIC, - "cubic": Image.BICUBIC, - "box": Image.BOX, - "hamming": Image.HAMMING, + "nearest": Resampling.NEAREST, + "none": Resampling.NEAREST, + "lanczos": Resampling.LANCZOS, + "antialias": Resampling.LANCZOS, + "bilinear": Resampling.BILINEAR, + "linear": Resampling.BILINEAR, + "bicubic": Resampling.BICUBIC, + "cubic": Resampling.BICUBIC, + "box": Resampling.BOX, + "hamming": Resampling.HAMMING, } # Geometry: directions -ORIGIN: np.ndarray = np.array((0.0, 0.0, 0.0)) +ORIGIN: Vector3D = np.array((0.0, 0.0, 0.0)) """The center of the coordinate system.""" -UP: np.ndarray = np.array((0.0, 1.0, 0.0)) +UP: Vector3D = np.array((0.0, 1.0, 0.0)) """One unit step in the positive Y direction.""" -DOWN: np.ndarray = np.array((0.0, -1.0, 0.0)) +DOWN: Vector3D = np.array((0.0, -1.0, 0.0)) """One unit step in the negative Y direction.""" -RIGHT: np.ndarray = np.array((1.0, 0.0, 0.0)) +RIGHT: Vector3D = np.array((1.0, 0.0, 0.0)) """One unit step in the positive X direction.""" -LEFT: np.ndarray = np.array((-1.0, 0.0, 0.0)) +LEFT: Vector3D = np.array((-1.0, 0.0, 0.0)) """One unit step in the negative X direction.""" -IN: np.ndarray = np.array((0.0, 0.0, -1.0)) +IN: Vector3D = np.array((0.0, 0.0, -1.0)) """One unit step in the negative Z direction.""" -OUT: np.ndarray = np.array((0.0, 0.0, 1.0)) +OUT: Vector3D = np.array((0.0, 0.0, 1.0)) """One unit step in the positive Z direction.""" # Geometry: axes -X_AXIS: np.ndarray = np.array((1.0, 0.0, 0.0)) -Y_AXIS: np.ndarray = np.array((0.0, 1.0, 0.0)) -Z_AXIS: np.ndarray = np.array((0.0, 0.0, 1.0)) +X_AXIS: Vector3D = np.array((1.0, 0.0, 0.0)) +Y_AXIS: Vector3D = np.array((0.0, 1.0, 0.0)) +Z_AXIS: Vector3D = np.array((0.0, 0.0, 1.0)) # Geometry: useful abbreviations for diagonals -UL: np.ndarray = UP + LEFT +UL: Vector3D = UP + LEFT """One step up plus one step left.""" -UR: np.ndarray = UP + RIGHT +UR: Vector3D = UP + RIGHT """One step up plus one step right.""" -DL: np.ndarray = DOWN + LEFT +DL: Vector3D = DOWN + LEFT """One step down plus one step left.""" -DR: np.ndarray = DOWN + RIGHT +DR: Vector3D = DOWN + RIGHT """One step down plus one step right.""" # Geometry -START_X: int = 30 -START_Y: int = 20 -DEFAULT_DOT_RADIUS: float = 0.08 -DEFAULT_SMALL_DOT_RADIUS: float = 0.04 -DEFAULT_DASH_LENGTH: float = 0.05 -DEFAULT_ARROW_TIP_LENGTH: float = 0.35 +START_X = 30 +START_Y = 20 +DEFAULT_DOT_RADIUS = 0.08 +DEFAULT_SMALL_DOT_RADIUS = 0.04 +DEFAULT_DASH_LENGTH = 0.05 +DEFAULT_ARROW_TIP_LENGTH = 0.35 # Default buffers (padding) -SMALL_BUFF: float = 0.1 -MED_SMALL_BUFF: float = 0.25 -MED_LARGE_BUFF: float = 0.5 -LARGE_BUFF: float = 1 -DEFAULT_MOBJECT_TO_EDGE_BUFFER: float = MED_LARGE_BUFF -DEFAULT_MOBJECT_TO_MOBJECT_BUFFER: float = MED_SMALL_BUFF +SMALL_BUFF = 0.1 +MED_SMALL_BUFF = 0.25 +MED_LARGE_BUFF = 0.5 +LARGE_BUFF = 1 +DEFAULT_MOBJECT_TO_EDGE_BUFFER = MED_LARGE_BUFF +DEFAULT_MOBJECT_TO_MOBJECT_BUFFER = MED_SMALL_BUFF # Times in seconds -DEFAULT_POINTWISE_FUNCTION_RUN_TIME: float = 3.0 -DEFAULT_WAIT_TIME: float = 1.0 +DEFAULT_POINTWISE_FUNCTION_RUN_TIME = 3.0 +DEFAULT_WAIT_TIME = 1.0 # Misc -DEFAULT_POINT_DENSITY_2D: int = 25 -DEFAULT_POINT_DENSITY_1D: int = 10 -DEFAULT_STROKE_WIDTH: int = 4 -DEFAULT_FONT_SIZE: float = 48 +DEFAULT_POINT_DENSITY_2D = 25 +DEFAULT_POINT_DENSITY_1D = 10 +DEFAULT_STROKE_WIDTH = 4 +DEFAULT_FONT_SIZE = 48 +SCALE_FACTOR_PER_FONT_POINT = 1 / 960 # Mathematical constants -PI: float = np.pi +PI = np.pi """The ratio of the circumference of a circle to its diameter.""" -TAU: float = 2 * PI +TAU = 2 * PI """The ratio of the circumference of a circle to its radius.""" -DEGREES: float = TAU / 360 +DEGREES = TAU / 360 """The exchange rate between radians and degrees.""" -# ffmpeg stuff -FFMPEG_BIN: str = "ffmpeg" -# gif stuff -GIF_FILE_EXTENSION: str = ".gif" +class QualityDict(TypedDict): + flag: str | None + pixel_height: int + pixel_width: int + frame_rate: int -FFMPEG_VERBOSITY_MAP: dict[str, str] = { - "DEBUG": "error", - "INFO": "error", - "WARNING": "error", - "ERROR": "error", - "CRITICAL": "fatal", -} -VERBOSITY_CHOICES = FFMPEG_VERBOSITY_MAP.keys() -WEBGL_RENDERER_INFO: str = ( - "The Electron frontend to Manim is hosted at " - "https://github.com/ManimCommunity/manim-renderer. After cloning and building it, " - "you can either start it prior to running Manim or specify the path to the " - "executable with the --webgl_renderer_path flag." -) # Video qualities -QUALITIES: dict[str, dict[str, str | int | None]] = { +QUALITIES: dict[str, QualityDict] = { "fourk_quality": { "flag": "k", "pixel_height": 2160, @@ -263,11 +246,108 @@ }, } -DEFAULT_QUALITY: str = "high_quality" -DEFAULT_QUALITY_SHORT = QUALITIES[DEFAULT_QUALITY]["flag"] +DEFAULT_QUALITY = "high_quality" EPILOG = "Made with <3 by Manim Community developers." -HELP_OPTIONS = ["-h", "--help"] -CONTEXT_SETTINGS = {"help_option_names": HELP_OPTIONS} SHIFT_VALUE = 65505 CTRL_VALUE = 65507 + +CONTEXT_SETTINGS = Context.settings( + align_option_groups=True, + align_sections=True, + show_constraints=True, +) + + +class RendererType(Enum): + """An enumeration of all renderer types that can be assigned to + the ``config.renderer`` attribute. + + Manim's configuration allows assigning string values to the renderer + setting, the values are then replaced by the corresponding enum object. + In other words, you can run:: + + config.renderer = "opengl" + + and checking the renderer afterwards reveals that the attribute has + assumed the value:: + + + """ + + CAIRO = "cairo" #: A renderer based on the cairo backend. + OPENGL = "opengl" #: An OpenGL-based renderer. + + +class LineJointType(Enum): + """Collection of available line joint types. + + See the example below for a visual illustration of the different + joint types. + + Examples + -------- + + .. manim:: LineJointVariants + :save_last_frame: + + class LineJointVariants(Scene): + def construct(self): + mob = VMobject(stroke_width=20, color=GREEN).set_points_as_corners([ + np.array([-2, 0, 0]), + np.array([0, 0, 0]), + np.array([-2, 1, 0]), + ]) + lines = VGroup(*[mob.copy() for _ in range(len(LineJointType))]) + for line, joint_type in zip(lines, LineJointType): + line.joint_type = joint_type + + lines.arrange(RIGHT, buff=1) + self.add(lines) + for line in lines: + label = Text(line.joint_type.name).next_to(line, DOWN) + self.add(label) + """ + + AUTO = 0 + ROUND = 1 + BEVEL = 2 + MITER = 3 + + +class CapStyleType(Enum): + """Collection of available cap styles. + + See the example below for a visual illustration of the different + cap styles. + + Examples + -------- + + .. manim:: CapStyleVariants + :save_last_frame: + + class CapStyleVariants(Scene): + def construct(self): + arcs = VGroup(*[ + Arc( + radius=1, + start_angle=0, + angle=TAU / 4, + stroke_width=20, + color=GREEN, + cap_style=cap_style, + ) + for cap_style in CapStyleType + ]) + arcs.arrange(RIGHT, buff=1) + self.add(arcs) + for arc in arcs: + label = Text(arc.cap_style.name, font_size=24).next_to(arc, DOWN) + self.add(label) + """ + + AUTO = 0 + ROUND = 1 + BUTT = 2 + SQUARE = 3 diff --git a/manim/grpc/gen/__init__.py b/manim/grpc/gen/__init__.py deleted file mode 100644 index 9eeae2a7ff..0000000000 --- a/manim/grpc/gen/__init__.py +++ /dev/null @@ -1,8 +0,0 @@ -# https://github.com/protocolbuffers/protobuf/issues/1491#issuecomment-547504972 - -from __future__ import annotations - -import sys -from pathlib import Path - -sys.path.append(str(Path(__file__).parent)) diff --git a/manim/grpc/gen/frameserver_pb2.py b/manim/grpc/gen/frameserver_pb2.py deleted file mode 100644 index 571eba3459..0000000000 --- a/manim/grpc/gen/frameserver_pb2.py +++ /dev/null @@ -1,1638 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: frameserver.proto -"""Generated protocol buffer code.""" -from __future__ import annotations - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor.FileDescriptor( - name="frameserver.proto", - package="frameserver", - syntax="proto3", - serialized_options=None, - create_key=_descriptor._internal_create_key, - serialized_pb=b'\n\x11\x66rameserver.proto\x12\x0b\x66rameserver"I\n\x16\x46\x65tchSceneDataResponse\x12!\n\x05scene\x18\x01 \x01(\x0b\x32\x12.frameserver.Scene\x12\x0c\n\x04path\x18\x02 \x01(\t"[\n\x05Scene\x12\x0c\n\x04name\x18\x01 \x01(\t\x12*\n\nanimations\x18\x02 \x03(\x0b\x32\x16.frameserver.Animation\x12\x18\n\x10\x62\x61\x63kground_color\x18\x03 \x01(\t"\xfd\x02\n\tAnimation\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x10\n\x08\x64uration\x18\x02 \x01(\x02\x12\x17\n\x0f\x65\x61sing_function\x18\x03 \x01(\t\x12G\n\x14\x61ttribute_tween_data\x18\x04 \x03(\x0b\x32).frameserver.Animation.AttributeTweenData\x12\x43\n\x12mobject_tween_data\x18\x05 \x03(\x0b\x32\'.frameserver.Animation.MobjectTweenData\x12\x1d\n\x15\x66lickered_mobject_ids\x18\x06 \x03(\t\x1aM\n\x12\x41ttributeTweenData\x12\x11\n\tattribute\x18\x01 \x01(\t\x12\x12\n\nstart_data\x18\x02 \x03(\x02\x12\x10\n\x08\x65nd_data\x18\x03 \x03(\x02\x1a;\n\x10MobjectTweenData\x12\n\n\x02id\x18\x01 \x01(\t\x12\x1b\n\x13root_mobject_offset\x18\x02 \x03(\x02"(\n\x07Updater\x12\x1d\n\x15\x66lickered_mobject_ids\x18\x01 \x03(\t"k\n\x0c\x46rameRequest\x12\x11\n\tend_index\x18\x01 \x01(\x05\x12\x15\n\rfirst_request\x18\x02 \x01(\x08\x12\x17\n\x0f\x61nimation_index\x18\x03 \x01(\x05\x12\x18\n\x10\x61nimation_offset\x18\x04 \x01(\x02"u\n\x05Style\x12\x12\n\nfill_color\x18\x01 \x01(\t\x12\x14\n\x0c\x66ill_opacity\x18\x02 \x01(\x02\x12\x14\n\x0cstroke_color\x18\x03 \x01(\t\x12\x16\n\x0estroke_opacity\x18\x04 \x01(\x02\x12\x14\n\x0cstroke_width\x18\x05 \x01(\x02"(\n\x05Point\x12\t\n\x01x\x18\x01 \x01(\x02\x12\t\n\x01y\x18\x02 \x01(\x02\x12\t\n\x01z\x18\x03 \x01(\x02"\xb4\x02\n\x0bMobjectData\x12\n\n\x02id\x18\x01 \x01(\t\x12!\n\x05style\x18\x02 \x01(\x0b\x32\x12.frameserver.Style\x12\x32\n\x04type\x18\x03 \x01(\x0e\x32$.frameserver.MobjectData.MobjectType\x12:\n\x17vectorized_mobject_data\x18\x04 \x01(\x0b\x32\x19.frameserver.VMobjectData\x12\x39\n\x12image_mobject_data\x18\x05 \x01(\x0b\x32\x1d.frameserver.ImageMobjectData\x12\x1b\n\x13root_mobject_offset\x18\x06 \x03(\x02".\n\x0bMobjectType\x12\x0c\n\x08VMOBJECT\x10\x00\x12\x11\n\rIMAGE_MOBJECT\x10\x01"H\n\x0cVMobjectData\x12"\n\x06points\x18\x01 \x03(\x0b\x32\x12.frameserver.Point\x12\x14\n\x0cneeds_redraw\x18\x02 \x01(\x08"c\n\x10ImageMobjectData\x12\x0c\n\x04path\x18\x01 \x01(\t\x12\x0e\n\x06height\x18\x02 \x01(\x02\x12\r\n\x05width\x18\x03 \x01(\x02\x12"\n\x06\x63\x65nter\x18\x04 \x01(\x0b\x32\x12.frameserver.Point"l\n\tFrameData\x12\x0e\n\x06remove\x18\x01 \x03(\t\x12%\n\x03\x61\x64\x64\x18\x02 \x03(\x0b\x32\x18.frameserver.MobjectData\x12(\n\x06update\x18\x03 \x03(\x0b\x32\x18.frameserver.MobjectData"\xfa\x01\n\rFrameResponse\x12*\n\nframe_data\x18\x01 \x01(\x0b\x32\x16.frameserver.FrameData\x12\x16\n\x0escene_finished\x18\x02 \x01(\x08\x12*\n\nanimations\x18\x03 \x03(\x0b\x32\x16.frameserver.Animation\x12&\n\x08updaters\x18\x04 \x03(\x0b\x32\x14.frameserver.Updater\x12\x17\n\x0f\x61nimation_index\x18\x05 \x01(\x05\x12\x18\n\x10\x61nimation_offset\x18\x06 \x01(\x02\x12\x1e\n\x16\x61ll_animations_tweened\x18\x07 \x01(\x08"\x0e\n\x0c\x45mptyRequest"\x0f\n\rEmptyResponse2\xf0\x01\n\x0b\x46rameServer\x12G\n\x0eGetFrameAtTime\x12\x19.frameserver.FrameRequest\x1a\x1a.frameserver.FrameResponse\x12P\n\x0e\x46\x65tchSceneData\x12\x19.frameserver.EmptyRequest\x1a#.frameserver.FetchSceneDataResponse\x12\x46\n\rScriptUpdated\x12\x19.frameserver.EmptyRequest\x1a\x1a.frameserver.EmptyResponseb\x06proto3', -) - - -_MOBJECTDATA_MOBJECTTYPE = _descriptor.EnumDescriptor( - name="MobjectType", - full_name="frameserver.MobjectData.MobjectType", - filename=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - values=[ - _descriptor.EnumValueDescriptor( - name="VMOBJECT", - index=0, - number=0, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.EnumValueDescriptor( - name="IMAGE_MOBJECT", - index=1, - number=1, - serialized_options=None, - type=None, - create_key=_descriptor._internal_create_key, - ), - ], - containing_type=None, - serialized_options=None, - serialized_start=1161, - serialized_end=1207, -) -_sym_db.RegisterEnumDescriptor(_MOBJECTDATA_MOBJECTTYPE) - - -_FETCHSCENEDATARESPONSE = _descriptor.Descriptor( - name="FetchSceneDataResponse", - full_name="frameserver.FetchSceneDataResponse", - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name="scene", - full_name="frameserver.FetchSceneDataResponse.scene", - index=0, - number=1, - type=11, - cpp_type=10, - label=1, - has_default_value=False, - default_value=None, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="path", - full_name="frameserver.FetchSceneDataResponse.path", - index=1, - number=2, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=b"".decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=34, - serialized_end=107, -) - - -_SCENE = _descriptor.Descriptor( - name="Scene", - full_name="frameserver.Scene", - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name="name", - full_name="frameserver.Scene.name", - index=0, - number=1, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=b"".decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="animations", - full_name="frameserver.Scene.animations", - index=1, - number=2, - type=11, - cpp_type=10, - label=3, - has_default_value=False, - default_value=[], - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="background_color", - full_name="frameserver.Scene.background_color", - index=2, - number=3, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=b"".decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=109, - serialized_end=200, -) - - -_ANIMATION_ATTRIBUTETWEENDATA = _descriptor.Descriptor( - name="AttributeTweenData", - full_name="frameserver.Animation.AttributeTweenData", - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name="attribute", - full_name="frameserver.Animation.AttributeTweenData.attribute", - index=0, - number=1, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=b"".decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="start_data", - full_name="frameserver.Animation.AttributeTweenData.start_data", - index=1, - number=2, - type=2, - cpp_type=6, - label=3, - has_default_value=False, - default_value=[], - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="end_data", - full_name="frameserver.Animation.AttributeTweenData.end_data", - index=2, - number=3, - type=2, - cpp_type=6, - label=3, - has_default_value=False, - default_value=[], - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=446, - serialized_end=523, -) - -_ANIMATION_MOBJECTTWEENDATA = _descriptor.Descriptor( - name="MobjectTweenData", - full_name="frameserver.Animation.MobjectTweenData", - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name="id", - full_name="frameserver.Animation.MobjectTweenData.id", - index=0, - number=1, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=b"".decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="root_mobject_offset", - full_name="frameserver.Animation.MobjectTweenData.root_mobject_offset", - index=1, - number=2, - type=2, - cpp_type=6, - label=3, - has_default_value=False, - default_value=[], - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=525, - serialized_end=584, -) - -_ANIMATION = _descriptor.Descriptor( - name="Animation", - full_name="frameserver.Animation", - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name="name", - full_name="frameserver.Animation.name", - index=0, - number=1, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=b"".decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="duration", - full_name="frameserver.Animation.duration", - index=1, - number=2, - type=2, - cpp_type=6, - label=1, - has_default_value=False, - default_value=float(0), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="easing_function", - full_name="frameserver.Animation.easing_function", - index=2, - number=3, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=b"".decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="attribute_tween_data", - full_name="frameserver.Animation.attribute_tween_data", - index=3, - number=4, - type=11, - cpp_type=10, - label=3, - has_default_value=False, - default_value=[], - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="mobject_tween_data", - full_name="frameserver.Animation.mobject_tween_data", - index=4, - number=5, - type=11, - cpp_type=10, - label=3, - has_default_value=False, - default_value=[], - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="flickered_mobject_ids", - full_name="frameserver.Animation.flickered_mobject_ids", - index=5, - number=6, - type=9, - cpp_type=9, - label=3, - has_default_value=False, - default_value=[], - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - ], - extensions=[], - nested_types=[ - _ANIMATION_ATTRIBUTETWEENDATA, - _ANIMATION_MOBJECTTWEENDATA, - ], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=203, - serialized_end=584, -) - - -_UPDATER = _descriptor.Descriptor( - name="Updater", - full_name="frameserver.Updater", - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name="flickered_mobject_ids", - full_name="frameserver.Updater.flickered_mobject_ids", - index=0, - number=1, - type=9, - cpp_type=9, - label=3, - has_default_value=False, - default_value=[], - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=586, - serialized_end=626, -) - - -_FRAMEREQUEST = _descriptor.Descriptor( - name="FrameRequest", - full_name="frameserver.FrameRequest", - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name="end_index", - full_name="frameserver.FrameRequest.end_index", - index=0, - number=1, - type=5, - cpp_type=1, - label=1, - has_default_value=False, - default_value=0, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="first_request", - full_name="frameserver.FrameRequest.first_request", - index=1, - number=2, - type=8, - cpp_type=7, - label=1, - has_default_value=False, - default_value=False, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="animation_index", - full_name="frameserver.FrameRequest.animation_index", - index=2, - number=3, - type=5, - cpp_type=1, - label=1, - has_default_value=False, - default_value=0, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="animation_offset", - full_name="frameserver.FrameRequest.animation_offset", - index=3, - number=4, - type=2, - cpp_type=6, - label=1, - has_default_value=False, - default_value=float(0), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=628, - serialized_end=735, -) - - -_STYLE = _descriptor.Descriptor( - name="Style", - full_name="frameserver.Style", - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name="fill_color", - full_name="frameserver.Style.fill_color", - index=0, - number=1, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=b"".decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="fill_opacity", - full_name="frameserver.Style.fill_opacity", - index=1, - number=2, - type=2, - cpp_type=6, - label=1, - has_default_value=False, - default_value=float(0), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="stroke_color", - full_name="frameserver.Style.stroke_color", - index=2, - number=3, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=b"".decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="stroke_opacity", - full_name="frameserver.Style.stroke_opacity", - index=3, - number=4, - type=2, - cpp_type=6, - label=1, - has_default_value=False, - default_value=float(0), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="stroke_width", - full_name="frameserver.Style.stroke_width", - index=4, - number=5, - type=2, - cpp_type=6, - label=1, - has_default_value=False, - default_value=float(0), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=737, - serialized_end=854, -) - - -_POINT = _descriptor.Descriptor( - name="Point", - full_name="frameserver.Point", - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name="x", - full_name="frameserver.Point.x", - index=0, - number=1, - type=2, - cpp_type=6, - label=1, - has_default_value=False, - default_value=float(0), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="y", - full_name="frameserver.Point.y", - index=1, - number=2, - type=2, - cpp_type=6, - label=1, - has_default_value=False, - default_value=float(0), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="z", - full_name="frameserver.Point.z", - index=2, - number=3, - type=2, - cpp_type=6, - label=1, - has_default_value=False, - default_value=float(0), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=856, - serialized_end=896, -) - - -_MOBJECTDATA = _descriptor.Descriptor( - name="MobjectData", - full_name="frameserver.MobjectData", - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name="id", - full_name="frameserver.MobjectData.id", - index=0, - number=1, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=b"".decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="style", - full_name="frameserver.MobjectData.style", - index=1, - number=2, - type=11, - cpp_type=10, - label=1, - has_default_value=False, - default_value=None, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="type", - full_name="frameserver.MobjectData.type", - index=2, - number=3, - type=14, - cpp_type=8, - label=1, - has_default_value=False, - default_value=0, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="vectorized_mobject_data", - full_name="frameserver.MobjectData.vectorized_mobject_data", - index=3, - number=4, - type=11, - cpp_type=10, - label=1, - has_default_value=False, - default_value=None, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="image_mobject_data", - full_name="frameserver.MobjectData.image_mobject_data", - index=4, - number=5, - type=11, - cpp_type=10, - label=1, - has_default_value=False, - default_value=None, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="root_mobject_offset", - full_name="frameserver.MobjectData.root_mobject_offset", - index=5, - number=6, - type=2, - cpp_type=6, - label=3, - has_default_value=False, - default_value=[], - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - ], - extensions=[], - nested_types=[], - enum_types=[ - _MOBJECTDATA_MOBJECTTYPE, - ], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=899, - serialized_end=1207, -) - - -_VMOBJECTDATA = _descriptor.Descriptor( - name="VMobjectData", - full_name="frameserver.VMobjectData", - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name="points", - full_name="frameserver.VMobjectData.points", - index=0, - number=1, - type=11, - cpp_type=10, - label=3, - has_default_value=False, - default_value=[], - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="needs_redraw", - full_name="frameserver.VMobjectData.needs_redraw", - index=1, - number=2, - type=8, - cpp_type=7, - label=1, - has_default_value=False, - default_value=False, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=1209, - serialized_end=1281, -) - - -_IMAGEMOBJECTDATA = _descriptor.Descriptor( - name="ImageMobjectData", - full_name="frameserver.ImageMobjectData", - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name="path", - full_name="frameserver.ImageMobjectData.path", - index=0, - number=1, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=b"".decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="height", - full_name="frameserver.ImageMobjectData.height", - index=1, - number=2, - type=2, - cpp_type=6, - label=1, - has_default_value=False, - default_value=float(0), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="width", - full_name="frameserver.ImageMobjectData.width", - index=2, - number=3, - type=2, - cpp_type=6, - label=1, - has_default_value=False, - default_value=float(0), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="center", - full_name="frameserver.ImageMobjectData.center", - index=3, - number=4, - type=11, - cpp_type=10, - label=1, - has_default_value=False, - default_value=None, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=1283, - serialized_end=1382, -) - - -_FRAMEDATA = _descriptor.Descriptor( - name="FrameData", - full_name="frameserver.FrameData", - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name="remove", - full_name="frameserver.FrameData.remove", - index=0, - number=1, - type=9, - cpp_type=9, - label=3, - has_default_value=False, - default_value=[], - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="add", - full_name="frameserver.FrameData.add", - index=1, - number=2, - type=11, - cpp_type=10, - label=3, - has_default_value=False, - default_value=[], - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="update", - full_name="frameserver.FrameData.update", - index=2, - number=3, - type=11, - cpp_type=10, - label=3, - has_default_value=False, - default_value=[], - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=1384, - serialized_end=1492, -) - - -_FRAMERESPONSE = _descriptor.Descriptor( - name="FrameResponse", - full_name="frameserver.FrameResponse", - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name="frame_data", - full_name="frameserver.FrameResponse.frame_data", - index=0, - number=1, - type=11, - cpp_type=10, - label=1, - has_default_value=False, - default_value=None, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="scene_finished", - full_name="frameserver.FrameResponse.scene_finished", - index=1, - number=2, - type=8, - cpp_type=7, - label=1, - has_default_value=False, - default_value=False, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="animations", - full_name="frameserver.FrameResponse.animations", - index=2, - number=3, - type=11, - cpp_type=10, - label=3, - has_default_value=False, - default_value=[], - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="updaters", - full_name="frameserver.FrameResponse.updaters", - index=3, - number=4, - type=11, - cpp_type=10, - label=3, - has_default_value=False, - default_value=[], - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="animation_index", - full_name="frameserver.FrameResponse.animation_index", - index=4, - number=5, - type=5, - cpp_type=1, - label=1, - has_default_value=False, - default_value=0, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="animation_offset", - full_name="frameserver.FrameResponse.animation_offset", - index=5, - number=6, - type=2, - cpp_type=6, - label=1, - has_default_value=False, - default_value=float(0), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="all_animations_tweened", - full_name="frameserver.FrameResponse.all_animations_tweened", - index=6, - number=7, - type=8, - cpp_type=7, - label=1, - has_default_value=False, - default_value=False, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=1495, - serialized_end=1745, -) - - -_EMPTYREQUEST = _descriptor.Descriptor( - name="EmptyRequest", - full_name="frameserver.EmptyRequest", - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=1747, - serialized_end=1761, -) - - -_EMPTYRESPONSE = _descriptor.Descriptor( - name="EmptyResponse", - full_name="frameserver.EmptyResponse", - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=1763, - serialized_end=1778, -) - -_FETCHSCENEDATARESPONSE.fields_by_name["scene"].message_type = _SCENE -_SCENE.fields_by_name["animations"].message_type = _ANIMATION -_ANIMATION_ATTRIBUTETWEENDATA.containing_type = _ANIMATION -_ANIMATION_MOBJECTTWEENDATA.containing_type = _ANIMATION -_ANIMATION.fields_by_name[ - "attribute_tween_data" -].message_type = _ANIMATION_ATTRIBUTETWEENDATA -_ANIMATION.fields_by_name[ - "mobject_tween_data" -].message_type = _ANIMATION_MOBJECTTWEENDATA -_MOBJECTDATA.fields_by_name["style"].message_type = _STYLE -_MOBJECTDATA.fields_by_name["type"].enum_type = _MOBJECTDATA_MOBJECTTYPE -_MOBJECTDATA.fields_by_name["vectorized_mobject_data"].message_type = _VMOBJECTDATA -_MOBJECTDATA.fields_by_name["image_mobject_data"].message_type = _IMAGEMOBJECTDATA -_MOBJECTDATA_MOBJECTTYPE.containing_type = _MOBJECTDATA -_VMOBJECTDATA.fields_by_name["points"].message_type = _POINT -_IMAGEMOBJECTDATA.fields_by_name["center"].message_type = _POINT -_FRAMEDATA.fields_by_name["add"].message_type = _MOBJECTDATA -_FRAMEDATA.fields_by_name["update"].message_type = _MOBJECTDATA -_FRAMERESPONSE.fields_by_name["frame_data"].message_type = _FRAMEDATA -_FRAMERESPONSE.fields_by_name["animations"].message_type = _ANIMATION -_FRAMERESPONSE.fields_by_name["updaters"].message_type = _UPDATER -DESCRIPTOR.message_types_by_name["FetchSceneDataResponse"] = _FETCHSCENEDATARESPONSE -DESCRIPTOR.message_types_by_name["Scene"] = _SCENE -DESCRIPTOR.message_types_by_name["Animation"] = _ANIMATION -DESCRIPTOR.message_types_by_name["Updater"] = _UPDATER -DESCRIPTOR.message_types_by_name["FrameRequest"] = _FRAMEREQUEST -DESCRIPTOR.message_types_by_name["Style"] = _STYLE -DESCRIPTOR.message_types_by_name["Point"] = _POINT -DESCRIPTOR.message_types_by_name["MobjectData"] = _MOBJECTDATA -DESCRIPTOR.message_types_by_name["VMobjectData"] = _VMOBJECTDATA -DESCRIPTOR.message_types_by_name["ImageMobjectData"] = _IMAGEMOBJECTDATA -DESCRIPTOR.message_types_by_name["FrameData"] = _FRAMEDATA -DESCRIPTOR.message_types_by_name["FrameResponse"] = _FRAMERESPONSE -DESCRIPTOR.message_types_by_name["EmptyRequest"] = _EMPTYREQUEST -DESCRIPTOR.message_types_by_name["EmptyResponse"] = _EMPTYRESPONSE -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -FetchSceneDataResponse = _reflection.GeneratedProtocolMessageType( - "FetchSceneDataResponse", - (_message.Message,), - { - "DESCRIPTOR": _FETCHSCENEDATARESPONSE, - "__module__": "frameserver_pb2", - # @@protoc_insertion_point(class_scope:frameserver.FetchSceneDataResponse) - }, -) -_sym_db.RegisterMessage(FetchSceneDataResponse) - -Scene = _reflection.GeneratedProtocolMessageType( - "Scene", - (_message.Message,), - { - "DESCRIPTOR": _SCENE, - "__module__": "frameserver_pb2", - # @@protoc_insertion_point(class_scope:frameserver.Scene) - }, -) -_sym_db.RegisterMessage(Scene) - -Animation = _reflection.GeneratedProtocolMessageType( - "Animation", - (_message.Message,), - { - "AttributeTweenData": _reflection.GeneratedProtocolMessageType( - "AttributeTweenData", - (_message.Message,), - { - "DESCRIPTOR": _ANIMATION_ATTRIBUTETWEENDATA, - "__module__": "frameserver_pb2", - # @@protoc_insertion_point(class_scope:frameserver.Animation.AttributeTweenData) - }, - ), - "MobjectTweenData": _reflection.GeneratedProtocolMessageType( - "MobjectTweenData", - (_message.Message,), - { - "DESCRIPTOR": _ANIMATION_MOBJECTTWEENDATA, - "__module__": "frameserver_pb2", - # @@protoc_insertion_point(class_scope:frameserver.Animation.MobjectTweenData) - }, - ), - "DESCRIPTOR": _ANIMATION, - "__module__": "frameserver_pb2", - # @@protoc_insertion_point(class_scope:frameserver.Animation) - }, -) -_sym_db.RegisterMessage(Animation) -_sym_db.RegisterMessage(Animation.AttributeTweenData) -_sym_db.RegisterMessage(Animation.MobjectTweenData) - -Updater = _reflection.GeneratedProtocolMessageType( - "Updater", - (_message.Message,), - { - "DESCRIPTOR": _UPDATER, - "__module__": "frameserver_pb2", - # @@protoc_insertion_point(class_scope:frameserver.Updater) - }, -) -_sym_db.RegisterMessage(Updater) - -FrameRequest = _reflection.GeneratedProtocolMessageType( - "FrameRequest", - (_message.Message,), - { - "DESCRIPTOR": _FRAMEREQUEST, - "__module__": "frameserver_pb2", - # @@protoc_insertion_point(class_scope:frameserver.FrameRequest) - }, -) -_sym_db.RegisterMessage(FrameRequest) - -Style = _reflection.GeneratedProtocolMessageType( - "Style", - (_message.Message,), - { - "DESCRIPTOR": _STYLE, - "__module__": "frameserver_pb2", - # @@protoc_insertion_point(class_scope:frameserver.Style) - }, -) -_sym_db.RegisterMessage(Style) - -Point = _reflection.GeneratedProtocolMessageType( - "Point", - (_message.Message,), - { - "DESCRIPTOR": _POINT, - "__module__": "frameserver_pb2", - # @@protoc_insertion_point(class_scope:frameserver.Point) - }, -) -_sym_db.RegisterMessage(Point) - -MobjectData = _reflection.GeneratedProtocolMessageType( - "MobjectData", - (_message.Message,), - { - "DESCRIPTOR": _MOBJECTDATA, - "__module__": "frameserver_pb2", - # @@protoc_insertion_point(class_scope:frameserver.MobjectData) - }, -) -_sym_db.RegisterMessage(MobjectData) - -VMobjectData = _reflection.GeneratedProtocolMessageType( - "VMobjectData", - (_message.Message,), - { - "DESCRIPTOR": _VMOBJECTDATA, - "__module__": "frameserver_pb2", - # @@protoc_insertion_point(class_scope:frameserver.VMobjectData) - }, -) -_sym_db.RegisterMessage(VMobjectData) - -ImageMobjectData = _reflection.GeneratedProtocolMessageType( - "ImageMobjectData", - (_message.Message,), - { - "DESCRIPTOR": _IMAGEMOBJECTDATA, - "__module__": "frameserver_pb2", - # @@protoc_insertion_point(class_scope:frameserver.ImageMobjectData) - }, -) -_sym_db.RegisterMessage(ImageMobjectData) - -FrameData = _reflection.GeneratedProtocolMessageType( - "FrameData", - (_message.Message,), - { - "DESCRIPTOR": _FRAMEDATA, - "__module__": "frameserver_pb2", - # @@protoc_insertion_point(class_scope:frameserver.FrameData) - }, -) -_sym_db.RegisterMessage(FrameData) - -FrameResponse = _reflection.GeneratedProtocolMessageType( - "FrameResponse", - (_message.Message,), - { - "DESCRIPTOR": _FRAMERESPONSE, - "__module__": "frameserver_pb2", - # @@protoc_insertion_point(class_scope:frameserver.FrameResponse) - }, -) -_sym_db.RegisterMessage(FrameResponse) - -EmptyRequest = _reflection.GeneratedProtocolMessageType( - "EmptyRequest", - (_message.Message,), - { - "DESCRIPTOR": _EMPTYREQUEST, - "__module__": "frameserver_pb2", - # @@protoc_insertion_point(class_scope:frameserver.EmptyRequest) - }, -) -_sym_db.RegisterMessage(EmptyRequest) - -EmptyResponse = _reflection.GeneratedProtocolMessageType( - "EmptyResponse", - (_message.Message,), - { - "DESCRIPTOR": _EMPTYRESPONSE, - "__module__": "frameserver_pb2", - # @@protoc_insertion_point(class_scope:frameserver.EmptyResponse) - }, -) -_sym_db.RegisterMessage(EmptyResponse) - - -_FRAMESERVER = _descriptor.ServiceDescriptor( - name="FrameServer", - full_name="frameserver.FrameServer", - file=DESCRIPTOR, - index=0, - serialized_options=None, - create_key=_descriptor._internal_create_key, - serialized_start=1781, - serialized_end=2021, - methods=[ - _descriptor.MethodDescriptor( - name="GetFrameAtTime", - full_name="frameserver.FrameServer.GetFrameAtTime", - index=0, - containing_service=None, - input_type=_FRAMEREQUEST, - output_type=_FRAMERESPONSE, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name="FetchSceneData", - full_name="frameserver.FrameServer.FetchSceneData", - index=1, - containing_service=None, - input_type=_EMPTYREQUEST, - output_type=_FETCHSCENEDATARESPONSE, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - _descriptor.MethodDescriptor( - name="ScriptUpdated", - full_name="frameserver.FrameServer.ScriptUpdated", - index=2, - containing_service=None, - input_type=_EMPTYREQUEST, - output_type=_EMPTYRESPONSE, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - ], -) -_sym_db.RegisterServiceDescriptor(_FRAMESERVER) - -DESCRIPTOR.services_by_name["FrameServer"] = _FRAMESERVER - -# @@protoc_insertion_point(module_scope) diff --git a/manim/grpc/gen/frameserver_pb2_grpc.py b/manim/grpc/gen/frameserver_pb2_grpc.py deleted file mode 100644 index b21b7c427d..0000000000 --- a/manim/grpc/gen/frameserver_pb2_grpc.py +++ /dev/null @@ -1,171 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -"""Client and server classes corresponding to protobuf-defined services.""" -from __future__ import annotations - -import frameserver_pb2 as frameserver__pb2 -import grpc - - -class FrameServerStub: - """Missing associated documentation comment in .proto file.""" - - def __init__(self, channel): - """Constructor. - - Args: - channel: A grpc.Channel. - """ - self.GetFrameAtTime = channel.unary_unary( - "/frameserver.FrameServer/GetFrameAtTime", - request_serializer=frameserver__pb2.FrameRequest.SerializeToString, - response_deserializer=frameserver__pb2.FrameResponse.FromString, - ) - self.FetchSceneData = channel.unary_unary( - "/frameserver.FrameServer/FetchSceneData", - request_serializer=frameserver__pb2.EmptyRequest.SerializeToString, - response_deserializer=frameserver__pb2.FetchSceneDataResponse.FromString, - ) - self.ScriptUpdated = channel.unary_unary( - "/frameserver.FrameServer/ScriptUpdated", - request_serializer=frameserver__pb2.EmptyRequest.SerializeToString, - response_deserializer=frameserver__pb2.EmptyResponse.FromString, - ) - - -class FrameServerServicer: - """Missing associated documentation comment in .proto file.""" - - def GetFrameAtTime(self, request, context): - """Returns a serialization of the scene at the specified time.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def FetchSceneData(self, request, context): - """Returns a list of the names and durations of all animations in the scene.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - def ScriptUpdated(self, request, context): - """Returns when the manim script changes""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - -def add_FrameServerServicer_to_server(servicer, server): - rpc_method_handlers = { - "GetFrameAtTime": grpc.unary_unary_rpc_method_handler( - servicer.GetFrameAtTime, - request_deserializer=frameserver__pb2.FrameRequest.FromString, - response_serializer=frameserver__pb2.FrameResponse.SerializeToString, - ), - "FetchSceneData": grpc.unary_unary_rpc_method_handler( - servicer.FetchSceneData, - request_deserializer=frameserver__pb2.EmptyRequest.FromString, - response_serializer=frameserver__pb2.FetchSceneDataResponse.SerializeToString, - ), - "ScriptUpdated": grpc.unary_unary_rpc_method_handler( - servicer.ScriptUpdated, - request_deserializer=frameserver__pb2.EmptyRequest.FromString, - response_serializer=frameserver__pb2.EmptyResponse.SerializeToString, - ), - } - generic_handler = grpc.method_handlers_generic_handler( - "frameserver.FrameServer", - rpc_method_handlers, - ) - server.add_generic_rpc_handlers((generic_handler,)) - - -# This class is part of an EXPERIMENTAL API. -class FrameServer: - """Missing associated documentation comment in .proto file.""" - - @staticmethod - def GetFrameAtTime( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/frameserver.FrameServer/GetFrameAtTime", - frameserver__pb2.FrameRequest.SerializeToString, - frameserver__pb2.FrameResponse.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) - - @staticmethod - def FetchSceneData( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/frameserver.FrameServer/FetchSceneData", - frameserver__pb2.EmptyRequest.SerializeToString, - frameserver__pb2.FetchSceneDataResponse.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) - - @staticmethod - def ScriptUpdated( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/frameserver.FrameServer/ScriptUpdated", - frameserver__pb2.EmptyRequest.SerializeToString, - frameserver__pb2.EmptyResponse.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) diff --git a/manim/grpc/gen/renderserver_pb2.py b/manim/grpc/gen/renderserver_pb2.py deleted file mode 100644 index 051be04c81..0000000000 --- a/manim/grpc/gen/renderserver_pb2.py +++ /dev/null @@ -1,376 +0,0 @@ -# Generated by the protocol buffer compiler. DO NOT EDIT! -# source: renderserver.proto -"""Generated protocol buffer code.""" -from __future__ import annotations - -from google.protobuf import descriptor as _descriptor -from google.protobuf import message as _message -from google.protobuf import reflection as _reflection -from google.protobuf import symbol_database as _symbol_database - -# @@protoc_insertion_point(imports) - -_sym_db = _symbol_database.Default() - - -DESCRIPTOR = _descriptor.FileDescriptor( - name="renderserver.proto", - package="renderserver", - syntax="proto3", - serialized_options=None, - create_key=_descriptor._internal_create_key, - serialized_pb=b'\n\x12renderserver.proto\x12\x0crenderserver"f\n\x16UpdateSceneDataRequest\x12"\n\x05scene\x18\x01 \x01(\x0b\x32\x13.renderserver.Scene\x12\x11\n\texception\x18\x02 \x01(\t\x12\x15\n\rhas_exception\x18\x03 \x01(\x08"\\\n\x05Scene\x12\x0c\n\x04name\x18\x01 \x01(\t\x12+\n\nanimations\x18\x02 \x03(\x0b\x32\x17.renderserver.Animation\x12\x18\n\x10\x62\x61\x63kground_color\x18\x03 \x01(\t"+\n\tAnimation\x12\x0c\n\x04name\x18\x01 \x01(\t\x12\x10\n\x08\x64uration\x18\x02 \x01(\x02"\x0e\n\x0c\x45mptyRequest"\x0f\n\rEmptyResponse2d\n\x0cRenderServer\x12T\n\x0fUpdateSceneData\x12$.renderserver.UpdateSceneDataRequest\x1a\x1b.renderserver.EmptyResponseb\x06proto3', -) - - -_UPDATESCENEDATAREQUEST = _descriptor.Descriptor( - name="UpdateSceneDataRequest", - full_name="renderserver.UpdateSceneDataRequest", - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name="scene", - full_name="renderserver.UpdateSceneDataRequest.scene", - index=0, - number=1, - type=11, - cpp_type=10, - label=1, - has_default_value=False, - default_value=None, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="exception", - full_name="renderserver.UpdateSceneDataRequest.exception", - index=1, - number=2, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=b"".decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="has_exception", - full_name="renderserver.UpdateSceneDataRequest.has_exception", - index=2, - number=3, - type=8, - cpp_type=7, - label=1, - has_default_value=False, - default_value=False, - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=36, - serialized_end=138, -) - - -_SCENE = _descriptor.Descriptor( - name="Scene", - full_name="renderserver.Scene", - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name="name", - full_name="renderserver.Scene.name", - index=0, - number=1, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=b"".decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="animations", - full_name="renderserver.Scene.animations", - index=1, - number=2, - type=11, - cpp_type=10, - label=3, - has_default_value=False, - default_value=[], - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="background_color", - full_name="renderserver.Scene.background_color", - index=2, - number=3, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=b"".decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=140, - serialized_end=232, -) - - -_ANIMATION = _descriptor.Descriptor( - name="Animation", - full_name="renderserver.Animation", - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[ - _descriptor.FieldDescriptor( - name="name", - full_name="renderserver.Animation.name", - index=0, - number=1, - type=9, - cpp_type=9, - label=1, - has_default_value=False, - default_value=b"".decode("utf-8"), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - _descriptor.FieldDescriptor( - name="duration", - full_name="renderserver.Animation.duration", - index=1, - number=2, - type=2, - cpp_type=6, - label=1, - has_default_value=False, - default_value=float(0), - message_type=None, - enum_type=None, - containing_type=None, - is_extension=False, - extension_scope=None, - serialized_options=None, - file=DESCRIPTOR, - create_key=_descriptor._internal_create_key, - ), - ], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=234, - serialized_end=277, -) - - -_EMPTYREQUEST = _descriptor.Descriptor( - name="EmptyRequest", - full_name="renderserver.EmptyRequest", - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=279, - serialized_end=293, -) - - -_EMPTYRESPONSE = _descriptor.Descriptor( - name="EmptyResponse", - full_name="renderserver.EmptyResponse", - filename=None, - file=DESCRIPTOR, - containing_type=None, - create_key=_descriptor._internal_create_key, - fields=[], - extensions=[], - nested_types=[], - enum_types=[], - serialized_options=None, - is_extendable=False, - syntax="proto3", - extension_ranges=[], - oneofs=[], - serialized_start=295, - serialized_end=310, -) - -_UPDATESCENEDATAREQUEST.fields_by_name["scene"].message_type = _SCENE -_SCENE.fields_by_name["animations"].message_type = _ANIMATION -DESCRIPTOR.message_types_by_name["UpdateSceneDataRequest"] = _UPDATESCENEDATAREQUEST -DESCRIPTOR.message_types_by_name["Scene"] = _SCENE -DESCRIPTOR.message_types_by_name["Animation"] = _ANIMATION -DESCRIPTOR.message_types_by_name["EmptyRequest"] = _EMPTYREQUEST -DESCRIPTOR.message_types_by_name["EmptyResponse"] = _EMPTYRESPONSE -_sym_db.RegisterFileDescriptor(DESCRIPTOR) - -UpdateSceneDataRequest = _reflection.GeneratedProtocolMessageType( - "UpdateSceneDataRequest", - (_message.Message,), - { - "DESCRIPTOR": _UPDATESCENEDATAREQUEST, - "__module__": "renderserver_pb2", - # @@protoc_insertion_point(class_scope:renderserver.UpdateSceneDataRequest) - }, -) -_sym_db.RegisterMessage(UpdateSceneDataRequest) - -Scene = _reflection.GeneratedProtocolMessageType( - "Scene", - (_message.Message,), - { - "DESCRIPTOR": _SCENE, - "__module__": "renderserver_pb2", - # @@protoc_insertion_point(class_scope:renderserver.Scene) - }, -) -_sym_db.RegisterMessage(Scene) - -Animation = _reflection.GeneratedProtocolMessageType( - "Animation", - (_message.Message,), - { - "DESCRIPTOR": _ANIMATION, - "__module__": "renderserver_pb2", - # @@protoc_insertion_point(class_scope:renderserver.Animation) - }, -) -_sym_db.RegisterMessage(Animation) - -EmptyRequest = _reflection.GeneratedProtocolMessageType( - "EmptyRequest", - (_message.Message,), - { - "DESCRIPTOR": _EMPTYREQUEST, - "__module__": "renderserver_pb2", - # @@protoc_insertion_point(class_scope:renderserver.EmptyRequest) - }, -) -_sym_db.RegisterMessage(EmptyRequest) - -EmptyResponse = _reflection.GeneratedProtocolMessageType( - "EmptyResponse", - (_message.Message,), - { - "DESCRIPTOR": _EMPTYRESPONSE, - "__module__": "renderserver_pb2", - # @@protoc_insertion_point(class_scope:renderserver.EmptyResponse) - }, -) -_sym_db.RegisterMessage(EmptyResponse) - - -_RENDERSERVER = _descriptor.ServiceDescriptor( - name="RenderServer", - full_name="renderserver.RenderServer", - file=DESCRIPTOR, - index=0, - serialized_options=None, - create_key=_descriptor._internal_create_key, - serialized_start=312, - serialized_end=412, - methods=[ - _descriptor.MethodDescriptor( - name="UpdateSceneData", - full_name="renderserver.RenderServer.UpdateSceneData", - index=0, - containing_service=None, - input_type=_UPDATESCENEDATAREQUEST, - output_type=_EMPTYRESPONSE, - serialized_options=None, - create_key=_descriptor._internal_create_key, - ), - ], -) -_sym_db.RegisterServiceDescriptor(_RENDERSERVER) - -DESCRIPTOR.services_by_name["RenderServer"] = _RENDERSERVER - -# @@protoc_insertion_point(module_scope) diff --git a/manim/grpc/gen/renderserver_pb2_grpc.py b/manim/grpc/gen/renderserver_pb2_grpc.py deleted file mode 100644 index a195961f57..0000000000 --- a/manim/grpc/gen/renderserver_pb2_grpc.py +++ /dev/null @@ -1,81 +0,0 @@ -# Generated by the gRPC Python protocol compiler plugin. DO NOT EDIT! -"""Client and server classes corresponding to protobuf-defined services.""" -from __future__ import annotations - -import grpc -import renderserver_pb2 as renderserver__pb2 - - -class RenderServerStub: - """Missing associated documentation comment in .proto file.""" - - def __init__(self, channel): - """Constructor. - - Args: - channel: A grpc.Channel. - """ - self.UpdateSceneData = channel.unary_unary( - "/renderserver.RenderServer/UpdateSceneData", - request_serializer=renderserver__pb2.UpdateSceneDataRequest.SerializeToString, - response_deserializer=renderserver__pb2.EmptyResponse.FromString, - ) - - -class RenderServerServicer: - """Missing associated documentation comment in .proto file.""" - - def UpdateSceneData(self, request, context): - """Called from Manim when a scene has been newly rendered.""" - context.set_code(grpc.StatusCode.UNIMPLEMENTED) - context.set_details("Method not implemented!") - raise NotImplementedError("Method not implemented!") - - -def add_RenderServerServicer_to_server(servicer, server): - rpc_method_handlers = { - "UpdateSceneData": grpc.unary_unary_rpc_method_handler( - servicer.UpdateSceneData, - request_deserializer=renderserver__pb2.UpdateSceneDataRequest.FromString, - response_serializer=renderserver__pb2.EmptyResponse.SerializeToString, - ), - } - generic_handler = grpc.method_handlers_generic_handler( - "renderserver.RenderServer", - rpc_method_handlers, - ) - server.add_generic_rpc_handlers((generic_handler,)) - - -# This class is part of an EXPERIMENTAL API. -class RenderServer: - """Missing associated documentation comment in .proto file.""" - - @staticmethod - def UpdateSceneData( - request, - target, - options=(), - channel_credentials=None, - call_credentials=None, - insecure=False, - compression=None, - wait_for_ready=None, - timeout=None, - metadata=None, - ): - return grpc.experimental.unary_unary( - request, - target, - "/renderserver.RenderServer/UpdateSceneData", - renderserver__pb2.UpdateSceneDataRequest.SerializeToString, - renderserver__pb2.EmptyResponse.FromString, - options, - channel_credentials, - insecure, - call_credentials, - compression, - wait_for_ready, - timeout, - metadata, - ) diff --git a/manim/grpc/impl/frame_server_impl.py b/manim/grpc/impl/frame_server_impl.py deleted file mode 100644 index a04ca9dca8..0000000000 --- a/manim/grpc/impl/frame_server_impl.py +++ /dev/null @@ -1,409 +0,0 @@ -from __future__ import annotations - -import copy -import subprocess as sp -import traceback -import types -from concurrent import futures - -import grpc - -from manim.mobject.value_tracker import ValueTracker - -from ... import config, logger -from ...constants import WEBGL_RENDERER_INFO -from ...mobject.types.image_mobject import ImageMobject -from ...mobject.types.vectorized_mobject import VMobject -from ...renderer.webgl_renderer import WebGLRenderer -from ...utils.family import extract_mobject_family_members -from ...utils.module_ops import scene_classes_from_file -from ..gen import ( - frameserver_pb2, - frameserver_pb2_grpc, - renderserver_pb2, - renderserver_pb2_grpc, -) - - -class FrameServer(frameserver_pb2_grpc.FrameServerServicer): - def __init__(self, server, input_file_path): - self.server = server - self.input_file_path = input_file_path - self.exception = None - self.load_scene_module() - - try: - self.update_renderer_scene_data() - except grpc._channel._InactiveRpcError: - logger.warning("No frontend was detected at localhost:50052.") - try: - sp.Popen(config["webgl_renderer_path"]) - except PermissionError: - logger.info(WEBGL_RENDERER_INFO) - self.server.stop(None) - return - - def GetFrameAtTime(self, request, context): - try: - requested_scene_index = request.animation_index - - # Find the requested scene. - scene_finished = False - if requested_scene_index == request.end_index: - scene_finished = True - - if ( - request.animation_offset - <= self.keyframes[requested_scene_index].duration - ): - animation_offset = request.animation_offset - else: - if requested_scene_index + 1 < request.end_index: - requested_scene_index += 1 - animation_offset = 0 - else: - scene_finished = True - animation_offset = self.keyframes[requested_scene_index].duration - - if requested_scene_index == self.previous_scene_index: - requested_scene = self.previous_scene - update_previous_scene = False - else: - requested_scene = copy.deepcopy(self.keyframes[requested_scene_index]) - update_previous_scene = True - - requested_scene.update_to_time(animation_offset) - - ids_to_remove = [] - mobjects_to_add = [] - animations = [] - updaters = [] - update_data = [] - # TODO: Only remove/add changed mobjects rather than all of them. - if self.previous_scene is not None and ( - request.first_request or self.previous_scene != requested_scene - ): - previous_mobjects = extract_mobject_family_members( - self.previous_scene.mobjects, - only_those_with_points=True, - ) - # Remove everything from the previous scene. - ids_to_remove = [ - mob.original_id - for mob in previous_mobjects - if not isinstance(mob, ValueTracker) - ] - - if request.first_request or self.previous_scene != requested_scene: - # Add everything from the requested scene. - mobjects_to_add = [ - serialize_mobject(mobject) - for mobject in extract_mobject_family_members( - requested_scene.mobjects, - only_those_with_points=True, - ) - if not isinstance(mobject, ValueTracker) - ] - - # Send animation and updater info. - all_animations_tweened = True - for animation in requested_scene.animations: - attribute_tween_data = generate_attribute_tween_data(animation) - mobject_tween_data_list = [] - flickered_mobject_ids = [] - if attribute_tween_data is None: - all_animations_tweened = False - flickered_mobject_ids = [ - mob.original_id - for mob in extract_mobject_family_members( - animation.mobject, - only_those_with_points=True, - ) - ] - else: - if animation.mobject is not None: - # Add offset vector to submobjects. - root_mobject_center = animation.mobject.get_center() - for updated_mobject in extract_mobject_family_members( - animation.mobject, - only_those_with_points=True, - ): - mobject_tween_data_list.append( - frameserver_pb2.Animation.MobjectTweenData( - id=updated_mobject.original_id, - root_mobject_offset=updated_mobject.get_center() - - root_mobject_center, - ), - ) - animation_proto = frameserver_pb2.Animation( - name=animation.__class__.__name__, - duration=requested_scene.duration, - easing_function=animation.rate_func.__name__, - attribute_tween_data=attribute_tween_data, - mobject_tween_data=mobject_tween_data_list, - flickered_mobject_ids=flickered_mobject_ids, - ) - animations.append(animation_proto) - for ( - updated_mobject, - updater_list, - ) in requested_scene.mobject_updater_lists: - all_updaters_tweened = True - for updater in updater_list: - attribute_tween_data = generate_attribute_tween_data(updater) - if attribute_tween_data is None: - all_animations_tweened = False - all_updaters_tweened = False - updaters.append( - frameserver_pb2.Updater( - flickered_mobject_ids=[ - mob.original_id - for mob in extract_mobject_family_members( - updated_mobject, - only_those_with_points=True, - ) - ], - ), - ) - break - else: - raise NotImplementedError("Add tween data for updaters.") - if all_updaters_tweened: - # Append an updater with tween data. - pass - else: - all_animations_tweened = False - for animation in requested_scene.animations: - # Only send update data for animations that don't have tween data. - if generate_attribute_tween_data(animation) is None: - update_data.extend( - [ - serialize_mobject(mobject) - for mobject in extract_mobject_family_members( - animation.mobject, - only_those_with_points=True, - ) - if not isinstance(mobject, ValueTracker) - ], - ) - for ( - updated_mobject, - updater_list, - ) in requested_scene.mobject_updater_lists: - for updater in updater_list: - # Only send update data for updaters that don't have tween data. - if generate_attribute_tween_data(updater) is None: - update_data.extend( - [ - serialize_mobject(mobject) - for mobject in extract_mobject_family_members( - updated_mobject, - only_those_with_points=True, - ) - if not isinstance(mobject, ValueTracker) - ], - ) - - resp = frameserver_pb2.FrameResponse( - frame_data=frameserver_pb2.FrameData( - remove=ids_to_remove, - add=mobjects_to_add, - update=update_data, - ), - scene_finished=scene_finished, - animations=animations, - updaters=updaters, - animation_index=requested_scene_index, - animation_offset=animation_offset, - all_animations_tweened=all_animations_tweened, - ) - if update_previous_scene: - self.previous_scene = requested_scene - self.previous_scene_index = requested_scene_index - return resp - except Exception: - traceback.print_exc() - - def FetchSceneData(self, request, context): - try: - request = frameserver_pb2.FetchSceneDataResponse( - scene=frameserver_pb2.Scene( - name=str(self.scene), - animations=[ - frameserver_pb2.Animation( - name=animations_to_name(scene.animations), - duration=scene.duration, - ) - for scene in self.keyframes - ], - ), - path=str(self.input_file_path), - ) - if hasattr(self.scene.camera, "background_color"): - request.scene.background_color = self.scene.camera.background_color - else: - request.scene.background_color = "#000000" - return request - except Exception: - traceback.print_exc() - - def ScriptUpdated(self, request, context): - self.load_scene_module() - with grpc.insecure_channel("localhost:50052") as channel: - stub = renderserver_pb2_grpc.RenderServerStub(channel) - try: - self.update_renderer_scene_data() - except grpc._channel._InactiveRpcError: - logger.warning("No frontend was detected at localhost:50052.") - sp.Popen(config["js_renderer_path"]) - return frameserver_pb2.EmptyResponse() - - def load_scene_module(self): - self.exception = None - try: - self.scene_class = scene_classes_from_file( - self.input_file_path, - require_single_scene=True, - ) - self.generate_keyframe_data() - except Exception as e: - self.exception = e - - def generate_keyframe_data(self): - self.keyframes = [] - self.previous_scene_index = None - self.previous_scene = None - self.renderer = WebGLRenderer(self) - self.scene = self.scene_class(self.renderer) - self.scene.render() - - def update_renderer_scene_data(self): - # If a javascript renderer is running, notify it of the scene being served. If - # not, spawn one and it will request the scene when it starts. - with grpc.insecure_channel("localhost:50052") as channel: - stub = renderserver_pb2_grpc.RenderServerStub(channel) - if not self.exception: - request = renderserver_pb2.UpdateSceneDataRequest( - scene=renderserver_pb2.Scene( - name=str(self.scene), - animations=[ - renderserver_pb2.Animation( - name=animations_to_name(scene.animations), - duration=scene.duration, - ) - for scene in self.keyframes - ], - ), - ) - if hasattr(self.scene.camera, "background_color"): - request.scene.background_color = self.scene.camera.background_color - else: - request.scene.background_color = "#000000" - else: - lines = traceback.format_exception( - None, - self.exception, - self.exception.__traceback__, - ) - request = renderserver_pb2.UpdateSceneDataRequest( - has_exception=True, - exception="\n".join(lines), - ) - stub.UpdateSceneData(request) - - -def generate_attribute_tween_data(animation): - if isinstance(animation, types.FunctionType): - return None - animation_name = animation.__class__.__name__ - if animation_name == "_MethodAnimation": - tween_data_array = [] - for method in animation.methods: - if method.__name__ in ["shift", "to_edge"]: - tween_data_array.append( - frameserver_pb2.Animation.AttributeTweenData( - attribute="position", - start_data=animation.starting_mobject.get_center(), - end_data=animation.target_mobject.get_center(), - ), - ) - else: - return None - return tween_data_array - elif animation_name == "FadeIn": - return [ - frameserver_pb2.Animation.AttributeTweenData( - attribute="fill_opacity", - start_data=[animation.starting_mobject.fill_opacity], - end_data=[animation.target_copy.fill_opacity], - ), - frameserver_pb2.Animation.AttributeTweenData( - attribute="stroke_opacity", - start_data=[animation.starting_mobject.stroke_opacity], - end_data=[animation.target_copy.stroke_opacity], - ), - ] - elif animation_name == "Wait": - return [] - else: - return None - - -def animations_to_name(animations): - if len(animations) == 1: - return str(animations[0].__class__.__name__) - return f"{str(animations[0].__class__.__name__)}..." - - -def serialize_mobject(mobject): - mob_proto = frameserver_pb2.MobjectData(id=mobject.original_id) - - if isinstance(mobject, VMobject): - needs_redraw = False - point_hash = hash(tuple(mobject.points.flatten())) - if mobject.point_hash != point_hash: - mobject.point_hash = point_hash - needs_redraw = True - mob_proto.vectorized_mobject_data.needs_redraw = needs_redraw - - for point in mobject.points: - point_proto = mob_proto.vectorized_mobject_data.points.add() - point_proto.x = point[0] - point_proto.y = point[1] - point_proto.z = point[2] - - mob_style = mobject.get_style(simple=True) - mob_proto.style.fill_color = mob_style["fill_color"] - mob_proto.style.fill_opacity = float(mob_style["fill_opacity"]) - mob_proto.style.stroke_color = mob_style["stroke_color"] - mob_proto.style.stroke_opacity = float(mob_style["stroke_opacity"]) - mob_proto.style.stroke_width = float(mob_style["stroke_width"]) - elif isinstance(mobject, ImageMobject): - mob_proto.type = frameserver_pb2.MobjectData.MobjectType.IMAGE_MOBJECT - mob_style = mobject.get_style() - mob_proto.style.fill_color = mob_style["fill_color"] - mob_proto.style.fill_opacity = float(mob_style["fill_opacity"]) - assets_dir_path = str(config.get_dir("assets_dir")) - if mobject.path.startswith(assets_dir_path): - mob_proto.image_mobject_data.path = mobject.path[len(assets_dir_path) + 1 :] - else: - logger.info( - f"Expected path {mobject.path} to be under the assets dir ({assets_dir_path})", - ) - mob_proto.image_mobject_data.height = mobject.height - mob_proto.image_mobject_data.width = mobject.width - mob_center = mobject.get_center() - mob_proto.image_mobject_data.center.x = mob_center[0] - mob_proto.image_mobject_data.center.y = mob_center[1] - mob_proto.image_mobject_data.center.z = mob_center[2] - return mob_proto - - -def get(input_file_path): - server = grpc.server(futures.ThreadPoolExecutor(max_workers=10)) - frameserver_pb2_grpc.add_FrameServerServicer_to_server( - FrameServer(server, input_file_path), - server, - ) - server.add_insecure_port("localhost:50051") - return server diff --git a/manim/grpc/proto/frameserver.proto b/manim/grpc/proto/frameserver.proto deleted file mode 100644 index 17151fd3a9..0000000000 --- a/manim/grpc/proto/frameserver.proto +++ /dev/null @@ -1,114 +0,0 @@ -syntax = "proto3"; - -package frameserver; - -service FrameServer { - // Returns a serialization of the scene at the specified time. - rpc GetFrameAtTime (FrameRequest) returns (FrameResponse); - - // Returns a list of the names and durations of all animations in the scene. - rpc FetchSceneData (EmptyRequest) returns (FetchSceneDataResponse); - - // Returns when the manim script changes - rpc ScriptUpdated (EmptyRequest) returns (EmptyResponse); -} - -message FetchSceneDataResponse { - Scene scene = 1; - string path = 2; -} - -message Scene { - string name = 1; - repeated Animation animations = 2; - string background_color = 3; -} - -message Animation { - string name = 1; - float duration = 2; - string easing_function = 3; - - message AttributeTweenData { - string attribute = 1; - repeated float start_data = 2; - repeated float end_data = 3; - } - repeated AttributeTweenData attribute_tween_data = 4; - - message MobjectTweenData { - string id = 1; - repeated float root_mobject_offset = 2; - } - repeated MobjectTweenData mobject_tween_data = 5; - repeated string flickered_mobject_ids = 6; -} - -message Updater { - repeated string flickered_mobject_ids = 1; -} - -message FrameRequest { - int32 end_index = 1; - bool first_request = 2; - int32 animation_index = 3; - float animation_offset = 4; -} - -message Style { - string fill_color = 1; - float fill_opacity = 2; - string stroke_color = 3; - float stroke_opacity = 4; - float stroke_width = 5; -} - -message Point { - float x = 1; - float y = 2; - float z = 3; -} - -message MobjectData { - string id = 1; - Style style = 2; - enum MobjectType { - VMOBJECT = 0; - IMAGE_MOBJECT = 1; - } - MobjectType type = 3; - VMobjectData vectorized_mobject_data = 4; - ImageMobjectData image_mobject_data = 5; - repeated float root_mobject_offset = 6; -} - -message VMobjectData { - repeated Point points = 1; - bool needs_redraw = 2; -} - -message ImageMobjectData { - string path = 1; - float height = 2; - float width = 3; - Point center = 4; -} - -message FrameData { - repeated string remove = 1; - repeated MobjectData add = 2; - repeated MobjectData update = 3; -} - -message FrameResponse { - FrameData frame_data = 1; - bool scene_finished = 2; - repeated Animation animations = 3; - repeated Updater updaters = 4; - int32 animation_index = 5; - float animation_offset = 6; - bool all_animations_tweened = 7; -} - -message EmptyRequest {} -message EmptyResponse {} diff --git a/manim/grpc/proto/renderserver.proto b/manim/grpc/proto/renderserver.proto deleted file mode 100644 index 0d42c5244a..0000000000 --- a/manim/grpc/proto/renderserver.proto +++ /dev/null @@ -1,28 +0,0 @@ -syntax = "proto3"; - -package renderserver; - -service RenderServer { - // Called from Manim when a scene has been newly rendered. - rpc UpdateSceneData (UpdateSceneDataRequest) returns (EmptyResponse); -} - -message UpdateSceneDataRequest { - Scene scene = 1; - string exception = 2; - bool has_exception = 3; -} - -message Scene { - string name = 1; - repeated Animation animations = 2; - string background_color = 3; -} - -message Animation { - string name = 1; - float duration = 2; -} - -message EmptyRequest {} -message EmptyResponse {} diff --git a/manim/gui/gui.py b/manim/gui/gui.py index 9890093666..75ec67312c 100644 --- a/manim/gui/gui.py +++ b/manim/gui/gui.py @@ -13,6 +13,8 @@ from .. import __version__, config from ..utils.module_ops import scene_classes_from_file +__all__ = ["configure_pygui"] + if dearpygui_imported: dpg.create_context() window = dpg.generate_uuid() diff --git a/manim/mobject/frame.py b/manim/mobject/frame.py index b854643911..639e8c384e 100644 --- a/manim/mobject/frame.py +++ b/manim/mobject/frame.py @@ -24,7 +24,6 @@ def aspect_ratio(self): When set, the width is stretched to accommodate the new aspect ratio. """ - return self.width / self.height @aspect_ratio.setter diff --git a/manim/mobject/geometry/__init__.py b/manim/mobject/geometry/__init__.py index abae9c0da0..cf3283bc69 100644 --- a/manim/mobject/geometry/__init__.py +++ b/manim/mobject/geometry/__init__.py @@ -8,6 +8,7 @@ ~arc ~boolean_ops + ~labeled ~line ~polygram ~shape_matchers diff --git a/manim/mobject/geometry/arc.py b/manim/mobject/geometry/arc.py index a15debefe0..2923239944 100644 --- a/manim/mobject/geometry/arc.py +++ b/manim/mobject/geometry/arc.py @@ -43,17 +43,16 @@ def construct(self): ] import itertools -import math import warnings -from typing import TYPE_CHECKING, Sequence +from typing import TYPE_CHECKING, cast import numpy as np -from colour import Color +from typing_extensions import Self from manim.constants import * from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL -from manim.mobject.types.vectorized_mobject import VMobject -from manim.utils.color import * +from manim.mobject.types.vectorized_mobject import VGroup, VMobject +from manim.utils.color import BLACK, BLUE, RED, WHITE, ParsableManimColor from manim.utils.iterables import adjacent_pairs from manim.utils.space_ops import ( angle_of_vector, @@ -64,9 +63,19 @@ def construct(self): ) if TYPE_CHECKING: + from collections.abc import Iterable + from typing import Any + + import manim.mobject.geometry.tips as tips from manim.mobject.mobject import Mobject from manim.mobject.text.tex_mobject import SingleStringMathTex, Tex from manim.mobject.text.text_mobject import Text + from manim.typing import ( + Point3D, + Point3DLike, + QuadraticSpline, + Vector3D, + ) class TipableVMobject(VMobject, metaclass=ConvertToOpenGL): @@ -89,25 +98,32 @@ class TipableVMobject(VMobject, metaclass=ConvertToOpenGL): def __init__( self, - tip_length=DEFAULT_ARROW_TIP_LENGTH, - normal_vector=OUT, - tip_style={}, - **kwargs, - ): - self.tip_length = tip_length - self.normal_vector = normal_vector - self.tip_style = tip_style + tip_length: float = DEFAULT_ARROW_TIP_LENGTH, + normal_vector: Vector3D = OUT, + tip_style: dict = {}, + **kwargs: Any, + ) -> None: + self.tip_length: float = tip_length + self.normal_vector: Vector3D = normal_vector + self.tip_style: dict = tip_style super().__init__(**kwargs) # Adding, Creating, Modifying tips - def add_tip(self, tip=None, tip_shape=None, tip_length=None, at_start=False): + def add_tip( + self, + tip: tips.ArrowTip | None = None, + tip_shape: type[tips.ArrowTip] | None = None, + tip_length: float | None = None, + tip_width: float | None = None, + at_start: bool = False, + ) -> Self: """Adds a tip to the TipableVMobject instance, recognising that the endpoints might need to be switched if it's a 'starting tip' or not. """ if tip is None: - tip = self.create_tip(tip_shape, tip_length, at_start) + tip = self.create_tip(tip_shape, tip_length, tip_width, at_start) else: self.position_tip(tip, at_start) self.reset_endpoints_based_on_tip(tip, at_start) @@ -115,31 +131,50 @@ def add_tip(self, tip=None, tip_shape=None, tip_length=None, at_start=False): self.add(tip) return self - def create_tip(self, tip_shape=None, tip_length=None, at_start=False): + def create_tip( + self, + tip_shape: type[tips.ArrowTip] | None = None, + tip_length: float | None = None, + tip_width: float | None = None, + at_start: bool = False, + ) -> tips.ArrowTip: """Stylises the tip, positions it spatially, and returns the newly instantiated tip to the caller. """ - tip = self.get_unpositioned_tip(tip_shape, tip_length) + tip = self.get_unpositioned_tip(tip_shape, tip_length, tip_width) self.position_tip(tip, at_start) return tip - def get_unpositioned_tip(self, tip_shape=None, tip_length=None): + def get_unpositioned_tip( + self, + tip_shape: type[tips.ArrowTip] | None = None, + tip_length: float | None = None, + tip_width: float | None = None, + ) -> tips.ArrowTip | tips.ArrowTriangleFilledTip: """Returns a tip that has been stylistically configured, but has not yet been given a position in space. """ from manim.mobject.geometry.tips import ArrowTriangleFilledTip + style: dict[str, Any] = {} + if tip_shape is None: tip_shape = ArrowTriangleFilledTip + + if tip_shape is ArrowTriangleFilledTip: + if tip_width is None: + tip_width = self.get_default_tip_length() + style.update({"width": tip_width}) if tip_length is None: tip_length = self.get_default_tip_length() + color = self.get_color() - style = {"fill_color": color, "stroke_color": color} + style.update({"fill_color": color, "stroke_color": color}) style.update(self.tip_style) tip = tip_shape(length=tip_length, **style) return tip - def position_tip(self, tip, at_start=False): + def position_tip(self, tip: tips.ArrowTip, at_start: bool = False) -> tips.ArrowTip: # Last two control points, defining both # the end, and the tangency direction if at_start: @@ -148,16 +183,18 @@ def position_tip(self, tip, at_start=False): else: handle = self.get_last_handle() anchor = self.get_end() - angles = cartesian_to_spherical(handle - anchor) + angles = cartesian_to_spherical((handle - anchor).tolist()) tip.rotate( angles[1] - PI - tip.tip_angle, ) # Rotates the tip along the azimuthal if not hasattr(self, "_init_positioning_axis"): - axis = [ - np.sin(angles[1]), - -np.cos(angles[1]), - 0, - ] # Obtains the perpendicular of the tip + axis = np.array( + [ + np.sin(angles[1]), + -np.cos(angles[1]), + 0, + ] + ) # Obtains the perpendicular of the tip tip.rotate( -angles[2] + PI / 2, axis=axis, @@ -166,7 +203,7 @@ def position_tip(self, tip, at_start=False): tip.shift(anchor - tip.tip_point) return tip - def reset_endpoints_based_on_tip(self, tip, at_start): + def reset_endpoints_based_on_tip(self, tip: tips.ArrowTip, at_start: bool) -> Self: if self.get_length() == 0: # Zero length, put_start_and_end_on wouldn't work return self @@ -177,7 +214,7 @@ def reset_endpoints_based_on_tip(self, tip, at_start): self.put_start_and_end_on(self.get_start(), tip.base) return self - def asign_tip_attr(self, tip, at_start): + def asign_tip_attr(self, tip: tips.ArrowTip, at_start: bool) -> Self: if at_start: self.start_tip = tip else: @@ -186,15 +223,15 @@ def asign_tip_attr(self, tip, at_start): # Checking for tips - def has_tip(self): + def has_tip(self) -> bool: return hasattr(self, "tip") and self.tip in self - def has_start_tip(self): + def has_start_tip(self) -> bool: return hasattr(self, "start_tip") and self.start_tip in self # Getters - def pop_tips(self): + def pop_tips(self) -> VGroup: start, end = self.get_start_and_end() result = self.get_group_class()() if self.has_tip(): @@ -206,7 +243,7 @@ def pop_tips(self): self.put_start_and_end_on(start, end) return result - def get_tips(self): + def get_tips(self) -> VGroup: """Returns a VGroup (collection of VMobjects) containing the TipableVMObject instance's tips. """ @@ -217,39 +254,49 @@ def get_tips(self): result.add(self.start_tip) return result - def get_tip(self): + def get_tip(self) -> VMobject: """Returns the TipableVMobject instance's (first) tip, - otherwise throws an exception.""" + otherwise throws an exception. + """ tips = self.get_tips() if len(tips) == 0: raise Exception("tip not found") else: - return tips[0] + tip: VMobject = tips[0] + return tip - def get_default_tip_length(self): + def get_default_tip_length(self) -> float: return self.tip_length - def get_first_handle(self): - return self.points[1] - - def get_last_handle(self): - return self.points[-2] - - def get_end(self): + def get_first_handle(self) -> Point3D: + # Type inference of extracting an element from a list, is not + # supported by numpy, see this numpy issue + # https://github.com/numpy/numpy/issues/16544 + first_handle: Point3D = self.points[1] + return first_handle + + def get_last_handle(self) -> Point3D: + # Type inference of extracting an element from a list, is not + # supported by numpy, see this numpy issue + # https://github.com/numpy/numpy/issues/16544 + last_handle: Point3D = self.points[-2] + return last_handle + + def get_end(self) -> Point3D: if self.has_tip(): return self.tip.get_start() else: return super().get_end() - def get_start(self): + def get_start(self) -> Point3D: if self.has_start_tip(): return self.start_tip.get_start() else: return super().get_start() - def get_length(self): + def get_length(self) -> float: start, end = self.get_start_and_end() - return np.linalg.norm(start - end) + return float(np.linalg.norm(start - end)) class Arc(TipableVMobject): @@ -269,24 +316,24 @@ def construct(self): def __init__( self, - radius: float = 1.0, - start_angle=0, - angle=TAU / 4, - num_components=9, - arc_center=ORIGIN, - **kwargs, + radius: float | None = 1.0, + start_angle: float = 0, + angle: float = TAU / 4, + num_components: int = 9, + arc_center: Point3DLike = ORIGIN, + **kwargs: Any, ): if radius is None: # apparently None is passed by ArcBetweenPoints radius = 1.0 self.radius = radius self.num_components = num_components - self.arc_center = arc_center + self.arc_center: Point3D = np.asarray(arc_center) self.start_angle = start_angle self.angle = angle - self._failed_to_get_center = False + self._failed_to_get_center: bool = False super().__init__(**kwargs) - def generate_points(self): + def generate_points(self) -> None: self._set_pre_positioned_points() self.scale(self.radius, about_point=ORIGIN) self.shift(self.arc_center) @@ -294,7 +341,7 @@ def generate_points(self): # Points are set a bit differently when rendering via OpenGL. # TODO: refactor Arc so that only one strategy for setting points # has to be used. - def init_points(self): + def init_points(self) -> None: self.set_points( Arc._create_quadratic_bezier_points( angle=self.angle, @@ -306,7 +353,9 @@ def init_points(self): self.shift(self.arc_center) @staticmethod - def _create_quadratic_bezier_points(angle, start_angle=0, n_components=8): + def _create_quadratic_bezier_points( + angle: float, start_angle: float = 0, n_components: int = 8 + ) -> QuadraticSpline: samples = np.array( [ [np.cos(a), np.sin(a), 0] @@ -326,7 +375,7 @@ def _create_quadratic_bezier_points(angle, start_angle=0, n_components=8): points[2::3] = samples[2::2] return points - def _set_pre_positioned_points(self): + def _set_pre_positioned_points(self) -> None: anchors = np.array( [ np.cos(a) * RIGHT + np.sin(a) * UP @@ -345,11 +394,12 @@ def _set_pre_positioned_points(self): tangent_vectors[:, 1] = anchors[:, 0] tangent_vectors[:, 0] = -anchors[:, 1] # Use tangent vectors to deduce anchors - handles1 = anchors[:-1] + (d_theta / 3) * tangent_vectors[:-1] - handles2 = anchors[1:] - (d_theta / 3) * tangent_vectors[1:] + factor = 4 / 3 * np.tan(d_theta / 4) + handles1 = anchors[:-1] + factor * tangent_vectors[:-1] + handles2 = anchors[1:] - factor * tangent_vectors[1:] self.set_anchors_and_handles(anchors[:-1], handles1, handles2, anchors[1:]) - def get_arc_center(self, warning=True): + def get_arc_center(self, warning: bool = True) -> Point3D: """Looks at the normals to the first two anchors, and finds their intersection points """ @@ -360,7 +410,7 @@ def get_arc_center(self, warning=True): # For a1 and a2 to lie at the same point arc radius # must be zero. Thus arc_center will also lie at # that point. - return a1 + return np.copy(a1) # Tangent vectors t1 = h1 - a1 t2 = h2 - a2 @@ -371,16 +421,21 @@ def get_arc_center(self, warning=True): return line_intersection(line1=(a1, a1 + n1), line2=(a2, a2 + n2)) except Exception: if warning: - warnings.warn("Can't find Arc center, using ORIGIN instead") + warnings.warn( + "Can't find Arc center, using ORIGIN instead", stacklevel=1 + ) self._failed_to_get_center = True return np.array(ORIGIN) - def move_arc_center_to(self, point): + def move_arc_center_to(self, point: Point3DLike) -> Self: self.shift(point - self.get_arc_center()) return self - def stop_angle(self): - return angle_of_vector(self.points[-1] - self.get_arc_center()) % TAU + def stop_angle(self) -> float: + return cast( + float, + angle_of_vector(self.points[-1] - self.get_arc_center()) % TAU, + ) class ArcBetweenPoints(Arc): @@ -402,7 +457,14 @@ def construct(self): self.play(Create(arc)) """ - def __init__(self, start, end, angle=TAU / 4, radius=None, **kwargs): + def __init__( + self, + start: Point3DLike, + end: Point3DLike, + angle: float = TAU / 4, + radius: float | None = None, + **kwargs: Any, + ) -> None: if radius is not None: self.radius = radius if radius < 0: @@ -416,24 +478,29 @@ def __init__(self, start, end, angle=TAU / 4, radius=None, **kwargs): """ArcBetweenPoints called with a radius that is smaller than half the distance between the points.""", ) - arc_height = radius - math.sqrt(radius**2 - halfdist**2) - angle = math.acos((radius - arc_height) / radius) * sign + arc_height = radius - np.sqrt(radius**2 - halfdist**2) + angle = np.arccos((radius - arc_height) / radius) * sign super().__init__(radius=radius, angle=angle, **kwargs) if angle == 0: - self.set_points_as_corners([LEFT, RIGHT]) + self.set_points_as_corners(np.array([LEFT, RIGHT])) self.put_start_and_end_on(start, end) if radius is None: center = self.get_arc_center(warning=False) if not self._failed_to_get_center: - self.radius = np.linalg.norm(np.array(start) - np.array(center)) + # np.linalg.norm returns floating[Any] which is not compatible with float + self.radius = cast( + float, np.linalg.norm(np.array(start) - np.array(center)) + ) else: - self.radius = math.inf + self.radius = np.inf class CurvedArrow(ArcBetweenPoints): - def __init__(self, start_point, end_point, **kwargs): + def __init__( + self, start_point: Point3DLike, end_point: Point3DLike, **kwargs: Any + ) -> None: from manim.mobject.geometry.tips import ArrowTriangleFilledTip tip_shape = kwargs.pop("tip_shape", ArrowTriangleFilledTip) @@ -442,7 +509,9 @@ def __init__(self, start_point, end_point, **kwargs): class CurvedDoubleArrow(CurvedArrow): - def __init__(self, start_point, end_point, **kwargs): + def __init__( + self, start_point: Point3DLike, end_point: Point3DLike, **kwargs: Any + ) -> None: if "tip_shape_end" in kwargs: kwargs["tip_shape"] = kwargs.pop("tip_shape_end") from manim.mobject.geometry.tips import ArrowTriangleFilledTip @@ -480,9 +549,9 @@ def construct(self): def __init__( self, radius: float | None = None, - color: Color | str = RED, - **kwargs, - ): + color: ParsableManimColor = RED, + **kwargs: Any, + ) -> None: super().__init__( radius=radius, start_angle=0, @@ -497,7 +566,7 @@ def surround( dim_to_match: int = 0, stretch: bool = False, buffer_factor: float = 1.2, - ): + ) -> Self: """Modifies a circle so that it surrounds a given mobject. Parameters @@ -533,7 +602,6 @@ def construct(self): group = Group(group1, group2, group3).arrange(buff=1) self.add(group) """ - # Ignores dim_to_match and stretch; result will always be a circle # TODO: Perhaps create an ellipse class to handle single-dimension stretching @@ -544,7 +612,7 @@ def construct(self): self.width = np.sqrt(mobject.width**2 + mobject.height**2) return self.scale(buffer_factor) - def point_at_angle(self, angle: float): + def point_at_angle(self, angle: float) -> Point3D: """Returns the position of a point on the circle. Parameters @@ -573,16 +641,15 @@ def construct(self): self.add(circle, s1, s2) """ - start_angle = angle_of_vector(self.points[0] - self.get_center()) proportion = (angle - start_angle) / TAU - proportion -= math.floor(proportion) + proportion -= np.floor(proportion) return self.point_from_proportion(proportion) @staticmethod def from_three_points( - p1: Sequence[float], p2: Sequence[float], p3: Sequence[float], **kwargs - ): + p1: Point3DLike, p2: Point3DLike, p3: Point3DLike, **kwargs: Any + ) -> Circle: """Returns a circle passing through the specified three points. @@ -602,10 +669,11 @@ def construct(self): self.add(NumberPlane(), circle, dots) """ center = line_intersection( - perpendicular_bisector([p1, p2]), - perpendicular_bisector([p2, p3]), + perpendicular_bisector([np.asarray(p1), np.asarray(p2)]), + perpendicular_bisector([np.asarray(p2), np.asarray(p3)]), ) - radius = np.linalg.norm(p1 - center) + # np.linalg.norm returns floating[Any] which is not compatible with float + radius = cast(float, np.linalg.norm(p1 - center)) return Circle(radius=radius, **kwargs).shift(center) @@ -642,13 +710,13 @@ def construct(self): def __init__( self, - point: list | np.ndarray = ORIGIN, + point: Point3DLike = ORIGIN, radius: float = DEFAULT_DOT_RADIUS, stroke_width: float = 0, fill_opacity: float = 1.0, - color: Color | str = WHITE, - **kwargs, - ): + color: ParsableManimColor = WHITE, + **kwargs: Any, + ) -> None: super().__init__( arc_center=point, radius=radius, @@ -665,11 +733,11 @@ class AnnotationDot(Dot): def __init__( self, radius: float = DEFAULT_DOT_RADIUS * 1.3, - stroke_width=5, - stroke_color=WHITE, - fill_color=BLUE, - **kwargs, - ): + stroke_width: float = 5, + stroke_color: ParsableManimColor = WHITE, + fill_color: ParsableManimColor = BLUE, + **kwargs: Any, + ) -> None: super().__init__( radius=radius, stroke_width=stroke_width, @@ -717,12 +785,12 @@ def __init__( self, label: str | SingleStringMathTex | Text | Tex, radius: float | None = None, - **kwargs, + **kwargs: Any, ) -> None: if isinstance(label, str): from manim import MathTex - rendered_label = MathTex(label, color=BLACK) + rendered_label: VMobject = MathTex(label, color=BLACK) else: rendered_label = label @@ -758,14 +826,16 @@ def construct(self): self.add(ellipse_group) """ - def __init__(self, width: float = 2, height: float = 1, **kwargs): + def __init__(self, width: float = 2, height: float = 1, **kwargs: Any) -> None: super().__init__(**kwargs) self.stretch_to_fit_width(width) self.stretch_to_fit_height(height) class AnnularSector(Arc): - """ + """A sector of an annulus. + + Parameters ---------- inner_radius @@ -810,15 +880,15 @@ def construct(self): def __init__( self, - inner_radius=1, - outer_radius=2, - angle=TAU / 4, - start_angle=0, - fill_opacity=1, - stroke_width=0, - color=WHITE, - **kwargs, - ): + inner_radius: float = 1, + outer_radius: float = 2, + angle: float = TAU / 4, + start_angle: float = 0, + fill_opacity: float = 1, + stroke_width: float = 0, + color: ParsableManimColor = WHITE, + **kwargs: Any, + ) -> None: self.inner_radius = inner_radius self.outer_radius = outer_radius super().__init__( @@ -830,7 +900,7 @@ def __init__( **kwargs, ) - def generate_points(self): + def generate_points(self) -> None: inner_arc, outer_arc = ( Arc( start_angle=self.start_angle, @@ -850,7 +920,8 @@ def generate_points(self): class Sector(AnnularSector): - """ + """A sector of a circle. + Examples -------- .. manim:: ExampleSector @@ -858,15 +929,15 @@ class Sector(AnnularSector): class ExampleSector(Scene): def construct(self): - sector = Sector(outer_radius=2, inner_radius=1) - sector2 = Sector(outer_radius=2.5, inner_radius=0.8).move_to([-3, 0, 0]) + sector = Sector(radius=2) + sector2 = Sector(radius=2.5, angle=60*DEGREES).move_to([-3, 0, 0]) sector.set_color(RED) sector2.set_color(PINK) self.add(sector, sector2) """ - def __init__(self, outer_radius=1, inner_radius=0, **kwargs): - super().__init__(inner_radius=inner_radius, outer_radius=outer_radius, **kwargs) + def __init__(self, radius: float = 1, **kwargs: Any) -> None: + super().__init__(inner_radius=0, outer_radius=radius, **kwargs) class Annulus(Circle): @@ -895,14 +966,14 @@ def construct(self): def __init__( self, - inner_radius: float | None = 1, - outer_radius: float | None = 2, - fill_opacity=1, - stroke_width=0, - color=WHITE, - mark_paths_closed=False, - **kwargs, - ): + inner_radius: float = 1, + outer_radius: float = 2, + fill_opacity: float = 1, + stroke_width: float = 0, + color: ParsableManimColor = WHITE, + mark_paths_closed: bool = False, + **kwargs: Any, + ) -> None: self.mark_paths_closed = mark_paths_closed # is this even used? self.inner_radius = inner_radius self.outer_radius = outer_radius @@ -910,7 +981,7 @@ def __init__( fill_opacity=fill_opacity, stroke_width=stroke_width, color=color, **kwargs ) - def generate_points(self): + def generate_points(self) -> None: self.radius = self.outer_radius outer_circle = Circle(radius=self.outer_radius) inner_circle = Circle(radius=self.inner_radius) @@ -923,7 +994,8 @@ def generate_points(self): class CubicBezier(VMobject, metaclass=ConvertToOpenGL): - """ + """A cubic Bézier curve. + Example ------- .. manim:: BezierSplineExample @@ -944,7 +1016,14 @@ def construct(self): """ - def __init__(self, start_anchor, start_handle, end_handle, end_anchor, **kwargs): + def __init__( + self, + start_anchor: Point3DLike, + start_handle: Point3DLike, + end_handle: Point3DLike, + end_anchor: Point3DLike, + **kwargs: Any, + ) -> None: super().__init__(**kwargs) self.add_cubic_bezier_curve(start_anchor, start_handle, end_handle, end_anchor) @@ -1030,18 +1109,20 @@ def construct(self): def __init__( self, - *vertices: list | np.ndarray, + *vertices: Point3DLike, angle: float = PI / 4, radius: float | None = None, arc_config: list[dict] | None = None, - **kwargs, - ): + **kwargs: Any, + ) -> None: n = len(vertices) point_pairs = [(vertices[k], vertices[(k + 1) % n]) for k in range(n)] if not arc_config: if radius: - all_arc_configs = itertools.repeat({"radius": radius}, len(point_pairs)) + all_arc_configs: Iterable[dict] = itertools.repeat( + {"radius": radius}, len(point_pairs) + ) else: all_arc_configs = itertools.repeat({"angle": angle}, len(point_pairs)) elif isinstance(arc_config, dict): @@ -1173,7 +1254,7 @@ def construct(self): self.wait(2) """ - def __init__(self, *arcs: Arc | ArcBetweenPoints, **kwargs): + def __init__(self, *arcs: Arc | ArcBetweenPoints, **kwargs: Any) -> None: if not all(isinstance(m, (Arc, ArcBetweenPoints)) for m in arcs): raise ValueError( "All ArcPolygon submobjects must be of type Arc/ArcBetweenPoints", @@ -1192,7 +1273,7 @@ def __init__(self, *arcs: Arc | ArcBetweenPoints, **kwargs): self.append_points(arc1.points) line = Line(arc1.get_end(), arc2.get_start()) len_ratio = line.get_length() / arc1.get_arc_length() - if math.isnan(len_ratio) or math.isinf(len_ratio): + if np.isnan(len_ratio) or np.isinf(len_ratio): continue line.insert_n_curves(int(arc1.get_num_curves() * len_ratio)) self.append_points(line.points) diff --git a/manim/mobject/geometry/boolean_ops.py b/manim/mobject/geometry/boolean_ops.py index a7900339bc..f02b4f7be6 100644 --- a/manim/mobject/geometry/boolean_ops.py +++ b/manim/mobject/geometry/boolean_ops.py @@ -2,7 +2,7 @@ from __future__ import annotations -import typing +from typing import TYPE_CHECKING import numpy as np from pathops import Path as SkiaPath @@ -12,6 +12,13 @@ from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL from manim.mobject.types.vectorized_mobject import VMobject +if TYPE_CHECKING: + from typing import Any + + from manim.typing import Point2DLike_Array, Point3D_Array, Point3DLike_Array + +from ...constants import RendererType + __all__ = ["Union", "Intersection", "Difference", "Exclusion"] @@ -21,41 +28,39 @@ class _BooleanOps(VMobject, metaclass=ConvertToOpenGL): objects (:class:`~.VMobject`). """ - def __init__(self, *args, **kwargs): - super().__init__(*args, **kwargs) - def _convert_2d_to_3d_array( self, - points: typing.Iterable, + points: Point2DLike_Array | Point3DLike_Array, z_dim: float = 0.0, - ) -> list[np.ndarray]: - """Converts an iterable with coordinates in 2d to 3d by adding - :attr:`z_dim` as the z coordinate. + ) -> Point3D_Array: + """Converts an iterable with coordinates in 2D to 3D by adding + :attr:`z_dim` as the Z coordinate. Parameters ---------- - points: - An iterable which has the coordinates. - z_dim: - The default value of z coordinate. + points + An iterable of points. + z_dim + Default value for the Z coordinate. Returns ------- - typing.List[np.ndarray] - A list of array converted to 3d. + Point3D_Array + A list of the points converted to 3D. Example ------- >>> a = _BooleanOps() >>> p = [(1, 2), (3, 4)] >>> a._convert_2d_to_3d_array(p) - [array([1., 2., 0.]), array([3., 4., 0.])] + array([[1., 2., 0.], + [3., 4., 0.]]) """ - points = list(points) - for i, point in enumerate(points): + list_of_points = list(points) + for i, point in enumerate(list_of_points): if len(point) == 2: - points[i] = np.array(list(point) + [z_dim]) - return points + list_of_points[i] = np.array(list(point) + [z_dim]) + return np.asarray(list_of_points) def _convert_vmobject_to_skia_path(self, vmobject: VMobject) -> SkiaPath: """Converts a :class:`~.VMobject` to SkiaPath. This method only works for @@ -68,7 +73,7 @@ def _convert_vmobject_to_skia_path(self, vmobject: VMobject) -> SkiaPath: Returns ------- - SkiaPath: + SkiaPath The converted path. """ path = SkiaPath() @@ -82,23 +87,23 @@ def _convert_vmobject_to_skia_path(self, vmobject: VMobject) -> SkiaPath: return path # In OpenGL it's quadratic beizer curves while on Cairo it's cubic... - if config.renderer == "opengl": + if config.renderer == RendererType.OPENGL: subpaths = vmobject.get_subpaths_from_points(points) for subpath in subpaths: quads = vmobject.get_bezier_tuples_from_points(subpath) start = subpath[0] path.moveTo(*start[:2]) - for p0, p1, p2 in quads: + for _p0, p1, p2 in quads: path.quadTo(*p1[:2], *p2[:2]) if vmobject.consider_points_equals(subpath[0], subpath[-1]): path.close() - else: - subpaths = vmobject.gen_subpaths_from_points_2d(points) + elif config.renderer == RendererType.CAIRO: + subpaths = vmobject.gen_subpaths_from_points_2d(points) # type: ignore[assignment] for subpath in subpaths: quads = vmobject.gen_cubic_bezier_tuples_from_points(subpath) start = subpath[0] path.moveTo(*start[:2]) - for p0, p1, p2, p3 in quads: + for _p0, p1, p2, p3 in quads: path.cubicTo(*p1[:2], *p2[:2], *p3[:2]) if vmobject.consider_points_equals_2d(subpath[0], subpath[-1]): @@ -140,7 +145,7 @@ def _convert_skia_path_to_vmobject(self, path: SkiaPath) -> VMobject: n1, n2 = self._convert_2d_to_3d_array(points) vmobject.add_quadratic_bezier_curve_to(n1, n2) else: - raise Exception("Unsupported: %s" % path_verb) + raise Exception(f"Unsupported: {path_verb}") return vmobject @@ -175,7 +180,7 @@ def construct(self): """ - def __init__(self, *vmobjects: VMobject, **kwargs) -> None: + def __init__(self, *vmobjects: VMobject, **kwargs: Any) -> None: if len(vmobjects) < 2: raise ValueError("At least 2 mobjects needed for Union.") super().__init__(**kwargs) @@ -214,7 +219,7 @@ def construct(self): """ - def __init__(self, subject, clip, **kwargs) -> None: + def __init__(self, subject: VMobject, clip: VMobject, **kwargs: Any) -> None: super().__init__(**kwargs) outpen = SkiaPath() difference( @@ -256,7 +261,7 @@ def construct(self): """ - def __init__(self, *vmobjects, **kwargs) -> None: + def __init__(self, *vmobjects: VMobject, **kwargs: Any) -> None: if len(vmobjects) < 2: raise ValueError("At least 2 mobjects needed for Intersection.") @@ -309,7 +314,7 @@ def construct(self): """ - def __init__(self, subject, clip, **kwargs) -> None: + def __init__(self, subject: VMobject, clip: VMobject, **kwargs: Any) -> None: super().__init__(**kwargs) outpen = SkiaPath() xor( diff --git a/manim/mobject/geometry/labeled.py b/manim/mobject/geometry/labeled.py new file mode 100644 index 0000000000..51b74ccb44 --- /dev/null +++ b/manim/mobject/geometry/labeled.py @@ -0,0 +1,378 @@ +r"""Mobjects that inherit from lines and contain a label along the length.""" + +from __future__ import annotations + +__all__ = ["Label", "LabeledLine", "LabeledArrow", "LabeledPolygram"] + +from typing import TYPE_CHECKING + +import numpy as np + +from manim.constants import * +from manim.mobject.geometry.line import Arrow, Line +from manim.mobject.geometry.polygram import Polygram +from manim.mobject.geometry.shape_matchers import ( + BackgroundRectangle, + SurroundingRectangle, +) +from manim.mobject.text.tex_mobject import MathTex, Tex +from manim.mobject.text.text_mobject import Text +from manim.mobject.types.vectorized_mobject import VGroup +from manim.utils.color import WHITE +from manim.utils.polylabel import polylabel + +if TYPE_CHECKING: + from typing import Any + + from manim.typing import Point3DLike_Array + + +class Label(VGroup): + """A Label consisting of text surrounded by a frame. + + Parameters + ---------- + label + Label that will be displayed. + label_config + A dictionary containing the configuration for the label. + This is only applied if ``label`` is of type ``str``. + box_config + A dictionary containing the configuration for the background box. + frame_config + A dictionary containing the configuration for the frame. + + Examples + -------- + .. manim:: LabelExample + :save_last_frame: + :quality: high + + class LabelExample(Scene): + def construct(self): + label = Label( + label=Text('Label Text', font='sans-serif'), + box_config = { + "color" : BLUE, + "fill_opacity" : 0.75 + } + ) + label.scale(3) + self.add(label) + """ + + def __init__( + self, + label: str | Tex | MathTex | Text, + label_config: dict[str, Any] | None = None, + box_config: dict[str, Any] | None = None, + frame_config: dict[str, Any] | None = None, + **kwargs: Any, + ) -> None: + super().__init__(**kwargs) + + # Setup Defaults + default_label_config: dict[str, Any] = { + "color": WHITE, + "font_size": DEFAULT_FONT_SIZE, + } + + default_box_config: dict[str, Any] = { + "color": None, + "buff": 0.05, + "fill_opacity": 1, + "stroke_width": 0.5, + } + + default_frame_config: dict[str, Any] = { + "color": WHITE, + "buff": 0.05, + "stroke_width": 0.5, + } + + # Merge Defaults + label_config = default_label_config | (label_config or {}) + box_config = default_box_config | (box_config or {}) + frame_config = default_frame_config | (frame_config or {}) + + # Determine the type of label and instantiate the appropriate object + self.rendered_label: MathTex | Tex | Text + if isinstance(label, str): + self.rendered_label = MathTex(label, **label_config) + elif isinstance(label, (MathTex, Tex, Text)): + self.rendered_label = label + else: + raise TypeError("Unsupported label type. Must be MathTex, Tex, or Text.") + + # Add a background box + self.background_rect = BackgroundRectangle(self.rendered_label, **box_config) + + # Add a frame around the label + self.frame = SurroundingRectangle(self.rendered_label, **frame_config) + + # Add components to the VGroup + self.add(self.background_rect, self.rendered_label, self.frame) + + +class LabeledLine(Line): + """Constructs a line containing a label box somewhere along its length. + + Parameters + ---------- + label + Label that will be displayed on the line. + label_position + A ratio in the range [0-1] to indicate the position of the label with respect to the length of the line. Default value is 0.5. + label_config + A dictionary containing the configuration for the label. + This is only applied if ``label`` is of type ``str``. + box_config + A dictionary containing the configuration for the background box. + frame_config + A dictionary containing the configuration for the frame. + + .. seealso:: + :class:`LabeledArrow` + + Examples + -------- + .. manim:: LabeledLineExample + :save_last_frame: + :quality: high + + class LabeledLineExample(Scene): + def construct(self): + line = LabeledLine( + label = '0.5', + label_position = 0.8, + label_config = { + "font_size" : 20 + }, + start=LEFT+DOWN, + end=RIGHT+UP) + + line.set_length(line.get_length() * 2) + self.add(line) + """ + + def __init__( + self, + label: str | Tex | MathTex | Text, + label_position: float = 0.5, + label_config: dict[str, Any] | None = None, + box_config: dict[str, Any] | None = None, + frame_config: dict[str, Any] | None = None, + *args: Any, + **kwargs: Any, + ) -> None: + super().__init__(*args, **kwargs) + + # Create Label + self.label = Label( + label=label, + label_config=label_config, + box_config=box_config, + frame_config=frame_config, + ) + + # Compute Label Position + line_start, line_end = self.get_start_and_end() + new_vec = (line_end - line_start) * label_position + label_coords = line_start + new_vec + + self.label.move_to(label_coords) + self.add(self.label) + + +class LabeledArrow(LabeledLine, Arrow): + """Constructs an arrow containing a label box somewhere along its length. + This class inherits its label properties from `LabeledLine`, so the main parameters controlling it are the same. + + Parameters + ---------- + label + Label that will be displayed on the Arrow. + label_position + A ratio in the range [0-1] to indicate the position of the label with respect to the length of the line. Default value is 0.5. + label_config + A dictionary containing the configuration for the label. + This is only applied if ``label`` is of type ``str``. + box_config + A dictionary containing the configuration for the background box. + frame_config + A dictionary containing the configuration for the frame. + + .. seealso:: + :class:`LabeledLine` + + Examples + -------- + .. manim:: LabeledArrowExample + :save_last_frame: + :quality: high + + class LabeledArrowExample(Scene): + def construct(self): + l_arrow = LabeledArrow("0.5", start=LEFT*3, end=RIGHT*3 + UP*2, label_position=0.5) + + self.add(l_arrow) + """ + + def __init__( + self, + *args: Any, + **kwargs: Any, + ) -> None: + super().__init__(*args, **kwargs) + + +class LabeledPolygram(Polygram): + """Constructs a polygram containing a label box at its pole of inaccessibility. + + Parameters + ---------- + vertex_groups + Vertices passed to the :class:`~.Polygram` constructor. + label + Label that will be displayed on the Polygram. + precision + The precision used by the PolyLabel algorithm. + label_config + A dictionary containing the configuration for the label. + This is only applied if ``label`` is of type ``str``. + box_config + A dictionary containing the configuration for the background box. + frame_config + A dictionary containing the configuration for the frame. + + .. note:: + The PolyLabel Algorithm expects each vertex group to form a closed ring. + If the input is open, :class:`LabeledPolygram` will attempt to close it. + This may cause the polygon to intersect itself leading to unexpected results. + + .. tip:: + Make sure the precision corresponds to the scale of your inputs! + For instance, if the bounding box of your polygon stretches from 0 to 10,000, a precision of 1.0 or 10.0 should be sufficient. + + Examples + -------- + .. manim:: LabeledPolygramExample + :save_last_frame: + :quality: high + + class LabeledPolygramExample(Scene): + def construct(self): + # Define Rings + ring1 = [ + [-3.8, -2.4, 0], [-2.4, -2.5, 0], [-1.3, -1.6, 0], [-0.2, -1.7, 0], + [1.7, -2.5, 0], [2.9, -2.6, 0], [3.5, -1.5, 0], [4.9, -1.4, 0], + [4.5, 0.2, 0], [4.7, 1.6, 0], [3.5, 2.4, 0], [1.1, 2.5, 0], + [-0.1, 0.9, 0], [-1.2, 0.5, 0], [-1.6, 0.7, 0], [-1.4, 1.9, 0], + [-2.6, 2.6, 0], [-4.4, 1.2, 0], [-4.9, -0.8, 0], [-3.8, -2.4, 0] + ] + ring2 = [ + [0.2, -1.2, 0], [0.9, -1.2, 0], [1.4, -2.0, 0], [2.1, -1.6, 0], + [2.2, -0.5, 0], [1.4, 0.0, 0], [0.4, -0.2, 0], [0.2, -1.2, 0] + ] + ring3 = [[-2.7, 1.4, 0], [-2.3, 1.7, 0], [-2.8, 1.9, 0], [-2.7, 1.4, 0]] + + # Create Polygons (for reference) + p1 = Polygon(*ring1, fill_opacity=0.75) + p2 = Polygon(*ring2, fill_color=BLACK, fill_opacity=1) + p3 = Polygon(*ring3, fill_color=BLACK, fill_opacity=1) + + # Create Labeled Polygram + polygram = LabeledPolygram( + *[ring1, ring2, ring3], + label=Text('Pole', font='sans-serif'), + precision=0.01, + ) + + # Display Circle (for reference) + circle = Circle(radius=polygram.radius, color=WHITE).move_to(polygram.pole) + + self.add(p1, p2, p3) + self.add(polygram) + self.add(circle) + + .. manim:: LabeledCountryExample + :save_last_frame: + :quality: high + + import requests + import json + + class LabeledCountryExample(Scene): + def construct(self): + # Fetch JSON data and process arcs + data = requests.get('https://cdn.jsdelivr.net/npm/us-atlas@3/nation-10m.json').json() + arcs, transform = data['arcs'], data['transform'] + sarcs = [np.cumsum(arc, axis=0) * transform['scale'] + transform['translate'] for arc in arcs] + ssarcs = sorted(sarcs, key=len, reverse=True)[:1] + + # Compute Bounding Box + points = np.concatenate(ssarcs) + mins, maxs = np.min(points, axis=0), np.max(points, axis=0) + + # Build Axes + ax = Axes( + x_range=[mins[0], maxs[0], maxs[0] - mins[0]], x_length=10, + y_range=[mins[1], maxs[1], maxs[1] - mins[1]], y_length=7, + tips=False + ) + + # Adjust Coordinates + array = [[ax.c2p(*point) for point in sarc] for sarc in ssarcs] + + # Add Polygram + polygram = LabeledPolygram( + *array, + label=Text('USA', font='sans-serif'), + precision=0.01, + fill_color=BLUE, + stroke_width=0, + fill_opacity=0.75 + ) + + # Display Circle (for reference) + circle = Circle(radius=polygram.radius, color=WHITE).move_to(polygram.pole) + + self.add(ax) + self.add(polygram) + self.add(circle) + """ + + def __init__( + self, + *vertex_groups: Point3DLike_Array, + label: str | Tex | MathTex | Text, + precision: float = 0.01, + label_config: dict[str, Any] | None = None, + box_config: dict[str, Any] | None = None, + frame_config: dict[str, Any] | None = None, + **kwargs: Any, + ) -> None: + # Initialize the Polygram with the vertex groups + super().__init__(*vertex_groups, **kwargs) + + # Create Label + self.label = Label( + label=label, + label_config=label_config, + box_config=box_config, + frame_config=frame_config, + ) + + # Close Vertex Groups + rings = [ + group if np.array_equal(group[0], group[-1]) else list(group) + [group[0]] + for group in vertex_groups + ] + + # Compute the Pole of Inaccessibility + cell = polylabel(rings, precision=precision) + self.pole, self.radius = np.pad(cell.c, (0, 1), "constant"), cell.d + + # Position the label at the pole + self.label.move_to(self.pole) + self.add(self.label) diff --git a/manim/mobject/geometry/line.py b/manim/mobject/geometry/line.py index 76e17cc288..be6c3a77ba 100644 --- a/manim/mobject/geometry/line.py +++ b/manim/mobject/geometry/line.py @@ -14,10 +14,9 @@ "RightAngle", ] -from typing import Sequence +from typing import TYPE_CHECKING import numpy as np -from colour import Color from manim import config from manim.constants import * @@ -27,53 +26,119 @@ from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL from manim.mobject.opengl.opengl_mobject import OpenGLMobject from manim.mobject.types.vectorized_mobject import DashedVMobject, VGroup, VMobject -from manim.utils.color import * +from manim.utils.color import WHITE from manim.utils.space_ops import angle_of_vector, line_intersection, normalize +if TYPE_CHECKING: + from typing import Any + + from typing_extensions import Literal, Self, TypeAlias + + from manim.typing import Point2DLike, Point3D, Point3DLike, Vector3D + from manim.utils.color import ParsableManimColor + + from ..matrix import Matrix # Avoid circular import + + AngleQuadrant: TypeAlias = tuple[Literal[-1, 1], Literal[-1, 1]] + r"""A tuple of 2 integers which can be either +1 or -1, allowing to select + one of the 4 quadrants of the Cartesian plane. + + Let :math:`L_1,\ L_2` be two lines defined by start points + :math:`S_1,\ S_2` and end points :math:`E_1,\ E_2`. We define the "positive + direction" of :math:`L_1` as the direction from :math:`S_1` to :math:`E_1`, + and its "negative direction" as the opposite one. We do the same with + :math:`L_2`. + + If :math:`L_1` and :math:`L_2` intersect, they divide the plane into 4 + quadrants. To pick one quadrant, choose the integers in this tuple in the + following way: + + - If the 1st integer is +1, select one of the 2 quadrants towards the + positive direction of :math:`L_1`, i.e. closest to `E_1`. Otherwise, if + the 1st integer is -1, select one of the 2 quadrants towards the + negative direction of :math:`L_1`, i.e. closest to `S_1`. + + - Similarly, the sign of the 2nd integer picks the positive or negative + direction of :math:`L_2` and, thus, selects one of the 2 quadrants + which are closest to :math:`E_2` or :math:`S_2` respectively. + """ + class Line(TipableVMobject): - def __init__(self, start=LEFT, end=RIGHT, buff=0, path_arc=None, **kwargs): + def __init__( + self, + start: Point3DLike | Mobject = LEFT, + end: Point3DLike | Mobject = RIGHT, + buff: float = 0, + path_arc: float | None = None, + **kwargs: Any, + ) -> None: self.dim = 3 self.buff = buff self.path_arc = path_arc self._set_start_and_end_attrs(start, end) super().__init__(**kwargs) + # TODO: Deal with the situation where path_arc is None - def generate_points(self): + def generate_points(self) -> None: self.set_points_by_ends( start=self.start, end=self.end, buff=self.buff, - path_arc=self.path_arc, + path_arc=self.path_arc, # type: ignore[arg-type] ) - def set_points_by_ends(self, start, end, buff=0, path_arc=0): + def set_points_by_ends( + self, + start: Point3DLike | Mobject, + end: Point3DLike | Mobject, + buff: float = 0, + path_arc: float = 0, + ) -> None: + """Sets the points of the line based on its start and end points. + Unlike :meth:`put_start_and_end_on`, this method respects `self.buff` and + Mobject bounding boxes. + + Parameters + ---------- + start + The start point or Mobject of the line. + end + The end point or Mobject of the line. + buff + The empty space between the start and end of the line, by default 0. + path_arc + The angle of a circle spanned by this arc, by default 0 which is a straight line. + """ + self._set_start_and_end_attrs(start, end) if path_arc: + # self.path_arc could potentially be None, which is not accepted + # as parameter. + assert self.path_arc is not None arc = ArcBetweenPoints(self.start, self.end, angle=self.path_arc) self.set_points(arc.points) else: - self.set_points_as_corners([start, end]) + self.set_points_as_corners(np.asarray([self.start, self.end])) self._account_for_buff(buff) init_points = generate_points - def _account_for_buff(self, buff): + def _account_for_buff(self, buff: float) -> None: if buff == 0: return # - if self.path_arc == 0: - length = self.get_length() - else: - length = self.get_arc_length() + length = self.get_length() if self.path_arc == 0 else self.get_arc_length() # if length < 2 * buff: return buff_proportion = buff / length self.pointwise_become_partial(self, buff_proportion, 1 - buff_proportion) - return self + return - def _set_start_and_end_attrs(self, start, end): + def _set_start_and_end_attrs( + self, start: Point3DLike | Mobject, end: Point3DLike | Mobject + ) -> None: # If either start or end are Mobjects, this # gives their centers rough_start = self._pointify(start) @@ -87,9 +152,9 @@ def _set_start_and_end_attrs(self, start, end): def _pointify( self, - mob_or_point: Mobject | Sequence[float], - direction: Sequence[float] | None = None, - ) -> np.ndarray: + mob_or_point: Mobject | Point3DLike, + direction: Vector3D | None = None, + ) -> Point3D: """Transforms a mobject into its corresponding point. Does nothing if a point is passed. ``direction`` determines the location of the point along its bounding box in that direction. @@ -109,11 +174,15 @@ def _pointify( return mob.get_boundary_point(direction) return np.array(mob_or_point) - def set_path_arc(self, new_value): + def set_path_arc(self, new_value: float) -> None: self.path_arc = new_value self.init_points() - def put_start_and_end_on(self, start: Sequence[float], end: Sequence[float]): + def put_start_and_end_on( + self, + start: Point3DLike, + end: Point3DLike, + ) -> Self: """Sets starts and end coordinates of a line. Examples @@ -139,21 +208,21 @@ def construct(self): if np.all(curr_start == curr_end): # TODO, any problems with resetting # these attrs? - self.start = start - self.end = end + self.start = np.asarray(start) + self.end = np.asarray(end) self.generate_points() return super().put_start_and_end_on(start, end) - def get_vector(self): + def get_vector(self) -> Vector3D: return self.get_end() - self.get_start() - def get_unit_vector(self): + def get_unit_vector(self) -> Vector3D: return normalize(self.get_vector()) - def get_angle(self): + def get_angle(self) -> float: return angle_of_vector(self.get_vector()) - def get_projection(self, point: Sequence[float]) -> Sequence[float]: + def get_projection(self, point: Point3DLike) -> Point3D: """Returns the projection of a point onto a line. Parameters @@ -161,16 +230,15 @@ def get_projection(self, point: Sequence[float]) -> Sequence[float]: point The point to which the line is projected. """ - start = self.get_start() end = self.get_end() unit_vect = normalize(end - start) - return start + np.dot(point - start, unit_vect) * unit_vect + return start + float(np.dot(point - start, unit_vect)) * unit_vect - def get_slope(self): - return np.tan(self.get_angle()) + def get_slope(self) -> float: + return float(np.tan(self.get_angle())) - def set_angle(self, angle, about_point=None): + def set_angle(self, angle: float, about_point: Point3DLike | None = None) -> Self: if about_point is None: about_point = self.get_start() @@ -181,8 +249,9 @@ def set_angle(self, angle, about_point=None): return self - def set_length(self, length): - return self.scale(length / self.get_length()) + def set_length(self, length: float) -> Self: + scale_factor: float = length / self.get_length() + return self.scale(scale_factor) class DashedLine(Line): @@ -190,13 +259,13 @@ class DashedLine(Line): Parameters ---------- - args : Any + args Arguments to be passed to :class:`Line` - dash_length : :class:`float`, optional + dash_length The length of each individual dash of the line. - dashed_ratio : :class:`float`, optional + dashed_ratio The ratio of dash space to empty space. Range of 0-1. - kwargs : Any + kwargs Additional arguments to be passed to :class:`Line` @@ -221,11 +290,11 @@ def construct(self): def __init__( self, - *args, - dash_length=DEFAULT_DASH_LENGTH, - dashed_ratio=0.5, - **kwargs, - ): + *args: Any, + dash_length: float = DEFAULT_DASH_LENGTH, + dashed_ratio: float = 0.5, + **kwargs: Any, + ) -> None: self.dash_length = dash_length self.dashed_ratio = dashed_ratio super().__init__(*args, **kwargs) @@ -247,14 +316,13 @@ def _calculate_num_dashes(self) -> int: >>> DashedLine()._calculate_num_dashes() 20 """ - # Minimum number of dashes has to be 2 return max( 2, int(np.ceil((self.get_length() / self.dash_length) * self.dashed_ratio)), ) - def get_start(self) -> np.ndarray: + def get_start(self) -> Point3D: """Returns the start point of the line. Examples @@ -264,13 +332,12 @@ def get_start(self) -> np.ndarray: >>> DashedLine().get_start() array([-1., 0., 0.]) """ - if len(self.submobjects) > 0: return self.submobjects[0].get_start() else: return super().get_start() - def get_end(self) -> np.ndarray: + def get_end(self) -> Point3D: """Returns the end point of the line. Examples @@ -280,13 +347,12 @@ def get_end(self) -> np.ndarray: >>> DashedLine().get_end() array([1., 0., 0.]) """ - if len(self.submobjects) > 0: return self.submobjects[-1].get_end() else: return super().get_end() - def get_first_handle(self) -> np.ndarray: + def get_first_handle(self) -> Point3D: """Returns the point of the first handle. Examples @@ -296,10 +362,13 @@ def get_first_handle(self) -> np.ndarray: >>> DashedLine().get_first_handle() array([-0.98333333, 0. , 0. ]) """ + # Type inference of extracting an element from a list, is not + # supported by numpy, see this numpy issue + # https://github.com/numpy/numpy/issues/16544 + first_handle: Point3D = self.submobjects[0].points[1] + return first_handle - return self.submobjects[0].points[1] - - def get_last_handle(self) -> np.ndarray: + def get_last_handle(self) -> Point3D: """Returns the point of the last handle. Examples @@ -309,8 +378,11 @@ def get_last_handle(self) -> np.ndarray: >>> DashedLine().get_last_handle() array([0.98333333, 0. , 0. ]) """ - - return self.submobjects[-1].points[-2] + # Type inference of extracting an element from a list, is not + # supported by numpy, see this numpy issue + # https://github.com/numpy/numpy/issues/16544 + last_handle: Point3D = self.submobjects[-1].points[2] + return last_handle class TangentLine(Line): @@ -318,15 +390,15 @@ class TangentLine(Line): Parameters ---------- - vmob : :class:`~.VMobject` + vmob The VMobject on which the tangent line is drawn. - alpha : :class:`float` + alpha How far along the shape that the line will be constructed. range: 0-1. - length : :class:`float`, optional + length Length of the tangent line. - d_alpha: :class:`float`, optional + d_alpha The ``dx`` value - kwargs : Any + kwargs Additional arguments to be passed to :class:`Line` @@ -346,7 +418,14 @@ def construct(self): self.add(circle, line_1, line_2) """ - def __init__(self, vmob, alpha, length=1, d_alpha=1e-6, **kwargs): + def __init__( + self, + vmob: VMobject, + alpha: float, + length: float = 1, + d_alpha: float = 1e-6, + **kwargs: Any, + ) -> None: self.length = length self.d_alpha = d_alpha da = self.d_alpha @@ -363,11 +442,11 @@ class Elbow(VMobject, metaclass=ConvertToOpenGL): Parameters ---------- - width : :class:`float`, optional + width The length of the elbow's sides. - angle : :class:`float`, optional + angle The rotation of the elbow. - kwargs : Any + kwargs Additional arguments to be passed to :class:`~.VMobject` .. seealso:: @@ -388,10 +467,10 @@ def construct(self): self.add(elbow_group) """ - def __init__(self, width=0.2, angle=0, **kwargs): + def __init__(self, width: float = 0.2, angle: float = 0, **kwargs: Any) -> None: self.angle = angle super().__init__(**kwargs) - self.set_points_as_corners([UP, UP + RIGHT, RIGHT]) + self.set_points_as_corners(np.array([UP, UP + RIGHT, RIGHT])) self.scale_to_fit_width(width, about_point=ORIGIN) self.rotate(self.angle, about_point=ORIGIN) @@ -401,17 +480,17 @@ class Arrow(Line): Parameters ---------- - args : Any + args Arguments to be passed to :class:`Line`. - stroke_width : :class:`float`, optional + stroke_width The thickness of the arrow. Influenced by :attr:`max_stroke_width_to_length_ratio`. - buff : :class:`float`, optional + buff The distance of the arrow from its start and end points. - max_tip_length_to_length_ratio : :class:`float`, optional + max_tip_length_to_length_ratio :attr:`tip_length` scales with the length of the arrow. Increasing this ratio raises the max value of :attr:`tip_length`. - max_stroke_width_to_length_ratio : :class:`float`, optional + max_stroke_width_to_length_ratio :attr:`stroke_width` scales with the length of the arrow. Increasing this ratio ratios the max value of :attr:`stroke_width`. - kwargs : Any + kwargs Additional arguments to be passed to :class:`Line`. @@ -486,24 +565,24 @@ def construct(self): def __init__( self, - *args, - stroke_width=6, - buff=MED_SMALL_BUFF, - max_tip_length_to_length_ratio=0.25, - max_stroke_width_to_length_ratio=5, - **kwargs, - ): + *args: Any, + stroke_width: float = 6, + buff: float = MED_SMALL_BUFF, + max_tip_length_to_length_ratio: float = 0.25, + max_stroke_width_to_length_ratio: float = 5, + **kwargs: Any, + ) -> None: self.max_tip_length_to_length_ratio = max_tip_length_to_length_ratio self.max_stroke_width_to_length_ratio = max_stroke_width_to_length_ratio tip_shape = kwargs.pop("tip_shape", ArrowTriangleFilledTip) - super().__init__(*args, buff=buff, stroke_width=stroke_width, **kwargs) + super().__init__(*args, buff=buff, stroke_width=stroke_width, **kwargs) # type: ignore[misc] # TODO, should this be affected when # Arrow.set_stroke is called? self.initial_stroke_width = self.stroke_width self.add_tip(tip_shape=tip_shape) self._set_stroke_width_from_length() - def scale(self, factor, scale_tips=False, **kwargs): + def scale(self, factor: float, scale_tips: bool = False, **kwargs: Any) -> Self: # type: ignore[override] r"""Scale an arrow, but keep stroke width and arrow tip size fixed. @@ -553,7 +632,7 @@ def scale(self, factor, scale_tips=False, **kwargs): self.add_tip(tip=old_tips[1], at_start=True) return self - def get_normal_vector(self) -> np.ndarray: + def get_normal_vector(self) -> Vector3D: """Returns the normal of a vector. Examples @@ -563,11 +642,10 @@ def get_normal_vector(self) -> np.ndarray: >>> np.round(Arrow().get_normal_vector()) + 0. # add 0. to avoid negative 0 in output array([ 0., 0., -1.]) """ - p0, p1, p2 = self.tip.get_start_anchors()[:3] return normalize(np.cross(p2 - p1, p1 - p0)) - def reset_normal_vector(self): + def reset_normal_vector(self) -> Self: """Resets the normal of a vector""" self.normal_vector = self.get_normal_vector() return self @@ -583,15 +661,18 @@ def get_default_tip_length(self) -> float: >>> Arrow().get_default_tip_length() 0.35 """ - max_ratio = self.max_tip_length_to_length_ratio return min(self.tip_length, max_ratio * self.get_length()) - def _set_stroke_width_from_length(self): + def _set_stroke_width_from_length(self) -> Self: """Sets stroke width based on length.""" max_ratio = self.max_stroke_width_to_length_ratio - if config.renderer == "opengl": - self.set_stroke( + if config.renderer == RendererType.OPENGL: + # Mypy does not recognize that the self object in this case + # is a OpenGLVMobject and that the set_stroke method is + # defined here: + # mobject/opengl/opengl_vectorized_mobject.py#L248 + self.set_stroke( # type: ignore[call-arg] width=min(self.initial_stroke_width, max_ratio * self.get_length()), recurse=False, ) @@ -606,13 +687,18 @@ def _set_stroke_width_from_length(self): class Vector(Arrow): """A vector specialized for use in graphs. + .. caution:: + Do not confuse with the :class:`~.Vector2D`, + :class:`~.Vector3D` or :class:`~.VectorND` type aliases, + which are not Mobjects! + Parameters ---------- - direction : Union[:class:`list`, :class:`numpy.ndarray`] + direction The direction of the arrow. - buff : :class:`float` + buff The distance of the vector from its endpoints. - kwargs : Any + kwargs Additional arguments to be passed to :class:`Arrow` Examples @@ -628,7 +714,12 @@ def construct(self): self.add(plane, vector_1, vector_2) """ - def __init__(self, direction=RIGHT, buff=0, **kwargs): + def __init__( + self, + direction: Point2DLike | Point3DLike = RIGHT, + buff: float = 0, + **kwargs: Any, + ) -> None: self.buff = buff if len(direction) == 2: direction = np.hstack([direction, 0]) @@ -639,9 +730,9 @@ def coordinate_label( self, integer_labels: bool = True, n_dim: int = 2, - color: Color | None = None, - **kwargs, - ): + color: ParsableManimColor | None = None, + **kwargs: Any, + ) -> Matrix: """Creates a label based on the coordinates of the vector. Parameters @@ -676,7 +767,6 @@ def construct(self): self.add(plane, vec_1, vec_2, label_1, label_2) """ - # avoiding circular imports from ..matrix import Matrix @@ -704,9 +794,9 @@ class DoubleArrow(Arrow): Parameters ---------- - args : Any + args Arguments to be passed to :class:`Arrow` - kwargs : Any + kwargs Additional arguments to be passed to :class:`Arrow` @@ -744,7 +834,7 @@ def construct(self): self.add(box, d1, d2, d3) """ - def __init__(self, *args, **kwargs): + def __init__(self, *args: Any, **kwargs: Any) -> None: if "tip_shape_end" in kwargs: kwargs["tip_shape"] = kwargs.pop("tip_shape_end") tip_shape_start = kwargs.pop("tip_shape_start", ArrowTriangleFilledTip) @@ -763,7 +853,7 @@ class Angle(VMobject, metaclass=ConvertToOpenGL): The second line. radius : The radius of the :class:`Arc`. - quadrant : Sequence[:class:`int`] + quadrant A sequence of two :class:`int` numbers determining which of the 4 quadrants should be used. The first value indicates whether to anchor the arc on the first line closer to the end point (1) or start point (-1), and the second value functions similarly for the @@ -773,16 +863,16 @@ class Angle(VMobject, metaclass=ConvertToOpenGL): Toggles between the two possible angles defined by two points and an arc center. If set to False (default), the arc will always go counterclockwise from the point on line1 until the point on line2 is reached. If set to True, the angle will go clockwise from line1 to line2. - dot : :class:`bool` + dot Allows for a :class:`Dot` in the arc. Mainly used as an convention to indicate a right angle. The dot can be customized in the next three parameters. - dot_radius : :class:`float` + dot_radius The radius of the :class:`Dot`. If not specified otherwise, this radius will be 1/10 of the arc radius. - dot_distance : :class:`float` + dot_distance Relative distance from the center to the arc: 0 puts the dot in the center and 1 on the arc itself. - dot_color : :class:`~.Colors` + dot_color The color of the :class:`Dot`. - elbow : :class:`bool` + elbow Produces an elbow-type mobject indicating a right angle, see :class:`RightAngle` for more information and a shorthand. **kwargs @@ -865,16 +955,16 @@ def __init__( self, line1: Line, line2: Line, - radius: float = None, - quadrant=(1, 1), + radius: float | None = None, + quadrant: AngleQuadrant = (1, 1), other_angle: bool = False, - dot=False, - dot_radius=None, - dot_distance=0.55, - dot_color=WHITE, - elbow=False, - **kwargs, - ): + dot: bool = False, + dot_radius: float | None = None, + dot_distance: float = 0.55, + dot_color: ParsableManimColor = WHITE, + elbow: bool = False, + **kwargs: Any, + ) -> None: super().__init__(**kwargs) self.lines = (line1, line2) self.quadrant = quadrant @@ -910,9 +1000,9 @@ def __init__( + quadrant[0] * radius * line1.get_unit_vector() + quadrant[1] * radius * line2.get_unit_vector() ) - angle_mobject = Elbow(**kwargs) + angle_mobject: VMobject = Elbow(**kwargs) angle_mobject.set_points_as_corners( - [anchor_angle_1, anchor_middle, anchor_angle_2], + np.array([anchor_angle_1, anchor_middle, anchor_angle_2]), ) else: angle_1 = angle_of_vector(anchor_angle_1 - inter) @@ -976,11 +1066,10 @@ def get_lines(self) -> VGroup: >>> angle.get_lines() VGroup(Line, Line) """ - return VGroup(*self.lines) def get_value(self, degrees: bool = False) -> float: - """Get the value of an angle of the :class:`Angle` class. + r"""Get the value of an angle of the :class:`Angle` class. Parameters ---------- @@ -1005,15 +1094,52 @@ def construct(self): angle = Angle(line1, line2, radius=0.4) - value = DecimalNumber(angle.get_value(degrees=True), unit="^{\\circ}") + value = DecimalNumber(angle.get_value(degrees=True), unit=r"^{\circ}") value.next_to(angle, UR) self.add(line1, line2, angle, value) """ + return self.angle_value / DEGREES if degrees else self.angle_value + + @staticmethod + def from_three_points( + A: Point3DLike, B: Point3DLike, C: Point3DLike, **kwargs: Any + ) -> Angle: + r"""The angle between the lines AB and BC. + + This constructs the angle :math:`\\angle ABC`. + + Parameters + ---------- + A + The endpoint of the first angle leg + B + The vertex of the angle + C + The endpoint of the second angle leg + + **kwargs + Further keyword arguments are passed to :class:`.Angle` + + Returns + ------- + The Angle calculated from the three points - if degrees: - return self.angle_value / DEGREES - return self.angle_value + Angle(line1, line2, radius=0.5, quadrant=(-1,1), stroke_width=8), + Angle(line1, line2, radius=0.7, quadrant=(-1,-1), color=RED, other_angle=True), + + Examples + -------- + .. manim:: AngleFromThreePointsExample + :save_last_frame: + + class AngleFromThreePointsExample(Scene): + def construct(self): + sample_angle = Angle.from_three_points(UP, ORIGIN, LEFT) + red_angle = Angle.from_three_points(LEFT + UP, ORIGIN, RIGHT, radius=.8, quadrant=(-1,-1), color=RED, stroke_width=8, other_angle=True) + self.add(red_angle, sample_angle) + """ + return Angle(Line(B, A), Line(B, C), **kwargs) class RightAngle(Angle): @@ -1053,5 +1179,11 @@ def construct(self): self.add(plots) """ - def __init__(self, line1: Line, line2: Line, length: float | None = None, **kwargs): + def __init__( + self, + line1: Line, + line2: Line, + length: float | None = None, + **kwargs: Any, + ) -> None: super().__init__(line1, line2, radius=length, elbow=True, **kwargs) diff --git a/manim/mobject/geometry/polygram.py b/manim/mobject/geometry/polygram.py index dbc1e77fae..5a8dabdaca 100644 --- a/manim/mobject/geometry/polygram.py +++ b/manim/mobject/geometry/polygram.py @@ -13,21 +13,38 @@ "Square", "RoundedRectangle", "Cutout", + "ConvexHull", ] -from typing import Iterable, Sequence + +from math import ceil +from typing import TYPE_CHECKING import numpy as np -from colour import Color from manim.constants import * from manim.mobject.geometry.arc import ArcBetweenPoints from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL from manim.mobject.types.vectorized_mobject import VGroup, VMobject -from manim.utils.color import * +from manim.utils.color import BLUE, WHITE, ParsableManimColor from manim.utils.iterables import adjacent_n_tuples, adjacent_pairs +from manim.utils.qhull import QuickHull from manim.utils.space_ops import angle_between_vectors, normalize, regular_vertices +if TYPE_CHECKING: + from typing import Any, Literal + + import numpy.typing as npt + from typing_extensions import Self + + from manim.typing import ( + Point3D, + Point3D_Array, + Point3DLike, + Point3DLike_Array, + ) + from manim.utils.color import ParsableManimColor + class Polygram(VMobject, metaclass=ConvertToOpenGL): """A generalized :class:`Polygon`, allowing for disconnected sets of edges. @@ -64,10 +81,17 @@ def construct(self): self.wait() """ - def __init__(self, *vertex_groups: Iterable[Sequence[float]], color=BLUE, **kwargs): + def __init__( + self, + *vertex_groups: Point3DLike_Array, + color: ParsableManimColor = BLUE, + **kwargs: Any, + ): super().__init__(color=color, **kwargs) for vertices in vertex_groups: + # The inferred type for *vertices is Any, but it should be + # Point3D_Array first_vertex, *vertices = vertices first_vertex = np.array(first_vertex) @@ -76,7 +100,7 @@ def __init__(self, *vertex_groups: Iterable[Sequence[float]], color=BLUE, **kwar [*(np.array(vertex) for vertex in vertices), first_vertex], ) - def get_vertices(self) -> np.ndarray: + def get_vertices(self) -> Point3D_Array: """Gets the vertices of the :class:`Polygram`. Returns @@ -95,56 +119,94 @@ def get_vertices(self) -> np.ndarray: [-1., -1., 0.], [ 1., -1., 0.]]) """ - return self.get_start_anchors() - def get_vertex_groups(self) -> np.ndarray: + def get_vertex_groups(self) -> list[Point3D_Array]: """Gets the vertex groups of the :class:`Polygram`. Returns ------- - :class:`numpy.ndarray` - The vertex groups of the :class:`Polygram`. + list[Point3D_Array] + The list of vertex groups of the :class:`Polygram`. Examples -------- :: - >>> poly = Polygram([ORIGIN, RIGHT, UP], [LEFT, LEFT + UP, 2 * LEFT]) - >>> poly.get_vertex_groups() - array([[[ 0., 0., 0.], - [ 1., 0., 0.], - [ 0., 1., 0.]], - - [[-1., 0., 0.], - [-1., 1., 0.], - [-2., 0., 0.]]]) + >>> poly = Polygram([ORIGIN, RIGHT, UP, LEFT + UP], [LEFT, LEFT + UP, 2 * LEFT]) + >>> groups = poly.get_vertex_groups() + >>> len(groups) + 2 + >>> groups[0] + array([[ 0., 0., 0.], + [ 1., 0., 0.], + [ 0., 1., 0.], + [-1., 1., 0.]]) + >>> groups[1] + array([[-1., 0., 0.], + [-1., 1., 0.], + [-2., 0., 0.]]) """ - vertex_groups = [] + # TODO: If any of the original vertex groups contained the starting vertex N + # times, then .get_vertex_groups() splits it into N vertex groups. group = [] for start, end in zip(self.get_start_anchors(), self.get_end_anchors()): group.append(start) if self.consider_points_equals(end, group[0]): - vertex_groups.append(group) + vertex_groups.append(np.array(group)) group = [] - return np.array(vertex_groups) + return vertex_groups - def round_corners(self, radius: float = 0.5): + def round_corners( + self, + radius: float | list[float] = 0.5, + evenly_distribute_anchors: bool = False, + components_per_rounded_corner: int = 2, + ) -> Self: """Rounds off the corners of the :class:`Polygram`. Parameters ---------- radius The curvature of the corners of the :class:`Polygram`. + evenly_distribute_anchors + Break long line segments into proportionally-sized segments. + components_per_rounded_corner + The number of points used to represent the rounded corner curve. .. seealso:: :class:`.~RoundedRectangle` + .. note:: + If `radius` is supplied as a single value, then the same radius + will be applied to all corners. If `radius` is a list, then the + individual values will be applied sequentially, with the first + corner receiving `radius[0]`, the second corner receiving + `radius[1]`, etc. The radius list will be repeated as necessary. + + The `components_per_rounded_corner` value is provided so that the + fidelity of the rounded corner may be fine-tuned as needed. 2 is + an appropriate value for most shapes, however a larger value may be + need if the rounded corner is particularly large. 2 is the minimum + number allowed, representing the start and end of the curve. 3 will + result in a start, middle, and end point, meaning 2 curves will be + generated. + + The option to `evenly_distribute_anchors` is provided so that the + line segments (the part part of each line remaining after rounding + off the corners) can be subdivided to a density similar to that of + the average density of the rounded corners. This may be desirable + in situations in which an even distribution of curves is desired + for use in later transformation animations. Be aware, though, that + enabling this option can result in an an object containing + significantly more points than the original, especially when the + rounded corner curves are small. + Examples -------- .. manim:: PolygramRoundCorners @@ -161,15 +223,24 @@ def construct(self): shapes.arrange(RIGHT) self.add(shapes) """ - if radius == 0: return self - new_points = [] + new_points: list[Point3D] = [] - for vertices in self.get_vertex_groups(): + for vertex_group in self.get_vertex_groups(): arcs = [] - for v1, v2, v3 in adjacent_n_tuples(vertices, 3): + + # Repeat the radius list as necessary in order to provide a radius + # for each vertex. + if isinstance(radius, (int, float)): + radius_list = [radius] * len(vertex_group) + else: + radius_list = radius * ceil(len(vertex_group) / len(radius)) + + for current_radius, (v1, v2, v3) in zip( + radius_list, adjacent_n_tuples(vertex_group, 3) + ): vect1 = v2 - v1 vect2 = v3 - v2 unit_vect1 = normalize(vect1) @@ -177,10 +248,10 @@ def construct(self): angle = angle_between_vectors(vect1, vect2) # Negative radius gives concave curves - angle *= np.sign(radius) + angle *= np.sign(current_radius) # Distance between vertex and start of the arc - cut_off_length = radius * np.tan(angle / 2) + cut_off_length = current_radius * np.tan(angle / 2) # Determines counterclockwise vs. clockwise sign = np.sign(np.cross(vect1, vect2)[2]) @@ -189,9 +260,24 @@ def construct(self): v2 - unit_vect1 * cut_off_length, v2 + unit_vect2 * cut_off_length, angle=sign * angle, + num_components=components_per_rounded_corner, ) arcs.append(arc) + if evenly_distribute_anchors: + # Determine the average length of each curve + nonzero_length_arcs = [arc for arc in arcs if len(arc.points) > 4] + if len(nonzero_length_arcs) > 0: + total_arc_length = sum( + [arc.get_arc_length() for arc in nonzero_length_arcs] + ) + num_curves = ( + sum([len(arc.points) for arc in nonzero_length_arcs]) / 4 + ) + average_arc_length = total_arc_length / num_curves + else: + average_arc_length = 1.0 + # To ensure that we loop through starting with last arcs = [arcs[-1], *arcs[:-1]] from manim.mobject.geometry.line import Line @@ -201,14 +287,13 @@ def construct(self): line = Line(arc1.get_end(), arc2.get_start()) - # Make sure anchors are evenly distributed - len_ratio = line.get_length() / arc1.get_arc_length() - - line.insert_n_curves(int(arc1.get_num_curves() * len_ratio)) + # Make sure anchors are evenly distributed, if necessary + if evenly_distribute_anchors: + line.insert_n_curves(ceil(line.get_length() / average_arc_length)) new_points.extend(line.points) - self.set_points(new_points) + self.set_points(np.array(new_points)) return self @@ -243,7 +328,7 @@ def construct(self): self.add(isosceles, square_and_triangles) """ - def __init__(self, *vertices: Sequence[float], **kwargs): + def __init__(self, *vertices: Point3DLike, **kwargs: Any) -> None: super().__init__(vertices, **kwargs) @@ -286,8 +371,8 @@ def __init__( density: int = 2, radius: float = 1, start_angle: float | None = None, - **kwargs, - ): + **kwargs: Any, + ) -> None: # Regular polygrams can be expressed by the number of their vertices # and their density. This relation can be expressed as its Schläfli # symbol: {num_vertices/density}. @@ -307,7 +392,7 @@ def __init__( # Utility function for generating the individual # polygon vertices. - def gen_polygon_vertices(start_angle): + def gen_polygon_vertices(start_angle: float | None) -> tuple[list[Any], float]: reg_vertices, start_angle = regular_vertices( num_vertices, radius=radius, @@ -363,7 +448,7 @@ def construct(self): self.add(poly_group) """ - def __init__(self, n: int = 6, **kwargs): + def __init__(self, n: int = 6, **kwargs: Any) -> None: super().__init__(n, density=1, **kwargs) @@ -403,7 +488,6 @@ class Star(Polygon): Examples -------- .. manim:: StarExample - :save_as_gif: class StarExample(Scene): def construct(self): @@ -434,8 +518,8 @@ def __init__( inner_radius: float | None = None, density: int = 2, start_angle: float | None = TAU / 4, - **kwargs, - ): + **kwargs: Any, + ) -> None: inner_angle = TAU / (2 * n) if inner_radius is None: @@ -466,7 +550,7 @@ def __init__( start_angle=self.start_angle + inner_angle, ) - vertices = [] + vertices: list[npt.NDArray] = [] for pair in zip(outer_vertices, inner_vertices): vertices.extend(pair) @@ -478,7 +562,7 @@ class Triangle(RegularPolygon): Parameters ---------- - kwargs : Any + kwargs Additional arguments to be passed to :class:`RegularPolygon` Examples @@ -494,7 +578,7 @@ def construct(self): self.add(tri_group) """ - def __init__(self, **kwargs): + def __init__(self, **kwargs: Any) -> None: super().__init__(n=3, **kwargs) @@ -503,21 +587,21 @@ class Rectangle(Polygon): Parameters ---------- - color : :class:`~.Colors`, optional + color The color of the rectangle. - height : :class:`float`, optional + height The vertical height of the rectangle. - width : :class:`float`, optional + width The horizontal width of the rectangle. - grid_xstep : :class:`float`, optional + grid_xstep Space between vertical grid lines. - grid_ystep : :class:`float`, optional + grid_ystep Space between horizontal grid lines. - mark_paths_closed : :class:`bool`, optional + mark_paths_closed No purpose. - close_new_points : :class:`bool`, optional + close_new_points No purpose. - kwargs : Any + kwargs Additional arguments to be passed to :class:`Polygon` Examples @@ -529,29 +613,37 @@ class RectangleExample(Scene): def construct(self): rect1 = Rectangle(width=4.0, height=2.0, grid_xstep=1.0, grid_ystep=0.5) rect2 = Rectangle(width=1.0, height=4.0) + rect3 = Rectangle(width=2.0, height=2.0, grid_xstep=1.0, grid_ystep=1.0) + rect3.grid_lines.set_stroke(width=1) - rects = Group(rect1,rect2).arrange(buff=1) + rects = Group(rect1, rect2, rect3).arrange(buff=1) self.add(rects) """ def __init__( self, - color: Color = WHITE, + color: ParsableManimColor = WHITE, height: float = 2.0, width: float = 4.0, grid_xstep: float | None = None, grid_ystep: float | None = None, - mark_paths_closed=True, - close_new_points=True, - **kwargs, + mark_paths_closed: bool = True, + close_new_points: bool = True, + **kwargs: Any, ): super().__init__(UR, UL, DL, DR, color=color, **kwargs) self.stretch_to_fit_width(width) self.stretch_to_fit_height(height) + v = self.get_vertices() - if grid_xstep is not None: + self.grid_lines = VGroup() + + if grid_xstep or grid_ystep: from manim.mobject.geometry.line import Line + v = self.get_vertices() + + if grid_xstep: grid_xstep = abs(grid_xstep) count = int(width / grid_xstep) grid = VGroup( @@ -564,8 +656,9 @@ def __init__( for i in range(1, count) ) ) - self.add(grid) - if grid_ystep is not None: + self.grid_lines.add(grid) + + if grid_ystep: grid_ystep = abs(grid_ystep) count = int(height / grid_ystep) grid = VGroup( @@ -578,7 +671,10 @@ def __init__( for i in range(1, count) ) ) - self.add(grid) + self.grid_lines.add(grid) + + if self.grid_lines: + self.add(self.grid_lines) class Square(Rectangle): @@ -586,9 +682,9 @@ class Square(Rectangle): Parameters ---------- - side_length : :class:`float`, optional + side_length The length of the sides of the square. - kwargs : Any + kwargs Additional arguments to be passed to :class:`Rectangle`. Examples @@ -604,19 +700,26 @@ def construct(self): self.add(square_1, square_2, square_3) """ - def __init__(self, side_length=2.0, **kwargs): - self.side_length = side_length + def __init__(self, side_length: float = 2.0, **kwargs: Any) -> None: super().__init__(height=side_length, width=side_length, **kwargs) + @property + def side_length(self) -> float: + return float(np.linalg.norm(self.get_vertices()[0] - self.get_vertices()[1])) + + @side_length.setter + def side_length(self, value: float) -> None: + self.scale(value / self.side_length) + class RoundedRectangle(Rectangle): """A rectangle with rounded corners. Parameters ---------- - corner_radius : :class:`float`, optional + corner_radius The curvature of the corners of the rectangle. - kwargs : Any + kwargs Additional arguments to be passed to :class:`Rectangle` Examples @@ -633,7 +736,7 @@ def construct(self): self.add(rect_group) """ - def __init__(self, corner_radius=0.5, **kwargs): + def __init__(self, corner_radius: float | list[float] = 0.5, **kwargs: Any): super().__init__(**kwargs) self.corner_radius = corner_radius self.round_corners(self.corner_radius) @@ -644,9 +747,9 @@ class Cutout(VMobject, metaclass=ConvertToOpenGL): Parameters ---------- - main_shape : :class:`~.VMobject` + main_shape The primary shape from which cutouts are made. - mobjects : :class:`~.VMobject` + mobjects The smaller shapes which are to be cut out of the ``main_shape``. kwargs Further keyword arguments that are passed to the constructor of @@ -674,12 +777,77 @@ def construct(self): self.wait() """ - def __init__(self, main_shape, *mobjects, **kwargs): + def __init__( + self, main_shape: VMobject, *mobjects: VMobject, **kwargs: Any + ) -> None: super().__init__(**kwargs) self.append_points(main_shape.points) - if main_shape.get_direction() == "CW": - sub_direction = "CCW" - else: - sub_direction = "CW" + sub_direction: Literal["CCW", "CW"] = ( + "CCW" if main_shape.get_direction() == "CW" else "CW" + ) for mobject in mobjects: self.append_points(mobject.force_direction(sub_direction).points) + + +class ConvexHull(Polygram): + """Constructs a convex hull for a set of points in no particular order. + + Parameters + ---------- + points + The points to consider. + tolerance + The tolerance used by quickhull. + kwargs + Forwarded to the parent constructor. + + Examples + -------- + .. manim:: ConvexHullExample + :save_last_frame: + :quality: high + + class ConvexHullExample(Scene): + def construct(self): + points = [ + [-2.35, -2.25, 0], + [1.65, -2.25, 0], + [2.65, -0.25, 0], + [1.65, 1.75, 0], + [-0.35, 2.75, 0], + [-2.35, 0.75, 0], + [-0.35, -1.25, 0], + [0.65, -0.25, 0], + [-1.35, 0.25, 0], + [0.15, 0.75, 0] + ] + hull = ConvexHull(*points, color=BLUE) + dots = VGroup(*[Dot(point) for point in points]) + self.add(hull) + self.add(dots) + """ + + def __init__( + self, *points: Point3DLike, tolerance: float = 1e-5, **kwargs: Any + ) -> None: + # Build Convex Hull + array = np.array(points)[:, :2] + hull = QuickHull(tolerance) + hull.build(array) + + # Extract Vertices + facets = set(hull.facets) - hull.removed + facet = facets.pop() + subfacets = list(facet.subfacets) + while len(subfacets) <= len(facets): + sf = subfacets[-1] + (facet,) = hull.neighbors[sf] - {facet} + (sf,) = facet.subfacets - {sf} + subfacets.append(sf) + + # Setup Vertices as Point3D + coordinates = np.vstack([sf.coordinates for sf in subfacets]) + vertices = np.hstack((coordinates, np.zeros((len(coordinates), 1)))) + + # Call Polygram + super().__init__(vertices, **kwargs) diff --git a/manim/mobject/geometry/shape_matchers.py b/manim/mobject/geometry/shape_matchers.py index 5aad303090..892f912599 100644 --- a/manim/mobject/geometry/shape_matchers.py +++ b/manim/mobject/geometry/shape_matchers.py @@ -4,13 +4,25 @@ __all__ = ["SurroundingRectangle", "BackgroundRectangle", "Cross", "Underline"] -from manim import config -from manim.constants import * +from typing import Any + +from typing_extensions import Self + +from manim import logger +from manim._config import config +from manim.constants import ( + DOWN, + LEFT, + RIGHT, + SMALL_BUFF, + UP, +) from manim.mobject.geometry.line import Line from manim.mobject.geometry.polygram import RoundedRectangle from manim.mobject.mobject import Mobject +from manim.mobject.opengl.opengl_mobject import OpenGLMobject from manim.mobject.types.vectorized_mobject import VGroup -from manim.utils.color import BLACK, RED, YELLOW, Color, Colors +from manim.utils.color import BLACK, RED, YELLOW, ManimColor, ParsableManimColor class SurroundingRectangle(RoundedRectangle): @@ -38,17 +50,30 @@ def construct(self): """ def __init__( - self, mobject, color=YELLOW, buff=SMALL_BUFF, corner_radius=0.0, **kwargs - ): + self, + *mobjects: Mobject, + color: ParsableManimColor = YELLOW, + buff: float = SMALL_BUFF, + corner_radius: float = 0.0, + **kwargs: Any, + ) -> None: + from manim.mobject.mobject import Group + + if not all(isinstance(mob, (Mobject, OpenGLMobject)) for mob in mobjects): + raise TypeError( + "Expected all inputs for parameter mobjects to be a Mobjects" + ) + + group = Group(*mobjects) super().__init__( color=color, - width=mobject.width + 2 * buff, - height=mobject.height + 2 * buff, + width=group.width + 2 * buff, + height=group.height + 2 * buff, corner_radius=corner_radius, **kwargs, ) self.buff = buff - self.move_to(mobject) + self.move_to(group) class BackgroundRectangle(SurroundingRectangle): @@ -78,19 +103,19 @@ def construct(self): def __init__( self, - mobject, - color: Colors | None = None, + *mobjects: Mobject, + color: ParsableManimColor | None = None, stroke_width: float = 0, stroke_opacity: float = 0, fill_opacity: float = 0.75, buff: float = 0, - **kwargs, - ): + **kwargs: Any, + ) -> None: if color is None: color = config.background_color super().__init__( - mobject, + *mobjects, color=color, stroke_width=stroke_width, stroke_opacity=stroke_opacity, @@ -98,31 +123,33 @@ def __init__( buff=buff, **kwargs, ) - self.original_fill_opacity = self.fill_opacity + self.original_fill_opacity: float = self.fill_opacity - def pointwise_become_partial(self, mobject, a, b): + def pointwise_become_partial(self, mobject: Mobject, a: Any, b: float) -> Self: self.set_fill(opacity=b * self.original_fill_opacity) return self - def set_style( - self, - stroke_color=None, - stroke_width=None, - fill_color=None, - fill_opacity=None, - family=True, - ): + def set_style(self, fill_opacity: float, **kwargs: Any) -> Self: # type: ignore[override] # Unchangeable style, except for fill_opacity + # All other style arguments are ignored super().set_style( stroke_color=BLACK, stroke_width=0, fill_color=BLACK, fill_opacity=fill_opacity, ) + if len(kwargs) > 0: + logger.info( + "Argument %s is ignored in BackgroundRectangle.set_style.", + kwargs, + ) return self - def get_fill_color(self): - return Color(self.color) + def get_fill_color(self) -> ManimColor: + # The type of the color property is set to Any using the property decorator + # vectorized_mobject.py#L571 + temp_color: ManimColor = self.color + return temp_color class Cross(VGroup): @@ -153,11 +180,11 @@ def construct(self): def __init__( self, mobject: Mobject | None = None, - stroke_color: Color = RED, - stroke_width: float = 6, - scale_factor: float = 1, - **kwargs, - ): + stroke_color: ParsableManimColor = RED, + stroke_width: float = 6.0, + scale_factor: float = 1.0, + **kwargs: Any, + ) -> None: super().__init__( Line(UP + LEFT, DOWN + RIGHT), Line(UP + RIGHT, DOWN + LEFT), **kwargs ) @@ -170,11 +197,6 @@ def __init__( class Underline(Line): """Creates an underline. - Parameters - ---------- - Line - The underline. - Examples -------- .. manim:: UnderLine @@ -187,7 +209,9 @@ def construct(self): self.add(man, ul) """ - def __init__(self, mobject, buff=SMALL_BUFF, **kwargs): + def __init__( + self, mobject: Mobject, buff: float = SMALL_BUFF, **kwargs: Any + ) -> None: super().__init__(LEFT, RIGHT, buff=buff, **kwargs) self.match_width(mobject) self.next_to(mobject, DOWN, buff=self.buff) diff --git a/manim/mobject/geometry/tips.py b/manim/mobject/geometry/tips.py index 30f71ceb96..ea7c6c2414 100644 --- a/manim/mobject/geometry/tips.py +++ b/manim/mobject/geometry/tips.py @@ -8,8 +8,13 @@ "ArrowCircleTip", "ArrowSquareTip", "ArrowSquareFilledTip", + "ArrowTriangleTip", + "ArrowTriangleFilledTip", + "StealthTip", ] +from typing import TYPE_CHECKING + import numpy as np from manim.constants import * @@ -19,6 +24,11 @@ from manim.mobject.types.vectorized_mobject import VMobject from manim.utils.space_ops import angle_of_vector +if TYPE_CHECKING: + from typing import Any + + from manim.typing import Point3D, Vector3D + class ArrowTip(VMobject, metaclass=ConvertToOpenGL): r"""Base class for arrow tips. @@ -30,6 +40,7 @@ class ArrowTip(VMobject, metaclass=ConvertToOpenGL): :class:`ArrowCircleFilledTip` :class:`ArrowSquareTip` :class:`ArrowSquareFilledTip` + :class:`StealthTip` Examples -------- @@ -51,8 +62,9 @@ class ArrowTip(VMobject, metaclass=ConvertToOpenGL): ... RegularPolygon.__init__(self, n=5, **kwargs) ... self.width = length ... self.stretch_to_fit_height(length) - >>> arr = Arrow(np.array([-2, -2, 0]), np.array([2, 2, 0]), - ... tip_shape=MyCustomArrowTip) + >>> arr = Arrow( + ... np.array([-2, -2, 0]), np.array([2, 2, 0]), tip_shape=MyCustomArrowTip + ... ) >>> isinstance(arr.tip, RegularPolygon) True >>> from manim import Scene, Create @@ -72,30 +84,41 @@ class ArrowTip(VMobject, metaclass=ConvertToOpenGL): .. manim:: ArrowTipsShowcase :save_last_frame: - from manim.mobject.geometry.tips import ArrowTriangleTip,\ - ArrowSquareTip, ArrowSquareFilledTip,\ - ArrowCircleTip, ArrowCircleFilledTip class ArrowTipsShowcase(Scene): def construct(self): - a00 = Arrow(start=[-2, 3, 0], end=[2, 3, 0], color=YELLOW) - a11 = Arrow(start=[-2, 2, 0], end=[2, 2, 0], tip_shape=ArrowTriangleTip) - a12 = Arrow(start=[-2, 1, 0], end=[2, 1, 0]) - a21 = Arrow(start=[-2, 0, 0], end=[2, 0, 0], tip_shape=ArrowSquareTip) - a22 = Arrow([-2, -1, 0], [2, -1, 0], tip_shape=ArrowSquareFilledTip) - a31 = Arrow([-2, -2, 0], [2, -2, 0], tip_shape=ArrowCircleTip) - a32 = Arrow([-2, -3, 0], [2, -3, 0], tip_shape=ArrowCircleFilledTip) - b11 = a11.copy().scale(0.5, scale_tips=True).next_to(a11, RIGHT) - b12 = a12.copy().scale(0.5, scale_tips=True).next_to(a12, RIGHT) - b21 = a21.copy().scale(0.5, scale_tips=True).next_to(a21, RIGHT) - self.add(a00, a11, a12, a21, a22, a31, a32, b11, b12, b21) - + tip_names = [ + 'Default (YELLOW)', 'ArrowTriangleTip', 'Default', 'ArrowSquareTip', + 'ArrowSquareFilledTip', 'ArrowCircleTip', 'ArrowCircleFilledTip', 'StealthTip' + ] + + big_arrows = [ + Arrow(start=[-4, 3.5, 0], end=[2, 3.5, 0], color=YELLOW), + Arrow(start=[-4, 2.5, 0], end=[2, 2.5, 0], tip_shape=ArrowTriangleTip), + Arrow(start=[-4, 1.5, 0], end=[2, 1.5, 0]), + Arrow(start=[-4, 0.5, 0], end=[2, 0.5, 0], tip_shape=ArrowSquareTip), + + Arrow([-4, -0.5, 0], [2, -0.5, 0], tip_shape=ArrowSquareFilledTip), + Arrow([-4, -1.5, 0], [2, -1.5, 0], tip_shape=ArrowCircleTip), + Arrow([-4, -2.5, 0], [2, -2.5, 0], tip_shape=ArrowCircleFilledTip), + Arrow([-4, -3.5, 0], [2, -3.5, 0], tip_shape=StealthTip) + ] + + small_arrows = ( + arrow.copy().scale(0.5, scale_tips=True).next_to(arrow, RIGHT) for arrow in big_arrows + ) + + labels = ( + Text(tip_names[i], font='monospace', font_size=20, color=BLUE).next_to(big_arrows[i], LEFT) for i in range(len(big_arrows)) + ) + + self.add(*big_arrows, *small_arrows, *labels) """ - def __init__(self, *args, **kwargs): + def __init__(self, *args: Any, **kwargs: Any) -> None: raise NotImplementedError("Has to be implemented in inheriting subclasses.") @property - def base(self): + def base(self) -> Point3D: r"""The base point of the arrow tip. This is the point connecting to the arrow line. @@ -113,7 +136,7 @@ def base(self): return self.point_from_proportion(0.5) @property - def tip_point(self): + def tip_point(self) -> Point3D: r"""The tip point of the arrow tip. Examples @@ -126,10 +149,14 @@ def tip_point(self): array([2., 0., 0.]) """ - return self.points[0] + # Type inference of extracting an element from a list, is not + # supported by numpy, see this numpy issue + # https://github.com/numpy/numpy/issues/16544 + tip_point: Point3D = self.points[0] + return tip_point @property - def vector(self): + def vector(self) -> Vector3D: r"""The vector pointing from the base point to the tip point. Examples @@ -145,7 +172,7 @@ def vector(self): return self.tip_point - self.base @property - def tip_angle(self): + def tip_angle(self) -> float: r"""The angle of the arrow tip. Examples @@ -154,14 +181,14 @@ def tip_angle(self): >>> from manim import Arrow >>> arrow = Arrow(np.array([0, 0, 0]), np.array([1, 1, 0]), buff=0) - >>> round(arrow.tip.tip_angle, 5) == round(PI/4, 5) + >>> bool(round(arrow.tip.tip_angle, 5) == round(PI/4, 5)) True """ return angle_of_vector(self.vector) @property - def length(self): + def length(self) -> float: r"""The length of the arrow tip. Examples @@ -174,7 +201,50 @@ def length(self): 0.35 """ - return np.linalg.norm(self.vector) + return float(np.linalg.norm(self.vector)) + + +class StealthTip(ArrowTip): + r"""'Stealth' fighter / kite arrow shape. + + Naming is inspired by the corresponding + `TikZ arrow shape `__. + """ + + def __init__( + self, + fill_opacity: float = 1, + stroke_width: float = 3, + length: float = DEFAULT_ARROW_TIP_LENGTH / 2, + start_angle: float = PI, + **kwargs: Any, + ): + self.start_angle = start_angle + VMobject.__init__( + self, fill_opacity=fill_opacity, stroke_width=stroke_width, **kwargs + ) + self.set_points_as_corners( + np.array( + [ + [2, 0, 0], # tip + [-1.2, 1.6, 0], + [0, 0, 0], # base + [-1.2, -1.6, 0], + [2, 0, 0], # close path, back to tip + ] + ) + ) + self.scale(length / self.length) + + @property + def length(self) -> float: + """The length of the arrow tip. + + In this case, the length is computed as the height of + the triangle encompassing the stealth tip (otherwise, + the tip is scaled too large). + """ + return float(np.linalg.norm(self.vector) * 1.6) class ArrowTriangleTip(ArrowTip, Triangle): @@ -182,12 +252,13 @@ class ArrowTriangleTip(ArrowTip, Triangle): def __init__( self, - fill_opacity=0, - stroke_width=3, - length=DEFAULT_ARROW_TIP_LENGTH, - start_angle=PI, - **kwargs, - ): + fill_opacity: float = 0, + stroke_width: float = 3, + length: float = DEFAULT_ARROW_TIP_LENGTH, + width: float = DEFAULT_ARROW_TIP_LENGTH, + start_angle: float = PI, + **kwargs: Any, + ) -> None: Triangle.__init__( self, fill_opacity=fill_opacity, @@ -195,8 +266,10 @@ def __init__( start_angle=start_angle, **kwargs, ) - self.width = length - self.stretch_to_fit_height(length) + self.width = width + + self.stretch_to_fit_width(length) + self.stretch_to_fit_height(width) class ArrowTriangleFilledTip(ArrowTriangleTip): @@ -205,7 +278,9 @@ class ArrowTriangleFilledTip(ArrowTriangleTip): This is the default arrow tip shape. """ - def __init__(self, fill_opacity=1, stroke_width=0, **kwargs): + def __init__( + self, fill_opacity: float = 1, stroke_width: float = 0, **kwargs: Any + ) -> None: super().__init__(fill_opacity=fill_opacity, stroke_width=stroke_width, **kwargs) @@ -214,12 +289,12 @@ class ArrowCircleTip(ArrowTip, Circle): def __init__( self, - fill_opacity=0, - stroke_width=3, - length=DEFAULT_ARROW_TIP_LENGTH, - start_angle=PI, - **kwargs, - ): + fill_opacity: float = 0, + stroke_width: float = 3, + length: float = DEFAULT_ARROW_TIP_LENGTH, + start_angle: float = PI, + **kwargs: Any, + ) -> None: self.start_angle = start_angle Circle.__init__( self, fill_opacity=fill_opacity, stroke_width=stroke_width, **kwargs @@ -231,7 +306,9 @@ def __init__( class ArrowCircleFilledTip(ArrowCircleTip): r"""Circular arrow tip with filled tip.""" - def __init__(self, fill_opacity=1, stroke_width=0, **kwargs): + def __init__( + self, fill_opacity: float = 1, stroke_width: float = 0, **kwargs: Any + ) -> None: super().__init__(fill_opacity=fill_opacity, stroke_width=stroke_width, **kwargs) @@ -240,12 +317,12 @@ class ArrowSquareTip(ArrowTip, Square): def __init__( self, - fill_opacity=0, - stroke_width=3, - length=DEFAULT_ARROW_TIP_LENGTH, - start_angle=PI, - **kwargs, - ): + fill_opacity: float = 0, + stroke_width: float = 3, + length: float = DEFAULT_ARROW_TIP_LENGTH, + start_angle: float = PI, + **kwargs: Any, + ) -> None: self.start_angle = start_angle Square.__init__( self, @@ -261,5 +338,7 @@ def __init__( class ArrowSquareFilledTip(ArrowSquareTip): r"""Square arrow tip with filled tip.""" - def __init__(self, fill_opacity=1, stroke_width=0, **kwargs): + def __init__( + self, fill_opacity: float = 1, stroke_width: float = 0, **kwargs: Any + ) -> None: super().__init__(fill_opacity=fill_opacity, stroke_width=stroke_width, **kwargs) diff --git a/manim/mobject/graph.py b/manim/mobject/graph.py index 20d430a5a5..3e9b91ede3 100644 --- a/manim/mobject/graph.py +++ b/manim/mobject/graph.py @@ -4,128 +4,341 @@ __all__ = [ "Graph", + "DiGraph", ] import itertools as it +from collections.abc import Hashable, Iterable, Sequence from copy import copy -from typing import Hashable, Iterable +from typing import TYPE_CHECKING, Any, Literal, Protocol, cast import networkx as nx import numpy as np +if TYPE_CHECKING: + from typing_extensions import TypeAlias + + from manim.scene.scene import Scene + from manim.typing import Point3D, Point3DLike + + NxGraph: TypeAlias = nx.classes.graph.Graph | nx.classes.digraph.DiGraph + +from manim.animation.composition import AnimationGroup +from manim.animation.creation import Create, Uncreate from manim.mobject.geometry.arc import Dot, LabeledDot from manim.mobject.geometry.line import Line +from manim.mobject.mobject import Mobject, override_animate from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL from manim.mobject.opengl.opengl_mobject import OpenGLMobject from manim.mobject.text.tex_mobject import MathTex +from manim.mobject.types.vectorized_mobject import VMobject +from manim.utils.color import BLACK -from ..animation.composition import AnimationGroup -from ..animation.creation import Create, Uncreate -from ..utils.color import BLACK -from .mobject import Mobject, override_animate -from .types.vectorized_mobject import VMobject +class LayoutFunction(Protocol): + """A protocol for automatic layout functions that compute a layout for a graph to be used in :meth:`~.Graph.change_layout`. -def _determine_graph_layout( - nx_graph: nx.classes.graph.Graph, - layout: str | dict = "spring", - layout_scale: float = 2, - layout_config: dict | None = None, - partitions: list[list[Hashable]] | None = None, - root_vertex: Hashable | None = None, -) -> dict: - automatic_layouts = { - "circular": nx.layout.circular_layout, - "kamada_kawai": nx.layout.kamada_kawai_layout, - "planar": nx.layout.planar_layout, - "random": nx.layout.random_layout, - "shell": nx.layout.shell_layout, - "spectral": nx.layout.spectral_layout, - "partite": nx.layout.multipartite_layout, - "tree": _tree_layout, - "spiral": nx.layout.spiral_layout, - "spring": nx.layout.spring_layout, - } - - custom_layouts = ["random", "partite", "tree"] + .. note:: The layout function must be a pure function, i.e., it must not modify the graph passed to it. - if layout_config is None: - layout_config = {} + Examples + -------- - if isinstance(layout, dict): - return layout - elif layout in automatic_layouts and layout not in custom_layouts: - auto_layout = automatic_layouts[layout]( - nx_graph, scale=layout_scale, **layout_config - ) - return {k: np.append(v, [0]) for k, v in auto_layout.items()} - elif layout == "tree": - return _tree_layout( - nx_graph, root_vertex=root_vertex, scale=layout_scale, **layout_config - ) - elif layout == "partite": - if partitions is None or len(partitions) == 0: - raise ValueError( - "The partite layout requires the 'partitions' parameter to contain the partition of the vertices", - ) - partition_count = len(partitions) - for i in range(partition_count): - for v in partitions[i]: - if nx_graph.nodes[v] is None: - raise ValueError( - "The partition must contain arrays of vertices in the graph", - ) - nx_graph.nodes[v]["subset"] = i - # Add missing vertices to their own side - for v in nx_graph.nodes: - if "subset" not in nx_graph.nodes[v]: - nx_graph.nodes[v]["subset"] = partition_count - - auto_layout = automatic_layouts["partite"]( - nx_graph, scale=layout_scale, **layout_config - ) - return {k: np.append(v, [0]) for k, v in auto_layout.items()} - elif layout == "random": - # the random layout places coordinates in [0, 1) - # we need to rescale manually afterwards... - auto_layout = automatic_layouts["random"](nx_graph, **layout_config) - for k, v in auto_layout.items(): - auto_layout[k] = 2 * layout_scale * (v - np.array([0.5, 0.5])) - return {k: np.append(v, [0]) for k, v in auto_layout.items()} - else: + Here is an example that arranges nodes in an n x m grid in sorted order. + + .. manim:: CustomLayoutExample + :save_last_frame: + + class CustomLayoutExample(Scene): + def construct(self): + import numpy as np + import networkx as nx + + # create custom layout + def custom_layout( + graph: nx.Graph, + scale: float | tuple[float, float, float] = 2, + n: int | None = None, + *args: Any, + **kwargs: Any, + ): + nodes = sorted(list(graph)) + height = len(nodes) // n + return { + node: (scale * np.array([ + (i % n) - (n-1)/2, + -(i // n) + height/2, + 0 + ])) for i, node in enumerate(graph) + } + + # draw graph + n = 4 + graph = Graph( + [i for i in range(4 * 2 - 1)], + [(0, 1), (0, 4), (1, 2), (1, 5), (2, 3), (2, 6), (4, 5), (5, 6)], + labels=True, + layout=custom_layout, + layout_config={'n': n} + ) + self.add(graph) + + Several automatic layouts are provided by manim, and can be used by passing their name as the ``layout`` parameter to :meth:`~.Graph.change_layout`. + Alternatively, a custom layout function can be passed to :meth:`~.Graph.change_layout` as the ``layout`` parameter. Such a function must adhere to the :class:`~.LayoutFunction` protocol. + + The :class:`~.LayoutFunction` s provided by manim are illustrated below: + + - Circular Layout: places the vertices on a circle + + .. manim:: CircularLayout + :save_last_frame: + + class CircularLayout(Scene): + def construct(self): + graph = Graph( + [1, 2, 3, 4, 5, 6], + [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 1), (5, 1), (1, 3), (3, 5)], + layout="circular", + labels=True + ) + self.add(graph) + + - Kamada Kawai Layout: tries to place the vertices such that the given distances between them are respected + + .. manim:: KamadaKawaiLayout + :save_last_frame: + + class KamadaKawaiLayout(Scene): + def construct(self): + from collections import defaultdict + distances: dict[int, dict[int, float]] = defaultdict(dict) + + # set desired distances + distances[1][2] = 1 # distance between vertices 1 and 2 is 1 + distances[2][3] = 1 # distance between vertices 2 and 3 is 1 + distances[3][4] = 2 # etc + distances[4][5] = 3 + distances[5][6] = 5 + distances[6][1] = 8 + + graph = Graph( + [1, 2, 3, 4, 5, 6], + [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 1)], + layout="kamada_kawai", + layout_config={"dist": distances}, + layout_scale=4, + labels=True + ) + self.add(graph) + + - Partite Layout: places vertices into distinct partitions + + .. manim:: PartiteLayout + :save_last_frame: + + class PartiteLayout(Scene): + def construct(self): + graph = Graph( + [1, 2, 3, 4, 5, 6], + [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 1), (5, 1), (1, 3), (3, 5)], + layout="partite", + layout_config={"partitions": [[1,2],[3,4],[5,6]]}, + labels=True + ) + self.add(graph) + + - Planar Layout: places vertices such that edges do not cross + + .. manim:: PlanarLayout + :save_last_frame: + + class PlanarLayout(Scene): + def construct(self): + graph = Graph( + [1, 2, 3, 4, 5, 6], + [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 1), (5, 1), (1, 3), (3, 5)], + layout="planar", + layout_scale=4, + labels=True + ) + self.add(graph) + + - Random Layout: randomly places vertices + + .. manim:: RandomLayout + :save_last_frame: + + class RandomLayout(Scene): + def construct(self): + graph = Graph( + [1, 2, 3, 4, 5, 6], + [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 1), (5, 1), (1, 3), (3, 5)], + layout="random", + labels=True + ) + self.add(graph) + + - Shell Layout: places vertices in concentric circles + + .. manim:: ShellLayout + :save_last_frame: + + class ShellLayout(Scene): + def construct(self): + nlist = [[1, 2, 3], [4, 5, 6, 7, 8, 9]] + graph = Graph( + [1, 2, 3, 4, 5, 6, 7, 8, 9], + [(1, 2), (2, 3), (3, 1), (4, 1), (4, 2), (5, 2), (6, 2), (6, 3), (7, 3), (8, 3), (8, 1), (9, 1)], + layout="shell", + layout_config={"nlist": nlist}, + labels=True + ) + self.add(graph) + + - Spectral Layout: places vertices using the eigenvectors of the graph Laplacian (clusters nodes which are an approximation of the ratio cut) + + .. manim:: SpectralLayout + :save_last_frame: + + class SpectralLayout(Scene): + def construct(self): + graph = Graph( + [1, 2, 3, 4, 5, 6], + [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 1), (5, 1), (1, 3), (3, 5)], + layout="spectral", + labels=True + ) + self.add(graph) + + - Sprial Layout: places vertices in a spiraling pattern + + .. manim:: SpiralLayout + :save_last_frame: + + class SpiralLayout(Scene): + def construct(self): + graph = Graph( + [1, 2, 3, 4, 5, 6], + [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 1), (5, 1), (1, 3), (3, 5)], + layout="spiral", + labels=True + ) + self.add(graph) + + - Spring Layout: places nodes according to the Fruchterman-Reingold force-directed algorithm (attempts to minimize edge length while maximizing node separation) + + .. manim:: SpringLayout + :save_last_frame: + + class SpringLayout(Scene): + def construct(self): + graph = Graph( + [1, 2, 3, 4, 5, 6], + [(1, 2), (2, 3), (3, 4), (4, 5), (5, 6), (6, 1), (5, 1), (1, 3), (3, 5)], + layout="spring", + labels=True + ) + self.add(graph) + + - Tree Layout: places vertices into a tree with a root node and branches (can only be used with legal trees) + + .. manim:: TreeLayout + :save_last_frame: + + class TreeLayout(Scene): + def construct(self): + graph = Graph( + [1, 2, 3, 4, 5, 6, 7], + [(1, 2), (1, 3), (2, 4), (2, 5), (3, 6), (3, 7)], + layout="tree", + layout_config={"root_vertex": 1}, + labels=True + ) + self.add(graph) + + """ + + def __call__( + self, + graph: NxGraph, + scale: float | tuple[float, float, float] = 2, + *args: Any, + **kwargs: Any, + ) -> dict[Hashable, Point3D]: + """Given a graph and a scale, return a dictionary of coordinates. + + Parameters + ---------- + graph + The underlying NetworkX graph to be laid out. DO NOT MODIFY. + scale + Either a single float value, or a tuple of three float values specifying the scale along each axis. + + Returns + ------- + dict[Hashable, Point3D] + A dictionary mapping vertices to their positions. + """ + ... + + +def _partite_layout( + nx_graph: NxGraph, + scale: float = 2, + partitions: Sequence[Sequence[Hashable]] | None = None, + **kwargs: Any, +) -> dict[Hashable, Point3D]: + if partitions is None or len(partitions) == 0: raise ValueError( - f"The layout '{layout}' is neither a recognized automatic layout, " - "nor a vertex placement dictionary.", + "The partite layout requires partitions parameter to contain the partition of the vertices", ) + partition_count = len(partitions) + for i in range(partition_count): + for v in partitions[i]: + if nx_graph.nodes[v] is None: + raise ValueError( + "The partition must contain arrays of vertices in the graph", + ) + nx_graph.nodes[v]["subset"] = i + # Add missing vertices to their own side + for v in nx_graph.nodes: + if "subset" not in nx_graph.nodes[v]: + nx_graph.nodes[v]["subset"] = partition_count + + return nx.layout.multipartite_layout(nx_graph, scale=scale, **kwargs) + + +def _random_layout(nx_graph: NxGraph, scale: float = 2, **kwargs: Any): + # the random layout places coordinates in [0, 1) + # we need to rescale manually afterwards... + auto_layout = nx.layout.random_layout(nx_graph, **kwargs) + for k, v in auto_layout.items(): + auto_layout[k] = 2 * scale * (v - np.array([0.5, 0.5])) + return {k: np.append(v, [0]) for k, v in auto_layout.items()} def _tree_layout( - T: nx.classes.graph.Graph, - root_vertex: Hashable | None, + T: NxGraph, + root_vertex: Hashable | None = None, scale: float | tuple | None = 2, vertex_spacing: tuple | None = None, orientation: str = "down", ): - children = {root_vertex: list(T.neighbors(root_vertex))} - - if not nx.is_tree(T): - raise ValueError("The tree layout must be used with trees") if root_vertex is None: raise ValueError("The tree layout requires the root_vertex parameter") + if not nx.is_tree(T): + raise ValueError("The tree layout must be used with trees") + children = {root_vertex: list(T.neighbors(root_vertex))} # The following code is SageMath's tree layout implementation, taken from # https://github.com/sagemath/sage/blob/cc60cfebc4576fed8b01f0fc487271bdee3cefed/src/sage/graphs/graph_plot.py#L1447 # Always make a copy of the children because they get eaten stack = [list(children[root_vertex]).copy()] stick = [root_vertex] - parent = {u: root_vertex for u in children[root_vertex]} + parent = dict.fromkeys(children[root_vertex], root_vertex) pos = {} obstruction = [0.0] * len(T) - if orientation == "down": - o = -1 - else: - o = 1 + o = -1 if orientation == "down" else 1 def slide(v, dx): """ @@ -188,15 +401,9 @@ def slide(v, dx): if isinstance(scale, (float, int)) and (width > 0 or height > 0): sf = 2 * scale / max(width, height) elif isinstance(scale, tuple): - if scale[0] is not None and width > 0: - sw = 2 * scale[0] / width - else: - sw = 1 + sw = 2 * scale[0] / width if scale[0] is not None and width > 0 else 1 - if scale[1] is not None and height > 0: - sh = 2 * scale[1] / height - else: - sh = 1 + sh = 2 * scale[1] / height if scale[1] is not None and height > 0 else 1 sf = np.array([sw, sh, 0]) else: @@ -207,18 +414,89 @@ def slide(v, dx): return {v: (np.array([x, y, 0]) - center) * sf for v, (x, y) in pos.items()} -class Graph(VMobject, metaclass=ConvertToOpenGL): - """An undirected graph (that is, a collection of vertices connected with edges). +LayoutName = Literal[ + "circular", + "kamada_kawai", + "partite", + "planar", + "random", + "shell", + "spectral", + "spiral", + "spring", + "tree", +] + +_layouts: dict[LayoutName, LayoutFunction] = { + "circular": cast(LayoutFunction, nx.layout.circular_layout), + "kamada_kawai": cast(LayoutFunction, nx.layout.kamada_kawai_layout), + "partite": cast(LayoutFunction, _partite_layout), + "planar": cast(LayoutFunction, nx.layout.planar_layout), + "random": cast(LayoutFunction, _random_layout), + "shell": cast(LayoutFunction, nx.layout.shell_layout), + "spectral": cast(LayoutFunction, nx.layout.spectral_layout), + "spiral": cast(LayoutFunction, nx.layout.spiral_layout), + "spring": cast(LayoutFunction, nx.layout.spring_layout), + "tree": cast(LayoutFunction, _tree_layout), +} + + +def _determine_graph_layout( + nx_graph: nx.classes.graph.Graph | nx.classes.digraph.DiGraph, + layout: LayoutName | dict[Hashable, Point3DLike] | LayoutFunction = "spring", + layout_scale: float | tuple[float, float, float] = 2, + layout_config: dict[str, Any] | None = None, +) -> dict[Hashable, Point3DLike]: + if layout_config is None: + layout_config = {} + + if isinstance(layout, dict): + return layout + elif layout in _layouts: + auto_layout = _layouts[layout](nx_graph, scale=layout_scale, **layout_config) + # NetworkX returns a dictionary of 3D points if the dimension + # is specified to be 3. Otherwise, it returns a dictionary of + # 2D points, so adjusting is required. + if ( + layout_config.get("dim") == 3 + or auto_layout[next(auto_layout.__iter__())].shape[0] == 3 + ): + return auto_layout + else: + return {k: np.append(v, [0]) for k, v in auto_layout.items()} + else: + try: + return cast(LayoutFunction, layout)( + nx_graph, scale=layout_scale, **layout_config + ) + except TypeError as e: + raise ValueError( + f"The layout '{layout}' is neither a recognized layout, a layout function," + "nor a vertex placement dictionary.", + ) from e + + +class GenericGraph(VMobject, metaclass=ConvertToOpenGL): + """Abstract base class for graphs (that is, a collection of vertices + connected with edges). Graphs can be instantiated by passing both a list of (distinct, hashable) vertex names, together with list of edges (as tuples of vertex names). See - the examples below for details. + the examples for concrete implementations of this class for details. .. note:: This implementation uses updaters to make the edges move with the vertices. + + See also + -------- + + :class:`.Graph` + :class:`.DiGraph` + + Parameters ---------- @@ -240,14 +518,14 @@ class Graph(VMobject, metaclass=ConvertToOpenGL): layout Either one of ``"spring"`` (the default), ``"circular"``, ``"kamada_kawai"``, ``"planar"``, ``"random"``, ``"shell"``, ``"spectral"``, ``"spiral"``, ``"tree"``, and ``"partite"`` - for automatic vertex positioning using ``networkx`` + for automatic vertex positioning primarily using ``networkx`` (see `their documentation `_ - for more details), or a dictionary specifying a coordinate (value) - for each vertex (key) for manual positioning. + for more details), a dictionary specifying a coordinate (value) + for each vertex (key) for manual positioning, or a .:class:`~.LayoutFunction` with a user-defined automatic layout. layout_config - Only for automatically generated layouts. A dictionary whose entries - are passed as keyword arguments to the automatic layout algorithm - specified via ``layout`` of``networkx``. + Only for automatic layouts. A dictionary whose entries + are passed as keyword arguments to the named layout or automatic layout function + specified via ``layout``. The ``tree`` layout also accepts a special parameter ``vertex_spacing`` passed as a keyword argument inside the ``layout_config`` dictionary. Passing a tuple ``(space_x, space_y)`` as this argument overrides @@ -274,310 +552,141 @@ class Graph(VMobject, metaclass=ConvertToOpenGL): all other configuration options for a vertex. edge_type The mobject class used for displaying edges in the scene. + Must be a subclass of :class:`~.Line` for default updaters to work. edge_config Either a dictionary containing keyword arguments to be passed to the class specified via ``edge_type``, or a dictionary whose keys are the edges, and whose values are dictionaries containing keyword arguments for the mobject related to the corresponding edge. + """ - Examples - -------- + def __init__( + self, + vertices: Sequence[Hashable], + edges: Sequence[tuple[Hashable, Hashable]], + labels: bool | dict = False, + label_fill_color: str = BLACK, + layout: LayoutName | dict[Hashable, Point3DLike] | LayoutFunction = "spring", + layout_scale: float | tuple[float, float, float] = 2, + layout_config: dict | None = None, + vertex_type: type[Mobject] = Dot, + vertex_config: dict | None = None, + vertex_mobjects: dict | None = None, + edge_type: type[Mobject] = Line, + partitions: Sequence[Sequence[Hashable]] | None = None, + root_vertex: Hashable | None = None, + edge_config: dict | None = None, + ) -> None: + super().__init__() - First, we create a small graph and demonstrate that the edges move - together with the vertices. + nx_graph = self._empty_networkx_graph() + nx_graph.add_nodes_from(vertices) + nx_graph.add_edges_from(edges) + self._graph = nx_graph - .. manim:: MovingVertices + if isinstance(labels, dict): + self._labels = labels + elif isinstance(labels, bool): + if labels: + self._labels = { + v: MathTex(v, fill_color=label_fill_color) for v in vertices + } + else: + self._labels = {} - class MovingVertices(Scene): - def construct(self): - vertices = [1, 2, 3, 4] - edges = [(1, 2), (2, 3), (3, 4), (1, 3), (1, 4)] - g = Graph(vertices, edges) - self.play(Create(g)) - self.wait() - self.play(g[1].animate.move_to([1, 1, 0]), - g[2].animate.move_to([-1, 1, 0]), - g[3].animate.move_to([1, -1, 0]), - g[4].animate.move_to([-1, -1, 0])) - self.wait() + if self._labels and vertex_type is Dot: + vertex_type = LabeledDot - There are several automatic positioning algorithms to choose from: + if vertex_mobjects is None: + vertex_mobjects = {} - .. manim:: GraphAutoPosition - :save_last_frame: + # build vertex_config + if vertex_config is None: + vertex_config = {} + default_vertex_config = {} + if vertex_config: + default_vertex_config = { + k: v for k, v in vertex_config.items() if k not in vertices + } + self._vertex_config = { + v: vertex_config.get(v, copy(default_vertex_config)) for v in vertices + } + self.default_vertex_config = default_vertex_config + for v, label in self._labels.items(): + self._vertex_config[v]["label"] = label - class GraphAutoPosition(Scene): - def construct(self): - vertices = [1, 2, 3, 4, 5, 6, 7, 8] - edges = [(1, 7), (1, 8), (2, 3), (2, 4), (2, 5), - (2, 8), (3, 4), (6, 1), (6, 2), - (6, 3), (7, 2), (7, 4)] - autolayouts = ["spring", "circular", "kamada_kawai", - "planar", "random", "shell", - "spectral", "spiral"] - graphs = [Graph(vertices, edges, layout=lt).scale(0.5) - for lt in autolayouts] - r1 = VGroup(*graphs[:3]).arrange() - r2 = VGroup(*graphs[3:6]).arrange() - r3 = VGroup(*graphs[6:]).arrange() - self.add(VGroup(r1, r2, r3).arrange(direction=DOWN)) + self.vertices = {v: vertex_type(**self._vertex_config[v]) for v in vertices} + self.vertices.update(vertex_mobjects) - Vertices can also be positioned manually: + self.change_layout( + layout=layout, + layout_scale=layout_scale, + layout_config=layout_config, + partitions=partitions, + root_vertex=root_vertex, + ) - .. manim:: GraphManualPosition - :save_last_frame: + # build edge_config + if edge_config is None: + edge_config = {} + default_tip_config = {} + default_edge_config = {} + if edge_config: + default_tip_config = edge_config.pop("tip_config", {}) + default_edge_config = { + k: v + for k, v in edge_config.items() + if not isinstance( + k, tuple + ) # everything that is not an edge is an option + } + self._edge_config = {} + self._tip_config = {} + for e in edges: + if e in edge_config: + self._tip_config[e] = edge_config[e].pop( + "tip_config", copy(default_tip_config) + ) + self._edge_config[e] = edge_config[e] + else: + self._tip_config[e] = copy(default_tip_config) + self._edge_config[e] = copy(default_edge_config) - class GraphManualPosition(Scene): - def construct(self): - vertices = [1, 2, 3, 4] - edges = [(1, 2), (2, 3), (3, 4), (4, 1)] - lt = {1: [0, 0, 0], 2: [1, 1, 0], 3: [1, -1, 0], 4: [-1, 0, 0]} - G = Graph(vertices, edges, layout=lt) - self.add(G) - - The vertices in graphs can be labeled, and configurations for vertices - and edges can be modified both by default and for specific vertices and - edges. - - .. note:: - - In ``edge_config``, edges can be passed in both directions: if - ``(u, v)`` is an edge in the graph, both ``(u, v)`` as well - as ``(v, u)`` can be used as keys in the dictionary. - - .. manim:: LabeledModifiedGraph - :save_last_frame: - - class LabeledModifiedGraph(Scene): - def construct(self): - vertices = [1, 2, 3, 4, 5, 6, 7, 8] - edges = [(1, 7), (1, 8), (2, 3), (2, 4), (2, 5), - (2, 8), (3, 4), (6, 1), (6, 2), - (6, 3), (7, 2), (7, 4)] - g = Graph(vertices, edges, layout="circular", layout_scale=3, - labels=True, vertex_config={7: {"fill_color": RED}}, - edge_config={(1, 7): {"stroke_color": RED}, - (2, 7): {"stroke_color": RED}, - (4, 7): {"stroke_color": RED}}) - self.add(g) - - You can also lay out a partite graph on columns by specifying - a list of the vertices on each side and choosing the partite layout. - - .. note:: - - All vertices in your graph which are not listed in any of the partitions - are collected in their own partition and rendered in the rightmost column. - - .. manim:: PartiteGraph - :save_last_frame: - - import networkx as nx - - class PartiteGraph(Scene): - def construct(self): - G = nx.Graph() - G.add_nodes_from([0, 1, 2, 3]) - G.add_edges_from([(0, 2), (0,3), (1, 2)]) - graph = Graph(list(G.nodes), list(G.edges), layout="partite", partitions=[[0, 1]]) - self.play(Create(graph)) - - The custom tree layout can be used to show the graph - by distance from the root vertex. You must pass the root vertex - of the tree. - - .. manim:: Tree - - import networkx as nx - - class Tree(Scene): - def construct(self): - G = nx.Graph() - - G.add_node("ROOT") - - for i in range(5): - G.add_node("Child_%i" % i) - G.add_node("Grandchild_%i" % i) - G.add_node("Greatgrandchild_%i" % i) - - G.add_edge("ROOT", "Child_%i" % i) - G.add_edge("Child_%i" % i, "Grandchild_%i" % i) - G.add_edge("Grandchild_%i" % i, "Greatgrandchild_%i" % i) - - self.play(Create( - Graph(list(G.nodes), list(G.edges), layout="tree", root_vertex="ROOT"))) - - The following code sample illustrates the use of the ``vertex_spacing`` - layout parameter specific to the ``"tree"`` layout. As mentioned - above, setting ``vertex_spacing`` overrides the specified value - for ``layout_scale``, and as such it is harder to control the size - of the mobject. However, we can adjust the captured frame and - zoom out by using a :class:`.MovingCameraScene`:: - - class LargeTreeGeneration(MovingCameraScene): - DEPTH = 4 - CHILDREN_PER_VERTEX = 3 - LAYOUT_CONFIG = {"vertex_spacing": (0.5, 1)} - VERTEX_CONF = {"radius": 0.25, "color": BLUE_B, "fill_opacity": 1} - - def expand_vertex(self, g, vertex_id: str, depth: int): - new_vertices = [f"{vertex_id}/{i}" for i in range(self.CHILDREN_PER_VERTEX)] - new_edges = [(vertex_id, child_id) for child_id in new_vertices] - g.add_edges( - *new_edges, - vertex_config=self.VERTEX_CONF, - positions={ - k: g.vertices[vertex_id].get_center() + 0.1 * DOWN for k in new_vertices - }, - ) - if depth < self.DEPTH: - for child_id in new_vertices: - self.expand_vertex(g, child_id, depth + 1) - - return g - - def construct(self): - g = Graph(["ROOT"], [], vertex_config=self.VERTEX_CONF) - g = self.expand_vertex(g, "ROOT", 1) - self.add(g) - - self.play( - g.animate.change_layout( - "tree", - root_vertex="ROOT", - layout_config=self.LAYOUT_CONFIG, - ) - ) - self.play(self.camera.auto_zoom(g, margin=1), run_time=0.5) - """ - - def __init__( - self, - vertices: list[Hashable], - edges: list[tuple[Hashable, Hashable]], - labels: bool | dict = False, - label_fill_color: str = BLACK, - layout: str | dict = "spring", - layout_scale: float | tuple = 2, - layout_config: dict | None = None, - vertex_type: type[Mobject] = Dot, - vertex_config: dict | None = None, - vertex_mobjects: dict | None = None, - edge_type: type[Mobject] = Line, - partitions: list[list[Hashable]] | None = None, - root_vertex: Hashable | None = None, - edge_config: dict | None = None, - ) -> None: - super().__init__() - - nx_graph = nx.Graph() - nx_graph.add_nodes_from(vertices) - nx_graph.add_edges_from(edges) - self._graph = nx_graph - - self._layout = _determine_graph_layout( - nx_graph, - layout=layout, - layout_scale=layout_scale, - layout_config=layout_config, - partitions=partitions, - root_vertex=root_vertex, - ) - - if isinstance(labels, dict): - self._labels = labels - elif isinstance(labels, bool): - if labels: - self._labels = { - v: MathTex(v, fill_color=label_fill_color) for v in vertices - } - else: - self._labels = {} - - if self._labels and vertex_type is Dot: - vertex_type = LabeledDot - - if vertex_mobjects is None: - vertex_mobjects = {} - - # build vertex_config - if vertex_config is None: - vertex_config = {} - default_vertex_config = {} - if vertex_config: - default_vertex_config = { - k: v for k, v in vertex_config.items() if k not in vertices - } - self._vertex_config = { - v: vertex_config.get(v, copy(default_vertex_config)) for v in vertices - } - self.default_vertex_config = default_vertex_config - for v, label in self._labels.items(): - self._vertex_config[v]["label"] = label - - self.vertices = {v: vertex_type(**self._vertex_config[v]) for v in vertices} - self.vertices.update(vertex_mobjects) - for v in self.vertices: - self[v].move_to(self._layout[v]) - - # build edge_config - if edge_config is None: - edge_config = {} - default_edge_config = {} - if edge_config: - default_edge_config = { - k: v - for k, v in edge_config.items() - if k not in edges and k[::-1] not in edges - } - self._edge_config = {} - for e in edges: - if e in edge_config: - self._edge_config[e] = edge_config[e] - elif e[::-1] in edge_config: - self._edge_config[e] = edge_config[e[::-1]] - else: - self._edge_config[e] = copy(default_edge_config) - - self.default_edge_config = default_edge_config - self.edges = { - (u, v): edge_type( - self[u].get_center(), - self[v].get_center(), - z_index=-1, - **self._edge_config[(u, v)], - ) - for (u, v) in edges - } + self.default_edge_config = default_edge_config + self._populate_edge_dict(edges, edge_type) self.add(*self.vertices.values()) self.add(*self.edges.values()) - def update_edges(graph): - for (u, v), edge in graph.edges.items(): - edge.put_start_and_end_on(graph[u].get_center(), graph[v].get_center()) + self.add_updater(self.update_edges) + + @staticmethod + def _empty_networkx_graph() -> nx.classes.graph.Graph: + """Return an empty networkx graph for the given graph type.""" + raise NotImplementedError("To be implemented in concrete subclasses") - self.add_updater(update_edges) + def _populate_edge_dict( + self, edges: list[tuple[Hashable, Hashable]], edge_type: type[Mobject] + ): + """Helper method for populating the edges of the graph.""" + raise NotImplementedError("To be implemented in concrete subclasses") def __getitem__(self: Graph, v: Hashable) -> Mobject: return self.vertices[v] - def __repr__(self: Graph) -> str: - return f"Graph on {len(self.vertices)} vertices and {len(self.edges)} edges" - def _create_vertex( self, vertex: Hashable, - position: np.ndarray | None = None, + position: Point3DLike | None = None, label: bool = False, label_fill_color: str = BLACK, vertex_type: type[Mobject] = Dot, vertex_config: dict | None = None, vertex_mobject: dict | None = None, - ) -> tuple[Hashable, np.ndarray, dict, Mobject]: - if position is None: - position = self.get_center() + ) -> tuple[Hashable, Point3D, dict, Mobject]: + np_position: Point3D = ( + self.get_center() if position is None else np.asarray(position) + ) if vertex_config is None: vertex_config = {} @@ -587,13 +696,11 @@ def _create_vertex( f"Vertex identifier '{vertex}' is already used for a vertex in this graph.", ) - if isinstance(label, (Mobject, OpenGLMobject)): - label = label - elif label is True: + if label is True: label = MathTex(vertex, fill_color=label_fill_color) elif vertex in self._labels: label = self._labels[vertex] - else: + elif not isinstance(label, (Mobject, OpenGLMobject)): label = None base_vertex_config = copy(self.default_vertex_config) @@ -608,14 +715,14 @@ def _create_vertex( if vertex_mobject is None: vertex_mobject = vertex_type(**vertex_config) - vertex_mobject.move_to(position) + vertex_mobject.move_to(np_position) - return (vertex, position, vertex_config, vertex_mobject) + return (vertex, np_position, vertex_config, vertex_mobject) def _add_created_vertex( self, vertex: Hashable, - position: np.ndarray, + position: Point3DLike, vertex_config: dict, vertex_mobject: Mobject, ) -> Mobject: @@ -641,7 +748,7 @@ def _add_created_vertex( def _add_vertex( self, vertex: Hashable, - position: np.ndarray | None = None, + position: Point3DLike | None = None, label: bool = False, label_fill_color: str = BLACK, vertex_type: type[Mobject] = Dot, @@ -696,22 +803,22 @@ def _create_vertices( vertex_type: type[Mobject] = Dot, vertex_config: dict | None = None, vertex_mobjects: dict | None = None, - ) -> Iterable[tuple[Hashable, np.ndarray, dict, Mobject]]: + ) -> Iterable[tuple[Hashable, Point3D, dict, Mobject]]: if positions is None: positions = {} if vertex_mobjects is None: vertex_mobjects = {} graph_center = self.get_center() - base_positions = {v: graph_center for v in vertices} + base_positions = dict.fromkeys(vertices, graph_center) base_positions.update(positions) positions = base_positions if isinstance(labels, bool): - labels = {v: labels for v in vertices} + labels = dict.fromkeys(vertices, labels) else: assert isinstance(labels, dict) - base_labels = {v: False for v in vertices} + base_labels = dict.fromkeys(vertices, False) base_labels.update(labels) labels = base_labels @@ -736,7 +843,7 @@ def _create_vertices( label_fill_color=label_fill_color, vertex_type=vertex_type, vertex_config=vertex_config[v], - vertex_mobject=vertex_mobjects[v] if v in vertex_mobjects else None, + vertex_mobject=vertex_mobjects.get(v), ) for v in vertices ] @@ -865,7 +972,7 @@ def remove_vertices(self, *vertices): >>> removed = G.remove_vertices(2, 3); removed VGroup(Line, Line, Dot, Dot) >>> G - Graph on 1 vertices and 0 edges + Undirected graph on 1 vertices and 0 edges """ mobjects = [] @@ -1025,9 +1132,7 @@ def _remove_edge(self, edge: tuple[Hashable]): """ if edge not in self.edges: - edge = edge[::-1] - if edge not in self.edges: - raise ValueError(f"The graph does not contain a edge '{edge}'") + raise ValueError(f"The graph does not contain a edge '{edge}'") edge_mobject = self.edges.pop(edge) @@ -1064,15 +1169,18 @@ def _remove_edges_animation(self, *edges, anim_args=None): mobjects = self.remove_edges(*edges) return AnimationGroup(*(animation(mobj, **anim_args) for mobj in mobjects)) - @staticmethod - def from_networkx(nxgraph: nx.classes.graph.Graph, **kwargs) -> Graph: - """Build a :class:`~.Graph` from a given ``networkx`` graph. + @classmethod + def from_networkx( + cls, nxgraph: nx.classes.graph.Graph | nx.classes.digraph.DiGraph, **kwargs + ): + """Build a :class:`~.Graph` or :class:`~.DiGraph` from a + given ``networkx`` graph. Parameters ---------- nxgraph - A ``networkx`` graph. + A ``networkx`` graph or digraph. **kwargs Keywords to be passed to the constructor of :class:`~.Graph`. @@ -1095,13 +1203,13 @@ def construct(self): self.play(Uncreate(G)) """ - return Graph(list(nxgraph.nodes), list(nxgraph.edges), **kwargs) + return cls(list(nxgraph.nodes), list(nxgraph.edges), **kwargs) def change_layout( self, - layout: str | dict = "spring", - layout_scale: float = 2, - layout_config: dict | None = None, + layout: LayoutName | dict[Hashable, Point3DLike] | LayoutFunction = "spring", + layout_scale: float | tuple[float, float, float] = 2, + layout_config: dict[str, Any] | None = None, partitions: list[list[Hashable]] | None = None, root_vertex: Hashable | None = None, ) -> Graph: @@ -1125,14 +1233,551 @@ def construct(self): self.play(G.animate.change_layout("circular")) self.wait() """ + layout_config = {} if layout_config is None else layout_config + if partitions is not None and "partitions" not in layout_config: + layout_config["partitions"] = partitions + if root_vertex is not None and "root_vertex" not in layout_config: + layout_config["root_vertex"] = root_vertex + self._layout = _determine_graph_layout( self._graph, layout=layout, layout_scale=layout_scale, layout_config=layout_config, - partitions=partitions, - root_vertex=root_vertex, ) + for v in self.vertices: self[v].move_to(self._layout[v]) return self + + +class Graph(GenericGraph): + """An undirected graph (vertices connected with edges). + + The graph comes with an updater which makes the edges stick to + the vertices when moved around. See :class:`.DiGraph` for + a version with directed edges. + + See also + -------- + + :class:`.GenericGraph` + + Parameters + ---------- + + vertices + A list of vertices. Must be hashable elements. + edges + A list of edges, specified as tuples ``(u, v)`` where both ``u`` + and ``v`` are vertices. The vertex order is irrelevant. + labels + Controls whether or not vertices are labeled. If ``False`` (the default), + the vertices are not labeled; if ``True`` they are labeled using their + names (as specified in ``vertices``) via :class:`~.MathTex`. Alternatively, + custom labels can be specified by passing a dictionary whose keys are + the vertices, and whose values are the corresponding vertex labels + (rendered via, e.g., :class:`~.Text` or :class:`~.Tex`). + label_fill_color + Sets the fill color of the default labels generated when ``labels`` + is set to ``True``. Has no effect for other values of ``labels``. + layout + Either one of ``"spring"`` (the default), ``"circular"``, ``"kamada_kawai"``, + ``"planar"``, ``"random"``, ``"shell"``, ``"spectral"``, ``"spiral"``, ``"tree"``, and ``"partite"`` + for automatic vertex positioning using ``networkx`` + (see `their documentation `_ + for more details), or a dictionary specifying a coordinate (value) + for each vertex (key) for manual positioning. + layout_config + Only for automatically generated layouts. A dictionary whose entries + are passed as keyword arguments to the automatic layout algorithm + specified via ``layout`` of ``networkx``. + The ``tree`` layout also accepts a special parameter ``vertex_spacing`` + passed as a keyword argument inside the ``layout_config`` dictionary. + Passing a tuple ``(space_x, space_y)`` as this argument overrides + the value of ``layout_scale`` and ensures that vertices are arranged + in a way such that the centers of siblings in the same layer are + at least ``space_x`` units apart horizontally, and neighboring layers + are spaced ``space_y`` units vertically. + layout_scale + The scale of automatically generated layouts: the vertices will + be arranged such that the coordinates are located within the + interval ``[-scale, scale]``. Some layouts accept a tuple ``(scale_x, scale_y)`` + causing the first coordinate to be in the interval ``[-scale_x, scale_x]``, + and the second in ``[-scale_y, scale_y]``. Default: 2. + vertex_type + The mobject class used for displaying vertices in the scene. + vertex_config + Either a dictionary containing keyword arguments to be passed to + the class specified via ``vertex_type``, or a dictionary whose keys + are the vertices, and whose values are dictionaries containing keyword + arguments for the mobject related to the corresponding vertex. + vertex_mobjects + A dictionary whose keys are the vertices, and whose values are + mobjects to be used as vertices. Passing vertices here overrides + all other configuration options for a vertex. + edge_type + The mobject class used for displaying edges in the scene. + edge_config + Either a dictionary containing keyword arguments to be passed + to the class specified via ``edge_type``, or a dictionary whose + keys are the edges, and whose values are dictionaries containing + keyword arguments for the mobject related to the corresponding edge. + + + Examples + -------- + + First, we create a small graph and demonstrate that the edges move + together with the vertices. + + .. manim:: MovingVertices + + class MovingVertices(Scene): + def construct(self): + vertices = [1, 2, 3, 4] + edges = [(1, 2), (2, 3), (3, 4), (1, 3), (1, 4)] + g = Graph(vertices, edges) + self.play(Create(g)) + self.wait() + self.play(g[1].animate.move_to([1, 1, 0]), + g[2].animate.move_to([-1, 1, 0]), + g[3].animate.move_to([1, -1, 0]), + g[4].animate.move_to([-1, -1, 0])) + self.wait() + + There are several automatic positioning algorithms to choose from: + + .. manim:: GraphAutoPosition + :save_last_frame: + + class GraphAutoPosition(Scene): + def construct(self): + vertices = [1, 2, 3, 4, 5, 6, 7, 8] + edges = [(1, 7), (1, 8), (2, 3), (2, 4), (2, 5), + (2, 8), (3, 4), (6, 1), (6, 2), + (6, 3), (7, 2), (7, 4)] + autolayouts = ["spring", "circular", "kamada_kawai", + "planar", "random", "shell", + "spectral", "spiral"] + graphs = [Graph(vertices, edges, layout=lt).scale(0.5) + for lt in autolayouts] + r1 = VGroup(*graphs[:3]).arrange() + r2 = VGroup(*graphs[3:6]).arrange() + r3 = VGroup(*graphs[6:]).arrange() + self.add(VGroup(r1, r2, r3).arrange(direction=DOWN)) + + Vertices can also be positioned manually: + + .. manim:: GraphManualPosition + :save_last_frame: + + class GraphManualPosition(Scene): + def construct(self): + vertices = [1, 2, 3, 4] + edges = [(1, 2), (2, 3), (3, 4), (4, 1)] + lt = {1: [0, 0, 0], 2: [1, 1, 0], 3: [1, -1, 0], 4: [-1, 0, 0]} + G = Graph(vertices, edges, layout=lt) + self.add(G) + + The vertices in graphs can be labeled, and configurations for vertices + and edges can be modified both by default and for specific vertices and + edges. + + .. note:: + + In ``edge_config``, edges can be passed in both directions: if + ``(u, v)`` is an edge in the graph, both ``(u, v)`` as well + as ``(v, u)`` can be used as keys in the dictionary. + + .. manim:: LabeledModifiedGraph + :save_last_frame: + + class LabeledModifiedGraph(Scene): + def construct(self): + vertices = [1, 2, 3, 4, 5, 6, 7, 8] + edges = [(1, 7), (1, 8), (2, 3), (2, 4), (2, 5), + (2, 8), (3, 4), (6, 1), (6, 2), + (6, 3), (7, 2), (7, 4)] + g = Graph(vertices, edges, layout="circular", layout_scale=3, + labels=True, vertex_config={7: {"fill_color": RED}}, + edge_config={(1, 7): {"stroke_color": RED}, + (2, 7): {"stroke_color": RED}, + (4, 7): {"stroke_color": RED}}) + self.add(g) + + You can also lay out a partite graph on columns by specifying + a list of the vertices on each side and choosing the partite layout. + + .. note:: + + All vertices in your graph which are not listed in any of the partitions + are collected in their own partition and rendered in the rightmost column. + + .. manim:: PartiteGraph + :save_last_frame: + + import networkx as nx + + class PartiteGraph(Scene): + def construct(self): + G = nx.Graph() + G.add_nodes_from([0, 1, 2, 3]) + G.add_edges_from([(0, 2), (0,3), (1, 2)]) + graph = Graph(list(G.nodes), list(G.edges), layout="partite", partitions=[[0, 1]]) + self.play(Create(graph)) + + The representation of a linear artificial neural network is facilitated + by the use of the partite layout and defining partitions for each layer. + + .. manim:: LinearNN + :save_last_frame: + + class LinearNN(Scene): + def construct(self): + edges = [] + partitions = [] + c = 0 + layers = [2, 3, 3, 2] # the number of neurons in each layer + + for i in layers: + partitions.append(list(range(c + 1, c + i + 1))) + c += i + for i, v in enumerate(layers[1:]): + last = sum(layers[:i+1]) + for j in range(v): + for k in range(last - layers[i], last): + edges.append((k + 1, j + last + 1)) + + vertices = np.arange(1, sum(layers) + 1) + + graph = Graph( + vertices, + edges, + layout='partite', + partitions=partitions, + layout_scale=3, + vertex_config={'radius': 0.20}, + ) + self.add(graph) + + The custom tree layout can be used to show the graph + by distance from the root vertex. You must pass the root vertex + of the tree. + + .. manim:: Tree + + import networkx as nx + + class Tree(Scene): + def construct(self): + G = nx.Graph() + + G.add_node("ROOT") + + for i in range(5): + G.add_node("Child_%i" % i) + G.add_node("Grandchild_%i" % i) + G.add_node("Greatgrandchild_%i" % i) + + G.add_edge("ROOT", "Child_%i" % i) + G.add_edge("Child_%i" % i, "Grandchild_%i" % i) + G.add_edge("Grandchild_%i" % i, "Greatgrandchild_%i" % i) + + self.play(Create( + Graph(list(G.nodes), list(G.edges), layout="tree", root_vertex="ROOT"))) + + The following code sample illustrates the use of the ``vertex_spacing`` + layout parameter specific to the ``"tree"`` layout. As mentioned + above, setting ``vertex_spacing`` overrides the specified value + for ``layout_scale``, and as such it is harder to control the size + of the mobject. However, we can adjust the captured frame and + zoom out by using a :class:`.MovingCameraScene`:: + + class LargeTreeGeneration(MovingCameraScene): + DEPTH = 4 + CHILDREN_PER_VERTEX = 3 + LAYOUT_CONFIG = {"vertex_spacing": (0.5, 1)} + VERTEX_CONF = {"radius": 0.25, "color": BLUE_B, "fill_opacity": 1} + + def expand_vertex(self, g, vertex_id: str, depth: int): + new_vertices = [ + f"{vertex_id}/{i}" for i in range(self.CHILDREN_PER_VERTEX) + ] + new_edges = [(vertex_id, child_id) for child_id in new_vertices] + g.add_edges( + *new_edges, + vertex_config=self.VERTEX_CONF, + positions={ + k: g.vertices[vertex_id].get_center() + 0.1 * DOWN + for k in new_vertices + }, + ) + if depth < self.DEPTH: + for child_id in new_vertices: + self.expand_vertex(g, child_id, depth + 1) + + return g + + def construct(self): + g = Graph(["ROOT"], [], vertex_config=self.VERTEX_CONF) + g = self.expand_vertex(g, "ROOT", 1) + self.add(g) + + self.play( + g.animate.change_layout( + "tree", + root_vertex="ROOT", + layout_config=self.LAYOUT_CONFIG, + ) + ) + self.play(self.camera.auto_zoom(g, margin=1), run_time=0.5) + """ + + @staticmethod + def _empty_networkx_graph() -> nx.Graph: + return nx.Graph() + + def _populate_edge_dict( + self, edges: list[tuple[Hashable, Hashable]], edge_type: type[Mobject] + ): + self.edges = { + (u, v): edge_type( + self[u].get_center(), + self[v].get_center(), + z_index=-1, + **self._edge_config[(u, v)], + ) + for (u, v) in edges + } + + def update_edges(self, graph): + for (u, v), edge in graph.edges.items(): + # Undirected graph has a Line edge + edge.set_points_by_ends( + graph[u].get_center(), + graph[v].get_center(), + buff=self._edge_config.get("buff", 0), + path_arc=self._edge_config.get("path_arc", 0), + ) + + def __repr__(self: Graph) -> str: + return f"Undirected graph on {len(self.vertices)} vertices and {len(self.edges)} edges" + + +class DiGraph(GenericGraph): + """A directed graph. + + .. note:: + + In contrast to undirected graphs, the order in which vertices in a given + edge are specified is relevant here. + + See also + -------- + + :class:`.GenericGraph` + + Parameters + ---------- + + vertices + A list of vertices. Must be hashable elements. + edges + A list of edges, specified as tuples ``(u, v)`` where both ``u`` + and ``v`` are vertices. The edge is directed from ``u`` to ``v``. + labels + Controls whether or not vertices are labeled. If ``False`` (the default), + the vertices are not labeled; if ``True`` they are labeled using their + names (as specified in ``vertices``) via :class:`~.MathTex`. Alternatively, + custom labels can be specified by passing a dictionary whose keys are + the vertices, and whose values are the corresponding vertex labels + (rendered via, e.g., :class:`~.Text` or :class:`~.Tex`). + label_fill_color + Sets the fill color of the default labels generated when ``labels`` + is set to ``True``. Has no effect for other values of ``labels``. + layout + Either one of ``"spring"`` (the default), ``"circular"``, ``"kamada_kawai"``, + ``"planar"``, ``"random"``, ``"shell"``, ``"spectral"``, ``"spiral"``, ``"tree"``, and ``"partite"`` + for automatic vertex positioning using ``networkx`` + (see `their documentation `_ + for more details), or a dictionary specifying a coordinate (value) + for each vertex (key) for manual positioning. + layout_config + Only for automatically generated layouts. A dictionary whose entries + are passed as keyword arguments to the automatic layout algorithm + specified via ``layout`` of ``networkx``. + The ``tree`` layout also accepts a special parameter ``vertex_spacing`` + passed as a keyword argument inside the ``layout_config`` dictionary. + Passing a tuple ``(space_x, space_y)`` as this argument overrides + the value of ``layout_scale`` and ensures that vertices are arranged + in a way such that the centers of siblings in the same layer are + at least ``space_x`` units apart horizontally, and neighboring layers + are spaced ``space_y`` units vertically. + layout_scale + The scale of automatically generated layouts: the vertices will + be arranged such that the coordinates are located within the + interval ``[-scale, scale]``. Some layouts accept a tuple ``(scale_x, scale_y)`` + causing the first coordinate to be in the interval ``[-scale_x, scale_x]``, + and the second in ``[-scale_y, scale_y]``. Default: 2. + vertex_type + The mobject class used for displaying vertices in the scene. + vertex_config + Either a dictionary containing keyword arguments to be passed to + the class specified via ``vertex_type``, or a dictionary whose keys + are the vertices, and whose values are dictionaries containing keyword + arguments for the mobject related to the corresponding vertex. + vertex_mobjects + A dictionary whose keys are the vertices, and whose values are + mobjects to be used as vertices. Passing vertices here overrides + all other configuration options for a vertex. + edge_type + The mobject class used for displaying edges in the scene. + edge_config + Either a dictionary containing keyword arguments to be passed + to the class specified via ``edge_type``, or a dictionary whose + keys are the edges, and whose values are dictionaries containing + keyword arguments for the mobject related to the corresponding edge. + You can further customize the tip by adding a ``tip_config`` dictionary + for global styling, or by adding the dict to a specific ``edge_config``. + + Examples + -------- + + .. manim:: MovingDiGraph + + class MovingDiGraph(Scene): + def construct(self): + vertices = [1, 2, 3, 4] + edges = [(1, 2), (2, 3), (3, 4), (1, 3), (1, 4)] + + g = DiGraph(vertices, edges) + + self.add(g) + self.play( + g[1].animate.move_to([1, 1, 1]), + g[2].animate.move_to([-1, 1, 2]), + g[3].animate.move_to([1, -1, -1]), + g[4].animate.move_to([-1, -1, 0]), + ) + self.wait() + + You can customize the edges and arrow tips globally or locally. + + .. manim:: CustomDiGraph + + class CustomDiGraph(Scene): + def construct(self): + vertices = [i for i in range(5)] + edges = [ + (0, 1), + (1, 2), + (3, 2), + (3, 4), + ] + + edge_config = { + "stroke_width": 2, + "tip_config": { + "tip_shape": ArrowSquareTip, + "tip_length": 0.15, + }, + (3, 4): { + "color": RED, + "tip_config": {"tip_length": 0.25, "tip_width": 0.25} + }, + } + + g = DiGraph( + vertices, + edges, + labels=True, + layout="circular", + edge_config=edge_config, + ).scale(1.4) + + self.play(Create(g)) + self.wait() + + Since this implementation respects the labels boundary you can also use + it for an undirected moving graph with labels. + + .. manim:: UndirectedMovingDiGraph + + class UndirectedMovingDiGraph(Scene): + def construct(self): + vertices = [i for i in range(5)] + edges = [ + (0, 1), + (1, 2), + (3, 2), + (3, 4), + ] + + edge_config = { + "stroke_width": 2, + "tip_config": {"tip_length": 0, "tip_width": 0}, + (3, 4): {"color": RED}, + } + + g = DiGraph( + vertices, + edges, + labels=True, + layout="circular", + edge_config=edge_config, + ).scale(1.4) + + self.play(Create(g)) + self.wait() + + self.play( + g[1].animate.move_to([1, 1, 1]), + g[2].animate.move_to([-1, 1, 2]), + g[3].animate.move_to([-1.5, -1.5, -1]), + g[4].animate.move_to([1, -2, -1]), + ) + self.wait() + + """ + + @staticmethod + def _empty_networkx_graph() -> nx.DiGraph: + return nx.DiGraph() + + def _populate_edge_dict( + self, edges: list[tuple[Hashable, Hashable]], edge_type: type[Mobject] + ): + self.edges = { + (u, v): edge_type( + self[u], + self[v], + z_index=-1, + **self._edge_config[(u, v)], + ) + for (u, v) in edges + } + + for (u, v), edge in self.edges.items(): + edge.add_tip(**self._tip_config[(u, v)]) + + def update_edges(self, graph): + """Updates the edges to stick at their corresponding vertices. + + Arrow tips need to be repositioned since otherwise they can be + deformed. + """ + for (u, v), edge in graph.edges.items(): + tip = edge.pop_tips()[0] + # Passing the Mobject instead of the vertex makes the tip + # stop on the bounding box of the vertex. + edge.set_points_by_ends( + graph[u], + graph[v], + buff=self._edge_config.get("buff", 0), + path_arc=self._edge_config.get("path_arc", 0), + ) + edge.add_tip(tip) + + def __repr__(self: DiGraph) -> str: + return f"Directed graph on {len(self.vertices)} vertices and {len(self.edges)} edges" diff --git a/manim/mobject/graphing/coordinate_systems.py b/manim/mobject/graphing/coordinate_systems.py index 57d4748607..b21879b90b 100644 --- a/manim/mobject/graphing/coordinate_systems.py +++ b/manim/mobject/graphing/coordinate_systems.py @@ -1,6 +1,5 @@ """Mobjects that represent coordinate systems.""" - from __future__ import annotations __all__ = [ @@ -14,10 +13,11 @@ import fractions as fr import numbers -from typing import TYPE_CHECKING, Any, Callable, Iterable, Sequence +from collections.abc import Iterable, Sequence +from typing import TYPE_CHECKING, Any, Callable, TypeVar, overload import numpy as np -from colour import Color +from typing_extensions import Self from manim import config from manim.constants import * @@ -27,8 +27,11 @@ from manim.mobject.graphing.functions import ImplicitFunction, ParametricFunction from manim.mobject.graphing.number_line import NumberLine from manim.mobject.graphing.scale import LinearBase +from manim.mobject.mobject import Mobject from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL +from manim.mobject.opengl.opengl_surface import OpenGLSurface from manim.mobject.text.tex_mobject import MathTex +from manim.mobject.three_d.three_dimensions import Surface from manim.mobject.types.vectorized_mobject import ( VDict, VectorizedPoint, @@ -42,7 +45,10 @@ GREEN, WHITE, YELLOW, + ManimColor, + ParsableManimColor, color_gradient, + interpolate_color, invert_color, ) from manim.utils.config_ops import merge_dicts_recursively, update_dict_recursively @@ -51,11 +57,20 @@ if TYPE_CHECKING: from manim.mobject.mobject import Mobject + from manim.typing import ( + ManimFloat, + Point2D, + Point2DLike, + Point3D, + Point3DLike, + Vector3D, + ) + + LineType = TypeVar("LineType", bound=Line) class CoordinateSystem: - r""" - Abstract class for Axes and NumberPlane + r"""Abstract base class for Axes and NumberPlane. Examples -------- @@ -90,10 +105,10 @@ def construct(self): ) # Extra lines and labels for point (1,1) - graphs += grid.get_horizontal_line(grid.c2p(1, 1, 0), color=BLUE) - graphs += grid.get_vertical_line(grid.c2p(1, 1, 0), color=BLUE) - graphs += Dot(point=grid.c2p(1, 1, 0), color=YELLOW) - graphs += Tex("(1,1)").scale(0.75).next_to(grid.c2p(1, 1, 0)) + graphs += grid.get_horizontal_line(grid @ (1, 1, 0), color=BLUE) + graphs += grid.get_vertical_line(grid @ (1, 1, 0), color=BLUE) + graphs += Dot(point=grid @ (1, 1, 0), color=YELLOW) + graphs += Tex("(1,1)").scale(0.75).next_to(grid @ (1, 1, 0)) title = Title( # spaces between braces to prevent SyntaxError r"Graphs of $y=x^{ {1}\over{n} }$ and $y=x^n (n=1,2,3,...,20)$", @@ -106,12 +121,12 @@ def construct(self): def __init__( self, - x_range=None, - y_range=None, - x_length=None, - y_length=None, - dimension=2, - ): + x_range: Sequence[float] | None = None, + y_range: Sequence[float] | None = None, + x_length: float | None = None, + y_length: float | None = None, + dimension: int = 2, + ) -> None: self.dimension = dimension default_step = 1 @@ -139,13 +154,13 @@ def __init__( self.y_length = y_length self.num_sampled_graph_points_per_tick = 10 - def coords_to_point(self, *coords): + def coords_to_point(self, *coords: ManimFloat): raise NotImplementedError() - def point_to_coords(self, point): + def point_to_coords(self, point: Point3DLike): raise NotImplementedError() - def polar_to_point(self, radius: float, azimuth: float) -> np.ndarray: + def polar_to_point(self, radius: float, azimuth: float) -> Point2D: r"""Gets a point from polar coordinates. Parameters @@ -176,7 +191,7 @@ def construct(self): """ return self.coords_to_point(radius * np.cos(azimuth), radius * np.sin(azimuth)) - def point_to_polar(self, point: np.ndarray) -> tuple[float, float]: + def point_to_polar(self, point: Point2DLike) -> Point2D: r"""Gets polar coordinates from a point. Parameters @@ -192,12 +207,14 @@ def point_to_polar(self, point: np.ndarray) -> tuple[float, float]: x, y = self.point_to_coords(point) return np.sqrt(x**2 + y**2), np.arctan2(y, x) - def c2p(self, *coords): - """Abbreviation for coords_to_point""" + def c2p( + self, *coords: float | Sequence[float] | Sequence[Sequence[float]] | np.ndarray + ) -> np.ndarray: + """Abbreviation for :meth:`coords_to_point`""" return self.coords_to_point(*coords) - def p2c(self, point): - """Abbreviation for point_to_coords""" + def p2c(self, point: Point3DLike): + """Abbreviation for :meth:`point_to_coords`""" return self.point_to_coords(point) def pr2pt(self, radius: float, azimuth: float) -> np.ndarray: @@ -211,7 +228,7 @@ def pt2pr(self, point: np.ndarray) -> tuple[float, float]: def get_axes(self): raise NotImplementedError() - def get_axis(self, index): + def get_axis(self, index: int) -> Mobject: return self.get_axes()[index] def get_origin(self) -> np.ndarray: @@ -224,19 +241,19 @@ def get_origin(self) -> np.ndarray: """ return self.coords_to_point(0, 0) - def get_x_axis(self): + def get_x_axis(self) -> Mobject: return self.get_axis(0) - def get_y_axis(self): + def get_y_axis(self) -> Mobject: return self.get_axis(1) - def get_z_axis(self): + def get_z_axis(self) -> Mobject: return self.get_axis(2) - def get_x_unit_size(self): + def get_x_unit_size(self) -> float: return self.get_x_axis().get_unit_size() - def get_y_unit_size(self): + def get_y_unit_size(self) -> float: return self.get_y_axis().get_unit_size() def get_x_axis_label( @@ -289,7 +306,7 @@ def get_y_axis_label( direction: Sequence[float] = UP * 0.5 + RIGHT, buff: float = SMALL_BUFF, **kwargs, - ): + ) -> Mobject: """Generate a y-axis label. Parameters @@ -297,7 +314,7 @@ def get_y_axis_label( label The label. Defaults to :class:`~.MathTex` for ``str`` and ``float`` inputs. edge - The edge of the x-axis to which the label will be added, by default ``UR``. + The edge of the y-axis to which the label will be added, by default ``UR``. direction Allows for further positioning of the label from an edge, by default ``UR`` buff @@ -324,7 +341,6 @@ def construct(self): ) self.add(ax, y_label) """ - return self._get_axis_label( label, self.get_y_axis(), edge, direction, buff=buff, **kwargs ) @@ -357,62 +373,19 @@ def _get_axis_label( :class:`~.Mobject` The positioned label along the given axis. """ - label = self.x_axis._create_label_tex(label) label.next_to(axis.get_edge_center(edge), direction=direction, buff=buff) label.shift_onto_screen(buff=MED_SMALL_BUFF) return label - def get_axis_labels( - self, - x_label: float | str | Mobject = "x", - y_label: float | str | Mobject = "y", - ) -> VGroup: - """Defines labels for the x_axis and y_axis of the graph. For increased control over the position of the labels, - use :meth:`get_x_axis_label` and :meth:`get_y_axis_label`. - - Parameters - ---------- - x_label - The label for the x_axis. Defaults to :class:`~.MathTex` for ``str`` and ``float`` inputs. - y_label - The label for the y_axis. Defaults to :class:`~.MathTex` for ``str`` and ``float`` inputs. - - Returns - ------- - :class:`~.VGroup` - A :class:`~.Vgroup` of the labels for the x_axis and y_axis. - - - .. seealso:: - :class:`get_x_axis_label` - :class:`get_y_axis_label` - - Examples - -------- - .. manim:: GetAxisLabelsExample - :save_last_frame: - - class GetAxisLabelsExample(Scene): - def construct(self): - ax = Axes() - labels = ax.get_axis_labels( - Tex("x-axis").scale(0.7), Text("y-axis").scale(0.45) - ) - self.add(ax, labels) - """ - - self.axis_labels = VGroup( - self.get_x_axis_label(x_label), - self.get_y_axis_label(y_label), - ) - return self.axis_labels + def get_axis_labels(self): + raise NotImplementedError() def add_coordinates( self, - *axes_numbers: (Iterable[float] | None | dict[float, str | float | Mobject]), - **kwargs, - ): + *axes_numbers: Iterable[float] | None | dict[float, str | float | Mobject], + **kwargs: Any, + ) -> Self: """Adds labels to the axes. Use ``Axes.coordinate_labels`` to access the coordinates after creation. @@ -428,7 +401,9 @@ def add_coordinates( ax = ThreeDAxes() x_labels = range(-4, 5) z_labels = range(-4, 4, 2) - ax.add_coordinates(x_labels, None, z_labels) # default y labels, custom x & z labels + ax.add_coordinates( + x_labels, None, z_labels + ) # default y labels, custom x & z labels ax.add_coordinates(x_labels) # only x labels You can also specifically control the position and value of the labels using a dict. @@ -438,12 +413,19 @@ def add_coordinates( ax = Axes(x_range=[0, 7]) x_pos = [x for x in range(1, 8)] - # strings are automatically converted into a `Tex` mobject. - x_vals = ["Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"] + # strings are automatically converted into a Tex mobject. + x_vals = [ + "Monday", + "Tuesday", + "Wednesday", + "Thursday", + "Friday", + "Saturday", + "Sunday", + ] x_dict = dict(zip(x_pos, x_vals)) ax.add_coordinates(x_dict) """ - self.coordinate_labels = VGroup() # if nothing is passed to axes_numbers, produce axes with default labelling if not axes_numbers: @@ -466,15 +448,37 @@ def add_coordinates( return self + # overload necessary until https://github.com/python/mypy/issues/3737 is supported + @overload + def get_line_from_axis_to_point( + self, + index: int, + point: Sequence[float], + line_config: dict | None = ..., + color: ParsableManimColor | None = ..., + stroke_width: float = ..., + ) -> DashedLine: ... + + @overload def get_line_from_axis_to_point( self, index: int, point: Sequence[float], - line_func: Line = DashedLine, - line_config: dict | None = None, - color: Color | None = None, - stroke_width: float = 2, - ) -> Line: + line_func: type[LineType], + line_config: dict | None = ..., + color: ParsableManimColor | None = ..., + stroke_width: float = ..., + ) -> LineType: ... + + def get_line_from_axis_to_point( # type: ignore[no-untyped-def] + self, + index, + point, + line_func=DashedLine, + line_config=None, + color=None, + stroke_width=2, + ): """Returns a straight line from a given axis to a point in the scene. Parameters @@ -502,20 +506,19 @@ def get_line_from_axis_to_point( :meth:`~.CoordinateSystem.get_vertical_line` :meth:`~.CoordinateSystem.get_horizontal_line` """ - line_config = line_config if line_config is not None else {} if color is None: color = VMobject().color - line_config["color"] = color + line_config["color"] = ManimColor.parse(color) line_config["stroke_width"] = stroke_width axis = self.get_axis(index) line = line_func(axis.get_projection(point), point, **line_config) return line - def get_vertical_line(self, point: Sequence[float], **kwargs) -> Line: + def get_vertical_line(self, point: Sequence[float], **kwargs: Any) -> Line: """A vertical line from the x-axis to a given point in the scene. Parameters @@ -572,14 +575,13 @@ def get_horizontal_line(self, point: Sequence[float], **kwargs) -> Line: class GetHorizontalLineExample(Scene): def construct(self): ax = Axes().add_coordinates() - point = ax.c2p(-4, 1.5) + point = ax @ (-4, 1.5) dot = Dot(point) line = ax.get_horizontal_line(point, line_func=Line) self.add(ax, line, dot) """ - return self.get_line_from_axis_to_point(1, point, **kwargs) def get_lines_to_point(self, point: Sequence[float], **kwargs) -> VGroup: @@ -616,7 +618,6 @@ def construct(self): lines_2 = ax.get_lines_to_point(circ.get_corner(DL), color=BLUE_B) self.add(ax, lines_1, lines_2, circ) """ - return VGroup( self.get_horizontal_line(point, **kwargs), self.get_vertical_line(point, **kwargs), @@ -628,8 +629,11 @@ def plot( self, function: Callable[[float], float], x_range: Sequence[float] | None = None, - **kwargs, - ): + use_vectorized: bool = False, + colorscale: Union[Iterable[Color], Iterable[Color, float]] | None = None, + colorscale_axis: int = 1, + **kwargs: Any, + ) -> ParametricFunction: """Generates a curve based on a function. Parameters @@ -638,6 +642,15 @@ def plot( The function used to construct the :class:`~.ParametricFunction`. x_range The range of the curve along the axes. ``x_range = [x_min, x_max, x_step]``. + use_vectorized + Whether to pass in the generated t value array to the function. Only use this if your function supports it. + Output should be a numpy array of shape ``[y_0, y_1, ...]`` + colorscale + Colors of the function. Optional parameter used when coloring a function by values. Passing a list of colors + and a colorscale_axis will color the function by y-value. Passing a list of tuples in the form ``(color, pivot)`` + allows user-defined pivots where the color transitions. + colorscale_axis + Defines the axis on which the colorscale is applied (0 = x, 1 = y), default is y-axis (1). kwargs Additional parameters to be passed to :class:`~.ParametricFunction`. @@ -697,7 +710,6 @@ def log_func(x): self.add(axes, curves) """ - t_range = np.array(self.x_range, dtype=float) if x_range is not None: t_range[: len(x_range)] = x_range @@ -713,17 +725,68 @@ def log_func(x): lambda t: self.coords_to_point(t, function(t)), t_range=t_range, scaling=self.x_axis.scaling, + use_vectorized=use_vectorized, **kwargs, ) + graph.underlying_function = function + + if colorscale: + if type(colorscale[0]) in (list, tuple): + new_colors, pivots = [ + [i for i, j in colorscale], + [j for i, j in colorscale], + ] + else: + new_colors = colorscale + + ranges = [self.x_range, self.y_range] + pivot_min = ranges[colorscale_axis][0] + pivot_max = ranges[colorscale_axis][1] + pivot_frequency = (pivot_max - pivot_min) / (len(new_colors) - 1) + pivots = np.arange( + start=pivot_min, + stop=pivot_max + pivot_frequency, + step=pivot_frequency, + ) + + resolution = 0.01 if len(x_range) == 2 else x_range[2] + sample_points = np.arange(x_range[0], x_range[1] + resolution, resolution) + color_list = [] + for samp_x in sample_points: + axis_value = (samp_x, function(samp_x))[colorscale_axis] + if axis_value <= pivots[0]: + color_list.append(new_colors[0]) + elif axis_value >= pivots[-1]: + color_list.append(new_colors[-1]) + else: + for i, pivot in enumerate(pivots): + if pivot > axis_value: + color_index = (axis_value - pivots[i - 1]) / ( + pivots[i] - pivots[i - 1] + ) + color_index = min(color_index, 1) + mob_color = interpolate_color( + new_colors[i - 1], + new_colors[i], + color_index, + ) + color_list.append(mob_color) + break + if config.renderer == RendererType.OPENGL: + graph.set_color(color_list) + else: + graph.set_stroke(color_list) + graph.set_sheen_direction(RIGHT) + return graph def plot_implicit_curve( self, - func: Callable, + func: Callable[[float, float], float], min_depth: int = 5, max_quads: int = 1500, - **kwargs, + **kwargs: Any, ) -> ImplicitFunction: """Creates the curves of an implicit function. @@ -751,8 +814,10 @@ def construct(self): ) self.add(ax, a) """ + x_scale = self.get_x_axis().scaling + y_scale = self.get_y_axis().scaling graph = ImplicitFunction( - func=func, + func=(lambda x, y: func(x_scale.function(x), y_scale.function(y))), x_range=self.x_range[:2], y_range=self.y_range[:2], min_depth=min_depth, @@ -766,10 +831,50 @@ def construct(self): ) return graph - def plot_parametric_curve(self, function, **kwargs): + def plot_parametric_curve( + self, + function: Callable[[float], np.ndarray], + use_vectorized: bool = False, + **kwargs: Any, + ) -> ParametricFunction: + """A parametric curve. + + Parameters + ---------- + function + A parametric function mapping a number to a point in the + coordinate system. + use_vectorized + Whether to pass in the generated t value array to the function. Only use this if your function supports it. + kwargs + Any further keyword arguments are passed to :class:`.ParametricFunction`. + + Example + ------- + .. manim:: ParametricCurveExample + :save_last_frame: + + class ParametricCurveExample(Scene): + def construct(self): + ax = Axes() + cardioid = ax.plot_parametric_curve( + lambda t: np.array( + [ + np.exp(1) * np.cos(t) * (1 - np.cos(t)), + np.exp(1) * np.sin(t) * (1 - np.cos(t)), + 0, + ] + ), + t_range=[0, 2 * PI], + color="#0FF1CE", + ) + self.add(ax, cardioid) + """ dim = self.dimension graph = ParametricFunction( - lambda t: self.coords_to_point(*function(t)[:dim]), **kwargs + lambda t: self.coords_to_point(*function(t)[:dim]), + use_vectorized=use_vectorized, + **kwargs, ) graph.underlying_function = function return graph @@ -777,8 +882,8 @@ def plot_parametric_curve(self, function, **kwargs): def plot_polar_graph( self, r_func: Callable[[float], float], - theta_range: Sequence[float] = [0, 2 * PI], - **kwargs, + theta_range: Sequence[float] | None = None, + **kwargs: Any, ) -> ParametricFunction: """A polar graph. @@ -804,6 +909,7 @@ def construct(self): graph = plane.plot_polar_graph(r, [0, 2 * PI], color=ORANGE) self.add(plane, graph) """ + theta_range = theta_range if theta_range is not None else [0, 2 * PI] graph = ParametricFunction( function=lambda th: self.pr2pt(r_func(th), th), t_range=theta_range, @@ -812,11 +918,99 @@ def construct(self): graph.underlying_function = r_func return graph + def plot_surface( + self, + function: Callable[[float], float], + u_range: Sequence[float] | None = None, + v_range: Sequence[float] | None = None, + colorscale: ( + Sequence[ParsableManimColor] + | Sequence[tuple[ParsableManimColor, float]] + | None + ) = None, + colorscale_axis: int = 2, + **kwargs: Any, + ) -> Surface | OpenGLSurface: + """Generates a surface based on a function. + + Parameters + ---------- + function + The function used to construct the :class:`~.Surface`. + u_range + The range of the ``u`` variable: ``(u_min, u_max)``. + v_range + The range of the ``v`` variable: ``(v_min, v_max)``. + colorscale + Colors of the surface. Passing a list of colors will color the surface by z-value. + Passing a list of tuples in the form ``(color, pivot)`` allows user-defined pivots + where the color transitions. + colorscale_axis + Defines the axis on which the colorscale is applied (0 = x, 1 = y, 2 = z), default + is z-axis (2). + kwargs + Additional parameters to be passed to :class:`~.Surface`. + + Returns + ------- + :class:`~.Surface` + The plotted surface. + + Examples + -------- + .. manim:: PlotSurfaceExample + :save_last_frame: + + class PlotSurfaceExample(ThreeDScene): + def construct(self): + resolution_fa = 16 + self.set_camera_orientation(phi=75 * DEGREES, theta=-60 * DEGREES) + axes = ThreeDAxes(x_range=(-3, 3, 1), y_range=(-3, 3, 1), z_range=(-5, 5, 1)) + def param_trig(u, v): + x = u + y = v + z = 2 * np.sin(x) + 2 * np.cos(y) + return z + trig_plane = axes.plot_surface( + param_trig, + resolution=(resolution_fa, resolution_fa), + u_range = (-3, 3), + v_range = (-3, 3), + colorscale = [BLUE, GREEN, YELLOW, ORANGE, RED], + ) + self.add(axes, trig_plane) + """ + if config.renderer == RendererType.CAIRO: + surface = Surface( + lambda u, v: self.c2p(u, v, function(u, v)), + u_range=u_range, + v_range=v_range, + **kwargs, + ) + if colorscale: + surface.set_fill_by_value( + axes=self.copy(), + colorscale=colorscale, + axis=colorscale_axis, + ) + elif config.renderer == RendererType.OPENGL: + surface = OpenGLSurface( + lambda u, v: self.c2p(u, v, function(u, v)), + u_range=u_range, + v_range=v_range, + axes=self.copy(), + colorscale=colorscale, + colorscale_axis=colorscale_axis, + **kwargs, + ) + + return surface + def input_to_graph_point( self, x: float, graph: ParametricFunction | VMobject, - ) -> np.ndarray: + ) -> Point3D: """Returns the coordinates of the point on a ``graph`` corresponding to an ``x`` value. Parameters @@ -852,7 +1046,6 @@ def construct(self): self.add(ax, curve, sq) """ - if hasattr(graph, "underlying_function"): return graph.function(x) else: @@ -871,7 +1064,9 @@ def construct(self): f"x={x} not located in the range of the graph ([{self.p2c(graph.get_start())[0]}, {self.p2c(graph.get_end())[0]}])", ) - def input_to_graph_coords(self, x: float, graph: ParametricFunction) -> tuple: + def input_to_graph_coords( + self, x: float, graph: ParametricFunction + ) -> tuple[float, float]: """Returns a tuple of the axis relative coordinates of the point on the graph based on the x-value given. @@ -881,13 +1076,13 @@ def input_to_graph_coords(self, x: float, graph: ParametricFunction) -> tuple: >>> from manim import Axes >>> ax = Axes() - >>> parabola = ax.plot(lambda x: x ** 2) + >>> parabola = ax.plot(lambda x: x**2) >>> ax.input_to_graph_coords(x=3, graph=parabola) (3, 9) """ return x, graph.underlying_function(x) - def i2gc(self, x: float, graph: ParametricFunction) -> tuple: + def i2gc(self, x: float, graph: ParametricFunction) -> tuple[float, float]: """Alias for :meth:`input_to_graph_coords`.""" return self.input_to_graph_coords(x, graph) @@ -902,11 +1097,11 @@ def get_graph_label( x_val: float | None = None, direction: Sequence[float] = RIGHT, buff: float = MED_SMALL_BUFF, - color: Color | None = None, + color: ParsableManimColor | None = None, dot: bool = False, - dot_config: dict | None = None, + dot_config: dict[str, Any] | None = None, ) -> Mobject: - """Creates a properly positioned label for the passed graph, with an optional dot. + r"""Creates a properly positioned label for the passed graph, with an optional dot. Parameters ---------- @@ -943,7 +1138,7 @@ def construct(self): sin = ax.plot(lambda x: np.sin(x), color=PURPLE_B) label = ax.get_graph_label( graph=sin, - label= MathTex(r"\\frac{\\pi}{2}"), + label= MathTex(r"\frac{\pi}{2}"), x_val=PI / 2, dot=True, direction=UR, @@ -951,10 +1146,10 @@ def construct(self): self.add(ax, sin, label) """ - if dot_config is None: dot_config = {} - color = color or graph.get_color() + if color is None: + color = graph.get_color() label = self.x_axis._create_label_tex(label).set_color(color) if x_val is None: @@ -984,9 +1179,9 @@ def get_riemann_rectangles( dx: float | None = 0.1, input_sample_type: str = "left", stroke_width: float = 1, - stroke_color: Color = BLACK, + stroke_color: ParsableManimColor = BLACK, fill_opacity: float = 1, - color: Iterable[Color] | Color = np.array((BLUE, GREEN)), + color: Iterable[ParsableManimColor] | ParsableManimColor = (BLUE, GREEN), show_signed_area: bool = True, bounded_graph: ParametricFunction = None, blend: bool = False, @@ -1070,7 +1265,6 @@ def construct(self): ax, bounding_line, quadratic, rects_right, rects_left, bounded_rects ) """ - # setting up x_range, overwrite user's third input if x_range is None: if bounded_graph is None: @@ -1085,11 +1279,12 @@ def construct(self): rectangles = VGroup() x_range = np.arange(*x_range) - # allows passing a string to color the graph - if type(color) is str: - colors = [color] * len(x_range) + if isinstance(color, (list, tuple)): + color = [ManimColor(c) for c in color] else: - colors = color_gradient(color, len(x_range)) + color = [ManimColor(color)] + + colors = color_gradient(color, len(x_range)) for x, color in zip(x_range, colors): if input_sample_type == "left": @@ -1144,11 +1339,11 @@ def get_area( self, graph: ParametricFunction, x_range: tuple[float, float] | None = None, - color: Color | Iterable[Color] = [BLUE, GREEN], + color: ParsableManimColor | Iterable[ParsableManimColor] = (BLUE, GREEN), opacity: float = 0.3, bounded_graph: ParametricFunction = None, - **kwargs, - ): + **kwargs: Any, + ) -> Polygon: """Returns a :class:`~.Polygon` representing the area under the graph passed. Parameters @@ -1255,16 +1450,17 @@ def angle_of_tangent( .. code-block:: python ax = Axes() - curve = ax.plot(lambda x: x ** 2) + curve = ax.plot(lambda x: x**2) ax.angle_of_tangent(x=3, graph=curve) # 1.4056476493802699 """ - p0 = np.array([*self.input_to_graph_coords(x, graph)]) p1 = np.array([*self.input_to_graph_coords(x + dx, graph)]) return angle_of_vector(p1 - p0) - def slope_of_tangent(self, x: float, graph: ParametricFunction, **kwargs) -> float: + def slope_of_tangent( + self, x: float, graph: ParametricFunction, **kwargs: Any + ) -> float: """Returns the slope of the tangent to the plotted curve at a particular x-value. @@ -1285,15 +1481,14 @@ def slope_of_tangent(self, x: float, graph: ParametricFunction, **kwargs) -> flo .. code-block:: python ax = Axes() - curve = ax.plot(lambda x: x ** 2) + curve = ax.plot(lambda x: x**2) ax.slope_of_tangent(x=-2, graph=curve) # -3.5000000259052038 """ - return np.tan(self.angle_of_tangent(x, graph, **kwargs)) def plot_derivative_graph( - self, graph: ParametricFunction, color: Color = GREEN, **kwargs + self, graph: ParametricFunction, color: ParsableManimColor = GREEN, **kwargs ) -> ParametricFunction: """Returns the curve of the derivative of the passed graph. @@ -1341,8 +1536,9 @@ def plot_antiderivative_graph( graph: ParametricFunction, y_intercept: float = 0, samples: int = 50, - **kwargs, - ): + use_vectorized: bool = False, + **kwargs: Any, + ) -> ParametricFunction: """Plots an antiderivative graph. Parameters @@ -1353,6 +1549,10 @@ def plot_antiderivative_graph( The y-value at which the graph intercepts the y-axis. samples The number of points to take the area under the graph. + use_vectorized + Whether to use the vectorized version of the antiderivative. This means + to pass in the generated t value array to the function. Only use this if your function supports it. + Output should be a numpy array of shape ``[y_0, y_1, ...]`` kwargs Any valid keyword argument of :class:`~.ParametricFunction`. @@ -1384,24 +1584,24 @@ def construct(self): """ def antideriv(x): - x_vals = np.linspace(0, x, samples) + x_vals = np.linspace(0, x, samples, axis=1 if use_vectorized else 0) f_vec = np.vectorize(graph.underlying_function) y_vals = f_vec(x_vals) return np.trapz(y_vals, x_vals) + y_intercept - return self.plot(antideriv, **kwargs) + return self.plot(antideriv, use_vectorized=use_vectorized, **kwargs) def get_secant_slope_group( self, x: float, graph: ParametricFunction, dx: float | None = None, - dx_line_color: Color = YELLOW, - dy_line_color: Color | None = None, + dx_line_color: ParsableManimColor = YELLOW, + dy_line_color: ParsableManimColor | None = None, dx_label: float | str | None = None, dy_label: float | str | None = None, include_secant_line: bool = True, - secant_line_color: Color = GREEN, + secant_line_color: ParsableManimColor = GREEN, secant_line_length: float = 10, ) -> VGroup: """Creates two lines representing `dx` and `df`, the labels for `dx` and `df`, and @@ -1519,7 +1719,7 @@ def get_vertical_lines_to_graph( graph: ParametricFunction, x_range: Sequence[float] | None = None, num_lines: int = 20, - **kwargs, + **kwargs: Any, ) -> VGroup: """Obtains multiple lines from the x-axis to the curve. @@ -1560,7 +1760,6 @@ def construct(self): self.add(ax, curve, lines) """ - x_range = x_range if x_range is not None else self.x_range return VGroup( @@ -1575,11 +1774,11 @@ def get_T_label( x_val: float, graph: ParametricFunction, label: float | str | Mobject | None = None, - label_color: Color | None = None, + label_color: ParsableManimColor | None = None, triangle_size: float = MED_SMALL_BUFF, - triangle_color: Color | None = WHITE, - line_func: Line = Line, - line_color: Color = YELLOW, + triangle_color: ParsableManimColor | None = WHITE, + line_func: type[Line] = Line, + line_color: ParsableManimColor = YELLOW, ) -> VGroup: """Creates a labelled triangle marker with a vertical line from the x-axis to a curve at a given x-value. @@ -1610,10 +1809,10 @@ def get_T_label( Examples -------- - .. manim:: T_labelExample + .. manim:: TLabelExample :save_last_frame: - class T_labelExample(Scene): + class TLabelExample(Scene): def construct(self): # defines the axes and linear function axes = Axes(x_range=[-1, 10], y_range=[-1, 10], x_length=9, y_length=6) @@ -1622,7 +1821,6 @@ def construct(self): t_label = axes.get_T_label(x_val=4, graph=func, label=Tex("x-value")) self.add(axes, func, t_label) """ - T_label_group = VGroup() triangle = RegularPolygon(n=3, start_angle=np.pi / 2, stroke_width=0).set_fill( color=triangle_color, @@ -1645,6 +1843,14 @@ def construct(self): return T_label_group + def __matmul__(self, coord: Point3DLike | Mobject): + if isinstance(coord, Mobject): + coord = coord.get_center() + return self.coords_to_point(*coord) + + def __rmatmul__(self, point: Point3DLike): + return self.point_to_coords(point) + class Axes(VGroup, CoordinateSystem, metaclass=ConvertToOpenGL): """Creates a set of axes. @@ -1688,6 +1894,17 @@ def construct(self): # x_min must be > 0 because log is undefined at 0. graph = ax.plot(lambda x: x ** 2, x_range=[0.001, 10], use_smoothing=False) self.add(ax, graph) + + Styling arguments can be passed to the underlying :class:`.NumberLine` + mobjects that represent the axes: + + .. manim:: AxesWithDifferentTips + :save_last_frame: + + class AxesWithDifferentTips(Scene): + def construct(self): + ax = Axes(axis_config={'tip_shape': StealthTip}) + self.add(ax) """ def __init__( @@ -1700,8 +1917,8 @@ def __init__( x_axis_config: dict | None = None, y_axis_config: dict | None = None, tips: bool = True, - **kwargs, - ): + **kwargs: Any, + ) -> None: VGroup.__init__(self, **kwargs) CoordinateSystem.__init__(self, x_range, y_range, x_length, y_length) @@ -1768,7 +1985,7 @@ def __init__( @staticmethod def _update_default_configs( default_configs: tuple[dict[Any, Any]], passed_configs: tuple[dict[Any, Any]] - ): + ) -> None: """Takes in two tuples of dicts and return modifies the first such that values from ``passed_configs`` overwrite values in ``default_configs``. If a key does not exist in default_configs, it is added to the dict. @@ -1783,6 +2000,8 @@ def _update_default_configs( passed_configs The dict that will be used to update. + Examples + -------- To create a tuple with one dictionary, add a comma after the element: .. code-block:: python @@ -1793,7 +2012,6 @@ def _update_default_configs( ) ) """ - for default_config, passed_config in zip(default_configs, passed_configs): if passed_config is not None: update_dict_recursively(default_config, passed_config) @@ -1801,7 +2019,7 @@ def _update_default_configs( def _create_axis( self, range_terms: Sequence[float], - axis_config: dict, + axis_config: dict[str, Any], length: float, ) -> NumberLine: """Creates an axis and dynamically adjusts its position depending on where 0 is located on the line. @@ -1828,21 +2046,52 @@ def _create_axis( axis.shift(-axis.number_to_point(self._origin_shift([axis.x_min, axis.x_max]))) return axis - def coords_to_point(self, *coords: Sequence[float]) -> np.ndarray: + def coords_to_point( + self, *coords: float | Sequence[float] | Sequence[Sequence[float]] | np.ndarray + ) -> np.ndarray: """Accepts coordinates from the axes and returns a point with respect to the scene. + Equivalent to `ax @ (coord1)` Parameters ---------- coords The coordinates. Each coord is passed as a separate argument: ``ax.coords_to_point(1, 2, 3)``. + Also accepts a list of coordinates + + ``ax.coords_to_point( [x_0, x_1, ...], [y_0, y_1, ...], ... )`` + + ``ax.coords_to_point( [[x_0, y_0, z_0], [x_1, y_1, z_1]] )`` + Returns ------- np.ndarray A point with respect to the scene's coordinate system. + The shape of the array will be similar to the shape of the input. Examples -------- + + .. code-block:: pycon + + >>> from manim import Axes + >>> import numpy as np + >>> ax = Axes() + >>> np.around(ax.coords_to_point(1, 0, 0), 2) + array([0.86, 0. , 0. ]) + >>> np.around(ax @ (1, 0, 0), 2) + array([0.86, 0. , 0. ]) + >>> np.around(ax.coords_to_point([[0, 1], [1, 1], [1, 0]]), 2) + array([[0. , 0.75, 0. ], + [0.86, 0.75, 0. ], + [0.86, 0. , 0. ]]) + >>> np.around( + ... ax.coords_to_point([0, 1, 1], [1, 1, 0]), 2 + ... ) # Transposed version of the above + array([[0. , 0.86, 0.86], + [0.75, 0.75, 0. ], + [0. , 0. , 0. ]]) + .. manim:: CoordsToPointExample :save_last_frame: @@ -1861,29 +2110,78 @@ def construct(self): self.add(plane, dot_scene, ax, dot_axes, lines) """ + coords = np.asarray(coords) origin = self.x_axis.number_to_point( self._origin_shift([self.x_axis.x_min, self.x_axis.x_max]), ) - result = np.array(origin) - for axis, coord in zip(self.get_axes(), coords): - result += axis.number_to_point(coord) - origin - return result - def point_to_coords(self, point: Sequence[float]) -> tuple[float]: + # Is coords in the format ([[x1 y1 z1] [x2 y2 z2] ...])? (True) + # Or is coords in the format (x, y, z) or ([x1 x2 ...], [y1 y2 ...], [z1 z2 ...])? (False) + # The latter is preferred. + are_coordinates_transposed = False + + # If coords is in the format ([[x1 y1 z1] [x2 y2 z2] ...]): + if coords.ndim == 3: + # Extract from original tuple: now coords looks like [[x y z]] or [[x1 y1 z1] [x2 y2 z2] ...]. + coords = coords[0] + # If there's a single coord (coords = [[x y z]]), extract it so that + # coords = [x y z] and coords_to_point returns a single point. + if coords.shape[0] == 1: + coords = coords[0] + # Else, if coords looks more like [[x1 y1 z1] [x2 y2 z2] ...], transform them (by + # transposing) into the format [[x1 x2 ...] [y1 y2 ...] [z1 z2 ...]] for later processing. + else: + coords = coords.T + are_coordinates_transposed = True + # Otherwise, coords already looked like (x, y, z) or ([x1 x2 ...], [y1 y2 ...], [z1 z2 ...]), + # so no further processing is needed. + + # Now coords should either look like [x y z] or [[x1 x2 ...] [y1 y2 ...] [z1 z2 ...]], + # so it can be iterated directly. Each element is either a float representing a single + # coordinate, or a float ndarray of coordinates corresponding to a single axis. + # Although "points" and "nums" are in plural, there might be a single point or number. + points = self.x_axis.number_to_point(coords[0]) + other_axes = self.axes.submobjects[1:] + for axis, nums in zip(other_axes, coords[1:]): + points += axis.number_to_point(nums) - origin + + # Return points as is, except if coords originally looked like + # ([x1 x2 ...], [y1 y2 ...], [z1 z2 ...]), which is determined by the conditions below. In + # that case, the current implementation requires that the results have to be transposed. + if are_coordinates_transposed or points.ndim == 1: + return points + return points.T + + def point_to_coords(self, point: Sequence[float]) -> np.ndarray: """Accepts a point from the scene and returns its coordinates with respect to the axes. Parameters ---------- point The point, i.e. ``RIGHT`` or ``[0, 1, 0]``. + Also accepts a list of points as ``[RIGHT, [0, 1, 0]]``. Returns ------- - Tuple[float] - The coordinates on the axes, i.e. ``(4.0, 7.0)``. + np.ndarray[float] + The coordinates on the axes, i.e. ``[4.0, 7.0]``. + Or a list of coordinates if `point` is a list of points. Examples -------- + + .. code-block:: pycon + + >>> from manim import Axes, RIGHT + >>> import numpy as np + >>> ax = Axes(x_range=[0, 10, 2]) + >>> np.around(ax.point_to_coords(RIGHT), 2) + array([5.83, 0. ]) + >>> np.around(ax.point_to_coords([[0, 0, 1], [1, 0, 0]]), 2) + array([[5. , 0. ], + [5.83, 0. ]]) + + .. manim:: PointToCoordsExample :save_last_frame: @@ -1901,7 +2199,11 @@ def construct(self): self.add(ax, circ, label, Dot(circ.get_right())) """ - return tuple(axis.point_to_number(point) for axis in self.get_axes()) + point = np.asarray(point) + result = np.asarray([axis.point_to_number(point) for axis in self.get_axes()]) + if point.ndim == 2: + return result.T + return result def get_axes(self) -> VGroup: """Gets the axes. @@ -1913,16 +2215,63 @@ def get_axes(self) -> VGroup: """ return self.axes + def get_axis_labels( + self, + x_label: float | str | Mobject = "x", + y_label: float | str | Mobject = "y", + ) -> VGroup: + """Defines labels for the x-axis and y-axis of the graph. + + For increased control over the position of the labels, + use :meth:`~.CoordinateSystem.get_x_axis_label` and + :meth:`~.CoordinateSystem.get_y_axis_label`. + + Parameters + ---------- + x_label + The label for the x_axis. Defaults to :class:`~.MathTex` for ``str`` and ``float`` inputs. + y_label + The label for the y_axis. Defaults to :class:`~.MathTex` for ``str`` and ``float`` inputs. + + Returns + ------- + :class:`~.VGroup` + A :class:`~.VGroup` of the labels for the x_axis and y_axis. + + + .. seealso:: + :meth:`~.CoordinateSystem.get_x_axis_label` + :meth:`~.CoordinateSystem.get_y_axis_label` + + Examples + -------- + .. manim:: GetAxisLabelsExample + :save_last_frame: + + class GetAxisLabelsExample(Scene): + def construct(self): + ax = Axes() + labels = ax.get_axis_labels( + Tex("x-axis").scale(0.7), Text("y-axis").scale(0.45) + ) + self.add(ax, labels) + """ + self.axis_labels = VGroup( + self.get_x_axis_label(x_label), + self.get_y_axis_label(y_label), + ) + return self.axis_labels + def plot_line_graph( self, x_values: Iterable[float], y_values: Iterable[float], z_values: Iterable[float] | None = None, - line_color: Color = YELLOW, + line_color: ParsableManimColor = YELLOW, add_vertex_dots: bool = True, vertex_dot_radius: float = DEFAULT_DOT_RADIUS, - vertex_dot_style: dict | None = None, - **kwargs, + vertex_dot_style: dict[str, Any] | None = None, + **kwargs: Any, ) -> VDict: """Draws a line graph. @@ -2064,16 +2413,15 @@ def __init__( x_length: float | None = config.frame_height + 2.5, y_length: float | None = config.frame_height + 2.5, z_length: float | None = config.frame_height - 1.5, - z_axis_config: dict | None = None, - z_normal: Sequence[float] = DOWN, + z_axis_config: dict[str, Any] | None = None, + z_normal: Vector3D = DOWN, num_axis_pieces: int = 20, light_source: Sequence[float] = 9 * DOWN + 7 * LEFT + 10 * OUT, # opengl stuff (?) depth=None, gloss=0.5, - **kwargs, - ): - + **kwargs: dict[str, Any], + ) -> None: super().__init__( x_range=x_range, x_length=x_length, @@ -2125,18 +2473,18 @@ def __init__( self.add(z_axis) self.z_axis = z_axis - if config.renderer != "opengl": + if config.renderer == RendererType.CAIRO: self._add_3d_pieces() self._set_axis_shading() - def _add_3d_pieces(self): + def _add_3d_pieces(self) -> None: for axis in self.axes: axis.pieces = VGroup(*axis.get_pieces(self.num_axis_pieces)) axis.add(axis.pieces) axis.set_stroke(width=0, family=False) axis.set_shade_in_3d(True) - def _set_axis_shading(self): + def _set_axis_shading(self) -> None: def make_func(axis): vect = self.light_source return lambda: ( @@ -2150,28 +2498,78 @@ def make_func(axis): submob.get_unit_normal = lambda a: np.ones(3) submob.set_sheen(0.2) - def get_z_axis_label( + def get_y_axis_label( self, label: float | str | Mobject, - edge: Sequence[float] = OUT, - direction: Sequence[float] = RIGHT, + edge: Sequence[float] = UR, + direction: Sequence[float] = UR, buff: float = SMALL_BUFF, - rotation=PI / 2, - rotation_axis=RIGHT, + rotation: float = PI / 2, + rotation_axis: Vector3D = OUT, **kwargs, ) -> Mobject: - """Generate a z-axis label. + """Generate a y-axis label. Parameters ---------- label The label. Defaults to :class:`~.MathTex` for ``str`` and ``float`` inputs. edge - The edge of the x-axis to which the label will be added, by default ``UR``. + The edge of the y-axis to which the label will be added, by default ``UR``. direction Allows for further positioning of the label from an edge, by default ``UR``. buff - The distance of the label from the line. + The distance of the label from the line, by default ``SMALL_BUFF``. + rotation + The angle at which to rotate the label, by default ``PI/2``. + rotation_axis + The axis about which to rotate the label, by default ``OUT``. + + Returns + ------- + :class:`~.Mobject` + The positioned label. + + Examples + -------- + .. manim:: GetYAxisLabelExample + :save_last_frame: + + class GetYAxisLabelExample(ThreeDScene): + def construct(self): + ax = ThreeDAxes() + lab = ax.get_y_axis_label(Tex("$y$-label")) + self.set_camera_orientation(phi=2*PI/5, theta=PI/5) + self.add(ax, lab) + """ + positioned_label = self._get_axis_label( + label, self.get_y_axis(), edge, direction, buff=buff, **kwargs + ) + positioned_label.rotate(rotation, axis=rotation_axis) + return positioned_label + + def get_z_axis_label( + self, + label: float | str | Mobject, + edge: Vector3D = OUT, + direction: Vector3D = RIGHT, + buff: float = SMALL_BUFF, + rotation: float = PI / 2, + rotation_axis: Vector3D = RIGHT, + **kwargs: Any, + ) -> Mobject: + """Generate a z-axis label. + + Parameters + ---------- + label + The label. Defaults to :class:`~.MathTex` for ``str`` and ``float`` inputs. + edge + The edge of the z-axis to which the label will be added, by default ``OUT``. + direction + Allows for further positioning of the label from an edge, by default ``RIGHT``. + buff + The distance of the label from the line, by default ``SMALL_BUFF``. rotation The angle at which to rotate the label, by default ``PI/2``. rotation_axis @@ -2194,13 +2592,66 @@ def construct(self): self.set_camera_orientation(phi=2*PI/5, theta=PI/5) self.add(ax, lab) """ - positioned_label = self._get_axis_label( label, self.get_z_axis(), edge, direction, buff=buff, **kwargs ) positioned_label.rotate(rotation, axis=rotation_axis) return positioned_label + def get_axis_labels( + self, + x_label: float | str | Mobject = "x", + y_label: float | str | Mobject = "y", + z_label: float | str | Mobject = "z", + ) -> VGroup: + """Defines labels for the x_axis and y_axis of the graph. + + For increased control over the position of the labels, + use :meth:`~.CoordinateSystem.get_x_axis_label`, + :meth:`~.ThreeDAxes.get_y_axis_label`, and + :meth:`~.ThreeDAxes.get_z_axis_label`. + + Parameters + ---------- + x_label + The label for the x_axis. Defaults to :class:`~.MathTex` for ``str`` and ``float`` inputs. + y_label + The label for the y_axis. Defaults to :class:`~.MathTex` for ``str`` and ``float`` inputs. + z_label + The label for the z_axis. Defaults to :class:`~.MathTex` for ``str`` and ``float`` inputs. + + Returns + ------- + :class:`~.VGroup` + A :class:`~.VGroup` of the labels for the x_axis, y_axis, and z_axis. + + + .. seealso:: + :meth:`~.CoordinateSystem.get_x_axis_label` + :meth:`~.ThreeDAxes.get_y_axis_label` + :meth:`~.ThreeDAxes.get_z_axis_label` + + Examples + -------- + .. manim:: GetAxisLabelsExample + :save_last_frame: + + class GetAxisLabelsExample(ThreeDScene): + def construct(self): + self.set_camera_orientation(phi=2*PI/5, theta=PI/5) + axes = ThreeDAxes() + labels = axes.get_axis_labels( + Text("x-axis").scale(0.7), Text("y-axis").scale(0.45), Text("z-axis").scale(0.45) + ) + self.add(axes, labels) + """ + self.axis_labels = VGroup( + self.get_x_axis_label(x_label), + self.get_y_axis_label(y_label), + self.get_z_axis_label(z_label), + ) + return self.axis_labels + class NumberPlane(Axes): """Creates a cartesian plane with background lines. @@ -2228,8 +2679,8 @@ class NumberPlane(Axes): .. note:: - If :attr:`x_length` or :attr:`y_length` are not defined, the plane automatically adjusts its lengths based - on the :attr:`x_range` and :attr:`y_range` values to set the ``unit_size`` to 1. + If :attr:`x_length` or :attr:`y_length` are not defined, they are automatically calculated such that + one unit on each axis is one Manim unit long. Examples -------- @@ -2239,8 +2690,6 @@ class NumberPlane(Axes): class NumberPlaneExample(Scene): def construct(self): number_plane = NumberPlane( - x_range=[-10, 10, 1], - y_range=[-10, 10, 1], background_line_style={ "stroke_color": TEAL, "stroke_width": 4, @@ -2248,31 +2697,49 @@ def construct(self): } ) self.add(number_plane) + + .. manim:: NumberPlaneScaled + :save_last_frame: + + class NumberPlaneScaled(Scene): + def construct(self): + number_plane = NumberPlane( + x_range=(-4, 11, 1), + y_range=(-3, 3, 1), + x_length=5, + y_length=2, + ).move_to(LEFT*3) + + number_plane_scaled_y = NumberPlane( + x_range=(-4, 11, 1), + x_length=5, + y_length=4, + ).move_to(RIGHT*3) + + self.add(number_plane) + self.add(number_plane_scaled_y) """ def __init__( self, - x_range: Sequence[float] - | None = ( + x_range: Sequence[float] | None = ( -config["frame_x_radius"], config["frame_x_radius"], 1, ), - y_range: Sequence[float] - | None = ( + y_range: Sequence[float] | None = ( -config["frame_y_radius"], config["frame_y_radius"], 1, ), x_length: float | None = None, y_length: float | None = None, - background_line_style: dict | None = None, - faded_line_style: dict | None = None, + background_line_style: dict[str, Any] | None = None, + faded_line_style: dict[str, Any] | None = None, faded_line_ratio: int = 1, make_smooth_after_applying_functions: bool = True, - **kwargs, + **kwargs: dict[str, Any], ): - # configs self.axis_config = { "stroke_width": 2, @@ -2316,7 +2783,7 @@ def __init__( self._init_background_lines() - def _init_background_lines(self): + def _init_background_lines(self) -> None: """Will init all the lines of NumberPlanes (faded or not)""" if self.faded_line_style is None: style = dict(self.background_line_style) @@ -2401,7 +2868,6 @@ def _get_lines_parallel_to_axis( The first (i.e the non-faded lines parallel to `axis_parallel_to`) and second (i.e the faded lines parallel to `axis_parallel_to`) sets of lines, respectively. """ - line = Line(axis_parallel_to.get_start(), axis_parallel_to.get_end()) if ratio_faded_lines == 0: # don't show faded lines ratio_faded_lines = 1 # i.e. set ratio to 1 @@ -2422,27 +2888,28 @@ def _get_lines_parallel_to_axis( # min/max used in case range does not include 0. i.e. if (2,6): # the range becomes (0,4), not (0,6). ranges = ( - np.arange(0, min(x_max - x_min, x_max), step), - np.arange(0, max(x_min - x_max, x_min), -step), + [0], + np.arange(step, min(x_max - x_min, x_max), step), + np.arange(-step, max(x_min - x_max, x_min), -step), ) for inputs in ranges: for k, x in enumerate(inputs): new_line = line.copy() new_line.shift(unit_vector_axis_perp_to * x) - if k % ratio_faded_lines == 0: + if (k + 1) % ratio_faded_lines == 0: lines1.add(new_line) else: lines2.add(new_line) return lines1, lines2 - def get_vector(self, coords: Sequence[float], **kwargs): + def get_vector(self, coords: Sequence[ManimFloat], **kwargs: Any) -> Arrow: kwargs["buff"] = 0 return Arrow( self.coords_to_point(0, 0), self.coords_to_point(*coords), **kwargs ) - def prepare_for_nonlinear_transform(self, num_inserted_curves: int = 50): + def prepare_for_nonlinear_transform(self, num_inserted_curves: int = 50) -> Self: for mob in self.family_members_with_points(): num_curves = mob.get_num_curves() if num_inserted_curves > num_curves: @@ -2536,13 +3003,13 @@ def __init__( azimuth_direction: str = "CCW", azimuth_label_buff: float = SMALL_BUFF, azimuth_label_font_size: float = 24, - radius_config: dict | None = None, - background_line_style: dict | None = None, - faded_line_style: dict | None = None, + radius_config: dict[str, Any] | None = None, + background_line_style: dict[str, Any] | None = None, + faded_line_style: dict[str, Any] | None = None, faded_line_ratio: int = 1, make_smooth_after_applying_functions: bool = True, - **kwargs, - ): + **kwargs: Any, + ) -> None: # error catching if azimuth_units in ["PI radians", "TAU radians", "degrees", "gradians", None]: self.azimuth_units = azimuth_units @@ -2613,7 +3080,7 @@ def __init__( self._init_background_lines() - def _init_background_lines(self): + def _init_background_lines(self) -> None: """Will init all the lines of NumberPlanes (faded or not)""" if self.faded_line_style is None: style = dict(self.background_line_style) @@ -2693,13 +3160,13 @@ def get_axes(self) -> VGroup: """ return self.axes - def get_vector(self, coords, **kwargs): + def get_vector(self, coords: Sequence[ManimFloat], **kwargs: Any) -> Arrow: kwargs["buff"] = 0 return Arrow( self.coords_to_point(0, 0), self.coords_to_point(*coords), **kwargs ) - def prepare_for_nonlinear_transform(self, num_inserted_curves=50): + def prepare_for_nonlinear_transform(self, num_inserted_curves: int = 50) -> Self: for mob in self.family_members_with_points(): num_curves = mob.get_num_curves() if num_inserted_curves > num_curves: @@ -2710,7 +3177,7 @@ def get_coordinate_labels( self, r_values: Iterable[float] | None = None, a_values: Iterable[float] | None = None, - **kwargs, + **kwargs: Any, ) -> VDict: """Gets labels for the coordinates @@ -2768,7 +3235,7 @@ def get_coordinate_labels( elif self.azimuth_units == "degrees": a_tex = [ MathTex( - f'{360 * i["label"]:g}' + r"^{\circ}", + f"{360 * i['label']:g}" + r"^{\circ}", font_size=self.azimuth_label_font_size, ).next_to( i["point"], @@ -2781,7 +3248,7 @@ def get_coordinate_labels( elif self.azimuth_units == "gradians": a_tex = [ MathTex( - f'{400 * i["label"]:g}' + r"^{g}", + f"{400 * i['label']:g}" + r"^{g}", font_size=self.azimuth_label_font_size, ).next_to( i["point"], @@ -2794,7 +3261,7 @@ def get_coordinate_labels( elif self.azimuth_units is None: a_tex = [ MathTex( - f'{i["label"]:g}', + f"{i['label']:g}", font_size=self.azimuth_label_font_size, ).next_to( i["point"], @@ -2812,7 +3279,7 @@ def add_coordinates( self, r_values: Iterable[float] | None = None, a_values: Iterable[float] | None = None, - ): + ) -> Self: """Adds the coordinates. Parameters @@ -2825,7 +3292,7 @@ def add_coordinates( self.add(self.get_coordinate_labels(r_values, a_values)) return self - def get_radian_label(self, number, font_size=24, **kwargs): + def get_radian_label(self, number, font_size: float = 24, **kwargs: Any) -> MathTex: constant_label = {"PI radians": r"\pi", "TAU radians": r"\tau"}[ self.azimuth_units ] @@ -2894,7 +3361,7 @@ def construct(self): """ - def __init__(self, **kwargs): + def __init__(self, **kwargs: Any) -> None: super().__init__( **kwargs, ) @@ -2912,7 +3379,6 @@ def number_to_point(self, number: float | complex) -> np.ndarray: np.ndarray The point on the plane. """ - number = complex(number) return self.coords_to_point(number.real, number.imag) @@ -2920,7 +3386,7 @@ def n2p(self, number: float | complex) -> np.ndarray: """Abbreviation for :meth:`number_to_point`.""" return self.number_to_point(number) - def point_to_number(self, point: Sequence[float]) -> complex: + def point_to_number(self, point: Point3DLike) -> complex: """Accepts a point and returns a complex number equivalent to that point on the plane. Parameters @@ -2933,11 +3399,10 @@ def point_to_number(self, point: Sequence[float]) -> complex: complex A complex number consisting of real and imaginary components. """ - x, y = self.point_to_coords(point) return complex(x, y) - def p2n(self, point: Sequence[float]) -> complex: + def p2n(self, point: Point3DLike) -> complex: """Abbreviation for :meth:`point_to_number`.""" return self.point_to_number(point) @@ -2955,7 +3420,7 @@ def _get_default_coordinate_values(self) -> list[float | complex]: return [*x_numbers, *y_numbers] def get_coordinate_labels( - self, *numbers: Iterable[float | complex], **kwargs + self, *numbers: Iterable[float | complex], **kwargs: Any ) -> VGroup: """Generates the :class:`~.DecimalNumber` mobjects for the coordinates of the plane. @@ -2971,7 +3436,6 @@ def get_coordinate_labels( :class:`~.VGroup` A :class:`~.VGroup` containing the positioned label mobjects. """ - # TODO: Make this work the same as coord_sys.add_coordinates() if len(numbers) == 0: numbers = self._get_default_coordinate_values() @@ -2990,7 +3454,9 @@ def get_coordinate_labels( self.coordinate_labels.add(number_mob) return self.coordinate_labels - def add_coordinates(self, *numbers: Iterable[float | complex], **kwargs): + def add_coordinates( + self, *numbers: Iterable[float | complex], **kwargs: Any + ) -> Self: """Adds the labels produced from :meth:`~.NumberPlane.get_coordinate_labels` to the plane. Parameters @@ -3000,6 +3466,5 @@ def add_coordinates(self, *numbers: Iterable[float | complex], **kwargs): kwargs Additional arguments to be passed to :meth:`~.NumberLine.get_number_mobject`, i.e. :class:`~.DecimalNumber`. """ - self.add(self.get_coordinate_labels(*numbers, **kwargs)) return self diff --git a/manim/mobject/graphing/functions.py b/manim/mobject/graphing/functions.py index e937420570..83c48b1092 100644 --- a/manim/mobject/graphing/functions.py +++ b/manim/mobject/graphing/functions.py @@ -5,7 +5,8 @@ __all__ = ["ParametricFunction", "FunctionGraph", "ImplicitFunction"] -from typing import Callable, Iterable, Sequence +from collections.abc import Iterable, Sequence +from typing import TYPE_CHECKING, Callable import numpy as np from isosurfaces import plot_isoline @@ -14,6 +15,12 @@ from manim.mobject.graphing.scale import LinearBase, _ScaleBase from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL from manim.mobject.types.vectorized_mobject import VMobject + +if TYPE_CHECKING: + from typing_extensions import Self + + from manim.typing import Point3D, Point3DLike + from manim.utils.color import YELLOW @@ -23,14 +30,19 @@ class ParametricFunction(VMobject, metaclass=ConvertToOpenGL): Parameters ---------- function - The function to be plotted in the form of ``(lambda x: x**2)`` + The function to be plotted in the form of ``(lambda t: (x(t), y(t), z(t)))`` t_range - Determines the length that the function spans. By default ``[0, 1]`` + Determines the length that the function spans in the form of (t_min, t_max, step=0.01). By default ``[0, 1]`` scaling Scaling class applied to the points of the function. Default of :class:`~.LinearBase`. use_smoothing Whether to interpolate between the points of the function after they have been created. (Will have odd behaviour with a low number of points) + use_vectorized + Whether to pass in the generated t value array to the function as ``[t_0, t_1, ...]``. + Only use this if your function supports it. Output should be a numpy array + of shape ``[[x_0, x_1, ...], [y_0, y_1, ...], [z_0, z_1, ...]]`` but ``z`` can + also be 0 if the Axes is 2D discontinuities Values of t at which the function experiences discontinuity. dt @@ -44,10 +56,10 @@ class ParametricFunction(VMobject, metaclass=ConvertToOpenGL): class PlotParametricFunction(Scene): def func(self, t): - return np.array((np.sin(2 * t), np.sin(3 * t), 0)) + return (np.sin(2 * t), np.sin(3 * t), 0) def construct(self): - func = ParametricFunction(self.func, t_range = np.array([0, TAU]), fill_opacity=0).set_color(RED) + func = ParametricFunction(self.func, t_range = (0, TAU), fill_opacity=0).set_color(RED) self.add(func.scale(3)) .. manim:: ThreeDParametricSpring @@ -56,11 +68,11 @@ def construct(self): class ThreeDParametricSpring(ThreeDScene): def construct(self): curve1 = ParametricFunction( - lambda u: np.array([ + lambda u: ( 1.2 * np.cos(u), 1.2 * np.sin(u), u * 0.05 - ]), color=RED, t_range = np.array([-3*TAU, 5*TAU, 0.01]) + ), color=RED, t_range = (-3*TAU, 5*TAU, 0.01) ).set_shade_in_3d(True) axes = ThreeDAxes() self.add(axes, curve1) @@ -92,36 +104,40 @@ def construct(self): def __init__( self, - function: Callable[[float, float], float], - t_range: Sequence[float] | None = None, + function: Callable[[float], Point3DLike], + t_range: tuple[float, float] | tuple[float, float, float] = (0, 1), scaling: _ScaleBase = LinearBase(), dt: float = 1e-8, discontinuities: Iterable[float] | None = None, use_smoothing: bool = True, + use_vectorized: bool = False, **kwargs, ): - self.function = function - t_range = [0, 1, 0.01] if t_range is None else t_range + def internal_parametric_function(t: float) -> Point3D: + """Wrap ``function``'s output inside a NumPy array.""" + return np.asarray(function(t)) + + self.function = internal_parametric_function if len(t_range) == 2: - t_range = np.array([*t_range, 0.01]) + t_range = (*t_range, 0.01) self.scaling = scaling self.dt = dt self.discontinuities = discontinuities self.use_smoothing = use_smoothing + self.use_vectorized = use_vectorized self.t_min, self.t_max, self.t_step = t_range super().__init__(**kwargs) - def get_function(self): + def get_function(self) -> Callable[[float], Point3D]: return self.function - def get_point_from_function(self, t): + def get_point_from_function(self, t: float) -> Point3D: return self.function(t) - def generate_points(self): - + def generate_points(self) -> Self: if self.discontinuities is not None: discontinuities = filter( lambda t: self.t_min <= t <= self.t_max, @@ -147,7 +163,15 @@ def generate_points(self): self.scaling.function(t2), ], ) - points = np.array([self.function(t) for t in t_range]) + + if self.use_vectorized: + x, y, z = self.function(t_range) + if not isinstance(z, np.ndarray): + z = np.zeros_like(x) + points = np.stack([x, y, z], axis=1) + else: + points = np.array([self.function(t) for t in t_range]) + self.start_new_path(points[0]) self.add_points_as_corners(points[1:]) if self.use_smoothing: @@ -188,7 +212,6 @@ def construct(self): """ def __init__(self, function, x_range=None, color=YELLOW, **kwargs): - if x_range is None: x_range = np.array([-config["frame_x_radius"], config["frame_x_radius"]]) diff --git a/manim/mobject/graphing/number_line.py b/manim/mobject/graphing/number_line.py index c7676a6b23..017fac5bcb 100644 --- a/manim/mobject/graphing/number_line.py +++ b/manim/mobject/graphing/number_line.py @@ -2,9 +2,18 @@ from __future__ import annotations +from manim.mobject.mobject import Mobject +from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject + __all__ = ["NumberLine", "UnitInterval"] -from typing import Iterable, Sequence + +from collections.abc import Iterable, Sequence +from typing import TYPE_CHECKING, Callable + +if TYPE_CHECKING: + from manim.mobject.geometry.tips import ArrowTip + from manim.typing import Point3DLike import numpy as np @@ -49,6 +58,10 @@ class NumberLine(Line): The width of the tip. tip_height The height of the tip. + tip_shape + The mobject class used to construct the tip, or ``None`` (the + default) for the default arrow tip. Passed classes have to inherit + from :class:`.ArrowTip`. include_numbers Whether to add numbers to the tick marks. The number of decimal places is determined by the step size, this default can be overridden by ``decimal_number_config``. @@ -138,8 +151,9 @@ def __init__( stroke_width: float = 2.0, # tip include_tip: bool = False, - tip_width: float = 0.25, - tip_height: float = 0.25, + tip_width: float = DEFAULT_ARROW_TIP_LENGTH, + tip_height: float = DEFAULT_ARROW_TIP_LENGTH, + tip_shape: type[ArrowTip] | None = None, # numbers/labels include_numbers: bool = False, font_size: float = 36, @@ -173,7 +187,7 @@ def __init__( "num_decimal_places": self._decimal_places_from_step(x_range[2]), } - # turn into into an np array to scale by just applying the function + # turn into a NumPy array to scale by just applying the function self.x_range = np.array(x_range, dtype=float) self.x_min, self.x_max, self.x_step = scaling.function(self.x_range) self.length = length @@ -217,7 +231,11 @@ def __init__( self.center() if self.include_tip: - self.add_tip() + self.add_tip( + tip_length=self.tip_height, + tip_width=self.tip_width, + tip_shape=tip_shape, + ) self.tip.set_stroke(self.stroke_color, self.stroke_width) if self.include_ticks: @@ -259,12 +277,14 @@ def rotate_about_number( def add_ticks(self): """Adds ticks to the number line. Ticks can be accessed after creation - via ``self.ticks``.""" + via ``self.ticks``. + """ ticks = VGroup() elongated_tick_size = self.tick_size * self.longer_tick_multiple + elongated_tick_offsets = self.numbers_with_elongated_ticks - self.x_min for x in self.get_tick_range(): size = self.tick_size - if x in self.numbers_with_elongated_ticks: + if np.any(np.isclose(x - self.x_min, elongated_tick_offsets)): size = elongated_tick_size ticks.add(self.get_tick(x, size)) self.add(ticks) @@ -324,24 +344,43 @@ def get_tick_range(self) -> np.ndarray: return self.scaling.function(tick_range) - def number_to_point(self, number: float) -> np.ndarray: + def number_to_point(self, number: float | np.ndarray) -> np.ndarray: """Accepts a value along the number line and returns a point with respect to the scene. + Equivalent to `NumberLine @ number` Parameters ---------- number - The value to be transformed into a coordinate. + The value to be transformed into a coordinate. Or a list of values. Returns ------- np.ndarray - A point with respect to the scene's coordinate system. + A point with respect to the scene's coordinate system. Or a list of points. + + Examples + -------- + + >>> from manim import NumberLine + >>> number_line = NumberLine() + >>> number_line.number_to_point(0) + array([0., 0., 0.]) + >>> number_line.number_to_point(1) + array([1., 0., 0.]) + >>> number_line @ 1 + array([1., 0., 0.]) + >>> number_line.number_to_point([1, 2, 3]) + array([[1., 0., 0.], + [2., 0., 0.], + [3., 0., 0.]]) """ - + number = np.asarray(number) + scalar = number.ndim == 0 number = self.scaling.inverse_function(number) - alpha = float(number - self.x_range[0]) / (self.x_range[1] - self.x_range[0]) - val = interpolate(self.get_start(), self.get_end(), alpha) + alphas = (number - self.x_range[0]) / (self.x_range[1] - self.x_range[0]) + alphas = float(alphas) if scalar else np.vstack(alphas) + val = interpolate(self.get_start(), self.get_end(), alphas) return val def point_to_number(self, point: Sequence[float]) -> float: @@ -357,13 +396,27 @@ def point_to_number(self, point: Sequence[float]) -> float: ------- float A float representing a value along the number line. + + Examples + -------- + + >>> from manim import NumberLine + >>> number_line = NumberLine() + >>> number_line.point_to_number((0, 0, 0)) + np.float64(0.0) + >>> number_line.point_to_number((1, 0, 0)) + np.float64(1.0) + >>> number_line.point_to_number([[0.5, 0, 0], [1, 0, 0], [1.5, 0, 0]]) + array([0.5, 1. , 1.5]) + """ + point = np.asarray(point) start, end = self.get_start_and_end() unit_vect = normalize(end - start) proportion = np.dot(point - start, unit_vect) / np.dot(end - start, unit_vect) return interpolate(self.x_min, self.x_max, proportion) - def n2p(self, number: float) -> np.ndarray: + def n2p(self, number: float | np.ndarray) -> np.ndarray: """Abbreviation for :meth:`~.NumberLine.number_to_point`.""" return self.number_to_point(number) @@ -429,7 +482,7 @@ def get_number_mobject( num_mob.next_to(self.number_to_point(x), direction=direction, buff=buff) if x < 0 and self.label_direction[0] == 0: # Align without the minus sign - num_mob.shift(num_mob[0].get_width() * LEFT / 2) + num_mob.shift(num_mob[0].width * LEFT / 2) return num_mob def get_number_mobjects(self, *numbers, **kwargs) -> VGroup: @@ -528,24 +581,21 @@ def add_labels( AttributeError If the label does not have a ``font_size`` attribute, an ``AttributeError`` is raised. """ - direction = self.label_direction if direction is None else direction buff = self.line_to_number_buff if buff is None else buff font_size = self.font_size if font_size is None else font_size - label_constructor = ( - self.label_constructor if label_constructor is None else label_constructor - ) + if label_constructor is None: + label_constructor = self.label_constructor labels = VGroup() for x, label in dict_values.items(): - # TODO: remove this check and ability to call # this method via CoordinateSystem.add_coordinates() # must be explicitly called - if isinstance(label, str) and self.label_constructor is MathTex: + if isinstance(label, str) and label_constructor is MathTex: label = Tex(label) else: - label = self._create_label_tex(label) + label = self._create_label_tex(label, label_constructor) if hasattr(label, "font_size"): label.font_size = font_size @@ -559,28 +609,36 @@ def add_labels( return self def _create_label_tex( - self, label_tex: str | float | VMobject, **kwargs + self, + label_tex: str | float | VMobject, + label_constructor: Callable | None = None, + **kwargs, ) -> VMobject: """Checks if the label is a :class:`~.VMobject`, otherwise, creates a - label according to the ``label_constructor``. + label by passing ``label_tex`` to ``label_constructor``. Parameters ---------- label_tex - The label to be compared against the above types. + The label for which a mobject should be created. If the label already + is a mobject, no new mobject is created. label_constructor - The VMobject class used to construct the label. + Optional. A class or function returning a mobject when + passing ``label_tex`` as an argument. If ``None`` is passed + (the default), the label constructor from the :attr:`.label_constructor` + attribute is used. Returns ------- :class:`~.VMobject` The label. """ - - if isinstance(label_tex, VMobject): + if label_constructor is None: + label_constructor = self.label_constructor + if isinstance(label_tex, (VMobject, OpenGLVMobject)): return label_tex else: - return self.label_constructor(label_tex, **kwargs) + return label_constructor(label_tex, **kwargs) @staticmethod def _decimal_places_from_step(step) -> int: @@ -589,6 +647,14 @@ def _decimal_places_from_step(step) -> int: return 0 return len(step.split(".")[-1]) + def __matmul__(self, other: float): + return self.n2p(other) + + def __rmatmul__(self, other: Point3DLike | Mobject): + if isinstance(other, Mobject): + other = other.get_center() + return self.p2n(other) + class UnitInterval(NumberLine): def __init__( diff --git a/manim/mobject/graphing/probability.py b/manim/mobject/graphing/probability.py index 477b561bec..24134c0a7a 100644 --- a/manim/mobject/graphing/probability.py +++ b/manim/mobject/graphing/probability.py @@ -5,12 +5,11 @@ __all__ = ["SampleSpace", "BarChart"] -from typing import Iterable, Sequence +from collections.abc import Iterable, MutableSequence, Sequence import numpy as np -from colour import Color -from manim import config +from manim import config, logger from manim.constants import * from manim.mobject.geometry.polygram import Rectangle from manim.mobject.graphing.coordinate_systems import Axes @@ -26,6 +25,7 @@ LIGHT_GREY, MAROON_B, YELLOW, + ParsableManimColor, color_gradient, ) from manim.utils.iterables import tuplify @@ -34,7 +34,8 @@ class SampleSpace(Rectangle): - """ + """A mobject representing a twodimensional rectangular + sampling space. Examples -------- @@ -192,9 +193,9 @@ class BarChart(Axes): Parameters ---------- values - An iterable of values that determines the height of each bar. Accepts negative values. + A sequence of values that determines the height of each bar. Accepts negative values. bar_names - An iterable of names for each bar. Does not have to match the length of ``values``. + A sequence of names for each bar. Does not have to match the length of ``values``. y_range The y_axis range of values. If ``None``, the range will be calculated based on the min/max of ``values`` and the step will be calculated based on ``y_length``. @@ -204,7 +205,7 @@ class BarChart(Axes): y_length The length of the y-axis. bar_colors - The color for the bars. Accepts a single color or an iterable of colors. + The color for the bars. Accepts a sequence of colors (can contain just one item). If the length of``bar_colors`` does not match that of ``values``, intermediate colors will be automatically determined. bar_width @@ -237,14 +238,12 @@ def construct(self): def __init__( self, - values: Iterable[float], - bar_names: Iterable[str] | None = None, + values: MutableSequence[float], + bar_names: Sequence[str] | None = None, y_range: Sequence[float] | None = None, x_length: float | None = None, - y_length: float | None = config.frame_height - 4, - bar_colors: str - | Iterable[str] - | None = [ + y_length: float | None = None, + bar_colors: Iterable[str] = [ "#003f5c", "#58508d", "#bc5090", @@ -256,6 +255,13 @@ def __init__( bar_stroke_width: float = 3, **kwargs, ): + if isinstance(bar_colors, str): + logger.warning( + "Passing a string to `bar_colors` has been deprecated since v0.15.2 and will be removed after v0.17.0, the parameter must be a list. " + ) + bar_colors = list(bar_colors) + + y_length = y_length if y_length is not None else config.frame_height - 4 self.values = values self.bar_names = bar_names @@ -272,6 +278,7 @@ def __init__( max(0, max(self.values)), round(max(self.values) / y_length, 2), ] + elif len(y_range) == 2: y_range = [*y_range, round(max(self.values) / y_length, 2)] @@ -283,9 +290,9 @@ def __init__( (x_axis_config,), (kwargs.pop("x_axis_config", None),) ) - self.bars = None - self.x_labels = None - self.bar_labels = None + self.bars: VGroup = VGroup() + self.x_labels: VGroup | None = None + self.bar_labels: VGroup | None = None super().__init__( x_range=x_range, @@ -304,14 +311,23 @@ def __init__( self.y_axis.add_numbers() + def _update_colors(self): + """Initialize the colors of the bars of the chart. + + Sets the color of ``self.bars`` via ``self.bar_colors``. + + Primarily used when the bars are initialized with ``self._add_bars`` + or updated via ``self.change_bar_values``. + """ + self.bars.set_color_by_gradient(*self.bar_colors) + def _add_x_axis_labels(self): - """Essentially ``:meth:~.NumberLine.add_labels``, but differs in that + """Essentially :meth`:~.NumberLine.add_labels`, but differs in that the direction of the label with respect to the x_axis changes to UP or DOWN depending on the value. UP for negative values and DOWN for positive values. """ - val_range = np.arange( 0.5, len(self.bar_names), 1 ) # 0.5 shifted so that labels are centered, not on ticks @@ -321,10 +337,7 @@ def _add_x_axis_labels(self): for i, (value, bar_name) in enumerate(zip(val_range, self.bar_names)): # to accommodate negative bars, the label may need to be # below or above the x_axis depending on the value of the bar - if self.values[i] < 0: - direction = UP - else: - direction = DOWN + direction = UP if self.values[i] < 0 else DOWN bar_name_label = self.x_axis.label_constructor(bar_name) bar_name_label.font_size = self.x_axis.font_size @@ -339,35 +352,53 @@ def _add_x_axis_labels(self): self.x_axis.labels = labels self.x_axis.add(labels) - def _add_bars(self): - self.bars = VGroup() + def _create_bar(self, bar_number: int, value: float) -> Rectangle: + """Creates a positioned bar on the chart. - for i, value in enumerate(self.values): - bar_h = abs(self.c2p(0, value)[1] - self.c2p(0, 0)[1]) - bar_w = self.c2p(self.bar_width, 0)[0] - self.c2p(0, 0)[0] - bar = Rectangle( - height=bar_h, - width=bar_w, - stroke_width=self.bar_stroke_width, - fill_opacity=self.bar_fill_opacity, - ) + Parameters + ---------- + bar_number + Determines the x-position of the bar. + value + The value that determines the height of the bar. + + Returns + ------- + Rectangle + A positioned rectangle representing a bar on the chart. + """ + # bar measurements relative to the axis + + # distance from between the y-axis and the top of the bar + bar_h = abs(self.c2p(0, value)[1] - self.c2p(0, 0)[1]) + # width of the bar + bar_w = self.c2p(self.bar_width, 0)[0] - self.c2p(0, 0)[0] + + bar = Rectangle( + height=bar_h, + width=bar_w, + stroke_width=self.bar_stroke_width, + fill_opacity=self.bar_fill_opacity, + ) - pos = UP if (value >= 0) else DOWN - bar.next_to(self.c2p(i + 0.5, 0), pos, buff=0) - self.bars.add(bar) - if isinstance(self.bar_colors, str): - self.bars.set_color_by_gradient(self.bar_colors) - else: - self.bars.set_color_by_gradient(*self.bar_colors) + pos = UP if (value >= 0) else DOWN + bar.next_to(self.c2p(bar_number + 0.5, 0), pos, buff=0) + return bar + + def _add_bars(self) -> None: + for i, value in enumerate(self.values): + tmp_bar = self._create_bar(bar_number=i, value=value) + self.bars.add(tmp_bar) + self._update_colors() self.add_to_back(self.bars) def get_bar_labels( self, - color: Color | None = None, + color: ParsableManimColor | None = None, font_size: float = 24, buff: float = MED_SMALL_BUFF, - label_constructor: VMobject = Tex, + label_constructor: type[VMobject] = Tex, ): """Annotates each bar with its corresponding value. Use ``self.bar_labels`` to access the labels after creation. @@ -398,7 +429,6 @@ def construct(self): self.add(chart, c_bar_lbls) """ - bar_labels = VGroup() for bar, value in zip(self.bars, self.values): bar_lbl = label_constructor(str(value)) @@ -416,7 +446,7 @@ def construct(self): return bar_labels - def change_bar_values(self, values: Iterable[float]): + def change_bar_values(self, values: Iterable[float], update_colors: bool = True): """Updates the height of the bars of the chart. Parameters @@ -424,6 +454,8 @@ def change_bar_values(self, values: Iterable[float]): values The values that will be used to update the height of the bars. Does not have to match the number of bars. + update_colors + Whether to re-initalize the colors of the bars based on ``self.bar_colors``. Examples -------- @@ -444,7 +476,6 @@ def construct(self): chart.change_bar_values(list(reversed(values))) self.add(chart.get_bar_labels(font_size=24)) """ - for i, (bar, value) in enumerate(zip(self.bars, values)): chart_val = self.values[i] @@ -455,10 +486,10 @@ def construct(self): bar_lim = bar.get_top() aligned_edge = UP - try: + # check if the bar has height + if chart_val != 0: quotient = value / chart_val if quotient < 0: - aligned_edge = UP if chart_val > 0 else DOWN # if the bar is already positive, then we now want to move it @@ -468,11 +499,17 @@ def construct(self): # if already negative, then we move the bottom edge of the bar # to the location of the previous top - bar.stretch_to_fit_height(quotient * bar.height) + bar.stretch_to_fit_height(abs(quotient) * bar.height) - except ZeroDivisionError: - bar.height = 0 + else: + # create a new bar since the current one has a height of zero (doesn't exist) + temp_bar = self._create_bar(i, value) + self.bars.remove(bar) + self.bars.insert(i, temp_bar) bar.move_to(bar_lim, aligned_edge) + if update_colors: + self._update_colors() + self.values[: len(values)] = values diff --git a/manim/mobject/graphing/scale.py b/manim/mobject/graphing/scale.py index 2aaae7a5a6..78ffa2308b 100644 --- a/manim/mobject/graphing/scale.py +++ b/manim/mobject/graphing/scale.py @@ -1,7 +1,10 @@ from __future__ import annotations import math -from typing import TYPE_CHECKING, Any, Iterable +from collections.abc import Iterable +from typing import TYPE_CHECKING, Any + +import numpy as np __all__ = ["LogBase", "LinearBase"] @@ -12,15 +15,15 @@ class _ScaleBase: - """Scale baseclass for graphing/functions.""" + """Scale baseclass for graphing/functions. + + Parameters + ---------- + custom_labels + Whether to create custom labels when plotted on a :class:`~.NumberLine`. + """ def __init__(self, custom_labels: bool = False): - """ - Parameters - ---------- - custom_labels - Whether to create custom labels when plotted on a :class:`~.NumberLine`. - """ self.custom_labels = custom_labels def function(self, value: float) -> float: @@ -87,7 +90,6 @@ def __init__(self, scale_factor: float = 1.0): scale_factor The slope of the linear function, by default 1.0 """ - super().__init__() self.scale_factor = scale_factor @@ -120,9 +122,9 @@ def __init__(self, base: float = 10, custom_labels: bool = True): ---------- base The base of the log, by default 10. - custom_labels : bool, optional + custom_labels For use with :class:`~.Axes`: - Whetherer or not to include ``LaTeX`` axis labels, by default True. + Whether or not to include ``LaTeX`` axis labels, by default True. Examples -------- @@ -141,11 +143,20 @@ def function(self, value: float) -> float: def inverse_function(self, value: float) -> float: """Inverse of ``function``. The value must be greater than 0""" - if value <= 0: + if isinstance(value, np.ndarray): + condition = value.any() <= 0 + + def func(value, base): + return np.log(value) / np.log(base) + else: + condition = value <= 0 + func = math.log + + if condition: raise ValueError( "log(0) is undefined. Make sure the value is in the domain of the function" ) - value = math.log(value, self.base) + value = func(value, self.base) return value def get_custom_labels( @@ -165,12 +176,11 @@ def get_custom_labels( base_config Additional arguments to be passed to :class:`~.Integer`. """ - # uses `format` syntax to control the number of decimal places. tex_labels = [ Integer( self.base, - unit="^{%s}" % (f"{self.inverse_function(i):.{unit_decimal_places}f}"), + unit="^{%s}" % (f"{self.inverse_function(i):.{unit_decimal_places}f}"), # noqa: UP031 **base_config, ) for i in val_range diff --git a/manim/mobject/logo.py b/manim/mobject/logo.py index 67339d47b9..6242a4c645 100644 --- a/manim/mobject/logo.py +++ b/manim/mobject/logo.py @@ -4,19 +4,100 @@ __all__ = ["ManimBanner"] +import svgelements as se + from manim.animation.updaters.update import UpdateFromAlphaFunc from manim.mobject.geometry.arc import Circle from manim.mobject.geometry.polygram import Square, Triangle -from manim.mobject.text.tex_mobject import MathTex, Tex +from .. import constants as cst from ..animation.animation import override_animation from ..animation.composition import AnimationGroup, Succession from ..animation.creation import Create, SpiralIn from ..animation.fading import FadeIn -from ..constants import DOWN, LEFT, ORIGIN, RIGHT, TAU, UP +from ..mobject.svg.svg_mobject import VMobjectFromSVGPath from ..mobject.types.vectorized_mobject import VGroup -from ..utils.rate_functions import ease_in_out_cubic, ease_out_sine, smooth -from ..utils.tex_templates import TexFontTemplates +from ..utils.rate_functions import ease_in_out_cubic, smooth + +MANIM_SVG_PATHS: list[se.Path] = [ + se.Path( # double stroke letter M + "M4.64259-2.092154L2.739726-6.625156C2.660025-6.824408 2.650062-6.824408 " + "2.381071-6.824408H.52802C.348692-6.824408 .199253-6.824408 .199253-6.645" + "081C.199253-6.475716 .37858-6.475716 .428394-6.475716C.547945-6.475716 ." + "816936-6.455791 1.036115-6.37609V-1.05604C1.036115-.846824 1.036115-.408" + "468 .358655-.348692C.169365-.328767 .169365-.18929 .169365-.179328C.1693" + "65 0 .328767 0 .508095 0H2.052304C2.231631 0 2.381071 0 2.381071-.179328" + "C2.381071-.268991 2.30137-.33873 2.221669-.348692C1.454545-.408468 1.454" + "545-.826899 1.454545-1.05604V-6.017435L1.464508-6.027397L3.895392-.20921" + "5C3.975093-.029888 4.044832 0 4.104608 0C4.224159 0 4.254047-.079701 4.3" + "03861-.199253L6.744707-6.027397L6.75467-6.017435V-1.05604C6.75467-.84682" + "4 6.75467-.408468 6.07721-.348692C5.88792-.328767 5.88792-.18929 5.88792" + "-.179328C5.88792 0 6.047323 0 6.22665 0H8.886675C9.066002 0 9.215442 0 9" + ".215442-.179328C9.215442-.268991 9.135741-.33873 9.05604-.348692C8.28891" + "7-.408468 8.288917-.826899 8.288917-1.05604V-5.768369C8.288917-5.977584 " + "8.288917-6.41594 8.966376-6.475716C9.066002-6.485679 9.155666-6.535492 9" + ".155666-6.645081C9.155666-6.824408 9.006227-6.824408 8.826899-6.824408H6" + ".90411C6.645081-6.824408 6.625156-6.824408 6.535492-6.615193L4.64259-2.0" + "92154ZM4.343711-1.912827C4.423412-1.743462 4.433375-1.733499 4.552927-1." + "693649L4.11457-.637609H4.094645L1.823163-6.057285C1.77335-6.1868 1.69364" + "9-6.356164 1.554172-6.475716H2.420922L4.343711-1.912827ZM1.334994-.34869" + "2H1.165629C1.185554-.37858 1.205479-.408468 1.225405-.428394C1.235367-.4" + "38356 1.235367-.448319 1.24533-.458281L1.334994-.348692ZM7.103362-6.4757" + "16H8.159402C7.940224-6.22665 7.940224-5.967621 7.940224-5.788294V-1.0361" + "15C7.940224-.856787 7.940224-.597758 8.169365-.348692H6.884184C7.103362-" + ".597758 7.103362-.856787 7.103362-1.036115V-6.475716Z" + ), + se.Path( # letter a + "M1.464508-4.024907C1.464508-4.234122 1.743462-4.393524 2.092154-4.393524" + "C2.669988-4.393524 2.929016-4.124533 2.929016-3.516812V-2.789539C1.77335" + "-2.440847 .249066-2.042341 .249066-.916563C.249066-.308842 .71731 .13947" + "7 1.354919 .139477C1.92279 .139477 2.381071-.059776 2.929016-.557908C3.0" + "38605-.049813 3.257783 .139477 3.745953 .139477C4.174346 .139477 4.48318" + "8-.019925 4.861768-.428394L4.712329-.637609L4.612702-.537983C4.582814-.5" + "08095 4.552927-.498132 4.503113-.498132C4.363636-.498132 4.293898-.58779" + "6 4.293898-.747198V-3.347447C4.293898-4.184309 3.536737-4.712329 2.32129" + "5-4.712329C1.195517-4.712329 .438356-4.204234 .438356-3.457036C.438356-3" + ".048568 .67746-2.799502 1.085928-2.799502C1.484433-2.799502 1.763387-3.0" + "38605 1.763387-3.377335C1.763387-3.676214 1.464508-3.88543 1.464508-4.02" + "4907ZM2.919054-.996264C2.650062-.687422 2.450809-.56787 2.211706-.56787C" + "1.912827-.56787 1.703611-.836862 1.703611-1.235367C1.703611-1.8132 2.122" + "042-2.231631 2.919054-2.440847V-.996264Z" + ), + se.Path( # letter n + "M2.948941-4.044832C3.297634-4.044832 3.466999-3.775841 3.466999-3.217933" + "V-.806974C3.466999-.438356 3.337484-.278954 2.998755-.239103V0H5.339975V" + "-.239103C4.951432-.268991 4.851806-.388543 4.851806-.806974V-3.307597C4." + "851806-4.164384 4.323786-4.712329 3.506849-4.712329C2.909091-4.712329 2." + "450809-4.433375 2.082192-3.845579V-4.592777H.179328V-4.353674C.617684-4." + "283935 .707347-4.184309 .707347-3.765878V-.836862C.707347-.418431 .62764" + "6-.328767 .179328-.239103V0H2.580324V-.239103C2.211706-.288917 2.092154-" + ".438356 2.092154-.806974V-3.466999C2.092154-3.576588 2.530511-4.044832 2" + ".948941-4.044832Z" + ), + se.Path( # letter i + "M2.15193-4.592777H.239103V-4.353674C.67746-4.26401 .767123-4.174346 .767" + "123-3.765878V-.836862C.767123-.428394 .697385-.348692 .239103-.239103V0H" + "2.6401V-.239103C2.291407-.288917 2.15193-.428394 2.15193-.806974V-4.5927" + "77ZM1.454545-6.884184C1.026152-6.884184 .67746-6.535492 .67746-6.117061C" + ".67746-5.668742 1.006227-5.339975 1.444583-5.339975S2.221669-5.668742 2." + "221669-6.107098C2.221669-6.535492 1.882939-6.884184 1.454545-6.884184Z" + ), + se.Path( # letter m + "M2.929016-4.044832C3.317559-4.044832 3.466999-3.815691 3.466999-3.217933" + "V-.806974C3.466999-.398506 3.35741-.268991 2.988792-.239103V0H5.32005V-." + "239103C4.971357-.278954 4.851806-.428394 4.851806-.806974V-3.466999C4.85" + "1806-3.576588 5.310087-4.044832 5.69863-4.044832C6.07721-4.044832 6.2266" + "5-3.805729 6.22665-3.217933V-.806974C6.22665-.388543 6.117061-.268991 5." + "738481-.239103V0H8.109589V-.239103C7.721046-.259029 7.611457-.37858 7.61" + "1457-.806974V-3.307597C7.611457-4.164384 7.083437-4.712329 6.266501-4.71" + "2329C5.69863-4.712329 5.32005-4.483188 4.801993-3.845579C4.503113-4.4732" + "25 4.154421-4.712329 3.526775-4.712329S2.440847-4.443337 2.062267-3.8455" + "79V-4.592777H.179328V-4.353674C.617684-4.293898 .707347-4.174346 .707347" + "-3.765878V-.836862C.707347-.428394 .617684-.318804 .179328-.239103V0H2.5" + "50436V-.239103C2.201743-.288917 2.092154-.428394 2.092154-.806974V-3.466" + "999C2.092154-3.58655 2.530511-4.044832 2.929016-4.044832Z" + ), +] class ManimBanner(VGroup): @@ -67,27 +148,32 @@ def __init__(self, dark_theme: bool = True): self.font_color = "#ece6e2" if dark_theme else "#343434" self.scale_factor = 1 - self.M = MathTex(r"\mathbb{M}").scale(7).set_color(self.font_color) - self.M.shift(2.25 * LEFT + 1.5 * UP) + self.M = VMobjectFromSVGPath(MANIM_SVG_PATHS[0]).flip(cst.RIGHT).center() + self.M.set(stroke_width=0).scale( + 7 * cst.DEFAULT_FONT_SIZE * cst.SCALE_FACTOR_PER_FONT_POINT + ) + self.M.set_fill(color=self.font_color, opacity=1).shift( + 2.25 * cst.LEFT + 1.5 * cst.UP + ) - self.circle = Circle(color=logo_green, fill_opacity=1).shift(LEFT) - self.square = Square(color=logo_blue, fill_opacity=1).shift(UP) - self.triangle = Triangle(color=logo_red, fill_opacity=1).shift(RIGHT) + self.circle = Circle(color=logo_green, fill_opacity=1).shift(cst.LEFT) + self.square = Square(color=logo_blue, fill_opacity=1).shift(cst.UP) + self.triangle = Triangle(color=logo_red, fill_opacity=1).shift(cst.RIGHT) self.shapes = VGroup(self.triangle, self.square, self.circle) self.add(self.shapes, self.M) - self.move_to(ORIGIN) + self.move_to(cst.ORIGIN) anim = VGroup() - for i, ch in enumerate("anim"): - tex = Tex( - "\\textbf{" + ch + "}", - tex_template=TexFontTemplates.gnu_freeserif_freesans, + for ind, path in enumerate(MANIM_SVG_PATHS[1:]): + tex = VMobjectFromSVGPath(path).flip(cst.RIGHT).center() + tex.set(stroke_width=0).scale( + cst.DEFAULT_FONT_SIZE * cst.SCALE_FACTOR_PER_FONT_POINT ) - if i != 0: + if ind > 0: tex.next_to(anim, buff=0.01) - tex.align_to(self.M, DOWN) + tex.align_to(self.M, cst.DOWN) anim.add(tex) - anim.set_color(self.font_color) + anim.set_fill(color=self.font_color, opacity=1) anim.height = m_height_over_anim_height * self.M.height # Note: "anim" is only shown in the expanded state @@ -128,7 +214,7 @@ def create(self, run_time: float = 2) -> AnimationGroup: An animation to be used in a :meth:`.Scene.play` call. """ return AnimationGroup( - SpiralIn(self.shapes), + SpiralIn(self.shapes, run_time=run_time), FadeIn(self.M, run_time=run_time / 2), lag_ratio=0.1, ) @@ -181,7 +267,7 @@ def construct(self): m_shape_offset = 6.25 * self.scale_factor shape_sliding_overshoot = self.scale_factor * 0.8 m_anim_buff = 0.06 - self.anim.next_to(self.M, buff=m_anim_buff).align_to(self.M, DOWN) + self.anim.next_to(self.M, buff=m_anim_buff).align_to(self.M, cst.DOWN) self.anim.set_opacity(0) self.shapes.save_state() m_clone = self.anim[-1].copy() @@ -193,7 +279,7 @@ def construct(self): def shift(vector): self.shapes.restore() - left_group.align_to(self.M.saved_state, LEFT) + left_group.align_to(self.M.saved_state, cst.LEFT) if direction == "right": self.shapes.shift(vector) elif direction == "center": @@ -203,13 +289,13 @@ def shift(vector): left_group.shift(-vector) def slide_and_uncover(mob, alpha): - shift(alpha * (m_shape_offset + shape_sliding_overshoot) * RIGHT) + shift(alpha * (m_shape_offset + shape_sliding_overshoot) * cst.RIGHT) # Add letters when they are covered for letter in mob.anim: if mob.square.get_center()[0] > letter.get_center()[0]: letter.set_opacity(1) - self.add(letter) + self.add_to_back(letter) # Finish animation if alpha == 1: @@ -225,7 +311,7 @@ def slide_back(mob, alpha): m_clone.move_to(mob.anim[-1]) mob.anim.set_opacity(1) - shift(alpha * shape_sliding_overshoot * LEFT) + shift(alpha * shape_sliding_overshoot * cst.LEFT) if alpha == 1: mob.remove(m_clone) diff --git a/manim/mobject/matrix.py b/manim/mobject/matrix.py index d190146666..673aba1877 100644 --- a/manim/mobject/matrix.py +++ b/manim/mobject/matrix.py @@ -15,8 +15,8 @@ def construct(self): m2 = DecimalMatrix( [[3.456, 2.122], [33.2244, 12.33]], element_to_mobject_config={"num_decimal_places": 2}, - left_bracket="\\{", - right_bracket="\\}") + left_bracket=r"\{", + right_bracket=r"\}") m3 = MobjectMatrix( [[Circle().scale(0.3), Square().scale(0.3)], [MathTex("\\pi").scale(2), Star().scale(0.3)]], @@ -40,10 +40,11 @@ def construct(self): import itertools as it -from typing import Iterable, Sequence +from collections.abc import Iterable, Sequence import numpy as np +from manim.mobject.mobject import Mobject from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL from manim.mobject.text.numbers import DecimalNumber, Integer from manim.mobject.text.tex_mobject import MathTex, Tex @@ -71,7 +72,40 @@ def matrix_to_mobject(matrix): class Matrix(VMobject, metaclass=ConvertToOpenGL): - """A mobject that displays a matrix on the screen. + r"""A mobject that displays a matrix on the screen. + + Parameters + ---------- + matrix + A numpy 2d array or list of lists. + v_buff + Vertical distance between elements, by default 0.8. + h_buff + Horizontal distance between elements, by default 1.3. + bracket_h_buff + Distance of the brackets from the matrix, by default ``MED_SMALL_BUFF``. + bracket_v_buff + Height of the brackets, by default ``MED_SMALL_BUFF``. + add_background_rectangles_to_entries + ``True`` if should add backgraound rectangles to entries, by default ``False``. + include_background_rectangle + ``True`` if should include background rectangle, by default ``False``. + element_to_mobject + The mobject class used to construct the elements, by default :class:`~.MathTex`. + element_to_mobject_config + Additional arguments to be passed to the constructor in ``element_to_mobject``, + by default ``{}``. + element_alignment_corner + The corner to which elements are aligned, by default ``DR``. + left_bracket + The left bracket type, by default ``"["``. + right_bracket + The right bracket type, by default ``"]"``. + stretch_brackets + ``True`` if should stretch the brackets to fit the height of matrix contents, by default ``True``. + bracket_config + Additional arguments to be passed to :class:`~.MathTex` when constructing + the brackets. Examples -------- @@ -84,22 +118,22 @@ class Matrix(VMobject, metaclass=ConvertToOpenGL): class MatrixExamples(Scene): def construct(self): - m0 = Matrix([[2, "\\pi"], [-1, 1]]) + m0 = Matrix([[2, r"\pi"], [-1, 1]]) m1 = Matrix([[2, 0, 4], [-1, 1, 5]], v_buff=1.3, h_buff=0.8, bracket_h_buff=SMALL_BUFF, bracket_v_buff=SMALL_BUFF, - left_bracket="\\{", - right_bracket="\\}") + left_bracket=r"\{", + right_bracket=r"\}") m1.add(SurroundingRectangle(m1.get_columns()[1])) m2 = Matrix([[2, 1], [-1, 3]], element_alignment_corner=UL, left_bracket="(", right_bracket=")") m3 = Matrix([[2, 1], [-1, 3]], - left_bracket="\\\\langle", - right_bracket="\\\\rangle") + left_bracket=r"\langle", + right_bracket=r"\rangle") m4 = Matrix([[2, 1], [-1, 3]], ).set_column_colors(RED, GREEN) m5 = Matrix([[2, 1], [-1, 3]], @@ -141,44 +175,10 @@ def __init__( element_alignment_corner: Sequence[float] = DR, left_bracket: str = "[", right_bracket: str = "]", + stretch_brackets: bool = True, bracket_config: dict = {}, **kwargs, ): - """ - - Parameters - ---------- - matrix - A numpy 2d array or list of lists. - v_buff - Vertical distance between elements, by default 0.8. - h_buff - Horizontal distance between elements, by default 1.3. - bracket_h_buff - Distance of the brackets from the matrix, by default ``MED_SMALL_BUFF``. - bracket_v_buff - Height of the brackets, by default ``MED_SMALL_BUFF``. - add_background_rectangles_to_entries - ``True`` if should add backgraound rectangles to entries, by default ``False``. - include_background_rectangle - ``True`` if should include background rectangle, by default ``False``. - element_to_mobject - The mobject class used to construct the elements, by default :class:`~.MathTex`. - element_to_mobject_config - Additional arguments to be passed to the constructor in ``element_to_mobject``, - by default ``{}``. - element_alignment_corner - The corner to which elements are aligned, by default ``DR``. - left_bracket - The left bracket type, by default ``"["``. - right_bracket - The right bracket type, by default ``"]"``. - bracket_config - Additional arguments to be passed to :class:`~.MathTex` when constructing - the brackets. - - """ - self.v_buff = v_buff self.h_buff = h_buff self.bracket_h_buff = bracket_h_buff @@ -190,6 +190,7 @@ def __init__( self.element_alignment_corner = element_alignment_corner self.left_bracket = left_bracket self.right_bracket = right_bracket + self.stretch_brackets = stretch_brackets super().__init__(**kwargs) mob_matrix = self._matrix_to_mob_matrix(matrix) self._organize_mob_matrix(mob_matrix) @@ -223,16 +224,16 @@ def _organize_mob_matrix(self, matrix): ) return self - def _add_brackets(self, left="[", right="]", **kwargs): + def _add_brackets(self, left: str = "[", right: str = "]", **kwargs): """Adds the brackets to the Matrix mobject. See Latex document for various bracket types. Parameters ---------- - left : :class:`str`, optional + left the left bracket, by default "[" - right : :class:`str`, optional + right the right bracket, by default "]" Returns @@ -240,19 +241,45 @@ def _add_brackets(self, left="[", right="]", **kwargs): :class:`Matrix` The current matrix object (self). """ + # Height per row of LaTeX array with default settings + BRACKET_HEIGHT = 0.5977 - bracket_pair = MathTex(left, right, **kwargs) - bracket_pair.scale(2) - bracket_pair.stretch_to_fit_height(self.height + 2 * self.bracket_v_buff) - l_bracket, r_bracket = bracket_pair.split() + n = int((self.height) / BRACKET_HEIGHT) + 1 + empty_tex_array = "".join( + [ + r"\begin{array}{c}", + *n * [r"\quad \\"], + r"\end{array}", + ] + ) + tex_left = "".join( + [ + r"\left" + left, + empty_tex_array, + r"\right.", + ] + ) + tex_right = "".join( + [ + r"\left.", + empty_tex_array, + r"\right" + right, + ] + ) + l_bracket = MathTex(tex_left, **kwargs) + r_bracket = MathTex(tex_right, **kwargs) + + bracket_pair = VGroup(l_bracket, r_bracket) + if self.stretch_brackets: + bracket_pair.stretch_to_fit_height(self.height + 2 * self.bracket_v_buff) l_bracket.next_to(self, LEFT, self.bracket_h_buff) r_bracket.next_to(self, RIGHT, self.bracket_h_buff) + self.brackets = bracket_pair self.add(l_bracket, r_bracket) - self.brackets = VGroup(l_bracket, r_bracket) return self def get_columns(self): - """Return columns of the matrix as VGroups. + r"""Return columns of the matrix as VGroups. Returns -------- @@ -267,11 +294,10 @@ def get_columns(self): class GetColumnsExample(Scene): def construct(self): - m0 = Matrix([["\\pi", 3], [1, 5]]) + m0 = Matrix([[r"\pi", 3], [1, 5]]) m0.add(SurroundingRectangle(m0.get_columns()[1])) self.add(m0) """ - return VGroup( *( VGroup(*(row[i] for row in self.mob_matrix)) @@ -279,12 +305,12 @@ def construct(self): ) ) - def set_column_colors(self, *colors): - """Set individual colors for each columns of the matrix. + def set_column_colors(self, *colors: str): + r"""Set individual colors for each columns of the matrix. Parameters ---------- - colors : :class:`str` + colors The list of colors; each color specified corresponds to a column. Returns @@ -310,7 +336,7 @@ def construct(self): return self def get_rows(self): - """Return rows of the matrix as VGroups. + r"""Return rows of the matrix as VGroups. Returns -------- @@ -331,12 +357,12 @@ def construct(self): """ return VGroup(*(VGroup(*row) for row in self.mob_matrix)) - def set_row_colors(self, *colors): - """Set individual colors for each row of the matrix. + def set_row_colors(self, *colors: str): + r"""Set individual colors for each row of the matrix. Parameters ---------- - colors : :class:`str` + colors The list of colors; each color specified corresponds to a row. Returns @@ -410,7 +436,7 @@ def construct(self): return self.elements def get_brackets(self): - """Return the bracket mobjects. + r"""Return the bracket mobjects. Returns -------- @@ -436,7 +462,7 @@ def construct(self): class DecimalMatrix(Matrix): - """A mobject that displays a matrix with decimal entries on the screen. + r"""A mobject that displays a matrix with decimal entries on the screen. Examples -------- @@ -456,9 +482,9 @@ def construct(self): def __init__( self, - matrix, - element_to_mobject=DecimalNumber, - element_to_mobject_config={"num_decimal_places": 1}, + matrix: Iterable, + element_to_mobject: Mobject = DecimalNumber, + element_to_mobject_config: dict[str, Mobject] = {"num_decimal_places": 1}, **kwargs, ): """ @@ -466,11 +492,11 @@ def __init__( Parameters ---------- - matrix : :class:`typing.Iterable` + matrix A numpy 2d array or list of lists - element_to_mobject : :class:`~.Mobject`, optional + element_to_mobject Mobject to use, by default DecimalNumber - element_to_mobject_config : Dict[:class:`str`, :class:`~.Mobject`], optional + element_to_mobject_config Config for the desired mobject, by default {"num_decimal_places": 1} """ super().__init__( @@ -499,22 +525,24 @@ def construct(self): self.add(m0) """ - def __init__(self, matrix, element_to_mobject=Integer, **kwargs): + def __init__( + self, matrix: Iterable, element_to_mobject: Mobject = Integer, **kwargs + ): """ Will round if there are decimal entries in the matrix. Parameters ---------- - matrix : :class:`typing.Iterable` + matrix A numpy 2d array or list of lists - element_to_mobject : :class:`~.Mobject`, optional + element_to_mobject Mobject to use, by default Integer """ super().__init__(matrix, element_to_mobject=element_to_mobject, **kwargs) class MobjectMatrix(Matrix): - """A mobject that displays a matrix of mobject entries on the screen. + r"""A mobject that displays a matrix of mobject entries on the screen. Examples -------- @@ -537,25 +565,25 @@ def __init__(self, matrix, element_to_mobject=lambda m: m, **kwargs): def get_det_text( - matrix, - determinant=None, - background_rect=False, - initial_scale_factor=2, + matrix: Matrix, + determinant: int | str | None = None, + background_rect: bool = False, + initial_scale_factor: float = 2, ): r"""Helper function to create determinant. Parameters ---------- - matrix : :class:`~.Matrix` + matrix The matrix whose determinant is to be created - determinant : :class:`int|str` + determinant The value of the determinant of the matrix - background_rect : :class:`bool` + background_rect The background rectangle - initial_scale_factor : :class:`float` + initial_scale_factor The scale of the text `det` w.r.t the matrix Returns diff --git a/manim/mobject/mobject.py b/manim/mobject/mobject.py index b2ababb994..6ad3ece777 100644 --- a/manim/mobject/mobject.py +++ b/manim/mobject/mobject.py @@ -1,62 +1,67 @@ """Base classes for objects that can be displayed.""" +from __future__ import annotations __all__ = ["Mobject", "Group", "override_animate"] import copy +import inspect import itertools as it +import math import operator as op import random import sys import types import warnings +from collections.abc import Iterable from functools import partialmethod, reduce -from math import ceil from pathlib import Path -from typing import ( - TYPE_CHECKING, - Callable, - Dict, - Iterable, - List, - Optional, - Sequence, - Tuple, - Type, - TypeVar, - Union, -) +from typing import TYPE_CHECKING import numpy as np -from colour import Color from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL -from .. import config +from .. import config, logger from ..constants import * from ..utils.color import ( BLACK, WHITE, YELLOW_C, - Colors, + ManimColor, + ParsableManimColor, color_gradient, interpolate_color, ) from ..utils.exceptions import MultiAnimationOverrideException from ..utils.iterables import list_update, remove_list_redundancies from ..utils.paths import straight_path -from ..utils.simple_functions import get_parameters from ..utils.space_ops import angle_between_vectors, normalize, rotation_matrix -# TODO: Explain array_attrs - -Updater = Union[Callable[["Mobject"], None], Callable[["Mobject", float], None]] -T = TypeVar("T", bound="Mobject") - if TYPE_CHECKING: + from typing import Any, Callable, Literal + + from typing_extensions import Self, TypeAlias + + from manim.typing import ( + FunctionOverride, + MappingFunction, + MultiMappingFunction, + PathFuncType, + PixelArray, + Point3D, + Point3DLike, + Point3DLike_Array, + Vector3D, + ) + from ..animation.animation import Animation + TimeBasedUpdater: TypeAlias = Callable[["Mobject", float], object] + NonTimeBasedUpdater: TypeAlias = Callable[["Mobject"], object] + Updater: TypeAlias = NonTimeBasedUpdater | TimeBasedUpdater + class Mobject: """Mathematical Object: base class for objects that can be displayed on screen. @@ -81,36 +86,100 @@ class Mobject: animation_overrides = {} @classmethod - def __init_subclass__(cls, **kwargs): + def __init_subclass__(cls, **kwargs) -> None: super().__init_subclass__(**kwargs) - cls.animation_overrides: Dict[ - Type["Animation"], - Callable[["Mobject"], "Animation"], + cls.animation_overrides: dict[ + type[Animation], + FunctionOverride, ] = {} cls._add_intrinsic_animation_overrides() cls._original__init__ = cls.__init__ - def __init__(self, color=WHITE, name=None, dim=3, target=None, z_index=0): + def __init__( + self, + color: ParsableManimColor | list[ParsableManimColor] = WHITE, + name: str | None = None, + dim: int = 3, + target=None, + z_index: float = 0, + ) -> None: self.name = self.__class__.__name__ if name is None else name self.dim = dim self.target = target self.z_index = z_index self.point_hash = None self.submobjects = [] - self.updaters = [] + self.updaters: list[Updater] = [] self.updating_suspended = False - self.color = Color(color) if color else None + self.color = ManimColor.parse(color) self.reset_points() self.generate_points() self.init_colors() + def _assert_valid_submobjects(self, submobjects: Iterable[Mobject]) -> Self: + """Check that all submobjects are actually instances of + :class:`Mobject`, and that none of them is ``self`` (a + :class:`Mobject` cannot contain itself). + + This is an auxiliary function called when adding Mobjects to the + :attr:`submobjects` list. + + This function is intended to be overridden by subclasses such as + :class:`VMobject`, which should assert that only other VMobjects + may be added into it. + + Parameters + ---------- + submobjects + The list containing values to validate. + + Returns + ------- + :class:`Mobject` + The Mobject itself. + + Raises + ------ + TypeError + If any of the values in `submobjects` is not a :class:`Mobject`. + ValueError + If there was an attempt to add a :class:`Mobject` as its own + submobject. + """ + return self._assert_valid_submobjects_internal(submobjects, Mobject) + + def _assert_valid_submobjects_internal( + self, submobjects: list[Mobject], mob_class: type[Mobject] + ) -> Self: + for i, submob in enumerate(submobjects): + if not isinstance(submob, mob_class): + error_message = ( + f"Only values of type {mob_class.__name__} can be added " + f"as submobjects of {type(self).__name__}, but the value " + f"{submob} (at index {i}) is of type " + f"{type(submob).__name__}." + ) + # Intended for subclasses such as VMobject, which + # cannot have regular Mobjects as submobjects + if isinstance(submob, Mobject): + error_message += ( + " You can try adding this value into a Group instead." + ) + raise TypeError(error_message) + if submob is self: + raise ValueError( + f"Cannot add {type(self).__name__} as a submobject of " + f"itself (at index {i})." + ) + return self + @classmethod def animation_override_for( cls, - animation_class: Type["Animation"], - ) -> "Optional[Callable[[Mobject, ...], Animation]]": + animation_class: type[Animation], + ) -> FunctionOverride | None: """Returns the function defining a specific animation override for this class. Parameters @@ -130,7 +199,7 @@ def animation_override_for( return None @classmethod - def _add_intrinsic_animation_overrides(cls): + def _add_intrinsic_animation_overrides(cls) -> None: """Initializes animation overrides marked with the :func:`~.override_animation` decorator. """ @@ -147,9 +216,9 @@ def _add_intrinsic_animation_overrides(cls): @classmethod def add_animation_override( cls, - animation_class: Type["Animation"], - override_func: "Callable[[Mobject, ...], Animation]", - ): + animation_class: type[Animation], + override_func: FunctionOverride, + ) -> None: """Add an animation override. This does not apply to subclasses. @@ -160,7 +229,7 @@ def add_animation_override( The animation type to be overridden override_func The function returning an animation replacing the default animation. It gets - passed the parameters given to the animnation constructor. + passed the parameters given to the animation constructor. Raises ------ @@ -178,7 +247,7 @@ def add_animation_override( ) @classmethod - def set_default(cls, **kwargs): + def set_default(cls, **kwargs) -> None: """Sets the default values of keyword arguments. If this method is called without any additional keyword @@ -201,10 +270,10 @@ def set_default(cls, **kwargs): >>> from manim import Square, GREEN >>> Square.set_default(color=GREEN, fill_opacity=0.25) >>> s = Square(); s.color, s.fill_opacity - (, 0.25) + (ManimColor('#83C167'), 0.25) >>> Square.set_default() >>> s = Square(); s.color, s.fill_opacity - (, 0.0) + (ManimColor('#FFFFFF'), 0.0) .. manim:: ChangedDefaultTextcolor :save_last_frame: @@ -226,7 +295,7 @@ def construct(self): cls.__init__ = cls._original__init__ @property - def animate(self): + def animate(self) -> _AnimationBuilder | Self: """Used to animate the application of any method of :code:`self`. Any method called on :code:`animate` is converted to an animation of applying @@ -249,7 +318,9 @@ def animate(self): :: - self.play(my_mobject.animate.shift(RIGHT), my_mobject.animate.rotate(PI)) + self.play( + my_mobject.animate.shift(RIGHT), my_mobject.animate.rotate(PI) + ) make use of method chaining. @@ -323,7 +394,7 @@ def construct(self): """ return _AnimationBuilder(self) - def __deepcopy__(self, clone_from_id): + def __deepcopy__(self, clone_from_id) -> Self: cls = self.__class__ result = cls.__new__(cls) clone_from_id[id(self)] = result @@ -332,33 +403,28 @@ def __deepcopy__(self, clone_from_id): result.original_id = str(id(self)) return result - def __repr__(self): - if config["renderer"] == "opengl": - return super().__repr__() - else: - return str(self.name) + def __repr__(self) -> str: + return str(self.name) - def reset_points(self): + def reset_points(self) -> None: """Sets :attr:`points` to be an empty array.""" self.points = np.zeros((0, self.dim)) - def init_colors(self): + def init_colors(self) -> object: """Initializes the colors. Gets called upon creation. This is an empty method that can be implemented by subclasses. """ - pass - def generate_points(self): + def generate_points(self) -> object: """Initializes :attr:`points` and therefore the shape. Gets called upon creation. This is an empty method that can be implemented by subclasses. """ - pass - def add(self, *mobjects: "Mobject"): + def add(self, *mobjects: Mobject) -> Self: """Add mobjects as submobjects. The mobjects are added to :attr:`submobjects`. @@ -409,29 +475,68 @@ def add(self, *mobjects: "Mobject"): >>> len(outer.submobjects) 1 + Only Mobjects can be added:: + + >>> outer.add(3) + Traceback (most recent call last): + ... + TypeError: Only values of type Mobject can be added as submobjects of Mobject, but the value 3 (at index 0) is of type int. + Adding an object to itself raises an error:: >>> outer.add(outer) Traceback (most recent call last): ... - ValueError: Mobject cannot contain self + ValueError: Cannot add Mobject as a submobject of itself (at index 0). + + A given mobject cannot be added as a submobject + twice to some parent:: + + >>> parent = Mobject(name="parent") + >>> child = Mobject(name="child") + >>> parent.add(child, child) + [...] WARNING ... + parent + >>> parent.submobjects + [child] """ - for m in mobjects: - if not isinstance(m, Mobject): - raise TypeError("All submobjects must be of type Mobject") - if m is self: - raise ValueError("Mobject cannot contain self") - self.submobjects = list_update(self.submobjects, mobjects) + self._assert_valid_submobjects(mobjects) + unique_mobjects = remove_list_redundancies(mobjects) + if len(mobjects) != len(unique_mobjects): + logger.warning( + "Attempted adding some Mobject as a child more than once, " + "this is not possible. Repetitions are ignored.", + ) + + self.submobjects = list_update(self.submobjects, unique_mobjects) return self - def __add__(self, mobject): + def insert(self, index: int, mobject: Mobject) -> None: + """Inserts a mobject at a specific position into self.submobjects + + Effectively just calls ``self.submobjects.insert(index, mobject)``, + where ``self.submobjects`` is a list. + + Highly adapted from ``Mobject.add``. + + Parameters + ---------- + index + The index at which + mobject + The mobject to be inserted. + """ + self._assert_valid_submobjects([mobject]) + self.submobjects.insert(index, mobject) + + def __add__(self, mobject: Mobject): raise NotImplementedError - def __iadd__(self, mobject): + def __iadd__(self, mobject: Mobject): raise NotImplementedError - def add_to_back(self, *mobjects: "Mobject"): + def add_to_back(self, *mobjects: Mobject) -> Self: """Add all passed mobjects to the back of the submobjects. If :attr:`submobjects` already contains the given mobjects, they just get moved @@ -475,19 +580,13 @@ def add_to_back(self, *mobjects: "Mobject"): :meth:`add` """ - if self in mobjects: - raise ValueError("A mobject shouldn't contain itself") - - for mobject in mobjects: - if not isinstance(mobject, Mobject): - raise TypeError("All submobjects must be of type Mobject") - + self._assert_valid_submobjects(mobjects) self.remove(*mobjects) # dict.fromkeys() removes duplicates while maintaining order self.submobjects = list(dict.fromkeys(mobjects)) + self.submobjects return self - def remove(self, *mobjects: "Mobject"): + def remove(self, *mobjects: Mobject) -> Self: """Remove :attr:`submobjects`. The mobjects are removed from :attr:`submobjects`, if they exist. @@ -520,7 +619,7 @@ def __sub__(self, other): def __isub__(self, other): raise NotImplementedError - def set(self, **kwargs): + def set(self, **kwargs) -> Self: """Sets attributes. I.e. ``my_mobject.set(foo=1)`` applies ``my_mobject.foo = 1``. @@ -571,13 +670,12 @@ def set(self, **kwargs): >>> mob.foo 0 """ - for attr, value in kwargs.items(): setattr(self, attr, value) return self - def __getattr__(self, attr): + def __getattr__(self, attr: str) -> types.MethodType: # Add automatic compatibility layer # between properties and get_* and set_* # methods. @@ -625,7 +723,7 @@ def setter(self, value): raise AttributeError(f"{type(self).__name__} object has no attribute '{attr}'") @property - def width(self): + def width(self) -> float: """The width of the mobject. Returns @@ -653,16 +751,15 @@ def construct(self): :meth:`length_over_dim` """ - # Get the length across the X dimension return self.length_over_dim(0) @width.setter - def width(self, value): + def width(self, value: float): self.scale_to_fit_width(value) @property - def height(self): + def height(self) -> float: """The height of the mobject. Returns @@ -690,16 +787,15 @@ def construct(self): :meth:`length_over_dim` """ - # Get the length across the Y dimension return self.length_over_dim(1) @height.setter - def height(self, value): + def height(self, value: float): self.scale_to_fit_height(value) @property - def depth(self): + def depth(self) -> float: """The depth of the mobject. Returns @@ -711,25 +807,25 @@ def depth(self): :meth:`length_over_dim` """ - # Get the length across the Z dimension return self.length_over_dim(2) @depth.setter - def depth(self, value): + def depth(self, value: float): self.scale_to_fit_depth(value) - def get_array_attrs(self): + # Can't be staticmethod because of point_cloud_mobject.py + def get_array_attrs(self) -> list[Literal["points"]]: return ["points"] - def apply_over_attr_arrays(self, func): + def apply_over_attr_arrays(self, func: MultiMappingFunction) -> Self: for attr in self.get_array_attrs(): setattr(self, attr, func(getattr(self, attr))) return self # Displaying - def get_image(self, camera=None): + def get_image(self, camera=None) -> PixelArray: if camera is None: from ..camera.camera import Camera @@ -737,17 +833,18 @@ def get_image(self, camera=None): camera.capture_mobject(self) return camera.get_image() - def show(self, camera=None): + def show(self, camera=None) -> None: self.get_image(camera=camera).show() - def save_image(self, name=None): + def save_image(self, name: str | None = None) -> None: """Saves an image of only this :class:`Mobject` at its position to a png - file.""" + file. + """ self.get_image().save( Path(config.get_dir("video_dir")).joinpath((name or str(self)) + ".png"), ) - def copy(self: T) -> T: + def copy(self) -> Self: """Create and return an identical copy of the :class:`Mobject` including all :attr:`submobjects`. @@ -762,7 +859,7 @@ def copy(self: T) -> T: """ return copy.deepcopy(self) - def generate_target(self, use_deepcopy=False): + def generate_target(self, use_deepcopy: bool = False) -> Self: self.target = None # Prevent unbounded linear recursion if use_deepcopy: self.target = copy.deepcopy(self) @@ -772,7 +869,7 @@ def generate_target(self, use_deepcopy=False): # Updating - def update(self, dt: float = 0, recursive: bool = True): + def update(self, dt: float = 0, recursive: bool = True) -> Self: """Apply all updaters. Does nothing if updating is suspended. @@ -799,8 +896,7 @@ def update(self, dt: float = 0, recursive: bool = True): if self.updating_suspended: return self for updater in self.updaters: - parameters = get_parameters(updater) - if "dt" in parameters: + if "dt" in inspect.signature(updater).parameters: updater(self, dt) else: updater(self) @@ -809,7 +905,7 @@ def update(self, dt: float = 0, recursive: bool = True): submob.update(dt, recursive) return self - def get_time_based_updaters(self) -> List[Updater]: + def get_time_based_updaters(self) -> list[TimeBasedUpdater]: """Return all updaters using the ``dt`` parameter. The updaters use this parameter as the input for difference in time. @@ -825,14 +921,18 @@ def get_time_based_updaters(self) -> List[Updater]: :meth:`has_time_based_updater` """ - return [updater for updater in self.updaters if "dt" in get_parameters(updater)] + return [ + updater + for updater in self.updaters + if "dt" in inspect.signature(updater).parameters + ] def has_time_based_updater(self) -> bool: """Test if ``self`` has a time based updater. Returns ------- - class:`bool` + :class:`bool` ``True`` if at least one updater uses the ``dt`` parameter, ``False`` otherwise. @@ -841,9 +941,11 @@ def has_time_based_updater(self) -> bool: :meth:`get_time_based_updaters` """ - return any("dt" in get_parameters(updater) for updater in self.updaters) + return any( + "dt" in inspect.signature(updater).parameters for updater in self.updaters + ) - def get_updaters(self) -> List[Updater]: + def get_updaters(self) -> list[Updater]: """Return all updaters. Returns @@ -859,15 +961,15 @@ def get_updaters(self) -> List[Updater]: """ return self.updaters - def get_family_updaters(self): + def get_family_updaters(self) -> list[Updater]: return list(it.chain(*(sm.get_updaters() for sm in self.get_family()))) def add_updater( self, update_function: Updater, - index: Optional[int] = None, + index: int | None = None, call_updater: bool = False, - ): + ) -> Self: """Add an update function to this mobject. Update functions, or updaters in short, are functions that are applied to the @@ -915,11 +1017,11 @@ def dot_position(mobject): class DtUpdater(Scene): def construct(self): - line = Square() + square = Square() - #Let the line rotate 90° per second - line.add_updater(lambda mobject, dt: mobject.rotate(dt*90*DEGREES)) - self.add(line) + #Let the square rotate 90° per second + square.add_updater(lambda mobject, dt: mobject.rotate(dt*90*DEGREES)) + self.add(square) self.wait(2) See also @@ -928,16 +1030,19 @@ def construct(self): :meth:`remove_updater` :class:`~.UpdateFromFunc` """ - if index is None: self.updaters.append(update_function) else: self.updaters.insert(index, update_function) if call_updater: - update_function(self, 0) + parameters = inspect.signature(update_function).parameters + if "dt" in parameters: + update_function(self, 0) + else: + update_function(self) return self - def remove_updater(self, update_function: Updater): + def remove_updater(self, update_function: Updater) -> Self: """Remove an updater. If the same updater is applied multiple times, every instance gets removed. @@ -964,7 +1069,7 @@ def remove_updater(self, update_function: Updater): self.updaters.remove(update_function) return self - def clear_updaters(self, recursive: bool = True): + def clear_updaters(self, recursive: bool = True) -> Self: """Remove every updater. Parameters @@ -990,7 +1095,7 @@ def clear_updaters(self, recursive: bool = True): submob.clear_updaters() return self - def match_updaters(self, mobject: "Mobject"): + def match_updaters(self, mobject: Mobject) -> Self: """Match the updaters of the given mobject. Parameters @@ -1014,13 +1119,12 @@ def match_updaters(self, mobject: "Mobject"): :meth:`clear_updaters` """ - self.clear_updaters() for updater in mobject.get_updaters(): self.add_updater(updater) return self - def suspend_updating(self, recursive: bool = True): + def suspend_updating(self, recursive: bool = True) -> Self: """Disable updating from updaters and animations. @@ -1040,14 +1144,13 @@ def suspend_updating(self, recursive: bool = True): :meth:`add_updater` """ - self.updating_suspended = True if recursive: for submob in self.submobjects: submob.suspend_updating(recursive) return self - def resume_updating(self, recursive: bool = True): + def resume_updating(self, recursive: bool = True) -> Self: """Enable updating from updaters and animations. Parameters @@ -1075,7 +1178,7 @@ def resume_updating(self, recursive: bool = True): # Transforming operations - def apply_to_family(self, func: Callable[["Mobject"], None]): + def apply_to_family(self, func: Callable[[Mobject], None]) -> None: """Apply a function to ``self`` and every submobject with points recursively. Parameters @@ -1097,7 +1200,7 @@ def apply_to_family(self, func: Callable[["Mobject"], None]): for mob in self.family_members_with_points(): func(mob) - def shift(self, *vectors: np.ndarray): + def shift(self, *vectors: Vector3D) -> Self: """Shift by the given vectors. Parameters @@ -1115,7 +1218,6 @@ def shift(self, *vectors: np.ndarray): -------- :meth:`move_to` """ - total_vector = reduce(op.add, vectors) for mob in self.family_members_with_points(): mob.points = mob.points.astype("float") @@ -1123,7 +1225,7 @@ def shift(self, *vectors: np.ndarray): return self - def scale(self, scale_factor: float, **kwargs): + def scale(self, scale_factor: float, **kwargs) -> Self: r"""Scale the size by a factor. Default behavior is to scale about the center of the mobject. @@ -1169,17 +1271,17 @@ def construct(self): ) return self - def rotate_about_origin(self, angle, axis=OUT, axes=[]): + def rotate_about_origin(self, angle: float, axis: Vector3D = OUT, axes=[]) -> Self: """Rotates the :class:`~.Mobject` about the ORIGIN, which is at [0,0,0].""" return self.rotate(angle, axis, about_point=ORIGIN) def rotate( self, - angle, - axis=OUT, - about_point: Optional[Sequence[float]] = None, + angle: float, + axis: Vector3D = OUT, + about_point: Point3DLike | None = None, **kwargs, - ): + ) -> Self: """Rotates the :class:`~.Mobject` about a certain point.""" rot_matrix = rotation_matrix(angle, axis) self.apply_points_function_about_point( @@ -1187,7 +1289,7 @@ def rotate( ) return self - def flip(self, axis=UP, **kwargs): + def flip(self, axis: Vector3D = UP, **kwargs) -> Self: """Flips/Mirrors an mobject about its center. Examples @@ -1206,33 +1308,36 @@ def construct(self): """ return self.rotate(TAU / 2, axis, **kwargs) - def stretch(self, factor, dim, **kwargs): - def func(points): + def stretch(self, factor: float, dim: int, **kwargs) -> Self: + def func(points: Point3D_Array) -> Point3D_Array: points[:, dim] *= factor return points self.apply_points_function_about_point(func, **kwargs) return self - def apply_function(self, function, **kwargs): + def apply_function(self, function: MappingFunction, **kwargs) -> Self: # Default to applying matrix about the origin, not mobjects center if len(kwargs) == 0: kwargs["about_point"] = ORIGIN - self.apply_points_function_about_point( - lambda points: np.apply_along_axis(function, 1, points), **kwargs - ) + + def multi_mapping_function(points: Point3D_Array) -> Point3D_Array: + result: Point3D_Array = np.apply_along_axis(function, 1, points) + return result + + self.apply_points_function_about_point(multi_mapping_function, **kwargs) return self - def apply_function_to_position(self, function): + def apply_function_to_position(self, function: MappingFunction) -> Self: self.move_to(function(self.get_center())) return self - def apply_function_to_submobject_positions(self, function): + def apply_function_to_submobject_positions(self, function: MappingFunction) -> Self: for submob in self.submobjects: submob.apply_function_to_position(function) return self - def apply_matrix(self, matrix, **kwargs): + def apply_matrix(self, matrix, **kwargs) -> Self: # Default to applying matrix about the origin, not mobjects center if ("about_point" not in kwargs) and ("about_edge" not in kwargs): kwargs["about_point"] = ORIGIN @@ -1244,9 +1349,11 @@ def apply_matrix(self, matrix, **kwargs): ) return self - def apply_complex_function(self, function, **kwargs): + def apply_complex_function( + self, function: Callable[[complex], complex], **kwargs + ) -> Self: """Applies a complex function to a :class:`Mobject`. - The x and y coordinates correspond to the real and imaginary parts respectively. + The x and y Point3Ds correspond to the real and imaginary parts respectively. Example ------- @@ -1278,24 +1385,12 @@ def R3_func(point): return self.apply_function(R3_func) - def wag(self, direction=RIGHT, axis=DOWN, wag_factor=1.0): - for mob in self.family_members_with_points(): - alphas = np.dot(mob.points, np.transpose(axis)) - alphas -= min(alphas) - alphas /= max(alphas) - alphas = alphas**wag_factor - mob.points += np.dot( - alphas.reshape((len(alphas), 1)), - np.array(direction).reshape((1, mob.dim)), - ) - return self - - def reverse_points(self): + def reverse_points(self) -> Self: for mob in self.family_members_with_points(): mob.apply_over_attr_arrays(lambda arr: np.array(list(reversed(arr)))) return self - def repeat(self, count: int): + def repeat(self, count: int) -> Self: """This can make transition animations nicer""" def repeat_array(array): @@ -1309,12 +1404,13 @@ def repeat_array(array): # Note, much of these are now redundant with default behavior of # above methods + # TODO: name is inconsistent with OpenGLMobject.apply_points_function() def apply_points_function_about_point( self, - func, - about_point=None, - about_edge=None, - ): + func: MultiMappingFunction, + about_point: Point3DLike | None = None, + about_edge: Vector3D | None = None, + ) -> Self: if about_point is None: if about_edge is None: about_edge = ORIGIN @@ -1331,11 +1427,20 @@ def pose_at_angle(self, **kwargs): # Positioning methods - def center(self): + def center(self) -> Self: + """Moves the center of the mobject to the center of the scene. + + Returns + ------- + :class:`.Mobject` + The centered mobject. + """ self.shift(-self.get_center()) return self - def align_on_border(self, direction, buff=DEFAULT_MOBJECT_TO_EDGE_BUFFER): + def align_on_border( + self, direction: Vector3D, buff: float = DEFAULT_MOBJECT_TO_EDGE_BUFFER + ) -> Self: """Direction just needs to be a vector pointing towards side or corner in the 2d plane. """ @@ -1350,23 +1455,75 @@ def align_on_border(self, direction, buff=DEFAULT_MOBJECT_TO_EDGE_BUFFER): self.shift(shift_val) return self - def to_corner(self, corner=LEFT + DOWN, buff=DEFAULT_MOBJECT_TO_EDGE_BUFFER): + def to_corner( + self, corner: Vector3D = DL, buff: float = DEFAULT_MOBJECT_TO_EDGE_BUFFER + ) -> Self: + """Moves this :class:`~.Mobject` to the given corner of the screen. + + Returns + ------- + :class:`.Mobject` + The newly positioned mobject. + + Examples + -------- + + .. manim:: ToCornerExample + :save_last_frame: + + class ToCornerExample(Scene): + def construct(self): + c = Circle() + c.to_corner(UR) + t = Tex("To the corner!") + t2 = MathTex("x^3").shift(DOWN) + self.add(c,t,t2) + t.to_corner(DL, buff=0) + t2.to_corner(UL, buff=1.5) + """ return self.align_on_border(corner, buff) - def to_edge(self, edge=LEFT, buff=DEFAULT_MOBJECT_TO_EDGE_BUFFER): + def to_edge( + self, edge: Vector3D = LEFT, buff: float = DEFAULT_MOBJECT_TO_EDGE_BUFFER + ) -> Self: + """Moves this :class:`~.Mobject` to the given edge of the screen, + without affecting its position in the other dimension. + + Returns + ------- + :class:`.Mobject` + The newly positioned mobject. + + Examples + -------- + + .. manim:: ToEdgeExample + :save_last_frame: + + class ToEdgeExample(Scene): + def construct(self): + tex_top = Tex("I am at the top!") + tex_top.to_edge(UP) + tex_side = Tex("I am moving to the side!") + c = Circle().shift(2*DOWN) + self.add(tex_top, tex_side, c) + tex_side.to_edge(LEFT) + c.to_edge(RIGHT, buff=0) + + """ return self.align_on_border(edge, buff) def next_to( self, - mobject_or_point, - direction=RIGHT, - buff=DEFAULT_MOBJECT_TO_MOBJECT_BUFFER, - aligned_edge=ORIGIN, - submobject_to_align=None, - index_of_submobject_to_align=None, - coor_mask=np.array([1, 1, 1]), - ): - """Move this :class:`~.Mobject` next to another's :class:`~.Mobject` or coordinate. + mobject_or_point: Mobject | Point3DLike, + direction: Vector3D = RIGHT, + buff: float = DEFAULT_MOBJECT_TO_MOBJECT_BUFFER, + aligned_edge: Vector3D = ORIGIN, + submobject_to_align: Mobject | None = None, + index_of_submobject_to_align: int | None = None, + coor_mask: Vector3D = np.array([1, 1, 1]), + ) -> Self: + """Move this :class:`~.Mobject` next to another's :class:`~.Mobject` or Point3D. Examples -------- @@ -1405,7 +1562,7 @@ def construct(self): self.shift((target_point - point_to_align + buff * direction) * coor_mask) return self - def shift_onto_screen(self, **kwargs): + def shift_onto_screen(self, **kwargs) -> Self: space_lengths = [config["frame_x_radius"], config["frame_y_radius"]] for vect in UP, DOWN, LEFT, RIGHT: dim = np.argmax(np.abs(vect)) @@ -1423,14 +1580,14 @@ def is_off_screen(self): return True if self.get_bottom()[1] > config["frame_y_radius"]: return True - if self.get_top()[1] < -config["frame_y_radius"]: - return True - return False + return self.get_top()[1] < -config["frame_y_radius"] - def stretch_about_point(self, factor, dim, point): + def stretch_about_point(self, factor: float, dim: int, point: Point3DLike) -> Self: return self.stretch(factor, dim, about_point=point) - def rescale_to_fit(self, length, dim, stretch=False, **kwargs): + def rescale_to_fit( + self, length: float, dim: int, stretch: bool = False, **kwargs + ) -> Self: old_length = self.length_over_dim(dim) if old_length == 0: return self @@ -1440,7 +1597,7 @@ def rescale_to_fit(self, length, dim, stretch=False, **kwargs): self.scale(length / old_length, **kwargs) return self - def scale_to_fit_width(self, width, **kwargs): + def scale_to_fit_width(self, width: float, **kwargs) -> Self: """Scales the :class:`~.Mobject` to fit a width while keeping height/depth proportional. Returns @@ -1455,18 +1612,17 @@ def scale_to_fit_width(self, width, **kwargs): >>> from manim import * >>> sq = Square() >>> sq.height - 2.0 + np.float64(2.0) >>> sq.scale_to_fit_width(5) Square >>> sq.width - 5.0 + np.float64(5.0) >>> sq.height - 5.0 + np.float64(5.0) """ - return self.rescale_to_fit(width, 0, stretch=False, **kwargs) - def stretch_to_fit_width(self, width, **kwargs): + def stretch_to_fit_width(self, width: float, **kwargs) -> Self: """Stretches the :class:`~.Mobject` to fit a width, not keeping height/depth proportional. Returns @@ -1481,18 +1637,17 @@ def stretch_to_fit_width(self, width, **kwargs): >>> from manim import * >>> sq = Square() >>> sq.height - 2.0 + np.float64(2.0) >>> sq.stretch_to_fit_width(5) Square >>> sq.width - 5.0 + np.float64(5.0) >>> sq.height - 2.0 + np.float64(2.0) """ - return self.rescale_to_fit(width, 0, stretch=True, **kwargs) - def scale_to_fit_height(self, height, **kwargs): + def scale_to_fit_height(self, height: float, **kwargs) -> Self: """Scales the :class:`~.Mobject` to fit a height while keeping width/depth proportional. Returns @@ -1507,18 +1662,17 @@ def scale_to_fit_height(self, height, **kwargs): >>> from manim import * >>> sq = Square() >>> sq.width - 2.0 + np.float64(2.0) >>> sq.scale_to_fit_height(5) Square >>> sq.height - 5.0 + np.float64(5.0) >>> sq.width - 5.0 + np.float64(5.0) """ - return self.rescale_to_fit(height, 1, stretch=False, **kwargs) - def stretch_to_fit_height(self, height, **kwargs): + def stretch_to_fit_height(self, height: float, **kwargs) -> Self: """Stretches the :class:`~.Mobject` to fit a height, not keeping width/depth proportional. Returns @@ -1533,47 +1687,44 @@ def stretch_to_fit_height(self, height, **kwargs): >>> from manim import * >>> sq = Square() >>> sq.width - 2.0 + np.float64(2.0) >>> sq.stretch_to_fit_height(5) Square >>> sq.height - 5.0 + np.float64(5.0) >>> sq.width - 2.0 + np.float64(2.0) """ - return self.rescale_to_fit(height, 1, stretch=True, **kwargs) - def scale_to_fit_depth(self, depth, **kwargs): + def scale_to_fit_depth(self, depth: float, **kwargs) -> Self: """Scales the :class:`~.Mobject` to fit a depth while keeping width/height proportional.""" - return self.rescale_to_fit(depth, 2, stretch=False, **kwargs) - def stretch_to_fit_depth(self, depth, **kwargs): + def stretch_to_fit_depth(self, depth: float, **kwargs) -> Self: """Stretches the :class:`~.Mobject` to fit a depth, not keeping width/height proportional.""" - return self.rescale_to_fit(depth, 2, stretch=True, **kwargs) - def set_coord(self, value, dim, direction=ORIGIN): + def set_coord(self, value, dim: int, direction: Vector3D = ORIGIN) -> Self: curr = self.get_coord(dim, direction) shift_vect = np.zeros(self.dim) shift_vect[dim] = value - curr self.shift(shift_vect) return self - def set_x(self, x, direction=ORIGIN): + def set_x(self, x: float, direction: Vector3D = ORIGIN) -> Self: """Set x value of the center of the :class:`~.Mobject` (``int`` or ``float``)""" return self.set_coord(x, 0, direction) - def set_y(self, y, direction=ORIGIN): + def set_y(self, y: float, direction: Vector3D = ORIGIN) -> Self: """Set y value of the center of the :class:`~.Mobject` (``int`` or ``float``)""" return self.set_coord(y, 1, direction) - def set_z(self, z, direction=ORIGIN): + def set_z(self, z: float, direction: Vector3D = ORIGIN) -> Self: """Set z value of the center of the :class:`~.Mobject` (``int`` or ``float``)""" return self.set_coord(z, 2, direction) - def space_out_submobjects(self, factor=1.5, **kwargs): + def space_out_submobjects(self, factor: float = 1.5, **kwargs) -> Self: self.scale(factor, **kwargs) for submob in self.submobjects: submob.scale(1.0 / factor) @@ -1581,11 +1732,11 @@ def space_out_submobjects(self, factor=1.5, **kwargs): def move_to( self, - point_or_mobject, - aligned_edge=ORIGIN, - coor_mask=np.array([1, 1, 1]), - ): - """Move center of the :class:`~.Mobject` to certain coordinate.""" + point_or_mobject: Point3DLike | Mobject, + aligned_edge: Vector3D = ORIGIN, + coor_mask: Vector3D = np.array([1, 1, 1]), + ) -> Self: + """Move center of the :class:`~.Mobject` to certain Point3D.""" if isinstance(point_or_mobject, Mobject): target = point_or_mobject.get_critical_point(aligned_edge) else: @@ -1594,7 +1745,9 @@ def move_to( self.shift((target - point_to_align) * coor_mask) return self - def replace(self, mobject, dim_to_match=0, stretch=False): + def replace( + self, mobject: Mobject, dim_to_match: int = 0, stretch: bool = False + ) -> Self: if not mobject.get_num_points() and not mobject.submobjects: raise Warning("Attempting to replace mobject with no points") if stretch: @@ -1611,22 +1764,26 @@ def replace(self, mobject, dim_to_match=0, stretch=False): def surround( self, - mobject: "Mobject", - dim_to_match=0, - stretch=False, - buff=MED_SMALL_BUFF, - ): + mobject: Mobject, + dim_to_match: int = 0, + stretch: bool = False, + buff: float = MED_SMALL_BUFF, + ) -> Self: self.replace(mobject, dim_to_match, stretch) length = mobject.length_over_dim(dim_to_match) self.scale((length + buff) / length) return self - def put_start_and_end_on(self, start, end): + def put_start_and_end_on(self, start: Point3DLike, end: Point3DLike) -> Self: curr_start, curr_end = self.get_start_and_end() curr_vect = curr_end - curr_start if np.all(curr_vect == 0): - raise Exception("Cannot position endpoints of closed loop") - target_vect = np.array(end) - np.array(start) + # TODO: this looks broken. It makes self.points a Point3D instead + # of a Point3D_Array. However, modifying this breaks some tests + # where this is currently expected. + self.points = np.array(start) + return self + target_vect = np.asarray(end) - np.asarray(start) axis = ( normalize(np.cross(curr_vect, target_vect)) if np.linalg.norm(np.cross(curr_vect, target_vect)) != 0 @@ -1646,8 +1803,8 @@ def put_start_and_end_on(self, start, end): # Background rectangle def add_background_rectangle( - self, color: Optional[Colors] = None, opacity: float = 0.75, **kwargs - ): + self, color: ParsableManimColor | None = None, opacity: float = 0.75, **kwargs + ) -> Self: """Add a BackgroundRectangle as submobject. The BackgroundRectangle is added behind other submobjects. @@ -1675,7 +1832,6 @@ def add_background_rectangle( :class:`~.BackgroundRectangle` """ - # TODO, this does not behave well when the mobject has points, # since it gets displayed on top from manim.mobject.geometry.shape_matchers import BackgroundRectangle @@ -1686,19 +1842,21 @@ def add_background_rectangle( self.add_to_back(self.background_rectangle) return self - def add_background_rectangle_to_submobjects(self, **kwargs): + def add_background_rectangle_to_submobjects(self, **kwargs) -> Self: for submobject in self.submobjects: submobject.add_background_rectangle(**kwargs) return self - def add_background_rectangle_to_family_members_with_points(self, **kwargs): + def add_background_rectangle_to_family_members_with_points(self, **kwargs) -> Self: for mob in self.family_members_with_points(): mob.add_background_rectangle(**kwargs) return self # Color functions - def set_color(self, color: Color = YELLOW_C, family: bool = True): + def set_color( + self, color: ParsableManimColor = YELLOW_C, family: bool = True + ) -> Self: """Condition is function which takes in one arguments, (x, y, z). Here it just recurses to submobjects, but in subclasses this should be further implemented based on the the inner workings @@ -1707,20 +1865,30 @@ def set_color(self, color: Color = YELLOW_C, family: bool = True): if family: for submob in self.submobjects: submob.set_color(color, family=family) - self.color = Color(color) + + self.color = ManimColor.parse(color) return self - def set_color_by_gradient(self, *colors): + def set_color_by_gradient(self, *colors: ParsableManimColor) -> Self: + """ + Parameters + ---------- + colors + The colors to use for the gradient. Use like `set_color_by_gradient(RED, BLUE, GREEN)`. + + self.color = ManimColor.parse(color) + return self + """ self.set_submobject_colors_by_gradient(*colors) return self def set_colors_by_radial_gradient( self, - center=None, - radius=1, - inner_color=WHITE, - outer_color=BLACK, - ): + center: Point3DLike | None = None, + radius: float = 1, + inner_color: ParsableManimColor = WHITE, + outer_color: ParsableManimColor = BLACK, + ) -> Self: self.set_submobject_colors_by_radial_gradient( center, radius, @@ -1729,7 +1897,7 @@ def set_colors_by_radial_gradient( ) return self - def set_submobject_colors_by_gradient(self, *colors): + def set_submobject_colors_by_gradient(self, *colors: Iterable[ParsableManimColor]): if len(colors) == 0: raise ValueError("Need at least one color") elif len(colors) == 1: @@ -1744,11 +1912,11 @@ def set_submobject_colors_by_gradient(self, *colors): def set_submobject_colors_by_radial_gradient( self, - center=None, - radius=1, - inner_color=WHITE, - outer_color=BLACK, - ): + center: Point3DLike | None = None, + radius: float = 1, + inner_color: ParsableManimColor = WHITE, + outer_color: ParsableManimColor = BLACK, + ) -> Self: if center is None: center = self.get_center() @@ -1760,11 +1928,13 @@ def set_submobject_colors_by_radial_gradient( return self - def to_original_color(self): + def to_original_color(self) -> Self: self.set_color(self.color) return self - def fade_to(self, color, alpha, family=True): + def fade_to( + self, color: ParsableManimColor, alpha: float, family: bool = True + ) -> Self: if self.get_num_points() > 0: new_color = interpolate_color(self.get_color(), color, alpha) self.set_color(new_color, family=False) @@ -1773,19 +1943,29 @@ def fade_to(self, color, alpha, family=True): submob.fade_to(color, alpha) return self - def fade(self, darkness=0.5, family=True): + def fade(self, darkness: float = 0.5, family: bool = True) -> Self: if family: for submob in self.submobjects: submob.fade(darkness, family) return self - def get_color(self): - """Returns the color of the :class:`~.Mobject`""" + def get_color(self) -> ManimColor: + """Returns the color of the :class:`~.Mobject` + + Examples + -------- + :: + + >>> from manim import Square, RED + >>> Square(color=RED).get_color() == RED + True + + """ return self.color ## - def save_state(self): + def save_state(self) -> Self: """Save the current state (position, color & size). Can be restored with :meth:`~.Mobject.restore`.""" if hasattr(self, "saved_state"): # Prevent exponential growth of data @@ -1794,52 +1974,78 @@ def save_state(self): return self - def restore(self): + def restore(self) -> Self: """Restores the state that was previously saved with :meth:`~.Mobject.save_state`.""" if not hasattr(self, "saved_state") or self.save_state is None: raise Exception("Trying to restore without having saved") self.become(self.saved_state) return self - ## - - def reduce_across_dimension(self, points_func, reduce_func, dim): - points = self.get_all_points() - if points is None or len(points) == 0: - # Note, this default means things like empty VGroups - # will appear to have a center at [0, 0, 0] + def reduce_across_dimension(self, reduce_func: Callable, dim: int): + """Find the min or max value from a dimension across all points in this and submobjects.""" + assert dim >= 0 + assert dim <= 2 + if len(self.submobjects) == 0 and len(self.points) == 0: + # If we have no points and no submobjects, return 0 (e.g. center) return 0 - values = points_func(points[:, dim]) - return reduce_func(values) - def nonempty_submobjects(self): + # If we do not have points (but do have submobjects) + # use only the points from those. + if len(self.points) == 0: # noqa: SIM108 + rv = None + else: + # Otherwise, be sure to include our own points + rv = reduce_func(self.points[:, dim]) + # Recursively ask submobjects (if any) for the biggest/ + # smallest dimension they have and compare it to the return value. + for mobj in self.submobjects: + value = mobj.reduce_across_dimension(reduce_func, dim) + rv = value if rv is None else reduce_func([value, rv]) + return rv + + def nonempty_submobjects(self) -> list[Self]: return [ submob for submob in self.submobjects if len(submob.submobjects) != 0 or len(submob.points) != 0 ] - def get_merged_array(self, array_attr): + def get_merged_array(self, array_attr: str) -> np.ndarray: + """Return all of a given attribute from this mobject and all submobjects. + + May contain duplicates; the order is in a depth-first (pre-order) + traversal of the submobjects. + """ result = getattr(self, array_attr) for submob in self.submobjects: result = np.append(result, submob.get_merged_array(array_attr), axis=0) return result - def get_all_points(self): + def get_all_points(self) -> Point3D_Array: + """Return all points from this mobject and all submobjects. + + May contain duplicates; the order is in a depth-first (pre-order) + traversal of the submobjects. + """ return self.get_merged_array("points") # Getters - def get_points_defining_boundary(self): + def get_points_defining_boundary(self) -> Point3D_Array: return self.get_all_points() - def get_num_points(self): + def get_num_points(self) -> int: return len(self.points) - def get_extremum_along_dim(self, points=None, dim=0, key=0): - if points is None: - points = self.get_points_defining_boundary() - values = points[:, dim] + def get_extremum_along_dim( + self, points: Point3DLike_Array | None = None, dim: int = 0, key: int = 0 + ) -> float: + np_points: Point3D_Array = ( + self.get_points_defining_boundary() + if points is None + else np.asarray(points) + ) + values = np_points[:, dim] if key < 0: return np.min(values) elif key == 0: @@ -1847,14 +2053,14 @@ def get_extremum_along_dim(self, points=None, dim=0, key=0): else: return np.max(values) - def get_critical_point(self, direction): + def get_critical_point(self, direction: Vector3D) -> Point3D: """Picture a box bounding the :class:`~.Mobject`. Such a box has 9 'critical points': 4 corners, 4 edge center, the center. This returns one of them, along the given direction. :: - sample = Arc(start_angle=PI/7, angle = PI/5) + sample = Arc(start_angle=PI / 7, angle=PI / 5) # These are all equivalent max_y_1 = sample.get_top()[1] @@ -1876,28 +2082,28 @@ def get_critical_point(self, direction): # Pseudonyms for more general get_critical_point method - def get_edge_center(self, direction) -> np.ndarray: - """Get edge coordinates for certain direction.""" + def get_edge_center(self, direction: Vector3D) -> Point3D: + """Get edge Point3Ds for certain direction.""" return self.get_critical_point(direction) - def get_corner(self, direction) -> np.ndarray: - """Get corner coordinates for certain direction.""" + def get_corner(self, direction: Vector3D) -> Point3D: + """Get corner Point3Ds for certain direction.""" return self.get_critical_point(direction) - def get_center(self) -> np.ndarray: - """Get center coordinates""" + def get_center(self) -> Point3D: + """Get center Point3Ds""" return self.get_critical_point(np.zeros(self.dim)) - def get_center_of_mass(self): + def get_center_of_mass(self) -> Point3D: return np.apply_along_axis(np.mean, 0, self.get_all_points()) - def get_boundary_point(self, direction): + def get_boundary_point(self, direction: Vector3D) -> Point3D: all_points = self.get_points_defining_boundary() index = np.argmax(np.dot(all_points, np.array(direction).T)) return all_points[index] - def get_midpoint(self) -> np.ndarray: - """Get coordinates of the middle of the path that forms the :class:`~.Mobject`. + def get_midpoint(self) -> Point3D: + """Get Point3Ds of the middle of the path that forms the :class:`~.Mobject`. Examples -------- @@ -1919,75 +2125,74 @@ def construct(self): """ return self.point_from_proportion(0.5) - def get_top(self) -> np.ndarray: - """Get top coordinates of a box bounding the :class:`~.Mobject`""" + def get_top(self) -> Point3D: + """Get top Point3Ds of a box bounding the :class:`~.Mobject`""" return self.get_edge_center(UP) - def get_bottom(self) -> np.ndarray: - """Get bottom coordinates of a box bounding the :class:`~.Mobject`""" + def get_bottom(self) -> Point3D: + """Get bottom Point3Ds of a box bounding the :class:`~.Mobject`""" return self.get_edge_center(DOWN) - def get_right(self) -> np.ndarray: - """Get right coordinates of a box bounding the :class:`~.Mobject`""" + def get_right(self) -> Point3D: + """Get right Point3Ds of a box bounding the :class:`~.Mobject`""" return self.get_edge_center(RIGHT) - def get_left(self) -> np.ndarray: - """Get left coordinates of a box bounding the :class:`~.Mobject`""" + def get_left(self) -> Point3D: + """Get left Point3Ds of a box bounding the :class:`~.Mobject`""" return self.get_edge_center(LEFT) - def get_zenith(self) -> np.ndarray: - """Get zenith coordinates of a box bounding a 3D :class:`~.Mobject`.""" + def get_zenith(self) -> Point3D: + """Get zenith Point3Ds of a box bounding a 3D :class:`~.Mobject`.""" return self.get_edge_center(OUT) - def get_nadir(self) -> np.ndarray: - """Get nadir (opposite the zenith) coordinates of a box bounding a 3D :class:`~.Mobject`.""" + def get_nadir(self) -> Point3D: + """Get nadir (opposite the zenith) Point3Ds of a box bounding a 3D :class:`~.Mobject`.""" return self.get_edge_center(IN) - def length_over_dim(self, dim): + def length_over_dim(self, dim: int) -> float: """Measure the length of an :class:`~.Mobject` in a certain direction.""" return self.reduce_across_dimension( - np.max, - np.max, + max, dim, - ) - self.reduce_across_dimension(np.min, np.min, dim) + ) - self.reduce_across_dimension(min, dim) - def get_coord(self, dim, direction=ORIGIN): + def get_coord(self, dim: int, direction: Vector3D = ORIGIN): """Meant to generalize ``get_x``, ``get_y`` and ``get_z``""" return self.get_extremum_along_dim(dim=dim, key=direction[dim]) - def get_x(self, direction=ORIGIN) -> np.float64: - """Returns x coordinate of the center of the :class:`~.Mobject` as ``float``""" + def get_x(self, direction: Vector3D = ORIGIN) -> float: + """Returns x Point3D of the center of the :class:`~.Mobject` as ``float``""" return self.get_coord(0, direction) - def get_y(self, direction=ORIGIN) -> np.float64: - """Returns y coordinate of the center of the :class:`~.Mobject` as ``float``""" + def get_y(self, direction: Vector3D = ORIGIN) -> float: + """Returns y Point3D of the center of the :class:`~.Mobject` as ``float``""" return self.get_coord(1, direction) - def get_z(self, direction=ORIGIN) -> np.float64: - """Returns z coordinate of the center of the :class:`~.Mobject` as ``float``""" + def get_z(self, direction: Vector3D = ORIGIN) -> float: + """Returns z Point3D of the center of the :class:`~.Mobject` as ``float``""" return self.get_coord(2, direction) - def get_start(self): + def get_start(self) -> Point3D: """Returns the point, where the stroke that surrounds the :class:`~.Mobject` starts.""" self.throw_error_if_no_points() return np.array(self.points[0]) - def get_end(self): + def get_end(self) -> Point3D: """Returns the point, where the stroke that surrounds the :class:`~.Mobject` ends.""" self.throw_error_if_no_points() return np.array(self.points[-1]) - def get_start_and_end(self): + def get_start_and_end(self) -> tuple[Point3D, Point3D]: """Returns starting and ending point of a stroke as a ``tuple``.""" return self.get_start(), self.get_end() - def point_from_proportion(self, alpha): + def point_from_proportion(self, alpha: float) -> Point3D: raise NotImplementedError("Please override in a child class.") - def proportion_from_point(self, point): + def proportion_from_point(self, point: Point3DLike) -> float: raise NotImplementedError("Please override in a child class.") - def get_pieces(self, n_pieces): + def get_pieces(self, n_pieces: float) -> Group: template = self.copy() template.submobjects = [] alphas = np.linspace(0, 1, n_pieces + 1) @@ -1998,7 +2203,7 @@ def get_pieces(self, n_pieces): ) ) - def get_z_index_reference_point(self): + def get_z_index_reference_point(self) -> Point3D: # TODO, better place to define default z_index_group? z_index_group = getattr(self, "z_index_group", self) return z_index_group.get_center() @@ -2013,61 +2218,58 @@ def has_no_points(self) -> bool: # Match other mobject properties - def match_color(self, mobject: "Mobject"): + def match_color(self, mobject: Mobject) -> Self: """Match the color with the color of another :class:`~.Mobject`.""" return self.set_color(mobject.get_color()) - def match_dim_size(self, mobject: "Mobject", dim, **kwargs): + def match_dim_size(self, mobject: Mobject, dim: int, **kwargs) -> Self: """Match the specified dimension with the dimension of another :class:`~.Mobject`.""" return self.rescale_to_fit(mobject.length_over_dim(dim), dim, **kwargs) - def match_width(self, mobject: "Mobject", **kwargs): + def match_width(self, mobject: Mobject, **kwargs) -> Self: """Match the width with the width of another :class:`~.Mobject`.""" return self.match_dim_size(mobject, 0, **kwargs) - def match_height(self, mobject: "Mobject", **kwargs): + def match_height(self, mobject: Mobject, **kwargs) -> Self: """Match the height with the height of another :class:`~.Mobject`.""" return self.match_dim_size(mobject, 1, **kwargs) - def match_depth(self, mobject: "Mobject", **kwargs): + def match_depth(self, mobject: Mobject, **kwargs) -> Self: """Match the depth with the depth of another :class:`~.Mobject`.""" return self.match_dim_size(mobject, 2, **kwargs) - def match_coord(self, mobject: "Mobject", dim, direction=ORIGIN): - """Match the coordinates with the coordinates of another :class:`~.Mobject`.""" + def match_coord( + self, mobject: Mobject, dim: int, direction: Vector3D = ORIGIN + ) -> Self: + """Match the Point3Ds with the Point3Ds of another :class:`~.Mobject`.""" return self.set_coord( mobject.get_coord(dim, direction), dim=dim, direction=direction, ) - def match_x(self, mobject: "Mobject", direction=ORIGIN): + def match_x(self, mobject: Mobject, direction=ORIGIN) -> Self: """Match x coord. to the x coord. of another :class:`~.Mobject`.""" return self.match_coord(mobject, 0, direction) - def match_y(self, mobject: "Mobject", direction=ORIGIN): + def match_y(self, mobject: Mobject, direction=ORIGIN) -> Self: """Match y coord. to the x coord. of another :class:`~.Mobject`.""" return self.match_coord(mobject, 1, direction) - def match_z(self, mobject: "Mobject", direction=ORIGIN): + def match_z(self, mobject: Mobject, direction=ORIGIN) -> Self: """Match z coord. to the x coord. of another :class:`~.Mobject`.""" return self.match_coord(mobject, 2, direction) def align_to( self, - mobject_or_point: Union["Mobject", np.ndarray, List], - direction=ORIGIN, - alignment_vect=UP, - ): + mobject_or_point: Mobject | Point3DLike, + direction: Vector3D = ORIGIN, + ) -> Self: """Aligns mobject to another :class:`~.Mobject` in a certain direction. Examples: mob1.align_to(mob2, UP) moves mob1 vertically so that its top edge lines ups with mob2's top edge. - - mob1.align_to(mob2, alignment_vect = RIGHT) moves mob1 - horizontally so that it's center is directly above/below - the center of mob2 """ if isinstance(mobject_or_point, Mobject): point = mobject_or_point.get_critical_point(direction) @@ -2094,28 +2296,58 @@ def __iter__(self): def __len__(self): return len(self.split()) - def get_group_class(self): + def get_group_class(self) -> type[Group]: return Group - def split(self): + @staticmethod + def get_mobject_type_class() -> type[Mobject]: + """Return the base class of this mobject type.""" + return Mobject + + def split(self) -> list[Self]: result = [self] if len(self.points) > 0 else [] return result + self.submobjects - def get_family(self, recurse=True): - sub_families = list(map(Mobject.get_family, self.submobjects)) + def get_family(self, recurse: bool = True) -> list[Self]: + """Lists all mobjects in the hierarchy (family) of the given mobject, + including the mobject itself and all its submobjects recursively. + + Parameters + ---------- + recurse + Just for consistency with get_family method in OpenGLMobject. + + Returns + ------- + list + A list of mobjects in the family of the given mobject. + + Examples + -------- + :: + + >>> from manim import Square, Rectangle, VGroup, Group, Mobject, VMobject + >>> s, r, m, v = Square(), Rectangle(), Mobject(), VMobject() + >>> vg = VGroup(s, r) + >>> gr = Group(vg, m, v) + >>> gr.get_family() + [Group, VGroup(Square, Rectangle), Square, Rectangle, Mobject, VMobject] + + """ + sub_families = [x.get_family() for x in self.submobjects] all_mobjects = [self] + list(it.chain(*sub_families)) return remove_list_redundancies(all_mobjects) - def family_members_with_points(self): + def family_members_with_points(self) -> list[Self]: return [m for m in self.get_family() if m.get_num_points() > 0] def arrange( self, - direction: Sequence[float] = RIGHT, - buff=DEFAULT_MOBJECT_TO_MOBJECT_BUFFER, - center=True, + direction: Vector3D = RIGHT, + buff: float = DEFAULT_MOBJECT_TO_MOBJECT_BUFFER, + center: bool = True, **kwargs, - ): + ) -> Self: """Sorts :class:`~.Mobject` next to each other on screen. Examples @@ -2141,17 +2373,17 @@ def construct(self): def arrange_in_grid( self, - rows: Optional[int] = None, - cols: Optional[int] = None, - buff: Union[float, Tuple[float, float]] = MED_SMALL_BUFF, - cell_alignment: np.ndarray = ORIGIN, - row_alignments: Optional[str] = None, # "ucd" - col_alignments: Optional[str] = None, # "lcr" - row_heights: Optional[Iterable[Optional[float]]] = None, - col_widths: Optional[Iterable[Optional[float]]] = None, + rows: int | None = None, + cols: int | None = None, + buff: float | tuple[float, float] = MED_SMALL_BUFF, + cell_alignment: Vector3D = ORIGIN, + row_alignments: str | None = None, # "ucd" + col_alignments: str | None = None, # "lcr" + row_heights: Iterable[float | None] | None = None, + col_widths: Iterable[float | None] | None = None, flow_order: str = "rd", **kwargs, - ): + ) -> Self: """Arrange submobjects in a grid. Parameters @@ -2221,11 +2453,9 @@ def construct(self): class ArrangeInGrid(Scene): def construct(self): - #Add some numbered boxes: - np.random.seed(3) boxes = VGroup(*[ - Rectangle(WHITE, np.random.random()+.5, np.random.random()+.5).add(Text(str(i+1)).scale(0.5)) - for i in range(22) + Rectangle(WHITE, 0.5, 0.5).add(Text(str(i+1)).scale(0.5)) + for i in range(24) ]) self.add(boxes) @@ -2233,7 +2463,8 @@ def construct(self): buff=(0.25,0.5), col_alignments="lccccr", row_alignments="uccd", - col_widths=[2, *[None]*4, 2], + col_widths=[1, *[None]*4, 1], + row_heights=[1, None, None, 1], flow_order="dr" ) @@ -2258,15 +2489,15 @@ def init_size(num, alignments, sizes): # calculate rows cols if rows is None and cols is None: - cols = ceil(np.sqrt(len(mobs))) + cols = math.ceil(math.sqrt(len(mobs))) # make the grid as close to quadratic as possible. # choosing cols first can results in cols>rows. # This is favored over rows>cols since in general # the sceene is wider than high. if rows is None: - rows = ceil(len(mobs) / cols) + rows = math.ceil(len(mobs) / cols) if cols is None: - cols = ceil(len(mobs) / rows) + cols = math.ceil(len(mobs) / rows) if rows * cols < len(mobs): raise ValueError("Too few rows and columns to fit all submobjetcs.") # rows and cols are now finally valid. @@ -2278,10 +2509,10 @@ def init_size(num, alignments, sizes): buff_x = buff_y = buff # Initialize alignments correctly - def init_alignments(alignments, num, mapping, name, dir): + def init_alignments(alignments, num, mapping, name, dir_): if alignments is None: # Use cell_alignment as fallback - return [cell_alignment * dir] * num + return [cell_alignment * dir_] * num if len(alignments) != num: raise ValueError(f"{name}_alignments has a mismatching size.") alignments = list(alignments) @@ -2381,24 +2612,28 @@ def init_sizes(sizes, num, measures, name): self.move_to(start_pos) return self - def sort(self, point_to_num_func=lambda p: p[0], submob_func=None): + def sort( + self, + point_to_num_func: Callable[[Point3DLike], float] = lambda p: p[0], + submob_func: Callable[[Mobject], Any] | None = None, + ) -> Self: """Sorts the list of :attr:`submobjects` by a function defined by ``submob_func``.""" if submob_func is None: - def submob_func(m): + def submob_func(m: Mobject) -> float: return point_to_num_func(m.get_center()) self.submobjects.sort(key=submob_func) return self - def shuffle(self, recursive=False): + def shuffle(self, recursive: bool = False) -> None: """Shuffles the list of :attr:`submobjects`.""" if recursive: for submob in self.submobjects: submob.shuffle(recursive=True) random.shuffle(self.submobjects) - def invert(self, recursive=False): + def invert(self, recursive: bool = False) -> None: """Inverts the list of :attr:`submobjects`. Parameters @@ -2422,10 +2657,10 @@ def construct(self): if recursive: for submob in self.submobjects: submob.invert(recursive=True) - list.reverse(self.submobjects) + self.submobjects.reverse() # Just here to keep from breaking old scenes. - def arrange_submobjects(self, *args, **kwargs): + def arrange_submobjects(self, *args, **kwargs) -> Self: """Arrange the position of :attr:`submobjects` with a small buffer. Examples @@ -2446,11 +2681,11 @@ def construct(self): """ return self.arrange(*args, **kwargs) - def sort_submobjects(self, *args, **kwargs): + def sort_submobjects(self, *args, **kwargs) -> Self: """Sort the :attr:`submobjects`""" return self.sort(*args, **kwargs) - def shuffle_submobjects(self, *args, **kwargs): + def shuffle_submobjects(self, *args, **kwargs) -> None: """Shuffles the order of :attr:`submobjects` Examples @@ -2469,7 +2704,7 @@ def construct(self): return self.shuffle(*args, **kwargs) # Alignment - def align_data(self, mobject: "Mobject", skip_point_alignment: bool = False): + def align_data(self, mobject: Mobject, skip_point_alignment: bool = False) -> None: """Aligns the data of this mobject with another mobject. Afterwards, the two mobjects will have the same number of submobjects @@ -2500,7 +2735,7 @@ def get_point_mobject(self, center=None): msg = f"get_point_mobject not implemented for {self.__class__.__name__}" raise NotImplementedError(msg) - def align_points(self, mobject): + def align_points(self, mobject: Mobject) -> Self: count1 = self.get_num_points() count2 = mobject.get_num_points() if count1 < count2: @@ -2509,10 +2744,10 @@ def align_points(self, mobject): mobject.align_points_with_larger(self) return self - def align_points_with_larger(self, larger_mobject): + def align_points_with_larger(self, larger_mobject: Mobject): raise NotImplementedError("Please override in a child class.") - def align_submobjects(self, mobject): + def align_submobjects(self, mobject: Mobject) -> Self: mob1 = self mob2 = mobject n1 = len(mob1.submobjects) @@ -2521,7 +2756,7 @@ def align_submobjects(self, mobject): mob2.add_n_more_submobjects(max(0, n1 - n2)) return self - def null_point_align(self, mobject: "Mobject"): + def null_point_align(self, mobject: Mobject): """If a :class:`~.Mobject` with points is being aligned to one without, treat both as groups, and push the one with points into its own submobjects @@ -2537,22 +2772,22 @@ def null_point_align(self, mobject: "Mobject"): m2.push_self_into_submobjects() return self - def push_self_into_submobjects(self): + def push_self_into_submobjects(self) -> Self: copy = self.copy() copy.submobjects = [] self.reset_points() self.add(copy) return self - def add_n_more_submobjects(self, n): + def add_n_more_submobjects(self, n: int) -> Self | None: if n == 0: - return + return None curr = len(self.submobjects) if curr == 0: # If empty, simply add n point mobjects self.submobjects = [self.get_point_mobject() for k in range(n)] - return + return None target = curr + n # TODO, factor this out to utils so as to reuse @@ -2567,10 +2802,16 @@ def add_n_more_submobjects(self, n): self.submobjects = new_submobs return self - def repeat_submobject(self, submob): + def repeat_submobject(self, submob: Mobject) -> Self: return submob.copy() - def interpolate(self, mobject1, mobject2, alpha, path_func=straight_path()): + def interpolate( + self, + mobject1: Mobject, + mobject2: Mobject, + alpha: float, + path_func: PathFuncType = straight_path(), + ) -> Self: """Turns this :class:`~.Mobject` into an interpolation between ``mobject1`` and ``mobject2``. @@ -2595,39 +2836,43 @@ def construct(self): self.interpolate_color(mobject1, mobject2, alpha) return self - def interpolate_color(self, mobject1, mobject2, alpha): + def interpolate_color(self, mobject1: Mobject, mobject2: Mobject, alpha: float): raise NotImplementedError("Please override in a child class.") def become( self, - mobject: "Mobject", - copy_submobjects: bool = True, + mobject: Mobject, match_height: bool = False, match_width: bool = False, match_depth: bool = False, match_center: bool = False, stretch: bool = False, - ): + ) -> Self: """Edit points, colors and submobjects to be identical to another :class:`~.Mobject` .. note:: If both match_height and match_width are ``True`` then the transformed :class:`~.Mobject` - will match the height first and then the width + will match the height first and then the width. Parameters ---------- match_height - If ``True``, then the transformed :class:`~.Mobject` will match the height of the original + Whether or not to preserve the height of the original + :class:`~.Mobject`. match_width - If ``True``, then the transformed :class:`~.Mobject` will match the width of the original + Whether or not to preserve the width of the original + :class:`~.Mobject`. match_depth - If ``True``, then the transformed :class:`~.Mobject` will match the depth of the original + Whether or not to preserve the depth of the original + :class:`~.Mobject`. match_center - If ``True``, then the transformed :class:`~.Mobject` will match the center of the original + Whether or not to preserve the center of the original + :class:`~.Mobject`. stretch - If ``True``, then the transformed :class:`~.Mobject` will stretch to fit the proportions of the original + Whether or not to stretch the target mobject to match the + the proportions of the original :class:`~.Mobject`. Examples -------- @@ -2641,8 +2886,65 @@ def construct(self): self.wait(0.5) circ.become(square) self.wait(0.5) - """ + + The following examples illustrate how mobject measurements + change when using the ``match_...`` and ``stretch`` arguments. + We start with a rectangle that is 2 units high and 4 units wide, + which we want to turn into a circle of radius 3:: + + >>> from manim import Rectangle, Circle + >>> import numpy as np + >>> rect = Rectangle(height=2, width=4) + >>> circ = Circle(radius=3) + + With ``stretch=True``, the target circle is deformed to match + the proportions of the rectangle, which results in the target + mobject being an ellipse with height 2 and width 4. We can + check that the resulting points satisfy the ellipse equation + :math:`x^2/a^2 + y^2/b^2 = 1` with :math:`a = 4/2` and :math:`b = 2/2` + being the semi-axes:: + + >>> result = rect.copy().become(circ, stretch=True) + >>> result.height, result.width + (np.float64(2.0), np.float64(4.0)) + >>> ellipse_points = np.array(result.get_anchors()) + >>> ellipse_eq = np.sum(ellipse_points**2 * [1/4, 1, 0], axis=1) + >>> np.allclose(ellipse_eq, 1) + True + + With ``match_height=True`` and ``match_width=True`` the circle is + scaled such that the height or the width of the rectangle will + be preserved, respectively. + The points of the resulting mobject satisfy the circle equation + :math:`x^2 + y^2 = r^2` for the corresponding radius :math:`r`:: + + >>> result = rect.copy().become(circ, match_height=True) + >>> result.height, result.width + (np.float64(2.0), np.float64(2.0)) + >>> circle_points = np.array(result.get_anchors()) + >>> circle_eq = np.sum(circle_points**2, axis=1) + >>> np.allclose(circle_eq, 1) + True + >>> result = rect.copy().become(circ, match_width=True) + >>> result.height, result.width + (np.float64(4.0), np.float64(4.0)) + >>> circle_points = np.array(result.get_anchors()) + >>> circle_eq = np.sum(circle_points**2, axis=1) + >>> np.allclose(circle_eq, 2**2) + True + + With ``match_center=True``, the resulting mobject is moved such that + its center is the same as the center of the original mobject:: + + >>> rect = rect.shift(np.array([0, 1, 0])) + >>> np.allclose(rect.get_center(), circ.get_center()) + False + >>> result = rect.copy().become(circ, match_center=True) + >>> np.allclose(rect.get_center(), result.get_center()) + True + """ + mobject = mobject.copy() if stretch: mobject.stretch_to_fit_height(self.height) mobject.stretch_to_fit_width(self.width) @@ -2664,7 +2966,7 @@ def construct(self): sm1.interpolate_color(sm1, sm2, 1) return self - def match_points(self, mobject: "Mobject", copy_submobjects: bool = True): + def match_points(self, mobject: Mobject, copy_submobjects: bool = True) -> Self: """Edit points, positions, and submobjects to be identical to another :class:`~.Mobject`, while keeping the style unchanged. @@ -2686,7 +2988,7 @@ def construct(self): return self # Errors - def throw_error_if_no_points(self): + def throw_error_if_no_points(self) -> None: if self.has_no_points(): caller_name = sys._getframe(1).f_code.co_name raise Exception( @@ -2698,7 +3000,7 @@ def set_z_index( self, z_index_value: float, family: bool = True, - ) -> "VMobject": + ) -> Self: """Sets the :class:`~.Mobject`'s :attr:`z_index` to the value specified in `z_index_value`. Parameters @@ -2737,8 +3039,8 @@ def construct(self): self.z_index = z_index_value return self - def set_z_index_by_z_coordinate(self): - """Sets the :class:`~.Mobject`'s z coordinate to the value of :attr:`z_index`. + def set_z_index_by_z_Point3D(self) -> Self: + """Sets the :class:`~.Mobject`'s z Point3D to the value of :attr:`z_index`. Returns ------- @@ -2751,15 +3053,22 @@ def set_z_index_by_z_coordinate(self): class Group(Mobject, metaclass=ConvertToOpenGL): - """Groups together multiple :class:`Mobjects <.Mobject>`.""" + """Groups together multiple :class:`Mobjects <.Mobject>`. + + Notes + ----- + When adding the same mobject more than once, repetitions are ignored. + Use :meth:`.Mobject.copy` to create a separate copy which can then + be added to the group. + """ - def __init__(self, *mobjects, **kwargs): + def __init__(self, *mobjects, **kwargs) -> None: super().__init__(**kwargs) self.add(*mobjects) class _AnimationBuilder: - def __init__(self, mobject): + def __init__(self, mobject) -> None: self.mobject = mobject self.mobject.generate_target() @@ -2771,7 +3080,7 @@ def __init__(self, mobject): self.cannot_pass_args = False self.anim_args = {} - def __call__(self, **kwargs): + def __call__(self, **kwargs) -> Self: if self.cannot_pass_args: raise ValueError( "Animation arguments must be passed before accessing methods and can only be passed once", @@ -2782,15 +3091,13 @@ def __call__(self, **kwargs): return self - def __getattr__(self, method_name): + def __getattr__(self, method_name) -> types.MethodType: method = getattr(self.mobject.target, method_name) - self.methods.append(method) has_overridden_animation = hasattr(method, "_override_animate") if (self.is_chaining and has_overridden_animation) or self.overridden_animation: raise NotImplementedError( - "Method chaining is currently not supported for " - "overridden animations", + "Method chaining is currently not supported for overridden animations", ) def update_target(*method_args, **method_kwargs): @@ -2802,6 +3109,7 @@ def update_target(*method_args, **method_kwargs): **method_kwargs, ) else: + self.methods.append([method, method_args, method_kwargs]) method(*method_args, **method_kwargs) return self @@ -2810,8 +3118,10 @@ def update_target(*method_args, **method_kwargs): return update_target - def build(self): - from ..animation.transform import _MethodAnimation + def build(self) -> Animation: + from ..animation.transform import ( # is this to prevent circular import? + _MethodAnimation, + ) if self.overridden_animation: anim = self.overridden_animation @@ -2824,7 +3134,7 @@ def build(self): return anim -def override_animate(method): +def override_animate(method) -> types.FunctionType: r"""Decorator for overriding method animations. This allows to specify a method (returning an :class:`~.Animation`) diff --git a/manim/mobject/opengl/opengl_compatibility.py b/manim/mobject/opengl/opengl_compatibility.py index 611bbea190..6632175417 100644 --- a/manim/mobject/opengl/opengl_compatibility.py +++ b/manim/mobject/opengl/opengl_compatibility.py @@ -8,21 +8,21 @@ from manim.mobject.opengl.opengl_three_dimensions import OpenGLSurface from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject +from ...constants import RendererType + +__all__ = ["ConvertToOpenGL"] + class ConvertToOpenGL(ABCMeta): """Metaclass for swapping (V)Mobject with its OpenGL counterpart at runtime depending on config.renderer. This metaclass should only need to be inherited on the lowest order inheritance classes such as Mobject and VMobject. - - Note that with this implementation, changing the value of ``config.renderer`` - after Manim has been imported won't have the desired effect and will lead to - spurious errors. """ _converted_classes = [] - def __new__(mcls, name, bases, namespace): - if config.renderer == "opengl": + def __new__(mcls, name, bases, namespace): # noqa: B902 + if config.renderer == RendererType.OPENGL: # Must check class names to prevent # cyclic importing. base_names_to_opengl = { @@ -40,6 +40,6 @@ def __new__(mcls, name, bases, namespace): return super().__new__(mcls, name, bases, namespace) - def __init__(cls, name, bases, namespace): + def __init__(cls, name, bases, namespace): # noqa: B902 super().__init__(name, bases, namespace) cls._converted_classes.append(cls) diff --git a/manim/mobject/opengl/opengl_geometry.py b/manim/mobject/opengl/opengl_geometry.py index 3f9379b14d..dc9a3fc2c2 100644 --- a/manim/mobject/opengl/opengl_geometry.py +++ b/manim/mobject/opengl/opengl_geometry.py @@ -23,11 +23,36 @@ ) DEFAULT_DOT_RADIUS = 0.08 -DEFAULT_SMALL_DOT_RADIUS = 0.04 DEFAULT_DASH_LENGTH = 0.05 DEFAULT_ARROW_TIP_LENGTH = 0.35 DEFAULT_ARROW_TIP_WIDTH = 0.35 +__all__ = [ + "OpenGLTipableVMobject", + "OpenGLArc", + "OpenGLArcBetweenPoints", + "OpenGLCurvedArrow", + "OpenGLCurvedDoubleArrow", + "OpenGLCircle", + "OpenGLDot", + "OpenGLEllipse", + "OpenGLAnnularSector", + "OpenGLSector", + "OpenGLAnnulus", + "OpenGLLine", + "OpenGLDashedLine", + "OpenGLTangentLine", + "OpenGLElbow", + "OpenGLArrow", + "OpenGLVector", + "OpenGLDoubleArrow", + "OpenGLCubicBezier", + "OpenGLPolygon", + "OpenGLRegularPolygon", + "OpenGLTriangle", + "OpenGLArrowTip", +] + class OpenGLTipableVMobject(OpenGLVMobject): """ @@ -162,7 +187,8 @@ def get_tips(self): def get_tip(self): """Returns the TipableVMobject instance's (first) tip, - otherwise throws an exception.""" + otherwise throws an exception. + """ tips = self.get_tips() if len(tips) == 0: raise Exception("tip not found") @@ -438,10 +464,7 @@ def account_for_buff(self, buff): if buff == 0: return # - if self.path_arc == 0: - length = self.get_length() - else: - length = self.get_arc_length() + length = self.get_length() if self.path_arc == 0 else self.get_arc_length() # if length < 2 * buff: return @@ -494,9 +517,7 @@ def get_angle(self): return angle_of_vector(self.get_vector()) def get_projection(self, point): - """ - Return projection of a point onto the line - """ + """Return projection of a point onto the line""" unit_vect = self.get_unit_vector() start = self.get_start() return start + np.dot(point - start, unit_vect) * unit_vect diff --git a/manim/mobject/opengl/opengl_image_mobject.py b/manim/mobject/opengl/opengl_image_mobject.py new file mode 100644 index 0000000000..84e3ef7ad6 --- /dev/null +++ b/manim/mobject/opengl/opengl_image_mobject.py @@ -0,0 +1,83 @@ +from __future__ import annotations + +__all__ = [ + "OpenGLImageMobject", +] + +from pathlib import Path + +import numpy as np +from PIL import Image +from PIL.Image import Resampling + +from manim.mobject.opengl.opengl_surface import OpenGLSurface, OpenGLTexturedSurface +from manim.utils.images import get_full_raster_image_path + +__all__ = ["OpenGLImageMobject"] + + +class OpenGLImageMobject(OpenGLTexturedSurface): + def __init__( + self, + filename_or_array: str | Path | np.ndarray, + width: float = None, + height: float = None, + image_mode: str = "RGBA", + resampling_algorithm: int = Resampling.BICUBIC, + opacity: float = 1, + gloss: float = 0, + shadow: float = 0, + **kwargs, + ): + self.image = filename_or_array + self.resampling_algorithm = resampling_algorithm + if isinstance(filename_or_array, np.ndarray): + self.size = self.image.shape[1::-1] + elif isinstance(filename_or_array, (str, Path)): + path = get_full_raster_image_path(filename_or_array) + self.size = Image.open(path).size + + if width is None and height is None: + width = 4 * self.size[0] / self.size[1] + height = 4 + if height is None: + height = width * self.size[1] / self.size[0] + if width is None: + width = height * self.size[0] / self.size[1] + + surface = OpenGLSurface( + lambda u, v: np.array([u, v, 0]), + [-width / 2, width / 2], + [-height / 2, height / 2], + opacity=opacity, + gloss=gloss, + shadow=shadow, + ) + + super().__init__( + surface, + self.image, + image_mode=image_mode, + opacity=opacity, + gloss=gloss, + shadow=shadow, + **kwargs, + ) + + def get_image_from_file( + self, + image_file: str | Path | np.ndarray, + image_mode: str, + ): + if isinstance(image_file, (str, Path)): + return super().get_image_from_file(image_file, image_mode) + else: + return ( + Image.fromarray(image_file.astype("uint8")) + .convert(image_mode) + .resize( + np.array(image_file.shape[:2]) + * 200, # assumption of 200 ppmu (pixels per manim unit) would suffice + resample=self.resampling_algorithm, + ) + ) diff --git a/manim/mobject/opengl/opengl_mobject.py b/manim/mobject/opengl/opengl_mobject.py index 9aae1a5765..d57d96af32 100644 --- a/manim/mobject/opengl/opengl_mobject.py +++ b/manim/mobject/opengl/opengl_mobject.py @@ -1,22 +1,31 @@ from __future__ import annotations import copy +import inspect import itertools as it import random import sys +import types +from collections.abc import Iterable, Iterator, Sequence from functools import partialmethod, wraps from math import ceil -from typing import Iterable, Sequence +from typing import TYPE_CHECKING, Any, Callable, TypeVar import moderngl import numpy as np -from colour import Color -from manim import config +from manim import config, logger from manim.constants import * +from manim.renderer.shader_wrapper import get_colormap_code from manim.utils.bezier import integer_interpolate, interpolate -from manim.utils.color import * -from manim.utils.color import Colors +from manim.utils.color import ( + WHITE, + ManimColor, + ParsableManimColor, + color_gradient, + color_to_rgb, + rgb_to_hex, +) from manim.utils.config_ops import _Data, _Uniforms # from ..utils.iterables import batch_by_property @@ -31,13 +40,52 @@ uniq_chain, ) from manim.utils.paths import straight_path -from manim.utils.simple_functions import get_parameters from manim.utils.space_ops import ( angle_between_vectors, normalize, rotation_matrix_transpose, ) +if TYPE_CHECKING: + import numpy.typing as npt + from typing_extensions import Self, TypeAlias + + from manim.renderer.shader_wrapper import ShaderWrapper + from manim.typing import ( + ManimFloat, + MappingFunction, + MatrixMN, + MultiMappingFunction, + PathFuncType, + Point3D, + Point3D_Array, + Point3DLike, + Point3DLike_Array, + Vector3D, + ) + + TimeBasedUpdater: TypeAlias = Callable[["Mobject", float], object] + NonTimeBasedUpdater: TypeAlias = Callable[["Mobject"], object] + Updater: TypeAlias = NonTimeBasedUpdater | TimeBasedUpdater + + T = TypeVar("T") + + +def affects_shader_info_id( + func: Callable[[OpenGLMobject], OpenGLMobject], +) -> Callable[[OpenGLMobject], OpenGLMobject]: + @wraps(func) + def wrapper(self: OpenGLMobject) -> OpenGLMobject: + for mob in self.get_family(): + func(mob) + mob.refresh_shader_wrapper_id() + return self + + return wrapper + + +__all__ = ["OpenGLMobject", "OpenGLGroup", "OpenGLPoint", "_AnimationBuilder"] + class OpenGLMobject: """Mathematical Object: base class for objects that can be displayed on screen. @@ -73,28 +121,30 @@ class OpenGLMobject: def __init__( self, - color=WHITE, - opacity=1, - dim=3, # TODO, get rid of this + color: ParsableManimColor | Iterable[ParsableManimColor] = WHITE, + opacity: float = 1, + dim: int = 3, # TODO, get rid of this # Lighting parameters # Positive gloss up to 1 makes it reflect the light. - gloss=0.0, + gloss: float = 0.0, # Positive shadow up to 1 makes a side opposite the light darker - shadow=0.0, + shadow: float = 0.0, # For shaders - render_primitive=moderngl.TRIANGLES, - texture_paths=None, - depth_test=False, + render_primitive: int = moderngl.TRIANGLES, + texture_paths: dict[str, str] | None = None, + depth_test: bool = False, # If true, the mobject will not get rotated according to camera position - is_fixed_in_frame=False, - is_fixed_orientation=False, + is_fixed_in_frame: bool = False, + is_fixed_orientation: bool = False, # Must match in attributes of vert shader # Event listener - listen_to_events=False, - model_matrix=None, - should_render=True, + listen_to_events: bool = False, + model_matrix: MatrixMN | None = None, + should_render: bool = True, + name: str | None = None, **kwargs, ): + self.name = self.__class__.__name__ if name is None else name # getattr in case data/uniforms are already defined in parent classes. self.data = getattr(self, "data", {}) self.uniforms = getattr(self, "uniforms", {}) @@ -133,7 +183,7 @@ def __init__( self.init_updaters() # self.init_event_listners() self.init_points() - self.color = Color(color) if color else None + self.color = ManimColor.parse(color) self.init_colors() self.shader_indices = None @@ -143,31 +193,89 @@ def __init__( self.should_render = should_render + def _assert_valid_submobjects(self, submobjects: Iterable[OpenGLMobject]) -> Self: + """Check that all submobjects are actually instances of + :class:`OpenGLMobject`, and that none of them is + ``self`` (an :class:`OpenGLMobject` cannot contain itself). + + This is an auxiliary function called when adding OpenGLMobjects to the + :attr:`submobjects` list. + + This function is intended to be overridden by subclasses such as + :class:`OpenGLVMobject`, which should assert that only other + OpenGLVMobjects may be added into it. + + Parameters + ---------- + submobjects + The list containing values to validate. + + Returns + ------- + :class:`OpenGLMobject` + The OpenGLMobject itself. + + Raises + ------ + TypeError + If any of the values in `submobjects` is not an + :class:`OpenGLMobject`. + ValueError + If there was an attempt to add an :class:`OpenGLMobject` as its own + submobject. + """ + return self._assert_valid_submobjects_internal(submobjects, OpenGLMobject) + + def _assert_valid_submobjects_internal( + self, submobjects: Iterable[OpenGLMobject], mob_class: type[OpenGLMobject] + ) -> Self: + for i, submob in enumerate(submobjects): + if not isinstance(submob, mob_class): + error_message = ( + f"Only values of type {mob_class.__name__} can be added " + f"as submobjects of {type(self).__name__}, but the value " + f"{submob} (at index {i}) is of type " + f"{type(submob).__name__}." + ) + # Intended for subclasses such as OpenGLVMobject, which + # cannot have regular OpenGLMobjects as submobjects + if isinstance(submob, OpenGLMobject): + error_message += ( + " You can try adding this value into a Group instead." + ) + raise TypeError(error_message) + if submob is self: + raise ValueError( + f"Cannot add {type(self).__name__} as a submobject of " + f"itself (at index {i})." + ) + return self + @classmethod - def __init_subclass__(cls, **kwargs): + def __init_subclass__(cls, **kwargs) -> None: super().__init_subclass__(**kwargs) cls._original__init__ = cls.__init__ - def __str__(self): + def __str__(self) -> str: return self.__class__.__name__ - def __repr__(self): - return self.__class__.__name__ + def __repr__(self) -> str: + return str(self.name) def __sub__(self, other): - raise NotImplementedError + return NotImplemented def __isub__(self, other): - raise NotImplementedError + return NotImplemented def __add__(self, mobject): - raise NotImplementedError + return NotImplemented def __iadd__(self, mobject): - raise NotImplementedError + return NotImplemented @classmethod - def set_default(cls, **kwargs): + def set_default(cls, **kwargs) -> None: """Sets the default values of keyword arguments. If this method is called without any additional keyword @@ -190,10 +298,10 @@ def set_default(cls, **kwargs): >>> from manim import Square, GREEN >>> Square.set_default(color=GREEN, fill_opacity=0.25) >>> s = Square(); s.color, s.fill_opacity - (, 0.25) + (ManimColor('#83C167'), 0.25) >>> Square.set_default() >>> s = Square(); s.color, s.fill_opacity - (, 0.0) + (ManimColor('#FFFFFF'), 0.0) .. manim:: ChangedDefaultTextcolor :save_last_frame: @@ -214,28 +322,31 @@ def construct(self): else: cls.__init__ = cls._original__init__ - def init_data(self): + def init_data(self) -> None: """Initializes the ``points``, ``bounding_box`` and ``rgbas`` attributes and groups them into self.data. - Subclasses can inherit and overwrite this method to extend `self.data`.""" + Subclasses can inherit and overwrite this method to extend `self.data`. + """ self.points = np.zeros((0, 3)) self.bounding_box = np.zeros((3, 3)) self.rgbas = np.zeros((1, 4)) - def init_colors(self): + def init_colors(self) -> object: """Initializes the colors. - Gets called upon creation""" + Gets called upon creation + """ self.set_color(self.color, self.opacity) - def init_points(self): + def init_points(self) -> object: """Initializes :attr:`points` and therefore the shape. Gets called upon creation. This is an empty method that can be implemented by - subclasses.""" + subclasses. + """ # Typically implemented in subclass, unless purposefully left blank pass - def set(self, **kwargs) -> OpenGLMobject: + def set(self, **kwargs) -> Self: """Sets attributes. Mainly to be used along with :attr:`animate` to @@ -263,24 +374,23 @@ def set(self, **kwargs) -> OpenGLMobject: """ - for attr, value in kwargs.items(): setattr(self, attr, value) return self - def set_data(self, data): + def set_data(self, data: dict[str, Any]) -> Self: for key in data: self.data[key] = data[key].copy() return self - def set_uniforms(self, uniforms): + def set_uniforms(self, uniforms: dict[str, Any]) -> Self: for key in uniforms: self.uniforms[key] = uniforms[key] # Copy? return self @property - def animate(self): + def animate(self) -> _AnimationBuilder | Self: """Used to animate the application of a method. .. warning:: @@ -291,7 +401,9 @@ def animate(self): :: - self.play(my_mobject.animate.shift(RIGHT), my_mobject.animate.rotate(PI)) + self.play( + my_mobject.animate.shift(RIGHT), my_mobject.animate.rotate(PI) + ) make use of method chaining for ``animate``, meaning:: @@ -368,7 +480,7 @@ def construct(self): return _AnimationBuilder(self) @property - def width(self): + def width(self) -> float: """The width of the mobject. Returns @@ -396,17 +508,16 @@ def construct(self): :meth:`length_over_dim` """ - # Get the length across the X dimension return self.length_over_dim(0) # Only these methods should directly affect points @width.setter - def width(self, value): + def width(self, value: float) -> None: self.rescale_to_fit(value, 0, stretch=False) @property - def height(self): + def height(self) -> float: """The height of the mobject. Returns @@ -434,16 +545,15 @@ def construct(self): :meth:`length_over_dim` """ - # Get the length across the Y dimension return self.length_over_dim(1) @height.setter - def height(self, value): + def height(self, value: float) -> None: self.rescale_to_fit(value, 1, stretch=False) @property - def depth(self): + def depth(self) -> float: """The depth of the mobject. Returns @@ -455,12 +565,11 @@ def depth(self): :meth:`length_over_dim` """ - # Get the length across the Z dimension return self.length_over_dim(2) @depth.setter - def depth(self, value): + def depth(self, value: float) -> None: self.rescale_to_fit(value, 2, stretch=False) def resize_points(self, new_length, resize_func=resize_array): @@ -469,7 +578,7 @@ def resize_points(self, new_length, resize_func=resize_array): self.refresh_bounding_box() return self - def set_points(self, points): + def set_points(self, points: Point3DLike_Array) -> Self: if len(points) == len(self.points): self.points[:] = points elif isinstance(points, np.ndarray): @@ -479,23 +588,26 @@ def set_points(self, points): self.refresh_bounding_box() return self - def apply_over_attr_arrays(self, func): + def apply_over_attr_arrays( + self, func: Callable[[npt.NDArray[T]], npt.NDArray[T]] + ) -> Self: + # TODO: OpenGLMobject.get_array_attrs() doesn't even exist! for attr in self.get_array_attrs(): setattr(self, attr, func(getattr(self, attr))) return self - def append_points(self, new_points): + def append_points(self, new_points: Point3DLike_Array) -> Self: self.points = np.vstack([self.points, new_points]) self.refresh_bounding_box() return self - def reverse_points(self): + def reverse_points(self) -> Self: for mob in self.get_family(): for key in mob.data: mob.data[key] = mob.data[key][::-1] return self - def get_midpoint(self) -> np.ndarray: + def get_midpoint(self) -> Point3D: """Get coordinates of the middle of the path that forms the :class:`~.OpenGLMobject`. Examples @@ -518,13 +630,14 @@ def construct(self): """ return self.point_from_proportion(0.5) + # TODO: name is inconsistent with Mobject.apply_points_function_about_point() def apply_points_function( self, - func, - about_point=None, - about_edge=ORIGIN, - works_on_bounding_box=False, - ): + func: MultiMappingFunction, + about_point: Point3DLike | None = None, + about_edge: Vector3D | None = ORIGIN, + works_on_bounding_box: bool = False, + ) -> Self: if about_point is None and about_edge is not None: about_point = self.get_bounding_box_point(about_edge) @@ -550,7 +663,7 @@ def apply_points_function( # Others related to points - def match_points(self, mobject): + def match_points(self, mobject: OpenGLMobject) -> Self: """Edit points, positions, and submobjects to be identical to another :class:`~.OpenGLMobject`, while keeping the style unchanged. @@ -568,29 +681,31 @@ def construct(self): self.wait(0.5) """ self.set_points(mobject.points) + return self - def clear_points(self): - self.resize_points(0) + def clear_points(self) -> Self: + self.points = np.empty((0, 3)) + return self - def get_num_points(self): + def get_num_points(self) -> int: return len(self.points) - def get_all_points(self): + def get_all_points(self) -> Point3D_Array: if self.submobjects: return np.vstack([sm.points for sm in self.get_family()]) else: return self.points - def has_points(self): + def has_points(self) -> bool: return self.get_num_points() > 0 - def get_bounding_box(self): + def get_bounding_box(self) -> npt.NDArray[float]: if self.needs_new_bounding_box: self.bounding_box = self.compute_bounding_box() self.needs_new_bounding_box = False return self.bounding_box - def compute_bounding_box(self): + def compute_bounding_box(self) -> npt.NDArray[float]: all_points = np.vstack( [ self.points, @@ -610,7 +725,9 @@ def compute_bounding_box(self): mids = (mins + maxs) / 2 return np.array([mins, mids, maxs]) - def refresh_bounding_box(self, recurse_down=False, recurse_up=True): + def refresh_bounding_box( + self, recurse_down: bool = False, recurse_up: bool = True + ) -> Self: for mob in self.get_family(recurse_down): mob.needs_new_bounding_box = True if recurse_up: @@ -618,7 +735,9 @@ def refresh_bounding_box(self, recurse_down=False, recurse_up=True): parent.refresh_bounding_box() return self - def is_point_touching(self, point, buff=MED_SMALL_BUFF): + def is_point_touching( + self, point: Point3DLike, buff: float = MED_SMALL_BUFF + ) -> bool: bb = self.get_bounding_box() mins = bb[0] - buff maxs = bb[2] + buff @@ -626,22 +745,22 @@ def is_point_touching(self, point, buff=MED_SMALL_BUFF): # Family matters - def __getitem__(self, value): + def __getitem__(self, value: int | slice) -> OpenGLMobject: if isinstance(value, slice): GroupClass = self.get_group_class() return GroupClass(*self.split().__getitem__(value)) return self.split().__getitem__(value) - def __iter__(self): + def __iter__(self) -> Iterator[OpenGLMobject]: return iter(self.split()) - def __len__(self): + def __len__(self) -> int: return len(self.split()) - def split(self): + def split(self) -> Sequence[OpenGLMobject]: return self.submobjects - def assemble_family(self): + def assemble_family(self) -> Self: sub_families = (sm.get_family() for sm in self.submobjects) self.family = [self, *uniq_chain(*sub_families)] self.refresh_has_updater_status() @@ -650,18 +769,16 @@ def assemble_family(self): parent.assemble_family() return self - def get_family(self, recurse=True): + def get_family(self, recurse: bool = True) -> Sequence[OpenGLMobject]: if recurse and hasattr(self, "family"): return self.family else: return [self] - def family_members_with_points(self): + def family_members_with_points(self) -> Sequence[OpenGLMobject]: return [m for m in self.get_family() if m.has_points()] - def add( - self, *mobjects: OpenGLMobject, update_parent: bool = False - ) -> OpenGLMobject: + def add(self, *mobjects: OpenGLMobject, update_parent: bool = False) -> Self: """Add mobjects as submobjects. The mobjects are added to :attr:`submobjects`. @@ -712,23 +829,33 @@ def add( >>> len(outer.submobjects) 1 + Only OpenGLMobjects can be added:: + + >>> outer.add(3) + Traceback (most recent call last): + ... + TypeError: Only values of type OpenGLMobject can be added as submobjects of OpenGLMobject, but the value 3 (at index 0) is of type int. + Adding an object to itself raises an error:: >>> outer.add(outer) Traceback (most recent call last): ... - ValueError: OpenGLMobject cannot contain self + ValueError: Cannot add OpenGLMobject as a submobject of itself (at index 0). """ if update_parent: assert len(mobjects) == 1, "Can't set multiple parents." mobjects[0].parent = self - if self in mobjects: - raise ValueError("OpenGLMobject cannot contain self") + self._assert_valid_submobjects(mobjects) + + if any(mobjects.count(elem) > 1 for elem in mobjects): + logger.warning( + "Attempted adding some Mobject as a child more than once, " + "this is not possible. Repetitions are ignored.", + ) for mobject in mobjects: - if not isinstance(mobject, OpenGLMobject): - raise TypeError("All submobjects must be of type OpenGLMobject") if mobject not in self.submobjects: self.submobjects.append(mobject) if self not in mobject.parents: @@ -736,9 +863,40 @@ def add( self.assemble_family() return self - def remove( - self, *mobjects: OpenGLMobject, update_parent: bool = False - ) -> OpenGLMobject: + def insert( + self, index: int, mobject: OpenGLMobject, update_parent: bool = False + ) -> Self: + """Inserts a mobject at a specific position into self.submobjects + + Effectively just calls ``self.submobjects.insert(index, mobject)``, + where ``self.submobjects`` is a list. + + Highly adapted from ``OpenGLMobject.add``. + + Parameters + ---------- + index + The index at which + mobject + The mobject to be inserted. + update_parent + Whether or not to set ``mobject.parent`` to ``self``. + """ + if update_parent: + mobject.parent = self + + self._assert_valid_submobjects([mobject]) + + if mobject not in self.submobjects: + self.submobjects.insert(index, mobject) + + if self not in mobject.parents: + mobject.parents.append(self) + + self.assemble_family() + return self + + def remove(self, *mobjects: OpenGLMobject, update_parent: bool = False) -> Self: """Remove :attr:`submobjects`. The mobjects are removed from :attr:`submobjects`, if they exist. @@ -772,7 +930,7 @@ def remove( self.assemble_family() return self - def add_to_back(self, *mobjects: OpenGLMobject) -> OpenGLMobject: + def add_to_back(self, *mobjects: OpenGLMobject) -> Self: # NOTE: is the note true OpenGLMobjects? """Add all passed mobjects to the back of the submobjects. @@ -817,10 +975,12 @@ def add_to_back(self, *mobjects: OpenGLMobject) -> OpenGLMobject: :meth:`add` """ + self._assert_valid_submobjects(mobjects) self.submobjects = list_update(mobjects, self.submobjects) return self - def replace_submobject(self, index, new_submob): + def replace_submobject(self, index: int, new_submob: OpenGLMobject) -> Self: + self._assert_valid_submobjects([new_submob]) old_submob = self.submobjects[index] if self in old_submob.parents: old_submob.parents.remove(self) @@ -828,36 +988,11 @@ def replace_submobject(self, index, new_submob): self.assemble_family() return self - def invert(self, recursive=False): - """Inverts the list of :attr:`submobjects`. - - Parameters - ---------- - recursive - If ``True``, all submobject lists of this mobject's family are inverted. - - Examples - -------- - - .. manim:: InvertSumobjectsExample - - class InvertSumobjectsExample(Scene): - def construct(self): - s = VGroup(*[Dot().shift(i*0.1*RIGHT) for i in range(-20,20)]) - s2 = s.copy() - s2.invert() - s2.shift(DOWN) - self.play(Write(s), Write(s2)) - """ - if recursive: - for submob in self.submobjects: - submob.invert(recursive=True) - list.reverse(self.submobjects) - self.assemble_family() - # Submobject organization - def arrange(self, direction=RIGHT, center=True, **kwargs): + def arrange( + self, direction: Vector3D = RIGHT, center: bool = True, **kwargs + ) -> Self: """Sorts :class:`~.OpenGLMobject` next to each other on screen. Examples @@ -886,14 +1021,14 @@ def arrange_in_grid( rows: int | None = None, cols: int | None = None, buff: float | tuple[float, float] = MED_SMALL_BUFF, - cell_alignment: np.ndarray = ORIGIN, + cell_alignment: Vector3D = ORIGIN, row_alignments: str | None = None, # "ucd" col_alignments: str | None = None, # "lcr" - row_heights: Iterable[float | None] | None = None, - col_widths: Iterable[float | None] | None = None, + row_heights: Sequence[float | None] | None = None, + col_widths: Sequence[float | None] | None = None, flow_order: str = "rd", **kwargs, - ) -> OpenGLMobject: + ) -> Self: """Arrange submobjects in a grid. Parameters @@ -989,16 +1124,27 @@ def construct(self): start_pos = self.get_center() # get cols / rows values if given (implicitly) - def init_size(num, alignments, sizes): + def init_size( + num: int | None, + alignments: str | None, + sizes: Sequence[float | None] | None, + name: str, + ) -> int: if num is not None: return num if alignments is not None: return len(alignments) if sizes is not None: return len(sizes) + raise ValueError( + f"At least one of the following parameters: '{name}s', " + f"'{name}_alignments' or " + f"'{name}_{'widths' if name == 'col' else 'heights'}', " + "must not be None" + ) - cols = init_size(cols, col_alignments, col_widths) - rows = init_size(rows, row_alignments, row_heights) + cols = init_size(cols, col_alignments, col_widths, "col") + rows = init_size(rows, row_alignments, row_heights, "row") # calculate rows cols if rows is None and cols is None: @@ -1022,16 +1168,19 @@ def init_size(num, alignments, sizes): buff_x = buff_y = buff # Initialize alignments correctly - def init_alignments(alignments, num, mapping, name, dir): - if alignments is None: + def init_alignments( + str_alignments: str | None, + num: int, + mapping: dict[str, Vector3D], + name: str, + direction: Vector3D, + ) -> Sequence[Vector3D]: + if str_alignments is None: # Use cell_alignment as fallback - return [cell_alignment * dir] * num - if len(alignments) != num: + return [cell_alignment * direction] * num + if len(str_alignments) != num: raise ValueError(f"{name}_alignments has a mismatching size.") - alignments = list(alignments) - for i in range(num): - alignments[i] = mapping[alignments[i]] - return alignments + return [mapping[letter] for letter in str_alignments] row_alignments = init_alignments( row_alignments, @@ -1067,11 +1216,12 @@ def init_alignments(alignments, num, mapping, name, dir): # Reverse row_alignments and row_heights. Necessary since the # grid filling is handled bottom up for simplicity reasons. - def reverse(maybe_list): + def reverse(maybe_list: Sequence[Any] | None) -> Sequence[Any] | None: if maybe_list is not None: maybe_list = list(maybe_list) maybe_list.reverse() return maybe_list + return None row_alignments = reverse(row_alignments) row_heights = reverse(row_heights) @@ -1092,7 +1242,12 @@ def reverse(maybe_list): ] # Initialize row_heights / col_widths correctly using measurements as fallback - def init_sizes(sizes, num, measures, name): + def init_sizes( + sizes: Sequence[float | None] | None, + num: int, + measures: Sequence[float], + name: str, + ) -> Sequence[float]: if sizes is None: sizes = [None] * num if len(sizes) != num: @@ -1125,7 +1280,9 @@ def init_sizes(sizes, num, measures, name): self.move_to(start_pos) return self - def get_grid(self, n_rows, n_cols, height=None, **kwargs): + def get_grid( + self, n_rows: int, n_cols: int, height: float | None = None, **kwargs + ) -> OpenGLGroup: """ Returns a new mobject containing multiple copies of this one arranged in a grid @@ -1136,11 +1293,15 @@ def get_grid(self, n_rows, n_cols, height=None, **kwargs): grid.set_height(height) return grid - def duplicate(self, n: int): - """Returns an :class:`~.OpenGLVGroup` containing ``n`` copies of the mobject.""" + def duplicate(self, n: int) -> OpenGLGroup: + """Returns an :class:`~.OpenGLGroup` containing ``n`` copies of the mobject.""" return self.get_group_class()(*[self.copy() for _ in range(n)]) - def sort(self, point_to_num_func=lambda p: p[0], submob_func=None): + def sort( + self, + point_to_num_func: Callable[[Point3DLike], float] = lambda p: p[0], + submob_func: Callable[[OpenGLMobject], Any] | None = None, + ) -> Self: """Sorts the list of :attr:`submobjects` by a function defined by ``submob_func``.""" if submob_func is not None: self.submobjects.sort(key=submob_func) @@ -1148,7 +1309,7 @@ def sort(self, point_to_num_func=lambda p: p[0], submob_func=None): self.submobjects.sort(key=lambda m: point_to_num_func(m.get_center())) return self - def shuffle(self, recurse=False): + def shuffle(self, recurse: bool = False) -> Self: """Shuffles the order of :attr:`submobjects` Examples @@ -1171,7 +1332,7 @@ def construct(self): self.assemble_family() return self - def invert(self, recursive=False): + def invert(self, recursive: bool = False) -> Self: """Inverts the list of :attr:`submobjects`. Parameters @@ -1195,11 +1356,13 @@ def construct(self): if recursive: for submob in self.submobjects: submob.invert(recursive=True) - list.reverse(self.submobjects) + self.submobjects.reverse() + self.assemble_family() + return self # Copying - def copy(self, shallow: bool = False): + def copy(self, shallow: bool = False) -> OpenGLMobject: """Create and return an identical copy of the :class:`OpenGLMobject` including all :attr:`submobjects`. @@ -1257,14 +1420,14 @@ def copy(self, shallow: bool = False): # setattr(copy_mobject, attr, value.copy()) return copy_mobject - def deepcopy(self): + def deepcopy(self) -> OpenGLMobject: parents = self.parents self.parents = [] result = copy.deepcopy(self) self.parents = parents return result - def generate_target(self, use_deepcopy: bool = False): + def generate_target(self, use_deepcopy: bool = False) -> OpenGLMobject: self.target = None # Prevent exponential explosion if use_deepcopy: self.target = self.deepcopy() @@ -1272,7 +1435,7 @@ def generate_target(self, use_deepcopy: bool = False): self.target = self.copy() return self.target - def save_state(self, use_deepcopy: bool = False): + def save_state(self, use_deepcopy: bool = False) -> Self: """Save the current state (position, color & size). Can be restored with :meth:`~.OpenGLMobject.restore`.""" if hasattr(self, "saved_state"): # Prevent exponential growth of data @@ -1283,7 +1446,7 @@ def save_state(self, use_deepcopy: bool = False): self.saved_state = self.copy() return self - def restore(self): + def restore(self) -> Self: """Restores the state that was previously saved with :meth:`~.OpenGLMobject.save_state`.""" if not hasattr(self, "saved_state") or self.save_state is None: raise Exception("Trying to restore without having saved") @@ -1292,13 +1455,13 @@ def restore(self): # Updating - def init_updaters(self): + def init_updaters(self) -> None: self.time_based_updaters = [] self.non_time_updaters = [] self.has_updaters = False self.updating_suspended = False - def update(self, dt=0, recurse=True): + def update(self, dt: float = 0, recurse: bool = True) -> Self: if not self.has_updaters or self.updating_suspended: return self for updater in self.time_based_updaters: @@ -1310,20 +1473,25 @@ def update(self, dt=0, recurse=True): submob.update(dt, recurse) return self - def get_time_based_updaters(self): + def get_time_based_updaters(self) -> Sequence[TimeBasedUpdater]: return self.time_based_updaters - def has_time_based_updater(self): + def has_time_based_updater(self) -> bool: return len(self.time_based_updaters) > 0 - def get_updaters(self): + def get_updaters(self) -> Sequence[Updater]: return self.time_based_updaters + self.non_time_updaters - def get_family_updaters(self): + def get_family_updaters(self) -> Sequence[Updater]: return list(it.chain(*(sm.get_updaters() for sm in self.get_family()))) - def add_updater(self, update_function, index=None, call_updater=False): - if "dt" in get_parameters(update_function): + def add_updater( + self, + update_function: Updater, + index: int | None = None, + call_updater: bool = False, + ) -> Self: + if "dt" in inspect.signature(update_function).parameters: updater_list = self.time_based_updaters else: updater_list = self.non_time_updaters @@ -1338,14 +1506,14 @@ def add_updater(self, update_function, index=None, call_updater=False): self.update() return self - def remove_updater(self, update_function): + def remove_updater(self, update_function: Updater) -> Self: for updater_list in [self.time_based_updaters, self.non_time_updaters]: while update_function in updater_list: updater_list.remove(update_function) self.refresh_has_updater_status() return self - def clear_updaters(self, recurse=True): + def clear_updaters(self, recurse: bool = True) -> Self: self.time_based_updaters = [] self.non_time_updaters = [] self.refresh_has_updater_status() @@ -1354,20 +1522,20 @@ def clear_updaters(self, recurse=True): submob.clear_updaters() return self - def match_updaters(self, mobject): + def match_updaters(self, mobject: OpenGLMobject) -> Self: self.clear_updaters() for updater in mobject.get_updaters(): self.add_updater(updater) return self - def suspend_updating(self, recurse=True): + def suspend_updating(self, recurse: bool = True) -> Self: self.updating_suspended = True if recurse: for submob in self.submobjects: submob.suspend_updating(recurse) return self - def resume_updating(self, recurse=True, call_updater=True): + def resume_updating(self, recurse: bool = True, call_updater: bool = True) -> Self: self.updating_suspended = False if recurse: for submob in self.submobjects: @@ -1378,13 +1546,13 @@ def resume_updating(self, recurse=True, call_updater=True): self.update(dt=0, recurse=recurse) return self - def refresh_has_updater_status(self): + def refresh_has_updater_status(self) -> Self: self.has_updaters = any(mob.get_updaters() for mob in self.get_family()) return self # Transforming operations - def shift(self, vector): + def shift(self, vector: Vector3D) -> Self: self.apply_points_function( lambda points: points + vector, about_edge=None, @@ -1398,7 +1566,7 @@ def scale( about_point: Sequence[float] | None = None, about_edge: Sequence[float] = ORIGIN, **kwargs, - ) -> OpenGLMobject: + ) -> Self: r"""Scale the size by a factor. Default behavior is to scale about the center of the mobject. @@ -1417,7 +1585,7 @@ def scale( if :math:`\alpha < 0`, the mobject is also flipped. kwargs Additional keyword arguments passed to - :meth:`apply_points_function_about_point`. + :meth:`apply_points_function`. Returns ------- @@ -1454,24 +1622,24 @@ def construct(self): ) return self - def stretch(self, factor, dim, **kwargs): - def func(points): + def stretch(self, factor: float, dim: int, **kwargs) -> Self: + def func(points: Point3D_Array) -> Point3D_Array: points[:, dim] *= factor return points self.apply_points_function(func, works_on_bounding_box=True, **kwargs) return self - def rotate_about_origin(self, angle, axis=OUT): + def rotate_about_origin(self, angle: float, axis: Vector3D = OUT) -> Self: return self.rotate(angle, axis, about_point=ORIGIN) def rotate( self, - angle, - axis=OUT, + angle: float, + axis: Vector3D = OUT, about_point: Sequence[float] | None = None, **kwargs, - ): + ) -> Self: """Rotates the :class:`~.OpenGLMobject` about a certain point.""" rot_matrix_T = rotation_matrix_transpose(angle, axis) self.apply_points_function( @@ -1481,7 +1649,7 @@ def rotate( ) return self - def flip(self, axis=UP, **kwargs): + def flip(self, axis: Vector3D = UP, **kwargs) -> Self: """Flips/Mirrors an mobject about its center. Examples @@ -1500,25 +1668,28 @@ def construct(self): """ return self.rotate(TAU / 2, axis, **kwargs) - def apply_function(self, function, **kwargs): + def apply_function(self, function: MappingFunction, **kwargs) -> Self: # Default to applying matrix about the origin, not mobjects center if len(kwargs) == 0: kwargs["about_point"] = ORIGIN - self.apply_points_function( - lambda points: np.array([function(p) for p in points]), **kwargs - ) + + def multi_mapping_function(points: Point3D_Array) -> Point3D_Array: + result: Point3D_Array = np.apply_along_axis(function, 1, points) + return result + + self.apply_points_function(multi_mapping_function, **kwargs) return self - def apply_function_to_position(self, function): + def apply_function_to_position(self, function: MappingFunction) -> Self: self.move_to(function(self.get_center())) return self - def apply_function_to_submobject_positions(self, function): + def apply_function_to_submobject_positions(self, function: MappingFunction) -> Self: for submob in self.submobjects: submob.apply_function_to_position(function) return self - def apply_matrix(self, matrix, **kwargs): + def apply_matrix(self, matrix: MatrixMN, **kwargs) -> Self: # Default to applying matrix about the origin, not mobjects center if ("about_point" not in kwargs) and ("about_edge" not in kwargs): kwargs["about_point"] = ORIGIN @@ -1530,7 +1701,9 @@ def apply_matrix(self, matrix, **kwargs): ) return self - def apply_complex_function(self, function, **kwargs): + def apply_complex_function( + self, function: Callable[[complex], complex], **kwargs + ) -> Self: """Applies a complex function to a :class:`OpenGLMobject`. The x and y coordinates correspond to the real and imaginary parts respectively. @@ -1564,7 +1737,7 @@ def R3_func(point): return self.apply_function(R3_func) - def hierarchical_model_matrix(self): + def hierarchical_model_matrix(self) -> MatrixMN: if self.parent is None: return self.model_matrix @@ -1575,7 +1748,12 @@ def hierarchical_model_matrix(self): current_object = current_object.parent return np.linalg.multi_dot(list(reversed(model_matrices))) - def wag(self, direction=RIGHT, axis=DOWN, wag_factor=1.0): + def wag( + self, + direction: Vector3D = RIGHT, + axis: Vector3D = DOWN, + wag_factor: float = 1.0, + ) -> Self: for mob in self.family_members_with_points(): alphas = np.dot(mob.points, np.transpose(axis)) alphas -= min(alphas) @@ -1592,12 +1770,16 @@ def wag(self, direction=RIGHT, axis=DOWN, wag_factor=1.0): # Positioning methods - def center(self): + def center(self) -> Self: """Moves the mobject to the center of the Scene.""" self.shift(-self.get_center()) return self - def align_on_border(self, direction, buff=DEFAULT_MOBJECT_TO_EDGE_BUFFER): + def align_on_border( + self, + direction: Vector3D, + buff: float = DEFAULT_MOBJECT_TO_EDGE_BUFFER, + ) -> Self: """ Direction just needs to be a vector pointing towards side or corner in the 2d plane. @@ -1613,22 +1795,30 @@ def align_on_border(self, direction, buff=DEFAULT_MOBJECT_TO_EDGE_BUFFER): self.shift(shift_val) return self - def to_corner(self, corner=LEFT + DOWN, buff=DEFAULT_MOBJECT_TO_EDGE_BUFFER): + def to_corner( + self, + corner: Vector3D = LEFT + DOWN, + buff: float = DEFAULT_MOBJECT_TO_EDGE_BUFFER, + ) -> Self: return self.align_on_border(corner, buff) - def to_edge(self, edge=LEFT, buff=DEFAULT_MOBJECT_TO_EDGE_BUFFER): + def to_edge( + self, + edge: Vector3D = LEFT, + buff: float = DEFAULT_MOBJECT_TO_EDGE_BUFFER, + ) -> Self: return self.align_on_border(edge, buff) def next_to( self, - mobject_or_point, - direction=RIGHT, - buff=DEFAULT_MOBJECT_TO_MOBJECT_BUFFER, - aligned_edge=ORIGIN, - submobject_to_align=None, - index_of_submobject_to_align=None, - coor_mask=np.array([1, 1, 1]), - ): + mobject_or_point: OpenGLMobject | Point3DLike, + direction: Vector3D = RIGHT, + buff: float = DEFAULT_MOBJECT_TO_MOBJECT_BUFFER, + aligned_edge: Vector3D = ORIGIN, + submobject_to_align: OpenGLMobject | None = None, + index_of_submobject_to_align: int | None = None, + coor_mask: Point3DLike = np.array([1, 1, 1]), + ) -> Self: """Move this :class:`~.OpenGLMobject` next to another's :class:`~.OpenGLMobject` or coordinate. Examples @@ -1670,7 +1860,7 @@ def construct(self): self.shift((target_point - point_to_align + buff * direction) * coor_mask) return self - def shift_onto_screen(self, **kwargs): + def shift_onto_screen(self, **kwargs) -> Self: space_lengths = [config["frame_x_radius"], config["frame_y_radius"]] for vect in UP, DOWN, LEFT, RIGHT: dim = np.argmax(np.abs(vect)) @@ -1681,21 +1871,21 @@ def shift_onto_screen(self, **kwargs): self.to_edge(vect, **kwargs) return self - def is_off_screen(self): + def is_off_screen(self) -> bool: if self.get_left()[0] > config.frame_x_radius: return True if self.get_right()[0] < config.frame_x_radius: return True if self.get_bottom()[1] > config.frame_y_radius: return True - if self.get_top()[1] < -config.frame_y_radius: - return True - return False + return self.get_top()[1] < -config.frame_y_radius - def stretch_about_point(self, factor, dim, point): + def stretch_about_point(self, factor: float, dim: int, point: Point3DLike) -> Self: return self.stretch(factor, dim, about_point=point) - def rescale_to_fit(self, length, dim, stretch=False, **kwargs): + def rescale_to_fit( + self, length: float, dim: int, stretch: bool = False, **kwargs + ) -> Self: old_length = self.length_over_dim(dim) if old_length == 0: return self @@ -1705,7 +1895,7 @@ def rescale_to_fit(self, length, dim, stretch=False, **kwargs): self.scale(length / old_length, **kwargs) return self - def stretch_to_fit_width(self, width, **kwargs): + def stretch_to_fit_width(self, width: float, **kwargs) -> Self: """Stretches the :class:`~.OpenGLMobject` to fit a width, not keeping height/depth proportional. Returns @@ -1730,15 +1920,15 @@ def stretch_to_fit_width(self, width, **kwargs): """ return self.rescale_to_fit(width, 0, stretch=True, **kwargs) - def stretch_to_fit_height(self, height, **kwargs): + def stretch_to_fit_height(self, height: float, **kwargs) -> Self: """Stretches the :class:`~.OpenGLMobject` to fit a height, not keeping width/height proportional.""" return self.rescale_to_fit(height, 1, stretch=True, **kwargs) - def stretch_to_fit_depth(self, depth, **kwargs): + def stretch_to_fit_depth(self, depth: float, **kwargs) -> Self: """Stretches the :class:`~.OpenGLMobject` to fit a depth, not keeping width/height proportional.""" return self.rescale_to_fit(depth, 1, stretch=True, **kwargs) - def set_width(self, width, stretch=False, **kwargs): + def set_width(self, width: float, stretch: bool = False, **kwargs) -> Self: """Scales the :class:`~.OpenGLMobject` to fit a width while keeping height/depth proportional. Returns @@ -1765,38 +1955,38 @@ def set_width(self, width, stretch=False, **kwargs): scale_to_fit_width = set_width - def set_height(self, height, stretch=False, **kwargs): + def set_height(self, height: float, stretch: bool = False, **kwargs) -> Self: """Scales the :class:`~.OpenGLMobject` to fit a height while keeping width/depth proportional.""" return self.rescale_to_fit(height, 1, stretch=stretch, **kwargs) scale_to_fit_height = set_height - def set_depth(self, depth, stretch=False, **kwargs): + def set_depth(self, depth: float, stretch: bool = False, **kwargs): """Scales the :class:`~.OpenGLMobject` to fit a depth while keeping width/height proportional.""" return self.rescale_to_fit(depth, 2, stretch=stretch, **kwargs) scale_to_fit_depth = set_depth - def set_coord(self, value, dim, direction=ORIGIN): + def set_coord(self, value: float, dim: int, direction: Vector3D = ORIGIN) -> Self: curr = self.get_coord(dim, direction) shift_vect = np.zeros(self.dim) shift_vect[dim] = value - curr self.shift(shift_vect) return self - def set_x(self, x, direction=ORIGIN): + def set_x(self, x: float, direction: Vector3D = ORIGIN) -> Self: """Set x value of the center of the :class:`~.OpenGLMobject` (``int`` or ``float``)""" return self.set_coord(x, 0, direction) - def set_y(self, y, direction=ORIGIN): + def set_y(self, y: float, direction: Vector3D = ORIGIN) -> Self: """Set y value of the center of the :class:`~.OpenGLMobject` (``int`` or ``float``)""" return self.set_coord(y, 1, direction) - def set_z(self, z, direction=ORIGIN): + def set_z(self, z: float, direction: Vector3D = ORIGIN) -> Self: """Set z value of the center of the :class:`~.OpenGLMobject` (``int`` or ``float``)""" return self.set_coord(z, 2, direction) - def space_out_submobjects(self, factor=1.5, **kwargs): + def space_out_submobjects(self, factor: float = 1.5, **kwargs) -> Self: self.scale(factor, **kwargs) for submob in self.submobjects: submob.scale(1.0 / factor) @@ -1804,10 +1994,10 @@ def space_out_submobjects(self, factor=1.5, **kwargs): def move_to( self, - point_or_mobject, - aligned_edge=ORIGIN, - coor_mask=np.array([1, 1, 1]), - ): + point_or_mobject: Point3DLike | OpenGLMobject, + aligned_edge: Vector3D = ORIGIN, + coor_mask: Point3DLike = np.array([1, 1, 1]), + ) -> Self: """Move center of the :class:`~.OpenGLMobject` to certain coordinate.""" if isinstance(point_or_mobject, OpenGLMobject): target = point_or_mobject.get_bounding_box_point(aligned_edge) @@ -1817,7 +2007,12 @@ def move_to( self.shift((target - point_to_align) * coor_mask) return self - def replace(self, mobject, dim_to_match=0, stretch=False): + def replace( + self, + mobject: OpenGLMobject, + dim_to_match: int = 0, + stretch: bool = False, + ) -> Self: if not mobject.get_num_points() and not mobject.submobjects: self.scale(0) return self @@ -1839,13 +2034,13 @@ def surround( dim_to_match: int = 0, stretch: bool = False, buff: float = MED_SMALL_BUFF, - ): + ) -> Self: self.replace(mobject, dim_to_match, stretch) length = mobject.length_over_dim(dim_to_match) self.scale((length + buff) / length) return self - def put_start_and_end_on(self, start, end): + def put_start_and_end_on(self, start: Point3DLike, end: Point3DLike) -> Self: curr_start, curr_end = self.get_start_and_end() curr_vect = curr_end - curr_start if np.all(curr_vect == 0): @@ -1870,7 +2065,13 @@ def put_start_and_end_on(self, start, end): # Color functions - def set_rgba_array(self, color=None, opacity=None, name="rgbas", recurse=True): + def set_rgba_array( + self, + color: ParsableManimColor | Iterable[ParsableManimColor] | None = None, + opacity: float | Iterable[float] | None = None, + name: str = "rgbas", + recurse: bool = True, + ) -> Self: if color is not None: rgbs = np.array([color_to_rgb(c) for c in listify(color)]) if opacity is not None: @@ -1900,7 +2101,12 @@ def set_rgba_array(self, color=None, opacity=None, name="rgbas", recurse=True): mob.data[name] = rgbas.copy() return self - def set_rgba_array_direct(self, rgbas: np.ndarray, name="rgbas", recurse=True): + def set_rgba_array_direct( + self, + rgbas: npt.NDArray[RGBA_Array_Float], + name: str = "rgbas", + recurse: bool = True, + ) -> Self: """Directly set rgba data from `rgbas` and optionally do the same recursively with submobjects. This can be used if the `rgbas` have already been generated with the correct shape and simply need to be set. @@ -1917,12 +2123,17 @@ def set_rgba_array_direct(self, rgbas: np.ndarray, name="rgbas", recurse=True): for mob in self.get_family(recurse): mob.data[name] = rgbas.copy() - def set_color(self, color, opacity=None, recurse=True): + def set_color( + self, + color: ParsableManimColor | Iterable[ParsableManimColor] | None, + opacity: float | Iterable[float] | None = None, + recurse: bool = True, + ) -> Self: self.set_rgba_array(color, opacity, recurse=False) # Recurse to submobjects differently from how set_rgba_array # in case they implement set_color differently if color is not None: - self.color = Color(color) + self.color: ManimColor = ManimColor.parse(color) if opacity is not None: self.opacity = opacity if recurse: @@ -1930,24 +2141,25 @@ def set_color(self, color, opacity=None, recurse=True): submob.set_color(color, recurse=True) return self - def set_opacity(self, opacity, recurse=True): + def set_opacity( + self, opacity: float | Iterable[float] | None, recurse: bool = True + ) -> Self: self.set_rgba_array(color=None, opacity=opacity, recurse=False) if recurse: for submob in self.submobjects: submob.set_opacity(opacity, recurse=True) return self - def get_color(self): + def get_color(self) -> str: return rgb_to_hex(self.rgbas[0, :3]) - def get_opacity(self): + def get_opacity(self) -> float: return self.rgbas[0, 3] - def set_color_by_gradient(self, *colors): - self.set_submobject_colors_by_gradient(*colors) - return self + def set_color_by_gradient(self, *colors: ParsableManimColor) -> Self: + return self.set_submobject_colors_by_gradient(*colors) - def set_submobject_colors_by_gradient(self, *colors): + def set_submobject_colors_by_gradient(self, *colors: ParsableManimColor) -> Self: if len(colors) == 0: raise Exception("Need at least one color") elif len(colors) == 1: @@ -1961,21 +2173,21 @@ def set_submobject_colors_by_gradient(self, *colors): mob.set_color(color) return self - def fade(self, darkness=0.5, recurse=True): - self.set_opacity(1.0 - darkness, recurse=recurse) + def fade(self, darkness: float = 0.5, recurse: bool = True) -> Self: + return self.set_opacity(1.0 - darkness, recurse=recurse) - def get_gloss(self): + def get_gloss(self) -> float: return self.gloss - def set_gloss(self, gloss, recurse=True): + def set_gloss(self, gloss: float, recurse: bool = True) -> Self: for mob in self.get_family(recurse): mob.gloss = gloss return self - def get_shadow(self): + def get_shadow(self) -> float: return self.shadow - def set_shadow(self, shadow, recurse=True): + def set_shadow(self, shadow: float, recurse: bool = True) -> Self: for mob in self.get_family(recurse): mob.shadow = shadow return self @@ -1983,8 +2195,11 @@ def set_shadow(self, shadow, recurse=True): # Background rectangle def add_background_rectangle( - self, color: Colors | None = None, opacity: float = 0.75, **kwargs - ): + self, + color: ParsableManimColor | None = None, + opacity: float = 0.75, + **kwargs, + ) -> Self: # TODO, this does not behave well when the mobject has points, # since it gets displayed on top """Add a BackgroundRectangle as submobject. @@ -2022,39 +2237,39 @@ def add_background_rectangle( self.add_to_back(self.background_rectangle) return self - def add_background_rectangle_to_submobjects(self, **kwargs): + def add_background_rectangle_to_submobjects(self, **kwargs) -> Self: for submobject in self.submobjects: submobject.add_background_rectangle(**kwargs) return self - def add_background_rectangle_to_family_members_with_points(self, **kwargs): + def add_background_rectangle_to_family_members_with_points(self, **kwargs) -> Self: for mob in self.family_members_with_points(): mob.add_background_rectangle(**kwargs) return self # Getters - def get_bounding_box_point(self, direction): + def get_bounding_box_point(self, direction: Vector3D) -> Point3D: bb = self.get_bounding_box() indices = (np.sign(direction) + 1).astype(int) return np.array([bb[indices[i]][i] for i in range(3)]) - def get_edge_center(self, direction) -> np.ndarray: + def get_edge_center(self, direction: Vector3D) -> Point3D: """Get edge coordinates for certain direction.""" return self.get_bounding_box_point(direction) - def get_corner(self, direction) -> np.ndarray: + def get_corner(self, direction: Vector3D) -> Point3D: """Get corner coordinates for certain direction.""" return self.get_bounding_box_point(direction) - def get_center(self) -> np.ndarray: + def get_center(self) -> Point3D: """Get center coordinates.""" return self.get_bounding_box()[1] - def get_center_of_mass(self): + def get_center_of_mass(self) -> Point3D: return self.get_all_points().mean(0) - def get_boundary_point(self, direction): + def get_boundary_point(self, direction: Vector3D) -> Point3D: all_points = self.get_all_points() boundary_directions = all_points - self.get_center() norms = np.linalg.norm(boundary_directions, axis=1) @@ -2062,7 +2277,7 @@ def get_boundary_point(self, direction): index = np.argmax(np.dot(boundary_directions, np.array(direction).T)) return all_points[index] - def get_continuous_bounding_box_point(self, direction): + def get_continuous_bounding_box_point(self, direction: Vector3D) -> Point3D: dl, center, ur = self.get_bounding_box() corner_vect = ur - center return center + direction / np.max( @@ -2076,86 +2291,86 @@ def get_continuous_bounding_box_point(self, direction): ), ) - def get_top(self) -> np.ndarray: + def get_top(self) -> Point3D: """Get top coordinates of a box bounding the :class:`~.OpenGLMobject`""" return self.get_edge_center(UP) - def get_bottom(self) -> np.ndarray: + def get_bottom(self) -> Point3D: """Get bottom coordinates of a box bounding the :class:`~.OpenGLMobject`""" return self.get_edge_center(DOWN) - def get_right(self) -> np.ndarray: + def get_right(self) -> Point3D: """Get right coordinates of a box bounding the :class:`~.OpenGLMobject`""" return self.get_edge_center(RIGHT) - def get_left(self) -> np.ndarray: + def get_left(self) -> Point3D: """Get left coordinates of a box bounding the :class:`~.OpenGLMobject`""" return self.get_edge_center(LEFT) - def get_zenith(self) -> np.ndarray: + def get_zenith(self) -> Point3D: """Get zenith coordinates of a box bounding a 3D :class:`~.OpenGLMobject`.""" return self.get_edge_center(OUT) - def get_nadir(self) -> np.ndarray: + def get_nadir(self) -> Point3D: """Get nadir (opposite the zenith) coordinates of a box bounding a 3D :class:`~.OpenGLMobject`.""" return self.get_edge_center(IN) - def length_over_dim(self, dim): + def length_over_dim(self, dim: int) -> float: bb = self.get_bounding_box() return abs((bb[2] - bb[0])[dim]) - def get_width(self): + def get_width(self) -> float: """Returns the width of the mobject.""" return self.length_over_dim(0) - def get_height(self): + def get_height(self) -> float: """Returns the height of the mobject.""" return self.length_over_dim(1) - def get_depth(self): + def get_depth(self) -> float: """Returns the depth of the mobject.""" return self.length_over_dim(2) - def get_coord(self, dim: int, direction=ORIGIN): + def get_coord(self, dim: int, direction: Vector3D = ORIGIN) -> ManimFloat: """Meant to generalize ``get_x``, ``get_y`` and ``get_z``""" return self.get_bounding_box_point(direction)[dim] - def get_x(self, direction=ORIGIN) -> np.float64: + def get_x(self, direction: Vector3D = ORIGIN) -> ManimFloat: """Returns x coordinate of the center of the :class:`~.OpenGLMobject` as ``float``""" return self.get_coord(0, direction) - def get_y(self, direction=ORIGIN) -> np.float64: + def get_y(self, direction: Vector3D = ORIGIN) -> ManimFloat: """Returns y coordinate of the center of the :class:`~.OpenGLMobject` as ``float``""" return self.get_coord(1, direction) - def get_z(self, direction=ORIGIN) -> np.float64: + def get_z(self, direction: Vector3D = ORIGIN) -> ManimFloat: """Returns z coordinate of the center of the :class:`~.OpenGLMobject` as ``float``""" return self.get_coord(2, direction) - def get_start(self): + def get_start(self) -> Point3D: """Returns the point, where the stroke that surrounds the :class:`~.OpenGLMobject` starts.""" self.throw_error_if_no_points() return np.array(self.points[0]) - def get_end(self): + def get_end(self) -> Point3D: """Returns the point, where the stroke that surrounds the :class:`~.OpenGLMobject` ends.""" self.throw_error_if_no_points() return np.array(self.points[-1]) - def get_start_and_end(self): + def get_start_and_end(self) -> tuple[Point3D, Point3D]: """Returns starting and ending point of a stroke as a ``tuple``.""" return self.get_start(), self.get_end() - def point_from_proportion(self, alpha): + def point_from_proportion(self, alpha: float) -> Point3D: points = self.points i, subalpha = integer_interpolate(0, len(points) - 1, alpha) return interpolate(points[i], points[i + 1], subalpha) - def pfp(self, alpha): + def pfp(self, alpha: float) -> Point3D: """Abbreviation for point_from_proportion""" return self.point_from_proportion(alpha) - def get_pieces(self, n_pieces): + def get_pieces(self, n_pieces: int) -> OpenGLMobject: template = self.copy() template.submobjects = [] alphas = np.linspace(0, 1, n_pieces + 1) @@ -2166,34 +2381,36 @@ def get_pieces(self, n_pieces): ) ) - def get_z_index_reference_point(self): + def get_z_index_reference_point(self) -> Point3D: # TODO, better place to define default z_index_group? z_index_group = getattr(self, "z_index_group", self) return z_index_group.get_center() # Match other mobject properties - def match_color(self, mobject: OpenGLMobject): + def match_color(self, mobject: OpenGLMobject) -> Self: """Match the color with the color of another :class:`~.OpenGLMobject`.""" return self.set_color(mobject.get_color()) - def match_dim_size(self, mobject: OpenGLMobject, dim, **kwargs): + def match_dim_size(self, mobject: OpenGLMobject, dim: int, **kwargs) -> Self: """Match the specified dimension with the dimension of another :class:`~.OpenGLMobject`.""" return self.rescale_to_fit(mobject.length_over_dim(dim), dim, **kwargs) - def match_width(self, mobject: OpenGLMobject, **kwargs): + def match_width(self, mobject: OpenGLMobject, **kwargs) -> Self: """Match the width with the width of another :class:`~.OpenGLMobject`.""" return self.match_dim_size(mobject, 0, **kwargs) - def match_height(self, mobject: OpenGLMobject, **kwargs): + def match_height(self, mobject: OpenGLMobject, **kwargs) -> Self: """Match the height with the height of another :class:`~.OpenGLMobject`.""" return self.match_dim_size(mobject, 1, **kwargs) - def match_depth(self, mobject: OpenGLMobject, **kwargs): + def match_depth(self, mobject: OpenGLMobject, **kwargs) -> Self: """Match the depth with the depth of another :class:`~.OpenGLMobject`.""" return self.match_dim_size(mobject, 2, **kwargs) - def match_coord(self, mobject: OpenGLMobject, dim, direction=ORIGIN): + def match_coord( + self, mobject: OpenGLMobject, dim: int, direction: Vector3D = ORIGIN + ) -> Self: """Match the coordinates with the coordinates of another :class:`~.OpenGLMobject`.""" return self.set_coord( mobject.get_coord(dim, direction), @@ -2201,23 +2418,23 @@ def match_coord(self, mobject: OpenGLMobject, dim, direction=ORIGIN): direction=direction, ) - def match_x(self, mobject, direction=ORIGIN): + def match_x(self, mobject: OpenGLMobject, direction: Vector3D = ORIGIN) -> Self: """Match x coord. to the x coord. of another :class:`~.OpenGLMobject`.""" return self.match_coord(mobject, 0, direction) - def match_y(self, mobject, direction=ORIGIN): + def match_y(self, mobject: OpenGLMobject, direction: Vector3D = ORIGIN) -> Self: """Match y coord. to the x coord. of another :class:`~.OpenGLMobject`.""" return self.match_coord(mobject, 1, direction) - def match_z(self, mobject, direction=ORIGIN): + def match_z(self, mobject: OpenGLMobject, direction: Vector3D = ORIGIN) -> Self: """Match z coord. to the x coord. of another :class:`~.OpenGLMobject`.""" return self.match_coord(mobject, 2, direction) def align_to( self, - mobject_or_point: OpenGLMobject | Sequence[float], - direction=ORIGIN, - ): + mobject_or_point: OpenGLMobject | Point3DLike, + direction: Vector3D = ORIGIN, + ) -> Self: """ Examples: mob1.align_to(mob2, UP) moves mob1 vertically so that its @@ -2237,16 +2454,22 @@ def align_to( self.set_coord(point[dim], dim, direction) return self - def get_group_class(self): + def get_group_class(self) -> type[OpenGLGroup]: return OpenGLGroup + @staticmethod + def get_mobject_type_class() -> type[OpenGLMobject]: + """Return the base class of this mobject type.""" + return OpenGLMobject + # Alignment - def align_data_and_family(self, mobject): + def align_data_and_family(self, mobject: OpenGLMobject) -> Self: self.align_family(mobject) self.align_data(mobject) + return self - def align_data(self, mobject): + def align_data(self, mobject: OpenGLMobject) -> Self: # In case any data arrays get resized when aligned to shader data # self.refresh_shader_data() for mob1, mob2 in zip(self.get_family(), mobject.get_family()): @@ -2262,14 +2485,15 @@ def align_data(self, mobject): mob1.data[key] = resize_preserving_order(arr1, len(arr2)) elif len(arr1) > len(arr2): mob2.data[key] = resize_preserving_order(arr2, len(arr1)) + return self - def align_points(self, mobject): + def align_points(self, mobject: OpenGLMobject) -> Self: max_len = max(self.get_num_points(), mobject.get_num_points()) for mob in (self, mobject): mob.resize_points(max_len, resize_func=resize_preserving_order) return self - def align_family(self, mobject): + def align_family(self, mobject: OpenGLMobject) -> Self: mob1 = self mob2 = mobject n1 = len(mob1) @@ -2282,14 +2506,14 @@ def align_family(self, mobject): sm1.align_family(sm2) return self - def push_self_into_submobjects(self): + def push_self_into_submobjects(self) -> Self: copy = self.deepcopy() copy.submobjects = [] self.resize_points(0) self.add(copy) return self - def add_n_more_submobjects(self, n): + def add_n_more_submobjects(self, n: int) -> Self: if n == 0: return self @@ -2318,7 +2542,13 @@ def add_n_more_submobjects(self, n): # Interpolate - def interpolate(self, mobject1, mobject2, alpha, path_func=straight_path()): + def interpolate( + self, + mobject1: OpenGLMobject, + mobject2: OpenGLMobject, + alpha: float, + path_func: PathFuncType = straight_path(), + ) -> Self: """Turns this :class:`~.OpenGLMobject` into an interpolation between ``mobject1`` and ``mobject2``. @@ -2347,12 +2577,10 @@ def construct(self): if key not in mobject1.data or key not in mobject2.data: continue - if key in ("points", "bounding_box"): - func = path_func - else: - func = interpolate + func = path_func if key in ("points", "bounding_box") else interpolate self.data[key][:] = func(mobject1.data[key], mobject2.data[key], alpha) + for key in self.uniforms: if key != "fixed_orientation_center": self.uniforms[key] = interpolate( @@ -2370,7 +2598,9 @@ def construct(self): ) return self - def pointwise_become_partial(self, mobject, a, b): + def pointwise_become_partial( + self, mobject: OpenGLMobject, a: float, b: float + ) -> None: """ Set points in such a way as to become only part of mobject. @@ -2387,7 +2617,7 @@ def become( match_depth: bool = False, match_center: bool = False, stretch: bool = False, - ): + ) -> Self: """Edit all data and submobjects to be identical to another :class:`~.OpenGLMobject` @@ -2422,7 +2652,6 @@ def construct(self): circ.become(square) self.wait(0.5) """ - if stretch: mobject.stretch_to_fit_height(self.height) mobject.stretch_to_fit_width(self.width) @@ -2447,7 +2676,7 @@ def construct(self): # Locking data - def lock_data(self, keys): + def lock_data(self, keys: Iterable[str]) -> None: """ To speed up some animations, particularly transformations, it can be handy to acknowledge which pieces of data @@ -2461,7 +2690,9 @@ def lock_data(self, keys): self.refresh_shader_data() self.locked_data_keys = set(keys) - def lock_matching_data(self, mobject1, mobject2): + def lock_matching_data( + self, mobject1: OpenGLMobject, mobject2: OpenGLMobject + ) -> Self: for sm, sm1, sm2 in zip( self.get_family(), mobject1.get_family(), @@ -2478,67 +2709,57 @@ def lock_matching_data(self, mobject1, mobject2): ) return self - def unlock_data(self): + def unlock_data(self) -> None: for mob in self.get_family(): mob.locked_data_keys = set() # Operations touching shader uniforms - def affects_shader_info_id(func): - @wraps(func) - def wrapper(self): - for mob in self.get_family(): - func(mob) - # mob.refresh_shader_wrapper_id() - return self - - return wrapper - @affects_shader_info_id - def fix_in_frame(self): + def fix_in_frame(self) -> Self: self.is_fixed_in_frame = 1.0 return self @affects_shader_info_id - def fix_orientation(self): + def fix_orientation(self) -> Self: self.is_fixed_orientation = 1.0 self.fixed_orientation_center = tuple(self.get_center()) self.depth_test = True return self @affects_shader_info_id - def unfix_from_frame(self): + def unfix_from_frame(self) -> Self: self.is_fixed_in_frame = 0.0 return self @affects_shader_info_id - def unfix_orientation(self): + def unfix_orientation(self) -> Self: self.is_fixed_orientation = 0.0 self.fixed_orientation_center = (0, 0, 0) self.depth_test = False return self @affects_shader_info_id - def apply_depth_test(self): + def apply_depth_test(self) -> Self: self.depth_test = True return self @affects_shader_info_id - def deactivate_depth_test(self): + def deactivate_depth_test(self) -> Self: self.depth_test = False return self # Shader code manipulation - def replace_shader_code(self, old, new): + def replace_shader_code(self, old_code: str, new_code: str) -> Self: # TODO, will this work with VMobject structure, given # that it does not simpler return shader_wrappers of # family? for wrapper in self.get_shader_wrapper_list(): - wrapper.replace_code(old, new) + wrapper.replace_code(old_code, new_code) return self - def set_color_by_code(self, glsl_code): + def set_color_by_code(self, glsl_code: str) -> Self: """ Takes a snippet of code and inserts it into a context which has the following variables: @@ -2550,11 +2771,11 @@ def set_color_by_code(self, glsl_code): def set_color_by_xyz_func( self, - glsl_snippet, - min_value=-5.0, - max_value=5.0, - colormap="viridis", - ): + glsl_snippet: str, + min_value: float = -5.0, + max_value: float = 5.0, + colormap: str = "viridis", + ) -> Self: """ Pass in a glsl expression in terms of x, y and z which returns a float. @@ -2565,24 +2786,22 @@ def set_color_by_xyz_func( glsl_snippet = glsl_snippet.replace(char, "point." + char) rgb_list = get_colormap_list(colormap) self.set_color_by_code( - "color.rgb = float_to_color({}, {}, {}, {});".format( - glsl_snippet, - float(min_value), - float(max_value), - get_colormap_code(rgb_list), - ), + f"color.rgb = float_to_color({glsl_snippet}, {float(min_value)}, {float(max_value)}, {get_colormap_code(rgb_list)});", ) return self # For shader data - # def refresh_shader_wrapper_id(self): - # self.shader_wrapper.refresh_id() - # return self + def refresh_shader_wrapper_id(self) -> Self: + self.get_shader_wrapper().refresh_id() + return self - def get_shader_wrapper(self): + def get_shader_wrapper(self) -> ShaderWrapper: from manim.renderer.shader_wrapper import ShaderWrapper + # if hasattr(self, "__shader_wrapper"): + # return self.__shader_wrapper + self.shader_wrapper = ShaderWrapper( vert_data=self.get_shader_data(), vert_indices=self.get_shader_vert_indices(), @@ -2594,7 +2813,7 @@ def get_shader_wrapper(self): ) return self.shader_wrapper - def get_shader_wrapper_list(self): + def get_shader_wrapper_list(self) -> Sequence[ShaderWrapper]: shader_wrappers = it.chain( [self.get_shader_wrapper()], *(sm.get_shader_wrapper_list() for sm in self.submobjects), @@ -2611,7 +2830,7 @@ def get_shader_wrapper_list(self): result.append(shader_wrapper) return result - def check_data_alignment(self, array, data_key): + def check_data_alignment(self, array: npt.NDArray, data_key: str) -> Self: # Makes sure that self.data[key] can be broadcast into # the given array, meaning its length has to be either 1 # or the length of the array @@ -2623,45 +2842,50 @@ def check_data_alignment(self, array, data_key): ) return self - def get_resized_shader_data_array(self, length): + def get_resized_shader_data_array(self, length: float) -> npt.NDArray: # If possible, try to populate an existing array, rather # than recreating it each frame points = self.points shader_data = np.zeros(len(points), dtype=self.shader_dtype) return shader_data - def read_data_to_shader(self, shader_data, shader_data_key, data_key): + def read_data_to_shader( + self, + shader_data: npt.NDArray, # has structured data type, ex. ("point", np.float32, (3,)) + shader_data_key: str, + data_key: str, + ) -> None: if data_key in self.locked_data_keys: return self.check_data_alignment(shader_data, data_key) shader_data[shader_data_key] = self.data[data_key] - def get_shader_data(self): + def get_shader_data(self) -> npt.NDArray: shader_data = self.get_resized_shader_data_array(self.get_num_points()) self.read_data_to_shader(shader_data, "point", "points") return shader_data - def refresh_shader_data(self): + def refresh_shader_data(self) -> None: self.get_shader_data() - def get_shader_uniforms(self): + def get_shader_uniforms(self) -> dict[str, Any]: return self.uniforms - def get_shader_vert_indices(self): + def get_shader_vert_indices(self) -> Sequence[int]: return self.shader_indices @property - def submobjects(self): + def submobjects(self) -> Sequence[OpenGLMobject]: return self._submobjects if hasattr(self, "_submobjects") else [] @submobjects.setter - def submobjects(self, submobject_list): + def submobjects(self, submobject_list: Iterable[OpenGLMobject]) -> None: self.remove(*self.submobjects) self.add(*submobject_list) # Errors - def throw_error_if_no_points(self): + def throw_error_if_no_points(self) -> None: if not self.has_points(): message = ( "Cannot call OpenGLMobject.{} " + "for a OpenGLMobject with no points" @@ -2671,40 +2895,42 @@ def throw_error_if_no_points(self): class OpenGLGroup(OpenGLMobject): - def __init__(self, *mobjects, **kwargs): - if not all([isinstance(m, OpenGLMobject) for m in mobjects]): - raise Exception("All submobjects must be of type OpenGLMobject") + def __init__(self, *mobjects: OpenGLMobject, **kwargs): super().__init__(**kwargs) self.add(*mobjects) class OpenGLPoint(OpenGLMobject): def __init__( - self, location=ORIGIN, artificial_width=1e-6, artificial_height=1e-6, **kwargs + self, + location: Point3DLike = ORIGIN, + artificial_width: float = 1e-6, + artificial_height: float = 1e-6, + **kwargs, ): self.artificial_width = artificial_width self.artificial_height = artificial_height super().__init__(**kwargs) self.set_location(location) - def get_width(self): + def get_width(self) -> float: return self.artificial_width - def get_height(self): + def get_height(self) -> float: return self.artificial_height - def get_location(self): + def get_location(self) -> Point3D: return self.points[0].copy() - def get_bounding_box_point(self, *args, **kwargs): + def get_bounding_box_point(self, *args, **kwargs) -> Point3D: return self.get_location() - def set_location(self, new_loc): + def set_location(self, new_loc: Point3D) -> None: self.set_points(np.array(new_loc, ndmin=2, dtype=float)) class _AnimationBuilder: - def __init__(self, mobject): + def __init__(self, mobject: OpenGLMobject): self.mobject = mobject self.mobject.generate_target() @@ -2716,7 +2942,7 @@ def __init__(self, mobject): self.cannot_pass_args = False self.anim_args = {} - def __call__(self, **kwargs): + def __call__(self, **kwargs) -> Self: if self.cannot_pass_args: raise ValueError( "Animation arguments must be passed before accessing methods and can only be passed once", @@ -2727,15 +2953,13 @@ def __call__(self, **kwargs): return self - def __getattr__(self, method_name): + def __getattr__(self, method_name: str) -> Callable[..., Self]: method = getattr(self.mobject.target, method_name) - self.methods.append(method) has_overridden_animation = hasattr(method, "_override_animate") if (self.is_chaining and has_overridden_animation) or self.overridden_animation: raise NotImplementedError( - "Method chaining is currently not supported for " - "overridden animations", + "Method chaining is currently not supported for overridden animations", ) def update_target(*method_args, **method_kwargs): @@ -2747,6 +2971,7 @@ def update_target(*method_args, **method_kwargs): **method_kwargs, ) else: + self.methods.append([method, method_args, method_kwargs]) method(*method_args, **method_kwargs) return self @@ -2755,7 +2980,7 @@ def update_target(*method_args, **method_kwargs): return update_target - def build(self): + def build(self) -> _MethodAnimation: from manim.animation.transform import _MethodAnimation if self.overridden_animation: @@ -2769,7 +2994,7 @@ def build(self): return anim -def override_animate(method): +def override_animate(method: types.FunctionType) -> types.FunctionType: r"""Decorator for overriding method animations. This allows to specify a method (returning an :class:`~.Animation`) diff --git a/manim/mobject/opengl/opengl_point_cloud_mobject.py b/manim/mobject/opengl/opengl_point_cloud_mobject.py index 1732b23dc5..1725eccee8 100644 --- a/manim/mobject/opengl/opengl_point_cloud_mobject.py +++ b/manim/mobject/opengl/opengl_point_cloud_mobject.py @@ -12,6 +12,8 @@ from manim.utils.config_ops import _Uniforms from manim.utils.iterables import resize_with_interpolation +__all__ = ["OpenGLPMobject", "OpenGLPGroup", "OpenGLPMPoint"] + class OpenGLPMobject(OpenGLMobject): shader_folder = "true_dot" @@ -63,13 +65,11 @@ def add_points(self, points, rgbas=None, color=None, opacity=None): return self def thin_out(self, factor=5): - """ - Removes all but every nth point for n = factor - """ + """Removes all but every nth point for n = factor""" for mob in self.family_members_with_points(): num_points = mob.get_num_points() - def thin_func(): + def thin_func(num_points=num_points): return np.arange(0, num_points, factor) if len(mob.points) == len(mob.rgbas): @@ -124,9 +124,7 @@ def filter_out(self, condition): return self def sort_points(self, function=lambda p: p[0]): - """ - function is any map from R^3 to R - """ + """function is any map from R^3 to R""" for mob in self.family_members_with_points(): indices = np.argsort(np.apply_along_axis(function, 1, mob.points)) for key in mob.data: @@ -155,10 +153,14 @@ def get_shader_data(self): self.read_data_to_shader(shader_data, "color", "rgbas") return shader_data + @staticmethod + def get_mobject_type_class(): + return OpenGLPMobject + class OpenGLPGroup(OpenGLPMobject): def __init__(self, *pmobs, **kwargs): - if not all([isinstance(m, OpenGLPMobject) for m in pmobs]): + if not all(isinstance(m, OpenGLPMobject) for m in pmobs): raise Exception("All submobjects must be of type OpenglPMObject") super().__init__(**kwargs) self.add(*pmobs) diff --git a/manim/mobject/opengl/opengl_surface.py b/manim/mobject/opengl/opengl_surface.py index 1d72d56a8d..565b8c71cf 100644 --- a/manim/mobject/opengl/opengl_surface.py +++ b/manim/mobject/opengl/opengl_surface.py @@ -1,19 +1,56 @@ from __future__ import annotations +from collections.abc import Iterable +from pathlib import Path + import moderngl import numpy as np +from PIL import Image from manim.constants import * from manim.mobject.opengl.opengl_mobject import OpenGLMobject from manim.utils.bezier import integer_interpolate, interpolate from manim.utils.color import * from manim.utils.config_ops import _Data, _Uniforms -from manim.utils.images import get_full_raster_image_path +from manim.utils.images import change_to_rgba_array, get_full_raster_image_path from manim.utils.iterables import listify from manim.utils.space_ops import normalize_along_axis +__all__ = ["OpenGLSurface", "OpenGLTexturedSurface"] + class OpenGLSurface(OpenGLMobject): + r"""Creates a Surface. + + Parameters + ---------- + uv_func + The function that defines the surface. + u_range + The range of the ``u`` variable: ``(u_min, u_max)``. + v_range + The range of the ``v`` variable: ``(v_min, v_max)``. + resolution + The number of samples taken of the surface. + axes + Axes on which the surface is to be drawn. Optional + parameter used when coloring a surface by z-value. + color + Color of the surface. Defaults to grey. + colorscale + Colors of the surface. Optional parameter used when + coloring a surface by values. Passing a list of + colors and an axes will color the surface by z-value. + Passing a list of tuples in the form ``(color, pivot)`` + allows user-defined pivots where the color transitions. + colorscale_axis + Defines the axis on which the colorscale is applied + (0 = x, 1 = y, 2 = z), default is z-axis (2). + opacity + Opacity of the surface from 0 being fully transparent + to 1 being fully opaque. Defaults to 1. + """ + shader_dtype = [ ("point", np.float32, (3,)), ("du_point", np.float32, (3,)), @@ -31,7 +68,10 @@ def __init__( # each coordinate is one more than the the number of # rows/columns of approximating squares resolution=None, + axes=None, color=GREY, + colorscale=None, + colorscale_axis=2, opacity=1.0, gloss=0.3, shadow=0.4, @@ -51,11 +91,15 @@ def __init__( # each coordinate is one more than the the number of # rows/columns of approximating squares self.resolution = resolution if resolution is not None else (101, 101) + self.axes = axes + self.colorscale = colorscale + self.colorscale_axis = colorscale_axis self.prefered_creation_axis = prefered_creation_axis # For du and dv steps. Much smaller and numerical error # can crop up in the shaders. self.epsilon = epsilon + self.triangle_indices = None super().__init__( color=color, opacity=opacity, @@ -85,7 +129,7 @@ def init_points(self): # - Those generated by values nudged by du # - Those generated by values nudged by dv point_lists = [] - for (du, dv) in [(0, 0), (self.epsilon, 0), (0, self.epsilon)]: + for du, dv in [(0, 0), (self.epsilon, 0), (0, self.epsilon)]: uv_grid = np.array([[[u + du, v + dv] for v in v_range] for u in u_range]) point_grid = np.apply_along_axis(lambda p: self.uv_func(*p), 2, uv_grid) point_lists.append(point_grid.reshape((nu * nv, dim))) @@ -202,71 +246,70 @@ def index_dot(index): # For shaders def get_shader_data(self): + """Called by parent Mobject to calculate and return + the shader data. + + Returns + ------- + shader_dtype + An array containing the shader data (vertices and + color of each vertex) + """ s_points, du_points, dv_points = self.get_surface_points_and_nudged_points() shader_data = np.zeros(len(s_points), dtype=self.shader_dtype) if "points" not in self.locked_data_keys: shader_data["point"] = s_points shader_data["du_point"] = du_points shader_data["dv_point"] = dv_points - self.fill_in_shader_color_info(shader_data) + if self.colorscale: + if not hasattr(self, "color_by_val"): + self.color_by_val = self._get_color_by_value(s_points) + shader_data["color"] = self.color_by_val + else: + self.fill_in_shader_color_info(shader_data) return shader_data def fill_in_shader_color_info(self, shader_data): + """Fills in the shader color data when the surface + is all one color. + + Parameters + ---------- + shader_data + The vertices of the surface. + + Returns + ------- + shader_dtype + An array containing the shader data (vertices and + color of each vertex) + """ self.read_data_to_shader(shader_data, "color", "rgbas") return shader_data - def get_shader_vert_indices(self): - return self.get_triangle_indices() - - def set_fill_by_value(self, axes, colors): - # directly copied from three_dimensions.py with some compatibility changes. - """Sets the color of each mobject of a parametric surface to a color relative to its z-value + def _get_color_by_value(self, s_points): + """Matches each vertex to a color associated to it's z-value. Parameters ---------- - axes : - The axes for the parametric surface, which will be used to map z-values to colors. - colors : - A list of colors, ordered from lower z-values to higher z-values. If a list of tuples is passed - containing colors paired with numbers, then those numbers will be used as the pivots. + s_points + The vertices of the surface. Returns ------- - :class:`~.Surface` - The parametric surface with a gradient applied by value. For chaining. - - Examples - -------- - .. manim:: FillByValueExample - :save_last_frame: - - class FillByValueExample(ThreeDScene): - def construct(self): - resolution_fa = 42 - self.set_camera_orientation(phi=75 * DEGREES, theta=-120 * DEGREES) - axes = ThreeDAxes(x_range=(0, 5, 1), y_range=(0, 5, 1), z_range=(-1, 1, 0.5)) - def param_surface(u, v): - x = u - y = v - z = np.sin(x) * np.cos(y) - return z - surface_plane = Surface( - lambda u, v: axes.c2p(u, v, param_surface(u, v)), - resolution=(resolution_fa, resolution_fa), - v_range=[0, 5], - u_range=[0, 5], - ) - # surface_plane.set_style(fill_opacity=1) - surface_plane.set_fill_by_value(axes=axes, colors=[(RED, -0.4), (YELLOW, 0), (GREEN, 0.4)]) - self.add(axes, surface_plane) + List + A list of colors matching the vertex inputs. """ - if type(colors[0]) is tuple: - new_colors, pivots = [[i for i, j in colors], [j for i, j in colors]] + if type(self.colorscale[0]) in (list, tuple): + new_colors, pivots = [ + [i for i, j in self.colorscale], + [j for i, j in self.colorscale], + ] else: - new_colors = colors + new_colors = self.colorscale - pivot_min = axes.z_range[0] - pivot_max = axes.z_range[1] + pivot_min = self.axes.z_range[0] + pivot_max = self.axes.z_range[1] pivot_frequency = (pivot_max - pivot_min) / (len(new_colors) - 1) pivots = np.arange( start=pivot_min, @@ -274,30 +317,32 @@ def param_surface(u, v): step=pivot_frequency, ) - for mob in self.family_members_with_points(): - # import ipdb; ipdb.set_trace(context=7) - z_value = axes.point_to_coords(mob.get_midpoint())[2] - if z_value <= pivots[0]: - mob.set_color(new_colors[0]) - elif z_value >= pivots[-1]: - mob.set_color(new_colors[-1]) + return_colors = [] + for point in s_points: + axis_value = self.axes.point_to_coords(point)[self.colorscale_axis] + if axis_value <= pivots[0]: + return_colors.append(color_to_rgba(new_colors[0], self.opacity)) + elif axis_value >= pivots[-1]: + return_colors.append(color_to_rgba(new_colors[-1], self.opacity)) else: for i, pivot in enumerate(pivots): - if pivot > z_value: - color_index = (z_value - pivots[i - 1]) / ( + if pivot > axis_value: + color_index = (axis_value - pivots[i - 1]) / ( pivots[i] - pivots[i - 1] ) - color_index = min(color_index, 1) - mob_color = interpolate_color( + color_index = max(min(color_index, 1), 0) + temp_color = interpolate_color( new_colors[i - 1], new_colors[i], color_index, ) - mob.set_color(mob_color, recurse=False) - break + return_colors.append(color_to_rgba(temp_color, self.opacity)) - return self + return return_colors + + def get_shader_vert_indices(self): + return self.get_triangle_indices() class OpenGLSurfaceGroup(OpenGLSurface): @@ -324,22 +369,37 @@ class OpenGLTexturedSurface(OpenGLSurface): num_textures = _Uniforms() def __init__( - self, uv_surface, image_file, dark_image_file=None, shader_folder=None, **kwargs + self, + uv_surface: OpenGLSurface, + image_file: str | Path, + dark_image_file: str | Path = None, + image_mode: str | Iterable[str] = "RGBA", + shader_folder: str | Path = None, + **kwargs, ): self.uniforms = {} if not isinstance(uv_surface, OpenGLSurface): raise Exception("uv_surface must be of type OpenGLSurface") + if isinstance(image_file, np.ndarray): + image_file = change_to_rgba_array(image_file) + # Set texture information - if dark_image_file is None: - dark_image_file = image_file - self.num_textures = 1 - else: - self.num_textures = 2 + if isinstance(image_mode, (str, Path)): + image_mode = [image_mode] * 2 + image_mode_light, image_mode_dark = image_mode texture_paths = { - "LightTexture": get_full_raster_image_path(image_file), - "DarkTexture": get_full_raster_image_path(dark_image_file), + "LightTexture": self.get_image_from_file( + image_file, + image_mode_light, + ), + "DarkTexture": self.get_image_from_file( + dark_image_file or image_file, + image_mode_dark, + ), } + if dark_image_file: + self.num_textures = 2 self.uv_surface = uv_surface self.uv_func = uv_surface.uv_func @@ -349,6 +409,14 @@ def __init__( self.gloss = self.uv_surface.gloss super().__init__(texture_paths=texture_paths, **kwargs) + def get_image_from_file( + self, + image_file: str | Path, + image_mode: str, + ): + image_file = get_full_raster_image_path(image_file) + return Image.open(image_file).convert(image_mode) + def init_data(self): super().init_data() self.im_coords = np.zeros((0, 2)) diff --git a/manim/mobject/opengl/opengl_three_dimensions.py b/manim/mobject/opengl/opengl_three_dimensions.py index 097d5739b9..930ff9ef20 100644 --- a/manim/mobject/opengl/opengl_three_dimensions.py +++ b/manim/mobject/opengl/opengl_three_dimensions.py @@ -5,6 +5,8 @@ from manim.mobject.opengl.opengl_surface import OpenGLSurface from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVGroup, OpenGLVMobject +__all__ = ["OpenGLSurfaceMesh"] + class OpenGLSurfaceMesh(OpenGLVGroup): def __init__( diff --git a/manim/mobject/opengl/opengl_vectorized_mobject.py b/manim/mobject/opengl/opengl_vectorized_mobject.py index 46dffe11b2..b31934e999 100644 --- a/manim/mobject/opengl/opengl_vectorized_mobject.py +++ b/manim/mobject/opengl/opengl_vectorized_mobject.py @@ -2,12 +2,12 @@ import itertools as it import operator as op +from collections.abc import Iterable, Sequence from functools import reduce, wraps -from typing import Callable, Iterable, Sequence +from typing import Callable import moderngl import numpy as np -from colour import Color from manim import config from manim.constants import * @@ -15,16 +15,17 @@ from manim.renderer.shader_wrapper import ShaderWrapper from manim.utils.bezier import ( bezier, + bezier_remap, get_quadratic_approximation_of_cubic, get_smooth_cubic_bezier_handle_points, integer_interpolate, interpolate, - partial_quadratic_bezier_points, + partial_bezier_points, proportions_along_bezier_curve_for_point, ) -from manim.utils.color import * +from manim.utils.color import BLACK, WHITE, ManimColor, ParsableManimColor from manim.utils.config_ops import _Data -from manim.utils.iterables import listify, make_even, resize_with_interpolation +from manim.utils.iterables import make_even, resize_with_interpolation, tuplify from manim.utils.space_ops import ( angle_between_vectors, cross2d, @@ -34,12 +35,32 @@ z_to_vector, ) -JOINT_TYPE_MAP = { - "auto": 0, - "round": 1, - "bevel": 2, - "miter": 3, -} +__all__ = [ + "triggers_refreshed_triangulation", + "OpenGLVMobject", + "OpenGLVGroup", + "OpenGLVectorizedPoint", + "OpenGLCurvesAsSubmobjects", + "OpenGLDashedVMobject", +] + + +def triggers_refreshed_triangulation(func): + @wraps(func) + def wrapper(self, *args, **kwargs): + old_points = np.empty((0, 3)) + for mob in self.family_members_with_points(): + old_points = np.concatenate((old_points, mob.points), axis=0) + func(self, *args, **kwargs) + new_points = np.empty((0, 3)) + for mob in self.family_members_with_points(): + new_points = np.concatenate((new_points, mob.points), axis=0) + if not np.array_equal(new_points, old_points): + self.refresh_triangulation() + self.refresh_unit_normal() + return self + + return wrapper class OpenGLVMobject(OpenGLMobject): @@ -69,9 +90,9 @@ class OpenGLVMobject(OpenGLMobject): def __init__( self, - fill_color: Color | None = None, + fill_color: ParsableManimColor | None = None, fill_opacity: float = 0.0, - stroke_color: Color | None = None, + stroke_color: ParsableManimColor | None = None, stroke_opacity: float = 1.0, stroke_width: float = DEFAULT_STROKE_WIDTH, draw_stroke_behind_fill: bool = False, @@ -89,7 +110,7 @@ def __init__( should_subdivide_sharp_curves: bool = False, should_remove_null_curves: bool = False, # Could also be "bevel", "miter", "round" - joint_type: str = "auto", + joint_type: LineJointType | None = None, flat_stroke: bool = True, render_primitive=moderngl.TRIANGLES, triangulation_locked: bool = False, @@ -115,23 +136,16 @@ def __init__( self.long_lines = long_lines self.should_subdivide_sharp_curves = should_subdivide_sharp_curves self.should_remove_null_curves = should_remove_null_curves - # Could also be "bevel", "miter", "round" + if joint_type is None: + joint_type = LineJointType.AUTO self.joint_type = joint_type self.flat_stroke = flat_stroke self.render_primitive = render_primitive self.triangulation_locked = triangulation_locked - self.n_points_per_curve = n_points_per_curve self.needs_new_triangulation = True self.triangulation = np.zeros(0, dtype="i4") self.orientation = 1 - super().__init__(**kwargs) - self.refresh_unit_normal() - - if fill_color: - self.fill_color = Color(fill_color) - if stroke_color: - self.stroke_color = Color(stroke_color) self.fill_data = None self.stroke_data = None @@ -139,9 +153,24 @@ def __init__( self.stroke_shader_wrapper = None self.init_shader_data() + super().__init__(**kwargs) + self.refresh_unit_normal() + + if fill_color is not None: + self.fill_color = ManimColor.parse(fill_color) + if stroke_color is not None: + self.stroke_color = ManimColor.parse(stroke_color) + + def _assert_valid_submobjects(self, submobjects: Iterable[OpenGLVMobject]) -> Self: + return self._assert_valid_submobjects_internal(submobjects, OpenGLVMobject) + def get_group_class(self): return OpenGLVGroup + @staticmethod + def get_mobject_type_class(): + return OpenGLVMobject + def init_data(self): super().init_data() self.data.pop("rgbas") @@ -168,7 +197,7 @@ def init_colors(self): def set_fill( self, - color: Color | None = None, + color: ParsableManimColor | None = None, opacity: float | None = None, recurse: bool = True, ) -> OpenGLVMobject: @@ -180,7 +209,7 @@ def set_fill( Fill color of the :class:`OpenGLVMobject`. opacity Fill opacity of the :class:`OpenGLVMobject`. - family + recurse If ``True``, the fill color of all submobjects is also set. Returns @@ -240,7 +269,7 @@ def set_stroke( if width is not None: for mob in self.get_family(recurse): - mob.stroke_width = np.array([[width] for width in listify(width)]) + mob.stroke_width = np.array([[width] for width in tuplify(width)]) if background is not None: for mob in self.get_family(recurse): @@ -293,8 +322,9 @@ def get_style(self): def match_style(self, vmobject, recurse=True): vmobject_style = vmobject.get_style() - if config.renderer == "opengl": + if config.renderer == RendererType.OPENGL: vmobject_style["stroke_width"] = vmobject_style["stroke_width"][0][0] + vmobject_style["fill_opacity"] = self.get_fill_opacity() self.set_style(**vmobject_style, recurse=False) if recurse: # Does its best to match up submobject lists, and @@ -334,14 +364,15 @@ def fade(self, darkness=0.5, recurse=True): super().fade(darkness, recurse) return self + # Todo im not quite sure why we are doing this def get_fill_colors(self): - return [Color(rgb_to_hex(rgba[:3])) for rgba in self.fill_rgba] + return [ManimColor.from_rgb(rgba[:3]) for rgba in self.fill_rgba] def get_fill_opacities(self): return self.fill_rgba[:, 3] def get_stroke_colors(self): - return [Color(rgb_to_hex(rgba[:3])) for rgba in self.stroke_rgba] + return [ManimColor.from_rgb(rgba[:3]) for rgba in self.stroke_rgba] def get_stroke_opacities(self): return self.stroke_rgba[:, 3] @@ -375,7 +406,7 @@ def get_stroke_opacity(self): return self.get_stroke_opacities()[0] def get_color(self): - if self.has_stroke(): + if not self.has_fill(): return self.get_stroke_color() return self.get_fill_color() @@ -389,10 +420,18 @@ def get_colors(self): fill_color = property(get_fill_color, set_fill) def has_stroke(self): - return any(self.get_stroke_widths()) and any(self.get_stroke_opacities()) + stroke_widths = self.get_stroke_widths() + stroke_opacities = self.get_stroke_opacities() + return ( + stroke_widths is not None + and stroke_opacities is not None + and any(stroke_widths) + and any(stroke_opacities) + ) def has_fill(self): - return any(self.get_fill_opacities()) + fill_opacities = self.get_fill_opacities() + return fill_opacities is not None and any(fill_opacities) def get_opacity(self): if self.has_fill(): @@ -433,9 +472,7 @@ def add_cubic_bezier_curve(self, anchor1, handle1, handle2, anchor2): self.append_points(new_points) def add_cubic_bezier_curve_to(self, handle1, handle2, anchor): - """ - Add cubic bezier curve to the path. - """ + """Add cubic bezier curve to the path.""" self.throw_error_if_no_points() quadratic_approx = get_quadratic_approximation_of_cubic( self.get_last_point(), @@ -461,7 +498,7 @@ def add_line_to(self, point: Sequence[float]) -> OpenGLVMobject: Parameters ---------- - point : Sequence[float] + point end of the straight line. """ end = self.points[-1] @@ -520,7 +557,7 @@ def subdivide_sharp_curves(self, angle_threshold=30 * DEGREES, recurse=True): alphas = np.linspace(0, 1, n + 1) new_points.extend( [ - partial_quadratic_bezier_points(tup, a1, a2) + partial_bezier_points(tup, a1, a2) for a1, a2 in zip(alphas, alphas[1:]) ], ) @@ -542,7 +579,7 @@ def set_points_as_corners(self, points: Iterable[float]) -> OpenGLVMobject: Parameters ---------- - points : Iterable[float] + points Array of points that will be set as corners. Returns @@ -644,13 +681,13 @@ def consider_points_equals(self, p0, p1): return np.linalg.norm(p1 - p0) < self.tolerance_for_point_equality # Information about the curve - def force_direction(self, target_direction): + def force_direction(self, target_direction: str): """Makes sure that points are either directed clockwise or counterclockwise. Parameters ---------- - target_direction : :class:`str` + target_direction Either ``"CW"`` or ``"CCW"``. """ if target_direction not in ("CW", "CCW"): @@ -690,7 +727,7 @@ def get_bezier_tuples_from_points(self, points): nppc = self.n_points_per_curve remainder = len(points) % nppc points = points[: len(points) - remainder] - return [points[i : i + nppc] for i in range(0, len(points), nppc)] + return points.reshape((-1, nppc, 3)) def get_bezier_tuples(self): return self.get_bezier_tuples_from_points(self.points) @@ -730,7 +767,7 @@ def get_nth_curve_points(self, n: int) -> np.ndarray: Parameters ---------- - n : int + n index of the desired bezier curve. Returns @@ -747,7 +784,7 @@ def get_nth_curve_function(self, n: int) -> Callable[[float], np.ndarray]: Parameters ---------- - n : int + n index of the desired curve. Returns @@ -778,15 +815,11 @@ def get_nth_curve_function_with_length( length : :class:`float` The length of the nth curve. """ - if sample_points is None: sample_points = 10 curve = self.get_nth_curve_function(n) - - points = np.array([curve(a) for a in np.linspace(0, 1, sample_points)]) - diffs = points[1:] - points[:-1] - norms = np.apply_along_axis(np.linalg.norm, 1, diffs) + norms = self.get_nth_curve_length_pieces(n, sample_points) length = np.sum(norms) @@ -821,17 +854,31 @@ def get_nth_curve_length( length : :class:`float` The length of the nth curve. """ - _, length = self.get_nth_curve_function_with_length(n, sample_points) return length - def get_nth_curve_function_with_length( + def get_curve_functions( + self, + ) -> Iterable[Callable[[float], np.ndarray]]: + """Gets the functions for the curves of the mobject. + + Returns + ------- + Iterable[Callable[[float], np.ndarray]] + The functions for the curves. + """ + num_curves = self.get_num_curves() + + for n in range(num_curves): + yield self.get_nth_curve_function(n) + + def get_nth_curve_length_pieces( self, n: int, sample_points: int | None = None, - ) -> tuple[Callable[[float], np.ndarray], float]: - """Returns the expression of the nth curve along with its (approximate) length. + ) -> np.ndarray: + """Returns the array of short line lengths used for length approximation. Parameters ---------- @@ -842,40 +889,18 @@ def get_nth_curve_function_with_length( Returns ------- - curve : typing.Callable[[float], np.ndarray] - The function for the nth curve. - length : :class:`float` - The length of the nth curve. + np.ndarray + The short length-pieces of the nth curve. """ - if sample_points is None: sample_points = 10 curve = self.get_nth_curve_function(n) - points = np.array([curve(a) for a in np.linspace(0, 1, sample_points)]) diffs = points[1:] - points[:-1] norms = np.apply_along_axis(np.linalg.norm, 1, diffs) - length = np.sum(norms) - - return curve, length - - def get_curve_functions( - self, - ) -> Iterable[Callable[[float], np.ndarray]]: - """Gets the functions for the curves of the mobject. - - Returns - ------- - Iterable[Callable[[float], np.ndarray]] - The functions for the curves. - """ - - num_curves = self.get_num_curves() - - for n in range(num_curves): - yield self.get_nth_curve_function(n) + return norms def get_curve_functions_with_lengths( self, **kwargs @@ -892,7 +917,6 @@ def get_curve_functions_with_lengths( Iterable[Tuple[Callable[[float], np.ndarray], float]] The functions and lengths of the curves. """ - num_curves = self.get_num_curves() for n in range(num_curves): @@ -918,7 +942,6 @@ def point_from_proportion(self, alpha: float) -> np.ndarray: :exc:`Exception` If the :class:`OpenGLVMobject` has no points. """ - if alpha < 0 or alpha > 1: raise ValueError(f"Alpha {alpha} not between 0 and 1.") @@ -928,7 +951,9 @@ def point_from_proportion(self, alpha: float) -> np.ndarray: curves_and_lengths = tuple(self.get_curve_functions_with_lengths()) - target_length = alpha * np.sum(length for _, length in curves_and_lengths) + target_length = alpha * np.sum( + np.fromiter((length for _, length in curves_and_lengths), dtype=np.float64) + ) current_length = 0 for curve, length in curves_and_lengths: @@ -998,7 +1023,7 @@ def proportion_from_point( return alpha - def get_anchors_and_handles(self): + def get_anchors_and_handles(self) -> Iterable[np.ndarray]: """ Returns anchors1, handles, anchors2, where (anchors1[i], handles[i], anchors2[i]) @@ -1030,27 +1055,21 @@ def get_end_anchors(self) -> np.ndarray: nppc = self.n_points_per_curve return self.points[nppc - 1 :: nppc] - def get_anchors(self) -> np.ndarray: + def get_anchors(self) -> Iterable[np.ndarray]: """Returns the anchors of the curves forming the OpenGLVMobject. Returns ------- - np.ndarray + Iterable[np.ndarray] The anchors. """ points = self.points if len(points) == 1: return points - return np.array( - list( - it.chain( - *zip( - self.get_start_anchors(), - self.get_end_anchors(), - ) - ), - ), - ) + + s = self.get_start_anchors() + e = self.get_end_anchors() + return list(it.chain.from_iterable(zip(s, e))) def get_points_without_null_curves(self, atol=1e-9): nppc = self.n_points_per_curve @@ -1077,7 +1096,6 @@ def get_arc_length(self, sample_points_per_curve: int | None = None) -> float: float The length of the :class:`OpenGLVMobject`. """ - return np.sum( length for _, length in self.get_curve_functions_with_lengths( @@ -1198,8 +1216,8 @@ def get_nth_subpath(path_list, n): return path for n in range(n_subpaths): - sp1 = get_nth_subpath(subpaths1, n) - sp2 = get_nth_subpath(subpaths2, n) + sp1 = np.asarray(get_nth_subpath(subpaths1, n)) + sp2 = np.asarray(get_nth_subpath(subpaths2, n)) diff1 = max(0, (len(sp2) - len(sp1)) // nppc) diff2 = max(0, (len(sp1) - len(sp2)) // nppc) sp1 = self.insert_n_curves_to_point_list(diff1, sp1) @@ -1239,9 +1257,9 @@ def insert_n_curves_to_point_list(self, n: int, points: np.ndarray) -> np.ndarra Parameters ---------- - n : int + n Number of desired curves. - points : np.ndarray + points Starting points. Returns @@ -1253,30 +1271,12 @@ def insert_n_curves_to_point_list(self, n: int, points: np.ndarray) -> np.ndarra if len(points) == 1: return np.repeat(points, nppc * n, 0) - bezier_groups = self.get_bezier_tuples_from_points(points) - norms = np.array([np.linalg.norm(bg[nppc - 1] - bg[0]) for bg in bezier_groups]) - total_norm = sum(norms) - # Calculate insertions per curve (ipc) - if total_norm < 1e-6: - ipc = [n] + [0] * (len(bezier_groups) - 1) - else: - ipc = np.round(n * norms / sum(norms)).astype(int) - - diff = n - sum(ipc) - for _ in range(diff): - ipc[np.argmin(ipc)] += 1 - for _ in range(-diff): - ipc[np.argmax(ipc)] -= 1 - - new_points = [] - for group, n_inserts in zip(bezier_groups, ipc): - # What was once a single quadratic curve defined - # by "group" will now be broken into n_inserts + 1 - # smaller quadratic curves - alphas = np.linspace(0, 1, n_inserts + 2) - for a1, a2 in zip(alphas, alphas[1:]): - new_points += partial_quadratic_bezier_points(group, a1, a2) - return np.vstack(new_points) + bezier_tuples = self.get_bezier_tuples_from_points(points) + current_number_of_curves = len(bezier_tuples) + new_number_of_curves = current_number_of_curves + n + new_bezier_tuples = bezier_remap(bezier_tuples, new_number_of_curves) + new_points = new_bezier_tuples.reshape(-1, 3) + return new_points def interpolate(self, mobject1, mobject2, alpha, *args, **kwargs): super().interpolate(mobject1, mobject2, alpha, *args, **kwargs) @@ -1286,79 +1286,70 @@ def interpolate(self, mobject1, mobject2, alpha, *args, **kwargs): if self.has_fill(): tri1 = mobject1.get_triangulation() tri2 = mobject2.get_triangulation() - if len(tri1) != len(tri1) or not np.all(tri1 == tri2): + if len(tri1) != len(tri2) or not np.all(tri1 == tri2): self.refresh_triangulation() return self def pointwise_become_partial( - self, - vmobject: OpenGLVMobject, - a: float, - b: float, + self, vmobject: OpenGLVMobject, a: float, b: float, remap: bool = True ) -> OpenGLVMobject: """Given two bounds a and b, transforms the points of the self vmobject into the points of the vmobject passed as parameter with respect to the bounds. Points here stand for control points of the bezier curves (anchors and handles) Parameters ---------- - vmobject : OpenGLVMobject + vmobject The vmobject that will serve as a model. - a : float + a upper-bound. - b : float + b lower-bound + remap + if the point amount should be kept the same (True) + This option should be manually set to False if keeping the number of points is not needed """ assert isinstance(vmobject, OpenGLVMobject) - if a <= 0 and b >= 1: - self.become(vmobject) - return self - num_curves = vmobject.get_num_curves() - nppc = self.n_points_per_curve - # Partial curve includes three portions: # - A middle section, which matches the curve exactly - # - A start, which is some ending portion of an inner quadratic - # - An end, which is the starting portion of a later inner quadratic - - lower_index, lower_residue = integer_interpolate(0, num_curves, a) - upper_index, upper_residue = integer_interpolate(0, num_curves, b) - i1 = nppc * lower_index - i2 = nppc * (lower_index + 1) - i3 = nppc * upper_index - i4 = nppc * (upper_index + 1) - - vm_points = vmobject.points - new_points = vm_points.copy() - if num_curves == 0: - new_points[:] = 0 + # - A start, which is some ending portion of an inner cubic + # - An end, which is the starting portion of a later inner cubic + if a <= 0 and b >= 1: + self.set_points(vmobject.points) + return self + bezier_triplets = vmobject.get_bezier_tuples() + num_quadratics = len(bezier_triplets) + + # The following two lines will compute which bezier curves of the given mobject need to be processed. + # The residue basically indicates the proportion of the selected Bèzier curve. + # Ex: if lower_index is 3, and lower_residue is 0.4, then the algorithm will append to the points 0.4 of the third bezier curve + lower_index, lower_residue = integer_interpolate(0, num_quadratics, a) + upper_index, upper_residue = integer_interpolate(0, num_quadratics, b) + self.clear_points() + if num_quadratics == 0: return self if lower_index == upper_index: - tup = partial_quadratic_bezier_points( - vm_points[i1:i2], - lower_residue, - upper_residue, + self.append_points( + partial_bezier_points( + bezier_triplets[lower_index], + lower_residue, + upper_residue, + ), ) - new_points[:i1] = tup[0] - new_points[i1:i4] = tup - new_points[i4:] = tup[2] - new_points[nppc:] = new_points[nppc - 1] else: - low_tup = partial_quadratic_bezier_points( - vm_points[i1:i2], - lower_residue, - 1, + self.append_points( + partial_bezier_points(bezier_triplets[lower_index], lower_residue, 1), ) - high_tup = partial_quadratic_bezier_points( - vm_points[i3:i4], - 0, - upper_residue, + inner_points = bezier_triplets[lower_index + 1 : upper_index] + if len(inner_points) > 0: + if remap: + new_triplets = bezier_remap(inner_points, num_quadratics - 2) + else: + new_triplets = bezier_triplets + + self.append_points(np.asarray(new_triplets).reshape(-1, 3)) + self.append_points( + partial_bezier_points(bezier_triplets[upper_index], 0, upper_residue), ) - new_points[0:i1] = low_tup[0] - new_points[i1:i2] = low_tup - # Keep new_points i2:i3 as they are - new_points[i3:i4] = high_tup - new_points[i4:] = high_tup[2] - self.set_points(new_points) return self def get_subcurve(self, a: float, b: float) -> OpenGLVMobject: @@ -1449,23 +1440,6 @@ def get_triangulation(self, normal_vector=None): self.needs_new_triangulation = False return tri_indices - def triggers_refreshed_triangulation(func): - @wraps(func) - def wrapper(self, *args, **kwargs): - old_points = np.empty((0, 3)) - for mob in self.family_members_with_points(): - old_points = np.concatenate((old_points, mob.points), axis=0) - func(self, *args, **kwargs) - new_points = np.empty((0, 3)) - for mob in self.family_members_with_points(): - new_points = np.concatenate((new_points, mob.points), axis=0) - if not np.array_equal(new_points, old_points): - self.refresh_triangulation() - self.refresh_unit_normal() - return self - - return wrapper - @triggers_refreshed_triangulation def set_points(self, points): super().set_points(points) @@ -1523,6 +1497,7 @@ def update_fill_shader_wrapper(self): self.fill_shader_wrapper.vert_data = self.get_fill_shader_data() self.fill_shader_wrapper.vert_indices = self.get_triangulation() self.fill_shader_wrapper.uniforms = self.get_fill_uniforms() + self.fill_shader_wrapper.depth_test = self.depth_test def get_stroke_shader_wrapper(self): self.update_stroke_shader_wrapper() @@ -1531,6 +1506,7 @@ def get_stroke_shader_wrapper(self): def update_stroke_shader_wrapper(self): self.stroke_shader_wrapper.vert_data = self.get_stroke_shader_data() self.stroke_shader_wrapper.uniforms = self.get_stroke_uniforms() + self.stroke_shader_wrapper.depth_test = self.depth_test def get_shader_wrapper_list(self): # Build up data lists @@ -1563,7 +1539,7 @@ def get_shader_wrapper_list(self): def get_stroke_uniforms(self): result = dict(super().get_shader_uniforms()) - result["joint_type"] = JOINT_TYPE_MAP[self.joint_type] + result["joint_type"] = self.joint_type.value result["flat_stroke"] = float(self.flat_stroke) return result @@ -1629,26 +1605,39 @@ class OpenGLVGroup(OpenGLVMobject): can subtract elements of a OpenGLVGroup via :meth:`~.OpenGLVGroup.remove` method, or `-` and `-=` operators: - >>> from manim import Triangle, Square, OpenGLVGroup + .. doctest:: + + >>> from manim import config + >>> original_renderer = config.renderer + >>> config.renderer = "opengl" + + >>> from manim import Triangle, Square + >>> from manim.opengl import OpenGLVGroup + >>> config.renderer + >>> vg = OpenGLVGroup() >>> triangle, square = Triangle(), Square() >>> vg.add(triangle) OpenGLVGroup(Triangle) - >>> vg + square # a new OpenGLVGroup is constructed + >>> vg + square # a new OpenGLVGroup is constructed OpenGLVGroup(Triangle, Square) - >>> vg # not modified + >>> vg # not modified OpenGLVGroup(Triangle) - >>> vg += square; vg # modifies vg + >>> vg += square # modifies vg + >>> vg OpenGLVGroup(Triangle, Square) >>> vg.remove(triangle) OpenGLVGroup(Square) - >>> vg - square; # a new OpenGLVGroup is constructed + >>> vg - square # a new OpenGLVGroup is constructed OpenGLVGroup() - >>> vg # not modified + >>> vg # not modified OpenGLVGroup(Square) - >>> vg -= square; vg # modifies vg + >>> vg -= square # modifies vg + >>> vg OpenGLVGroup() + >>> config.renderer = original_renderer + .. manim:: ArcShapeIris :save_last_frame: @@ -1666,8 +1655,6 @@ def construct(self): """ def __init__(self, *vmobjects, **kwargs): - if not all([isinstance(m, OpenGLVMobject) for m in vmobjects]): - raise Exception("All submobjects must be of type OpenGLVMobject") super().__init__(**kwargs) self.add(*vmobjects) @@ -1685,12 +1672,12 @@ def __str__(self): f"submobject{'s' if len(self.submobjects) > 0 else ''}" ) - def add(self, *vmobjects): + def add(self, *vmobjects: OpenGLVMobject): """Checks if all passed elements are an instance of OpenGLVMobject and then add them to submobjects Parameters ---------- - vmobjects : :class:`~.OpenGLVMobject` + vmobjects List of OpenGLVMobject to add Returns @@ -1733,8 +1720,6 @@ def construct(self): (gr-circle_red).animate.shift(RIGHT) ) """ - if not all(isinstance(m, OpenGLVMobject) for m in vmobjects): - raise TypeError("All submobjects must be of type OpenGLVMobject") return super().add(*vmobjects) def __add__(self, vmobject): @@ -1765,16 +1750,22 @@ def __setitem__(self, key: int, value: OpenGLVMobject | Sequence[OpenGLVMobject] ------- None - Examples - -------- - Normal usage:: + Tests + ----- + + .. doctest:: + + >>> from manim import config + >>> original_renderer = config.renderer + >>> config.renderer = "opengl" >>> vgroup = OpenGLVGroup(OpenGLVMobject()) >>> new_obj = OpenGLVMobject() >>> vgroup[0] = new_obj + + >>> config.renderer = original_renderer """ - if not all(isinstance(m, OpenGLVMobject) for m in value): - raise TypeError("All submobjects must be of type OpenGLVMobject") + self._assert_valid_submobjects(tuplify(value)) self.submobjects[key] = value @@ -1864,7 +1855,7 @@ def __init__( vmobject: OpenGLVMobject, num_dashes: int = 15, dashed_ratio: float = 0.5, - color: Color = WHITE, + color: ParsableManimColor = WHITE, **kwargs, ): self.dashed_ratio = dashed_ratio @@ -1875,10 +1866,7 @@ def __init__( if num_dashes > 0: # Assuming total length is 1 dash_len = r / n - if vmobject.is_closed(): - void_len = (1 - r) / n - else: - void_len = (1 - r) / (n - 1) + void_len = (1 - r) / n if vmobject.is_closed() else (1 - r) / (n - 1) self.add( *( diff --git a/manim/mobject/svg/__init__.py b/manim/mobject/svg/__init__.py index 7aa13c29c3..9bb6807f35 100644 --- a/manim/mobject/svg/__init__.py +++ b/manim/mobject/svg/__init__.py @@ -7,7 +7,5 @@ :toctree: ../reference ~brace - ~style_utils ~svg_mobject - ~svg_path """ diff --git a/manim/mobject/svg/brace.py b/manim/mobject/svg/brace.py index 580df9788d..3d826f4f01 100644 --- a/manim/mobject/svg/brace.py +++ b/manim/mobject/svg/brace.py @@ -4,13 +4,16 @@ __all__ = ["Brace", "BraceLabel", "ArcBrace", "BraceText", "BraceBetweenPoints"] -from typing import Sequence +from collections.abc import Sequence +from typing import TYPE_CHECKING import numpy as np +import svgelements as se from manim._config import config from manim.mobject.geometry.arc import Arc from manim.mobject.geometry.line import Line +from manim.mobject.mobject import Mobject from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL from manim.mobject.text.tex_mobject import MathTex, Tex @@ -18,12 +21,18 @@ from ...animation.fading import FadeIn from ...animation.growing import GrowFromCenter from ...constants import * -from ...mobject.svg.svg_path import SVGPathMobject from ...mobject.types.vectorized_mobject import VMobject from ...utils.color import BLACK +from ..svg.svg_mobject import VMobjectFromSVGPath +if TYPE_CHECKING: + from manim.typing import Point3DLike, Vector3D + from manim.utils.color.core import ParsableManimColor -class Brace(SVGPathMobject): +__all__ = ["Brace", "BraceBetweenPoints", "BraceLabel", "ArcBrace"] + + +class Brace(VMobjectFromSVGPath): """Takes a mobject and draws a brace adjacent to it. Passing a direction vector determines the direction from which the @@ -31,7 +40,7 @@ class Brace(SVGPathMobject): Parameters ---------- - mobject : :class:`~.Mobject` + mobject The mobject adjacent to which the brace is placed. direction : The direction from which the brace faces the mobject. @@ -60,14 +69,14 @@ def construct(self): def __init__( self, - mobject, - direction: Sequence[float] | None = DOWN, - buff=0.2, - sharpness=2, - stroke_width=0, - fill_opacity=1.0, - background_stroke_width=0, - background_stroke_color=BLACK, + mobject: Mobject, + direction: Vector3D | None = DOWN, + buff: float = 0.2, + sharpness: float = 2, + stroke_width: float = 0, + fill_opacity: float = 1.0, + background_stroke_width: float = 0, + background_stroke_color: ParsableManimColor = BLACK, **kwargs, ): path_string_template = ( @@ -99,26 +108,42 @@ def __init__( (target_width * sharpness - default_min_width) / 2, ) - path = path_string_template.format( - linear_section_length, - -linear_section_length, + path = se.Path( + path_string_template.format( + linear_section_length, + -linear_section_length, + ) ) super().__init__( - path_string=path, + path_obj=path, stroke_width=stroke_width, fill_opacity=fill_opacity, background_stroke_width=background_stroke_width, background_stroke_color=background_stroke_color, **kwargs, ) + self.flip(RIGHT) self.stretch_to_fit_width(target_width) self.shift(left - self.get_corner(UP + LEFT) + self.buff * DOWN) for mob in mobject, self: mob.rotate(angle, about_point=ORIGIN) - def put_at_tip(self, mob, use_next_to=True, **kwargs): + def put_at_tip(self, mob: Mobject, use_next_to: bool = True, **kwargs): + """Puts the given mobject at the brace tip. + + Parameters + ---------- + mob + The mobject to be placed at the tip. + use_next_to + If true, then :meth:`next_to` is used to place the mobject at the + tip. + kwargs + Any additional keyword arguments are passed to :meth:`next_to` which + is used to put the mobject next to the brace tip. + """ if use_next_to: mob.next_to(self.get_tip(), np.round(self.get_direction()), **kwargs) else: @@ -129,16 +154,45 @@ def put_at_tip(self, mob, use_next_to=True, **kwargs): return self def get_text(self, *text, **kwargs): + """Places the text at the brace tip. + + Parameters + ---------- + text + The text to be placed at the brace tip. + kwargs + Any additional keyword arguments are passed to :meth:`.put_at_tip` which + is used to position the text at the brace tip. + + Returns + ------- + :class:`~.Tex` + """ text_mob = Tex(*text) self.put_at_tip(text_mob, **kwargs) return text_mob def get_tex(self, *tex, **kwargs): + """Places the tex at the brace tip. + + Parameters + ---------- + tex + The tex to be placed at the brace tip. + kwargs + Any further keyword arguments are passed to :meth:`.put_at_tip` which + is used to position the tex at the brace tip. + + Returns + ------- + :class:`~.MathTex` + """ tex_mob = MathTex(*tex) self.put_at_tip(tex_mob, **kwargs) return tex_mob def get_tip(self): + """Returns the point at the brace tip.""" # Returns the position of the seventh point in the path, which is the tip. if config["renderer"] == "opengl": return self.points[34] @@ -146,32 +200,56 @@ def get_tip(self): return self.points[28] # = 7*4 def get_direction(self): + """Returns the direction from the center to the brace tip.""" vect = self.get_tip() - self.get_center() return vect / np.linalg.norm(vect) class BraceLabel(VMobject, metaclass=ConvertToOpenGL): + """Create a brace with a label attached. + + Parameters + ---------- + obj + The mobject adjacent to which the brace is placed. + text + The label text. + brace_direction + The direction of the brace. By default ``DOWN``. + label_constructor + A class or function used to construct a mobject representing + the label. By default :class:`~.MathTex`. + font_size + The font size of the label, passed to the ``label_constructor``. + buff + The buffer between the mobject and the brace. + brace_config + Arguments to be passed to :class:`.Brace`. + kwargs + Additional arguments to be passed to :class:`~.VMobject`. + """ + def __init__( self, - obj, - text, - brace_direction=DOWN, - label_constructor=MathTex, - font_size=DEFAULT_FONT_SIZE, - buff=0.2, + obj: Mobject, + text: str, + brace_direction: np.ndarray = DOWN, + label_constructor: type = MathTex, + font_size: float = DEFAULT_FONT_SIZE, + buff: float = 0.2, + brace_config: dict | None = None, **kwargs, ): self.label_constructor = label_constructor super().__init__(**kwargs) self.brace_direction = brace_direction - self.buff = buff - if isinstance(obj, list): - obj = self.get_group_class()(*obj) - self.brace = Brace(obj, brace_direction, buff, **kwargs) + if brace_config is None: + brace_config = {} + self.brace = Brace(obj, brace_direction, buff, **brace_config) if isinstance(text, (tuple, list)): - self.label = self.label_constructor(font_size=font_size, *text, **kwargs) + self.label = self.label_constructor(*text, font_size=font_size, **kwargs) else: self.label = self.label_constructor(str(text), font_size=font_size) @@ -239,9 +317,9 @@ def construct(self): def __init__( self, - point_1: Sequence[float] | None, - point_2: Sequence[float] | None, - direction: Sequence[float] | None = ORIGIN, + point_1: Point3DLike | None, + point_2: Point3DLike | None, + direction: Vector3D | None = ORIGIN, **kwargs, ): if all(direction == ORIGIN): @@ -307,10 +385,12 @@ def construct(self): def __init__( self, - arc: Arc = Arc(start_angle=-1, angle=2, radius=1), + arc: Arc | None = None, direction: Sequence[float] = RIGHT, **kwargs, ): + if arc is None: + arc = Arc(start_angle=-1, angle=2, radius=1) arc_end_angle = arc.start_angle + arc.angle line = Line(UP * arc.start_angle, UP * arc_end_angle) scale_shift = RIGHT * np.log(arc.radius) diff --git a/manim/mobject/svg/style_utils.py b/manim/mobject/svg/style_utils.py deleted file mode 100644 index bb886805c6..0000000000 --- a/manim/mobject/svg/style_utils.py +++ /dev/null @@ -1,186 +0,0 @@ -"""Utility functions for parsing SVG styles.""" - - -from __future__ import annotations - -__all__ = ["cascade_element_style", "parse_style", "parse_color_string"] - -from xml.dom.minidom import Element as MinidomElement - -from colour import web2hex - -from ...utils.color import rgb_to_hex - -CASCADING_STYLING_ATTRIBUTES: list[str] = [ - "fill", - "stroke", - "fill-opacity", - "stroke-opacity", -] - - -# The default styling specifications for SVG images, -# according to https://www.w3.org/TR/SVG/painting.html -# (ctrl-F for "initial") -SVG_DEFAULT_ATTRIBUTES: dict[str, str] = { - "fill": "black", - "fill-opacity": "1", - "stroke": "none", - "stroke-opacity": "1", -} - - -def cascade_element_style( - element: MinidomElement, - inherited: dict[str, str], -) -> dict[str, str]: - """Collect the element's style attributes based upon both its inheritance and its own attributes. - - SVG uses cascading element styles. A closer ancestor's style takes precedence over a more distant ancestor's - style. In order to correctly calculate the styles, the attributes are passed down through the inheritance tree, - updating where necessary. - - Note that this method only copies the values and does not parse them. See :meth:`parse_color_string` for converting - from SVG attributes to manim keyword arguments. - - Parameters - ---------- - element : :class:`MinidomElement` - Element of the SVG parse tree - - inherited : :class:`dict` - Dictionary of SVG attributes inherited from the parent element. - - Returns - ------- - :class:`dict` - Dictionary mapping svg attributes to values with `element`'s values overriding inherited values. - """ - - style = inherited.copy() - - # cascade the regular elements. - for attr in CASCADING_STYLING_ATTRIBUTES: - entry = element.getAttribute(attr) - if entry: - style[attr] = entry - - # the style attribute should be handled separately in order to - # break it up nicely. furthermore, style takes priority over other - # attributes in the same element. - style_specs = element.getAttribute("style") - if style_specs: - for style_spec in style_specs.split(";"): - try: - key, value = style_spec.split(":") - except ValueError as e: - if not style_spec.strip(): - # there was just a stray semicolon at the end, producing an emptystring - pass - else: - raise e - else: - style[key.strip()] = value.strip() - - return style - - -def parse_color_string(color_spec: str) -> str: - """Handle the SVG-specific color strings and convert them to HTML #rrggbb format. - - Parameters - ---------- - color_spec : :class:`str` - String in any web-compatible format - - Returns - ------- - :class:`str` - Hexadecimal color string in the format `#rrggbb` - """ - - if color_spec[0:3] == "rgb": - # these are only in integer form, but the Colour module wants them in floats. - splits = color_spec[4:-1].split(",") - if splits[0][-1] == "%": - # if the last character of the first number is a percentage, - # then interpret the number as a percentage - parsed_rgbs = [float(i[:-1]) / 100.0 for i in splits] - else: - parsed_rgbs = [int(i) / 255.0 for i in splits] - - hex_color = rgb_to_hex(parsed_rgbs) - - elif color_spec[0] == "#": - # its OK, parse as hex color standard. - hex_color = color_spec - - else: - # attempt to convert color names like "red" to hex color - hex_color = web2hex(color_spec, force_long=True) - - return hex_color - - -def fill_default_values(svg_style: dict) -> None: - """ - Fill in the default values for properties of SVG elements, - if they are not currently set in the style dictionary. - - Parameters - ---------- - svg_style : :class:`dict` - Style dictionary with SVG property names. Some may be missing. - - Returns - ------- - :class:`dict` - Style attributes; none are missing. - """ - for key in SVG_DEFAULT_ATTRIBUTES: - if key not in svg_style: - svg_style[key] = SVG_DEFAULT_ATTRIBUTES[key] - - -def parse_style(svg_style: dict[str, str]) -> dict: - """Convert a dictionary of SVG attributes to Manim VMobject keyword arguments. - - Parameters - ---------- - svg_style : :class:`dict` - Style attributes as a string-to-string dictionary. Keys are valid SVG element attributes (fill, stroke, etc) - - Returns - ------- - :class:`dict` - Style attributes, but in manim kwargs form, e.g., keys are fill_color, stroke_color - """ - - manim_style = {} - fill_default_values(svg_style) - - if "fill-opacity" in svg_style: - manim_style["fill_opacity"] = float(svg_style["fill-opacity"]) - - if "stroke-opacity" in svg_style: - manim_style["stroke_opacity"] = float(svg_style["stroke-opacity"]) - - # nones need to be handled specially - if "fill" in svg_style: - if svg_style["fill"] == "none": - manim_style["fill_opacity"] = 0 - else: - manim_style["fill_color"] = parse_color_string(svg_style["fill"]) - - if "stroke" in svg_style: - if svg_style["stroke"] == "none": - # In order to not break animations.creation.Write, - # we interpret no stroke as stroke-width of zero and - # color the same as the fill color, if it exists. - manim_style["stroke_width"] = 0 - if "fill_color" in manim_style: - manim_style["stroke_color"] = manim_style["fill_color"] - else: - manim_style["stroke_color"] = parse_color_string(svg_style["stroke"]) - - return manim_style diff --git a/manim/mobject/svg/svg_mobject.py b/manim/mobject/svg/svg_mobject.py index b5ebd856d7..82c121fce7 100644 --- a/manim/mobject/svg/svg_mobject.py +++ b/manim/mobject/svg/svg_mobject.py @@ -2,620 +2,600 @@ from __future__ import annotations -__all__ = ["SVGMobject"] - -import itertools as it import os -import re -import string -import warnings -from xml.dom.minidom import Element as MinidomElement -from xml.dom.minidom import parse as minidom_parse +from pathlib import Path +from xml.etree import ElementTree as ET import numpy as np -from colour import Color +import svgelements as se -from manim.mobject.geometry.arc import Circle -from manim.mobject.geometry.line import Line -from manim.mobject.geometry.polygram import Rectangle, RoundedRectangle -from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL +from manim import config, logger -from ... import config, logger -from ...constants import * -from ...mobject.types.vectorized_mobject import VMobject -from .style_utils import cascade_element_style, parse_style -from .svg_path import SVGPathMobject +from ...constants import RIGHT +from ...utils.bezier import get_quadratic_approximation_of_cubic +from ...utils.images import get_full_vector_image_path +from ...utils.iterables import hash_obj +from ..geometry.arc import Circle +from ..geometry.line import Line +from ..geometry.polygram import Polygon, Rectangle, RoundedRectangle +from ..opengl.opengl_compatibility import ConvertToOpenGL +from ..types.vectorized_mobject import VMobject +__all__ = ["SVGMobject", "VMobjectFromSVGPath"] -class SVGMobject(VMobject, metaclass=ConvertToOpenGL): - """A SVGMobject is a Vector Mobject constructed from an SVG (or XDV) file. - SVGMobjects are constructed from the XML data within the SVG file - structure. As such, subcomponents from the XML data can be accessed via - the submobjects attribute. There is varying amounts of support for SVG - elements, experiment with SVG files at your own peril. +SVG_HASH_TO_MOB_MAP: dict[int, VMobject] = {} - Examples - -------- - .. code-block:: python +def _convert_point_to_3d(x: float, y: float) -> np.ndarray: + return np.array([x, y, 0.0]) - class Sample(Scene): - def construct(self): - self.play(FadeIn(SVGMobject("manim-logo-sidebar.svg"))) + +class SVGMobject(VMobject, metaclass=ConvertToOpenGL): + """A vectorized mobject created from importing an SVG file. Parameters - -------- - file_name : :class:`str` - The file's path name. When possible, the full path is preferred but a - relative path may be used as well. Relative paths are relative to the - directory specified by the `--assets_dir` command line argument. - - Other Parameters - -------- - should_center : :class:`bool` - Whether the SVGMobject should be centered to the origin. Defaults to `True`. - height : :class:`float` - Specify the final height of the SVG file. Defaults to 2 units. - width : :class:`float` - Specify the width the SVG file should occupy. Defaults to `None`. - unpack_groups : :class:`bool` - Whether the hierarchies of VGroups generated should be flattened. Defaults to `True`. - stroke_width : :class:`float` - The stroke width of the outer edge of an SVG path element. Defaults to `4`. - fill_opacity : :class:`float` - Specifies the opacity of the image. `1` is opaque, `0` is transparent. Defaults to `1`. + ---------- + file_name + The path to the SVG file. + should_center + Whether or not the mobject should be centered after + being imported. + height + The target height of the mobject, set to 2 Manim units by default. + If the height and width are both set to ``None``, the mobject + is imported without being scaled. + width + The target width of the mobject, set to ``None`` by default. If + the height and the width are both set to ``None``, the mobject + is imported without being scaled. + color + The color (both fill and stroke color) of the mobject. If + ``None`` (the default), the colors set in the SVG file + are used. + opacity + The opacity (both fill and stroke opacity) of the mobject. + If ``None`` (the default), the opacity set in the SVG file + is used. + fill_color + The fill color of the mobject. If ``None`` (the default), + the fill colors set in the SVG file are used. + fill_opacity + The fill opacity of the mobject. If ``None`` (the default), + the fill opacities set in the SVG file are used. + stroke_color + The stroke color of the mobject. If ``None`` (the default), + the stroke colors set in the SVG file are used. + stroke_opacity + The stroke opacity of the mobject. If ``None`` (the default), + the stroke opacities set in the SVG file are used. + stroke_width + The stroke width of the mobject. If ``None`` (the default), + the stroke width values set in the SVG file are used. + svg_default + A dictionary in which fallback values for unspecified + properties of elements in the SVG file are defined. If + ``None`` (the default), ``color``, ``opacity``, ``fill_color`` + ``fill_opacity``, ``stroke_color``, and ``stroke_opacity`` + are set to ``None``, and ``stroke_width`` is set to 0. + path_string_config + A dictionary with keyword arguments passed to + :class:`.VMobjectFromSVGPath` used for importing path elements. + If ``None`` (the default), no additional arguments are passed. + use_svg_cache + If True (default), the svg inputs (e.g. file_name, settings) + will be used as a key and a copy of the created mobject will + be saved using that key to be quickly retrieved if the same + inputs need be processed later. For large SVGs which are used + only once, this can be omitted to improve performance. + kwargs + Further arguments passed to the parent class. """ def __init__( self, - file_name=None, - should_center=True, - height=2, - width=None, - unpack_groups=True, # if False, creates a hierarchy of VGroups - stroke_width=DEFAULT_STROKE_WIDTH, - fill_opacity=1.0, - should_subdivide_sharp_curves=False, - should_remove_null_curves=False, - color=None, - *, - fill_color=None, - stroke_color=None, - stroke_opacity=1.0, + file_name: str | os.PathLike | None = None, + should_center: bool = True, + height: float | None = 2, + width: float | None = None, + color: str | None = None, + opacity: float | None = None, + fill_color: str | None = None, + fill_opacity: float | None = None, + stroke_color: str | None = None, + stroke_opacity: float | None = None, + stroke_width: float | None = None, + svg_default: dict | None = None, + path_string_config: dict | None = None, + use_svg_cache: bool = True, **kwargs, ): + super().__init__(color=None, stroke_color=None, fill_color=None, **kwargs) + + # process keyword arguments + self.file_name = Path(file_name) if file_name is not None else None - self.def_map = {} - self.file_name = file_name or self.file_name - self._ensure_valid_file() self.should_center = should_center - self.unpack_groups = unpack_groups - self.path_string_config = ( - { - "should_subdivide_sharp_curves": should_subdivide_sharp_curves, - "should_remove_null_curves": should_remove_null_curves, + self.svg_height = height + self.svg_width = width + self.color = color + self.opacity = opacity + self.fill_color = fill_color + self.fill_opacity = fill_opacity + self.stroke_color = stroke_color + self.stroke_opacity = stroke_opacity + self.stroke_width = stroke_width + + if svg_default is None: + svg_default = { + "color": None, + "opacity": None, + "fill_color": None, + "fill_opacity": None, + "stroke_width": 0, + "stroke_color": None, + "stroke_opacity": None, } - if config.renderer == "opengl" - else {} - ) - self._initial_svg_style = self.generate_style( - Color(color) if color else None, - Color(fill_color) if fill_color else None, - Color(stroke_color) if stroke_color else None, - fill_opacity, - stroke_opacity, - ) - super().__init__( - color=color, - fill_opacity=fill_opacity, - stroke_width=stroke_width, + self.svg_default = svg_default + + if path_string_config is None: + path_string_config = {} + self.path_string_config = path_string_config + + self.init_svg_mobject(use_svg_cache=use_svg_cache) + + self.set_style( fill_color=fill_color, - stroke_opacity=stroke_opacity, + fill_opacity=fill_opacity, stroke_color=stroke_color, - **kwargs, + stroke_opacity=stroke_opacity, + stroke_width=stroke_width, ) - self._move_into_position(width, height) + self.move_into_position() + + def init_svg_mobject(self, use_svg_cache: bool) -> None: + """Checks whether the SVG has already been imported and + generates it if not. - def _ensure_valid_file(self): - """Reads self.file_name and determines whether the given input file_name - is valid. + See also + -------- + :meth:`.SVGMobject.generate_mobject` """ - if self.file_name is None: - raise Exception("Must specify file for SVGMobject") + if use_svg_cache: + hash_val = hash_obj(self.hash_seed) + if hash_val in SVG_HASH_TO_MOB_MAP: + mob = SVG_HASH_TO_MOB_MAP[hash_val].copy() + self.add(*mob) + return - if os.path.exists(self.file_name): - self.file_path = self.file_name - return + self.generate_mobject() + if use_svg_cache: + SVG_HASH_TO_MOB_MAP[hash_val] = self.copy() - relative = os.path.join(os.getcwd(), self.file_name) - if os.path.exists(relative): - self.file_path = relative - return + @property + def hash_seed(self) -> tuple: + """A unique hash representing the result of the generated + mobject points. - possible_paths = [ - os.path.join(config.get_dir("assets_dir"), self.file_name), - os.path.join(config.get_dir("assets_dir"), self.file_name + ".svg"), - os.path.join(config.get_dir("assets_dir"), self.file_name + ".xdv"), + Used as keys in the ``SVG_HASH_TO_MOB_MAP`` caching dictionary. + """ + return ( + self.__class__.__name__, + self.svg_default, + self.path_string_config, self.file_name, - self.file_name + ".svg", - self.file_name + ".xdv", - ] - for path in possible_paths: - if os.path.exists(path): - self.file_path = path - return - error = f"From: {os.getcwd()}, could not find {self.file_name} at either of these locations: {possible_paths}" - raise OSError(error) + config.renderer, + ) - def generate_points(self): - """Called by the Mobject abstract base class. Responsible for generating - the SVGMobject's points from XML tags, populating self.mobjects, and - any submobjects within self.mobjects. - """ - doc = minidom_parse(self.file_path) - for node in doc.childNodes: - if not isinstance(node, MinidomElement) or node.tagName != "svg": - continue - mobjects = self._get_mobjects_from(node, self._initial_svg_style) - if self.unpack_groups: - self.add(*mobjects) - else: - self.add(*mobjects[0].submobjects) - doc.unlink() + def generate_mobject(self) -> None: + """Parse the SVG and translate its elements to submobjects.""" + file_path = self.get_file_path() + element_tree = ET.parse(file_path) + new_tree = self.modify_xml_tree(element_tree) + # Create a temporary svg file to dump modified svg to be parsed + modified_file_path = file_path.with_name(f"{file_path.stem}_{file_path.suffix}") + new_tree.write(modified_file_path) - init_points = generate_points + svg = se.SVG.parse(modified_file_path) + modified_file_path.unlink() - def _get_mobjects_from( - self, - element: MinidomElement, - inherited_style: dict[str, str], - within_defs: bool = False, - ) -> list[VMobject]: - """Parses a given SVG element into a Mobject. + mobjects = self.get_mobjects_from(svg) + self.add(*mobjects) + self.flip(RIGHT) # Flip y + + def get_file_path(self) -> Path: + """Search for an existing file based on the specified file name.""" + if self.file_name is None: + raise ValueError("Must specify file for SVGMobject") + return get_full_vector_image_path(self.file_name) + + def modify_xml_tree(self, element_tree: ET.ElementTree) -> ET.ElementTree: + """Modifies the SVG element tree to include default + style information. Parameters ---------- - element : :class:`Element` - The SVG data in the XML to be parsed. - - inherited_style : :class:`dict` - Dictionary of the SVG attributes for children to inherit. + element_tree + The parsed element tree from the SVG file. + """ + config_style_dict = self.generate_config_style_dict() + style_keys = ( + "fill", + "fill-opacity", + "stroke", + "stroke-opacity", + "stroke-width", + "style", + ) + root = element_tree.getroot() + root_style_dict = {k: v for k, v in root.attrib.items() if k in style_keys} + + new_root = ET.Element("svg", {}) + config_style_node = ET.SubElement(new_root, "g", config_style_dict) + root_style_node = ET.SubElement(config_style_node, "g", root_style_dict) + root_style_node.extend(root) + return ET.ElementTree(new_root) + + def generate_config_style_dict(self) -> dict[str, str]: + """Generate a dictionary holding the default style information.""" + keys_converting_dict = { + "fill": ("color", "fill_color"), + "fill-opacity": ("opacity", "fill_opacity"), + "stroke": ("color", "stroke_color"), + "stroke-opacity": ("opacity", "stroke_opacity"), + "stroke-width": ("stroke_width",), + } + svg_default_dict = self.svg_default + result = {} + for svg_key, style_keys in keys_converting_dict.items(): + for style_key in style_keys: + if svg_default_dict[style_key] is None: + continue + result[svg_key] = str(svg_default_dict[style_key]) + return result - within_defs : :class:`bool` - Whether ``element`` is within a ``defs`` element, which indicates - whether elements with `id` attributes should be added to the - definitions list. + def get_mobjects_from(self, svg: se.SVG) -> list[VMobject]: + """Convert the elements of the SVG to a list of mobjects. - Returns - ------- - List[VMobject] - A VMobject representing the associated SVG element. + Parameters + ---------- + svg + The parsed SVG file. """ - result = [] - # First, let all non-elements pass (like text entries) - if not isinstance(element, MinidomElement): - return result - - style = cascade_element_style(element, inherited_style) - is_defs = element.tagName == "defs" - - if element.tagName == "style": - pass # TODO, handle style - elif element.tagName in ["g", "svg", "symbol", "defs"]: - result += it.chain( - *( - self._get_mobjects_from( - child, - style, - within_defs=within_defs or is_defs, - ) - for child in element.childNodes - ) - ) - elif element.tagName == "path": - temp = element.getAttribute("d") - if temp != "": - result.append(self._path_string_to_mobject(temp, style)) - elif element.tagName == "use": - # note, style is calcuated in a different way for `use` elements. - result += self._use_to_mobjects(element, style) - elif element.tagName in ["line"]: - result.append(self._line_to_mobject(element, style)) - elif element.tagName == "rect": - result.append(self._rect_to_mobject(element, style)) - elif element.tagName == "circle": - result.append(self._circle_to_mobject(element, style)) - elif element.tagName == "ellipse": - result.append(self._ellipse_to_mobject(element, style)) - elif element.tagName in ["polygon", "polyline"]: - result.append(self._polygon_to_mobject(element, style)) - else: - pass # TODO - - result = [m for m in result if m is not None] - group_cls = self.get_group_class() - - self._handle_transforms(element, group_cls(*result)) - if len(result) > 1 and not self.unpack_groups: - result = [group_cls(*result)] - - if within_defs and element.hasAttribute("id"): - # it seems wasteful to throw away the actual element, - # but I'd like the parsing to be as similar as possible - self.def_map[element.getAttribute("id")] = (style, element) - if is_defs: - # defs shouldn't be part of the result tree, only the id dictionary. - return [] - + for shape in svg.elements(): + # can we combine the two continue cases into one? + if isinstance(shape, se.Group): # noqa: SIM114 + continue + elif isinstance(shape, se.Path): + mob = self.path_to_mobject(shape) + elif isinstance(shape, se.SimpleLine): + mob = self.line_to_mobject(shape) + elif isinstance(shape, se.Rect): + mob = self.rect_to_mobject(shape) + elif isinstance(shape, (se.Circle, se.Ellipse)): + mob = self.ellipse_to_mobject(shape) + elif isinstance(shape, se.Polygon): + mob = self.polygon_to_mobject(shape) + elif isinstance(shape, se.Polyline): + mob = self.polyline_to_mobject(shape) + elif isinstance(shape, se.Text): + mob = self.text_to_mobject(shape) + elif isinstance(shape, se.Use) or type(shape) is se.SVGElement: + continue + else: + logger.warning(f"Unsupported element type: {type(shape)}") + continue + if mob is None or not mob.has_points(): + continue + self.apply_style_to_mobject(mob, shape) + if isinstance(shape, se.Transformable) and shape.apply: + self.handle_transform(mob, shape.transform) + result.append(mob) return result - def generate_style( - self, - color: Color | None, - fill_color: Color | None, - stroke_color: Color | None, - fill_opacity: float, - stroke_opacity: float, - ): - style = { - "fill-opacity": fill_opacity, - "stroke-opacity": stroke_opacity, - } - if color: - style["fill"] = style["stroke"] = color.get_hex_l() - if fill_color: - style["fill"] = fill_color.hex_l - if stroke_color: - style["stroke"] = stroke_color.hex_l - - return style - - def _path_string_to_mobject(self, path_string: str, style: dict): - """Converts a SVG path element's ``d`` attribute to a mobject. + @staticmethod + def handle_transform(mob: VMobject, matrix: se.Matrix) -> VMobject: + """Apply SVG transformations to the converted mobject. Parameters ---------- - path_string : :class:`str` - A path with potentially multiple path commands to create a shape. - - style : :class:`dict` - Style specification, using the SVG names for properties. - - Returns - ------- - SVGPathMobject - A VMobject from the given path string, or d attribute. + mob + The converted mobject. + matrix + The transformation matrix determined from the SVG + transformation. """ - return SVGPathMobject( - path_string, **self.path_string_config, **parse_style(style) - ) + mat = np.array([[matrix.a, matrix.c], [matrix.b, matrix.d]]) + vec = np.array([matrix.e, matrix.f, 0.0]) + mob.apply_matrix(mat) + mob.shift(vec) + return mob - def _attribute_to_float(self, attr): - """A helper method which converts the attribute to float. + @staticmethod + def apply_style_to_mobject(mob: VMobject, shape: se.GraphicObject) -> VMobject: + """Apply SVG style information to the converted mobject. Parameters ---------- - attr : str - An SVG path attribute. - - Returns - ------- - float - A float representing the attribute string value. + mob + The converted mobject. + shape + The parsed SVG element. """ - stripped_attr = "".join( - [char for char in attr if char in string.digits + ".-e"], + mob.set_style( + stroke_width=shape.stroke_width, + stroke_color=shape.stroke.hexrgb, + stroke_opacity=shape.stroke.opacity, + fill_color=shape.fill.hexrgb, + fill_opacity=shape.fill.opacity, ) - return float(stripped_attr) + return mob - def _use_to_mobjects( - self, - use_element: MinidomElement, - local_style: dict, - ) -> list[VMobject]: - """Converts a SVG element to a collection of VMobjects. + def path_to_mobject(self, path: se.Path) -> VMobjectFromSVGPath: + """Convert a path element to a vectorized mobject. Parameters ---------- - use_element : :class:`MinidomElement` - An SVG element which represents nodes that should be - duplicated elsewhere. - - local_style : :class:`Dict` - The styling using SVG property names at the point the element is ``d. - Not all values are applied; styles defined when the element is specified in - the `` tag cannot be overridden here. - - Returns - ------- - List[VMobject] - A collection of VMobjects that are a copy of the defined object + path + The parsed SVG path. """ + return VMobjectFromSVGPath(path, **self.path_string_config) - # Remove initial "#" character - ref = use_element.getAttribute("xlink:href")[1:] - - try: - def_style, def_element = self.def_map[ref] - except KeyError: - warning_text = f"{self.file_name} contains a reference to id #{ref}, which is not recognized" - warnings.warn(warning_text) - return [] - - # In short, the def-ed style overrides the new style, - # in cases when the def-ed styled is defined. - style = local_style.copy() - style.update(def_style) - - return self._get_mobjects_from(def_element, style) - - def _line_to_mobject(self, line_element: MinidomElement, style: dict): - """Creates a Line VMobject from an SVG element. + @staticmethod + def line_to_mobject(line: se.Line) -> Line: + """Convert a line element to a vectorized mobject. Parameters ---------- - line_element : :class:`minidom.Element` - An SVG line element. - - style : :class:`dict` - Style specification, using the SVG names for properties. - - Returns - ------- - Line - A Line VMobject + line + The parsed SVG line. """ - x1, y1, x2, y2 = ( - self._attribute_to_float(line_element.getAttribute(key)) - if line_element.hasAttribute(key) - else 0.0 - for key in ("x1", "y1", "x2", "y2") + return Line( + start=_convert_point_to_3d(line.x1, line.y1), + end=_convert_point_to_3d(line.x2, line.y2), ) - return Line([x1, -y1, 0], [x2, -y2, 0], **parse_style(style)) - def _rect_to_mobject(self, rect_element: MinidomElement, style: dict): - """Converts a SVG command to a VMobject. + @staticmethod + def rect_to_mobject(rect: se.Rect) -> Rectangle: + """Convert a rectangle element to a vectorized mobject. Parameters ---------- - rect_element : minidom.Element - A SVG rect path command. - - style : dict - Style specification, using the SVG names for properties. - - Returns - ------- - Rectangle - Creates either a Rectangle, or RoundRectangle, VMobject from a - rect element. + rect + The parsed SVG rectangle. """ - - stroke_width = rect_element.getAttribute("stroke-width") - corner_radius = rect_element.getAttribute("rx") - - if stroke_width in ["", "none", "0"]: - stroke_width = 0 - - if corner_radius in ["", "0", "none"]: - corner_radius = 0 - - corner_radius = float(corner_radius) - - parsed_style = parse_style(style) - parsed_style["stroke_width"] = stroke_width - - if corner_radius == 0: + if rect.rx == 0 or rect.ry == 0: mob = Rectangle( - width=self._attribute_to_float(rect_element.getAttribute("width")), - height=self._attribute_to_float(rect_element.getAttribute("height")), - **parsed_style, + width=rect.width, + height=rect.height, ) else: mob = RoundedRectangle( - width=self._attribute_to_float(rect_element.getAttribute("width")), - height=self._attribute_to_float(rect_element.getAttribute("height")), - corner_radius=corner_radius, - **parsed_style, + width=rect.width, + height=rect.height * rect.rx / rect.ry, + corner_radius=rect.rx, ) - - mob.shift(mob.get_center() - mob.get_corner(UP + LEFT)) + mob.stretch_to_fit_height(rect.height) + mob.shift( + _convert_point_to_3d(rect.x + rect.width / 2, rect.y + rect.height / 2) + ) return mob - def _circle_to_mobject(self, circle_element: MinidomElement, style: dict): - """Creates a Circle VMobject from a SVG command. + @staticmethod + def ellipse_to_mobject(ellipse: se.Ellipse | se.Circle) -> Circle: + """Convert an ellipse or circle element to a vectorized mobject. Parameters ---------- - circle_element : :class:`minidom.Element` - A SVG circle path command. + ellipse + The parsed SVG ellipse or circle. + """ + mob = Circle(radius=ellipse.rx) + if ellipse.rx != ellipse.ry: + mob.stretch_to_fit_height(2 * ellipse.ry) + mob.shift(_convert_point_to_3d(ellipse.cx, ellipse.cy)) + return mob - style : :class:`dict` - Style specification, using the SVG names for properties. + @staticmethod + def polygon_to_mobject(polygon: se.Polygon) -> Polygon: + """Convert a polygon element to a vectorized mobject. - Returns - ------- - Circle - A Circle VMobject + Parameters + ---------- + polygon + The parsed SVG polygon. """ - x, y, r = ( - self._attribute_to_float(circle_element.getAttribute(key)) - if circle_element.hasAttribute(key) - else 0.0 - for key in ("cx", "cy", "r") - ) - return Circle(radius=r, **parse_style(style)).shift(x * RIGHT + y * DOWN) + points = [_convert_point_to_3d(*point) for point in polygon] + return Polygon(*points) - def _ellipse_to_mobject(self, circle_element: MinidomElement, style: dict): - """Creates a stretched Circle VMobject from a SVG path - command. + def polyline_to_mobject(self, polyline: se.Polyline) -> VMobject: + """Convert a polyline element to a vectorized mobject. Parameters ---------- - circle_element : :class:`minidom.Element` - A SVG circle path command. + polyline + The parsed SVG polyline. + """ + points = [_convert_point_to_3d(*point) for point in polyline] + vmobject_class = self.get_mobject_type_class() + return vmobject_class().set_points_as_corners(points) - style : :class:`dict` - Style specification, using the SVG names for properties. + @staticmethod + def text_to_mobject(text: se.Text): + """Convert a text element to a vectorized mobject. - Returns - ------- - Circle - A Circle VMobject - """ - x, y, rx, ry = ( - self._attribute_to_float(circle_element.getAttribute(key)) - if circle_element.hasAttribute(key) - else 0.0 - for key in ("cx", "cy", "rx", "ry") - ) - return ( - Circle(**parse_style(style)) - .scale(rx * RIGHT + ry * UP) - .shift(x * RIGHT + y * DOWN) - ) + .. warning:: - def _polygon_to_mobject(self, polygon_element: MinidomElement, style: dict): - """Constructs a VMobject from a SVG element. + Not yet implemented. Parameters ---------- - polygon_element : :class:`minidom.Element` - An SVG polygon element. + text + The parsed SVG text. + """ + logger.warning(f"Unsupported element type: {type(text)}") + return - style : :class:`dict` - Style specification, using the SVG names for properties. + def move_into_position(self) -> None: + """Scale and move the generated mobject into position.""" + if self.should_center: + self.center() + if self.svg_height is not None: + self.set(height=self.svg_height) + if self.svg_width is not None: + self.set(width=self.svg_width) - Returns - ------- - SVGPathMobject - A VMobject representing the polygon. - """ - # This seems hacky... yes it is. - path_string = polygon_element.getAttribute("points").lstrip() - for digit in string.digits: - path_string = path_string.replace(" " + digit, " L" + digit) - path_string = "M" + path_string - if polygon_element.tagName == "polygon": - path_string = path_string + "Z" - return self._path_string_to_mobject(path_string, style) - - def _handle_transforms(self, element, mobject): - """Applies the SVG transform to the specified mobject. Transforms include: - ``matrix``, ``translate``, and ``scale``. - Parameters - ---------- - element : :class:`minidom.Element` - The transform command to perform +class VMobjectFromSVGPath(VMobject, metaclass=ConvertToOpenGL): + """A vectorized mobject representing an SVG path. - mobject : :class:`Mobject` - The Mobject to transform. - """ + .. note:: - x, y = ( - self._attribute_to_float(element.getAttribute(key)) - if element.hasAttribute(key) - else 0.0 - for key in ("x", "y") - ) - mobject.shift(x * RIGHT + y * DOWN) - - transform_attr_value = element.getAttribute("transform") - - # parse the various transforms in the attribute value - transform_names = ["matrix", "translate", "scale", "rotate", "skewX", "skewY"] - - # Borrowed/Inspired from: - # https://github.com/cjlano/svg/blob/3ea3384457c9780fa7d67837c9c5fd4ebc42cb3b/svg/svg.py#L75 - - # match any SVG transformation with its parameter (until final parenthesis) - # [^)]* == anything but a closing parenthesis - # '|'.join == OR-list of SVG transformations - transform_regex = "|".join([x + r"[^)]*\)" for x in transform_names]) - transforms = re.findall(transform_regex, transform_attr_value)[::-1] - - number_regex = r"[-+]?(?:\d+(?:\.\d*)?|\.\d+)(?:[eE][-+]?\d+)?" - - for t in transforms: - op_name, op_args = t.split("(") - op_name = op_name.strip() - op_args = [float(x) for x in re.findall(number_regex, op_args)] - - if op_name == "matrix": - transform_args = np.array(op_args).reshape([3, 2]) - x = transform_args[2][0] - y = -transform_args[2][1] - matrix = np.identity(self.dim) - matrix[:2, :2] = transform_args[:2, :] - matrix[1] *= -1 - matrix[:, 1] *= -1 - - for mob in mobject.family_members_with_points(): - if config["renderer"] == "opengl": - mob.points = np.dot(mob.points, matrix) - else: - mob.points = np.dot(mob.points, matrix) - mobject.shift(x * RIGHT + y * UP) - - elif op_name == "scale": - scale_values = op_args - if len(scale_values) == 2: - scale_x, scale_y = scale_values - mobject.scale(np.array([scale_x, scale_y, 1]), about_point=ORIGIN) - elif len(scale_values) == 1: - scale = scale_values[0] - mobject.scale(np.array([scale, scale, 1]), about_point=ORIGIN) - - elif op_name == "translate": - if len(op_args) == 2: - x, y = op_args - else: - x = op_args - y = 0 - mobject.shift(x * RIGHT + y * DOWN) + The ``long_lines``, ``should_subdivide_sharp_curves``, + and ``should_remove_null_curves`` keyword arguments are + only respected with the OpenGL renderer. - else: - # TODO: handle rotate, skewX and skewY - # for now adding a warning message - logger.warning( - "Handling of %s transform is not supported yet!", - op_name, - ) + Parameters + ---------- + path_obj + A parsed SVG path object. + long_lines + Whether or not straight lines in the vectorized mobject + are drawn in one or two segments. + should_subdivide_sharp_curves + Whether or not to subdivide subcurves further in case + two segments meet at an angle that is sharper than a + given threshold. + should_remove_null_curves + Whether or not to remove subcurves of length 0. + kwargs + Further keyword arguments are passed to the parent + class. + """ - def _flatten(self, input_list): - """A helper method to flatten the ``input_list`` into an 1D array.""" - output_list = [] - for i in input_list: - if isinstance(i, list): - output_list.extend(self._flatten(i)) - else: - output_list.append(i) - return output_list + def __init__( + self, + path_obj: se.Path, + long_lines: bool = False, + should_subdivide_sharp_curves: bool = False, + should_remove_null_curves: bool = False, + **kwargs, + ): + # Get rid of arcs + path_obj.approximate_arcs_with_quads() + self.path_obj = path_obj - def _move_into_position(self, width, height): - """Uses the SVGMobject's config dictionary to set the Mobject's - width, height, and/or center it. Use ``width``, ``height``, and - ``should_center`` respectively to modify this. - """ - if self.should_center: - self.center() - if height is not None: - self.height = height - if width is not None: - self.width = width + self.long_lines = long_lines + self.should_subdivide_sharp_curves = should_subdivide_sharp_curves + self.should_remove_null_curves = should_remove_null_curves + + super().__init__(**kwargs) + + def init_points(self) -> None: + # TODO: cache mobject in a re-importable way + + self.handle_commands() - def init_colors(self, propagate_colors=False): if config.renderer == "opengl": - self.set_style( - fill_color=self.fill_color or self.color, - fill_opacity=self.fill_opacity, - stroke_color=self.stroke_color or self.color, - stroke_width=self.stroke_width, - stroke_opacity=self.stroke_opacity, - recurse=propagate_colors, - ) + if self.should_subdivide_sharp_curves: + # For a healthy triangulation later + self.subdivide_sharp_curves() + if self.should_remove_null_curves: + # Get rid of any null curves + self.set_points(self.get_points_without_null_curves()) + + generate_points = init_points + + def handle_commands(self) -> None: + all_points: list[np.ndarray] = [] + last_move = None + curve_start = None + last_true_move = None + + def move_pen(pt, *, true_move: bool = False): + nonlocal last_move, curve_start, last_true_move + last_move = pt + if curve_start is None: + curve_start = last_move + if true_move: + last_true_move = last_move + + if self.n_points_per_curve == 4: + + def add_cubic(start, cp1, cp2, end): + nonlocal all_points + assert len(all_points) % 4 == 0, len(all_points) + all_points += [start, cp1, cp2, end] + move_pen(end) + + def add_quad(start, cp, end): + add_cubic(start, (start + cp + cp) / 3, (cp + cp + end) / 3, end) + move_pen(end) + + def add_line(start, end): + add_cubic( + start, (start + start + end) / 3, (start + end + end) / 3, end + ) + move_pen(end) + else: - super().init_colors(propagate_colors=propagate_colors) + + def add_cubic(start, cp1, cp2, end): + nonlocal all_points + assert len(all_points) % 3 == 0, len(all_points) + two_quads = get_quadratic_approximation_of_cubic( + start, + cp1, + cp2, + end, + ) + all_points += two_quads[:3].tolist() + all_points += two_quads[3:].tolist() + move_pen(end) + + def add_quad(start, cp, end): + nonlocal all_points + assert len(all_points) % 3 == 0, len(all_points) + all_points += [start, cp, end] + move_pen(end) + + def add_line(start, end): + add_quad(start, (start + end) / 2, end) + move_pen(end) + + for segment in self.path_obj: + segment_class = segment.__class__ + if segment_class == se.Move: + move_pen(_convert_point_to_3d(*segment.end), true_move=True) + elif segment_class == se.Line: + add_line(last_move, _convert_point_to_3d(*segment.end)) + elif segment_class == se.QuadraticBezier: + add_quad( + last_move, + _convert_point_to_3d(*segment.control), + _convert_point_to_3d(*segment.end), + ) + elif segment_class == se.CubicBezier: + add_cubic( + last_move, + _convert_point_to_3d(*segment.control1), + _convert_point_to_3d(*segment.control2), + _convert_point_to_3d(*segment.end), + ) + elif segment_class == se.Close: + # If the SVG path naturally ends at the beginning of the curve, + # we do *not* need to draw a closing line. To account for floating + # point precision, we use a small value to compare the two points. + if abs(np.linalg.norm(last_move - last_true_move)) > 0.0001: + add_line(last_move, last_true_move) + curve_start = None + else: + raise AssertionError(f"Not implemented: {segment_class}") + + self.points = np.array(all_points, ndmin=2, dtype="float64") + # If we have no points, make sure the array is shaped properly + # (0 rows tall by 3 columns wide) so future operations can + # add or remove points correctly. + if len(all_points) == 0: + self.points = np.reshape(self.points, (0, 3)) diff --git a/manim/mobject/svg/svg_path.py b/manim/mobject/svg/svg_path.py deleted file mode 100644 index 9d23bb7ca2..0000000000 --- a/manim/mobject/svg/svg_path.py +++ /dev/null @@ -1,483 +0,0 @@ -"""Mobjects generated from an SVG pathstring.""" - - -from __future__ import annotations - -__all__ = ["SVGPathMobject", "string_to_numbers"] - - -import re -from math import * - -import numpy as np - -from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL - -from ... import config -from ...constants import * -from ..types.vectorized_mobject import VMobject - - -def correct_out_of_range_radii(rx, ry, x1p, y1p): - """Correction of out-of-range radii. - - See: https://www.w3.org/TR/SVG11/implnote.html#ArcCorrectionOutOfRangeRadii - """ - # Step 1: Ensure radii are non-zero (taken care of in elliptical_arc_to_cubic_bezier). - # Step 2: Ensure radii are positive. If rx or ry have negative signs, these are dropped; - # the absolute value is used instead. - rx = abs(rx) - ry = abs(ry) - # Step 3: Ensure radii are large enough. - Lambda = (x1p * x1p) / (rx * rx) + (y1p * y1p) / (ry * ry) - if Lambda > 1: - rx = sqrt(Lambda) * rx - ry = sqrt(Lambda) * ry - - # Step 4: Proceed with computations. - return rx, ry - - -def vector_angle(ux, uy, vx, vy): - """Calculate the dot product angle between two vectors. - - This clamps the argument to the arc cosine due to roundoff errors - from some SVG files. - """ - sign = -1 if ux * vy - uy * vx < 0 else 1 - ua = sqrt(ux * ux + uy * uy) - va = sqrt(vx * vx + vy * vy) - dot = ux * vx + uy * vy - - # Clamp argument between [-1,1]. - return sign * acos(max(min(dot / (ua * va), 1), -1)) - - -def get_elliptical_arc_center_parameters(x1, y1, rx, ry, phi, fA, fS, x2, y2): - """Conversion from endpoint to center parameterization. - - See: https://www.w3.org/TR/SVG11/implnote.html#ArcConversionEndpointToCenter - """ - cos_phi = cos(phi) - sin_phi = sin(phi) - # Step 1: Compute (x1p,y1p). - x = (x1 - x2) / 2 - y = (y1 - y2) / 2 - x1p = x * cos_phi + y * sin_phi - y1p = -x * sin_phi + y * cos_phi - - # Correct out of range radii - rx, ry = correct_out_of_range_radii(rx, ry, x1p, y1p) - - # Step 2: Compute (cxp,cyp). - rx2 = rx * rx - ry2 = ry * ry - x1p2 = x1p * x1p - y1p2 = y1p * y1p - k = sqrt(max((rx2 * ry2 - rx2 * y1p2 - ry2 * x1p2) / (rx2 * y1p2 + ry2 * x1p2), 0)) - sign = -1 if fA == fS else 1 - cxp = sign * k * (rx * y1p) / ry - cyp = sign * k * (-ry * x1p) / rx - - # Step 3: Compute (cx,cy) from (cxp,cyp). - x = (x1 + x2) / 2 - y = (y1 + y2) / 2 - cx = cxp * cos_phi - cyp * sin_phi + x - cy = cxp * sin_phi + cyp * cos_phi + y - - # Step 4: Compute theta1 and dtheta. - x = (x1p - cxp) / rx - y = (y1p - cyp) / ry - theta1 = vector_angle(1, 0, x, y) - - x_ = (-x1p - cxp) / rx - y_ = (-y1p - cyp) / ry - dtheta = degrees(vector_angle(x, y, x_, y_)) % 360 - - if fS == 0 and dtheta > 0: - dtheta -= 360 - elif fS == 1 and dtheta < 0: - dtheta += 360 - - return cx, cy, theta1, radians(dtheta) - - -def elliptical_arc_to_cubic_bezier(x1, y1, rx, ry, phi, fA, fS, x2, y2): - """Generate cubic bezier points to approximate SVG elliptical arc. - - See: http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes - """ - # Out of range parameters - # See: https://www.w3.org/TR/SVG11/implnote.html#ArcOutOfRangeParameters - # If rx or ry are 0 then this arc is treated as a - # straight line segment (a "lineto") joining the endpoints. - if not rx or not ry: - return [x1, y1, x2, y2, x2, y2] - - # phi is taken mod 360 degrees and set to radians for subsequent calculations. - phi = radians(phi % 360) - - # Any nonzero value for either of the flags fA or fS is taken to mean the value 1. - fA = 1 if fA else 0 - fS = 1 if fS else 0 - - # Convert from endpoint to center parameterization. - cx, cy, theta1, dtheta = get_elliptical_arc_center_parameters( - x1, - y1, - rx, - ry, - phi, - fA, - fS, - x2, - y2, - ) - - # For a given arc we should "chop" it up into segments if it is too big - # to help miminze cubic bezier curve approximation errors. - # If dtheta is a multiple of 90 degrees, set the limit to 90 degrees, - # otherwise 360/10=36 degrees is a decent sweep limit. - if degrees(dtheta) % 90 == 0: - sweep_limit = 90 - else: - sweep_limit = 36 - - segments = int(ceil(abs(degrees(dtheta)) / sweep_limit)) - segment = dtheta / float(segments) - current_angle = theta1 - start_x = x1 - start_y = y1 - cos_phi = cos(phi) - sin_phi = sin(phi) - alpha = sin(segment) * (sqrt(4 + 3 * pow(tan(segment / 2.0), 2)) - 1) / 3.0 - bezier_points = [] - - # Calculate the cubic bezier points from elliptical arc parametric equations. - # See: (the box on page 18) http://www.spaceroots.org/documents/ellipse/elliptical-arc.pdf - for idx in range(segments): - next_angle = current_angle + segment - - cos_start = cos(current_angle) - sin_start = sin(current_angle) - - e1x = -rx * cos_phi * sin_start - ry * sin_phi * cos_start - e1y = -rx * sin_phi * sin_start + ry * cos_phi * cos_start - q1_x = start_x + alpha * e1x - q1_y = start_y + alpha * e1y - - cos_end = cos(next_angle) - sin_end = sin(next_angle) - - p2x = cx + rx * cos_phi * cos_end - ry * sin_phi * sin_end - p2y = cy + rx * sin_phi * cos_end + ry * cos_phi * sin_end - - end_x = p2x - end_y = p2y - - if idx == segments - 1: - end_x = x2 - end_y = y2 - - e2x = -rx * cos_phi * sin_end - ry * sin_phi * cos_end - e2y = -rx * sin_phi * sin_end + ry * cos_phi * cos_end - q2_x = end_x - alpha * e2x - q2_y = end_y - alpha * e2y - - bezier_points += [[q1_x, q1_y, 0], [q2_x, q2_y, 0], [end_x, end_y, 0]] - start_x = end_x - start_y = end_y - current_angle = next_angle - - return bezier_points - - -def string_to_numbers(num_string: str) -> list[float]: - """Parse the SVG string representing a sequence of numbers into an array of floats. - - Parameters - ---------- - num_string : :class:`str` - String representing a sequence of numbers, separated by commas, spaces, etc. - - Returns - ------- - list(float) - List of float values parsed out of the string. - """ - num_string = num_string.replace("-", ",-") - num_string = num_string.replace("e,-", "e-") - float_results = [] - for s in re.split("[ ,]", num_string): - if s != "": - try: - float_results.append(float(s)) - except ValueError: - # in this case, it's something like "2.4.3.14 which should be parsed as "2.4 0.3 0.14" - undotted_parts = s.split(".") - float_results.append(float(undotted_parts[0] + "." + undotted_parts[1])) - float_results += [float("." + u) for u in undotted_parts[2:]] - return float_results - - -def grouped(iterable, n): - """Group iterable into arrays of n items.""" - return (np.array(v) for v in zip(*[iter(iterable)] * n)) - - -class SVGPathMobject(VMobject, metaclass=ConvertToOpenGL): - def __init__(self, path_string, **kwargs): - self.path_string = path_string - if config.renderer == "opengl": - kwargs["long_lines"] = True - super().__init__(**kwargs) - self.current_path_start = np.zeros((1, self.dim)) - - def get_path_commands(self): - """Returns a list of possible path commands used within an SVG ``d`` - attribute. - - See: https://svgwg.org/svg2-draft/paths.html#DProperty for further - details on what each path command does. - - Returns - ------- - List[:class:`str`] - The various upper and lower cased path commands. - """ - result = [ - "M", # moveto - "L", # lineto - "H", # horizontal lineto - "V", # vertical lineto - "C", # curveto - "S", # smooth curveto - "Q", # quadratic Bezier curve - "T", # smooth quadratic Bezier curveto - "A", # elliptical Arc - "Z", # closepath - ] - result += [s.lower() for s in result] - return result - - def generate_points(self): - """Generates points from a given an SVG ``d`` attribute.""" - pattern = "[%s]" % ("".join(self.get_path_commands())) - pairs = list( - zip( - re.findall(pattern, self.path_string), - re.split(pattern, self.path_string)[1:], - ), - ) - # Which mobject should new points be added to - prev_command = None - for command, coord_string in pairs: - self.handle_command(command, coord_string, prev_command) - prev_command = command - if config["renderer"] == "opengl": - if self.should_subdivide_sharp_curves: - # For a healthy triangulation later - self.subdivide_sharp_curves() - if self.should_remove_null_curves: - # Get rid of any null curves - self.set_points(self.get_points_without_null_curves()) - # people treat y-coordinate differently - self.rotate(np.pi, RIGHT, about_point=ORIGIN) - - init_points = generate_points - - def handle_command(self, command, coord_string, prev_command): - """Core logic for handling each of the various path commands.""" - # Relative SVG commands are specified as lowercase letters - is_relative = command.islower() - command = command.upper() - - # Keep track of the most recently completed point - if config["renderer"] == "opengl": - points = self.points - else: - points = self.points - start_point = points[-1] if points.shape[0] else np.zeros((1, self.dim)) - - # Produce the (absolute) coordinates of the controls and handles - new_points = self.string_to_points( - command, - is_relative, - coord_string, - start_point, - ) - - if command == "M": # moveto - self.start_new_path(new_points[0]) - for p in new_points[1:]: - self.add_line_to(p) - return - - elif command in ["H", "V", "L"]: # lineto of any kind - for p in new_points: - self.add_line_to(p) - return - - elif command == "C": # Cubic - # points must be added in groups of 3. - for i in range(0, len(new_points), 3): - self.add_cubic_bezier_curve_to(*new_points[i : i + 3]) - return - - elif command == "S": # Smooth cubic - if config["renderer"] == "opengl": - points = self.points - else: - points = self.points - prev_handle = start_point - if prev_command.upper() in ["C", "S"]: - prev_handle = points[-2] - for i in range(0, len(new_points), 2): - new_handle = 2 * start_point - prev_handle - self.add_cubic_bezier_curve_to( - new_handle, - new_points[i], - new_points[i + 1], - ) - start_point = new_points[i + 1] - prev_handle = new_points[i] - return - - elif command == "Q": # quadratic Bezier curve - for i in range(0, len(new_points), 2): - self.add_quadratic_bezier_curve_to(new_points[i], new_points[i + 1]) - return - - elif command == "T": # smooth quadratic - prev_quad_handle = start_point - if prev_command.upper() in ["Q", "T"]: - # because of the conversion from quadratic to cubic, - # our actual previous handle was 3/2 in the direction of p[-2] from p[-1] - prev_quad_handle = 1.5 * points[-2] - 0.5 * points[-1] - for p in new_points: - new_quad_handle = 2 * start_point - prev_quad_handle - self.add_quadratic_bezier_curve_to(new_quad_handle, p) - start_point = p - prev_quad_handle = new_quad_handle - - elif command == "A": # elliptical Arc - # points must be added in groups of 3. See `string_to_points` for - # case that new_points can be None. - if new_points is not None: - for i in range(0, len(new_points), 3): - self.add_cubic_bezier_curve_to(*new_points[i : i + 3]) - return - - elif command == "Z": # closepath - if config["renderer"] == "opengl": - self.close_path() - else: - self.add_line_to(self.current_path_start) - return - - def string_to_points(self, command, is_relative, coord_string, start_point): - """Convert an SVG command string into a sequence of absolute-positioned control points. - - Parameters - ----- - command : `str` - A string containing a single uppercase letter representing the SVG command. - - is_relative : `bool` - Whether the command is relative to the end of the previous command - - coord_string : `str` - A string that contains many comma- or space-separated numbers that defined the control points. Different - commands require different numbers of numbers as arguments. - - start_point : `ndarray` - If the command is relative, the position to begin the relations from. - """ - - # this call to "string to numbers" where problems like parsing 0.5.6 lie - numbers = string_to_numbers(coord_string) - - # arcs are weirdest, handle them first. - if command == "A": - result = np.zeros((0, self.dim)) - last_end_point = None - for elliptic_numbers in grouped(numbers, 7): - # The startpoint changes with each iteration. - if last_end_point is not None: - start_point = last_end_point - - # We have to handle offsets here because ellipses are complicated. - if is_relative: - elliptic_numbers[5] += start_point[0] - elliptic_numbers[6] += start_point[1] - - # If the endpoints (x1, y1) and (x2, y2) are identical, then this - # is equivalent to omitting the elliptical arc segment entirely. - # for more information of where this math came from visit: - # http://www.w3.org/TR/SVG11/implnote.html#ArcImplementationNotes - if ( - start_point[0] == elliptic_numbers[5] - and start_point[1] == elliptic_numbers[6] - ): - continue - - result = np.append( - result, - elliptical_arc_to_cubic_bezier(*start_point[:2], *elliptic_numbers), - axis=0, - ) - - # We store the endpoint so that it can be the startpoint for the - # next iteration. - last_end_point = elliptic_numbers[5:] - - return result - - # H and V expect a sequence of single coords, not coord pairs like the rest of the commands. - elif command == "H": - result = np.zeros((len(numbers), self.dim)) - result[:, 0] = numbers - if not is_relative: - result[:, 1] = start_point[1] - - elif command == "V": - result = np.zeros((len(numbers), self.dim)) - result[:, 1] = numbers - if not is_relative: - result[:, 0] = start_point[0] - - else: - num_points = len(numbers) // 2 - result = np.zeros((num_points, self.dim)) - result[:, :2] = np.array(numbers).reshape((num_points, 2)) - - # If it's not relative, we don't have any more work! - if not is_relative: - return result - - # Each control / target point is calculated relative to the ending position of the previous curve. - # Curves consist of multiple point listings depending on the command. - entries = 1 - # Quadratic curves expect pairs, S expects 3 (cubic) but one is implied by smoothness - if command in ["Q", "S"]: - entries = 2 - # Only cubic curves expect three points. - elif command == "C": - entries = 3 - - offset = start_point - for i in range(result.shape[0]): - result[i, :] = result[i, :] + offset - if (i + 1) % entries == 0: - offset = result[i, :] - - return result - - def get_original_path_string(self): - """A simple getter for the path's ``d`` attribute.""" - return self.path_string - - def start_new_path(self, point): - self.current_path_start = point - super().start_new_path(point) - return self diff --git a/manim/mobject/table.py b/manim/mobject/table.py index 35690b0788..9d65263dfd 100644 --- a/manim/mobject/table.py +++ b/manim/mobject/table.py @@ -65,9 +65,8 @@ def construct(self): import itertools as it -from typing import Callable, Iterable, Sequence - -from colour import Color +from collections.abc import Iterable, Sequence +from typing import Callable from manim.mobject.geometry.line import Line from manim.mobject.geometry.polygram import Polygon @@ -76,17 +75,54 @@ def construct(self): from manim.mobject.text.tex_mobject import MathTex from manim.mobject.text.text_mobject import Paragraph -from .. import config from ..animation.animation import Animation from ..animation.composition import AnimationGroup from ..animation.creation import Create, Write from ..animation.fading import FadeIn from ..mobject.types.vectorized_mobject import VGroup, VMobject -from ..utils.color import BLACK, YELLOW +from ..utils.color import BLACK, YELLOW, ManimColor, ParsableManimColor +from .utils import get_vectorized_mobject_class class Table(VGroup): - """A mobject that displays a table on the screen. + r"""A mobject that displays a table on the screen. + + Parameters + ---------- + table + A 2D array or list of lists. Content of the table has to be a valid input + for the callable set in ``element_to_mobject``. + row_labels + List of :class:`~.VMobject` representing the labels of each row. + col_labels + List of :class:`~.VMobject` representing the labels of each column. + top_left_entry + The top-left entry of the table, can only be specified if row and + column labels are given. + v_buff + Vertical buffer passed to :meth:`~.Mobject.arrange_in_grid`, by default 0.8. + h_buff + Horizontal buffer passed to :meth:`~.Mobject.arrange_in_grid`, by default 1.3. + include_outer_lines + ``True`` if the table should include outer lines, by default False. + add_background_rectangles_to_entries + ``True`` if background rectangles should be added to entries, by default ``False``. + entries_background_color + Background color of entries if ``add_background_rectangles_to_entries`` is ``True``. + include_background_rectangle + ``True`` if the table should have a background rectangle, by default ``False``. + background_rectangle_color + Background color of table if ``include_background_rectangle`` is ``True``. + element_to_mobject + The :class:`~.Mobject` class applied to the table entries. by default :class:`~.Paragraph`. For common choices, see :mod:`~.text_mobject`/:mod:`~.tex_mobject`. + element_to_mobject_config + Custom configuration passed to :attr:`element_to_mobject`, by default {}. + arrange_in_grid_config + Dict passed to :meth:`~.Mobject.arrange_in_grid`, customizes the arrangement of the table. + line_config + Dict passed to :class:`~.Line`, customizes the lines of the table. + kwargs + Additional arguments to be passed to :class:`~.VGroup`. Examples -------- @@ -159,9 +195,9 @@ def __init__( h_buff: float = 1.3, include_outer_lines: bool = False, add_background_rectangles_to_entries: bool = False, - entries_background_color: Color = BLACK, + entries_background_color: ParsableManimColor = BLACK, include_background_rectangle: bool = False, - background_rectangle_color: Color = BLACK, + background_rectangle_color: ParsableManimColor = BLACK, element_to_mobject: Callable[ [float | str | VMobject], VMobject, @@ -171,45 +207,6 @@ def __init__( line_config: dict = {}, **kwargs, ): - """ - Parameters - ---------- - table - A 2D array or list of lists. Content of the table has to be a valid input - for the callable set in ``element_to_mobject``. - row_labels - List of :class:`~.VMobject` representing the labels of each row. - col_labels - List of :class:`~.VMobject` representing the labels of each column. - top_left_entry - The top-left entry of the table, can only be specified if row and - column labels are given. - v_buff - Vertical buffer passed to :meth:`~.Mobject.arrange_in_grid`, by default 0.8. - h_buff - Horizontal buffer passed to :meth:`~.Mobject.arrange_in_grid`, by default 1.3. - include_outer_lines - ``True`` if the table should include outer lines, by default False. - add_background_rectangles_to_entries - ``True`` if background rectangles should be added to entries, by default ``False``. - entries_background_color - Background color of entries if ``add_background_rectangles_to_entries`` is ``True``. - include_background_rectangle - ``True`` if the table should have a background rectangle, by default ``False``. - background_rectangle_color - Background color of table if ``include_background_rectangle`` is ``True``. - element_to_mobject - The :class:`~.Mobject` class applied to the table entries. by default :class:`~.Paragraph`. For common choices, see :mod:`~.text_mobject`/:mod:`~.tex_mobject`. - element_to_mobject_config - Custom configuration passed to :attr:`element_to_mobject`, by default {}. - arrange_in_grid_config - Dict passed to :meth:`~.Mobject.arrange_in_grid`, customizes the arrangement of the table. - line_config - Dict passed to :class:`~.Line`, customizes the lines of the table. - kwargs : Any - Additional arguments to be passed to :class:`~.VGroup`. - """ - self.row_labels = row_labels self.col_labels = col_labels self.top_left_entry = top_left_entry @@ -219,9 +216,9 @@ def __init__( self.h_buff = h_buff self.include_outer_lines = include_outer_lines self.add_background_rectangles_to_entries = add_background_rectangles_to_entries - self.entries_background_color = entries_background_color + self.entries_background_color = ManimColor(entries_background_color) self.include_background_rectangle = include_background_rectangle - self.background_rectangle_color = background_rectangle_color + self.background_rectangle_color = ManimColor(background_rectangle_color) self.element_to_mobject = element_to_mobject self.element_to_mobject_config = element_to_mobject_config self.arrange_in_grid_config = arrange_in_grid_config @@ -257,7 +254,7 @@ def _table_to_mob_table( self, table: Iterable[Iterable[float | str | VMobject]], ) -> list: - """Initilaizes the entries of ``table`` as :class:`~.VMobject`. + """Initializes the entries of ``table`` as :class:`~.VMobject`. Parameters ---------- @@ -328,13 +325,7 @@ def _add_labels(self, mob_table: VGroup) -> VGroup: else: # Placeholder to use arrange_in_grid if top_left_entry is not set. # Import OpenGLVMobject to work with --renderer=opengl - if config.renderer == "opengl": - from manim.opengl import OpenGLVMobject - - dummy_class = OpenGLVMobject - else: - dummy_class = VMobject - dummy_mobject = dummy_class() + dummy_mobject = get_vectorized_mobject_class()() col_labels = [dummy_mobject] + self.col_labels mob_table.insert(0, col_labels) else: @@ -511,7 +502,7 @@ def construct(self): """ return VGroup(*(VGroup(*row) for row in self.mob_table)) - def set_column_colors(self, *colors: Iterable[Color]) -> Table: + def set_column_colors(self, *colors: Iterable[ParsableManimColor]) -> Table: """Set individual colors for each column of the table. Parameters @@ -540,7 +531,7 @@ def construct(self): column.set_color(color) return self - def set_row_colors(self, *colors: Iterable[Color]) -> Table: + def set_row_colors(self, *colors: Iterable[ParsableManimColor]) -> Table: """Set individual colors for each row of the table. Parameters @@ -692,7 +683,6 @@ def construct(self): item.set_color(random_bright_color()) self.add(table) """ - return VGroup(*self.row_labels) def get_col_labels(self) -> VGroup: @@ -721,7 +711,6 @@ def construct(self): item.set_color(random_bright_color()) self.add(table) """ - return VGroup(*self.col_labels) def get_labels(self) -> VGroup: @@ -759,10 +748,10 @@ def construct(self): label_group.add(*label) return label_group - def add_background_to_entries(self, color: Color = BLACK) -> Table: + def add_background_to_entries(self, color: ParsableManimColor = BLACK) -> Table: """Adds a black :class:`~.BackgroundRectangle` to each entry of the table.""" for mob in self.get_entries(): - mob.add_background_rectangle(color=color) + mob.add_background_rectangle(color=ManimColor(color)) return self def get_cell(self, pos: Sequence[int] = (1, 1), **kwargs) -> Polygon: @@ -773,7 +762,7 @@ def get_cell(self, pos: Sequence[int] = (1, 1), **kwargs) -> Polygon: pos The position of a specific entry on the table. ``(1,1)`` being the top left entry of the table. - kwargs : Any + kwargs Additional arguments to be passed to :class:`~.Polygon`. Returns @@ -823,7 +812,7 @@ def construct(self): return rec def get_highlighted_cell( - self, pos: Sequence[int] = (1, 1), color: Color = YELLOW, **kwargs + self, pos: Sequence[int] = (1, 1), color: ParsableManimColor = YELLOW, **kwargs ) -> BackgroundRectangle: """Returns a :class:`~.BackgroundRectangle` of the cell at the given position. @@ -834,7 +823,7 @@ def get_highlighted_cell( of the table. color The color used to highlight the cell. - kwargs : Any + kwargs Additional arguments to be passed to :class:`~.BackgroundRectangle`. Examples @@ -855,11 +844,11 @@ def construct(self): self.add(table) """ cell = self.get_cell(pos) - bg_cell = BackgroundRectangle(cell, color=color, **kwargs) + bg_cell = BackgroundRectangle(cell, color=ManimColor(color), **kwargs) return bg_cell def add_highlighted_cell( - self, pos: Sequence[int] = (1, 1), color: Color = YELLOW, **kwargs + self, pos: Sequence[int] = (1, 1), color: ParsableManimColor = YELLOW, **kwargs ) -> Table: """Highlights one cell at a specific position on the table by adding a :class:`~.BackgroundRectangle`. @@ -870,7 +859,7 @@ def add_highlighted_cell( of the table. color The color used to highlight the cell. - kwargs : Any + kwargs Additional arguments to be passed to :class:`~.BackgroundRectangle`. Examples @@ -889,7 +878,7 @@ def construct(self): table.add_highlighted_cell((2,2), color=GREEN) self.add(table) """ - bg_cell = self.get_highlighted_cell(pos, color=color, **kwargs) + bg_cell = self.get_highlighted_cell(pos, color=ManimColor(color), **kwargs) self.add_to_back(bg_cell) entry = self.get_entries(pos) entry.background_rectangle = bg_cell @@ -901,15 +890,13 @@ def create( line_animation: Callable[[VMobject | VGroup], Animation] = Create, label_animation: Callable[[VMobject | VGroup], Animation] = Write, element_animation: Callable[[VMobject | VGroup], Animation] = Create, - entry_animation=FadeIn, + entry_animation: Callable[[VMobject | VGroup], Animation] = FadeIn, **kwargs, ) -> AnimationGroup: """Customized create-type function for tables. Parameters ---------- - run_time - The run time of the line creation and the writing of the elements. lag_ratio The lag ratio of the animation. line_animation @@ -918,7 +905,9 @@ def create( The animation style of the table labels, see :mod:`~.creation` for examples. element_animation The animation style of the table elements, see :mod:`~.creation` for examples. - kwargs : Any + entry_animation + The entry animation of the table background, see :mod:`~.creation` for examples. + kwargs Further arguments passed to the creation animations. Returns @@ -979,7 +968,7 @@ def scale(self, scale_factor: float, **kwargs): class MathTable(Table): - """A specialized :class:`~.Table` mobject for use with with LaTeX. + """A specialized :class:`~.Table` mobject for use with LaTeX. Examples -------- @@ -1015,7 +1004,7 @@ def __init__( for :class:`~.MathTex`. element_to_mobject The :class:`~.Mobject` class applied to the table entries. Set as :class:`~.MathTex`. - kwargs : Any + kwargs Additional arguments to be passed to :class:`~.Table`. """ super().__init__( @@ -1026,7 +1015,7 @@ def __init__( class MobjectTable(Table): - """A specialized :class:`~.Table` mobject for use with with :class:`~.Mobject`. + """A specialized :class:`~.Table` mobject for use with :class:`~.Mobject`. Examples -------- @@ -1069,14 +1058,14 @@ def __init__( A 2D array or list of lists. Content of the table must be of type :class:`~.Mobject`. element_to_mobject The :class:`~.Mobject` class applied to the table entries. Set as ``lambda m : m`` to return itself. - kwargs : Any + kwargs Additional arguments to be passed to :class:`~.Table`. """ super().__init__(table, element_to_mobject=element_to_mobject, **kwargs) class IntegerTable(Table): - """A specialized :class:`~.Table` mobject for use with with :class:`~.Integer`. + r"""A specialized :class:`~.Table` mobject for use with :class:`~.Integer`. Examples -------- @@ -1090,14 +1079,14 @@ def construct(self): [[0,30,45,60,90], [90,60,45,30,0]], col_labels=[ - MathTex("\\\\frac{\\sqrt{0}}{2}"), - MathTex("\\\\frac{\\sqrt{1}}{2}"), - MathTex("\\\\frac{\\sqrt{2}}{2}"), - MathTex("\\\\frac{\\sqrt{3}}{2}"), - MathTex("\\\\frac{\\sqrt{4}}{2}")], - row_labels=[MathTex("\\sin"), MathTex("\\cos")], + MathTex(r"\frac{\sqrt{0}}{2}"), + MathTex(r"\frac{\sqrt{1}}{2}"), + MathTex(r"\frac{\sqrt{2}}{2}"), + MathTex(r"\frac{\sqrt{3}}{2}"), + MathTex(r"\frac{\sqrt{4}}{2}")], + row_labels=[MathTex(r"\sin"), MathTex(r"\cos")], h_buff=1, - element_to_mobject_config={"unit": "^{\\circ}"}) + element_to_mobject_config={"unit": r"^{\circ}"}) self.add(t0) """ @@ -1118,14 +1107,14 @@ def __init__( for :class:`~.Integer`. element_to_mobject The :class:`~.Mobject` class applied to the table entries. Set as :class:`~.Integer`. - kwargs : Any + kwargs Additional arguments to be passed to :class:`~.Table`. """ super().__init__(table, element_to_mobject=element_to_mobject, **kwargs) class DecimalTable(Table): - """A specialized :class:`~.Table` mobject for use with with :class:`~.DecimalNumber` to display decimal entries. + """A specialized :class:`~.Table` mobject for use with :class:`~.DecimalNumber` to display decimal entries. Examples -------- @@ -1166,7 +1155,7 @@ def __init__( The :class:`~.Mobject` class applied to the table entries. Set as :class:`~.DecimalNumber`. element_to_mobject_config Element to mobject config, here set as {"num_decimal_places": 1}. - kwargs : Any + kwargs Additional arguments to be passed to :class:`~.Table`. """ super().__init__( diff --git a/manim/mobject/text/code_mobject.py b/manim/mobject/text/code_mobject.py index 0d5e7cb231..b3109c23e4 100644 --- a/manim/mobject/text/code_mobject.py +++ b/manim/mobject/text/code_mobject.py @@ -6,49 +6,28 @@ "Code", ] -import html -import os -import re +from pathlib import Path +from typing import Any, Literal -import numpy as np +from bs4 import BeautifulSoup, Tag from pygments import highlight from pygments.formatters.html import HtmlFormatter -from pygments.lexers import get_lexer_by_name, guess_lexer_for_filename +from pygments.lexers import get_lexer_by_name, guess_lexer, guess_lexer_for_filename from pygments.styles import get_all_styles from manim.constants import * from manim.mobject.geometry.arc import Dot -from manim.mobject.geometry.polygram import RoundedRectangle from manim.mobject.geometry.shape_matchers import SurroundingRectangle +from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL from manim.mobject.text.text_mobject import Paragraph -from manim.mobject.types.vectorized_mobject import VGroup -from manim.utils.color import WHITE +from manim.mobject.types.vectorized_mobject import VGroup, VMobject +from manim.typing import StrPath +from manim.utils.color import WHITE, ManimColor -class Code(VGroup): +class Code(VMobject, metaclass=ConvertToOpenGL): """A highlighted source code listing. - An object ``listing`` of :class:`.Code` is a :class:`.VGroup` consisting - of three objects: - - - The background, ``listing.background_mobject``. This is either - a :class:`.Rectangle` (if the listing has been initialized with - ``background="rectangle"``, the default option) or a :class:`.VGroup` - resembling a window (if ``background="window"`` has been passed). - - - The line numbers, ``listing.line_numbers`` (a :class:`.Paragraph` - object). - - - The highlighted code itself, ``listing.code`` (a :class:`.Paragraph` - object). - - .. WARNING:: - - Using a :class:`.Transform` on text with leading whitespace (and in - this particular case: code) can look - `weird `_. Consider using - :meth:`remove_invisible_chars` to resolve this issue. - Examples -------- @@ -57,16 +36,16 @@ class Code(VGroup): listing = Code( "helloworldcpp.cpp", tab_width=4, - background_stroke_width=1, - background_stroke_color=WHITE, - insert_line_no=True, - style=Code.styles_list[15], + formatter_style="emacs", background="window", language="cpp", + background_config={"stroke_color": WHITE}, + paragraph_config={"font": "Noto Sans Mono"}, ) - We can also render code passed as a string (but note that - the language has to be specified in this case): + We can also render code passed as a string. As the automatic language + detection can be a bit flaky, it is recommended to specify the language + explicitly: .. manim:: CodeFromString :save_last_frame: @@ -80,539 +59,203 @@ def construct(self): s = Square() self.play(FadeIn(s)) self.play(s.animate.scale(2)) - self.wait() - ''' - rendered_code = Code(code=code, tab_width=4, background="window", - language="Python", font="Monospace") + self.wait()''' + + rendered_code = Code( + code_string=code, + language="python", + background="window", + background_config={"stroke_color": "maroon"}, + ) self.add(rendered_code) Parameters ---------- - file_name : :class:`str` - Name of the code file to display. - code : :class:`str` - If ``file_name`` is not specified, a code string can be - passed directly. - tab_width : :class:`int`, optional - Number of space characters corresponding to a tab character. Defaults to 3. - line_spacing : :class:`float`, optional - Amount of space between lines in relation to font size. Defaults to 0.3, which means 30% of font size. - font_size : class:`float`, optional - A number which scales displayed code. Defaults to 24. - font : :class:`str`, optional - The name of the text font to be used. Defaults to ``"Monospac821 BT"``. - stroke_width : class:`float`, optional - Stroke width for text. 0 is recommended, and the default. - margin: class :`float`, optional - Inner margin of text from the background. Defaults to 0.3. - indentation_chars : :class:`str`, optional - "Indentation chars" refers to the spaces/tabs at the beginning of a given code line. Defaults to ``" "`` (spaces). - background : :class:`str`, optional - Defines the background's type. Currently supports only ``"rectangle"`` (default) and ``"window"``. - background_stroke_width : class:`float`, optional - Defines the stroke width of the background. Defaults to 1. - background_stroke_color : class:`str`, optional - Defines the stroke color for the background. Defaults to ``WHITE``. - corner_radius : :class:`float`, optional - Defines the corner radius for the background. Defaults to 0.2. - insert_line_no : :class:`bool`, optional - Defines whether line numbers should be inserted in displayed code. Defaults to ``True``. - line_no_from : :class:`int`, optional - Defines the first line's number in the line count. Defaults to 1. - line_no_buff : :class:`float`, optional - Defines the spacing between line numbers and displayed code. Defaults to 0.4. - style : :class:`str`, optional - Defines the style type of displayed code. You can see possible names of styles in with :attr:`styles_list`. Defaults to ``"vim"``. - language : Optional[:class:`str`], optional - Specifies the programming language the given code was written in. If ``None`` - (the default), the language will be automatically detected. For the list of - possible options, visit https://pygments.org/docs/lexers/ and look for - 'aliases or short names'. - generate_html_file : :class:`bool`, optional - Defines whether to generate highlighted html code to the folder `assets/codes/generated_html_files`. Defaults to `False`. - - Attributes - ---------- - background_mobject : :class:`~.VGroup` - The background of the code listing. - line_numbers : :class:`~.Paragraph` - The line numbers for the code listing. Empty, if - ``insert_line_no=False`` has been specified. - code : :class:`~.Paragraph` - The highlighted code. - + code_file + The path to the code file to display. + code_string + Alternatively, the code string to display. + language + The programming language of the code. If not specified, it will be + guessed from the file extension or the code itself. + formatter_style + The style to use for the code highlighting. Defaults to ``"vim"``. + A list of all available styles can be obtained by calling + :meth:`.Code.get_styles_list`. + tab_width + The width of a tab character in spaces. Defaults to 4. + add_line_numbers + Whether to display line numbers. Defaults to ``True``. + line_numbers_from + The first line number to display. Defaults to 1. + background + The type of background to use. Can be either ``"rectangle"`` (the + default) or ``"window"``. + background_config + Keyword arguments passed to the background constructor. Default + settings are stored in the class attribute + :attr:`.default_background_config` (which can also be modified + directly). + paragraph_config + Keyword arguments passed to the constructor of the + :class:`.Paragraph` objects holding the code, and the line + numbers. Default settings are stored in the class attribute + :attr:`.default_paragraph_config` (which can also be modified + directly). """ - # tuples in the form (name, aliases, filetypes, mimetypes) - # 'language' is aliases or short names - # For more information about pygments.lexers visit https://pygments.org/docs/lexers/ - # from pygments.lexers import get_all_lexers - # all_lexers = get_all_lexers() - styles_list = list(get_all_styles()) - # For more information about pygments.styles visit https://pygments.org/docs/styles/ + _styles_list_cache: list[str] | None = None + default_background_config: dict[str, Any] = { + "buff": 0.3, + "fill_color": ManimColor("#222"), + "stroke_color": WHITE, + "corner_radius": 0.2, + "stroke_width": 1, + "fill_opacity": 1, + } + default_paragraph_config: dict[str, Any] = { + "font": "Monospace", + "font_size": 24, + "line_spacing": 0.5, + "disable_ligatures": True, + } def __init__( self, - file_name=None, - code=None, - tab_width=3, - line_spacing=0.3, - font_size=24, - font="Monospac821 BT", - stroke_width=0, - margin=0.3, - indentation_chars=" ", - background="rectangle", # or window - background_stroke_width=1, - background_stroke_color=WHITE, - corner_radius=0.2, - insert_line_no=True, - line_no_from=1, - line_no_buff=0.4, - style="vim", - language=None, - generate_html_file=False, - **kwargs, + code_file: StrPath | None = None, + code_string: str | None = None, + language: str | None = None, + formatter_style: str = "vim", + tab_width: int = 4, + add_line_numbers: bool = True, + line_numbers_from: int = 1, + background: Literal["rectangle", "window"] = "rectangle", + background_config: dict[str, Any] | None = None, + paragraph_config: dict[str, Any] | None = None, ): - super().__init__( - stroke_width=stroke_width, - **kwargs, - ) - self.background_stroke_color = background_stroke_color - self.background_stroke_width = background_stroke_width - self.tab_width = tab_width - self.line_spacing = line_spacing - self.font = font - self.font_size = font_size - self.margin = margin - self.indentation_chars = indentation_chars - self.background = background - self.corner_radius = corner_radius - self.insert_line_no = insert_line_no - self.line_no_from = line_no_from - self.line_no_buff = line_no_buff - self.style = style - self.language = language - self.generate_html_file = generate_html_file - - self.file_path = None - self.file_name = file_name - if self.file_name: - self._ensure_valid_file() - with open(self.file_path) as f: - self.code_string = f.read() - elif code: - self.code_string = code - else: - raise ValueError( - "Neither a code file nor a code string have been specified.", - ) - if isinstance(self.style, str): - self.style = self.style.lower() - self._gen_html_string() - strati = self.html_string.find("background:") - self.background_color = self.html_string[strati + 12 : strati + 19] - self._gen_code_json() - - self.code = self._gen_colored_lines() - if self.insert_line_no: - self.line_numbers = self._gen_line_numbers() - self.line_numbers.next_to(self.code, direction=LEFT, buff=self.line_no_buff) - if self.background == "rectangle": - if self.insert_line_no: - foreground = VGroup(self.code, self.line_numbers) + super().__init__() + + if code_file is not None: + code_file = Path(code_file) + code_string = code_file.read_text(encoding="utf-8") + lexer = guess_lexer_for_filename(code_file.name, code_string) + elif code_string is not None: + if language is not None: + lexer = get_lexer_by_name(language) else: - foreground = self.code - rect = SurroundingRectangle( - foreground, - buff=self.margin, - color=self.background_color, - fill_color=self.background_color, - stroke_width=self.background_stroke_width, - stroke_color=self.background_stroke_color, - fill_opacity=1, - ) - rect.round_corners(self.corner_radius) - self.background_mobject = rect + lexer = guess_lexer(code_string) else: - if self.insert_line_no: - foreground = VGroup(self.code, self.line_numbers) - else: - foreground = self.code - height = foreground.height + 0.1 * 3 + 2 * self.margin - width = foreground.width + 0.1 * 3 + 2 * self.margin - - rect = RoundedRectangle( - corner_radius=self.corner_radius, - height=height, - width=width, - stroke_width=self.background_stroke_width, - stroke_color=self.background_stroke_color, - color=self.background_color, - fill_opacity=1, - ) - red_button = Dot(radius=0.1, stroke_width=0, color="#ff5f56") - red_button.shift(LEFT * 0.1 * 3) - yellow_button = Dot(radius=0.1, stroke_width=0, color="#ffbd2e") - green_button = Dot(radius=0.1, stroke_width=0, color="#27c93f") - green_button.shift(RIGHT * 0.1 * 3) - buttons = VGroup(red_button, yellow_button, green_button) - buttons.shift( - UP * (height / 2 - 0.1 * 2 - 0.05) - + LEFT * (width / 2 - 0.1 * 5 - self.corner_radius / 2 - 0.05), - ) - - self.background_mobject = VGroup(rect, buttons) - x = (height - foreground.height) / 2 - 0.1 * 3 - self.background_mobject.shift(foreground.get_center()) - self.background_mobject.shift(UP * x) - if self.insert_line_no: - super().__init__( - self.background_mobject, self.line_numbers, self.code, **kwargs - ) - else: - super().__init__( - self.background_mobject, - Dot(fill_opacity=0, stroke_opacity=0), - self.code, - **kwargs, - ) - self.move_to(np.array([0, 0, 0])) - - def _ensure_valid_file(self): - """Function to validate file.""" - if self.file_name is None: - raise Exception("Must specify file for Code") - possible_paths = [ - os.path.join(os.path.join("assets", "codes"), self.file_name), - self.file_name, - ] - for path in possible_paths: - if os.path.exists(path): - self.file_path = path - return - error = ( - f"From: {os.getcwd()}, could not find {self.file_name} at either " - + f"of these locations: {possible_paths}" - ) - raise OSError(error) - - def _gen_line_numbers(self): - """Function to generate line_numbers. - - Returns - ------- - :class:`~.Paragraph` - The generated line_numbers according to parameters. - """ - line_numbers_array = [] - for line_no in range(0, self.code_json.__len__()): - number = str(self.line_no_from + line_no) - line_numbers_array.append(number) - line_numbers = Paragraph( - *list(line_numbers_array), - line_spacing=self.line_spacing, - alignment="right", - font_size=self.font_size, - font=self.font, - disable_ligatures=True, - stroke_width=self.stroke_width, - ) - for i in line_numbers: - i.set_color(self.default_color) - return line_numbers + raise ValueError("Either a code file or a code string must be specified.") - def _gen_colored_lines(self): - """Function to generate code. + code_string = code_string.expandtabs(tabsize=tab_width) - Returns - ------- - :class:`~.Paragraph` - The generated code according to parameters. - """ - lines_text = [] - for line_no in range(0, self.code_json.__len__()): - line_str = "" - for word_index in range(self.code_json[line_no].__len__()): - line_str = line_str + self.code_json[line_no][word_index][0] - lines_text.append(self.tab_spaces[line_no] * "\t" + line_str) - code = Paragraph( - *list(lines_text), - line_spacing=self.line_spacing, - tab_width=self.tab_width, - font_size=self.font_size, - font=self.font, - disable_ligatures=True, - stroke_width=self.stroke_width, + formatter = HtmlFormatter( + style=formatter_style, + noclasses=True, + cssclasses="", ) - for line_no in range(code.__len__()): - line = code.chars[line_no] - line_char_index = self.tab_spaces[line_no] - for word_index in range(self.code_json[line_no].__len__()): - line[ - line_char_index : line_char_index - + self.code_json[line_no][word_index][0].__len__() - ].set_color(self.code_json[line_no][word_index][1]) - line_char_index += self.code_json[line_no][word_index][0].__len__() - return code - - def _gen_html_string(self): - """Function to generate html string with code highlighted and stores in variable html_string.""" - self.html_string = _hilite_me( - self.code_string, - self.language, - self.style, - self.insert_line_no, - "border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;", - self.file_path, - self.line_no_from, + soup = BeautifulSoup( + highlight(code_string, lexer, formatter), features="html.parser" ) - - if self.generate_html_file: - os.makedirs( - os.path.join("assets", "codes", "generated_html_files"), - exist_ok=True, - ) - with open( - os.path.join( - "assets", - "codes", - "generated_html_files", - self.file_name + ".html", - ), - "w", - ) as file: - file.write(self.html_string) - - def _gen_code_json(self): - """Function to background_color, generate code_json and tab_spaces from html_string. - background_color is just background color of displayed code. - code_json is 2d array with rows as line numbers - and columns as a array with length 2 having text and text's color value. - tab_spaces is 2d array with rows as line numbers - and columns as corresponding number of indentation_chars in front of that line in code. - """ - if ( - self.background_color == "#111111" - or self.background_color == "#272822" - or self.background_color == "#202020" - or self.background_color == "#000000" - ): - self.default_color = "#ffffff" - else: - self.default_color = "#000000" - # print(self.default_color,self.background_color) - for i in range(3, -1, -1): - self.html_string = self.html_string.replace("" + " " * i, - " " * i + "", - ) - self.html_string = self.html_string.replace("background-color:", "background:") - - if self.insert_line_no: - start_point = self.html_string.find("") - lines[0] = lines[0][start_point + 1 :] - # print(lines) - self.code_json = [] - self.tab_spaces = [] - code_json_line_index = -1 - for line_index in range(0, lines.__len__()): - # print(lines[line_index]) - self.code_json.append([]) - code_json_line_index = code_json_line_index + 1 - if lines[line_index].startswith(self.indentation_chars): - start_point = lines[line_index].find("<") - starting_string = lines[line_index][:start_point] - indentation_chars_count = lines[line_index][:start_point].count( - self.indentation_chars, - ) - if ( - starting_string.__len__() - != indentation_chars_count * self.indentation_chars.__len__() - ): - lines[line_index] = ( - "\t" * indentation_chars_count - + starting_string[ - starting_string.rfind(self.indentation_chars) - + self.indentation_chars.__len__() : - ] - + lines[line_index][start_point:] - ) - else: - lines[line_index] = ( - "\t" * indentation_chars_count + lines[line_index][start_point:] + self._code_html = soup.find("pre") + assert isinstance(self._code_html, Tag) + + # as we are using Paragraph to render the text, we need to find the character indices + # of the segments of changed color in the HTML code + color_ranges = [] + current_line_color_ranges = [] + current_line_char_index = 0 + for child in self._code_html.children: + if child.name == "span": + try: + child_style = child["style"] + if isinstance(child_style, str): + color = child_style.removeprefix("color: ") + else: + color = None + except KeyError: + color = None + current_line_color_ranges.append( + ( + current_line_char_index, + current_line_char_index + len(child.text), + color, ) - indentation_chars_count = 0 - if lines[line_index]: - while lines[line_index][indentation_chars_count] == "\t": - indentation_chars_count = indentation_chars_count + 1 - self.tab_spaces.append(indentation_chars_count) - # print(lines[line_index]) - lines[line_index] = self._correct_non_span(lines[line_index]) - # print(lines[line_index]) - words = lines[line_index].split("") - end_point = words[word_index].find("") - text = words[word_index][start_point + 1 : end_point] - text = html.unescape(text) - if text != "": - # print(text, "'" + color + "'") - self.code_json[code_json_line_index].append([text, color]) - # print(self.code_json) - - def _correct_non_span(self, line_str): - """Function put text color to those strings that don't have one according to background_color of displayed code. - - Parameters - --------- - line_str : :class:`str` - Takes a html element's string to put color to it according to background_color of displayed code. - - Returns - ------- - :class:`str` - The generated html element's string with having color attributes. - """ - words = line_str.split("") - line_str = "" - for i in range(0, words.__len__()): - if i != words.__len__() - 1: - j = words[i].find("' - + words[i][starti:j] - + "" - ) - else: - temp = ( - '' - + words[i][starti:j] - ) - temp = temp + words[i][j:] - words[i] = temp - if words[i] != "": - line_str = line_str + words[i] + "" - return line_str - - -def _hilite_me( - code, - language, - style, - insert_line_no, - divstyles, - file_path, - line_no_from, -): - """Function to highlight code from string to html. - - Parameters - --------- - code : :class:`str` - Code string. - language : :class:`str` - The name of the programming language the given code was written in. - style : :class:`str` - Code style name. - insert_line_no : :class:`bool` - Defines whether line numbers should be inserted in the html file. - divstyles : :class:`str` - Some html css styles. - file_path : :class:`str` - Path of code file. - line_no_from : :class:`int` - Defines the first line's number in the line count. - """ - style = style or "colorful" - defstyles = "overflow:auto;width:auto;" - - formatter = HtmlFormatter( - style=style, - linenos=False, - noclasses=True, - cssclass="", - cssstyles=defstyles + divstyles, - prestyles="margin: 0", - ) - if language is None and file_path: - lexer = guess_lexer_for_filename(file_path, code) - html = highlight(code, lexer, formatter) - elif language is None: - raise ValueError( - "The code language has to be specified when rendering a code string", + for char in child.text: + if char == "\n": + color_ranges.append(current_line_color_ranges) + current_line_color_ranges = [] + current_line_char_index = 0 + else: + current_line_char_index += 1 + + color_ranges.append(current_line_color_ranges) + code_lines = self._code_html.get_text().removesuffix("\n").split("\n") + + if paragraph_config is None: + paragraph_config = {} + base_paragraph_config = self.default_paragraph_config.copy() + base_paragraph_config.update(paragraph_config) + + self.code_lines = Paragraph( + *code_lines, + **base_paragraph_config, ) - else: - html = highlight(code, get_lexer_by_name(language, **{}), formatter) - if insert_line_no: - html = _insert_line_numbers_in_html(html, line_no_from) - html = "" + html - return html + for line, color_range in zip(self.code_lines, color_ranges): + for start, end, color in color_range: + line[start:end].set_color(color) + + if add_line_numbers: + base_paragraph_config.update({"alignment": "right"}) + self.line_numbers = Paragraph( + *[ + str(i) + for i in range( + line_numbers_from, line_numbers_from + len(self.code_lines) + ) + ], + **base_paragraph_config, + ) + self.line_numbers.next_to(self.code_lines, direction=LEFT).align_to( + self.code_lines, UP + ) + self.add(self.line_numbers) + self.add(self.code_lines) -def _insert_line_numbers_in_html(html, line_no_from): - """Function that inserts line numbers in the highlighted HTML code. + if background_config is None: + background_config = {} + background_config_base = self.default_background_config.copy() + background_config_base.update(background_config) - Parameters - --------- - html : :class:`str` - html string of highlighted code. - line_no_from : :class:`int` - Defines the first line's number in the line count. + if background == "rectangle": + self.background = SurroundingRectangle( + self, + **background_config_base, + ) + elif background == "window": + buttons = VGroup( + Dot(radius=0.1, stroke_width=0, color=button_color) + for button_color in ["#ff5f56", "#ffbd2e", "#27c93f"] + ).arrange(RIGHT, buff=0.1) + buttons.next_to(self, UP, buff=0.1).align_to(self, LEFT).shift(LEFT * 0.1) + self.background = SurroundingRectangle( + VGroup(self, buttons), + **background_config_base, + ) + buttons.shift(UP * 0.1 + LEFT * 0.1) + self.background.add(buttons) + else: + raise ValueError(f"Unknown background type: {background}") - Returns - ------- - :class:`str` - The generated html string with having line numbers. - """ - match = re.search("(]*>)(.*)()", html, re.DOTALL) - if not match: - return html - pre_open = match.group(1) - pre = match.group(2) - pre_close = match.group(3) + self.add_to_back(self.background) - html = html.replace(pre_close, "") - numbers = range(line_no_from, line_no_from + pre.count("\n") + 1) - format_lines = "%" + str(len(str(numbers[-1]))) + "i" - lines = "\n".join(format_lines % i for i in numbers) - html = html.replace( - pre_open, - "
" + pre_open + lines + "" + pre_open, - ) - return html + @classmethod + def get_styles_list(cls) -> list[str]: + """Get the list of all available formatter styles.""" + if cls._styles_list_cache is None: + cls._styles_list_cache = list(get_all_styles()) + return cls._styles_list_cache diff --git a/manim/mobject/text/numbers.py b/manim/mobject/text/numbers.py index 624ec950b3..1c74cf5f0a 100644 --- a/manim/mobject/text/numbers.py +++ b/manim/mobject/text/numbers.py @@ -4,22 +4,54 @@ __all__ = ["DecimalNumber", "Integer", "Variable"] -from typing import Sequence +from collections.abc import Sequence +from typing import Any import numpy as np from manim import config from manim.constants import * from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL -from manim.mobject.text.tex_mobject import MathTex, SingleStringMathTex +from manim.mobject.text.tex_mobject import MathTex, SingleStringMathTex, Tex +from manim.mobject.text.text_mobject import Text from manim.mobject.types.vectorized_mobject import VMobject from manim.mobject.value_tracker import ValueTracker string_to_mob_map = {} +__all__ = ["DecimalNumber", "Integer", "Variable"] + class DecimalNumber(VMobject, metaclass=ConvertToOpenGL): - """An mobject representing a decimal number. + r"""An mobject representing a decimal number. + + Parameters + ---------- + number + The numeric value to be displayed. It can later be modified using :meth:`.set_value`. + num_decimal_places + The number of decimal places after the decimal separator. Values are automatically rounded. + mob_class + The class for rendering digits and units, by default :class:`.MathTex`. + include_sign + Set to ``True`` to include a sign for positive numbers and zero. + group_with_commas + When ``True`` thousands groups are separated by commas for readability. + digit_buff_per_font_unit + Additional spacing between digits. Scales with font size. + show_ellipsis + When a number has been truncated by rounding, indicate with an ellipsis (``...``). + unit + A unit string which can be placed to the right of the numerical values. + unit_buff_per_font_unit + An additional spacing between the numerical values and the unit. A value + of ``unit_buff_per_font_unit=0.003`` gives a decent spacing. Scales with font size. + include_background_rectangle + Adds a background rectangle to increase contrast on busy scenes. + edge_to_fix + Assuring right- or left-alignment of the full object. + font_size + Size of the font. Examples -------- @@ -33,6 +65,8 @@ def construct(self): show_ellipsis=True, num_decimal_places=3, include_sign=True, + unit=r"\text{M-Units}", + unit_buff_per_font_unit=0.003 ) square = Square().to_edge(UP) @@ -58,6 +92,7 @@ def __init__( digit_buff_per_font_unit: float = 0.001, show_ellipsis: bool = False, unit: str | None = None, # Aligned to bottom unless it starts with "^" + unit_buff_per_font_unit: float = 0, include_background_rectangle: bool = False, edge_to_fix: Sequence[float] = LEFT, font_size: float = DEFAULT_FONT_SIZE, @@ -65,7 +100,7 @@ def __init__( fill_opacity: float = 1.0, **kwargs, ): - super().__init__(**kwargs) + super().__init__(**kwargs, stroke_width=stroke_width) self.number = number self.num_decimal_places = num_decimal_places self.include_sign = include_sign @@ -74,10 +109,10 @@ def __init__( self.digit_buff_per_font_unit = digit_buff_per_font_unit self.show_ellipsis = show_ellipsis self.unit = unit + self.unit_buff_per_font_unit = unit_buff_per_font_unit self.include_background_rectangle = include_background_rectangle self.edge_to_fix = edge_to_fix self._font_size = font_size - self.stroke_width = stroke_width self.fill_opacity = fill_opacity self.initial_config = kwargs.copy() @@ -89,6 +124,7 @@ def __init__( "digit_buff_per_font_unit": digit_buff_per_font_unit, "show_ellipsis": show_ellipsis, "unit": unit, + "unit_buff_per_font_unit": unit_buff_per_font_unit, "include_background_rectangle": include_background_rectangle, "edge_to_fix": edge_to_fix, "font_size": font_size, @@ -130,15 +166,25 @@ def _set_submobjects_from_number(self, number): self._string_to_mob("\\dots", SingleStringMathTex, color=self.color), ) - if self.unit is not None: - self.unit_sign = self._string_to_mob(self.unit, SingleStringMathTex) - self.add(self.unit_sign) - self.arrange( buff=self.digit_buff_per_font_unit * self._font_size, aligned_edge=DOWN, ) + if self.unit is not None: + self.unit_sign = self._string_to_mob(self.unit, SingleStringMathTex) + self.add( + self.unit_sign.next_to( + self, + direction=RIGHT, + buff=(self.unit_buff_per_font_unit + self.digit_buff_per_font_unit) + * self._font_size, + aligned_edge=DOWN, + ) + ) + + self.move_to(ORIGIN) + # Handle alignment of parts that should be aligned # to the bottom for i, c in enumerate(num_string): @@ -165,15 +211,11 @@ def _get_num_string(self, number): rounded_num = np.round(number, self.num_decimal_places) if num_string.startswith("-") and rounded_num == 0: - if self.include_sign: - num_string = "+" + num_string[1:] - else: - num_string = num_string[1:] + num_string = "+" + num_string[1:] if self.include_sign else num_string[1:] return num_string def _string_to_mob(self, string: str, mob_class: VMobject | None = None, **kwargs): - if mob_class is None: mob_class = self.mob_class @@ -251,7 +293,7 @@ def set_value(self, number: float): for sm1, sm2 in zip(self.submobjects, old_submobjects): sm1.match_style(sm2) - if config.renderer != "opengl": + if config.renderer == RendererType.CAIRO: for mob in old_family: # Dumb hack...due to how scene handles families # of animated mobjects @@ -286,7 +328,9 @@ def construct(self): self.add(Integer(number=6.28).set_x(-1.5).set_y(-2).set_color(YELLOW).scale(1.4)) """ - def __init__(self, number=0, num_decimal_places=0, **kwargs): + def __init__( + self, number: float = 0, num_decimal_places: int = 0, **kwargs: Any + ) -> None: super().__init__(number=number, num_decimal_places=num_decimal_places, **kwargs) def get_value(self): @@ -299,21 +343,21 @@ class Variable(VMobject, metaclass=ConvertToOpenGL): Parameters ---------- - var : Union[:class:`int`, :class:`float`] + var The initial value you need to keep track of and display. - label : Union[:class:`str`, :class:`~.Tex`, :class:`~.MathTex`, :class:`~.Text`, :class:`~.TexSymbol`, :class:`~.SingleStringMathTex`] + label The label for your variable. Raw strings are convertex to :class:`~.MathTex` objects. - var_type : Union[:class:`DecimalNumber`, :class:`Integer`], optional + var_type The class used for displaying the number. Defaults to :class:`DecimalNumber`. - num_decimal_places : :class:`int`, optional + num_decimal_places The number of decimal places to display in your variable. Defaults to 2. If `var_type` is an :class:`Integer`, this parameter is ignored. - kwargs : Any + kwargs Other arguments to be passed to `~.Mobject`. Attributes ---------- - label : Union[:class:`str`, :class:`~.Tex`, :class:`~.MathTex`, :class:`~.Text`, :class:`~.TexSymbol`, :class:`~.SingleStringMathTex`] + label : Union[:class:`str`, :class:`~.Tex`, :class:`~.MathTex`, :class:`~.Text`, :class:`~.SingleStringMathTex`] The label for your variable, for example ``x = ...``. tracker : :class:`~.ValueTracker` Useful in updating the value of your variable on-screen. @@ -397,9 +441,13 @@ def construct(self): """ def __init__( - self, var, label, var_type=DecimalNumber, num_decimal_places=2, **kwargs + self, + var: float, + label: str | Tex | MathTex | Text | SingleStringMathTex, + var_type: DecimalNumber | Integer = DecimalNumber, + num_decimal_places: int = 2, + **kwargs, ): - self.label = MathTex(label) if isinstance(label, str) else label equals = MathTex("=").next_to(self.label, RIGHT) self.label.add(equals) diff --git a/manim/mobject/text/tex_mobject.py b/manim/mobject/text/tex_mobject.py index f918a3bd78..26334a60d9 100644 --- a/manim/mobject/text/tex_mobject.py +++ b/manim/mobject/text/tex_mobject.py @@ -12,8 +12,9 @@ from __future__ import annotations +from manim.utils.color import BLACK, ManimColor, ParsableManimColor + __all__ = [ - "TexSymbol", "SingleStringMathTex", "MathTex", "Tex", @@ -25,33 +26,21 @@ import itertools as it import operator as op import re +from collections.abc import Iterable from functools import reduce from textwrap import dedent -from typing import Dict, Iterable, Optional - -from colour import Color from manim import config, logger from manim.constants import * from manim.mobject.geometry.line import Line -from manim.mobject.svg.style_utils import parse_style from manim.mobject.svg.svg_mobject import SVGMobject -from manim.mobject.svg.svg_path import SVGPathMobject -from manim.mobject.types.vectorized_mobject import VectorizedPoint, VGroup, VMobject +from manim.mobject.types.vectorized_mobject import VGroup, VMobject from manim.utils.tex import TexTemplate from manim.utils.tex_file_writing import tex_to_svg_file -SCALE_FACTOR_PER_FONT_POINT = 1 / 960 - tex_string_to_mob_map = {} -class TexSymbol(SVGPathMobject): - """Purely a renaming of SVGPathMobject.""" - - pass - - class SingleStringMathTex(SVGMobject): """Elementary building block for rendering text with LaTeX. @@ -73,13 +62,11 @@ def __init__( tex_environment: str = "align*", tex_template: TexTemplate | None = None, font_size: float = DEFAULT_FONT_SIZE, + color: ParsableManimColor | None = None, **kwargs, ): - - if kwargs.get("color") is None: - # makes it so that color isn't explicitly passed for these mobs, - # and can instead inherit from the parent - kwargs["color"] = VMobject().color + if color is None: + color = VMobject().color self._font_size = font_size self.organize_left_to_right = organize_left_to_right @@ -100,10 +87,15 @@ def __init__( should_center=should_center, stroke_width=stroke_width, height=height, - should_subdivide_sharp_curves=True, - should_remove_null_curves=True, + color=color, + path_string_config={ + "should_subdivide_sharp_curves": True, + "should_remove_null_curves": True, + }, **kwargs, ) + self.init_colors() + # used for scaling via font_size.setter self.initial_height = self.height @@ -183,8 +175,8 @@ def _modify_special_strings(self, tex): tex = self._remove_stray_braces(tex) for context in ["array"]: - begin_in = ("\\begin{%s}" % context) in tex - end_in = ("\\end{%s}" % context) in tex + begin_in = ("\\begin{%s}" % context) in tex # noqa: UP031 + end_in = ("\\end{%s}" % context) in tex # noqa: UP031 if begin_in ^ end_in: # Just turn this into a blank string, # which means caller should leave a @@ -199,7 +191,6 @@ def _remove_stray_braces(self, tex): This is important when the braces in the TeX code are spread over multiple arguments as in, e.g., ``MathTex(r"e^{i", r"\tau} = 1")``. """ - # "\{" does not count (it's a brace literal), but "\\{" counts (it's a new line and then brace) num_lefts = tex.count("{") - tex.count("\\{") + tex.count("\\\\{") num_rights = tex.count("}") - tex.count("\\}") + tex.count("\\\\}") @@ -218,13 +209,17 @@ def _organize_submobjects_left_to_right(self): def get_tex_string(self): return self.tex_string - def path_string_to_mobject(self, path_string, style): - # Overwrite superclass default to use - # specialized path_string mobject - return TexSymbol(path_string, **self.path_string_config, **parse_style(style)) - def init_colors(self, propagate_colors=True): - super().init_colors(propagate_colors=propagate_colors) + for submobject in self.submobjects: + # needed to preserve original (non-black) + # TeX colors of individual submobjects + if submobject.color != BLACK: + continue + submobject.color = self.color + if config.renderer == RendererType.OPENGL: + submobject.init_colors() + elif config.renderer == RendererType.CAIRO: + submobject.init_colors(propagate_colors=propagate_colors) class MathTex(SingleStringMathTex): @@ -263,7 +258,7 @@ def __init__( *tex_strings, arg_separator: str = " ", substrings_to_isolate: Iterable[str] | None = None, - tex_to_color_map: dict[str, Color] = None, + tex_to_color_map: dict[str, ManimColor] = None, tex_environment: str = "align*", **kwargs, ): @@ -354,10 +349,6 @@ def _break_up_by_substrings(self): curr_index + num_submobs + len("".join(self.arg_separator.split())) ) if num_submobs == 0: - # For cases like empty tex_strings, we want the corresponding - # part of the whole MathTex to be a VectorizedPoint - # positioned in the right part of the MathTex - sub_tex_mob.submobjects = [VectorizedPoint()] last_submob_index = min(curr_index, len(self.submobjects) - 1) sub_tex_mob.move_to(self.submobjects[last_submob_index], RIGHT) else: @@ -389,6 +380,29 @@ def set_color_by_tex(self, tex, color, **kwargs): part.set_color(color) return self + def set_opacity_by_tex( + self, tex: str, opacity: float = 0.5, remaining_opacity: float = None, **kwargs + ): + """ + Sets the opacity of the tex specified. If 'remaining_opacity' is specified, + then the remaining tex will be set to that opacity. + + Parameters + ---------- + tex + The tex to set the opacity of. + opacity + Default 0.5. The opacity to set the tex to + remaining_opacity + Default None. The opacity to set the remaining tex to. + If None, then the remaining tex will not be changed + """ + if remaining_opacity is not None: + self.set_opacity(opacity=remaining_opacity) + for part in self.get_parts_by_tex(tex): + part.set_opacity(opacity) + return self + def set_color_by_tex_to_color_map(self, texs_to_color_map, **kwargs): for texs, color in list(texs_to_color_map.items()): try: @@ -418,6 +432,10 @@ def sort_alphabetically(self): class Tex(MathTex): r"""A string compiled with LaTeX in normal mode. + The color can be set using + the ``color`` argument. Any parts of the ``tex_string`` that are colored by the + TeX commands ``\color`` or ``\textcolor`` will retain their original color. + Tests ----- @@ -440,7 +458,8 @@ def __init__( class BulletedList(Tex): - """ + """A bulleted list. + Examples -------- @@ -493,7 +512,8 @@ def fade_all_but(self, index_or_string, opacity=0.5): class Title(Tex): - """ + """A mobject representing an underlined title. + Examples -------- .. manim:: TitleExample @@ -517,7 +537,6 @@ def __init__( underline_buff=MED_SMALL_BUFF, **kwargs, ): - self.include_underline = include_underline self.match_underline_width_to_text = match_underline_width_to_text self.underline_buff = underline_buff diff --git a/manim/mobject/text/text_mobject.py b/manim/mobject/text/text_mobject.py index f01a88c551..5f20dff2a4 100644 --- a/manim/mobject/text/text_mobject.py +++ b/manim/mobject/text/text_mobject.py @@ -6,7 +6,7 @@ .. important:: - See the corresponding tutorial :ref:`rendering-with-latex` + See the corresponding tutorial :ref:`using-text-objects`, especially for information about fonts. The simplest way to add text to your animations is to use the :class:`~.Text` class. It uses the Pango library to render text. @@ -49,21 +49,21 @@ def construct(self): from __future__ import annotations +import functools + __all__ = ["Text", "Paragraph", "MarkupText", "register_font"] import copy import hashlib -import os import re +from collections.abc import Iterable, Sequence from contextlib import contextmanager from itertools import chain from pathlib import Path -from typing import Iterable, Sequence import manimpango import numpy as np -from colour import Color from manimpango import MarkupUtils, PangoUtils, TextSetting from manim import config, logger @@ -71,20 +71,22 @@ def construct(self): from manim.mobject.geometry.arc import Dot from manim.mobject.svg.svg_mobject import SVGMobject from manim.mobject.types.vectorized_mobject import VGroup, VMobject -from manim.utils.color import Colors, color_gradient +from manim.utils.color import ManimColor, ParsableManimColor, color_gradient from manim.utils.deprecation import deprecated TEXT_MOB_SCALE_FACTOR = 0.05 DEFAULT_LINE_SPACING_SCALE = 0.3 TEXT2SVG_ADJUSTMENT_FACTOR = 4.8 +__all__ = ["Text", "Paragraph", "MarkupText", "register_font"] + -def remove_invisible_chars(mobject): +def remove_invisible_chars(mobject: SVGMobject) -> SVGMobject: """Function to remove unwanted invisible characters from some mobjects. Parameters ---------- - mobject : :class:`~.SVGMobject` + mobject Any SVGMobject from which we want to remove unwanted invisible characters. Returns @@ -92,7 +94,7 @@ def remove_invisible_chars(mobject): :class:`~.SVGMobject` The SVGMobject without unwanted invisible characters. """ - + # TODO: Refactor needed iscode = False if mobject.__class__.__name__ == "Text": mobject = mobject[:] @@ -102,7 +104,7 @@ def remove_invisible_chars(mobject): mobject = mobject.code mobject_without_dots = VGroup() if mobject[0].__class__ == VGroup: - for i in range(mobject.__len__()): + for i in range(len(mobject)): mobject_without_dots.add(VGroup()) mobject_without_dots[i].add(*(k for k in mobject[i] if k.__class__ != Dot)) else: @@ -123,19 +125,26 @@ class Paragraph(VGroup): Parameters ---------- - line_spacing : :class:`float`, optional - Represents the spacing between lines. Default to -1, which means auto. - alignment : :class:`str`, optional - Defines the alignment of paragraph. Default to "left". Possible values are "left", "right", "center" + line_spacing + Represents the spacing between lines. Defaults to -1, which means auto. + alignment + Defines the alignment of paragraph. Defaults to None. Possible values are "left", "right" or "center". Examples -------- Normal usage:: - paragraph = Paragraph('this is a awesome', 'paragraph', - 'With \nNewlines', '\tWith Tabs', - ' With Spaces', 'With Alignments', - 'center', 'left', 'right') + paragraph = Paragraph( + "this is a awesome", + "paragraph", + "With \nNewlines", + "\tWith Tabs", + " With Spaces", + "With Alignments", + "center", + "left", + "right", + ) Remove unwanted invisible characters:: @@ -144,50 +153,37 @@ class Paragraph(VGroup): """ - def __init__(self, *text, line_spacing=-1, alignment=None, **config): + def __init__( + self, + *text: Sequence[str], + line_spacing: float = -1, + alignment: str | None = None, + **kwargs, + ) -> None: self.line_spacing = line_spacing self.alignment = alignment + self.consider_spaces_as_chars = kwargs.get("disable_ligatures", False) super().__init__() lines_str = "\n".join(list(text)) - self.lines_text = Text(lines_str, line_spacing=line_spacing, **config) + self.lines_text = Text(lines_str, line_spacing=line_spacing, **kwargs) lines_str_list = lines_str.split("\n") self.chars = self._gen_chars(lines_str_list) - chars_lines_text_list = self.get_group_class()() - char_index_counter = 0 - for line_index in range(lines_str_list.__len__()): - chars_lines_text_list.add( - self.lines_text[ - char_index_counter : char_index_counter - + lines_str_list[line_index].__len__() - + 1 - ], - ) - char_index_counter += lines_str_list[line_index].__len__() + 1 - self.lines = [] - self.lines.append([]) - for line_no in range(chars_lines_text_list.__len__()): - self.lines[0].append(chars_lines_text_list[line_no]) - self.lines_initial_positions = [] - for line_no in range(self.lines[0].__len__()): - self.lines_initial_positions.append(self.lines[0][line_no].get_center()) - self.lines.append([]) - self.lines[1].extend( - [self.alignment for _ in range(chars_lines_text_list.__len__())], - ) + self.lines = [list(self.chars), [self.alignment] * len(self.chars)] + self.lines_initial_positions = [line.get_center() for line in self.lines[0]] self.add(*self.lines[0]) self.move_to(np.array([0, 0, 0])) if self.alignment: self._set_all_lines_alignments(self.alignment) - def _gen_chars(self, lines_str_list): - """Function to convert plain string to 2d-VGroup of chars. 2d-VGroup mean "VGroup of VGroup". + def _gen_chars(self, lines_str_list: list) -> VGroup: + """Function to convert a list of plain strings to a VGroup of VGroups of chars. Parameters ---------- - lines_str_list : :class:`str` - Plain text string. + lines_str_list + List of plain text strings. Returns ------- @@ -196,72 +192,85 @@ def _gen_chars(self, lines_str_list): """ char_index_counter = 0 chars = self.get_group_class()() - for line_no in range(lines_str_list.__len__()): + for line_no in range(len(lines_str_list)): + line_str = lines_str_list[line_no] + # Count all the characters in line_str + # Spaces may or may not count as characters + if self.consider_spaces_as_chars: + char_count = len(line_str) + else: + char_count = 0 + for char in line_str: + if not char.isspace(): + char_count += 1 + chars.add(self.get_group_class()()) chars[line_no].add( *self.lines_text.chars[ - char_index_counter : char_index_counter - + lines_str_list[line_no].__len__() - + 1 + char_index_counter : char_index_counter + char_count ] ) - char_index_counter += lines_str_list[line_no].__len__() + 1 + char_index_counter += char_count + if self.consider_spaces_as_chars: + # If spaces count as characters, count the extra \n character + # which separates Paragraph's lines to avoid issues + char_index_counter += 1 return chars - def _set_all_lines_alignments(self, alignment): + def _set_all_lines_alignments(self, alignment: str) -> Paragraph: """Function to set all line's alignment to a specific value. Parameters ---------- - alignment : :class:`str` + alignment Defines the alignment of paragraph. Possible values are "left", "right", "center". """ - for line_no in range(0, self.lines[0].__len__()): + for line_no in range(len(self.lines[0])): self._change_alignment_for_a_line(alignment, line_no) return self - def _set_line_alignment(self, alignment, line_no): + def _set_line_alignment(self, alignment: str, line_no: int) -> Paragraph: """Function to set one line's alignment to a specific value. Parameters ---------- - alignment : :class:`str` + alignment Defines the alignment of paragraph. Possible values are "left", "right", "center". - line_no : :class:`int` + line_no Defines the line number for which we want to set given alignment. """ self._change_alignment_for_a_line(alignment, line_no) return self - def _set_all_lines_to_initial_positions(self): + def _set_all_lines_to_initial_positions(self) -> Paragraph: """Set all lines to their initial positions.""" - self.lines[1] = [None for _ in range(self.lines[0].__len__())] - for line_no in range(0, self.lines[0].__len__()): + self.lines[1] = [None] * len(self.lines[0]) + for line_no in range(len(self.lines[0])): self[line_no].move_to( self.get_center() + self.lines_initial_positions[line_no], ) return self - def _set_line_to_initial_position(self, line_no): + def _set_line_to_initial_position(self, line_no: int) -> Paragraph: """Function to set one line to initial positions. Parameters ---------- - line_no : :class:`int` + line_no Defines the line number for which we want to set given alignment. """ self.lines[1][line_no] = None self[line_no].move_to(self.get_center() + self.lines_initial_positions[line_no]) return self - def _change_alignment_for_a_line(self, alignment, line_no): + def _change_alignment_for_a_line(self, alignment: str, line_no: int) -> None: """Function to change one line's alignment to a specific value. Parameters ---------- - alignment : :class:`str` + alignment Defines the alignment of paragraph. Possible values are "left", "right", "center". - line_no : :class:`int` + line_no Defines the line number for which we want to set given alignment. """ self.lines[1][line_no] = alignment @@ -292,20 +301,27 @@ def _change_alignment_for_a_line(self, alignment, line_no): class Text(SVGMobject): - r"""Display (non-LaTeX) text rendered using `Pango `_. + r"""Display (non-LaTeX) text rendered using `Pango `_. Text objects behave like a :class:`.VGroup`-like iterable of all characters in the given text. In particular, slicing is possible. Parameters ---------- - text : :class:`str` - The text that need to created as mobject. + text + The text that needs to be created as a mobject. + font + The font family to be used to render the text. This is either a system font or + one loaded with `register_font()`. Note that font family names may be different + across operating systems. + warn_missing_font + If True (default), Manim will issue a warning if the font does not exist in the + (case-sensitive) list of fonts returned from `manimpango.list_fonts()`. Returns ------- :class:`Text` - The mobject like :class:`.VGroup`. + The mobject-like :class:`.VGroup`. Examples --------- @@ -344,7 +360,7 @@ def construct(self): ) text6.scale(1.3).shift(DOWN) self.add(text1, text2, text3, text4, text5 , text6) - Group(*self.mobjects).arrange(DOWN, buff=.8).set_height(config.frame_height-LARGE_BUFF) + Group(*self.mobjects).arrange(DOWN, buff=.8).set(height=config.frame_height-LARGE_BUFF) .. manim:: TextMoreCustomization :save_last_frame: @@ -401,12 +417,17 @@ def construct(self): """ + @staticmethod + @functools.cache + def font_list() -> list[str]: + return manimpango.list_fonts() + def __init__( self, text: str, fill_opacity: float = 1.0, stroke_width: float = 0, - color: Color | str | None = None, + color: ParsableManimColor | None = None, font_size: float = DEFAULT_FONT_SIZE, line_spacing: float = -1, font: str = "", @@ -419,16 +440,31 @@ def __init__( t2w: dict[str, str] = None, gradient: tuple = None, tab_width: int = 4, + warn_missing_font: bool = True, # Mobject height: float = None, width: float = None, should_center: bool = True, - unpack_groups: bool = True, disable_ligatures: bool = False, + use_svg_cache: bool = False, **kwargs, - ): - + ) -> None: self.line_spacing = line_spacing + if font and warn_missing_font: + fonts_list = Text.font_list() + # handle special case of sans/sans-serif + if font.lower() == "sans-serif": + font = "sans" + if font not in fonts_list: + # check if the capitalized version is in the supported fonts + if font.capitalize() in fonts_list: + font = font.capitalize() + elif font.lower() in fonts_list: + font = font.lower() + elif font.title() in fonts_list: + font = font.title() + else: + logger.warning(f"Font {font} not in {fonts_list}.") self.font = font self._font_size = float(font_size) # needs to be a float or else size is inflated when font_size = 24 @@ -453,7 +489,7 @@ def __init__( t2g = kwargs.pop("text2gradient", t2g) t2s = kwargs.pop("text2slant", t2s) t2w = kwargs.pop("text2weight", t2w) - self.t2c = t2c + self.t2c = {k: ManimColor(v).to_hex() for k, v in t2c.items()} self.t2f = t2f self.t2g = t2g self.t2s = t2s @@ -472,8 +508,8 @@ def __init__( else: self.line_spacing = self._font_size + self._font_size * self.line_spacing - color = Color(color) if color else VMobject().color - file_name = self._text2svg(color) + color: ManimColor = ManimColor(color) if color else VMobject().color + file_name = self._text2svg(color.to_hex()) PangoUtils.remove_last_M(file_name) super().__init__( file_name, @@ -482,7 +518,7 @@ def __init__( height=height, width=width, should_center=should_center, - unpack_groups=unpack_groups, + use_svg_cache=use_svg_cache, **kwargs, ) self.text = text @@ -490,26 +526,63 @@ def __init__( self.submobjects = [*self._gen_chars()] self.chars = self.get_group_class()(*self.submobjects) self.text = text_without_tabs.replace(" ", "").replace("\n", "") - if config.renderer == "opengl": - nppc = self.n_points_per_curve - else: - nppc = self.n_points_per_cubic_curve + nppc = self.n_points_per_curve for each in self: if len(each.points) == 0: continue points = each.points - last = points[0] - each.clear_points() + curve_start = points[0] + assert len(curve_start) == self.dim, curve_start + # Some of the glyphs in this text might not be closed, + # so we close them by identifying when one curve ends + # but it is not where the next curve starts. + # It is more efficient to temporarily create a list + # of points and add them one at a time, then turn them + # into a numpy array at the end, rather than creating + # new numpy arrays every time a point or fixing line + # is added (which is O(n^2) for numpy arrays). + closed_curve_points = [] + # OpenGL has points be part of quadratic Bezier curves; + # Cairo uses cubic Bezier curves. + if nppc == 3: # RendererType.OPENGL + + def add_line_to(end): + nonlocal closed_curve_points + start = closed_curve_points[-1] + closed_curve_points += [ + start, + (start + end) / 2, + end, + ] + + else: # RendererType.CAIRO + + def add_line_to(end): + nonlocal closed_curve_points + start = closed_curve_points[-1] + closed_curve_points += [ + start, + (start + start + end) / 3, + (start + end + end) / 3, + end, + ] + for index, point in enumerate(points): - each.append_points([point]) + closed_curve_points.append(point) if ( index != len(points) - 1 and (index + 1) % nppc == 0 and any(point != points[index + 1]) ): - each.add_line_to(last) - last = points[index + 1] - each.add_line_to(last) + # Add straight line from last point on this curve to the + # start point on the next curve. We represent the line + # as a cubic bezier curve where the two control points + # are half-way between the start and stop point. + add_line_to(curve_start) + curve_start = points[index + 1] + # Make sure last curve is closed + add_line_to(curve_start) + each.points = np.array(closed_curve_points, ndmin=2) # anti-aliasing if height is None and width is None: self.scale(TEXT_MOB_SCALE_FACTOR) @@ -540,8 +613,8 @@ def font_size(self, font_val): def _gen_chars(self): chars = self.get_group_class()() submobjects_char_index = 0 - for char_index in range(self.text.__len__()): - if self.text[char_index] in (" ", "\t", "\n"): + for char_index in range(len(self.text)): + if self.text[char_index].isspace(): space = Dot(radius=0, fill_opacity=0, stroke_opacity=0) if char_index == 0: space.move_to(self.submobjects[submobjects_char_index].get_center()) @@ -590,16 +663,17 @@ def _set_color_by_t2c(self, t2c=None): ) def _set_color_by_t2g(self, t2g=None): """Sets gradient colors for specified - strings. Behaves similarly to ``set_color_by_t2c``.""" + strings. Behaves similarly to ``set_color_by_t2c``. + """ t2g = t2g if t2g else self.t2g for word, gradient in list(t2g.items()): for start, end in self._find_indexes(word, self.text): self.chars[start:end].set_color_by_gradient(*gradient) - def _text2hash(self, color: Color): + def _text2hash(self, color: ManimColor): """Generates ``sha256`` hash for file name.""" settings = ( - "PANGO" + self.font + self.slant + self.weight + color.hex_l + "PANGO" + self.font + self.slant + self.weight + str(color) ) # to differentiate Text and CairoText settings += str(self.t2f) + str(self.t2s) + str(self.t2w) + str(self.t2c) settings += str(self.line_spacing) + str(self._font_size) @@ -629,7 +703,7 @@ def _merge_settings( default = default_args[arg] if left != default and getattr(right_setting, arg) != default: raise ValueError( - f"Ambiguous style for text '{self.text[right_setting.start:right_setting.end]}':" + f"Ambiguous style for text '{self.text[right_setting.start : right_setting.end]}':" + f"'{arg}' cannot be both '{left}' and '{right}'." ) setattr(right_setting, arg, left if left != default else right) @@ -644,7 +718,9 @@ def _get_settings_from_t2xs( t2xwords = set(chain(*([*t2x.keys()] for t2x, _ in t2xs))) for word in t2xwords: setting_args = { - arg: t2x[word] if word in t2x else default_args[arg] + arg: str(t2x[word]) if word in t2x else default_args[arg] + # NOTE: when t2x[word] is a ManimColor, str will yield the + # hex representation for t2x, arg in t2xs } @@ -660,13 +736,13 @@ def _get_settings_from_gradient( if self.gradient: colors = color_gradient(self.gradient, len(self.text)) for i in range(len(self.text)): - args["color"] = colors[i].hex + args["color"] = colors[i].to_hex() settings.append(TextSetting(i, i + 1, **args)) for word, gradient in self.t2g.items(): if isinstance(gradient, str) or len(gradient) == 1: color = gradient if isinstance(gradient, str) else gradient[0] - gradient = [Color(color)] + gradient = [ManimColor(color)] colors = ( color_gradient(gradient, len(word)) if len(gradient) != 1 @@ -674,11 +750,11 @@ def _get_settings_from_gradient( ) for start, end in self._find_indexes(word, self.text): for i in range(start, end): - args["color"] = colors[i - start].hex + args["color"] = colors[i - start].to_hex() settings.append(TextSetting(i, i + 1, **args)) return settings - def _text2settings(self, color: Color): + def _text2settings(self, color: str): """Converts the texts and styles to a setting for parsing.""" t2xs = [ (self.t2f, "font"), @@ -687,8 +763,9 @@ def _text2settings(self, color: Color): (self.t2c, "color"), ] # setting_args requires values to be strings + default_args = { - arg: getattr(self, arg) if arg != "color" else str(color) for _, arg in t2xs + arg: getattr(self, arg) if arg != "color" else color for _, arg in t2xs } settings = self._get_settings_from_t2xs(t2xs, default_args) @@ -744,7 +821,7 @@ def _text2settings(self, color: Color): return settings - def _text2svg(self, color: Color): + def _text2svg(self, color: ManimColor): """Convert the text to SVG using Pango.""" size = self._font_size line_spacing = self.line_spacing @@ -752,13 +829,13 @@ def _text2svg(self, color: Color): line_spacing /= TEXT2SVG_ADJUSTMENT_FACTOR dir_name = config.get_dir("text_dir") - if not os.path.exists(dir_name): - os.makedirs(dir_name) + if not dir_name.is_dir(): + dir_name.mkdir(parents=True) hash_name = self._text2hash(color) - file_name = os.path.join(dir_name, hash_name) + ".svg" + file_name = dir_name / (hash_name + ".svg") - if os.path.exists(file_name): - svg_file = file_name + if file_name.exists(): + svg_file = str(file_name.resolve()) else: settings = self._text2settings(color) width = config["pixel_width"] @@ -769,7 +846,7 @@ def _text2svg(self, color: Color): size, line_spacing, self.disable_ligatures, - file_name, + str(file_name.resolve()), START_X, START_Y, width, @@ -780,11 +857,14 @@ def _text2svg(self, color: Color): return svg_file def init_colors(self, propagate_colors=True): - super().init_colors(propagate_colors=propagate_colors) + if config.renderer == RendererType.OPENGL: + super().init_colors() + elif config.renderer == RendererType.CAIRO: + super().init_colors(propagate_colors=propagate_colors) class MarkupText(SVGMobject): - r"""Display (non-LaTeX) text rendered using `Pango `_. + r"""Display (non-LaTeX) text rendered using `Pango `_. Text objects behave like a :class:`.VGroup`-like iterable of all characters in the given text. In particular, slicing is possible. @@ -834,7 +914,7 @@ def construct(self): Here is a list of supported tags: - ``bold``, ``italic`` and ``bold+italic`` - - ``
    underline
`` and ``strike through`` + - ``underline`` and ``strike through`` - ``typewriter font`` - ``bigger font`` and ``smaller font`` - ``superscript`` and ``subscript`` @@ -888,32 +968,34 @@ def construct(self): You can find more information about Pango markup formatting at the corresponding documentation page: - `Pango Markup `_. + `Pango Markup `_. Please be aware that not all features are supported by this class and that the ```` tag mentioned above is not supported by Pango. Parameters ---------- - text : :class:`str` - The text that need to created as mobject. - fill_opacity : :class:`int` - The fill opacity with 1 meaning opaque and 0 meaning transparent. - stroke_width : :class:`int` + text + The text that needs to be created as mobject. + fill_opacity + The fill opacity, with 1 meaning opaque and 0 meaning transparent. + stroke_width Stroke width. - font_size : :class:`float` + font_size Font size. - line_spacing : :class:`int` + line_spacing Line spacing. - font : :class:`str` + font Global font setting for the entire text. Local overrides are possible. - slant : :class:`str` + slant Global slant setting, e.g. `NORMAL` or `ITALIC`. Local overrides are possible. - weight : :class:`str` + weight Global weight setting, e.g. `NORMAL` or `BOLD`. Local overrides are possible. - gradient: :class:`tuple` + gradient Global gradient setting. Local overrides are possible. - + warn_missing_font + If True (default), Manim will issue a warning if the font does not exist in the + (case-sensitive) list of fonts returned from `manimpango.list_fonts()`. Returns ------- @@ -1054,10 +1136,7 @@ def construct(self): "Praesent feugiat metus sit amet iaculis pulvinar. Nulla posuere " "quam a ex aliquam, eleifend consectetur tellus viverra. Aliquam " "fermentum interdum justo, nec rutrum elit pretium ac. Nam quis " - "leo pulvinar, dignissim est at, venenatis nisi. Quisque mattis " - "dolor ut euismod hendrerit. Nullam eu ante sollicitudin, commodo " - "risus a, vehicula odio. Nam urna tortor, aliquam a nibh eu, commodo " - "imperdiet arcu. Donec tincidunt commodo enim a tincidunt." + "leo pulvinar, dignissim est at, venenatis nisi." ) justified_text = MarkupText(ipsum_text, justify=True).scale(0.4) not_justified_text = MarkupText(ipsum_text, justify=False).scale(0.4) @@ -1065,15 +1144,10 @@ def construct(self): njust_title = Title("Not Justified") self.add(njust_title, not_justified_text) self.play( - Transform( - not_justified_text, - justified_text, - ), - Transform( - njust_title, - just_title, - ), - run_time=2, + FadeOut(not_justified_text), + FadeIn(justified_text), + FadeOut(njust_title), + FadeIn(just_title), ) self.wait(1) @@ -1087,12 +1161,17 @@ def construct(self): """ + @staticmethod + @functools.cache + def font_list() -> list[str]: + return manimpango.list_fonts() + def __init__( self, text: str, fill_opacity: float = 1, stroke_width: float = 0, - color: Color | None = None, + color: ParsableManimColor | None = None, font_size: float = DEFAULT_FONT_SIZE, line_spacing: int = -1, font: str = "", @@ -1104,13 +1183,27 @@ def __init__( height: int = None, width: int = None, should_center: bool = True, - unpack_groups: bool = True, disable_ligatures: bool = False, + warn_missing_font: bool = True, **kwargs, - ): - + ) -> None: self.text = text self.line_spacing = line_spacing + if font and warn_missing_font: + fonts_list = Text.font_list() + # handle special case of sans/sans-serif + if font.lower() == "sans-serif": + font = "sans" + if font not in fonts_list: + # check if the capitalized version is in the supported fonts + if font.capitalize() in fonts_list: + font = font.capitalize() + elif font.lower() in fonts_list: + font = font.lower() + elif font.title() in fonts_list: + font = font.title() + else: + logger.warning(f"Font {font} not in {fonts_list}.") self.font = font self._font_size = float(font_size) self.slant = slant @@ -1142,7 +1235,7 @@ def __init__( else: self.line_spacing = self._font_size + self._font_size * self.line_spacing - color = Color(color) if color else VMobject().color + color: ManimColor = ManimColor(color) if color else VMobject().color file_name = self._text2svg(color) PangoUtils.remove_last_M(file_name) @@ -1153,47 +1246,79 @@ def __init__( height=height, width=width, should_center=should_center, - unpack_groups=unpack_groups, **kwargs, ) self.chars = self.get_group_class()(*self.submobjects) self.text = text_without_tabs.replace(" ", "").replace("\n", "") - if config.renderer == "opengl": - nppc = self.n_points_per_curve - else: - nppc = self.n_points_per_cubic_curve + nppc = self.n_points_per_curve for each in self: if len(each.points) == 0: continue points = each.points - last = points[0] - each.clear_points() + curve_start = points[0] + assert len(curve_start) == self.dim, curve_start + # Some of the glyphs in this text might not be closed, + # so we close them by identifying when one curve ends + # but it is not where the next curve starts. + # It is more efficient to temporarily create a list + # of points and add them one at a time, then turn them + # into a numpy array at the end, rather than creating + # new numpy arrays every time a point or fixing line + # is added (which is O(n^2) for numpy arrays). + closed_curve_points = [] + # OpenGL has points be part of quadratic Bezier curves; + # Cairo uses cubic Bezier curves. + if nppc == 3: # RendererType.OPENGL + + def add_line_to(end): + nonlocal closed_curve_points + start = closed_curve_points[-1] + closed_curve_points += [ + start, + (start + end) / 2, + end, + ] + + else: # RendererType.CAIRO + + def add_line_to(end): + nonlocal closed_curve_points + start = closed_curve_points[-1] + closed_curve_points += [ + start, + (start + start + end) / 3, + (start + end + end) / 3, + end, + ] + for index, point in enumerate(points): - each.append_points([point]) + closed_curve_points.append(point) if ( index != len(points) - 1 and (index + 1) % nppc == 0 and any(point != points[index + 1]) ): - each.add_line_to(last) - last = points[index + 1] - each.add_line_to(last) + # Add straight line from last point on this curve to the + # start point on the next curve. + add_line_to(curve_start) + curve_start = points[index + 1] + # Make sure last curve is closed + add_line_to(curve_start) + each.points = np.array(closed_curve_points, ndmin=2) if self.gradient: self.set_color_by_gradient(*self.gradient) for col in colormap: self.chars[ - col["start"] - - col["start_offset"] : col["end"] + col["start"] - col["start_offset"] : col["end"] - col["start_offset"] - col["end_offset"] ].set_color(self._parse_color(col["color"])) for grad in gradientmap: self.chars[ - grad["start"] - - grad["start_offset"] : grad["end"] + grad["start"] - grad["start_offset"] : grad["end"] - grad["start_offset"] - grad["end_offset"] ].set_color_by_gradient( @@ -1224,10 +1349,14 @@ def font_size(self, font_val): else: self.scale(font_val / self.font_size) - def _text2hash(self, color: Color): + def _text2hash(self, color: ParsableManimColor): """Generates ``sha256`` hash for file name.""" settings = ( - "MARKUPPANGO" + self.font + self.slant + self.weight + color.hex_l + "MARKUPPANGO" + + self.font + + self.slant + + self.weight + + ManimColor(color).to_hex().lower() ) # to differentiate from classical Pango Text settings += str(self.line_spacing) + str(self._font_size) settings += str(self.disable_ligatures) @@ -1237,23 +1366,25 @@ def _text2hash(self, color: Color): hasher.update(id_str.encode()) return hasher.hexdigest()[:16] - def _text2svg(self, color: Color | None): + def _text2svg(self, color: ParsableManimColor | None): """Convert the text to SVG using Pango.""" + color = ManimColor(color) size = self._font_size line_spacing = self.line_spacing size /= TEXT2SVG_ADJUSTMENT_FACTOR line_spacing /= TEXT2SVG_ADJUSTMENT_FACTOR dir_name = config.get_dir("text_dir") - if not os.path.exists(dir_name): - os.makedirs(dir_name) + if not dir_name.is_dir(): + dir_name.mkdir(parents=True) hash_name = self._text2hash(color) - file_name = os.path.join(dir_name, hash_name) + ".svg" - if os.path.exists(file_name): - svg_file = file_name + file_name = dir_name / (hash_name + ".svg") + + if file_name.exists(): + svg_file = str(file_name.resolve()) else: final_text = ( - f'{self.text}' + f'{self.text}' if color is not None else self.text ) @@ -1266,7 +1397,7 @@ def _text2svg(self, color: Color | None): size, line_spacing, self.disable_ligatures, - file_name, + str(file_name.resolve()), START_X, START_Y, 600, # width @@ -1280,7 +1411,8 @@ def _count_real_chars(self, s): """Counts characters that will be displayed. This is needed for partial coloring or gradients, because space - counts to the text's `len`, but has no corresponding character.""" + counts to the text's `len`, but has no corresponding character. + """ count = 0 level = 0 # temporarily replace HTML entities by single char @@ -1323,7 +1455,9 @@ def _extract_gradient_tags(self): "end_offset": end_offset, }, ) - self.text = re.sub("]+>(.+?)", r"\1", self.text, 0, re.S) + self.text = re.sub( + "]+>(.+?)", r"\1", self.text, count=0, flags=re.S + ) return gradientmap def _parse_color(self, col): @@ -1331,7 +1465,7 @@ def _parse_color(self, col): if re.match("#[0-9a-f]{6}", col): return col else: - return Colors[col.lower()].value + return ManimColor(col).to_hex() def _extract_color_tags(self): """Used to determine which parts (if any) of the string should be formatted @@ -1365,7 +1499,9 @@ def _extract_color_tags(self): "end_offset": end_offset, }, ) - self.text = re.sub("]+>(.+?)", r"\1", self.text, 0, re.S) + self.text = re.sub( + "]+>(.+?)", r"\1", self.text, count=0, flags=re.S + ) return colormap def __repr__(self): @@ -1385,7 +1521,7 @@ def register_font(font_file: str | Path): Parameters ---------- - font_file : + font_file The font file to add. Examples @@ -1411,7 +1547,6 @@ def register_font(font_file: str | Path): This method is available for macOS for ``ManimPango>=v0.2.3``. Using this method with previous releases will raise an :class:`AttributeError` on macOS. """ - input_folder = Path(config.input_file).parent.resolve() possible_paths = [ Path(font_file), @@ -1426,7 +1561,7 @@ def register_font(font_file: str | Path): logger.debug("Found file at %s", file_path.absolute()) break else: - error = f"Can't find {font_file}." f"Tried these : {possible_paths}" + error = f"Can't find {font_file}.Tried these : {possible_paths}" raise FileNotFoundError(error) try: diff --git a/manim/mobject/three_d/polyhedra.py b/manim/mobject/three_d/polyhedra.py index 300cf660a8..8046f6066c 100644 --- a/manim/mobject/three_d/polyhedra.py +++ b/manim/mobject/three_d/polyhedra.py @@ -10,11 +10,20 @@ from manim.mobject.graph import Graph from manim.mobject.three_d.three_dimensions import Dot3D from manim.mobject.types.vectorized_mobject import VGroup +from manim.utils.qhull import QuickHull if TYPE_CHECKING: from manim.mobject.mobject import Mobject + from manim.typing import Point3D -__all__ = ["Polyhedron", "Tetrahedron", "Octahedron", "Icosahedron", "Dodecahedron"] +__all__ = [ + "Polyhedron", + "Tetrahedron", + "Octahedron", + "Icosahedron", + "Dodecahedron", + "ConvexHull3D", +] class Polyhedron(VGroup): @@ -361,3 +370,91 @@ def __init__(self, edge_length: float = 1, **kwargs): ], **kwargs, ) + + +class ConvexHull3D(Polyhedron): + """A convex hull for a set of points + + Parameters + ---------- + points + The points to consider. + tolerance + The tolerance used for quickhull. + kwargs + Forwarded to the parent constructor. + + Examples + -------- + .. manim:: ConvexHull3DExample + :save_last_frame: + :quality: high + + class ConvexHull3DExample(ThreeDScene): + def construct(self): + self.set_camera_orientation(phi=75 * DEGREES, theta=30 * DEGREES) + points = [ + [ 1.93192757, 0.44134585, -1.52407061], + [-0.93302521, 1.23206983, 0.64117067], + [-0.44350918, -0.61043677, 0.21723705], + [-0.42640268, -1.05260843, 1.61266094], + [-1.84449637, 0.91238739, -1.85172623], + [ 1.72068132, -0.11880457, 0.51881751], + [ 0.41904805, 0.44938012, -1.86440686], + [ 0.83864666, 1.66653337, 1.88960123], + [ 0.22240514, -0.80986286, 1.34249326], + [-1.29585759, 1.01516189, 0.46187522], + [ 1.7776499, -1.59550796, -1.70240747], + [ 0.80065226, -0.12530398, 1.70063977], + [ 1.28960948, -1.44158255, 1.39938582], + [-0.93538943, 1.33617705, -0.24852643], + [-1.54868271, 1.7444399, -0.46170734] + ] + hull = ConvexHull3D( + *points, + faces_config = {"stroke_opacity": 0}, + graph_config = { + "vertex_type": Dot3D, + "edge_config": { + "stroke_color": BLUE, + "stroke_width": 2, + "stroke_opacity": 0.05, + } + } + ) + dots = VGroup(*[Dot3D(point) for point in points]) + self.add(hull) + self.add(dots) + """ + + def __init__(self, *points: Point3D, tolerance: float = 1e-5, **kwargs): + # Build Convex Hull + array = np.array(points) + hull = QuickHull(tolerance) + hull.build(array) + + # Setup Lists + vertices = [] + faces = [] + + # Extract Faces + c = 0 + d = {} + facets = set(hull.facets) - hull.removed + for facet in facets: + tmp = set() + for subfacet in facet.subfacets: + for point in subfacet.points: + if point not in d: + vertices.append(point.coordinates) + d[point] = c + c += 1 + tmp.add(point) + faces.append([d[point] for point in tmp]) + + # Call Polyhedron + super().__init__( + vertex_coords=vertices, + faces_list=faces, + **kwargs, + ) diff --git a/manim/mobject/three_d/three_d_utils.py b/manim/mobject/three_d/three_d_utils.py index 397e304af1..0a9ccb8a2d 100644 --- a/manim/mobject/three_d/three_d_utils.py +++ b/manim/mobject/three_d/three_d_utils.py @@ -14,40 +14,45 @@ ] +from typing import TYPE_CHECKING, Literal + import numpy as np from manim.constants import ORIGIN, UP from manim.utils.space_ops import get_unit_normal +if TYPE_CHECKING: + from manim.typing import Point3D, Vector3D + -def get_3d_vmob_gradient_start_and_end_points(vmob): +def get_3d_vmob_gradient_start_and_end_points(vmob) -> tuple[Point3D, Point3D]: return ( get_3d_vmob_start_corner(vmob), get_3d_vmob_end_corner(vmob), ) -def get_3d_vmob_start_corner_index(vmob): +def get_3d_vmob_start_corner_index(vmob) -> Literal[0]: return 0 -def get_3d_vmob_end_corner_index(vmob): +def get_3d_vmob_end_corner_index(vmob) -> int: return ((len(vmob.points) - 1) // 6) * 3 -def get_3d_vmob_start_corner(vmob): +def get_3d_vmob_start_corner(vmob) -> Point3D: if vmob.get_num_points() == 0: return np.array(ORIGIN) return vmob.points[get_3d_vmob_start_corner_index(vmob)] -def get_3d_vmob_end_corner(vmob): +def get_3d_vmob_end_corner(vmob) -> Point3D: if vmob.get_num_points() == 0: return np.array(ORIGIN) return vmob.points[get_3d_vmob_end_corner_index(vmob)] -def get_3d_vmob_unit_normal(vmob, point_index): +def get_3d_vmob_unit_normal(vmob, point_index: int) -> Vector3D: n_points = vmob.get_num_points() if len(vmob.get_anchors()) <= 2: return np.array(UP) @@ -63,9 +68,9 @@ def get_3d_vmob_unit_normal(vmob, point_index): return unit_normal -def get_3d_vmob_start_corner_unit_normal(vmob): +def get_3d_vmob_start_corner_unit_normal(vmob) -> Vector3D: return get_3d_vmob_unit_normal(vmob, get_3d_vmob_start_corner_index(vmob)) -def get_3d_vmob_end_corner_unit_normal(vmob): +def get_3d_vmob_end_corner_unit_normal(vmob) -> Vector3D: return get_3d_vmob_unit_normal(vmob, get_3d_vmob_end_corner_index(vmob)) diff --git a/manim/mobject/three_d/three_dimensions.py b/manim/mobject/three_d/three_dimensions.py index 80aa100788..5732ebb98c 100644 --- a/manim/mobject/three_d/three_dimensions.py +++ b/manim/mobject/three_d/three_dimensions.py @@ -2,6 +2,9 @@ from __future__ import annotations +from manim.typing import Point3DLike, Vector3D +from manim.utils.color import BLUE, BLUE_D, BLUE_E, LIGHT_GREY, WHITE, interpolate_color + __all__ = [ "ThreeDVMobject", "Surface", @@ -16,27 +19,30 @@ "Torus", ] - -from typing import * +from collections.abc import Iterable, Sequence +from typing import Any, Callable import numpy as np -from colour import Color +from typing_extensions import Self -from manim import config +from manim import config, logger from manim.constants import * from manim.mobject.geometry.arc import Circle from manim.mobject.geometry.polygram import Square from manim.mobject.mobject import * from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL from manim.mobject.opengl.opengl_mobject import OpenGLMobject -from manim.mobject.types.vectorized_mobject import VGroup, VMobject -from manim.utils.color import * +from manim.mobject.types.vectorized_mobject import VectorizedPoint, VGroup, VMobject +from manim.utils.color import ( + ManimColor, + ParsableManimColor, +) from manim.utils.iterables import tuplify from manim.utils.space_ops import normalize, perpendicular_bisector, z_to_vector class ThreeDVMobject(VMobject, metaclass=ConvertToOpenGL): - def __init__(self, shade_in_3d=True, **kwargs): + def __init__(self, shade_in_3d: bool = True, **kwargs): super().__init__(shade_in_3d=shade_in_3d, **kwargs) @@ -45,16 +51,31 @@ class Surface(VGroup, metaclass=ConvertToOpenGL): Parameters ---------- - func : - The function that defines the surface. - u_range : + func + The function defining the :class:`Surface`. + u_range The range of the ``u`` variable: ``(u_min, u_max)``. - v_range : + v_range The range of the ``v`` variable: ``(v_min, v_max)``. - resolution : - The number of samples taken of the surface. A tuple - can be used to define different resolutions for ``u`` and - ``v`` respectively. + resolution + The number of samples taken of the :class:`Surface`. A tuple can be + used to define different resolutions for ``u`` and ``v`` respectively. + fill_color + The color of the :class:`Surface`. Ignored if ``checkerboard_colors`` + is set. + fill_opacity + The opacity of the :class:`Surface`, from 0 being fully transparent + to 1 being fully opaque. Defaults to 1. + checkerboard_colors + ng individual faces alternating colors. Overrides ``fill_color``. + stroke_color + Color of the stroke surrounding each face of :class:`Surface`. + stroke_width + Width of the stroke surrounding each face of :class:`Surface`. + Defaults to 0.5. + should_make_jagged + Changes the anchor mode of the Bézier curves from smooth to jagged. + Defaults to ``False``. Examples -------- @@ -70,7 +91,8 @@ def construct(self): surface = Surface( lambda u, v: axes.c2p(*self.func(u, v)), u_range=[-PI, PI], - v_range=[0, TAU] + v_range=[0, TAU], + resolution=8, ) self.set_camera_orientation(theta=70 * DEGREES, phi=75 * DEGREES) self.add(axes, surface) @@ -83,36 +105,44 @@ def __init__( v_range: Sequence[float] = [0, 1], resolution: Sequence[int] = 32, surface_piece_config: dict = {}, - fill_color: Color = BLUE_D, + fill_color: ParsableManimColor = BLUE_D, fill_opacity: float = 1.0, - checkerboard_colors: Sequence[Color] = [BLUE_D, BLUE_E], - stroke_color: Color = LIGHT_GREY, + checkerboard_colors: Sequence[ParsableManimColor] | bool = [BLUE_D, BLUE_E], + stroke_color: ParsableManimColor = LIGHT_GREY, stroke_width: float = 0.5, should_make_jagged: bool = False, pre_function_handle_to_anchor_scale_factor: float = 0.00001, - **kwargs, + **kwargs: Any, ) -> None: self.u_range = u_range self.v_range = v_range super().__init__(**kwargs) self.resolution = resolution self.surface_piece_config = surface_piece_config - self.fill_color = fill_color + self.fill_color: ManimColor = ManimColor(fill_color) self.fill_opacity = fill_opacity - self.checkerboard_colors = checkerboard_colors - self.stroke_color = stroke_color + if checkerboard_colors: + self.checkerboard_colors: list[ManimColor] = [ + ManimColor(x) for x in checkerboard_colors + ] + else: + self.checkerboard_colors = checkerboard_colors + self.stroke_color: ManimColor = ManimColor(stroke_color) self.stroke_width = stroke_width self.should_make_jagged = should_make_jagged self.pre_function_handle_to_anchor_scale_factor = ( pre_function_handle_to_anchor_scale_factor ) - self.func = func + self._func = func self._setup_in_uv_space() self.apply_function(lambda p: func(p[0], p[1])) if self.should_make_jagged: self.make_jagged() - def _get_u_values_and_v_values(self): + def func(self, u: float, v: float) -> np.ndarray: + return self._func(u, v) + + def _get_u_values_and_v_values(self) -> tuple[np.ndarray, np.ndarray]: res = tuplify(self.resolution) if len(res) == 1: u_res = v_res = res[0] @@ -124,7 +154,7 @@ def _get_u_values_and_v_values(self): return u_values, v_values - def _setup_in_uv_space(self): + def _setup_in_uv_space(self) -> None: u_values, v_values = self._get_u_values_and_v_values() faces = VGroup() for i in range(len(u_values) - 1): @@ -158,7 +188,25 @@ def _setup_in_uv_space(self): if self.checkerboard_colors: self.set_fill_by_checkerboard(*self.checkerboard_colors) - def set_fill_by_checkerboard(self, *colors, opacity=None): + def set_fill_by_checkerboard( + self, *colors: Iterable[ParsableManimColor], opacity: float | None = None + ) -> Self: + """Sets the fill_color of each face of :class:`Surface` in + an alternating pattern. + + Parameters + ---------- + colors + List of colors for alternating pattern. + opacity + The fill_opacity of :class:`Surface`, from 0 being fully transparent + to 1 being fully opaque. + + Returns + ------- + :class:`~.Surface` + The parametric surface with an alternating pattern. + """ n_colors = len(colors) for face in self: c_index = (face.u_index + face.v_index) % n_colors @@ -168,19 +216,23 @@ def set_fill_by_checkerboard(self, *colors, opacity=None): def set_fill_by_value( self, axes: Mobject, - colors: Union[Iterable[Color], Color], + colorscale: list[ParsableManimColor] | ParsableManimColor | None = None, axis: int = 2, - ): - """Sets the color of each mobject of a parametric surface to a color relative to its axis-value + **kwargs, + ) -> Self: + """Sets the color of each mobject of a parametric surface to a color + relative to its axis-value. Parameters ---------- - axes : - The axes for the parametric surface, which will be used to map axis-values to colors. - colors : - A list of colors, ordered from lower axis-values to higher axis-values. If a list of tuples is passed - containing colors paired with numbers, then those numbers will be used as the pivots. - axis : + axes + The axes for the parametric surface, which will be used to map + axis-values to colors. + colorscale + A list of colors, ordered from lower axis-values to higher axis-values. + If a list of tuples is passed containing colors paired with numbers, + then those numbers will be used as the pivots. + axis The chosen axis to use for the color mapping. (0 = x, 1 = y, 2 = z) Returns @@ -195,7 +247,7 @@ def set_fill_by_value( class FillByValueExample(ThreeDScene): def construct(self): - resolution_fa = 42 + resolution_fa = 8 self.set_camera_orientation(phi=75 * DEGREES, theta=-160 * DEGREES) axes = ThreeDAxes(x_range=(0, 5, 1), y_range=(0, 5, 1), z_range=(-1, 1, 0.5)) def param_surface(u, v): @@ -210,16 +262,32 @@ def param_surface(u, v): u_range=[0, 5], ) surface_plane.set_style(fill_opacity=1) - surface_plane.set_fill_by_value(axes=axes, colors=[(RED, -0.5), (YELLOW, 0), (GREEN, 0.5)], axis=2) + surface_plane.set_fill_by_value(axes=axes, colorscale=[(RED, -0.5), (YELLOW, 0), (GREEN, 0.5)], axis=2) self.add(axes, surface_plane) """ + if "colors" in kwargs and colorscale is None: + colorscale = kwargs.pop("colors") + if kwargs: + raise ValueError( + "Unsupported keyword argument(s): " + f"{', '.join(str(key) for key in kwargs)}" + ) + if colorscale is None: + logger.warning( + "The value passed to the colorscale keyword argument was None, " + "the surface fill color has not been changed" + ) + return self ranges = [axes.x_range, axes.y_range, axes.z_range] - if type(colors[0]) is tuple: - new_colors, pivots = [[i for i, j in colors], [j for i, j in colors]] + if type(colorscale[0]) is tuple: + new_colors, pivots = [ + [i for i, j in colorscale], + [j for i, j in colorscale], + ] else: - new_colors = colors + new_colors = colorscale pivot_min = ranges[axis][0] pivot_max = ranges[axis][1] @@ -248,9 +316,9 @@ def param_surface(u, v): new_colors[i], color_index, ) - if config.renderer == "opengl": + if config.renderer == RendererType.OPENGL: mob.set_color(mob_color, recurse=False) - else: + elif config.renderer == RendererType.CAIRO: mob.set_color(mob_color, family=False) break @@ -261,10 +329,24 @@ def param_surface(u, v): class Sphere(Surface): - """A mobject representing a three-dimensional sphere. + """A three-dimensional sphere. + + Parameters + ---------- + center + Center of the :class:`Sphere`. + radius + The radius of the :class:`Sphere`. + resolution + The number of samples taken of the :class:`Sphere`. A tuple can be used + to define different resolutions for ``u`` and ``v`` respectively. + u_range + The range of the ``u`` variable: ``(u_min, u_max)``. + v_range + The range of the ``v`` variable: ``(v_min, v_max)``. Examples - --------- + -------- .. manim:: ExampleSphere :save_last_frame: @@ -291,17 +373,19 @@ def construct(self): def __init__( self, - center=ORIGIN, - radius=1, - resolution=None, - u_range=(0, TAU), - v_range=(0, PI), + center: Point3DLike = ORIGIN, + radius: float = 1, + resolution: Sequence[int] | None = None, + u_range: Sequence[float] = (0, TAU), + v_range: Sequence[float] = (0, PI), **kwargs, - ): - if config.renderer == "opengl": + ) -> None: + if config.renderer == RendererType.OPENGL: res_value = (101, 51) - else: + elif config.renderer == RendererType.CAIRO: res_value = (24, 12) + else: + raise Exception("Unknown renderer") resolution = resolution if resolution is not None else res_value @@ -317,7 +401,14 @@ def __init__( self.shift(center) - def func(self, u, v): + def func(self, u: float, v: float) -> np.ndarray: + """The z values defining the :class:`Sphere` being plotted. + + Returns + ------- + :class:`numpy.array` + The z values defining the :class:`Sphere`. + """ return self.radius * np.array( [np.cos(u) * np.sin(v), np.sin(u) * np.sin(v), -np.cos(v)], ) @@ -327,13 +418,16 @@ class Dot3D(Sphere): """A spherical dot. Parameters - -------- - point : Union[:class:`list`, :class:`numpy.ndarray`], optional + ---------- + point The location of the dot. - radius : :class:`float`, optional + radius The radius of the dot. - color : :class:`~.Colors`, optional - The color of the :class:`Dot3D` + color + The color of the :class:`Dot3D`. + resolution + The number of samples taken of the :class:`Dot3D`. A tuple can be + used to define different resolutions for ``u`` and ``v`` respectively. Examples -------- @@ -354,25 +448,54 @@ def construct(self): def __init__( self, - point=ORIGIN, - radius=DEFAULT_DOT_RADIUS, - color=WHITE, - resolution=(8, 8), + point: list | np.ndarray = ORIGIN, + radius: float = DEFAULT_DOT_RADIUS, + color: ParsableManimColor = WHITE, + resolution: tuple[int, int] = (8, 8), **kwargs, - ): + ) -> None: super().__init__(center=point, radius=radius, resolution=resolution, **kwargs) self.set_color(color) class Cube(VGroup): + """A three-dimensional cube. + + Parameters + ---------- + side_length + Length of each side of the :class:`Cube`. + fill_opacity + The opacity of the :class:`Cube`, from 0 being fully transparent to 1 being + fully opaque. Defaults to 0.75. + fill_color + The color of the :class:`Cube`. + stroke_width + The width of the stroke surrounding each face of the :class:`Cube`. + + Examples + -------- + + .. manim:: CubeExample + :save_last_frame: + + class CubeExample(ThreeDScene): + def construct(self): + self.set_camera_orientation(phi=75*DEGREES, theta=-45*DEGREES) + + axes = ThreeDAxes() + cube = Cube(side_length=3, fill_opacity=0.7, fill_color=BLUE) + self.add(cube) + """ + def __init__( self, - side_length=2, - fill_opacity=0.75, - fill_color=BLUE, - stroke_width=0, + side_length: float = 2, + fill_opacity: float = 0.75, + fill_color: ParsableManimColor = BLUE, + stroke_width: float = 0, **kwargs, - ): + ) -> None: self.side_length = side_length super().__init__( fill_color=fill_color, @@ -381,7 +504,8 @@ def __init__( **kwargs, ) - def generate_points(self): + def generate_points(self) -> None: + """Creates the sides of the :class:`Cube`.""" for vect in IN, OUT, LEFT, RIGHT, UP, DOWN: face = Square( side_length=self.side_length, @@ -397,7 +521,13 @@ def generate_points(self): class Prism(Cube): - """A cuboid. + """A right rectangular prism (or rectangular cuboid). + Defined by the length of each side in ``[x, y, z]`` format. + + Parameters + ---------- + dimensions + Dimensions of the :class:`Prism` in ``[x, y, z]`` format. Examples -------- @@ -413,11 +543,14 @@ def construct(self): self.add(prismSmall, prismLarge) """ - def __init__(self, dimensions=[3, 2, 1], **kwargs): + def __init__( + self, dimensions: tuple[float, float, float] | np.ndarray = [3, 2, 1], **kwargs + ) -> None: self.dimensions = dimensions super().__init__(**kwargs) - def generate_points(self): + def generate_points(self) -> None: + """Creates the sides of the :class:`Prism`.""" super().generate_points() for dim, value in enumerate(self.dimensions): self.rescale_to_fit(value, dim, stretch=True) @@ -430,6 +563,24 @@ class Cone(Surface): height) The spherical radius, r, is calculated using the pythagorean theorem. + Parameters + ---------- + base_radius + The base radius from which the cone tapers. + height + The height measured from the plane formed by the base_radius to + the apex of the cone. + direction + The direction of the apex. + show_base + Whether to show the base plane or not. + v_range + The azimuthal angle to start and end at. + u_min + The radius at the apex. + checkerboard_colors + Show checkerboard grid texture on the cone. + Examples -------- .. manim:: ExampleCone @@ -438,39 +589,22 @@ class Cone(Surface): class ExampleCone(ThreeDScene): def construct(self): axes = ThreeDAxes() - cone = Cone(direction=X_AXIS+Y_AXIS+2*Z_AXIS) + cone = Cone(direction=X_AXIS+Y_AXIS+2*Z_AXIS, resolution=8) self.set_camera_orientation(phi=5*PI/11, theta=PI/9) self.add(axes, cone) - - Parameters - -------- - base_radius : :class:`float` - The base radius from which the cone tapers. - height : :class:`float` - The height measured from the plane formed by the base_radius to the apex of the cone. - direction : :class:`numpy.array` - The direction of the apex. - show_base : :class:`bool` - Whether to show the base plane or not. - v_range : :class:`Sequence[float]` - The azimuthal angle to start and end at. - u_min : :class:`float` - The radius at the apex. - checkerboard_colors : :class:`bool` - Show checkerboard grid texture on the cone. """ def __init__( self, - base_radius=1, - height=1, - direction=Z_AXIS, - show_base=False, - v_range=[0, TAU], - u_min=0, - checkerboard_colors=False, - **kwargs, - ): + base_radius: float = 1, + height: float = 1, + direction: np.ndarray = Z_AXIS, + show_base: bool = False, + v_range: Sequence[float] = [0, TAU], + u_min: float = 0, + checkerboard_colors: bool = False, + **kwargs: Any, + ) -> None: self.direction = direction self.theta = PI - np.arctan(base_radius / height) @@ -482,29 +616,36 @@ def __init__( **kwargs, ) # used for rotations + self.new_height = height self._current_theta = 0 self._current_phi = 0 - + self.base_circle = Circle( + radius=base_radius, + color=self.fill_color, + fill_opacity=self.fill_opacity, + stroke_width=0, + ) + self.base_circle.shift(height * IN) + self._set_start_and_end_attributes(direction) if show_base: - self.base_circle = Circle( - radius=base_radius, - color=self.fill_color, - fill_opacity=self.fill_opacity, - stroke_width=0, - ) - self.base_circle.shift(height * IN) self.add(self.base_circle) self._rotate_to_direction() - def func(self, u, v): + def func(self, u: float, v: float) -> np.ndarray: """Converts from spherical coordinates to cartesian. + Parameters - --------- - u : :class:`float` + ---------- + u The radius. - v : :class:`float` + v The azimuthal angle. + + Returns + ------- + :class:`numpy.array` + Points defining the :class:`Cone`. """ r = u phi = v @@ -516,14 +657,17 @@ def func(self, u, v): ], ) - def _rotate_to_direction(self): + def get_start(self) -> np.ndarray: + return self.start_point.get_center() + + def get_end(self) -> np.ndarray: + return self.end_point.get_center() + + def _rotate_to_direction(self) -> None: x, y, z = self.direction r = np.sqrt(x**2 + y**2 + z**2) - if r > 0: - theta = np.arccos(z / r) - else: - theta = 0 + theta = np.arccos(z / r) if r > 0 else 0 if x == 0: if y == 0: # along the z axis @@ -549,19 +693,58 @@ def _rotate_to_direction(self): self._current_theta = theta self._current_phi = phi - def set_direction(self, direction): + def set_direction(self, direction: np.ndarray) -> None: + """Changes the direction of the apex of the :class:`Cone`. + + Parameters + ---------- + direction + The direction of the apex. + """ self.direction = direction self._rotate_to_direction() - def get_direction(self): + def get_direction(self) -> np.ndarray: + """Returns the current direction of the apex of the :class:`Cone`. + + Returns + ------- + direction : :class:`numpy.array` + The direction of the apex. + """ return self.direction + def _set_start_and_end_attributes(self, direction): + normalized_direction = direction * np.linalg.norm(direction) + + start = self.base_circle.get_center() + end = start + normalized_direction * self.new_height + self.start_point = VectorizedPoint(start) + self.end_point = VectorizedPoint(end) + self.add(self.start_point, self.end_point) + class Cylinder(Surface): """A cylinder, defined by its height, radius and direction, + Parameters + ---------- + radius + The radius of the cylinder. + height + The height of the cylinder. + direction + The direction of the central axis of the cylinder. + v_range + The height along the height axis (given by direction) to start and end on. + show_ends + Whether to show the end caps or not. + resolution + The number of samples taken of the :class:`Cylinder`. A tuple can be used + to define different resolutions for ``u`` and ``v`` respectively. + Examples - --------- + -------- .. manim:: ExampleCylinder :save_last_frame: @@ -571,31 +754,18 @@ def construct(self): cylinder = Cylinder(radius=2, height=3) self.set_camera_orientation(phi=75 * DEGREES, theta=30 * DEGREES) self.add(axes, cylinder) - - Parameters - --------- - radius : :class:`float` - The radius of the cylinder. - height : :class:`float` - The height of the cylinder. - direction : :class:`numpy.array` - The direction of the central axis of the cylinder. - v_range : :class:`Sequence[float]` - The height along the height axis (given by direction) to start and end on. - show_ends : :class:`bool` - Whether to show the end caps or not. """ def __init__( self, - radius=1, - height=2, - direction=Z_AXIS, - v_range=[0, TAU], - show_ends=True, - resolution=(24, 24), + radius: float = 1, + height: float = 2, + direction: np.ndarray = Z_AXIS, + v_range: Sequence[float] = [0, TAU], + show_ends: bool = True, + resolution: Sequence[int] = (24, 24), **kwargs, - ): + ) -> None: self._height = height self.radius = radius super().__init__( @@ -611,24 +781,35 @@ def __init__( self._current_theta = 0 self.set_direction(direction) - def func(self, u, v): + def func(self, u: float, v: float) -> np.ndarray: """Converts from cylindrical coordinates to cartesian. + Parameters - --------- - u : :class:`float` + ---------- + u The height. - v : :class:`float` + v The azimuthal angle. + + Returns + ------- + :class:`numpy.ndarray` + Points defining the :class:`Cylinder`. """ height = u phi = v r = self.radius return np.array([r * np.cos(phi), r * np.sin(phi), height]) - def add_bases(self): + def add_bases(self) -> None: """Adds the end caps of the cylinder.""" - color = self.color if config["renderer"] == "opengl" else self.fill_color - opacity = self.opacity if config["renderer"] == "opengl" else self.fill_opacity + if config.renderer == RendererType.OPENGL: + color = self.color + opacity = self.opacity + elif config.renderer == RendererType.CAIRO: + color = self.fill_color + opacity = self.fill_opacity + self.base_top = Circle( radius=self.radius, color=color, @@ -647,14 +828,11 @@ def add_bases(self): self.base_bottom.shift(self.u_range[0] * IN) self.add(self.base_top, self.base_bottom) - def _rotate_to_direction(self): + def _rotate_to_direction(self) -> None: x, y, z = self.direction r = np.sqrt(x**2 + y**2 + z**2) - if r > 0: - theta = np.arccos(z / r) - else: - theta = 0 + theta = np.arccos(z / r) if r > 0 else 0 if x == 0: if y == 0: # along the z axis @@ -680,21 +858,52 @@ def _rotate_to_direction(self): self._current_theta = theta self._current_phi = phi - def set_direction(self, direction): + def set_direction(self, direction: np.ndarray) -> None: + """Sets the direction of the central axis of the :class:`Cylinder`. + + Parameters + ---------- + direction : :class:`numpy.array` + The direction of the central axis of the :class:`Cylinder`. + """ # if get_norm(direction) is get_norm(self.direction): # pass self.direction = direction self._rotate_to_direction() - def get_direction(self): + def get_direction(self) -> np.ndarray: + """Returns the direction of the central axis of the :class:`Cylinder`. + + Returns + ------- + direction : :class:`numpy.array` + The direction of the central axis of the :class:`Cylinder`. + """ return self.direction class Line3D(Cylinder): """A cylindrical line, for use in ThreeDScene. + Parameters + ---------- + start + The start point of the line. + end + The end point of the line. + thickness + The thickness of the line. + color + The color of the line. + resolution + The resolution of the line. + By default this value is the number of points the line will sampled at. + If you want the line to also come out checkered, use a tuple. + For example, for a line made of 24 points with 4 checker points on each + cylinder, pass the tuple (4, 24). + Examples - --------- + -------- .. manim:: ExampleLine3D :save_last_frame: @@ -704,27 +913,37 @@ def construct(self): line = Line3D(start=np.array([0, 0, 0]), end=np.array([2, 2, 2])) self.set_camera_orientation(phi=75 * DEGREES, theta=30 * DEGREES) self.add(axes, line) - - Parameters - --------- - start : :class:`numpy.array` - The start position of the line. - end : :class:`numpy.array` - The end position of the line. - thickness : :class:`float` - The thickness of the line. """ - def __init__(self, start=LEFT, end=RIGHT, thickness=0.02, color=None, **kwargs): + def __init__( + self, + start: np.ndarray = LEFT, + end: np.ndarray = RIGHT, + thickness: float = 0.02, + color: ParsableManimColor | None = None, + resolution: int | Sequence[int] = 24, + **kwargs, + ): self.thickness = thickness + self.resolution = (2, resolution) if isinstance(resolution, int) else resolution self.set_start_and_end_attrs(start, end, **kwargs) if color is not None: self.set_color(color) - def set_start_and_end_attrs(self, start, end, **kwargs): + def set_start_and_end_attrs( + self, start: np.ndarray, end: np.ndarray, **kwargs + ) -> None: """Sets the start and end points of the line. - If either ``start`` or ``end`` are :class:`Mobjects <.Mobject>`, this gives their centers. + If either ``start`` or ``end`` are :class:`Mobjects <.Mobject>`, + this gives their centers. + + Parameters + ---------- + start + Starting point or :class:`Mobject`. + end + Ending point or :class:`Mobject`. """ rough_start = self.pointify(start) rough_end = self.pointify(end) @@ -740,11 +959,30 @@ def set_start_and_end_attrs(self, start, end, **kwargs): height=np.linalg.norm(self.vect), radius=self.thickness, direction=self.direction, + resolution=self.resolution, **kwargs, ) self.shift((self.start + self.end) / 2) - def pointify(self, mob_or_point, direction=None): + def pointify( + self, + mob_or_point: Mobject | Point3DLike, + direction: Vector3D = None, + ) -> np.ndarray: + """Gets a point representing the center of the :class:`Mobjects <.Mobject>`. + + Parameters + ---------- + mob_or_point + :class:`Mobjects <.Mobject>` or point whose center should be returned. + direction + If an edge of a :class:`Mobjects <.Mobject>` should be returned, the direction of the edge. + + Returns + ------- + :class:`numpy.array` + Center of the :class:`Mobjects <.Mobject>` or point, or edge if direction is given. + """ if isinstance(mob_or_point, (Mobject, OpenGLMobject)): mob = mob_or_point if direction is None: @@ -753,16 +991,34 @@ def pointify(self, mob_or_point, direction=None): return mob.get_boundary_point(direction) return np.array(mob_or_point) - def get_start(self): + def get_start(self) -> np.ndarray: + """Returns the starting point of the :class:`Line3D`. + + Returns + ------- + start : :class:`numpy.array` + Starting point of the :class:`Line3D`. + """ return self.start - def get_end(self): + def get_end(self) -> np.ndarray: + """Returns the ending point of the :class:`Line3D`. + + Returns + ------- + end : :class:`numpy.array` + Ending point of the :class:`Line3D`. + """ return self.end @classmethod def parallel_to( - cls, line: Line3D, point: Sequence[float] = ORIGIN, length: float = 5, **kwargs - ): + cls, + line: Line3D, + point: Vector3D = ORIGIN, + length: float = 5, + **kwargs, + ) -> Line3D: """Returns a line parallel to another line going through a given point. @@ -772,9 +1028,16 @@ def parallel_to( The line to be parallel to. point The point to pass through. + length + Length of the parallel line. kwargs Additional parameters to be passed to the class. + Returns + ------- + :class:`Line3D` + Line parallel to ``line``. + Examples -------- .. manim:: ParallelLineExample @@ -798,8 +1061,12 @@ def construct(self): @classmethod def perpendicular_to( - cls, line: Line3D, point: Sequence[float] = ORIGIN, length: float = 5, **kwargs - ): + cls, + line: Line3D, + point: Vector3D = ORIGIN, + length: float = 5, + **kwargs, + ) -> Line3D: """Returns a line perpendicular to another line going through a given point. @@ -809,9 +1076,16 @@ def perpendicular_to( The line to be perpendicular to. point The point to pass through. + length + Length of the perpendicular line. kwargs Additional parameters to be passed to the class. + Returns + ------- + :class:`Line3D` + Line perpendicular to ``line``. + Examples -------- .. manim:: PerpLineExample @@ -843,44 +1117,58 @@ def construct(self): class Arrow3D(Line3D): """An arrow made out of a cylindrical line and a conical tip. + Parameters + ---------- + start + The start position of the arrow. + end + The end position of the arrow. + thickness + The thickness of the arrow. + height + The height of the conical tip. + base_radius + The base radius of the conical tip. + color + The color of the arrow. + resolution + The resolution of the arrow line. + Examples - --------- + -------- .. manim:: ExampleArrow3D :save_last_frame: class ExampleArrow3D(ThreeDScene): def construct(self): axes = ThreeDAxes() - arrow = Arrow3D(start=np.array([0, 0, 0]), end=np.array([2, 2, 2])) + arrow = Arrow3D( + start=np.array([0, 0, 0]), + end=np.array([2, 2, 2]), + resolution=8 + ) self.set_camera_orientation(phi=75 * DEGREES, theta=30 * DEGREES) self.add(axes, arrow) - - Parameters - --------- - start : :class:`numpy.array` - The start position of the arrow. - end : :class:`numpy.array` - The end position of the arrow. - thickness : :class:`float` - The thickness of the arrow. - height : :class:`float` - The height of the conical tip. - base_radius: :class:`float` - The base radius of the conical tip. """ def __init__( self, - start=LEFT, - end=RIGHT, - thickness=0.02, - height=0.3, - base_radius=0.08, - color=WHITE, + start: np.ndarray = LEFT, + end: np.ndarray = RIGHT, + thickness: float = 0.02, + height: float = 0.3, + base_radius: float = 0.08, + color: ParsableManimColor = WHITE, + resolution: int | Sequence[int] = 24, **kwargs, - ): + ) -> None: super().__init__( - start=start, end=end, thickness=thickness, color=color, **kwargs + start=start, + end=end, + thickness=thickness, + color=color, + resolution=resolution, + **kwargs, ) self.length = np.linalg.norm(self.vect) @@ -889,20 +1177,40 @@ def __init__( self.end - height * self.direction, **kwargs, ) - self.cone = Cone( - direction=self.direction, base_radius=base_radius, height=height, **kwargs + direction=self.direction, + base_radius=base_radius, + height=height, + **kwargs, ) self.cone.shift(end) - self.add(self.cone) + self.end_point = VectorizedPoint(end) + self.add(self.end_point, self.cone) self.set_color(color) + def get_end(self) -> np.ndarray: + return self.end_point.get_center() + class Torus(Surface): """A torus. + Parameters + ---------- + major_radius + Distance from the center of the tube to the center of the torus. + minor_radius + Radius of the tube. + u_range + The range of the ``u`` variable: ``(u_min, u_max)``. + v_range + The range of the ``v`` variable: ``(v_min, v_max)``. + resolution + The number of samples taken of the :class:`Torus`. A tuple can be + used to define different resolutions for ``u`` and ``v`` respectively. + Examples - --------- + -------- .. manim :: ExampleTorus :save_last_frame: @@ -912,27 +1220,20 @@ def construct(self): torus = Torus() self.set_camera_orientation(phi=75 * DEGREES, theta=30 * DEGREES) self.add(axes, torus) - - Parameters - --------- - major_radius : :class:`float` - Distance from the center of the tube to the center of the torus. - minor_radius : :class:`float` - Radius of the tube. """ def __init__( self, - major_radius=3, - minor_radius=1, - u_range=(0, TAU), - v_range=(0, TAU), - resolution=None, + major_radius: float = 3, + minor_radius: float = 1, + u_range: Sequence[float] = (0, TAU), + v_range: Sequence[float] = (0, TAU), + resolution: tuple[int, int] | None = None, **kwargs, - ): - if config.renderer == "opengl": + ) -> None: + if config.renderer == RendererType.OPENGL: res_value = (101, 101) - else: + elif config.renderer == RendererType.CAIRO: res_value = (24, 24) resolution = resolution if resolution is not None else res_value @@ -947,6 +1248,13 @@ def __init__( **kwargs, ) - def func(self, u, v): + def func(self, u: float, v: float) -> np.ndarray: + """The z values defining the :class:`Torus` being plotted. + + Returns + ------- + :class:`numpy.ndarray` + The z values defining the :class:`Torus`. + """ P = np.array([np.cos(u), np.sin(u), 0]) return (self.R - self.r * np.cos(v)) * P - self.r * np.sin(v) * OUT diff --git a/manim/mobject/types/image_mobject.py b/manim/mobject/types/image_mobject.py index 10b61a27af..56029f941e 100644 --- a/manim/mobject/types/image_mobject.py +++ b/manim/mobject/types/image_mobject.py @@ -5,10 +5,11 @@ __all__ = ["AbstractImageMobject", "ImageMobject", "ImageMobjectFromCamera"] import pathlib +from typing import TYPE_CHECKING -import colour import numpy as np from PIL import Image +from PIL.Image import Resampling from manim.mobject.geometry.shape_matchers import SurroundingRectangle @@ -16,8 +17,18 @@ from ...constants import * from ...mobject.mobject import Mobject from ...utils.bezier import interpolate -from ...utils.color import WHITE, color_to_int_rgb -from ...utils.images import get_full_raster_image_path +from ...utils.color import WHITE, ManimColor, color_to_int_rgb +from ...utils.images import change_to_rgba_array, get_full_raster_image_path + +__all__ = ["ImageMobject", "ImageMobjectFromCamera"] + +if TYPE_CHECKING: + from typing import Any + + import numpy.typing as npt + from typing_extensions import Self + + from manim.typing import StrPath class AbstractImageMobject(Mobject): @@ -26,7 +37,7 @@ class AbstractImageMobject(Mobject): Parameters ---------- - scale_to_resolution : :class:`int` + scale_to_resolution At this resolution the image is placed pixel by pixel onto the screen, so it will look the sharpest and best. This is a custom parameter of ImageMobject so that rendering a scene with @@ -36,24 +47,24 @@ class AbstractImageMobject(Mobject): def __init__( self, - scale_to_resolution, - pixel_array_dtype="uint8", - resampling_algorithm=Image.BICUBIC, - **kwargs, - ): + scale_to_resolution: int, + pixel_array_dtype: str = "uint8", + resampling_algorithm: Resampling = Resampling.BICUBIC, + **kwargs: Any, + ) -> None: self.pixel_array_dtype = pixel_array_dtype self.scale_to_resolution = scale_to_resolution self.set_resampling_algorithm(resampling_algorithm) super().__init__(**kwargs) - def get_pixel_array(self): + def get_pixel_array(self) -> None: raise NotImplementedError() def set_color(self, color, alpha=None, family=True): # Likely to be implemented in subclasses, but no obligation pass - def set_resampling_algorithm(self, resampling_algorithm): + def set_resampling_algorithm(self, resampling_algorithm: int) -> Self: """ Sets the interpolation method for upscaling the image. By default the image is interpolated using bicubic algorithm. This method lets you change it. @@ -62,15 +73,17 @@ def set_resampling_algorithm(self, resampling_algorithm): Parameters ---------- - resampling_algorithm : :class:`int`, an integer constant described in the - Pillow library, or one from the RESAMPLING_ALGORITHMS global dictionary, under - the following keys: - * 'bicubic' or 'cubic' - * 'nearest' or 'none' - * 'box' - * 'bilinear' or 'linear' - * 'hamming' - * 'lanczos' or 'antialias' + resampling_algorithm + An integer constant described in the Pillow library, + or one from the RESAMPLING_ALGORITHMS global dictionary, + under the following keys: + + * 'bicubic' or 'cubic' + * 'nearest' or 'none' + * 'box' + * 'bilinear' or 'linear' + * 'hamming' + * 'lanczos' or 'antialias' """ if isinstance(resampling_algorithm, int): self.resampling_algorithm = resampling_algorithm @@ -81,14 +94,16 @@ def set_resampling_algorithm(self, resampling_algorithm): "Available algorithms: 'bicubic', 'nearest', 'box', 'bilinear', " "'hamming', 'lanczos'.", ) + return self - def reset_points(self): - # Corresponding corners of image are fixed to these 3 points + def reset_points(self) -> None: + """Sets :attr:`points` to be the four image corners.""" self.points = np.array( [ UP + LEFT, UP + RIGHT, DOWN + LEFT, + DOWN + RIGHT, ], ) self.center() @@ -106,7 +121,7 @@ class ImageMobject(AbstractImageMobject): Parameters ---------- - scale_to_resolution : :class:`int` + scale_to_resolution At this resolution the image is placed pixel by pixel onto the screen, so it will look the sharpest and best. This is a custom parameter of ImageMobject so that rendering a scene with @@ -165,15 +180,15 @@ def construct(self): def __init__( self, - filename_or_array, - scale_to_resolution=QUALITIES[DEFAULT_QUALITY]["pixel_height"], - invert=False, - image_mode="RGBA", - **kwargs, - ): - self.fill_opacity = 1 - self.stroke_opacity = 1 - self.invert = invert + filename_or_array: StrPath | npt.NDArray, + scale_to_resolution: int = QUALITIES[DEFAULT_QUALITY]["pixel_height"], + invert: bool = False, + image_mode: str = "RGBA", + **kwargs: Any, + ) -> None: + self.fill_opacity: float = 1 + self.stroke_opacity: float = 1 + self.invert_image = invert self.image_mode = image_mode if isinstance(filename_or_array, (str, pathlib.PurePath)): path = get_full_raster_image_path(filename_or_array) @@ -183,25 +198,14 @@ def __init__( else: self.pixel_array = np.array(filename_or_array) self.pixel_array_dtype = kwargs.get("pixel_array_dtype", "uint8") - self.change_to_rgba_array() - if self.invert: - self.pixel_array[:, :, :3] = 255 - self.pixel_array[:, :, :3] - super().__init__(scale_to_resolution, **kwargs) - - def change_to_rgba_array(self): - """Converts an RGB array into RGBA with the alpha value opacity maxed.""" - pa = self.pixel_array - if len(pa.shape) == 2: - pa = pa.reshape(list(pa.shape) + [1]) - if pa.shape[2] == 1: - pa = pa.repeat(3, axis=2) - if pa.shape[2] == 3: - alphas = 255 * np.ones( - list(pa.shape[:2]) + [1], - dtype=self.pixel_array_dtype, + self.pixel_array = change_to_rgba_array( + self.pixel_array, self.pixel_array_dtype + ) + if self.invert_image: + self.pixel_array[:, :, :3] = ( + np.iinfo(self.pixel_array_dtype).max - self.pixel_array[:, :, :3] ) - pa = np.append(pa, alphas, axis=2) - self.pixel_array = pa + super().__init__(scale_to_resolution, **kwargs) def get_pixel_array(self): """A simple getter method.""" @@ -217,12 +221,12 @@ def set_color(self, color, alpha=None, family=True): self.color = color return self - def set_opacity(self, alpha): + def set_opacity(self, alpha: float) -> Self: """Sets the image's opacity. Parameters ---------- - alpha : float + alpha The alpha value of the object, 1 being opaque and 0 being transparent. """ @@ -231,34 +235,36 @@ def set_opacity(self, alpha): self.stroke_opacity = alpha return self - def fade(self, darkness=0.5, family=True): + def fade(self, darkness: float = 0.5, family: bool = True) -> Self: """Sets the image's opacity using a 1 - alpha relationship. Parameters ---------- - darkness : float + darkness The alpha value of the object, 1 being transparent and 0 being opaque. - family : Boolean + family Whether the submobjects of the ImageMobject should be affected. """ self.set_opacity(1 - darkness) super().fade(darkness, family) return self - def interpolate_color(self, mobject1, mobject2, alpha): - """Interpolates an array of pixel color values into another array of - equal size. + def interpolate_color( + self, mobject1: ImageMobject, mobject2: ImageMobject, alpha: float + ) -> None: + """Interpolates the array of pixel color values from one ImageMobject + into an array of equal size in the target ImageMobject. Parameters ---------- - mobject1 : ImageMobject + mobject1 The ImageMobject to transform from. - mobject1 : ImageMobject - + mobject2 The ImageMobject to transform into. - alpha : float + + alpha Used to track the lerp relationship. Not opacity related. """ assert mobject1.pixel_array.shape == mobject2.pixel_array.shape, ( @@ -282,9 +288,9 @@ def interpolate_color(self, mobject1, mobject2, alpha): alpha, ).astype(self.pixel_array_dtype) - def get_style(self): + def get_style(self) -> dict[str, Any]: return { - "fill_color": colour.rgb2hex(self.color.get_rgb()), + "fill_color": ManimColor(self.color.get_rgb()).to_hex(), "fill_opacity": self.fill_opacity, } @@ -295,7 +301,12 @@ def get_style(self): class ImageMobjectFromCamera(AbstractImageMobject): - def __init__(self, camera, default_display_frame_config=None, **kwargs): + def __init__( + self, + camera, + default_display_frame_config: dict[str, Any] | None = None, + **kwargs: Any, + ) -> None: self.camera = camera if default_display_frame_config is None: default_display_frame_config = { @@ -312,14 +323,14 @@ def get_pixel_array(self): self.pixel_array = self.camera.pixel_array return self.pixel_array - def add_display_frame(self, **kwargs): + def add_display_frame(self, **kwargs: Any) -> Self: config = dict(self.default_display_frame_config) config.update(kwargs) self.display_frame = SurroundingRectangle(self, **config) self.add(self.display_frame) return self - def interpolate_color(self, mobject1, mobject2, alpha): + def interpolate_color(self, mobject1, mobject2, alpha) -> None: assert mobject1.pixel_array.shape == mobject2.pixel_array.shape, ( f"Mobject pixel array shapes incompatible for interpolation.\n" f"Mobject 1 ({mobject1}) : {mobject1.pixel_array.shape}\n" diff --git a/manim/mobject/types/point_cloud_mobject.py b/manim/mobject/types/point_cloud_mobject.py index acc981cc68..f5953aab8c 100644 --- a/manim/mobject/types/point_cloud_mobject.py +++ b/manim/mobject/types/point_cloud_mobject.py @@ -4,8 +4,9 @@ __all__ = ["PMobject", "Mobject1D", "Mobject2D", "PGroup", "PointCloudDot", "Point"] +from typing import TYPE_CHECKING + import numpy as np -from colour import Color from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL from manim.mobject.opengl.opengl_point_cloud_mobject import OpenGLPMobject @@ -17,12 +18,25 @@ BLACK, WHITE, YELLOW, + ManimColor, + ParsableManimColor, color_gradient, color_to_rgba, rgba_to_color, ) from ...utils.iterables import stretch_array_to_length +__all__ = ["PMobject", "Mobject1D", "Mobject2D", "PGroup", "PointCloudDot", "Point"] + +if TYPE_CHECKING: + from collections.abc import Callable + from typing import Any + + import numpy.typing as npt + from typing_extensions import Self + + from manim.typing import ManimFloat, Point3DLike, Vector3D + class PMobject(Mobject, metaclass=ConvertToOpenGL): """A disc made of a cloud of Dots @@ -53,19 +67,25 @@ def construct(self): """ - def __init__(self, stroke_width=DEFAULT_STROKE_WIDTH, **kwargs): + def __init__(self, stroke_width: int = DEFAULT_STROKE_WIDTH, **kwargs: Any) -> None: self.stroke_width = stroke_width super().__init__(**kwargs) - def reset_points(self): + def reset_points(self) -> Self: self.rgbas = np.zeros((0, 4)) self.points = np.zeros((0, 3)) return self - def get_array_attrs(self): + def get_array_attrs(self) -> list[str]: return super().get_array_attrs() + ["rgbas"] - def add_points(self, points, rgbas=None, color=None, alpha=1): + def add_points( + self, + points: npt.NDArray, + rgbas: npt.NDArray | None = None, + color: ParsableManimColor | None = None, + alpha: float = 1, + ) -> Self: """Add points. Points must be a Nx3 numpy array. @@ -76,31 +96,33 @@ def add_points(self, points, rgbas=None, color=None, alpha=1): num_new_points = len(points) self.points = np.append(self.points, points, axis=0) if rgbas is None: - color = Color(color) if color else self.color + color = ManimColor(color) if color else self.color rgbas = np.repeat([color_to_rgba(color, alpha)], num_new_points, axis=0) elif len(rgbas) != len(points): raise ValueError("points and rgbas must have same length") self.rgbas = np.append(self.rgbas, rgbas, axis=0) return self - def set_color(self, color=YELLOW, family=True): + def set_color( + self, color: ParsableManimColor = YELLOW, family: bool = True + ) -> Self: rgba = color_to_rgba(color) mobs = self.family_members_with_points() if family else [self] for mob in mobs: mob.rgbas[:, :] = rgba - self.color = color + self.color = ManimColor.parse(color) return self - def get_stroke_width(self): + def get_stroke_width(self) -> int: return self.stroke_width - def set_stroke_width(self, width, family=True): + def set_stroke_width(self, width: int, family: bool = True) -> Self: mobs = self.family_members_with_points() if family else [self] for mob in mobs: mob.stroke_width = width return self - def set_color_by_gradient(self, *colors): + def set_color_by_gradient(self, *colors: ParsableManimColor) -> Self: self.rgbas = np.array( list(map(color_to_rgba, color_gradient(*colors, len(self.points)))), ) @@ -108,11 +130,11 @@ def set_color_by_gradient(self, *colors): def set_colors_by_radial_gradient( self, - center=None, - radius=1, - inner_color=WHITE, - outer_color=BLACK, - ): + center: Point3DLike | None = None, + radius: float = 1, + inner_color: ParsableManimColor = WHITE, + outer_color: ParsableManimColor = BLACK, + ) -> Self: start_rgba, end_rgba = list(map(color_to_rgba, [inner_color, outer_color])) if center is None: center = self.get_center() @@ -127,48 +149,48 @@ def set_colors_by_radial_gradient( ) return self - def match_colors(self, mobject): + def match_colors(self, mobject: Mobject) -> Self: Mobject.align_data(self, mobject) self.rgbas = np.array(mobject.rgbas) return self - def filter_out(self, condition): + def filter_out(self, condition: npt.NDArray) -> Self: for mob in self.family_members_with_points(): to_eliminate = ~np.apply_along_axis(condition, 1, mob.points) mob.points = mob.points[to_eliminate] mob.rgbas = mob.rgbas[to_eliminate] return self - def thin_out(self, factor=5): - """ - Removes all but every nth point for n = factor - """ + def thin_out(self, factor: int = 5) -> Self: + """Removes all but every nth point for n = factor""" for mob in self.family_members_with_points(): num_points = self.get_num_points() mob.apply_over_attr_arrays( - lambda arr: arr[np.arange(0, num_points, factor)], + lambda arr, n=num_points: arr[np.arange(0, n, factor)], ) return self - def sort_points(self, function=lambda p: p[0]): - """ - Function is any map from R^3 to R - """ + def sort_points( + self, function: Callable[[npt.NDArray[ManimFloat]], float] = lambda p: p[0] + ) -> Self: + """Function is any map from R^3 to R""" for mob in self.family_members_with_points(): indices = np.argsort(np.apply_along_axis(function, 1, mob.points)) - mob.apply_over_attr_arrays(lambda arr: arr[indices]) + mob.apply_over_attr_arrays(lambda arr, idx=indices: arr[idx]) return self - def fade_to(self, color, alpha, family=True): + def fade_to( + self, color: ParsableManimColor, alpha: float, family: bool = True + ) -> Self: self.rgbas = interpolate(self.rgbas, color_to_rgba(color), alpha) for mob in self.submobjects: mob.fade_to(color, alpha, family) return self - def get_all_rgbas(self): + def get_all_rgbas(self) -> npt.NDArray: return self.get_merged_array("rgbas") - def ingest_submobjects(self): + def ingest_submobjects(self) -> Self: attrs = self.get_array_attrs() arrays = list(map(self.get_merged_array, attrs)) for attr, array in zip(attrs, arrays): @@ -176,26 +198,32 @@ def ingest_submobjects(self): self.submobjects = [] return self - def get_color(self): + def get_color(self) -> ManimColor: return rgba_to_color(self.rgbas[0, :]) - def point_from_proportion(self, alpha): + def point_from_proportion(self, alpha: float) -> Any: index = alpha * (self.get_num_points() - 1) - return self.points[index] + return self.points[np.floor(index)] + + @staticmethod + def get_mobject_type_class() -> type[PMobject]: + return PMobject # Alignment - def align_points_with_larger(self, larger_mobject): + def align_points_with_larger(self, larger_mobject: Mobject) -> None: assert isinstance(larger_mobject, PMobject) self.apply_over_attr_arrays( lambda a: stretch_array_to_length(a, larger_mobject.get_num_points()), ) - def get_point_mobject(self, center=None): + def get_point_mobject(self, center: Point3DLike | None = None) -> Point: if center is None: center = self.get_center() return Point(center) - def interpolate_color(self, mobject1, mobject2, alpha): + def interpolate_color( + self, mobject1: Mobject, mobject2: Mobject, alpha: float + ) -> Self: self.rgbas = interpolate(mobject1.rgbas, mobject2.rgbas, alpha) self.set_stroke_width( interpolate( @@ -206,7 +234,7 @@ def interpolate_color(self, mobject1, mobject2, alpha): ) return self - def pointwise_become_partial(self, mobject, a, b): + def pointwise_become_partial(self, mobject: Mobject, a: float, b: float) -> None: lower_index, upper_index = (int(x * mobject.get_num_points()) for x in (a, b)) for attr in self.get_array_attrs(): full_array = getattr(mobject, attr) @@ -216,31 +244,39 @@ def pointwise_become_partial(self, mobject, a, b): # TODO, Make the two implementations below non-redundant class Mobject1D(PMobject, metaclass=ConvertToOpenGL): - def __init__(self, density=DEFAULT_POINT_DENSITY_1D, **kwargs): + def __init__(self, density: int = DEFAULT_POINT_DENSITY_1D, **kwargs: Any) -> None: self.density = density self.epsilon = 1.0 / self.density super().__init__(**kwargs) - def add_line(self, start, end, color=None): + def add_line( + self, + start: npt.NDArray, + end: npt.NDArray, + color: ParsableManimColor | None = None, + ) -> None: start, end = list(map(np.array, [start, end])) length = np.linalg.norm(end - start) if length == 0: - points = [start] + points = np.array([start]) else: epsilon = self.epsilon / length - points = [interpolate(start, end, t) for t in np.arange(0, 1, epsilon)] + points = np.array( + [interpolate(start, end, t) for t in np.arange(0, 1, epsilon)] + ) self.add_points(points, color=color) class Mobject2D(PMobject, metaclass=ConvertToOpenGL): - def __init__(self, density=DEFAULT_POINT_DENSITY_2D, **kwargs): + def __init__(self, density: int = DEFAULT_POINT_DENSITY_2D, **kwargs: Any) -> None: self.density = density self.epsilon = 1.0 / self.density super().__init__(**kwargs) class PGroup(PMobject): - """ + """A group for several point mobjects. + Examples -------- @@ -261,8 +297,8 @@ def construct(self): """ - def __init__(self, *pmobs, **kwargs): - if not all([isinstance(m, (PMobject, OpenGLPMobject)) for m in pmobs]): + def __init__(self, *pmobs: Any, **kwargs: Any) -> None: + if not all(isinstance(m, (PMobject, OpenGLPMobject)) for m in pmobs): raise ValueError( "All submobjects must be of type PMobject or OpenGLPMObject" " if using the opengl renderer", @@ -270,14 +306,18 @@ def __init__(self, *pmobs, **kwargs): super().__init__(**kwargs) self.add(*pmobs) - def fade_to(self, color, alpha, family=True): + def fade_to( + self, color: ParsableManimColor, alpha: float, family: bool = True + ) -> Self: if family: for mob in self.submobjects: mob.fade_to(color, alpha, family) + return self class PointCloudDot(Mobject1D): - """A disc made of a cloud of Dots + """A disc made of a cloud of dots. + Examples -------- .. manim:: PointCloudDotExample @@ -309,13 +349,13 @@ def construct(self): def __init__( self, - center=ORIGIN, - radius=2.0, - stroke_width=2, - density=DEFAULT_POINT_DENSITY_1D, - color=YELLOW, - **kwargs, - ): + center: Vector3D = ORIGIN, + radius: float = 2.0, + stroke_width: int = 2, + density: int = DEFAULT_POINT_DENSITY_1D, + color: ManimColor = YELLOW, + **kwargs: Any, + ) -> None: self.radius = radius self.epsilon = 1.0 / density super().__init__( @@ -323,27 +363,29 @@ def __init__( ) self.shift(center) - def init_points(self): + def init_points(self) -> None: self.reset_points() self.generate_points() - def generate_points(self): + def generate_points(self) -> None: self.add_points( - [ - r * (np.cos(theta) * RIGHT + np.sin(theta) * UP) - for r in np.arange(self.epsilon, self.radius, self.epsilon) - # Num is equal to int(stop - start)/ (step + 1) reformulated. - for theta in np.linspace( - 0, - 2 * np.pi, - num=int(2 * np.pi * (r + self.epsilon) / self.epsilon), - ) - ], + np.array( + [ + r * (np.cos(theta) * RIGHT + np.sin(theta) * UP) + for r in np.arange(self.epsilon, self.radius, self.epsilon) + # Num is equal to int(stop - start)/ (step + 1) reformulated. + for theta in np.linspace( + 0, + 2 * np.pi, + num=int(2 * np.pi * (r + self.epsilon) / self.epsilon), + ) + ] + ), ) class Point(PMobject): - """ + """A mobject representing a point. Examples -------- @@ -363,14 +405,16 @@ def construct(self): self.add(point) """ - def __init__(self, location=ORIGIN, color=BLACK, **kwargs): + def __init__( + self, location: Vector3D = ORIGIN, color: ManimColor = BLACK, **kwargs: Any + ) -> None: self.location = location super().__init__(color=color, **kwargs) - def init_points(self): + def init_points(self) -> None: self.reset_points() self.generate_points() self.set_points([self.location]) - def generate_points(self): - self.add_points([self.location]) + def generate_points(self) -> None: + self.add_points(np.array([self.location])) diff --git a/manim/mobject/types/vectorized_mobject.py b/manim/mobject/types/vectorized_mobject.py index d7bb731346..321fe4287b 100644 --- a/manim/mobject/types/vectorized_mobject.py +++ b/manim/mobject/types/vectorized_mobject.py @@ -1,5 +1,6 @@ """Mobjects that use vector graphics.""" +from __future__ import annotations __all__ = [ "VMobject", @@ -13,34 +14,60 @@ import itertools as it import sys -import typing -from typing import Optional, Sequence, Union +from collections.abc import Hashable, Iterable, Mapping, Sequence +from typing import TYPE_CHECKING, Callable, Literal -import colour import numpy as np from PIL.Image import Image +from manim import config +from manim.constants import * +from manim.mobject.mobject import Mobject from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL +from manim.mobject.opengl.opengl_mobject import OpenGLMobject from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject from manim.mobject.three_d.three_d_utils import ( get_3d_vmob_gradient_start_and_end_points, ) - -from ... import config -from ...constants import * -from ...mobject.mobject import Mobject -from ...utils.bezier import ( +from manim.utils.bezier import ( bezier, - get_smooth_handle_points, + bezier_remap, + get_smooth_cubic_bezier_handle_points, integer_interpolate, interpolate, partial_bezier_points, proportions_along_bezier_curve_for_point, ) -from ...utils.color import BLACK, WHITE, color_to_rgba -from ...utils.deprecation import deprecated -from ...utils.iterables import make_even, stretch_array_to_length, tuplify -from ...utils.space_ops import rotate_vector, shoelace_direction +from manim.utils.color import BLACK, WHITE, ManimColor, ParsableManimColor +from manim.utils.iterables import ( + make_even, + resize_array, + stretch_array_to_length, + tuplify, +) +from manim.utils.space_ops import rotate_vector, shoelace_direction + +if TYPE_CHECKING: + from typing import Any + + import numpy.typing as npt + from typing_extensions import Self + + from manim.typing import ( + CubicBezierPath, + CubicBezierPointsLike, + CubicSpline, + ManimFloat, + MappingFunction, + Point2DLike, + Point3D, + Point3D_Array, + Point3DLike, + Point3DLike_Array, + RGBA_Array_Float, + Vector3D, + Zeros, + ) # TODO # - Change cubic curve groups to have 4 points instead of 3 @@ -68,63 +95,98 @@ class VMobject(Mobject): close_new_points Indicates that it will not be displayed, but that it should count in parent mobject's path - tolerance_point_for_equality + tolerance_for_point_equality This is within a pixel + joint_type + The line joint type used to connect the curve segments + of this vectorized mobject. See :class:`.LineJointType` + for options. """ sheen_factor = 0.0 def __init__( self, - fill_color=None, - fill_opacity=0.0, - stroke_color=None, - stroke_opacity=1.0, - stroke_width=DEFAULT_STROKE_WIDTH, - background_stroke_color=BLACK, - background_stroke_opacity=1.0, - background_stroke_width=0, - sheen_factor=0.0, - sheen_direction=UL, - close_new_points=False, - pre_function_handle_to_anchor_scale_factor=0.01, - make_smooth_after_applying_functions=False, - background_image=None, - shade_in_3d=False, + fill_color: ParsableManimColor | None = None, + fill_opacity: float = 0.0, + stroke_color: ParsableManimColor | None = None, + stroke_opacity: float = 1.0, + stroke_width: float = DEFAULT_STROKE_WIDTH, + background_stroke_color: ParsableManimColor | None = BLACK, + background_stroke_opacity: float = 1.0, + background_stroke_width: float = 0, + sheen_factor: float = 0.0, + joint_type: LineJointType | None = None, + sheen_direction: Vector3D = UL, + close_new_points: bool = False, + pre_function_handle_to_anchor_scale_factor: float = 0.01, + make_smooth_after_applying_functions: bool = False, + background_image: Image | str | None = None, + shade_in_3d: bool = False, # TODO, do we care about accounting for varying zoom levels? - tolerance_for_point_equality=1e-6, - n_points_per_cubic_curve=4, - **kwargs, + tolerance_for_point_equality: float = 1e-6, + n_points_per_cubic_curve: int = 4, + cap_style: CapStyleType = CapStyleType.AUTO, + **kwargs: Any, ): self.fill_opacity = fill_opacity self.stroke_opacity = stroke_opacity self.stroke_width = stroke_width - self.background_stroke_color = background_stroke_color - self.background_stroke_opacity = background_stroke_opacity - self.background_stroke_width = background_stroke_width - self.sheen_factor = sheen_factor - self.sheen_direction = sheen_direction - self.close_new_points = close_new_points - self.pre_function_handle_to_anchor_scale_factor = ( + if background_stroke_color is not None: + self.background_stroke_color: ManimColor = ManimColor( + background_stroke_color + ) + self.background_stroke_opacity: float = background_stroke_opacity + self.background_stroke_width: float = background_stroke_width + self.sheen_factor: float = sheen_factor + self.joint_type: LineJointType = ( + LineJointType.AUTO if joint_type is None else joint_type + ) + self.sheen_direction: Vector3D = sheen_direction + self.close_new_points: bool = close_new_points + self.pre_function_handle_to_anchor_scale_factor: float = ( pre_function_handle_to_anchor_scale_factor ) - self.make_smooth_after_applying_functions = make_smooth_after_applying_functions - self.background_image = background_image - self.shade_in_3d = shade_in_3d - self.tolerance_for_point_equality = tolerance_for_point_equality - self.n_points_per_cubic_curve = n_points_per_cubic_curve + self.make_smooth_after_applying_functions: bool = ( + make_smooth_after_applying_functions + ) + self.background_image: Image | str | None = background_image + self.shade_in_3d: bool = shade_in_3d + self.tolerance_for_point_equality: float = tolerance_for_point_equality + self.n_points_per_cubic_curve: int = n_points_per_cubic_curve + self._bezier_t_values: npt.NDArray[float] = np.linspace( + 0, 1, n_points_per_cubic_curve + ) + self.cap_style: CapStyleType = cap_style super().__init__(**kwargs) - - if fill_color: - self.fill_color = fill_color - if stroke_color: - self.stroke_color = stroke_color - - def get_group_class(self): + self.submobjects: list[VMobject] + + # TODO: Find where color overwrites are happening and remove the color doubling + # if "color" in kwargs: + # fill_color = kwargs["color"] + # stroke_color = kwargs["color"] + if fill_color is not None: + self.fill_color = ManimColor.parse(fill_color) + if stroke_color is not None: + self.stroke_color = ManimColor.parse(stroke_color) + + def _assert_valid_submobjects(self, submobjects: Iterable[VMobject]) -> Self: + return self._assert_valid_submobjects_internal(submobjects, VMobject) + + # OpenGL compatibility + @property + def n_points_per_curve(self) -> int: + return self.n_points_per_cubic_curve + + def get_group_class(self) -> type[VGroup]: return VGroup + @staticmethod + def get_mobject_type_class() -> type[VMobject]: + return VMobject + # Colors - def init_colors(self, propagate_colors=True): + def init_colors(self, propagate_colors: bool = True) -> Self: self.set_fill( color=self.fill_color, opacity=self.fill_opacity, @@ -154,7 +216,9 @@ def init_colors(self, propagate_colors=True): return self - def generate_rgbas_array(self, color, opacity): + def generate_rgbas_array( + self, color: ManimColor | list[ManimColor], opacity: float | Iterable[float] + ) -> RGBA_Array_Float: """ First arg can be either a color, or a tuple/list of colors. Likewise, opacity can either be a float, or a tuple of floats. @@ -162,10 +226,14 @@ def generate_rgbas_array(self, color, opacity): one color was passed in, a second slightly light color will automatically be added for the gradient """ - colors = [c if (c is not None) else BLACK for c in tuplify(color)] - opacities = [o if (o is not None) else 0 for o in tuplify(opacity)] - rgbas = np.array( - [color_to_rgba(c, o) for c, o in zip(*make_even(colors, opacities))], + colors: list[ManimColor] = [ + ManimColor(c) if (c is not None) else BLACK for c in tuplify(color) + ] + opacities: list[float] = [ + o if (o is not None) else 0.0 for o in tuplify(opacity) + ] + rgbas: npt.NDArray[RGBA_Array_Float] = np.array( + [c.to_rgba_with_alpha(o) for c, o in zip(*make_even(colors, opacities))], ) sheen_factor = self.get_sheen_factor() @@ -176,7 +244,12 @@ def generate_rgbas_array(self, color, opacity): rgbas = np.append(rgbas, light_rgbas, axis=0) return rgbas - def update_rgbas_array(self, array_name, color=None, opacity=None): + def update_rgbas_array( + self, + array_name: str, + color: ManimColor | None = None, + opacity: float | None = None, + ) -> Self: rgbas = self.generate_rgbas_array(color, opacity) if not hasattr(self, array_name): setattr(self, array_name, rgbas) @@ -199,10 +272,10 @@ def update_rgbas_array(self, array_name, color=None, opacity=None): def set_fill( self, - color: Optional[str] = None, - opacity: Optional[float] = None, + color: ParsableManimColor | None = None, + opacity: float | None = None, family: bool = True, - ): + ) -> Self: """Set the fill color and fill opacity of a :class:`VMobject`. Parameters @@ -242,18 +315,19 @@ def construct(self): for submobject in self.submobjects: submobject.set_fill(color, opacity, family) self.update_rgbas_array("fill_rgbas", color, opacity) + self.fill_rgbas: RGBA_Array_Float if opacity is not None: self.fill_opacity = opacity return self def set_stroke( self, - color=None, - width=None, - opacity=None, + color: ParsableManimColor = None, + width: float | None = None, + opacity: float | None = None, background=False, - family=True, - ): + family: bool = True, + ) -> Self: if family: for submobject in self.submobjects: submobject.set_stroke(color, width, opacity, background, family) @@ -271,29 +345,60 @@ def set_stroke( if opacity is not None: setattr(self, opacity_name, opacity) if color is not None and background: - self.background_stroke_color = color + if isinstance(color, (list, tuple)): + self.background_stroke_color = ManimColor.parse(color) + else: + self.background_stroke_color = ManimColor(color) return self - def set_background_stroke(self, **kwargs): + def set_cap_style(self, cap_style: CapStyleType) -> Self: + """ + Sets the cap style of the :class:`VMobject`. + + Parameters + ---------- + cap_style + The cap style to be set. See :class:`.CapStyleType` for options. + + Returns + ------- + :class:`VMobject` + ``self`` + + Examples + -------- + .. manim:: CapStyleExample + :save_last_frame: + + class CapStyleExample(Scene): + def construct(self): + line = Line(LEFT, RIGHT, color=YELLOW, stroke_width=20) + line.set_cap_style(CapStyleType.ROUND) + self.add(line) + """ + self.cap_style = cap_style + return self + + def set_background_stroke(self, **kwargs) -> Self: kwargs["background"] = True self.set_stroke(**kwargs) return self def set_style( self, - fill_color=None, - fill_opacity=None, - stroke_color=None, - stroke_width=None, - stroke_opacity=None, - background_stroke_color=None, - background_stroke_width=None, - background_stroke_opacity=None, - sheen_factor=None, - sheen_direction=None, - background_image=None, - family=True, - ): + fill_color: ParsableManimColor | None = None, + fill_opacity: float | None = None, + stroke_color: ParsableManimColor | None = None, + stroke_width: float | None = None, + stroke_opacity: float | None = None, + background_stroke_color: ParsableManimColor | None = None, + background_stroke_width: float | None = None, + background_stroke_opacity: float | None = None, + sheen_factor: float | None = None, + sheen_direction: Vector3D | None = None, + background_image: Image | str | None = None, + family: bool = True, + ) -> Self: self.set_fill(color=fill_color, opacity=fill_opacity, family=family) self.set_stroke( color=stroke_color, @@ -317,16 +422,17 @@ def set_style( self.color_using_background_image(background_image) return self - def get_style(self, simple=False): + def get_style(self, simple: bool = False) -> dict: ret = { "stroke_opacity": self.get_stroke_opacity(), "stroke_width": self.get_stroke_width(), } + # TODO: FIX COLORS HERE if simple: - ret["fill_color"] = colour.rgb2hex(self.get_fill_color().get_rgb()) + ret["fill_color"] = self.get_fill_color() ret["fill_opacity"] = self.get_fill_opacity() - ret["stroke_color"] = colour.rgb2hex(self.get_stroke_color().get_rgb()) + ret["stroke_color"] = self.get_stroke_color() else: ret["fill_color"] = self.get_fill_colors() ret["fill_opacity"] = self.get_fill_opacities() @@ -340,7 +446,7 @@ def get_style(self, simple=False): return ret - def match_style(self, vmobject, family=True): + def match_style(self, vmobject: VMobject, family: bool = True) -> Self: self.set_style(**vmobject.get_style(), family=False) if family: @@ -355,18 +461,76 @@ def match_style(self, vmobject, family=True): sm1.match_style(sm2) return self - def set_color(self, color, family=True): + def set_color(self, color: ParsableManimColor, family: bool = True) -> Self: self.set_fill(color, family=family) self.set_stroke(color, family=family) return self - def set_opacity(self, opacity, family=True): + def set_opacity(self, opacity: float, family: bool = True) -> Self: self.set_fill(opacity=opacity, family=family) self.set_stroke(opacity=opacity, family=family) self.set_stroke(opacity=opacity, family=family, background=True) return self - def fade(self, darkness=0.5, family=True): + def scale(self, scale_factor: float, scale_stroke: bool = False, **kwargs) -> Self: + r"""Scale the size by a factor. + + Default behavior is to scale about the center of the vmobject. + + Parameters + ---------- + scale_factor + The scaling factor :math:`\alpha`. If :math:`0 < |\alpha| < 1`, the mobject + will shrink, and for :math:`|\alpha| > 1` it will grow. Furthermore, + if :math:`\alpha < 0`, the mobject is also flipped. + scale_stroke + Boolean determining if the object's outline is scaled when the object is scaled. + If enabled, and object with 2px outline is scaled by a factor of .5, it will have an outline of 1px. + kwargs + Additional keyword arguments passed to + :meth:`~.Mobject.scale`. + + Returns + ------- + :class:`VMobject` + ``self`` + + Examples + -------- + + .. manim:: MobjectScaleExample + :save_last_frame: + + class MobjectScaleExample(Scene): + def construct(self): + c1 = Circle(1, RED).set_x(-1) + c2 = Circle(1, GREEN).set_x(1) + + vg = VGroup(c1, c2) + vg.set_stroke(width=50) + self.add(vg) + + self.play( + c1.animate.scale(.25), + c2.animate.scale(.25, + scale_stroke=True) + ) + + See also + -------- + :meth:`move_to` + + """ + if scale_stroke: + self.set_stroke(width=abs(scale_factor) * self.get_stroke_width()) + self.set_stroke( + width=abs(scale_factor) * self.get_stroke_width(background=True), + background=True, + ) + super().scale(scale_factor, **kwargs) + return self + + def fade(self, darkness: float = 0.5, family: bool = True) -> Self: factor = 1.0 - darkness self.set_fill(opacity=factor * self.get_fill_opacity(), family=False) self.set_stroke(opacity=factor * self.get_stroke_opacity(), family=False) @@ -377,13 +541,13 @@ def fade(self, darkness=0.5, family=True): super().fade(darkness, family) return self - def get_fill_rgbas(self): + def get_fill_rgbas(self) -> RGBA_Array_Float | Zeros: try: return self.fill_rgbas except AttributeError: return np.zeros((1, 4)) - def get_fill_color(self): + def get_fill_color(self) -> ManimColor: """ If there are multiple colors (for gradient) this returns the first one @@ -392,71 +556,76 @@ def get_fill_color(self): fill_color = property(get_fill_color, set_fill) - def get_fill_opacity(self): + def get_fill_opacity(self) -> ManimFloat: """ If there are multiple opacities, this returns the first """ return self.get_fill_opacities()[0] - def get_fill_colors(self): + # TODO: Does this just do a copy? + # TODO: I have the feeling that this function should not return None, does that have any usage ? + def get_fill_colors(self) -> list[ManimColor | None]: return [ - colour.Color(rgb=rgba[:3]) if rgba.any() else None + ManimColor(rgba[:3]) if rgba.any() else None for rgba in self.get_fill_rgbas() ] - def get_fill_opacities(self): + def get_fill_opacities(self) -> npt.NDArray[ManimFloat]: return self.get_fill_rgbas()[:, 3] - def get_stroke_rgbas(self, background=False): + def get_stroke_rgbas(self, background: bool = False) -> RGBA_Array_float | Zeros: try: if background: + self.background_stroke_rgbas: RGBA_Array_Float rgbas = self.background_stroke_rgbas else: + self.stroke_rgbas: RGBA_Array_Float rgbas = self.stroke_rgbas return rgbas except AttributeError: return np.zeros((1, 4)) - def get_stroke_color(self, background=False): + def get_stroke_color(self, background: bool = False) -> ManimColor | None: return self.get_stroke_colors(background)[0] stroke_color = property(get_stroke_color, set_stroke) - def get_stroke_width(self, background=False): + def get_stroke_width(self, background: bool = False) -> float: if background: + self.background_stroke_width: float width = self.background_stroke_width else: width = self.stroke_width if isinstance(width, str): width = int(width) - return max(0, width) + return max(0.0, width) - def get_stroke_opacity(self, background=False): + def get_stroke_opacity(self, background: bool = False) -> ManimFloat: return self.get_stroke_opacities(background)[0] - def get_stroke_colors(self, background=False): + def get_stroke_colors(self, background: bool = False) -> list[ManimColor | None]: return [ - colour.Color(rgb=rgba[:3]) if rgba.any() else None + ManimColor(rgba[:3]) if rgba.any() else None for rgba in self.get_stroke_rgbas(background) ] - def get_stroke_opacities(self, background=False): + def get_stroke_opacities(self, background: bool = False) -> npt.NDArray[ManimFloat]: return self.get_stroke_rgbas(background)[:, 3] - def get_color(self): + def get_color(self) -> ManimColor: if np.all(self.get_fill_opacities() == 0): return self.get_stroke_color() return self.get_fill_color() color = property(get_color, set_color) - def set_sheen_direction(self, direction: np.ndarray, family=True): + def set_sheen_direction(self, direction: Vector3D, family: bool = True) -> Self: """Sets the direction of the applied sheen. Parameters ---------- - direction : :class:`numpy.ndarray`, optional + direction Direction from where the gradient is applied. Examples @@ -470,23 +639,24 @@ def set_sheen_direction(self, direction: np.ndarray, family=True): :meth:`~.VMobject.set_sheen` :meth:`~.VMobject.rotate_sheen_direction` """ - direction = np.array(direction) if family: for submob in self.get_family(): submob.sheen_direction = direction else: - self.sheen_direction = direction + self.sheen_direction: Vector3D = direction return self - def rotate_sheen_direction(self, angle: np.ndarray, axis: float = OUT, family=True): + def rotate_sheen_direction( + self, angle: float, axis: Vector3D = OUT, family: bool = True + ) -> Self: """Rotates the direction of the applied sheen. Parameters ---------- - angle : :class:`float` + angle Angle by which the direction of sheen is rotated. - axis : :class:`numpy.ndarray` + axis Axis of rotation. Examples @@ -510,16 +680,18 @@ def rotate_sheen_direction(self, angle: np.ndarray, axis: float = OUT, family=Tr self.sheen_direction = rotate_vector(self.sheen_direction, angle, axis) return self - def set_sheen(self, factor, direction: np.ndarray = None, family=True): + def set_sheen( + self, factor: float, direction: Vector3D | None = None, family: bool = True + ) -> Self: """Applies a color gradient from a direction. Parameters ---------- - factor : :class:`float` + factor The extent of lustre/gradient to apply. If negative, the gradient starts from black, if positive the gradient starts from white and changes to the current color. - direction : :class:`numpy.ndarray`, optional + direction Direction from where the gradient is applied. Examples @@ -532,11 +704,10 @@ def construct(self): circle = Circle(fill_opacity=1).set_sheen(-0.3, DR) self.add(circle) """ - if family: for submob in self.submobjects: submob.set_sheen(factor, direction, family) - self.sheen_factor = factor + self.sheen_factor: float = factor if direction is not None: # family set to false because recursion will # already be handled above @@ -547,13 +718,13 @@ def construct(self): self.set_fill(self.get_fill_color(), family=family) return self - def get_sheen_direction(self): + def get_sheen_direction(self) -> Vector3D: return np.array(self.sheen_direction) - def get_sheen_factor(self): + def get_sheen_factor(self) -> float: return self.sheen_factor - def get_gradient_start_and_end_points(self): + def get_gradient_start_and_end_points(self) -> tuple[Point3D, Point3D]: if self.shade_in_3d: return get_3d_vmob_gradient_start_and_end_points(self) else: @@ -565,38 +736,61 @@ def get_gradient_start_and_end_points(self): offset = np.dot(bases, direction) return (c - offset, c + offset) - def color_using_background_image(self, background_image: Union[Image, str]): - self.background_image = background_image + def color_using_background_image(self, background_image: Image | str) -> Self: + self.background_image: Image | str = background_image self.set_color(WHITE) for submob in self.submobjects: submob.color_using_background_image(background_image) return self - def get_background_image(self) -> Union[Image, str]: + def get_background_image(self) -> Image | str: return self.background_image - def match_background_image(self, vmobject): + def match_background_image(self, vmobject: VMobject) -> Self: self.color_using_background_image(vmobject.get_background_image()) return self - def set_shade_in_3d(self, value=True, z_index_as_group=False): + def set_shade_in_3d( + self, value: bool = True, z_index_as_group: bool = False + ) -> Self: for submob in self.get_family(): submob.shade_in_3d = value if z_index_as_group: submob.z_index_group = self return self - def set_points(self, points): - self.points = np.array(points) + def set_points(self, points: Point3DLike_Array) -> Self: + self.points: Point3D_Array = np.array(points) + return self + + def resize_points( + self, + new_length: int, + resize_func: Callable[[Point3D_Array, int], Point3D_Array] = resize_array, + ) -> Self: + """Resize the array of anchor points and handles to have + the specified size. + + Parameters + ---------- + new_length + The new (total) number of points. + resize_func + A function mapping a Numpy array (the points) and an integer + (the target size) to a Numpy array. The default implementation + is based on Numpy's ``resize`` function. + """ + if new_length != len(self.points): + self.points = resize_func(self.points, new_length) return self def set_anchors_and_handles( self, - anchors1: Sequence[float], - handles1: Sequence[float], - handles2: Sequence[float], - anchors2: Sequence[float], - ): + anchors1: Point3DLike_Array, + handles1: Point3DLike_Array, + handles2: Point3DLike_Array, + anchors2: Point3DLike_Array, + ) -> Self: """Given two sets of anchors and handles, process them to set them as anchors and handles of the VMobject. @@ -613,7 +807,7 @@ def set_anchors_and_handles( assert len(anchors1) == len(handles1) == len(handles2) == len(anchors2) nppcc = self.n_points_per_cubic_curve # 4 total_len = nppcc * len(anchors1) - self.points = np.zeros((total_len, self.dim)) + self.points = np.empty((total_len, self.dim)) # the following will, from the four sets, dispatch them in points such that # self.points = [ # anchors1[0], handles1[0], handles2[0], anchors1[0], anchors1[1], @@ -624,48 +818,95 @@ def set_anchors_and_handles( self.points[index::nppcc] = array return self - def clear_points(self): + def clear_points(self) -> None: + # TODO: shouldn't this return self instead of None? self.points = np.zeros((0, self.dim)) - def append_points(self, new_points): + def append_points(self, new_points: Point3DLike_Array) -> Self: + """Append the given ``new_points`` to the end of + :attr:`VMobject.points`. + + Parameters + ---------- + new_points + An array of 3D points to append. + + Returns + ------- + :class:`VMobject` + The VMobject itself, after appending ``new_points``. + """ # TODO, check that number new points is a multiple of 4? # or else that if len(self.points) % 4 == 1, then # len(new_points) % 4 == 3? - self.points = np.append(self.points, new_points, axis=0) + n = len(self.points) + points = np.empty((n + len(new_points), self.dim)) + points[:n] = self.points + points[n:] = new_points + self.points = points return self - def start_new_path(self, point): - # TODO, make sure that len(self.points) % 4 == 0? - self.append_points([point]) + def start_new_path(self, point: Point3DLike) -> Self: + """Append a ``point`` to the :attr:`VMobject.points`, which will be the + beginning of a new Bézier curve in the path given by the points. If + there's an unfinished curve at the end of :attr:`VMobject.points`, + complete it by appending the last Bézier curve's start anchor as many + times as needed. + + Parameters + ---------- + point + A 3D point to append to :attr:`VMobject.points`. + + Returns + ------- + :class:`VMobject` + The VMobject itself, after appending ``point`` and starting a new + curve. + """ + n_points = len(self.points) + nppc = self.n_points_per_curve + if n_points % nppc != 0: + # close the open path by appending the last + # start anchor sufficiently often + last_anchor = self.get_start_anchors()[-1] + closure = [last_anchor] * (nppc - (n_points % nppc)) + self.append_points(closure + [point]) + else: + self.append_points([point]) return self def add_cubic_bezier_curve( self, - anchor1: np.ndarray, - handle1: np.ndarray, - handle2: np.ndarray, - anchor2, + anchor1: Point3DLike, + handle1: Point3DLike, + handle2: Point3DLike, + anchor2: Point3DLike, ) -> None: # TODO, check the len(self.points) % 4 == 0? self.append_points([anchor1, handle1, handle2, anchor2]) + # what type is curves? + def add_cubic_bezier_curves(self, curves) -> None: + self.append_points(curves.flatten()) + def add_cubic_bezier_curve_to( self, - handle1: np.ndarray, - handle2: np.ndarray, - anchor: np.ndarray, - ): + handle1: Point3DLike, + handle2: Point3DLike, + anchor: Point3DLike, + ) -> Self: """Add cubic bezier curve to the path. NOTE : the first anchor is not a parameter as by default the end of the last sub-path! Parameters ---------- - handle1 : np.ndarray + handle1 first handle - handle2 : np.ndarray + handle2 second handle - anchor : np.ndarray + anchor anchor Returns @@ -683,9 +924,9 @@ def add_cubic_bezier_curve_to( def add_quadratic_bezier_curve_to( self, - handle: np.ndarray, - anchor: np.ndarray, - ): + handle: Point3DLike, + anchor: Point3DLike, + ) -> Self: """Add Quadratic bezier curve to the path. Returns @@ -707,36 +948,35 @@ def add_quadratic_bezier_curve_to( ) return self - def add_line_to(self, point: np.ndarray): + def add_line_to(self, point: Point3DLike) -> Self: """Add a straight line from the last point of VMobject to the given point. Parameters ---------- - point : np.ndarray - end of the straight line. + point + The end of the straight line. Returns ------- :class:`VMobject` ``self`` """ - nppcc = self.n_points_per_cubic_curve self.add_cubic_bezier_curve_to( *( - interpolate(self.get_last_point(), point, a) - for a in np.linspace(0, 1, nppcc)[1:] + interpolate(self.get_last_point(), point, t) + for t in self._bezier_t_values[1:] ) ) return self - def add_smooth_curve_to(self, *points: np.array): + def add_smooth_curve_to(self, *points: Point3DLike) -> Self: """Creates a smooth curve from given points and add it to the VMobject. If two points are passed in, the first is interpreted as a handle, the second as an anchor. Parameters ---------- - points: np.array + points Points (anchor and handle, or just anchor) to add a smooth curve from Returns @@ -773,54 +1013,120 @@ def add_smooth_curve_to(self, *points: np.array): self.append_points([last_a2, handle1, handle2, new_anchor]) return self - def has_new_path_started(self): + def has_new_path_started(self) -> bool: nppcc = self.n_points_per_cubic_curve # 4 # A new path starting is defined by a control point which is not part of a bezier subcurve. return len(self.points) % nppcc == 1 - def get_last_point(self): + def get_last_point(self) -> Point3D: return self.points[-1] - def is_closed(self): + def is_closed(self) -> bool: # TODO use consider_points_equals_2d ? return self.consider_points_equals(self.points[0], self.points[-1]) - def add_points_as_corners(self, points: np.ndarray) -> "VMobject": - for point in points: - self.add_line_to(point) - return points + def close_path(self) -> None: + if not self.is_closed(): + self.add_line_to(self.get_subpaths()[-1][0]) + + def add_points_as_corners(self, points: Point3DLike_Array) -> Self: + """Append multiple straight lines at the end of + :attr:`VMobject.points`, which connect the given ``points`` in order + starting from the end of the current path. These ``points`` would be + therefore the corners of the new polyline appended to the path. + + Parameters + ---------- + points + An array of 3D points representing the corners of the polyline to + append to :attr:`VMobject.points`. - def set_points_as_corners(self, points: Sequence[float]): - """Given an array of points, set them as corner of the vmobject. + Returns + ------- + :class:`VMobject` + The VMobject itself, after appending the straight lines to its + path. + """ + points = np.asarray(points).reshape(-1, self.dim) + num_points = points.shape[0] + if num_points == 0: + return self - To achieve that, this algorithm sets handles aligned with the anchors such that the resultant bezier curve will be the segment - between the two anchors. + if self.has_new_path_started(): + # Pop the last point from self.points and + # add it to start_corners + start_corners = np.empty((num_points, self.dim)) + start_corners[0] = self.points[-1] + start_corners[1:] = points[:-1] + end_corners = points + self.points = self.points[:-1] + else: + start_corners = points[:-1] + end_corners = points[1:] + + nppcc = self.n_points_per_cubic_curve + new_points = np.empty((nppcc * start_corners.shape[0], self.dim)) + new_points[::nppcc] = start_corners + new_points[nppcc - 1 :: nppcc] = end_corners + for i, t in enumerate(self._bezier_t_values): + new_points[i::nppcc] = interpolate(start_corners, end_corners, t) + + self.append_points(new_points) + return self + + def set_points_as_corners(self, points: Point3DLike_Array) -> Self: + """Given an array of points, set them as corners of the + :class:`VMobject`. + + To achieve that, this algorithm sets handles aligned with the anchors + such that the resultant Bézier curve will be the segment between the + two anchors. Parameters ---------- - points : Iterable[float] + points Array of points that will be set as corners. Returns ------- :class:`VMobject` - ``self`` + The VMobject itself, after setting the new points as corners. + + + Examples + -------- + .. manim:: PointsAsCornersExample + :save_last_frame: + + class PointsAsCornersExample(Scene): + def construct(self): + corners = ( + # create square + UR, UL, + DL, DR, + UR, + # create crosses + DL, UL, + DR + ) + vmob = VMobject(stroke_color=RED) + vmob.set_points_as_corners(corners).scale(2) + self.add(vmob) """ - nppcc = self.n_points_per_cubic_curve points = np.array(points) # This will set the handles aligned with the anchors. # Id est, a bezier curve will be the segment from the two anchors such that the handles belongs to this segment. self.set_anchors_and_handles( - *(interpolate(points[:-1], points[1:], a) for a in np.linspace(0, 1, nppcc)) + *(interpolate(points[:-1], points[1:], t) for t in self._bezier_t_values) ) return self - def set_points_smoothly(self, points): + def set_points_smoothly(self, points: Point3DLike_Array) -> Self: self.set_points_as_corners(points) self.make_smooth() return self - def change_anchor_mode(self, mode: str): + def change_anchor_mode(self, mode: Literal["jagged", "smooth"]) -> Self: """Changes the anchor mode of the bezier curves. This will modify the handles. There can be only two modes, "jagged", and "smooth". @@ -830,7 +1136,7 @@ def change_anchor_mode(self, mode: str): :class:`VMobject` ``self`` """ - assert mode in ["jagged", "smooth"] + assert mode in ["jagged", "smooth"], 'mode must be either "jagged" or "smooth"' nppcc = self.n_points_per_cubic_curve for submob in self.family_members_with_points(): subpaths = submob.get_subpaths() @@ -841,8 +1147,8 @@ def change_anchor_mode(self, mode: str): # The append is needed as the last element is not reached when slicing with numpy. anchors = np.append(subpath[::nppcc], subpath[-1:], 0) if mode == "smooth": - h1, h2 = get_smooth_handle_points(anchors) - elif mode == "jagged": + h1, h2 = get_smooth_cubic_bezier_handle_points(anchors) + else: # mode == "jagged" # The following will make the handles aligned with the anchors, thus making the bezier curve a segment a1 = anchors[:-1] a2 = anchors[1:] @@ -854,27 +1160,25 @@ def change_anchor_mode(self, mode: str): submob.append_points(new_subpath) return self - def make_smooth(self): + def make_smooth(self) -> Self: return self.change_anchor_mode("smooth") - def make_jagged(self): + def make_jagged(self) -> Self: return self.change_anchor_mode("jagged") - def add_subpath(self, points: np.ndarray): + def add_subpath(self, points: CubicBezierPathLike) -> Self: assert len(points) % 4 == 0 - self.points = np.append(self.points, points, axis=0) + self.append_points(points) return self - def append_vectorized_mobject(self, vectorized_mobject): - new_points = list(vectorized_mobject.points) - + def append_vectorized_mobject(self, vectorized_mobject: VMobject) -> None: if self.has_new_path_started(): # Remove last point, which is starting # a new path self.points = self.points[:-1] - self.append_points(new_points) + self.append_points(vectorized_mobject.points) - def apply_function(self, function): + def apply_function(self, function: MappingFunction) -> Self: factor = self.pre_function_handle_to_anchor_scale_factor self.scale_handle_to_anchor_distances(factor) super().apply_function(function) @@ -886,15 +1190,15 @@ def apply_function(self, function): def rotate( self, angle: float, - axis: np.ndarray = OUT, - about_point: Optional[Sequence[float]] = None, + axis: Vector3D = OUT, + about_point: Point3DLike | None = None, **kwargs, - ): + ) -> Self: self.rotate_sheen_direction(angle, axis) super().rotate(angle, axis, about_point, **kwargs) return self - def scale_handle_to_anchor_distances(self, factor: float): + def scale_handle_to_anchor_distances(self, factor: float) -> Self: """If the distance between a given handle point H and its associated anchor point A is d, then it changes H to be a distances factor*d away from A, but so that the line from A to H doesn't change. @@ -926,19 +1230,19 @@ def scale_handle_to_anchor_distances(self, factor: float): return self # - def consider_points_equals(self, p0, p1): + def consider_points_equals(self, p0: Point3DLike, p1: Point3DLike) -> bool: return np.allclose(p0, p1, atol=self.tolerance_for_point_equality) - def consider_points_equals_2d(self, p0: np.ndarray, p1: np.ndarray) -> bool: + def consider_points_equals_2d(self, p0: Point2DLike, p1: Point2DLike) -> bool: """Determine if two points are close enough to be considered equal. This uses the algorithm from np.isclose(), but expanded here for the 2D point case. NumPy is overkill for such a small question. Parameters ---------- - p0 : np.ndarray + p0 first point - p1 : np.ndarray + p1 second point Returns @@ -950,15 +1254,17 @@ def consider_points_equals_2d(self, p0: np.ndarray, p1: np.ndarray) -> bool: atol = self.tolerance_for_point_equality if abs(p0[0] - p1[0]) > atol + rtol * abs(p1[0]): return False - if abs(p0[1] - p1[1]) > atol + rtol * abs(p1[1]): - return False - return True + return abs(p0[1] - p1[1]) <= atol + rtol * abs(p1[1]) # Information about line - def get_cubic_bezier_tuples_from_points(self, points): - return np.array(list(self.gen_cubic_bezier_tuples_from_points(points))) - - def gen_cubic_bezier_tuples_from_points(self, points: np.ndarray) -> typing.Tuple: + def get_cubic_bezier_tuples_from_points( + self, points: CubicBezierPathLike + ) -> CubicBezierPoints_Array: + return np.array(self.gen_cubic_bezier_tuples_from_points(points)) + + def gen_cubic_bezier_tuples_from_points( + self, points: CubicBezierPathLike + ) -> tuple[CubicBezierPointsLike, ...]: """Returns the bezier tuples from an array of points. self.points is a list of the anchors and handles of the bezier curves of the mobject (ie [anchor1, handle1, handle2, anchor2, anchor3 ..]) @@ -968,28 +1274,28 @@ def gen_cubic_bezier_tuples_from_points(self, points: np.ndarray) -> typing.Tupl Parameters ---------- - points : np.ndarray + points Points from which control points will be extracted. Returns ------- - typing.Tuple + tuple Bezier control points. """ nppcc = self.n_points_per_cubic_curve remainder = len(points) % nppcc points = points[: len(points) - remainder] # Basically take every nppcc element. - return (points[i : i + nppcc] for i in range(0, len(points), nppcc)) + return tuple(points[i : i + nppcc] for i in range(0, len(points), nppcc)) - def get_cubic_bezier_tuples(self): + def get_cubic_bezier_tuples(self) -> CubicBezierPoints_Array: return self.get_cubic_bezier_tuples_from_points(self.points) def _gen_subpaths_from_points( self, - points: np.ndarray, - filter_func: typing.Callable[[int], bool], - ) -> typing.Tuple: + points: CubicBezierPath, + filter_func: Callable[[int], bool], + ) -> Iterable[CubicSpline]: """Given an array of points defining the bezier curves of the vmobject, return subpaths formed by these points. Here, Two bezier curves form a path if at least two of their anchors are evaluated True by the relation defined by filter_func. @@ -1000,14 +1306,14 @@ def _gen_subpaths_from_points( Parameters ---------- - points : np.ndarray + points points defining the bezier curve. - filter_func : typing.Callable[int, bool] + filter_func Filter-func defining the relation. Returns ------- - typing.Tuple + Iterable[CubicSpline] subpaths formed by the points. """ nppcc = self.n_points_per_cubic_curve @@ -1019,7 +1325,7 @@ def _gen_subpaths_from_points( if (i2 - i1) >= nppcc ) - def get_subpaths_from_points(self, points): + def get_subpaths_from_points(self, points: CubicBezierPath) -> list[CubicSpline]: return list( self._gen_subpaths_from_points( points, @@ -1027,52 +1333,54 @@ def get_subpaths_from_points(self, points): ), ) - def gen_subpaths_from_points_2d(self, points): + def gen_subpaths_from_points_2d( + self, points: CubicBezierPath + ) -> Iterable[CubicSpline]: return self._gen_subpaths_from_points( points, lambda n: not self.consider_points_equals_2d(points[n - 1], points[n]), ) - def get_subpaths(self) -> typing.Tuple: + def get_subpaths(self) -> list[CubicSpline]: """Returns subpaths formed by the curves of the VMobject. Subpaths are ranges of curves with each pair of consecutive curves having their end/start points coincident. Returns ------- - typing.Tuple + list[CubicSpline] subpaths. """ return self.get_subpaths_from_points(self.points) - def get_nth_curve_points(self, n: int) -> np.ndarray: + def get_nth_curve_points(self, n: int) -> CubicBezierPoints: """Returns the points defining the nth curve of the vmobject. Parameters ---------- - n : int + n index of the desired bezier curve. Returns ------- - np.ndarray - points defininf the nth bezier curve (anchors, handles) + CubicBezierPoints + points defining the nth bezier curve (anchors, handles) """ assert n < self.get_num_curves() nppcc = self.n_points_per_cubic_curve return self.points[nppcc * n : nppcc * (n + 1)] - def get_nth_curve_function(self, n: int) -> typing.Callable[[float], np.ndarray]: + def get_nth_curve_function(self, n: int) -> Callable[[float], Point3D]: """Returns the expression of the nth curve. Parameters ---------- - n : int + n index of the desired curve. Returns ------- - typing.Callable[float] + Callable[float, Point3D] expression of the nth bezier curve. """ return bezier(self.get_nth_curve_points(n)) @@ -1080,8 +1388,8 @@ def get_nth_curve_function(self, n: int) -> typing.Callable[[float], np.ndarray] def get_nth_curve_length_pieces( self, n: int, - sample_points: Optional[int] = None, - ) -> np.ndarray: + sample_points: int | None = None, + ) -> npt.NDArray[ManimFloat]: """Returns the array of short line lengths used for length approximation. Parameters @@ -1093,7 +1401,6 @@ def get_nth_curve_length_pieces( Returns ------- - np.ndarray The short length-pieces of the nth curve. """ if sample_points is None: @@ -1102,14 +1409,14 @@ def get_nth_curve_length_pieces( curve = self.get_nth_curve_function(n) points = np.array([curve(a) for a in np.linspace(0, 1, sample_points)]) diffs = points[1:] - points[:-1] - norms = np.apply_along_axis(np.linalg.norm, 1, diffs) + norms = np.linalg.norm(diffs, axis=1) return norms def get_nth_curve_length( self, n: int, - sample_points: Optional[int] = None, + sample_points: int | None = None, ) -> float: """Returns the (approximate) length of the nth curve. @@ -1125,7 +1432,6 @@ def get_nth_curve_length( length : :class:`float` The length of the nth curve. """ - _, length = self.get_nth_curve_function_with_length(n, sample_points) return length @@ -1133,8 +1439,8 @@ def get_nth_curve_length( def get_nth_curve_function_with_length( self, n: int, - sample_points: Optional[int] = None, - ) -> typing.Tuple[typing.Callable[[float], np.ndarray], float]: + sample_points: int | None = None, + ) -> tuple[Callable[[float], Point3D], float]: """Returns the expression of the nth curve along with its (approximate) length. Parameters @@ -1146,12 +1452,11 @@ def get_nth_curve_function_with_length( Returns ------- - curve : typing.Callable[[float], np.ndarray] + curve : Callable[[float], Point3D] The function for the nth curve. length : :class:`float` The length of the nth curve. """ - curve = self.get_nth_curve_function(n) norms = self.get_nth_curve_length_pieces(n, sample_points=sample_points) length = np.sum(norms) @@ -1164,22 +1469,21 @@ def get_num_curves(self) -> int: Returns ------- int - number of curves. of the vmobject. + number of curves of the vmobject. """ nppcc = self.n_points_per_cubic_curve return len(self.points) // nppcc def get_curve_functions( self, - ) -> typing.Iterable[typing.Callable[[float], np.ndarray]]: + ) -> Iterable[Callable[[float], Point3D]]: """Gets the functions for the curves of the mobject. Returns ------- - typing.Iterable[typing.Callable[[float], np.ndarray]] + Iterable[Callable[[float], Point3D]] The functions for the curves. """ - num_curves = self.get_num_curves() for n in range(num_curves): @@ -1187,7 +1491,7 @@ def get_curve_functions( def get_curve_functions_with_lengths( self, **kwargs - ) -> typing.Iterable[typing.Tuple[typing.Callable[[float], np.ndarray], float]]: + ) -> Iterable[tuple[Callable[[float], Point3D], float]]: """Gets the functions and lengths of the curves for the mobject. Parameters @@ -1197,16 +1501,15 @@ def get_curve_functions_with_lengths( Returns ------- - typing.Iterable[typing.Tuple[typing.Callable[[float], np.ndarray], float]] + Iterable[tuple[Callable[[float], Point3D], float]] The functions and lengths of the curves. """ - num_curves = self.get_num_curves() for n in range(num_curves): yield self.get_nth_curve_function_with_length(n, **kwargs) - def point_from_proportion(self, alpha: float) -> np.ndarray: + def point_from_proportion(self, alpha: float) -> Point3D: """Gets the point at a proportion along the path of the :class:`VMobject`. Parameters @@ -1225,8 +1528,23 @@ def point_from_proportion(self, alpha: float) -> np.ndarray: If ``alpha`` is not between 0 and 1. :exc:`Exception` If the :class:`VMobject` has no points. - """ + Example + ------- + .. manim:: PointFromProportion + :save_last_frame: + + class PointFromProportion(Scene): + def construct(self): + line = Line(2*DL, 2*UR) + self.add(line) + colors = (RED, BLUE, YELLOW) + proportions = (1/4, 1/2, 3/4) + for color, proportion in zip(colors, proportions): + self.add(Dot(color=color).move_to( + line.point_from_proportion(proportion) + )) + """ if alpha < 0 or alpha > 1: raise ValueError(f"Alpha {alpha} not between 0 and 1.") @@ -1249,10 +1567,13 @@ def point_from_proportion(self, alpha: float) -> np.ndarray: return curve(residue) current_length += length + raise Exception( + "Not sure how you reached here, please file a bug report at https://github.com/ManimCommunity/manim/issues/new/choose" + ) def proportion_from_point( self, - point: typing.Iterable[typing.Union[float, int]], + point: Point3DLike, ) -> float: """Returns the proportion along the path of the :class:`VMobject` a particular given point is at. @@ -1306,7 +1627,7 @@ def proportion_from_point( return alpha - def get_anchors_and_handles(self) -> typing.Iterable[np.ndarray]: + def get_anchors_and_handles(self) -> list[Point3D_Array]: """Returns anchors1, handles1, handles2, anchors2, where (anchors1[i], handles1[i], handles2[i], anchors2[i]) will be four points defining a cubic bezier curve @@ -1314,52 +1635,55 @@ def get_anchors_and_handles(self) -> typing.Iterable[np.ndarray]: Returns ------- - typing.Iterable[np.ndarray] + `list[Point3D_Array]` Iterable of the anchors and handles. """ nppcc = self.n_points_per_cubic_curve return [self.points[i::nppcc] for i in range(nppcc)] - def get_start_anchors(self) -> np.ndarray: + def get_start_anchors(self) -> Point3D_Array: """Returns the start anchors of the bezier curves. Returns ------- - np.ndarray + Point3D_Array Starting anchors """ - return self.points[0 :: self.n_points_per_cubic_curve] + return self.points[:: self.n_points_per_cubic_curve] - def get_end_anchors(self) -> np.ndarray: - """Return the starting anchors of the bezier curves. + def get_end_anchors(self) -> Point3D_Array: + """Return the end anchors of the bezier curves. Returns ------- - np.ndarray + Point3D_Array Starting anchors """ nppcc = self.n_points_per_cubic_curve return self.points[nppcc - 1 :: nppcc] - def get_anchors(self) -> np.ndarray: + def get_anchors(self) -> list[Point3D]: """Returns the anchors of the curves forming the VMobject. Returns ------- - np.ndarray + Point3D_Array The anchors. """ if self.points.shape[0] == 1: return self.points - return np.array( - list(it.chain(*zip(self.get_start_anchors(), self.get_end_anchors()))), - ) - def get_points_defining_boundary(self): + s = self.get_start_anchors() + e = self.get_end_anchors() + return list(it.chain.from_iterable(zip(s, e))) + + def get_points_defining_boundary(self) -> Point3D_Array: # Probably returns all anchors, but this is weird regarding the name of the method. - return np.array(list(it.chain(*(sm.get_anchors() for sm in self.get_family())))) + return np.array( + tuple(it.chain(*(sm.get_anchors() for sm in self.get_family()))) + ) - def get_arc_length(self, sample_points_per_curve: Optional[int] = None) -> float: + def get_arc_length(self, sample_points_per_curve: int | None = None) -> float: """Return the approximated length of the whole curve. Parameters @@ -1372,7 +1696,6 @@ def get_arc_length(self, sample_points_per_curve: Optional[int] = None) -> float float The length of the :class:`VMobject`. """ - return sum( length for _, length in self.get_curve_functions_with_lengths( @@ -1381,7 +1704,7 @@ def get_arc_length(self, sample_points_per_curve: Optional[int] = None) -> float ) # Alignment - def align_points(self, vmobject: "VMobject"): + def align_points(self, vmobject: VMobject) -> Self: """Adds points to self and vmobject so that they both have the same number of subpaths, with corresponding subpaths each containing the same number of points. @@ -1452,7 +1775,7 @@ def get_nth_subpath(path_list, n): vmobject.set_points(new_path2) return self - def insert_n_curves(self, n: int): + def insert_n_curves(self, n: int) -> Self: """Inserts n curves to the bezier curves of the vmobject. Parameters @@ -1476,62 +1799,33 @@ def insert_n_curves(self, n: int): self.append_points([new_path_point]) return self - def insert_n_curves_to_point_list(self, n: int, points: np.ndarray) -> np.ndarray: + def insert_n_curves_to_point_list( + self, n: int, points: BezierPathLike + ) -> BezierPath: """Given an array of k points defining a bezier curves (anchors and handles), returns points defining exactly k + n bezier curves. Parameters ---------- - n : int + n Number of desired curves. - points : np.ndarray + points Starting points. Returns ------- - np.ndarray Points generated. """ - if len(points) == 1: nppcc = self.n_points_per_cubic_curve return np.repeat(points, nppcc * n, 0) - bezier_quads = self.get_cubic_bezier_tuples_from_points(points) - curr_num = len(bezier_quads) - target_num = curr_num + n - # This is an array with values ranging from 0 - # up to curr_num, with repeats such that - # it's total length is target_num. For example, - # with curr_num = 10, target_num = 15, this would - # be [0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9] - repeat_indices = (np.arange(target_num, dtype="i") * curr_num) // target_num - - # If the nth term of this list is k, it means - # that the nth curve of our path should be split - # into k pieces. - # In the above example our array had the following elements - # [0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9] - # We have two 0s, one 1, two 2s and so on. - # The split factors array would hence be: - # [2, 1, 2, 1, 2, 1, 2, 1, 2, 1] - split_factors = np.zeros(curr_num, dtype="i") - for val in repeat_indices: - split_factors[val] += 1 - - new_points = np.zeros((0, self.dim)) - for quad, sf in zip(bezier_quads, split_factors): - # What was once a single cubic curve defined - # by "quad" will now be broken into sf - # smaller cubic curves - alphas = np.linspace(0, 1, sf + 1) - for a1, a2 in zip(alphas, alphas[1:]): - new_points = np.append( - new_points, - partial_bezier_points(quad, a1, a2), - axis=0, - ) + bezier_tuples = self.get_cubic_bezier_tuples_from_points(points) + current_number_of_curves = len(bezier_tuples) + new_number_of_curves = current_number_of_curves + n + new_bezier_tuples = bezier_remap(bezier_tuples, new_number_of_curves) + new_points = new_bezier_tuples.reshape(-1, 3) return new_points - def align_rgbas(self, vmobject): + def align_rgbas(self, vmobject: VMobject) -> Self: attrs = ["fill_rgbas", "stroke_rgbas", "background_stroke_rgbas"] for attr in attrs: a1 = getattr(self, attr) @@ -1544,14 +1838,16 @@ def align_rgbas(self, vmobject): setattr(self, attr, new_a1) return self - def get_point_mobject(self, center=None): + def get_point_mobject(self, center: Point3DLike | None = None) -> VectorizedPoint: if center is None: center = self.get_center() point = VectorizedPoint(center) point.match_style(self) return point - def interpolate_color(self, mobject1, mobject2, alpha): + def interpolate_color( + self, mobject1: VMobject, mobject2: VMobject, alpha: float + ) -> None: attrs = [ "fill_rgbas", "stroke_rgbas", @@ -1568,71 +1864,105 @@ def interpolate_color(self, mobject1, mobject2, alpha): interpolate(getattr(mobject1, attr), getattr(mobject2, attr), alpha), ) if alpha == 1.0: - setattr(self, attr, getattr(mobject2, attr)) + val = getattr(mobject2, attr) + if isinstance(val, np.ndarray): + val = val.copy() + setattr(self, attr, val) def pointwise_become_partial( self, - vmobject: "VMobject", + vmobject: VMobject, a: float, b: float, - ): - """Given two bounds a and b, transforms the points of the self vmobject into the points of the vmobject - passed as parameter with respect to the bounds. Points here stand for control points of the bezier curves (anchors and handles) + ) -> Self: + """Given a 2nd :class:`.VMobject` ``vmobject``, a lower bound ``a`` and + an upper bound ``b``, modify this :class:`.VMobject`'s points to + match the portion of the Bézier spline described by ``vmobject.points`` + with the parameter ``t`` between ``a`` and ``b``. Parameters ---------- - vmobject : VMobject - The vmobject that will serve as a model. - a : float - upper-bound. - b : float - lower-bound + vmobject + The :class:`.VMobject` that will serve as a model. + a + The lower bound for ``t``. + b + The upper bound for ``t`` Returns ------- - :class:`VMobject` - ``self`` + :class:`.VMobject` + The :class:`.VMobject` itself, after the transformation. + + Raises + ------ + TypeError + If ``vmobject`` is not an instance of :class:`VMobject`. """ - assert isinstance(vmobject, VMobject) + if not isinstance(vmobject, VMobject): + raise TypeError( + f"Expected a VMobject, got value {vmobject} of type " + f"{type(vmobject).__name__}." + ) # Partial curve includes three portions: - # - A middle section, which matches the curve exactly - # - A start, which is some ending portion of an inner cubic - # - An end, which is the starting portion of a later inner cubic + # - A middle section, which matches the curve exactly. + # - A start, which is some ending portion of an inner cubic. + # - An end, which is the starting portion of a later inner cubic. if a <= 0 and b >= 1: self.set_points(vmobject.points) return self - bezier_quads = vmobject.get_cubic_bezier_tuples() - num_cubics = len(bezier_quads) - - # The following two lines will compute which bezier curves of the given mobject need to be processed. - # The residue basically indicates de proportion of the selected bezier curve that have to be selected. - # Ex : if lower_index is 3, and lower_residue is 0.4, then the algorithm will append to the points 0.4 of the third bezier curve - lower_index, lower_residue = integer_interpolate(0, num_cubics, a) - upper_index, upper_residue = integer_interpolate(0, num_cubics, b) - - self.clear_points() - if num_cubics == 0: + num_curves = vmobject.get_num_curves() + if num_curves == 0: + self.clear_points() return self + + # The following two lines will compute which Bézier curves of the given Mobject must be processed. + # The residue indicates the proportion of the selected Bézier curve which must be selected. + # + # Example: if num_curves is 10, a is 0.34 and b is 0.78, then: + # - lower_index is 3 and lower_residue is 0.4, which means the algorithm will look at the 3rd Bézier + # and select its part which ranges from t=0.4 to t=1. + # - upper_index is 7 and upper_residue is 0.8, which means the algorithm will look at the 7th Bézier + # and select its part which ranges from t=0 to t=0.8. + lower_index, lower_residue = integer_interpolate(0, num_curves, a) + upper_index, upper_residue = integer_interpolate(0, num_curves, b) + + nppc = self.n_points_per_curve + # If both indices coincide, get a part of a single Bézier curve. if lower_index == upper_index: - self.append_points( - partial_bezier_points( - bezier_quads[lower_index], - lower_residue, - upper_residue, - ), + # Look at the "lower_index"-th Bézier curve and select its part from + # t=lower_residue to t=upper_residue. + self.points = partial_bezier_points( + vmobject.points[nppc * lower_index : nppc * (lower_index + 1)], + lower_residue, + upper_residue, ) else: - self.append_points( - partial_bezier_points(bezier_quads[lower_index], lower_residue, 1), + # Allocate space for (upper_index-lower_index+1) Bézier curves. + self.points = np.empty((nppc * (upper_index - lower_index + 1), self.dim)) + # Look at the "lower_index"-th Bezier curve and select its part from + # t=lower_residue to t=1. This is the first curve in self.points. + self.points[:nppc] = partial_bezier_points( + vmobject.points[nppc * lower_index : nppc * (lower_index + 1)], + lower_residue, + 1, ) - for quad in bezier_quads[lower_index + 1 : upper_index]: - self.append_points(quad) - self.append_points( - partial_bezier_points(bezier_quads[upper_index], 0, upper_residue), + # If there are more curves between the "lower_index"-th and the + # "upper_index"-th Béziers, add them all to self.points. + self.points[nppc:-nppc] = vmobject.points[ + nppc * (lower_index + 1) : nppc * upper_index + ] + # Look at the "upper_index"-th Bézier curve and select its part from + # t=0 to t=upper_residue. This is the last curve in self.points. + self.points[-nppc:] = partial_bezier_points( + vmobject.points[nppc * upper_index : nppc * (upper_index + 1)], + 0, + upper_residue, ) + return self - def get_subcurve(self, a: float, b: float) -> "VMobject": + def get_subcurve(self, a: float, b: float) -> Self: """Returns the subcurve of the VMobject between the interval [a, b]. The curve is a VMobject itself. @@ -1660,7 +1990,7 @@ def get_subcurve(self, a: float, b: float) -> "VMobject": vmob.pointwise_become_partial(self, a, b) return vmob - def get_direction(self): + def get_direction(self) -> Literal["CW", "CCW"]: """Uses :func:`~.space_ops.shoelace_direction` to calculate the direction. The direction of points determines in which direction the object is drawn, clockwise or counterclockwise. @@ -1680,7 +2010,7 @@ def get_direction(self): """ return shoelace_direction(self.get_start_anchors()) - def reverse_direction(self): + def reverse_direction(self) -> Self: """Reverts the point direction by inverting the point order. Returns @@ -1705,13 +2035,13 @@ def construct(self): self.points = self.points[::-1] return self - def force_direction(self, target_direction): + def force_direction(self, target_direction: Literal["CW", "CCW"]) -> Self: """Makes sure that points are either directed clockwise or counterclockwise. Parameters ---------- - target_direction : :class:`str` + target_direction Either ``"CW"`` or ``"CCW"``. """ if target_direction not in ("CW", "CCW"): @@ -1729,6 +2059,12 @@ class VGroup(VMobject, metaclass=ConvertToOpenGL): This can be used to group multiple :class:`~.VMobject` instances together in order to scale, move, ... them together. + Notes + ----- + When adding the same mobject more than once, repetitions are ignored. + Use :meth:`.Mobject.copy` to create a separate copy which can then + be added to the group. + Examples -------- @@ -1742,19 +2078,21 @@ class VGroup(VMobject, metaclass=ConvertToOpenGL): >>> triangle, square = Triangle(), Square() >>> vg.add(triangle) VGroup(Triangle) - >>> vg + square # a new VGroup is constructed + >>> vg + square # a new VGroup is constructed VGroup(Triangle, Square) - >>> vg # not modified + >>> vg # not modified VGroup(Triangle) - >>> vg += square; vg # modifies vg + >>> vg += square + >>> vg # modifies vg VGroup(Triangle, Square) >>> vg.remove(triangle) VGroup(Square) - >>> vg - square; # a new VGroup is constructed + >>> vg - square # a new VGroup is constructed VGroup() - >>> vg # not modified + >>> vg # not modified VGroup(Square) - >>> vg -= square; vg # modifies vg + >>> vg -= square + >>> vg # modifies vg VGroup() .. manim:: ArcShapeIris @@ -1774,31 +2112,31 @@ def construct(self): """ - def __init__(self, *vmobjects, **kwargs): + def __init__( + self, *vmobjects: VMobject | Iterable[VMobject], **kwargs: Any + ) -> None: super().__init__(**kwargs) self.add(*vmobjects) - def __repr__(self): - return ( - self.__class__.__name__ - + "(" - + ", ".join(str(mob) for mob in self.submobjects) - + ")" - ) + def __repr__(self) -> str: + return f"{self.__class__.__name__}({', '.join(str(mob) for mob in self.submobjects)})" - def __str__(self): + def __str__(self) -> str: return ( f"{self.__class__.__name__} of {len(self.submobjects)} " f"submobject{'s' if len(self.submobjects) > 0 else ''}" ) - def add(self, *vmobjects): - """Checks if all passed elements are an instance of VMobject and then add them to submobjects + def add( + self, + *vmobjects: VMobject | Iterable[VMobject], + ) -> Self: + """Checks if all passed elements are an instance, or iterables of VMobject and then adds them to submobjects Parameters ---------- - vmobjects : :class:`~.VMobject` - List of VMobject to add + vmobjects + List or iterable of VMobjects to add Returns ------- @@ -1807,10 +2145,13 @@ def add(self, *vmobjects): Raises ------ TypeError - If one element of the list is not an instance of VMobject + If one element of the list, or iterable is not an instance of VMobject Examples -------- + The following example shows how to add individual or multiple `VMobject` instances through the `VGroup` + constructor and its `.add()` method. + .. manim:: AddToVGroup class AddToVGroup(Scene): @@ -1839,26 +2180,81 @@ def construct(self): self.play( # Animate group without component (gr-circle_red).animate.shift(RIGHT) ) + + A `VGroup` can be created using iterables as well. Keep in mind that all generated values from an + iterable must be an instance of `VMobject`. This is demonstrated below: + + .. manim:: AddIterableToVGroupExample + :save_last_frame: + + class AddIterableToVGroupExample(Scene): + def construct(self): + v = VGroup( + Square(), # Singular VMobject instance + [Circle(), Triangle()], # List of VMobject instances + Dot(), + (Dot() for _ in range(2)), # Iterable that generates VMobjects + ) + v.arrange() + self.add(v) + + To facilitate this, the iterable is unpacked before its individual instances are added to the `VGroup`. + As a result, when you index a `VGroup`, you will never get back an iterable. + Instead, you will always receive `VMobject` instances, including those + that were part of the iterable/s that you originally added to the `VGroup`. """ - if not all(isinstance(m, (VMobject, OpenGLVMobject)) for m in vmobjects): - raise TypeError("All submobjects must be of type VMobject") - return super().add(*vmobjects) - def __add__(self, vmobject): + def get_type_error_message(invalid_obj, invalid_indices): + return ( + f"Only values of type {vmobject_render_type.__name__} can be added " + "as submobjects of VGroup, but the value " + f"{repr(invalid_obj)} (at index {invalid_indices[1]} of " + f"parameter {invalid_indices[0]}) is of type " + f"{type(invalid_obj).__name__}." + ) + + vmobject_render_type = ( + OpenGLVMobject if config.renderer == RendererType.OPENGL else VMobject + ) + valid_vmobjects = [] + + for i, vmobject in enumerate(vmobjects): + if isinstance(vmobject, vmobject_render_type): + valid_vmobjects.append(vmobject) + elif isinstance(vmobject, Iterable) and not isinstance( + vmobject, (Mobject, OpenGLMobject) + ): + for j, subvmobject in enumerate(vmobject): + if not isinstance(subvmobject, vmobject_render_type): + raise TypeError(get_type_error_message(subvmobject, (i, j))) + valid_vmobjects.append(subvmobject) + elif isinstance(vmobject, Iterable) and isinstance( + vmobject, (Mobject, OpenGLMobject) + ): + raise TypeError( + f"{get_type_error_message(vmobject, (i, 0))} " + "You can try adding this value into a Group instead." + ) + else: + raise TypeError(get_type_error_message(vmobject, (i, 0))) + + return super().add(*valid_vmobjects) + + def __add__(self, vmobject: VMobject) -> Self: return VGroup(*self.submobjects, vmobject) - def __iadd__(self, vmobject): + def __iadd__(self, vmobject: VMobject) -> Self: return self.add(vmobject) - def __sub__(self, vmobject): + def __sub__(self, vmobject: VMobject) -> Self: copy = VGroup(*self.submobjects) copy.remove(vmobject) return copy - def __isub__(self, vmobject): + def __isub__(self, vmobject: VMobject) -> Self: return self.remove(vmobject) - def __setitem__(self, key: int, value: Union[VMobject, typing.Sequence[VMobject]]): + def __setitem__(self, key: int, value: VMobject | Sequence[VMobject]) -> None: """Override the [] operator for item assignment. Parameters @@ -1872,16 +2268,14 @@ def __setitem__(self, key: int, value: Union[VMobject, typing.Sequence[VMobject] ------- None - Examples - -------- - Normal usage:: - + Tests + ----- + Check that item assignment does not raise error:: >>> vgroup = VGroup(VMobject()) >>> new_obj = VMobject() >>> vgroup[0] = new_obj """ - if not all(isinstance(m, (VMobject, OpenGLVMobject)) for m in value): - raise TypeError("All submobjects must be of type VMobject") + self._assert_valid_submobjects(tuplify(value)) self.submobjects[key] = value @@ -1891,14 +2285,14 @@ class VDict(VMobject, metaclass=ConvertToOpenGL): Parameters ---------- - mapping_or_iterable : Union[:class:`Mapping`, Iterable[Tuple[Hashable, :class:`~.VMobject`]]], optional + mapping_or_iterable The parameter specifying the key-value mapping of keys and mobjects. - show_keys : :class:`bool`, optional + show_keys Whether to also display the key associated with the mobject. This might be useful when debugging, especially when there are a lot of mobjects in the :class:`VDict`. Defaults to False. - kwargs : Any + kwargs Other arguments to be passed to `Mobject`. Attributes @@ -1983,16 +2377,28 @@ def construct(self): self.wait() """ - def __init__(self, mapping_or_iterable={}, show_keys=False, **kwargs): + def __init__( + self, + mapping_or_iterable: ( + Mapping[Hashable, VMobject] | Iterable[tuple[Hashable, VMobject]] + ) = {}, + show_keys: bool = False, + **kwargs, + ) -> None: super().__init__(**kwargs) self.show_keys = show_keys self.submob_dict = {} self.add(mapping_or_iterable) - def __repr__(self): - return __class__.__name__ + "(" + repr(self.submob_dict) + ")" + def __repr__(self) -> str: + return f"{self.__class__.__name__}({repr(self.submob_dict)})" - def add(self, mapping_or_iterable): + def add( + self, + mapping_or_iterable: ( + Mapping[Hashable, VMobject] | Iterable[tuple[Hashable, VMobject]] + ), + ) -> Self: """Adds the key-value pairs to the :class:`VDict` object. Also, it internally adds the value to the `submobjects` :class:`list` @@ -2000,7 +2406,7 @@ def add(self, mapping_or_iterable): Parameters --------- - mapping_or_iterable : Union[:class:`Mapping`, Iterable[Tuple[Hashable, :class:`~.VMobject`]]], optional + mapping_or_iterable The parameter specifying the key-value mapping of keys and mobjects. Returns @@ -2013,14 +2419,14 @@ def add(self, mapping_or_iterable): Normal usage:: square_obj = Square() - my_dict.add([('s', square_obj)]) + my_dict.add([("s", square_obj)]) """ for key, value in dict(mapping_or_iterable).items(): self.add_key_value_pair(key, value) return self - def remove(self, key): + def remove(self, key: Hashable) -> Self: """Removes the mobject from the :class:`VDict` object having the key `key` Also, it internally removes the mobject from the `submobjects` :class:`list` @@ -2028,7 +2434,7 @@ def remove(self, key): Parameters ---------- - key : :class:`typing.Hashable` + key The key of the submoject to be removed. Returns @@ -2040,20 +2446,20 @@ def remove(self, key): -------- Normal usage:: - my_dict.remove('square') + my_dict.remove("square") """ if key not in self.submob_dict: - raise KeyError("The given key '%s' is not present in the VDict" % str(key)) + raise KeyError(f"The given key '{key!s}' is not present in the VDict") super().remove(self.submob_dict[key]) del self.submob_dict[key] return self - def __getitem__(self, key): + def __getitem__(self, key: Hashable): """Override the [] operator for item retrieval. Parameters ---------- - key : :class:`typing.Hashable` + key The key of the submoject to be accessed Returns @@ -2065,19 +2471,19 @@ def __getitem__(self, key): -------- Normal usage:: - self.play(Create(my_dict['s'])) + self.play(Create(my_dict["s"])) """ submob = self.submob_dict[key] return submob - def __setitem__(self, key, value): + def __setitem__(self, key: Hashable, value: VMobject) -> None: """Override the [] operator for item assignment. Parameters ---------- - key : :class:`typing.Hashable` + key The key of the submoject to be assigned - value : :class:`VMobject` + value The submobject to bind the key to Returns @@ -2089,18 +2495,18 @@ def __setitem__(self, key, value): Normal usage:: square_obj = Square() - my_dict['sq'] = square_obj + my_dict["sq"] = square_obj """ if key in self.submob_dict: self.remove(key) self.add([(key, value)]) - def __delitem__(self, key): + def __delitem__(self, key: Hashable): """Override the del operator for deleting an item. Parameters ---------- - key : :class:`typing.Hashable` + key The key of the submoject to be deleted Returns @@ -2127,12 +2533,12 @@ def __delitem__(self, key): """ del self.submob_dict[key] - def __contains__(self, key): + def __contains__(self, key: Hashable): """Override the in operator. Parameters ---------- - key : :class:`typing.Hashable` + key The key to check membership of. Returns @@ -2151,7 +2557,7 @@ def __contains__(self, key): """ return key in self.submob_dict - def get_all_submobjects(self): + def get_all_submobjects(self) -> list[list]: """To get all the submobjects associated with a particular :class:`VDict` object Returns @@ -2169,15 +2575,15 @@ def get_all_submobjects(self): submobjects = self.submob_dict.values() return submobjects - def add_key_value_pair(self, key, value): + def add_key_value_pair(self, key: Hashable, value: VMobject) -> None: """A utility function used by :meth:`add` to add the key-value pair to :attr:`submob_dict`. Not really meant to be used externally. Parameters ---------- - key : :class:`typing.Hashable` + key The key of the submobject to be added. - value : :class:`~.VMobject` + value The mobject associated with the key Returns @@ -2194,11 +2600,10 @@ def add_key_value_pair(self, key, value): Normal usage:: square_obj = Square() - self.add_key_value_pair('s', square_obj) + self.add_key_value_pair("s", square_obj) """ - if not isinstance(value, (VMobject, OpenGLVMobject)): - raise TypeError("All submobjects must be of type VMobject") + self._assert_valid_submobjects([value]) mob = value if self.show_keys: # This import is here and not at the top to avoid circular import @@ -2214,14 +2619,14 @@ def add_key_value_pair(self, key, value): class VectorizedPoint(VMobject, metaclass=ConvertToOpenGL): def __init__( self, - location=ORIGIN, - color=BLACK, - fill_opacity=0, - stroke_width=0, - artificial_width=0.01, - artificial_height=0.01, + location: Point3DLike = ORIGIN, + color: ManimColor = BLACK, + fill_opacity: float = 0, + stroke_width: float = 0, + artificial_width: float = 0.01, + artificial_height: float = 0.01, **kwargs, - ): + ) -> None: self.artificial_width = artificial_width self.artificial_height = artificial_height super().__init__( @@ -2232,20 +2637,20 @@ def __init__( ) self.set_points(np.array([location])) - basecls = OpenGLVMobject if config.renderer == "opengl" else VMobject + basecls = OpenGLVMobject if config.renderer == RendererType.OPENGL else VMobject @basecls.width.getter - def width(self): + def width(self) -> float: return self.artificial_width @basecls.height.getter - def height(self): + def height(self) -> float: return self.artificial_height - def get_location(self): + def get_location(self) -> Point3D: return np.array(self.points[0]) - def set_location(self, new_loc): + def set_location(self, new_loc: Point3D): self.set_points(np.array([new_loc])) @@ -2266,7 +2671,7 @@ def construct(self): """ - def __init__(self, vmobject, **kwargs): + def __init__(self, vmobject: VMobject, **kwargs) -> None: super().__init__(**kwargs) tuples = vmobject.get_cubic_bezier_tuples() for tup in tuples: @@ -2275,6 +2680,69 @@ def __init__(self, vmobject, **kwargs): part.match_style(vmobject) self.add(part) + def point_from_proportion(self, alpha: float) -> Point3D: + """Gets the point at a proportion along the path of the :class:`CurvesAsSubmobjects`. + + Parameters + ---------- + alpha + The proportion along the the path of the :class:`CurvesAsSubmobjects`. + + Returns + ------- + :class:`numpy.ndarray` + The point on the :class:`CurvesAsSubmobjects`. + + Raises + ------ + :exc:`ValueError` + If ``alpha`` is not between 0 and 1. + :exc:`Exception` + If the :class:`CurvesAsSubmobjects` has no submobjects, or no submobject has points. + """ + if alpha < 0 or alpha > 1: + raise ValueError(f"Alpha {alpha} not between 0 and 1.") + + self._throw_error_if_no_submobjects() + submobjs_with_pts = self._get_submobjects_with_points() + + if alpha == 1: + return submobjs_with_pts[-1].points[-1] + + submobjs_arc_lengths = tuple( + part.get_arc_length() for part in submobjs_with_pts + ) + + total_length = sum(submobjs_arc_lengths) + target_length = alpha * total_length + current_length = 0 + + for i, part in enumerate(submobjs_with_pts): + part_length = submobjs_arc_lengths[i] + if current_length + part_length >= target_length: + residue = (target_length - current_length) / part_length + return part.point_from_proportion(residue) + + current_length += part_length + + def _throw_error_if_no_submobjects(self): + if len(self.submobjects) == 0: + caller_name = sys._getframe(1).f_code.co_name + raise Exception( + f"Cannot call CurvesAsSubmobjects. {caller_name} for a CurvesAsSubmobject with no submobjects" + ) + + def _get_submobjects_with_points(self): + submobjs_with_pts = tuple( + part for part in self.submobjects if len(part.points) > 0 + ) + if len(submobjs_with_pts) == 0: + caller_name = sys._getframe(1).f_code.co_name + raise Exception( + f"Cannot call CurvesAsSubmobjects. {caller_name} for a CurvesAsSubmobject whose submobjects have no points" + ) + return submobjs_with_pts + class DashedVMobject(VMobject, metaclass=ConvertToOpenGL): """A :class:`VMobject` composed of dashes instead of lines. @@ -2332,15 +2800,14 @@ def construct(self): def __init__( self, - vmobject, - num_dashes=15, - dashed_ratio=0.5, - dash_offset=0, - color=WHITE, - equal_lengths=True, + vmobject: VMobject, + num_dashes: int = 15, + dashed_ratio: float = 0.5, + dash_offset: float = 0, + color: ManimColor = WHITE, + equal_lengths: bool = True, **kwargs, - ): - + ) -> None: self.dashed_ratio = dashed_ratio self.num_dashes = num_dashes super().__init__(color=color, **kwargs) @@ -2352,15 +2819,12 @@ def __init__( if vmobject.is_closed(): void_len = (1 - r) / n else: - if n == 1: - void_len = 1 - r - else: - void_len = (1 - r) / (n - 1) + void_len = 1 - r if n == 1 else (1 - r) / (n - 1) period = dash_len + void_len phase_shift = (dash_offset % 1) * period - if vmobject.is_closed(): + if vmobject.is_closed(): # noqa: SIM108 # closed curves have equal amount of dashes and voids pattern_len = 1 else: @@ -2431,7 +2895,7 @@ def __init__( ) # Family is already taken care of by get_subcurve # implementation - if config.renderer == "opengl": + if config.renderer == RendererType.OPENGL: self.match_style(vmobject, recurse=False) else: self.match_style(vmobject, family=False) diff --git a/manim/mobject/utils.py b/manim/mobject/utils.py new file mode 100644 index 0000000000..b38bb57f2e --- /dev/null +++ b/manim/mobject/utils.py @@ -0,0 +1,107 @@ +"""Utilities for working with mobjects.""" + +from __future__ import annotations + +__all__ = [ + "get_mobject_class", + "get_point_mobject_class", + "get_vectorized_mobject_class", +] + +from .._config import config +from ..constants import RendererType +from .mobject import Mobject +from .opengl.opengl_mobject import OpenGLMobject +from .opengl.opengl_point_cloud_mobject import OpenGLPMobject +from .opengl.opengl_vectorized_mobject import OpenGLVMobject +from .types.point_cloud_mobject import PMobject +from .types.vectorized_mobject import VMobject + + +def get_mobject_class() -> type: + """Gets the base mobject class, depending on the currently active renderer. + + .. NOTE:: + + This method is intended to be used in the code base of Manim itself + or in plugins where code should work independent of the selected + renderer. + + Examples + -------- + + The function has to be explicitly imported. We test that + the name of the returned class is one of the known mobject + base classes:: + + >>> from manim.mobject.utils import get_mobject_class + >>> get_mobject_class().__name__ in ['Mobject', 'OpenGLMobject'] + True + """ + if config.renderer == RendererType.CAIRO: + return Mobject + if config.renderer == RendererType.OPENGL: + return OpenGLMobject + raise NotImplementedError( + "Base mobjects are not implemented for the active renderer." + ) + + +def get_vectorized_mobject_class() -> type: + """Gets the vectorized mobject class, depending on the currently + active renderer. + + .. NOTE:: + + This method is intended to be used in the code base of Manim itself + or in plugins where code should work independent of the selected + renderer. + + Examples + -------- + + The function has to be explicitly imported. We test that + the name of the returned class is one of the known mobject + base classes:: + + >>> from manim.mobject.utils import get_vectorized_mobject_class + >>> get_vectorized_mobject_class().__name__ in ['VMobject', 'OpenGLVMobject'] + True + """ + if config.renderer == RendererType.CAIRO: + return VMobject + if config.renderer == RendererType.OPENGL: + return OpenGLVMobject + raise NotImplementedError( + "Vectorized mobjects are not implemented for the active renderer." + ) + + +def get_point_mobject_class() -> type: + """Gets the point cloud mobject class, depending on the currently + active renderer. + + .. NOTE:: + + This method is intended to be used in the code base of Manim itself + or in plugins where code should work independent of the selected + renderer. + + Examples + -------- + + The function has to be explicitly imported. We test that + the name of the returned class is one of the known mobject + base classes:: + + >>> from manim.mobject.utils import get_point_mobject_class + >>> get_point_mobject_class().__name__ in ['PMobject', 'OpenGLPMobject'] + True + """ + if config.renderer == RendererType.CAIRO: + return PMobject + if config.renderer == RendererType.OPENGL: + return OpenGLPMobject + raise NotImplementedError( + "Point cloud mobjects are not implemented for the active renderer." + ) diff --git a/manim/mobject/value_tracker.py b/manim/mobject/value_tracker.py index b60d89887e..9d81035e89 100644 --- a/manim/mobject/value_tracker.py +++ b/manim/mobject/value_tracker.py @@ -45,7 +45,7 @@ def construct(self): self.wait(1) tracker -= 4 self.wait(0.5) - self.play(tracker.animate.set_value(5)), + self.play(tracker.animate.set_value(5)) self.wait(0.5) self.play(tracker.animate.set_value(3)) self.play(tracker.animate.increment_value(-2)) @@ -71,7 +71,7 @@ def construct(self): def __init__(self, value=0, **kwargs): super().__init__(**kwargs) - self.set_points(np.zeros((1, 3))) + self.set(points=np.zeros((1, 3))) self.set_value(value) def get_value(self) -> float: @@ -132,7 +132,7 @@ def interpolate(self, mobject1, mobject2, alpha, path_func=straight_path()): Turns self into an interpolation between mobject1 and mobject2. """ - self.set_points(path_func(mobject1.points, mobject2.points, alpha)) + self.set(points=path_func(mobject1.points, mobject2.points, alpha)) return self @@ -165,7 +165,8 @@ def get_value(self): """Get the current value of this value tracker as a complex number. The value is internally stored as a points array [a, b, 0]. This can be accessed directly - to represent the value geometrically, see the usage example.""" + to represent the value geometrically, see the usage example. + """ return complex(*self.points[0, :2]) def set_value(self, z): diff --git a/manim/mobject/vector_field.py b/manim/mobject/vector_field.py index 2c09edcb3c..28f5c6d26f 100644 --- a/manim/mobject/vector_field.py +++ b/manim/mobject/vector_field.py @@ -10,26 +10,36 @@ import itertools as it import random +from collections.abc import Iterable, Sequence from math import ceil, floor -from typing import Callable, Iterable, Sequence +from typing import Callable import numpy as np -from colour import Color from PIL import Image from manim.animation.updaters.update import UpdateFromAlphaFunc from manim.mobject.geometry.line import Vector -from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject +from manim.mobject.graphing.coordinate_systems import CoordinateSystem from .. import config from ..animation.composition import AnimationGroup, Succession from ..animation.creation import Create from ..animation.indication import ShowPassingFlash -from ..constants import OUT, RIGHT, UP +from ..constants import OUT, RIGHT, UP, RendererType from ..mobject.mobject import Mobject -from ..mobject.types.vectorized_mobject import VGroup, VMobject +from ..mobject.types.vectorized_mobject import VGroup +from ..mobject.utils import get_vectorized_mobject_class from ..utils.bezier import interpolate, inverse_interpolate -from ..utils.color import BLUE_E, GREEN, RED, YELLOW, color_to_rgb, rgb_to_color +from ..utils.color import ( + BLUE_E, + GREEN, + RED, + YELLOW, + ManimColor, + ParsableManimColor, + color_to_rgb, + rgb_to_color, +) from ..utils.rate_functions import ease_out_sine, linear from ..utils.simple_functions import sigmoid @@ -57,7 +67,7 @@ class VectorField(VGroup): The value of the color_scheme function to be mapped to the last color in `colors`. Higher values also result in the last color of the gradient. colors The colors defining the color gradient of the vector field. - kwargs : Any + kwargs Additional arguments to be passed to the :class:`~.VGroup` constructor """ @@ -65,11 +75,11 @@ class VectorField(VGroup): def __init__( self, func: Callable[[np.ndarray], np.ndarray], - color: Color | None = None, + color: ParsableManimColor | None = None, color_scheme: Callable[[np.ndarray], float] | None = None, min_color_scheme_value: float = 0, max_color_scheme_value: float = 2, - colors: Sequence[Color] = DEFAULT_SCALAR_FIELD_COLORS, + colors: Sequence[ParsableManimColor] = DEFAULT_SCALAR_FIELD_COLORS, **kwargs, ): super().__init__(**kwargs) @@ -106,7 +116,7 @@ def pos_to_rgb(pos: np.ndarray) -> tuple[float, float, float, float]: self.pos_to_color = lambda pos: rgb_to_color(self.pos_to_rgb(pos)) else: self.single_color = True - self.color = color + self.color = ManimColor.parse(color) self.submob_movement_updater = None @staticmethod @@ -142,7 +152,7 @@ def scale_func( ---------- func The function defining a vector field. - shift_vector + scalar The scalar to be applied to the vector field. Examples @@ -168,6 +178,22 @@ def construct(self): """ return lambda p: func(p * scalar) + def fit_to_coordinate_system(self, coordinate_system: CoordinateSystem): + """Scale the vector field to fit a coordinate system. + + This method is useful when the vector field is defined in a coordinate system + different from the one used to display the vector field. + + This method can only be used once because it transforms the origin of each vector. + + Parameters + ---------- + coordinate_system + The coordinate system to fit the vector field to. + + """ + self.apply_function(lambda pos: coordinate_system.coords_to_point(*pos)) + def nudge( self, mob: Mobject, @@ -327,7 +353,6 @@ def start_submobject_movement( This vector field. """ - self.stop_submobject_movement() self.submob_movement_updater = lambda mob, dt: mob.nudge_submobjects( dt * speed, @@ -392,7 +417,7 @@ def get_vectorized_rgba_gradient_function( self, start: float, end: float, - colors: Iterable, + colors: Iterable[ParsableManimColor], ): """ Generates a gradient of rgbas as a numpy array @@ -469,7 +494,7 @@ class ArrowVectorField(VectorField): The opacity of the arrows. vector_config Additional arguments to be passed to the :class:`~.Vector` constructor - kwargs : Any + kwargs Additional arguments to be passed to the :class:`~.VGroup` constructor Examples @@ -516,11 +541,11 @@ def construct(self): def __init__( self, func: Callable[[np.ndarray], np.ndarray], - color: Color | None = None, + color: ParsableManimColor | None = None, color_scheme: Callable[[np.ndarray], float] | None = None, min_color_scheme_value: float = 0, max_color_scheme_value: float = 2, - colors: Sequence[Color] = DEFAULT_SCALAR_FIELD_COLORS, + colors: Sequence[ParsableManimColor] = DEFAULT_SCALAR_FIELD_COLORS, # Determining Vector positions: x_range: Sequence[float] = None, y_range: Sequence[float] = None, @@ -575,8 +600,12 @@ def __init__( x_range = np.arange(*self.x_range) y_range = np.arange(*self.y_range) z_range = np.arange(*self.z_range) - for x, y, z in it.product(x_range, y_range, z_range): - self.add(self.get_vector(x * RIGHT + y * UP + z * OUT)) + self.add( + *[ + self.get_vector(x * RIGHT + y * UP + z * OUT) + for x, y, z in it.product(x_range, y_range, z_range) + ] + ) self.set_opacity(self.opacity) def get_vector(self, point: np.ndarray): @@ -590,8 +619,6 @@ def get_vector(self, point: np.ndarray): ---------- point The root point of the vector. - kwargs : Any - Additional arguments to be passed to the :class:`~.Vector` constructor """ output = np.array(self.func(point)) @@ -688,11 +715,11 @@ def construct(self): def __init__( self, func: Callable[[np.ndarray], np.ndarray], - color: Color | None = None, + color: ParsableManimColor | None = None, color_scheme: Callable[[np.ndarray], float] | None = None, min_color_scheme_value: float = 0, max_color_scheme_value: float = 2, - colors: Sequence[Color] = DEFAULT_SCALAR_FIELD_COLORS, + colors: Sequence[ParsableManimColor] = DEFAULT_SCALAR_FIELD_COLORS, # Determining stream line starting positions: x_range: Sequence[float] = None, y_range: Sequence[float] = None, @@ -780,7 +807,7 @@ def outside_box(p): max_steps = ceil(virtual_time / dt) + 1 if not self.single_color: self.background_img = self.get_colored_background_image() - if config["renderer"] == "opengl": + if config["renderer"] == RendererType.OPENGL: self.values_to_rgbas = self.get_vectorized_rgba_gradient_function( min_color_scheme_value, max_color_scheme_value, @@ -797,17 +824,16 @@ def outside_box(p): step = max_steps if not step: continue - if config["renderer"] == "opengl": - line = OpenGLVMobject() - else: - line = VMobject() + line = get_vectorized_mobject_class()() line.duration = step * dt step = max(1, int(len(points) / self.max_anchors_per_line)) line.set_points_smoothly(points[::step]) if self.single_color: - line.set_stroke(self.color) + line.set_stroke( + color=self.color, width=self.stroke_width, opacity=opacity + ) else: - if config["renderer"] == "opengl": + if config.renderer == RendererType.OPENGL: # scaled for compatibility with cairo line.set_stroke(width=self.stroke_width / 4.0) norms = np.array( @@ -886,7 +912,7 @@ def construct(self): def start_animation( self, - warm_up=True, + warm_up: bool = True, flow_speed: float = 1, time_width: float = 0.3, rate_func: Callable[[float], float] = linear, @@ -899,7 +925,7 @@ def start_animation( Parameters ---------- - warm_up : bool, optional + warm_up If `True` the animation is initialized line by line. Otherwise it starts with all lines shown. flow_speed At `flow_speed=1` the distance the flow moves per second is equal to the magnitude of the vector field along its path. The speed value scales the speed of this flow. @@ -924,7 +950,6 @@ def construct(self): self.wait(stream_lines.virtual_time / stream_lines.flow_speed) """ - for line in self.stream_lines: run_time = line.duration / flow_speed line.anim = line_animation_class( @@ -984,7 +1009,6 @@ def construct(self): self.play(stream_lines.end_animation()) """ - if self.flow_animation is None: raise ValueError("You have to start the animation before fading it out.") diff --git a/manim/opengl/__init__.py b/manim/opengl/__init__.py index 85d583086a..e5bad5cd2c 100644 --- a/manim/opengl/__init__.py +++ b/manim/opengl/__init__.py @@ -1,12 +1,13 @@ from __future__ import annotations -try: +import contextlib + +with contextlib.suppress(ImportError): from dearpygui import dearpygui as dpg -except ImportError: - pass from manim.mobject.opengl.dot_cloud import * +from manim.mobject.opengl.opengl_image_mobject import * from manim.mobject.opengl.opengl_mobject import * from manim.mobject.opengl.opengl_point_cloud_mobject import * from manim.mobject.opengl.opengl_surface import * diff --git a/manim/plugins/__init__.py b/manim/plugins/__init__.py index a899f63bb8..d6f82f0923 100644 --- a/manim/plugins/__init__.py +++ b/manim/plugins/__init__.py @@ -1,3 +1,16 @@ from __future__ import annotations -from .import_plugins import * +from manim._config import config, logger +from manim.plugins.plugins_flags import get_plugins, list_plugins + +__all__ = [ + "get_plugins", + "list_plugins", +] + +requested_plugins: set[str] = set(config["plugins"]) +missing_plugins = requested_plugins - set(get_plugins().keys()) + + +if missing_plugins: + logger.warning("Missing Plugins: %s", missing_plugins) diff --git a/manim/plugins/import_plugins.py b/manim/plugins/import_plugins.py deleted file mode 100644 index 8cbb7f5644..0000000000 --- a/manim/plugins/import_plugins.py +++ /dev/null @@ -1,43 +0,0 @@ -from __future__ import annotations - -import types - -import pkg_resources - -from .. import config, logger - -__all__ = [] - - -plugins_requested: list = config["plugins"] -if "" in plugins_requested: - plugins_requested.remove("") -for plugin in pkg_resources.iter_entry_points("manim.plugins"): - if plugin.name not in plugins_requested: - continue - loaded_plugin = plugin.load() - if isinstance(loaded_plugin, types.ModuleType): - # it is a module so it can't be called - # see if __all__ is defined - # if it is defined use that to load all the modules necessary - # essentially this would be similar to `from plugin import *`` - # if not just import the module with the plugin name - if hasattr(loaded_plugin, "__all__"): - for thing in loaded_plugin.__all__: # type: ignore - exec(f"{thing}=loaded_plugin.{thing}") - __all__.append(thing) - else: - exec(f"{plugin.name}=loaded_plugin") - __all__.append(plugin.name) - elif isinstance(loaded_plugin, types.FunctionType): - # call the function first - # it will return a list of modules to add globally - # finally add it - lists = loaded_plugin() - for lst in lists: - exec(f"{lst.__name__}=lst") - __all__.append(lst.__name__) - plugins_requested.remove(plugin.name) - -if plugins_requested != []: - logger.warning("Missing Plugins: %s", plugins_requested) diff --git a/manim/plugins/plugins_flags.py b/manim/plugins/plugins_flags.py index 44b0dce7fc..3080b6256a 100644 --- a/manim/plugins/plugins_flags.py +++ b/manim/plugins/plugins_flags.py @@ -1,30 +1,31 @@ -""" -plugins_flags.py ------------- - -Plugin Managing Utility. -""" +"""Plugin Managing Utility""" from __future__ import annotations -import pkg_resources +import sys +from typing import Any + +if sys.version_info < (3, 10): + from importlib_metadata import entry_points +else: + from importlib.metadata import entry_points -from manim import console +from manim._config import console __all__ = ["list_plugins"] -def get_plugins(): - plugins = { +def get_plugins() -> dict[str, Any]: + plugins: dict[str, Any] = { entry_point.name: entry_point.load() - for entry_point in pkg_resources.iter_entry_points("manim.plugins") + for entry_point in entry_points(group="manim.plugins") } return plugins -def list_plugins(): +def list_plugins() -> None: console.print("[green bold]Plugins:[/green bold]", justify="left") plugins = get_plugins() - for plugin in plugins: - console.print(f" • {plugin}") + for plugin_name in plugins: + console.print(f" • {plugin_name}") diff --git a/manim/renderer/cairo_renderer.py b/manim/renderer/cairo_renderer.py index c47e17909f..7efd7b022f 100644 --- a/manim/renderer/cairo_renderer.py +++ b/manim/renderer/cairo_renderer.py @@ -1,7 +1,6 @@ from __future__ import annotations import typing -from typing import Any import numpy as np @@ -9,11 +8,21 @@ from .. import config, logger from ..camera.camera import Camera -from ..mobject.mobject import Mobject +from ..mobject.mobject import Mobject, _AnimationBuilder from ..scene.scene_file_writer import SceneFileWriter from ..utils.exceptions import EndSceneEarlyException from ..utils.iterables import list_update +if typing.TYPE_CHECKING: + from typing import Any + + from manim.animation.animation import Animation + from manim.scene.scene import Scene + + from ..typing import PixelArray + +__all__ = ["CairoRenderer"] + class CairoRenderer: """A renderer using Cairo. @@ -48,7 +57,12 @@ def init_scene(self, scene): scene.__class__.__name__, ) - def play(self, scene, *args, **kwargs): + def play( + self, + scene: Scene, + *args: Animation | Mobject | _AnimationBuilder, + **kwargs, + ): # Reset skip_animations to the original state. # Needed when rendering only some animations, and skipping others. self.skip_animations = self._original_skipping_status @@ -90,7 +104,7 @@ def play(self, scene, *args, **kwargs): scene.begin_animations() # Save a static image, to avoid rendering non moving objects. - self.static_image = self.save_static_frame_data(scene, scene.static_mobjects) + self.save_static_frame_data(scene, scene.static_mobjects) if scene.is_current_animation_frozen_frame(): self.update_frame(scene, mobjects=scene.moving_mobjects) @@ -106,24 +120,23 @@ def play(self, scene, *args, **kwargs): def update_frame( # TODO Description in Docstring self, scene, - mobjects=None, - include_submobjects=True, - ignore_skipping=True, + mobjects: typing.Iterable[Mobject] | None = None, + include_submobjects: bool = True, + ignore_skipping: bool = True, **kwargs, ): """Update the frame. Parameters ---------- - mobjects: list, optional - list of mobjects + scene - background: np.ndarray, optional - Pixel Array for Background. + mobjects + list of mobjects - include_submobjects: bool, optional + include_submobjects - ignore_skipping : bool, optional + ignore_skipping **kwargs @@ -147,7 +160,7 @@ def render(self, scene, time, moving_mobjects): self.update_frame(scene, moving_mobjects) self.add_frame(self.get_frame()) - def get_frame(self): + def get_frame(self) -> PixelArray: """ Gets the current frame as NumPy array. @@ -159,30 +172,29 @@ def get_frame(self): """ return np.array(self.camera.pixel_array) - def add_frame(self, frame, num_frames=1): + def add_frame(self, frame: np.ndarray, num_frames: int = 1): """ Adds a frame to the video_file_stream Parameters ---------- - frame : numpy.ndarray + frame The frame to add, as a pixel array. - num_frames: int + num_frames The number of times to add frame. """ dt = 1 / self.camera.frame_rate if self.skip_animations: return self.time += num_frames * dt - for _ in range(num_frames): - self.file_writer.write_frame(frame) + self.file_writer.write_frame(frame, num_frames=num_frames) def freeze_current_frame(self, duration: float): """Adds a static frame to the movie for a given duration. The static frame is the current frame. Parameters ---------- - duration : float + duration [description] """ dt = 1 / self.camera.frame_rate @@ -201,23 +213,23 @@ def show_frame(self): def save_static_frame_data( self, - scene, + scene: Scene, static_mobjects: typing.Iterable[Mobject], ) -> typing.Iterable[Mobject] | None: - """Compute and save the static frame, that will be reused at each frame to avoid to unecesseraly computer - static mobjects. + """Compute and save the static frame, that will be reused at each frame + to avoid unnecessarily computing static mobjects. Parameters ---------- - scene : Scene + scene The scene played. - static_mobjects : typing.Iterable[Mobject] + static_mobjects Static mobjects of the scene. If None, self.static_image is set to None Returns ------- typing.Iterable[Mobject] - the static image computed. + The static image computed. """ self.static_image = None if not static_mobjects: @@ -240,13 +252,13 @@ def update_skipping_status(self): if config["save_last_frame"]: self.skip_animations = True if ( - config["from_animation_number"] - and self.num_plays < config["from_animation_number"] + config.from_animation_number > 0 + and self.num_plays < config.from_animation_number ): self.skip_animations = True if ( - config["upto_animation_number"] - and self.num_plays > config["upto_animation_number"] + config.upto_animation_number >= 0 + and self.num_plays > config.upto_animation_number ): self.skip_animations = True raise EndSceneEarlyException() diff --git a/manim/renderer/opengl_renderer.py b/manim/renderer/opengl_renderer.py index 3490ac2c0d..7d4b6a4467 100644 --- a/manim/renderer/opengl_renderer.py +++ b/manim/renderer/opengl_renderer.py @@ -1,15 +1,11 @@ from __future__ import annotations +import contextlib import itertools as it -import sys import time +from functools import cached_property from typing import Any -if sys.version_info < (3, 8): - from backports.cached_property import cached_property -else: - from functools import cached_property - import moderngl import numpy as np from PIL import Image @@ -39,6 +35,8 @@ render_opengl_vectorized_mobject_stroke, ) +__all__ = ["OpenGLCamera", "OpenGLRenderer"] + class OpenGLCamera(OpenGLMobject): euler_angles = _Data() @@ -65,12 +63,12 @@ def __init__( if self.orthographic: self.projection_matrix = opengl.orthographic_projection_matrix() self.unformatted_projection_matrix = opengl.orthographic_projection_matrix( - format=False, + format_=False, ) else: self.projection_matrix = opengl.perspective_projection_matrix() self.unformatted_projection_matrix = opengl.perspective_projection_matrix( - format=False, + format_=False, ) if frame_shape is None: @@ -217,17 +215,12 @@ def interpolate(self, *args, **kwargs): self.refresh_rotation_matrix() -points_per_curve = 3 -JOINT_TYPE_MAP = { - "auto": 0, - "round": 1, - "bevel": 2, - "miter": 3, -} - - class OpenGLRenderer: - def __init__(self, file_writer_class=SceneFileWriter, skip_animations=False): + def __init__( + self, + file_writer_class: type[SceneFileWriter] = SceneFileWriter, + skip_animations: bool = False, + ) -> None: # Measured in pixel widths, used for vector graphics self.anti_alias_width = 1.5 self._file_writer_class = file_writer_class @@ -246,7 +239,7 @@ def __init__(self, file_writer_class=SceneFileWriter, skip_animations=False): # Initialize texture map. self.path_to_texture_id = {} - self._background_color = color_to_rgba(config["background_color"], 1.0) + self.background_color = config["background_color"] def init_scene(self, scene): self.partial_movie_files = [] @@ -255,6 +248,7 @@ def init_scene(self, scene): scene.__class__.__name__, ) self.scene = scene + self.background_color = config["background_color"] if not hasattr(self, "window"): if self.should_create_window(): from .opengl_renderer_window import Window @@ -347,10 +341,8 @@ def render_mobject(self, mobject): shader_wrapper.uniforms.items(), self.perspective_uniforms.items(), ): - try: + with contextlib.suppress(KeyError): shader.set_uniform(name, value) - except KeyError: - pass try: shader.set_uniform( "u_view_matrix", self.scene.camera.formatted_view_matrix @@ -380,20 +372,23 @@ def render_mobject(self, mobject): mesh.render() def get_texture_id(self, path): - if path not in self.path_to_texture_id: - # A way to increase tid's sequentially + if repr(path) not in self.path_to_texture_id: tid = len(self.path_to_texture_id) - im = Image.open(path) texture = self.context.texture( - size=im.size, - components=len(im.getbands()), - data=im.tobytes(), + size=path.size, + components=len(path.getbands()), + data=path.tobytes(), ) + texture.repeat_x = False + texture.repeat_y = False + texture.filter = (moderngl.NEAREST, moderngl.NEAREST) + texture.swizzle = "RRR1" if path.mode == "L" else "RGBA" texture.use(location=tid) - self.path_to_texture_id[path] = tid - return self.path_to_texture_id[path] + self.path_to_texture_id[repr(path)] = tid - def update_skipping_status(self): + return self.path_to_texture_id[repr(path)] + + def update_skipping_status(self) -> None: """ This method is used internally to check if the current animation needs to be skipped or not. It also checks if @@ -405,13 +400,13 @@ def update_skipping_status(self): if self.file_writer.sections[-1].skip_animations: self.skip_animations = True if ( - config["from_animation_number"] - and self.num_plays < config["from_animation_number"] + config.from_animation_number > 0 + and self.num_plays < config.from_animation_number ): self.skip_animations = True if ( - config["upto_animation_number"] - and self.num_plays > config["upto_animation_number"] + config.upto_animation_number >= 0 + and self.num_plays > config.upto_animation_number ): self.skip_animations = True raise EndSceneEarlyException() @@ -428,8 +423,9 @@ def play(self, scene, *args, **kwargs): self.update_frame(scene) if not self.skip_animations: - for _ in range(int(config.frame_rate * scene.duration)): - self.file_writer.write_frame(self) + self.file_writer.write_frame( + self, num_frames=int(config.frame_rate * scene.duration) + ) if self.window is not None: self.window.swap_buffers() @@ -575,7 +571,7 @@ def pixel_coords_to_space_coords(self, px, py, relative=False, top_left=False): if pixel_shape is None: return np.array([0, 0, 0]) pw, ph = pixel_shape - fw, fh = config["frame_width"], config["frame_height"] + fh = config["frame_height"] fc = self.camera.get_center() if relative: return 2 * np.array([px / pw, py / ph, 0]) diff --git a/manim/renderer/opengl_renderer_window.py b/manim/renderer/opengl_renderer_window.py index 14d913899c..610f61646b 100644 --- a/manim/renderer/opengl_renderer_window.py +++ b/manim/renderer/opengl_renderer_window.py @@ -7,6 +7,8 @@ from .. import __version__, config +__all__ = ["Window"] + class Window(PygletWindow): fullscreen = False diff --git a/manim/renderer/shader.py b/manim/renderer/shader.py index ce40a701ff..a098ed30ca 100644 --- a/manim/renderer/shader.py +++ b/manim/renderer/shader.py @@ -1,6 +1,7 @@ from __future__ import annotations -import os +import contextlib +import inspect import re import textwrap from pathlib import Path @@ -10,7 +11,6 @@ from .. import config from ..utils import opengl -from ..utils.simple_functions import get_parameters SHADER_FOLDER = Path(__file__).parent / "shaders" shader_program_cache: dict = {} @@ -24,24 +24,23 @@ ] -def get_shader_code_from_file(file_path): +def get_shader_code_from_file(file_path: Path) -> str: if file_path in file_path_to_code_map: return file_path_to_code_map[file_path] - with open(file_path) as f: - source = f.read() - include_lines = re.finditer( - r"^#include (?P.*\.glsl)$", - source, - flags=re.MULTILINE, + source = file_path.read_text() + include_lines = re.finditer( + r"^#include (?P.*\.glsl)$", + source, + flags=re.MULTILINE, + ) + for match in include_lines: + include_path = match.group("include_path") + included_code = get_shader_code_from_file( + file_path.parent / include_path, ) - for match in include_lines: - include_path = match.group("include_path") - included_code = get_shader_code_from_file( - os.path.join(file_path.parent / include_path), - ) - source = source.replace(match.group(0), included_code) - file_path_to_code_map[file_path] = source - return source + source = source.replace(match.group(0), included_code) + file_path_to_code_map[file_path] = source + return source def filter_attributes(unfiltered_attributes, attributes): @@ -201,7 +200,7 @@ def get_updaters(self): return self.time_based_updaters + self.non_time_updaters def add_updater(self, update_function, index=None, call_updater=True): - if "dt" in get_parameters(update_function): + if "dt" in inspect.signature(update_function).parameters: updater_list = self.time_based_updaters else: updater_list = self.non_time_updaters @@ -314,7 +313,7 @@ def render(self): else: self.shader.context.disable(moderngl.DEPTH_TEST) - from moderngl.program_members.attribute import Attribute + from moderngl import Attribute shader_attributes = [] for k, v in self.shader.shader_program._members.items(): @@ -384,10 +383,8 @@ def __init__( shader_program_cache[self.name] = self.shader_program def set_uniform(self, name, value): - try: + with contextlib.suppress(KeyError): self.shader_program[name] = value - except KeyError: - pass class FullScreenQuad(Mesh): diff --git a/manim/renderer/shader_wrapper.py b/manim/renderer/shader_wrapper.py index 9fe87f3c53..8a2b0d1fbe 100644 --- a/manim/renderer/shader_wrapper.py +++ b/manim/renderer/shader_wrapper.py @@ -1,33 +1,35 @@ from __future__ import annotations import copy -import os +import logging import re from pathlib import Path import moderngl import numpy as np -from .. import logger - # Mobjects that should be rendered with # the same shader will be organized and # clumped together based on keeping track # of a dict holding all the relevant information # to that shader +__all__ = ["ShaderWrapper"] + +logger = logging.getLogger("manim") + def get_shader_dir(): return Path(__file__).parent / "shaders" -def find_file(file_name, directories=None): +def find_file(file_name: Path, directories: list[Path]) -> Path: # Check if what was passed in is already a valid path to a file - if os.path.exists(file_name): + if file_name.exists(): return file_name - possible_paths = (os.path.join(directory, file_name) for directory in directories) + possible_paths = (directory / file_name for directory in directories) for path in possible_paths: - if os.path.exists(path): + if path.exists(): return path else: logger.debug(f"{path} does not exist.") @@ -48,7 +50,7 @@ def __init__( self.vert_data = vert_data self.vert_indices = vert_indices self.vert_attributes = vert_data.dtype.names - self.shader_folder = shader_folder + self.shader_folder = Path(shader_folder or "") self.uniforms = uniforms or {} self.texture_paths = texture_paths or {} self.depth_test = depth_test @@ -110,9 +112,9 @@ def create_program_id(self): ) def init_program_code(self): - def get_code(name): + def get_code(name: str) -> str | None: return get_shader_code_from_file( - os.path.join(self.shader_folder, f"{name}.glsl"), + self.shader_folder / f"{name}.glsl", ) self.program_code = { @@ -126,7 +128,7 @@ def get_program_code(self): def replace_code(self, old, new): code_map = self.program_code - for (name, _code) in code_map.items(): + for name, _code in code_map.items(): if code_map[name] is None: continue code_map[name] = re.sub(old, new, code_map[name]) @@ -157,22 +159,19 @@ def combine_with(self, *shader_wrappers): filename_to_code_map: dict = {} -def get_shader_code_from_file(filename): - if not filename: - return None +def get_shader_code_from_file(filename: Path) -> str | None: if filename in filename_to_code_map: return filename_to_code_map[filename] try: filepath = find_file( filename, - directories=[get_shader_dir(), "/"], + directories=[get_shader_dir(), Path("/")], ) except OSError: return None - with open(filepath) as f: - result = f.read() + result = filepath.read_text() # To share functionality between shaders, some functions are read in # from other files an inserted into the relevant strings before @@ -185,8 +184,10 @@ def get_shader_code_from_file(filename): ) for line in insertions: inserted_code = get_shader_code_from_file( - os.path.join("include", line.replace("#include ../include/", "")), + Path() / "include" / line.replace("#include ../include/", ""), ) + if inserted_code is None: + return None result = result.replace(line, inserted_code) filename_to_code_map[filename] = result return result diff --git a/manim/renderer/vectorized_mobject_rendering.py b/manim/renderer/vectorized_mobject_rendering.py index 4cfd582d20..4245d65b0e 100644 --- a/manim/renderer/vectorized_mobject_rendering.py +++ b/manim/renderer/vectorized_mobject_rendering.py @@ -8,6 +8,11 @@ from ..utils.space_ops import cross2d, earclip_triangulation from .shader import Shader +__all__ = [ + "render_opengl_vectorized_mobject_fill", + "render_opengl_vectorized_mobject_stroke", +] + def build_matrix_lists(mob): root_hierarchical_matrix = mob.hierarchical_model_matrix() diff --git a/manim/renderer/webgl_renderer.py b/manim/renderer/webgl_renderer.py deleted file mode 100644 index 72501b1d74..0000000000 --- a/manim/renderer/webgl_renderer.py +++ /dev/null @@ -1,67 +0,0 @@ -from __future__ import annotations - -import copy - -from manim import config - -from ..utils.family import extract_mobject_family_members - - -class WebGLRenderer: - def __init__(self, frame_server): - self.skip_animations = True - self.frame_server = frame_server - self.camera = WebGLCamera() - self.num_plays = 0 - - def init_scene(self, scene): - pass - - def scene_finished(self, scene): - pass - - def play(self, scene, *args, **kwargs): - self.num_plays += 1 - # If the scene contains an updater it must be updated frame by frame. - for mob in extract_mobject_family_members(scene.mobjects): - if len(mob.updaters) > 0: - self.skip_animations = False - break - s = scene.compile_animation_data(*args, skip_rendering=True, **kwargs) - scene.begin_animations() - self.skip_animations = True - - scene_copy = copy.deepcopy(scene) - scene_copy.renderer = self - self.frame_server.keyframes.append(scene_copy) - if s is None: - # Nothing happens in this animation, so there's no need to update it. - scene_copy.is_static = True - else: - scene_copy.is_static = False - scene.play_internal(skip_rendering=True) - - def update_frame( # TODO Description in Docstring - self, - scene, - mobjects=None, - include_submobjects=True, - ignore_skipping=True, - **kwargs, - ): - pass - - def save_static_frame_data(self, scene, static_mobjects): - pass - - def add_frame(self, frame, num_frames=1): - pass - - def get_frame(self): - pass - - -class WebGLCamera: - def __init__(self, use_z_index=True): - self.use_z_index = use_z_index - self.frame_rate = config["frame_rate"] diff --git a/manim/scene/moving_camera_scene.py b/manim/scene/moving_camera_scene.py index f68ca45865..eafc992ef5 100644 --- a/manim/scene/moving_camera_scene.py +++ b/manim/scene/moving_camera_scene.py @@ -64,12 +64,33 @@ def construct(self): self.play(Restore(self.camera.frame)) self.wait() +.. manim:: SlidingMultipleScenes + + class SlidingMultipleScenes(MovingCameraScene): + def construct(self): + def create_scene(number): + frame = Rectangle(width=16,height=9) + circ = Circle().shift(LEFT) + text = Tex(f"This is Scene {str(number)}").next_to(circ, RIGHT) + frame.add(circ,text) + return frame + + group = VGroup(*(create_scene(i) for i in range(4))).arrange_in_grid(buff=4) + self.add(group) + self.camera.auto_zoom(group[0], animate=False) + for scene in group: + self.play(self.camera.auto_zoom(scene)) + self.wait() + + self.play(self.camera.auto_zoom(group, margin=2)) """ from __future__ import annotations __all__ = ["MovingCameraScene"] +from manim.animation.animation import Animation + from ..camera.moving_camera import MovingCamera from ..scene.scene import Scene from ..utils.family import extract_mobject_family_members @@ -81,22 +102,26 @@ class MovingCameraScene(Scene): This is a Scene, with special configurations and properties that make it suitable for cases where the camera must be moved around. + Note: Examples are included in the moving_camera_scene module + documentation, see below in the 'see also' section. + .. SEEALSO:: + :mod:`.moving_camera_scene` :class:`.MovingCamera` """ def __init__(self, camera_class=MovingCamera, **kwargs): super().__init__(camera_class=camera_class, **kwargs) - def get_moving_mobjects(self, *animations): + def get_moving_mobjects(self, *animations: Animation): """ This method returns a list of all of the Mobjects in the Scene that are moving, that are also in the animations passed. Parameters ---------- - *animations : Animation + *animations The Animations whose mobjects will be checked. """ moving_mobjects = super().get_moving_mobjects(*animations) diff --git a/manim/scene/scene.py b/manim/scene/scene.py index 2fc4add87e..fc3d3ede54 100644 --- a/manim/scene/scene.py +++ b/manim/scene/scene.py @@ -2,6 +2,8 @@ from __future__ import annotations +from manim.utils.parameter_parsing import flatten_iterable_parameters + __all__ = ["Scene"] import copy @@ -13,7 +15,6 @@ import time import types from queue import Queue -from typing import Callable import srt @@ -25,11 +26,14 @@ dearpygui_imported = True except ImportError: dearpygui_imported = False +from typing import TYPE_CHECKING + import numpy as np from tqdm import tqdm from watchdog.events import FileSystemEventHandler from watchdog.observers import Observer +from manim.mobject.mobject import Mobject from manim.mobject.opengl.opengl_mobject import OpenGLPoint from .. import config, logger @@ -47,6 +51,12 @@ from ..utils.file_ops import open_media_file from ..utils.iterables import list_difference_update, list_update +if TYPE_CHECKING: + from collections.abc import Sequence + from typing import Callable + + from manim.mobject.mobject import _AnimationBuilder + class RerunSceneHandler(FileSystemEventHandler): """A class to handle rerunning a Scene after the input file is modified.""" @@ -92,12 +102,12 @@ def construct(self): def __init__( self, - renderer=None, - camera_class=Camera, - always_update_mobjects=False, - random_seed=None, - skip_animations=False, - ): + renderer: CairoRenderer | OpenGLRenderer | None = None, + camera_class: type[Camera] = Camera, + always_update_mobjects: bool = False, + random_seed: int | None = None, + skip_animations: bool = False, + ) -> None: self.camera_class = camera_class self.always_update_mobjects = always_update_mobjects self.random_seed = random_seed @@ -123,7 +133,7 @@ def __init__( self.mouse_press_callbacks = [] self.interactive_mode = False - if config.renderer == "opengl": + if config.renderer == RendererType.OPENGL: # Items associated with interaction self.mouse_point = OpenGLPoint() self.mouse_drag_point = OpenGLPoint() @@ -150,6 +160,11 @@ def __init__( def camera(self): return self.renderer.camera + @property + def time(self) -> float: + """The time since the start of the scene.""" + return self.renderer.time + def __deepcopy__(self, clone_from_id): cls = self.__class__ result = cls.__new__(cls) @@ -208,13 +223,13 @@ def __deepcopy__(self, clone_from_id): result.mobject_updater_lists.append((mobject_clone, cloned_updaters)) return result - def render(self, preview=False): + def render(self, preview: bool = False): """ Renders this Scene. Parameters --------- - preview : bool + preview If true, opens scene in a file viewer. """ self.setup() @@ -222,7 +237,7 @@ def render(self, preview=False): self.construct() except EndSceneEarlyException: pass - except RerunSceneException as e: + except RerunSceneException: self.remove(*self.mobjects) self.renderer.clear_screen() self.renderer.num_plays = 0 @@ -280,7 +295,7 @@ def construct(self): Examples -------- A typical manim script includes a class derived from :class:`Scene` with an - overridden :meth:`Scene.contruct` method: + overridden :meth:`Scene.construct` method: .. code-block:: python @@ -300,25 +315,25 @@ def construct(self): def next_section( self, name: str = "unnamed", - type: str = DefaultSectionType.NORMAL, + section_type: str = DefaultSectionType.NORMAL, skip_animations: bool = False, ) -> None: """Create separation here; the last section gets finished and a new one gets created. ``skip_animations`` skips the rendering of all animations in this section. - Refer to :doc:`the documentation` on how to use sections. + Refer to :doc:`the documentation` on how to use sections. """ - self.renderer.file_writer.next_section(name, type, skip_animations) + self.renderer.file_writer.next_section(name, section_type, skip_animations) def __str__(self): return self.__class__.__name__ - def get_attrs(self, *keys): + def get_attrs(self, *keys: str): """ Gets attributes of a scene given the attribute's identifier/name. Parameters ---------- - *keys : str + *keys Name(s) of the argument(s) to return the attribute of. Returns @@ -328,13 +343,13 @@ def get_attrs(self, *keys): """ return [getattr(self, key) for key in keys] - def update_mobjects(self, dt): + def update_mobjects(self, dt: float): """ Begins updating all mobjects in the Scene. Parameters ---------- - dt: int or float + dt Change in time between updates. Defaults (mostly) to 1/frames_per_second """ for mobject in self.mobjects: @@ -345,7 +360,22 @@ def update_meshes(self, dt): for mesh in obj.get_family(): mesh.update(dt) - def update_self(self, dt): + def update_self(self, dt: float): + """Run all scene updater functions. + + Among all types of update functions (mobject updaters, mesh updaters, + scene updaters), scene update functions are called last. + + Parameters + ---------- + dt + Scene time since last update. + + See Also + -------- + :meth:`.Scene.add_updater` + :meth:`.Scene.remove_updater` + """ for func in self.updaters: func(dt) @@ -367,11 +397,10 @@ def should_update_mobjects(self) -> bool: should_update = ( self.always_update_mobjects or self.updaters + or wait_animation.stop_condition is not None or any( - [ - mob.has_time_based_updater() - for mob in self.get_mobject_family_members() - ], + mob.has_time_based_updater() + for mob in self.get_mobject_family_members() ) ) wait_animation.is_static_wait = not should_update @@ -408,25 +437,25 @@ def get_mobject_family_members(self): list List of mobject family members. """ - if config.renderer == "opengl": + if config.renderer == RendererType.OPENGL: family_members = [] for mob in self.mobjects: family_members.extend(mob.get_family()) return family_members - else: + elif config.renderer == RendererType.CAIRO: return extract_mobject_family_members( self.mobjects, use_z_index=self.renderer.camera.use_z_index, ) - def add(self, *mobjects): + def add(self, *mobjects: Mobject): """ Mobjects will be displayed, from background to foreground in the order with which they are added. Parameters --------- - *mobjects : Mobject + *mobjects Mobjects to add. Returns @@ -435,7 +464,7 @@ def add(self, *mobjects): The same scene after adding the Mobjects in. """ - if config.renderer == "opengl": + if config.renderer == RendererType.OPENGL: new_mobjects = [] new_meshes = [] for mobject_or_mesh in mobjects: @@ -447,7 +476,7 @@ def add(self, *mobjects): self.mobjects += new_mobjects self.remove(*new_meshes) self.meshes += new_meshes - else: + elif config.renderer == RendererType.CAIRO: mobjects = [*mobjects, *self.foreground_mobjects] self.restructure_mobjects(to_remove=mobjects) self.mobjects += mobjects @@ -459,7 +488,7 @@ def add(self, *mobjects): self.moving_mobjects += mobjects return self - def add_mobjects_from_animations(self, animations): + def add_mobjects_from_animations(self, animations: list[Animation]) -> None: curr_mobjects = self.get_mobject_family_members() for animation in animations: if animation.is_introducer(): @@ -471,7 +500,7 @@ def add_mobjects_from_animations(self, animations): self.add(mob) curr_mobjects += mob.get_family() - def remove(self, *mobjects): + def remove(self, *mobjects: Mobject): """ Removes mobjects in the passed list of mobjects from the scene and the foreground, by removing them @@ -479,10 +508,10 @@ def remove(self, *mobjects): Parameters ---------- - *mobjects : Mobject + *mobjects The mobjects to remove. """ - if config.renderer == "opengl": + if config.renderer == RendererType.OPENGL: mobjects_to_remove = [] meshes_to_remove = set() for mobject_or_mesh in mobjects: @@ -498,22 +527,109 @@ def remove(self, *mobjects): filter(lambda mesh: mesh not in set(meshes_to_remove), self.meshes), ) return self - else: + elif config.renderer == RendererType.CAIRO: for list_name in "mobjects", "foreground_mobjects": self.restructure_mobjects(mobjects, list_name, False) return self - def add_updater(self, func): + def replace(self, old_mobject: Mobject, new_mobject: Mobject) -> None: + """Replace one mobject in the scene with another, preserving draw order. + + If ``old_mobject`` is a submobject of some other Mobject (e.g. a + :class:`.Group`), the new_mobject will replace it inside the group, + without otherwise changing the parent mobject. + + Parameters + ---------- + old_mobject + The mobject to be replaced. Must be present in the scene. + new_mobject + A mobject which must not already be in the scene. + + """ + if old_mobject is None or new_mobject is None: + raise ValueError("Specified mobjects cannot be None") + + def replace_in_list( + mobj_list: list[Mobject], old_m: Mobject, new_m: Mobject + ) -> bool: + # We use breadth-first search because some Mobjects get very deep and + # we expect top-level elements to be the most common targets for replace. + for i in range(0, len(mobj_list)): + # Is this the old mobject? + if mobj_list[i] == old_m: + # If so, write the new object to the same spot and stop looking. + mobj_list[i] = new_m + return True + # Now check all the children of all these mobs. + for mob in mobj_list: # noqa: SIM110 + if replace_in_list(mob.submobjects, old_m, new_m): + # If we found it in a submobject, stop looking. + return True + # If we did not find the mobject in the mobject list or any submobjects, + # (or the list was empty), indicate we did not make the replacement. + return False + + # Make use of short-circuiting conditionals to check mobjects and then + # foreground_mobjects + replaced = replace_in_list( + self.mobjects, old_mobject, new_mobject + ) or replace_in_list(self.foreground_mobjects, old_mobject, new_mobject) + + if not replaced: + raise ValueError(f"Could not find {old_mobject} in scene") + + def add_updater(self, func: Callable[[float], None]) -> None: + """Add an update function to the scene. + + The scene updater functions are run every frame, + and they are the last type of updaters to run. + + .. WARNING:: + + When using the Cairo renderer, scene updaters that + modify mobjects are not detected in the same way + that mobject updaters are. To be more concrete, + a mobject only modified via a scene updater will + not necessarily be added to the list of *moving + mobjects* and thus might not be updated every frame. + + TL;DR: Use mobject updaters to update mobjects. + + Parameters + ---------- + func + The updater function. It takes a float, which is the + time difference since the last update (usually equal + to the frame rate). + + See also + -------- + :meth:`.Scene.remove_updater` + :meth:`.Scene.update_self` + """ self.updaters.append(func) - def remove_updater(self, func): + def remove_updater(self, func: Callable[[float], None]) -> None: + """Remove an update function from the scene. + + Parameters + ---------- + func + The updater function to be removed. + + See also + -------- + :meth:`.Scene.add_updater` + :meth:`.Scene.update_self` + """ self.updaters = [f for f in self.updaters if f is not func] def restructure_mobjects( self, - to_remove, - mobject_list_name="mobjects", - extract_families=True, + to_remove: Sequence[Mobject], + mobject_list_name: str = "mobjects", + extract_families: bool = True, ): """ tl:wr @@ -528,13 +644,13 @@ def restructure_mobjects( Parameters ---------- - to_remove : Mobject + to_remove The Mobject to remove. - mobject_list_name : str, optional + mobject_list_name The list of mobjects ("mobjects", "foreground_mobjects" etc) to remove from. - extract_families : bool, optional + extract_families Whether the mobject's families should be recursively extracted. Returns @@ -552,7 +668,7 @@ def restructure_mobjects( setattr(self, mobject_list_name, new_list) return self - def get_restructured_mobject_list(self, mobjects, to_remove): + def get_restructured_mobject_list(self, mobjects: list, to_remove: list): """ Given a list of mobjects and a list of mobjects to be removed, this filters out the removable mobjects from the list of mobjects. @@ -560,10 +676,10 @@ def get_restructured_mobject_list(self, mobjects, to_remove): Parameters ---------- - mobjects : list + mobjects The Mobjects to check. - to_remove : list + to_remove The list of mobjects to remove. Returns @@ -571,7 +687,6 @@ def get_restructured_mobject_list(self, mobjects, to_remove): list The list of mobjects with the mobjects to remove removed. """ - new_mobjects = [] def add_safe_mobjects_from_list(list_to_examine, set_to_remove): @@ -588,14 +703,14 @@ def add_safe_mobjects_from_list(list_to_examine, set_to_remove): return new_mobjects # TODO, remove this, and calls to this - def add_foreground_mobjects(self, *mobjects): + def add_foreground_mobjects(self, *mobjects: Mobject): """ Adds mobjects to the foreground, and internally to the list foreground_mobjects, and mobjects. Parameters ---------- - *mobjects : Mobject + *mobjects The Mobjects to add to the foreground. Returns @@ -607,14 +722,14 @@ def add_foreground_mobjects(self, *mobjects): self.add(*mobjects) return self - def add_foreground_mobject(self, mobject): + def add_foreground_mobject(self, mobject: Mobject): """ Adds a single mobject to the foreground, and internally to the list foreground_mobjects, and mobjects. Parameters ---------- - mobject : Mobject + mobject The Mobject to add to the foreground. Returns @@ -624,14 +739,14 @@ def add_foreground_mobject(self, mobject): """ return self.add_foreground_mobjects(mobject) - def remove_foreground_mobjects(self, *to_remove): + def remove_foreground_mobjects(self, *to_remove: Mobject): """ Removes mobjects from the foreground, and internally from the list foreground_mobjects. Parameters ---------- - *to_remove : Mobject + *to_remove The mobject(s) to remove from the foreground. Returns @@ -642,14 +757,14 @@ def remove_foreground_mobjects(self, *to_remove): self.restructure_mobjects(to_remove, "foreground_mobjects") return self - def remove_foreground_mobject(self, mobject): + def remove_foreground_mobject(self, mobject: Mobject): """ Removes a single mobject from the foreground, and internally from the list foreground_mobjects. Parameters ---------- - mobject : Mobject + mobject The mobject to remove from the foreground. Returns @@ -659,14 +774,14 @@ def remove_foreground_mobject(self, mobject): """ return self.remove_foreground_mobjects(mobject) - def bring_to_front(self, *mobjects): + def bring_to_front(self, *mobjects: Mobject): """ Adds the passed mobjects to the scene again, pushing them to he front of the scene. Parameters ---------- - *mobjects : Mobject + *mobjects The mobject(s) to bring to the front of the scene. Returns @@ -678,14 +793,14 @@ def bring_to_front(self, *mobjects): self.add(*mobjects) return self - def bring_to_back(self, *mobjects): + def bring_to_back(self, *mobjects: Mobject): """ Removes the mobject from the scene and adds them to the back of the scene. Parameters ---------- - *mobjects : Mobject + *mobjects The mobject(s) to push to the back of the scene. Returns @@ -714,13 +829,13 @@ def clear(self): self.foreground_mobjects = [] return self - def get_moving_mobjects(self, *animations): + def get_moving_mobjects(self, *animations: Animation): """ Gets all moving mobjects in the passed animation(s). Parameters ---------- - *animations : Animation + *animations The animations to check for moving mobjects. Returns @@ -763,14 +878,18 @@ def get_moving_and_static_mobjects(self, animations): ) return all_moving_mobject_families, static_mobjects - def compile_animations(self, *args, **kwargs): + def compile_animations( + self, + *args: Animation | Mobject | _AnimationBuilder, + **kwargs, + ): """ Creates _MethodAnimations from any _AnimationBuilders and updates animation kwargs with kwargs passed to play(). Parameters ---------- - *args : Tuple[:class:`Animation`] + *args Animations to be played. **kwargs Configuration for the call to play(). @@ -781,19 +900,21 @@ def compile_animations(self, *args, **kwargs): Animations to be played. """ animations = [] - for arg in args: + arg_anims = flatten_iterable_parameters(args) + # Allow passing a generator to self.play instead of comma separated arguments + for arg in arg_anims: try: animations.append(prepare_animation(arg)) - except TypeError: + except TypeError as e: if inspect.ismethod(arg): raise TypeError( "Passing Mobject methods to Scene.play is no longer" " supported. Use Mobject.animate instead.", - ) + ) from e else: raise TypeError( f"Unexpected argument {arg} passed to Scene.play().", - ) + ) from e for animation in animations: for k, v in kwargs.items(): @@ -801,7 +922,9 @@ def compile_animations(self, *args, **kwargs): return animations - def _get_animation_time_progression(self, animations, duration): + def _get_animation_time_progression( + self, animations: list[Animation], duration: float + ): """ You will hardly use this when making your own animations. This method is for Manim's internal use. @@ -812,11 +935,11 @@ def _get_animation_time_progression(self, animations, duration): Parameters ---------- - animations : List[:class:`~.Animation`, ...] + animations The list of animations to get the time progression for. - duration : int or float + duration duration of wait time Returns @@ -853,10 +976,10 @@ def _get_animation_time_progression(self, animations, duration): def get_time_progression( self, - run_time, + run_time: float, description, - n_iterations=None, - override_skip_animations=False, + n_iterations: int | None = None, + override_skip_animations: bool = False, ): """ You will hardly use this when making your own animations. @@ -870,13 +993,13 @@ def get_time_progression( Parameters ---------- - run_time : float + run_time The ``run_time`` of the animation. - n_iterations : int, optional + n_iterations The number of iterations in the animation. - override_skip_animations : bool, optional + override_skip_animations Whether or not to show skipped animations in the progress bar. Returns @@ -899,13 +1022,42 @@ def get_time_progression( ) return time_progression - def get_run_time(self, animations): + @classmethod + def validate_run_time( + cls, + run_time: float, + method: Callable[[Any, ...], Any], + parameter_name: str = "run_time", + ) -> float: + method_name = f"{cls.__name__}.{method.__name__}()" + if run_time <= 0: + raise ValueError( + f"{method_name} has a {parameter_name} of " + f"{run_time:g} <= 0 seconds which Manim cannot render. " + f"The {parameter_name} must be a positive number." + ) + + # config.frame_rate holds the number of frames per second + fps = config.frame_rate + seconds_per_frame = 1 / fps + if run_time < seconds_per_frame: + logger.warning( + f"The original {parameter_name} of {method_name}, " + f"{run_time:g} seconds, is too short for the current frame " + f"rate of {fps:g} FPS. Rendering with the shortest possible " + f"{parameter_name} of {seconds_per_frame:g} seconds instead." + ) + run_time = seconds_per_frame + + return run_time + + def get_run_time(self, animations: list[Animation]): """ Gets the total run time for a list of animations. Parameters ---------- - animations : List[:class:`Animation`, ...] + animations A list of the animations whose total ``run_time`` is to be calculated. @@ -914,19 +1066,13 @@ def get_run_time(self, animations): float The total ``run_time`` of all of the animations in the list. """ - - if len(animations) == 1 and isinstance(animations[0], Wait): - if animations[0].stop_condition is not None: - return 0 - else: - return animations[0].duration - - else: - return np.max([animation.run_time for animation in animations]) + run_time = max(animation.run_time for animation in animations) + run_time = self.validate_run_time(run_time, self.play, "total run_time") + return run_time def play( self, - *args, + *args: Animation | Mobject | _AnimationBuilder, subcaption=None, subcaption_duration=None, subcaption_offset=0, @@ -953,15 +1099,37 @@ def play( All other keywords are passed to the renderer. """ - start_time = self.renderer.time + # If we are in interactive embedded mode, make sure this is running on the main thread (required for OpenGL) + if ( + self.interactive_mode + and config.renderer == RendererType.OPENGL + and threading.current_thread().name != "MainThread" + ): + kwargs.update( + { + "subcaption": subcaption, + "subcaption_duration": subcaption_duration, + "subcaption_offset": subcaption_offset, + } + ) + self.queue.put( + ( + "play", + args, + kwargs, + ) + ) + return + + start_time = self.time self.renderer.play(self, *args, **kwargs) - run_time = self.renderer.time - start_time + run_time = self.time - start_time if subcaption: if subcaption_duration is None: subcaption_duration = run_time # The start of the subcaption needs to be offset by the # run_time of the animation because it is added after - # the animation has already been played (and Scene.renderer.time + # the animation has already been played (and Scene.time # has already been updated). self.add_subcaption( content=subcaption, @@ -984,7 +1152,8 @@ def wait( stop_condition A function without positional arguments that is evaluated every time a frame is rendered. The animation only stops when the return value - of the function is truthy. Overrides any value passed to ``duration``. + of the function is truthy, or when the time specified in ``duration`` + passes. frozen_frame If True, updater functions are not evaluated, and the animation outputs a frozen frame. If False, updater functions are called and frames @@ -995,6 +1164,7 @@ def wait( -------- :class:`.Wait`, :meth:`.should_mobjects_update` """ + duration = self.validate_run_time(duration, self.wait, "duration") self.play( Wait( run_time=duration, @@ -1018,25 +1188,28 @@ def pause(self, duration: float = DEFAULT_WAIT_TIME): -------- :meth:`.wait`, :class:`.Wait` """ + duration = self.validate_run_time(duration, self.pause, "duration") self.wait(duration=duration, frozen_frame=True) - def wait_until(self, stop_condition, max_time=60): - """ - Like a wrapper for wait(). - You pass a function that determines whether to continue waiting, - and a max wait time if that is never fulfilled. + def wait_until(self, stop_condition: Callable[[], bool], max_time: float = 60): + """Wait until a condition is satisfied, up to a given maximum duration. Parameters ---------- - stop_condition : function - The function whose boolean return value determines whether to continue waiting - - max_time : int or float, optional - The maximum wait time in seconds, if the stop_condition is never fulfilled. + stop_condition + A function with no arguments that determines whether or not the + scene should keep waiting. + max_time + The maximum wait time in seconds. """ + max_time = self.validate_run_time(max_time, self.wait_until, "max_time") self.wait(max_time, stop_condition=stop_condition) - def compile_animation_data(self, *animations: Animation, **play_kwargs): + def compile_animation_data( + self, + *animations: Animation | Mobject | _AnimationBuilder, + **play_kwargs, + ): """Given a list of animations, compile the corresponding static and moving mobjects, and gather the animation durations. @@ -1044,8 +1217,11 @@ def compile_animation_data(self, *animations: Animation, **play_kwargs): Parameters ---------- - skip_rendering : bool, optional - Whether the rendering should be skipped, by default False + animations + Animation or mobject with mobject method and params + play_kwargs + Named parameters affecting what was passed in ``animations``, + e.g. ``run_time``, ``lag_ratio`` and so on. Returns ------- @@ -1065,16 +1241,16 @@ def compile_animation_data(self, *animations: Animation, **play_kwargs): self.moving_mobjects = [] self.static_mobjects = [] + self.duration = self.get_run_time(self.animations) if len(self.animations) == 1 and isinstance(self.animations[0], Wait): if self.should_update_mobjects(): self.update_mobjects(dt=0) # Any problems with this? self.stop_condition = self.animations[0].stop_condition else: - self.duration = self.animations[0].duration # Static image logic when the wait is static is done by the renderer, not here. self.animations[0].is_static_wait = True return None - self.duration = self.get_run_time(self.animations) + return self def begin_animations(self) -> None: @@ -1083,7 +1259,7 @@ def begin_animations(self) -> None: animation._setup_scene(self) animation.begin() - if config.renderer != "opengl": + if config.renderer == RendererType.CAIRO: # Paint all non-moving objects onto the screen, so they don't # have to be rendered every frame ( @@ -1099,7 +1275,7 @@ def is_current_animation_frozen_frame(self) -> bool: and self.animations[0].is_static_wait ) - def play_internal(self, skip_rendering=False): + def play_internal(self, skip_rendering: bool = False): """ This method is used to prep the animations for rendering, apply the arguments and parameters required to them, @@ -1107,11 +1283,8 @@ def play_internal(self, skip_rendering=False): Parameters ---------- - args - Animation or mobject with mobject method and params - kwargs - named parameters affecting what was passed in ``args``, - e.g. ``run_time``, ``lag_ratio`` and so on. + skip_rendering + Whether the rendering should be skipped, by default False """ self.duration = self.get_run_time(self.animations) self.time_progression = self._get_animation_time_progression( @@ -1161,9 +1334,7 @@ def check_interactive_embed_is_valid(self): return True def interactive_embed(self): - """ - Like embed(), but allows for screen interaction. - """ + """Like embed(), but allows for screen interaction.""" if not self.check_interactive_embed_is_valid(): return self.interactive_mode = True @@ -1196,12 +1367,20 @@ def get_embedded_method(method_name): # Allow for calling scene methods without prepending 'self.'. local_namespace[method] = embedded_method + from sqlite3 import connect + + from IPython.core.getipython import get_ipython from IPython.terminal.embed import InteractiveShellEmbed from traitlets.config import Config cfg = Config() cfg.TerminalInteractiveShell.confirm_exit = False - shell = InteractiveShellEmbed(config=cfg) + if get_ipython() is None: + shell = InteractiveShellEmbed.instance(config=cfg) + else: + shell = InteractiveShellEmbed(config=cfg) + hist = get_ipython().history_manager + hist.db = connect(hist.hist_file, check_same_thread=False) keyboard_thread = threading.Thread( target=ipython, @@ -1363,7 +1542,7 @@ def add_subcaption( r"""Adds an entry in the corresponding subcaption file at the current time stamp. - The current time stamp is obtained from ``Scene.renderer.time``. + The current time stamp is obtained from ``Scene.time``. Parameters ---------- @@ -1393,37 +1572,43 @@ def construct(self): # second option: within the call to Scene.play self.play( - Transform(square, circle), - subcaption="The square transforms." + Transform(square, circle), subcaption="The square transforms." ) """ subtitle = srt.Subtitle( index=len(self.renderer.file_writer.subcaptions), content=content, - start=datetime.timedelta(seconds=self.renderer.time + offset), - end=datetime.timedelta(seconds=self.renderer.time + offset + duration), + start=datetime.timedelta(seconds=float(self.time + offset)), + end=datetime.timedelta(seconds=float(self.time + offset + duration)), ) self.renderer.file_writer.subcaptions.append(subtitle) - def add_sound(self, sound_file, time_offset=0, gain=None, **kwargs): + def add_sound( + self, + sound_file: str, + time_offset: float = 0, + gain: float | None = None, + **kwargs, + ): """ This method is used to add a sound to the animation. Parameters ---------- - sound_file : str + sound_file The path to the sound file. - time_offset : int,float, optional + time_offset The offset in the sound file after which the sound can be played. - gain : float + gain Amplification of the sound. Examples -------- .. manim:: SoundExample + :no_autoplay: class SoundExample(Scene): # Source of sound under Creative Commons 0 License. https://freesound.org/people/Druminfected/sounds/250551/ @@ -1443,7 +1628,7 @@ def construct(self): """ if self.renderer.skip_animations: return - time = self.renderer.time + time_offset + time = self.time + time_offset self.renderer.file_writer.add_sound(sound_file, time, gain, **kwargs) def on_mouse_motion(self, point, d_point): diff --git a/manim/scene/scene_file_writer.py b/manim/scene/scene_file_writer.py index b1010aefd3..d256afb736 100644 --- a/manim/scene/scene_file_writer.py +++ b/manim/scene/scene_file_writer.py @@ -5,34 +5,74 @@ __all__ = ["SceneFileWriter"] import json -import os import shutil -import subprocess +from fractions import Fraction from pathlib import Path -from typing import Any +from queue import Queue +from tempfile import NamedTemporaryFile +from threading import Thread +from typing import TYPE_CHECKING, Any +import av import numpy as np import srt from PIL import Image from pydub import AudioSegment from manim import __version__ +from manim.typing import PixelArray, StrPath from .. import config, logger -from ..constants import FFMPEG_BIN, GIF_FILE_EXTENSION +from .._config.logger_utils import set_file_logger +from ..constants import RendererType from ..utils.file_ops import ( add_extension_if_not_present, add_version_before_extension, guarantee_existence, is_gif_format, is_png_format, - is_webm_format, modify_atime, write_to_movie, ) from ..utils.sounds import get_full_sound_file_path from .section import DefaultSectionType, Section +if TYPE_CHECKING: + from manim.renderer.cairo_renderer import CairoRenderer + from manim.renderer.opengl_renderer import OpenGLRenderer + + +def to_av_frame_rate(fps): + epsilon1 = 1e-4 + epsilon2 = 0.02 + + if isinstance(fps, int): + (num, denom) = (fps, 1) + elif abs(fps - round(fps)) < epsilon1: + (num, denom) = (round(fps), 1) + else: + denom = 1001 + num = round(fps * denom / 1000) * 1000 + if abs(fps - num / denom) >= epsilon2: + raise ValueError("invalid frame rate") + + return Fraction(num, denom) + + +def convert_audio(input_path: Path, output_path: Path, codec_name: str): + with ( + av.open(input_path) as input_audio, + av.open(output_path, "w") as output_audio, + ): + input_audio_stream = input_audio.streams.audio[0] + output_audio_stream = output_audio.add_stream(codec_name) + for frame in input_audio.decode(input_audio_stream): + for packet in output_audio_stream.encode(frame): + output_audio.mux(packet) + + for packet in output_audio_stream.encode(): + output_audio.mux(packet) + class SceneFileWriter: """ @@ -47,7 +87,7 @@ class SceneFileWriter: sections : list of :class:`.Section` used to segment scene - sections_output_dir : str + sections_output_dir : :class:`pathlib.Path` where are section videos stored output_name : str @@ -65,7 +105,12 @@ class SceneFileWriter: force_output_as_scene_name = False - def __init__(self, renderer, scene_name, **kwargs): + def __init__( + self, + renderer: CairoRenderer | OpenGLRenderer, + scene_name: StrPath, + **kwargs: Any, + ) -> None: self.renderer = renderer self.init_output_directories(scene_name) self.init_audio() @@ -76,10 +121,10 @@ def __init__(self, renderer, scene_name, **kwargs): # first section gets automatically created for convenience # if you need the first section to be skipped, add a first section by hand, it will replace this one self.next_section( - name="autocreated", type=DefaultSectionType.NORMAL, skip_animations=False + name="autocreated", type_=DefaultSectionType.NORMAL, skip_animations=False ) - def init_output_directories(self, scene_name): + def init_output_directories(self, scene_name: StrPath) -> None: """Initialise output directories. Notes @@ -92,10 +137,7 @@ def init_output_directories(self, scene_name): if config["dry_run"]: # in dry-run mode there is no output return - if config["input_file"]: - module_name = config.get_dir("input_file").stem - else: - module_name = "" + module_name = config.get_dir("input_file").stem if config["input_file"] else "" if SceneFileWriter.force_output_as_scene_name: self.output_name = Path(scene_name) @@ -110,9 +152,8 @@ def init_output_directories(self, scene_name): "images_dir", module_name=module_name, scene_name=scene_name ), ) - self.image_file_path = os.path.join( - image_dir, - add_extension_if_not_present(self.output_name, ".png"), + self.image_file_path = image_dir / add_extension_if_not_present( + self.output_name, ".png" ) if write_to_movie(): @@ -121,16 +162,12 @@ def init_output_directories(self, scene_name): "video_dir", module_name=module_name, scene_name=scene_name ), ) - - self.movie_file_path = os.path.join( - movie_dir, - add_extension_if_not_present( - self.output_name, - config["movie_file_extension"], - ), + self.movie_file_path = movie_dir / add_extension_if_not_present( + self.output_name, config["movie_file_extension"] ) - # TODO: /dev/null would be good in case sections_output_dir is used without bein set (doesn't work on Windows), everyone likes defensive programming, right? - self.sections_output_dir = "" + + # TODO: /dev/null would be good in case sections_output_dir is used without being set (doesn't work on Windows), everyone likes defensive programming, right? + self.sections_output_dir = Path("") if config.save_sections: self.sections_output_dir = guarantee_existence( config.get_dir( @@ -140,7 +177,7 @@ def init_output_directories(self, scene_name): if is_gif_format(): self.gif_file_path = add_extension_if_not_present( - self.output_name, GIF_FILE_EXTENSION + self.output_name, ".gif" ) if not config["output_file"]: @@ -148,7 +185,7 @@ def init_output_directories(self, scene_name): self.gif_file_path ) - self.gif_file_path = os.path.join(movie_dir, self.gif_file_path) + self.gif_file_path = movie_dir / self.gif_file_path self.partial_movie_directory = guarantee_existence( config.get_dir( @@ -158,12 +195,18 @@ def init_output_directories(self, scene_name): ), ) + if config["log_to_file"]: + log_dir = guarantee_existence(config.get_dir("log_dir")) + set_file_logger( + scene_name=scene_name, module_name=module_name, log_dir=log_dir + ) + def finish_last_section(self) -> None: """Delete current section if it is empty.""" if len(self.sections) and self.sections[-1].is_empty(): self.sections.pop() - def next_section(self, name: str, type: str, skip_animations: bool) -> None: + def next_section(self, name: str, type_: str, skip_animations: bool) -> None: """Create segmentation cut here.""" self.finish_last_section() @@ -177,24 +220,24 @@ def next_section(self, name: str, type: str, skip_animations: bool) -> None: and not skip_animations ): # relative to index file - section_video = f"{self.output_name}_{len(self.sections):04}{config.movie_file_extension}" + section_video = f"{self.output_name}_{len(self.sections):04}_{name}{config.movie_file_extension}" self.sections.append( Section( - type, + type_, section_video, name, skip_animations, ), ) - def add_partial_movie_file(self, hash_animation): + def add_partial_movie_file(self, hash_animation: str): """Adds a new partial movie file path to `scene.partial_movie_files` and current section from a hash. This method will compute the path from the hash. In addition to that it adds the new animation to the current section. Parameters ---------- - hash_animation : str + hash_animation Hash of the animation. """ if not hasattr(self, "partial_movie_directory") or not write_to_movie(): @@ -206,9 +249,9 @@ def add_partial_movie_file(self, hash_animation): self.partial_movie_files.append(None) self.sections[-1].partial_movie_files.append(None) else: - new_partial_movie_file = os.path.join( - self.partial_movie_directory, - f"{hash_animation}{config['movie_file_extension']}", + new_partial_movie_file = str( + self.partial_movie_directory + / f"{hash_animation}{config['movie_file_extension']}" ) self.partial_movie_files.append(new_partial_movie_file) self.sections[-1].partial_movie_files.append(new_partial_movie_file) @@ -244,32 +287,33 @@ def get_resolution_directory(self): # Sound def init_audio(self): - """ - Preps the writer for adding audio to the movie. - """ + """Preps the writer for adding audio to the movie.""" self.includes_sound = False def create_audio_segment(self): - """ - Creates an empty, silent, Audio Segment. - """ + """Creates an empty, silent, Audio Segment.""" self.audio_segment = AudioSegment.silent() - def add_audio_segment(self, new_segment, time=None, gain_to_background=None): + def add_audio_segment( + self, + new_segment: AudioSegment, + time: float | None = None, + gain_to_background: float | None = None, + ): """ This method adds an audio segment from an AudioSegment type object and suitable parameters. Parameters ---------- - new_segment : AudioSegment + new_segment The audio segment to add - time : int, float, optional + time the timestamp at which the sound should be added. - gain_to_background : optional + gain_to_background The gain of the segment from the background. """ if not self.includes_sound: @@ -295,19 +339,25 @@ def add_audio_segment(self, new_segment, time=None, gain_to_background=None): gain_during_overlay=gain_to_background, ) - def add_sound(self, sound_file, time=None, gain=None, **kwargs): + def add_sound( + self, + sound_file: str, + time: float | None = None, + gain: float | None = None, + **kwargs, + ): """ This method adds an audio segment from a sound file. Parameters ---------- - sound_file : str + sound_file The path to the sound file. - time : float or int, optional + time The timestamp at which the audio should be added. - gain : optional + gain The gain of the given audio segment. **kwargs @@ -316,80 +366,116 @@ def add_sound(self, sound_file, time=None, gain=None, **kwargs): """ file_path = get_full_sound_file_path(sound_file) - new_segment = AudioSegment.from_file(file_path) + # we assume files with .wav / .raw suffix are actually + # .wav and .raw files, respectively. + if file_path.suffix not in (".wav", ".raw"): + # we need to pass delete=False to work on Windows + # TODO: figure out a way to cache the wav file generated (benchmark needed) + with NamedTemporaryFile(suffix=".wav", delete=False) as wav_file_path: + convert_audio(file_path, wav_file_path, "pcm_s16le") + new_segment = AudioSegment.from_file(wav_file_path.name) + logger.info(f"Automatically converted {file_path} to .wav") + Path(wav_file_path.name).unlink() + else: + new_segment = AudioSegment.from_file(file_path) + if gain: new_segment = new_segment.apply_gain(gain) self.add_audio_segment(new_segment, time, **kwargs) # Writers - def begin_animation(self, allow_write=False, file_path=None): + def begin_animation( + self, allow_write: bool = False, file_path: StrPath | None = None + ) -> None: """ Used internally by manim to stream the animation to FFMPEG for displaying or writing to a file. Parameters ---------- - allow_write : bool, optional + allow_write Whether or not to write to a video file. """ if write_to_movie() and allow_write: - self.open_movie_pipe(file_path=file_path) + self.open_partial_movie_stream(file_path=file_path) - def end_animation(self, allow_write=False): + def end_animation(self, allow_write: bool = False) -> None: """ Internally used by Manim to stop streaming to FFMPEG gracefully. Parameters ---------- - allow_write : bool, optional + allow_write Whether or not to write to a video file. """ if write_to_movie() and allow_write: - self.close_movie_pipe() + self.close_partial_movie_stream() + + def listen_and_write(self): + """For internal use only: blocks until new frame is available on the queue.""" + while True: + num_frames, frame_data = self.queue.get() + if frame_data is None: + break - def write_frame(self, frame_or_renderer): + self.encode_and_write_frame(frame_data, num_frames) + + def encode_and_write_frame(self, frame: PixelArray, num_frames: int) -> None: + """ + For internal use only: takes a given frame in ``np.ndarray`` format and + write it to the stream + """ + for _ in range(num_frames): + # Notes: precomputing reusing packets does not work! + # I.e., you cannot do `packets = encode(...)` + # and reuse it, as it seems that `mux(...)` + # consumes the packet. + # The same issue applies for `av_frame`, + # reusing it renders weird-looking frames. + av_frame = av.VideoFrame.from_ndarray(frame, format="rgba") + for packet in self.video_stream.encode(av_frame): + self.video_container.mux(packet) + + def write_frame( + self, frame_or_renderer: np.ndarray | OpenGLRenderer, num_frames: int = 1 + ): """ Used internally by Manim to write a frame to the FFMPEG input buffer. Parameters ---------- - frame : np.array + frame_or_renderer Pixel array of the frame. + num_frames + The number of times to write frame. """ - if config.renderer == "opengl": - self.write_opengl_frame(frame_or_renderer) - else: - frame = frame_or_renderer - if write_to_movie(): - self.writing_process.stdin.write(frame.tobytes()) - if is_png_format() and not config["dry_run"]: - self.output_image_from_array(frame) - - def write_opengl_frame(self, renderer): if write_to_movie(): - self.writing_process.stdin.write( - renderer.get_raw_frame_buffer_object_data(), + frame: np.ndarray = ( + frame_or_renderer.get_frame() + if config.renderer == RendererType.OPENGL + else frame_or_renderer ) - elif is_png_format() and not config["dry_run"]: - target_dir, extension = os.path.splitext(self.image_file_path) + + msg = (num_frames, frame) + self.queue.put(msg) + + if is_png_format() and not config["dry_run"]: + image: Image = ( + frame_or_renderer.get_image() + if config.renderer == RendererType.OPENGL + else Image.fromarray(frame_or_renderer) + ) + target_dir = self.image_file_path.parent / self.image_file_path.stem + extension = self.image_file_path.suffix self.output_image( - renderer.get_image(), + image, target_dir, extension, config["zero_pad"], ) - def output_image_from_array(self, frame_data): - target_dir, extension = os.path.splitext(self.image_file_path) - self.output_image( - Image.fromarray(frame_data), - target_dir, - extension, - config["zero_pad"], - ) - def output_image(self, image: Image.Image, target_dir, ext, zero_pad: bool): if zero_pad: image.save(f"{target_dir}{str(self.frame_count).zfill(zero_pad)}{ext}") @@ -397,14 +483,14 @@ def output_image(self, image: Image.Image, target_dir, ext, zero_pad: bool): image.save(f"{target_dir}{self.frame_count}{ext}") self.frame_count += 1 - def save_final_image(self, image): + def save_final_image(self, image: np.ndarray): """ The name is a misnomer. This method saves the image passed to it as an in the default image directory. Parameters ---------- - image : np.array + image The pixel array of the image to save. """ if config["dry_run"]: @@ -415,7 +501,7 @@ def save_final_image(self, image): image.save(self.image_file_path) self.print_file_ready_message(self.image_file_path) - def finish(self): + def finish(self) -> None: """ Finishes writing to the FFMPEG buffer or writing images to output directory. @@ -425,8 +511,6 @@ def finish(self): frame in the default image directory. """ if write_to_movie(): - if hasattr(self, "writing_process"): - self.writing_process.terminate() self.combine_to_movie() if config.save_sections: self.combine_to_section_videos() @@ -435,79 +519,83 @@ def finish(self): else: self.clean_cache() elif is_png_format() and not config["dry_run"]: - target_dir, _ = os.path.splitext(self.image_file_path) - logger.info("\n%i images ready at %s\n", self.frame_count, target_dir) + target_dir = self.image_file_path.parent / self.image_file_path.stem + logger.info("\n%i images ready at %s\n", self.frame_count, str(target_dir)) if self.subcaptions: self.write_subcaption_file() - def open_movie_pipe(self, file_path=None): - """ - Used internally by Manim to initialise - FFMPEG and begin writing to FFMPEG's input - buffer. + def open_partial_movie_stream(self, file_path=None) -> None: + """Open a container holding a video stream. + + This is used internally by Manim initialize the container holding + the video stream of a partial movie file. """ if file_path is None: file_path = self.partial_movie_files[self.renderer.num_plays] self.partial_movie_file_path = file_path - fps = config["frame_rate"] - if fps == int(fps): # fps is integer - fps = int(fps) - if config.renderer == "opengl": - width, height = self.renderer.get_pixel_shape() - else: - height = config["pixel_height"] - width = config["pixel_width"] - - command = [ - FFMPEG_BIN, - "-y", # overwrite output file if it exists - "-f", - "rawvideo", - "-s", - "%dx%d" % (width, height), # size of one frame - "-pix_fmt", - "rgba", - "-r", - str(fps), # frames per second - "-i", - "-", # The input comes from a pipe - "-an", # Tells FFMPEG not to expect any audio - "-loglevel", - config["ffmpeg_loglevel"].lower(), - "-metadata", - f"comment=Rendered with Manim Community v{__version__}", - ] - if config.renderer == "opengl": - command += ["-vf", "vflip"] - if is_webm_format(): - command += ["-vcodec", "libvpx-vp9", "-auto-alt-ref", "0"] - # .mov format - elif config["transparent"]: - command += ["-vcodec", "qtrle"] - else: - command += ["-vcodec", "libx264", "-pix_fmt", "yuv420p"] - command += [file_path] - self.writing_process = subprocess.Popen(command, stdin=subprocess.PIPE) + fps = to_av_frame_rate(config.frame_rate) + + partial_movie_file_codec = "libx264" + partial_movie_file_pix_fmt = "yuv420p" + av_options = { + "an": "1", # ffmpeg: -an, no audio + "crf": "23", # ffmpeg: -crf, constant rate factor (improved bitrate) + } + + if config.movie_file_extension == ".webm": + partial_movie_file_codec = "libvpx-vp9" + av_options["-auto-alt-ref"] = "1" + if config.transparent: + partial_movie_file_pix_fmt = "yuva420p" + + elif config.transparent: + partial_movie_file_codec = "qtrle" + partial_movie_file_pix_fmt = "argb" + + with av.open(file_path, mode="w") as video_container: + stream = video_container.add_stream( + partial_movie_file_codec, + rate=fps, + options=av_options, + ) + stream.pix_fmt = partial_movie_file_pix_fmt + stream.width = config.pixel_width + stream.height = config.pixel_height - def close_movie_pipe(self): - """ - Used internally by Manim to gracefully stop writing to FFMPEG's input buffer + self.video_container = video_container + self.video_stream = stream + + self.queue: Queue[tuple[int, PixelArray | None]] = Queue() + self.writer_thread = Thread(target=self.listen_and_write, args=()) + self.writer_thread.start() + + def close_partial_movie_stream(self) -> None: + """Close the currently opened video container. + + Used internally by Manim to first flush the remaining packages + in the video stream holding a partial file, and then close + the corresponding container. """ - self.writing_process.stdin.close() - self.writing_process.wait() + self.queue.put((-1, None)) + self.writer_thread.join() + + for packet in self.video_stream.encode(): + self.video_container.mux(packet) + + self.video_container.close() logger.info( f"Animation {self.renderer.num_plays} : Partial movie file written in %(path)s", {"path": f"'{self.partial_movie_file_path}'"}, ) - def is_already_cached(self, hash_invocation): + def is_already_cached(self, hash_invocation: str): """Will check if a file named with `hash_invocation` exists. Parameters ---------- - hash_invocation : :class:`str` + hash_invocation The hash corresponding to an invocation to either `scene.play` or `scene.wait`. Returns @@ -517,64 +605,116 @@ def is_already_cached(self, hash_invocation): """ if not hasattr(self, "partial_movie_directory") or not write_to_movie(): return False - path = os.path.join( - self.partial_movie_directory, - f"{hash_invocation}{config['movie_file_extension']}", + path = ( + self.partial_movie_directory + / f"{hash_invocation}{config['movie_file_extension']}" ) - return os.path.exists(path) + return path.exists() def combine_files( self, input_files: list[str], - output_file: Path | str, + output_file: Path, create_gif=False, includes_sound=False, ): - file_list = os.path.join( - self.partial_movie_directory, - "partial_movie_file_list.txt", - ) + file_list = self.partial_movie_directory / "partial_movie_file_list.txt" logger.debug( f"Partial movie files to combine ({len(input_files)} files): %(p)s", {"p": input_files[:5]}, ) - with open(file_list, "w", encoding="utf-8") as fp: + with file_list.open("w", encoding="utf-8") as fp: fp.write("# This file is used internally by FFMPEG.\n") for pf_path in input_files: - if os.name == "nt": - pf_path = pf_path.replace("\\", "/") + pf_path = Path(pf_path).as_posix() fp.write(f"file 'file:{pf_path}'\n") - commands = [ - FFMPEG_BIN, - "-y", # overwrite output file if it exists - "-f", - "concat", - "-safe", - "0", - "-i", - file_list, - "-loglevel", - config.ffmpeg_loglevel.lower(), - "-metadata", - f"comment=Rendered with Manim Community v{__version__}", - "-nostdin", - ] + av_options = { + "safe": "0", # needed to read files + } + + if not includes_sound: + av_options["an"] = "1" + + partial_movies_input = av.open( + str(file_list), options=av_options, format="concat" + ) + partial_movies_stream = partial_movies_input.streams.video[0] + output_container = av.open(str(output_file), mode="w") + output_container.metadata["comment"] = ( + f"Rendered with Manim Community v{__version__}" + ) + output_stream = output_container.add_stream( + codec_name="gif" if create_gif else None, + template=partial_movies_stream if not create_gif else None, + ) + if config.transparent and config.movie_file_extension == ".webm": + output_stream.pix_fmt = "yuva420p" if create_gif: - commands += [ - "-vf", - f"fps={np.clip(config['frame_rate'], 1, 50)},split[s0][s1];[s0]palettegen=stats_mode=diff[p];[s1][p]paletteuse=dither=bayer:bayer_scale=5:diff_mode=rectangle", - ] + """ + The following solution was largely inspired from this comment + https://github.com/imageio/imageio/issues/995#issuecomment-1580533018, + and the following code + https://github.com/imageio/imageio/blob/65d79140018bb7c64c0692ea72cb4093e8d632a0/imageio/plugins/pyav.py#L927-L996. + """ + output_stream.pix_fmt = "rgb8" + if config.transparent: + output_stream.pix_fmt = "pal8" + output_stream.width = config.pixel_width + output_stream.height = config.pixel_height + output_stream.rate = to_av_frame_rate(config.frame_rate) + graph = av.filter.Graph() + input_buffer = graph.add_buffer(template=partial_movies_stream) + split = graph.add("split") + palettegen = graph.add("palettegen", "stats_mode=diff") + paletteuse = graph.add( + "paletteuse", "dither=bayer:bayer_scale=5:diff_mode=rectangle" + ) + output_sink = graph.add("buffersink") + + input_buffer.link_to(split) + split.link_to(palettegen, 0, 0) # 1st input of split -> input of palettegen + split.link_to(paletteuse, 1, 0) # 2nd output of split -> 1st input + palettegen.link_to(paletteuse, 0, 1) # output of palettegen -> 2nd input + paletteuse.link_to(output_sink) + + graph.configure() + + for frame in partial_movies_input.decode(video=0): + graph.push(frame) + + graph.push(None) # EOF: https://github.com/PyAV-Org/PyAV/issues/886. + + frames_written = 0 + while True: + try: + frame = graph.pull() + if output_stream.codec_context.time_base is not None: + frame.time_base = output_stream.codec_context.time_base + frame.pts = frames_written + frames_written += 1 + output_container.mux(output_stream.encode(frame)) + except av.error.EOFError: + break + + for packet in output_stream.encode(): + output_container.mux(packet) + else: - commands += ["-c", "copy"] + for packet in partial_movies_input.demux(partial_movies_stream): + # We need to skip the "flushing" packets that `demux` generates. + if packet.dts is None: + continue - if not includes_sound: - commands += ["-an"] + packet.dts = None # This seems to be needed, as dts from consecutive + # files may not be monotically increasing, so we let libav compute it. - commands += [output_file] + # We need to assign the packet to the new stream. + packet.stream = output_stream + output_container.mux(packet) - combine_process = subprocess.Popen(commands) - combine_process.wait() + partial_movies_input.close() + output_container.close() def combine_to_movie(self): """Used internally by Manim to combine the separate @@ -591,6 +731,11 @@ def combine_to_movie(self): movie_file_path = self.movie_file_path if is_gif_format(): movie_file_path = self.gif_file_path + + if len(partial_movie_files) == 0: # Prevent calling concat on empty list + logger.info("No animations are contained in this scene.") + return + logger.info("Combining to Movie file.") self.combine_files( partial_movie_files, @@ -600,47 +745,76 @@ def combine_to_movie(self): ) # handle sound - if self.includes_sound: - extension = config["movie_file_extension"] - sound_file_path = movie_file_path.replace(extension, ".wav") + if self.includes_sound and config.format != "gif": + sound_file_path = movie_file_path.with_suffix(".wav") # Makes sure sound file length will match video file self.add_audio_segment(AudioSegment.silent(0)) self.audio_segment.export( sound_file_path, + format="wav", bitrate="312k", ) - temp_file_path = movie_file_path.replace(extension, f"_temp{extension}") - commands = [ - FFMPEG_BIN, - "-i", - movie_file_path, - "-i", - sound_file_path, - "-y", # overwrite output file if it exists - "-c:v", - "copy", - "-c:a", - "aac", - "-b:a", - "320k", - # select video stream from first file - "-map", - "0:v:0", - # select audio stream from second file - "-map", - "1:a:0", - "-loglevel", - config.ffmpeg_loglevel.lower(), - "-metadata", - f"comment=Rendered with Manim Community v{__version__}", - # "-shortest", - temp_file_path, - ] - subprocess.call(commands) - shutil.move(temp_file_path, movie_file_path) - os.remove(sound_file_path) - - self.print_file_ready_message(movie_file_path) + # Audio added to a VP9 encoded (webm) video file needs + # to be encoded as vorbis or opus. Directly exporting + # self.audio_segment with such a codec works in principle, + # but tries to call ffmpeg via its CLI -- which we want + # to avoid. This is why we need to do the conversion + # manually. + if config.movie_file_extension == ".webm": + ogg_sound_file_path = sound_file_path.with_suffix(".ogg") + convert_audio(sound_file_path, ogg_sound_file_path, "libvorbis") + sound_file_path = ogg_sound_file_path + elif config.movie_file_extension == ".mp4": + # Similarly, pyav may reject wav audio in an .mp4 file; + # convert to AAC. + aac_sound_file_path = sound_file_path.with_suffix(".aac") + convert_audio(sound_file_path, aac_sound_file_path, "aac") + sound_file_path = aac_sound_file_path + + temp_file_path = movie_file_path.with_name( + f"{movie_file_path.stem}_temp{movie_file_path.suffix}" + ) + av_options = { + "shortest": "1", + "metadata": f"comment=Rendered with Manim Community v{__version__}", + } + + with ( + av.open(movie_file_path) as video_input, + av.open(sound_file_path) as audio_input, + ): + video_stream = video_input.streams.video[0] + audio_stream = audio_input.streams.audio[0] + output_container = av.open( + str(temp_file_path), mode="w", options=av_options + ) + output_video_stream = output_container.add_stream(template=video_stream) + output_audio_stream = output_container.add_stream(template=audio_stream) + + for packet in video_input.demux(video_stream): + # We need to skip the "flushing" packets that `demux` generates. + if packet.dts is None: + continue + + # We need to assign the packet to the new stream. + packet.stream = output_video_stream + output_container.mux(packet) + + for packet in audio_input.demux(audio_stream): + # We need to skip the "flushing" packets that `demux` generates. + if packet.dts is None: + continue + + # We need to assign the packet to the new stream. + packet.stream = output_audio_stream + output_container.mux(packet) + + output_container.close() + + shutil.move(str(temp_file_path), str(movie_file_path)) + sound_file_path.unlink() + + self.print_file_ready_message(str(movie_file_path)) if write_to_movie(): for file_path in partial_movie_files: # We have to modify the accessed time so if we have to clean the cache we remove the one used the longest. @@ -648,7 +822,6 @@ def combine_to_movie(self): def combine_to_section_videos(self) -> None: """Concatenate partial movie files for each section.""" - self.finish_last_section() sections_index: list[dict[str, Any]] = [] for section in self.sections: @@ -657,19 +830,17 @@ def combine_to_section_videos(self) -> None: logger.info(f"Combining partial files for section '{section.name}'") self.combine_files( section.get_clean_partial_movie_files(), - os.path.join(self.sections_output_dir, section.video), + self.sections_output_dir / section.video, ) sections_index.append(section.get_dict(self.sections_output_dir)) - with open( - os.path.join(self.sections_output_dir, f"{self.output_name}.json"), "w" - ) as file: + with (self.sections_output_dir / f"{self.output_name}.json").open("w") as file: json.dump(sections_index, file, indent=4) def clean_cache(self): """Will clean the cache by removing the oldest partial_movie_files.""" cached_partial_movies = [ - os.path.join(self.partial_movie_directory, file_name) - for file_name in os.listdir(self.partial_movie_directory) + (self.partial_movie_directory / file_name) + for file_name in self.partial_movie_directory.iterdir() if file_name != "partial_movie_file_list.txt" ] if len(cached_partial_movies) > config["max_files_cached"]: @@ -678,11 +849,10 @@ def clean_cache(self): ) oldest_files_to_delete = sorted( cached_partial_movies, - key=os.path.getatime, + key=lambda path: path.stat().st_atime, )[:number_files_to_delete] - # oldest_file_path = min(cached_partial_movies, key=os.path.getatime) for file_to_delete in oldest_files_to_delete: - os.remove(file_to_delete) + file_to_delete.unlink() logger.info( f"The partial movie directory is full (> {config['max_files_cached']} files). Therefore, manim has removed the {number_files_to_delete} oldest file(s)." " You can change this behaviour by changing max_files_cached in config.", @@ -691,12 +861,12 @@ def clean_cache(self): def flush_cache_directory(self): """Delete all the cached partial movie files""" cached_partial_movies = [ - os.path.join(self.partial_movie_directory, file_name) - for file_name in os.listdir(self.partial_movie_directory) + self.partial_movie_directory / file_name + for file_name in self.partial_movie_directory.iterdir() if file_name != "partial_movie_file_list.txt" ] for f in cached_partial_movies: - os.remove(f) + f.unlink() logger.info( f"Cache flushed. {len(cached_partial_movies)} file(s) deleted in %(par_dir)s.", {"par_dir": self.partial_movie_directory}, @@ -704,9 +874,10 @@ def flush_cache_directory(self): def write_subcaption_file(self): """Writes the subcaption file.""" + if config.output_file is None: + return subcaption_file = Path(config.output_file).with_suffix(".srt") - with open(subcaption_file, "w") as f: - f.write(srt.compose(self.subcaptions)) + subcaption_file.write_text(srt.compose(self.subcaptions), encoding="utf-8") logger.info(f"Subcaption file has been written as {subcaption_file}") def print_file_ready_message(self, file_path): diff --git a/manim/scene/section.py b/manim/scene/section.py index ce42e1309e..af005b52da 100644 --- a/manim/scene/section.py +++ b/manim/scene/section.py @@ -2,12 +2,14 @@ from __future__ import annotations -import os from enum import Enum +from pathlib import Path from typing import Any from manim import get_video_metadata +__all__ = ["Section", "DefaultSectionType"] + class DefaultSectionType(str, Enum): """The type of a section can be used for third party applications. @@ -32,23 +34,23 @@ class PresentationSectionType(str, Enum): class Section: - """A :class:`.Scene` can be segmented into multiple Sections. - Refer to :doc:`the documentation` for more info. + r"""A :class:`.Scene` can be segmented into multiple Sections. + Refer to :doc:`the documentation` for more info. It consists of multiple animations. Attributes ---------- - type - Can be used by a third party applications to classify different types of sections. - video - Path to video file with animations belonging to section relative to sections directory. - If ``None``, then the section will not be saved. - name - Human readable, non-unique name for this section. - skip_animations - Skip rendering the animations in this section when ``True``. - partial_movie_files - Animations belonging to this section. + type\_ + Can be used by a third party applications to classify different types of sections. + video + Path to video file with animations belonging to section relative to sections directory. + If ``None``, then the section will not be saved. + name + Human readable, non-unique name for this section. + skip_animations + Skip rendering the animations in this section when ``True``. + partial_movie_files + Animations belonging to this section. See Also -------- @@ -57,8 +59,8 @@ class Section: :meth:`.OpenGLRenderer.update_skipping_status` """ - def __init__(self, type: str, video: str | None, name: str, skip_animations: bool): - self.type = type + def __init__(self, type_: str, video: str | None, name: str, skip_animations: bool): + self.type_ = type_ # None when not to be saved -> still keeps section alive self.video: str | None = video self.name = name @@ -76,7 +78,7 @@ def get_clean_partial_movie_files(self) -> list[str]: """Return all partial movie files that are not ``None``.""" return [el for el in self.partial_movie_files if el is not None] - def get_dict(self, sections_dir: str) -> dict[str, Any]: + def get_dict(self, sections_dir: Path) -> dict[str, Any]: """Get dictionary representation with metadata of output video. The output from this function is used from every section to build the sections index file. @@ -88,11 +90,11 @@ def get_dict(self, sections_dir: str) -> dict[str, Any]: f"Section '{self.name}' cannot be exported as dict, it does not have a video path assigned to it" ) - video_metadata = get_video_metadata(os.path.join(sections_dir, self.video)) + video_metadata = get_video_metadata(sections_dir / self.video) return dict( { "name": self.name, - "type": self.type, + "type": self.type_, "video": self.video, }, **video_metadata, diff --git a/manim/scene/three_d_scene.py b/manim/scene/three_d_scene.py index db49e663e1..7f39f4cf32 100644 --- a/manim/scene/three_d_scene.py +++ b/manim/scene/three_d_scene.py @@ -6,7 +6,7 @@ import warnings -from typing import Iterable, Sequence +from collections.abc import Iterable, Sequence import numpy as np @@ -20,7 +20,7 @@ from ..animation.animation import Animation from ..animation.transform import Transform from ..camera.three_d_camera import ThreeDCamera -from ..constants import DEGREES +from ..constants import DEGREES, RendererType from ..mobject.mobject import Mobject from ..mobject.types.vectorized_mobject import VectorizedPoint, VGroup from ..renderer.opengl_renderer import OpenGLCamera @@ -67,26 +67,25 @@ def set_camera_orientation( Parameters ---------- - phi : int or float, optional + phi The polar angle i.e the angle between Z_AXIS and Camera through ORIGIN in radians. - theta : int or float, optional + theta The azimuthal angle i.e the angle that spins the camera around the Z_AXIS. - focal_distance : int or float, optional + focal_distance The focal_distance of the Camera. - gamma : int or float, optional + gamma The rotation of the camera about the vector from the ORIGIN to the Camera. - zoom : float, optional + zoom The zoom factor of the scene. - frame_center : list, tuple or np.array, optional + frame_center The new center of the camera frame in cartesian coordinates. """ - if phi is not None: self.renderer.camera.set_phi(phi) if theta is not None: @@ -100,24 +99,24 @@ def set_camera_orientation( if frame_center is not None: self.renderer.camera._frame_center.move_to(frame_center) - def begin_ambient_camera_rotation(self, rate=0.02, about="theta"): + def begin_ambient_camera_rotation(self, rate: float = 0.02, about: str = "theta"): """ This method begins an ambient rotation of the camera about the Z_AXIS, in the anticlockwise direction Parameters ---------- - rate : int or float, optional + rate The rate at which the camera should rotate about the Z_AXIS. Negative rate means clockwise rotation. - about: (str) + about one of 3 options: ["theta", "phi", "gamma"]. defaults to theta. """ # TODO, use a ValueTracker for rate, so that it # can begin and end smoothly about: str = about.lower() try: - if config.renderer != "opengl": + if config.renderer == RendererType.CAIRO: trackers = { "theta": self.camera.theta_tracker, "phi": self.camera.phi_tracker, @@ -126,7 +125,7 @@ def begin_ambient_camera_rotation(self, rate=0.02, about="theta"): x: ValueTracker = trackers[about] x.add_updater(lambda m, dt: x.increment_value(rate * dt)) self.add(x) - else: + elif config.renderer == RendererType.OPENGL: cam: OpenGLCamera = self.camera methods = { "theta": cam.increment_theta, @@ -135,16 +134,14 @@ def begin_ambient_camera_rotation(self, rate=0.02, about="theta"): } cam.add_updater(lambda m, dt: methods[about](rate * dt)) self.add(self.camera) - except Exception: - raise ValueError("Invalid ambient rotation angle.") + except Exception as e: + raise ValueError("Invalid ambient rotation angle.") from e def stop_ambient_camera_rotation(self, about="theta"): - """ - This method stops all ambient camera rotation. - """ + """This method stops all ambient camera rotation.""" about: str = about.lower() try: - if config.renderer != "opengl": + if config.renderer == RendererType.CAIRO: trackers = { "theta": self.camera.theta_tracker, "phi": self.camera.phi_tracker, @@ -153,10 +150,10 @@ def stop_ambient_camera_rotation(self, about="theta"): x: ValueTracker = trackers[about] x.clear_updaters() self.remove(x) - else: + elif config.renderer == RendererType.OPENGL: self.camera.clear_updaters() - except Exception: - raise ValueError("Invalid ambient rotation angle.") + except Exception as e: + raise ValueError("Invalid ambient rotation angle.") from e def begin_3dillusion_camera_rotation( self, @@ -205,9 +202,7 @@ def update_phi(m, dt): self.add(self.renderer.camera.phi_tracker) def stop_3dillusion_camera_rotation(self): - """ - This method stops all illusion camera rotations. - """ + """This method stops all illusion camera rotations.""" self.renderer.camera.theta_tracker.clear_updaters() self.remove(self.renderer.camera.theta_tracker) self.renderer.camera.phi_tracker.clear_updaters() @@ -230,31 +225,31 @@ def move_camera( Parameters ---------- - phi : int or float, optional + phi The polar angle i.e the angle between Z_AXIS and Camera through ORIGIN in radians. - theta : int or float, optional + theta The azimuthal angle i.e the angle that spins the camera around the Z_AXIS. - focal_distance : int or float, optional + focal_distance The radial focal_distance between ORIGIN and Camera. - gamma : int or float, optional + gamma The rotation of the camera about the vector from the ORIGIN to the Camera. - zoom : int or float, optional + zoom The zoom factor of the camera. - frame_center : list, tuple or np.array, optional + frame_center The new center of the camera frame in cartesian coordinates. - added_anims : list, optional + added_anims Any other animations to be played at the same time. """ anims = [] - if config.renderer != "opengl": + if config.renderer == RendererType.CAIRO: self.camera: ThreeDCamera value_tracker_pairs = [ (phi, self.camera.phi_tracker), @@ -268,7 +263,7 @@ def move_camera( anims.append(tracker.animate.set_value(value)) if frame_center is not None: anims.append(self.camera._frame_center.animate.move_to(frame_center)) - else: + elif config.renderer == RendererType.OPENGL: cam: OpenGLCamera = self.camera cam2 = cam.copy() methods = { @@ -283,16 +278,15 @@ def move_camera( frame_center = frame_center.get_center() frame_center = list(frame_center) + zoom_value = None + if zoom is not None: + zoom_value = config.frame_height / (zoom * cam.height) + for value, method in [ [theta, "theta"], [phi, "phi"], [gamma, "gamma"], - [ - config.frame_height / (zoom * cam.height) - if zoom is not None - else None, - "zoom", - ], + [zoom_value, "zoom"], [frame_center, "frame_center"], ]: if value is not None: @@ -312,28 +306,28 @@ def move_camera( # it is required to redraw every object. These lines remove frame_center from the Scene once # its animation is done, ensuring that manim does not think that it is moving. Since the # frame_center is never actually drawn, this shouldn't break anything. - if frame_center is not None and config.renderer != "opengl": + if frame_center is not None and config.renderer == RendererType.CAIRO: self.remove(self.camera._frame_center) - def get_moving_mobjects(self, *animations): + def get_moving_mobjects(self, *animations: Animation): """ This method returns a list of all of the Mobjects in the Scene that are moving, that are also in the animations passed. Parameters ---------- - *animations : Animation + *animations The animations whose mobjects will be checked. """ moving_mobjects = super().get_moving_mobjects(*animations) camera_mobjects = self.renderer.camera.get_value_trackers() + [ self.renderer.camera._frame_center, ] - if any([cm in moving_mobjects for cm in camera_mobjects]): + if any(cm in moving_mobjects for cm in camera_mobjects): return self.mobjects return moving_mobjects - def add_fixed_orientation_mobjects(self, *mobjects, **kwargs): + def add_fixed_orientation_mobjects(self, *mobjects: Mobject, **kwargs): """ This method is used to prevent the rotation and tilting of mobjects as the camera moves around. The mobject can @@ -343,7 +337,7 @@ def add_fixed_orientation_mobjects(self, *mobjects, **kwargs): Parameters ---------- - *mobjects : Mobject + *mobjects The Mobject(s) whose orientation must be fixed. **kwargs @@ -351,16 +345,16 @@ def add_fixed_orientation_mobjects(self, *mobjects, **kwargs): use_static_center_func : bool center_func : function """ - if config.renderer != "opengl": + if config.renderer == RendererType.CAIRO: self.add(*mobjects) self.renderer.camera.add_fixed_orientation_mobjects(*mobjects, **kwargs) - else: + elif config.renderer == RendererType.OPENGL: for mob in mobjects: mob: OpenGLMobject mob.fix_orientation() self.add(mob) - def add_fixed_in_frame_mobjects(self, *mobjects): + def add_fixed_in_frame_mobjects(self, *mobjects: Mobject): """ This method is used to prevent the rotation and movement of mobjects as the camera moves around. The mobject is @@ -369,20 +363,20 @@ def add_fixed_in_frame_mobjects(self, *mobjects): Parameters ---------- - *mobjects : Mobjects + *mobjects The Mobjects whose orientation must be fixed. """ - if config.renderer != "opengl": + if config.renderer == RendererType.CAIRO: self.add(*mobjects) self.camera: ThreeDCamera self.camera.add_fixed_in_frame_mobjects(*mobjects) - else: + elif config.renderer == RendererType.OPENGL: for mob in mobjects: mob: OpenGLMobject mob.fix_in_frame() self.add(mob) - def remove_fixed_orientation_mobjects(self, *mobjects): + def remove_fixed_orientation_mobjects(self, *mobjects: Mobject): """ This method "unfixes" the orientation of the mobjects passed, meaning they will no longer be at the same angle @@ -391,18 +385,18 @@ def remove_fixed_orientation_mobjects(self, *mobjects): Parameters ---------- - *mobjects : Mobjects + *mobjects The Mobjects whose orientation must be unfixed. """ - if config.renderer != "opengl": + if config.renderer == RendererType.CAIRO: self.renderer.camera.remove_fixed_orientation_mobjects(*mobjects) - else: + elif config.renderer == RendererType.OPENGL: for mob in mobjects: mob: OpenGLMobject mob.unfix_orientation() self.remove(mob) - def remove_fixed_in_frame_mobjects(self, *mobjects): + def remove_fixed_in_frame_mobjects(self, *mobjects: Mobject): """ This method undoes what add_fixed_in_frame_mobjects does. It allows the mobject to be affected by the movement of @@ -410,12 +404,12 @@ def remove_fixed_in_frame_mobjects(self, *mobjects): Parameters ---------- - *mobjects : Mobjects + *mobjects The Mobjects whose position and orientation must be unfixed. """ - if config.renderer != "opengl": + if config.renderer == RendererType.CAIRO: self.renderer.camera.remove_fixed_in_frame_mobjects(*mobjects) - else: + elif config.renderer == RendererType.OPENGL: for mob in mobjects: mob: OpenGLMobject mob.unfix_from_frame() @@ -546,7 +540,5 @@ def get_default_camera_position(self): return self.default_angled_camera_position def set_camera_to_default_position(self): - """ - Sets the camera to its default position. - """ + """Sets the camera to its default position.""" self.set_camera_orientation(**self.default_angled_camera_position) diff --git a/manim/scene/vector_space_scene.py b/manim/scene/vector_space_scene.py index aa4df4997b..be75151471 100644 --- a/manim/scene/vector_space_scene.py +++ b/manim/scene/vector_space_scene.py @@ -4,8 +4,9 @@ __all__ = ["VectorScene", "LinearTransformationScene"] +from typing import Callable + import numpy as np -from colour import Color from manim.mobject.geometry.arc import Dot from manim.mobject.geometry.line import Arrow, Line, Vector @@ -26,7 +27,17 @@ from ..mobject.mobject import Mobject from ..mobject.types.vectorized_mobject import VGroup, VMobject from ..scene.scene import Scene -from ..utils.color import BLUE_D, GREEN_C, GREY, RED_C, WHITE, YELLOW +from ..utils.color import ( + BLACK, + BLUE_D, + GREEN_C, + GREY, + RED_C, + WHITE, + YELLOW, + ManimColor, + ParsableManimColor, +) from ..utils.rate_functions import rush_from, rush_into from ..utils.space_ops import angle_of_vector @@ -46,13 +57,13 @@ def __init__(self, basis_vector_stroke_width=6, **kwargs): super().__init__(**kwargs) self.basis_vector_stroke_width = basis_vector_stroke_width - def add_plane(self, animate=False, **kwargs): + def add_plane(self, animate: bool = False, **kwargs): """ Adds a NumberPlane object to the background. Parameters ---------- - animate : bool, optional + animate Whether or not to animate the addition of the plane via Create. **kwargs Any valid keyword arguments accepted by NumberPlane. @@ -68,15 +79,15 @@ def add_plane(self, animate=False, **kwargs): self.add(plane) return plane - def add_axes(self, animate=False, color=WHITE, **kwargs): + def add_axes(self, animate: bool = False, color: bool = WHITE, **kwargs): """ Adds a pair of Axes to the Scene. Parameters ---------- - animate : bool, optional + animate Whether or not to animate the addition of the axes through Create. - color : bool, optional + color The color of the axes. Defaults to WHITE. """ axes = Axes(color=color, axis_config={"unit_size": 1}) @@ -85,17 +96,17 @@ def add_axes(self, animate=False, color=WHITE, **kwargs): self.add(axes) return axes - def lock_in_faded_grid(self, dimness=0.7, axes_dimness=0.5): + def lock_in_faded_grid(self, dimness: float = 0.7, axes_dimness: float = 0.5): """ This method freezes the NumberPlane and Axes that were already in the background, and adds new, manipulatable ones to the foreground. Parameters ---------- - dimness : int, float, optional + dimness The required dimness of the NumberPlane - axes_dimness : int, float, optional + axes_dimness The required dimness of the Axes. """ plane = self.add_plane() @@ -109,13 +120,13 @@ def lock_in_faded_grid(self, dimness=0.7, axes_dimness=0.5): self.renderer.camera = Camera(self.renderer.get_frame()) self.clear() - def get_vector(self, numerical_vector, **kwargs): + def get_vector(self, numerical_vector: np.ndarray | list | tuple, **kwargs): """ Returns an arrow on the Plane given an input numerical vector. Parameters ---------- - numerical_vector : np.array, list, tuple + numerical_vector The Vector to plot. **kwargs Any valid keyword argument of Arrow. @@ -132,22 +143,28 @@ def get_vector(self, numerical_vector, **kwargs): **kwargs, ) - def add_vector(self, vector, color=YELLOW, animate=True, **kwargs): + def add_vector( + self, + vector: Arrow | list | tuple | np.ndarray, + color: str = YELLOW, + animate: bool = True, + **kwargs, + ): """ Returns the Vector after adding it to the Plane. Parameters ---------- - vector : Arrow, list, tuple, np.array + vector It can be a pre-made graphical vector, or the coordinates of one. - color : str + color The string of the hex color of the vector. This is only taken into consideration if 'vector' is not an Arrow. Defaults to YELLOW. - animate : bool + animate Whether or not to animate the addition of the vector by using GrowArrow @@ -168,25 +185,18 @@ def add_vector(self, vector, color=YELLOW, animate=True, **kwargs): self.add(vector) return vector - def write_vector_coordinates(self, vector, **kwargs): + def write_vector_coordinates(self, vector: Arrow, **kwargs): """ Returns a column matrix indicating the vector coordinates, after writing them to the screen. Parameters ---------- - vector : :class:`.Arrow` + vector The arrow representing the vector. **kwargs - Any valid keyword arguments of :meth:`~.geometry.Vector.coordinate_label`: - - integer_labels : :class:`bool` - Whether or not to round the coordinates to integers. Default: ``True``. - n_dim : :class:`int` - The number of dimensions of the vector. Default: ``2``. - color - The color of the label. Default: ``WHITE``. + Any valid keyword arguments of :meth:`~.Vector.coordinate_label`: Returns ------- @@ -197,16 +207,16 @@ def write_vector_coordinates(self, vector, **kwargs): self.play(Write(coords)) return coords - def get_basis_vectors(self, i_hat_color=X_COLOR, j_hat_color=Y_COLOR): + def get_basis_vectors(self, i_hat_color: str = X_COLOR, j_hat_color: str = Y_COLOR): """ Returns a VGroup of the Basis Vectors (1,0) and (0,1) Parameters ---------- - i_hat_color : str + i_hat_color The hex colour to use for the basis vector in the x direction - j_hat_color : str + j_hat_color The hex colour to use for the basis vector in the y direction Returns @@ -252,32 +262,32 @@ def get_basis_vector_labels(self, **kwargs): def get_vector_label( self, - vector, + vector: Vector, label, - at_tip=False, - direction="left", - rotate=False, - color=None, - label_scale_factor=LARGE_BUFF - 0.2, + at_tip: bool = False, + direction: str = "left", + rotate: bool = False, + color: str | None = None, + label_scale_factor: float = LARGE_BUFF - 0.2, ): """ Returns naming labels for the passed vector. Parameters ---------- - vector : Vector + vector Vector Object for which to get the label. - at_tip : bool + at_tip Whether or not to place the label at the tip of the vector. - direction : {"left"} + direction If the label should be on the "left" or right of the vector. - rotate : bool + rotate Whether or not to rotate it to align it with the vector. - color : str + color The color to give the label. - label_scale_factor (Union[int,float]) + label_scale_factor How much to scale the label by. Returns @@ -287,7 +297,7 @@ def get_vector_label( """ if not isinstance(label, MathTex): if len(label) == 1: - label = "\\vec{\\textbf{%s}}" % label + label = "\\vec{\\textbf{%s}}" % label # noqa: UP031 label = MathTex(label) if color is None: color = vector.get_color() @@ -311,20 +321,22 @@ def get_vector_label( label.shift((vector.get_end() - vector.get_start()) / 2) return label - def label_vector(self, vector, label, animate=True, **kwargs): + def label_vector( + self, vector: Vector, label: MathTex | str, animate: bool = True, **kwargs + ): """ Shortcut method for creating, and animating the addition of a label for the vector. Parameters ---------- - vector : Vector + vector The vector for which the label must be added. - label : MathTex, str + label The MathTex/string of the label. - animate : bool, optional + animate Whether or not to animate the labelling w/ Write **kwargs @@ -361,7 +373,12 @@ def position_y_coordinate( y_coord.set_color(Y_COLOR) return y_coord - def coords_to_vector(self, vector, coords_start=2 * RIGHT + 2 * UP, clean_up=True): + def coords_to_vector( + self, + vector: np.ndarray | list | tuple, + coords_start: np.ndarray | list | tuple = 2 * RIGHT + 2 * UP, + clean_up: bool = True, + ): """ This method writes the vector as a column matrix (henceforth called the label), takes the values in it one by one, and form the corresponding @@ -370,16 +387,16 @@ def coords_to_vector(self, vector, coords_start=2 * RIGHT + 2 * UP, clean_up=Tru Parameters ---------- - vector : np.ndarray, list, tuple + vector The vector to show. - coords_start : np.ndarray,list,tuple, optional + coords_start The starting point of the location of the label of the vector that shows it numerically. Defaults to 2 * RIGHT + 2 * UP or (2,2) - clean_up : bool, optional + clean_up Whether or not to remove whatever this method did after it's done. @@ -419,7 +436,12 @@ def coords_to_vector(self, vector, coords_start=2 * RIGHT + 2 * UP, clean_up=Tru self.clear() self.add(*starting_mobjects) - def vector_to_coords(self, vector, integer_labels=True, clean_up=True): + def vector_to_coords( + self, + vector: np.ndarray | list | tuple, + integer_labels: bool = True, + clean_up: bool = True, + ): """ This method displays vector as a Vector() based vector, and then shows the corresponding lines that make up the x and y components of the vector. @@ -428,14 +450,14 @@ def vector_to_coords(self, vector, integer_labels=True, clean_up=True): Parameters ---------- - vector : np.ndarray, list, tuple + vector The vector to show. - integer_label : bool, optional + integer_labels Whether or not to round the value displayed. in the vector's label to the nearest integer - clean_up : bool, optional + clean_up Whether or not to remove whatever this method did after it's done. @@ -477,7 +499,7 @@ def vector_to_coords(self, vector, integer_labels=True, clean_up=True): self.add(*starting_mobjects) return array, x_line, y_line - def show_ghost_movement(self, vector): + def show_ghost_movement(self, vector: Arrow | list | tuple | np.ndarray): """ This method plays an animation that partially shows the entire plane moving in the direction of a particular vector. This is useful when you wish to @@ -486,7 +508,7 @@ def show_ghost_movement(self, vector): Parameters ---------- - vector : Arrow, list, tuple, np.ndarray + vector The vector which indicates the direction of movement. """ if isinstance(vector, Arrow): @@ -545,11 +567,12 @@ class LinearTransformationScene(VectorScene): .. manim:: LinearTransformationSceneExample class LinearTransformationSceneExample(LinearTransformationScene): - def __init__(self): + def __init__(self, **kwargs): LinearTransformationScene.__init__( self, show_coordinates=True, leave_ghost_vectors=True, + **kwargs ) def construct(self): @@ -567,12 +590,11 @@ def __init__( show_coordinates: bool = False, show_basis_vectors: bool = True, basis_vector_stroke_width: float = 6, - i_hat_color: Color = X_COLOR, - j_hat_color: Color = Y_COLOR, + i_hat_color: ParsableManimColor = X_COLOR, + j_hat_color: ParsableManimColor = Y_COLOR, leave_ghost_vectors: bool = False, **kwargs, ): - super().__init__(**kwargs) self.include_background_plane = include_background_plane @@ -580,8 +602,8 @@ def __init__( self.show_coordinates = show_coordinates self.show_basis_vectors = show_basis_vectors self.basis_vector_stroke_width = basis_vector_stroke_width - self.i_hat_color = i_hat_color - self.j_hat_color = j_hat_color + self.i_hat_color = ManimColor(i_hat_color) + self.j_hat_color = ManimColor(j_hat_color) self.leave_ghost_vectors = leave_ghost_vectors self.background_plane_kwargs = { "color": GREY, @@ -594,6 +616,8 @@ def __init__( }, } + self.ghost_vectors = VGroup() + self.foreground_plane_kwargs = { "x_range": np.array([-config["frame_width"], config["frame_width"], 1.0]), "y_range": np.array([-config["frame_width"], config["frame_width"], 1.0]), @@ -641,18 +665,18 @@ def setup(self): self.i_hat, self.j_hat = self.basis_vectors self.add(self.basis_vectors) - def add_special_mobjects(self, mob_list, *mobs_to_add): + def add_special_mobjects(self, mob_list: list, *mobs_to_add: Mobject): """ Adds mobjects to a separate list that can be tracked, if these mobjects have some extra importance. Parameters ---------- - mob_list : list + mob_list The special list to which you want to add these mobjects. - *mobs_to_add : Mobject + *mobs_to_add The mobjects to add. """ @@ -661,44 +685,46 @@ def add_special_mobjects(self, mob_list, *mobs_to_add): mob_list.append(mobject) self.add(mobject) - def add_background_mobject(self, *mobjects): + def add_background_mobject(self, *mobjects: Mobject): """ Adds the mobjects to the special list self.background_mobjects. Parameters ---------- - *mobjects : Mobject + *mobjects The mobjects to add to the list. """ self.add_special_mobjects(self.background_mobjects, *mobjects) # TODO, this conflicts with Scene.add_fore - def add_foreground_mobject(self, *mobjects): + def add_foreground_mobject(self, *mobjects: Mobject): """ Adds the mobjects to the special list self.foreground_mobjects. Parameters ---------- - *mobjects : Mobject + *mobjects The mobjects to add to the list """ self.add_special_mobjects(self.foreground_mobjects, *mobjects) - def add_transformable_mobject(self, *mobjects): + def add_transformable_mobject(self, *mobjects: Mobject): """ Adds the mobjects to the special list self.transformable_mobjects. Parameters ---------- - *mobjects : Mobject + *mobjects The mobjects to add to the list. """ self.add_special_mobjects(self.transformable_mobjects, *mobjects) - def add_moving_mobject(self, mobject, target_mobject=None): + def add_moving_mobject( + self, mobject: Mobject, target_mobject: Mobject | None = None + ): """ Adds the mobject to the special list self.moving_mobject, and adds a property @@ -708,28 +734,37 @@ def add_moving_mobject(self, mobject, target_mobject=None): Parameters ---------- - mobject : Mobject + mobject The mobjects to add to the list - target_mobject : Mobject, optional + target_mobject What the moving_mobject goes to, etc. """ mobject.target = target_mobject self.add_special_mobjects(self.moving_mobjects, mobject) - def get_unit_square(self, color=YELLOW, opacity=0.3, stroke_width=3): + def get_ghost_vectors(self) -> VGroup: + """ + Returns all ghost vectors ever added to ``self``. Each element is a ``VGroup`` of + two ghost vectors. + """ + return self.ghost_vectors + + def get_unit_square( + self, color: str = YELLOW, opacity: float = 0.3, stroke_width: float = 3 + ): """ Returns a unit square for the current NumberPlane. Parameters ---------- - color : str, optional + color The string of the hex color code of the color wanted. - opacity : float, int, optional + opacity The opacity of the square - stroke_width : int, float, optional + stroke_width The stroke_width in pixels of the border of the square Returns @@ -748,14 +783,14 @@ def get_unit_square(self, color=YELLOW, opacity=0.3, stroke_width=3): square.move_to(self.plane.coords_to_point(0, 0), DL) return square - def add_unit_square(self, animate=False, **kwargs): + def add_unit_square(self, animate: bool = False, **kwargs): """ Adds a unit square to the scene via self.get_unit_square. Parameters ---------- - animate (bool) + animate Whether or not to animate the addition with DrawBorderThenFill. **kwargs @@ -778,18 +813,20 @@ def add_unit_square(self, animate=False, **kwargs): self.square = square return self - def add_vector(self, vector, color=YELLOW, **kwargs): + def add_vector( + self, vector: Arrow | list | tuple | np.ndarray, color: str = YELLOW, **kwargs + ): """ Adds a vector to the scene, and puts it in the special list self.moving_vectors. Parameters ---------- - vector : Arrow,list,tuple,np.ndarray + vector It can be a pre-made graphical vector, or the coordinates of one. - color : str + color The string of the hex color of the vector. This is only taken into consideration if 'vector' is not an Arrow. Defaults to YELLOW. @@ -806,7 +843,7 @@ def add_vector(self, vector, color=YELLOW, **kwargs): self.moving_vectors.append(vector) return vector - def write_vector_coordinates(self, vector, **kwargs): + def write_vector_coordinates(self, vector: Arrow, **kwargs): """ Returns a column matrix indicating the vector coordinates, after writing them to the screen, and adding them to the @@ -814,7 +851,7 @@ def write_vector_coordinates(self, vector, **kwargs): Parameters ---------- - vector : Arrow + vector The arrow representing the vector. **kwargs @@ -830,7 +867,12 @@ def write_vector_coordinates(self, vector, **kwargs): return coords def add_transformable_label( - self, vector, label, transformation_name="L", new_label=None, **kwargs + self, + vector: Vector, + label: MathTex | str, + transformation_name: str | MathTex = "L", + new_label: str | MathTex | None = None, + **kwargs, ): """ Method for creating, and animating the addition of @@ -838,16 +880,16 @@ def add_transformable_label( Parameters ---------- - vector : Vector + vector The vector for which the label must be added. - label : Union[:class:`~.MathTex`, :class:`str`] + label The MathTex/string of the label. - transformation_name : Union[:class:`str`, :class:`~.MathTex`], optional + transformation_name The name to give the transformation as a label. - new_label : Union[:class:`str`, :class:`~.MathTex`], optional + new_label What the label should display after a Linear Transformation **kwargs @@ -862,9 +904,8 @@ def add_transformable_label( if new_label: label_mob.target_text = new_label else: - label_mob.target_text = "{}({})".format( - transformation_name, - label_mob.get_tex_string(), + label_mob.target_text = ( + f"{transformation_name}({label_mob.get_tex_string()})" ) label_mob.vector = vector label_mob.kwargs = kwargs @@ -873,7 +914,12 @@ def add_transformable_label( self.transformable_labels.append(label_mob) return label_mob - def add_title(self, title, scale_factor=1.5, animate=False): + def add_title( + self, + title: str | MathTex | Tex, + scale_factor: float = 1.5, + animate: bool = False, + ): """ Adds a title, after scaling it, adding a background rectangle, moving it to the top and adding it to foreground_mobjects adding @@ -881,13 +927,13 @@ def add_title(self, title, scale_factor=1.5, animate=False): Parameters ---------- - title : Union[:class:`str`, :class:`~.MathTex`, :class:`~.Tex`] + title What the title should be. - scale_factor : int, float, optional + scale_factor How much the title should be scaled by. - animate : bool + animate Whether or not to animate the addition. Returns @@ -905,19 +951,21 @@ def add_title(self, title, scale_factor=1.5, animate=False): self.title = title return self - def get_matrix_transformation(self, matrix): + def get_matrix_transformation(self, matrix: np.ndarray | list | tuple): """ Returns a function corresponding to the linear transformation represented by the matrix passed. Parameters ---------- - matrix : np.ndarray, list, tuple + matrix The matrix. """ return self.get_transposed_matrix_transformation(np.array(matrix).T) - def get_transposed_matrix_transformation(self, transposed_matrix): + def get_transposed_matrix_transformation( + self, transposed_matrix: np.ndarray | list | tuple + ): """ Returns a function corresponding to the linear transformation represented by the transposed @@ -925,7 +973,7 @@ def get_transposed_matrix_transformation(self, transposed_matrix): Parameters ---------- - matrix : np.ndarray, list, tuple + transposed_matrix The matrix. """ transposed_matrix = np.array(transposed_matrix) @@ -937,7 +985,7 @@ def get_transposed_matrix_transformation(self, transposed_matrix): raise ValueError("Matrix has bad dimensions") return lambda point: np.dot(point, transposed_matrix) - def get_piece_movement(self, pieces): + def get_piece_movement(self, pieces: list | tuple | np.ndarray): """ This method returns an animation that moves an arbitrary mobject in "pieces" to its corresponding .target value. @@ -946,7 +994,7 @@ def get_piece_movement(self, pieces): Parameters ---------- - pieces : list, tuple, np.array + pieces The pieces for which the movement must be shown. Returns @@ -954,13 +1002,18 @@ def get_piece_movement(self, pieces): Animation The animation of the movement. """ - start = VGroup(*pieces) - target = VGroup(*(mob.target for mob in pieces)) - if self.leave_ghost_vectors: - self.add(start.copy().fade(0.7)) + v_pieces = [piece for piece in pieces if isinstance(piece, VMobject)] + start = VGroup(*v_pieces) + target = VGroup(*(mob.target for mob in v_pieces)) + + # don't add empty VGroups + if self.leave_ghost_vectors and start.submobjects: + # start.copy() gives a VGroup of Vectors + self.ghost_vectors.add(start.copy().fade(0.7)) + self.add(self.ghost_vectors[-1]) return Transform(start, target, lag_ratio=0) - def get_moving_mobject_movement(self, func): + def get_moving_mobject_movement(self, func: Callable[[np.ndarray], np.ndarray]): """ This method returns an animation that moves a mobject in "self.moving_mobjects" to its corresponding .target value. @@ -969,7 +1022,7 @@ def get_moving_mobject_movement(self, func): Parameters ---------- - func : function + func The function that determines where the .target of the moving mobject goes. @@ -985,7 +1038,7 @@ def get_moving_mobject_movement(self, func): m.target.move_to(target_point) return self.get_piece_movement(self.moving_mobjects) - def get_vector_movement(self, func): + def get_vector_movement(self, func: Callable[[np.ndarray], np.ndarray]): """ This method returns an animation that moves a mobject in "self.moving_vectors" to its corresponding .target value. @@ -994,7 +1047,7 @@ def get_vector_movement(self, func): Parameters ---------- - func : function + func The function that determines where the .target of the moving mobject goes. @@ -1026,7 +1079,7 @@ def get_transformable_label_movement(self): ) return self.get_piece_movement(self.transformable_labels) - def apply_matrix(self, matrix, **kwargs): + def apply_matrix(self, matrix: np.ndarray | list | tuple, **kwargs): """ Applies the transformation represented by the given matrix to the number plane, and each vector/similar @@ -1034,14 +1087,14 @@ def apply_matrix(self, matrix, **kwargs): Parameters ---------- - matrix : np.ndarray, list, tuple + matrix The matrix. **kwargs Any valid keyword argument of self.apply_transposed_matrix() """ self.apply_transposed_matrix(np.array(matrix).T, **kwargs) - def apply_inverse(self, matrix, **kwargs): + def apply_inverse(self, matrix: np.ndarray | list | tuple, **kwargs): """ This method applies the linear transformation represented by the inverse of the passed matrix @@ -1049,14 +1102,16 @@ def apply_inverse(self, matrix, **kwargs): Parameters ---------- - matrix : np.ndarray, list, tuple + matrix The matrix whose inverse is to be applied. **kwargs Any valid keyword argument of self.apply_matrix() """ self.apply_matrix(np.linalg.inv(matrix), **kwargs) - def apply_transposed_matrix(self, transposed_matrix, **kwargs): + def apply_transposed_matrix( + self, transposed_matrix: np.ndarray | list | tuple, **kwargs + ): """ Applies the transformation represented by the given transposed matrix to the number plane, @@ -1064,7 +1119,7 @@ def apply_transposed_matrix(self, transposed_matrix, **kwargs): Parameters ---------- - matrix : np.ndarray, list, tuple + transposed_matrix The matrix. **kwargs Any valid keyword argument of self.apply_function() @@ -1077,7 +1132,7 @@ def apply_transposed_matrix(self, transposed_matrix, **kwargs): kwargs["path_arc"] = net_rotation self.apply_function(func, **kwargs) - def apply_inverse_transpose(self, t_matrix, **kwargs): + def apply_inverse_transpose(self, t_matrix: np.ndarray | list | tuple, **kwargs): """ Applies the inverse of the transformation represented by the given transposed matrix to the number plane and each @@ -1085,7 +1140,7 @@ def apply_inverse_transpose(self, t_matrix, **kwargs): Parameters ---------- - matrix : np.ndarray, list, tuple + t_matrix The matrix. **kwargs Any valid keyword argument of self.apply_transposed_matrix() @@ -1093,7 +1148,9 @@ def apply_inverse_transpose(self, t_matrix, **kwargs): t_inv = np.linalg.inv(np.array(t_matrix).T).T self.apply_transposed_matrix(t_inv, **kwargs) - def apply_nonlinear_transformation(self, function, **kwargs): + def apply_nonlinear_transformation( + self, function: Callable[[np.ndarray], np.ndarray], **kwargs + ): """ Applies the non-linear transformation represented by the given function to the number plane and each @@ -1101,7 +1158,7 @@ def apply_nonlinear_transformation(self, function, **kwargs): Parameters ---------- - function : Function + function The function. **kwargs Any valid keyword argument of self.apply_function() @@ -1109,7 +1166,12 @@ def apply_nonlinear_transformation(self, function, **kwargs): self.plane.prepare_for_nonlinear_transform() self.apply_function(function, **kwargs) - def apply_function(self, function, added_anims=[], **kwargs): + def apply_function( + self, + function: Callable[[np.ndarray], np.ndarray], + added_anims: list = [], + **kwargs, + ): """ Applies the given function to each of the mobjects in self.transformable_mobjects, and plays the animation showing @@ -1117,11 +1179,11 @@ def apply_function(self, function, added_anims=[], **kwargs): Parameters ---------- - function : Function + function The function that affects each point of each mobject in self.transformable_mobjects. - added_anims : list, optional + added_anims Any other animations that need to be played simultaneously with this. diff --git a/manim/scene/zoomed_scene.py b/manim/scene/zoomed_scene.py index 06bc2213ee..361c4eaf55 100644 --- a/manim/scene/zoomed_scene.py +++ b/manim/scene/zoomed_scene.py @@ -132,14 +132,14 @@ def setup(self): self.zoomed_camera = zoomed_camera self.zoomed_display = zoomed_display - def activate_zooming(self, animate=False): + def activate_zooming(self, animate: bool = False): """ This method is used to activate the zooming for the zoomed_camera. Parameters ---------- - animate : bool, optional + animate Whether or not to animate the activation of the zoomed camera. """ @@ -153,13 +153,13 @@ def activate_zooming(self, animate=False): self.zoomed_display, ) - def get_zoom_in_animation(self, run_time=2, **kwargs): + def get_zoom_in_animation(self, run_time: float = 2, **kwargs): """ Returns the animation of camera zooming in. Parameters ---------- - run_time : int or float, optional + run_time The run_time of the animation of the camera zooming in. **kwargs Any valid keyword arguments of ApplyMethod() diff --git a/manim/typing.py b/manim/typing.py new file mode 100644 index 0000000000..660b4a1821 --- /dev/null +++ b/manim/typing.py @@ -0,0 +1,893 @@ +"""Custom type definitions used in Manim. + +.. admonition:: Note for developers + :class: important + + Around the source code there are multiple strings which look like this: + + .. code-block:: + + ''' + [CATEGORY] + + ''' + + All type aliases defined under those strings will be automatically + classified under that category. + + If you need to define a new category, respect the format described above. +""" + +from __future__ import annotations + +from collections.abc import Sequence +from os import PathLike +from typing import Callable, Union + +import numpy as np +import numpy.typing as npt +from typing_extensions import TypeAlias + +__all__ = [ + "ManimFloat", + "ManimInt", + "ManimColorDType", + "RGB_Array_Float", + "RGB_Tuple_Float", + "RGB_Array_Int", + "RGB_Tuple_Int", + "RGBA_Array_Float", + "RGBA_Tuple_Float", + "RGBA_Array_Int", + "RGBA_Tuple_Int", + "HSV_Array_Float", + "HSV_Tuple_Float", + "HSL_Array_Float", + "HSL_Tuple_Float", + "HSVA_Array_Float", + "HSVA_Tuple_Float", + "ManimColorInternal", + "PointDType", + "Point2D", + "Point2DLike", + "Point2D_Array", + "Point2DLike_Array", + "Point3D", + "Point3DLike", + "Point3D_Array", + "Point3DLike_Array", + "PointND", + "PointNDLike", + "PointND_Array", + "PointNDLike_Array", + "Vector2D", + "Vector2D_Array", + "Vector3D", + "Vector3D_Array", + "VectorND", + "VectorND_Array", + "RowVector", + "ColVector", + "MatrixMN", + "Zeros", + "QuadraticBezierPoints", + "QuadraticBezierPointsLike", + "QuadraticBezierPoints_Array", + "QuadraticBezierPointsLike_Array", + "QuadraticBezierPath", + "QuadraticBezierPathLike", + "QuadraticSpline", + "QuadraticSplineLike", + "CubicBezierPoints", + "CubicBezierPointsLike", + "CubicBezierPoints_Array", + "CubicBezierPointsLike_Array", + "CubicBezierPath", + "CubicBezierPathLike", + "CubicSpline", + "CubicSplineLike", + "BezierPoints", + "BezierPointsLike", + "BezierPoints_Array", + "BezierPointsLike_Array", + "BezierPath", + "BezierPathLike", + "Spline", + "SplineLike", + "FlatBezierPoints", + "FunctionOverride", + "PathFuncType", + "MappingFunction", + "MultiMappingFunction", + "PixelArray", + "GrayscalePixelArray", + "RGBPixelArray", + "RGBAPixelArray", + "StrPath", + "StrOrBytesPath", +] + + +""" +[CATEGORY] +Primitive data types +""" + +ManimFloat: TypeAlias = np.float64 +"""A double-precision floating-point value (64 bits, or 8 bytes), +according to the IEEE 754 standard. +""" + +ManimInt: TypeAlias = np.int64 +r"""A long integer (64 bits, or 8 bytes). + +It can take values between :math:`-2^{63}` and :math:`+2^{63} - 1`, +which expressed in base 10 is a range between around +:math:`-9.223 \cdot 10^{18}` and :math:`+9.223 \cdot 10^{18}`. +""" + + +""" +[CATEGORY] +Color types +""" + +ManimColorDType: TypeAlias = ManimFloat +"""Data type used in :class:`~.ManimColorInternal`: a +double-precision float between 0 and 1. +""" + +RGB_Array_Float: TypeAlias = npt.NDArray[ManimColorDType] +"""``shape: (3,)`` + +A :class:`numpy.ndarray` of 3 floats between 0 and 1, representing a +color in RGB format. + +Its components describe, in order, the intensity of Red, Green, and +Blue in the represented color. +""" + +RGB_Tuple_Float: TypeAlias = tuple[float, float, float] +"""``shape: (3,)`` + +A tuple of 3 floats between 0 and 1, representing a color in RGB +format. + +Its components describe, in order, the intensity of Red, Green, and +Blue in the represented color. +""" + +RGB_Array_Int: TypeAlias = npt.NDArray[ManimInt] +"""``shape: (3,)`` + +A :class:`numpy.ndarray` of 3 integers between 0 and 255, +representing a color in RGB format. + +Its components describe, in order, the intensity of Red, Green, and +Blue in the represented color. +""" + +RGB_Tuple_Int: TypeAlias = tuple[int, int, int] +"""``shape: (3,)`` + +A tuple of 3 integers between 0 and 255, representing a color in RGB +format. + +Its components describe, in order, the intensity of Red, Green, and +Blue in the represented color. +""" + +RGBA_Array_Float: TypeAlias = npt.NDArray[ManimColorDType] +"""``shape: (4,)`` + +A :class:`numpy.ndarray` of 4 floats between 0 and 1, representing a +color in RGBA format. + +Its components describe, in order, the intensity of Red, Green, Blue +and Alpha (opacity) in the represented color. +""" + +RGBA_Tuple_Float: TypeAlias = tuple[float, float, float, float] +"""``shape: (4,)`` + +A tuple of 4 floats between 0 and 1, representing a color in RGBA +format. + +Its components describe, in order, the intensity of Red, Green, Blue +and Alpha (opacity) in the represented color. +""" + +RGBA_Array_Int: TypeAlias = npt.NDArray[ManimInt] +"""``shape: (4,)`` + +A :class:`numpy.ndarray` of 4 integers between 0 and 255, +representing a color in RGBA format. + +Its components describe, in order, the intensity of Red, Green, Blue +and Alpha (opacity) in the represented color. +""" + +RGBA_Tuple_Int: TypeAlias = tuple[int, int, int, int] +"""``shape: (4,)`` + +A tuple of 4 integers between 0 and 255, representing a color in RGBA +format. + +Its components describe, in order, the intensity of Red, Green, Blue +and Alpha (opacity) in the represented color. +""" + +HSV_Array_Float: TypeAlias = RGB_Array_Float +"""``shape: (3,)`` + +A :class:`numpy.ndarray` of 3 floats between 0 and 1, representing a +color in HSV (or HSB) format. + +Its components describe, in order, the Hue, Saturation and Value (or +Brightness) in the represented color. +""" + +HSV_Tuple_Float: TypeAlias = RGB_Tuple_Float +"""``shape: (3,)`` + +A tuple of 3 floats between 0 and 1, representing a color in HSV (or +HSB) format. + +Its components describe, in order, the Hue, Saturation and Value (or +Brightness) in the represented color. +""" + +HSVA_Array_Float: TypeAlias = RGBA_Array_Float +"""``shape: (4,)`` + +A :class:`numpy.ndarray` of 4 floats between 0 and 1, representing a +color in HSVA (or HSBA) format. + +Its components describe, in order, the Hue, Saturation and Value (or +Brightness) in the represented color. +""" + +HSVA_Tuple_Float: TypeAlias = RGBA_Tuple_Float +"""``shape: (4,)`` + +A tuple of 4 floats between 0 and 1, representing a color in HSVA (or +HSBA) format. + +Its components describe, in order, the Hue, Saturation and Value (or +Brightness) in the represented color. +""" + +HSL_Array_Float: TypeAlias = RGB_Array_Float +"""``shape: (3,)`` + +A :class:`numpy.ndarray` of 3 floats between 0 and 1, representing a +color in HSL format. + +Its components describe, in order, the Hue, Saturation and Lightness +in the represented color. +""" + +HSL_Tuple_Float: TypeAlias = RGB_Tuple_Float +"""``shape: (3,)`` + +A :class:`numpy.ndarray` of 3 floats between 0 and 1, representing a +color in HSL format. + +Its components describe, in order, the Hue, Saturation and Lightness +in the represented color. +""" + +ManimColorInternal: TypeAlias = RGBA_Array_Float +"""``shape: (4,)`` + +Internal color representation used by :class:`~.ManimColor`, +following the RGBA format. + +It is a :class:`numpy.ndarray` consisting of 4 floats between 0 and +1, describing respectively the intensities of Red, Green, Blue and +Alpha (opacity) in the represented color. +""" + + +""" +[CATEGORY] +Point types +""" + +PointDType: TypeAlias = ManimFloat +"""Default type for arrays representing points: a double-precision +floating point value. +""" + +Point2D: TypeAlias = npt.NDArray[PointDType] +"""``shape: (2,)`` + +A NumPy array representing a 2-dimensional point: ``[float, float]``. +""" + +Point2DLike: TypeAlias = Union[Point2D, tuple[float, float]] +"""``shape: (2,)`` + +A 2-dimensional point: ``[float, float]``. + +This represents anything which can be converted to a :class:`Point2D` NumPy +array. + +Normally, a function or method which expects a `Point2D` as a +parameter can handle being passed a `Point3D` instead. +""" + +Point2D_Array: TypeAlias = npt.NDArray[PointDType] +"""``shape: (M, 2)`` + +A NumPy array representing a sequence of `Point2D` objects: +``[[float, float], ...]``. +""" + +Point2DLike_Array: TypeAlias = Union[Point2D_Array, Sequence[Point2DLike]] +"""``shape: (M, 2)`` + +An array of `Point2DLike` objects: ``[[float, float], ...]``. + +This represents anything which can be converted to a :class:`Point2D_Array` +NumPy array. + +Normally, a function or method which expects a `Point2D_Array` as a +parameter can handle being passed a `Point3D_Array` instead. + +Please refer to the documentation of the function you are using for +further type information. +""" + +Point3D: TypeAlias = npt.NDArray[PointDType] +"""``shape: (3,)`` + +A NumPy array representing a 3-dimensional point: ``[float, float, float]``. +""" + +Point3DLike: TypeAlias = Union[Point3D, tuple[float, float, float]] +"""``shape: (3,)`` + +A 3-dimensional point: ``[float, float, float]``. + +This represents anything which can be converted to a :class:`Point3D` NumPy +array. +""" + +Point3D_Array: TypeAlias = npt.NDArray[PointDType] +"""``shape: (M, 3)`` + +A NumPy array representing a sequence of `Point3D` objects: +``[[float, float, float], ...]``. +""" + +Point3DLike_Array: TypeAlias = Union[Point3D_Array, Sequence[Point3DLike]] +"""``shape: (M, 3)`` + +An array of `Point3D` objects: ``[[float, float, float], ...]``. + +This represents anything which can be converted to a :class:`Point3D_Array` +NumPy array. + +Please refer to the documentation of the function you are using for +further type information. +""" + +PointND: TypeAlias = npt.NDArray[PointDType] +"""``shape: (N,)`` + +A NumPy array representing an N-dimensional point: ``[float, ...]``. +""" + +PointNDLike: TypeAlias = Union[PointND, Sequence[float]] +"""``shape: (N,)`` + +An N-dimensional point: ``[float, ...]``. + +This represents anything which can be converted to a :class:`PointND` NumPy +array. +""" + +PointND_Array: TypeAlias = npt.NDArray[PointDType] +"""``shape: (M, N)`` + +A NumPy array representing a sequence of `PointND` objects: +``[[float, ...], ...]``. +""" + +PointNDLike_Array: TypeAlias = Union[PointND_Array, Sequence[PointNDLike]] +"""``shape: (M, N)`` + +An array of `PointND` objects: ``[[float, ...], ...]``. + +This represents anything which can be converted to a :class:`PointND_Array` +NumPy array. + +Please refer to the documentation of the function you are using for +further type information. +""" + + +""" +[CATEGORY] +Vector types +""" + +Vector2D: TypeAlias = npt.NDArray[PointDType] +"""``shape: (2,)`` + +A 2-dimensional vector: ``[float, float]``. + +Normally, a function or method which expects a `Vector2D` as a +parameter can handle being passed a `Vector3D` instead. + +.. caution:: + Do not confuse with the :class:`~.Vector` or :class:`~.Arrow` + VMobjects! +""" + +Vector2D_Array: TypeAlias = npt.NDArray[PointDType] +"""``shape: (M, 2)`` + +An array of `Vector2D` objects: ``[[float, float], ...]``. + +Normally, a function or method which expects a `Vector2D_Array` as a +parameter can handle being passed a `Vector3D_Array` instead. +""" + +Vector3D: TypeAlias = npt.NDArray[PointDType] +"""``shape: (3,)`` + +A 3-dimensional vector: ``[float, float, float]``. + +.. caution:: + Do not confuse with the :class:`~.Vector` or :class:`~.Arrow3D` + VMobjects! +""" + +Vector3D_Array: TypeAlias = npt.NDArray[PointDType] +"""``shape: (M, 3)`` + +An array of `Vector3D` objects: ``[[float, float, float], ...]``. +""" + +VectorND: TypeAlias = npt.NDArray[PointDType] +"""``shape (N,)`` + +An :math:`N`-dimensional vector: ``[float, ...]``. + +.. caution:: + Do not confuse with the :class:`~.Vector` VMobject! This type alias + is named "VectorND" instead of "Vector" to avoid potential name + collisions. +""" + +VectorND_Array: TypeAlias = npt.NDArray[PointDType] +"""``shape (M, N)`` + +An array of `VectorND` objects: ``[[float, ...], ...]``. +""" + +RowVector: TypeAlias = npt.NDArray[PointDType] +"""``shape: (1, N)`` + +A row vector: ``[[float, ...]]``. +""" + +ColVector: TypeAlias = npt.NDArray[PointDType] +"""``shape: (N, 1)`` + +A column vector: ``[[float], [float], ...]``. +""" + + +""" +[CATEGORY] +Matrix types +""" + +MatrixMN: TypeAlias = npt.NDArray[PointDType] +"""``shape: (M, N)`` + +A matrix: ``[[float, ...], [float, ...], ...]``. +""" + +Zeros: TypeAlias = MatrixMN +"""``shape: (M, N)`` + +A `MatrixMN` filled with zeros, typically created with +``numpy.zeros((M, N))``. +""" + + +""" +[CATEGORY] +Bézier types +""" + +QuadraticBezierPoints: TypeAlias = Point3D_Array +"""``shape: (3, 3)`` + +A `Point3D_Array` of three 3D control points for a single quadratic Bézier +curve: +``[[float, float, float], [float, float, float], [float, float, float]]``. +""" + +QuadraticBezierPointsLike: TypeAlias = Union[ + QuadraticBezierPoints, tuple[Point3DLike, Point3DLike, Point3DLike] +] +"""``shape: (3, 3)`` + +A `Point3DLike_Array` of three 3D control points for a single quadratic Bézier +curve: +``[[float, float, float], [float, float, float], [float, float, float]]``. + +This represents anything which can be converted to a +:class:`QuadraticBezierPoints` NumPy array. +""" + +QuadraticBezierPoints_Array: TypeAlias = npt.NDArray[PointDType] +"""``shape: (N, 3, 3)`` + +A NumPy array containing :math:`N` `QuadraticBezierPoints` objects: +``[[[float, float, float], [float, float, float], [float, float, float]], ...]``. +""" + +QuadraticBezierPointsLike_Array: TypeAlias = Union[ + QuadraticBezierPoints_Array, Sequence[QuadraticBezierPointsLike] +] +"""``shape: (N, 3, 3)`` + +A sequence of :math:`N` `QuadraticBezierPointsLike` objects: +``[[[float, float, float], [float, float, float], [float, float, float]], ...]``. + +This represents anything which can be converted to a +:class:`QuadraticBezierPoints_Array` NumPy array. +""" + +QuadraticBezierPath: TypeAlias = Point3D_Array +"""``shape: (3*N, 3)`` + +A `Point3D_Array` of :math:`3N` points, where each one of the +:math:`N` consecutive blocks of 3 points represents a quadratic +Bézier curve: +``[[float, float, float], ...], ...]``. + +Please refer to the documentation of the function you are using for +further type information. +""" + +QuadraticBezierPathLike: TypeAlias = Point3DLike_Array +"""``shape: (3*N, 3)`` + +A `Point3DLike_Array` of :math:`3N` points, where each one of the +:math:`N` consecutive blocks of 3 points represents a quadratic +Bézier curve: +``[[float, float, float], ...], ...]``. + +This represents anything which can be converted to a +:class:`QuadraticBezierPath` NumPy array. + +Please refer to the documentation of the function you are using for +further type information. +""" + +QuadraticSpline: TypeAlias = QuadraticBezierPath +"""``shape: (3*N, 3)`` + +A special case of `QuadraticBezierPath` where all the :math:`N` +quadratic Bézier curves are connected, forming a quadratic spline: +``[[float, float, float], ...], ...]``. + +Please refer to the documentation of the function you are using for +further type information. +""" + +QuadraticSplineLike: TypeAlias = QuadraticBezierPathLike +"""``shape: (3*N, 3)`` + +A special case of `QuadraticBezierPathLike` where all the :math:`N` +quadratic Bézier curves are connected, forming a quadratic spline: +``[[float, float, float], ...], ...]``. + +This represents anything which can be converted to a :class:`QuadraticSpline` +NumPy array. + +Please refer to the documentation of the function you are using for +further type information. +""" + +CubicBezierPoints: TypeAlias = Point3D_Array +"""``shape: (4, 3)`` + +A `Point3D_Array` of four 3D control points for a single cubic Bézier curve: +``[[float, float, float], [float, float, float], [float, float, float], [float, float, float]]``. +""" + +CubicBezierPointsLike: TypeAlias = Union[ + CubicBezierPoints, tuple[Point3DLike, Point3DLike, Point3DLike, Point3DLike] +] +"""``shape: (4, 3)`` + +A `Point3DLike_Array` of 4 control points for a single cubic Bézier curve: +``[[float, float, float], [float, float, float], [float, float, float], [float, float, float]]``. + +This represents anything which can be converted to a :class:`CubicBezierPoints` +NumPy array. +""" + +CubicBezierPoints_Array: TypeAlias = npt.NDArray[PointDType] +"""``shape: (N, 4, 3)`` + +A NumPy array containing :math:`N` `CubicBezierPoints` objects: +``[[[float, float, float], [float, float, float], [float, float, float], [float, float, float]], ...]``. +""" + +CubicBezierPointsLike_Array: TypeAlias = Union[ + CubicBezierPoints_Array, Sequence[CubicBezierPointsLike] +] +"""``shape: (N, 4, 3)`` + +A sequence of :math:`N` `CubicBezierPointsLike` objects: +``[[[float, float, float], [float, float, float], [float, float, float], [float, float, float]], ...]``. + +This represents anything which can be converted to a +:class:`CubicBezierPoints_Array` NumPy array. +""" + +CubicBezierPath: TypeAlias = Point3D_Array +"""``shape: (4*N, 3)`` + +A `Point3D_Array` of :math:`4N` points, where each one of the +:math:`N` consecutive blocks of 4 points represents a cubic Bézier +curve: +``[[float, float, float], ...], ...]``. + +Please refer to the documentation of the function you are using for +further type information. +""" + +CubicBezierPathLike: TypeAlias = Point3DLike_Array +"""``shape: (4*N, 3)`` + +A `Point3DLike_Array` of :math:`4N` points, where each one of the +:math:`N` consecutive blocks of 4 points represents a cubic Bézier +curve: +``[[float, float, float], ...], ...]``. + +This represents anything which can be converted to a +:class:`CubicBezierPath` NumPy array. + +Please refer to the documentation of the function you are using for +further type information. +""" + +CubicSpline: TypeAlias = CubicBezierPath +"""``shape: (4*N, 3)`` + +A special case of `CubicBezierPath` where all the :math:`N` cubic +Bézier curves are connected, forming a quadratic spline: +``[[float, float, float], ...], ...]``. + +Please refer to the documentation of the function you are using for +further type information. +""" + +CubicSplineLike: TypeAlias = CubicBezierPathLike +"""``shape: (4*N, 3)`` + +A special case of `CubicBezierPath` where all the :math:`N` cubic +Bézier curves are connected, forming a quadratic spline: +``[[float, float, float], ...], ...]``. + +This represents anything which can be converted to a +:class:`CubicSpline` NumPy array. + +Please refer to the documentation of the function you are using for +further type information. +""" + +BezierPoints: TypeAlias = Point3D_Array +r"""``shape: (PPC, 3)`` + +A `Point3D_Array` of :math:`\text{PPC}` control points +(:math:`\text{PPC: Points Per Curve} = n + 1`) for a single +:math:`n`-th degree Bézier curve: +``[[float, float, float], ...]``. + +Please refer to the documentation of the function you are using for +further type information. +""" + +BezierPointsLike: TypeAlias = Point3DLike_Array +r"""``shape: (PPC, 3)`` + +A `Point3DLike_Array` of :math:`\text{PPC}` control points +(:math:`\text{PPC: Points Per Curve} = n + 1`) for a single +:math:`n`-th degree Bézier curve: +``[[float, float, float], ...]``. + +This represents anything which can be converted to a +:class:`BezierPoints` NumPy array. + +Please refer to the documentation of the function you are using for +further type information. +""" + +BezierPoints_Array: TypeAlias = npt.NDArray[PointDType] +r"""``shape: (N, PPC, 3)`` + +A NumPy array of :math:`N` `BezierPoints` objects containing +:math:`\text{PPC}` `Point3D` objects each +(:math:`\text{PPC: Points Per Curve} = n + 1`): +``[[[float, float, float], ...], ...]``. + +Please refer to the documentation of the function you are using for +further type information. +""" + +BezierPointsLike_Array: TypeAlias = Union[ + BezierPoints_Array, Sequence[BezierPointsLike] +] +r"""``shape: (N, PPC, 3)`` + +A sequence of :math:`N` `BezierPointsLike` objects containing +:math:`\text{PPC}` `Point3DLike` objects each +(:math:`\text{PPC: Points Per Curve} = n + 1`): +``[[[float, float, float], ...], ...]``. + +This represents anything which can be converted to a +:class:`BezierPoints_Array` NumPy array. + +Please refer to the documentation of the function you are using for +further type information. +""" + +BezierPath: TypeAlias = Point3D_Array +r"""``shape: (PPC*N, 3)`` + +A `Point3D_Array` of :math:`\text{PPC} \cdot N` points, where each +one of the :math:`N` consecutive blocks of :math:`\text{PPC}` control +points (:math:`\text{PPC: Points Per Curve} = n + 1`) represents a +Bézier curve of :math:`n`-th degree: +``[[float, float, float], ...], ...]``. + +Please refer to the documentation of the function you are using for +further type information. +""" + +BezierPathLike: TypeAlias = Point3DLike_Array +r"""``shape: (PPC*N, 3)`` + +A `Point3DLike_Array` of :math:`\text{PPC} \cdot N` points, where each +one of the :math:`N` consecutive blocks of :math:`\text{PPC}` control +points (:math:`\text{PPC: Points Per Curve} = n + 1`) represents a +Bézier curve of :math:`n`-th degree: +``[[float, float, float], ...], ...]``. + +This represents anything which can be converted to a +:class:`BezierPath` NumPy array. + +Please refer to the documentation of the function you are using for +further type information. +""" + +Spline: TypeAlias = BezierPath +r"""``shape: (PPC*N, 3)`` + +A special case of `BezierPath` where all the :math:`N` Bézier curves +consisting of :math:`\text{PPC}` `Point3D` objects +(:math:`\text{PPC: Points Per Curve} = n + 1`) are connected, forming +an :math:`n`-th degree spline: +``[[float, float, float], ...], ...]``. + +Please refer to the documentation of the function you are using for +further type information. +""" + +SplineLike: TypeAlias = BezierPathLike +r"""``shape: (PPC*N, 3)`` + +A special case of `BezierPathLike` where all the :math:`N` Bézier curves +consisting of :math:`\text{PPC}` `Point3D` objects +(:math:`\text{PPC: Points Per Curve} = n + 1`) are connected, forming +an :math:`n`-th degree spline: +``[[float, float, float], ...], ...]``. + +This represents anything which can be converted to a +:class:`Spline` NumPy array. + +Please refer to the documentation of the function you are using for +further type information. +""" + +FlatBezierPoints: TypeAlias = Union[npt.NDArray[PointDType], tuple[float, ...]] +"""``shape: (3*PPC*N,)`` + +A flattened array of Bézier control points: +``[float, ...]``. +""" + + +""" +[CATEGORY] +Function types +""" + +# Due to current limitations +# (see https://github.com/python/mypy/issues/14656 / 8263), +# we don't specify the first argument type (Mobject). +# Nor are we able to specify the return type (Animation) since we cannot import +# that here. +FunctionOverride: TypeAlias = Callable +"""Function type returning an :class:`~.Animation` for the specified +:class:`~.Mobject`. +""" + +PathFuncType: TypeAlias = Callable[[Point3DLike, Point3DLike, float], Point3DLike] +"""Function mapping two :class:`Point3D` objects and an alpha value to a new +:class:`Point3D`. +""" + +MappingFunction: TypeAlias = Callable[[Point3D], Point3D] +"""A function mapping a :class:`Point3D` to another :class:`Point3D`.""" + +MultiMappingFunction: TypeAlias = Callable[[Point3D_Array], Point3D_Array] +"""A function mapping a :class:`Point3D_Array` to another +:class:`Point3D_Array`. +""" + +""" +[CATEGORY] +Image types +""" + +PixelArray: TypeAlias = npt.NDArray[ManimInt] +"""``shape: (height, width) | (height, width, 3) | (height, width, 4)`` + +A rasterized image with a height of ``height`` pixels and a width of +``width`` pixels. + +Every value in the array is an integer from 0 to 255. + +Every pixel is represented either by a single integer indicating its +lightness (for greyscale images), an `RGB_Array_Int` or an +`RGBA_Array_Int`. +""" + +GrayscalePixelArray: TypeAlias = PixelArray +"""``shape: (height, width)`` + +A 100% opaque grayscale `PixelArray`, where every pixel value is a +`ManimInt` indicating its lightness (black -> gray -> white). +""" + +RGBPixelArray: TypeAlias = PixelArray +"""``shape: (height, width, 3)`` + +A 100% opaque `PixelArray` in color, where every pixel value is an +`RGB_Array_Int` object. +""" + +RGBAPixelArray: TypeAlias = PixelArray +"""``shape: (height, width, 4)`` + +A `PixelArray` in color where pixels can be transparent. Every pixel +value is an `RGBA_Array_Int` object. +""" + + +""" +[CATEGORY] +Path types +""" + +StrPath: TypeAlias = Union[str, PathLike[str]] +"""A string or :class:`os.PathLike` representing a path to a +directory or file. +""" + +StrOrBytesPath: TypeAlias = Union[str, bytes, PathLike[str], PathLike[bytes]] +"""A string, bytes or :class:`os.PathLike` object representing a path +to a directory or file. +""" diff --git a/manim/utils/bezier.py b/manim/utils/bezier.py index d96b6af62c..28958309a5 100644 --- a/manim/utils/bezier.py +++ b/manim/utils/bezier.py @@ -5,107 +5,1060 @@ __all__ = [ "bezier", "partial_bezier_points", - "partial_quadratic_bezier_points", + "split_bezier", + "subdivide_bezier", + "bezier_remap", "interpolate", "integer_interpolate", "mid", "inverse_interpolate", "match_interpolate", - "get_smooth_handle_points", "get_smooth_cubic_bezier_handle_points", - "diag_to_matrix", "is_closed", "proportions_along_bezier_curve_for_point", "point_lies_on_bezier", ] -import typing +from collections.abc import Sequence from functools import reduce +from typing import TYPE_CHECKING, Callable, overload import numpy as np -from scipy import linalg -from ..utils.simple_functions import choose -from ..utils.space_ops import cross2d, find_intersection +from manim.utils.simple_functions import choose + +if TYPE_CHECKING: + from manim.typing import ( + BezierPoints, + BezierPoints_Array, + BezierPointsLike, + BezierPointsLike_Array, + ColVector, + MatrixMN, + Point3D, + Point3D_Array, + Point3DLike, + Point3DLike_Array, + QuadraticBezierPath, + QuadraticSpline, + Spline, + ) + +# l is a commonly used name in linear algebra +# ruff: noqa: E741 + + +@overload +def bezier( + points: BezierPointsLike, +) -> Callable[[float | ColVector], Point3D | Point3D_Array]: ... + + +@overload +def bezier( + points: Sequence[Point3DLike_Array], +) -> Callable[[float | ColVector], Point3D_Array]: ... def bezier( - points: np.ndarray, -) -> typing.Callable[[float], int | typing.Iterable]: - """Classic implementation of a bezier curve. + points: Point3D_Array | Sequence[Point3D_Array], +) -> Callable[[float | ColVector], Point3D_Array]: + """Classic implementation of a Bézier curve. Parameters ---------- - points : np.ndarray - points defining the desired bezier curve. + points + :math:`(d+1, 3)`-shaped array of :math:`d+1` control points defining a single Bézier + curve of degree :math:`d`. Alternatively, for vectorization purposes, ``points`` can + also be a :math:`(d+1, M, 3)`-shaped sequence of :math:`d+1` arrays of :math:`M` + control points each, which define `M` Bézier curves instead. Returns ------- - typing.Callable[[float], typing.Union[int, typing.Iterable]] - function describing the bezier curve. + bezier_func : :class:`typing.Callable` [[:class:`float` | :class:`~.ColVector`], :class:`~.Point3D` | :class:`~.Point3D_Array`] + Function describing the Bézier curve. The behaviour of this function depends on + the shape of ``points``: + + * If ``points`` was a :math:`(d+1, 3)` array representing a single Bézier curve, + then ``bezier_func`` can receive either: + + * a :class:`float` ``t``, in which case it returns a + single :math:`(1, 3)`-shaped :class:`~.Point3D` representing the evaluation + of the Bézier at ``t``, or + * an :math:`(n, 1)`-shaped :class:`~.ColVector` + containing :math:`n` values to evaluate the Bézier curve at, returning instead + an :math:`(n, 3)`-shaped :class:`~.Point3D_Array` containing the points + resulting from evaluating the Bézier at each of the :math:`n` values. + .. warning:: + If passing a vector of :math:`t`-values to ``bezier_func``, it **must** + be a column vector/matrix of shape :math:`(n, 1)`. Passing an 1D array of + shape :math:`(n,)` is not supported and **will result in undefined behaviour**. + + * If ``points`` was a :math:`(d+1, M, 3)` array describing :math:`M` Bézier curves, + then ``bezier_func`` can receive either: + + * a :class:`float` ``t``, in which case it returns an + :math:`(M, 3)`-shaped :class:`~.Point3D_Array` representing the evaluation + of the :math:`M` Bézier curves at the same value ``t``, or + * an :math:`(M, 1)`-shaped + :class:`~.ColVector` containing :math:`M` values, such that the :math:`i`-th + Bézier curve defined by ``points`` is evaluated at the corresponding :math:`i`-th + value in ``t``, returning again an :math:`(M, 3)`-shaped :class:`~.Point3D_Array` + containing those :math:`M` evaluations. + .. warning:: + Unlike the previous case, if you pass a :class:`~.ColVector` to ``bezier_func``, + it **must** contain exactly :math:`M` values, each value for each of the :math:`M` + Bézier curves defined by ``points``. Any array of shape other than :math:`(M, 1)` + **will result in undefined behaviour**. """ - n = len(points) - 1 - return lambda t: sum( - ((1 - t) ** (n - k)) * (t**k) * choose(n, k) * point - for k, point in enumerate(points) - ) + P = np.asarray(points) + degree = P.shape[0] - 1 + + if degree == 0: + + def zero_bezier(t: float | ColVector) -> Point3D | Point3D_Array: + return np.ones_like(t) * P[0] + + return zero_bezier + if degree == 1: -def partial_bezier_points(points: np.ndarray, a: float, b: float) -> np.ndarray: - """Given an array of points which define bezier curve, and two numbers 0<=a Point3D | Point3D_Array: + return P[0] + t * (P[1] - P[0]) - This algorithm is pretty nifty, and pretty dense. + return linear_bezier + + if degree == 2: + + def quadratic_bezier(t: float | ColVector) -> Point3D | Point3D_Array: + t2 = t * t + mt = 1 - t + mt2 = mt * mt + return mt2 * P[0] + 2 * t * mt * P[1] + t2 * P[2] + + return quadratic_bezier + + if degree == 3: + + def cubic_bezier(t: float | ColVector) -> Point3D | Point3D_Array: + t2 = t * t + t3 = t2 * t + mt = 1 - t + mt2 = mt * mt + mt3 = mt2 * mt + return mt3 * P[0] + 3 * t * mt2 * P[1] + 3 * t2 * mt * P[2] + t3 * P[3] + + return cubic_bezier + + def nth_grade_bezier(t: float | ColVector) -> Point3D | Point3D_Array: + is_scalar = not isinstance(t, np.ndarray) + if is_scalar: + B = np.empty((1, *P.shape)) + else: + assert isinstance(t, np.ndarray) + t = t.reshape(-1, *[1 for dim in P.shape]) + B = np.empty((t.shape[0], *P.shape)) + B[:] = P + + for i in range(degree): + # After the i-th iteration (i in [0, ..., d-1]) there are evaluations at t + # of (d-i) Bezier curves of grade (i+1), stored in the first d-i slots of B + B[:, : degree - i] += t * (B[:, 1 : degree - i + 1] - B[:, : degree - i]) + + # In the end, there shall be the evaluation at t of a single Bezier curve of + # grade d, stored in the first slot of B + if is_scalar: + val: Point3D = B[0, 0] + return val + return B[:, 0] + + return nth_grade_bezier + + +def partial_bezier_points(points: BezierPointsLike, a: float, b: float) -> BezierPoints: + r"""Given an array of ``points`` which define a Bézier curve, and two numbers :math:`a, b` + such that :math:`0 \le a < b \le 1`, return an array of the same size, which describes the + portion of the original Bézier curve on the interval :math:`[a, b]`. + + :func:`partial_bezier_points` is conceptually equivalent to calling :func:`split_bezier` + twice and discarding unused Bézier curves, but this is more efficient and doesn't waste + computations. + + .. seealso:: + See :func:`split_bezier` for an explanation on how to split Bézier curves. + + .. note:: + To find the portion of a Bézier curve with :math:`t` between :math:`a` and :math:`b`: + + 1. Split the curve at :math:`t = a` and extract its 2nd subcurve. + 2. We cannot evaluate the new subcurve at :math:`t = b` because its range of values for :math:`t` is different. + To find the correct value, we need to transform the interval :math:`[a, 1]` into :math:`[0, 1]` + by first subtracting :math:`a` to get :math:`[0, 1-a]` and then dividing by :math:`1-a`. Thus, our new + value must be :math:`t = \frac{b - a}{1 - a}`. Define :math:`u = \frac{b - a}{1 - a}`. + 3. Split the subcurve at :math:`t = u` and extract its 1st subcurve. + + The final portion is a linear combination of points, and thus the process can be + summarized as a linear transformation by some matrix in terms of :math:`a` and :math:`b`. + This matrix is given explicitly for Bézier curves up to degree 3, which are often used in Manim. + For higher degrees, the algorithm described previously is used. + + For the case of a quadratic Bézier curve: + + * Step 1: + + .. math:: + H'_1 + = + \begin{pmatrix} + (1-a)^2 & 2(1-a)a & a^2 \\ + 0 & (1-a) & a \\ + 0 & 0 & 1 + \end{pmatrix} + \begin{pmatrix} + p_0 \\ + p_1 \\ + p_2 + \end{pmatrix} + + * Step 2: + + .. math:: + H''_0 + &= + \begin{pmatrix} + 1 & 0 & 0 \\ + (1-u) & u & 0\\ + (1-u)^2 & 2(1-u)u & u^2 + \end{pmatrix} + H'_1 + \\ + & + \\ + &= + \begin{pmatrix} + 1 & 0 & 0 \\ + (1-u) & u & 0\\ + (1-u)^2 & 2(1-u)u & u^2 + \end{pmatrix} + \begin{pmatrix} + (1-a)^2 & 2(1-a)a & a^2 \\ + 0 & (1-a) & a \\ + 0 & 0 & 1 + \end{pmatrix} + \begin{pmatrix} + p_0 \\ + p_1 \\ + p_2 + \end{pmatrix} + \\ + & + \\ + &= + \begin{pmatrix} + (1-a)^2 & 2(1-a)a & a^2 \\ + (1-a)(1-b) & a(1-b) + (1-a)b & ab \\ + (1-b)^2 & 2(1-b)b & b^2 + \end{pmatrix} + \begin{pmatrix} + p_0 \\ + p_1 \\ + p_2 + \end{pmatrix} + + from where one can define a :math:`(3, 3)` matrix :math:`P_2` which, when applied over + the array of ``points``, will return the desired partial quadratic Bézier curve: + + .. math:: + P_2 + = + \begin{pmatrix} + (1-a)^2 & 2(1-a)a & a^2 \\ + (1-a)(1-b) & a(1-b) + (1-a)b & ab \\ + (1-b)^2 & 2(1-b)b & b^2 + \end{pmatrix} + + Similarly, for the cubic Bézier curve case, one can define the following + :math:`(4, 4)` matrix :math:`P_3`: + + .. math:: + P_3 + = + \begin{pmatrix} + (1-a)^3 & 3(1-a)^2a & 3(1-a)a^2 & a^3 \\ + (1-a)^2(1-b) & 2(1-a)a(1-b) + (1-a)^2b & a^2(1-b) + 2(1-a)ab & a^2b \\ + (1-a)(1-b)^2 & a(1-b)^2 + 2(1-a)(1-b)b & 2a(1-b)b + (1-a)b^2 & ab^2 \\ + (1-b)^3 & 3(1-b)^2b & 3(1-b)b^2 & b^3 + \end{pmatrix} Parameters ---------- - points : np.ndarray + points set of points defining the bezier curve. - a : float + a lower bound of the desired partial bezier curve. - b : float + b upper bound of the desired partial bezier curve. Returns ------- - np.ndarray - Set of points defining the partial bezier curve. + :class:`~.BezierPoints` + An array containing the control points defining the partial Bézier curve. """ + # Border cases if a == 1: - return [points[-1]] * len(points) + arr = np.array(points) + arr[:] = arr[-1] + return arr + if b == 0: + arr = np.array(points) + arr[:] = arr[0] + return arr + + points = np.asarray(points) + degree = points.shape[0] - 1 + + if degree == 3: + ma, mb = 1 - a, 1 - b + a2, b2, ma2, mb2 = a * a, b * b, ma * ma, mb * mb + a3, b3, ma3, mb3 = a2 * a, b2 * b, ma2 * ma, mb2 * mb + + portion_matrix = np.array( + [ + [ma3, 3 * ma2 * a, 3 * ma * a2, a3], + [ma2 * mb, 2 * ma * a * mb + ma2 * b, a2 * mb + 2 * ma * a * b, a2 * b], + [ma * mb2, a * mb2 + 2 * ma * mb * b, 2 * a * mb * b + ma * b2, a * b2], + [mb3, 3 * mb2 * b, 3 * mb * b2, b3], + ] + ) + return portion_matrix @ points - a_to_1 = np.array([bezier(points[i:])(a) for i in range(len(points))]) - end_prop = (b - a) / (1.0 - a) - return np.array([bezier(a_to_1[: i + 1])(end_prop) for i in range(len(points))]) + if degree == 2: + ma, mb = 1 - a, 1 - b + portion_matrix = np.array( + [ + [ma * ma, 2 * a * ma, a * a], + [ma * mb, a * mb + ma * b, a * b], + [mb * mb, 2 * b * mb, b * b], + ] + ) + return portion_matrix @ points + + if degree == 1: + direction = points[1] - points[0] + return np.array( + [ + points[0] + a * direction, + points[0] + b * direction, + ] + ) -# Shortened version of partial_bezier_points just for quadratics, -# since this is called a fair amount -def partial_quadratic_bezier_points(points, a, b): - if a == 1: - return 3 * [points[-1]] + if degree == 0: + return points + + # Fallback case for nth degree Béziers + # It is convenient that np.array copies points + arr = np.array(points, dtype=float) + N = arr.shape[0] + + # Current state for an example Bézier curve C0 = [P0, P1, P2, P3]: + # arr = [P0, P1, P2, P3] + if a != 0: + for i in range(1, N): + # 1st iter: arr = [L0(a), L1(a), L2(a), P3] + # 2nd iter: arr = [Q0(a), Q1(a), L2(a), P3] + # 3rd iter: arr = [C0(a), Q1(a), L2(a), P3] + arr[: N - i] += a * (arr[1 : N - i + 1] - arr[: N - i]) + + # For faster calculations we shall define mu = 1 - u = (1 - b) / (1 - a). + # This is because: + # L0'(u) = P0' + u(P1' - P0') + # = (1-u)P0' + uP1' + # = muP0' + (1-mu)P1' + # = P1' + mu(P0' - P1) + # In this way, one can do something similar to the first loop. + # + # Current state: + # arr = [C0(a), Q1(a), L2(a), P3] + # = [P0', P1', P2', P3'] + if b != 1: + mu = (1 - b) / (1 - a) + for i in range(1, N): + # 1st iter: arr = [P0', L0'(u), L1'(u), L2'(u)] + # 2nd iter: arr = [P0', L0'(u), Q0'(u), Q1'(u)] + # 3rd iter: arr = [P0', L0'(u), Q0'(u), C0'(u)] + arr[i:] += mu * (arr[i - 1 : -1] - arr[i:]) + + return arr + + +def split_bezier(points: BezierPointsLike, t: float) -> Spline: + r"""Split a Bézier curve at argument ``t`` into two curves. + + .. note:: + + .. seealso:: + `A Primer on Bézier Curves #10: Splitting curves. Pomax. `_ + + As an example for a cubic Bézier curve, let :math:`p_0, p_1, p_2, p_3` be the points + needed for the curve :math:`C_0 = [p_0, \ p_1, \ p_2, \ p_3]`. + + Define the 3 linear Béziers :math:`L_0, L_1, L_2` as interpolations of :math:`p_0, p_1, p_2, p_3`: + + .. math:: + L_0(t) &= p_0 + t(p_1 - p_0) \\ + L_1(t) &= p_1 + t(p_2 - p_1) \\ + L_2(t) &= p_2 + t(p_3 - p_2) + + Define the 2 quadratic Béziers :math:`Q_0, Q_1` as interpolations of :math:`L_0, L_1, L_2`: + + .. math:: + Q_0(t) &= L_0(t) + t(L_1(t) - L_0(t)) \\ + Q_1(t) &= L_1(t) + t(L_2(t) - L_1(t)) + + Then :math:`C_0` is the following interpolation of :math:`Q_0` and :math:`Q_1`: + + .. math:: + C_0(t) = Q_0(t) + t(Q_1(t) - Q_0(t)) + + Evaluating :math:`C_0` at a value :math:`t=t'` splits :math:`C_0` into two cubic Béziers :math:`H_0` + and :math:`H_1`, defined by some of the points we calculated earlier: + + .. math:: + H_0 &= [p_0, &\ L_0(t'), &\ Q_0(t'), &\ C_0(t') &] \\ + H_1 &= [p_0(t'), &\ Q_1(t'), &\ L_2(t'), &\ p_3 &] + + As the resulting curves are obtained from linear combinations of ``points``, everything can + be encoded into a matrix for efficiency, which is done for Bézier curves of degree up to 3. + + .. seealso:: + `A Primer on Bézier Curves #11: Splitting curves using matrices. Pomax. `_ + + For the simpler case of a quadratic Bézier curve: + + .. math:: + H_0 + &= + \begin{pmatrix} + p_0 \\ + (1-t) p_0 + t p_1 \\ + (1-t)^2 p_0 + 2(1-t)t p_1 + t^2 p_2 \\ + \end{pmatrix} + &= + \begin{pmatrix} + 1 & 0 & 0 \\ + (1-t) & t & 0\\ + (1-t)^2 & 2(1-t)t & t^2 + \end{pmatrix} + \begin{pmatrix} + p_0 \\ + p_1 \\ + p_2 + \end{pmatrix} + \\ + & + \\ + H_1 + &= + \begin{pmatrix} + (1-t)^2 p_0 + 2(1-t)t p_1 + t^2 p_2 \\ + (1-t) p_1 + t p_2 \\ + p_2 + \end{pmatrix} + &= + \begin{pmatrix} + (1-t)^2 & 2(1-t)t & t^2 \\ + 0 & (1-t) & t \\ + 0 & 0 & 1 + \end{pmatrix} + \begin{pmatrix} + p_0 \\ + p_1 \\ + p_2 + \end{pmatrix} + + from where one can define a :math:`(6, 3)` split matrix :math:`S_2` which can multiply + the array of ``points`` to compute the return value: + + .. math:: + S_2 + &= + \begin{pmatrix} + 1 & 0 & 0 \\ + (1-t) & t & 0 \\ + (1-t)^2 & 2(1-t)t & t^2 \\ + (1-t)^2 & 2(1-t)t & t^2 \\ + 0 & (1-t) & t \\ + 0 & 0 & 1 + \end{pmatrix} + \\ + & + \\ + S_2 P + &= + \begin{pmatrix} + 1 & 0 & 0 \\ + (1-t) & t & 0 \\ + (1-t)^2 & 2(1-t)t & t^2 \\ + (1-t)^2 & 2(1-t)t & t^2 \\ + 0 & (1-t) & t \\ + 0 & 0 & 1 + \end{pmatrix} + \begin{pmatrix} + p_0 \\ + p_1 \\ + p_2 + \end{pmatrix} + = + \begin{pmatrix} + \vert \\ + H_0 \\ + \vert \\ + \vert \\ + H_1 \\ + \vert + \end{pmatrix} + + For the previous example with a cubic Bézier curve: + + .. math:: + H_0 + &= + \begin{pmatrix} + p_0 \\ + (1-t) p_0 + t p_1 \\ + (1-t)^2 p_0 + 2(1-t)t p_1 + t^2 p_2 \\ + (1-t)^3 p_0 + 3(1-t)^2 t p_1 + 3(1-t)t^2 p_2 + t^3 p_3 + \end{pmatrix} + &= + \begin{pmatrix} + 1 & 0 & 0 & 0 \\ + (1-t) & t & 0 & 0 \\ + (1-t)^2 & 2(1-t)t & t^2 & 0 \\ + (1-t)^3 & 3(1-t)^2 t & 3(1-t)t^2 & t^3 + \end{pmatrix} + \begin{pmatrix} + p_0 \\ + p_1 \\ + p_2 \\ + p_3 + \end{pmatrix} + \\ + & + \\ + H_1 + &= + \begin{pmatrix} + (1-t)^3 p_0 + 3(1-t)^2 t p_1 + 3(1-t)t^2 p_2 + t^3 p_3 \\ + (1-t)^2 p_1 + 2(1-t)t p_2 + t^2 p_3 \\ + (1-t) p_2 + t p_3 \\ + p_3 + \end{pmatrix} + &= + \begin{pmatrix} + (1-t)^3 & 3(1-t)^2 t & 3(1-t)t^2 & t^3 \\ + 0 & (1-t)^2 & 2(1-t)t & t^2 \\ + 0 & 0 & (1-t) & t \\ + 0 & 0 & 0 & 1 + \end{pmatrix} + \begin{pmatrix} + p_0 \\ + p_1 \\ + p_2 \\ + p_3 + \end{pmatrix} + + from where one can define a :math:`(8, 4)` split matrix :math:`S_3` which can multiply + the array of ``points`` to compute the return value: + + .. math:: + S_3 + &= + \begin{pmatrix} + 1 & 0 & 0 & 0 \\ + (1-t) & t & 0 & 0 \\ + (1-t)^2 & 2(1-t)t & t^2 & 0 \\ + (1-t)^3 & 3(1-t)^2 t & 3(1-t)t^2 & t^3 \\ + (1-t)^3 & 3(1-t)^2 t & 3(1-t)t^2 & t^3 \\ + 0 & (1-t)^2 & 2(1-t)t & t^2 \\ + 0 & 0 & (1-t) & t \\ + 0 & 0 & 0 & 1 + \end{pmatrix} + \\ + & + \\ + S_3 P + &= + \begin{pmatrix} + 1 & 0 & 0 & 0 \\ + (1-t) & t & 0 & 0 \\ + (1-t)^2 & 2(1-t)t & t^2 & 0 \\ + (1-t)^3 & 3(1-t)^2 t & 3(1-t)t^2 & t^3 \\ + (1-t)^3 & 3(1-t)^2 t & 3(1-t)t^2 & t^3 \\ + 0 & (1-t)^2 & 2(1-t)t & t^2 \\ + 0 & 0 & (1-t) & t \\ + 0 & 0 & 0 & 1 + \end{pmatrix} + \begin{pmatrix} + p_0 \\ + p_1 \\ + p_2 \\ + p_3 + \end{pmatrix} + = + \begin{pmatrix} + \vert \\ + H_0 \\ + \vert \\ + \vert \\ + H_1 \\ + \vert + \end{pmatrix} - def curve(t): - return ( - points[0] * (1 - t) * (1 - t) - + 2 * points[1] * t * (1 - t) - + points[2] * t * t + Parameters + ---------- + points + The control points of the Bézier curve. + + t + The ``t``-value at which to split the Bézier curve. + + Returns + ------- + :class:`~.Point3D_Array` + An array containing the control points defining the two Bézier curves. + """ + points = np.asarray(points) + N, dim = points.shape + degree = N - 1 + + if degree == 3: + mt = 1 - t + mt2 = mt * mt + mt3 = mt2 * mt + t2 = t * t + t3 = t2 * t + two_mt_t = 2 * mt * t + three_mt2_t = 3 * mt2 * t + three_mt_t2 = 3 * mt * t2 + + # Split matrix S3 explained in the docstring + split_matrix = np.array( + [ + [1, 0, 0, 0], + [mt, t, 0, 0], + [mt2, two_mt_t, t2, 0], + [mt3, three_mt2_t, three_mt_t2, t3], + [mt3, three_mt2_t, three_mt_t2, t3], + [0, mt2, two_mt_t, t2], + [0, 0, mt, t], + [0, 0, 0, 1], + ] + ) + + return split_matrix @ points + + if degree == 2: + mt = 1 - t + mt2 = mt * mt + t2 = t * t + two_tmt = 2 * t * mt + + # Split matrix S2 explained in the docstring + split_matrix = np.array( + [ + [1, 0, 0], + [mt, t, 0], + [mt2, two_tmt, t2], + [mt2, two_tmt, t2], + [0, mt, t], + [0, 0, 1], + ] ) - # bezier(points) - h0 = curve(a) if a > 0 else points[0] - h2 = curve(b) if b < 1 else points[2] - h1_prime = (1 - a) * points[1] + a * points[2] - end_prop = (b - a) / (1.0 - a) - h1 = (1 - end_prop) * h0 + end_prop * h1_prime - return [h0, h1, h2] + return split_matrix @ points + + if degree == 1: + middle = points[0] + t * (points[1] - points[0]) + return np.array([points[0], middle, middle, points[1]]) + + if degree == 0: + return np.array([points[0], points[0]]) + + # Fallback case for nth degree Béziers + arr = np.empty((2, N, dim)) + arr[1] = points + arr[0, 0] = points[0] + + # Example for a cubic Bézier + # arr[0] = [P0 .. .. ..] + # arr[1] = [P0 P1 P2 P3] + for i in range(1, N): + # 1st iter: arr[1] = [L0 L1 L2 P3] + # 2nd iter: arr[1] = [Q0 Q1 L2 P3] + # 3rd iter: arr[1] = [C0 Q1 L2 P3] + arr[1, : N - i] += t * (arr[1, 1 : N - i + 1] - arr[1, : N - i]) + # 1st iter: arr[0] = [P0 L0 .. ..] + # 2nd iter: arr[0] = [P0 L0 Q0 ..] + # 3rd iter: arr[0] = [P0 L0 Q0 C0] + arr[0, i] = arr[1, 0] + + return arr.reshape(2 * N, dim) + + +# Memos explained in subdivide_bezier docstring +SUBDIVISION_MATRICES: list[dict[int, MatrixMN]] = [{} for i in range(4)] + + +def _get_subdivision_matrix(n_points: int, n_divisions: int) -> MatrixMN: + """Gets the matrix which subdivides a Bézier curve of + ``n_points`` control points into ``n_divisions`` parts. + + Auxiliary function for :func:`subdivide_bezier`. See its + docstrings for an explanation of the matrix build process. + + Parameters + ---------- + n_points + The number of control points of the Bézier curve to + subdivide. This function only handles up to 4 points. + n_divisions + The number of parts to subdivide the Bézier curve into. + + Returns + ------- + MatrixMN + The matrix which, upon multiplying the control points of the + Bézier curve, subdivides it into ``n_divisions`` parts. + """ + if n_points not in (1, 2, 3, 4): + raise NotImplementedError( + "This function does not support subdividing Bézier " + "curves with 0 or more than 4 control points." + ) + + subdivision_matrix = SUBDIVISION_MATRICES[n_points - 1].get(n_divisions, None) + if subdivision_matrix is not None: + return subdivision_matrix + + subdivision_matrix = np.empty((n_points * n_divisions, n_points)) + + # Cubic Bézier + if n_points == 4: + for i in range(n_divisions): + i2 = i * i + i3 = i2 * i + ip1 = i + 1 + ip12 = ip1 * ip1 + ip13 = ip12 * ip1 + nmi = n_divisions - i + nmi2 = nmi * nmi + nmi3 = nmi2 * nmi + nmim1 = nmi - 1 + nmim12 = nmim1 * nmim1 + nmim13 = nmim12 * nmim1 + + subdivision_matrix[4 * i : 4 * (i + 1)] = np.array( + [ + [ + nmi3, + 3 * nmi2 * i, + 3 * nmi * i2, + i3, + ], + [ + nmi2 * nmim1, + 2 * nmi * nmim1 * i + nmi2 * ip1, + nmim1 * i2 + 2 * nmi * i * ip1, + i2 * ip1, + ], + [ + nmi * nmim12, + nmim12 * i + 2 * nmi * nmim1 * ip1, + 2 * nmim1 * i * ip1 + nmi * ip12, + i * ip12, + ], + [ + nmim13, + 3 * nmim12 * ip1, + 3 * nmim1 * ip12, + ip13, + ], + ] + ) + subdivision_matrix /= n_divisions * n_divisions * n_divisions + + # Quadratic Bézier + elif n_points == 3: + for i in range(n_divisions): + ip1 = i + 1 + nmi = n_divisions - i + nmim1 = nmi - 1 + subdivision_matrix[3 * i : 3 * (i + 1)] = np.array( + [ + [nmi * nmi, 2 * i * nmi, i * i], + [nmi * nmim1, i * nmim1 + ip1 * nmi, i * ip1], + [nmim1 * nmim1, 2 * ip1 * nmim1, ip1 * ip1], + ] + ) + subdivision_matrix /= n_divisions * n_divisions + + # Linear Bézier (straight line) + elif n_points == 2: + aux_range = np.arange(n_divisions + 1) + subdivision_matrix[::2, 1] = aux_range[:-1] + subdivision_matrix[1::2, 1] = aux_range[1:] + subdivision_matrix[:, 0] = subdivision_matrix[::-1, 1] + subdivision_matrix /= n_divisions + + # Zero-degree Bézier (single point) + elif n_points == 1: + subdivision_matrix[:] = 1 + + SUBDIVISION_MATRICES[n_points - 1][n_divisions] = subdivision_matrix + return subdivision_matrix + + +def subdivide_bezier(points: BezierPointsLike, n_divisions: int) -> Spline: + r"""Subdivide a Bézier curve into :math:`n` subcurves which have the same shape. + + The points at which the curve is split are located at the + arguments :math:`t = \frac{i}{n}`, for :math:`i \in \{1, ..., n-1\}`. + + .. seealso:: + + * See :func:`split_bezier` for an explanation on how to split Bézier curves. + * See :func:`partial_bezier_points` for an extra understanding of this function. + + + .. note:: + The resulting subcurves can be expressed as linear combinations of + ``points``, which can be encoded in a single matrix that is precalculated + for 2nd and 3rd degree Bézier curves. + + As an example for a quadratic Bézier curve: taking inspiration from the + explanation in :func:`partial_bezier_points`, where the following matrix + :math:`P_2` was defined to extract the portion of a quadratic Bézier + curve for :math:`t \in [a, b]`: + + .. math:: + P_2 + = + \begin{pmatrix} + (1-a)^2 & 2(1-a)a & a^2 \\ + (1-a)(1-b) & a(1-b) + (1-a)b & ab \\ + (1-b)^2 & 2(1-b)b & b^2 + \end{pmatrix} + + the plan is to replace :math:`[a, b]` with + :math:`\left[ \frac{i-1}{n}, \frac{i}{n} \right], \ \forall i \in \{1, ..., n\}`. + + As an example for :math:`n = 2` divisions, construct :math:`P_1` for + the interval :math:`\left[ 0, \frac{1}{2} \right]`, and :math:`P_2` for the + interval :math:`\left[ \frac{1}{2}, 1 \right]`: + + .. math:: + P_1 + = + \begin{pmatrix} + 1 & 0 & 0 \\ + 0.5 & 0.5 & 0 \\ + 0.25 & 0.5 & 0.25 + \end{pmatrix} + , + \quad + P_2 + = + \begin{pmatrix} + 0.25 & 0.5 & 0.25 \\ + 0 & 0.5 & 0.5 \\ + 0 & 0 & 1 + \end{pmatrix} + + Therefore, the following :math:`(6, 3)` subdivision matrix :math:`D_2` can be + constructed, which will subdivide an array of ``points`` into 2 parts: + + .. math:: + D_2 + = + \begin{pmatrix} + M_1 \\ + M_2 + \end{pmatrix} + = + \begin{pmatrix} + 1 & 0 & 0 \\ + 0.5 & 0.5 & 0 \\ + 0.25 & 0.5 & 0.25 \\ + 0.25 & 0.5 & 0.25 \\ + 0 & 0.5 & 0.5 \\ + 0 & 0 & 1 + \end{pmatrix} + + For quadratic and cubic Bézier curves, the subdivision matrices are memoized for + efficiency. For higher degree curves, an iterative algorithm inspired by the + one from :func:`split_bezier` is used instead. + + .. image:: /_static/bezier_subdivision_example.png + + Parameters + ---------- + points + The control points of the Bézier curve. + + n_divisions + The number of curves to subdivide the Bézier curve into + + Returns + ------- + :class:`~.Spline` + An array containing the points defining the new :math:`n` subcurves. + """ + if n_divisions == 1: + return points + + points = np.asarray(points) + N, dim = points.shape + + if N <= 4: + subdivision_matrix = _get_subdivision_matrix(N, n_divisions) + return subdivision_matrix @ points + + # Fallback case for an nth degree Bézier: successive splitting + beziers = np.empty((n_divisions, N, dim)) + beziers[-1] = points + for curve_num in range(n_divisions - 1, 0, -1): + curr = beziers[curve_num] + prev = beziers[curve_num - 1] + prev[0] = curr[0] + a = (n_divisions - curve_num) / (n_divisions - curve_num + 1) + # Current state for an example cubic Bézier curve: + # prev = [P0 .. .. ..] + # curr = [P0 P1 P2 P3] + for i in range(1, N): + # 1st iter: curr = [L0 L1 L2 P3] + # 2nd iter: curr = [Q0 Q1 L2 P3] + # 3rd iter: curr = [C0 Q1 L2 P3] + curr[: N - i] += a * (curr[1 : N - i + 1] - curr[: N - i]) + # 1st iter: prev = [P0 L0 .. ..] + # 2nd iter: prev = [P0 L0 Q0 ..] + # 3rd iter: prev = [P0 L0 Q0 C0] + prev[i] = curr[0] + + return beziers.reshape(n_divisions * N, dim) + + +def bezier_remap( + bezier_tuples: BezierPointsLike_Array, + new_number_of_curves: int, +) -> BezierPoints_Array: + """Subdivides each curve in ``bezier_tuples`` into as many parts as necessary, until the final number of + curves reaches a desired amount, ``new_number_of_curves``. + + Parameters + ---------- + bezier_tuples + An array of multiple Bézier curves of degree :math:`d` to be remapped. The shape of this array + must be ``(current_number_of_curves, nppc, dim)``, where: + + * ``current_number_of_curves`` is the current amount of curves in the array ``bezier_tuples``, + * ``nppc`` is the amount of points per curve, such that their degree is ``nppc-1``, and + * ``dim`` is the dimension of the points, usually :math:`3`. + + new_number_of_curves + The number of curves that the output will contain. This needs to be higher than the current number. + + Returns + ------- + :class:`~.BezierPoints_Array` + The new array of shape ``(new_number_of_curves, nppc, dim)``, + containing the new Bézier curves after the remap. + """ + bezier_tuples = np.asarray(bezier_tuples) + current_number_of_curves, nppc, dim = bezier_tuples.shape + # This is an array with values ranging from 0 + # up to curr_num_curves, with repeats such that + # its total length is target_num_curves. For example, + # with curr_num_curves = 10, target_num_curves = 15, this + # would be [0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9]. + repeat_indices = ( + np.arange(new_number_of_curves, dtype="i") * current_number_of_curves + ) // new_number_of_curves + + # If the nth term of this list is k, it means + # that the nth curve of our path should be split + # into k pieces. + # In the above example our array had the following elements + # [0, 0, 1, 2, 2, 3, 4, 4, 5, 6, 6, 7, 8, 8, 9] + # We have two 0s, one 1, two 2s and so on. + # The split factors array would hence be: + # [2, 1, 2, 1, 2, 1, 2, 1, 2, 1] + split_factors = np.zeros(current_number_of_curves, dtype="i") + np.add.at(split_factors, repeat_indices, 1) + + new_tuples = np.empty((new_number_of_curves, nppc, dim)) + index = 0 + for curve, sf in zip(bezier_tuples, split_factors): + new_tuples[index : index + sf] = subdivide_bezier(curve, sf).reshape( + sf, nppc, dim + ) + index += sf + + return new_tuples # Linear interpolation variants -def interpolate(start: int, end: int, alpha: float) -> float: +@overload +def interpolate(start: float, end: float, alpha: float) -> float: ... + + +@overload +def interpolate(start: float, end: float, alpha: ColVector) -> ColVector: ... + + +@overload +def interpolate(start: Point3D, end: Point3D, alpha: float) -> Point3D: ... + + +@overload +def interpolate(start: Point3D, end: Point3D, alpha: ColVector) -> Point3D_Array: ... + + +def interpolate( + start: float | Point3D, + end: float | Point3D, + alpha: float | ColVector, +) -> float | ColVector | Point3D | Point3D_Array: + """Linearly interpolates between two values ``start`` and ``end``. + + Parameters + ---------- + start + The start of the range. + end + The end of the range. + alpha + A float between 0 and 1, or an :math:`(n, 1)` column vector containing + :math:`n` floats between 0 and 1 to interpolate in a vectorized fashion. + + Returns + ------- + :class:`float` | :class:`~.ColVector` | :class:`~.Point3D` | :class:`~.Point3D_Array` + The result of the linear interpolation. + + * If ``start`` and ``end`` are of type :class:`float`, and: + + * ``alpha`` is also a :class:`float`, the return is simply another :class:`float`. + * ``alpha`` is a :class:`~.ColVector`, the return is another :class:`~.ColVector`. + + * If ``start`` and ``end`` are of type :class:`~.Point3D`, and: + + * ``alpha`` is a :class:`float`, the return is another :class:`~.Point3D`. + * ``alpha`` is a :class:`~.ColVector`, the return is a :class:`~.Point3D_Array`. + """ return (1 - alpha) * start + alpha * end @@ -115,277 +1068,904 @@ def integer_interpolate( alpha: float, ) -> tuple[int, float]: """ - Alpha is a float between 0 and 1. This returns - an integer between start and end (inclusive) representing - appropriate interpolation between them, along with a - "residue" representing a new proportion between the - returned integer and the next one of the - list. - - For example, if start=0, end=10, alpha=0.46, This - would return (4, 0.6). + This is a variant of interpolate that returns an integer and the residual + + Parameters + ---------- + start + The start of the range + end + The end of the range + alpha + a float between 0 and 1. + + Returns + ------- + tuple[int, float] + This returns an integer between start and end (inclusive) representing + appropriate interpolation between them, along with a + "residue" representing a new proportion between the + returned integer and the next one of the + list. + + Example + ------- + + .. code-block:: pycon + + >>> integer, residue = integer_interpolate(start=0, end=10, alpha=0.46) + >>> np.allclose((integer, residue), (4, 0.6)) + True """ if alpha >= 1: - return (end - 1, 1.0) + return (int(end - 1), 1.0) if alpha <= 0: - return (start, 0) + return (int(start), 0) value = int(interpolate(start, end, alpha)) residue = ((end - start) * alpha) % 1 return (value, residue) -def mid(start: float, end: float) -> float: +@overload +def mid(start: float, end: float) -> float: ... + + +@overload +def mid(start: Point3D, end: Point3D) -> Point3D: ... + + +def mid(start: float | Point3D, end: float | Point3D) -> float | Point3D: + """Returns the midpoint between two values. + + Parameters + ---------- + start + The first value + end + The second value + + Returns + ------- + The midpoint between the two values + """ return (start + end) / 2.0 -def inverse_interpolate(start: float, end: float, value: float) -> np.ndarray: +@overload +def inverse_interpolate(start: float, end: float, value: float) -> float: ... + + +@overload +def inverse_interpolate(start: float, end: float, value: Point3D) -> Point3D: ... + + +@overload +def inverse_interpolate(start: Point3D, end: Point3D, value: Point3D) -> Point3D: ... + + +def inverse_interpolate( + start: float | Point3D, + end: float | Point3D, + value: float | Point3D, +) -> float | Point3D: + """Perform inverse interpolation to determine the alpha + values that would produce the specified ``value`` + given the ``start`` and ``end`` values or points. + + Parameters + ---------- + start + The start value or point of the interpolation. + end + The end value or point of the interpolation. + value + The value or point for which the alpha value + should be determined. + + Returns + ------- + The alpha values producing the given input + when interpolating between ``start`` and ``end``. + + Example + ------- + + .. code-block:: pycon + + >>> inverse_interpolate(start=2, end=6, value=4) + np.float64(0.5) + + >>> start = np.array([1, 2, 1]) + >>> end = np.array([7, 8, 11]) + >>> value = np.array([4, 5, 5]) + >>> inverse_interpolate(start, end, value) + array([0.5, 0.5, 0.4]) + """ return np.true_divide(value - start, end - start) +@overload def match_interpolate( new_start: float, new_end: float, old_start: float, old_end: float, old_value: float, -) -> np.ndarray: +) -> float: ... + + +@overload +def match_interpolate( + new_start: float, + new_end: float, + old_start: float, + old_end: float, + old_value: Point3D, +) -> Point3D: ... + + +def match_interpolate( + new_start: float, + new_end: float, + old_start: float, + old_end: float, + old_value: float | Point3D, +) -> float | Point3D: + """Interpolate a value from an old range to a new range. + + Parameters + ---------- + new_start + The start of the new range. + new_end + The end of the new range. + old_start + The start of the old range. + old_end + The end of the old range. + old_value + The value within the old range whose corresponding + value in the new range (with the same alpha value) + is desired. + + Returns + ------- + The interpolated value within the new range. + + Examples + -------- + >>> match_interpolate(0, 100, 10, 20, 15) + np.float64(50.0) + """ + old_alpha = inverse_interpolate(old_start, old_end, old_value) return interpolate( new_start, new_end, - inverse_interpolate(old_start, old_end, old_value), + old_alpha, ) -# Figuring out which bezier curves most smoothly connect a sequence of points +# Figuring out which Bézier curves most smoothly connect a sequence of points +def get_smooth_cubic_bezier_handle_points( + anchors: Point3DLike_Array, +) -> tuple[Point3D_Array, Point3D_Array]: + """Given an array of anchors for a cubic spline (array of connected cubic + Bézier curves), compute the 1st and 2nd handle for every curve, so that + the resulting spline is smooth. + Parameters + ---------- + anchors + Anchors of a cubic spline. -def get_smooth_cubic_bezier_handle_points(points): - points = np.array(points) - num_handles = len(points) - 1 - dim = points.shape[1] - if num_handles < 1: - return np.zeros((0, dim)), np.zeros((0, dim)) - # Must solve 2*num_handles equations to get the handles. - # l and u are the number of lower an upper diagonal rows - # in the matrix to solve. - l, u = 2, 1 - # diag is a representation of the matrix in diagonal form - # See https://www.particleincell.com/2012/bezier-splines/ - # for how to arrive at these equations - diag = np.zeros((l + u + 1, 2 * num_handles)) - diag[0, 1::2] = -1 - diag[0, 2::2] = 1 - diag[1, 0::2] = 2 - diag[1, 1::2] = 1 - diag[2, 1:-2:2] = -2 - diag[3, 0:-3:2] = 1 - # last - diag[2, -2] = -1 - diag[1, -1] = 2 - # This is the b as in Ax = b, where we are solving for x, - # and A is represented using diag. However, think of entries - # to x and b as being points in space, not numbers - b = np.zeros((2 * num_handles, dim)) - b[1::2] = 2 * points[1:] - b[0] = points[0] - b[-1] = points[-1] - - def solve_func(b): - return linalg.solve_banded((l, u), diag, b) - - use_closed_solve_function = is_closed(points) - if use_closed_solve_function: - # Get equations to relate first and last points - matrix = diag_to_matrix((l, u), diag) - # last row handles second derivative - matrix[-1, [0, 1, -2, -1]] = [2, -1, 1, -2] - # first row handles first derivative - matrix[0, :] = np.zeros(matrix.shape[1]) - matrix[0, [0, -1]] = [1, 1] - b[0] = 2 * points[0] - b[-1] = np.zeros(dim) - - def closed_curve_solve_func(b): - return linalg.solve(matrix, b) - - handle_pairs = np.zeros((2 * num_handles, dim)) - for i in range(dim): - if use_closed_solve_function: - handle_pairs[:, i] = closed_curve_solve_func(b[:, i]) - else: - handle_pairs[:, i] = solve_func(b[:, i]) - return handle_pairs[0::2], handle_pairs[1::2] + Returns + ------- + :class:`tuple` [:class:`~.Point3D_Array`, :class:`~.Point3D_Array`] + A tuple of two arrays: one containing the 1st handle for every curve in + the cubic spline, and the other containing the 2nd handles. + """ + anchors = np.asarray(anchors) + n_anchors = anchors.shape[0] + # If there's a single anchor, there's no Bézier curve. + # Return empty arrays. + if n_anchors == 1: + dim = anchors.shape[1] + return np.zeros((0, dim)), np.zeros((0, dim)) -def get_smooth_handle_points( - points: np.ndarray, -) -> tuple[np.ndarray, np.ndarray]: - """Given some anchors (points), compute handles so the resulting bezier curve is smooth. + # If there are only two anchors (thus only one pair of handles), + # they can only be an interpolation of these two anchors with alphas + # 1/3 and 2/3, which will draw a straight line between the anchors. + if n_anchors == 2: + val = interpolate(anchors[0], anchors[1], np.array([[1 / 3], [2 / 3]])) + return (val[0], val[1]) + + # Handle different cases depending on whether the points form a closed + # curve or not + curve_is_closed = is_closed(anchors) + if curve_is_closed: + return get_smooth_closed_cubic_bezier_handle_points(anchors) + else: + return get_smooth_open_cubic_bezier_handle_points(anchors) + + +CP_CLOSED_MEMO = np.array([1 / 3]) +UP_CLOSED_MEMO = np.array([1 / 3]) + + +def get_smooth_closed_cubic_bezier_handle_points( + anchors: Point3DLike_Array, +) -> tuple[Point3D_Array, Point3D_Array]: + r"""Special case of :func:`get_smooth_cubic_bezier_handle_points`, + when the ``anchors`` form a closed loop. + + .. note:: + A system of equations must be solved to get the first handles of + every Bézier curve (referred to as :math:`H_1`). + Then :math:`H_2` (the second handles) can be obtained separately. + + .. seealso:: + The equations were obtained from: + + * `Conditions on control points for continuous curvature. (2016). Jaco Stuifbergen. `_ + + In general, if there are :math:`N+1` anchors, there will be :math:`N` Bézier curves + and thus :math:`N` pairs of handles to find. We must solve the following + system of equations for the 1st handles (example for :math:`N = 5`): + + .. math:: + \begin{pmatrix} + 4 & 1 & 0 & 0 & 1 \\ + 1 & 4 & 1 & 0 & 0 \\ + 0 & 1 & 4 & 1 & 0 \\ + 0 & 0 & 1 & 4 & 1 \\ + 1 & 0 & 0 & 1 & 4 + \end{pmatrix} + \begin{pmatrix} + H_{1,0} \\ + H_{1,1} \\ + H_{1,2} \\ + H_{1,3} \\ + H_{1,4} + \end{pmatrix} + = + \begin{pmatrix} + 4A_0 + 2A_1 \\ + 4A_1 + 2A_2 \\ + 4A_2 + 2A_3 \\ + 4A_3 + 2A_4 \\ + 4A_4 + 2A_5 + \end{pmatrix} + + which will be expressed as :math:`RH_1 = D`. + + :math:`R` is almost a tridiagonal matrix, so we could use Thomas' algorithm. + + .. seealso:: + `Tridiagonal matrix algorithm. Wikipedia. `_ + + However, :math:`R` has ones at the opposite corners. A solution to this is + the first decomposition proposed in the link below, with :math:`\alpha = 1`: + + .. seealso:: + `Tridiagonal matrix algorithm # Variants. Wikipedia. `_ + + .. math:: + R + = + \begin{pmatrix} + 4 & 1 & 0 & 0 & 1 \\ + 1 & 4 & 1 & 0 & 0 \\ + 0 & 1 & 4 & 1 & 0 \\ + 0 & 0 & 1 & 4 & 1 \\ + 1 & 0 & 0 & 1 & 4 + \end{pmatrix} + &= + \begin{pmatrix} + 3 & 1 & 0 & 0 & 0 \\ + 1 & 4 & 1 & 0 & 0 \\ + 0 & 1 & 4 & 1 & 0 \\ + 0 & 0 & 1 & 4 & 1 \\ + 0 & 0 & 0 & 1 & 3 + \end{pmatrix} + + + \begin{pmatrix} + 1 & 0 & 0 & 0 & 1 \\ + 0 & 0 & 0 & 0 & 0 \\ + 0 & 0 & 0 & 0 & 0 \\ + 0 & 0 & 0 & 0 & 0 \\ + 1 & 0 & 0 & 0 & 1 + \end{pmatrix} + \\ + & + \\ + &= + \begin{pmatrix} + 3 & 1 & 0 & 0 & 0 \\ + 1 & 4 & 1 & 0 & 0 \\ + 0 & 1 & 4 & 1 & 0 \\ + 0 & 0 & 1 & 4 & 1 \\ + 0 & 0 & 0 & 1 & 3 + \end{pmatrix} + + + \begin{pmatrix} + 1 \\ + 0 \\ + 0 \\ + 0 \\ + 1 + \end{pmatrix} + \begin{pmatrix} + 1 & 0 & 0 & 0 & 1 + \end{pmatrix} + \\ + & + \\ + &= + T + uv^t + + We decompose :math:`R = T + uv^t`, where :math:`T` is a tridiagonal matrix, and + :math:`u, v` are :math:`N`-D vectors such that :math:`u_0 = u_{N-1} = v_0 = v_{N-1} = 1`, + and :math:`u_i = v_i = 0, \forall i \in \{1, ..., N-2\}`. + + Thus: + + .. math:: + RH_1 &= D \\ + \Rightarrow (T + uv^t)H_1 &= D + + If we find a vector :math:`q` such that :math:`Tq = u`: + + .. math:: + \Rightarrow (T + Tqv^t)H_1 &= D \\ + \Rightarrow T(I + qv^t)H_1 &= D \\ + \Rightarrow H_1 &= (I + qv^t)^{-1} T^{-1} D + + According to Sherman-Morrison's formula: + + .. seealso:: + `Sherman-Morrison's formula. Wikipedia. `_ + + .. math:: + (I + qv^t)^{-1} = I - \frac{1}{1 + v^tq} qv^t + + If we find :math:`Y = T^{-1} D`, or in other words, if we solve for + :math:`Y` in :math:`TY = D`: + + .. math:: + H_1 &= (I + qv^t)^{-1} T^{-1} D \\ + &= (I + qv^t)^{-1} Y \\ + &= (I - \frac{1}{1 + v^tq} qv^t) Y \\ + &= Y - \frac{1}{1 + v^tq} qv^tY + + Therefore, we must solve for :math:`q` and :math:`Y` in :math:`Tq = u` and :math:`TY = D`. + As :math:`T` is now tridiagonal, we shall use Thomas' algorithm. + + Define: + + * :math:`a = [a_0, \ a_1, \ ..., \ a_{N-2}]` as :math:`T`'s lower diagonal of :math:`N-1` elements, + such that :math:`a_0 = a_1 = ... = a_{N-2} = 1`, so this diagonal is filled with ones; + * :math:`b = [b_0, \ b_1, \ ..., \ b_{N-2}, \ b_{N-1}]` as :math:`T`'s main diagonal of :math:`N` elements, + such that :math:`b_0 = b_{N-1} = 3`, and :math:`b_1 = b_2 = ... = b_{N-2} = 4`; + * :math:`c = [c_0, \ c_1, \ ..., \ c_{N-2}]` as :math:`T`'s upper diagonal of :math:`N-1` elements, + such that :math:`c_0 = c_1 = ... = c_{N-2} = 1`: this diagonal is also filled with ones. + + If, according to Thomas' algorithm, we define: + + .. math:: + c'_0 &= \frac{c_0}{b_0} & \\ + c'_i &= \frac{c_i}{b_i - a_{i-1} c'_{i-1}}, & \quad \forall i \in \{1, ..., N-2\} \\ + & & \\ + u'_0 &= \frac{u_0}{b_0} & \\ + u'_i &= \frac{u_i - a_{i-1} u'_{i-1}}{b_i - a_{i-1} c'_{i-1}}, & \quad \forall i \in \{1, ..., N-1\} \\ + & & \\ + D'_0 &= \frac{1}{b_0} D_0 & \\ + D'_i &= \frac{1}{b_i - a_{i-1} c'_{i-1}} (D_i - a_{i-1} D'_{i-1}), & \quad \forall i \in \{1, ..., N-1\} + + Then: + + .. math:: + c'_0 &= \frac{1}{3} & \\ + c'_i &= \frac{1}{4 - c'_{i-1}}, & \quad \forall i \in \{1, ..., N-2\} \\ + & & \\ + u'_0 &= \frac{1}{3} & \\ + u'_i &= \frac{-u'_{i-1}}{4 - c'_{i-1}} = -c'_i u'_{i-1}, & \quad \forall i \in \{1, ..., N-2\} \\ + u'_{N-1} &= \frac{1 - u'_{N-2}}{3 - c'_{N-2}} & \\ + & & \\ + D'_0 &= \frac{1}{3} (4A_0 + 2A_1) & \\ + D'_i &= \frac{1}{4 - c'_{i-1}} (4A_i + 2A_{i+1} - D'_{i-1}) & \\ + &= c_i (4A_i + 2A_{i+1} - D'_{i-1}), & \quad \forall i \in \{1, ..., N-2\} \\ + D'_{N-1} &= \frac{1}{3 - c'_{N-2}} (4A_{N-1} + 2A_N - D'_{N-2}) & + + Finally, we can do Backward Substitution to find :math:`q` and :math:`Y`: + + .. math:: + q_{N-1} &= u'_{N-1} & \\ + q_i &= u'_{i} - c'_i q_{i+1}, & \quad \forall i \in \{0, ..., N-2\} \\ + & & \\ + Y_{N-1} &= D'_{N-1} & \\ + Y_i &= D'_i - c'_i Y_{i+1}, & \quad \forall i \in \{0, ..., N-2\} + + With those values, we can finally calculate :math:`H_1 = Y - \frac{1}{1 + v^tq} qv^tY`. + Given that :math:`v_0 = v_{N-1} = 1`, and :math:`v_1 = v_2 = ... = v_{N-2} = 0`, its dot products + with :math:`q` and :math:`Y` are respectively :math:`v^tq = q_0 + q_{N-1}` and + :math:`v^tY = Y_0 + Y_{N-1}`. Thus: + + .. math:: + H_1 = Y - \frac{1}{1 + q_0 + q_{N-1}} q(Y_0 + Y_{N-1}) + + Once we have :math:`H_1`, we can get :math:`H_2` (the array of second handles) as follows: + + .. math:: + H_{2, i} &= 2A_{i+1} - H_{1, i+1}, & \quad \forall i \in \{0, ..., N-2\} \\ + H_{2, N-1} &= 2A_0 - H_{1, 0} & + + Because the matrix :math:`R` always follows the same pattern (and thus :math:`T, u, v` as well), + we can define a memo list for :math:`c'` and :math:`u'` to avoid recalculation. We cannot + memoize :math:`D` and :math:`Y`, however, because they are always different matrices. We + cannot make a memo for :math:`q` either, but we can calculate it faster because :math:`u'` + can be memoized. Parameters ---------- - points : np.ndarray - Anchors. + anchors + Anchors of a closed cubic spline. Returns ------- - typing.Tuple[np.ndarray, np.ndarray] - Computed handles. + :class:`tuple` [:class:`~.Point3D_Array`, :class:`~.Point3D_Array`] + A tuple of two arrays: one containing the 1st handle for every curve in + the closed cubic spline, and the other containing the 2nd handles. """ - # NOTE points here are anchors. - points = np.array(points) - num_handles = len(points) - 1 - dim = points.shape[1] - if num_handles < 1: - return np.zeros((0, dim)), np.zeros((0, dim)) - # Must solve 2*num_handles equations to get the handles. - # l and u are the number of lower an upper diagonal rows - # in the matrix to solve. - l, u = 2, 1 - # diag is a representation of the matrix in diagonal form - # See https://www.particleincell.com/2012/bezier-splines/ - # for how to arrive at these equations - diag = np.zeros((l + u + 1, 2 * num_handles)) - diag[0, 1::2] = -1 - diag[0, 2::2] = 1 - diag[1, 0::2] = 2 - diag[1, 1::2] = 1 - diag[2, 1:-2:2] = -2 - diag[3, 0:-3:2] = 1 - # last - diag[2, -2] = -1 - diag[1, -1] = 2 - # This is the b as in Ax = b, where we are solving for x, - # and A is represented using diag. However, think of entries - # to x and b as being points in space, not numbers - b = np.zeros((2 * num_handles, dim)) - b[1::2] = 2 * points[1:] - b[0] = points[0] - b[-1] = points[-1] - - def solve_func(b: np.ndarray) -> np.ndarray: - return linalg.solve_banded((l, u), diag, b) - - use_closed_solve_function = is_closed(points) - if use_closed_solve_function: - # Get equations to relate first and last points - matrix = diag_to_matrix((l, u), diag) - # last row handles second derivative - matrix[-1, [0, 1, -2, -1]] = [2, -1, 1, -2] - # first row handles first derivative - matrix[0, :] = np.zeros(matrix.shape[1]) - matrix[0, [0, -1]] = [1, 1] - b[0] = 2 * points[0] - b[-1] = np.zeros(dim) - - def closed_curve_solve_func(b: np.ndarray) -> np.ndarray: - return linalg.solve(matrix, b) - - handle_pairs = np.zeros((2 * num_handles, dim)) - for i in range(dim): - if use_closed_solve_function: - handle_pairs[:, i] = closed_curve_solve_func(b[:, i]) - else: - handle_pairs[:, i] = solve_func(b[:, i]) - return handle_pairs[0::2], handle_pairs[1::2] + global CP_CLOSED_MEMO + global UP_CLOSED_MEMO + + A = np.asarray(anchors) + N = A.shape[0] - 1 + dim = A.shape[1] + + # Calculate cp (c prime) and up (u prime) with help from + # CP_CLOSED_MEMO and UP_CLOSED_MEMO. + len_memo = CP_CLOSED_MEMO.size + if len_memo < N - 1: + cp = np.empty(N - 1) + up = np.empty(N - 1) + cp[:len_memo] = CP_CLOSED_MEMO + up[:len_memo] = UP_CLOSED_MEMO + # Forward Substitution 1 + # Calculate up (at the same time we calculate cp). + for i in range(len_memo, N - 1): + cp[i] = 1 / (4 - cp[i - 1]) + up[i] = -cp[i] * up[i - 1] + CP_CLOSED_MEMO = cp + UP_CLOSED_MEMO = up + else: + cp = CP_CLOSED_MEMO[: N - 1] + up = UP_CLOSED_MEMO[: N - 1] + + # The last element of u' is different + cp_last_division = 1 / (3 - cp[N - 2]) + up_last = cp_last_division * (1 - up[N - 2]) + + # Backward Substitution 1 + # Calculate q. + q = np.empty((N, dim)) + q[N - 1] = up_last + for i in range(N - 2, -1, -1): + q[i] = up[i] - cp[i] * q[i + 1] + + # Forward Substitution 2 + # Calculate Dp (D prime). + Dp = np.empty((N, dim)) + AUX = 4 * A[:N] + 2 * A[1:] # Vectorize the sum for efficiency. + Dp[0] = AUX[0] / 3 + for i in range(1, N - 1): + Dp[i] = cp[i] * (AUX[i] - Dp[i - 1]) + Dp[N - 1] = cp_last_division * (AUX[N - 1] - Dp[N - 2]) + + # Backward Substitution + # Calculate Y, which is defined as a view of Dp for efficiency + # and semantic convenience at the same time. + Y = Dp + # Y[N-1] = Dp[N-1] (redundant) + for i in range(N - 2, -1, -1): + Y[i] = Dp[i] - cp[i] * Y[i + 1] + + # Calculate H1. + H1 = Y - 1 / (1 + q[0] + q[N - 1]) * q * (Y[0] + Y[N - 1]) + + # Calculate H2. + H2 = np.empty((N, dim)) + H2[0 : N - 1] = 2 * A[1:N] - H1[1:N] + H2[N - 1] = 2 * A[N] - H1[0] + + return H1, H2 + + +CP_OPEN_MEMO = np.array([0.5]) + + +def get_smooth_open_cubic_bezier_handle_points( + anchors: Point3DLike_Array, +) -> tuple[Point3D_Array, Point3D_Array]: + r"""Special case of :func:`get_smooth_cubic_bezier_handle_points`, + when the ``anchors`` do not form a closed loop. + + .. note:: + A system of equations must be solved to get the first handles of + every Bèzier curve (referred to as :math:`H_1`). + Then :math:`H_2` (the second handles) can be obtained separately. + + .. seealso:: + The equations were obtained from: + + * `Smooth Bézier Spline Through Prescribed Points. (2012). Particle in Cell Consulting LLC. `_ + * `Conditions on control points for continuous curvature. (2016). Jaco Stuifbergen. `_ + + .. warning:: + The equations in the first webpage have some typos which were corrected in the comments. + + In general, if there are :math:`N+1` anchors, there will be :math:`N` Bézier curves + and thus :math:`N` pairs of handles to find. We must solve the following + system of equations for the 1st handles (example for :math:`N = 5`): + + .. math:: + \begin{pmatrix} + 2 & 1 & 0 & 0 & 0 \\ + 1 & 4 & 1 & 0 & 0 \\ + 0 & 1 & 4 & 1 & 0 \\ + 0 & 0 & 1 & 4 & 1 \\ + 0 & 0 & 0 & 2 & 7 + \end{pmatrix} + \begin{pmatrix} + H_{1,0} \\ + H_{1,1} \\ + H_{1,2} \\ + H_{1,3} \\ + H_{1,4} + \end{pmatrix} + = + \begin{pmatrix} + A_0 + 2A_1 \\ + 4A_1 + 2A_2 \\ + 4A_2 + 2A_3 \\ + 4A_3 + 2A_4 \\ + 8A_4 + A_5 + \end{pmatrix} + + which will be expressed as :math:`TH_1 = D`. + :math:`T` is a tridiagonal matrix, so the system can be solved in :math:`O(N)` + operations. Here we shall use Thomas' algorithm or the tridiagonal matrix + algorithm. + + .. seealso:: + `Tridiagonal matrix algorithm. Wikipedia. `_ + + Define: + + * :math:`a = [a_0, \ a_1, \ ..., \ a_{N-2}]` as :math:`T`'s lower diagonal of :math:`N-1` elements, + such that :math:`a_0 = a_1 = ... = a_{N-3} = 1`, and :math:`a_{N-2} = 2`; + * :math:`b = [b_0, \ b_1, \ ..., \ b_{N-2}, \ b_{N-1}]` as :math:`T`'s main diagonal of :math:`N` elements, + such that :math:`b_0 = 2`, :math:`b_1 = b_2 = ... = b_{N-2} = 4`, and :math:`b_{N-1} = 7`; + * :math:`c = [c_0, \ c_1, \ ..., \ c_{N-2}]` as :math:`T`'s upper diagonal of :math:`{N-1}` elements, + such that :math:`c_0 = c_1 = ... = c_{N-2} = 1`: this diagonal is filled with ones. + + If, according to Thomas' algorithm, we define: + + .. math:: + c'_0 &= \frac{c_0}{b_0} & \\ + c'_i &= \frac{c_i}{b_i - a_{i-1} c'_{i-1}}, & \quad \forall i \in \{1, ..., N-2\} \\ + & & \\ + D'_0 &= \frac{1}{b_0} D_0 & \\ + D'_i &= \frac{1}{b_i - a_{i-1} c'{i-1}} (D_i - a_{i-1} D'_{i-1}), & \quad \forall i \in \{1, ..., N-1\} + + Then: + + .. math:: + c'_0 &= 0.5 & \\ + c'_i &= \frac{1}{4 - c'_{i-1}}, & \quad \forall i \in \{1, ..., N-2\} \\ + & & \\ + D'_0 &= 0.5A_0 + A_1 & \\ + D'_i &= \frac{1}{4 - c'_{i-1}} (4A_i + 2A_{i+1} - D'_{i-1}) & \\ + &= c_i (4A_i + 2A_{i+1} - D'_{i-1}), & \quad \forall i \in \{1, ..., N-2\} \\ + D'_{N-1} &= \frac{1}{7 - 2c'_{N-2}} (8A_{N-1} + A_N - 2D'_{N-2}) & + + Finally, we can do Backward Substitution to find :math:`H_1`: + + .. math:: + H_{1, N-1} &= D'_{N-1} & \\ + H_{1, i} &= D'_i - c'_i H_{1, i+1}, & \quad \forall i \in \{0, ..., N-2\} + + Once we have :math:`H_1`, we can get :math:`H_2` (the array of second handles) as follows: + + .. math:: + H_{2, i} &= 2A_{i+1} - H_{1, i+1}, & \quad \forall i \in \{0, ..., N-2\} \\ + H_{2, N-1} &= 0.5A_N + 0.5H_{1, N-1} & + + As the matrix :math:`T` always follows the same pattern, we can define a memo list + for :math:`c'` to avoid recalculation. We cannot do the same for :math:`D`, however, + because it is always a different matrix. + Parameters + ---------- + anchors + Anchors of an open cubic spline. -def diag_to_matrix(l_and_u: tuple[int, int], diag: np.ndarray) -> np.ndarray: + Returns + ------- + :class:`tuple` [:class:`~.Point3D_Array`, :class:`~.Point3D_Array`] + A tuple of two arrays: one containing the 1st handle for every curve in + the open cubic spline, and the other containing the 2nd handles. """ - Converts array whose rows represent diagonal - entries of a matrix into the matrix itself. - See scipy.linalg.solve_banded + global CP_OPEN_MEMO + + A = np.asarray(anchors) + N = A.shape[0] - 1 + dim = A.shape[1] + + # Calculate cp (c prime) with help from CP_OPEN_MEMO. + len_memo = CP_OPEN_MEMO.size + if len_memo < N - 1: + cp = np.empty(N - 1) + cp[:len_memo] = CP_OPEN_MEMO + for i in range(len_memo, N - 1): + cp[i] = 1 / (4 - cp[i - 1]) + CP_OPEN_MEMO = cp + else: + cp = CP_OPEN_MEMO[: N - 1] + + # Calculate Dp (D prime). + Dp = np.empty((N, dim)) + Dp[0] = 0.5 * A[0] + A[1] + AUX = 4 * A[1 : N - 1] + 2 * A[2:N] # Vectorize the sum for efficiency. + for i in range(1, N - 1): + Dp[i] = cp[i] * (AUX[i - 1] - Dp[i - 1]) + Dp[N - 1] = (1 / (7 - 2 * cp[N - 2])) * (8 * A[N - 1] + A[N] - 2 * Dp[N - 2]) + + # Backward Substitution. + # H1 (array of the first handles) is defined as a view of Dp for efficiency + # and semantic convenience at the same time. + H1 = Dp + # H1[N-1] = Dp[N-1] (redundant) + for i in range(N - 2, -1, -1): + H1[i] = Dp[i] - cp[i] * H1[i + 1] + + # Calculate H2. + H2 = np.empty((N, dim)) + H2[0 : N - 1] = 2 * A[1:N] - H1[1:N] + H2[N - 1] = 0.5 * (A[N] + H1[N - 1]) + + return H1, H2 + + +@overload +def get_quadratic_approximation_of_cubic( + a0: Point3DLike, h0: Point3DLike, h1: Point3DLike, a1: Point3DLike +) -> QuadraticSpline: ... + + +@overload +def get_quadratic_approximation_of_cubic( + a0: Point3DLike_Array, + h0: Point3DLike_Array, + h1: Point3DLike_Array, + a1: Point3DLike_Array, +) -> QuadraticBezierPath: ... + + +def get_quadratic_approximation_of_cubic( + a0: Point3D | Point3D_Array, + h0: Point3D | Point3D_Array, + h1: Point3D | Point3D_Array, + a1: Point3D | Point3D_Array, +) -> QuadraticSpline | QuadraticBezierPath: + r"""If ``a0``, ``h0``, ``h1`` and ``a1`` are the control points of a cubic + Bézier curve, approximate the curve with two quadratic Bézier curves and + return an array of 6 points, where the first 3 points represent the first + quadratic curve and the last 3 represent the second one. + + Otherwise, if ``a0``, ``h0``, ``h1`` and ``a1`` are _arrays_ of :math:`N` + points representing :math:`N` cubic Bézier curves, return an array of + :math:`6N` points where each group of :math:`6` consecutive points + approximates each of the :math:`N` curves in a similar way as above. + + .. note:: + If the cubic spline given by the original cubic Bézier curves is + smooth, this algorithm will generate a quadratic spline which is also + smooth. + + If a cubic Bézier is given by + + .. math:: + C(t) = (1-t)^3 A_0 + 3(1-t)^2 t H_0 + 3(1-t)t^2 H_1 + t^3 A_1 + + where :math:`A_0`, :math:`H_0`, :math:`H_1` and :math:`A_1` are its + control points, then this algorithm should generate two quadratic + Béziers given by + + .. math:: + Q_0(t) &= (1-t)^2 A_0 + 2(1-t)t M_0 + t^2 K \\ + Q_1(t) &= (1-t)^2 K + 2(1-t)t M_1 + t^2 A_1 + + where :math:`M_0` and :math:`M_1` are the respective handles to be + found for both curves, and :math:`K` is the end anchor of the 1st curve + and the start anchor of the 2nd, which must also be found. + + To solve for :math:`M_0`, :math:`M_1` and :math:`K`, three conditions + can be imposed: + + 1. :math:`Q_0'(0) = \frac{1}{2}C'(0)`. The derivative of the first + quadratic curve at :math:`t = 0` should be proportional to that of + the original cubic curve, also at :math:`t = 0`. Because the cubic + curve is split into two parts, it is necessary to divide this by + two: the speed of a point travelling through the curve should be + half of the original. This gives: + + .. math:: + Q_0'(0) &= \frac{1}{2}C'(0) \\ + 2(M_0 - A_0) &= \frac{3}{2}(H_0 - A_0) \\ + 2M_0 - 2A_0 &= \frac{3}{2}H_0 - \frac{3}{2}A_0 \\ + 2M_0 &= \frac{3}{2}H_0 + \frac{1}{2}A_0 \\ + M_0 &= \frac{1}{4}(3H_0 + A_0) + + 2. :math:`Q_1'(1) = \frac{1}{2}C'(1)`. The derivative of the second + quadratic curve at :math:`t = 1` should be half of that of the + original cubic curve for the same reasons as above, also at + :math:`t = 1`. This gives: + + .. math:: + Q_1'(1) &= \frac{1}{2}C'(1) \\ + 2(A_1 - M_1) &= \frac{3}{2}(A_1 - H_1) \\ + 2A_1 - 2M_1 &= \frac{3}{2}A_1 - \frac{3}{2}H_1 \\ + -2M_1 &= -\frac{1}{2}A_1 - \frac{3}{2}H_1 \\ + M_1 &= \frac{1}{4}(3H_1 + A_1) + + 3. :math:`Q_0'(1) = Q_1'(0)`. The derivatives of both quadratic curves + should match at the point :math:`K`, in order for the final spline + to be smooth. This gives: + + .. math:: + Q_0'(1) &= Q_1'(0) \\ + 2(K - M_0) &= 2(M_1 - K) \\ + 2K - 2M_0 &= 2M_1 - 2K \\ + 4K &= 2M_0 + 2M_1 \\ + K &= \frac{1}{2}(M_0 + M_1) + + This is sufficient to find proper control points for the quadratic + Bézier curves. + + Parameters + ---------- + a0 + The start anchor of a single cubic Bézier curve, or an array of + :math:`N` start anchors for :math:`N` curves. + h0 + The first handle of a single cubic Bézier curve, or an array of + :math:`N` first handles for :math:`N` curves. + h1 + The second handle of a single cubic Bézier curve, or an array of + :math:`N` second handles for :math:`N` curves. + a1 + The end anchor of a single cubic Bézier curve, or an array of + :math:`N` end anchors for :math:`N` curves. + + Returns + ------- + result + An array containing either 6 points for 2 quadratic Bézier curves + approximating the original cubic curve, or :math:`6N` points for + :math:`2N` quadratic curves approximating :math:`N` cubic curves. + + Raises + ------ + ValueError + If ``a0``, ``h0``, ``h1`` and ``a1`` have different dimensions, or + if their number of dimensions is not 1 or 2. """ - l, u = l_and_u - dim = diag.shape[1] - matrix = np.zeros((dim, dim)) - for i in range(l + u + 1): - np.fill_diagonal( - matrix[max(0, i - u) :, max(0, u - i) :], - diag[i, max(0, u - i) :], - ) - return matrix - - -# Given 4 control points for a cubic bezier curve (or arrays of such) -# return control points for 2 quadratics (or 2n quadratics) approximating them. -def get_quadratic_approximation_of_cubic(a0, h0, h1, a1): - a0 = np.array(a0, ndmin=2) - h0 = np.array(h0, ndmin=2) - h1 = np.array(h1, ndmin=2) - a1 = np.array(a1, ndmin=2) - # Tangent vectors at the start and end. - T0 = h0 - a0 - T1 = a1 - h1 - - # Search for inflection points. If none are found, use the - # midpoint as a cut point. - # Based on http://www.caffeineowl.com/graphics/2d/vectorial/cubic-inflexion.html - has_infl = np.ones(len(a0), dtype=bool) - - p = h0 - a0 - q = h1 - 2 * h0 + a0 - r = a1 - 3 * h1 + 3 * h0 - a0 - - a = cross2d(q, r) - b = cross2d(p, r) - c = cross2d(p, q) - - disc = b * b - 4 * a * c - has_infl &= disc > 0 - sqrt_disc = np.sqrt(np.abs(disc)) - settings = np.seterr(all="ignore") - ti_bounds = [] - for sgn in [-1, +1]: - ti = (-b + sgn * sqrt_disc) / (2 * a) - ti[a == 0] = (-c / b)[a == 0] - ti[(a == 0) & (b == 0)] = 0 - ti_bounds.append(ti) - ti_min, ti_max = ti_bounds - np.seterr(**settings) - ti_min_in_range = has_infl & (0 < ti_min) & (ti_min < 1) - ti_max_in_range = has_infl & (0 < ti_max) & (ti_max < 1) - - # Choose a value of t which starts at 0.5, - # but is updated to one of the inflection points - # if they lie between 0 and 1 - - t_mid = 0.5 * np.ones(len(a0)) - t_mid[ti_min_in_range] = ti_min[ti_min_in_range] - t_mid[ti_max_in_range] = ti_max[ti_max_in_range] - - m, n = a0.shape - t_mid = t_mid.repeat(n).reshape((m, n)) - - # Compute bezier point and tangent at the chosen value of t - mid = bezier([a0, h0, h1, a1])(t_mid) - Tm = bezier([h0 - a0, h1 - h0, a1 - h1])(t_mid) - - # Intersection between tangent lines at end points - # and tangent in the middle - i0 = find_intersection(a0, T0, mid, Tm) - i1 = find_intersection(a1, T1, mid, Tm) - - m, n = np.shape(a0) - result = np.zeros((6 * m, n)) - result[0::6] = a0 - result[1::6] = i0 - result[2::6] = mid - result[3::6] = mid - result[4::6] = i1 - result[5::6] = a1 + a0c = np.asarray(a0) + h0c = np.asarray(h0) + h1c = np.asarray(h1) + a1c = np.asarray(a1) + + if all(arr.ndim == 1 for arr in (a0c, h0c, h1c, a1c)): + num_curves, dim = 1, a0c.shape[0] + elif all(arr.ndim == 2 for arr in (a0c, h0c, h1c, a1c)): + num_curves, dim = a0c.shape + else: + raise ValueError("All arguments must be Point3D or Point3D_Array.") + + m0 = 0.25 * (3 * h0c + a0c) + m1 = 0.25 * (3 * h1c + a1c) + k = 0.5 * (m0 + m1) + + result = np.empty((6 * num_curves, dim)) + result[0::6] = a0c + result[1::6] = m0 + result[2::6] = k + result[3::6] = k + result[4::6] = m1 + result[5::6] = a1c return result -def is_closed(points: tuple[np.ndarray, np.ndarray]) -> bool: - return np.allclose(points[0], points[-1]) +def is_closed(points: Point3D_Array) -> bool: + """Returns ``True`` if the spline given by ``points`` is closed, by + checking if its first and last points are close to each other, or``False`` + otherwise. + + .. note:: + + This function reimplements :meth:`np.allclose`, because repeated + calling of :meth:`np.allclose` for only 2 points is inefficient. + + Parameters + ---------- + points + An array of points defining a spline. + + Returns + ------- + :class:`bool` + Whether the first and last points of the array are close enough or not + to be considered the same, thus considering the defined spline as + closed. + + Examples + -------- + .. code-block:: pycon + + >>> import numpy as np + >>> from manim import is_closed + >>> is_closed( + ... np.array( + ... [ + ... [0, 0, 0], + ... [1, 2, 3], + ... [3, 2, 1], + ... [0, 0, 0], + ... ] + ... ) + ... ) + True + >>> is_closed( + ... np.array( + ... [ + ... [0, 0, 0], + ... [1, 2, 3], + ... [3, 2, 1], + ... [1e-10, 1e-10, 1e-10], + ... ] + ... ) + ... ) + True + >>> is_closed( + ... np.array( + ... [ + ... [0, 0, 0], + ... [1, 2, 3], + ... [3, 2, 1], + ... [1e-2, 1e-2, 1e-2], + ... ] + ... ) + ... ) + False + """ + start, end = points[0], points[-1] + rtol = 1e-5 + atol = 1e-8 + tolerance = atol + rtol * start + if abs(end[0] - start[0]) > tolerance[0]: + return False + if abs(end[1] - start[1]) > tolerance[1]: + return False + return bool(abs(end[2] - start[2]) <= tolerance[2]) def proportions_along_bezier_curve_for_point( - point: typing.Iterable[float | int], - control_points: typing.Iterable[typing.Iterable[float | int]], - round_to: float | int | None = 1e-6, -) -> np.ndarray: + point: Point3DLike, + control_points: BezierPointsLike, + round_to: float = 1e-6, +) -> MatrixMN: """Obtains the proportion along the bezier curve corresponding to a given point given the bezier curve's control points. @@ -460,15 +2040,17 @@ def proportions_along_bezier_curve_for_point( roots.append(polynom_roots) roots = [[root for root in rootlist if root.imag == 0] for rootlist in roots] - roots = reduce(np.intersect1d, roots) # Get common roots. - roots = np.array([r.real for r in roots]) - return roots + # Get common roots + # arg-type: ignore + roots = reduce(np.intersect1d, roots) + result = np.asarray([r.real for r in roots if 0 <= r.real <= 1]) + return result def point_lies_on_bezier( - point: typing.Iterable[float | int], - control_points: typing.Iterable[typing.Iterable[float | int]], - round_to: float | int | None = 1e-6, + point: Point3DLike, + control_points: BezierPointsLike, + round_to: float = 1e-6, ) -> bool: """Checks if a given point lies on the bezier curves with the given control points. @@ -492,7 +2074,6 @@ def point_lies_on_bezier( bool Whether the point lies on the curve. """ - roots = proportions_along_bezier_curve_for_point(point, control_points, round_to) return len(roots) > 0 diff --git a/manim/utils/caching.py b/manim/utils/caching.py index 4e776d9777..177bb11c5c 100644 --- a/manim/utils/caching.py +++ b/manim/utils/caching.py @@ -1,10 +1,20 @@ from __future__ import annotations +from typing import TYPE_CHECKING, Callable + from .. import config, logger from ..utils.hashing import get_hash_from_play_call +__all__ = ["handle_caching_play"] + +if TYPE_CHECKING: + from typing import Any + + from manim.renderer.opengl_renderer import OpenGLRenderer + from manim.scene.scene import Scene -def handle_caching_play(func): + +def handle_caching_play(func: Callable[..., None]) -> Callable[..., None]: """Decorator that returns a wrapped version of func that will compute the hash of the play invocation. @@ -14,18 +24,17 @@ def handle_caching_play(func): Parameters ---------- - func : Callable[[...], None] + func The play like function that has to be written to the video file stream. Take the same parameters as `scene.play`. """ - # NOTE : This is only kept for OpenGL renderer. # The play logic of the cairo renderer as been refactored and does not need this function anymore. # When OpenGL renderer will have a proper testing system, # the play logic of the latter has to be refactored in the same way the cairo renderer has been, and thus this # method has to be deleted. - def wrapper(self, scene, *args, **kwargs): + def wrapper(self: OpenGLRenderer, scene: Scene, *args: Any, **kwargs: Any) -> None: self.skip_animations = self._original_skipping_status self.update_skipping_status() animations = scene.compile_animations(*args, **kwargs) @@ -40,8 +49,9 @@ def wrapper(self, scene, *args, **kwargs): return if not config["disable_caching"]: mobjects_on_scene = scene.mobjects + # TODO: the first argument seems wrong. Shouldn't it be scene instead? hash_play = get_hash_from_play_call( - self, + self, # type: ignore[arg-type] self.camera, animations, mobjects_on_scene, diff --git a/manim/utils/color.py b/manim/utils/color.py deleted file mode 100644 index 6356fb3f04..0000000000 --- a/manim/utils/color.py +++ /dev/null @@ -1,552 +0,0 @@ -"""Colors and utility functions for conversion between different color models.""" - -from __future__ import annotations - -__all__ = [ - "color_to_rgb", - "color_to_rgba", - "rgb_to_color", - "rgba_to_color", - "rgb_to_hex", - "hex_to_rgb", - "invert_color", - "color_to_int_rgb", - "color_to_int_rgba", - "color_gradient", - "interpolate_color", - "average_color", - "random_bright_color", - "random_color", - "get_shaded_rgb", -] - -import random -from enum import Enum -from typing import Iterable - -import numpy as np -from colour import Color - -from ..utils.bezier import interpolate -from ..utils.space_ops import normalize - - -class Colors(Enum): - """A list of pre-defined colors. - - Examples - -------- - - .. manim:: ColorsOverview - :save_last_frame: - :hide_source: - - from manim.utils.color import Colors - class ColorsOverview(Scene): - def construct(self): - def color_group(color): - group = VGroup( - *[ - Line(ORIGIN, RIGHT * 1.5, stroke_width=35, color=Colors[name].value) - for name in subnames(color) - ] - ).arrange_submobjects(buff=0.4, direction=DOWN) - - name = Text(color).scale(0.6).next_to(group, UP, buff=0.3) - if any(decender in color for decender in "gjpqy"): - name.shift(DOWN * 0.08) - group.add(name) - return group - - def subnames(name): - return [name + "_" + char for char in "abcde"] - - color_groups = VGroup( - *[ - color_group(color) - for color in [ - "blue", - "teal", - "green", - "yellow", - "gold", - "red", - "maroon", - "purple", - ] - ] - ).arrange_submobjects(buff=0.2, aligned_edge=DOWN) - - for line, char in zip(color_groups[0], "abcde"): - color_groups.add(Text(char).scale(0.6).next_to(line, LEFT, buff=0.2)) - - def named_lines_group(length, colors, names, text_colors, align_to_block): - lines = VGroup( - *[ - Line( - ORIGIN, - RIGHT * length, - stroke_width=55, - color=Colors[color].value, - ) - for color in colors - ] - ).arrange_submobjects(buff=0.6, direction=DOWN) - - for line, name, color in zip(lines, names, text_colors): - line.add(Text(name, color=color).scale(0.6).move_to(line)) - lines.next_to(color_groups, DOWN, buff=0.5).align_to( - color_groups[align_to_block], LEFT - ) - return lines - - other_colors = ( - "pink", - "light_pink", - "orange", - "light_brown", - "dark_brown", - "gray_brown", - ) - - other_lines = named_lines_group( - 3.2, - other_colors, - other_colors, - [BLACK] * 4 + [WHITE] * 2, - 0, - ) - - gray_lines = named_lines_group( - 6.6, - ["white"] + subnames("gray") + ["black"], - [ - "white", - "lighter_gray / gray_a", - "light_gray / gray_b", - "gray / gray_c", - "dark_gray / gray_d", - "darker_gray / gray_e", - "black", - ], - [BLACK] * 3 + [WHITE] * 4, - 2, - ) - - pure_colors = ( - "pure_red", - "pure_green", - "pure_blue", - ) - - pure_lines = named_lines_group( - 3.2, - pure_colors, - pure_colors, - [BLACK, BLACK, WHITE], - 6, - ) - - self.add(color_groups, other_lines, gray_lines, pure_lines) - - VGroup(*self.mobjects).move_to(ORIGIN) - - - The preferred way of using these colors is by importing their constants from manim: - - .. code-block:: pycon - - >>> from manim import RED, GREEN, BLUE - >>> RED - '#FC6255' - - Note this way uses the name of the colors in UPPERCASE. - - Alternatively, you can also import this Enum directly and use its members - directly, through the use of :code:`color.value`. Note this way uses the - name of the colors in lowercase. - - .. code-block:: pycon - - >>> from manim.utils.color import Colors - >>> Colors.red.value - '#FC6255' - - .. note:: - - The colors of type "C" have an alias equal to the colorname without a letter, - e.g. GREEN = GREEN_C - - """ - - white: str = "#FFFFFF" - gray_a: str = "#DDDDDD" - gray_b: str = "#BBBBBB" - gray_c: str = "#888888" - gray_d: str = "#444444" - gray_e: str = "#222222" - black: str = "#000000" - lighter_gray: str = gray_a - light_gray: str = gray_b - gray: str = gray_c - dark_gray: str = gray_d - darker_gray: str = gray_e - - blue_a: str = "#C7E9F1" - blue_b: str = "#9CDCEB" - blue_c: str = "#58C4DD" - blue_d: str = "#29ABCA" - blue_e: str = "#236B8E" - pure_blue: str = "#0000FF" - blue: str = blue_c - dark_blue: str = blue_e - - teal_a: str = "#ACEAD7" - teal_b: str = "#76DDC0" - teal_c: str = "#5CD0B3" - teal_d: str = "#55C1A7" - teal_e: str = "#49A88F" - teal: str = teal_c - - green_a: str = "#C9E2AE" - green_b: str = "#A6CF8C" - green_c: str = "#83C167" - green_d: str = "#77B05D" - green_e: str = "#699C52" - pure_green: str = "#00FF00" - green: str = green_c - - yellow_a: str = "#FFF1B6" - yellow_b: str = "#FFEA94" - yellow_c: str = "#FFFF00" - yellow_d: str = "#F4D345" - yellow_e: str = "#E8C11C" - yellow: str = yellow_c - - gold_a: str = "#F7C797" - gold_b: str = "#F9B775" - gold_c: str = "#F0AC5F" - gold_d: str = "#E1A158" - gold_e: str = "#C78D46" - gold: str = gold_c - - red_a: str = "#F7A1A3" - red_b: str = "#FF8080" - red_c: str = "#FC6255" - red_d: str = "#E65A4C" - red_e: str = "#CF5044" - pure_red: str = "#FF0000" - red: str = red_c - - maroon_a: str = "#ECABC1" - maroon_b: str = "#EC92AB" - maroon_c: str = "#C55F73" - maroon_d: str = "#A24D61" - maroon_e: str = "#94424F" - maroon: str = maroon_c - - purple_a: str = "#CAA3E8" - purple_b: str = "#B189C6" - purple_c: str = "#9A72AC" - purple_d: str = "#715582" - purple_e: str = "#644172" - purple: str = purple_c - - pink: str = "#D147BD" - light_pink: str = "#DC75CD" - - orange: str = "#FF862F" - light_brown: str = "#CD853F" - dark_brown: str = "#8B4513" - gray_brown: str = "#736357" - - -def print_constant_definitions(): - """ - A simple function used to generate the constant values below. To run it - paste this function and the Colors class into a file and run them. - """ - constants_names: list[str] = [] - for name in Colors.__members__.keys(): - name_upper = name.upper() - - constants_names.append(name_upper) - print(f"{name_upper} = Colors.{name}") - - if "GRAY" in name_upper: - name_upper = name_upper.replace("GRAY", "GREY") - - constants_names.append(name_upper) - print(f"{name_upper} = Colors.{name}") - - constants_names_repr = '[\n "' + '",\n "'.join(constants_names) + '",\n]' - - print(f"\n__all__ += {constants_names_repr}") - - -WHITE: str = "#FFFFFF" -GRAY_A: str = "#DDDDDD" -GREY_A: str = "#DDDDDD" -GRAY_B: str = "#BBBBBB" -GREY_B: str = "#BBBBBB" -GRAY_C: str = "#888888" -GREY_C: str = "#888888" -GRAY_D: str = "#444444" -GREY_D: str = "#444444" -GRAY_E: str = "#222222" -GREY_E: str = "#222222" -BLACK: str = "#000000" -LIGHTER_GRAY: str = "#DDDDDD" -LIGHTER_GREY: str = "#DDDDDD" -LIGHT_GRAY: str = "#BBBBBB" -LIGHT_GREY: str = "#BBBBBB" -GRAY: str = "#888888" -GREY: str = "#888888" -DARK_GRAY: str = "#444444" -DARK_GREY: str = "#444444" -DARKER_GRAY: str = "#222222" -DARKER_GREY: str = "#222222" -BLUE_A: str = "#C7E9F1" -BLUE_B: str = "#9CDCEB" -BLUE_C: str = "#58C4DD" -BLUE_D: str = "#29ABCA" -BLUE_E: str = "#236B8E" -PURE_BLUE: str = "#0000FF" -BLUE: str = "#58C4DD" -DARK_BLUE: str = "#236B8E" -TEAL_A: str = "#ACEAD7" -TEAL_B: str = "#76DDC0" -TEAL_C: str = "#5CD0B3" -TEAL_D: str = "#55C1A7" -TEAL_E: str = "#49A88F" -TEAL: str = "#5CD0B3" -GREEN_A: str = "#C9E2AE" -GREEN_B: str = "#A6CF8C" -GREEN_C: str = "#83C167" -GREEN_D: str = "#77B05D" -GREEN_E: str = "#699C52" -PURE_GREEN: str = "#00FF00" -GREEN: str = "#83C167" -YELLOW_A: str = "#FFF1B6" -YELLOW_B: str = "#FFEA94" -YELLOW_C: str = "#FFFF00" -YELLOW_D: str = "#F4D345" -YELLOW_E: str = "#E8C11C" -YELLOW: str = "#FFFF00" -GOLD_A: str = "#F7C797" -GOLD_B: str = "#F9B775" -GOLD_C: str = "#F0AC5F" -GOLD_D: str = "#E1A158" -GOLD_E: str = "#C78D46" -GOLD: str = "#F0AC5F" -RED_A: str = "#F7A1A3" -RED_B: str = "#FF8080" -RED_C: str = "#FC6255" -RED_D: str = "#E65A4C" -RED_E: str = "#CF5044" -PURE_RED: str = "#FF0000" -RED: str = "#FC6255" -MAROON_A: str = "#ECABC1" -MAROON_B: str = "#EC92AB" -MAROON_C: str = "#C55F73" -MAROON_D: str = "#A24D61" -MAROON_E: str = "#94424F" -MAROON: str = "#C55F73" -PURPLE_A: str = "#CAA3E8" -PURPLE_B: str = "#B189C6" -PURPLE_C: str = "#9A72AC" -PURPLE_D: str = "#715582" -PURPLE_E: str = "#644172" -PURPLE: str = "#9A72AC" -PINK: str = "#D147BD" -LIGHT_PINK: str = "#DC75CD" -ORANGE: str = "#FF862F" -LIGHT_BROWN: str = "#CD853F" -DARK_BROWN: str = "#8B4513" -GRAY_BROWN: str = "#736357" -GREY_BROWN: str = "#736357" - -__all__ += [ - "WHITE", - "GRAY_A", - "GREY_A", - "GRAY_B", - "GREY_B", - "GRAY_C", - "GREY_C", - "GRAY_D", - "GREY_D", - "GRAY_E", - "GREY_E", - "BLACK", - "LIGHTER_GRAY", - "LIGHTER_GREY", - "LIGHT_GRAY", - "LIGHT_GREY", - "GRAY", - "GREY", - "DARK_GRAY", - "DARK_GREY", - "DARKER_GRAY", - "DARKER_GREY", - "BLUE_A", - "BLUE_B", - "BLUE_C", - "BLUE_D", - "BLUE_E", - "PURE_BLUE", - "BLUE", - "DARK_BLUE", - "TEAL_A", - "TEAL_B", - "TEAL_C", - "TEAL_D", - "TEAL_E", - "TEAL", - "GREEN_A", - "GREEN_B", - "GREEN_C", - "GREEN_D", - "GREEN_E", - "PURE_GREEN", - "GREEN", - "YELLOW_A", - "YELLOW_B", - "YELLOW_C", - "YELLOW_D", - "YELLOW_E", - "YELLOW", - "GOLD_A", - "GOLD_B", - "GOLD_C", - "GOLD_D", - "GOLD_E", - "GOLD", - "RED_A", - "RED_B", - "RED_C", - "RED_D", - "RED_E", - "PURE_RED", - "RED", - "MAROON_A", - "MAROON_B", - "MAROON_C", - "MAROON_D", - "MAROON_E", - "MAROON", - "PURPLE_A", - "PURPLE_B", - "PURPLE_C", - "PURPLE_D", - "PURPLE_E", - "PURPLE", - "PINK", - "LIGHT_PINK", - "ORANGE", - "LIGHT_BROWN", - "DARK_BROWN", - "GRAY_BROWN", - "GREY_BROWN", -] - - -def color_to_rgb(color: Color | str) -> np.ndarray: - if isinstance(color, str): - return hex_to_rgb(color) - elif isinstance(color, Color): - return np.array(color.get_rgb()) - else: - raise ValueError("Invalid color type: " + str(color)) - - -def color_to_rgba(color: Color | str, alpha: float = 1) -> np.ndarray: - return np.array([*color_to_rgb(color), alpha]) - - -def rgb_to_color(rgb: Iterable[float]) -> Color: - return Color(rgb=rgb) - - -def rgba_to_color(rgba: Iterable[float]) -> Color: - return rgb_to_color(rgba[:3]) - - -def rgb_to_hex(rgb: Iterable[float]) -> str: - return "#" + "".join("%02x" % round(255 * x) for x in rgb) - - -def hex_to_rgb(hex_code: str) -> np.ndarray: - hex_part = hex_code[1:] - if len(hex_part) == 3: - hex_part = "".join([2 * c for c in hex_part]) - return np.array([int(hex_part[i : i + 2], 16) / 255 for i in range(0, 6, 2)]) - - -def invert_color(color: Color) -> Color: - return rgb_to_color(1.0 - color_to_rgb(color)) - - -def color_to_int_rgb(color: Color) -> np.ndarray: - return (255 * color_to_rgb(color)).astype("uint8") - - -def color_to_int_rgba(color: Color, opacity: float = 1.0) -> np.ndarray: - alpha_multiplier = np.vectorize(lambda x: int(x * opacity)) - - return alpha_multiplier(np.append(color_to_int_rgb(color), 255)) - - -def color_gradient( - reference_colors: Iterable[Color], - length_of_output: int, -) -> list[Color]: - if length_of_output == 0: - return reference_colors[0] - rgbs = list(map(color_to_rgb, reference_colors)) - alphas = np.linspace(0, (len(rgbs) - 1), length_of_output) - floors = alphas.astype("int") - alphas_mod1 = alphas % 1 - # End edge case - alphas_mod1[-1] = 1 - floors[-1] = len(rgbs) - 2 - return [ - rgb_to_color(interpolate(rgbs[i], rgbs[i + 1], alpha)) - for i, alpha in zip(floors, alphas_mod1) - ] - - -def interpolate_color(color1: Color, color2: Color, alpha: float) -> Color: - rgb = interpolate(color_to_rgb(color1), color_to_rgb(color2), alpha) - return rgb_to_color(rgb) - - -def average_color(*colors: Color) -> Color: - rgbs = np.array(list(map(color_to_rgb, colors))) - mean_rgb = np.apply_along_axis(np.mean, 0, rgbs) - return rgb_to_color(mean_rgb) - - -def random_bright_color() -> Color: - color = random_color() - curr_rgb = color_to_rgb(color) - new_rgb = interpolate(curr_rgb, np.ones(len(curr_rgb)), 0.5) - return Color(rgb=new_rgb) - - -def random_color() -> Color: - return random.choice([c.value for c in list(Colors)]) - - -def get_shaded_rgb( - rgb: np.ndarray, - point: np.ndarray, - unit_normal_vect: np.ndarray, - light_source: np.ndarray, -) -> np.ndarray: - to_sun = normalize(light_source - point) - factor = 0.5 * np.dot(unit_normal_vect, to_sun) ** 3 - if factor < 0: - factor *= 0.5 - result = rgb + factor - return result diff --git a/manim/utils/color/AS2700.py b/manim/utils/color/AS2700.py new file mode 100644 index 0000000000..7b6dc6256c --- /dev/null +++ b/manim/utils/color/AS2700.py @@ -0,0 +1,236 @@ +"""Australian Color Standard + +In 1985 the Australian Independent Color Standard AS 2700 was created. In +this standard, all colors can be identified via a category code (one of +B -- Blue, G -- Green, N -- Neutrals (grey), P -- Purple, R -- Red, T -- Blue/Green, +X -- Yellow/Red, Y -- Yellow) and a number. The colors also have (natural) names. + +To use the colors from this list, access them directly from the module (which +is exposed to Manim's global name space): + +.. code:: pycon + + >>> from manim import AS2700 + >>> AS2700.B23_BRIGHT_BLUE + ManimColor('#174F90') + +List of Color Constants +----------------------- + +These hex values (taken from https://www.w3schools.com/colors/colors_australia.asp) +are non official approximate values intended to simulate AS 2700 colors: + +.. automanimcolormodule:: manim.utils.color.AS2700 + +""" + +from __future__ import annotations + +from .core import ManimColor + +B11_RICH_BLUE = ManimColor("#2B3770") +B12_ROYAL_BLUE = ManimColor("#2C3563") +B13_NAVY_BLUE = ManimColor("#28304D") +B14_SAPHHIRE = ManimColor("#28426B") +B15_MID_BLUE = ManimColor("#144B6F") +B21_ULTRAMARINE = ManimColor("#2C5098") +B22_HOMEBUSH_BLUE = ManimColor("#215097") +B23_BRIGHT_BLUE = ManimColor("#174F90") +B24_HARBOUR_BLUE = ManimColor("#1C6293") +B25_AQUA = ManimColor("#5097AC") +B32_POWDER_BLUE = ManimColor("#B7C8DB") +B33_MIST_BLUE = ManimColor("#E0E6E2") +B34_PARADISE_BLUE = ManimColor("#3499BA") +B35_PALE_BLUE = ManimColor("#CDE4E2") +B41_BLUEBELL = ManimColor("#5B94D1") +B42_PURPLE_BLUE = ManimColor("#5E7899") +B43_GREY_BLUE = ManimColor("#627C8D") +B44_LIGHT_GREY_BLUE = ManimColor("#C0C0C1") +B45_SKY_BLUE = ManimColor("#7DB7C7") +B51_PERIWINKLE = ManimColor("#3871AC") +B53_DARK_GREY_BLUE = ManimColor("#4F6572") +B55_STORM_BLUE = ManimColor("#3F7C94") +B61_CORAL_SEA = ManimColor("#2B3873") +B62_MIDNIGHT_BLUE = ManimColor("#292A34") +B64_CHARCOAL = ManimColor("#363E45") +G11_BOTTLE_GREEN = ManimColor("#253A32") +G12_HOLLY = ManimColor("#21432D") +G13_EMERALD = ManimColor("#195F35") +G14_MOSS_GREEN = ManimColor("#33572D") +G15_RAINFOREST_GREEN = ManimColor("#3D492D") +G16_TRAFFIC_GREEN = ManimColor("#305442") +G17_MINT_GREEN = ManimColor("#006B45") +G21_JADE = ManimColor("#127453") +G22_SERPENTINE = ManimColor("#78A681") +G23_SHAMROCK = ManimColor("#336634") +G24_FERN_TREE = ManimColor("#477036") +G25_OLIVE = ManimColor("#595B2A") +G26_APPLE_GREEN = ManimColor("#4E9843") +G27_HOMEBUSH_GREEN = ManimColor("#017F4D") +G31_VERTIGRIS = ManimColor("#468A65") +G32_OPALINE = ManimColor("#AFCBB8") +G33_LETTUCE = ManimColor("#7B9954") +G34_AVOCADO = ManimColor("#757C4C") +G35_LIME_GREEN = ManimColor("#89922E") +G36_KIKUYU = ManimColor("#95B43B") +G37_BEANSTALK = ManimColor("#45A56A") +G41_LAWN_GREEN = ManimColor("#0D875D") +G42_GLACIER = ManimColor("#D5E1D2") +G43_SURF_GREEN = ManimColor("#C8C8A7") +G44_PALM_GREEN = ManimColor("#99B179") +G45_CHARTREUSE = ManimColor("#C7C98D") +G46_CITRONELLA = ManimColor("#BFC83E") +G47_CRYSTAL_GREEN = ManimColor("#ADCCA8") +G51_SPRUCE = ManimColor("#05674F") +G52_EUCALYPTUS = ManimColor("#66755B") +G53_BANKSIA = ManimColor("#929479") +G54_MIST_GREEN = ManimColor("#7A836D") +G55_LICHEN = ManimColor("#A7A98C") +G56_SAGE_GREEN = ManimColor("#677249") +G61_DARK_GREEN = ManimColor("#283533") +G62_RIVERGUM = ManimColor("#617061") +G63_DEEP_BRONZE_GREEN = ManimColor("#333334") +G64_SLATE = ManimColor("#5E6153") +G65_TI_TREE = ManimColor("#5D5F4E") +G66_ENVIRONMENT_GREEN = ManimColor("#484C3F") +G67_ZUCCHINI = ManimColor("#2E443A") +N11_PEARL_GREY = ManimColor("#D8D3C7") +N12_PASTEL_GREY = ManimColor("#CCCCCC") +N14_WHITE = ManimColor("#FFFFFF") +N15_HOMEBUSH_GREY = ManimColor("#A29B93") +N22_CLOUD_GREY = ManimColor("#C4C1B9") +N23_NEUTRAL_GREY = ManimColor("#CCCCCC") +N24_SILVER_GREY = ManimColor("#BDC7C5") +N25_BIRCH_GREY = ManimColor("#ABA498") +N32_GREEN_GREY = ManimColor("#8E9282") +N33_LIGHTBOX_GREY = ManimColor("#ACADAD") +N35_LIGHT_GREY = ManimColor("#A6A7A1") +N41_OYSTER = ManimColor("#998F78") +N42_STORM_GREY = ManimColor("#858F88") +N43_PIPELINE_GREY = ManimColor("#999999") +N44_BRIDGE_GREY = ManimColor("#767779") +N45_KOALA_GREY = ManimColor("#928F88") +N52_MID_GREY = ManimColor("#727A77") +N53_BLUE_GREY = ManimColor("#7C8588") +N54_BASALT = ManimColor("#585C63") +N55_LEAD_GREY = ManimColor("#5E5C58") +N61_BLACK = ManimColor("#2A2A2C") +N63_PEWTER = ManimColor("#596064") +N64_DARK_GREY = ManimColor("#4B5259") +N65_GRAPHITE_GREY = ManimColor("#45474A") +P11_MAGENTA = ManimColor("#7B2B48") +P12_PURPLE = ManimColor("#85467B") +P13_VIOLET = ManimColor("#5D3A61") +P14_BLUEBERRY = ManimColor("#4C4176") +P21_SUNSET_PINK = ManimColor("#E3BBBD") +P22_CYCLAMEN = ManimColor("#83597D") +P23_LILAC = ManimColor("#A69FB1") +P24_JACKARANDA = ManimColor("#795F91") +P31_DUSTY_PINK = ManimColor("#DBBEBC") +P33_RIBBON_PINK = ManimColor("#D1BCC9") +P41_ERICA_PINK = ManimColor("#C55A83") +P42_MULBERRY = ManimColor("#A06574") +P43_WISTERIA = ManimColor("#756D91") +P52_PLUM = ManimColor("#6E3D4B") +R11_INTERNATIONAL_ORANGE = ManimColor("#CE482A") +R12_SCARLET = ManimColor("#CD392A") +R13_SIGNAL_RED = ManimColor("#BA312B") +R14_WARATAH = ManimColor("#AA2429") +R15_CRIMSON = ManimColor("#9E2429") +R21_TANGERINE = ManimColor("#E96957") +R22_HOMEBUSH_RED = ManimColor("#D83A2D") +R23_LOLLIPOP = ManimColor("#CC5058") +R24_STRAWBERRY = ManimColor("#B4292A") +R25_ROSE_PINK = ManimColor("#E8919C") +R32_APPLE_BLOSSOM = ManimColor("#F2E1D8") +R33_GHOST_GUM = ManimColor("#E8DAD4") +R34_MUSHROOM = ManimColor("#D7C0B6") +R35_DEEP_ROSE = ManimColor("#CD6D71") +R41_SHELL_PINK = ManimColor("#F9D9BB") +R42_SALMON_PINK = ManimColor("#D99679") +R43_RED_DUST = ManimColor("#D0674F") +R44_POSSUM = ManimColor("#A18881") +R45_RUBY = ManimColor("#8F3E5C") +R51_BURNT_PINK = ManimColor("#E19B8E") +R52_TERRACOTTA = ManimColor("#A04C36") +R53_RED_GUM = ManimColor("#8D4338") +R54_RASPBERRY = ManimColor("#852F31") +R55_CLARET = ManimColor("#67292D") +R62_VENETIAN_RED = ManimColor("#77372B") +R63_RED_OXIDE = ManimColor("#663334") +R64_DEEP_INDIAN_RED = ManimColor("#542E2B") +R65_MAROON = ManimColor("#3F2B3C") +T11_TROPICAL_BLUE = ManimColor("#006698") +T12_DIAMANTIA = ManimColor("#006C74") +T14_MALACHITE = ManimColor("#105154") +T15_TURQUOISE = ManimColor("#098587") +T22_ORIENTAL_BLUE = ManimColor("#358792") +T24_BLUE_JADE = ManimColor("#427F7E") +T32_HUON_GREEN = ManimColor("#72B3B1") +T33_SMOKE_BLUE = ManimColor("#9EB6B2") +T35_GREEN_ICE = ManimColor("#78AEA2") +T44_BLUE_GUM = ManimColor("#6A8A88") +T45_COOTAMUNDRA = ManimColor("#759E91") +T51_MOUNTAIN_BLUE = ManimColor("#295668") +T53_PEACOCK_BLUE = ManimColor("#245764") +T63_TEAL = ManimColor("#183F4E") +X11_BUTTERSCOTCH = ManimColor("#D38F43") +X12_PUMPKIN = ManimColor("#DD7E1A") +X13_MARIGOLD = ManimColor("#ED7F15") +X14_MANDARIN = ManimColor("#E45427") +X15_ORANGE = ManimColor("#E36C2B") +X21_PALE_OCHRE = ManimColor("#DAA45F") +X22_SAFFRON = ManimColor("#F6AA51") +X23_APRICOT = ManimColor("#FEB56D") +X24_ROCKMELON = ManimColor("#F6894B") +X31_RAFFIA = ManimColor("#EBC695") +X32_MAGNOLIA = ManimColor("#F1DEBE") +X33_WARM_WHITE = ManimColor("#F3E7D4") +X34_DRIFTWOOD = ManimColor("#D5C4AE") +X41_BUFF = ManimColor("#C28A44") +X42_BISCUIT = ManimColor("#DEBA92") +X43_BEIGE = ManimColor("#C9AA8C") +X45_CINNAMON = ManimColor("#AC826D") +X51_TAN = ManimColor("#8F5F32") +X52_COFFEE = ManimColor("#AD7948") +X53_GOLDEN_TAN = ManimColor("#925629") +X54_BROWN = ManimColor("#68452C") +X55_NUT_BROWN = ManimColor("#764832") +X61_WOMBAT = ManimColor("#6E5D52") +X62_DARK_EARTH = ManimColor("#6E5D52") +X63_IRONBARK = ManimColor("#443B36") +X64_CHOCOLATE = ManimColor("#4A3B31") +X65_DARK_BROWN = ManimColor("#4F372D") +Y11_CANARY = ManimColor("#E7BD11") +Y12_WATTLE = ManimColor("#E8AF01") +Y13_VIVID_YELLOW = ManimColor("#FCAE01") +Y14_GOLDEN_YELLOW = ManimColor("#F5A601") +Y15_SUNFLOWER = ManimColor("#FFA709") +Y16_INCA_GOLD = ManimColor("#DF8C19") +Y21_PRIMROSE = ManimColor("#F5CF5B") +Y22_CUSTARD = ManimColor("#EFD25C") +Y23_BUTTERCUP = ManimColor("#E0CD41") +Y24_STRAW = ManimColor("#E3C882") +Y25_DEEP_CREAM = ManimColor("#F3C968") +Y26_HOMEBUSH_GOLD = ManimColor("#FCC51A") +Y31_LILY_GREEN = ManimColor("#E3E3CD") +Y32_FLUMMERY = ManimColor("#E6DF9E") +Y33_PALE_PRIMROSE = ManimColor("#F5F3CE") +Y34_CREAM = ManimColor("#EFE3BE") +Y35_OFF_WHITE = ManimColor("#F1E9D5") +Y41_OLIVE_YELLOW = ManimColor("#8E7426") +Y42_MUSTARD = ManimColor("#C4A32E") +Y43_PARCHMENT = ManimColor("#D4C9A3") +Y44_SAND = ManimColor("#DCC18B") +Y45_MANILLA = ManimColor("#E5D0A7") +Y51_BRONZE_OLIVE = ManimColor("#695D3E") +Y52_CHAMOIS = ManimColor("#BEA873") +Y53_SANDSTONE = ManimColor("#D5BF8E") +Y54_OATMEAL = ManimColor("#CAAE82") +Y55_DEEP_STONE = ManimColor("#BC9969") +Y56_MERINO = ManimColor("#C9B79E") +Y61_BLACK_OLIVE = ManimColor("#47473B") +Y62_SUGAR_CANE = ManimColor("#BCA55C") +Y63_KHAKI = ManimColor("#826843") +Y65_MUSHROOM = ManimColor("#A39281") +Y66_MUDSTONE = ManimColor("#574E45") diff --git a/manim/utils/color/BS381.py b/manim/utils/color/BS381.py new file mode 100644 index 0000000000..60e8567a50 --- /dev/null +++ b/manim/utils/color/BS381.py @@ -0,0 +1,318 @@ +"""British Color Standard + +This module contains colors defined in one of the British Standards +for colors, BS381C. This standard specifies colors used in identification, +coding, and other special purposes. See https://www.britishstandardcolour.com/ +for more information. + +To use the colors from this list, access them directly from the module (which +is exposed to Manim's global name space): + +.. code:: pycon + + >>> from manim import BS381 + >>> BS381.OXFORD_BLUE + ManimColor('#1F3057') + +List of Color Constants +----------------------- + +These hex values (taken from https://www.w3schools.com/colors/colors_british.asp) +are non official approximate values intended to simulate the ones defined +in the standard: + +.. automanimcolormodule:: manim.utils.color.BS381 + +""" + +from __future__ import annotations + +from .core import ManimColor + +BS381_101 = ManimColor("#94BFAC") +SKY_BLUE = ManimColor("#94BFAC") +BS381_102 = ManimColor("#5B9291") +TURQUOISE_BLUE = ManimColor("#5B9291") +BS381_103 = ManimColor("#3B6879") +PEACOCK_BLUE = ManimColor("#3B6879") +BS381_104 = ManimColor("#264D7E") +AZURE_BLUE = ManimColor("#264D7E") +BS381_105 = ManimColor("#1F3057") +OXFORD_BLUE = ManimColor("#1F3057") +BS381_106 = ManimColor("#2A283D") +ROYAL_BLUE = ManimColor("#2A283D") +BS381_107 = ManimColor("#3A73A9") +STRONG_BLUE = ManimColor("#3A73A9") +BS381_108 = ManimColor("#173679") +AIRCRAFT_BLUE = ManimColor("#173679") +BS381_109 = ManimColor("#1C5680") +MIDDLE_BLUE = ManimColor("#1C5680") +BS381_110 = ManimColor("#2C3E75") +ROUNDEL_BLUE = ManimColor("#2C3E75") +BS381_111 = ManimColor("#8CC5BB") +PALE_BLUE = ManimColor("#8CC5BB") +BS381_112 = ManimColor("#78ADC2") +ARCTIC_BLUE = ManimColor("#78ADC2") +FIESTA_BLUE = ManimColor("#78ADC2") +BS381_113 = ManimColor("#3F687D") +DEEP_SAXE_BLUE = ManimColor("#3F687D") +BS381_114 = ManimColor("#1F4B61") +RAIL_BLUE = ManimColor("#1F4B61") +BS381_115 = ManimColor("#5F88C1") +COBALT_BLUE = ManimColor("#5F88C1") +BS381_166 = ManimColor("#2458AF") +FRENCH_BLUE = ManimColor("#2458AF") +BS381_169 = ManimColor("#135B75") +TRAFFIC_BLUE = ManimColor("#135B75") +BS381_172 = ManimColor("#A7C6EB") +PALE_ROUNDEL_BLUE = ManimColor("#A7C6EB") +BS381_174 = ManimColor("#64A0AA") +ORIENT_BLUE = ManimColor("#64A0AA") +BS381_175 = ManimColor("#4F81C5") +LIGHT_FRENCH_BLUE = ManimColor("#4F81C5") +BS381_210 = ManimColor("#BBC9A5") +SKY = ManimColor("#BBC9A5") +BS381_216 = ManimColor("#BCD890") +EAU_DE_NIL = ManimColor("#BCD890") +BS381_217 = ManimColor("#96BF65") +SEA_GREEN = ManimColor("#96BF65") +BS381_218 = ManimColor("#698B47") +GRASS_GREEN = ManimColor("#698B47") +BS381_219 = ManimColor("#757639") +SAGE_GREEN = ManimColor("#757639") +BS381_220 = ManimColor("#4B5729") +OLIVE_GREEN = ManimColor("#4B5729") +BS381_221 = ManimColor("#507D3A") +BRILLIANT_GREEN = ManimColor("#507D3A") +BS381_222 = ManimColor("#6A7031") +LIGHT_BRONZE_GREEN = ManimColor("#6A7031") +BS381_223 = ManimColor("#49523A") +MIDDLE_BRONZE_GREEN = ManimColor("#49523A") +BS381_224 = ManimColor("#3E4630") +DEEP_BRONZE_GREEN = ManimColor("#3E4630") +BS381_225 = ManimColor("#406A28") +LIGHT_BRUNSWICK_GREEN = ManimColor("#406A28") +BS381_226 = ManimColor("#33533B") +MID_BRUNSWICK_GREEN = ManimColor("#33533B") +BS381_227 = ManimColor("#254432") +DEEP_BRUNSWICK_GREEN = ManimColor("#254432") +BS381_228 = ManimColor("#428B64") +EMERALD_GREEN = ManimColor("#428B64") +BS381_241 = ManimColor("#4F5241") +DARK_GREEN = ManimColor("#4F5241") +BS381_262 = ManimColor("#44945E") +BOLD_GREEN = ManimColor("#44945E") +BS381_267 = ManimColor("#476A4C") +DEEP_CHROME_GREEN = ManimColor("#476A4C") +TRAFFIC_GREEN = ManimColor("#476A4C") +BS381_275 = ManimColor("#8FC693") +OPALINE_GREEN = ManimColor("#8FC693") +BS381_276 = ManimColor("#2E4C1E") +LINCON_GREEN = ManimColor("#2E4C1E") +BS381_277 = ManimColor("#364A20") +CYPRESS_GREEN = ManimColor("#364A20") +BS381_278 = ManimColor("#87965A") +LIGHT_OLIVE_GREEN = ManimColor("#87965A") +BS381_279 = ManimColor("#3B3629") +STEEL_FURNITURE_GREEN = ManimColor("#3B3629") +BS381_280 = ManimColor("#68AB77") +VERDIGRIS_GREEN = ManimColor("#68AB77") +BS381_282 = ManimColor("#506B52") +FOREST_GREEN = ManimColor("#506B52") +BS381_283 = ManimColor("#7E8F6E") +AIRCRAFT_GREY_GREEN = ManimColor("#7E8F6E") +BS381_284 = ManimColor("#6B6F5A") +SPRUCE_GREEN = ManimColor("#6B6F5A") +BS381_285 = ManimColor("#5F5C4B") +NATO_GREEN = ManimColor("#5F5C4B") +BS381_298 = ManimColor("#4F5138") +OLIVE_DRAB = ManimColor("#4F5138") +BS381_309 = ManimColor("#FEEC04") +CANARY_YELLOW = ManimColor("#FEEC04") +BS381_310 = ManimColor("#FEF963") +PRIMROSE = ManimColor("#FEF963") +BS381_315 = ManimColor("#FEF96A") +GRAPEFRUIT = ManimColor("#FEF96A") +BS381_320 = ManimColor("#9E7339") +LIGHT_BROWN = ManimColor("#9E7339") +BS381_337 = ManimColor("#4C4A3C") +VERY_DARK_DRAB = ManimColor("#4C4A3C") +BS381_350 = ManimColor("#7B6B4F") +DARK_EARTH = ManimColor("#7B6B4F") +BS381_352 = ManimColor("#FCED96") +PALE_CREAM = ManimColor("#FCED96") +BS381_353 = ManimColor("#FDF07A") +DEEP_CREAM = ManimColor("#FDF07A") +BS381_354 = ManimColor("#E9BB43") +PRIMROSE_2 = ManimColor("#E9BB43") +BS381_355 = ManimColor("#FDD906") +LEMON = ManimColor("#FDD906") +BS381_356 = ManimColor("#FCC808") +GOLDEN_YELLOW = ManimColor("#FCC808") +BS381_358 = ManimColor("#F6C870") +LIGHT_BUFF = ManimColor("#F6C870") +BS381_359 = ManimColor("#DBAC50") +MIDDLE_BUFF = ManimColor("#DBAC50") +BS381_361 = ManimColor("#D4B97D") +LIGHT_STONE = ManimColor("#D4B97D") +BS381_362 = ManimColor("#AC7C42") +MIDDLE_STONE = ManimColor("#AC7C42") +BS381_363 = ManimColor("#FDE706") +BOLD_YELLOW = ManimColor("#FDE706") +BS381_364 = ManimColor("#CEC093") +PORTLAND_STONE = ManimColor("#CEC093") +BS381_365 = ManimColor("#F4F0BD") +VELLUM = ManimColor("#F4F0BD") +BS381_366 = ManimColor("#F5E7A1") +LIGHT_BEIGE = ManimColor("#F5E7A1") +BS381_367 = ManimColor("#FEF6BF") +MANILLA = ManimColor("#fef6bf") +BS381_368 = ManimColor("#DD7B00") +TRAFFIC_YELLOW = ManimColor("#DD7B00") +BS381_369 = ManimColor("#FEEBA8") +BISCUIT = ManimColor("#feeba8") +BS381_380 = ManimColor("#BBA38A") +CAMOUFLAGE_DESERT_SAND = ManimColor("#BBA38A") +BS381_384 = ManimColor("#EEDFA5") +LIGHT_STRAW = ManimColor("#EEDFA5") +BS381_385 = ManimColor("#E8C88F") +LIGHT_BISCUIT = ManimColor("#E8C88F") +BS381_386 = ManimColor("#E6C18D") +CHAMPAGNE = ManimColor("#e6c18d") +BS381_387 = ManimColor("#CFB48A") +SUNRISE = ManimColor("#cfb48a") +SUNSHINE = ManimColor("#cfb48a") +BS381_388 = ManimColor("#E4CF93") +BEIGE = ManimColor("#e4cf93") +BS381_389 = ManimColor("#B2A788") +CAMOUFLAGE_BEIGE = ManimColor("#B2A788") +BS381_397 = ManimColor("#F3D163") +JASMINE_YELLOW = ManimColor("#F3D163") +BS381_411 = ManimColor("#74542F") +MIDDLE_BROWN = ManimColor("#74542F") +BS381_412 = ManimColor("#5C422E") +DARK_BROWN = ManimColor("#5C422E") +BS381_413 = ManimColor("#402D21") +NUT_BROWN = ManimColor("#402D21") +BS381_414 = ManimColor("#A86C29") +GOLDEN_BROWN = ManimColor("#A86C29") +BS381_415 = ManimColor("#61361E") +IMPERIAL_BROWN = ManimColor("#61361E") +BS381_420 = ManimColor("#A89177") +DARK_CAMOUFLAGE_DESERT_SAND = ManimColor("#A89177") +BS381_435 = ManimColor("#845B4D") +CAMOUFLAGE_RED = ManimColor("#845B4D") +BS381_436 = ManimColor("#564B47") +DARK_CAMOUFLAGE_BROWN = ManimColor("#564B47") +BS381_439 = ManimColor("#753B1E") +ORANGE_BROWN = ManimColor("#753B1E") +BS381_443 = ManimColor("#C98A71") +SALMON = ManimColor("#c98a71") +BS381_444 = ManimColor("#A65341") +TERRACOTTA = ManimColor("#a65341") +BS381_445 = ManimColor("#83422B") +VENETIAN_RED = ManimColor("#83422B") +BS381_446 = ManimColor("#774430") +RED_OXIDE = ManimColor("#774430") +BS381_447 = ManimColor("#F3B28B") +SALMON_PINK = ManimColor("#F3B28B") +BS381_448 = ManimColor("#67403A") +DEEP_INDIAN_RED = ManimColor("#67403A") +BS381_449 = ManimColor("#693B3F") +LIGHT_PURPLE_BROWN = ManimColor("#693B3F") +BS381_452 = ManimColor("#613339") +DARK_CRIMSON = ManimColor("#613339") +BS381_453 = ManimColor("#FBDED6") +SHELL_PINK = ManimColor("#FBDED6") +BS381_454 = ManimColor("#E8A1A2") +PALE_ROUNDEL_RED = ManimColor("#E8A1A2") +BS381_460 = ManimColor("#BD8F56") +DEEP_BUFF = ManimColor("#BD8F56") +BS381_473 = ManimColor("#793932") +GULF_RED = ManimColor("#793932") +BS381_489 = ManimColor("#8D5B41") +LEAF_BROWN = ManimColor("#8D5B41") +BS381_490 = ManimColor("#573320") +BEECH_BROWN = ManimColor("#573320") +BS381_499 = ManimColor("#59493E") +SERVICE_BROWN = ManimColor("#59493E") +BS381_536 = ManimColor("#BB3016") +POPPY = ManimColor("#bb3016") +BS381_537 = ManimColor("#DD3420") +SIGNAL_RED = ManimColor("#DD3420") +BS381_538 = ManimColor("#C41C22") +POST_OFFICE_RED = ManimColor("#C41C22") +CHERRY = ManimColor("#c41c22") +BS381_539 = ManimColor("#D21E2B") +CURRANT_RED = ManimColor("#D21E2B") +BS381_540 = ManimColor("#8B1A32") +CRIMSON = ManimColor("#8b1a32") +BS381_541 = ManimColor("#471B21") +MAROON = ManimColor("#471b21") +BS381_542 = ManimColor("#982D57") +RUBY = ManimColor("#982d57") +BS381_557 = ManimColor("#EF841E") +LIGHT_ORANGE = ManimColor("#EF841E") +BS381_564 = ManimColor("#DD3524") +BOLD_RED = ManimColor("#DD3524") +BS381_568 = ManimColor("#FB9C06") +APRICOT = ManimColor("#fb9c06") +BS381_570 = ManimColor("#A83C19") +TRAFFIC_RED = ManimColor("#A83C19") +BS381_591 = ManimColor("#D04E09") +DEEP_ORANGE = ManimColor("#D04E09") +BS381_592 = ManimColor("#E45523") +INTERNATIONAL_ORANGE = ManimColor("#E45523") +BS381_593 = ManimColor("#F24816") +RAIL_RED = ManimColor("#F24816") +AZO_ORANGE = ManimColor("#F24816") +BS381_626 = ManimColor("#A0A9AA") +CAMOUFLAGE_GREY = ManimColor("#A0A9AA") +BS381_627 = ManimColor("#BEC0B8") +LIGHT_AIRCRAFT_GREY = ManimColor("#BEC0B8") +BS381_628 = ManimColor("#9D9D7E") +SILVER_GREY = ManimColor("#9D9D7E") +BS381_629 = ManimColor("#7A838B") +DARK_CAMOUFLAGE_GREY = ManimColor("#7A838B") +BS381_630 = ManimColor("#A5AD98") +FRENCH_GREY = ManimColor("#A5AD98") +BS381_631 = ManimColor("#9AAA9F") +LIGHT_GREY = ManimColor("#9AAA9F") +BS381_632 = ManimColor("#6B7477") +DARK_ADMIRALTY_GREY = ManimColor("#6B7477") +BS381_633 = ManimColor("#424C53") +RAF_BLUE_GREY = ManimColor("#424C53") +BS381_634 = ManimColor("#6F7264") +SLATE = ManimColor("#6f7264") +BS381_635 = ManimColor("#525B55") +LEAD = ManimColor("#525b55") +BS381_636 = ManimColor("#5F7682") +PRU_BLUE = ManimColor("#5F7682") +BS381_637 = ManimColor("#8E9B9C") +MEDIUM_SEA_GREY = ManimColor("#8E9B9C") +BS381_638 = ManimColor("#6C7377") +DARK_SEA_GREY = ManimColor("#6C7377") +BS381_639 = ManimColor("#667563") +LIGHT_SLATE_GREY = ManimColor("#667563") +BS381_640 = ManimColor("#566164") +EXTRA_DARK_SEA_GREY = ManimColor("#566164") +BS381_642 = ManimColor("#282B2F") +NIGHT = ManimColor("#282b2f") +BS381_671 = ManimColor("#4E5355") +MIDDLE_GRAPHITE = ManimColor("#4E5355") +BS381_676 = ManimColor("#A9B7B9") +LIGHT_WEATHERWORK_GREY = ManimColor("#A9B7B9") +BS381_677 = ManimColor("#676F76") +DARK_WEATHERWORK_GREY = ManimColor("#676F76") +BS381_692 = ManimColor("#7B93A3") +SMOKE_GREY = ManimColor("#7B93A3") +BS381_693 = ManimColor("#88918D") +AIRCRAFT_GREY = ManimColor("#88918D") +BS381_694 = ManimColor("#909A92") +DOVE_GREY = ManimColor("#909A92") +BS381_697 = ManimColor("#B6D3CC") +LIGHT_ADMIRALTY_GREY = ManimColor("#B6D3CC") +BS381_796 = ManimColor("#6E4A75") +DARK_VIOLET = ManimColor("#6E4A75") +BS381_797 = ManimColor("#C9A8CE") +LIGHT_VIOLET = ManimColor("#C9A8CE") diff --git a/manim/utils/color/DVIPSNAMES.py b/manim/utils/color/DVIPSNAMES.py new file mode 100644 index 0000000000..88fe8cf680 --- /dev/null +++ b/manim/utils/color/DVIPSNAMES.py @@ -0,0 +1,96 @@ +r"""dvips Colors + +This module contains the colors defined in the dvips driver, which are commonly accessed +as named colors in LaTeX via the ``\usepackage[dvipsnames]{xcolor}`` package. + +To use the colors from this list, access them directly from the module (which +is exposed to Manim's global name space): + +.. code:: pycon + + >>> from manim import DVIPSNAMES + >>> DVIPSNAMES.DARKORCHID + ManimColor('#A4538A') + +List of Color Constants +----------------------- + +These hex values are derived from those specified in the ``xcolor`` package +documentation (see https://ctan.org/pkg/xcolor): + +.. automanimcolormodule:: manim.utils.color.DVIPSNAMES + +""" + +from __future__ import annotations + +from .core import ManimColor + +AQUAMARINE = ManimColor("#00B5BE") +BITTERSWEET = ManimColor("#C04F17") +APRICOT = ManimColor("#FBB982") +BLACK = ManimColor("#221E1F") +BLUE = ManimColor("#2D2F92") +BLUEGREEN = ManimColor("#00B3B8") +BLUEVIOLET = ManimColor("#473992") +BRICKRED = ManimColor("#B6321C") +BROWN = ManimColor("#792500") +BURNTORANGE = ManimColor("#F7921D") +CADETBLUE = ManimColor("#74729A") +CARNATIONPINK = ManimColor("#F282B4") +CERULEAN = ManimColor("#00A2E3") +CORNFLOWERBLUE = ManimColor("#41B0E4") +CYAN = ManimColor("#00AEEF") +DANDELION = ManimColor("#FDBC42") +DARKORCHID = ManimColor("#A4538A") +EMERALD = ManimColor("#00A99D") +FORESTGREEN = ManimColor("#009B55") +FUCHSIA = ManimColor("#8C368C") +GOLDENROD = ManimColor("#FFDF42") +GRAY = ManimColor("#949698") +GREEN = ManimColor("#00A64F") +GREENYELLOW = ManimColor("#DFE674") +JUNGLEGREEN = ManimColor("#00A99A") +LAVENDER = ManimColor("#F49EC4") +LIMEGREEN = ManimColor("#8DC73E") +MAGENTA = ManimColor("#EC008C") +MAHOGANY = ManimColor("#A9341F") +MAROON = ManimColor("#AF3235") +MELON = ManimColor("#F89E7B") +MIDNIGHTBLUE = ManimColor("#006795") +MULBERRY = ManimColor("#A93C93") +NAVYBLUE = ManimColor("#006EB8") +OLIVEGREEN = ManimColor("#3C8031") +ORANGE = ManimColor("#F58137") +ORANGERED = ManimColor("#ED135A") +ORCHID = ManimColor("#AF72B0") +PEACH = ManimColor("#F7965A") +PERIWINKLE = ManimColor("#7977B8") +PINEGREEN = ManimColor("#008B72") +PLUM = ManimColor("#92268F") +PROCESSBLUE = ManimColor("#00B0F0") +PURPLE = ManimColor("#99479B") +RAWSIENNA = ManimColor("#974006") +RED = ManimColor("#ED1B23") +REDORANGE = ManimColor("#F26035") +REDVIOLET = ManimColor("#A1246B") +RHODAMINE = ManimColor("#EF559F") +ROYALBLUE = ManimColor("#0071BC") +ROYALPURPLE = ManimColor("#613F99") +RUBINERED = ManimColor("#ED017D") +SALMON = ManimColor("#F69289") +SEAGREEN = ManimColor("#3FBC9D") +SEPIA = ManimColor("#671800") +SKYBLUE = ManimColor("#46C5DD") +SPRINGGREEN = ManimColor("#C6DC67") +TAN = ManimColor("#DA9D76") +TEALBLUE = ManimColor("#00AEB3") +THISTLE = ManimColor("#D883B7") +TURQUOISE = ManimColor("#00B4CE") +VIOLET = ManimColor("#58429B") +VIOLETRED = ManimColor("#EF58A0") +WHITE = ManimColor("#FFFFFF") +WILDSTRAWBERRY = ManimColor("#EE2967") +YELLOW = ManimColor("#FFF200") +YELLOWGREEN = ManimColor("#98CC70") +YELLOWORANGE = ManimColor("#FAA21A") diff --git a/manim/utils/color/SVGNAMES.py b/manim/utils/color/SVGNAMES.py new file mode 100644 index 0000000000..d59eed66b4 --- /dev/null +++ b/manim/utils/color/SVGNAMES.py @@ -0,0 +1,179 @@ +r"""SVG 1.1 Colors + +This module contains the colors defined in the SVG 1.1 specification, which are commonly +accessed as named colors in LaTeX via the ``\usepackage[svgnames]{xcolor}`` package. + +To use the colors from this list, access them directly from the module (which +is exposed to Manim's global name space): + +.. code:: pycon + + >>> from manim import SVGNAMES + >>> SVGNAMES.LIGHTCORAL + ManimColor('#EF7F7F') + +List of Color Constants +----------------------- + +These hex values are derived from those specified in the ``xcolor`` package +documentation (see https://ctan.org/pkg/xcolor): + +.. automanimcolormodule:: manim.utils.color.SVGNAMES + +""" + +from __future__ import annotations + +from .core import ManimColor + +ALICEBLUE = ManimColor("#EFF7FF") +ANTIQUEWHITE = ManimColor("#F9EAD7") +AQUA = ManimColor("#00FFFF") +AQUAMARINE = ManimColor("#7EFFD3") +AZURE = ManimColor("#EFFFFF") +BEIGE = ManimColor("#F4F4DC") +BISQUE = ManimColor("#FFE3C4") +BLACK = ManimColor("#000000") +BLANCHEDALMOND = ManimColor("#FFEACD") +BLUE = ManimColor("#0000FF") +BLUEVIOLET = ManimColor("#892BE2") +BROWN = ManimColor("#A52A2A") +BURLYWOOD = ManimColor("#DDB787") +CADETBLUE = ManimColor("#5E9EA0") +CHARTREUSE = ManimColor("#7EFF00") +CHOCOLATE = ManimColor("#D2681D") +CORAL = ManimColor("#FF7E4F") +CORNFLOWERBLUE = ManimColor("#6395ED") +CORNSILK = ManimColor("#FFF7DC") +CRIMSON = ManimColor("#DC143B") +CYAN = ManimColor("#00FFFF") +DARKBLUE = ManimColor("#00008A") +DARKCYAN = ManimColor("#008A8A") +DARKGOLDENROD = ManimColor("#B7850B") +DARKGRAY = ManimColor("#A9A9A9") +DARKGREEN = ManimColor("#006300") +DARKGREY = ManimColor("#A9A9A9") +DARKKHAKI = ManimColor("#BCB66B") +DARKMAGENTA = ManimColor("#8A008A") +DARKOLIVEGREEN = ManimColor("#546B2F") +DARKORANGE = ManimColor("#FF8C00") +DARKORCHID = ManimColor("#9931CC") +DARKRED = ManimColor("#8A0000") +DARKSALMON = ManimColor("#E8967A") +DARKSEAGREEN = ManimColor("#8EBB8E") +DARKSLATEBLUE = ManimColor("#483D8A") +DARKSLATEGRAY = ManimColor("#2F4F4F") +DARKSLATEGREY = ManimColor("#2F4F4F") +DARKTURQUOISE = ManimColor("#00CED1") +DARKVIOLET = ManimColor("#9300D3") +DEEPPINK = ManimColor("#FF1492") +DEEPSKYBLUE = ManimColor("#00BFFF") +DIMGRAY = ManimColor("#686868") +DIMGREY = ManimColor("#686868") +DODGERBLUE = ManimColor("#1D90FF") +FIREBRICK = ManimColor("#B12121") +FLORALWHITE = ManimColor("#FFF9EF") +FORESTGREEN = ManimColor("#218A21") +FUCHSIA = ManimColor("#FF00FF") +GAINSBORO = ManimColor("#DCDCDC") +GHOSTWHITE = ManimColor("#F7F7FF") +GOLD = ManimColor("#FFD700") +GOLDENROD = ManimColor("#DAA51F") +GRAY = ManimColor("#7F7F7F") +GREEN = ManimColor("#007F00") +GREENYELLOW = ManimColor("#ADFF2F") +GREY = ManimColor("#7F7F7F") +HONEYDEW = ManimColor("#EFFFEF") +HOTPINK = ManimColor("#FF68B3") +INDIANRED = ManimColor("#CD5B5B") +INDIGO = ManimColor("#4A0082") +IVORY = ManimColor("#FFFFEF") +KHAKI = ManimColor("#EFE58C") +LAVENDER = ManimColor("#E5E5F9") +LAVENDERBLUSH = ManimColor("#FFEFF4") +LAWNGREEN = ManimColor("#7CFC00") +LEMONCHIFFON = ManimColor("#FFF9CD") +LIGHTBLUE = ManimColor("#ADD8E5") +LIGHTCORAL = ManimColor("#EF7F7F") +LIGHTCYAN = ManimColor("#E0FFFF") +LIGHTGOLDENROD = ManimColor("#EDDD82") +LIGHTGOLDENRODYELLOW = ManimColor("#F9F9D2") +LIGHTGRAY = ManimColor("#D3D3D3") +LIGHTGREEN = ManimColor("#90ED90") +LIGHTGREY = ManimColor("#D3D3D3") +LIGHTPINK = ManimColor("#FFB5C0") +LIGHTSALMON = ManimColor("#FFA07A") +LIGHTSEAGREEN = ManimColor("#1FB1AA") +LIGHTSKYBLUE = ManimColor("#87CEF9") +LIGHTSLATEBLUE = ManimColor("#8470FF") +LIGHTSLATEGRAY = ManimColor("#778799") +LIGHTSLATEGREY = ManimColor("#778799") +LIGHTSTEELBLUE = ManimColor("#AFC4DD") +LIGHTYELLOW = ManimColor("#FFFFE0") +LIME = ManimColor("#00FF00") +LIMEGREEN = ManimColor("#31CD31") +LINEN = ManimColor("#F9EFE5") +MAGENTA = ManimColor("#FF00FF") +MAROON = ManimColor("#7F0000") +MEDIUMAQUAMARINE = ManimColor("#66CDAA") +MEDIUMBLUE = ManimColor("#0000CD") +MEDIUMORCHID = ManimColor("#BA54D3") +MEDIUMPURPLE = ManimColor("#9270DB") +MEDIUMSEAGREEN = ManimColor("#3BB271") +MEDIUMSLATEBLUE = ManimColor("#7B68ED") +MEDIUMSPRINGGREEN = ManimColor("#00F99A") +MEDIUMTURQUOISE = ManimColor("#48D1CC") +MEDIUMVIOLETRED = ManimColor("#C61584") +MIDNIGHTBLUE = ManimColor("#181870") +MINTCREAM = ManimColor("#F4FFF9") +MISTYROSE = ManimColor("#FFE3E1") +MOCCASIN = ManimColor("#FFE3B5") +NAVAJOWHITE = ManimColor("#FFDDAD") +NAVY = ManimColor("#00007F") +NAVYBLUE = ManimColor("#00007F") +OLDLACE = ManimColor("#FCF4E5") +OLIVE = ManimColor("#7F7F00") +OLIVEDRAB = ManimColor("#6B8D22") +ORANGE = ManimColor("#FFA500") +ORANGERED = ManimColor("#FF4400") +ORCHID = ManimColor("#DA70D6") +PALEGOLDENROD = ManimColor("#EDE8AA") +PALEGREEN = ManimColor("#97FB97") +PALETURQUOISE = ManimColor("#AFEDED") +PALEVIOLETRED = ManimColor("#DB7092") +PAPAYAWHIP = ManimColor("#FFEED4") +PEACHPUFF = ManimColor("#FFDAB8") +PERU = ManimColor("#CD843F") +PINK = ManimColor("#FFBFCA") +PLUM = ManimColor("#DDA0DD") +POWDERBLUE = ManimColor("#AFE0E5") +PURPLE = ManimColor("#7F007F") +RED = ManimColor("#FF0000") +ROSYBROWN = ManimColor("#BB8E8E") +ROYALBLUE = ManimColor("#4168E1") +SADDLEBROWN = ManimColor("#8A4413") +SALMON = ManimColor("#F97F72") +SANDYBROWN = ManimColor("#F3A45F") +SEAGREEN = ManimColor("#2D8A56") +SEASHELL = ManimColor("#FFF4ED") +SIENNA = ManimColor("#A0512C") +SILVER = ManimColor("#BFBFBF") +SKYBLUE = ManimColor("#87CEEA") +SLATEBLUE = ManimColor("#6959CD") +SLATEGRAY = ManimColor("#707F90") +SLATEGREY = ManimColor("#707F90") +SNOW = ManimColor("#FFF9F9") +SPRINGGREEN = ManimColor("#00FF7E") +STEELBLUE = ManimColor("#4682B3") +TAN = ManimColor("#D2B38C") +TEAL = ManimColor("#007F7F") +THISTLE = ManimColor("#D8BFD8") +TOMATO = ManimColor("#FF6347") +TURQUOISE = ManimColor("#3FE0CF") +VIOLET = ManimColor("#ED82ED") +VIOLETRED = ManimColor("#D01F90") +WHEAT = ManimColor("#F4DDB2") +WHITE = ManimColor("#FFFFFF") +WHITESMOKE = ManimColor("#F4F4F4") +YELLOW = ManimColor("#FFFF00") +YELLOWGREEN = ManimColor("#9ACD30") diff --git a/manim/utils/color/X11.py b/manim/utils/color/X11.py new file mode 100644 index 0000000000..4338660200 --- /dev/null +++ b/manim/utils/color/X11.py @@ -0,0 +1,533 @@ +# from https://www.w3schools.com/colors/colors_x11.asp + +"""X11 Colors + +These color and their names (taken from +https://www.w3schools.com/colors/colors_x11.asp) were developed at the +Massachusetts Intitute of Technology (MIT) during +the development of color based computer display system. + +To use the colors from this list, access them directly from the module (which +is exposed to Manim's global name space): + +.. code:: pycon + + >>> from manim import X11 + >>> X11.BEIGE + ManimColor('#F5F5DC') + + +List of Color Constants +----------------------- + +.. automanimcolormodule:: manim.utils.color.X11 +""" + +from __future__ import annotations + +from .core import ManimColor + +ALICEBLUE = ManimColor("#F0F8FF") +ANTIQUEWHITE = ManimColor("#FAEBD7") +ANTIQUEWHITE1 = ManimColor("#FFEFDB") +ANTIQUEWHITE2 = ManimColor("#EEDFCC") +ANTIQUEWHITE3 = ManimColor("#CDC0B0") +ANTIQUEWHITE4 = ManimColor("#8B8378") +AQUAMARINE1 = ManimColor("#7FFFD4") +AQUAMARINE2 = ManimColor("#76EEC6") +AQUAMARINE4 = ManimColor("#458B74") +AZURE1 = ManimColor("#F0FFFF") +AZURE2 = ManimColor("#E0EEEE") +AZURE3 = ManimColor("#C1CDCD") +AZURE4 = ManimColor("#838B8B") +BEIGE = ManimColor("#F5F5DC") +BISQUE1 = ManimColor("#FFE4C4") +BISQUE2 = ManimColor("#EED5B7") +BISQUE3 = ManimColor("#CDB79E") +BISQUE4 = ManimColor("#8B7D6B") +BLACK = ManimColor("#000000") +BLANCHEDALMOND = ManimColor("#FFEBCD") +BLUE1 = ManimColor("#0000FF") +BLUE2 = ManimColor("#0000EE") +BLUE4 = ManimColor("#00008B") +BLUEVIOLET = ManimColor("#8A2BE2") +BROWN = ManimColor("#A52A2A") +BROWN1 = ManimColor("#FF4040") +BROWN2 = ManimColor("#EE3B3B") +BROWN3 = ManimColor("#CD3333") +BROWN4 = ManimColor("#8B2323") +BURLYWOOD = ManimColor("#DEB887") +BURLYWOOD1 = ManimColor("#FFD39B") +BURLYWOOD2 = ManimColor("#EEC591") +BURLYWOOD3 = ManimColor("#CDAA7D") +BURLYWOOD4 = ManimColor("#8B7355") +CADETBLUE = ManimColor("#5F9EA0") +CADETBLUE1 = ManimColor("#98F5FF") +CADETBLUE2 = ManimColor("#8EE5EE") +CADETBLUE3 = ManimColor("#7AC5CD") +CADETBLUE4 = ManimColor("#53868B") +CHARTREUSE1 = ManimColor("#7FFF00") +CHARTREUSE2 = ManimColor("#76EE00") +CHARTREUSE3 = ManimColor("#66CD00") +CHARTREUSE4 = ManimColor("#458B00") +CHOCOLATE = ManimColor("#D2691E") +CHOCOLATE1 = ManimColor("#FF7F24") +CHOCOLATE2 = ManimColor("#EE7621") +CHOCOLATE3 = ManimColor("#CD661D") +CORAL = ManimColor("#FF7F50") +CORAL1 = ManimColor("#FF7256") +CORAL2 = ManimColor("#EE6A50") +CORAL3 = ManimColor("#CD5B45") +CORAL4 = ManimColor("#8B3E2F") +CORNFLOWERBLUE = ManimColor("#6495ED") +CORNSILK1 = ManimColor("#FFF8DC") +CORNSILK2 = ManimColor("#EEE8CD") +CORNSILK3 = ManimColor("#CDC8B1") +CORNSILK4 = ManimColor("#8B8878") +CYAN1 = ManimColor("#00FFFF") +CYAN2 = ManimColor("#00EEEE") +CYAN3 = ManimColor("#00CDCD") +CYAN4 = ManimColor("#008B8B") +DARKGOLDENROD = ManimColor("#B8860B") +DARKGOLDENROD1 = ManimColor("#FFB90F") +DARKGOLDENROD2 = ManimColor("#EEAD0E") +DARKGOLDENROD3 = ManimColor("#CD950C") +DARKGOLDENROD4 = ManimColor("#8B6508") +DARKGREEN = ManimColor("#006400") +DARKKHAKI = ManimColor("#BDB76B") +DARKOLIVEGREEN = ManimColor("#556B2F") +DARKOLIVEGREEN1 = ManimColor("#CAFF70") +DARKOLIVEGREEN2 = ManimColor("#BCEE68") +DARKOLIVEGREEN3 = ManimColor("#A2CD5A") +DARKOLIVEGREEN4 = ManimColor("#6E8B3D") +DARKORANGE = ManimColor("#FF8C00") +DARKORANGE1 = ManimColor("#FF7F00") +DARKORANGE2 = ManimColor("#EE7600") +DARKORANGE3 = ManimColor("#CD6600") +DARKORANGE4 = ManimColor("#8B4500") +DARKORCHID = ManimColor("#9932CC") +DARKORCHID1 = ManimColor("#BF3EFF") +DARKORCHID2 = ManimColor("#B23AEE") +DARKORCHID3 = ManimColor("#9A32CD") +DARKORCHID4 = ManimColor("#68228B") +DARKSALMON = ManimColor("#E9967A") +DARKSEAGREEN = ManimColor("#8FBC8F") +DARKSEAGREEN1 = ManimColor("#C1FFC1") +DARKSEAGREEN2 = ManimColor("#B4EEB4") +DARKSEAGREEN3 = ManimColor("#9BCD9B") +DARKSEAGREEN4 = ManimColor("#698B69") +DARKSLATEBLUE = ManimColor("#483D8B") +DARKSLATEGRAY = ManimColor("#2F4F4F") +DARKSLATEGRAY1 = ManimColor("#97FFFF") +DARKSLATEGRAY2 = ManimColor("#8DEEEE") +DARKSLATEGRAY3 = ManimColor("#79CDCD") +DARKSLATEGRAY4 = ManimColor("#528B8B") +DARKTURQUOISE = ManimColor("#00CED1") +DARKVIOLET = ManimColor("#9400D3") +DEEPPINK1 = ManimColor("#FF1493") +DEEPPINK2 = ManimColor("#EE1289") +DEEPPINK3 = ManimColor("#CD1076") +DEEPPINK4 = ManimColor("#8B0A50") +DEEPSKYBLUE1 = ManimColor("#00BFFF") +DEEPSKYBLUE2 = ManimColor("#00B2EE") +DEEPSKYBLUE3 = ManimColor("#009ACD") +DEEPSKYBLUE4 = ManimColor("#00688B") +DIMGRAY = ManimColor("#696969") +DODGERBLUE1 = ManimColor("#1E90FF") +DODGERBLUE2 = ManimColor("#1C86EE") +DODGERBLUE3 = ManimColor("#1874CD") +DODGERBLUE4 = ManimColor("#104E8B") +FIREBRICK = ManimColor("#B22222") +FIREBRICK1 = ManimColor("#FF3030") +FIREBRICK2 = ManimColor("#EE2C2C") +FIREBRICK3 = ManimColor("#CD2626") +FIREBRICK4 = ManimColor("#8B1A1A") +FLORALWHITE = ManimColor("#FFFAF0") +FORESTGREEN = ManimColor("#228B22") +GAINSBORO = ManimColor("#DCDCDC") +GHOSTWHITE = ManimColor("#F8F8FF") +GOLD1 = ManimColor("#FFD700") +GOLD2 = ManimColor("#EEC900") +GOLD3 = ManimColor("#CDAD00") +GOLD4 = ManimColor("#8B7500") +GOLDENROD = ManimColor("#DAA520") +GOLDENROD1 = ManimColor("#FFC125") +GOLDENROD2 = ManimColor("#EEB422") +GOLDENROD3 = ManimColor("#CD9B1D") +GOLDENROD4 = ManimColor("#8B6914") +GRAY = ManimColor("#BEBEBE") +GRAY1 = ManimColor("#030303") +GRAY2 = ManimColor("#050505") +GRAY3 = ManimColor("#080808") +GRAY4 = ManimColor("#0A0A0A") +GRAY5 = ManimColor("#0D0D0D") +GRAY6 = ManimColor("#0F0F0F") +GRAY7 = ManimColor("#121212") +GRAY8 = ManimColor("#141414") +GRAY9 = ManimColor("#171717") +GRAY10 = ManimColor("#1A1A1A") +GRAY11 = ManimColor("#1C1C1C") +GRAY12 = ManimColor("#1F1F1F") +GRAY13 = ManimColor("#212121") +GRAY14 = ManimColor("#242424") +GRAY15 = ManimColor("#262626") +GRAY16 = ManimColor("#292929") +GRAY17 = ManimColor("#2B2B2B") +GRAY18 = ManimColor("#2E2E2E") +GRAY19 = ManimColor("#303030") +GRAY20 = ManimColor("#333333") +GRAY21 = ManimColor("#363636") +GRAY22 = ManimColor("#383838") +GRAY23 = ManimColor("#3B3B3B") +GRAY24 = ManimColor("#3D3D3D") +GRAY25 = ManimColor("#404040") +GRAY26 = ManimColor("#424242") +GRAY27 = ManimColor("#454545") +GRAY28 = ManimColor("#474747") +GRAY29 = ManimColor("#4A4A4A") +GRAY30 = ManimColor("#4D4D4D") +GRAY31 = ManimColor("#4F4F4F") +GRAY32 = ManimColor("#525252") +GRAY33 = ManimColor("#545454") +GRAY34 = ManimColor("#575757") +GRAY35 = ManimColor("#595959") +GRAY36 = ManimColor("#5C5C5C") +GRAY37 = ManimColor("#5E5E5E") +GRAY38 = ManimColor("#616161") +GRAY39 = ManimColor("#636363") +GRAY40 = ManimColor("#666666") +GRAY41 = ManimColor("#696969") +GRAY42 = ManimColor("#6B6B6B") +GRAY43 = ManimColor("#6E6E6E") +GRAY44 = ManimColor("#707070") +GRAY45 = ManimColor("#737373") +GRAY46 = ManimColor("#757575") +GRAY47 = ManimColor("#787878") +GRAY48 = ManimColor("#7A7A7A") +GRAY49 = ManimColor("#7D7D7D") +GRAY50 = ManimColor("#7F7F7F") +GRAY51 = ManimColor("#828282") +GRAY52 = ManimColor("#858585") +GRAY53 = ManimColor("#878787") +GRAY54 = ManimColor("#8A8A8A") +GRAY55 = ManimColor("#8C8C8C") +GRAY56 = ManimColor("#8F8F8F") +GRAY57 = ManimColor("#919191") +GRAY58 = ManimColor("#949494") +GRAY59 = ManimColor("#969696") +GRAY60 = ManimColor("#999999") +GRAY61 = ManimColor("#9C9C9C") +GRAY62 = ManimColor("#9E9E9E") +GRAY63 = ManimColor("#A1A1A1") +GRAY64 = ManimColor("#A3A3A3") +GRAY65 = ManimColor("#A6A6A6") +GRAY66 = ManimColor("#A8A8A8") +GRAY67 = ManimColor("#ABABAB") +GRAY68 = ManimColor("#ADADAD") +GRAY69 = ManimColor("#B0B0B0") +GRAY70 = ManimColor("#B3B3B3") +GRAY71 = ManimColor("#B5B5B5") +GRAY72 = ManimColor("#B8B8B8") +GRAY73 = ManimColor("#BABABA") +GRAY74 = ManimColor("#BDBDBD") +GRAY75 = ManimColor("#BFBFBF") +GRAY76 = ManimColor("#C2C2C2") +GRAY77 = ManimColor("#C4C4C4") +GRAY78 = ManimColor("#C7C7C7") +GRAY79 = ManimColor("#C9C9C9") +GRAY80 = ManimColor("#CCCCCC") +GRAY81 = ManimColor("#CFCFCF") +GRAY82 = ManimColor("#D1D1D1") +GRAY83 = ManimColor("#D4D4D4") +GRAY84 = ManimColor("#D6D6D6") +GRAY85 = ManimColor("#D9D9D9") +GRAY86 = ManimColor("#DBDBDB") +GRAY87 = ManimColor("#DEDEDE") +GRAY88 = ManimColor("#E0E0E0") +GRAY89 = ManimColor("#E3E3E3") +GRAY90 = ManimColor("#E5E5E5") +GRAY91 = ManimColor("#E8E8E8") +GRAY92 = ManimColor("#EBEBEB") +GRAY93 = ManimColor("#EDEDED") +GRAY94 = ManimColor("#F0F0F0") +GRAY95 = ManimColor("#F2F2F2") +GRAY97 = ManimColor("#F7F7F7") +GRAY98 = ManimColor("#FAFAFA") +GRAY99 = ManimColor("#FCFCFC") +GREEN1 = ManimColor("#00FF00") +GREEN2 = ManimColor("#00EE00") +GREEN3 = ManimColor("#00CD00") +GREEN4 = ManimColor("#008B00") +GREENYELLOW = ManimColor("#ADFF2F") +HONEYDEW1 = ManimColor("#F0FFF0") +HONEYDEW2 = ManimColor("#E0EEE0") +HONEYDEW3 = ManimColor("#C1CDC1") +HONEYDEW4 = ManimColor("#838B83") +HOTPINK = ManimColor("#FF69B4") +HOTPINK1 = ManimColor("#FF6EB4") +HOTPINK2 = ManimColor("#EE6AA7") +HOTPINK3 = ManimColor("#CD6090") +HOTPINK4 = ManimColor("#8B3A62") +INDIANRED = ManimColor("#CD5C5C") +INDIANRED1 = ManimColor("#FF6A6A") +INDIANRED2 = ManimColor("#EE6363") +INDIANRED3 = ManimColor("#CD5555") +INDIANRED4 = ManimColor("#8B3A3A") +IVORY1 = ManimColor("#FFFFF0") +IVORY2 = ManimColor("#EEEEE0") +IVORY3 = ManimColor("#CDCDC1") +IVORY4 = ManimColor("#8B8B83") +KHAKI = ManimColor("#F0E68C") +KHAKI1 = ManimColor("#FFF68F") +KHAKI2 = ManimColor("#EEE685") +KHAKI3 = ManimColor("#CDC673") +KHAKI4 = ManimColor("#8B864E") +LAVENDER = ManimColor("#E6E6FA") +LAVENDERBLUSH1 = ManimColor("#FFF0F5") +LAVENDERBLUSH2 = ManimColor("#EEE0E5") +LAVENDERBLUSH3 = ManimColor("#CDC1C5") +LAVENDERBLUSH4 = ManimColor("#8B8386") +LAWNGREEN = ManimColor("#7CFC00") +LEMONCHIFFON1 = ManimColor("#FFFACD") +LEMONCHIFFON2 = ManimColor("#EEE9BF") +LEMONCHIFFON3 = ManimColor("#CDC9A5") +LEMONCHIFFON4 = ManimColor("#8B8970") +LIGHT = ManimColor("#EEDD82") +LIGHTBLUE = ManimColor("#ADD8E6") +LIGHTBLUE1 = ManimColor("#BFEFFF") +LIGHTBLUE2 = ManimColor("#B2DFEE") +LIGHTBLUE3 = ManimColor("#9AC0CD") +LIGHTBLUE4 = ManimColor("#68838B") +LIGHTCORAL = ManimColor("#F08080") +LIGHTCYAN1 = ManimColor("#E0FFFF") +LIGHTCYAN2 = ManimColor("#D1EEEE") +LIGHTCYAN3 = ManimColor("#B4CDCD") +LIGHTCYAN4 = ManimColor("#7A8B8B") +LIGHTGOLDENROD1 = ManimColor("#FFEC8B") +LIGHTGOLDENROD2 = ManimColor("#EEDC82") +LIGHTGOLDENROD3 = ManimColor("#CDBE70") +LIGHTGOLDENROD4 = ManimColor("#8B814C") +LIGHTGOLDENRODYELLOW = ManimColor("#FAFAD2") +LIGHTGRAY = ManimColor("#D3D3D3") +LIGHTPINK = ManimColor("#FFB6C1") +LIGHTPINK1 = ManimColor("#FFAEB9") +LIGHTPINK2 = ManimColor("#EEA2AD") +LIGHTPINK3 = ManimColor("#CD8C95") +LIGHTPINK4 = ManimColor("#8B5F65") +LIGHTSALMON1 = ManimColor("#FFA07A") +LIGHTSALMON2 = ManimColor("#EE9572") +LIGHTSALMON3 = ManimColor("#CD8162") +LIGHTSALMON4 = ManimColor("#8B5742") +LIGHTSEAGREEN = ManimColor("#20B2AA") +LIGHTSKYBLUE = ManimColor("#87CEFA") +LIGHTSKYBLUE1 = ManimColor("#B0E2FF") +LIGHTSKYBLUE2 = ManimColor("#A4D3EE") +LIGHTSKYBLUE3 = ManimColor("#8DB6CD") +LIGHTSKYBLUE4 = ManimColor("#607B8B") +LIGHTSLATEBLUE = ManimColor("#8470FF") +LIGHTSLATEGRAY = ManimColor("#778899") +LIGHTSTEELBLUE = ManimColor("#B0C4DE") +LIGHTSTEELBLUE1 = ManimColor("#CAE1FF") +LIGHTSTEELBLUE2 = ManimColor("#BCD2EE") +LIGHTSTEELBLUE3 = ManimColor("#A2B5CD") +LIGHTSTEELBLUE4 = ManimColor("#6E7B8B") +LIGHTYELLOW1 = ManimColor("#FFFFE0") +LIGHTYELLOW2 = ManimColor("#EEEED1") +LIGHTYELLOW3 = ManimColor("#CDCDB4") +LIGHTYELLOW4 = ManimColor("#8B8B7A") +LIMEGREEN = ManimColor("#32CD32") +LINEN = ManimColor("#FAF0E6") +MAGENTA = ManimColor("#FF00FF") +MAGENTA2 = ManimColor("#EE00EE") +MAGENTA3 = ManimColor("#CD00CD") +MAGENTA4 = ManimColor("#8B008B") +MAROON = ManimColor("#B03060") +MAROON1 = ManimColor("#FF34B3") +MAROON2 = ManimColor("#EE30A7") +MAROON3 = ManimColor("#CD2990") +MAROON4 = ManimColor("#8B1C62") +MEDIUM = ManimColor("#66CDAA") +MEDIUMAQUAMARINE = ManimColor("#66CDAA") +MEDIUMBLUE = ManimColor("#0000CD") +MEDIUMORCHID = ManimColor("#BA55D3") +MEDIUMORCHID1 = ManimColor("#E066FF") +MEDIUMORCHID2 = ManimColor("#D15FEE") +MEDIUMORCHID3 = ManimColor("#B452CD") +MEDIUMORCHID4 = ManimColor("#7A378B") +MEDIUMPURPLE = ManimColor("#9370DB") +MEDIUMPURPLE1 = ManimColor("#AB82FF") +MEDIUMPURPLE2 = ManimColor("#9F79EE") +MEDIUMPURPLE3 = ManimColor("#8968CD") +MEDIUMPURPLE4 = ManimColor("#5D478B") +MEDIUMSEAGREEN = ManimColor("#3CB371") +MEDIUMSLATEBLUE = ManimColor("#7B68EE") +MEDIUMSPRINGGREEN = ManimColor("#00FA9A") +MEDIUMTURQUOISE = ManimColor("#48D1CC") +MEDIUMVIOLETRED = ManimColor("#C71585") +MIDNIGHTBLUE = ManimColor("#191970") +MINTCREAM = ManimColor("#F5FFFA") +MISTYROSE1 = ManimColor("#FFE4E1") +MISTYROSE2 = ManimColor("#EED5D2") +MISTYROSE3 = ManimColor("#CDB7B5") +MISTYROSE4 = ManimColor("#8B7D7B") +MOCCASIN = ManimColor("#FFE4B5") +NAVAJOWHITE1 = ManimColor("#FFDEAD") +NAVAJOWHITE2 = ManimColor("#EECFA1") +NAVAJOWHITE3 = ManimColor("#CDB38B") +NAVAJOWHITE4 = ManimColor("#8B795E") +NAVYBLUE = ManimColor("#000080") +OLDLACE = ManimColor("#FDF5E6") +OLIVEDRAB = ManimColor("#6B8E23") +OLIVEDRAB1 = ManimColor("#C0FF3E") +OLIVEDRAB2 = ManimColor("#B3EE3A") +OLIVEDRAB4 = ManimColor("#698B22") +ORANGE1 = ManimColor("#FFA500") +ORANGE2 = ManimColor("#EE9A00") +ORANGE3 = ManimColor("#CD8500") +ORANGE4 = ManimColor("#8B5A00") +ORANGERED1 = ManimColor("#FF4500") +ORANGERED2 = ManimColor("#EE4000") +ORANGERED3 = ManimColor("#CD3700") +ORANGERED4 = ManimColor("#8B2500") +ORCHID = ManimColor("#DA70D6") +ORCHID1 = ManimColor("#FF83FA") +ORCHID2 = ManimColor("#EE7AE9") +ORCHID3 = ManimColor("#CD69C9") +ORCHID4 = ManimColor("#8B4789") +PALE = ManimColor("#DB7093") +PALEGOLDENROD = ManimColor("#EEE8AA") +PALEGREEN = ManimColor("#98FB98") +PALEGREEN1 = ManimColor("#9AFF9A") +PALEGREEN2 = ManimColor("#90EE90") +PALEGREEN3 = ManimColor("#7CCD7C") +PALEGREEN4 = ManimColor("#548B54") +PALETURQUOISE = ManimColor("#AFEEEE") +PALETURQUOISE1 = ManimColor("#BBFFFF") +PALETURQUOISE2 = ManimColor("#AEEEEE") +PALETURQUOISE3 = ManimColor("#96CDCD") +PALETURQUOISE4 = ManimColor("#668B8B") +PALEVIOLETRED = ManimColor("#DB7093") +PALEVIOLETRED1 = ManimColor("#FF82AB") +PALEVIOLETRED2 = ManimColor("#EE799F") +PALEVIOLETRED3 = ManimColor("#CD6889") +PALEVIOLETRED4 = ManimColor("#8B475D") +PAPAYAWHIP = ManimColor("#FFEFD5") +PEACHPUFF1 = ManimColor("#FFDAB9") +PEACHPUFF2 = ManimColor("#EECBAD") +PEACHPUFF3 = ManimColor("#CDAF95") +PEACHPUFF4 = ManimColor("#8B7765") +PINK = ManimColor("#FFC0CB") +PINK1 = ManimColor("#FFB5C5") +PINK2 = ManimColor("#EEA9B8") +PINK3 = ManimColor("#CD919E") +PINK4 = ManimColor("#8B636C") +PLUM = ManimColor("#DDA0DD") +PLUM1 = ManimColor("#FFBBFF") +PLUM2 = ManimColor("#EEAEEE") +PLUM3 = ManimColor("#CD96CD") +PLUM4 = ManimColor("#8B668B") +POWDERBLUE = ManimColor("#B0E0E6") +PURPLE = ManimColor("#A020F0") +PURPLE1 = ManimColor("#9B30FF") +PURPLE2 = ManimColor("#912CEE") +PURPLE3 = ManimColor("#7D26CD") +PURPLE4 = ManimColor("#551A8B") +RED1 = ManimColor("#FF0000") +RED2 = ManimColor("#EE0000") +RED3 = ManimColor("#CD0000") +RED4 = ManimColor("#8B0000") +ROSYBROWN = ManimColor("#BC8F8F") +ROSYBROWN1 = ManimColor("#FFC1C1") +ROSYBROWN2 = ManimColor("#EEB4B4") +ROSYBROWN3 = ManimColor("#CD9B9B") +ROSYBROWN4 = ManimColor("#8B6969") +ROYALBLUE = ManimColor("#4169E1") +ROYALBLUE1 = ManimColor("#4876FF") +ROYALBLUE2 = ManimColor("#436EEE") +ROYALBLUE3 = ManimColor("#3A5FCD") +ROYALBLUE4 = ManimColor("#27408B") +SADDLEBROWN = ManimColor("#8B4513") +SALMON = ManimColor("#FA8072") +SALMON1 = ManimColor("#FF8C69") +SALMON2 = ManimColor("#EE8262") +SALMON3 = ManimColor("#CD7054") +SALMON4 = ManimColor("#8B4C39") +SANDYBROWN = ManimColor("#F4A460") +SEAGREEN1 = ManimColor("#54FF9F") +SEAGREEN2 = ManimColor("#4EEE94") +SEAGREEN3 = ManimColor("#43CD80") +SEAGREEN4 = ManimColor("#2E8B57") +SEASHELL1 = ManimColor("#FFF5EE") +SEASHELL2 = ManimColor("#EEE5DE") +SEASHELL3 = ManimColor("#CDC5BF") +SEASHELL4 = ManimColor("#8B8682") +SIENNA = ManimColor("#A0522D") +SIENNA1 = ManimColor("#FF8247") +SIENNA2 = ManimColor("#EE7942") +SIENNA3 = ManimColor("#CD6839") +SIENNA4 = ManimColor("#8B4726") +SKYBLUE = ManimColor("#87CEEB") +SKYBLUE1 = ManimColor("#87CEFF") +SKYBLUE2 = ManimColor("#7EC0EE") +SKYBLUE3 = ManimColor("#6CA6CD") +SKYBLUE4 = ManimColor("#4A708B") +SLATEBLUE = ManimColor("#6A5ACD") +SLATEBLUE1 = ManimColor("#836FFF") +SLATEBLUE2 = ManimColor("#7A67EE") +SLATEBLUE3 = ManimColor("#6959CD") +SLATEBLUE4 = ManimColor("#473C8B") +SLATEGRAY = ManimColor("#708090") +SLATEGRAY1 = ManimColor("#C6E2FF") +SLATEGRAY2 = ManimColor("#B9D3EE") +SLATEGRAY3 = ManimColor("#9FB6CD") +SLATEGRAY4 = ManimColor("#6C7B8B") +SNOW1 = ManimColor("#FFFAFA") +SNOW2 = ManimColor("#EEE9E9") +SNOW3 = ManimColor("#CDC9C9") +SNOW4 = ManimColor("#8B8989") +SPRINGGREEN1 = ManimColor("#00FF7F") +SPRINGGREEN2 = ManimColor("#00EE76") +SPRINGGREEN3 = ManimColor("#00CD66") +SPRINGGREEN4 = ManimColor("#008B45") +STEELBLUE = ManimColor("#4682B4") +STEELBLUE1 = ManimColor("#63B8FF") +STEELBLUE2 = ManimColor("#5CACEE") +STEELBLUE3 = ManimColor("#4F94CD") +STEELBLUE4 = ManimColor("#36648B") +TAN = ManimColor("#D2B48C") +TAN1 = ManimColor("#FFA54F") +TAN2 = ManimColor("#EE9A49") +TAN3 = ManimColor("#CD853F") +TAN4 = ManimColor("#8B5A2B") +THISTLE = ManimColor("#D8BFD8") +THISTLE1 = ManimColor("#FFE1FF") +THISTLE2 = ManimColor("#EED2EE") +THISTLE3 = ManimColor("#CDB5CD") +THISTLE4 = ManimColor("#8B7B8B") +TOMATO1 = ManimColor("#FF6347") +TOMATO2 = ManimColor("#EE5C42") +TOMATO3 = ManimColor("#CD4F39") +TOMATO4 = ManimColor("#8B3626") +TURQUOISE = ManimColor("#40E0D0") +TURQUOISE1 = ManimColor("#00F5FF") +TURQUOISE2 = ManimColor("#00E5EE") +TURQUOISE3 = ManimColor("#00C5CD") +TURQUOISE4 = ManimColor("#00868B") +VIOLET = ManimColor("#EE82EE") +VIOLETRED = ManimColor("#D02090") +VIOLETRED1 = ManimColor("#FF3E96") +VIOLETRED2 = ManimColor("#EE3A8C") +VIOLETRED3 = ManimColor("#CD3278") +VIOLETRED4 = ManimColor("#8B2252") +WHEAT = ManimColor("#F5DEB3") +WHEAT1 = ManimColor("#FFE7BA") +WHEAT2 = ManimColor("#EED8AE") +WHEAT3 = ManimColor("#CDBA96") +WHEAT4 = ManimColor("#8B7E66") +WHITE = ManimColor("#FFFFFF") +WHITESMOKE = ManimColor("#F5F5F5") +YELLOW1 = ManimColor("#FFFF00") +YELLOW2 = ManimColor("#EEEE00") +YELLOW3 = ManimColor("#CDCD00") +YELLOW4 = ManimColor("#8B8B00") +YELLOWGREEN = ManimColor("#9ACD32") diff --git a/manim/utils/color/XKCD.py b/manim/utils/color/XKCD.py new file mode 100644 index 0000000000..4c38af6862 --- /dev/null +++ b/manim/utils/color/XKCD.py @@ -0,0 +1,952 @@ +"""Colors from the XKCD Color Name Survey + +XKCD is a popular `web comic `__ created by Randall Munroe. +His "`Color Name Survey `__" (with +200000 participants) resulted in a list of nearly 1000 color names. + +While the ``XKCD`` module is exposed to Manim's global name space, the colors included +in it are not. This means that in order to use the colors, access them via the module name: + +.. code:: pycon + + >>> from manim import XKCD + >>> XKCD.MANGO + ManimColor('#FFA62B') + + +List of Color Constants +----------------------- + +These hex values are non official approximate values intended to simulate the colors in HTML, +taken from https://www.w3schools.com/colors/colors_xkcd.asp. + +.. automanimcolormodule:: manim.utils.color.XKCD + +""" + +from __future__ import annotations + +from .core import ManimColor + +ACIDGREEN = ManimColor("#8FFE09") +ADOBE = ManimColor("#BD6C48") +ALGAE = ManimColor("#54AC68") +ALGAEGREEN = ManimColor("#21C36F") +ALMOSTBLACK = ManimColor("#070D0D") +AMBER = ManimColor("#FEB308") +AMETHYST = ManimColor("#9B5FC0") +APPLE = ManimColor("#6ECB3C") +APPLEGREEN = ManimColor("#76CD26") +APRICOT = ManimColor("#FFB16D") +AQUA = ManimColor("#13EAC9") +AQUABLUE = ManimColor("#02D8E9") +AQUAGREEN = ManimColor("#12E193") +AQUAMARINE = ManimColor("#2EE8BB") +ARMYGREEN = ManimColor("#4B5D16") +ASPARAGUS = ManimColor("#77AB56") +AUBERGINE = ManimColor("#3D0734") +AUBURN = ManimColor("#9A3001") +AVOCADO = ManimColor("#90B134") +AVOCADOGREEN = ManimColor("#87A922") +AZUL = ManimColor("#1D5DEC") +AZURE = ManimColor("#069AF3") +BABYBLUE = ManimColor("#A2CFFE") +BABYGREEN = ManimColor("#8CFF9E") +BABYPINK = ManimColor("#FFB7CE") +BABYPOO = ManimColor("#AB9004") +BABYPOOP = ManimColor("#937C00") +BABYPOOPGREEN = ManimColor("#8F9805") +BABYPUKEGREEN = ManimColor("#B6C406") +BABYPURPLE = ManimColor("#CA9BF7") +BABYSHITBROWN = ManimColor("#AD900D") +BABYSHITGREEN = ManimColor("#889717") +BANANA = ManimColor("#FFFF7E") +BANANAYELLOW = ManimColor("#FAFE4B") +BARBIEPINK = ManimColor("#FE46A5") +BARFGREEN = ManimColor("#94AC02") +BARNEY = ManimColor("#AC1DB8") +BARNEYPURPLE = ManimColor("#A00498") +BATTLESHIPGREY = ManimColor("#6B7C85") +BEIGE = ManimColor("#E6DAA6") +BERRY = ManimColor("#990F4B") +BILE = ManimColor("#B5C306") +BLACK = ManimColor("#000000") +BLAND = ManimColor("#AFA88B") +BLOOD = ManimColor("#770001") +BLOODORANGE = ManimColor("#FE4B03") +BLOODRED = ManimColor("#980002") +BLUE = ManimColor("#0343DF") +BLUEBERRY = ManimColor("#464196") +BLUEBLUE = ManimColor("#2242C7") +BLUEGREEN = ManimColor("#0F9B8E") +BLUEGREY = ManimColor("#85A3B2") +BLUEPURPLE = ManimColor("#5A06EF") +BLUEVIOLET = ManimColor("#5D06E9") +BLUEWITHAHINTOFPURPLE = ManimColor("#533CC6") +BLUEYGREEN = ManimColor("#2BB179") +BLUEYGREY = ManimColor("#89A0B0") +BLUEYPURPLE = ManimColor("#6241C7") +BLUISH = ManimColor("#2976BB") +BLUISHGREEN = ManimColor("#10A674") +BLUISHGREY = ManimColor("#748B97") +BLUISHPURPLE = ManimColor("#703BE7") +BLURPLE = ManimColor("#5539CC") +BLUSH = ManimColor("#F29E8E") +BLUSHPINK = ManimColor("#FE828C") +BOOGER = ManimColor("#9BB53C") +BOOGERGREEN = ManimColor("#96B403") +BORDEAUX = ManimColor("#7B002C") +BORINGGREEN = ManimColor("#63B365") +BOTTLEGREEN = ManimColor("#044A05") +BRICK = ManimColor("#A03623") +BRICKORANGE = ManimColor("#C14A09") +BRICKRED = ManimColor("#8F1402") +BRIGHTAQUA = ManimColor("#0BF9EA") +BRIGHTBLUE = ManimColor("#0165FC") +BRIGHTCYAN = ManimColor("#41FDFE") +BRIGHTGREEN = ManimColor("#01FF07") +BRIGHTLAVENDER = ManimColor("#C760FF") +BRIGHTLIGHTBLUE = ManimColor("#26F7FD") +BRIGHTLIGHTGREEN = ManimColor("#2DFE54") +BRIGHTLILAC = ManimColor("#C95EFB") +BRIGHTLIME = ManimColor("#87FD05") +BRIGHTLIMEGREEN = ManimColor("#65FE08") +BRIGHTMAGENTA = ManimColor("#FF08E8") +BRIGHTOLIVE = ManimColor("#9CBB04") +BRIGHTORANGE = ManimColor("#FF5B00") +BRIGHTPINK = ManimColor("#FE01B1") +BRIGHTPURPLE = ManimColor("#BE03FD") +BRIGHTRED = ManimColor("#FF000D") +BRIGHTSEAGREEN = ManimColor("#05FFA6") +BRIGHTSKYBLUE = ManimColor("#02CCFE") +BRIGHTTEAL = ManimColor("#01F9C6") +BRIGHTTURQUOISE = ManimColor("#0FFEF9") +BRIGHTVIOLET = ManimColor("#AD0AFD") +BRIGHTYELLOW = ManimColor("#FFFD01") +BRIGHTYELLOWGREEN = ManimColor("#9DFF00") +BRITISHRACINGGREEN = ManimColor("#05480D") +BRONZE = ManimColor("#A87900") +BROWN = ManimColor("#653700") +BROWNGREEN = ManimColor("#706C11") +BROWNGREY = ManimColor("#8D8468") +BROWNISH = ManimColor("#9C6D57") +BROWNISHGREEN = ManimColor("#6A6E09") +BROWNISHGREY = ManimColor("#86775F") +BROWNISHORANGE = ManimColor("#CB7723") +BROWNISHPINK = ManimColor("#C27E79") +BROWNISHPURPLE = ManimColor("#76424E") +BROWNISHRED = ManimColor("#9E3623") +BROWNISHYELLOW = ManimColor("#C9B003") +BROWNORANGE = ManimColor("#B96902") +BROWNRED = ManimColor("#922B05") +BROWNYELLOW = ManimColor("#B29705") +BROWNYGREEN = ManimColor("#6F6C0A") +BROWNYORANGE = ManimColor("#CA6B02") +BRUISE = ManimColor("#7E4071") +BUBBLEGUM = ManimColor("#FF6CB5") +BUBBLEGUMPINK = ManimColor("#FF69AF") +BUFF = ManimColor("#FEF69E") +BURGUNDY = ManimColor("#610023") +BURNTORANGE = ManimColor("#C04E01") +BURNTRED = ManimColor("#9F2305") +BURNTSIENA = ManimColor("#B75203") +BURNTSIENNA = ManimColor("#B04E0F") +BURNTUMBER = ManimColor("#A0450E") +BURNTYELLOW = ManimColor("#D5AB09") +BURPLE = ManimColor("#6832E3") +BUTTER = ManimColor("#FFFF81") +BUTTERSCOTCH = ManimColor("#FDB147") +BUTTERYELLOW = ManimColor("#FFFD74") +CADETBLUE = ManimColor("#4E7496") +CAMEL = ManimColor("#C69F59") +CAMO = ManimColor("#7F8F4E") +CAMOGREEN = ManimColor("#526525") +CAMOUFLAGEGREEN = ManimColor("#4B6113") +CANARY = ManimColor("#FDFF63") +CANARYYELLOW = ManimColor("#FFFE40") +CANDYPINK = ManimColor("#FF63E9") +CARAMEL = ManimColor("#AF6F09") +CARMINE = ManimColor("#9D0216") +CARNATION = ManimColor("#FD798F") +CARNATIONPINK = ManimColor("#FF7FA7") +CAROLINABLUE = ManimColor("#8AB8FE") +CELADON = ManimColor("#BEFDB7") +CELERY = ManimColor("#C1FD95") +CEMENT = ManimColor("#A5A391") +CERISE = ManimColor("#DE0C62") +CERULEAN = ManimColor("#0485D1") +CERULEANBLUE = ManimColor("#056EEE") +CHARCOAL = ManimColor("#343837") +CHARCOALGREY = ManimColor("#3C4142") +CHARTREUSE = ManimColor("#C1F80A") +CHERRY = ManimColor("#CF0234") +CHERRYRED = ManimColor("#F7022A") +CHESTNUT = ManimColor("#742802") +CHOCOLATE = ManimColor("#3D1C02") +CHOCOLATEBROWN = ManimColor("#411900") +CINNAMON = ManimColor("#AC4F06") +CLARET = ManimColor("#680018") +CLAY = ManimColor("#B66A50") +CLAYBROWN = ManimColor("#B2713D") +CLEARBLUE = ManimColor("#247AFD") +COBALT = ManimColor("#1E488F") +COBALTBLUE = ManimColor("#030AA7") +COCOA = ManimColor("#875F42") +COFFEE = ManimColor("#A6814C") +COOLBLUE = ManimColor("#4984B8") +COOLGREEN = ManimColor("#33B864") +COOLGREY = ManimColor("#95A3A6") +COPPER = ManimColor("#B66325") +CORAL = ManimColor("#FC5A50") +CORALPINK = ManimColor("#FF6163") +CORNFLOWER = ManimColor("#6A79F7") +CORNFLOWERBLUE = ManimColor("#5170D7") +CRANBERRY = ManimColor("#9E003A") +CREAM = ManimColor("#FFFFC2") +CREME = ManimColor("#FFFFB6") +CRIMSON = ManimColor("#8C000F") +CUSTARD = ManimColor("#FFFD78") +CYAN = ManimColor("#00FFFF") +DANDELION = ManimColor("#FEDF08") +DARK = ManimColor("#1B2431") +DARKAQUA = ManimColor("#05696B") +DARKAQUAMARINE = ManimColor("#017371") +DARKBEIGE = ManimColor("#AC9362") +DARKBLUE = ManimColor("#030764") +DARKBLUEGREEN = ManimColor("#005249") +DARKBLUEGREY = ManimColor("#1F3B4D") +DARKBROWN = ManimColor("#341C02") +DARKCORAL = ManimColor("#CF524E") +DARKCREAM = ManimColor("#FFF39A") +DARKCYAN = ManimColor("#0A888A") +DARKFORESTGREEN = ManimColor("#002D04") +DARKFUCHSIA = ManimColor("#9D0759") +DARKGOLD = ManimColor("#B59410") +DARKGRASSGREEN = ManimColor("#388004") +DARKGREEN = ManimColor("#054907") +DARKGREENBLUE = ManimColor("#1F6357") +DARKGREY = ManimColor("#363737") +DARKGREYBLUE = ManimColor("#29465B") +DARKHOTPINK = ManimColor("#D90166") +DARKINDIGO = ManimColor("#1F0954") +DARKISHBLUE = ManimColor("#014182") +DARKISHGREEN = ManimColor("#287C37") +DARKISHPINK = ManimColor("#DA467D") +DARKISHPURPLE = ManimColor("#751973") +DARKISHRED = ManimColor("#A90308") +DARKKHAKI = ManimColor("#9B8F55") +DARKLAVENDER = ManimColor("#856798") +DARKLILAC = ManimColor("#9C6DA5") +DARKLIME = ManimColor("#84B701") +DARKLIMEGREEN = ManimColor("#7EBD01") +DARKMAGENTA = ManimColor("#960056") +DARKMAROON = ManimColor("#3C0008") +DARKMAUVE = ManimColor("#874C62") +DARKMINT = ManimColor("#48C072") +DARKMINTGREEN = ManimColor("#20C073") +DARKMUSTARD = ManimColor("#A88905") +DARKNAVY = ManimColor("#000435") +DARKNAVYBLUE = ManimColor("#00022E") +DARKOLIVE = ManimColor("#373E02") +DARKOLIVEGREEN = ManimColor("#3C4D03") +DARKORANGE = ManimColor("#C65102") +DARKPASTELGREEN = ManimColor("#56AE57") +DARKPEACH = ManimColor("#DE7E5D") +DARKPERIWINKLE = ManimColor("#665FD1") +DARKPINK = ManimColor("#CB416B") +DARKPLUM = ManimColor("#3F012C") +DARKPURPLE = ManimColor("#35063E") +DARKRED = ManimColor("#840000") +DARKROSE = ManimColor("#B5485D") +DARKROYALBLUE = ManimColor("#02066F") +DARKSAGE = ManimColor("#598556") +DARKSALMON = ManimColor("#C85A53") +DARKSAND = ManimColor("#A88F59") +DARKSEAFOAM = ManimColor("#1FB57A") +DARKSEAFOAMGREEN = ManimColor("#3EAF76") +DARKSEAGREEN = ManimColor("#11875D") +DARKSKYBLUE = ManimColor("#448EE4") +DARKSLATEBLUE = ManimColor("#214761") +DARKTAN = ManimColor("#AF884A") +DARKTAUPE = ManimColor("#7F684E") +DARKTEAL = ManimColor("#014D4E") +DARKTURQUOISE = ManimColor("#045C5A") +DARKVIOLET = ManimColor("#34013F") +DARKYELLOW = ManimColor("#D5B60A") +DARKYELLOWGREEN = ManimColor("#728F02") +DEEPAQUA = ManimColor("#08787F") +DEEPBLUE = ManimColor("#040273") +DEEPBROWN = ManimColor("#410200") +DEEPGREEN = ManimColor("#02590F") +DEEPLAVENDER = ManimColor("#8D5EB7") +DEEPLILAC = ManimColor("#966EBD") +DEEPMAGENTA = ManimColor("#A0025C") +DEEPORANGE = ManimColor("#DC4D01") +DEEPPINK = ManimColor("#CB0162") +DEEPPURPLE = ManimColor("#36013F") +DEEPRED = ManimColor("#9A0200") +DEEPROSE = ManimColor("#C74767") +DEEPSEABLUE = ManimColor("#015482") +DEEPSKYBLUE = ManimColor("#0D75F8") +DEEPTEAL = ManimColor("#00555A") +DEEPTURQUOISE = ManimColor("#017374") +DEEPVIOLET = ManimColor("#490648") +DENIM = ManimColor("#3B638C") +DENIMBLUE = ManimColor("#3B5B92") +DESERT = ManimColor("#CCAD60") +DIARRHEA = ManimColor("#9F8303") +DIRT = ManimColor("#8A6E45") +DIRTBROWN = ManimColor("#836539") +DIRTYBLUE = ManimColor("#3F829D") +DIRTYGREEN = ManimColor("#667E2C") +DIRTYORANGE = ManimColor("#C87606") +DIRTYPINK = ManimColor("#CA7B80") +DIRTYPURPLE = ManimColor("#734A65") +DIRTYYELLOW = ManimColor("#CDC50A") +DODGERBLUE = ManimColor("#3E82FC") +DRAB = ManimColor("#828344") +DRABGREEN = ManimColor("#749551") +DRIEDBLOOD = ManimColor("#4B0101") +DUCKEGGBLUE = ManimColor("#C3FBF4") +DULLBLUE = ManimColor("#49759C") +DULLBROWN = ManimColor("#876E4B") +DULLGREEN = ManimColor("#74A662") +DULLORANGE = ManimColor("#D8863B") +DULLPINK = ManimColor("#D5869D") +DULLPURPLE = ManimColor("#84597E") +DULLRED = ManimColor("#BB3F3F") +DULLTEAL = ManimColor("#5F9E8F") +DULLYELLOW = ManimColor("#EEDC5B") +DUSK = ManimColor("#4E5481") +DUSKBLUE = ManimColor("#26538D") +DUSKYBLUE = ManimColor("#475F94") +DUSKYPINK = ManimColor("#CC7A8B") +DUSKYPURPLE = ManimColor("#895B7B") +DUSKYROSE = ManimColor("#BA6873") +DUST = ManimColor("#B2996E") +DUSTYBLUE = ManimColor("#5A86AD") +DUSTYGREEN = ManimColor("#76A973") +DUSTYLAVENDER = ManimColor("#AC86A8") +DUSTYORANGE = ManimColor("#F0833A") +DUSTYPINK = ManimColor("#D58A94") +DUSTYPURPLE = ManimColor("#825F87") +DUSTYRED = ManimColor("#B9484E") +DUSTYROSE = ManimColor("#C0737A") +DUSTYTEAL = ManimColor("#4C9085") +EARTH = ManimColor("#A2653E") +EASTERGREEN = ManimColor("#8CFD7E") +EASTERPURPLE = ManimColor("#C071FE") +ECRU = ManimColor("#FEFFCA") +EGGPLANT = ManimColor("#380835") +EGGPLANTPURPLE = ManimColor("#430541") +EGGSHELL = ManimColor("#FFFCC4") +EGGSHELLBLUE = ManimColor("#C4FFF7") +ELECTRICBLUE = ManimColor("#0652FF") +ELECTRICGREEN = ManimColor("#21FC0D") +ELECTRICLIME = ManimColor("#A8FF04") +ELECTRICPINK = ManimColor("#FF0490") +ELECTRICPURPLE = ManimColor("#AA23FF") +EMERALD = ManimColor("#01A049") +EMERALDGREEN = ManimColor("#028F1E") +EVERGREEN = ManimColor("#05472A") +FADEDBLUE = ManimColor("#658CBB") +FADEDGREEN = ManimColor("#7BB274") +FADEDORANGE = ManimColor("#F0944D") +FADEDPINK = ManimColor("#DE9DAC") +FADEDPURPLE = ManimColor("#916E99") +FADEDRED = ManimColor("#D3494E") +FADEDYELLOW = ManimColor("#FEFF7F") +FAWN = ManimColor("#CFAF7B") +FERN = ManimColor("#63A950") +FERNGREEN = ManimColor("#548D44") +FIREENGINERED = ManimColor("#FE0002") +FLATBLUE = ManimColor("#3C73A8") +FLATGREEN = ManimColor("#699D4C") +FLUORESCENTGREEN = ManimColor("#08FF08") +FLUROGREEN = ManimColor("#0AFF02") +FOAMGREEN = ManimColor("#90FDA9") +FOREST = ManimColor("#0B5509") +FORESTGREEN = ManimColor("#06470C") +FORRESTGREEN = ManimColor("#154406") +FRENCHBLUE = ManimColor("#436BAD") +FRESHGREEN = ManimColor("#69D84F") +FROGGREEN = ManimColor("#58BC08") +FUCHSIA = ManimColor("#ED0DD9") +GOLD = ManimColor("#DBB40C") +GOLDEN = ManimColor("#F5BF03") +GOLDENBROWN = ManimColor("#B27A01") +GOLDENROD = ManimColor("#F9BC08") +GOLDENYELLOW = ManimColor("#FEC615") +GRAPE = ManimColor("#6C3461") +GRAPEFRUIT = ManimColor("#FD5956") +GRAPEPURPLE = ManimColor("#5D1451") +GRASS = ManimColor("#5CAC2D") +GRASSGREEN = ManimColor("#3F9B0B") +GRASSYGREEN = ManimColor("#419C03") +GREEN = ManimColor("#15B01A") +GREENAPPLE = ManimColor("#5EDC1F") +GREENBLUE = ManimColor("#01C08D") +GREENBROWN = ManimColor("#544E03") +GREENGREY = ManimColor("#77926F") +GREENISH = ManimColor("#40A368") +GREENISHBEIGE = ManimColor("#C9D179") +GREENISHBLUE = ManimColor("#0B8B87") +GREENISHBROWN = ManimColor("#696112") +GREENISHCYAN = ManimColor("#2AFEB7") +GREENISHGREY = ManimColor("#96AE8D") +GREENISHTAN = ManimColor("#BCCB7A") +GREENISHTEAL = ManimColor("#32BF84") +GREENISHTURQUOISE = ManimColor("#00FBB0") +GREENISHYELLOW = ManimColor("#CDFD02") +GREENTEAL = ManimColor("#0CB577") +GREENYBLUE = ManimColor("#42B395") +GREENYBROWN = ManimColor("#696006") +GREENYELLOW = ManimColor("#B5CE08") +GREENYGREY = ManimColor("#7EA07A") +GREENYYELLOW = ManimColor("#C6F808") +GREY = ManimColor("#929591") +GREYBLUE = ManimColor("#647D8E") +GREYBROWN = ManimColor("#7F7053") +GREYGREEN = ManimColor("#86A17D") +GREYISH = ManimColor("#A8A495") +GREYISHBLUE = ManimColor("#5E819D") +GREYISHBROWN = ManimColor("#7A6A4F") +GREYISHGREEN = ManimColor("#82A67D") +GREYISHPINK = ManimColor("#C88D94") +GREYISHPURPLE = ManimColor("#887191") +GREYISHTEAL = ManimColor("#719F91") +GREYPINK = ManimColor("#C3909B") +GREYPURPLE = ManimColor("#826D8C") +GREYTEAL = ManimColor("#5E9B8A") +GROSSGREEN = ManimColor("#A0BF16") +GUNMETAL = ManimColor("#536267") +HAZEL = ManimColor("#8E7618") +HEATHER = ManimColor("#A484AC") +HELIOTROPE = ManimColor("#D94FF5") +HIGHLIGHTERGREEN = ManimColor("#1BFC06") +HOSPITALGREEN = ManimColor("#9BE5AA") +HOTGREEN = ManimColor("#25FF29") +HOTMAGENTA = ManimColor("#F504C9") +HOTPINK = ManimColor("#FF028D") +HOTPURPLE = ManimColor("#CB00F5") +HUNTERGREEN = ManimColor("#0B4008") +ICE = ManimColor("#D6FFFA") +ICEBLUE = ManimColor("#D7FFFE") +ICKYGREEN = ManimColor("#8FAE22") +INDIANRED = ManimColor("#850E04") +INDIGO = ManimColor("#380282") +INDIGOBLUE = ManimColor("#3A18B1") +IRIS = ManimColor("#6258C4") +IRISHGREEN = ManimColor("#019529") +IVORY = ManimColor("#FFFFCB") +JADE = ManimColor("#1FA774") +JADEGREEN = ManimColor("#2BAF6A") +JUNGLEGREEN = ManimColor("#048243") +KELLEYGREEN = ManimColor("#009337") +KELLYGREEN = ManimColor("#02AB2E") +KERMITGREEN = ManimColor("#5CB200") +KEYLIME = ManimColor("#AEFF6E") +KHAKI = ManimColor("#AAA662") +KHAKIGREEN = ManimColor("#728639") +KIWI = ManimColor("#9CEF43") +KIWIGREEN = ManimColor("#8EE53F") +LAVENDER = ManimColor("#C79FEF") +LAVENDERBLUE = ManimColor("#8B88F8") +LAVENDERPINK = ManimColor("#DD85D7") +LAWNGREEN = ManimColor("#4DA409") +LEAF = ManimColor("#71AA34") +LEAFGREEN = ManimColor("#5CA904") +LEAFYGREEN = ManimColor("#51B73B") +LEATHER = ManimColor("#AC7434") +LEMON = ManimColor("#FDFF52") +LEMONGREEN = ManimColor("#ADF802") +LEMONLIME = ManimColor("#BFFE28") +LEMONYELLOW = ManimColor("#FDFF38") +LICHEN = ManimColor("#8FB67B") +LIGHTAQUA = ManimColor("#8CFFDB") +LIGHTAQUAMARINE = ManimColor("#7BFDC7") +LIGHTBEIGE = ManimColor("#FFFEB6") +LIGHTBLUE = ManimColor("#7BC8F6") +LIGHTBLUEGREEN = ManimColor("#7EFBB3") +LIGHTBLUEGREY = ManimColor("#B7C9E2") +LIGHTBLUISHGREEN = ManimColor("#76FDA8") +LIGHTBRIGHTGREEN = ManimColor("#53FE5C") +LIGHTBROWN = ManimColor("#AD8150") +LIGHTBURGUNDY = ManimColor("#A8415B") +LIGHTCYAN = ManimColor("#ACFFFC") +LIGHTEGGPLANT = ManimColor("#894585") +LIGHTERGREEN = ManimColor("#75FD63") +LIGHTERPURPLE = ManimColor("#A55AF4") +LIGHTFORESTGREEN = ManimColor("#4F9153") +LIGHTGOLD = ManimColor("#FDDC5C") +LIGHTGRASSGREEN = ManimColor("#9AF764") +LIGHTGREEN = ManimColor("#76FF7B") +LIGHTGREENBLUE = ManimColor("#56FCA2") +LIGHTGREENISHBLUE = ManimColor("#63F7B4") +LIGHTGREY = ManimColor("#D8DCD6") +LIGHTGREYBLUE = ManimColor("#9DBCD4") +LIGHTGREYGREEN = ManimColor("#B7E1A1") +LIGHTINDIGO = ManimColor("#6D5ACF") +LIGHTISHBLUE = ManimColor("#3D7AFD") +LIGHTISHGREEN = ManimColor("#61E160") +LIGHTISHPURPLE = ManimColor("#A552E6") +LIGHTISHRED = ManimColor("#FE2F4A") +LIGHTKHAKI = ManimColor("#E6F2A2") +LIGHTLAVENDAR = ManimColor("#EFC0FE") +LIGHTLAVENDER = ManimColor("#DFC5FE") +LIGHTLIGHTBLUE = ManimColor("#CAFFFB") +LIGHTLIGHTGREEN = ManimColor("#C8FFB0") +LIGHTLILAC = ManimColor("#EDC8FF") +LIGHTLIME = ManimColor("#AEFD6C") +LIGHTLIMEGREEN = ManimColor("#B9FF66") +LIGHTMAGENTA = ManimColor("#FA5FF7") +LIGHTMAROON = ManimColor("#A24857") +LIGHTMAUVE = ManimColor("#C292A1") +LIGHTMINT = ManimColor("#B6FFBB") +LIGHTMINTGREEN = ManimColor("#A6FBB2") +LIGHTMOSSGREEN = ManimColor("#A6C875") +LIGHTMUSTARD = ManimColor("#F7D560") +LIGHTNAVY = ManimColor("#155084") +LIGHTNAVYBLUE = ManimColor("#2E5A88") +LIGHTNEONGREEN = ManimColor("#4EFD54") +LIGHTOLIVE = ManimColor("#ACBF69") +LIGHTOLIVEGREEN = ManimColor("#A4BE5C") +LIGHTORANGE = ManimColor("#FDAA48") +LIGHTPASTELGREEN = ManimColor("#B2FBA5") +LIGHTPEACH = ManimColor("#FFD8B1") +LIGHTPEAGREEN = ManimColor("#C4FE82") +LIGHTPERIWINKLE = ManimColor("#C1C6FC") +LIGHTPINK = ManimColor("#FFD1DF") +LIGHTPLUM = ManimColor("#9D5783") +LIGHTPURPLE = ManimColor("#BF77F6") +LIGHTRED = ManimColor("#FF474C") +LIGHTROSE = ManimColor("#FFC5CB") +LIGHTROYALBLUE = ManimColor("#3A2EFE") +LIGHTSAGE = ManimColor("#BCECAC") +LIGHTSALMON = ManimColor("#FEA993") +LIGHTSEAFOAM = ManimColor("#A0FEBF") +LIGHTSEAFOAMGREEN = ManimColor("#a7ffb5") +LIGHTSEAGREEN = ManimColor("#98F6B0") +LIGHTSKYBLUE = ManimColor("#C6FCFF") +LIGHTTAN = ManimColor("#FBEEAC") +LIGHTTEAL = ManimColor("#90E4C1") +LIGHTTURQUOISE = ManimColor("#7EF4CC") +LIGHTURPLE = ManimColor("#B36FF6") +LIGHTVIOLET = ManimColor("#D6B4FC") +LIGHTYELLOW = ManimColor("#FFFE7A") +LIGHTYELLOWGREEN = ManimColor("#CCFD7F") +LIGHTYELLOWISHGREEN = ManimColor("#C2FF89") +LILAC = ManimColor("#CEA2FD") +LILIAC = ManimColor("#C48EFD") +LIME = ManimColor("#AAFF32") +LIMEGREEN = ManimColor("#89FE05") +LIMEYELLOW = ManimColor("#D0FE1D") +LIPSTICK = ManimColor("#D5174E") +LIPSTICKRED = ManimColor("#C0022F") +MACARONIANDCHEESE = ManimColor("#EFB435") +MAGENTA = ManimColor("#C20078") +MAHOGANY = ManimColor("#4A0100") +MAIZE = ManimColor("#F4D054") +MANGO = ManimColor("#FFA62B") +MANILLA = ManimColor("#FFFA86") +MARIGOLD = ManimColor("#FCC006") +MARINE = ManimColor("#042E60") +MARINEBLUE = ManimColor("#01386A") +MAROON = ManimColor("#650021") +MAUVE = ManimColor("#AE7181") +MEDIUMBLUE = ManimColor("#2C6FBB") +MEDIUMBROWN = ManimColor("#7F5112") +MEDIUMGREEN = ManimColor("#39AD48") +MEDIUMGREY = ManimColor("#7D7F7C") +MEDIUMPINK = ManimColor("#F36196") +MEDIUMPURPLE = ManimColor("#9E43A2") +MELON = ManimColor("#FF7855") +MERLOT = ManimColor("#730039") +METALLICBLUE = ManimColor("#4F738E") +MIDBLUE = ManimColor("#276AB3") +MIDGREEN = ManimColor("#50A747") +MIDNIGHT = ManimColor("#03012D") +MIDNIGHTBLUE = ManimColor("#020035") +MIDNIGHTPURPLE = ManimColor("#280137") +MILITARYGREEN = ManimColor("#667C3E") +MILKCHOCOLATE = ManimColor("#7F4E1E") +MINT = ManimColor("#9FFEB0") +MINTGREEN = ManimColor("#8FFF9F") +MINTYGREEN = ManimColor("#0BF77D") +MOCHA = ManimColor("#9D7651") +MOSS = ManimColor("#769958") +MOSSGREEN = ManimColor("#658B38") +MOSSYGREEN = ManimColor("#638B27") +MUD = ManimColor("#735C12") +MUDBROWN = ManimColor("#60460F") +MUDDYBROWN = ManimColor("#886806") +MUDDYGREEN = ManimColor("#657432") +MUDDYYELLOW = ManimColor("#BFAC05") +MUDGREEN = ManimColor("#606602") +MULBERRY = ManimColor("#920A4E") +MURKYGREEN = ManimColor("#6C7A0E") +MUSHROOM = ManimColor("#BA9E88") +MUSTARD = ManimColor("#CEB301") +MUSTARDBROWN = ManimColor("#AC7E04") +MUSTARDGREEN = ManimColor("#A8B504") +MUSTARDYELLOW = ManimColor("#D2BD0A") +MUTEDBLUE = ManimColor("#3B719F") +MUTEDGREEN = ManimColor("#5FA052") +MUTEDPINK = ManimColor("#D1768F") +MUTEDPURPLE = ManimColor("#805B87") +NASTYGREEN = ManimColor("#70B23F") +NAVY = ManimColor("#01153E") +NAVYBLUE = ManimColor("#001146") +NAVYGREEN = ManimColor("#35530A") +NEONBLUE = ManimColor("#04D9FF") +NEONGREEN = ManimColor("#0CFF0C") +NEONPINK = ManimColor("#FE019A") +NEONPURPLE = ManimColor("#BC13FE") +NEONRED = ManimColor("#FF073A") +NEONYELLOW = ManimColor("#CFFF04") +NICEBLUE = ManimColor("#107AB0") +NIGHTBLUE = ManimColor("#040348") +OCEAN = ManimColor("#017B92") +OCEANBLUE = ManimColor("#03719C") +OCEANGREEN = ManimColor("#3D9973") +OCHER = ManimColor("#BF9B0C") +OCHRE = ManimColor("#BF9005") +OCRE = ManimColor("#C69C04") +OFFBLUE = ManimColor("#5684AE") +OFFGREEN = ManimColor("#6BA353") +OFFWHITE = ManimColor("#FFFFE4") +OFFYELLOW = ManimColor("#F1F33F") +OLDPINK = ManimColor("#C77986") +OLDROSE = ManimColor("#C87F89") +OLIVE = ManimColor("#6E750E") +OLIVEBROWN = ManimColor("#645403") +OLIVEDRAB = ManimColor("#6F7632") +OLIVEGREEN = ManimColor("#677A04") +OLIVEYELLOW = ManimColor("#C2B709") +ORANGE = ManimColor("#F97306") +ORANGEBROWN = ManimColor("#BE6400") +ORANGEISH = ManimColor("#FD8D49") +ORANGEPINK = ManimColor("#FF6F52") +ORANGERED = ManimColor("#FE420F") +ORANGEYBROWN = ManimColor("#B16002") +ORANGEYELLOW = ManimColor("#FFAD01") +ORANGEYRED = ManimColor("#FA4224") +ORANGEYYELLOW = ManimColor("#FDB915") +ORANGISH = ManimColor("#FC824A") +ORANGISHBROWN = ManimColor("#B25F03") +ORANGISHRED = ManimColor("#F43605") +ORCHID = ManimColor("#C875C4") +PALE = ManimColor("#FFF9D0") +PALEAQUA = ManimColor("#B8FFEB") +PALEBLUE = ManimColor("#D0FEFE") +PALEBROWN = ManimColor("#B1916E") +PALECYAN = ManimColor("#B7FFFA") +PALEGOLD = ManimColor("#FDDE6C") +PALEGREEN = ManimColor("#C7FDB5") +PALEGREY = ManimColor("#FDFDFE") +PALELAVENDER = ManimColor("#EECFFE") +PALELIGHTGREEN = ManimColor("#B1FC99") +PALELILAC = ManimColor("#E4CBFF") +PALELIME = ManimColor("#BEFD73") +PALELIMEGREEN = ManimColor("#B1FF65") +PALEMAGENTA = ManimColor("#D767AD") +PALEMAUVE = ManimColor("#FED0FC") +PALEOLIVE = ManimColor("#B9CC81") +PALEOLIVEGREEN = ManimColor("#B1D27B") +PALEORANGE = ManimColor("#FFA756") +PALEPEACH = ManimColor("#FFE5AD") +PALEPINK = ManimColor("#FFCFDC") +PALEPURPLE = ManimColor("#B790D4") +PALERED = ManimColor("#D9544D") +PALEROSE = ManimColor("#FDC1C5") +PALESALMON = ManimColor("#FFB19A") +PALESKYBLUE = ManimColor("#BDF6FE") +PALETEAL = ManimColor("#82CBB2") +PALETURQUOISE = ManimColor("#A5FBD5") +PALEVIOLET = ManimColor("#CEAEFA") +PALEYELLOW = ManimColor("#FFFF84") +PARCHMENT = ManimColor("#FEFCAF") +PASTELBLUE = ManimColor("#A2BFFE") +PASTELGREEN = ManimColor("#B0FF9D") +PASTELORANGE = ManimColor("#FF964F") +PASTELPINK = ManimColor("#FFBACD") +PASTELPURPLE = ManimColor("#CAA0FF") +PASTELRED = ManimColor("#DB5856") +PASTELYELLOW = ManimColor("#FFFE71") +PEA = ManimColor("#A4BF20") +PEACH = ManimColor("#FFB07C") +PEACHYPINK = ManimColor("#FF9A8A") +PEACOCKBLUE = ManimColor("#016795") +PEAGREEN = ManimColor("#8EAB12") +PEAR = ManimColor("#CBF85F") +PEASOUP = ManimColor("#929901") +PEASOUPGREEN = ManimColor("#94A617") +PERIWINKLE = ManimColor("#8E82FE") +PERIWINKLEBLUE = ManimColor("#8F99FB") +PERRYWINKLE = ManimColor("#8F8CE7") +PETROL = ManimColor("#005F6A") +PIGPINK = ManimColor("#E78EA5") +PINE = ManimColor("#2B5D34") +PINEGREEN = ManimColor("#0A481E") +PINK = ManimColor("#FF81C0") +PINKISH = ManimColor("#D46A7E") +PINKISHBROWN = ManimColor("#B17261") +PINKISHGREY = ManimColor("#C8ACA9") +PINKISHORANGE = ManimColor("#FF724C") +PINKISHPURPLE = ManimColor("#D648D7") +PINKISHRED = ManimColor("#F10C45") +PINKISHTAN = ManimColor("#D99B82") +PINKPURPLE = ManimColor("#EF1DE7") +PINKRED = ManimColor("#F5054F") +PINKY = ManimColor("#FC86AA") +PINKYPURPLE = ManimColor("#C94CBE") +PINKYRED = ManimColor("#FC2647") +PISSYELLOW = ManimColor("#DDD618") +PISTACHIO = ManimColor("#C0FA8B") +PLUM = ManimColor("#580F41") +PLUMPURPLE = ManimColor("#4E0550") +POISONGREEN = ManimColor("#40FD14") +POO = ManimColor("#8F7303") +POOBROWN = ManimColor("#885F01") +POOP = ManimColor("#7F5E00") +POOPBROWN = ManimColor("#7A5901") +POOPGREEN = ManimColor("#6F7C00") +POWDERBLUE = ManimColor("#B1D1FC") +POWDERPINK = ManimColor("#FFB2D0") +PRIMARYBLUE = ManimColor("#0804F9") +PRUSSIANBLUE = ManimColor("#004577") +PUCE = ManimColor("#A57E52") +PUKE = ManimColor("#A5A502") +PUKEBROWN = ManimColor("#947706") +PUKEGREEN = ManimColor("#9AAE07") +PUKEYELLOW = ManimColor("#C2BE0E") +PUMPKIN = ManimColor("#E17701") +PUMPKINORANGE = ManimColor("#FB7D07") +PUREBLUE = ManimColor("#0203E2") +PURPLE = ManimColor("#7E1E9C") +PURPLEBLUE = ManimColor("#5D21D0") +PURPLEBROWN = ManimColor("#673A3F") +PURPLEGREY = ManimColor("#866F85") +PURPLEISH = ManimColor("#98568D") +PURPLEISHBLUE = ManimColor("#6140EF") +PURPLEISHPINK = ManimColor("#DF4EC8") +PURPLEPINK = ManimColor("#D725DE") +PURPLERED = ManimColor("#990147") +PURPLEY = ManimColor("#8756E4") +PURPLEYBLUE = ManimColor("#5F34E7") +PURPLEYGREY = ManimColor("#947E94") +PURPLEYPINK = ManimColor("#C83CB9") +PURPLISH = ManimColor("#94568C") +PURPLISHBLUE = ManimColor("#601EF9") +PURPLISHBROWN = ManimColor("#6B4247") +PURPLISHGREY = ManimColor("#7A687F") +PURPLISHPINK = ManimColor("#CE5DAE") +PURPLISHRED = ManimColor("#B0054B") +PURPLY = ManimColor("#983FB2") +PURPLYBLUE = ManimColor("#661AEE") +PURPLYPINK = ManimColor("#F075E6") +PUTTY = ManimColor("#BEAE8A") +RACINGGREEN = ManimColor("#014600") +RADIOACTIVEGREEN = ManimColor("#2CFA1F") +RASPBERRY = ManimColor("#B00149") +RAWSIENNA = ManimColor("#9A6200") +RAWUMBER = ManimColor("#A75E09") +REALLYLIGHTBLUE = ManimColor("#D4FFFF") +RED = ManimColor("#E50000") +REDBROWN = ManimColor("#8B2E16") +REDDISH = ManimColor("#C44240") +REDDISHBROWN = ManimColor("#7F2B0A") +REDDISHGREY = ManimColor("#997570") +REDDISHORANGE = ManimColor("#F8481C") +REDDISHPINK = ManimColor("#FE2C54") +REDDISHPURPLE = ManimColor("#910951") +REDDYBROWN = ManimColor("#6E1005") +REDORANGE = ManimColor("#FD3C06") +REDPINK = ManimColor("#FA2A55") +REDPURPLE = ManimColor("#820747") +REDVIOLET = ManimColor("#9E0168") +REDWINE = ManimColor("#8C0034") +RICHBLUE = ManimColor("#021BF9") +RICHPURPLE = ManimColor("#720058") +ROBINEGGBLUE = ManimColor("#8AF1FE") +ROBINSEGG = ManimColor("#6DEDFD") +ROBINSEGGBLUE = ManimColor("#98EFF9") +ROSA = ManimColor("#FE86A4") +ROSE = ManimColor("#CF6275") +ROSEPINK = ManimColor("#F7879A") +ROSERED = ManimColor("#BE013C") +ROSYPINK = ManimColor("#F6688E") +ROGUE = ManimColor("#AB1239") +ROYAL = ManimColor("#0C1793") +ROYALBLUE = ManimColor("#0504AA") +ROYALPURPLE = ManimColor("#4B006E") +RUBY = ManimColor("#CA0147") +RUSSET = ManimColor("#A13905") +RUST = ManimColor("#A83C09") +RUSTBROWN = ManimColor("#8B3103") +RUSTORANGE = ManimColor("#C45508") +RUSTRED = ManimColor("#AA2704") +RUSTYORANGE = ManimColor("#CD5909") +RUSTYRED = ManimColor("#AF2F0D") +SAFFRON = ManimColor("#FEB209") +SAGE = ManimColor("#87AE73") +SAGEGREEN = ManimColor("#88B378") +SALMON = ManimColor("#FF796C") +SALMONPINK = ManimColor("#FE7B7C") +SAND = ManimColor("#E2CA76") +SANDBROWN = ManimColor("#CBA560") +SANDSTONE = ManimColor("#C9AE74") +SANDY = ManimColor("#F1DA7A") +SANDYBROWN = ManimColor("#C4A661") +SANDYELLOW = ManimColor("#FCE166") +SANDYYELLOW = ManimColor("#FDEE73") +SAPGREEN = ManimColor("#5C8B15") +SAPPHIRE = ManimColor("#2138AB") +SCARLET = ManimColor("#BE0119") +SEA = ManimColor("#3C9992") +SEABLUE = ManimColor("#047495") +SEAFOAM = ManimColor("#80F9AD") +SEAFOAMBLUE = ManimColor("#78D1B6") +SEAFOAMGREEN = ManimColor("#7AF9AB") +SEAGREEN = ManimColor("#53FCA1") +SEAWEED = ManimColor("#18D17B") +SEAWEEDGREEN = ManimColor("#35AD6B") +SEPIA = ManimColor("#985E2B") +SHAMROCK = ManimColor("#01B44C") +SHAMROCKGREEN = ManimColor("#02C14D") +SHIT = ManimColor("#7F5F00") +SHITBROWN = ManimColor("#7B5804") +SHITGREEN = ManimColor("#758000") +SHOCKINGPINK = ManimColor("#FE02A2") +SICKGREEN = ManimColor("#9DB92C") +SICKLYGREEN = ManimColor("#94B21C") +SICKLYYELLOW = ManimColor("#D0E429") +SIENNA = ManimColor("#A9561E") +SILVER = ManimColor("#C5C9C7") +SKY = ManimColor("#82CAFC") +SKYBLUE = ManimColor("#75BBFD") +SLATE = ManimColor("#516572") +SLATEBLUE = ManimColor("#5B7C99") +SLATEGREEN = ManimColor("#658D6D") +SLATEGREY = ManimColor("#59656D") +SLIMEGREEN = ManimColor("#99CC04") +SNOT = ManimColor("#ACBB0D") +SNOTGREEN = ManimColor("#9DC100") +SOFTBLUE = ManimColor("#6488EA") +SOFTGREEN = ManimColor("#6FC276") +SOFTPINK = ManimColor("#FDB0C0") +SOFTPURPLE = ManimColor("#A66FB5") +SPEARMINT = ManimColor("#1EF876") +SPRINGGREEN = ManimColor("#A9F971") +SPRUCE = ManimColor("#0A5F38") +SQUASH = ManimColor("#F2AB15") +STEEL = ManimColor("#738595") +STEELBLUE = ManimColor("#5A7D9A") +STEELGREY = ManimColor("#6F828A") +STONE = ManimColor("#ADA587") +STORMYBLUE = ManimColor("#507B9C") +STRAW = ManimColor("#FCF679") +STRAWBERRY = ManimColor("#FB2943") +STRONGBLUE = ManimColor("#0C06F7") +STRONGPINK = ManimColor("#FF0789") +SUNFLOWER = ManimColor("#FFC512") +SUNFLOWERYELLOW = ManimColor("#FFDA03") +SUNNYYELLOW = ManimColor("#FFF917") +SUNSHINEYELLOW = ManimColor("#FFFD37") +SUNYELLOW = ManimColor("#FFDF22") +SWAMP = ManimColor("#698339") +SWAMPGREEN = ManimColor("#748500") +TAN = ManimColor("#D1B26F") +TANBROWN = ManimColor("#AB7E4C") +TANGERINE = ManimColor("#FF9408") +TANGREEN = ManimColor("#A9BE70") +TAUPE = ManimColor("#B9A281") +TEA = ManimColor("#65AB7C") +TEAGREEN = ManimColor("#BDF8A3") +TEAL = ManimColor("#029386") +TEALBLUE = ManimColor("#01889F") +TEALGREEN = ManimColor("#25A36F") +TEALISH = ManimColor("#24BCA8") +TEALISHGREEN = ManimColor("#0CDC73") +TERRACOTA = ManimColor("#CB6843") +TERRACOTTA = ManimColor("#C9643B") +TIFFANYBLUE = ManimColor("#7BF2DA") +TOMATO = ManimColor("#EF4026") +TOMATORED = ManimColor("#EC2D01") +TOPAZ = ManimColor("#13BBAF") +TOUPE = ManimColor("#C7AC7D") +TOXICGREEN = ManimColor("#61DE2A") +TREEGREEN = ManimColor("#2A7E19") +TRUEBLUE = ManimColor("#010FCC") +TRUEGREEN = ManimColor("#089404") +TURQUOISE = ManimColor("#06C2AC") +TURQUOISEBLUE = ManimColor("#06B1C4") +TURQUOISEGREEN = ManimColor("#04F489") +TURTLEGREEN = ManimColor("#75B84F") +TWILIGHT = ManimColor("#4E518B") +TWILIGHTBLUE = ManimColor("#0A437A") +UGLYBLUE = ManimColor("#31668A") +UGLYBROWN = ManimColor("#7D7103") +UGLYGREEN = ManimColor("#7A9703") +UGLYPINK = ManimColor("#CD7584") +UGLYPURPLE = ManimColor("#A442A0") +UGLYYELLOW = ManimColor("#D0C101") +ULTRAMARINE = ManimColor("#2000B1") +ULTRAMARINEBLUE = ManimColor("#1805DB") +UMBER = ManimColor("#B26400") +VELVET = ManimColor("#750851") +VERMILION = ManimColor("#F4320C") +VERYDARKBLUE = ManimColor("#000133") +VERYDARKBROWN = ManimColor("#1D0200") +VERYDARKGREEN = ManimColor("#062E03") +VERYDARKPURPLE = ManimColor("#2A0134") +VERYLIGHTBLUE = ManimColor("#D5FFFF") +VERYLIGHTBROWN = ManimColor("#D3B683") +VERYLIGHTGREEN = ManimColor("#D1FFBD") +VERYLIGHTPINK = ManimColor("#FFF4F2") +VERYLIGHTPURPLE = ManimColor("#F6CEFC") +VERYPALEBLUE = ManimColor("#D6FFFE") +VERYPALEGREEN = ManimColor("#CFFDBC") +VIBRANTBLUE = ManimColor("#0339F8") +VIBRANTGREEN = ManimColor("#0ADD08") +VIBRANTPURPLE = ManimColor("#AD03DE") +VIOLET = ManimColor("#9A0EEA") +VIOLETBLUE = ManimColor("#510AC9") +VIOLETPINK = ManimColor("#FB5FFC") +VIOLETRED = ManimColor("#A50055") +VIRIDIAN = ManimColor("#1E9167") +VIVIDBLUE = ManimColor("#152EFF") +VIVIDGREEN = ManimColor("#2FEF10") +VIVIDPURPLE = ManimColor("#9900FA") +VOMIT = ManimColor("#A2A415") +VOMITGREEN = ManimColor("#89A203") +VOMITYELLOW = ManimColor("#C7C10C") +WARMBLUE = ManimColor("#4B57DB") +WARMBROWN = ManimColor("#964E02") +WARMGREY = ManimColor("#978A84") +WARMPINK = ManimColor("#FB5581") +WARMPURPLE = ManimColor("#952E8F") +WASHEDOUTGREEN = ManimColor("#BCF5A6") +WATERBLUE = ManimColor("#0E87CC") +WATERMELON = ManimColor("#FD4659") +WEIRDGREEN = ManimColor("#3AE57F") +WHEAT = ManimColor("#FBDD7E") +WHITE = ManimColor("#FFFFFF") +WINDOWSBLUE = ManimColor("#3778BF") +WINE = ManimColor("#80013F") +WINERED = ManimColor("#7B0323") +WINTERGREEN = ManimColor("#20F986") +WISTERIA = ManimColor("#A87DC2") +YELLOW = ManimColor("#FFFF14") +YELLOWBROWN = ManimColor("#B79400") +YELLOWGREEN = ManimColor("#BBF90F") +YELLOWISH = ManimColor("#FAEE66") +YELLOWISHBROWN = ManimColor("#9B7A01") +YELLOWISHGREEN = ManimColor("#B0DD16") +YELLOWISHORANGE = ManimColor("#FFAB0F") +YELLOWISHTAN = ManimColor("#FCFC81") +YELLOWOCHRE = ManimColor("#CB9D06") +YELLOWORANGE = ManimColor("#FCB001") +YELLOWTAN = ManimColor("#FFE36E") +YELLOWYBROWN = ManimColor("#AE8B0C") +YELLOWYGREEN = ManimColor("#BFF128") diff --git a/manim/utils/color/__init__.py b/manim/utils/color/__init__.py new file mode 100644 index 0000000000..7ef3cb3505 --- /dev/null +++ b/manim/utils/color/__init__.py @@ -0,0 +1,61 @@ +"""Utilities for working with colors and predefined color constants. + +Color data structure +-------------------- + +.. autosummary:: + :toctree: ../reference + + core + + +Predefined colors +----------------- + +There are several predefined colors available in Manim: + +- The colors listed in :mod:`.color.manim_colors` are loaded into + Manim's global name space. +- The colors in :mod:`.color.AS2700`, :mod:`.color.BS381`, + :mod:`.color.DVIPSNAMES`, :mod:`.color.SVGNAMES`, :mod:`.color.X11` and + :mod:`.color.XKCD` need to be accessed via their module (which are available + in Manim's global name space), or imported separately. For example: + + .. code:: pycon + + >>> from manim import XKCD + >>> XKCD.AVOCADO + ManimColor('#90B134') + + Or, alternatively: + + .. code:: pycon + + >>> from manim.utils.color.XKCD import AVOCADO + >>> AVOCADO + ManimColor('#90B134') + +The following modules contain the predefined color constants: + +.. autosummary:: + :toctree: ../reference + + manim_colors + AS2700 + BS381 + DVIPSNAMES + SVGNAMES + XKCD + X11 + +""" + +from __future__ import annotations + +from . import AS2700, BS381, DVIPSNAMES, SVGNAMES, X11, XKCD +from .core import * +from .manim_colors import * + +_all_color_dict: dict[str, ManimColor] = { + k: v for k, v in globals().items() if isinstance(v, ManimColor) +} diff --git a/manim/utils/color/core.py b/manim/utils/color/core.py new file mode 100644 index 0000000000..d8731f5d1b --- /dev/null +++ b/manim/utils/color/core.py @@ -0,0 +1,1572 @@ +"""Manim's (internal) color data structure and some utilities for color conversion. + +This module contains the implementation of :class:`.ManimColor`, the data structure +internally used to represent colors. + +The preferred way of using these colors is by importing their constants from Manim: + +.. code-block:: pycon + + >>> from manim import RED, GREEN, BLUE + >>> print(RED) + #FC6255 + +Note that this way uses the name of the colors in UPPERCASE. + +.. note:: + + The colors with a ``_C`` suffix have an alias equal to the colorname without a + letter. For example, ``GREEN = GREEN_C``. + +=================== +Custom Color Spaces +=================== + +Hello, dear visitor. You seem to be interested in implementing a custom color class for +a color space we don't currently support. + +The current system is using a few indirections for ensuring a consistent behavior with +all other color types in Manim. + +To implement a custom color space, you must subclass :class:`ManimColor` and implement +three important methods: + + - :attr:`~.ManimColor._internal_value`: a ``@property`` implemented on + :class:`ManimColor` with the goal of keeping a consistent internal representation + which can be referenced by other functions in :class:`ManimColor`. This property acts + as a proxy to whatever representation you need in your class. + + - The getter should always return a NumPy array in the format ``[r,g,b,a]``, in + accordance with the type :class:`ManimColorInternal`. + + - The setter should always accept a value in the format ``[r,g,b,a]`` which can be + converted to whatever attributes you need. + + - :attr:`~ManimColor._internal_space`: a read-only ``@property`` implemented on + :class:`ManimColor` with the goal of providing a useful representation which can be + used by operators, interpolation and color transform functions. + + The only constraints on this value are: + + - It must be a NumPy array. + + - The last value must be the opacity in a range ``0.0`` to ``1.0``. + + Additionally, your ``__init__`` must support this format as an initialization value + without additional parameters to ensure correct functionality of all other methods in + :class:`ManimColor`. + + - :meth:`~ManimColor._from_internal`: a ``@classmethod`` which converts an + ``[r,g,b,a]`` value into suitable parameters for your ``__init__`` method and calls + the ``cls`` parameter. +""" + +from __future__ import annotations + +import colorsys + +# logger = _config.logger +import random +import re +from collections.abc import Sequence +from typing import TypeVar, Union, overload + +import numpy as np +import numpy.typing as npt +from typing_extensions import Self, TypeAlias, TypeIs, override + +from manim.typing import ( + HSL_Array_Float, + HSL_Tuple_Float, + HSV_Array_Float, + HSV_Tuple_Float, + HSVA_Array_Float, + HSVA_Tuple_Float, + ManimColorDType, + ManimColorInternal, + ManimFloat, + Point3D, + RGB_Array_Float, + RGB_Array_Int, + RGB_Tuple_Float, + RGB_Tuple_Int, + RGBA_Array_Float, + RGBA_Array_Int, + RGBA_Tuple_Float, + RGBA_Tuple_Int, + Vector3D, +) + +from ...utils.space_ops import normalize + +# import manim._config as _config + +re_hex = re.compile("((?<=#)|(?<=0x))[A-F0-9]{3,8}", re.IGNORECASE) + + +class ManimColor: + """Internal representation of a color. + + The :class:`ManimColor` class is the main class for the representation of a color. + Its internal representation is an array of 4 floats corresponding to a ``[r,g,b,a]`` + value where ``r,g,b,a`` can be between 0.0 and 1.0. + + This is done in order to reduce the amount of color inconsistencies by constantly + casting between integers and floats which introduces errors. + + The class can accept any value of type :class:`ParsableManimColor` i.e. + + ``ManimColor, int, str, RGB_Tuple_Int, RGB_Tuple_Float, RGBA_Tuple_Int, RGBA_Tuple_Float, RGB_Array_Int, + RGB_Array_Float, RGBA_Array_Int, RGBA_Array_Float`` + + :class:`ManimColor` itself only accepts singular values and will directly interpret + them into a single color if possible. Be careful when passing strings to + :class:`ManimColor`: it can create a big overhead for the color processing. + + If you want to parse a list of colors, use the :meth:`parse` method, which assumes + that you're going to pass a list of colors so that arrays will not be interpreted as + a single color. + + .. warning:: + If you pass an array of numbers to :meth:`parse`, it will interpret the + ``r,g,b,a`` numbers in that array as colors: Instead of the expected + singular color, you will get an array with 4 colors. + + For conversion behaviors, see the ``_internal`` functions for further documentation. + + You can create a :class:`ManimColor` instance via its classmethods. See the + respective methods for more info. + + .. code-block:: python + + mycolor = ManimColor.from_rgb((0, 1, 0.4, 0.5)) + myothercolor = ManimColor.from_rgb((153, 255, 255)) + + You can also convert between different color spaces: + + .. code-block:: python + + mycolor_hex = mycolor.to_hex() + myoriginalcolor = ManimColor.from_hex(mycolor_hex).to_hsv() + + Parameters + ---------- + value + Some representation of a color (e.g., a string or + a suitable tuple). The default ``None`` is ``BLACK``. + alpha + The opacity of the color. By default, colors are + fully opaque (value 1.0). + """ + + def __init__( + self, + value: ParsableManimColor | None, + alpha: float = 1.0, + ) -> None: + if value is None: + self._internal_value = np.array((0, 0, 0, alpha), dtype=ManimColorDType) + elif isinstance(value, ManimColor): + # logger.info( + # "ManimColor was passed another ManimColor. This is probably not what " + # "you want. Created a copy of the passed ManimColor instead." + # ) + self._internal_value = value._internal_value + elif isinstance(value, int): + self._internal_value = ManimColor._internal_from_integer(value, alpha) + elif isinstance(value, str): + result = re_hex.search(value) + if result is not None: + self._internal_value = ManimColor._internal_from_hex_string( + result.group(), alpha + ) + else: + # This is not expected to be called on module initialization time + # It can be horribly slow to convert a string to a color because + # it has to access the dictionary of colors and find the right color + self._internal_value = ManimColor._internal_from_string(value, alpha) + elif isinstance(value, (list, tuple, np.ndarray)): + length = len(value) + if all(isinstance(x, float) for x in value): + if length == 3: + self._internal_value = ManimColor._internal_from_rgb(value, alpha) # type: ignore[arg-type] + elif length == 4: + self._internal_value = ManimColor._internal_from_rgba(value) # type: ignore[arg-type] + else: + raise ValueError( + f"ManimColor only accepts lists/tuples/arrays of length 3 or 4, not {length}" + ) + else: + if length == 3: + self._internal_value = ManimColor._internal_from_int_rgb( + value, # type: ignore[arg-type] + alpha, + ) + elif length == 4: + self._internal_value = ManimColor._internal_from_int_rgba(value) # type: ignore[arg-type] + else: + raise ValueError( + f"ManimColor only accepts lists/tuples/arrays of length 3 or 4, not {length}" + ) + elif hasattr(value, "get_hex") and callable(value.get_hex): + result = re_hex.search(value.get_hex()) + if result is None: + raise ValueError(f"Failed to parse a color from {value}") + self._internal_value = ManimColor._internal_from_hex_string( + result.group(), alpha + ) + else: + # logger.error(f"Invalid color value: {value}") + raise TypeError( + "ManimColor only accepts int, str, list[int, int, int], " + "list[int, int, int, int], list[float, float, float], " + f"list[float, float, float, float], not {type(value)}" + ) + + @property + def _internal_space(self) -> npt.NDArray[ManimFloat]: + """This is a readonly property which is a custom representation for color space + operations. It is used for operators and can be used when implementing a custom + color space. + """ + return self._internal_value + + @property + def _internal_value(self) -> ManimColorInternal: + """Return the internal value of the current Manim color ``[r,g,b,a]`` float + array. + + Returns + ------- + ManimColorInternal + Internal color representation. + """ + return self.__value + + @_internal_value.setter + def _internal_value(self, value: ManimColorInternal) -> None: + """Overwrite the internal color value of this :class:`ManimColor`. + + Parameters + ---------- + value + The value which will overwrite the current color. + + Raises + ------ + TypeError + If an invalid array is passed. + """ + if not isinstance(value, np.ndarray): + raise TypeError("Value must be a NumPy array.") + if value.shape[0] != 4: + raise TypeError("Array must have exactly 4 values.") + self.__value: ManimColorInternal = value + + @classmethod + def _construct_from_space( + cls, + _space: npt.NDArray[ManimFloat] + | tuple[float, float, float] + | tuple[float, float, float, float], + ) -> Self: + """This function is used as a proxy for constructing a color with an internal + value. This can be used by subclasses to hook into the construction of new + objects using the internal value format. + """ + return cls(_space) + + @staticmethod + def _internal_from_integer(value: int, alpha: float) -> ManimColorInternal: + return np.asarray( + ( + ((value >> 16) & 0xFF) / 255, + ((value >> 8) & 0xFF) / 255, + ((value >> 0) & 0xFF) / 255, + alpha, + ), + dtype=ManimColorDType, + ) + + @staticmethod + def _internal_from_hex_string(hex_: str, alpha: float) -> ManimColorInternal: + """Internal function for converting a hex string into the internal representation + of a :class:`ManimColor`. + + .. warning:: + This does not accept any prefixes like # or similar in front of the hex string. + This is just intended for the raw hex part. + + *For internal use only* + + Parameters + ---------- + hex + Hex string to be parsed. + alpha + Alpha value used for the color, if the color is only 3 bytes long. Otherwise, + if the color is 4 bytes long, this parameter will not be used. + + Returns + ------- + ManimColorInternal + Internal color representation + """ + if len(hex_) in (3, 4): + hex_ = "".join([x * 2 for x in hex_]) + if len(hex_) == 6: + hex_ += "FF" + elif len(hex_) == 8: + alpha = (int(hex_, 16) & 0xFF) / 255 + else: + raise ValueError( + "Hex colors must be specified with either 0x or # as prefix and contain 6 or 8 hexadecimal numbers" + ) + tmp = int(hex_, 16) + return np.asarray( + ( + ((tmp >> 24) & 0xFF) / 255, + ((tmp >> 16) & 0xFF) / 255, + ((tmp >> 8) & 0xFF) / 255, + alpha, + ), + dtype=ManimColorDType, + ) + + @staticmethod + def _internal_from_int_rgb( + rgb: RGB_Tuple_Int, alpha: float = 1.0 + ) -> ManimColorInternal: + """Internal function for converting an RGB tuple of integers into the internal + representation of a :class:`ManimColor`. + + *For internal use only* + + Parameters + ---------- + rgb + Integer RGB tuple to be parsed + alpha + Optional alpha value. Default is 1.0. + + Returns + ------- + ManimColorInternal + Internal color representation. + """ + value: np.ndarray = np.asarray(rgb, dtype=ManimColorDType).copy() / 255 + value.resize(4, refcheck=False) + value[3] = alpha + return value + + @staticmethod + def _internal_from_rgb( + rgb: RGB_Tuple_Float, alpha: float = 1.0 + ) -> ManimColorInternal: + """Internal function for converting a rgb tuple of floats into the internal + representation of a :class:`ManimColor`. + + *For internal use only* + + Parameters + ---------- + rgb + Float RGB tuple to be parsed. + alpha + Optional alpha value. Default is 1.0. + + Returns + ------- + ManimColorInternal + Internal color representation. + """ + value: np.ndarray = np.asarray(rgb, dtype=ManimColorDType).copy() + value.resize(4, refcheck=False) + value[3] = alpha + return value + + @staticmethod + def _internal_from_int_rgba(rgba: RGBA_Tuple_Int) -> ManimColorInternal: + """Internal function for converting an RGBA tuple of integers into the internal + representation of a :class:`ManimColor`. + + *For internal use only* + + Parameters + ---------- + rgba + Int RGBA tuple to be parsed. + + Returns + ------- + ManimColorInternal + Internal color representation. + """ + return np.asarray(rgba, dtype=ManimColorDType) / 255 + + @staticmethod + def _internal_from_rgba(rgba: RGBA_Tuple_Float) -> ManimColorInternal: + """Internal function for converting an RGBA tuple of floats into the internal + representation of a :class:`ManimColor`. + + *For internal use only* + + Parameters + ---------- + rgba + Int RGBA tuple to be parsed. + + Returns + ------- + ManimColorInternal + Internal color representation. + """ + return np.asarray(rgba, dtype=ManimColorDType) + + @staticmethod + def _internal_from_string(name: str, alpha: float) -> ManimColorInternal: + """Internal function for converting a string into the internal representation of + a :class:`ManimColor`. This is not used for hex strings: please refer to + :meth:`_internal_from_hex` for this functionality. + + *For internal use only* + + Parameters + ---------- + name + The color name to be parsed into a color. Refer to the different color + modules in the documentation page to find the corresponding color names. + + Returns + ------- + ManimColorInternal + Internal color representation. + + Raises + ------ + ValueError + If the color name is not present in Manim. + """ + from . import _all_color_dict + + if tmp := _all_color_dict.get(name.upper()): + tmp._internal_value[3] = alpha + return tmp._internal_value.copy() + else: + raise ValueError(f"Color {name} not found") + + def to_integer(self) -> int: + """Convert the current :class:`ManimColor` into an integer. + + .. warning:: + This will return only the RGB part of the color. + + Returns + ------- + int + Integer representation of the color. + """ + tmp = (self._internal_value[:3] * 255).astype(dtype=np.byte).tobytes() + return int.from_bytes(tmp, "big") + + def to_rgb(self) -> RGB_Array_Float: + """Convert the current :class:`ManimColor` into an RGB array of floats. + + Returns + ------- + RGB_Array_Float + RGB array of 3 floats from 0.0 to 1.0. + """ + return self._internal_value[:3] + + def to_int_rgb(self) -> RGB_Array_Int: + """Convert the current :class:`ManimColor` into an RGB array of integers. + + Returns + ------- + RGB_Array_Int + RGB array of 3 integers from 0 to 255. + """ + return (self._internal_value[:3] * 255).astype(int) + + def to_rgba(self) -> RGBA_Array_Float: + """Convert the current :class:`ManimColor` into an RGBA array of floats. + + Returns + ------- + RGBA_Array_Float + RGBA array of 4 floats from 0.0 to 1.0. + """ + return self._internal_value + + def to_int_rgba(self) -> RGBA_Array_Int: + """Convert the current ManimColor into an RGBA array of integers. + + + Returns + ------- + RGBA_Array_Int + RGBA array of 4 integers from 0 to 255. + """ + return (self._internal_value * 255).astype(int) + + def to_rgba_with_alpha(self, alpha: float) -> RGBA_Array_Float: + """Convert the current :class:`ManimColor` into an RGBA array of floats. This is + similar to :meth:`to_rgba`, but you can change the alpha value. + + Parameters + ---------- + alpha + Alpha value to be used in the return value. + + Returns + ------- + RGBA_Array_Float + RGBA array of 4 floats from 0.0 to 1.0. + """ + return np.fromiter((*self._internal_value[:3], alpha), dtype=ManimColorDType) + + def to_int_rgba_with_alpha(self, alpha: float) -> RGBA_Array_Int: + """Convert the current :class:`ManimColor` into an RGBA array of integers. This + is similar to :meth:`to_int_rgba`, but you can change the alpha value. + + Parameters + ---------- + alpha + Alpha value to be used for the return value. Pass a float between 0.0 and + 1.0: it will automatically be scaled to an integer between 0 and 255. + + Returns + ------- + RGBA_Array_Int + RGBA array of 4 integers from 0 to 255. + """ + tmp = self._internal_value * 255 + tmp[3] = alpha * 255 + return tmp.astype(int) + + def to_hex(self, with_alpha: bool = False) -> str: + """Convert the :class:`ManimColor` to a hexadecimal representation of the color. + + Parameters + ---------- + with_alpha + If ``True``, append 2 extra characters to the hex string which represent the + alpha value of the color between 0 and 255. Default is ``False``. + + Returns + ------- + str + A hex string starting with a ``#``, with either 6 or 8 nibbles depending on + the ``with_alpha`` parameter. By default, it has 6 nibbles, i.e. ``#XXXXXX``. + """ + tmp = ( + f"#{int(self._internal_value[0] * 255):02X}" + f"{int(self._internal_value[1] * 255):02X}" + f"{int(self._internal_value[2] * 255):02X}" + ) + if with_alpha: + tmp += f"{int(self._internal_value[3] * 255):02X}" + return tmp + + def to_hsv(self) -> HSV_Array_Float: + """Convert the :class:`ManimColor` to an HSV array. + + .. note:: + Be careful: this returns an array in the form ``[h, s, v]``, where the + elements are floats. This might be confusing, because RGB can also be an array + of floats. You might want to annotate the usage of this function in your code + by typing your HSV array variables as :class:`HSV_Array_Float` in order to + differentiate them from RGB arrays. + + Returns + ------- + HSV_Array_Float + An HSV array of 3 floats from 0.0 to 1.0. + """ + return np.array(colorsys.rgb_to_hsv(*self.to_rgb())) + + def to_hsl(self) -> HSL_Array_Float: + """Convert the :class:`ManimColor` to an HSL array. + + .. note:: + Be careful: this returns an array in the form ``[h, s, l]``, where the + elements are floats. This might be confusing, because RGB can also be an array + of floats. You might want to annotate the usage of this function in your code + by typing your HSL array variables as :class:`HSL_Array_Float` in order to + differentiate them from RGB arrays. + + Returns + ------- + HSL_Array_Float + An HSL array of 3 floats from 0.0 to 1.0. + """ + hls = colorsys.rgb_to_hls(*self.to_rgb()) + return np.array([hls[0], hls[2], hls[1]]) + + def invert(self, with_alpha: bool = False) -> Self: + """Return a new, linearly inverted version of this :class:`ManimColor` (no + inplace changes). + + Parameters + ---------- + with_alpha + If ``True``, the alpha value will be inverted too. Default is ``False``. + + .. note:: + Setting ``with_alpha=True`` can result in unintended behavior where + objects are not displayed because their new alpha value is suddenly 0 or + very low. + + Returns + ------- + ManimColor + The linearly inverted :class:`ManimColor`. + """ + if with_alpha: + return self._construct_from_space(1.0 - self._internal_space) + else: + alpha = self._internal_space[3] + new = 1.0 - self._internal_space + new[-1] = alpha + return self._construct_from_space(new) + + def interpolate(self, other: Self, alpha: float) -> Self: + """Interpolate between the current and the given :class:`ManimColor`, and return + the result. + + Parameters + ---------- + other + The other :class:`ManimColor` to be used for interpolation. + alpha + A point on the line in RGBA colorspace connecting the two colors, i.e. the + interpolation point. 0.0 corresponds to the current :class:`ManimColor` and + 1.0 corresponds to the other :class:`ManimColor`. + + Returns + ------- + ManimColor + The interpolated :class:`ManimColor`. + """ + return self._construct_from_space( + self._internal_space * (1 - alpha) + other._internal_space * alpha + ) + + def darker(self, blend: float = 0.2) -> Self: + """Return a new color that is darker than the current color, i.e. + interpolated with ``BLACK``. The opacity is unchanged. + + Parameters + ---------- + blend + The blend ratio for the interpolation, from 0.0 (the current color + unchanged) to 1.0 (pure black). Default is 0.2, which results in a + slightly darker color. + + Returns + ------- + ManimColor + The darker :class:`ManimColor`. + + See Also + -------- + :meth:`lighter` + """ + from manim.utils.color.manim_colors import BLACK + + alpha = self._internal_space[3] + black = self._from_internal(BLACK._internal_value) + return self.interpolate(black, blend).opacity(alpha) + + def lighter(self, blend: float = 0.2) -> Self: + """Return a new color that is lighter than the current color, i.e. + interpolated with ``WHITE``. The opacity is unchanged. + + Parameters + ---------- + blend + The blend ratio for the interpolation, from 0.0 (the current color + unchanged) to 1.0 (pure white). Default is 0.2, which results in a + slightly lighter color. + + Returns + ------- + ManimColor + The lighter :class:`ManimColor`. + + See Also + -------- + :meth:`darker` + """ + from manim.utils.color.manim_colors import WHITE + + alpha = self._internal_space[3] + white = self._from_internal(WHITE._internal_value) + return self.interpolate(white, blend).opacity(alpha) + + def contrasting( + self, + threshold: float = 0.5, + light: Self | None = None, + dark: Self | None = None, + ) -> Self: + """Return one of two colors, light or dark (by default white or black), + that contrasts with the current color (depending on its luminance). + This is typically used to set text in a contrasting color that ensures + it is readable against a background of the current color. + + Parameters + ---------- + threshold + The luminance threshold which dictates whether the current color is + considered light or dark (and thus whether to return the dark or + light color, respectively). Default is 0.5. + light + The light color to return if the current color is considered dark. + Default is ``None``: in this case, pure ``WHITE`` will be returned. + dark + The dark color to return if the current color is considered light, + Default is ``None``: in this case, pure ``BLACK`` will be returned. + + Returns + ------- + ManimColor + The contrasting :class:`ManimColor`. + """ + from manim.utils.color.manim_colors import BLACK, WHITE + + luminance, _, _ = colorsys.rgb_to_yiq(*self.to_rgb()) + if luminance < threshold: + if light is not None: + return light + return self._from_internal(WHITE._internal_value) + else: + if dark is not None: + return dark + return self._from_internal(BLACK._internal_value) + + def opacity(self, opacity: float) -> Self: + """Create a new :class:`ManimColor` with the given opacity and the same color + values as before. + + Parameters + ---------- + opacity + The new opacity value to be used. + + Returns + ------- + ManimColor + The new :class:`ManimColor` with the same color values and the new opacity. + """ + tmp = self._internal_space.copy() + tmp[-1] = opacity + return self._construct_from_space(tmp) + + def into(self, class_type: type[ManimColorT]) -> ManimColorT: + """Convert the current color into a different colorspace given by ``class_type``, + without changing the :attr:`_internal_value`. + + Parameters + ---------- + class_type + The class that is used for conversion. It must be a subclass of + :class:`ManimColor` which respects the specification HSV, RGBA, ... + + Returns + ------- + ManimColorT + A new color object of type ``class_type`` and the same + :attr:`_internal_value` as the original color. + """ + return class_type._from_internal(self._internal_value) + + @classmethod + def _from_internal(cls, value: ManimColorInternal) -> Self: + """This method is intended to be overwritten by custom color space classes + which are subtypes of :class:`ManimColor`. + + The method constructs a new object of the given class by transforming the value + in the internal format ``[r,g,b,a]`` into a format which the constructor of the + custom class can understand. Look at :class:`.HSV` for an example. + """ + return cls(value) + + @classmethod + def from_rgb( + cls, + rgb: RGB_Array_Float | RGB_Tuple_Float | RGB_Array_Int | RGB_Tuple_Int, + alpha: float = 1.0, + ) -> Self: + """Create a ManimColor from an RGB array. Automagically decides which type it + is: ``int`` or ``float``. + + .. warning:: + Please make sure that your elements are not floats if you want integers. A + ``5.0`` will result in the input being interpreted as if it was an RGB float + array with the value ``5.0`` and not the integer ``5``. + + + Parameters + ---------- + rgb + Any iterable of 3 floats or 3 integers. + alpha + Alpha value to be used in the color. Default is 1.0. + + Returns + ------- + ManimColor + The :class:`ManimColor` which corresponds to the given ``rgb``. + """ + return cls._from_internal(ManimColor(rgb, alpha)._internal_value) + + @classmethod + def from_rgba( + cls, rgba: RGBA_Array_Float | RGBA_Tuple_Float | RGBA_Array_Int | RGBA_Tuple_Int + ) -> Self: + """Create a ManimColor from an RGBA Array. Automagically decides which type it + is: ``int`` or ``float``. + + .. warning:: + Please make sure that your elements are not floats if you want integers. A + ``5.0`` will result in the input being interpreted as if it was a float RGB + array with the float ``5.0`` and not the integer ``5``. + + Parameters + ---------- + rgba + Any iterable of 4 floats or 4 integers. + + Returns + ------- + ManimColor + The :class:`ManimColor` corresponding to the given ``rgba``. + """ + return cls(rgba) + + @classmethod + def from_hex(cls, hex_str: str, alpha: float = 1.0) -> Self: + """Create a :class:`ManimColor` from a hex string. + + Parameters + ---------- + hex_str + The hex string to be converted. The allowed prefixes for this string are + ``#`` and ``0x``. Currently, this method only supports 6 nibbles, i.e. only + strings in the format ``#XXXXXX`` or ``0xXXXXXX``. + alpha + Alpha value to be used for the hex string. Default is 1.0. + + Returns + ------- + ManimColor + The :class:`ManimColor` represented by the hex string. + """ + return cls._from_internal(ManimColor(hex_str, alpha)._internal_value) + + @classmethod + def from_hsv( + cls, hsv: HSV_Array_Float | HSV_Tuple_Float, alpha: float = 1.0 + ) -> Self: + """Create a :class:`ManimColor` from an HSV array. + + Parameters + ---------- + hsv + Any iterable containing 3 floats from 0.0 to 1.0. + alpha + The alpha value to be used. Default is 1.0. + + Returns + ------- + ManimColor + The :class:`ManimColor` with the corresponding RGB values to the given HSV + array. + """ + rgb = colorsys.hsv_to_rgb(*hsv) + return cls._from_internal(ManimColor(rgb, alpha)._internal_value) + + @classmethod + def from_hsl( + cls, hsl: HSL_Array_Float | HSL_Tuple_Float, alpha: float = 1.0 + ) -> Self: + """Create a :class:`ManimColor` from an HSL array. + + Parameters + ---------- + hsl + Any iterable containing 3 floats from 0.0 to 1.0. + alpha + The alpha value to be used. Default is 1.0. + + Returns + ------- + ManimColor + The :class:`ManimColor` with the corresponding RGB values to the given HSL + array. + """ + rgb = colorsys.hls_to_rgb(hsl[0], hsl[2], hsl[1]) + return cls._from_internal(ManimColor(rgb, alpha)._internal_value) + + @overload + @classmethod + def parse( + cls, + color: ParsableManimColor | None, + alpha: float = ..., + ) -> Self: ... + + @overload + @classmethod + def parse( + cls, + color: Sequence[ParsableManimColor], + alpha: float = ..., + ) -> list[Self]: ... + + @classmethod + def parse( + cls, + color: ParsableManimColor | Sequence[ParsableManimColor] | None, + alpha: float = 1.0, + ) -> Self | list[Self]: + """Parse one color as a :class:`ManimColor` or a sequence of colors as a list of + :class:`ManimColor`'s. + + Parameters + ---------- + color + The color or list of colors to parse. Note that this function can not accept + tuples: it will assume that you mean ``Sequence[ParsableManimColor]`` and will + return a ``list[ManimColor]``. + alpha + The alpha (opacity) value to use for the passed color(s). + + Returns + ------- + ManimColor | list[ManimColor] + Either a list of colors or a singular color, depending on the input. + """ + + def is_sequence( + color: ParsableManimColor | Sequence[ParsableManimColor] | None, + ) -> TypeIs[Sequence[ParsableManimColor]]: + return isinstance(color, (list, tuple)) + + if is_sequence(color): + return [ + cls._from_internal(ManimColor(c, alpha)._internal_value) for c in color + ] + else: + return cls._from_internal(ManimColor(color, alpha)._internal_value) + + @staticmethod + def gradient( + colors: list[ManimColor], length: int + ) -> ManimColor | list[ManimColor]: + """This method is currently not implemented. Refer to :func:`color_gradient` for + a working implementation for now. + """ + # TODO: implement proper gradient, research good implementation for this or look at 3b1b implementation + raise NotImplementedError + + def __repr__(self) -> str: + return f"{self.__class__.__name__}('{self.to_hex()}')" + + def __str__(self) -> str: + return f"{self.to_hex()}" + + def __eq__(self, other: object) -> bool: + if not isinstance(other, ManimColor): + raise TypeError( + f"Cannot compare {self.__class__.__name__} with {other.__class__.__name__}" + ) + are_equal: bool = np.allclose(self._internal_value, other._internal_value) + return are_equal + + def __add__(self, other: int | float | Self) -> Self: + if isinstance(other, (int, float)): + return self._construct_from_space(self._internal_space + other) + else: + return self._construct_from_space( + self._internal_space + other._internal_space + ) + + def __radd__(self, other: int | float | Self) -> Self: + return self + other + + def __sub__(self, other: int | float | Self) -> Self: + if isinstance(other, (int, float)): + return self._construct_from_space(self._internal_space - other) + else: + return self._construct_from_space( + self._internal_space - other._internal_space + ) + + def __rsub__(self, other: int | float | Self) -> Self: + return self - other + + def __mul__(self, other: int | float | Self) -> Self: + if isinstance(other, (int, float)): + return self._construct_from_space(self._internal_space * other) + else: + return self._construct_from_space( + self._internal_space * other._internal_space + ) + + def __rmul__(self, other: int | float | Self) -> Self: + return self * other + + def __truediv__(self, other: int | float | Self) -> Self: + if isinstance(other, (int, float)): + return self._construct_from_space(self._internal_space / other) + else: + return self._construct_from_space( + self._internal_space / other._internal_space + ) + + def __rtruediv__(self, other: int | float | Self) -> Self: + return self / other + + def __floordiv__(self, other: int | float | Self) -> Self: + if isinstance(other, (int, float)): + return self._construct_from_space(self._internal_space // other) + else: + return self._construct_from_space( + self._internal_space // other._internal_space + ) + + def __rfloordiv__(self, other: int | float | Self) -> Self: + return self // other + + def __mod__(self, other: int | float | Self) -> Self: + if isinstance(other, (int, float)): + return self._construct_from_space(self._internal_space % other) + else: + return self._construct_from_space( + self._internal_space % other._internal_space + ) + + def __rmod__(self, other: int | float | Self) -> Self: + return self % other + + def __pow__(self, other: int | float | Self) -> Self: + if isinstance(other, (int, float)): + return self._construct_from_space(self._internal_space**other) + else: + return self._construct_from_space( + self._internal_space**other._internal_space + ) + + def __rpow__(self, other: int | float | Self) -> Self: + return self**other + + def __invert__(self) -> Self: + return self.invert() + + def __int__(self) -> int: + return self.to_integer() + + def __getitem__(self, index: int) -> float: + item: float = self._internal_space[index] + return item + + def __and__(self, other: Self) -> Self: + return self._construct_from_space( + self._internal_from_integer(self.to_integer() & int(other), 1.0) + ) + + def __or__(self, other: Self) -> Self: + return self._construct_from_space( + self._internal_from_integer(self.to_integer() | int(other), 1.0) + ) + + def __xor__(self, other: Self) -> Self: + return self._construct_from_space( + self._internal_from_integer(self.to_integer() ^ int(other), 1.0) + ) + + def __hash__(self) -> int: + return hash(self.to_hex(with_alpha=True)) + + +RGBA = ManimColor +"""RGBA Color Space""" + + +class HSV(ManimColor): + """HSV Color Space""" + + def __init__( + self, + hsv: HSV_Array_Float | HSV_Tuple_Float | HSVA_Array_Float | HSVA_Tuple_Float, + alpha: float = 1.0, + ) -> None: + super().__init__(None) + self.__hsv: HSVA_Array_Float + if len(hsv) == 3: + self.__hsv = np.asarray((*hsv, alpha)) + elif len(hsv) == 4: + self.__hsv = np.asarray(hsv) + else: + raise ValueError("HSV Color must be an array of 3 values") + + @classmethod + @override + def _from_internal(cls, value: ManimColorInternal) -> Self: + hsv = colorsys.rgb_to_hsv(*value[:3]) + hsva = [*hsv, value[-1]] + return cls(np.array(hsva)) + + @property + def hue(self) -> float: + hue: float = self.__hsv[0] + return hue + + @hue.setter + def hue(self, hue: float) -> None: + self.__hsv[0] = hue + + @property + def saturation(self) -> float: + saturation: float = self.__hsv[1] + return saturation + + @saturation.setter + def saturation(self, saturation: float) -> None: + self.__hsv[1] = saturation + + @property + def value(self) -> float: + value: float = self.__hsv[2] + return value + + @value.setter + def value(self, value: float) -> None: + self.__hsv[2] = value + + @property + def h(self) -> float: + hue: float = self.__hsv[0] + return hue + + @h.setter + def h(self, hue: float) -> None: + self.__hsv[0] = hue + + @property + def s(self) -> float: + saturation: float = self.__hsv[1] + return saturation + + @s.setter + def s(self, saturation: float) -> None: + self.__hsv[1] = saturation + + @property + def v(self) -> float: + value: float = self.__hsv[2] + return value + + @v.setter + def v(self, value: float) -> None: + self.__hsv[2] = value + + @property + def _internal_space(self) -> npt.NDArray: + return self.__hsv + + @property + def _internal_value(self) -> ManimColorInternal: + """Return the internal value of the current :class:`ManimColor` as an + ``[r,g,b,a]`` float array. + + Returns + ------- + ManimColorInternal + Internal color representation. + """ + return np.array( + [ + *colorsys.hsv_to_rgb(self.__hsv[0], self.__hsv[1], self.__hsv[2]), + self.__alpha, + ], + dtype=ManimColorDType, + ) + + @_internal_value.setter + def _internal_value(self, value: ManimColorInternal) -> None: + """Overwrite the internal color value of this :class:`ManimColor`. + + Parameters + ---------- + value + The value which will overwrite the current color. + + Raises + ------ + TypeError + If an invalid array is passed. + """ + if not isinstance(value, np.ndarray): + raise TypeError("Value must be a NumPy array.") + if value.shape[0] != 4: + raise TypeError("Array must have exactly 4 values.") + tmp = colorsys.rgb_to_hsv(value[0], value[1], value[2]) + self.__hsv = np.array(tmp) + self.__alpha = value[3] + + +ParsableManimColor: TypeAlias = Union[ + ManimColor, + int, + str, + RGB_Tuple_Int, + RGB_Tuple_Float, + RGBA_Tuple_Int, + RGBA_Tuple_Float, + RGB_Array_Int, + RGB_Array_Float, + RGBA_Array_Int, + RGBA_Array_Float, +] +"""`ParsableManimColor` represents all the types which can be parsed +to a :class:`ManimColor` in Manim. +""" + + +ManimColorT = TypeVar("ManimColorT", bound=ManimColor) + + +def color_to_rgb(color: ParsableManimColor) -> RGB_Array_Float: + """Helper function for use in functional style programming. + Refer to :meth:`ManimColor.to_rgb`. + + Parameters + ---------- + color + A color to convert to an RGB float array. + + Returns + ------- + RGB_Array_Float + The corresponding RGB float array. + """ + return ManimColor(color).to_rgb() + + +def color_to_rgba(color: ParsableManimColor, alpha: float = 1.0) -> RGBA_Array_Float: + """Helper function for use in functional style programming. Refer to + :meth:`ManimColor.to_rgba_with_alpha`. + + Parameters + ---------- + color + A color to convert to an RGBA float array. + alpha + An alpha value between 0.0 and 1.0 to be used as opacity in the color. Default is + 1.0. + + Returns + ------- + RGBA_Array_Float + The corresponding RGBA float array. + """ + return ManimColor(color).to_rgba_with_alpha(alpha) + + +def color_to_int_rgb(color: ParsableManimColor) -> RGB_Array_Int: + """Helper function for use in functional style programming. Refer to + :meth:`ManimColor.to_int_rgb`. + + Parameters + ---------- + color + A color to convert to an RGB integer array. + + Returns + ------- + RGB_Array_Int + The corresponding RGB integer array. + """ + return ManimColor(color).to_int_rgb() + + +def color_to_int_rgba(color: ParsableManimColor, alpha: float = 1.0) -> RGBA_Array_Int: + """Helper function for use in functional style programming. Refer to + :meth:`ManimColor.to_int_rgba_with_alpha`. + + Parameters + ---------- + color + A color to convert to an RGBA integer array. + alpha + An alpha value between 0.0 and 1.0 to be used as opacity in the color. Default is + 1.0. + + Returns + ------- + RGBA_Array_Int + The corresponding RGBA integer array. + """ + return ManimColor(color).to_int_rgba_with_alpha(alpha) + + +def rgb_to_color( + rgb: RGB_Array_Float | RGB_Tuple_Float | RGB_Array_Int | RGB_Tuple_Int, +) -> ManimColor: + """Helper function for use in functional style programming. Refer to + :meth:`ManimColor.from_rgb`. + + Parameters + ---------- + rgb + A 3 element iterable. + + Returns + ------- + ManimColor + A ManimColor with the corresponding value. + """ + return ManimColor.from_rgb(rgb) + + +def rgba_to_color( + rgba: RGBA_Array_Float | RGBA_Tuple_Float | RGBA_Array_Int | RGBA_Tuple_Int, +) -> ManimColor: + """Helper function for use in functional style programming. Refer to + :meth:`ManimColor.from_rgba`. + + Parameters + ---------- + rgba + A 4 element iterable. + + Returns + ------- + ManimColor + A ManimColor with the corresponding value + """ + return ManimColor.from_rgba(rgba) + + +def rgb_to_hex( + rgb: RGB_Array_Float | RGB_Tuple_Float | RGB_Array_Int | RGB_Tuple_Int, +) -> str: + """Helper function for use in functional style programming. Refer to + :meth:`ManimColor.from_rgb` and :meth:`ManimColor.to_hex`. + + Parameters + ---------- + rgb + A 3 element iterable. + + Returns + ------- + str + A hex representation of the color. + """ + return ManimColor.from_rgb(rgb).to_hex() + + +def hex_to_rgb(hex_code: str) -> RGB_Array_Float: + """Helper function for use in functional style programming. Refer to + :meth:`ManimColor.to_rgb`. + + Parameters + ---------- + hex_code + A hex string representing a color. + + Returns + ------- + RGB_Array_Float + An RGB array representing the color. + """ + return ManimColor(hex_code).to_rgb() + + +def invert_color(color: ManimColorT) -> ManimColorT: + """Helper function for use in functional style programming. Refer to + :meth:`ManimColor.invert` + + Parameters + ---------- + color + The :class:`ManimColor` to invert. + + Returns + ------- + ManimColor + The linearly inverted :class:`ManimColor`. + """ + return color.invert() + + +def color_gradient( + reference_colors: Sequence[ParsableManimColor], + length_of_output: int, +) -> list[ManimColor] | ManimColor: + """Create a list of colors interpolated between the input array of colors with a + specific number of colors. + + Parameters + ---------- + reference_colors + The colors to be interpolated between or spread apart. + length_of_output + The number of colors that the output should have, ideally more than the input. + + Returns + ------- + list[ManimColor] | ManimColor + A :class:`ManimColor` or a list of interpolated :class:`ManimColor`'s. + """ + if length_of_output == 0: + return ManimColor(reference_colors[0]) + if len(reference_colors) == 1: + return [ManimColor(reference_colors[0])] * length_of_output + rgbs = [color_to_rgb(color) for color in reference_colors] + alphas = np.linspace(0, (len(rgbs) - 1), length_of_output) + floors = alphas.astype("int") + alphas_mod1 = alphas % 1 + # End edge case + alphas_mod1[-1] = 1 + floors[-1] = len(rgbs) - 2 + return [ + rgb_to_color((rgbs[i] * (1 - alpha)) + (rgbs[i + 1] * alpha)) + for i, alpha in zip(floors, alphas_mod1) + ] + + +def interpolate_color( + color1: ManimColorT, color2: ManimColorT, alpha: float +) -> ManimColorT: + """Standalone function to interpolate two ManimColors and get the result. Refer to + :meth:`ManimColor.interpolate`. + + Parameters + ---------- + color1 + The first :class:`ManimColor`. + color2 + The second :class:`ManimColor`. + alpha + The alpha value determining the point of interpolation between the colors. + + Returns + ------- + ManimColor + The interpolated ManimColor. + """ + return color1.interpolate(color2, alpha) + + +def average_color(*colors: ParsableManimColor) -> ManimColor: + """Determine the average color between the given parameters. + + .. note:: + This operation does not consider the alphas (opacities) of the colors. The + generated color has an alpha or opacity of 1.0. + + Returns + ------- + ManimColor + The average color of the input. + """ + rgbs = np.array([color_to_rgb(color) for color in colors]) + mean_rgb = np.apply_along_axis(np.mean, 0, rgbs) + return rgb_to_color(mean_rgb) + + +def random_bright_color() -> ManimColor: + """Return a random bright color: a random color averaged with ``WHITE``. + + .. warning:: + This operation is very expensive. Please keep in mind the performance loss. + + Returns + ------- + ManimColor + A random bright :class:`ManimColor`. + """ + curr_rgb = color_to_rgb(random_color()) + new_rgb = 0.5 * (curr_rgb + np.ones(3)) + return ManimColor(new_rgb) + + +def random_color() -> ManimColor: + """Return a random :class:`ManimColor`. + + .. warning:: + This operation is very expensive. Please keep in mind the performance loss. + + Returns + ------- + ManimColor + A random :class:`ManimColor`. + """ + import manim.utils.color.manim_colors as manim_colors + + return random.choice(manim_colors._all_manim_colors) + + +def get_shaded_rgb( + rgb: RGB_Array_Float, + point: Point3D, + unit_normal_vect: Vector3D, + light_source: Point3D, +) -> RGB_Array_Float: + """Add light or shadow to the ``rgb`` color of some surface which is located at a + given ``point`` in space and facing in the direction of ``unit_normal_vect``, + depending on whether the surface is facing a ``light_source`` or away from it. + + Parameters + ---------- + rgb + An RGB array of floats. + point + The location of the colored surface. + unit_normal_vect + The direction in which the colored surface is facing. + light_source + The location of a light source which might illuminate the surface. + + Returns + ------- + RGB_Array_Float + The color with added light or shadow, depending on the direction of the colored + surface. + """ + to_sun = normalize(light_source - point) + light = 0.5 * np.dot(unit_normal_vect, to_sun) ** 3 + if light < 0: + light *= 0.5 + shaded_rgb: RGB_Array_Float = rgb + light + return shaded_rgb + + +__all__ = [ + "ManimColor", + "ManimColorDType", + "ParsableManimColor", + "color_to_rgb", + "color_to_rgba", + "color_to_int_rgb", + "color_to_int_rgba", + "rgb_to_color", + "rgba_to_color", + "rgb_to_hex", + "hex_to_rgb", + "invert_color", + "color_gradient", + "interpolate_color", + "average_color", + "random_bright_color", + "random_color", + "get_shaded_rgb", + "HSV", + "RGBA", +] diff --git a/manim/utils/color/manim_colors.py b/manim/utils/color/manim_colors.py new file mode 100644 index 0000000000..44c7a8c0c4 --- /dev/null +++ b/manim/utils/color/manim_colors.py @@ -0,0 +1,218 @@ +"""Colors included in the global name space. + +These colors form Manim's default color space. + +.. manim:: ColorsOverview + :save_last_frame: + :hide_source: + + import manim.utils.color.manim_colors as Colors + + class ColorsOverview(Scene): + def construct(self): + def color_group(color): + group = VGroup( + *[ + Line(ORIGIN, RIGHT * 1.5, stroke_width=35, color=getattr(Colors, name.upper())) + for name in subnames(color) + ] + ).arrange_submobjects(buff=0.4, direction=DOWN) + + name = Text(color).scale(0.6).next_to(group, UP, buff=0.3) + if any(decender in color for decender in "gjpqy"): + name.shift(DOWN * 0.08) + group.add(name) + return group + + def subnames(name): + return [name + "_" + char for char in "abcde"] + + color_groups = VGroup( + *[ + color_group(color) + for color in [ + "blue", + "teal", + "green", + "yellow", + "gold", + "red", + "maroon", + "purple", + ] + ] + ).arrange_submobjects(buff=0.2, aligned_edge=DOWN) + + for line, char in zip(color_groups[0], "abcde"): + color_groups.add(Text(char).scale(0.6).next_to(line, LEFT, buff=0.2)) + + def named_lines_group(length, color_names, labels, align_to_block): + colors = [getattr(Colors, color.upper()) for color in color_names] + lines = VGroup( + *[ + Line( + ORIGIN, + RIGHT * length, + stroke_width=55, + color=color, + ) + for color in colors + ] + ).arrange_submobjects(buff=0.6, direction=DOWN) + + for line, name, color in zip(lines, labels, colors): + line.add(Text(name, color=color.contrasting()).scale(0.6).move_to(line)) + lines.next_to(color_groups, DOWN, buff=0.5).align_to( + color_groups[align_to_block], LEFT + ) + return lines + + other_colors = ( + "pink", + "light_pink", + "orange", + "light_brown", + "dark_brown", + "gray_brown", + ) + + other_lines = named_lines_group( + 3.2, + other_colors, + other_colors, + 0, + ) + + gray_lines = named_lines_group( + 6.6, + ["white"] + subnames("gray") + ["black"], + [ + "white", + "lighter_gray / gray_a", + "light_gray / gray_b", + "gray / gray_c", + "dark_gray / gray_d", + "darker_gray / gray_e", + "black", + ], + 2, + ) + + pure_colors = ( + "pure_red", + "pure_green", + "pure_blue", + ) + + pure_lines = named_lines_group( + 3.2, + pure_colors, + pure_colors, + 6, + ) + + self.add(color_groups, other_lines, gray_lines, pure_lines) + + VGroup(*self.mobjects).move_to(ORIGIN) + +.. automanimcolormodule:: manim.utils.color.manim_colors + +""" + +from __future__ import annotations + +from .core import ManimColor + +WHITE = ManimColor("#FFFFFF") +GRAY_A = ManimColor("#DDDDDD") +GREY_A = ManimColor("#DDDDDD") +GRAY_B = ManimColor("#BBBBBB") +GREY_B = ManimColor("#BBBBBB") +GRAY_C = ManimColor("#888888") +GREY_C = ManimColor("#888888") +GRAY_D = ManimColor("#444444") +GREY_D = ManimColor("#444444") +GRAY_E = ManimColor("#222222") +GREY_E = ManimColor("#222222") +BLACK = ManimColor("#000000") +LIGHTER_GRAY = ManimColor("#DDDDDD") +LIGHTER_GREY = ManimColor("#DDDDDD") +LIGHT_GRAY = ManimColor("#BBBBBB") +LIGHT_GREY = ManimColor("#BBBBBB") +GRAY = ManimColor("#888888") +GREY = ManimColor("#888888") +DARK_GRAY = ManimColor("#444444") +DARK_GREY = ManimColor("#444444") +DARKER_GRAY = ManimColor("#222222") +DARKER_GREY = ManimColor("#222222") +BLUE_A = ManimColor("#C7E9F1") +BLUE_B = ManimColor("#9CDCEB") +BLUE_C = ManimColor("#58C4DD") +BLUE_D = ManimColor("#29ABCA") +BLUE_E = ManimColor("#236B8E") +PURE_BLUE = ManimColor("#0000FF") +BLUE = ManimColor("#58C4DD") +DARK_BLUE = ManimColor("#236B8E") +TEAL_A = ManimColor("#ACEAD7") +TEAL_B = ManimColor("#76DDC0") +TEAL_C = ManimColor("#5CD0B3") +TEAL_D = ManimColor("#55C1A7") +TEAL_E = ManimColor("#49A88F") +TEAL = ManimColor("#5CD0B3") +GREEN_A = ManimColor("#C9E2AE") +GREEN_B = ManimColor("#A6CF8C") +GREEN_C = ManimColor("#83C167") +GREEN_D = ManimColor("#77B05D") +GREEN_E = ManimColor("#699C52") +PURE_GREEN = ManimColor("#00FF00") +GREEN = ManimColor("#83C167") +YELLOW_A = ManimColor("#FFF1B6") +YELLOW_B = ManimColor("#FFEA94") +YELLOW_C = ManimColor("#FFFF00") +YELLOW_D = ManimColor("#F4D345") +YELLOW_E = ManimColor("#E8C11C") +YELLOW = ManimColor("#FFFF00") +GOLD_A = ManimColor("#F7C797") +GOLD_B = ManimColor("#F9B775") +GOLD_C = ManimColor("#F0AC5F") +GOLD_D = ManimColor("#E1A158") +GOLD_E = ManimColor("#C78D46") +GOLD = ManimColor("#F0AC5F") +RED_A = ManimColor("#F7A1A3") +RED_B = ManimColor("#FF8080") +RED_C = ManimColor("#FC6255") +RED_D = ManimColor("#E65A4C") +RED_E = ManimColor("#CF5044") +PURE_RED = ManimColor("#FF0000") +RED = ManimColor("#FC6255") +MAROON_A = ManimColor("#ECABC1") +MAROON_B = ManimColor("#EC92AB") +MAROON_C = ManimColor("#C55F73") +MAROON_D = ManimColor("#A24D61") +MAROON_E = ManimColor("#94424F") +MAROON = ManimColor("#C55F73") +PURPLE_A = ManimColor("#CAA3E8") +PURPLE_B = ManimColor("#B189C6") +PURPLE_C = ManimColor("#9A72AC") +PURPLE_D = ManimColor("#715582") +PURPLE_E = ManimColor("#644172") +PURPLE = ManimColor("#9A72AC") +PINK = ManimColor("#D147BD") +LIGHT_PINK = ManimColor("#DC75CD") +ORANGE = ManimColor("#FF862F") +LIGHT_BROWN = ManimColor("#CD853F") +DARK_BROWN = ManimColor("#8B4513") +GRAY_BROWN = ManimColor("#736357") +GREY_BROWN = ManimColor("#736357") + +# Colors used for Manim Community's logo and banner + +LOGO_WHITE = ManimColor("#ECE7E2") +LOGO_GREEN = ManimColor("#87C2A5") +LOGO_BLUE = ManimColor("#525893") +LOGO_RED = ManimColor("#E07A5F") +LOGO_BLACK = ManimColor("#343434") + +_all_manim_colors: list[ManimColor] = [ + x for x in globals().values() if isinstance(x, ManimColor) +] diff --git a/manim/utils/commands.py b/manim/utils/commands.py index efc9d9c1f9..b8154ca8be 100644 --- a/manim/utils/commands.py +++ b/manim/utils/commands.py @@ -1,9 +1,14 @@ from __future__ import annotations -import json import os +from collections.abc import Generator +from pathlib import Path from subprocess import run -from typing import Any +from typing import TypedDict + +import av + +from manim.typing import StrOrBytesPath __all__ = [ "capture", @@ -12,34 +17,58 @@ ] -def capture(command, cwd=None, command_input=None): - p = run(command, cwd=cwd, input=command_input, capture_output=True, text=True) +def capture( + command: str, cwd: StrOrBytesPath | None = None, command_input: str | None = None +) -> tuple[str, str, int]: + p = run( + command, + cwd=cwd, + input=command_input, + capture_output=True, + text=True, + encoding="utf-8", + ) out, err = p.stdout, p.stderr return out, err, p.returncode -def get_video_metadata(path_to_video: str) -> dict[str, Any]: - command = [ - "ffprobe", - "-v", - "error", - "-select_streams", - "v:0", - "-show_entries", - "stream=width,height,nb_frames,duration,avg_frame_rate,codec_name", - "-print_format", - "json", - str(path_to_video), - ] - config, err, exitcode = capture(command) - assert exitcode == 0, f"FFprobe error: {err}" - return json.loads(config)["streams"][0] - - -def get_dir_layout(dirpath: str) -> list[str]: +class VideoMetadata(TypedDict): + width: int + height: int + nb_frames: str + duration: str + avg_frame_rate: str + codec_name: str + pix_fmt: str + + +def get_video_metadata(path_to_video: str | os.PathLike) -> VideoMetadata: + with av.open(str(path_to_video)) as container: + stream = container.streams.video[0] + ctxt = stream.codec_context + rate = stream.average_rate + if stream.duration is not None: + duration = float(stream.duration * stream.time_base) + num_frames = stream.frames + else: + num_frames = sum(1 for _ in container.decode(video=0)) + duration = float(num_frames / stream.base_rate) + + return { + "width": ctxt.width, + "height": ctxt.height, + "nb_frames": str(num_frames), + "duration": f"{duration:.6f}", + "avg_frame_rate": f"{rate.numerator}/{rate.denominator}", # Can be a Fraction + "codec_name": stream.codec_context.name, + "pix_fmt": stream.codec_context.pix_fmt, + } + + +def get_dir_layout(dirpath: Path) -> Generator[str, None, None]: """Get list of paths relative to dirpath of all files in dir and subdirs recursively.""" - index_files: list[str] = [] - for root, dirs, files in os.walk(dirpath): - for file in files: - index_files.append(f"{os.path.relpath(os.path.join(root, file), dirpath)}") - return index_files + for p in dirpath.iterdir(): + if p.is_dir(): + yield from get_dir_layout(p) + continue + yield str(p.relative_to(dirpath)) diff --git a/manim/utils/config_ops.py b/manim/utils/config_ops.py index 6e1f09990e..401144d55f 100644 --- a/manim/utils/config_ops.py +++ b/manim/utils/config_ops.py @@ -10,11 +10,12 @@ import itertools as it +from typing import Any -import numpy as np +import numpy.typing as npt -def merge_dicts_recursively(*dicts): +def merge_dicts_recursively(*dicts: dict[Any, Any]) -> dict[Any, Any]: """ Creates a dict whose keyset is the union of all the input dictionaries. The value for each key is based @@ -24,7 +25,7 @@ def merge_dicts_recursively(*dicts): When values are dictionaries, it is applied recursively """ - result = {} + result: dict = {} all_items = it.chain(*(d.items() for d in dicts)) for key, value in all_items: if key in result and isinstance(result[key], dict) and isinstance(value, dict): @@ -34,7 +35,9 @@ def merge_dicts_recursively(*dicts): return result -def update_dict_recursively(current_dict, *others): +def update_dict_recursively( + current_dict: dict[Any, Any], *others: dict[Any, Any] +) -> None: updated_dict = merge_dicts_recursively(current_dict, *others) current_dict.update(updated_dict) @@ -44,7 +47,7 @@ def update_dict_recursively(current_dict, *others): class DictAsObject: - def __init__(self, dictin): + def __init__(self, dictin: dict[str, Any]): self.__dict__ = dictin @@ -53,13 +56,14 @@ class _Data: self.data attributes must be arrays. """ - def __set_name__(self, obj, name): + def __set_name__(self, obj: Any, name: str) -> None: self.name = name - def __get__(self, obj, owner): - return obj.data[self.name] + def __get__(self, obj: Any, owner: Any) -> npt.NDArray[Any]: + value: npt.NDArray[Any] = obj.data[self.name] + return value - def __set__(self, obj, array: np.ndarray): + def __set__(self, obj: Any, array: npt.NDArray[Any]) -> None: obj.data[self.name] = array @@ -68,11 +72,12 @@ class _Uniforms: self.uniforms attributes must be floats. """ - def __set_name__(self, obj, name): + def __set_name__(self, obj: Any, name: str) -> None: self.name = name - def __get__(self, obj, owner): - return obj.__dict__["uniforms"][self.name] + def __get__(self, obj: Any, owner: Any) -> float: + val: float = obj.__dict__["uniforms"][self.name] + return val - def __set__(self, obj, num: float): + def __set__(self, obj: Any, num: float) -> None: obj.__dict__["uniforms"][self.name] = num diff --git a/manim/utils/debug.py b/manim/utils/debug.py index 3e066837e2..bca9537a7b 100644 --- a/manim/utils/debug.py +++ b/manim/utils/debug.py @@ -1,19 +1,21 @@ """Debugging utilities.""" - from __future__ import annotations __all__ = ["print_family", "index_labels"] +from typing import Any + from manim.mobject.mobject import Mobject from manim.mobject.text.numbers import Integer +from manim.utils.color import ManimColor from ..mobject.types.vectorized_mobject import VGroup from .color import BLACK -def print_family(mobject, n_tabs=0): +def print_family(mobject: Mobject, n_tabs: int = 0) -> None: """For debugging purposes""" print("\t" * n_tabs, mobject, id(mobject)) for submob in mobject.submobjects: @@ -23,10 +25,10 @@ def print_family(mobject, n_tabs=0): def index_labels( mobject: Mobject, label_height: float = 0.15, - background_stroke_width=5, - background_stroke_color=BLACK, - **kwargs, -): + background_stroke_width: float = 5, + background_stroke_color: ManimColor = BLACK, + **kwargs: Any, +) -> VGroup: r"""Returns a :class:`~.VGroup` of :class:`~.Integer` mobjects that shows the index of each submobject. @@ -68,7 +70,6 @@ def construct(self): self.add(text, indices) """ - labels = VGroup() for n, submob in enumerate(mobject): label = Integer(n, **kwargs) diff --git a/manim/utils/deprecation.py b/manim/utils/deprecation.py index 744aa8348c..d8bb9fb97c 100644 --- a/manim/utils/deprecation.py +++ b/manim/utils/deprecation.py @@ -6,15 +6,17 @@ import inspect +import logging import re -from typing import Any, Callable, Iterable +from collections.abc import Iterable +from typing import Any, Callable, TypeVar, overload from decorator import decorate, decorator -from .. import logger +logger = logging.getLogger("manim") -def _get_callable_info(callable: Callable) -> tuple[str, str]: +def _get_callable_info(callable_: Callable[..., Any], /) -> tuple[str, str]: """Returns type and name of a callable. Parameters @@ -28,8 +30,8 @@ def _get_callable_info(callable: Callable) -> tuple[str, str]: The type and name of the callable. Type can can be one of "class", "method" (for functions defined in classes) or "function"). For methods, name is Class.method. """ - what = type(callable).__name__ - name = callable.__qualname__ + what = type(callable_).__name__ + name = callable_.__qualname__ if what == "function" and "." in name: what = "method" elif what != "function": @@ -38,9 +40,9 @@ def _get_callable_info(callable: Callable) -> tuple[str, str]: def _deprecation_text_component( - since: str | None, - until: str | None, - message: str, + since: str | None = None, + until: str | None = None, + message: str | None = None, ) -> str: """Generates a text component used in deprecation messages. @@ -68,13 +70,37 @@ def _deprecation_text_component( return f"deprecated {since}and {until}.{msg}" +# TODO: Use ParamSpec to type decorated functions when Python 3.9 is out of life +T = TypeVar("T") + + +@overload +def deprecated( + func: Callable[..., T], + since: str | None = None, + until: str | None = None, + replacement: str | None = None, + message: str | None = "", +) -> Callable[..., T]: ... + + +@overload +def deprecated( + func: None = None, + since: str | None = None, + until: str | None = None, + replacement: str | None = None, + message: str | None = "", +) -> Callable[[Callable[..., T]], Callable[..., T]]: ... + + def deprecated( - func: Callable = None, + func: Callable[..., T] | None = None, since: str | None = None, until: str | None = None, replacement: str | None = None, message: str | None = "", -) -> Callable: +) -> Callable[..., T] | Callable[[Callable[..., T]], Callable[..., T]]: """Decorator to mark a callable as deprecated. The decorated callable will cause a warning when used. The docstring of the @@ -104,10 +130,12 @@ def deprecated( from manim.utils.deprecation import deprecated + @deprecated def foo(**kwargs): pass + @deprecated class Bar: def __init__(self): @@ -117,6 +145,7 @@ def __init__(self): def baz(self): pass + foo() # WARNING The function foo has been deprecated and may be removed in a later version. @@ -130,15 +159,14 @@ def baz(self): from manim.utils.deprecation import deprecated + @deprecated( - since="v0.2", - until="v0.4", - replacement="bar", - message="It is cooler." + since="v0.2", until="v0.4", replacement="bar", message="It is cooler." ) def foo(): pass + foo() # WARNING The function foo has been deprecated since v0.2 and is expected to be removed after v0.4. Use bar instead. It is cooler. @@ -146,10 +174,12 @@ def foo(): from manim.utils.deprecation import deprecated + @deprecated(since="05/01/2021", until="06/01/2021") def foo(): pass + foo() # WARNING The function foo has been deprecated since 05/01/2021 and is expected to be removed after 06/01/2021. @@ -183,7 +213,7 @@ def warning_msg(for_docs: bool = False) -> str: deprecated = _deprecation_text_component(since, until, msg) return f"The {what} {name} has been {deprecated}" - def deprecate_docs(func: Callable): + def deprecate_docs(func: Callable) -> None: """Adjust docstring to indicate the deprecation. Parameters @@ -193,9 +223,9 @@ def deprecate_docs(func: Callable): """ warning = warning_msg(True) doc_string = func.__doc__ or "" - func.__doc__ = f"{doc_string}\n\n.. admonition:: Deprecated\n :class: attention\n\n {warning}" + func.__doc__ = f"{doc_string}\n\n.. attention:: Deprecated\n {warning}" - def deprecate(func: Callable, *args, **kwargs): + def deprecate(func: Callable[..., T], *args: Any, **kwargs: Any) -> T: """The actual decorator used to extend the callables behavior. Logs a warning message. @@ -220,7 +250,10 @@ def deprecate(func: Callable, *args, **kwargs): if type(func).__name__ != "function": deprecate_docs(func) - func.__init__ = decorate(func.__init__, deprecate) + # The following line raises this mypy error: + # Accessing "__init__" on an instance is unsound, since instance.__init__ + # could be from an incompatible subclass [misc] + func.__init__ = decorate(func.__init__, deprecate) # type: ignore[misc] return func func = decorate(func, deprecate) @@ -232,10 +265,10 @@ def deprecated_params( params: str | Iterable[str] | None = None, since: str | None = None, until: str | None = None, - message: str | None = "", + message: str = "", redirections: None | (Iterable[tuple[str, str] | Callable[..., dict[str, Any]]]) = None, -) -> Callable: +) -> Callable[..., T]: """Decorator to mark parameters of a callable as deprecated. It can also be used to automatically redirect deprecated parameter values to their @@ -285,10 +318,12 @@ def deprecated_params( from manim.utils.deprecation import deprecated_params + @deprecated_params(params="a, b, c") def foo(**kwargs): pass + foo(x=2, y=3, z=4) # No warning @@ -299,15 +334,17 @@ def foo(**kwargs): from manim.utils.deprecation import deprecated_params + @deprecated_params( params="a, b, c", since="v0.2", until="v0.4", - message="The letters x, y, z are cooler." + message="The letters x, y, z are cooler.", ) def foo(**kwargs): pass + foo(a=2) # WARNING The parameter a of method foo has been deprecated since v0.2 and is expected to be removed after v0.4. The letters x, y, z are cooler. @@ -315,14 +352,18 @@ def foo(**kwargs): from manim.utils.deprecation import deprecated_params - @deprecated_params(redirections=[ - # Two ways to redirect one parameter to another: - ("old_param", "new_param"), - lambda old_param2: {"new_param22": old_param2} - ]) + + @deprecated_params( + redirections=[ + # Two ways to redirect one parameter to another: + ("old_param", "new_param"), + lambda old_param2: {"new_param22": old_param2}, + ] + ) def foo(**kwargs): return kwargs + foo(x=1, old_param=2) # WARNING The parameter old_param of method foo has been deprecated and may be removed in a later version. # returns {"x": 1, "new_param": 2} @@ -331,12 +372,14 @@ def foo(**kwargs): from manim.utils.deprecation import deprecated_params - @deprecated_params(redirections=[ - lambda runtime_in_ms: {"run_time": runtime_in_ms / 1000} - ]) + + @deprecated_params( + redirections=[lambda runtime_in_ms: {"run_time": runtime_in_ms / 1000}] + ) def foo(**kwargs): return kwargs + foo(runtime_in_ms=500) # WARNING The parameter runtime_in_ms of method foo has been deprecated and may be removed in a later version. # returns {"run_time": 0.5} @@ -345,12 +388,14 @@ def foo(**kwargs): from manim.utils.deprecation import deprecated_params - @deprecated_params(redirections=[ - lambda buff_x=1, buff_y=1: {"buff": (buff_x, buff_y)} - ]) + + @deprecated_params( + redirections=[lambda buff_x=1, buff_y=1: {"buff": (buff_x, buff_y)}] + ) def foo(**kwargs): return kwargs + foo(buff_x=2) # WARNING The parameter buff_x of method foo has been deprecated and may be removed in a later version. # returns {"buff": (2, 1)} @@ -359,18 +404,23 @@ def foo(**kwargs): from manim.utils.deprecation import deprecated_params - @deprecated_params(redirections=[ - lambda buff=1: {"buff_x": buff[0], "buff_y": buff[1]} if isinstance(buff, tuple) - else {"buff_x": buff, "buff_y": buff} - ]) + + @deprecated_params( + redirections=[ + lambda buff=1: {"buff_x": buff[0], "buff_y": buff[1]} + if isinstance(buff, tuple) + else {"buff_x": buff, "buff_y": buff} + ] + ) def foo(**kwargs): return kwargs + foo(buff=0) # WARNING The parameter buff of method foo has been deprecated and may be removed in a later version. # returns {"buff_x": 0, buff_y: 0} - foo(buff=(1,2)) + foo(buff=(1, 2)) # WARNING The parameter buff of method foo has been deprecated and may be removed in a later version. # returns {"buff_x": 1, buff_y: 2} @@ -405,7 +455,7 @@ def foo(**kwargs): redirections = list(redirections) - def warning_msg(func: Callable, used: list[str]): + def warning_msg(func: Callable[..., T], used: list[str]) -> str: """Generate the deprecation warning message. Parameters @@ -428,7 +478,7 @@ def warning_msg(func: Callable, used: list[str]): deprecated = _deprecation_text_component(since, until, message) return f"The parameter{parameter_s} {used_} of {what} {name} {has_have_been} {deprecated}" - def redirect_params(kwargs: dict, used: list[str]): + def redirect_params(kwargs: dict[str, Any], used: list[str]) -> None: """Adjust the keyword arguments as defined by the redirections. Parameters @@ -452,7 +502,7 @@ def redirect_params(kwargs: dict, used: list[str]): if len(redirector_args) > 0: kwargs.update(redirector(**redirector_args)) - def deprecate_params(func, *args, **kwargs): + def deprecate_params(func: Callable[..., T], *args: Any, **kwargs: Any) -> T: """The actual decorator function used to extend the callables behavior. Logs a warning message when a deprecated parameter is used and redirects it if @@ -484,4 +534,4 @@ def deprecate_params(func, *args, **kwargs): redirect_params(kwargs, used) return func(*args, **kwargs) - return decorator(deprecate_params) + return decorator(deprecate_params) # type: ignore[return-value] diff --git a/manim/utils/docbuild/__init__.py b/manim/utils/docbuild/__init__.py new file mode 100644 index 0000000000..dee15b8283 --- /dev/null +++ b/manim/utils/docbuild/__init__.py @@ -0,0 +1,17 @@ +"""Utilities for building the Manim documentation. + +For more information about the Manim documentation building, see: + +- :doc:`/contributing/development`, specifically the ``Documentation`` + bullet point under :ref:`polishing-changes-and-submitting-a-pull-request` +- :doc:`/contributing/docs` + +.. autosummary:: + :toctree: ../reference + + autoaliasattr_directive + autocolor_directive + manim_directive + module_parsing + +""" diff --git a/manim/utils/docbuild/autoaliasattr_directive.py b/manim/utils/docbuild/autoaliasattr_directive.py new file mode 100644 index 0000000000..76ef5a0a18 --- /dev/null +++ b/manim/utils/docbuild/autoaliasattr_directive.py @@ -0,0 +1,234 @@ +"""A directive for documenting type aliases and other module-level attributes.""" + +from __future__ import annotations + +from typing import TYPE_CHECKING + +from docutils import nodes +from docutils.parsers.rst import Directive +from docutils.statemachine import ViewList + +from manim.utils.docbuild.module_parsing import parse_module_attributes + +if TYPE_CHECKING: + from sphinx.application import Sphinx + +__all__ = ["AliasAttrDocumenter"] + + +ALIAS_DOCS_DICT, DATA_DICT, TYPEVAR_DICT = parse_module_attributes() +ALIAS_LIST = [ + alias_name + for module_dict in ALIAS_DOCS_DICT.values() + for category_dict in module_dict.values() + for alias_name in category_dict +] + + +def smart_replace(base: str, alias: str, substitution: str) -> str: + """Auxiliary function for substituting type aliases into a base + string, when there are overlaps between the aliases themselves. + + Parameters + ---------- + base + The string in which the type aliases will be located and + replaced. + alias + The substring to be substituted. + substitution + The string which will replace every occurrence of ``alias``. + + Returns + ------- + str + The new string after the alias substitution. + """ + occurrences = [] + len_alias = len(alias) + len_base = len(base) + + def condition(char: str) -> bool: + return not char.isalnum() and char != "_" + + start = 0 + i = 0 + while True: + i = base.find(alias, start) + if i == -1: + break + if (i == 0 or condition(base[i - 1])) and ( + i + len_alias == len_base or condition(base[i + len_alias]) + ): + occurrences.append(i) + start = i + len_alias + + for o in occurrences[::-1]: + base = base[:o] + substitution + base[o + len_alias :] + + return base + + +def setup(app: Sphinx) -> None: + app.add_directive("autoaliasattr", AliasAttrDocumenter) + + +class AliasAttrDocumenter(Directive): + """Directive which replaces Sphinx's Autosummary for module-level + attributes: instead, it manually crafts a new "Type Aliases" + section, where all the module-level attributes which are explicitly + annotated as :class:`TypeAlias` are considered as such, for their + use all around the Manim docs. + + These type aliases are separated from the "regular" module-level + attributes, which get their traditional "Module Attributes" + section autogenerated with Sphinx's Autosummary under "Type + Aliases". + + See ``docs/source/_templates/autosummary/module.rst`` to watch + this directive in action. + + See :func:`~.parse_module_attributes` for more information on how + the modules are parsed to obtain the :class:`TypeAlias` information + and separate it from the other attributes. + """ + + objtype = "autoaliasattr" + required_arguments = 1 + has_content = True + + def run(self) -> list[nodes.Element]: + module_name = self.arguments[0] + # not present in the keys of the DICTs + module_name = module_name.removeprefix("manim.") + module_alias_dict = ALIAS_DOCS_DICT.get(module_name, None) + module_attrs_list = DATA_DICT.get(module_name, None) + module_typevars = TYPEVAR_DICT.get(module_name, None) + + content = nodes.container() + + # Add "Type Aliases" section + if module_alias_dict is not None: + module_alias_section = nodes.section(ids=[f"{module_name}.alias"]) + content += module_alias_section + + # Use a rubric (title-like), just like in `module.rst` + module_alias_section += nodes.rubric(text="Type Aliases") + + # category_name: str + # category_dict: AliasCategoryDict = dict[str, AliasInfo] + for category_name, category_dict in module_alias_dict.items(): + category_section = nodes.section( + ids=[category_name.lower().replace(" ", "_")] + ) + module_alias_section += category_section + # category_name can be possibly "" for uncategorized aliases + if category_name: + category_section += nodes.title(text=category_name) + + category_alias_container = nodes.container() + category_section += category_alias_container + + # alias_name: str + # alias_info: AliasInfo = dict[str, str] + # Contains "definition": str + # Can possibly contain "doc": str + for alias_name, alias_info in category_dict.items(): + # Replace all occurrences of type aliases in the + # definition for automatic cross-referencing! + alias_def = alias_info["definition"] + for A in ALIAS_LIST: + alias_def = smart_replace(alias_def, A, f":class:`~.{A}`") + + # Using the `.. class::` directive is CRUCIAL, since + # function/method parameters are always annotated via + # classes - therefore Sphinx expects a class + unparsed = ViewList( + [ + f".. class:: {alias_name}", + "", + " .. parsed-literal::", + "", + f" {alias_def}", + "", + ] + ) + + if "doc" in alias_info: + # Replace all occurrences of type aliases in + # the docs for automatic cross-referencing! + alias_doc = alias_info["doc"] + for A in ALIAS_LIST: + alias_doc = alias_doc.replace(f"`{A}`", f":class:`~.{A}`") + + # also hyperlink the TypeVars from that module + if module_typevars is not None: + for T in module_typevars: + alias_doc = alias_doc.replace(f"`{T}`", f":class:`{T}`") + + # Add all the lines with 4 spaces behind, to consider all the + # documentation as a paragraph INSIDE the `.. class::` block + doc_lines = alias_doc.split("\n") + unparsed.extend(ViewList([f" {line}" for line in doc_lines])) + + # Parse the reST text into a fresh container + # https://www.sphinx-doc.org/en/master/extdev/markupapi.html#parsing-directive-content-as-rest + alias_container = nodes.container() + self.state.nested_parse(unparsed, 0, alias_container) + category_alias_container += alias_container + + # then add the module TypeVars section + if module_typevars is not None: + module_typevars_section = nodes.section(ids=[f"{module_name}.typevars"]) + content += module_typevars_section + + # Use a rubric (title-like), just like in `module.rst` + module_typevars_section += nodes.rubric(text="TypeVar's") + + # name: str + # definition: TypeVarDict = dict[str, str] + for name, definition in module_typevars.items(): + # Using the `.. class::` directive is CRUCIAL, since + # function/method parameters are always annotated via + # classes - therefore Sphinx expects a class + unparsed = ViewList( + [ + f".. class:: {name}", + "", + " .. parsed-literal::", + "", + f" {definition}", + "", + ] + ) + + # Parse the reST text into a fresh container + # https://www.sphinx-doc.org/en/master/extdev/markupapi.html#parsing-directive-content-as-rest + typevar_container = nodes.container() + self.state.nested_parse(unparsed, 0, typevar_container) + module_typevars_section += typevar_container + + # Then, add the traditional "Module Attributes" section + if module_attrs_list is not None: + module_attrs_section = nodes.section(ids=[f"{module_name}.data"]) + content += module_attrs_section + + # Use the same rubric (title-like) as in `module.rst` + module_attrs_section += nodes.rubric(text="Module Attributes") + # Let Sphinx Autosummary do its thing as always + # Add all the attribute names with 4 spaces behind, so that + # they're considered as INSIDE the `.. autosummary::` block + unparsed = ViewList( + [ + ".. autosummary::", + *(f" {attr}" for attr in module_attrs_list), + ] + ) + + # Parse the reST text into a fresh container + # https://www.sphinx-doc.org/en/master/extdev/markupapi.html#parsing-directive-content-as-rest + data_container = nodes.container() + self.state.nested_parse(unparsed, 0, data_container) + module_attrs_section += data_container + + return [content] diff --git a/manim/utils/docbuild/autocolor_directive.py b/manim/utils/docbuild/autocolor_directive.py new file mode 100644 index 0000000000..476dcb1326 --- /dev/null +++ b/manim/utils/docbuild/autocolor_directive.py @@ -0,0 +1,96 @@ +"""A directive for documenting colors in Manim.""" + +from __future__ import annotations + +import inspect +from typing import TYPE_CHECKING + +from docutils import nodes +from docutils.parsers.rst import Directive + +from manim import ManimColor + +if TYPE_CHECKING: + from sphinx.application import Sphinx + +__all__ = ["ManimColorModuleDocumenter"] + + +def setup(app: Sphinx) -> None: + app.add_directive("automanimcolormodule", ManimColorModuleDocumenter) + + +class ManimColorModuleDocumenter(Directive): + objtype = "automanimcolormodule" + required_arguments = 1 + has_content = True + + def add_directive_header(self, sig: str) -> None: + # TODO: The Directive class has no method named + # add_directive_header. + super().add_directive_header(sig) # type: ignore[misc] + + def run(self) -> list[nodes.Element]: + module_name = self.arguments[0] + try: + import importlib + + module = importlib.import_module(module_name) + except ImportError: + return [ + nodes.error( + None, # type: ignore[arg-type] + nodes.paragraph(text=f"Failed to import module '{module_name}'"), + ) + ] + + # Number of Colors displayed in one row + num_color_cols = 2 + table = nodes.table(align="center") + + tgroup = nodes.tgroup(cols=num_color_cols * 2) + table += tgroup + for _ in range(num_color_cols * 2): + tgroup += nodes.colspec(colwidth=1) + + # Create header rows for the table + thead = nodes.thead() + header_row = nodes.row() + for _ in range(num_color_cols): + header_col1 = nodes.paragraph(text="Color Name") + header_col2 = nodes.paragraph(text="RGB Hex Code") + header_row += nodes.entry("", header_col1) + header_row += nodes.entry("", header_col2) + thead += header_row + tgroup += thead + + color_elements = [] + for member_name, member_obj in inspect.getmembers(module): + if isinstance(member_obj, ManimColor): + r, g, b = member_obj.to_rgb() + luminance = 0.2126 * r + 0.7152 * g + 0.0722 * b + + # Choose the font color based on the background luminance + font_color = "black" if luminance > 0.5 else "white" + + color_elements.append((member_name, member_obj.to_hex(), font_color)) + + tbody = nodes.tbody() + + for base_i in range(0, len(color_elements), num_color_cols): + row = nodes.row() + for member_name, hex_code, font_color in color_elements[ + base_i : base_i + num_color_cols + ]: + col1 = nodes.literal(text=member_name) + col2 = nodes.raw( + "", + f'
{hex_code}
', + format="html", + ) + row += nodes.entry("", col1) + row += nodes.entry("", col2) + tbody += row + tgroup += tbody + + return [table] diff --git a/manim/utils/docbuild/manim_directive.py b/manim/utils/docbuild/manim_directive.py index 155e475c5b..b94b7386c9 100644 --- a/manim/utils/docbuild/manim_directive.py +++ b/manim/utils/docbuild/manim_directive.py @@ -26,7 +26,7 @@ def construct(self): >>> from manim import Create, Dot, RED, Scene >>> dot = Dot(color=RED) >>> dot.color - + ManimColor('#FC6255') >>> class DirectiveDoctestExample(Scene): ... def construct(self): ... self.play(Create(dot)) @@ -47,6 +47,10 @@ def construct(self): If this flag is present without argument, the source code is not displayed above the rendered video. + no_autoplay + If this flag is present without argument, + the video will not autoplay. + quality : {'low', 'medium', 'high', 'fourk'} Controls render quality of the video, in analogy to the corresponding command line flags. @@ -73,37 +77,62 @@ def construct(self): that is rendered in a reference block after the source code. """ + from __future__ import annotations import csv import itertools as it -import os import re import shutil import sys +import textwrap from pathlib import Path from timeit import timeit +from typing import TYPE_CHECKING, Any, TypedDict import jinja2 from docutils import nodes -from docutils.parsers.rst import Directive, directives # type: ignore +from docutils.parsers.rst import Directive, directives from docutils.statemachine import StringList from manim import QUALITIES +from manim import __version__ as manim_version + +if TYPE_CHECKING: + from sphinx.application import Sphinx + + +__all__ = ["ManimDirective"] + -classnamedict = {} +classnamedict: dict[str, int] = {} -class skip_manim_node(nodes.Admonition, nodes.Element): +class SetupMetadata(TypedDict): + parallel_read_safe: bool + parallel_write_safe: bool + + +class SkipManimNode(nodes.Admonition, nodes.Element): + """Auxiliary node class that is used when the ``skip-manim`` tag is present + or ``.pot`` files are being built. + + Skips rendering the manim directive and outputs a placeholder instead. + """ + pass -def visit(self, node, name=""): - self.visit_admonition(node, name) +def visit(self: SkipManimNode, node: nodes.Element, name: str = "") -> None: + # TODO: Parent classes don't have a visit_admonition() method. + self.visit_admonition(node, name) # type: ignore[attr-defined] + if not isinstance(node[0], nodes.title): + node.insert(0, nodes.title("skip-manim", "Example Placeholder")) -def depart(self, node): - self.depart_admonition(node) +def depart(self: SkipManimNode, node: nodes.Element) -> None: + # TODO: Parent classes don't have a depart_admonition() method. + self.depart_admonition(node) # type: ignore[attr-defined] def process_name_list(option_input: str, reference_type: str) -> list[str]: @@ -129,11 +158,13 @@ class ManimDirective(Directive): See the module docstring for documentation. """ + has_content = True required_arguments = 1 optional_arguments = 0 option_spec = { "hide_source": bool, + "no_autoplay": bool, "quality": lambda arg: directives.choice( arg, ("low", "medium", "high", "fourk"), @@ -147,20 +178,34 @@ class ManimDirective(Directive): } final_argument_whitespace = True - def run(self): - # Render is skipped if the tag skip-manim is present + def run(self) -> list[nodes.Element]: + # Rendering is skipped if the tag skip-manim is present, + # or if we are making the pot-files should_skip = ( - "skip-manim" in self.state.document.settings.env.app.builder.tags.tags - ) - # Or if we are making the pot-files - should_skip = ( - should_skip + "skip-manim" in self.state.document.settings.env.app.builder.tags or self.state.document.settings.env.app.builder.name == "gettext" ) if should_skip: - node = skip_manim_node() + clsname = self.arguments[0] + node = SkipManimNode() self.state.nested_parse( - StringList(self.content[0]), + StringList( + [ + f"Placeholder block for ``{clsname}``.", + "", + ".. code-block:: python", + "", + ] + + [" " + line for line in self.content] + + [ + "", + ".. raw:: html", + "", + f'
',
+                    ]
+                    + ["    " + line for line in self.content]
+                    + ["    
"], + ), self.content_offset, node, ) @@ -177,6 +222,7 @@ def run(self): classnamedict[clsname] += 1 hide_source = "hide_source" in self.options + no_autoplay = "no_autoplay" in self.options save_as_gif = "save_as_gif" in self.options save_last_frame = "save_last_frame" in self.options assert not (save_as_gif and save_last_frame) @@ -187,14 +233,10 @@ def run(self): + self.options.get("ref_functions", []) + self.options.get("ref_methods", []) ) - if ref_content: - ref_block = "References: " + " ".join(ref_content) - - else: - ref_block = "" + ref_block = "References: " + " ".join(ref_content) if ref_content else "" if "quality" in self.options: - quality = f'{self.options["quality"]}_quality' + quality = f"{self.options['quality']}_quality" else: quality = "example_quality" frame_rate = QUALITIES[quality]["frame_rate"] @@ -205,30 +247,38 @@ def run(self): document = state_machine.document source_file_name = Path(document.attributes["source"]) - source_rel_name = source_file_name.relative_to(setup.confdir) + source_rel_name = source_file_name.relative_to(setup.confdir) # type: ignore[attr-defined] source_rel_dir = source_rel_name.parents[0] - dest_dir = Path(setup.app.builder.outdir, source_rel_dir).absolute() + dest_dir = Path(setup.app.builder.outdir, source_rel_dir).absolute() # type: ignore[attr-defined] if not dest_dir.exists(): dest_dir.mkdir(parents=True, exist_ok=True) - source_block = [ + source_block_in = [ ".. code-block:: python", "", " from manim import *\n", *(" " + line for line in self.content), + "", + ".. raw:: html", + "", + f'
',
+            *("    " + line for line in self.content),
+            "",
+            "    
", ] - source_block = "\n".join(source_block) + source_block = "\n".join(source_block_in) - config.media_dir = (Path(setup.confdir) / "media").absolute() + config.media_dir = (Path(setup.confdir) / "media").absolute() # type: ignore[attr-defined,assignment] config.images_dir = "{media_dir}/images" config.video_dir = "{media_dir}/videos/{quality}" output_file = f"{clsname}-{classnamedict[clsname]}" - config.assets_dir = Path("_static") + config.assets_dir = Path("_static") # type: ignore[assignment] config.progress_bar = "none" config.verbosity = "WARNING" example_config = { "frame_rate": frame_rate, + "no_autoplay": no_autoplay, "pixel_height": pixel_height, "pixel_width": pixel_width, "save_last_frame": save_last_frame, @@ -240,7 +290,7 @@ def run(self): if save_as_gif: example_config["format"] = "gif" - user_code = self.content + user_code = list(self.content) if user_code[0].startswith(">>> "): # check whether block comes from doctest user_code = [ line[4:] for line in user_code if line.startswith((">>> ", "... ")) @@ -252,10 +302,13 @@ def run(self): f"{clsname}().render()", ] - with tempconfig(example_config): - run_time = timeit(lambda: exec("\n".join(code), globals()), number=1) - video_dir = config.get_dir("video_dir") - images_dir = config.get_dir("images_dir") + try: + with tempconfig(example_config): + run_time = timeit(lambda: exec("\n".join(code), globals()), number=1) + video_dir = config.get_dir("video_dir") + images_dir = config.get_dir("images_dir") + except Exception as e: + raise RuntimeError(f"Error while rendering example {clsname}") from e _write_rendering_stats( clsname, @@ -281,7 +334,8 @@ def run(self): clsname=clsname, clsname_lowercase=clsname.lower(), hide_source=hide_source, - filesrc_rel=Path(filesrc).relative_to(setup.confdir).as_posix(), + filesrc_rel=Path(filesrc).relative_to(setup.confdir).as_posix(), # type: ignore[attr-defined] + no_autoplay=no_autoplay, output_file=output_file, save_last_frame=save_last_frame, save_as_gif=save_as_gif, @@ -299,61 +353,77 @@ def run(self): rendering_times_file_path = Path("../rendering_times.csv") -def _write_rendering_stats(scene_name, run_time, file_name): - with open(rendering_times_file_path, "a") as file: +def _write_rendering_stats(scene_name: str, run_time: float, file_name: str) -> None: + with rendering_times_file_path.open("a") as file: csv.writer(file).writerow( [ re.sub(r"^(reference\/)|(manim\.)", "", file_name), scene_name, - "%.3f" % run_time, + f"{run_time:.3f}", ], ) -def _log_rendering_times(*args): +def _log_rendering_times(*args: tuple[Any]) -> None: if rendering_times_file_path.exists(): - with open(rendering_times_file_path) as file: + with rendering_times_file_path.open() as file: data = list(csv.reader(file)) - if len(data) == 0: - sys.exit() - - print("\nRendering Summary\n-----------------\n") - - max_file_length = max(len(row[0]) for row in data) - for key, group in it.groupby(data, key=lambda row: row[0]): - key = key.ljust(max_file_length + 1, ".") - group = list(group) - if len(group) == 1: - row = group[0] - print(f"{key}{row[2].rjust(7, '.')}s {row[1]}") - continue - time_sum = sum(float(row[2]) for row in group) - print( - f"{key}{f'{time_sum:.3f}'.rjust(7, '.')}s => {len(group)} EXAMPLES", - ) - for row in group: - print(f"{' '*(max_file_length)} {row[2].rjust(7)}s {row[1]}") + if len(data) == 0: + sys.exit() + + print("\nRendering Summary\n-----------------\n") + + # filter out empty lists caused by csv reader + data = [row for row in data if row] + + max_file_length = max(len(row[0]) for row in data) + for key, group_iter in it.groupby(data, key=lambda row: row[0]): + key = key.ljust(max_file_length + 1, ".") + group = list(group_iter) + if len(group) == 1: + row = group[0] + print(f"{key}{row[2].rjust(7, '.')}s {row[1]}") + continue + time_sum = sum(float(row[2]) for row in group) + print( + f"{key}{f'{time_sum:.3f}'.rjust(7, '.')}s => {len(group)} EXAMPLES", + ) + for row in group: + print(f"{' ' * max_file_length} {row[2].rjust(7)}s {row[1]}") print("") -def _delete_rendering_times(*args): +def _delete_rendering_times(*args: tuple[Any]) -> None: if rendering_times_file_path.exists(): - os.remove(rendering_times_file_path) + rendering_times_file_path.unlink() -def setup(app): - app.add_node(skip_manim_node, html=(visit, depart)) +def setup(app: Sphinx) -> SetupMetadata: + app.add_node(SkipManimNode, html=(visit, depart)) - setup.app = app - setup.config = app.config - setup.confdir = app.confdir + setup.app = app # type: ignore[attr-defined] + setup.config = app.config # type: ignore[attr-defined] + setup.confdir = app.confdir # type: ignore[attr-defined] app.add_directive("manim", ManimDirective) app.connect("builder-inited", _delete_rendering_times) app.connect("build-finished", _log_rendering_times) - metadata = {"parallel_read_safe": False, "parallel_write_safe": True} + app.add_js_file("manim-binder.min.js") + app.add_js_file( + None, + body=textwrap.dedent( + f"""\ + window.initManimBinder({{branch: "v{manim_version}"}}) + """ + ).strip(), + ) + + metadata: SetupMetadata = { + "parallel_read_safe": False, + "parallel_write_safe": True, + } return metadata @@ -369,7 +439,13 @@ def setup(app): {% if not (save_as_gif or save_last_frame) %} .. raw:: html - + {% elif save_as_gif %} .. image:: /{{ filesrc_rel }} @@ -385,9 +461,9 @@ def setup(app): {{ ref_block }} -{% endif %} - .. raw:: html + +{% endif %} """ diff --git a/manim/utils/docbuild/module_parsing.py b/manim/utils/docbuild/module_parsing.py new file mode 100644 index 0000000000..78769eb565 --- /dev/null +++ b/manim/utils/docbuild/module_parsing.py @@ -0,0 +1,245 @@ +"""Read and parse all the Manim modules and extract documentation from them.""" + +from __future__ import annotations + +import ast +import sys +from ast import Attribute, Name, Subscript +from pathlib import Path +from typing import Any + +from typing_extensions import TypeAlias + +__all__ = ["parse_module_attributes"] + + +AliasInfo: TypeAlias = dict[str, str] +"""Dictionary with a `definition` key containing the definition of +a :class:`TypeAlias` as a string, and optionally a `doc` key containing +the documentation for that alias, if it exists. +""" + +AliasCategoryDict: TypeAlias = dict[str, AliasInfo] +"""Dictionary which holds an `AliasInfo` for every alias name in a same +category. +""" + +ModuleLevelAliasDict: TypeAlias = dict[str, AliasCategoryDict] +"""Dictionary containing every :class:`TypeAlias` defined in a module, +classified by category in different `AliasCategoryDict` objects. +""" + +ModuleTypeVarDict: TypeAlias = dict[str, str] +"""Dictionary containing every :class:`TypeVar` defined in a module.""" + + +AliasDocsDict: TypeAlias = dict[str, ModuleLevelAliasDict] +"""Dictionary which, for every module in Manim, contains documentation +about their module-level attributes which are explicitly defined as +:class:`TypeAlias`, separating them from the rest of attributes. +""" + +DataDict: TypeAlias = dict[str, list[str]] +"""Type for a dictionary which, for every module, contains a list with +the names of all their DOCUMENTED module-level attributes (identified +by Sphinx via the ``data`` role, hence the name) which are NOT +explicitly defined as :class:`TypeAlias`. +""" + +TypeVarDict: TypeAlias = dict[str, ModuleTypeVarDict] +"""A dictionary mapping module names to dictionaries of :class:`TypeVar` objects.""" + +ALIAS_DOCS_DICT: AliasDocsDict = {} +DATA_DICT: DataDict = {} +TYPEVAR_DICT: TypeVarDict = {} + +MANIM_ROOT = Path(__file__).resolve().parent.parent.parent + +# In the following, we will use ``type(xyz) is xyz_type`` instead of +# isinstance checks to make sure no subclasses of the type pass the +# check +# ruff: noqa: E721 + + +def parse_module_attributes() -> tuple[AliasDocsDict, DataDict, TypeVarDict]: + """Read all files, generate Abstract Syntax Trees from them, and + extract useful information about the type aliases defined in the + files: the category they belong to, their definition and their + description, separating them from the "regular" module attributes. + + Returns + ------- + ALIAS_DOCS_DICT : :class:`AliasDocsDict` + A dictionary containing the information from all the type + aliases in Manim. See :class:`AliasDocsDict` for more information. + + DATA_DICT : :class:`DataDict` + A dictionary containing the names of all DOCUMENTED + module-level attributes which are not a :class:`TypeAlias`. + + TYPEVAR_DICT : :class:`TypeVarDict` + A dictionary containing the definitions of :class:`TypeVar` objects, + organized by modules. + """ + global ALIAS_DOCS_DICT + global DATA_DICT + global TYPEVAR_DICT + + if ALIAS_DOCS_DICT or DATA_DICT or TYPEVAR_DICT: + return ALIAS_DOCS_DICT, DATA_DICT, TYPEVAR_DICT + + for module_path in MANIM_ROOT.rglob("*.py"): + module_name_t1 = module_path.resolve().relative_to(MANIM_ROOT) + module_name_t2 = list(module_name_t1.parts) + module_name_t2[-1] = module_name_t2[-1].removesuffix(".py") + module_name = ".".join(module_name_t2) + + module_content = module_path.read_text(encoding="utf-8") + + # For storing TypeAliases + module_dict: ModuleLevelAliasDict = {} + category_dict: AliasCategoryDict | None = None + alias_info: AliasInfo | None = None + + # For storing TypeVars + module_typevars: ModuleTypeVarDict = {} + + # For storing regular module attributes + data_list: list[str] = [] + data_name: str | None = None + + for node in ast.iter_child_nodes(ast.parse(module_content)): + # If we encounter a string: + if ( + type(node) is ast.Expr + and type(node.value) is ast.Constant + and type(node.value.value) is str + ): + string = node.value.value.strip() + # It can be the start of a category + section_str = "[CATEGORY]" + if string.startswith(section_str): + category_name = string[len(section_str) :].strip() + module_dict[category_name] = {} + category_dict = module_dict[category_name] + alias_info = None + # or a docstring of the alias defined before + elif alias_info: + alias_info["doc"] = string + # or a docstring of the module attribute defined before + elif data_name: + data_list.append(data_name) + continue + + # if it's defined under if TYPE_CHECKING + # go through the body of the if statement + if ( + # NOTE: This logic does not (and cannot) + # check if the comparison is against a + # variable called TYPE_CHECKING + # It also says that you cannot do the following + # import typing as foo + # if foo.TYPE_CHECKING: + # BAR: TypeAlias = ... + type(node) is ast.If + and ( + ( + # if TYPE_CHECKING + type(node.test) is ast.Name and node.test.id == "TYPE_CHECKING" + ) + or ( + # if typing.TYPE_CHECKING + type(node.test) is ast.Attribute + and type(node.test.value) is ast.Name + and node.test.value.id == "typing" + and node.test.attr == "TYPE_CHECKING" + ) + ) + ): + inner_nodes: list[Any] = node.body + else: + inner_nodes = [node] + + for node in inner_nodes: + # Check if this node is a TypeAlias (type = ) + # or an AnnAssign annotated as TypeAlias (: TypeAlias = ). + is_type_alias = ( + sys.version_info >= (3, 12) and type(node) is ast.TypeAlias + ) + is_annotated_assignment_with_value = ( + type(node) is ast.AnnAssign + and type(node.annotation) is ast.Name + and node.annotation.id == "TypeAlias" + and type(node.target) is ast.Name + and node.value is not None + ) + if is_type_alias or is_annotated_assignment_with_value: + # TODO: ast.TypeAlias does not exist before Python 3.12, and that + # could be the reason why MyPy does not recognize these as + # attributes of node. + alias_name = node.name.id if is_type_alias else node.target.id # type: ignore[attr-defined] + definition_node = node.value # type: ignore[attr-defined] + + # If the definition is a Union, replace with vertical bar notation. + # Instead of "Union[Type1, Type2]", we'll have "Type1 | Type2". + if ( + type(definition_node) is ast.Subscript + and type(definition_node.value) is ast.Name + and definition_node.value.id == "Union" + ): + union_elements = definition_node.slice.elts # type: ignore[attr-defined] + definition = " | ".join( + ast.unparse(elem) for elem in union_elements + ) + else: + definition = ast.unparse(definition_node) + + definition = definition.replace("npt.", "") + if category_dict is None: + module_dict[""] = {} + category_dict = module_dict[""] + category_dict[alias_name] = {"definition": definition} + alias_info = category_dict[alias_name] + continue + + # Check if it is a typing.TypeVar ( = TypeVar(...)). + elif ( + type(node) is ast.Assign + and type(node.targets[0]) is ast.Name + and type(node.value) is ast.Call + and type(node.value.func) is ast.Name + and node.value.func.id.endswith("TypeVar") + ): + module_typevars[node.targets[0].id] = ast.unparse( + node.value + ).replace("_", r"\_") + continue + + # If here, the node is not a TypeAlias definition + alias_info = None + + # It could still be a module attribute definition. + # Does the assignment have a target of type Name? Then + # it could be considered a definition of a module attribute. + if type(node) is ast.AnnAssign: + target: Name | Attribute | Subscript | ast.expr | None = node.target + elif type(node) is ast.Assign and len(node.targets) == 1: + target = node.targets[0] + else: + target = None + + if type(target) is ast.Name and not ( + type(node) is ast.Assign and target.id not in module_typevars + ): + data_name = target.id + else: + data_name = None + + if len(module_dict) > 0: + ALIAS_DOCS_DICT[module_name] = module_dict + if len(data_list) > 0: + DATA_DICT[module_name] = data_list + if module_typevars: + TYPEVAR_DICT[module_name] = module_typevars + + return ALIAS_DOCS_DICT, DATA_DICT, TYPEVAR_DICT diff --git a/manim/utils/exceptions.py b/manim/utils/exceptions.py index a7cc7f5676..c1c2f8f951 100644 --- a/manim/utils/exceptions.py +++ b/manim/utils/exceptions.py @@ -1,5 +1,11 @@ from __future__ import annotations +__all__ = [ + "EndSceneEarlyException", + "RerunSceneException", + "MultiAnimationOverrideException", +] + class EndSceneEarlyException(Exception): pass diff --git a/manim/utils/family.py b/manim/utils/family.py index d4f31fbb32..89c93d5eb4 100644 --- a/manim/utils/family.py +++ b/manim/utils/family.py @@ -1,25 +1,28 @@ from __future__ import annotations import itertools as it +from collections.abc import Iterable from ..mobject.mobject import Mobject from ..utils.iterables import remove_list_redundancies +__all__ = ["extract_mobject_family_members"] + def extract_mobject_family_members( - mobjects, - use_z_index=False, - only_those_with_points=False, -): + mobjects: Iterable[Mobject], + use_z_index: bool = False, + only_those_with_points: bool = False, +) -> list[Mobject]: """Returns a list of the types of mobjects and their family members present. A "family" in this context refers to a mobject, its submobjects, and their submobjects, recursively. Parameters ---------- - mobjects : Mobject + mobjects The Mobjects currently in the Scene - only_those_with_points : bool, optional + only_those_with_points Whether or not to only do this for those mobjects that have points. By default False diff --git a/manim/utils/family_ops.py b/manim/utils/family_ops.py index 4a47e0591d..e7cf011161 100644 --- a/manim/utils/family_ops.py +++ b/manim/utils/family_ops.py @@ -2,15 +2,26 @@ import itertools as it +from manim.mobject.mobject import Mobject -def extract_mobject_family_members(mobject_list, only_those_with_points=False): +__all__ = [ + "extract_mobject_family_members", + "restructure_list_to_exclude_certain_family_members", +] + + +def extract_mobject_family_members( + mobject_list: list[Mobject], only_those_with_points: bool = False +) -> list[Mobject]: result = list(it.chain(*(mob.get_family() for mob in mobject_list))) if only_those_with_points: result = [mob for mob in result if mob.has_points()] return result -def restructure_list_to_exclude_certain_family_members(mobject_list, to_remove): +def restructure_list_to_exclude_certain_family_members( + mobject_list: list[Mobject], to_remove: list[Mobject] +) -> list[Mobject]: """ Removes anything in to_remove from mobject_list, but in the event that one of the items to be removed is a member of the family of an item in mobject_list, @@ -20,10 +31,12 @@ def restructure_list_to_exclude_certain_family_members(mobject_list, to_remove): but one of its submobjects is removed, e.g. scene.remove(m1), it's useful for the list of mobject_list to be edited to contain other submobjects, but not m1. """ - new_list = [] + new_list: list[Mobject] = [] to_remove = extract_mobject_family_members(to_remove) - def add_safe_mobjects_from_list(list_to_examine, set_to_remove): + def add_safe_mobjects_from_list( + list_to_examine: list[Mobject], set_to_remove: set[Mobject] + ) -> None: for mob in list_to_examine: if mob in set_to_remove: continue diff --git a/manim/utils/file_ops.py b/manim/utils/file_ops.py index b30a8cd1d0..5e239be548 100644 --- a/manim/utils/file_ops.py +++ b/manim/utils/file_ops.py @@ -15,6 +15,7 @@ "is_webm_format", "is_mov_format", "write_to_movie", + "ensure_executable", ] import os @@ -24,6 +25,12 @@ import time from pathlib import Path from shutil import copyfile +from typing import TYPE_CHECKING + +if TYPE_CHECKING: + from manim.typing import StrPath + + from ..scene.scene_file_writer import SceneFileWriter from manim import __version__, config, logger @@ -40,7 +47,8 @@ def is_mp4_format() -> bool: ``True`` if format is set as mp4 """ - return config["format"] == "mp4" + val: bool = config["format"] == "mp4" + return val def is_gif_format() -> bool: @@ -53,7 +61,8 @@ def is_gif_format() -> bool: ``True`` if format is set as gif """ - return config["format"] == "gif" + val: bool = config["format"] == "gif" + return val def is_webm_format() -> bool: @@ -66,7 +75,8 @@ def is_webm_format() -> bool: ``True`` if format is set as webm """ - return config["format"] == "webm" + val: bool = config["format"] == "webm" + return val def is_mov_format() -> bool: @@ -79,7 +89,8 @@ def is_mov_format() -> bool: ``True`` if format is set as mov """ - return config["format"] == "mov" + val: bool = config["format"] == "mov" + return val def is_png_format() -> bool: @@ -92,7 +103,8 @@ def is_png_format() -> bool: ``True`` if format is set as png """ - return config["format"] == "png" + val: bool = config["format"] == "png" + return val def write_to_movie() -> bool: @@ -117,78 +129,96 @@ def write_to_movie() -> bool: ) -def add_extension_if_not_present(file_name, extension): +def ensure_executable(path_to_exe: Path) -> bool: + if path_to_exe.parent == Path("."): + executable: StrPath | None = shutil.which(path_to_exe.stem) + if executable is None: + return False + else: + executable = path_to_exe + return os.access(executable, os.X_OK) + + +def add_extension_if_not_present(file_name: Path, extension: str) -> Path: if file_name.suffix != extension: - return file_name.with_suffix(extension) + return file_name.with_suffix(file_name.suffix + extension) else: return file_name -def add_version_before_extension(file_name): - file_name = Path(file_name) - path, name, suffix = file_name.parent, file_name.stem, file_name.suffix - return Path(path, f"{name}_ManimCE_v{__version__}{suffix}") +def add_version_before_extension(file_name: Path) -> Path: + return file_name.with_name( + f"{file_name.stem}_ManimCE_v{__version__}{file_name.suffix}" + ) -def guarantee_existence(path): - if not os.path.exists(path): - os.makedirs(path) - return os.path.abspath(path) +def guarantee_existence(path: Path) -> Path: + if not path.exists(): + path.mkdir(parents=True) + return path.resolve(strict=True) -def guarantee_empty_existence(path): - if os.path.exists(path): - shutil.rmtree(path) - os.makedirs(path) - return os.path.abspath(path) +def guarantee_empty_existence(path: Path) -> Path: + if path.exists(): + shutil.rmtree(str(path)) + path.mkdir(parents=True) + return path.resolve(strict=True) -def seek_full_path_from_defaults(file_name, default_dir, extensions): - possible_paths = [file_name] +def seek_full_path_from_defaults( + file_name: StrPath, default_dir: Path, extensions: list[str] +) -> Path: + possible_paths = [Path(file_name).expanduser()] possible_paths += [ Path(default_dir) / f"{file_name}{extension}" for extension in ["", *extensions] ] for path in possible_paths: - if os.path.exists(path): + if path.exists(): return path - error = f"From: {os.getcwd()}, could not find {file_name} at either of these locations: {possible_paths}" + error = ( + f"From: {Path.cwd()}, could not find {file_name} at either " + f"of these locations: {list(map(str, possible_paths))}" + ) raise OSError(error) -def modify_atime(file_path): +def modify_atime(file_path: str) -> None: """Will manually change the accessed time (called `atime`) of the file, as on a lot of OS the accessed time refresh is disabled by default. Parameters ---------- - file_path : :class:`str` + file_path The path of the file. """ - os.utime(file_path, times=(time.time(), os.path.getmtime(file_path))) + os.utime(file_path, times=(time.time(), Path(file_path).stat().st_mtime)) -def open_file(file_path, in_browser=False): +def open_file(file_path: Path, in_browser: bool = False) -> None: current_os = platform.system() if current_os == "Windows": - os.startfile(file_path if not in_browser else os.path.dirname(file_path)) + # The method os.startfile is only available in Windows, + # ignoring type error caused by this. + os.startfile(file_path if not in_browser else file_path.parent) # type: ignore[attr-defined] else: if current_os == "Linux": commands = ["xdg-open"] - file_path = file_path if not in_browser else os.path.dirname(file_path) + file_path = file_path if not in_browser else file_path.parent elif current_os.startswith("CYGWIN"): commands = ["cygstart"] - file_path = file_path if not in_browser else os.path.dirname(file_path) + file_path = file_path if not in_browser else file_path.parent elif current_os == "Darwin": - if is_gif_format(): - commands = ["ffplay", "-loglevel", config["ffmpeg_loglevel"].lower()] - else: - commands = ["open"] if not in_browser else ["open", "-R"] + commands = ["open"] if not in_browser else ["open", "-R"] else: raise OSError("Unable to identify your operating system...") - commands.append(file_path) - sp.Popen(commands) + + # check after so that file path is set correctly + if config.preview_command: + commands = [config.preview_command] + commands.append(str(file_path)) + sp.run(commands) -def open_media_file(file_writer): +def open_media_file(file_writer: SceneFileWriter) -> None: file_paths = [] if config["save_last_frame"]: @@ -207,7 +237,7 @@ def open_media_file(file_writer): logger.info(f"Previewed File at: '{file_path}'") -def get_template_names(): +def get_template_names() -> list[str]: """Returns template names from the templates directory. Returns @@ -218,7 +248,7 @@ def get_template_names(): return [template_name.stem for template_name in template_path.glob("*.mtp")] -def get_template_path(): +def get_template_path() -> Path: """Returns the Path of templates directory. Returns @@ -228,28 +258,30 @@ def get_template_path(): return Path.resolve(Path(__file__).parent.parent / "templates") -def add_import_statement(file): +def add_import_statement(file: Path) -> None: """Prepends an import statement in a file Parameters ---------- - file : :class:`Path` + file """ - with open(file, "r+") as f: + with file.open("r+") as f: import_line = "from manim import *" content = f.read() - f.seek(0, 0) - f.write(import_line.rstrip("\r\n") + "\n" + content) + f.seek(0) + f.write(import_line + "\n" + content) -def copy_template_files(project_dir=Path("."), template_name="Default"): +def copy_template_files( + project_dir: Path = Path("."), template_name: str = "Default" +) -> None: """Copies template files from templates dir to project_dir. Parameters ---------- - project_dir : :class:`Path` + project_dir Path to project directory. - template_name : :class:`str` + template_name Name of template. """ template_cfg_path = Path.resolve( diff --git a/manim/utils/hashing.py b/manim/utils/hashing.py index f84f2770d3..ca5d840cf6 100644 --- a/manim/utils/hashing.py +++ b/manim/utils/hashing.py @@ -14,7 +14,16 @@ import numpy as np -from .. import config, logger +from manim._config import config, logger + +if typing.TYPE_CHECKING: + from manim.animation.animation import Animation + from manim.camera.camera import Camera + from manim.mobject.mobject import Mobject + from manim.opengl.opengl_renderer import OpenGLCamera + from manim.scene.scene import Scene + +__all__ = ["KEYS_TO_FILTER_OUT", "get_hash_from_play_call", "get_json"] # Sometimes there are elements that are not suitable for hashing (too long or # run-dependent). This is used to filter them out. @@ -50,14 +59,14 @@ def reset_already_processed(cls): cls._already_processed.clear() @classmethod - def check_already_processed_decorator(cls: _Memoizer, is_method=False): + def check_already_processed_decorator(cls: _Memoizer, is_method: bool = False): """Decorator to handle the arguments that goes through the decorated function. Returns _ALREADY_PROCESSED_PLACEHOLDER if the obj has been processed, or lets the decorated function call go ahead. Parameters ---------- - is_method : bool, optional + is_method Whether the function passed is a method, by default False. """ @@ -81,7 +90,7 @@ def check_already_processed(cls, obj: Any) -> Any: Parameters ---------- - obj : Any + obj The object to check. Returns @@ -98,7 +107,7 @@ def mark_as_processed(cls, obj: Any) -> None: Parameters ---------- - obj : Any + obj The object to mark as processed. """ cls._handle_already_processed(obj, lambda x: x) @@ -164,7 +173,7 @@ def _return( class _CustomEncoder(json.JSONEncoder): - def default(self, obj): + def default(self, obj: Any): """ This method is used to serialize objects to JSON format. @@ -178,7 +187,7 @@ def default(self, obj): Parameters ---------- - obj : Any + obj Arbitrary object to convert Returns @@ -200,7 +209,7 @@ def default(self, obj): del cvardict[i] try: code = inspect.getsource(obj) - except OSError: + except (OSError, TypeError): # This happens when rendering videos included in the documentation # within doctests and should be replaced by a solution avoiding # hash collision (due to the same, empty, code strings) at some point. @@ -214,7 +223,7 @@ def default(self, obj): # We return the repr and not a list to avoid the JsonEncoder to iterate over it. return repr(obj) elif hasattr(obj, "__dict__"): - temp = getattr(obj, "__dict__") + temp = obj.__dict__ # MappingProxy is scene-caching nightmare. It contains all of the object methods and attributes. We skip it as the mechanism will at some point process the object, but instantiated. # Indeed, there is certainly no case where scene-caching will receive only a non instancied object, as this is never used in the library or encouraged to be used user-side. if isinstance(temp, MappingProxyType): @@ -225,7 +234,7 @@ def default(self, obj): # Serialize it with only the type of the object. You can change this to whatever string when debugging the serialization process. return str(type(obj)) - def _cleaned_iterable(self, iterable): + def _cleaned_iterable(self, iterable: typing.Iterable[Any]): """Check for circular reference at each iterable that will go through the JSONEncoder, as well as key of the wrong format. If a key with a bad format is found (i.e not a int, string, or float), it gets replaced byt its hash using the same process implemented here. @@ -233,7 +242,7 @@ def _cleaned_iterable(self, iterable): Parameters ---------- - iterable : Iterable[Any] + iterable The iterable to check. """ @@ -278,12 +287,12 @@ def _iter_check_dict(dct): elif isinstance(iterable, dict): return _iter_check_dict(iterable) - def encode(self, obj): + def encode(self, obj: Any): """Overriding of :meth:`JSONEncoder.encode`, to make our own process. Parameters ---------- - obj: Any + obj The object to encode in JSON. Returns @@ -297,12 +306,12 @@ def encode(self, obj): return super().encode(obj) -def get_json(obj): +def get_json(obj: dict): """Recursively serialize `object` to JSON using the :class:`CustomEncoder` class. Parameters ---------- - dict_config : :class:`dict` + obj The dict to flatten Returns @@ -314,25 +323,25 @@ def get_json(obj): def get_hash_from_play_call( - scene_object, - camera_object, - animations_list, - current_mobjects_list, + scene_object: Scene, + camera_object: Camera | OpenGLCamera, + animations_list: typing.Iterable[Animation], + current_mobjects_list: typing.Iterable[Mobject], ) -> str: """Take the list of animations and a list of mobjects and output their hashes. This is meant to be used for `scene.play` function. Parameters ----------- - scene_object : :class:`~.Scene` + scene_object The scene object. - camera_object : :class:`~.Camera` + camera_object The camera object used in the scene. - animations_list : Iterable[:class:`~.Animation`] + animations_list The list of animations. - current_mobjects_list : Iterable[:class:`~.Mobject`] + current_mobjects_list The list of mobjects. Returns diff --git a/manim/utils/images.py b/manim/utils/images.py index 544533f897..dd5c57858e 100644 --- a/manim/utils/images.py +++ b/manim/utils/images.py @@ -2,16 +2,29 @@ from __future__ import annotations -__all__ = ["get_full_raster_image_path", "drag_pixels", "invert_image"] +__all__ = [ + "get_full_raster_image_path", + "drag_pixels", + "invert_image", + "change_to_rgba_array", +] + +from pathlib import Path, PurePath +from typing import TYPE_CHECKING import numpy as np from PIL import Image +from manim.typing import RGBPixelArray + from .. import config from ..utils.file_ops import seek_full_path_from_defaults +if TYPE_CHECKING: + pass + -def get_full_raster_image_path(image_file_name: str) -> str: +def get_full_raster_image_path(image_file_name: str | PurePath) -> Path: return seek_full_path_from_defaults( image_file_name, default_dir=config.get_dir("assets_dir"), @@ -19,6 +32,14 @@ def get_full_raster_image_path(image_file_name: str) -> str: ) +def get_full_vector_image_path(image_file_name: str | PurePath) -> Path: + return seek_full_path_from_defaults( + image_file_name, + default_dir=config.get_dir("assets_dir"), + extensions=[".svg"], + ) + + def drag_pixels(frames: list[np.array]) -> list[np.array]: curr = frames[0] new_frames = [] @@ -32,3 +53,19 @@ def invert_image(image: np.array) -> Image: arr = np.array(image) arr = (255 * np.ones(arr.shape)).astype(arr.dtype) - arr return Image.fromarray(arr) + + +def change_to_rgba_array(image: RGBPixelArray, dtype: str = "uint8") -> RGBPixelArray: + """Converts an RGB array into RGBA with the alpha value opacity maxed.""" + pa = image + if len(pa.shape) == 2: + pa = pa.reshape(list(pa.shape) + [1]) + if pa.shape[2] == 1: + pa = pa.repeat(3, axis=2) + if pa.shape[2] == 3: + alphas = 255 * np.ones( + list(pa.shape[:2]) + [1], + dtype=dtype, + ) + pa = np.append(pa, alphas, axis=2) + return pa diff --git a/manim/utils/ipython_magic.py b/manim/utils/ipython_magic.py index 61caf706b9..ce6c93d552 100644 --- a/manim/utils/ipython_magic.py +++ b/manim/utils/ipython_magic.py @@ -3,16 +3,19 @@ from __future__ import annotations import mimetypes -import os import shutil from datetime import datetime from pathlib import Path from typing import Any -from manim import Group, config, logger, tempconfig +from manim import config, logger, tempconfig from manim.__main__ import main from manim.renderer.shader import shader_program_cache +from ..constants import RendererType + +__all__ = ["ManimMagic"] + try: from IPython import get_ipython from IPython.core.interactiveshell import InteractiveShell @@ -31,15 +34,15 @@ class ManimMagic(Magics): def __init__(self, shell: InteractiveShell) -> None: super().__init__(shell) - self.rendered_files = {} + self.rendered_files: dict[Path, Path] = {} @needs_local_scope @line_cell_magic def manim( self, line: str, - cell: str = None, - local_ns: dict[str, Any] = None, + cell: str | None = None, + local_ns: dict[str, Any] | None = None, ) -> None: r"""Render Manim scenes contained in IPython cells. Works as a line or cell magic. @@ -124,23 +127,15 @@ def construct(self): modified_args = self.add_additional_args(args) args = main(modified_args, standalone_mode=False, prog_name="manim") + assert isinstance(local_ns, dict) with tempconfig(local_ns.get("config", {})): - config.digest_args(args) + config.digest_args(args) # type: ignore[arg-type] renderer = None - if config.renderer == "opengl": - # Check if the imported mobjects extend the OpenGLMobject class - # meaning ConvertToOpenGL did its job - if "OpenGLMobject" in map(lambda cls: cls.__name__, Group.mro()): - from manim.renderer.opengl_renderer import OpenGLRenderer - - renderer = OpenGLRenderer() - else: - logger.warning( - "Renderer must be set to OpenGL in the configuration file " - "before importing Manim! Using cairo renderer instead.", - ) - config.renderer = "cairo" + if config.renderer == RendererType.OPENGL: + from manim.renderer.opengl_renderer import OpenGLRenderer + + renderer = OpenGLRenderer() try: SceneClass = local_ns[config["scene_names"][0]] @@ -169,12 +164,13 @@ def construct(self): if local_path in self.rendered_files: self.rendered_files[local_path].unlink() self.rendered_files[local_path] = tmpfile - os.makedirs(tmpfile.parent, exist_ok=True) + tmpfile.parent.mkdir(parents=True, exist_ok=True) shutil.copy(local_path, tmpfile) file_type = mimetypes.guess_type(config["output_file"])[0] + assert isinstance(file_type, str) embed = config["media_embed"] - if embed is None: + if not embed: # videos need to be embedded when running in google colab. # do this automatically in case config.media_embed has not been # set explicitly. @@ -200,4 +196,7 @@ def add_additional_args(self, args: list[str]) -> list[str]: def _generate_file_name() -> str: - return config["scene_names"][0] + "@" + datetime.now().strftime("%Y-%m-%d@%H-%M-%S") + val: str = ( + config["scene_names"][0] + "@" + datetime.now().strftime("%Y-%m-%d@%H-%M-%S") + ) + return val diff --git a/manim/utils/iterables.py b/manim/utils/iterables.py index 0984b75900..678750deb2 100644 --- a/manim/utils/iterables.py +++ b/manim/utils/iterables.py @@ -3,113 +3,105 @@ from __future__ import annotations __all__ = [ - "remove_list_redundancies", - "list_update", - "list_difference_update", - "all_elements_are_instances", "adjacent_n_tuples", "adjacent_pairs", - "tuplify", - "stretch_array_to_length", + "all_elements_are_instances", + "concatenate_lists", + "list_difference_update", + "list_update", + "listify", "make_even", "make_even_by_cycling", + "remove_list_redundancies", "remove_nones", - "concatenate_lists", - "listify", + "stretch_array_to_length", + "tuplify", ] - import itertools as it +from collections.abc import ( + Collection, + Generator, + Hashable, + Iterable, + Reversible, + Sequence, +) +from typing import TYPE_CHECKING, Callable, TypeVar, overload import numpy as np +T = TypeVar("T") +U = TypeVar("U") +F = TypeVar("F", np.float64, np.int_) +H = TypeVar("H", bound=Hashable) -def resize_array(nparray, length): - if len(nparray) == length: - return nparray - return np.resize(nparray, (length, *nparray.shape[1:])) +if TYPE_CHECKING: + import numpy.typing as npt -def resize_preserving_order(nparray, length): - if len(nparray) == 0: - return np.zeros((length, *nparray.shape[1:])) - if len(nparray) == length: - return nparray - indices = np.arange(length) * len(nparray) // length - return nparray[indices] - - -def resize_with_interpolation(nparray, length): - if len(nparray) == length: - return nparray - cont_indices = np.linspace(0, len(nparray) - 1, length) - return np.array( - [ - (1 - a) * nparray[lh] + a * nparray[rh] - for ci in cont_indices - for lh, rh, a in [(int(ci), int(np.ceil(ci)), ci % 1)] - ], - ) +def adjacent_n_tuples(objects: Sequence[T], n: int) -> zip[tuple[T, ...]]: + """Returns the Sequence objects cyclically split into n length tuples. -def remove_list_redundancies(lst): - """ - Used instead of list(set(l)) to maintain order - Keeps the last occurrence of each element - """ - reversed_result = [] - used = set() - for x in reversed(lst): - if x not in used: - reversed_result.append(x) - used.add(x) - reversed_result.reverse() - return reversed_result + See Also + -------- + adjacent_pairs : alias with n=2 + Examples + -------- + .. code-block:: pycon -def list_update(l1, l2): + >>> list(adjacent_n_tuples([1, 2, 3, 4], 2)) + [(1, 2), (2, 3), (3, 4), (4, 1)] + >>> list(adjacent_n_tuples([1, 2, 3, 4], 3)) + [(1, 2, 3), (2, 3, 4), (3, 4, 1), (4, 1, 2)] """ - Used instead of list(set(l1).update(l2)) to maintain order, - making sure duplicates are removed from l1, not l2. - """ - return [e for e in l1 if e not in l2] + list(l2) - - -def list_difference_update(l1, l2): - return [e for e in l1 if e not in l2] - + return zip(*([*objects[k:], *objects[:k]] for k in range(n))) -def all_elements_are_instances(iterable, Class): - return all([isinstance(e, Class) for e in iterable]) +def adjacent_pairs(objects: Sequence[T]) -> zip[tuple[T, ...]]: + """Alias for ``adjacent_n_tuples(objects, 2)``. -def adjacent_n_tuples(objects, n): - return zip(*([*objects[k:], *objects[:k]] for k in range(n))) + See Also + -------- + adjacent_n_tuples + Examples + -------- + .. code-block:: pycon -def adjacent_pairs(objects): + >>> list(adjacent_pairs([1, 2, 3, 4])) + [(1, 2), (2, 3), (3, 4), (4, 1)] + """ return adjacent_n_tuples(objects, 2) -def tuplify(obj): - if isinstance(obj, str): - return (obj,) - try: - return tuple(obj) - except TypeError: - return (obj,) +def all_elements_are_instances(iterable: Iterable[object], Class: type[object]) -> bool: + """Returns ``True`` if all elements of iterable are instances of Class. + False otherwise. + """ + return all(isinstance(e, Class) for e in iterable) -def batch_by_property(items, property_func): - """ - Takes in a list, and returns a list of tuples, (batch, prop) +def batch_by_property( + items: Iterable[T], property_func: Callable[[T], U] +) -> list[tuple[list[T], U | None]]: + """Takes in a Sequence, and returns a list of tuples, (batch, prop) such that all items in a batch have the same output when - put into property_func, and such that chaining all these - batches together would give the original list (i.e. order is - preserved) + put into the Callable property_func, and such that chaining all these + batches together would give the original Sequence (i.e. order is + preserved). + + Examples + -------- + .. code-block:: pycon + + >>> batch_by_property([(1, 2), (3, 4), (5, 6, 7), (8, 9)], len) + [([(1, 2), (3, 4)], 2), ([(5, 6, 7)], 3), ([(8, 9)], 2)] """ - batch_prop_pairs = [] - curr_batch = [] + batch_prop_pairs: list[tuple[list[T], U | None]] = [] + curr_batch: list[T] = [] curr_prop = None for item in items: prop = property_func(item) @@ -127,58 +119,361 @@ def batch_by_property(items, property_func): return batch_prop_pairs -def listify(obj): +def concatenate_lists(*list_of_lists: Iterable[T]) -> list[T]: + """Combines the Iterables provided as arguments into one list. + + Examples + -------- + .. code-block:: pycon + + >>> concatenate_lists([1, 2], [3, 4], [5]) + [1, 2, 3, 4, 5] + """ + return [item for lst in list_of_lists for item in lst] + + +def list_difference_update(l1: Iterable[T], l2: Iterable[T]) -> list[T]: + """Returns a list containing all the elements of l1 not in l2. + + Examples + -------- + .. code-block:: pycon + + >>> list_difference_update([1, 2, 3, 4], [2, 4]) + [1, 3] + """ + return [e for e in l1 if e not in l2] + + +def list_update(l1: Iterable[T], l2: Iterable[T]) -> list[T]: + """Used instead of ``set.update()`` to maintain order, + making sure duplicates are removed from l1, not l2. + Removes overlap of l1 and l2 and then concatenates l2 unchanged. + + Examples + -------- + .. code-block:: pycon + + >>> list_update([1, 2, 3], [2, 4, 4]) + [1, 3, 2, 4, 4] + """ + return [e for e in l1 if e not in l2] + list(l2) + + +@overload +def listify(obj: str) -> list[str]: ... + + +@overload +def listify(obj: Iterable[T]) -> list[T]: ... + + +@overload +def listify(obj: T) -> list[T]: ... + + +def listify(obj: str | Iterable[T] | T) -> list[str] | list[T]: + """Converts obj to a list intelligently. + + Examples + -------- + .. code-block:: pycon + + >>> listify("str") + ['str'] + >>> listify((1, 2)) + [1, 2] + >>> listify(len) + [] + """ if isinstance(obj, str): return [obj] - try: + if isinstance(obj, Iterable): return list(obj) - except TypeError: + else: return [obj] -def stretch_array_to_length(nparray, length): - curr_len = len(nparray) - if curr_len > length: - raise Warning("Trying to stretch array to a length shorter than its own") - indices = np.arange(length) / float(length) - indices *= curr_len - return nparray[indices.astype("int")] +def make_even( + iterable_1: Iterable[T], iterable_2: Iterable[U] +) -> tuple[list[T], list[U]]: + """Extends the shorter of the two iterables with duplicate values until its + length is equal to the longer iterable (favours earlier elements). + + See Also + -------- + make_even_by_cycling : cycles elements instead of favouring earlier ones + + Examples + -------- + .. code-block:: pycon + >>> make_even([1, 2], [3, 4, 5, 6]) + ([1, 1, 2, 2], [3, 4, 5, 6]) -def make_even(iterable_1, iterable_2): + >>> make_even([1, 2], [3, 4, 5, 6, 7]) + ([1, 1, 1, 2, 2], [3, 4, 5, 6, 7]) + """ list_1, list_2 = list(iterable_1), list(iterable_2) - length = max(len(list_1), len(list_2)) + len_list_1 = len(list_1) + len_list_2 = len(list_2) + length = max(len_list_1, len_list_2) return ( - [list_1[(n * len(list_1)) // length] for n in range(length)], - [list_2[(n * len(list_2)) // length] for n in range(length)], + [list_1[(n * len_list_1) // length] for n in range(length)], + [list_2[(n * len_list_2) // length] for n in range(length)], ) -def make_even_by_cycling(iterable_1, iterable_2): +def make_even_by_cycling( + iterable_1: Collection[T], iterable_2: Collection[U] +) -> tuple[list[T], list[U]]: + """Extends the shorter of the two iterables with duplicate values until its + length is equal to the longer iterable (cycles over shorter iterable). + + See Also + -------- + make_even : favours earlier elements instead of cycling them + + Examples + -------- + .. code-block:: pycon + + >>> make_even_by_cycling([1, 2], [3, 4, 5, 6]) + ([1, 2, 1, 2], [3, 4, 5, 6]) + + >>> make_even_by_cycling([1, 2], [3, 4, 5, 6, 7]) + ([1, 2, 1, 2, 1], [3, 4, 5, 6, 7]) + """ length = max(len(iterable_1), len(iterable_2)) cycle1 = it.cycle(iterable_1) cycle2 = it.cycle(iterable_2) return ( - [next(cycle1) for x in range(length)], - [next(cycle2) for x in range(length)], + [next(cycle1) for _ in range(length)], + [next(cycle2) for _ in range(length)], ) -def remove_nones(sequence): +def remove_list_redundancies(lst: Reversible[H]) -> list[H]: + """Used instead of ``list(set(l))`` to maintain order. + Keeps the last occurrence of each element. + """ + reversed_result = [] + used = set() + for x in reversed(lst): + if x not in used: + reversed_result.append(x) + used.add(x) + reversed_result.reverse() + return reversed_result + + +def remove_nones(sequence: Iterable[T | None]) -> list[T]: + """Removes elements where bool(x) evaluates to False. + + Examples + -------- + .. code-block:: pycon + + >>> remove_nones(["m", "", "l", 0, 42, False, True]) + ['m', 'l', 42, True] + """ + # Note this is redundant with it.chain return [x for x in sequence if x] -# Note this is redundant with it.chain +def resize_array(nparray: npt.NDArray[F], length: int) -> npt.NDArray[F]: + """Extends/truncates nparray so that ``len(result) == length``. + The elements of nparray are cycled to achieve the desired length. + + See Also + -------- + resize_preserving_order : favours earlier elements instead of cycling them + make_even_by_cycling : similar cycling behaviour for balancing 2 iterables + + Examples + -------- + .. code-block:: pycon + + >>> points = np.array([[1, 2], [3, 4]]) + >>> resize_array(points, 1) + array([[1, 2]]) + >>> resize_array(points, 3) + array([[1, 2], + [3, 4], + [1, 2]]) + >>> resize_array(points, 2) + array([[1, 2], + [3, 4]]) + """ + if len(nparray) == length: + return nparray + return np.resize(nparray, (length, *nparray.shape[1:])) -def concatenate_lists(*list_of_lists): - return [item for lst in list_of_lists for item in lst] +def resize_preserving_order( + nparray: npt.NDArray[np.float64], length: int +) -> npt.NDArray[np.float64]: + """Extends/truncates nparray so that ``len(result) == length``. + The elements of nparray are duplicated to achieve the desired length + (favours earlier elements). + + Constructs a zeroes array of length if nparray is empty. + + See Also + -------- + resize_array : cycles elements instead of favouring earlier ones + make_even : similar earlier-favouring behaviour for balancing 2 iterables + + Examples + -------- + .. code-block:: pycon + + >>> resize_preserving_order(np.array([]), 5) + array([0., 0., 0., 0., 0.]) + + >>> nparray = np.array([[1, 2], [3, 4]]) + >>> resize_preserving_order(nparray, 1) + array([[1, 2]]) + + >>> resize_preserving_order(nparray, 3) + array([[1, 2], + [1, 2], + [3, 4]]) + """ + if len(nparray) == 0: + return np.zeros((length, *nparray.shape[1:])) + if len(nparray) == length: + return nparray + indices = np.arange(length) * len(nparray) // length + return nparray[indices] + + +def resize_with_interpolation(nparray: npt.NDArray[F], length: int) -> npt.NDArray[F]: + """Extends/truncates nparray so that ``len(result) == length``. + New elements are interpolated to achieve the desired length. + + Note that if nparray's length changes, its dtype may too + (e.g. int -> float: see Examples) + + See Also + -------- + resize_array : cycles elements instead of interpolating + resize_preserving_order : favours earlier elements instead of interpolating + + Examples + -------- + .. code-block:: pycon + + >>> nparray = np.array([[1, 2], [3, 4]]) + >>> resize_with_interpolation(nparray, 1) + array([[1., 2.]]) + >>> resize_with_interpolation(nparray, 4) + array([[1. , 2. ], + [1.66666667, 2.66666667], + [2.33333333, 3.33333333], + [3. , 4. ]]) + >>> nparray = np.array([[[1, 2], [3, 4]]]) + >>> nparray = np.array([[1, 2], [3, 4], [5, 6]]) + >>> resize_with_interpolation(nparray, 4) + array([[1. , 2. ], + [2.33333333, 3.33333333], + [3.66666667, 4.66666667], + [5. , 6. ]]) + >>> nparray = np.array([[1, 2], [3, 4], [1, 2]]) + >>> resize_with_interpolation(nparray, 4) + array([[1. , 2. ], + [2.33333333, 3.33333333], + [2.33333333, 3.33333333], + [1. , 2. ]]) + """ + if len(nparray) == length: + return nparray + cont_indices = np.linspace(0, len(nparray) - 1, length) + return np.array( + [ + (1 - a) * nparray[lh] + a * nparray[rh] + for ci in cont_indices + for lh, rh, a in [(int(ci), int(np.ceil(ci)), ci % 1)] + ], + ) + + +def stretch_array_to_length(nparray: npt.NDArray[F], length: int) -> npt.NDArray[F]: + # todo: is this the same as resize_preserving_order()? + curr_len = len(nparray) + if curr_len > length: + raise Warning("Trying to stretch array to a length shorter than its own") + indices = np.arange(length) / float(length) + indices *= curr_len + return nparray[indices.astype(int)] + +@overload +def tuplify(obj: str) -> tuple[str]: ... -def uniq_chain(*args): + +@overload +def tuplify(obj: Iterable[T]) -> tuple[T]: ... + + +@overload +def tuplify(obj: T) -> tuple[T]: ... + + +def tuplify(obj: str | Iterable[T] | T) -> tuple[str] | tuple[T]: + """Converts obj to a tuple intelligently. + + Examples + -------- + .. code-block:: pycon + + >>> tuplify("str") + ('str',) + >>> tuplify([1, 2]) + (1, 2) + >>> tuplify(len) + (,) + """ + if isinstance(obj, str): + return (obj,) + if isinstance(obj, Iterable): + return tuple(obj) + else: + return (obj,) + + +def uniq_chain(*args: Iterable[T]) -> Generator[T, None, None]: + """Returns a generator that yields all unique elements of the Iterables + provided via args in the order provided. + + Examples + -------- + .. code-block:: pycon + + >>> gen = uniq_chain([1, 2], [2, 3], [1, 4, 4]) + >>> from collections.abc import Generator + >>> isinstance(gen, Generator) + True + >>> tuple(gen) + (1, 2, 3, 4) + """ unique_items = set() for x in it.chain(*args): if x in unique_items: continue unique_items.add(x) yield x + + +def hash_obj(obj: object) -> int: + """Determines a hash, even of potentially mutable objects.""" + if isinstance(obj, dict): + return hash(tuple(sorted((hash_obj(k), hash_obj(v)) for k, v in obj.items()))) + + if isinstance(obj, set): + return hash(tuple(sorted(hash_obj(e) for e in obj))) + + if isinstance(obj, (tuple, list)): + return hash(tuple(hash_obj(e) for e in obj)) + + return hash(obj) diff --git a/manim/utils/module_ops.py b/manim/utils/module_ops.py index 60871cf423..1b03e374f4 100644 --- a/manim/utils/module_ops.py +++ b/manim/utils/module_ops.py @@ -2,18 +2,31 @@ import importlib.util import inspect -import os import re import sys import types import warnings from pathlib import Path +from typing import TYPE_CHECKING, Literal, overload -from .. import config, console, constants, logger -from ..scene.scene_file_writer import SceneFileWriter +from manim._config import config, console, logger +from manim.constants import ( + CHOOSE_NUMBER_MESSAGE, + INVALID_NUMBER_MESSAGE, + NO_SCENE_MESSAGE, + SCENE_NOT_FOUND_MESSAGE, +) +from manim.scene.scene_file_writer import SceneFileWriter +if TYPE_CHECKING: + from typing import Any -def get_module(file_name: Path): + from manim.scene.scene import Scene + +__all__ = ["scene_classes_from_file"] + + +def get_module(file_name: Path) -> types.ModuleType: if str(file_name) == "-": module = types.ModuleType("input_scenes") logger.info( @@ -33,11 +46,11 @@ def get_module(file_name: Path): logger.error(f"Failed to render scene: {str(e)}") sys.exit(2) else: - if Path(file_name).exists(): + if file_name.exists(): ext = file_name.suffix if ext != ".py": raise ValueError(f"{file_name} is not a valid Manim python script.") - module_name = ext.replace(os.sep, ".").split(".")[-1] + module_name = ".".join(file_name.with_suffix("").parts) warnings.filterwarnings( "default", @@ -46,19 +59,22 @@ def get_module(file_name: Path): ) spec = importlib.util.spec_from_file_location(module_name, file_name) - module = importlib.util.module_from_spec(spec) - sys.modules[module_name] = module - sys.path.insert(0, str(file_name.parent.absolute())) - spec.loader.exec_module(module) - return module + if isinstance(spec, importlib.machinery.ModuleSpec): + module = importlib.util.module_from_spec(spec) + sys.modules[module_name] = module + sys.path.insert(0, str(file_name.parent.absolute())) + assert spec.loader + spec.loader.exec_module(module) + return module + raise FileNotFoundError(f"{file_name} not found") else: raise FileNotFoundError(f"{file_name} not found") -def get_scene_classes_from_module(module): +def get_scene_classes_from_module(module: types.ModuleType) -> list[type[Scene]]: from ..scene.scene import Scene - def is_child_scene(obj, module): + def is_child_scene(obj: Any, module: types.ModuleType) -> bool: return ( inspect.isclass(obj) and issubclass(obj, Scene) @@ -72,9 +88,9 @@ def is_child_scene(obj, module): ] -def get_scenes_to_render(scene_classes): +def get_scenes_to_render(scene_classes: list[type[Scene]]) -> list[type[Scene]]: if not scene_classes: - logger.error(constants.NO_SCENE_MESSAGE) + logger.error(NO_SCENE_MESSAGE) return [] if config["write_all"]: return scene_classes @@ -87,7 +103,7 @@ def get_scenes_to_render(scene_classes): found = True break if not found and (scene_name != ""): - logger.error(constants.SCENE_NOT_FOUND_MESSAGE.format(scene_name)) + logger.error(SCENE_NOT_FOUND_MESSAGE.format(scene_name)) if result: return result if len(scene_classes) == 1: @@ -96,7 +112,7 @@ def get_scenes_to_render(scene_classes): return prompt_user_for_choice(scene_classes) -def prompt_user_for_choice(scene_classes): +def prompt_user_for_choice(scene_classes: list[type[Scene]]) -> list[type[Scene]]: num_to_class = {} SceneFileWriter.force_output_as_scene_name = True for count, scene_class in enumerate(scene_classes, 1): @@ -105,7 +121,7 @@ def prompt_user_for_choice(scene_classes): num_to_class[count] = scene_class try: user_input = console.input( - f"[log.message] {constants.CHOOSE_NUMBER_MESSAGE} [/log.message]", + f"[log.message] {CHOOSE_NUMBER_MESSAGE} [/log.message]", ) scene_classes = [ num_to_class[int(num_str)] @@ -114,7 +130,7 @@ def prompt_user_for_choice(scene_classes): config["scene_names"] = [scene_class.__name__ for scene_class in scene_classes] return scene_classes except KeyError: - logger.error(constants.INVALID_NUMBER_MESSAGE) + logger.error(INVALID_NUMBER_MESSAGE) sys.exit(2) except EOFError: sys.exit(1) @@ -123,7 +139,31 @@ def prompt_user_for_choice(scene_classes): sys.exit(1) -def scene_classes_from_file(file_path, require_single_scene=False, full_list=False): +@overload +def scene_classes_from_file( + file_path: Path, require_single_scene: bool, full_list: Literal[True] +) -> list[type[Scene]]: ... + + +@overload +def scene_classes_from_file( + file_path: Path, + require_single_scene: Literal[True], + full_list: Literal[False] = False, +) -> type[Scene]: ... + + +@overload +def scene_classes_from_file( + file_path: Path, + require_single_scene: Literal[False] = False, + full_list: Literal[False] = False, +) -> list[type[Scene]]: ... + + +def scene_classes_from_file( + file_path: Path, require_single_scene: bool = False, full_list: bool = False +) -> type[Scene] | list[type[Scene]]: module = get_module(file_path) all_scene_classes = get_scene_classes_from_module(module) if full_list: diff --git a/manim/utils/opengl.py b/manim/utils/opengl.py index e84642d226..877cbc2e8f 100644 --- a/manim/utils/opengl.py +++ b/manim/utils/opengl.py @@ -1,24 +1,73 @@ from __future__ import annotations +from typing import TYPE_CHECKING + import numpy as np import numpy.linalg as linalg -from .. import config +from manim._config import config +from manim.typing import ManimFloat + +if TYPE_CHECKING: + import numpy.typing as npt + from typing_extensions import TypeAlias + + from manim.typing import MatrixMN, Point3D -depth = 20 +if TYPE_CHECKING: + from typing_extensions import TypeAlias + + from manim.typing import MatrixMN + + +depth = 20 -def matrix_to_shader_input(matrix): +__all__ = [ + "matrix_to_shader_input", + "orthographic_projection_matrix", + "perspective_projection_matrix", + "translation_matrix", + "x_rotation_matrix", + "y_rotation_matrix", + "z_rotation_matrix", + "rotate_in_place_matrix", + "rotation_matrix", + "scale_matrix", + "view_matrix", +] + +FlattenedMatrix4x4: TypeAlias = tuple[ + float, + float, + float, + float, + float, + float, + float, + float, + float, + float, + float, + float, + float, + float, + float, + float, +] + + +def matrix_to_shader_input(matrix: MatrixMN) -> FlattenedMatrix4x4: return tuple(matrix.T.ravel()) def orthographic_projection_matrix( - width=None, - height=None, - near=1, - far=depth + 1, - format=True, -): + width: float | None = None, + height: float | None = None, + near: float = 1, + far: float = depth + 1, + format_: bool = True, +) -> MatrixMN | FlattenedMatrix4x4: if width is None: width = config["frame_width"] if height is None: @@ -31,13 +80,19 @@ def orthographic_projection_matrix( [0, 0, 0, 1], ], ) - if format: + if format_: return matrix_to_shader_input(projection_matrix) else: return projection_matrix -def perspective_projection_matrix(width=None, height=None, near=2, far=50, format=True): +def perspective_projection_matrix( + width: float | None = None, + height: float | None = None, + near: float = 2, + far: float = 50, + format_: bool = True, +) -> MatrixMN | FlattenedMatrix4x4: if width is None: width = config["frame_width"] / 6 if height is None: @@ -50,13 +105,13 @@ def perspective_projection_matrix(width=None, height=None, near=2, far=50, forma [0, 0, -1, 0], ], ) - if format: + if format_: return matrix_to_shader_input(projection_matrix) else: return projection_matrix -def translation_matrix(x=0, y=0, z=0): +def translation_matrix(x: float = 0, y: float = 0, z: float = 0) -> MatrixMN: return np.array( [ [1, 0, 0, x], @@ -64,10 +119,11 @@ def translation_matrix(x=0, y=0, z=0): [0, 0, 1, z], [0, 0, 0, 1], ], + dtype=ManimFloat, ) -def x_rotation_matrix(x=0): +def x_rotation_matrix(x: float = 0) -> MatrixMN: return np.array( [ [1, 0, 0, 0], @@ -78,7 +134,7 @@ def x_rotation_matrix(x=0): ) -def y_rotation_matrix(y=0): +def y_rotation_matrix(y: float = 0) -> MatrixMN: return np.array( [ [np.cos(y), 0, np.sin(y), 0], @@ -89,7 +145,7 @@ def y_rotation_matrix(y=0): ) -def z_rotation_matrix(z=0): +def z_rotation_matrix(z: float = 0) -> MatrixMN: return np.array( [ [np.cos(z), -np.sin(z), 0, 0], @@ -101,7 +157,9 @@ def z_rotation_matrix(z=0): # TODO: When rotating around the x axis, rotation eventually stops. -def rotate_in_place_matrix(initial_position, x=0, y=0, z=0): +def rotate_in_place_matrix( + initial_position: Point3D, x: float = 0, y: float = 0, z: float = 0 +) -> MatrixMN: return np.matmul( translation_matrix(*-initial_position), np.matmul( @@ -111,14 +169,14 @@ def rotate_in_place_matrix(initial_position, x=0, y=0, z=0): ) -def rotation_matrix(x=0, y=0, z=0): +def rotation_matrix(x: float = 0, y: float = 0, z: float = 0) -> MatrixMN: return np.matmul( np.matmul(x_rotation_matrix(x), y_rotation_matrix(y)), z_rotation_matrix(z), ) -def scale_matrix(scale_factor=1): +def scale_matrix(scale_factor: float = 1) -> npt.NDArray: return np.array( [ [scale_factor, 0, 0, 0], @@ -126,15 +184,16 @@ def scale_matrix(scale_factor=1): [0, 0, scale_factor, 0], [0, 0, 0, 1], ], + dtype=ManimFloat, ) def view_matrix( - translation=None, - x_rotation=0, - y_rotation=0, - z_rotation=0, -): + translation: Point3D | None = None, + x_rotation: float = 0, + y_rotation: float = 0, + z_rotation: float = 0, +) -> MatrixMN: if translation is None: translation = np.array([0, 0, depth / 2 + 1]) model_matrix = np.matmul( diff --git a/manim/utils/parameter_parsing.py b/manim/utils/parameter_parsing.py new file mode 100644 index 0000000000..d3676c7301 --- /dev/null +++ b/manim/utils/parameter_parsing.py @@ -0,0 +1,32 @@ +from __future__ import annotations + +from collections.abc import Iterable +from types import GeneratorType +from typing import TypeVar + +T = TypeVar("T") + + +def flatten_iterable_parameters( + args: Iterable[T | Iterable[T] | GeneratorType], +) -> list[T]: + """Flattens an iterable of parameters into a list of parameters. + + Parameters + ---------- + args + The iterable of parameters to flatten. + [(generator), [], (), ...] + + Returns + ------- + :class:`list` + The flattened list of parameters. + """ + flattened_parameters: list[T] = [] + for arg in args: + if isinstance(arg, (Iterable, GeneratorType)): + flattened_parameters.extend(arg) + else: + flattened_parameters.append(arg) + return flattened_parameters diff --git a/manim/utils/paths.py b/manim/utils/paths.py index 9d7ec10d73..aa39732888 100644 --- a/manim/utils/paths.py +++ b/manim/utils/paths.py @@ -10,28 +10,22 @@ ] -from typing import Callable +from typing import TYPE_CHECKING import numpy as np from ..constants import OUT from ..utils.bezier import interpolate -from ..utils.deprecation import deprecated_params from ..utils.space_ops import rotation_matrix -STRAIGHT_PATH_THRESHOLD = 0.01 +if TYPE_CHECKING: + from manim.typing import PathFuncType, Point3D_Array, Vector3D + -PATH_FUNC_TYPE = Callable[[np.ndarray, np.ndarray, float], np.ndarray] +STRAIGHT_PATH_THRESHOLD = 0.01 -# Remove `*args` and the `if` inside the functions when removing deprecation -@deprecated_params( - params="start_points, end_points, alpha", - since="v0.14", - until="v0.15", - message="Straight path is now returning interpolating function to make it consistent with other path functions. Use straight_path()(a,b,c) instead of straight_path(a,b,c).", -) -def straight_path(*args) -> PATH_FUNC_TYPE: +def straight_path() -> PathFuncType: """Simplest path function. Each point in a set goes in a straight path toward its destination. Examples @@ -74,14 +68,12 @@ def construct(self): self.wait() """ - if len(args) > 0: - return interpolate(*args) return interpolate def path_along_circles( - arc_angle: float, circles_centers: np.ndarray, axis: np.ndarray = OUT -) -> PATH_FUNC_TYPE: + arc_angle: float, circles_centers: np.ndarray, axis: Vector3D = OUT +) -> PathFuncType: """This function transforms each point by moving it roughly along a circle, each with its own specified center. The path may be seen as each point smoothly changing its orbit from its starting position to its destination. @@ -144,7 +136,9 @@ def construct(self): axis = OUT unit_axis = axis / np.linalg.norm(axis) - def path(start_points: np.ndarray, end_points: np.ndarray, alpha: float): + def path( + start_points: Point3D_Array, end_points: Point3D_Array, alpha: float + ) -> Point3D_Array: detransformed_end_points = circles_centers + np.dot( end_points - circles_centers, rotation_matrix(-arc_angle, unit_axis).T ) @@ -158,7 +152,7 @@ def path(start_points: np.ndarray, end_points: np.ndarray, alpha: float): return path -def path_along_arc(arc_angle: float, axis: np.ndarray = OUT) -> PATH_FUNC_TYPE: +def path_along_arc(arc_angle: float, axis: Vector3D = OUT) -> PathFuncType: """This function transforms each point by moving it along a circular arc. Parameters @@ -214,7 +208,9 @@ def construct(self): axis = OUT unit_axis = axis / np.linalg.norm(axis) - def path(start_points: np.ndarray, end_points: np.ndarray, alpha: float): + def path( + start_points: Point3D_Array, end_points: Point3D_Array, alpha: float + ) -> Point3D_Array: vects = end_points - start_points centers = start_points + 0.5 * vects if arc_angle != np.pi: @@ -225,7 +221,7 @@ def path(start_points: np.ndarray, end_points: np.ndarray, alpha: float): return path -def clockwise_path() -> PATH_FUNC_TYPE: +def clockwise_path() -> PathFuncType: """This function transforms each point by moving clockwise around a half circle. Examples @@ -271,7 +267,7 @@ def construct(self): return path_along_arc(-np.pi) -def counterclockwise_path() -> PATH_FUNC_TYPE: +def counterclockwise_path() -> PathFuncType: """This function transforms each point by moving counterclockwise around a half circle. Examples @@ -317,7 +313,7 @@ def construct(self): return path_along_arc(np.pi) -def spiral_path(angle: float, axis: np.ndarray = OUT) -> PATH_FUNC_TYPE: +def spiral_path(angle: float, axis: Vector3D = OUT) -> PathFuncType: """This function transforms each point by moving along a spiral to its destination. Parameters @@ -373,7 +369,9 @@ def construct(self): axis = OUT unit_axis = axis / np.linalg.norm(axis) - def path(start_points: np.ndarray, end_points: np.ndarray, alpha: float): + def path( + start_points: Point3D_Array, end_points: Point3D_Array, alpha: float + ) -> Point3D_Array: rot_matrix = rotation_matrix((alpha - 1) * angle, unit_axis) return start_points + alpha * np.dot(end_points - start_points, rot_matrix.T) diff --git a/manim/utils/polylabel.py b/manim/utils/polylabel.py new file mode 100644 index 0000000000..9b40f29421 --- /dev/null +++ b/manim/utils/polylabel.py @@ -0,0 +1,168 @@ +#!/usr/bin/env python +from __future__ import annotations + +from queue import PriorityQueue +from typing import TYPE_CHECKING + +import numpy as np + +if TYPE_CHECKING: + from collections.abc import Sequence + + from manim.typing import ( + Point2D, + Point2D_Array, + Point2DLike, + Point2DLike_Array, + Point3DLike_Array, + ) + + +class Polygon: + """ + Initializes the Polygon with the given rings. + + Parameters + ---------- + rings + A collection of closed polygonal ring. + """ + + def __init__(self, rings: Sequence[Point2DLike_Array]) -> None: + np_rings: list[Point2D_Array] = [np.asarray(ring) for ring in rings] + # Flatten Array + csum = np.cumsum([ring.shape[0] for ring in np_rings]) + self.array: Point2D_Array = np.concatenate(np_rings, axis=0) + + # Compute Boundary + self.start: Point2D_Array = np.delete(self.array, csum - 1, axis=0) + self.stop: Point2D_Array = np.delete(self.array, csum % csum[-1], axis=0) + self.diff: Point2D_Array = np.delete( + np.diff(self.array, axis=0), csum[:-1] - 1, axis=0 + ) + self.norm: Point2D_Array = self.diff / np.einsum( + "ij,ij->i", self.diff, self.diff + ).reshape(-1, 1) + + # Compute Centroid + x, y = self.start[:, 0], self.start[:, 1] + xr, yr = self.stop[:, 0], self.stop[:, 1] + self.area: float = 0.5 * (np.dot(x, yr) - np.dot(xr, y)) + if self.area: + factor = x * yr - xr * y + cx = np.sum((x + xr) * factor) / (6.0 * self.area) + cy = np.sum((y + yr) * factor) / (6.0 * self.area) + self.centroid = np.array([cx, cy]) + + def compute_distance(self, point: Point2DLike) -> float: + """Compute the minimum distance from a point to the polygon.""" + scalars = np.einsum("ij,ij->i", self.norm, point - self.start) + clips = np.clip(scalars, 0, 1).reshape(-1, 1) + d: float = np.min( + np.linalg.norm(self.start + self.diff * clips - point, axis=1) + ) + return d if self.inside(point) else -d + + def inside(self, point: Point2DLike) -> bool: + """Check if a point is inside the polygon.""" + # Views + px, py = point + x, y = self.start[:, 0], self.start[:, 1] + xr, yr = self.stop[:, 0], self.stop[:, 1] + + # Count Crossings (enforce short-circuit) + c = (y > py) != (yr > py) + c = px < x[c] + (py - y[c]) * (xr[c] - x[c]) / (yr[c] - y[c]) + c_sum: int = np.sum(c) + return c_sum % 2 == 1 + + +class Cell: + """ + A square in a mesh covering the :class:`~.Polygon` passed as an argument. + + Parameters + ---------- + c + Center coordinates of the Cell. + h + Half-Size of the Cell. + polygon + :class:`~.Polygon` object for which the distance is computed. + """ + + def __init__(self, c: Point2DLike, h: float, polygon: Polygon) -> None: + self.c: Point2D = np.asarray(c) + self.h = h + self.d = polygon.compute_distance(self.c) + self.p = self.d + self.h * np.sqrt(2) + + def __lt__(self, other: Cell) -> bool: + return self.d < other.d + + def __gt__(self, other: Cell) -> bool: + return self.d > other.d + + def __le__(self, other: Cell) -> bool: + return self.d <= other.d + + def __ge__(self, other: Cell) -> bool: + return self.d >= other.d + + +def polylabel(rings: Sequence[Point3DLike_Array], precision: float = 0.01) -> Cell: + """ + Finds the pole of inaccessibility (the point that is farthest from the edges of the polygon) + using an iterative grid-based approach. + + Parameters + ---------- + rings + A list of lists, where each list is a sequence of points representing the rings of the polygon. + Typically, multiple rings indicate holes in the polygon. + precision + The precision of the result (default is 0.01). + + Returns + ------- + Cell + A Cell containing the pole of inaccessibility to a given precision. + """ + # Precompute Polygon Data + np_rings: list[Point2D_Array] = [np.asarray(ring)[:, :2] for ring in rings] + polygon = Polygon(np_rings) + + # Bounding Box + mins = np.min(polygon.array, axis=0) + maxs = np.max(polygon.array, axis=0) + dims = maxs - mins + s = np.min(dims) + h = s / 2.0 + + # Initial Grid + queue: PriorityQueue[Cell] = PriorityQueue() + xv, yv = np.meshgrid(np.arange(mins[0], maxs[0], s), np.arange(mins[1], maxs[1], s)) + for corner in np.vstack([xv.ravel(), yv.ravel()]).T: + queue.put(Cell(corner + h, h, polygon)) + + # Initial Guess + best = Cell(polygon.centroid, 0, polygon) + bbox = Cell(mins + (dims / 2), 0, polygon) + if bbox.d > best.d: + best = bbox + + # While there are cells to consider... + directions = np.array([[-1, -1], [1, -1], [-1, 1], [1, 1]]) + while not queue.empty(): + cell = queue.get() + if cell > best: + best = cell + # If a cell is promising, subdivide! + if cell.p - best.d > precision: + h = cell.h / 2.0 + offsets = cell.c + directions * h + queue.put(Cell(offsets[0], h, polygon)) + queue.put(Cell(offsets[1], h, polygon)) + queue.put(Cell(offsets[2], h, polygon)) + queue.put(Cell(offsets[3], h, polygon)) + return best diff --git a/manim/utils/qhull.py b/manim/utils/qhull.py new file mode 100644 index 0000000000..9e3b329561 --- /dev/null +++ b/manim/utils/qhull.py @@ -0,0 +1,218 @@ +#!/usr/bin/env python +from __future__ import annotations + +from typing import TYPE_CHECKING + +import numpy as np + +if TYPE_CHECKING: + from manim.typing import PointND, PointND_Array + + +class QuickHullPoint: + def __init__(self, coordinates: PointND_Array) -> None: + self.coordinates = coordinates + + def __hash__(self) -> int: + return hash(self.coordinates.tobytes()) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, QuickHullPoint): + raise ValueError + are_coordinates_equal: bool = np.array_equal( + self.coordinates, other.coordinates + ) + return are_coordinates_equal + + +class SubFacet: + def __init__(self, coordinates: PointND_Array) -> None: + self.coordinates = coordinates + self.points = frozenset(QuickHullPoint(c) for c in coordinates) + + def __hash__(self) -> int: + return hash(self.points) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, SubFacet): + raise ValueError + return self.points == other.points + + +class Facet: + def __init__(self, coordinates: PointND_Array, internal: PointND) -> None: + self.coordinates = coordinates + self.center: PointND = np.mean(coordinates, axis=0) + self.normal = self.compute_normal(internal) + self.subfacets = frozenset( + SubFacet(np.delete(self.coordinates, i, axis=0)) + for i in range(self.coordinates.shape[0]) + ) + + def compute_normal(self, internal: PointND) -> PointND: + centered = self.coordinates - self.center + _, _, vh = np.linalg.svd(centered) + normal: PointND = vh[-1, :] + normal /= np.linalg.norm(normal) + + # If the normal points towards the internal point, flip it! + if np.dot(normal, self.center - internal) < 0: + normal *= -1 + + return normal + + def __hash__(self) -> int: + return hash(self.subfacets) + + def __eq__(self, other: object) -> bool: + if not isinstance(other, Facet): + raise ValueError + return self.subfacets == other.subfacets + + +class Horizon: + def __init__(self) -> None: + self.facets: set[Facet] = set() + self.boundary: list[SubFacet] = [] + + +class QuickHull: + """ + QuickHull algorithm for constructing a convex hull from a set of points. + + Parameters + ---------- + tolerance + A tolerance threshold for determining when points lie on the convex hull (default is 1e-5). + + Attributes + ---------- + facets + List of facets considered. + removed + Set of internal facets that have been removed from the hull during the construction process. + outside + Dictionary mapping each facet to its outside points and eye point. + neighbors + Mapping of subfacets to their neighboring facets. Each subfacet links precisely two neighbors. + unclaimed + Points that have not yet been classified as inside or outside the current hull. + internal + An internal point (i.e., the center of the initial simplex) used as a reference during hull construction. + tolerance + The tolerance used to determine if points are considered outside the current hull. + """ + + def __init__(self, tolerance: float = 1e-5) -> None: + self.facets: list[Facet] = [] + self.removed: set[Facet] = set() + self.outside: dict[Facet, tuple[PointND_Array | None, PointND | None]] = {} + self.neighbors: dict[SubFacet, set[Facet]] = {} + self.unclaimed: PointND_Array | None = None + self.internal: PointND | None = None + self.tolerance = tolerance + + def initialize(self, points: PointND_Array) -> None: + # Sample Points + simplex = points[ + np.random.choice(points.shape[0], points.shape[1] + 1, replace=False) + ] + self.unclaimed = points + new_internal: PointND = np.mean(simplex, axis=0) + self.internal = new_internal + + # Build Simplex + for c in range(simplex.shape[0]): + facet = Facet(np.delete(simplex, c, axis=0), internal=new_internal) + self.classify(facet) + self.facets.append(facet) + + # Attach Neighbors + for f in self.facets: + for sf in f.subfacets: + self.neighbors.setdefault(sf, set()).add(f) + + def classify(self, facet: Facet) -> None: + assert self.unclaimed is not None, ( + "Call .initialize() before using .classify()." + ) + + if not self.unclaimed.size: + self.outside[facet] = (None, None) + return + + # Compute Projections + projections = (self.unclaimed - facet.center) @ facet.normal + arg = np.argmax(projections) + mask = projections > self.tolerance + + # Identify Eye and Outside Set + eye = self.unclaimed[arg] if projections[arg] > self.tolerance else None + outside = self.unclaimed[mask] + self.outside[facet] = (outside, eye) + self.unclaimed = self.unclaimed[~mask] + + def compute_horizon(self, eye: PointND, start_facet: Facet) -> Horizon: + horizon = Horizon() + self._recursive_horizon(eye, start_facet, horizon) + return horizon + + def _recursive_horizon(self, eye: PointND, facet: Facet, horizon: Horizon) -> bool: + visible = np.dot(facet.normal, eye - facet.center) > 0 + if not visible: + return False + + # If the eye is visible from the facet: + # Label the facet as visible and cross each edge + horizon.facets.add(facet) + for subfacet in facet.subfacets: + neighbor = (self.neighbors[subfacet] - {facet}).pop() + # If the neighbor is not visible, then the edge shared must be on the boundary + if neighbor not in horizon.facets and not self._recursive_horizon( + eye, neighbor, horizon + ): + horizon.boundary.append(subfacet) + return True + + def build(self, points: PointND_Array) -> None: + num, dim = points.shape + if (dim == 0) or (num < dim + 1): + raise ValueError("Not enough points supplied to build Convex Hull!") + if dim == 1: + raise ValueError("The Convex Hull of 1D data is its min-max!") + + self.initialize(points) + + # This helps the type checker. + assert self.unclaimed is not None + assert self.internal is not None + + while True: + updated = False + for facet in self.facets: + if facet in self.removed: + continue + outside, eye = self.outside[facet] + if eye is not None: + updated = True + horizon = self.compute_horizon(eye, facet) + for f in horizon.facets: + points_to_append = self.outside[f][0] + # TODO: is this always true? + assert points_to_append is not None + self.unclaimed = np.vstack((self.unclaimed, points_to_append)) + self.removed.add(f) + for sf in f.subfacets: + self.neighbors[sf].discard(f) + if self.neighbors[sf] == set(): + del self.neighbors[sf] + for sf in horizon.boundary: + nf = Facet( + np.vstack((sf.coordinates, eye)), internal=self.internal + ) + self.classify(nf) + self.facets.append(nf) + for nsf in nf.subfacets: + self.neighbors.setdefault(nsf, set()).add(nf) + if not updated: + break diff --git a/manim/utils/rate_functions.py b/manim/utils/rate_functions.py index 261199b524..6b9a30f6a2 100644 --- a/manim/utils/rate_functions.py +++ b/manim/utils/rate_functions.py @@ -83,12 +83,14 @@ def construct(self): self.wait() """ - from __future__ import annotations __all__ = [ "linear", "smooth", + "smoothstep", + "smootherstep", + "smoothererstep", "rush_into", "rush_from", "slow_into", @@ -103,21 +105,25 @@ def construct(self): "exponential_decay", ] -import typing from functools import wraps from math import sqrt +from typing import Any, Protocol import numpy as np -from ..utils.bezier import bezier -from ..utils.simple_functions import sigmoid +from manim.utils.simple_functions import sigmoid + + +# TODO: rewrite this to use ParamSpec when Python 3.9 is out of life +class RateFunction(Protocol): + def __call__(self, t: float, *args: Any, **kwargs: Any) -> float: ... # This is a decorator that makes sure any function it's used on will # return 0 if t<0 and 1 if t>1. -def unit_interval(function): +def unit_interval(function: RateFunction) -> RateFunction: @wraps(function) - def wrapper(t, *args, **kwargs): + def wrapper(t: float, *args: Any, **kwargs: Any) -> float: if 0 <= t <= 1: return function(t, *args, **kwargs) elif t < 0: @@ -130,9 +136,9 @@ def wrapper(t, *args, **kwargs): # This is a decorator that makes sure any function it's used on will # return 0 if t<0 or t>1. -def zero(function): +def zero(function: RateFunction) -> RateFunction: @wraps(function) - def wrapper(t, *args, **kwargs): + def wrapper(t: float, *args: Any, **kwargs: Any) -> float: if 0 <= t <= 1: return function(t, *args, **kwargs) else: @@ -155,6 +161,33 @@ def smooth(t: float, inflection: float = 10.0) -> float: ) +@unit_interval +def smoothstep(t: float) -> float: + """Implementation of the 1st order SmoothStep sigmoid function. + The 1st derivative (speed) is zero at the endpoints. + https://en.wikipedia.org/wiki/Smoothstep + """ + return 3 * t**2 - 2 * t**3 + + +@unit_interval +def smootherstep(t: float) -> float: + """Implementation of the 2nd order SmoothStep sigmoid function. + The 1st and 2nd derivatives (speed and acceleration) are zero at the endpoints. + https://en.wikipedia.org/wiki/Smoothstep + """ + return 6 * t**5 - 15 * t**4 + 10 * t**3 + + +@unit_interval +def smoothererstep(t: float) -> float: + """Implementation of the 3rd order SmoothStep sigmoid function. + The 1st, 2nd and 3rd derivatives (speed, acceleration and jerk) are zero at the endpoints. + https://en.wikipedia.org/wiki/Smoothstep + """ + return 35 * t**4 - 84 * t**5 + 70 * t**6 - 20 * t**7 + + @unit_interval def rush_into(t: float, inflection: float = 10.0) -> float: return 2 * smooth(t / 2.0, inflection) @@ -167,7 +200,8 @@ def rush_from(t: float, inflection: float = 10.0) -> float: @unit_interval def slow_into(t: float) -> float: - return np.sqrt(1 - (1 - t) * (1 - t)) + val: float = np.sqrt(1 - (1 - t) * (1 - t)) + return val @unit_interval @@ -186,7 +220,7 @@ def there_and_back(t: float, inflection: float = 10.0) -> float: @zero def there_and_back_with_pause(t: float, pause_ratio: float = 1.0 / 3) -> float: - a = 1.0 / pause_ratio + a = 2.0 / (1.0 - pause_ratio) if t < 0.5 - pause_ratio / 2: return smooth(a * t) elif t < 0.5 + pause_ratio / 2: @@ -199,40 +233,60 @@ def there_and_back_with_pause(t: float, pause_ratio: float = 1.0 / 3) -> float: def running_start( t: float, pull_factor: float = -0.5, -) -> typing.Iterable: # what is func return type? - return bezier([0, 0, pull_factor, pull_factor, 1, 1, 1])(t) +) -> float: + t2 = t * t + t3 = t2 * t + t4 = t3 * t + t5 = t4 * t + t6 = t5 * t + mt = 1 - t + mt2 = mt * mt + mt3 = mt2 * mt + mt4 = mt3 * mt + + # This is equivalent to creating a Bézier with [0, 0, pull_factor, pull_factor, 1, 1, 1] + # and evaluating it at t. + return ( + 15 * t2 * mt4 * pull_factor + + 20 * t3 * mt3 * pull_factor + + 15 * t4 * mt2 + + 6 * t5 * mt + + t6 + ) def not_quite_there( - func: typing.Callable[[float], float] = smooth, + func: RateFunction = smooth, proportion: float = 0.7, -) -> typing.Callable[[float], float]: - def result(t): - return proportion * func(t) +) -> RateFunction: + def result(t: float, *args: Any, **kwargs: Any) -> float: + return proportion * func(t, *args, **kwargs) return result @zero def wiggle(t: float, wiggles: float = 2) -> float: - return there_and_back(t) * np.sin(wiggles * np.pi * t) + val: float = np.sin(wiggles * np.pi * t) + return there_and_back(t) * val def squish_rate_func( - func: typing.Callable[[float], float], + func: RateFunction, a: float = 0.4, b: float = 0.6, -) -> typing.Callable[[float], float]: - def result(t): +) -> RateFunction: + def result(t: float, *args: Any, **kwargs: Any) -> float: if a == b: return a if t < a: - return func(0) + new_t = 0.0 elif t > b: - return func(1) + new_t = 1.0 else: - return func((t - a) / (b - a)) + new_t = (t - a) / (b - a) + return func(new_t, *args, **kwargs) return result @@ -245,29 +299,37 @@ def result(t): @unit_interval def lingering(t: float) -> float: - return squish_rate_func(lambda t: t, 0, 0.8)(t) + def identity(t: float) -> float: + return t + + # TODO: Isn't this just 0.8 * t? + return squish_rate_func(identity, 0, 0.8)(t) @unit_interval def exponential_decay(t: float, half_life: float = 0.1) -> float: # The half-life should be rather small to minimize # the cut-off error at the end - return 1 - np.exp(-t / half_life) + val: float = 1 - np.exp(-t / half_life) + return val @unit_interval def ease_in_sine(t: float) -> float: - return 1 - np.cos((t * np.pi) / 2) + val: float = 1 - np.cos((t * np.pi) / 2) + return val @unit_interval def ease_out_sine(t: float) -> float: - return np.sin((t * np.pi) / 2) + val: float = np.sin((t * np.pi) / 2) + return val @unit_interval def ease_in_out_sine(t: float) -> float: - return -(np.cos(np.pi * t) - 1) / 2 + val: float = -(np.cos(np.pi * t) - 1) / 2 + return val @unit_interval @@ -404,7 +466,8 @@ def ease_in_elastic(t: float) -> float: elif t == 1: return 1 else: - return -pow(2, 10 * t - 10) * np.sin((t * 10 - 10.75) * c4) + val: float = -pow(2, 10 * t - 10) * np.sin((t * 10 - 10.75) * c4) + return val @unit_interval @@ -415,7 +478,8 @@ def ease_out_elastic(t: float) -> float: elif t == 1: return 1 else: - return pow(2, -10 * t) * np.sin((t * 10 - 0.75) * c4) + 1 + val: float = pow(2, -10 * t) * np.sin((t * 10 - 0.75) * c4) + 1 + return val @unit_interval @@ -426,9 +490,11 @@ def ease_in_out_elastic(t: float) -> float: elif t == 1: return 1 elif t < 0.5: - return -(pow(2, 20 * t - 10) * np.sin((20 * t - 11.125) * c5)) / 2 + val: float = -(pow(2, 20 * t - 10) * np.sin((20 * t - 11.125) * c5)) / 2 + return val else: - return (pow(2, -20 * t + 10) * np.sin((20 * t - 11.125) * c5)) / 2 + 1 + val = (pow(2, -20 * t + 10) * np.sin((20 * t - 11.125) * c5)) / 2 + 1 + return val @unit_interval diff --git a/manim/utils/simple_functions.py b/manim/utils/simple_functions.py index e5f05d2a7f..78951c1059 100644 --- a/manim/utils/simple_functions.py +++ b/manim/utils/simple_functions.py @@ -3,59 +3,137 @@ from __future__ import annotations __all__ = [ - "sigmoid", - "choose", - "get_parameters", "binary_search", + "choose", + "clip", + "sigmoid", ] -import inspect from functools import lru_cache +from typing import Any, Callable, Protocol, TypeVar import numpy as np from scipy import special -def sigmoid(x): - return 1.0 / (1 + np.exp(-x)) +def binary_search( + function: Callable[[float], float], + target: float, + lower_bound: float, + upper_bound: float, + tolerance: float = 1e-4, +) -> float | None: + """Searches for a value in a range by repeatedly dividing the range in half. + To be more precise, performs numerical binary search to determine the + input to ``function``, between the bounds given, that outputs ``target`` + to within ``tolerance`` (default of 0.0001). + Returns ``None`` if no input can be found within the bounds. -@lru_cache(maxsize=10) -def choose(n, k): - return special.comb(n, k, exact=True) + Examples + -------- + Consider the polynomial :math:`x^2 + 3x + 1` where we search for + a target value of :math:`11`. An exact solution is :math:`x = 2`. -def get_parameters(function): - return inspect.signature(function).parameters + :: + >>> solution = binary_search(lambda x: x**2 + 3*x + 1, 11, 0, 5) + >>> bool(abs(solution - 2) < 1e-4) + True + >>> solution = binary_search(lambda x: x**2 + 3*x + 1, 11, 0, 5, tolerance=0.01) + >>> bool(abs(solution - 2) < 0.01) + True -def clip(a, min_a, max_a): - if a < min_a: - return min_a - elif a > max_a: - return max_a - return a - + Searching in the interval :math:`[0, 5]` for a target value of :math:`71` + does not yield a solution:: -def binary_search(function, target, lower_bound, upper_bound, tolerance=1e-4): + >>> binary_search(lambda x: x**2 + 3*x + 1, 71, 0, 5) is None + True + """ lh = lower_bound rh = upper_bound + mh: float = np.mean(np.array([lh, rh])) while abs(rh - lh) > tolerance: - mh = np.mean([lh, rh]) + mh = np.mean(np.array([lh, rh])) lx, mx, rx = (function(h) for h in (lh, mh, rh)) if lx == target: return lh if rx == target: return rh - if lx <= target and rx >= target: + if lx <= target <= rx: if mx > target: rh = mh else: lh = mh - elif lx > target and rx < target: + elif lx > target > rx: lh, rh = rh, lh else: return None + return mh + + +@lru_cache(maxsize=10) +def choose(n: int, k: int) -> int: + r"""The binomial coefficient n choose k. + + :math:`\binom{n}{k}` describes the number of possible choices of + :math:`k` elements from a set of :math:`n` elements. + + References + ---------- + - https://en.wikipedia.org/wiki/Combination + - https://docs.scipy.org/doc/scipy/reference/generated/scipy.special.comb.html + """ + value: int = special.comb(n, k, exact=True) + return value + + +class Comparable(Protocol): + def __lt__(self, other: Any) -> bool: ... + + def __gt__(self, other: Any) -> bool: ... + + +ComparableT = TypeVar("ComparableT", bound=Comparable) # noqa: Y001 + + +def clip(a: ComparableT, min_a: ComparableT, max_a: ComparableT) -> ComparableT: + """Clips ``a`` to the interval [``min_a``, ``max_a``]. + + Accepts any comparable objects (i.e. those that support <, >). + Returns ``a`` if it is between ``min_a`` and ``max_a``. + Otherwise, whichever of ``min_a`` and ``max_a`` is closest. + + Examples + -------- + :: + + >>> clip(15, 11, 20) + 15 + >>> clip('a', 'h', 'k') + 'h' + """ + if a < min_a: + return min_a + elif a > max_a: + return max_a + return a + + +def sigmoid(x: float) -> float: + r"""Returns the output of the logistic function. + + The logistic function, a common example of a sigmoid function, is defined + as :math:`\frac{1}{1 + e^{-x}}`. + + References + ---------- + - https://en.wikipedia.org/wiki/Sigmoid_function + - https://en.wikipedia.org/wiki/Logistic_function + """ + value: float = 1.0 / (1 + np.exp(-x)) + return value diff --git a/manim/utils/sounds.py b/manim/utils/sounds.py index 5e0ea060f3..de7b6be80e 100644 --- a/manim/utils/sounds.py +++ b/manim/utils/sounds.py @@ -6,13 +6,19 @@ "get_full_sound_file_path", ] +from typing import TYPE_CHECKING from .. import config from ..utils.file_ops import seek_full_path_from_defaults +if TYPE_CHECKING: + from pathlib import Path + + from manim.typing import StrPath + # Still in use by add_sound() function in scene_file_writer.py -def get_full_sound_file_path(sound_file_name): +def get_full_sound_file_path(sound_file_name: StrPath) -> Path: return seek_full_path_from_defaults( sound_file_name, default_dir=config.get_dir("assets_dir"), diff --git a/manim/utils/space_ops.py b/manim/utils/space_ops.py index 7f14c27500..963c0811ee 100644 --- a/manim/utils/space_ops.py +++ b/manim/utils/space_ops.py @@ -2,6 +2,35 @@ from __future__ import annotations +import itertools as it +from collections.abc import Sequence +from typing import TYPE_CHECKING, Callable + +import numpy as np +from mapbox_earcut import triangulate_float32 as earcut +from scipy.spatial.transform import Rotation + +from manim.constants import DOWN, OUT, PI, RIGHT, TAU, UP +from manim.utils.iterables import adjacent_pairs + +if TYPE_CHECKING: + import numpy.typing as npt + + from manim.typing import ( + ManimFloat, + MatrixMN, + Point2D_Array, + Point3D, + Point3DLike, + Point3DLike_Array, + PointND, + PointNDLike_Array, + Vector2D, + Vector2D_Array, + Vector3D, + Vector3D_Array, + ) + __all__ = [ "quaternion_mult", "quaternion_from_angle_axis", @@ -36,21 +65,19 @@ ] -import itertools as it -import math -from typing import Sequence - -import numpy as np -from mapbox_earcut import triangulate_float32 as earcut -from scipy.spatial.transform import Rotation - -from .. import config -from ..constants import DOWN, OUT, PI, RIGHT, TAU, UP -from ..utils.iterables import adjacent_pairs +def norm_squared(v: float) -> float: + val: float = np.dot(v, v) + return val -def norm_squared(v: float) -> float: - return np.dot(v, v) +def cross(v1: Vector3D, v2: Vector3D) -> Vector3D: + return np.array( + [ + v1[1] * v2[2] - v1[2] * v2[1], + v1[2] * v2[0] - v1[0] * v2[2], + v1[0] * v2[1] - v1[1] * v2[0], + ] + ) # Quaternions @@ -69,34 +96,19 @@ def quaternion_mult( Union[np.ndarray, List[Union[float, np.ndarray]]] Returns a list of product of two quaternions. """ - if config.renderer == "opengl": - if len(quats) == 0: - return [1, 0, 0, 0] - result = quats[0] - for next_quat in quats[1:]: - w1, x1, y1, z1 = result - w2, x2, y2, z2 = next_quat - result = [ - w1 * w2 - x1 * x2 - y1 * y2 - z1 * z2, - w1 * x2 + x1 * w2 + y1 * z2 - z1 * y2, - w1 * y2 + y1 * w2 + z1 * x2 - x1 * z2, - w1 * z2 + z1 * w2 + x1 * y2 - y1 * x2, - ] - return result - else: - q1 = quats[0] - q2 = quats[1] - - w1, x1, y1, z1 = q1 - w2, x2, y2, z2 = q2 - return np.array( - [ - w1 * w2 - x1 * x2 - y1 * y2 - z1 * z2, - w1 * x2 + x1 * w2 + y1 * z2 - z1 * y2, - w1 * y2 + y1 * w2 + z1 * x2 - x1 * z2, - w1 * z2 + z1 * w2 + x1 * y2 - y1 * x2, - ], - ) + if len(quats) == 0: + return [1, 0, 0, 0] + result = quats[0] + for next_quat in quats[1:]: + w1, x1, y1, z1 = result + w2, x2, y2, z2 = next_quat + result = [ + w1 * w2 - x1 * x2 - y1 * y2 - z1 * z2, + w1 * x2 + x1 * w2 + y1 * z2 - z1 * y2, + w1 * y2 + y1 * w2 + z1 * x2 - x1 * z2, + w1 * z2 + z1 * w2 + x1 * y2 - y1 * x2, + ] + return result def quaternion_from_angle_axis( @@ -114,20 +126,17 @@ def quaternion_from_angle_axis( The angle for the quaternion. axis The axis for the quaternion - axis_normalized : bool, optional + axis_normalized Checks whether the axis is normalized, by default False Returns ------- - List[float] + list[float] Gives back a quaternion from the angle and axis """ - if config.renderer == "opengl": - if not axis_normalized: - axis = normalize(axis) - return [math.cos(angle / 2), *(math.sin(angle / 2) * axis)] - else: - return np.append(np.cos(angle / 2), np.sin(angle / 2) * normalize(axis)) + if not axis_normalized: + axis = normalize(axis) + return [np.cos(angle / 2), *(np.sin(angle / 2) * axis)] def angle_axis_from_quaternion(quaternion: Sequence[float]) -> Sequence[float]: @@ -192,7 +201,6 @@ def rotate_vector( ValueError If vector is not of dimension 2 or 3. """ - if len(vector) > 3: raise ValueError("Vector must have the correct dimensions.") if len(vector) == 2: @@ -200,7 +208,7 @@ def rotate_vector( return rotation_matrix(angle, axis) @ vector -def thick_diagonal(dim: int, thickness=2) -> np.ndarray: +def thick_diagonal(dim: int, thickness: int = 2) -> MatrixMN: row_indices = np.arange(dim).repeat(dim).reshape((dim, dim)) col_indices = np.transpose(row_indices) return (np.abs(row_indices - col_indices) < thickness).astype("uint8") @@ -248,9 +256,7 @@ def rotation_matrix( axis: np.ndarray, homogeneous: bool = False, ) -> np.ndarray: - """ - Rotation in R^3 about a specified axis of rotation. - """ + """Rotation in R^3 about a specified axis of rotation.""" inhomogeneous_rotation_matrix = Rotation.from_rotvec( angle * normalize(np.array(axis)) ).as_matrix() @@ -267,7 +273,7 @@ def rotation_about_z(angle: float) -> np.ndarray: Parameters ---------- - angle : float + angle Angle for the rotation matrix. Returns @@ -275,7 +281,7 @@ def rotation_about_z(angle: float) -> np.ndarray: np.ndarray Gives back the rotated matrix. """ - c, s = math.cos(angle), math.sin(angle) + c, s = np.cos(angle), np.sin(angle) return np.array( [ [c, -s, 0], @@ -291,17 +297,17 @@ def z_to_vector(vector: np.ndarray) -> np.ndarray: (normalized) vector provided as an argument """ axis_z = normalize(vector) - axis_y = normalize(np.cross(axis_z, RIGHT)) - axis_x = np.cross(axis_y, axis_z) + axis_y = normalize(cross(axis_z, RIGHT)) + axis_x = cross(axis_y, axis_z) if np.linalg.norm(axis_y) == 0: # the vector passed just so happened to be in the x direction. - axis_x = normalize(np.cross(UP, axis_z)) - axis_y = -np.cross(axis_x, axis_z) + axis_x = normalize(cross(UP, axis_z)) + axis_y = -cross(axis_x, axis_z) return np.array([axis_x, axis_y, axis_z]).T -def angle_of_vector(vector: Sequence[float]) -> float: +def angle_of_vector(vector: Sequence[float] | np.ndarray) -> float: """Returns polar coordinate theta when vector is projected on xy plane. Parameters @@ -314,10 +320,19 @@ def angle_of_vector(vector: Sequence[float]) -> float: float The angle of the vector projected. """ - return np.angle(complex(*vector[:2])) - - -def angle_between_vectors(v1: np.ndarray, v2: np.ndarray) -> np.ndarray: + if isinstance(vector, np.ndarray) and len(vector.shape) > 1: + if vector.shape[0] < 2: + raise ValueError("Vector must have the correct dimensions. (2, n)") + c_vec = np.empty(vector.shape[1], dtype=np.complex128) + c_vec.real = vector[0] + c_vec.imag = vector[1] + val1: float = np.angle(c_vec) + return val1 + val: float = np.angle(complex(*vector[:2])) + return val + + +def angle_between_vectors(v1: np.ndarray, v2: np.ndarray) -> float: """Returns the angle between two vectors. This angle will always be between 0 and pi @@ -330,17 +345,20 @@ def angle_between_vectors(v1: np.ndarray, v2: np.ndarray) -> np.ndarray: Returns ------- - np.ndarray + float The angle between the vectors. """ - - return 2 * np.arctan2( + val: float = 2 * np.arctan2( np.linalg.norm(normalize(v1) - normalize(v2)), np.linalg.norm(normalize(v1) + normalize(v2)), ) + return val + -def normalize(vect: np.ndarray | tuple[float], fall_back=None) -> np.ndarray: +def normalize( + vect: np.ndarray | tuple[float], fall_back: np.ndarray | None = None +) -> np.ndarray: norm = np.linalg.norm(vect) if norm > 0: return np.array(vect) / norm @@ -370,7 +388,7 @@ def normalize_along_axis(array: np.ndarray, axis: np.ndarray) -> np.ndarray: return array -def get_unit_normal(v1: np.ndarray, v2: np.ndarray, tol: float = 1e-6) -> np.ndarray: +def get_unit_normal(v1: Vector3D, v2: Vector3D, tol: float = 1e-6) -> Vector3D: """Gets the unit normal of the vectors. Parameters @@ -387,16 +405,37 @@ def get_unit_normal(v1: np.ndarray, v2: np.ndarray, tol: float = 1e-6) -> np.nda np.ndarray The normal of the two vectors. """ - v1, v2 = (normalize(i) for i in (v1, v2)) - cp = np.cross(v1, v2) - cp_norm = np.linalg.norm(cp) - if cp_norm < tol: - # Vectors align, so find a normal to them in the plane shared with the z-axis - cp = np.cross(np.cross(v1, OUT), v1) - cp_norm = np.linalg.norm(cp) - if cp_norm < tol: + # Instead of normalizing v1 and v2, just divide by the greatest + # of all their absolute components, which is just enough + div1, div2 = max(np.abs(v1)), max(np.abs(v2)) + if div1 == 0.0: + if div2 == 0.0: return DOWN - return normalize(cp) + u = v2 / div2 + elif div2 == 0.0: + u = v1 / div1 + else: + # Normal scenario: v1 and v2 are both non-null + u1, u2 = v1 / div1, v2 / div2 + cp = cross(u1, u2) + cp_norm = np.sqrt(norm_squared(cp)) + if cp_norm > tol: + return cp / cp_norm + # Otherwise, v1 and v2 were aligned + u = u1 + + # If you are here, you have an "unique", non-zero, unit-ish vector u + # If it's also too aligned to the Z axis, just return DOWN + if abs(u[0]) < tol and abs(u[1]) < tol: + return DOWN + # Otherwise rotate u in the plane it shares with the Z axis, + # 90° TOWARDS the Z axis. This is done via (u x [0, 0, 1]) x u, + # which gives [-xz, -yz, x²+y²] (slightly scaled as well) + cp = np.array([-u[0] * u[2], -u[1] * u[2], u[0] * u[0] + u[1] * u[1]]) + cp_norm = np.sqrt(norm_squared(cp)) + # Because the norm(u) == 0 case was filtered in the beginning, + # there is no need to check if the norm of cp is 0 + return cp / cp_norm ### @@ -445,12 +484,8 @@ def regular_vertices( start_angle : :class:`float` The angle the vertices start at. """ - if start_angle is None: - if n % 2 == 0: - start_angle = 0 - else: - start_angle = TAU / 4 + start_angle = 0 if n % 2 == 0 else TAU / 4 start_vector = rotate_vector(RIGHT * radius, start_angle) vertices = compass_directions(n, start_vector) @@ -466,11 +501,13 @@ def R3_to_complex(point: Sequence[float]) -> np.ndarray: return complex(*point[:2]) -def complex_func_to_R3_func(complex_func): +def complex_func_to_R3_func( + complex_func: Callable[[complex], complex], +) -> Callable[[Point3DLike], Point3D]: return lambda p: complex_to_R3(complex_func(R3_to_complex(p))) -def center_of_mass(points: Sequence[float]) -> np.ndarray: +def center_of_mass(points: PointNDLike_Array) -> PointND: """Gets the center of mass of the points in space. Parameters @@ -540,8 +577,8 @@ def line_intersection( np.pad(np.array(i)[:, :2], ((0, 0), (0, 1)), constant_values=1) for i in (line1, line2) ) - line1, line2 = (np.cross(*i) for i in padded) - x, y, z = np.cross(line1, line2) + line1, line2 = (cross(*i) for i in padded) + x, y, z = cross(line1, line2) if z == 0: raise ValueError( @@ -552,12 +589,12 @@ def line_intersection( def find_intersection( - p0s: Sequence[np.ndarray], - v0s: Sequence[np.ndarray], - p1s: Sequence[np.ndarray], - v1s: Sequence[np.ndarray], + p0s: Point3DLike_Array, + v0s: Vector3D_Array, + p1s: Point3DLike_Array, + v1s: Vector3D_Array, threshold: float = 1e-5, -) -> Sequence[np.ndarray]: +) -> list[Point3D]: """ Return the intersection of a line passing through p0 in direction v0 with one passing through p1 in direction v1 (or array of intersections @@ -569,22 +606,45 @@ def find_intersection( result = [] for p0, v0, p1, v1 in zip(*[p0s, v0s, p1s, v1s]): - normal = np.cross(v1, np.cross(v0, v1)) + normal = cross(v1, cross(v0, v1)) denom = max(np.dot(v0, normal), threshold) result += [p0 + np.dot(p1 - p0, normal) / denom * v0] return result -def get_winding_number(points: Sequence[float]) -> float: - total_angle = 0 +def get_winding_number(points: Sequence[np.ndarray]) -> float: + """Determine the number of times a polygon winds around the origin. + + The orientation is measured mathematically positively, i.e., + counterclockwise. + + Parameters + ---------- + points + The vertices of the polygon being queried. + + Examples + -------- + + >>> from manim import Square, get_winding_number + >>> polygon = Square() + >>> get_winding_number(polygon.get_vertices()) + np.float64(1.0) + >>> polygon.shift(2 * UP) + Square + >>> get_winding_number(polygon.get_vertices()) + np.float64(0.0) + """ + total_angle: float = 0 for p1, p2 in adjacent_pairs(points): d_angle = angle_of_vector(p2) - angle_of_vector(p1) d_angle = ((d_angle + PI) % TAU) - PI total_angle += d_angle - return total_angle / TAU + val: float = total_angle / TAU + return val -def shoelace(x_y: np.ndarray) -> float: +def shoelace(x_y: Point2D_Array) -> float: """2D implementation of the shoelace formula. Returns @@ -594,10 +654,11 @@ def shoelace(x_y: np.ndarray) -> float: """ x = x_y[:, 0] y = x_y[:, 1] - return np.trapz(y, x) + val: float = np.trapz(y, x) + return val -def shoelace_direction(x_y: np.ndarray) -> str: +def shoelace_direction(x_y: Point2D_Array) -> str: """ Uses the area determined by the shoelace method to determine whether the input set of points is directed clockwise or counterclockwise. @@ -611,7 +672,39 @@ def shoelace_direction(x_y: np.ndarray) -> str: return "CW" if area > 0 else "CCW" -def cross2d(a, b): +def cross2d( + a: Vector2D | Vector2D_Array, + b: Vector2D | Vector2D_Array, +) -> ManimFloat | npt.NDArray[ManimFloat]: + """Compute the determinant(s) of the passed + vector (sequences). + + Parameters + ---------- + a + A vector or a sequence of vectors. + b + A vector or a sequence of vectors. + + Returns + ------- + Sequence[float] | float + The determinant or sequence of determinants + of the first two components of the specified + vectors. + + Examples + -------- + .. code-block:: pycon + + >>> cross2d(np.array([1, 2]), np.array([3, 4])) + np.int64(-2) + >>> cross2d( + ... np.array([[1, 2, 0], [1, 0, 0]]), + ... np.array([[3, 4, 0], [0, 1, 0]]), + ... ) + array([-2, 1]) + """ if len(a.shape) == 2: return a[:, 0] * b[:, 1] - a[:, 1] * b[:, 0] else: @@ -628,7 +721,7 @@ def earclip_triangulation(verts: np.ndarray, ring_ends: list) -> list: verts is a numpy array of points. ring_ends ring_ends is a list of indices indicating where - the ends of new paths are. + the ends of new paths are. Returns ------- @@ -673,12 +766,17 @@ def earclip_triangulation(verts: np.ndarray, ring_ends: list) -> list: # Move the ring which j belongs to from the # attached list to the detached list - new_ring = next(filter(lambda ring: ring[0] <= j < ring[-1], detached_rings)) - detached_rings.remove(new_ring) - attached_rings.append(new_ring) + new_ring = next( + (ring for ring in detached_rings if ring[0] <= j < ring[-1]), None + ) + if new_ring is not None: + detached_rings.remove(new_ring) + attached_rings.append(new_ring) + else: + raise Exception("Could not find a ring to attach") # Setup linked list - after = [] + after: list[int] = [] end0 = 0 for end1 in ring_ends: after.extend(range(end0 + 1, end1)) @@ -749,7 +847,7 @@ def spherical_to_cartesian(spherical: Sequence[float]) -> np.ndarray: def perpendicular_bisector( line: Sequence[np.ndarray], - norm_vector=OUT, + norm_vector: Vector3D = OUT, ) -> Sequence[np.ndarray]: """Returns a list of two points that correspond to the ends of the perpendicular bisector of the @@ -772,6 +870,6 @@ def perpendicular_bisector( """ p1 = line[0] p2 = line[1] - direction = np.cross(p1 - p2, norm_vector) + direction = cross(p1 - p2, norm_vector) m = midpoint(p1, p2) return [m + direction, m - direction] diff --git a/manim/utils/testing/__init__.py b/manim/utils/testing/__init__.py index e69de29bb2..f8d47040ed 100644 --- a/manim/utils/testing/__init__.py +++ b/manim/utils/testing/__init__.py @@ -0,0 +1,17 @@ +"""Utilities for Manim tests using `pytest `_. + +For more information about Manim testing, see: + +- :doc:`/contributing/development`, specifically the ``Tests`` bullet + point under :ref:`polishing-changes-and-submitting-a-pull-request` +- :doc:`/contributing/testing` + +.. autosummary:: + :toctree: ../reference + + frames_comparison + _frames_testers + _show_diff + _test_class_makers + +""" diff --git a/manim/utils/testing/_frames_testers.py b/manim/utils/testing/_frames_testers.py index 0496583c15..aa382bb7be 100644 --- a/manim/utils/testing/_frames_testers.py +++ b/manim/utils/testing/_frames_testers.py @@ -1,17 +1,25 @@ from __future__ import annotations import contextlib +import logging +import warnings +from collections.abc import Generator from pathlib import Path import numpy as np -from manim import logger +from manim.typing import PixelArray from ._show_diff import show_diff_helper +FRAME_ABSOLUTE_TOLERANCE = 1.01 +FRAME_MISMATCH_RATIO_TOLERANCE = 1e-5 + +logger = logging.getLogger("manim") + class _FramesTester: - def __init__(self, file_path: Path, show_diff=False) -> None: + def __init__(self, file_path: Path, show_diff: bool = False) -> None: self._file_path = file_path self._show_diff = show_diff self._frames: np.ndarray @@ -19,7 +27,7 @@ def __init__(self, file_path: Path, show_diff=False) -> None: self._frames_compared = 0 @contextlib.contextmanager - def testing(self): + def testing(self) -> Generator[None, None, None]: with np.load(self._file_path) as data: self._frames = data["frame_data"] # For backward compatibility, when the control data contains only one frame (<= v0.8.0) @@ -33,7 +41,7 @@ def testing(self): f"when there are {self._number_frames} control frames for this test." ) - def check_frame(self, frame_number: int, frame: np.ndarray): + def check_frame(self, frame_number: int, frame: PixelArray) -> None: assert frame_number < self._number_frames, ( f"The tested scene is at frame number {frame_number} " f"when there are {self._number_frames} control frames." @@ -42,14 +50,35 @@ def check_frame(self, frame_number: int, frame: np.ndarray): np.testing.assert_allclose( frame, self._frames[frame_number], - atol=1.01, + atol=FRAME_ABSOLUTE_TOLERANCE, err_msg=f"Frame no {frame_number}. You can use --show_diff to visually show the difference.", verbose=False, ) self._frames_compared += 1 except AssertionError as e: + number_of_matches = np.isclose( + frame, self._frames[frame_number], atol=FRAME_ABSOLUTE_TOLERANCE + ).sum() + number_of_mismatches = frame.size - number_of_matches + if number_of_mismatches / frame.size < FRAME_MISMATCH_RATIO_TOLERANCE: + # we tolerate a small (< 0.001%) amount of pixel value errors + # in the tests, this accounts for minor OS dependent inconsistencies + self._frames_compared += 1 + warnings.warn( + f"Mismatch of {number_of_mismatches} pixel values in frame {frame_number} " + f"against control data in {self._file_path}. Below error threshold, " + "continuing...", + stacklevel=1, + ) + return + if self._show_diff: - show_diff_helper(frame_number, frame, self._frames[frame_number]) + show_diff_helper( + frame_number, + frame, + self._frames[frame_number], + self._file_path.name, + ) raise e @@ -60,17 +89,17 @@ def __init__(self, file_path: Path, size_frame: tuple) -> None: self._number_frames_written: int = 0 # Actually write a frame. - def check_frame(self, index: int, frame: np.ndarray): + def check_frame(self, index: int, frame: PixelArray) -> None: frame = frame[np.newaxis, ...] self.frames = np.concatenate((self.frames, frame)) self._number_frames_written += 1 @contextlib.contextmanager - def testing(self): + def testing(self) -> Generator[None, None, None]: yield self.save_contol_data() - def save_contol_data(self): + def save_contol_data(self) -> None: self.frames = self.frames.astype("uint8") np.savez_compressed(self.file_path, frame_data=self.frames) logger.info( diff --git a/manim/utils/testing/_show_diff.py b/manim/utils/testing/_show_diff.py index 0e80295ef6..e1783a401f 100644 --- a/manim/utils/testing/_show_diff.py +++ b/manim/utils/testing/_show_diff.py @@ -1,13 +1,19 @@ from __future__ import annotations +import logging +import warnings + import numpy as np +from manim.typing import PixelArray + def show_diff_helper( frame_number: int, - frame_data: np.ndarray, - expected_frame_data: np.ndarray, -): + frame_data: PixelArray, + expected_frame_data: PixelArray, + control_data_filename: str, +) -> None: """Will visually display with matplotlib differences between frame generated and the one expected.""" import matplotlib.gridspec as gridspec import matplotlib.pyplot as plt @@ -18,11 +24,11 @@ def show_diff_helper( ax = fig.add_subplot(gs[0, 0]) ax.imshow(frame_data) - ax.set_title("Generated :") + ax.set_title("Generated") ax = fig.add_subplot(gs[0, 1]) ax.imshow(expected_frame_data) - ax.set_title("Expected :") + ax.set_title("Expected") ax = fig.add_subplot(gs[1, :]) diff_im = expected_frame_data.copy() @@ -37,6 +43,16 @@ def show_diff_helper( np.array([255, 0, 0, 255], dtype="uint8"), ) # Set any different pixels to red ax.imshow(diff_im, interpolation="nearest") - ax.set_title("Differences summary : (green = same, red = different)") - - plt.show() + ax.set_title("Difference summary: (green = same, red = different)") + + with warnings.catch_warnings(): + warnings.simplefilter("error") + try: + plt.show() + except UserWarning: + filename = f"{control_data_filename[:-4]}-diff.pdf" + plt.savefig(filename) + logging.warning( + "Interactive matplotlib interface not available," + f" diff saved to {filename}." + ) diff --git a/manim/utils/testing/_test_class_makers.py b/manim/utils/testing/_test_class_makers.py index aa9ab4f14f..084aab487b 100644 --- a/manim/utils/testing/_test_class_makers.py +++ b/manim/utils/testing/_test_class_makers.py @@ -1,9 +1,12 @@ from __future__ import annotations -from typing import Callable +from typing import Any, Callable +from manim.renderer.cairo_renderer import CairoRenderer +from manim.renderer.opengl_renderer import OpenGLRenderer from manim.scene.scene import Scene from manim.scene.scene_file_writer import SceneFileWriter +from manim.typing import PixelArray, StrPath from ._frames_testers import _FramesTester @@ -11,13 +14,14 @@ def _make_test_scene_class( base_scene: type[Scene], construct_test: Callable[[Scene], None], - test_renderer, + test_renderer: CairoRenderer | OpenGLRenderer | None, ) -> type[Scene]: - class _TestedScene(base_scene): - def __init__(self, *args, **kwargs): - super().__init__(renderer=test_renderer, *args, **kwargs) + # TODO: Get the type annotation right for the base_scene argument. + class _TestedScene(base_scene): # type: ignore[valid-type, misc] + def __init__(self, *args: Any, **kwargs: Any) -> None: + super().__init__(*args, renderer=test_renderer, **kwargs) - def construct(self): + def construct(self) -> None: construct_test(self) # Manim hack to render the very last frame (normally the last frame is not the very end of the animation) @@ -28,7 +32,7 @@ def construct(self): return _TestedScene -def _make_test_renderer_class(from_renderer): +def _make_test_renderer_class(from_renderer: type) -> Any: # Just for inheritance. class _TestRenderer(from_renderer): pass @@ -39,39 +43,50 @@ class _TestRenderer(from_renderer): class DummySceneFileWriter(SceneFileWriter): """Delegate of SceneFileWriter used to test the frames.""" - def __init__(self, renderer, scene_name, **kwargs): + def __init__( + self, + renderer: CairoRenderer | OpenGLRenderer, + scene_name: StrPath, + **kwargs: Any, + ) -> None: super().__init__(renderer, scene_name, **kwargs) self.i = 0 - def init_output_directories(self, scene_name): + def init_output_directories(self, scene_name: StrPath) -> None: pass - def add_partial_movie_file(self, hash_animation): + def add_partial_movie_file(self, hash_animation: str) -> None: pass - def begin_animation(self, allow_write=True): + def begin_animation( + self, allow_write: bool = True, file_path: StrPath | None = None + ) -> Any: pass - def end_animation(self, allow_write): + def end_animation(self, allow_write: bool = False) -> None: pass - def combine_to_movie(self): + def combine_to_movie(self) -> None: pass - def combine_to_section_videos(self): + def combine_to_section_videos(self) -> None: pass - def clean_cache(self): + def clean_cache(self) -> None: pass - def write_frame(self, frame_or_renderer): + def write_frame( + self, frame_or_renderer: PixelArray | OpenGLRenderer, num_frames: int = 1 + ) -> None: self.i += 1 def _make_scene_file_writer_class(tester: _FramesTester) -> type[SceneFileWriter]: class TestSceneFileWriter(DummySceneFileWriter): - def write_frame(self, frame_or_renderer): + def write_frame( + self, frame_or_renderer: PixelArray | OpenGLRenderer, num_frames: int = 1 + ) -> None: tester.check_frame(self.i, frame_or_renderer) - super().write_frame(frame_or_renderer) + super().write_frame(frame_or_renderer, num_frames=num_frames) return TestSceneFileWriter diff --git a/manim/utils/testing/frames_comparison.py b/manim/utils/testing/frames_comparison.py index e839145e28..7b5f23f8c8 100644 --- a/manim/utils/testing/frames_comparison.py +++ b/manim/utils/testing/frames_comparison.py @@ -3,8 +3,10 @@ import functools import inspect from pathlib import Path -from typing import Callable +from typing import Any, Callable +import cairo +import pytest from _pytest.fixtures import FixtureRequest from manim import Scene @@ -12,7 +14,9 @@ from manim._config.utils import ManimConfig from manim.camera.three_d_camera import ThreeDCamera from manim.renderer.cairo_renderer import CairoRenderer +from manim.renderer.opengl_renderer import OpenGLRenderer from manim.scene.three_d_scene import ThreeDScene +from manim.typing import StrPath from ._frames_testers import _ControlDataWriter, _FramesTester from ._test_class_makers import ( @@ -25,16 +29,17 @@ SCENE_PARAMETER_NAME = "scene" _tests_root_dir_path = Path(__file__).absolute().parents[2] PATH_CONTROL_DATA = _tests_root_dir_path / Path("control_data", "graphical_units_data") +MIN_CAIRO_VERSION = 11800 def frames_comparison( - func=None, + func: Callable | None = None, *, last_frame: bool = True, - renderer_class=CairoRenderer, - base_scene=Scene, - **custom_config, -): + renderer_class: type[CairoRenderer | OpenGLRenderer] = CairoRenderer, + base_scene: type[Scene] = Scene, + **custom_config: Any, +) -> Callable: """Compares the frames generated by the test with control frames previously registered. If there is no control frames for this test, the test will fail. To generate @@ -45,10 +50,6 @@ def frames_comparison( Parameters ---------- - test_name - The name of the test. - module_name - The module which the test belongs to. last_frame whether the test should test the last frame, by default True. renderer_class @@ -61,7 +62,7 @@ def frames_comparison( If the scene has a moving animation, then the test must set last_frame to False. """ - def decorator_maker(tested_scene_construct): + def decorator_maker(tested_scene_construct: Callable) -> Callable: if ( SCENE_PARAMETER_NAME not in inspect.getfullargspec(tested_scene_construct).args @@ -80,19 +81,30 @@ def decorator_maker(tested_scene_construct): "There is no module test name indicated for the graphical unit test. You have to declare __module_test__ in the test file.", ) module_name = tested_scene_construct.__globals__.get("__module_test__") + assert isinstance(module_name, str) test_name = tested_scene_construct.__name__[len("test_") :] @functools.wraps(tested_scene_construct) # The "request" parameter is meant to be used as a fixture by pytest. See below. - def wrapper(*args, request: FixtureRequest, tmp_path, **kwargs): + def wrapper( + *args: Any, request: FixtureRequest, tmp_path: StrPath, **kwargs: Any + ) -> None: + # check for cairo version + if ( + renderer_class is CairoRenderer + and cairo.cairo_version() < MIN_CAIRO_VERSION + ): + pytest.skip("Cairo version is too old. Skipping cairo graphical tests.") # Wraps the test_function to a construct method, to "freeze" the eventual additional arguments (parametrizations fixtures). construct = functools.partial(tested_scene_construct, *args, **kwargs) # Kwargs contains the eventual parametrization arguments. - # This modify the test_name so the it is defined by the parametrization arguments too. - # Ex : if "length" is parametrized from 0 to 20, the kwargs will be with once with {"length" : 1}, etc. + # This modifies the test_name so that it is defined by the parametrization + # arguments too. + # Example: if "length" is parametrized from 0 to 20, the kwargs + # will be once with {"length" : 1}, etc. test_name_with_param = test_name + "_".join( - map(lambda tup: f"{str(tup[0])}:{str(tup[1])}", kwargs.items()), + f"_{str(tup[0])}[{str(tup[1])}]" for tup in kwargs.items() ) config_tests = _config_test(last_frame) @@ -139,13 +151,13 @@ def wrapper(*args, request: FixtureRequest, tmp_path, **kwargs): inspect.Parameter("tmp_path", inspect.Parameter.KEYWORD_ONLY), ] new_sig = old_sig.replace(parameters=parameters) - wrapper.__signature__ = new_sig + wrapper.__signature__ = new_sig # type: ignore[attr-defined] # Reach a bit into pytest internals to hoist the marks from our wrapped # function. - setattr(wrapper, "pytestmark", []) + wrapper.pytestmark = [] # type: ignore[attr-defined] new_marks = getattr(tested_scene_construct, "pytestmark", []) - wrapper.pytestmark = new_marks + wrapper.pytestmark = new_marks # type: ignore[attr-defined] return wrapper # Case where the decorator is called with and without parentheses. @@ -159,7 +171,7 @@ def _make_test_comparing_frames( file_path: Path, base_scene: type[Scene], construct: Callable[[Scene], None], - renderer_class, # Renderer type, there is no superclass renderer yet ..... + renderer_class: type, # Renderer type, there is no superclass renderer yet ..... is_set_test_data_test: bool, last_frame: bool, show_diff: bool, @@ -169,15 +181,15 @@ def _make_test_comparing_frames( Parameters ---------- - file_path : Path + file_path The path of the control frames. - base_scene : Type[Scene] + base_scene The base scene class. - construct : Callable[[Scene], None] + construct The construct method (= the test function) - renderer_class : [type] + renderer_class The renderer base class. - show_diff : bool + show_diff whether to visually show_diff (see --show_diff) Returns @@ -185,9 +197,10 @@ def _make_test_comparing_frames( Callable[[], None] The pytest test. """ - if is_set_test_data_test: - frames_tester = _ControlDataWriter(file_path, size_frame=size_frame) + frames_tester: _FramesTester = _ControlDataWriter( + file_path, size_frame=size_frame + ) else: frames_tester = _FramesTester(file_path, show_diff=show_diff) @@ -198,7 +211,7 @@ def _make_test_comparing_frames( ) testRenderer = _make_test_renderer_class(renderer_class) - def real_test(): + def real_test() -> None: with frames_tester.testing(): sceneTested = _make_test_scene_class( base_scene=base_scene, @@ -207,11 +220,13 @@ def real_test(): # If you pass a custom renderer to the Scene, the Camera class given as an argument in the Scene # is not passed to the renderer. See __init__ of Scene. # This potentially prevents OpenGL testing. - test_renderer=testRenderer(file_writer_class=file_writer_class) - if base_scene is not ThreeDScene - else testRenderer( - file_writer_class=file_writer_class, - camera_class=ThreeDCamera, + test_renderer=( + testRenderer(file_writer_class=file_writer_class) + if base_scene is not ThreeDScene + else testRenderer( + file_writer_class=file_writer_class, + camera_class=ThreeDCamera, + ) ), # testRenderer(file_writer_class=file_writer_class), ) scene_tested = sceneTested(skip_animations=True) diff --git a/manim/utils/tex.py b/manim/utils/tex.py index 2ace7f230c..50f5f2dfc8 100644 --- a/manim/utils/tex.py +++ b/manim/utils/tex.py @@ -4,150 +4,135 @@ __all__ = [ "TexTemplate", - "TexTemplateFromFile", ] import copy import re +import warnings +from dataclasses import dataclass, field +from pathlib import Path +from typing import TYPE_CHECKING, Any +if TYPE_CHECKING: + from typing_extensions import Self -class TexTemplate: - """TeX templates are used for creating Tex() and MathTex() objects. - - Parameters - ---------- - tex_compiler : Optional[:class:`str`], optional - The TeX compiler to be used, e.g. ``latex``, ``pdflatex`` or ``lualatex`` - output_format : Optional[:class:`str`], optional - The output format resulting from compilation, e.g. ``.dvi`` or ``.pdf`` - documentclass : Optional[:class:`str`], optional - The command defining the documentclass, e.g. ``\\documentclass[preview]{standalone}`` - preamble : Optional[:class:`str`], optional - The document's preamble, i.e. the part between ``\\documentclass`` and ``\\begin{document}`` - placeholder_text : Optional[:class:`str`], optional - Text in the document that will be replaced by the expression to be rendered - post_doc_commands : Optional[:class:`str`], optional - Text (definitions, commands) to be inserted at right after ``\\begin{document}``, e.g. ``\\boldmath`` - - Attributes - ---------- - tex_compiler : :class:`str` - The TeX compiler to be used, e.g. ``latex``, ``pdflatex`` or ``lualatex`` - output_format : :class:`str` - The output format resulting from compilation, e.g. ``.dvi`` or ``.pdf`` - documentclass : :class:`str` - The command defining the documentclass, e.g. ``\\documentclass[preview]{standalone}`` - preamble : :class:`str` - The document's preamble, i.e. the part between ``\\documentclass`` and ``\\begin{document}`` - placeholder_text : :class:`str` - Text in the document that will be replaced by the expression to be rendered - post_doc_commands : :class:`str` - Text (definitions, commands) to be inserted at right after ``\\begin{document}``, e.g. ``\\boldmath`` - """ + from manim.typing import StrPath - default_documentclass = r"\documentclass[preview]{standalone}" - default_preamble = r""" -\usepackage[english]{babel} +_DEFAULT_PREAMBLE = r"""\usepackage[english]{babel} \usepackage{amsmath} -\usepackage{amssymb} -""" - default_placeholder_text = "YourTextHere" - default_tex_compiler = "latex" - default_output_format = ".dvi" - default_post_doc_commands = "" - - def __init__( - self, - tex_compiler=None, - output_format=None, - documentclass=None, - preamble=None, - placeholder_text=None, - post_doc_commands=None, - **kwargs, - ): - self.tex_compiler = ( - tex_compiler - if tex_compiler is not None - else TexTemplate.default_tex_compiler - ) - self.output_format = ( - output_format - if output_format is not None - else TexTemplate.default_output_format - ) - self.documentclass = ( - documentclass - if documentclass is not None - else TexTemplate.default_documentclass - ) - self.preamble = ( - preamble if preamble is not None else TexTemplate.default_preamble - ) - self.placeholder_text = ( - placeholder_text - if placeholder_text is not None - else TexTemplate.default_placeholder_text - ) - self.post_doc_commands = ( - post_doc_commands - if post_doc_commands is not None - else TexTemplate.default_post_doc_commands - ) - self._rebuild() - - def _rebuild(self): - """Rebuilds the entire TeX template text from ``\\documentclass`` to ``\\end{document}`` according to all settings and choices.""" - self.body = ( - self.documentclass - + "\n" - + self.preamble - + "\n" - + r"\begin{document}" - + "\n" - + self.post_doc_commands - + "\n" - + self.placeholder_text - + "\n" - + "\n" - + r"\end{document}" - + "\n" +\usepackage{amssymb}""" + +_BEGIN_DOCUMENT = r"\begin{document}" +_END_DOCUMENT = r"\end{document}" + + +@dataclass(eq=True) +class TexTemplate: + """TeX templates are used to create ``Tex`` and ``MathTex`` objects.""" + + _body: str = field(default="", init=False) + """A custom body, can be set from a file.""" + + tex_compiler: str = "latex" + """The TeX compiler to be used, e.g. ``latex``, ``pdflatex`` or ``lualatex``.""" + + description: str = "" + """A description of the template""" + + output_format: str = ".dvi" + """The output format resulting from compilation, e.g. ``.dvi`` or ``.pdf``.""" + + documentclass: str = r"\documentclass[preview]{standalone}" + r"""The command defining the documentclass, e.g. ``\documentclass[preview]{standalone}``.""" + + preamble: str = _DEFAULT_PREAMBLE + r"""The document's preamble, i.e. the part between ``\documentclass`` and ``\begin{document}``.""" + + placeholder_text: str = "YourTextHere" + """Text in the document that will be replaced by the expression to be rendered.""" + + post_doc_commands: str = "" + r"""Text (definitions, commands) to be inserted at right after ``\begin{document}``, e.g. ``\boldmath``.""" + + @property + def body(self) -> str: + """The entire TeX template.""" + return self._body or "\n".join( + filter( + None, + [ + self.documentclass, + self.preamble, + _BEGIN_DOCUMENT, + self.post_doc_commands, + self.placeholder_text, + _END_DOCUMENT, + ], + ) ) - def add_to_preamble(self, txt, prepend=False): - """Adds stuff to the TeX template's preamble (e.g. definitions, packages). Text can be inserted at the beginning or at the end of the preamble. + @body.setter + def body(self, value: str) -> None: + self._body = value + + @classmethod + def from_file(cls, file: StrPath = "tex_template.tex", **kwargs: Any) -> Self: + """Create an instance by reading the content of a file. + + Using the ``add_to_preamble`` and ``add_to_document`` methods on this instance + will have no effect, as the body is read from the file. + """ + instance = cls(**kwargs) + instance.body = Path(file).read_text(encoding="utf-8") + return instance + + def add_to_preamble(self, txt: str, prepend: bool = False) -> Self: + r"""Adds text to the TeX template's preamble (e.g. definitions, packages). Text can be inserted at the beginning or at the end of the preamble. Parameters ---------- - txt : :class:`string` - String containing the text to be added, e.g. ``\\usepackage{hyperref}`` - prepend : Optional[:class:`bool`], optional - Whether the text should be added at the beginning of the preamble, i.e. right after ``\\documentclass``. Default is to add it at the end of the preamble, i.e. right before ``\\begin{document}`` + txt + String containing the text to be added, e.g. ``\usepackage{hyperref}``. + prepend + Whether the text should be added at the beginning of the preamble, i.e. right after ``\documentclass``. + Default is to add it at the end of the preamble, i.e. right before ``\begin{document}``. """ + if self._body: + warnings.warn( + "This TeX template was created with a fixed body, trying to add text the preamble will have no effect.", + UserWarning, + stacklevel=2, + ) if prepend: self.preamble = txt + "\n" + self.preamble else: self.preamble += "\n" + txt - self._rebuild() + return self - def add_to_document(self, txt): - """Adds txt to the TeX template just after \\begin{document}, e.g. ``\\boldmath`` + def add_to_document(self, txt: str) -> Self: + r"""Adds text to the TeX template just after \begin{document}, e.g. ``\boldmath``. Parameters ---------- - txt : :class:`str` + txt String containing the text to be added. """ - self.post_doc_commands += "\n" + txt + "\n" - self._rebuild() - - def get_texcode_for_expression(self, expression): - """Inserts expression verbatim into TeX template. + if self._body: + warnings.warn( + "This TeX template was created with a fixed body, trying to add text the document will have no effect.", + UserWarning, + stacklevel=2, + ) + self.post_doc_commands += txt + return self + + def get_texcode_for_expression(self, expression: str) -> str: + r"""Inserts expression verbatim into TeX template. Parameters ---------- - expression : :class:`str` - The string containing the expression to be typeset, e.g. ``$\\sqrt{2}$`` + expression + The string containing the expression to be typeset, e.g. ``$\sqrt{2}$`` Returns ------- @@ -156,116 +141,59 @@ def get_texcode_for_expression(self, expression): """ return self.body.replace(self.placeholder_text, expression) - def _texcode_for_environment(self, environment): - """Processes the tex_environment string to return the correct ``\\begin{environment}[extra]{extra}`` and - ``\\end{environment}`` strings + def get_texcode_for_expression_in_env( + self, expression: str, environment: str + ) -> str: + r"""Inserts expression into TeX template wrapped in ``\begin{environment}`` and ``\end{environment}``. Parameters ---------- - environment : :class:`str` - The tex_environment as a string. Acceptable formats include: - ``{align*}``, ``align*``, ``{tabular}[t]{cccl}``, ``tabular}{cccl``, ``\\begin{tabular}[t]{cccl}``. - - Returns - ------- - Tuple[:class:`str`, :class:`str`] - A pair of strings representing the opening and closing of the tex environment, e.g. - ``\\begin{tabular}{cccl}`` and ``\\end{tabular}`` - """ - - # If the environment starts with \begin, remove it - if environment[0:6] == r"\begin": - environment = environment[6:] - - # If environment begins with { strip it - if environment[0] == r"{": - environment = environment[1:] - - # The \begin command takes everything and closes with a brace - begin = r"\begin{" + environment - if ( - begin[-1] != r"}" and begin[-1] != r"]" - ): # If it doesn't end on } or ], assume missing } - begin += r"}" - - # While the \end command terminates at the first closing brace - split_at_brace = re.split(r"}", environment, 1) - end = r"\end{" + split_at_brace[0] + r"}" - - return begin, end - - def get_texcode_for_expression_in_env(self, expression, environment): - r"""Inserts expression into TeX template wrapped in \begin{environment} and \end{environment} - - Parameters - ---------- - expression : :class:`str` - The string containing the expression to be typeset, e.g. ``$\\sqrt{2}$`` - environment : :class:`str` - The string containing the environment in which the expression should be typeset, e.g. ``align*`` + expression + The string containing the expression to be typeset, e.g. ``$\sqrt{2}$``. + environment + The string containing the environment in which the expression should be typeset, e.g. ``align*``. Returns ------- :class:`str` LaTeX code based on template, containing the given expression inside its environment, ready for typesetting """ - begin, end = self._texcode_for_environment(environment) - return self.body.replace(self.placeholder_text, f"{begin}\n{expression}\n{end}") + begin, end = _texcode_for_environment(environment) + return self.body.replace( + self.placeholder_text, "\n".join([begin, expression, end]) + ) - def copy(self) -> TexTemplate: + def copy(self) -> Self: + """Create a deep copy of the TeX template instance.""" return copy.deepcopy(self) -class TexTemplateFromFile(TexTemplate): - """A TexTemplate object created from a template file (default: tex_template.tex) +def _texcode_for_environment(environment: str) -> tuple[str, str]: + r"""Processes the tex_environment string to return the correct ``\begin{environment}[extra]{extra}`` and + ``\end{environment}`` strings. Parameters ---------- - tex_compiler : Optional[:class:`str`], optional - The TeX compiler to be used, e.g. ``latex``, ``pdflatex`` or ``lualatex`` - output_format : Optional[:class:`str`], optional - The output format resulting from compilation, e.g. ``.dvi`` or ``.pdf`` - documentclass : Optional[:class:`str`], optional - The command defining the documentclass, e.g. ``\\documentclass[preview]{standalone}`` - preamble : Optional[:class:`str`], optional - The document's preamble, i.e. the part between ``\\documentclass`` and ``\\begin{document}`` - placeholder_text : Optional[:class:`str`], optional - Text in the document that will be replaced by the expression to be rendered - post_doc_commands : Optional[:class:`str`], optional - Text (definitions, commands) to be inserted at right after ``\\begin{document}``, e.g. ``\\boldmath`` - kwargs : :class:`str` - The kwargs specified can only be strings. - - Other Parameters - ---------------- - tex_filename : Optional[:class:`str`], optional - Path to a valid TeX template file - - Attributes - ---------- - template_file : :class:`str` - Path to a valid TeX template file - body : :class:`str` - Content of the TeX template file - tex_compiler : :class:`str` - The TeX compiler to be used, e.g. ``latex``, ``pdflatex`` or ``lualatex`` - output_format : :class:`str` - The output format resulting from compilation, e.g. ``.dvi`` or ``.pdf`` + environment + The tex_environment as a string. Acceptable formats include: + ``{align*}``, ``align*``, ``{tabular}[t]{cccl}``, ``tabular}{cccl``, ``\begin{tabular}[t]{cccl}``. + + Returns + ------- + Tuple[:class:`str`, :class:`str`] + A pair of strings representing the opening and closing of the tex environment, e.g. + ``\begin{tabular}{cccl}`` and ``\end{tabular}`` """ + environment = environment.removeprefix(r"\begin").removeprefix("{") - def __init__(self, **kwargs): - self.template_file = kwargs.pop("tex_filename", "tex_template.tex") - super().__init__(**kwargs) - - def _rebuild(self): - with open(self.template_file) as infile: - self.body = infile.read() - - def file_not_mutable(self): - raise Exception("Cannot modify TexTemplate when using a template file.") + # The \begin command takes everything and closes with a brace + begin = r"\begin{" + environment + # If it doesn't end on } or ], assume missing } + if not begin.endswith(("}", "]")): + begin += "}" - def add_to_preamble(self, txt, prepend=False): - self.file_not_mutable() + # While the \end command terminates at the first closing brace + split_at_brace = re.split("}", environment, maxsplit=1) + end = r"\end{" + split_at_brace[0] + "}" - def add_to_document(self, txt): - self.file_not_mutable() + return begin, end diff --git a/manim/utils/tex_file_writing.py b/manim/utils/tex_file_writing.py index 8bdb0c3c44..8c2c9c8c00 100644 --- a/manim/utils/tex_file_writing.py +++ b/manim/utils/tex_file_writing.py @@ -9,15 +9,22 @@ from __future__ import annotations import hashlib -import os import re +import subprocess import unicodedata +from collections.abc import Generator, Iterable, Sequence from pathlib import Path +from re import Match +from typing import Any + +from manim.utils.tex import TexTemplate from .. import config, logger +__all__ = ["tex_to_svg_file"] + -def tex_hash(expression): +def tex_hash(expression: Any) -> str: id_str = str(expression) hasher = hashlib.sha256() hasher.update(id_str.encode()) @@ -25,50 +32,67 @@ def tex_hash(expression): return hasher.hexdigest()[:16] -def tex_to_svg_file(expression, environment=None, tex_template=None): - """Takes a tex expression and returns the svg version of the compiled tex +def tex_to_svg_file( + expression: str, + environment: str | None = None, + tex_template: TexTemplate | None = None, +) -> Path: + r"""Takes a tex expression and returns the svg version of the compiled tex Parameters ---------- - expression : :class:`str` + expression String containing the TeX expression to be rendered, e.g. ``\\sqrt{2}`` or ``foo`` - environment : Optional[:class:`str`], optional + environment The string containing the environment in which the expression should be typeset, e.g. ``align*`` - tex_template : Optional[:class:`~.TexTemplate`], optional + tex_template Template class used to typesetting. If not set, use default template set via `config["tex_template"]` Returns ------- - :class:`str` + :class:`Path` Path to generated SVG file. """ if tex_template is None: tex_template = config["tex_template"] tex_file = generate_tex_file(expression, environment, tex_template) + + # check if svg already exists + svg_file = tex_file.with_suffix(".svg") + if svg_file.exists(): + return svg_file + dvi_file = compile_tex( tex_file, tex_template.tex_compiler, tex_template.output_format, ) - return convert_to_svg(dvi_file, tex_template.output_format) - - -def generate_tex_file(expression, environment=None, tex_template=None): - """Takes a tex expression (and an optional tex environment), + svg_file = convert_to_svg(dvi_file, tex_template.output_format) + if not config["no_latex_cleanup"]: + delete_nonsvg_files() + return svg_file + + +def generate_tex_file( + expression: str, + environment: str | None = None, + tex_template: TexTemplate | None = None, +) -> Path: + r"""Takes a tex expression (and an optional tex environment), and returns a fully formed tex file ready for compilation. Parameters ---------- - expression : :class:`str` + expression String containing the TeX expression to be rendered, e.g. ``\\sqrt{2}`` or ``foo`` - environment : Optional[:class:`str`], optional + environment The string containing the environment in which the expression should be typeset, e.g. ``align*`` - tex_template : Optional[:class:`~.TexTemplate`], optional + tex_template Template class used to typesetting. If not set, use default template set via `config["tex_template"]` Returns ------- - :class:`str` + :class:`Path` Path to generated TeX file """ if tex_template is None: @@ -79,115 +103,111 @@ def generate_tex_file(expression, environment=None, tex_template=None): output = tex_template.get_texcode_for_expression(expression) tex_dir = config.get_dir("tex_dir") - if not os.path.exists(tex_dir): - os.makedirs(tex_dir) + if not tex_dir.exists(): + tex_dir.mkdir() - result = os.path.join(tex_dir, tex_hash(output)) + ".tex" - if not os.path.exists(result): + result = tex_dir / (tex_hash(output) + ".tex") + if not result.exists(): logger.info( "Writing %(expression)s to %(path)s", {"expression": expression, "path": f"{result}"}, ) - with open(result, "w", encoding="utf-8") as outfile: - outfile.write(output) + result.write_text(output, encoding="utf-8") return result -def tex_compilation_command(tex_compiler, output_format, tex_file, tex_dir): - """Prepares the tex compilation command with all necessary cli flags +def make_tex_compilation_command( + tex_compiler: str, output_format: str, tex_file: Path, tex_dir: Path +) -> list[str]: + """Prepares the TeX compilation command, i.e. the TeX compiler name + and all necessary CLI flags. Parameters ---------- - tex_compiler : :class:`str` + tex_compiler String containing the compiler to be used, e.g. ``pdflatex`` or ``lualatex`` - output_format : :class:`str` + output_format String containing the output format generated by the compiler, e.g. ``.dvi`` or ``.pdf`` - tex_file : :class:`str` + tex_file File name of TeX file to be typeset. - tex_dir : :class:`str` + tex_dir Path to the directory where compiler output will be stored. Returns ------- - :class:`str` + :class:`list[str]` Compilation command according to given parameters """ if tex_compiler in {"latex", "pdflatex", "luatex", "lualatex"}: - commands = [ + command = [ tex_compiler, "-interaction=batchmode", - f'-output-format="{output_format[1:]}"', + f"-output-format={output_format[1:]}", "-halt-on-error", - f'-output-directory="{tex_dir}"', - f'"{tex_file}"', - ">", - os.devnull, + f"-output-directory={tex_dir.as_posix()}", + f"{tex_file.as_posix()}", ] elif tex_compiler == "xelatex": if output_format == ".xdv": - outflag = "-no-pdf" + outflag = ["-no-pdf"] elif output_format == ".pdf": - outflag = "" + outflag = [] else: raise ValueError("xelatex output is either pdf or xdv") - commands = [ + command = [ "xelatex", - outflag, + *outflag, "-interaction=batchmode", "-halt-on-error", - f'-output-directory="{tex_dir}"', - f'"{tex_file}"', - ">", - os.devnull, + f"-output-directory={tex_dir.as_posix()}", + f"{tex_file.as_posix()}", ] else: raise ValueError(f"Tex compiler {tex_compiler} unknown.") - return " ".join(commands) + return command -def insight_inputenc_error(matching): +def insight_inputenc_error(matching: Match[str]) -> Generator[str]: code_point = chr(int(matching[1], 16)) name = unicodedata.name(code_point) yield f"TexTemplate does not support character '{name}' (U+{matching[1]})." yield "See the documentation for manim.mobject.svg.tex_mobject for details on using a custom TexTemplate." -def insight_package_not_found_error(matching): +def insight_package_not_found_error(matching: Match[str]) -> Generator[str]: yield f"You do not have package {matching[1]} installed." yield f"Install {matching[1]} it using your LaTeX package manager, or check for typos." -def compile_tex(tex_file, tex_compiler, output_format): +def compile_tex(tex_file: Path, tex_compiler: str, output_format: str) -> Path: """Compiles a tex_file into a .dvi or a .xdv or a .pdf Parameters ---------- - tex_file : :class:`str` + tex_file File name of TeX file to be typeset. - tex_compiler : :class:`str` + tex_compiler String containing the compiler to be used, e.g. ``pdflatex`` or ``lualatex`` - output_format : :class:`str` + output_format String containing the output format generated by the compiler, e.g. ``.dvi`` or ``.pdf`` Returns ------- - :class:`str` + :class:`Path` Path to generated output file in desired format (DVI, XDV or PDF). """ - result = tex_file.replace(".tex", output_format) - result = Path(result).as_posix() - tex_file = Path(tex_file).as_posix() - tex_dir = Path(config.get_dir("tex_dir")).as_posix() - if not os.path.exists(result): - command = tex_compilation_command( + result = tex_file.with_suffix(output_format) + tex_dir = config.get_dir("tex_dir") + if not result.exists(): + command = make_tex_compilation_command( tex_compiler, output_format, tex_file, tex_dir, ) - exit_code = os.system(command) - if exit_code != 0: - log_file = tex_file.replace(".tex", ".log") + cp = subprocess.run(command, stdout=subprocess.DEVNULL) + if cp.returncode != 0: + log_file = tex_file.with_suffix(".log") print_all_tex_errors(log_file, tex_compiler, tex_file) raise ValueError( f"{tex_compiler} error converting to" @@ -197,70 +217,81 @@ def compile_tex(tex_file, tex_compiler, output_format): return result -def convert_to_svg(dvi_file, extension, page=1): +def convert_to_svg(dvi_file: Path, extension: str, page: int = 1) -> Path: """Converts a .dvi, .xdv, or .pdf file into an svg using dvisvgm. Parameters ---------- - dvi_file : :class:`str` + dvi_file File name of the input file to be converted. - extension : :class:`str` + extension String containing the file extension and thus indicating the file type, e.g. ``.dvi`` or ``.pdf`` - page : Optional[:class:`int`], optional + page Page to be converted if input file is multi-page. Returns ------- - :class:`str` + :class:`Path` Path to generated SVG file. """ - result = dvi_file.replace(extension, ".svg") - result = Path(result).as_posix() - dvi_file = Path(dvi_file).as_posix() - if not os.path.exists(result): - commands = [ + result = dvi_file.with_suffix(".svg") + if not result.exists(): + command = [ "dvisvgm", - "--pdf" if extension == ".pdf" else "", - "-p " + str(page), - f'"{dvi_file}"', - "-n", - "-v 0", - "-o " + f'"{result}"', - ">", - os.devnull, + *(["--pdf"] if extension == ".pdf" else []), + f"--page={page}", + "--no-fonts", + "--verbosity=0", + f"--output={result.as_posix()}", + f"{dvi_file.as_posix()}", ] - os.system(" ".join(commands)) + subprocess.run(command, stdout=subprocess.DEVNULL) # if the file does not exist now, this means conversion failed - if not os.path.exists(result): + if not result.exists(): raise ValueError( - f"Your installation does not support converting {extension} files to SVG." + f"Your installation does not support converting {dvi_file.suffix} files to SVG." f" Consider updating dvisvgm to at least version 2.4." f" If this does not solve the problem, please refer to our troubleshooting guide at:" - f" https://docs.manim.community/en/stable/installation/troubleshooting.html", + f" https://docs.manim.community/en/stable/faq/general.html#my-installation-" + f"does-not-support-converting-pdf-to-svg-help", ) return result -def print_all_tex_errors(log_file, tex_compiler, tex_file): - if not Path(log_file).exists(): +def delete_nonsvg_files(additional_endings: Iterable[str] = ()) -> None: + """Deletes every file that does not have a suffix in ``(".svg", ".tex", *additional_endings)`` + + Parameters + ---------- + additional_endings + Additional endings to whitelist + """ + tex_dir = config.get_dir("tex_dir") + file_suffix_whitelist = {".svg", ".tex", *additional_endings} + + for f in tex_dir.iterdir(): + if f.suffix not in file_suffix_whitelist: + f.unlink() + + +def print_all_tex_errors(log_file: Path, tex_compiler: str, tex_file: Path) -> None: + if not log_file.exists(): raise RuntimeError( f"{tex_compiler} failed but did not produce a log file. " "Check your LaTeX installation.", ) - with open(log_file) as f: + with log_file.open(encoding="utf-8") as f: tex_compilation_log = f.readlines() - error_indices = [ - index - for index, line in enumerate(tex_compilation_log) - if line.startswith("!") - ] - if error_indices: - with open(tex_file) as g: - tex = g.readlines() - for error_index in error_indices: - print_tex_error(tex_compilation_log, error_index, tex) + error_indices = [ + index for index, line in enumerate(tex_compilation_log) if line.startswith("!") + ] + if error_indices: + with tex_file.open() as f: + tex = f.readlines() + for error_index in error_indices: + print_tex_error(tex_compilation_log, error_index, tex) LATEX_ERROR_INSIGHTS = [ @@ -275,7 +306,11 @@ def print_all_tex_errors(log_file, tex_compiler, tex_file): ] -def print_tex_error(tex_compilation_log, error_start_index, tex_source): +def print_tex_error( + tex_compilation_log: Sequence[str], + error_start_index: int, + tex_source: Sequence[str], +) -> None: logger.error( f"LaTeX compilation error: {tex_compilation_log[error_start_index][2:]}", ) @@ -309,8 +344,8 @@ def print_tex_error(tex_compilation_log, error_start_index, tex_source): context += tex_source[line_of_tex_error - 3 : line_of_tex_error + 3] context[-4] = "-> " + context[-4] - context = "".join(context) - logger.error(context) + context_joined = "".join(context) + logger.error(context_joined) for insights in LATEX_ERROR_INSIGHTS: prob, get_insight = insights diff --git a/manim/utils/tex_templates.py b/manim/utils/tex_templates.py index 43153f933e..7273b67d0f 100644 --- a/manim/utils/tex_templates.py +++ b/manim/utils/tex_templates.py @@ -1,4 +1,5 @@ """A library of LaTeX templates.""" + from __future__ import annotations __all__ = [ @@ -11,7 +12,7 @@ # This file makes TexTemplateLibrary and TexFontTemplates available for use in manim Tex and MathTex objects. -def _new_ams_template(): +def _new_ams_template() -> TexTemplate: """Returns a simple Tex Template with only basic AMS packages""" preamble = r""" \usepackage[english]{babel} diff --git a/manim/utils/unit.py b/manim/utils/unit.py index f629e070db..c4755f0191 100644 --- a/manim/utils/unit.py +++ b/manim/utils/unit.py @@ -5,20 +5,21 @@ import numpy as np from .. import config, constants +from ..typing import Vector3D __all__ = ["Pixels", "Degrees", "Munits", "Percent"] class _PixelUnits: - def __mul__(self, val): + def __mul__(self, val: float) -> float: return val * config.frame_width / config.pixel_width - def __rmul__(self, val): + def __rmul__(self, val: float) -> float: return val * config.frame_width / config.pixel_width class Percent: - def __init__(self, axis): + def __init__(self, axis: Vector3D) -> None: if np.array_equal(axis, constants.X_AXIS): self.length = config.frame_width if np.array_equal(axis, constants.Y_AXIS): @@ -26,10 +27,10 @@ def __init__(self, axis): if np.array_equal(axis, constants.Z_AXIS): raise NotImplementedError("length of Z axis is undefined") - def __mul__(self, val): + def __mul__(self, val: float) -> float: return val / 100 * self.length - def __rmul__(self, val): + def __rmul__(self, val: float) -> float: return val / 100 * self.length diff --git a/mypy.ini b/mypy.ini new file mode 100644 index 0000000000..80571869be --- /dev/null +++ b/mypy.ini @@ -0,0 +1,147 @@ +[mypy] +strict = False +files = manim +python_version = 3.10 +; plugins = numpy.typing.mypy_plugin +ignore_errors = False +cache_fine_grained = True +warn_unused_ignores = True + +# Disallow Dynamic Typing +# disallow_any_unimported = True +# disallow_any_expr = False +# disallow_any_decorated = True +# disallow_any_explicit = True +# disallow_any_generics = True +# disallow_subclassing_any = True +# +# # Disallow Untyped Defs and Calls +disallow_untyped_calls = True +disallow_untyped_defs = True +disallow_incomplete_defs = True +# check_untyped_defs = False +# disallow_untyped_decorators = True +# +# # None and Optional Handling +# implicit_optional = False +# strict_optional = True +# +# # Configuring Warnings +# warn_redundant_casts = True +# warn_unused_ignores = True +warn_return_any = True +# warn_unreachable = True +# +# # Strictness Flags +# allow_untyped_globals = False +# allow_redefinition = False +# local_partial_types = False +# strict_equality = True +# +# # Configuring Error Messages +# show_error_context = True +# show_column_numbers = True +# show_error_codes = True +# pretty = True +# color_output = True +# error_summary = True +# +# disable_recursive_aliases = True + +[mypy-manim._config.*] +ignore_errors = True +disable_error_code = return-value + +[mypy-manim.animation.*] +ignore_errors = True + +[mypy-manim.camera.*] +ignore_errors = True + +[mypy-manim.cli.*] +ignore_errors = False + +[mypy-manim.cli.cfg.*] +ignore_errors = False + +[mypy-manim.gui.*] +ignore_errors = True + +[mypy-manim.mobject.*] +ignore_errors = True + +[mypy-manim.mobject.text.code_mobject] +ignore_errors = False + +[mypy-manim.mobject.geometry.*] +ignore_errors = True + +[mypy-manim.renderer.*] +ignore_errors = True + +[mypy-manim.scene.*] +ignore_errors = True + +[mypy-manim.utils.hashing.*] +ignore_errors = True + +[mypy-manim.utils.color.*] +ignore_errors = False + +[mypy-manim.utils.iterables] +warn_return_any = False + + +# ---------------- We can't properly type this ------------------------ + +[mypy-manim.grpc.*] +ignore_errors = True + +# ---------------- Stubless imported Modules -------------------------- + +# We should be able to create stubs for this or type hint it +[mypy-manimpango] +ignore_missing_imports = True + +# Has stubs in 3.8 +[mypy-pydub] +ignore_missing_imports = True + +[mypy-matplotlib] +ignore_missing_imports = True + +[mypy-scipy.*] +ignore_missing_imports = True + +[mypy-networkx] +ignore_missing_imports = True + +[mypy-git] +ignore_missing_imports = True + +[mypy-moderngl.*] +ignore_missing_imports = True + +[mypy-moderngl_window.*] +ignore_missing_imports = True + +[mypy-dearpygui.*] +ignore_missing_imports = True + +[mypy-screeninfo] +ignore_missing_imports = True + +[mypy-IPython.*] +ignore_missing_imports = True + +[mypy-watchdog.*] +ignore_missing_imports = True + +[mypy-tqdm] +ignore_missing_imports = True + +[mypy-mapbox_earcut] +ignore_missing_imports = True + +[mypy-click_default_group] +ignore_missing_imports = True diff --git a/poetry.lock b/poetry.lock deleted file mode 100644 index 44edf83658..0000000000 --- a/poetry.lock +++ /dev/null @@ -1,4116 +0,0 @@ -[[package]] -name = "alabaster" -version = "0.7.12" -description = "A configurable sidebar-enabled Sphinx theme" -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "anyio" -version = "3.5.0" -description = "High level compatibility layer for multiple asynchronous event loop implementations" -category = "main" -optional = true -python-versions = ">=3.6.2" - -[package.dependencies] -idna = ">=2.8" -sniffio = ">=1.1" -typing-extensions = {version = "*", markers = "python_version < \"3.8\""} - -[package.extras] -doc = ["packaging", "sphinx-rtd-theme", "sphinx-autodoc-typehints (>=1.2.0)"] -test = ["coverage[toml] (>=4.5)", "hypothesis (>=4.0)", "pytest (>=6.0)", "pytest-mock (>=3.6.1)", "trustme", "contextlib2", "uvloop (<0.15)", "mock (>=4)", "uvloop (>=0.15)"] -trio = ["trio (>=0.16)"] - -[[package]] -name = "appnope" -version = "0.1.2" -description = "Disable App Nap on macOS >= 10.9" -category = "main" -optional = true -python-versions = "*" - -[[package]] -name = "argon2-cffi" -version = "21.3.0" -description = "The secure Argon2 password hashing algorithm." -category = "main" -optional = true -python-versions = ">=3.6" - -[package.dependencies] -argon2-cffi-bindings = "*" -typing-extensions = {version = "*", markers = "python_version < \"3.8\""} - -[package.extras] -dev = ["pre-commit", "cogapp", "tomli", "coverage[toml] (>=5.0.2)", "hypothesis", "pytest", "sphinx", "sphinx-notfound-page", "furo"] -docs = ["sphinx", "sphinx-notfound-page", "furo"] -tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pytest"] - -[[package]] -name = "argon2-cffi-bindings" -version = "21.2.0" -description = "Low-level CFFI bindings for Argon2" -category = "main" -optional = true -python-versions = ">=3.6" - -[package.dependencies] -cffi = ">=1.0.1" - -[package.extras] -dev = ["pytest", "cogapp", "pre-commit", "wheel"] -tests = ["pytest"] - -[[package]] -name = "astor" -version = "0.8.1" -description = "Read/rewrite/write Python ASTs" -category = "dev" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" - -[[package]] -name = "astroid" -version = "2.9.3" -description = "An abstract syntax tree for Python with inference support." -category = "dev" -optional = false -python-versions = ">=3.6.2" - -[package.dependencies] -lazy-object-proxy = ">=1.4.0" -typed-ast = {version = ">=1.4.0,<2.0", markers = "implementation_name == \"cpython\" and python_version < \"3.8\""} -typing-extensions = {version = ">=3.10", markers = "python_version < \"3.10\""} -wrapt = ">=1.11,<1.14" - -[[package]] -name = "atomicwrites" -version = "1.4.0" -description = "Atomic file writes." -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - -[[package]] -name = "attrs" -version = "21.4.0" -description = "Classes Without Boilerplate" -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" - -[package.extras] -dev = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "furo", "sphinx", "sphinx-notfound-page", "pre-commit", "cloudpickle"] -docs = ["furo", "sphinx", "zope.interface", "sphinx-notfound-page"] -tests = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "zope.interface", "cloudpickle"] -tests_no_zope = ["coverage[toml] (>=5.0.2)", "hypothesis", "pympler", "pytest (>=4.3.0)", "six", "mypy", "pytest-mypy-plugins", "cloudpickle"] - -[[package]] -name = "babel" -version = "2.9.1" -description = "Internationalization utilities" -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - -[package.dependencies] -pytz = ">=2015.7" - -[[package]] -name = "backcall" -version = "0.2.0" -description = "Specifications for callback functions passed in to an API" -category = "main" -optional = true -python-versions = "*" - -[[package]] -name = "backports.cached-property" -version = "1.0.1" -description = "cached_property() - computed once per instance, cached as attribute" -category = "main" -optional = false -python-versions = ">=3.6.0" - -[[package]] -name = "beautifulsoup4" -version = "4.10.0" -description = "Screen-scraping library" -category = "dev" -optional = false -python-versions = ">3.0.0" - -[package.dependencies] -soupsieve = ">1.2" - -[package.extras] -html5lib = ["html5lib"] -lxml = ["lxml"] - -[[package]] -name = "black" -version = "22.1.0" -description = "The uncompromising code formatter." -category = "dev" -optional = false -python-versions = ">=3.6.2" - -[package.dependencies] -click = ">=8.0.0" -mypy-extensions = ">=0.4.3" -pathspec = ">=0.9.0" -platformdirs = ">=2" -tomli = ">=1.1.0" -typed-ast = {version = ">=1.4.2", markers = "python_version < \"3.8\" and implementation_name == \"cpython\""} -typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} - -[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 = "bleach" -version = "4.1.0" -description = "An easy safelist-based HTML-sanitizing tool." -category = "main" -optional = true -python-versions = ">=3.6" - -[package.dependencies] -packaging = "*" -six = ">=1.9.0" -webencodings = "*" - -[[package]] -name = "certifi" -version = "2021.10.8" -description = "Python package for providing Mozilla's CA Bundle." -category = "main" -optional = false -python-versions = "*" - -[[package]] -name = "cffi" -version = "1.15.0" -description = "Foreign Function Interface for Python calling C code." -category = "main" -optional = false -python-versions = "*" - -[package.dependencies] -pycparser = "*" - -[[package]] -name = "cfgv" -version = "3.3.1" -description = "Validate configuration and produce human readable error messages." -category = "dev" -optional = false -python-versions = ">=3.6.1" - -[[package]] -name = "charset-normalizer" -version = "2.0.12" -description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." -category = "main" -optional = false -python-versions = ">=3.5.0" - -[package.extras] -unicode_backport = ["unicodedata2"] - -[[package]] -name = "click" -version = "8.0.3" -description = "Composable command line interface toolkit" -category = "main" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} - -[[package]] -name = "click-default-group" -version = "1.2.2" -description = "Extends click.Group to invoke a command without explicit subcommand name" -category = "main" -optional = false -python-versions = "*" - -[package.dependencies] -click = "*" - -[[package]] -name = "cloup" -version = "0.7.1" -description = "Option groups and subcommand help sections for pallets/click" -category = "main" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -click = ">=7.0,<9.0" - -[[package]] -name = "colorama" -version = "0.4.4" -description = "Cross-platform colored terminal text." -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" - -[[package]] -name = "colour" -version = "0.1.5" -description = "converts and manipulates various color representation (HSL, RVB, web, X11, ...)" -category = "main" -optional = false -python-versions = "*" - -[package.extras] -test = ["nose"] - -[[package]] -name = "commonmark" -version = "0.9.1" -description = "Python parser for the CommonMark Markdown spec" -category = "main" -optional = false -python-versions = "*" - -[package.extras] -test = ["flake8 (==3.7.8)", "hypothesis (==3.55.3)"] - -[[package]] -name = "coverage" -version = "6.3.1" -description = "Code coverage measurement for Python" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -tomli = {version = "*", optional = true, markers = "extra == \"toml\""} - -[package.extras] -toml = ["tomli"] - -[[package]] -name = "cycler" -version = "0.11.0" -description = "Composable style cycles" -category = "dev" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "cython" -version = "0.29.27" -description = "The Cython compiler for writing C extensions for the Python language." -category = "main" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" - -[[package]] -name = "data-science-types" -version = "0.2.23" -description = "Type stubs for Python machine learning libraries" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.extras] -dev = ["black", "flake8", "flake8-pyi", "matplotlib", "mypy (==0.770)", "numpy", "pandas", "pytest"] - -[[package]] -name = "dearpygui" -version = "1.3.1" -description = "DearPyGui: A simple Python GUI Toolkit" -category = "main" -optional = true -python-versions = ">=3.6" - -[[package]] -name = "debugpy" -version = "1.5.1" -description = "An implementation of the Debug Adapter Protocol for Python" -category = "main" -optional = true -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" - -[[package]] -name = "decorator" -version = "5.1.1" -description = "Decorators for Humans" -category = "main" -optional = false -python-versions = ">=3.5" - -[[package]] -name = "defusedxml" -version = "0.7.1" -description = "XML bomb protection for Python stdlib modules" -category = "main" -optional = true -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" - -[[package]] -name = "deprecated" -version = "1.2.13" -description = "Python @deprecated decorator to deprecate old python classes, functions or methods." -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - -[package.dependencies] -wrapt = ">=1.10,<2" - -[package.extras] -dev = ["tox", "bump2version (<1)", "sphinx (<2)", "importlib-metadata (<3)", "importlib-resources (<4)", "configparser (<5)", "sphinxcontrib-websupport (<2)", "zipp (<2)", "PyTest (<5)", "PyTest-Cov (<2.6)", "pytest", "pytest-cov"] - -[[package]] -name = "distlib" -version = "0.3.4" -description = "Distribution utilities" -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "docutils" -version = "0.17.1" -description = "Docutils -- Python Documentation Utilities" -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" - -[[package]] -name = "entrypoints" -version = "0.4" -description = "Discover and load entry points from installed packages." -category = "main" -optional = true -python-versions = ">=3.6" - -[[package]] -name = "execnet" -version = "1.9.0" -description = "execnet: rapid multi-Python deployment" -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" - -[package.extras] -testing = ["pre-commit"] - -[[package]] -name = "filelock" -version = "3.4.2" -description = "A platform independent file lock." -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.extras] -docs = ["furo (>=2021.8.17b43)", "sphinx (>=4.1)", "sphinx-autodoc-typehints (>=1.12)"] -testing = ["covdefaults (>=1.2.0)", "coverage (>=4)", "pytest (>=4)", "pytest-cov", "pytest-timeout (>=1.4.2)"] - -[[package]] -name = "flake8" -version = "3.9.2" -description = "the modular source code checker: pep8 pyflakes and co" -category = "dev" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" - -[package.dependencies] -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} -mccabe = ">=0.6.0,<0.7.0" -pycodestyle = ">=2.7.0,<2.8.0" -pyflakes = ">=2.3.0,<2.4.0" - -[[package]] -name = "flake8-bugbear" -version = "21.11.29" -description = "A plugin for flake8 finding likely bugs and design problems in your program. Contains warnings that don't belong in pyflakes and pycodestyle." -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -attrs = ">=19.2.0" -flake8 = ">=3.0.0" - -[package.extras] -dev = ["coverage", "hypothesis", "hypothesmith (>=0.2)", "pre-commit"] - -[[package]] -name = "flake8-builtins" -version = "1.5.3" -description = "Check for python builtins being used as variables or parameters." -category = "dev" -optional = false -python-versions = "*" - -[package.dependencies] -flake8 = "*" - -[package.extras] -test = ["coverage", "coveralls", "mock", "pytest", "pytest-cov"] - -[[package]] -name = "flake8-comprehensions" -version = "3.8.0" -description = "A flake8 plugin to help you write better list/set/dict comprehensions." -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -flake8 = ">=3.0,<3.2.0 || >3.2.0" -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} - -[[package]] -name = "flake8-docstrings" -version = "1.6.0" -description = "Extension for flake8 which uses pydocstyle to check docstrings" -category = "dev" -optional = false -python-versions = "*" - -[package.dependencies] -flake8 = ">=3" -pydocstyle = ">=2.1" - -[[package]] -name = "flake8-plugin-utils" -version = "1.3.2" -description = "The package provides base classes and utils for flake8 plugin writing" -category = "dev" -optional = false -python-versions = ">=3.6,<4.0" - -[[package]] -name = "flake8-pytest-style" -version = "1.6.0" -description = "A flake8 plugin checking common style issues or inconsistencies with pytest-based tests." -category = "dev" -optional = false -python-versions = ">=3.6.2,<4.0.0" - -[package.dependencies] -flake8-plugin-utils = ">=1.3.2,<2.0.0" - -[[package]] -name = "flake8-rst-docstrings" -version = "0.2.5" -description = "Python docstring reStructuredText (RST) validator" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -flake8 = ">=3.0.0" -pygments = "*" -restructuredtext-lint = "*" - -[[package]] -name = "flake8-simplify" -version = "0.14.6" -description = "flake8 plugin which checks for code that can be simplified" -category = "dev" -optional = false -python-versions = ">=3.6.1" - -[package.dependencies] -astor = ">=0.1" -flake8 = ">=3.7" -importlib-metadata = {version = ">=0.9", markers = "python_version < \"3.8\""} - -[[package]] -name = "fonttools" -version = "4.29.1" -description = "Tools to manipulate font files" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.extras] -all = ["fs (>=2.2.0,<3)", "lxml (>=4.0,<5)", "zopfli (>=0.1.4)", "lz4 (>=1.7.4.2)", "matplotlib", "sympy", "skia-pathops (>=0.5.0)", "brotlicffi (>=0.8.0)", "scipy", "brotli (>=1.0.1)", "munkres", "unicodedata2 (>=14.0.0)", "xattr"] -graphite = ["lz4 (>=1.7.4.2)"] -interpolatable = ["scipy", "munkres"] -lxml = ["lxml (>=4.0,<5)"] -pathops = ["skia-pathops (>=0.5.0)"] -plot = ["matplotlib"] -symfont = ["sympy"] -type1 = ["xattr"] -ufo = ["fs (>=2.2.0,<3)"] -unicode = ["unicodedata2 (>=14.0.0)"] -woff = ["zopfli (>=0.1.4)", "brotlicffi (>=0.8.0)", "brotli (>=1.0.1)"] - -[[package]] -name = "furo" -version = "2021.11.23" -description = "A clean customisable Sphinx documentation theme." -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -beautifulsoup4 = "*" -pygments = ">=2.7,<3.0" -sphinx = ">=4.0,<5.0" - -[package.extras] -test = ["pytest", "pytest-cov", "pytest-xdist"] -doc = ["myst-parser", "sphinx-copybutton", "sphinx-design", "sphinx-inline-tabs"] - -[[package]] -name = "gitdb" -version = "4.0.9" -description = "Git Object Database" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -smmap = ">=3.0.1,<6" - -[[package]] -name = "gitpython" -version = "3.1.26" -description = "GitPython is a python library used to interact with Git repositories" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -gitdb = ">=4.0.1,<5" -typing-extensions = {version = ">=3.7.4.3", markers = "python_version < \"3.8\""} - -[[package]] -name = "glcontext" -version = "2.3.4" -description = "Portable OpenGL Context" -category = "main" -optional = false -python-versions = "*" - -[[package]] -name = "grpcio" -version = "1.43.0" -description = "HTTP/2-based RPC framework" -category = "main" -optional = true -python-versions = ">=3.6" - -[package.dependencies] -six = ">=1.5.2" - -[package.extras] -protobuf = ["grpcio-tools (>=1.43.0)"] - -[[package]] -name = "grpcio-tools" -version = "1.43.0" -description = "Protobuf code generator for gRPC" -category = "main" -optional = true -python-versions = ">=3.6" - -[package.dependencies] -grpcio = ">=1.43.0" -protobuf = ">=3.5.0.post1,<4.0dev" - -[[package]] -name = "identify" -version = "2.4.9" -description = "File identification library for Python" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.extras] -license = ["ukkonen"] - -[[package]] -name = "idna" -version = "3.3" -description = "Internationalized Domain Names in Applications (IDNA)" -category = "main" -optional = false -python-versions = ">=3.5" - -[[package]] -name = "imagesize" -version = "1.3.0" -description = "Getting image size from png/jpeg/jpeg2000/gif file" -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - -[[package]] -name = "importlib-metadata" -version = "4.11.0" -description = "Read metadata from Python packages" -category = "main" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -typing-extensions = {version = ">=3.6.4", markers = "python_version < \"3.8\""} -zipp = ">=0.5" - -[package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -perf = ["ipython"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "packaging", "pyfakefs", "flufl.flake8", "pytest-perf (>=0.9.2)", "pytest-black (>=0.3.7)", "pytest-mypy", "importlib-resources (>=1.3)"] - -[[package]] -name = "importlib-resources" -version = "5.4.0" -description = "Read resources from Python packages" -category = "main" -optional = true -python-versions = ">=3.6" - -[package.dependencies] -zipp = {version = ">=3.1.0", markers = "python_version < \"3.10\""} - -[package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "pytest-black (>=0.3.7)", "pytest-mypy"] - -[[package]] -name = "iniconfig" -version = "1.1.1" -description = "iniconfig: brain-dead simple config-ini parsing" -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "ipykernel" -version = "6.9.0" -description = "IPython Kernel for Jupyter" -category = "main" -optional = true -python-versions = ">=3.7" - -[package.dependencies] -appnope = {version = "*", markers = "platform_system == \"Darwin\""} -debugpy = ">=1.0.0,<2.0" -ipython = ">=7.23.1" -jupyter-client = "<8.0" -matplotlib-inline = ">=0.1.0,<0.2.0" -nest-asyncio = "*" -tornado = ">=4.2,<7.0" -traitlets = ">=5.1.0,<6.0" - -[package.extras] -test = ["pytest (!=5.3.4)", "pytest-cov", "flaky", "ipyparallel"] - -[[package]] -name = "ipython" -version = "7.31.1" -description = "IPython: Productive Interactive Computing" -category = "main" -optional = true -python-versions = ">=3.7" - -[package.dependencies] -appnope = {version = "*", markers = "sys_platform == \"darwin\""} -backcall = "*" -colorama = {version = "*", markers = "sys_platform == \"win32\""} -decorator = "*" -jedi = ">=0.16" -matplotlib-inline = "*" -pexpect = {version = ">4.3", markers = "sys_platform != \"win32\""} -pickleshare = "*" -prompt-toolkit = ">=2.0.0,<3.0.0 || >3.0.0,<3.0.1 || >3.0.1,<3.1.0" -pygments = "*" -traitlets = ">=4.2" - -[package.extras] -all = ["Sphinx (>=1.3)", "ipykernel", "ipyparallel", "ipywidgets", "nbconvert", "nbformat", "nose (>=0.10.1)", "notebook", "numpy (>=1.17)", "pygments", "qtconsole", "requests", "testpath"] -doc = ["Sphinx (>=1.3)"] -kernel = ["ipykernel"] -nbconvert = ["nbconvert"] -nbformat = ["nbformat"] -notebook = ["notebook", "ipywidgets"] -parallel = ["ipyparallel"] -qtconsole = ["qtconsole"] -test = ["nose (>=0.10.1)", "requests", "testpath", "pygments", "nbformat", "ipykernel", "numpy (>=1.17)"] - -[[package]] -name = "ipython-genutils" -version = "0.2.0" -description = "Vestigial utilities from IPython" -category = "main" -optional = true -python-versions = "*" - -[[package]] -name = "isort" -version = "5.10.1" -description = "A Python utility / library to sort Python imports." -category = "dev" -optional = false -python-versions = ">=3.6.1,<4.0" - -[package.extras] -pipfile_deprecated_finder = ["pipreqs", "requirementslib"] -requirements_deprecated_finder = ["pipreqs", "pip-api"] -colors = ["colorama (>=0.4.3,<0.5.0)"] -plugins = ["setuptools"] - -[[package]] -name = "isosurfaces" -version = "0.1.0" -description = "Construct isolines/isosurfaces over a 2D/3D scalar field defined by a function (not a uniform grid)" -category = "main" -optional = false -python-versions = "*" - -[package.dependencies] -numpy = "*" - -[[package]] -name = "jedi" -version = "0.18.1" -description = "An autocompletion tool for Python that can be used for text editors." -category = "main" -optional = true -python-versions = ">=3.6" - -[package.dependencies] -parso = ">=0.8.0,<0.9.0" - -[package.extras] -qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] -testing = ["Django (<3.1)", "colorama", "docopt", "pytest (<7.0.0)"] - -[[package]] -name = "jinja2" -version = "3.0.3" -description = "A very fast and expressive template engine." -category = "main" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -MarkupSafe = ">=2.0" - -[package.extras] -i18n = ["Babel (>=2.7)"] - -[[package]] -name = "json5" -version = "0.9.6" -description = "A Python implementation of the JSON5 data format." -category = "main" -optional = true -python-versions = "*" - -[package.extras] -dev = ["hypothesis"] - -[[package]] -name = "jsonschema" -version = "4.4.0" -description = "An implementation of JSON Schema validation for Python" -category = "main" -optional = true -python-versions = ">=3.7" - -[package.dependencies] -attrs = ">=17.4.0" -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} -importlib-resources = {version = ">=1.4.0", markers = "python_version < \"3.9\""} -pyrsistent = ">=0.14.0,<0.17.0 || >0.17.0,<0.17.1 || >0.17.1,<0.17.2 || >0.17.2" -typing-extensions = {version = "*", markers = "python_version < \"3.8\""} - -[package.extras] -format = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3987", "uri-template", "webcolors (>=1.11)"] -format_nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339-validator", "rfc3986-validator (>0.1.0)", "uri-template", "webcolors (>=1.11)"] - -[[package]] -name = "jupyter-client" -version = "7.1.2" -description = "Jupyter protocol implementation and client libraries" -category = "main" -optional = true -python-versions = ">=3.6.1" - -[package.dependencies] -entrypoints = "*" -jupyter-core = ">=4.6.0" -nest-asyncio = ">=1.5" -python-dateutil = ">=2.1" -pyzmq = ">=13" -tornado = ">=4.1" -traitlets = "*" - -[package.extras] -doc = ["myst-parser", "sphinx (>=1.3.6)", "sphinx-rtd-theme", "sphinxcontrib-github-alt"] -test = ["codecov", "coverage", "ipykernel", "ipython", "mock", "mypy", "pre-commit", "pytest", "pytest-asyncio", "pytest-cov", "pytest-timeout", "jedi (<0.18)"] - -[[package]] -name = "jupyter-core" -version = "4.9.1" -description = "Jupyter core package. A base package on which Jupyter projects rely." -category = "main" -optional = true -python-versions = ">=3.6" - -[package.dependencies] -pywin32 = {version = ">=1.0", markers = "sys_platform == \"win32\" and platform_python_implementation != \"PyPy\""} -traitlets = "*" - -[[package]] -name = "jupyter-server" -version = "1.13.5" -description = "The backend—i.e. core services, APIs, and REST endpoints—to Jupyter web applications." -category = "main" -optional = true -python-versions = ">=3.7" - -[package.dependencies] -anyio = ">=3.1.0,<4" -argon2-cffi = "*" -ipython-genutils = "*" -jinja2 = "*" -jupyter-client = ">=6.1.1" -jupyter-core = ">=4.6.0" -nbconvert = "*" -nbformat = "*" -packaging = "*" -prometheus-client = "*" -pywinpty = {version = "<2", markers = "os_name == \"nt\""} -pyzmq = ">=17" -Send2Trash = "*" -terminado = ">=0.8.3" -tornado = ">=6.1.0" -traitlets = ">=5" -websocket-client = "*" - -[package.extras] -test = ["coverage", "pytest (>=6.0)", "pytest-cov", "pytest-mock", "pytest-timeout", "requests", "pytest-tornasync", "pytest-console-scripts", "ipykernel"] - -[[package]] -name = "jupyterlab" -version = "3.2.9" -description = "JupyterLab computational environment" -category = "main" -optional = true -python-versions = ">=3.6" - -[package.dependencies] -ipython = "*" -jinja2 = ">=2.1" -jupyter-core = "*" -jupyter-server = ">=1.4,<2.0" -jupyterlab-server = ">=2.3,<3.0" -nbclassic = ">=0.2,<1.0" -packaging = "*" -tornado = ">=6.1.0" - -[package.extras] -test = ["coverage", "pytest (>=6.0)", "pytest-cov", "pytest-console-scripts", "pytest-check-links (>=0.5)", "jupyterlab-server[test] (>=2.2,<3.0)", "requests", "requests-cache", "virtualenv", "check-manifest"] -ui-tests = ["build"] - -[[package]] -name = "jupyterlab-pygments" -version = "0.1.2" -description = "Pygments theme using JupyterLab CSS variables" -category = "main" -optional = true -python-versions = "*" - -[package.dependencies] -pygments = ">=2.4.1,<3" - -[[package]] -name = "jupyterlab-server" -version = "2.10.3" -description = "A set of server components for JupyterLab and JupyterLab like applications ." -category = "main" -optional = true -python-versions = ">=3.6" - -[package.dependencies] -babel = "*" -entrypoints = ">=0.2.2" -jinja2 = ">=2.10" -json5 = "*" -jsonschema = ">=3.0.1" -jupyter-server = ">=1.4,<2.0" -packaging = "*" -requests = "*" - -[package.extras] -test = ["codecov", "ipykernel", "pytest (>=5.3.2)", "pytest-cov", "jupyter-server", "openapi-core (>=0.14.0,<0.15.0)", "pytest-console-scripts", "strict-rfc3339", "ruamel.yaml", "wheel"] - -[[package]] -name = "kiwisolver" -version = "1.3.2" -description = "A fast implementation of the Cassowary constraint solver" -category = "dev" -optional = false -python-versions = ">=3.7" - -[[package]] -name = "lazy-object-proxy" -version = "1.7.1" -description = "A fast and thorough lazy object proxy." -category = "dev" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "manimpango" -version = "0.4.0.post2" -description = "Bindings for Pango for using with Manim." -category = "main" -optional = false -python-versions = ">=3.7" - -[[package]] -name = "mapbox-earcut" -version = "0.12.11" -description = "Python bindings for the mapbox earcut C++ polygon triangulation library." -category = "main" -optional = false -python-versions = "*" - -[package.dependencies] -numpy = "*" - -[package.extras] -test = ["pytest"] - -[[package]] -name = "markupsafe" -version = "2.0.1" -description = "Safely add untrusted strings to HTML/XML markup." -category = "main" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "matplotlib" -version = "3.5.1" -description = "Python plotting package" -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.dependencies] -cycler = ">=0.10" -fonttools = ">=4.22.0" -kiwisolver = ">=1.0.1" -numpy = ">=1.17" -packaging = ">=20.0" -pillow = ">=6.2.0" -pyparsing = ">=2.2.1" -python-dateutil = ">=2.7" -setuptools_scm = ">=4" - -[[package]] -name = "matplotlib-inline" -version = "0.1.3" -description = "Inline Matplotlib backend for Jupyter" -category = "main" -optional = true -python-versions = ">=3.5" - -[package.dependencies] -traitlets = "*" - -[[package]] -name = "mccabe" -version = "0.6.1" -description = "McCabe checker, plugin for flake8" -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "mistune" -version = "0.8.4" -description = "The fastest markdown parser in pure Python" -category = "main" -optional = true -python-versions = "*" - -[[package]] -name = "moderngl" -version = "5.6.4" -description = "ModernGL: High performance rendering for Python 3" -category = "main" -optional = false -python-versions = "*" - -[package.dependencies] -glcontext = ">=2,<3" - -[[package]] -name = "moderngl-window" -version = "2.4.1" -description = "A cross platform helper library for ModernGL making window creation and resource loading simple" -category = "main" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -moderngl = "<6" -numpy = ">=1.16,<2" -Pillow = ">=5" -pyglet = ">=1.5.8,<2" -pyrr = ">=0.10.3,<1" - -[package.extras] -pysdl2 = ["pysdl2"] -pyside2 = ["PySide2 (<6)"] -glfw = ["glfw"] -pygame = ["pygame (>=2.0.1)"] -pyqt5 = ["pyqt5"] -pywavefront = ["pywavefront (>=1.2.0,<2)"] -tk = ["pyopengltk (>=0.0.3)"] -trimesh = ["trimesh (>=3.2.6,<4)", "scipy (>=1.3.2)"] - -[[package]] -name = "multipledispatch" -version = "0.6.0" -description = "Multiple dispatch" -category = "main" -optional = false -python-versions = "*" - -[package.dependencies] -six = "*" - -[[package]] -name = "mypy" -version = "0.931" -description = "Optional static typing for Python" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -mypy-extensions = ">=0.4.3" -tomli = ">=1.1.0" -typed-ast = {version = ">=1.4.0,<2", markers = "python_version < \"3.8\""} -typing-extensions = ">=3.10" - -[package.extras] -dmypy = ["psutil (>=4.0)"] -python2 = ["typed-ast (>=1.4.0,<2)"] - -[[package]] -name = "mypy-extensions" -version = "0.4.3" -description = "Experimental type system extensions for programs checked with the mypy typechecker." -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "nbclassic" -version = "0.3.5" -description = "Jupyter Notebook as a Jupyter Server extension." -category = "main" -optional = true -python-versions = ">=3.6" - -[package.dependencies] -jupyter-server = ">=1.8,<2.0" -notebook = "<7" - -[package.extras] -test = ["pytest", "pytest-tornasync", "pytest-console-scripts"] - -[[package]] -name = "nbclient" -version = "0.5.10" -description = "A client library for executing notebooks. Formerly nbconvert's ExecutePreprocessor." -category = "main" -optional = true -python-versions = ">=3.7.0" - -[package.dependencies] -jupyter-client = ">=6.1.5" -nbformat = ">=5.0" -nest-asyncio = "*" -traitlets = ">=4.2" - -[package.extras] -sphinx = ["Sphinx (>=1.7)", "sphinx-book-theme", "mock", "moto", "myst-parser"] -test = ["ipython", "ipykernel", "ipywidgets (<8.0.0)", "pytest (>=4.1)", "pytest-cov (>=2.6.1)", "check-manifest", "flake8", "mypy", "xmltodict", "black", "pip (>=18.1)", "wheel (>=0.31.0)", "setuptools (>=38.6.0)", "twine (>=1.11.0)"] - -[[package]] -name = "nbconvert" -version = "6.4.2" -description = "Converting Jupyter Notebooks" -category = "main" -optional = true -python-versions = ">=3.7" - -[package.dependencies] -bleach = "*" -defusedxml = "*" -entrypoints = ">=0.2.2" -jinja2 = ">=2.4" -jupyter-core = "*" -jupyterlab-pygments = "*" -mistune = ">=0.8.1,<2" -nbclient = ">=0.5.0,<0.6.0" -nbformat = ">=4.4" -pandocfilters = ">=1.4.1" -pygments = ">=2.4.1" -testpath = "*" -traitlets = ">=5.0" - -[package.extras] -all = ["pytest", "pytest-cov", "pytest-dependency", "ipykernel", "ipywidgets (>=7)", "pyppeteer (>=1,<1.1)", "tornado (>=4.0)", "sphinx (>=1.5.1)", "sphinx-rtd-theme", "nbsphinx (>=0.2.12)", "ipython"] -docs = ["sphinx (>=1.5.1)", "sphinx-rtd-theme", "nbsphinx (>=0.2.12)", "ipython"] -serve = ["tornado (>=4.0)"] -test = ["pytest", "pytest-cov", "pytest-dependency", "ipykernel", "ipywidgets (>=7)", "pyppeteer (>=1,<1.1)"] -webpdf = ["pyppeteer (>=1,<1.1)"] - -[[package]] -name = "nbformat" -version = "5.1.3" -description = "The Jupyter Notebook format" -category = "main" -optional = true -python-versions = ">=3.5" - -[package.dependencies] -ipython-genutils = "*" -jsonschema = ">=2.4,<2.5.0 || >2.5.0" -jupyter-core = "*" -traitlets = ">=4.1" - -[package.extras] -fast = ["fastjsonschema"] -test = ["check-manifest", "fastjsonschema", "testpath", "pytest", "pytest-cov"] - -[[package]] -name = "nest-asyncio" -version = "1.5.4" -description = "Patch asyncio to allow nested event loops" -category = "main" -optional = true -python-versions = ">=3.5" - -[[package]] -name = "networkx" -version = "2.6.3" -description = "Python package for creating and manipulating graphs and networks" -category = "main" -optional = false -python-versions = ">=3.7" - -[package.extras] -default = ["numpy (>=1.19)", "scipy (>=1.5,!=1.6.1)", "matplotlib (>=3.3)", "pandas (>=1.1)"] -developer = ["black (==21.5b1)", "pre-commit (>=2.12)"] -doc = ["sphinx (>=4.0,<5.0)", "pydata-sphinx-theme (>=0.6,<1.0)", "sphinx-gallery (>=0.9,<1.0)", "numpydoc (>=1.1)", "pillow (>=8.2)", "nb2plots (>=0.6)", "texext (>=0.6.6)"] -extra = ["lxml (>=4.5)", "pygraphviz (>=1.7)", "pydot (>=1.4.1)"] -test = ["pytest (>=6.2)", "pytest-cov (>=2.12)", "codecov (>=2.1)"] - -[[package]] -name = "nodeenv" -version = "1.6.0" -description = "Node.js virtual environment builder" -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "notebook" -version = "6.4.8" -description = "A web-based notebook environment for interactive computing" -category = "main" -optional = true -python-versions = ">=3.6" - -[package.dependencies] -argon2-cffi = "*" -ipykernel = "*" -ipython-genutils = "*" -jinja2 = "*" -jupyter-client = ">=5.3.4" -jupyter-core = ">=4.6.1" -nbconvert = "*" -nbformat = "*" -nest-asyncio = ">=1.5" -prometheus-client = "*" -pyzmq = ">=17" -Send2Trash = ">=1.8.0" -terminado = ">=0.8.3" -tornado = ">=6.1" -traitlets = ">=4.2.1" - -[package.extras] -docs = ["sphinx", "nbsphinx", "sphinxcontrib-github-alt", "sphinx-rtd-theme", "myst-parser"] -json-logging = ["json-logging"] -test = ["pytest", "coverage", "requests", "nbval", "selenium", "pytest-cov", "requests-unixsocket"] - -[[package]] -name = "numpy" -version = "1.21.5" -description = "NumPy is the fundamental package for array computing with Python." -category = "main" -optional = false -python-versions = ">=3.7,<3.11" - -[[package]] -name = "packaging" -version = "21.3" -description = "Core utilities for Python packages" -category = "main" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -pyparsing = ">=2.0.2,<3.0.5 || >3.0.5" - -[[package]] -name = "pandocfilters" -version = "1.5.0" -description = "Utilities for writing pandoc filters in python" -category = "main" -optional = true -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - -[[package]] -name = "parso" -version = "0.8.3" -description = "A Python Parser" -category = "main" -optional = true -python-versions = ">=3.6" - -[package.extras] -qa = ["flake8 (==3.8.3)", "mypy (==0.782)"] -testing = ["docopt", "pytest (<6.0.0)"] - -[[package]] -name = "pathspec" -version = "0.9.0" -description = "Utility library for gitignore style pattern matching of file paths." -category = "dev" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" - -[[package]] -name = "pexpect" -version = "4.8.0" -description = "Pexpect allows easy control of interactive console applications." -category = "main" -optional = true -python-versions = "*" - -[package.dependencies] -ptyprocess = ">=0.5" - -[[package]] -name = "pickleshare" -version = "0.7.5" -description = "Tiny 'shelve'-like database with concurrency support" -category = "main" -optional = true -python-versions = "*" - -[[package]] -name = "pillow" -version = "9.0.1" -description = "Python Imaging Library (Fork)" -category = "main" -optional = false -python-versions = ">=3.7" - -[[package]] -name = "platformdirs" -version = "2.5.0" -description = "A small Python module for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." -category = "dev" -optional = false -python-versions = ">=3.7" - -[package.extras] -docs = ["Sphinx (>=4)", "furo (>=2021.7.5b38)", "proselint (>=0.10.2)", "sphinx-autodoc-typehints (>=1.12)"] -test = ["appdirs (==1.4.4)", "pytest (>=6)", "pytest-cov (>=2.7)", "pytest-mock (>=3.6)"] - -[[package]] -name = "pluggy" -version = "1.0.0" -description = "plugin and hook calling mechanisms for python" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - -[[package]] -name = "pre-commit" -version = "2.17.0" -description = "A framework for managing and maintaining multi-language pre-commit hooks." -category = "dev" -optional = false -python-versions = ">=3.6.1" - -[package.dependencies] -cfgv = ">=2.0.0" -identify = ">=1.0.0" -importlib-metadata = {version = "*", markers = "python_version < \"3.8\""} -nodeenv = ">=0.11.1" -pyyaml = ">=5.1" -toml = "*" -virtualenv = ">=20.0.8" - -[[package]] -name = "prometheus-client" -version = "0.13.1" -description = "Python client for the Prometheus monitoring system." -category = "main" -optional = true -python-versions = ">=3.6" - -[package.extras] -twisted = ["twisted"] - -[[package]] -name = "prompt-toolkit" -version = "3.0.28" -description = "Library for building powerful interactive command lines in Python" -category = "main" -optional = true -python-versions = ">=3.6.2" - -[package.dependencies] -wcwidth = "*" - -[[package]] -name = "protobuf" -version = "3.19.4" -description = "Protocol Buffers" -category = "main" -optional = true -python-versions = ">=3.5" - -[[package]] -name = "psutil" -version = "5.9.0" -description = "Cross-platform lib for process and system monitoring in Python." -category = "dev" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - -[package.extras] -test = ["ipaddress", "mock", "unittest2", "enum34", "pywin32", "wmi"] - -[[package]] -name = "psutil-wheels" -version = "5.8.0" -description = "Cross-platform lib for process and system monitoring in Python." -category = "dev" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - -[package.extras] -test = ["ipaddress", "mock", "unittest2", "enum34", "pywin32", "wmi"] - -[[package]] -name = "ptyprocess" -version = "0.7.0" -description = "Run a subprocess in a pseudo terminal" -category = "main" -optional = true -python-versions = "*" - -[[package]] -name = "py" -version = "1.11.0" -description = "library with cross-python path, ini-parsing, io, code, log facilities" -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*" - -[[package]] -name = "pycairo" -version = "1.20.1" -description = "Python interface for cairo" -category = "main" -optional = false -python-versions = ">=3.6, <4" - -[[package]] -name = "pycodestyle" -version = "2.7.0" -description = "Python style guide checker" -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - -[[package]] -name = "pycparser" -version = "2.21" -description = "C parser in Python" -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - -[[package]] -name = "pydocstyle" -version = "6.1.1" -description = "Python docstring style checker" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -snowballstemmer = "*" - -[package.extras] -toml = ["toml"] - -[[package]] -name = "pydub" -version = "0.25.1" -description = "Manipulate audio with an simple and easy high level interface" -category = "main" -optional = false -python-versions = "*" - -[[package]] -name = "pyflakes" -version = "2.3.1" -description = "passive checker of Python programs" -category = "dev" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" - -[[package]] -name = "pygithub" -version = "1.55" -description = "Use the full Github API v3" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -deprecated = "*" -pyjwt = ">=2.0" -pynacl = ">=1.4.0" -requests = ">=2.14.0" - -[package.extras] -integrations = ["cryptography"] - -[[package]] -name = "pyglet" -version = "1.5.21" -description = "Cross-platform windowing and multimedia library" -category = "main" -optional = false -python-versions = "*" - -[[package]] -name = "pygments" -version = "2.11.2" -description = "Pygments is a syntax highlighting package written in Python." -category = "main" -optional = false -python-versions = ">=3.5" - -[[package]] -name = "pyjwt" -version = "2.3.0" -description = "JSON Web Token implementation in Python" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.extras] -crypto = ["cryptography (>=3.3.1)"] -dev = ["sphinx", "sphinx-rtd-theme", "zope.interface", "cryptography (>=3.3.1)", "pytest (>=6.0.0,<7.0.0)", "coverage[toml] (==5.0.4)", "mypy", "pre-commit"] -docs = ["sphinx", "sphinx-rtd-theme", "zope.interface"] -tests = ["pytest (>=6.0.0,<7.0.0)", "coverage[toml] (==5.0.4)"] - -[[package]] -name = "pylint" -version = "2.12.2" -description = "python code static checker" -category = "dev" -optional = false -python-versions = ">=3.6.2" - -[package.dependencies] -astroid = ">=2.9.0,<2.10" -colorama = {version = "*", markers = "sys_platform == \"win32\""} -isort = ">=4.2.5,<6" -mccabe = ">=0.6,<0.7" -platformdirs = ">=2.2.0" -toml = ">=0.9.2" -typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} - -[[package]] -name = "pynacl" -version = "1.5.0" -description = "Python binding to the Networking and Cryptography (NaCl) library" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -cffi = ">=1.4.1" - -[package.extras] -docs = ["sphinx (>=1.6.5)", "sphinx-rtd-theme"] -tests = ["pytest (>=3.2.1,!=3.3.0)", "hypothesis (>=3.27.0)"] - -[[package]] -name = "pyobjc-core" -version = "8.2" -description = "Python<->ObjC Interoperability Module" -category = "main" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "pyobjc-framework-cocoa" -version = "8.2" -description = "Wrappers for the Cocoa frameworks on macOS" -category = "main" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -pyobjc-core = ">=8.2" - -[[package]] -name = "pyparsing" -version = "3.0.7" -description = "Python parsing module" -category = "main" -optional = false -python-versions = ">=3.6" - -[package.extras] -diagrams = ["jinja2", "railroad-diagrams"] - -[[package]] -name = "pyrr" -version = "0.10.3" -description = "3D mathematical functions using NumPy" -category = "main" -optional = false -python-versions = "*" - -[package.dependencies] -multipledispatch = "*" -numpy = "*" - -[[package]] -name = "pyrsistent" -version = "0.18.1" -description = "Persistent/Functional/Immutable data structures" -category = "main" -optional = true -python-versions = ">=3.7" - -[[package]] -name = "pytest" -version = "6.2.5" -description = "pytest: simple powerful testing with Python" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -atomicwrites = {version = ">=1.0", markers = "sys_platform == \"win32\""} -attrs = ">=19.2.0" -colorama = {version = "*", markers = "sys_platform == \"win32\""} -importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=0.12,<2.0" -py = ">=1.8.2" -toml = "*" - -[package.extras] -testing = ["argcomplete", "hypothesis (>=3.56)", "mock", "nose", "requests", "xmlschema"] - -[[package]] -name = "pytest-cov" -version = "3.0.0" -description = "Pytest plugin for measuring coverage." -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -coverage = {version = ">=5.2.1", extras = ["toml"]} -pytest = ">=4.6" - -[package.extras] -testing = ["fields", "hunter", "process-tests", "six", "pytest-xdist", "virtualenv"] - -[[package]] -name = "pytest-forked" -version = "1.4.0" -description = "run tests in isolated forked subprocesses" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -py = "*" -pytest = ">=3.10" - -[[package]] -name = "pytest-xdist" -version = "2.5.0" -description = "pytest xdist plugin for distributed testing and loop-on-failing modes" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -execnet = ">=1.1" -pytest = ">=6.2.0" -pytest-forked = "*" - -[package.extras] -psutil = ["psutil (>=3.0)"] -setproctitle = ["setproctitle"] -testing = ["filelock"] - -[[package]] -name = "python-dateutil" -version = "2.8.2" -description = "Extensions to the standard Python datetime module" -category = "main" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" - -[package.dependencies] -six = ">=1.5" - -[[package]] -name = "pytz" -version = "2021.3" -description = "World timezone definitions, modern and historical" -category = "main" -optional = false -python-versions = "*" - -[[package]] -name = "pywin32" -version = "303" -description = "Python for Window Extensions" -category = "main" -optional = true -python-versions = "*" - -[[package]] -name = "pywinpty" -version = "1.1.6" -description = "Pseudo terminal support for Windows from Python." -category = "main" -optional = true -python-versions = ">=3.6" - -[[package]] -name = "pyyaml" -version = "6.0" -description = "YAML parser and emitter for Python" -category = "dev" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "pyzmq" -version = "22.3.0" -description = "Python bindings for 0MQ" -category = "main" -optional = true -python-versions = ">=3.6" - -[package.dependencies] -cffi = {version = "*", markers = "implementation_name == \"pypy\""} -py = {version = "*", markers = "implementation_name == \"pypy\""} - -[[package]] -name = "recommonmark" -version = "0.7.1" -description = "A docutils-compatibility bridge to CommonMark, enabling you to write CommonMark inside of Docutils & Sphinx projects." -category = "dev" -optional = false -python-versions = "*" - -[package.dependencies] -commonmark = ">=0.8.1" -docutils = ">=0.11" -sphinx = ">=1.3.1" - -[[package]] -name = "requests" -version = "2.27.1" -description = "Python HTTP for Humans." -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*" - -[package.dependencies] -certifi = ">=2017.4.17" -charset-normalizer = {version = ">=2.0.0,<2.1.0", markers = "python_version >= \"3\""} -idna = {version = ">=2.5,<4", markers = "python_version >= \"3\""} -urllib3 = ">=1.21.1,<1.27" - -[package.extras] -socks = ["PySocks (>=1.5.6,!=1.5.7)", "win-inet-pton"] -use_chardet_on_py3 = ["chardet (>=3.0.2,<5)"] - -[[package]] -name = "restructuredtext-lint" -version = "1.3.2" -description = "reStructuredText linter" -category = "dev" -optional = false -python-versions = "*" - -[package.dependencies] -docutils = ">=0.11,<1.0" - -[[package]] -name = "rich" -version = "11.2.0" -description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" -category = "main" -optional = false -python-versions = ">=3.6.2,<4.0.0" - -[package.dependencies] -colorama = ">=0.4.0,<0.5.0" -commonmark = ">=0.9.0,<0.10.0" -pygments = ">=2.6.0,<3.0.0" -typing-extensions = {version = ">=3.7.4,<5.0", markers = "python_version < \"3.8\""} - -[package.extras] -jupyter = ["ipywidgets (>=7.5.1,<8.0.0)"] - -[[package]] -name = "scipy" -version = "1.7.3" -description = "SciPy: Scientific Library for Python" -category = "main" -optional = false -python-versions = ">=3.7,<3.11" - -[package.dependencies] -numpy = ">=1.16.5,<1.23.0" - -[[package]] -name = "screeninfo" -version = "0.8" -description = "Fetch location and size of physical screens." -category = "main" -optional = false -python-versions = ">=3.6.2,<4.0.0" - -[package.dependencies] -Cython = {version = "*", markers = "sys_platform == \"darwin\""} -pyobjc-framework-Cocoa = {version = "*", markers = "sys_platform == \"darwin\""} - -[[package]] -name = "send2trash" -version = "1.8.0" -description = "Send file to trash natively under Mac OS X, Windows and Linux." -category = "main" -optional = true -python-versions = "*" - -[package.extras] -nativelib = ["pyobjc-framework-cocoa", "pywin32"] -objc = ["pyobjc-framework-cocoa"] -win32 = ["pywin32"] - -[[package]] -name = "setuptools-scm" -version = "6.4.2" -description = "the blessed package to manage your versions by scm tags" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -packaging = ">=20.0" -tomli = ">=1.0.0" - -[package.extras] -test = ["pytest (>=6.2)", "virtualenv (>20)"] -toml = ["setuptools (>=42)"] - -[[package]] -name = "six" -version = "1.16.0" -description = "Python 2 and 3 compatibility utilities" -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" - -[[package]] -name = "skia-pathops" -version = "0.7.2" -description = "Python access to operations on paths using the Skia library" -category = "main" -optional = false -python-versions = ">=3.7" - -[package.extras] -testing = ["pytest", "coverage", "pytest-xdist", "pytest-randomly"] - -[[package]] -name = "smmap" -version = "5.0.0" -description = "A pure Python implementation of a sliding window memory map manager" -category = "dev" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "sniffio" -version = "1.2.0" -description = "Sniff out which async library your code is running under" -category = "main" -optional = true -python-versions = ">=3.5" - -[[package]] -name = "snowballstemmer" -version = "2.2.0" -description = "This package provides 29 stemmers for 28 languages generated from Snowball algorithms." -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "soupsieve" -version = "2.3.1" -description = "A modern CSS selector implementation for Beautiful Soup." -category = "dev" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "sphinx" -version = "4.4.0" -description = "Python documentation generator" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -alabaster = ">=0.7,<0.8" -babel = ">=1.3" -colorama = {version = ">=0.3.5", markers = "sys_platform == \"win32\""} -docutils = ">=0.14,<0.18" -imagesize = "*" -importlib-metadata = {version = ">=4.4", markers = "python_version < \"3.10\""} -Jinja2 = ">=2.3" -packaging = "*" -Pygments = ">=2.0" -requests = ">=2.5.0" -snowballstemmer = ">=1.1" -sphinxcontrib-applehelp = "*" -sphinxcontrib-devhelp = "*" -sphinxcontrib-htmlhelp = ">=2.0.0" -sphinxcontrib-jsmath = "*" -sphinxcontrib-qthelp = "*" -sphinxcontrib-serializinghtml = ">=1.1.5" - -[package.extras] -docs = ["sphinxcontrib-websupport"] -lint = ["flake8 (>=3.5.0)", "isort", "mypy (>=0.931)", "docutils-stubs", "types-typed-ast", "types-requests"] -test = ["pytest", "pytest-cov", "html5lib", "cython", "typed-ast"] - -[[package]] -name = "sphinx-copybutton" -version = "0.4.0" -description = "Add a copy button to each of your code cells." -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -sphinx = ">=1.8" - -[package.extras] -code_style = ["pre-commit (==2.12.1)"] -rtd = ["sphinx", "ipython", "sphinx-book-theme"] - -[[package]] -name = "sphinxcontrib-applehelp" -version = "1.0.2" -description = "sphinxcontrib-applehelp is a sphinx extension which outputs Apple help books" -category = "dev" -optional = false -python-versions = ">=3.5" - -[package.extras] -lint = ["flake8", "mypy", "docutils-stubs"] -test = ["pytest"] - -[[package]] -name = "sphinxcontrib-devhelp" -version = "1.0.2" -description = "sphinxcontrib-devhelp is a sphinx extension which outputs Devhelp document." -category = "dev" -optional = false -python-versions = ">=3.5" - -[package.extras] -lint = ["flake8", "mypy", "docutils-stubs"] -test = ["pytest"] - -[[package]] -name = "sphinxcontrib-htmlhelp" -version = "2.0.0" -description = "sphinxcontrib-htmlhelp is a sphinx extension which renders HTML help files" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.extras] -lint = ["flake8", "mypy", "docutils-stubs"] -test = ["pytest", "html5lib"] - -[[package]] -name = "sphinxcontrib-jsmath" -version = "1.0.1" -description = "A sphinx extension which renders display math in HTML via JavaScript" -category = "dev" -optional = false -python-versions = ">=3.5" - -[package.extras] -test = ["pytest", "flake8", "mypy"] - -[[package]] -name = "sphinxcontrib-programoutput" -version = "0.17" -description = "Sphinx extension to include program output" -category = "dev" -optional = false -python-versions = ">=2.7,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*" - -[package.dependencies] -Sphinx = ">=1.7.0" - -[[package]] -name = "sphinxcontrib-qthelp" -version = "1.0.3" -description = "sphinxcontrib-qthelp is a sphinx extension which outputs QtHelp document." -category = "dev" -optional = false -python-versions = ">=3.5" - -[package.extras] -lint = ["flake8", "mypy", "docutils-stubs"] -test = ["pytest"] - -[[package]] -name = "sphinxcontrib-serializinghtml" -version = "1.1.5" -description = "sphinxcontrib-serializinghtml is a sphinx extension which outputs \"serialized\" HTML files (json and pickle)." -category = "dev" -optional = false -python-versions = ">=3.5" - -[package.extras] -lint = ["flake8", "mypy", "docutils-stubs"] -test = ["pytest"] - -[[package]] -name = "sphinxext-opengraph" -version = "0.5.1" -description = "Sphinx Extension to enable OGP support" -category = "dev" -optional = false -python-versions = ">=3.6" - -[package.dependencies] -sphinx = ">=2.0" - -[[package]] -name = "srt" -version = "3.5.1" -description = "A tiny library for parsing, modifying, and composing SRT files." -category = "main" -optional = false -python-versions = ">=2.7" - -[[package]] -name = "terminado" -version = "0.13.1" -description = "Tornado websocket backend for the Xterm.js Javascript terminal emulator library." -category = "main" -optional = true -python-versions = ">=3.7" - -[package.dependencies] -ptyprocess = {version = "*", markers = "os_name != \"nt\""} -pywinpty = {version = ">=1.1.0", markers = "os_name == \"nt\""} -tornado = ">=4" - -[package.extras] -test = ["pytest"] - -[[package]] -name = "testpath" -version = "0.5.0" -description = "Test utilities for code working with files and commands" -category = "main" -optional = true -python-versions = ">= 3.5" - -[package.extras] -test = ["pytest", "pathlib2"] - -[[package]] -name = "toml" -version = "0.10.2" -description = "Python Library for Tom's Obvious, Minimal Language" -category = "dev" -optional = false -python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" - -[[package]] -name = "tomli" -version = "2.0.1" -description = "A lil' TOML parser" -category = "dev" -optional = false -python-versions = ">=3.7" - -[[package]] -name = "tornado" -version = "6.1" -description = "Tornado is a Python web framework and asynchronous networking library, originally developed at FriendFeed." -category = "main" -optional = true -python-versions = ">= 3.5" - -[[package]] -name = "tqdm" -version = "4.62.3" -description = "Fast, Extensible Progress Meter" -category = "main" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.7" - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - -[package.extras] -dev = ["py-make (>=0.1.0)", "twine", "wheel"] -notebook = ["ipywidgets (>=6)"] -telegram = ["requests"] - -[[package]] -name = "traitlets" -version = "5.1.1" -description = "Traitlets Python configuration system" -category = "main" -optional = true -python-versions = ">=3.7" - -[package.extras] -test = ["pytest"] - -[[package]] -name = "typed-ast" -version = "1.5.2" -description = "a fork of Python 2 and 3 ast modules with type comment support" -category = "dev" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "types-decorator" -version = "0.1.7" -description = "Typing stubs for decorator" -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "types-docutils" -version = "0.17.5" -description = "Typing stubs for docutils" -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "types-pillow" -version = "8.3.11" -description = "Typing stubs for Pillow" -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "types-protobuf" -version = "3.19.12" -description = "Typing stubs for protobuf" -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "types-pygments" -version = "2.9.16" -description = "Typing stubs for Pygments" -category = "dev" -optional = false -python-versions = "*" - -[package.dependencies] -types-docutils = "*" -types-setuptools = "*" - -[[package]] -name = "types-requests" -version = "2.27.9" -description = "Typing stubs for requests" -category = "dev" -optional = false -python-versions = "*" - -[package.dependencies] -types-urllib3 = "<1.27" - -[[package]] -name = "types-setuptools" -version = "57.4.9" -description = "Typing stubs for setuptools" -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "types-urllib3" -version = "1.26.9" -description = "Typing stubs for urllib3" -category = "dev" -optional = false -python-versions = "*" - -[[package]] -name = "typing-extensions" -version = "4.1.1" -description = "Backported and Experimental Type Hints for Python 3.6+" -category = "main" -optional = false -python-versions = ">=3.6" - -[[package]] -name = "urllib3" -version = "1.26.8" -description = "HTTP library with thread-safe connection pooling, file post, and more." -category = "main" -optional = false -python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4" - -[package.extras] -brotli = ["brotlipy (>=0.6.0)"] -secure = ["pyOpenSSL (>=0.14)", "cryptography (>=1.3.4)", "idna (>=2.0.0)", "certifi", "ipaddress"] -socks = ["PySocks (>=1.5.6,!=1.5.7,<2.0)"] - -[[package]] -name = "virtualenv" -version = "20.13.1" -description = "Virtual Python Environment builder" -category = "dev" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" - -[package.dependencies] -distlib = ">=0.3.1,<1" -filelock = ">=3.2,<4" -importlib-metadata = {version = ">=0.12", markers = "python_version < \"3.8\""} -platformdirs = ">=2,<3" -six = ">=1.9.0,<2" - -[package.extras] -docs = ["proselint (>=0.10.2)", "sphinx (>=3)", "sphinx-argparse (>=0.2.5)", "sphinx-rtd-theme (>=0.4.3)", "towncrier (>=21.3)"] -testing = ["coverage (>=4)", "coverage-enable-subprocess (>=1)", "flaky (>=3)", "pytest (>=4)", "pytest-env (>=0.6.2)", "pytest-freezegun (>=0.4.1)", "pytest-mock (>=2)", "pytest-randomly (>=1)", "pytest-timeout (>=1)", "packaging (>=20.0)"] - -[[package]] -name = "watchdog" -version = "2.1.6" -description = "Filesystem events monitoring" -category = "main" -optional = false -python-versions = ">=3.6" - -[package.extras] -watchmedo = ["PyYAML (>=3.10)"] - -[[package]] -name = "wcwidth" -version = "0.2.5" -description = "Measures the displayed width of unicode strings in a terminal" -category = "main" -optional = true -python-versions = "*" - -[[package]] -name = "webencodings" -version = "0.5.1" -description = "Character encoding aliases for legacy web content" -category = "main" -optional = true -python-versions = "*" - -[[package]] -name = "websocket-client" -version = "1.2.3" -description = "WebSocket client for Python with low level API options" -category = "main" -optional = true -python-versions = ">=3.6" - -[package.extras] -docs = ["Sphinx (>=3.4)", "sphinx-rtd-theme (>=0.5)"] -optional = ["python-socks", "wsaccel"] -test = ["websockets"] - -[[package]] -name = "wrapt" -version = "1.13.3" -description = "Module for decorators, wrappers and monkey patching." -category = "dev" -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,>=2.7" - -[[package]] -name = "zipp" -version = "3.7.0" -description = "Backport of pathlib-compatible object wrapper for zip files" -category = "main" -optional = false -python-versions = ">=3.7" - -[package.extras] -docs = ["sphinx", "jaraco.packaging (>=8.2)", "rst.linker (>=1.9)"] -testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-flake8", "pytest-cov", "pytest-enabler (>=1.0.1)", "jaraco.itertools", "func-timeout", "pytest-black (>=0.3.7)", "pytest-mypy"] - -[extras] -gui = ["dearpygui"] -jupyterlab = ["jupyterlab"] -webgl_renderer = ["grpcio", "grpcio-tools"] - -[metadata] -lock-version = "1.1" -python-versions = ">=3.7,<3.11" -content-hash = "71c0d7995d4b6645952dd39c6d84b51871eced3e238d82e23e3d9dec43fc8096" - -[metadata.files] -alabaster = [ - {file = "alabaster-0.7.12-py2.py3-none-any.whl", hash = "sha256:446438bdcca0e05bd45ea2de1668c1d9b032e1a9154c2c259092d77031ddd359"}, - {file = "alabaster-0.7.12.tar.gz", hash = "sha256:a661d72d58e6ea8a57f7a86e37d86716863ee5e92788398526d58b26a4e4dc02"}, -] -anyio = [ - {file = "anyio-3.5.0-py3-none-any.whl", hash = "sha256:b5fa16c5ff93fa1046f2eeb5bbff2dad4d3514d6cda61d02816dba34fa8c3c2e"}, - {file = "anyio-3.5.0.tar.gz", hash = "sha256:a0aeffe2fb1fdf374a8e4b471444f0f3ac4fb9f5a5b542b48824475e0042a5a6"}, -] -appnope = [ - {file = "appnope-0.1.2-py2.py3-none-any.whl", hash = "sha256:93aa393e9d6c54c5cd570ccadd8edad61ea0c4b9ea7a01409020c9aa019eb442"}, - {file = "appnope-0.1.2.tar.gz", hash = "sha256:dd83cd4b5b460958838f6eb3000c660b1f9caf2a5b1de4264e941512f603258a"}, -] -argon2-cffi = [ - {file = "argon2-cffi-21.3.0.tar.gz", hash = "sha256:d384164d944190a7dd7ef22c6aa3ff197da12962bd04b17f64d4e93d934dba5b"}, - {file = "argon2_cffi-21.3.0-py3-none-any.whl", hash = "sha256:8c976986f2c5c0e5000919e6de187906cfd81fb1c72bf9d88c01177e77da7f80"}, -] -argon2-cffi-bindings = [ - {file = "argon2-cffi-bindings-21.2.0.tar.gz", hash = "sha256:bb89ceffa6c791807d1305ceb77dbfacc5aa499891d2c55661c6459651fc39e3"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ccb949252cb2ab3a08c02024acb77cfb179492d5701c7cbdbfd776124d4d2367"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9524464572e12979364b7d600abf96181d3541da11e23ddf565a32e70bd4dc0d"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b746dba803a79238e925d9046a63aa26bf86ab2a2fe74ce6b009a1c3f5c8f2ae"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58ed19212051f49a523abb1dbe954337dc82d947fb6e5a0da60f7c8471a8476c"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:bd46088725ef7f58b5a1ef7ca06647ebaf0eb4baff7d1d0d177c6cc8744abd86"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_i686.whl", hash = "sha256:8cd69c07dd875537a824deec19f978e0f2078fdda07fd5c42ac29668dda5f40f"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:f1152ac548bd5b8bcecfb0b0371f082037e47128653df2e8ba6e914d384f3c3e"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-win32.whl", hash = "sha256:603ca0aba86b1349b147cab91ae970c63118a0f30444d4bc80355937c950c082"}, - {file = "argon2_cffi_bindings-21.2.0-cp36-abi3-win_amd64.whl", hash = "sha256:b2ef1c30440dbbcba7a5dc3e319408b59676e2e039e2ae11a8775ecf482b192f"}, - {file = "argon2_cffi_bindings-21.2.0-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e415e3f62c8d124ee16018e491a009937f8cf7ebf5eb430ffc5de21b900dad93"}, - {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3e385d1c39c520c08b53d63300c3ecc28622f076f4c2b0e6d7e796e9f6502194"}, - {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c3e3cc67fdb7d82c4718f19b4e7a87123caf8a93fde7e23cf66ac0337d3cb3f"}, - {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6a22ad9800121b71099d0fb0a65323810a15f2e292f2ba450810a7316e128ee5"}, - {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f9f8b450ed0547e3d473fdc8612083fd08dd2120d6ac8f73828df9b7d45bb351"}, - {file = "argon2_cffi_bindings-21.2.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:93f9bf70084f97245ba10ee36575f0c3f1e7d7724d67d8e5b08e61787c320ed7"}, - {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3b9ef65804859d335dc6b31582cad2c5166f0c3e7975f324d9ffaa34ee7e6583"}, - {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4966ef5848d820776f5f562a7d45fdd70c2f330c961d0d745b784034bd9f48d"}, - {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:20ef543a89dee4db46a1a6e206cd015360e5a75822f76df533845c3cbaf72670"}, - {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ed2937d286e2ad0cc79a7087d3c272832865f779430e0cc2b4f3718d3159b0cb"}, - {file = "argon2_cffi_bindings-21.2.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:5e00316dabdaea0b2dd82d141cc66889ced0cdcbfa599e8b471cf22c620c329a"}, -] -astor = [ - {file = "astor-0.8.1-py2.py3-none-any.whl", hash = "sha256:070a54e890cefb5b3739d19f30f5a5ec840ffc9c50ffa7d23cc9fc1a38ebbfc5"}, - {file = "astor-0.8.1.tar.gz", hash = "sha256:6a6effda93f4e1ce9f618779b2dd1d9d84f1e32812c23a29b3fff6fd7f63fa5e"}, -] -astroid = [ - {file = "astroid-2.9.3-py3-none-any.whl", hash = "sha256:506daabe5edffb7e696ad82483ad0228245a9742ed7d2d8c9cdb31537decf9f6"}, - {file = "astroid-2.9.3.tar.gz", hash = "sha256:1efdf4e867d4d8ba4a9f6cf9ce07cd182c4c41de77f23814feb27ca93ca9d877"}, -] -atomicwrites = [ - {file = "atomicwrites-1.4.0-py2.py3-none-any.whl", hash = "sha256:6d1784dea7c0c8d4a5172b6c620f40b6e4cbfdf96d783691f2e1302a7b88e197"}, - {file = "atomicwrites-1.4.0.tar.gz", hash = "sha256:ae70396ad1a434f9c7046fd2dd196fc04b12f9e91ffb859164193be8b6168a7a"}, -] -attrs = [ - {file = "attrs-21.4.0-py2.py3-none-any.whl", hash = "sha256:2d27e3784d7a565d36ab851fe94887c5eccd6a463168875832a1be79c82828b4"}, - {file = "attrs-21.4.0.tar.gz", hash = "sha256:626ba8234211db98e869df76230a137c4c40a12d72445c45d5f5b716f076e2fd"}, -] -babel = [ - {file = "Babel-2.9.1-py2.py3-none-any.whl", hash = "sha256:ab49e12b91d937cd11f0b67cb259a57ab4ad2b59ac7a3b41d6c06c0ac5b0def9"}, - {file = "Babel-2.9.1.tar.gz", hash = "sha256:bc0c176f9f6a994582230df350aa6e05ba2ebe4b3ac317eab29d9be5d2768da0"}, -] -backcall = [ - {file = "backcall-0.2.0-py2.py3-none-any.whl", hash = "sha256:fbbce6a29f263178a1f7915c1940bde0ec2b2a967566fe1c65c1dfb7422bd255"}, - {file = "backcall-0.2.0.tar.gz", hash = "sha256:5cbdbf27be5e7cfadb448baf0aa95508f91f2bbc6c6437cd9cd06e2a4c215e1e"}, -] -"backports.cached-property" = [ - {file = "backports.cached-property-1.0.1.tar.gz", hash = "sha256:1a5ef1e750f8bc7d0204c807aae8e0f450c655be0cf4b30407a35fd4bb27186c"}, - {file = "backports.cached_property-1.0.1-py3-none-any.whl", hash = "sha256:687b5fe14be40aadcf547cae91337a1fdb84026046a39370274e54d3fe4fb4f9"}, -] -beautifulsoup4 = [ - {file = "beautifulsoup4-4.10.0-py3-none-any.whl", hash = "sha256:9a315ce70049920ea4572a4055bc4bd700c940521d36fc858205ad4fcde149bf"}, - {file = "beautifulsoup4-4.10.0.tar.gz", hash = "sha256:c23ad23c521d818955a4151a67d81580319d4bf548d3d49f4223ae041ff98891"}, -] -black = [ - {file = "black-22.1.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1297c63b9e1b96a3d0da2d85d11cd9bf8664251fd69ddac068b98dc4f34f73b6"}, - {file = "black-22.1.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2ff96450d3ad9ea499fc4c60e425a1439c2120cbbc1ab959ff20f7c76ec7e866"}, - {file = "black-22.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0e21e1f1efa65a50e3960edd068b6ae6d64ad6235bd8bfea116a03b21836af71"}, - {file = "black-22.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e2f69158a7d120fd641d1fa9a921d898e20d52e44a74a6fbbcc570a62a6bc8ab"}, - {file = "black-22.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:228b5ae2c8e3d6227e4bde5920d2fc66cc3400fde7bcc74f480cb07ef0b570d5"}, - {file = "black-22.1.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:b1a5ed73ab4c482208d20434f700d514f66ffe2840f63a6252ecc43a9bc77e8a"}, - {file = "black-22.1.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:35944b7100af4a985abfcaa860b06af15590deb1f392f06c8683b4381e8eeaf0"}, - {file = "black-22.1.0-cp36-cp36m-win_amd64.whl", hash = "sha256:7835fee5238fc0a0baf6c9268fb816b5f5cd9b8793423a75e8cd663c48d073ba"}, - {file = "black-22.1.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:dae63f2dbf82882fa3b2a3c49c32bffe144970a573cd68d247af6560fc493ae1"}, - {file = "black-22.1.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fa1db02410b1924b6749c245ab38d30621564e658297484952f3d8a39fce7e8"}, - {file = "black-22.1.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c8226f50b8c34a14608b848dc23a46e5d08397d009446353dad45e04af0c8e28"}, - {file = "black-22.1.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:2d6f331c02f0f40aa51a22e479c8209d37fcd520c77721c034517d44eecf5912"}, - {file = "black-22.1.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:742ce9af3086e5bd07e58c8feb09dbb2b047b7f566eb5f5bc63fd455814979f3"}, - {file = "black-22.1.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:fdb8754b453fb15fad3f72cd9cad3e16776f0964d67cf30ebcbf10327a3777a3"}, - {file = "black-22.1.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f5660feab44c2e3cb24b2419b998846cbb01c23c7fe645fee45087efa3da2d61"}, - {file = "black-22.1.0-cp38-cp38-win_amd64.whl", hash = "sha256:6f2f01381f91c1efb1451998bd65a129b3ed6f64f79663a55fe0e9b74a5f81fd"}, - {file = "black-22.1.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:efbadd9b52c060a8fc3b9658744091cb33c31f830b3f074422ed27bad2b18e8f"}, - {file = "black-22.1.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8871fcb4b447206904932b54b567923e5be802b9b19b744fdff092bd2f3118d0"}, - {file = "black-22.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ccad888050f5393f0d6029deea2a33e5ae371fd182a697313bdbd835d3edaf9c"}, - {file = "black-22.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:07e5c049442d7ca1a2fc273c79d1aecbbf1bc858f62e8184abe1ad175c4f7cc2"}, - {file = "black-22.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:373922fc66676133ddc3e754e4509196a8c392fec3f5ca4486673e685a421321"}, - {file = "black-22.1.0-py3-none-any.whl", hash = "sha256:3524739d76b6b3ed1132422bf9d82123cd1705086723bc3e235ca39fd21c667d"}, - {file = "black-22.1.0.tar.gz", hash = "sha256:a7c0192d35635f6fc1174be575cb7915e92e5dd629ee79fdaf0dcfa41a80afb5"}, -] -bleach = [ - {file = "bleach-4.1.0-py2.py3-none-any.whl", hash = "sha256:4d2651ab93271d1129ac9cbc679f524565cc8a1b791909c4a51eac4446a15994"}, - {file = "bleach-4.1.0.tar.gz", hash = "sha256:0900d8b37eba61a802ee40ac0061f8c2b5dee29c1927dd1d233e075ebf5a71da"}, -] -certifi = [ - {file = "certifi-2021.10.8-py2.py3-none-any.whl", hash = "sha256:d62a0163eb4c2344ac042ab2bdf75399a71a2d8c7d47eac2e2ee91b9d6339569"}, - {file = "certifi-2021.10.8.tar.gz", hash = "sha256:78884e7c1d4b00ce3cea67b44566851c4343c120abd683433ce934a68ea58872"}, -] -cffi = [ - {file = "cffi-1.15.0-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:c2502a1a03b6312837279c8c1bd3ebedf6c12c4228ddbad40912d671ccc8a962"}, - {file = "cffi-1.15.0-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:23cfe892bd5dd8941608f93348c0737e369e51c100d03718f108bf1add7bd6d0"}, - {file = "cffi-1.15.0-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:41d45de54cd277a7878919867c0f08b0cf817605e4eb94093e7516505d3c8d14"}, - {file = "cffi-1.15.0-cp27-cp27m-win32.whl", hash = "sha256:4a306fa632e8f0928956a41fa8e1d6243c71e7eb59ffbd165fc0b41e316b2474"}, - {file = "cffi-1.15.0-cp27-cp27m-win_amd64.whl", hash = "sha256:e7022a66d9b55e93e1a845d8c9eba2a1bebd4966cd8bfc25d9cd07d515b33fa6"}, - {file = "cffi-1.15.0-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:14cd121ea63ecdae71efa69c15c5543a4b5fbcd0bbe2aad864baca0063cecf27"}, - {file = "cffi-1.15.0-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:d4d692a89c5cf08a8557fdeb329b82e7bf609aadfaed6c0d79f5a449a3c7c023"}, - {file = "cffi-1.15.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0104fb5ae2391d46a4cb082abdd5c69ea4eab79d8d44eaaf79f1b1fd806ee4c2"}, - {file = "cffi-1.15.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:91ec59c33514b7c7559a6acda53bbfe1b283949c34fe7440bcf917f96ac0723e"}, - {file = "cffi-1.15.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f5c7150ad32ba43a07c4479f40241756145a1f03b43480e058cfd862bf5041c7"}, - {file = "cffi-1.15.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:00c878c90cb53ccfaae6b8bc18ad05d2036553e6d9d1d9dbcf323bbe83854ca3"}, - {file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:abb9a20a72ac4e0fdb50dae135ba5e77880518e742077ced47eb1499e29a443c"}, - {file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a5263e363c27b653a90078143adb3d076c1a748ec9ecc78ea2fb916f9b861962"}, - {file = "cffi-1.15.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f54a64f8b0c8ff0b64d18aa76675262e1700f3995182267998c31ae974fbc382"}, - {file = "cffi-1.15.0-cp310-cp310-win32.whl", hash = "sha256:c21c9e3896c23007803a875460fb786118f0cdd4434359577ea25eb556e34c55"}, - {file = "cffi-1.15.0-cp310-cp310-win_amd64.whl", hash = "sha256:5e069f72d497312b24fcc02073d70cb989045d1c91cbd53979366077959933e0"}, - {file = "cffi-1.15.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:64d4ec9f448dfe041705426000cc13e34e6e5bb13736e9fd62e34a0b0c41566e"}, - {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2756c88cbb94231c7a147402476be2c4df2f6078099a6f4a480d239a8817ae39"}, - {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b96a311ac60a3f6be21d2572e46ce67f09abcf4d09344c49274eb9e0bf345fc"}, - {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75e4024375654472cc27e91cbe9eaa08567f7fbdf822638be2814ce059f58032"}, - {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:59888172256cac5629e60e72e86598027aca6bf01fa2465bdb676d37636573e8"}, - {file = "cffi-1.15.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:27c219baf94952ae9d50ec19651a687b826792055353d07648a5695413e0c605"}, - {file = "cffi-1.15.0-cp36-cp36m-win32.whl", hash = "sha256:4958391dbd6249d7ad855b9ca88fae690783a6be9e86df65865058ed81fc860e"}, - {file = "cffi-1.15.0-cp36-cp36m-win_amd64.whl", hash = "sha256:f6f824dc3bce0edab5f427efcfb1d63ee75b6fcb7282900ccaf925be84efb0fc"}, - {file = "cffi-1.15.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:06c48159c1abed75c2e721b1715c379fa3200c7784271b3c46df01383b593636"}, - {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c2051981a968d7de9dd2d7b87bcb9c939c74a34626a6e2f8181455dd49ed69e4"}, - {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:fd8a250edc26254fe5b33be00402e6d287f562b6a5b2152dec302fa15bb3e997"}, - {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91d77d2a782be4274da750752bb1650a97bfd8f291022b379bb8e01c66b4e96b"}, - {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:45db3a33139e9c8f7c09234b5784a5e33d31fd6907800b316decad50af323ff2"}, - {file = "cffi-1.15.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:263cc3d821c4ab2213cbe8cd8b355a7f72a8324577dc865ef98487c1aeee2bc7"}, - {file = "cffi-1.15.0-cp37-cp37m-win32.whl", hash = "sha256:17771976e82e9f94976180f76468546834d22a7cc404b17c22df2a2c81db0c66"}, - {file = "cffi-1.15.0-cp37-cp37m-win_amd64.whl", hash = "sha256:3415c89f9204ee60cd09b235810be700e993e343a408693e80ce7f6a40108029"}, - {file = "cffi-1.15.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:4238e6dab5d6a8ba812de994bbb0a79bddbdf80994e4ce802b6f6f3142fcc880"}, - {file = "cffi-1.15.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0808014eb713677ec1292301ea4c81ad277b6cdf2fdd90fd540af98c0b101d20"}, - {file = "cffi-1.15.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:57e9ac9ccc3101fac9d6014fba037473e4358ef4e89f8e181f8951a2c0162024"}, - {file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b6c2ea03845c9f501ed1313e78de148cd3f6cad741a75d43a29b43da27f2e1e"}, - {file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:10dffb601ccfb65262a27233ac273d552ddc4d8ae1bf93b21c94b8511bffe728"}, - {file = "cffi-1.15.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:786902fb9ba7433aae840e0ed609f45c7bcd4e225ebb9c753aa39725bb3e6ad6"}, - {file = "cffi-1.15.0-cp38-cp38-win32.whl", hash = "sha256:da5db4e883f1ce37f55c667e5c0de439df76ac4cb55964655906306918e7363c"}, - {file = "cffi-1.15.0-cp38-cp38-win_amd64.whl", hash = "sha256:181dee03b1170ff1969489acf1c26533710231c58f95534e3edac87fff06c443"}, - {file = "cffi-1.15.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:45e8636704eacc432a206ac7345a5d3d2c62d95a507ec70d62f23cd91770482a"}, - {file = "cffi-1.15.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:31fb708d9d7c3f49a60f04cf5b119aeefe5644daba1cd2a0fe389b674fd1de37"}, - {file = "cffi-1.15.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:6dc2737a3674b3e344847c8686cf29e500584ccad76204efea14f451d4cc669a"}, - {file = "cffi-1.15.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:74fdfdbfdc48d3f47148976f49fab3251e550a8720bebc99bf1483f5bfb5db3e"}, - {file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffaa5c925128e29efbde7301d8ecaf35c8c60ffbcd6a1ffd3a552177c8e5e796"}, - {file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f7d084648d77af029acb79a0ff49a0ad7e9d09057a9bf46596dac9514dc07df"}, - {file = "cffi-1.15.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ef1f279350da2c586a69d32fc8733092fd32cc8ac95139a00377841f59a3f8d8"}, - {file = "cffi-1.15.0-cp39-cp39-win32.whl", hash = "sha256:2a23af14f408d53d5e6cd4e3d9a24ff9e05906ad574822a10563efcef137979a"}, - {file = "cffi-1.15.0-cp39-cp39-win_amd64.whl", hash = "sha256:3773c4d81e6e818df2efbc7dd77325ca0dcb688116050fb2b3011218eda36139"}, - {file = "cffi-1.15.0.tar.gz", hash = "sha256:920f0d66a896c2d99f0adbb391f990a84091179542c205fa53ce5787aff87954"}, -] -cfgv = [ - {file = "cfgv-3.3.1-py2.py3-none-any.whl", hash = "sha256:c6a0883f3917a037485059700b9e75da2464e6c27051014ad85ba6aaa5884426"}, - {file = "cfgv-3.3.1.tar.gz", hash = "sha256:f5a830efb9ce7a445376bb66ec94c638a9787422f96264c98edc6bdeed8ab736"}, -] -charset-normalizer = [ - {file = "charset-normalizer-2.0.12.tar.gz", hash = "sha256:2857e29ff0d34db842cd7ca3230549d1a697f96ee6d3fb071cfa6c7393832597"}, - {file = "charset_normalizer-2.0.12-py3-none-any.whl", hash = "sha256:6881edbebdb17b39b4eaaa821b438bf6eddffb4468cf344f09f89def34a8b1df"}, -] -click = [ - {file = "click-8.0.3-py3-none-any.whl", hash = "sha256:353f466495adaeb40b6b5f592f9f91cb22372351c84caeb068132442a4518ef3"}, - {file = "click-8.0.3.tar.gz", hash = "sha256:410e932b050f5eed773c4cda94de75971c89cdb3155a72a0831139a79e5ecb5b"}, -] -click-default-group = [ - {file = "click-default-group-1.2.2.tar.gz", hash = "sha256:d9560e8e8dfa44b3562fbc9425042a0fd6d21956fcc2db0077f63f34253ab904"}, -] -cloup = [ - {file = "cloup-0.7.1-py2.py3-none-any.whl", hash = "sha256:947c881ada77ea2f7b2876f7b5bb2fc7e5406daac5a045342acf8de35bcce5d7"}, - {file = "cloup-0.7.1.tar.gz", hash = "sha256:f26cc500dda4e4c9444ac1008b82376df8d72ecfa43a6310a9b3d54ef98add7b"}, -] -colorama = [ - {file = "colorama-0.4.4-py2.py3-none-any.whl", hash = "sha256:9f47eda37229f68eee03b24b9748937c7dc3868f906e8ba69fbcbdd3bc5dc3e2"}, - {file = "colorama-0.4.4.tar.gz", hash = "sha256:5941b2b48a20143d2267e95b1c2a7603ce057ee39fd88e7329b0c292aa16869b"}, -] -colour = [ - {file = "colour-0.1.5-py2.py3-none-any.whl", hash = "sha256:33f6db9d564fadc16e59921a56999b79571160ce09916303d35346dddc17978c"}, - {file = "colour-0.1.5.tar.gz", hash = "sha256:af20120fefd2afede8b001fbef2ea9da70ad7d49fafdb6489025dae8745c3aee"}, -] -commonmark = [ - {file = "commonmark-0.9.1-py2.py3-none-any.whl", hash = "sha256:da2f38c92590f83de410ba1a3cbceafbc74fee9def35f9251ba9a971d6d66fd9"}, - {file = "commonmark-0.9.1.tar.gz", hash = "sha256:452f9dc859be7f06631ddcb328b6919c67984aca654e5fefb3914d54691aed60"}, -] -coverage = [ - {file = "coverage-6.3.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:eeffd96882d8c06d31b65dddcf51db7c612547babc1c4c5db6a011abe9798525"}, - {file = "coverage-6.3.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:621f6ea7260ea2ffdaec64fe5cb521669984f567b66f62f81445221d4754df4c"}, - {file = "coverage-6.3.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:84f2436d6742c01136dd940ee158bfc7cf5ced3da7e4c949662b8703b5cd8145"}, - {file = "coverage-6.3.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:de73fca6fb403dd72d4da517cfc49fcf791f74eee697d3219f6be29adf5af6ce"}, - {file = "coverage-6.3.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78fbb2be068a13a5d99dce9e1e7d168db880870f7bc73f876152130575bd6167"}, - {file = "coverage-6.3.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:f5a4551dfd09c3bd12fca8144d47fe7745275adf3229b7223c2f9e29a975ebda"}, - {file = "coverage-6.3.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:7bff3a98f63b47464480de1b5bdd80c8fade0ba2832c9381253c9b74c4153c27"}, - {file = "coverage-6.3.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a06c358f4aed05fa1099c39decc8022261bb07dfadc127c08cfbd1391b09689e"}, - {file = "coverage-6.3.1-cp310-cp310-win32.whl", hash = "sha256:9fff3ff052922cb99f9e52f63f985d4f7a54f6b94287463bc66b7cdf3eb41217"}, - {file = "coverage-6.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:276b13cc085474e482566c477c25ed66a097b44c6e77132f3304ac0b039f83eb"}, - {file = "coverage-6.3.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:56c4a409381ddd7bbff134e9756077860d4e8a583d310a6f38a2315b9ce301d0"}, - {file = "coverage-6.3.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9eb494070aa060ceba6e4bbf44c1bc5fa97bfb883a0d9b0c9049415f9e944793"}, - {file = "coverage-6.3.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5e15d424b8153756b7c903bde6d4610be0c3daca3986173c18dd5c1a1625e4cd"}, - {file = "coverage-6.3.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:61d47a897c1e91f33f177c21de897267b38fbb45f2cd8e22a710bcef1df09ac1"}, - {file = "coverage-6.3.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:25e73d4c81efa8ea3785274a2f7f3bfbbeccb6fcba2a0bdd3be9223371c37554"}, - {file = "coverage-6.3.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:fac0bcc5b7e8169bffa87f0dcc24435446d329cbc2b5486d155c2e0f3b493ae1"}, - {file = "coverage-6.3.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:72128176fea72012063200b7b395ed8a57849282b207321124d7ff14e26988e8"}, - {file = "coverage-6.3.1-cp37-cp37m-win32.whl", hash = "sha256:1bc6d709939ff262fd1432f03f080c5042dc6508b6e0d3d20e61dd045456a1a0"}, - {file = "coverage-6.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:618eeba986cea7f621d8607ee378ecc8c2504b98b3fdc4952b30fe3578304687"}, - {file = "coverage-6.3.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d5ed164af5c9078596cfc40b078c3b337911190d3faeac830c3f1274f26b8320"}, - {file = "coverage-6.3.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:352c68e233409c31048a3725c446a9e48bbff36e39db92774d4f2380d630d8f8"}, - {file = "coverage-6.3.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:448d7bde7ceb6c69e08474c2ddbc5b4cd13c9e4aa4a717467f716b5fc938a734"}, - {file = "coverage-6.3.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9fde6b90889522c220dd56a670102ceef24955d994ff7af2cb786b4ba8fe11e4"}, - {file = "coverage-6.3.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e647a0be741edbb529a72644e999acb09f2ad60465f80757da183528941ff975"}, - {file = "coverage-6.3.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a5cdc3adb4f8bb8d8f5e64c2e9e282bc12980ef055ec6da59db562ee9bdfefa"}, - {file = "coverage-6.3.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:2dd70a167843b4b4b2630c0c56f1b586fe965b4f8ac5da05b6690344fd065c6b"}, - {file = "coverage-6.3.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:9ad0a117b8dc2061ce9461ea4c1b4799e55edceb236522c5b8f958ce9ed8fa9a"}, - {file = "coverage-6.3.1-cp38-cp38-win32.whl", hash = "sha256:e92c7a5f7d62edff50f60a045dc9542bf939758c95b2fcd686175dd10ce0ed10"}, - {file = "coverage-6.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:482fb42eea6164894ff82abbcf33d526362de5d1a7ed25af7ecbdddd28fc124f"}, - {file = "coverage-6.3.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c5b81fb37db76ebea79aa963b76d96ff854e7662921ce742293463635a87a78d"}, - {file = "coverage-6.3.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a4f923b9ab265136e57cc14794a15b9dcea07a9c578609cd5dbbfff28a0d15e6"}, - {file = "coverage-6.3.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56d296cbc8254a7dffdd7bcc2eb70be5a233aae7c01856d2d936f5ac4e8ac1f1"}, - {file = "coverage-6.3.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1245ab82e8554fa88c4b2ab1e098ae051faac5af829efdcf2ce6b34dccd5567c"}, - {file = "coverage-6.3.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f2b05757c92ad96b33dbf8e8ec8d4ccb9af6ae3c9e9bd141c7cc44d20c6bcba"}, - {file = "coverage-6.3.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9e3dd806f34de38d4c01416344e98eab2437ac450b3ae39c62a0ede2f8b5e4ed"}, - {file = "coverage-6.3.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:d651fde74a4d3122e5562705824507e2f5b2d3d57557f1916c4b27635f8fbe3f"}, - {file = "coverage-6.3.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:704f89b87c4f4737da2860695a18c852b78ec7279b24eedacab10b29067d3a38"}, - {file = "coverage-6.3.1-cp39-cp39-win32.whl", hash = "sha256:2aed4761809640f02e44e16b8b32c1a5dee5e80ea30a0ff0912158bde9c501f2"}, - {file = "coverage-6.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:9976fb0a5709988778ac9bc44f3d50fccd989987876dfd7716dee28beed0a9fa"}, - {file = "coverage-6.3.1-pp36.pp37.pp38-none-any.whl", hash = "sha256:463e52616ea687fd323888e86bf25e864a3cc6335a043fad6bbb037dbf49bbe2"}, - {file = "coverage-6.3.1.tar.gz", hash = "sha256:6c3f6158b02ac403868eea390930ae64e9a9a2a5bbfafefbb920d29258d9f2f8"}, -] -cycler = [ - {file = "cycler-0.11.0-py3-none-any.whl", hash = "sha256:3a27e95f763a428a739d2add979fa7494c912a32c17c4c38c4d5f082cad165a3"}, - {file = "cycler-0.11.0.tar.gz", hash = "sha256:9c87405839a19696e837b3b818fed3f5f69f16f1eec1a1ad77e043dcea9c772f"}, -] -cython = [ - {file = "Cython-0.29.27-cp27-cp27m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:af2b4e1e267737dae1732f02a9b567f58420a3e2f572dc4416829647ec109886"}, - {file = "Cython-0.29.27-cp27-cp27m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:62326774873cd1eff0cf7ca9132a1b6442541fe67c84dcfe97beb6a30f983b22"}, - {file = "Cython-0.29.27-cp27-cp27mu-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:0cb3da73547ed22d4b579990c229620b274d6935e3964f21abe15e4f7af6abf1"}, - {file = "Cython-0.29.27-cp27-cp27mu-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:314280475ba4ab334e6b40e502a1b3b36ac37a710a63b0a74c6a61dde5f7593c"}, - {file = "Cython-0.29.27-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:8e2963153212c3e699276059095fd9e20c5c97872b6dda893e7acfc5cef64df8"}, - {file = "Cython-0.29.27-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:80ea3b60d5e5b3b13ce90a4071734bbd88cf688fcfd3c82db0b47ae1e944c6a2"}, - {file = "Cython-0.29.27-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_24_i686.whl", hash = "sha256:25cb8e663dbd1e14a8f05dd6a79974ce6f0232b4dc417000fd790938face0304"}, - {file = "Cython-0.29.27-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7f3a5b826d9650268ff9bd7308bf79d8077b3b452da03337656d455bba05a9be"}, - {file = "Cython-0.29.27-cp35-cp35m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a1035e568cdc48dbd74f565828b36019fdb1b1437b3d7c1164c6f2a0757608f7"}, - {file = "Cython-0.29.27-cp35-cp35m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:179e8cf796f72df8977705c7887eee3231945f665c594ad1631fe690363bfb8e"}, - {file = "Cython-0.29.27-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:abcefbfb2c8f1b35c121a727745eb03c64cc15d0d71ebd827a6ce5c609503daa"}, - {file = "Cython-0.29.27-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:7742cac4a5a41c73309bc1bab568e955ad35eacaedf3b00971bc44afe0b5f04e"}, - {file = "Cython-0.29.27-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_24_i686.whl", hash = "sha256:f4a01915e33a524fca2a1e2512c0afc07f9fc51637f874bed1a831b56e789374"}, - {file = "Cython-0.29.27-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3138e4f89cb7e79d35bd6cbefe2d62c4723f2184ee414905ee0981ae0fbd92d6"}, - {file = "Cython-0.29.27-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:2dfdb4d5f63a0ae6748592b319878cbe360b12997cd8074836ef159381955d16"}, - {file = "Cython-0.29.27-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:4b9dbe37907b6b76d9673720e848209399b48530f6ab6178fa3a49d1af4a8d00"}, - {file = "Cython-0.29.27-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:ab4301aabcd75a436df0bbe13dbd9a3a9b6d3ad6aeb3ab577606af1642e134c2"}, - {file = "Cython-0.29.27-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:93e9f7c522f5ab3ea4e32ce6f42b123cb0bd9cdfe49726b5e43c4e5719654146"}, - {file = "Cython-0.29.27-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_24_i686.whl", hash = "sha256:6d337965a49dd52bc410685dbf63f2a95d6aa8d8be153a87c4178a06ff0e8ccd"}, - {file = "Cython-0.29.27-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1500dce7ae102bb27243b92a8461b9f7fd08c4514886e9a0da8b266de8e5c561"}, - {file = "Cython-0.29.27-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:03e0e9164e0a279c094897c6ae1505d816da59f98d664a77911b8d33f492e3f3"}, - {file = "Cython-0.29.27-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:0636e377ad81b8a106b12cddc57d3e69df94e03c77bdbccd0bd4394dda2484c9"}, - {file = "Cython-0.29.27-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:77519bc6816a0fa648795ef0d5337c18e4b7be1c43c4944599a87004037579c5"}, - {file = "Cython-0.29.27-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:65757e10590a1fbce84135491a5b53a1dc8c792cff78db4bb76b09d6df21dc0e"}, - {file = "Cython-0.29.27-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_24_i686.whl", hash = "sha256:0bf5182c6bf3fe73cf14f902506baa2b6ec3cea057775393f24eb66d3f2d1a51"}, - {file = "Cython-0.29.27-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d46fef39778dfb1d62e577c02dd2bac3930b9d28419d070ee0dae297e4a90af1"}, - {file = "Cython-0.29.27-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:ca361afc6152221476bc89c335d54b8241502c57b89c760ded9f2f2de2e2a0b5"}, - {file = "Cython-0.29.27-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:00c0f379763bf5f37a2180e4943cb69d0d96e90637aba596c3d9bc061c09f44d"}, - {file = "Cython-0.29.27-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:a571dcba3fbd755c187bb464a4cdaf1ce71ca7b92bdb8122c46c1812b86b6c2f"}, - {file = "Cython-0.29.27-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:11e88a9826ad71a0ab7eda04d065cb34f320b2f453bc654436c42870f79a7c47"}, - {file = "Cython-0.29.27-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_24_i686.whl", hash = "sha256:f3c738662c572676883561a393c8fb6e7a807ffb8fcd286c510ed88c27f53a65"}, - {file = "Cython-0.29.27-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:6670e5643fa05112aa88ea8f54088396fe5c113383cd898100450ad156fe1e4a"}, - {file = "Cython-0.29.27-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:f054331ed29f81cfd22335b96af9d33788b01338b1a5b7939f18412336ab06fd"}, - {file = "Cython-0.29.27-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:7149835ef701f8f9a417059253f52f393e4334d3819caf8ceab4194c9c4098ce"}, - {file = "Cython-0.29.27-py2.py3-none-any.whl", hash = "sha256:8e7ced83f7a3ab619abe03fa2ae2de888cc429028263c95655189085346b8fcc"}, - {file = "Cython-0.29.27.tar.gz", hash = "sha256:c6a442504db906dfc13a480e96850cced994ecdc076bcf492c43515b78f70da2"}, -] -data-science-types = [ - {file = "data-science-types-0.2.23.tar.gz", hash = "sha256:8096b9a35a8a187bf9a122b4707c97de841d810744690ee2a4ac30c6462e0d16"}, - {file = "data_science_types-0.2.23-py3-none-any.whl", hash = "sha256:bca319abc0e53a0316f9fcb887937e942477cb9e5fc63c8581e0b0438903b977"}, -] -dearpygui = [ - {file = "dearpygui-1.3.1-cp310-cp310-macosx_10_6_x86_64.whl", hash = "sha256:c9a23601a6770c479e72d4d791f36fad1eb0d2a6513e312ef7178ee12838ab2e"}, - {file = "dearpygui-1.3.1-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:cecde17108172c1ebcd0de79a5f950c1b0dabfe3e12f6e03c179b5b132fa6f89"}, - {file = "dearpygui-1.3.1-cp310-cp310-win_amd64.whl", hash = "sha256:4ac6ee1dec934830da5dc981a8b16a6fe6410bec6c8c026cc04bca6e95105f83"}, - {file = "dearpygui-1.3.1-cp36-cp36m-macosx_10_6_x86_64.whl", hash = "sha256:bbaa36feedde71b9108a66c544d636201da87b264e4770f5ff1c9951fd19ab54"}, - {file = "dearpygui-1.3.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:928526c3f37ee82087903dd08fc887f3746d6df59a41b774a27c0fbb999b0da5"}, - {file = "dearpygui-1.3.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b8b7a54c7b4c97c90ab52015ae26b1df7f04ba455d571ed1fc59b82df045eb2b"}, - {file = "dearpygui-1.3.1-cp37-cp37m-macosx_10_6_x86_64.whl", hash = "sha256:9783d62ce222e5b7c053ac8d0adb0a23f80490130ff2f71b02c8964e499ed15e"}, - {file = "dearpygui-1.3.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:7f157a7a695e9c2c33a1392a9814f7f83bf53ed0f05e388213a5677a990b6e88"}, - {file = "dearpygui-1.3.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4f9deacd24aeda6520f78d7c6a51f3b1e5e3545375dd5427547578dd5547fc90"}, - {file = "dearpygui-1.3.1-cp38-cp38-macosx_10_6_x86_64.whl", hash = "sha256:d860ed3b724d7910f1d4f107ba2ee7033da182b4afa49cb9799e16d637225d70"}, - {file = "dearpygui-1.3.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:9451832c21d77454b4e90f96820eb001a2b9b517228c1573ffd15bac89b881ae"}, - {file = "dearpygui-1.3.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:781eb24932e68cc72700677982be0dc01ba08aae9c19f9d25c0ba5f50926defd"}, - {file = "dearpygui-1.3.1-cp38-cp38-win_amd64.whl", hash = "sha256:210ed14d571c4f84b88bcba957bf59add8a0fc116981729928a7658359c62147"}, - {file = "dearpygui-1.3.1-cp39-cp39-macosx_10_6_x86_64.whl", hash = "sha256:c399728c93b0188c2a284539aa0f69f75751c43667b082c8c964b558c07bfbbf"}, - {file = "dearpygui-1.3.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:19c9286a41931a3c9763ccf0e57f6c1f4a5fccf8dd5687c1d138ce786029f5b4"}, - {file = "dearpygui-1.3.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:d5fdf9b65f4eb881b05a4f8ed01d63cf16551455883e7196fc302f16b106c994"}, - {file = "dearpygui-1.3.1-cp39-cp39-win_amd64.whl", hash = "sha256:af0097756a15aef656fd1bec103c71f99a3c11a173e7f21c47fa8dac3a029fd8"}, -] -debugpy = [ - {file = "debugpy-1.5.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:70b422c63a833630c33e3f9cdbd9b6971f8c5afd452697e464339a21bbe862ba"}, - {file = "debugpy-1.5.1-cp310-cp310-win32.whl", hash = "sha256:3a457ad9c0059a21a6c7d563c1f18e924f5cf90278c722bd50ede6f56b77c7fe"}, - {file = "debugpy-1.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:5d76a4fd028d8009c3faf1185b4b78ceb2273dd2499447664b03939e0368bb90"}, - {file = "debugpy-1.5.1-cp36-cp36m-macosx_10_15_x86_64.whl", hash = "sha256:16db27b4b91991442f91d73604d32080b30de655aca9ba821b1972ea8171021b"}, - {file = "debugpy-1.5.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2b073ad5e8d8c488fbb6a116986858bab0c9c4558f28deb8832c7a5a27405bd6"}, - {file = "debugpy-1.5.1-cp36-cp36m-win32.whl", hash = "sha256:318f81f37341e4e054b4267d39896b73cddb3612ca13b39d7eea45af65165e1d"}, - {file = "debugpy-1.5.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b5b3157372e0e0a1297a8b6b5280bcf1d35a40f436c7973771c972726d1e32d5"}, - {file = "debugpy-1.5.1-cp37-cp37m-macosx_10_15_x86_64.whl", hash = "sha256:1ec3a086e14bba6c472632025b8fe5bdfbaef2afa1ebd5c6615ce6ed8d89bc67"}, - {file = "debugpy-1.5.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:26fbe53cca45a608679094791ce587b6e2798acd1d4777a8b303b07622e85182"}, - {file = "debugpy-1.5.1-cp37-cp37m-win32.whl", hash = "sha256:d876db8c312eeb02d85611e0f696abe66a2c1515e6405943609e725d5ff36f2a"}, - {file = "debugpy-1.5.1-cp37-cp37m-win_amd64.whl", hash = "sha256:4404a62fb5332ea5c8c9132290eef50b3a0ba38cecacad5529e969a783bcbdd7"}, - {file = "debugpy-1.5.1-cp38-cp38-macosx_10_15_x86_64.whl", hash = "sha256:f3a3dca9104aa14fd4210edcce6d9ce2b65bd9618c0b222135a40b9d6e2a9eeb"}, - {file = "debugpy-1.5.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b2df2c373e85871086bd55271c929670cd4e1dba63e94a08d442db830646203b"}, - {file = "debugpy-1.5.1-cp38-cp38-win32.whl", hash = "sha256:82f5f9ce93af6861a0713f804e62ab390bb12a17f113153e47fea8bbb1dfbe36"}, - {file = "debugpy-1.5.1-cp38-cp38-win_amd64.whl", hash = "sha256:17a25ce9d7714f92fc97ef00cc06269d7c2b163094990ada30156ed31d9a5030"}, - {file = "debugpy-1.5.1-cp39-cp39-macosx_10_15_x86_64.whl", hash = "sha256:01e98c594b3e66d529e40edf314f849cd1a21f7a013298df58cd8e263bf8e184"}, - {file = "debugpy-1.5.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f73988422b17f071ad3c4383551ace1ba5ed810cbab5f9c362783d22d40a08dc"}, - {file = "debugpy-1.5.1-cp39-cp39-win32.whl", hash = "sha256:23df67fc56d59e386c342428a7953c2c06cc226d8525b11319153e96afb65b0c"}, - {file = "debugpy-1.5.1-cp39-cp39-win_amd64.whl", hash = "sha256:a2aa64f6d2ca7ded8a7e8a4e7cae3bc71866b09876b7b05cecad231779cb9156"}, - {file = "debugpy-1.5.1-py2.py3-none-any.whl", hash = "sha256:194f95dd3e84568b5489aab5689a3a2c044e8fdc06f1890b8b4f70b6b89f2778"}, - {file = "debugpy-1.5.1.zip", hash = "sha256:d2b09e91fbd1efa4f4fda121d49af89501beda50c18ed7499712c71a4bf3452e"}, -] -decorator = [ - {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"}, - {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"}, -] -defusedxml = [ - {file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"}, - {file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"}, -] -deprecated = [ - {file = "Deprecated-1.2.13-py2.py3-none-any.whl", hash = "sha256:64756e3e14c8c5eea9795d93c524551432a0be75629f8f29e67ab8caf076c76d"}, - {file = "Deprecated-1.2.13.tar.gz", hash = "sha256:43ac5335da90c31c24ba028af536a91d41d53f9e6901ddb021bcc572ce44e38d"}, -] -distlib = [ - {file = "distlib-0.3.4-py2.py3-none-any.whl", hash = "sha256:6564fe0a8f51e734df6333d08b8b94d4ea8ee6b99b5ed50613f731fd4089f34b"}, - {file = "distlib-0.3.4.zip", hash = "sha256:e4b58818180336dc9c529bfb9a0b58728ffc09ad92027a3f30b7cd91e3458579"}, -] -docutils = [ - {file = "docutils-0.17.1-py2.py3-none-any.whl", hash = "sha256:cf316c8370a737a022b72b56874f6602acf974a37a9fba42ec2876387549fc61"}, - {file = "docutils-0.17.1.tar.gz", hash = "sha256:686577d2e4c32380bb50cbb22f575ed742d58168cee37e99117a854bcd88f125"}, -] -entrypoints = [ - {file = "entrypoints-0.4-py3-none-any.whl", hash = "sha256:f174b5ff827504fd3cd97cc3f8649f3693f51538c7e4bdf3ef002c8429d42f9f"}, - {file = "entrypoints-0.4.tar.gz", hash = "sha256:b706eddaa9218a19ebcd67b56818f05bb27589b1ca9e8d797b74affad4ccacd4"}, -] -execnet = [ - {file = "execnet-1.9.0-py2.py3-none-any.whl", hash = "sha256:a295f7cc774947aac58dde7fdc85f4aa00c42adf5d8f5468fc630c1acf30a142"}, - {file = "execnet-1.9.0.tar.gz", hash = "sha256:8f694f3ba9cc92cab508b152dcfe322153975c29bda272e2fd7f3f00f36e47c5"}, -] -filelock = [ - {file = "filelock-3.4.2-py3-none-any.whl", hash = "sha256:cf0fc6a2f8d26bd900f19bf33915ca70ba4dd8c56903eeb14e1e7a2fd7590146"}, - {file = "filelock-3.4.2.tar.gz", hash = "sha256:38b4f4c989f9d06d44524df1b24bd19e167d851f19b50bf3e3559952dddc5b80"}, -] -flake8 = [ - {file = "flake8-3.9.2-py2.py3-none-any.whl", hash = "sha256:bf8fd333346d844f616e8d47905ef3a3384edae6b4e9beb0c5101e25e3110907"}, - {file = "flake8-3.9.2.tar.gz", hash = "sha256:07528381786f2a6237b061f6e96610a4167b226cb926e2aa2b6b1d78057c576b"}, -] -flake8-bugbear = [ - {file = "flake8-bugbear-21.11.29.tar.gz", hash = "sha256:8b04cb2fafc6a78e1a9d873bd3988e4282f7959bb6b0d7c1ae648ec09b937a7b"}, - {file = "flake8_bugbear-21.11.29-py36.py37.py38-none-any.whl", hash = "sha256:179e41ddae5de5e3c20d1f61736feeb234e70958fbb56ab3c28a67739c8e9a82"}, -] -flake8-builtins = [ - {file = "flake8-builtins-1.5.3.tar.gz", hash = "sha256:09998853b2405e98e61d2ff3027c47033adbdc17f9fe44ca58443d876eb00f3b"}, - {file = "flake8_builtins-1.5.3-py2.py3-none-any.whl", hash = "sha256:7706babee43879320376861897e5d1468e396a40b8918ed7bccf70e5f90b8687"}, -] -flake8-comprehensions = [ - {file = "flake8-comprehensions-3.8.0.tar.gz", hash = "sha256:8e108707637b1d13734f38e03435984f6b7854fa6b5a4e34f93e69534be8e521"}, - {file = "flake8_comprehensions-3.8.0-py3-none-any.whl", hash = "sha256:9406314803abe1193c064544ab14fdc43c58424c0882f6ff8a581eb73fc9bb58"}, -] -flake8-docstrings = [ - {file = "flake8-docstrings-1.6.0.tar.gz", hash = "sha256:9fe7c6a306064af8e62a055c2f61e9eb1da55f84bb39caef2b84ce53708ac34b"}, - {file = "flake8_docstrings-1.6.0-py2.py3-none-any.whl", hash = "sha256:99cac583d6c7e32dd28bbfbef120a7c0d1b6dde4adb5a9fd441c4227a6534bde"}, -] -flake8-plugin-utils = [ - {file = "flake8-plugin-utils-1.3.2.tar.gz", hash = "sha256:20fa2a8ca2decac50116edb42e6af0a1253ef639ad79941249b840531889c65a"}, - {file = "flake8_plugin_utils-1.3.2-py3-none-any.whl", hash = "sha256:1fe43e3e9acf3a7c0f6b88f5338cad37044d2f156c43cb6b080b5f9da8a76f06"}, -] -flake8-pytest-style = [ - {file = "flake8-pytest-style-1.6.0.tar.gz", hash = "sha256:c1175713e9e11b78cd1a035ed0bca0d1e41d09c4af329a952750b61d4194ddac"}, - {file = "flake8_pytest_style-1.6.0-py3-none-any.whl", hash = "sha256:5fedb371a950e9fe0e0e6bfc854be7d99151271208f34cd2cc517681ece27780"}, -] -flake8-rst-docstrings = [ - {file = "flake8-rst-docstrings-0.2.5.tar.gz", hash = "sha256:4fe93f997dea45d9d3c8bd220f12f0b6c359948fb943b5b48021a3f927edd816"}, - {file = "flake8_rst_docstrings-0.2.5-py3-none-any.whl", hash = "sha256:b99d9041b769b857efe45a448dc8c71b1bb311f9cacbdac5de82f96498105082"}, -] -flake8-simplify = [ - {file = "flake8_simplify-0.14.6-py3-none-any.whl", hash = "sha256:8831fb8ff46dee1018d0b4c29f043a010cffafce7309fca536fde8461b98b6f6"}, - {file = "flake8_simplify-0.14.6.tar.gz", hash = "sha256:c4008db8016707684a1f0502ee69f3c2da37687d3cf7031cc1f326bf5986bf47"}, -] -fonttools = [ - {file = "fonttools-4.29.1-py3-none-any.whl", hash = "sha256:1933415e0fbdf068815cb1baaa1f159e17830215f7e8624e5731122761627557"}, - {file = "fonttools-4.29.1.zip", hash = "sha256:2b18a172120e32128a80efee04cff487d5d140fe7d817deb648b2eee023a40e4"}, -] -furo = [ - {file = "furo-2021.11.23-py3-none-any.whl", hash = "sha256:6d396451ad1aadce380c662fca9362cb10f4fd85f296d74fe3ca32006eb641d7"}, - {file = "furo-2021.11.23.tar.gz", hash = "sha256:54cecac5f3b688b5c7370d72ecdf1cd91a6c53f0f42751f4a719184b562cde70"}, -] -gitdb = [ - {file = "gitdb-4.0.9-py3-none-any.whl", hash = "sha256:8033ad4e853066ba6ca92050b9df2f89301b8fc8bf7e9324d412a63f8bf1a8fd"}, - {file = "gitdb-4.0.9.tar.gz", hash = "sha256:bac2fd45c0a1c9cf619e63a90d62bdc63892ef92387424b855792a6cabe789aa"}, -] -gitpython = [ - {file = "GitPython-3.1.26-py3-none-any.whl", hash = "sha256:26ac35c212d1f7b16036361ca5cff3ec66e11753a0d677fb6c48fa4e1a9dd8d6"}, - {file = "GitPython-3.1.26.tar.gz", hash = "sha256:fc8868f63a2e6d268fb25f481995ba185a85a66fcad126f039323ff6635669ee"}, -] -glcontext = [ - {file = "glcontext-2.3.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:e558960888be5a4aa8e2f6f43b5320a227c8519bc3517bf7202cb40925114a6d"}, - {file = "glcontext-2.3.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8983f0eae99c4ec04ece197537d3914a2c9e21f074bd518f21ce3c4be6d300cb"}, - {file = "glcontext-2.3.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:5e9289db306a4255328128cea0d250e078c9546678659499f5d1e819924e2225"}, - {file = "glcontext-2.3.4-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_27_x86_64.whl", hash = "sha256:1ca421ca610b4c3da6e41be28585839af48fd961a0f2f4c8f3377a445e9b016a"}, - {file = "glcontext-2.3.4-cp310-cp310-win_amd64.whl", hash = "sha256:821f354c60ea82e73d3d5f788c22c31e60af578b0d4fd6aa9329a770ca966257"}, - {file = "glcontext-2.3.4-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:1af3314f20c97fa2a8fc6d2b68d597463066416a7cc3c1ea4f05b4ecb0fc3e9c"}, - {file = "glcontext-2.3.4-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:3e1ef7e93a6a0f8b89a76fb41c58af4d9e69686504785883b628f0eeee29b153"}, - {file = "glcontext-2.3.4-cp36-cp36m-win32.whl", hash = "sha256:448bafceaad2716a260fce53f171f168546691dddd18c1d4532c8d0e6f305a50"}, - {file = "glcontext-2.3.4-cp36-cp36m-win_amd64.whl", hash = "sha256:1ceb88d1cb22387af5a3d5e0223835ed0676da350774ba15ba68f6d815519f90"}, - {file = "glcontext-2.3.4-cp37-cp37m-macosx_10_14_x86_64.whl", hash = "sha256:0be3e1cb47fe3a8f48b2e66cdcc2d330490990aba3913648c9d67d58c646765e"}, - {file = "glcontext-2.3.4-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:0f99726238ac132cc1fd7b9a62e449c7914957f451e6aea1a54e24be8b1ce04a"}, - {file = "glcontext-2.3.4-cp37-cp37m-win32.whl", hash = "sha256:4290542e696ca6c52230521552ed26322d62eda935c43da01d9913af2e95165b"}, - {file = "glcontext-2.3.4-cp37-cp37m-win_amd64.whl", hash = "sha256:2d585a586cd5a401e9aeeca18c8d56a4b908cd5b365241ab6834e35f28f7dafb"}, - {file = "glcontext-2.3.4-cp38-cp38-macosx_10_14_x86_64.whl", hash = "sha256:b7eecb1a1f689bcb3b77f8aed45e6b9139b3dec4fdeef894b6a7aa2b7c9b4312"}, - {file = "glcontext-2.3.4-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:1ad78fce244afa860cb11c30c42fb710251035b2df4d84b0e72457128b7a830f"}, - {file = "glcontext-2.3.4-cp38-cp38-win32.whl", hash = "sha256:e71121ac65a98808f9caaeaa3912756c07cd6cf73857a90b31170703103b644c"}, - {file = "glcontext-2.3.4-cp38-cp38-win_amd64.whl", hash = "sha256:a27c5bbbe9d88ae547ddb89d3f55edec14b44126999d7f6214838240b1cb8c2a"}, - {file = "glcontext-2.3.4-cp39-cp39-macosx_10_14_x86_64.whl", hash = "sha256:25100ea7df50728937f96cb3cb6cba5ce42d674a0a6c2efae23198674212032a"}, - {file = "glcontext-2.3.4-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:2f99c62f234f2859d626e1b24d7949d8d76a3a6fb7c2883b6f376e70586ce0ad"}, - {file = "glcontext-2.3.4-cp39-cp39-win32.whl", hash = "sha256:e1404b84e40daf7181168f4afa4f6ac5c4984e1f090fbd538da5b49046e4a078"}, - {file = "glcontext-2.3.4-cp39-cp39-win_amd64.whl", hash = "sha256:247ac15cbef85befb8c3ddb62659cc36b26786f0cec609724b60419ffb0a423a"}, - {file = "glcontext-2.3.4.tar.gz", hash = "sha256:537cd5113f7a5c17094dee50107587adeaea01d4854407bdab8e3bcd808e0bc6"}, -] -grpcio = [ - {file = "grpcio-1.43.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:a4e786a8ee8b30b25d70ee52cda6d1dbba2a8ca2f1208d8e20ed8280774f15c8"}, - {file = "grpcio-1.43.0-cp310-cp310-macosx_10_10_universal2.whl", hash = "sha256:af9c3742f6c13575c0d4147a8454da0ff5308c4d9469462ff18402c6416942fe"}, - {file = "grpcio-1.43.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:fdac966699707b5554b815acc272d81e619dd0999f187cd52a61aef075f870ee"}, - {file = "grpcio-1.43.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6e463b4aa0a6b31cf2e57c4abc1a1b53531a18a570baeed39d8d7b65deb16b7e"}, - {file = "grpcio-1.43.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f11d05402e0ac3a284443d8a432d3dfc76a6bd3f7b5858cddd75617af2d7bd9b"}, - {file = "grpcio-1.43.0-cp310-cp310-win32.whl", hash = "sha256:c36f418c925a41fccada8f7ae9a3d3e227bfa837ddbfddd3d8b0ac252d12dda9"}, - {file = "grpcio-1.43.0-cp310-cp310-win_amd64.whl", hash = "sha256:772b943f34374744f70236bbbe0afe413ed80f9ae6303503f85e2b421d4bca92"}, - {file = "grpcio-1.43.0-cp36-cp36m-linux_armv7l.whl", hash = "sha256:cbc9b83211d905859dcf234ad39d7193ff0f05bfc3269c364fb0d114ee71de59"}, - {file = "grpcio-1.43.0-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:fb7229fa2a201a0c377ff3283174ec966da8f9fd7ffcc9a92f162d2e7fc9025b"}, - {file = "grpcio-1.43.0-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:17b75f220ee6923338155b4fcef4c38802b9a57bc57d112c9599a13a03e99f8d"}, - {file = "grpcio-1.43.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:6620a5b751b099b3b25553cfc03dfcd873cda06f9bb2ff7e9948ac7090e20f05"}, - {file = "grpcio-1.43.0-cp36-cp36m-manylinux_2_17_aarch64.whl", hash = "sha256:1898f999383baac5fcdbdef8ea5b1ef204f38dc211014eb6977ac6e55944d738"}, - {file = "grpcio-1.43.0-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:47b6821238d8978014d23b1132713dac6c2d72cbb561cf257608b1673894f90a"}, - {file = "grpcio-1.43.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80398e9fb598060fa41050d1220f5a2440fe74ff082c36dda41ac3215ebb5ddd"}, - {file = "grpcio-1.43.0-cp36-cp36m-win32.whl", hash = "sha256:0110310eff07bb69782f53b7a947490268c4645de559034c43c0a635612e250f"}, - {file = "grpcio-1.43.0-cp36-cp36m-win_amd64.whl", hash = "sha256:45401d00f2ee46bde75618bf33e9df960daa7980e6e0e7328047191918c98504"}, - {file = "grpcio-1.43.0-cp37-cp37m-linux_armv7l.whl", hash = "sha256:af78ac55933811e6a25141336b1f2d5e0659c2f568d44d20539b273792563ca7"}, - {file = "grpcio-1.43.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:8b2b9dc4d7897566723b77422e11c009a0ebd397966b165b21b89a62891a9fdf"}, - {file = "grpcio-1.43.0-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:77ef653f966934b3bfdd00e4f2064b68880eb40cf09b0b99edfa5ee22a44f559"}, - {file = "grpcio-1.43.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:e95b5d62ec26d0cd0b90c202d73e7cb927c369c3358e027225239a4e354967dc"}, - {file = "grpcio-1.43.0-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:04239e8f71db832c26bbbedb4537b37550a39d77681d748ab4678e58dd6455d6"}, - {file = "grpcio-1.43.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4b4a7152187a49767a47d1413edde2304c96f41f7bc92cc512e230dfd0fba095"}, - {file = "grpcio-1.43.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8cc936a29c65ab39714e1ba67a694c41218f98b6e2a64efb83f04d9abc4386b"}, - {file = "grpcio-1.43.0-cp37-cp37m-win32.whl", hash = "sha256:577e024c8dd5f27cd98ba850bc4e890f07d4b5942e5bc059a3d88843a2f48f66"}, - {file = "grpcio-1.43.0-cp37-cp37m-win_amd64.whl", hash = "sha256:138f57e3445d4a48d9a8a5af1538fdaafaa50a0a3c243f281d8df0edf221dc02"}, - {file = "grpcio-1.43.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:08cf25f2936629db062aeddbb594bd76b3383ab0ede75ef0461a3b0bc3a2c150"}, - {file = "grpcio-1.43.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:01f4b887ed703fe82ebe613e1d2dadea517891725e17e7a6134dcd00352bd28c"}, - {file = "grpcio-1.43.0-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:0aa8285f284338eb68962fe1a830291db06f366ea12f213399b520c062b01f65"}, - {file = "grpcio-1.43.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:0edbfeb6729aa9da33ce7e28fb7703b3754934115454ae45e8cc1db601756fd3"}, - {file = "grpcio-1.43.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:c354017819201053d65212befd1dcb65c2d91b704d8977e696bae79c47cd2f82"}, - {file = "grpcio-1.43.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:50cfb7e1067ee5e00b8ab100a6b7ea322d37ec6672c0455106520b5891c4b5f5"}, - {file = "grpcio-1.43.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:57f1aeb65ed17dfb2f6cd717cc109910fe395133af7257a9c729c0b9604eac10"}, - {file = "grpcio-1.43.0-cp38-cp38-win32.whl", hash = "sha256:fa26a8bbb3fe57845acb1329ff700d5c7eaf06414c3e15f4cb8923f3a466ef64"}, - {file = "grpcio-1.43.0-cp38-cp38-win_amd64.whl", hash = "sha256:ade8b79a6b6aea68adb9d4bfeba5d647667d842202c5d8f3ba37ac1dc8e5c09c"}, - {file = "grpcio-1.43.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:124e718faf96fe44c98b05f3f475076be8b5198bb4c52a13208acf88a8548ba9"}, - {file = "grpcio-1.43.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:2f96142d0abc91290a63ba203f01649e498302b1b6007c67bad17f823ecde0cf"}, - {file = "grpcio-1.43.0-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:31e6e489ccd8f08884b9349a39610982df48535881ec34f05a11c6e6b6ebf9d0"}, - {file = "grpcio-1.43.0-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:0e731f660e1e68238f56f4ce11156f02fd06dc58bc7834778d42c0081d4ef5ad"}, - {file = "grpcio-1.43.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:1f16725a320460435a8a5339d8b06c4e00d307ab5ad56746af2e22b5f9c50932"}, - {file = "grpcio-1.43.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a4b4543e13acb4806917d883d0f70f21ba93b29672ea81f4aaba14821aaf9bb0"}, - {file = "grpcio-1.43.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:594aaa0469f4fca7773e80d8c27bf1298e7bbce5f6da0f084b07489a708f16ab"}, - {file = "grpcio-1.43.0-cp39-cp39-win32.whl", hash = "sha256:5449ae564349e7a738b8c38583c0aad954b0d5d1dd3cea68953bfc32eaee11e3"}, - {file = "grpcio-1.43.0-cp39-cp39-win_amd64.whl", hash = "sha256:bdf41550815a831384d21a498b20597417fd31bd084deb17d31ceb39ad9acc79"}, - {file = "grpcio-1.43.0.tar.gz", hash = "sha256:735d9a437c262ab039d02defddcb9f8f545d7009ae61c0114e19dda3843febe5"}, -] -grpcio-tools = [ - {file = "grpcio-tools-1.43.0.tar.gz", hash = "sha256:f42f1d713096808b1b0472dd2a3749b712d13f0092dab9442d9c096446e860b2"}, - {file = "grpcio_tools-1.43.0-cp310-cp310-linux_armv7l.whl", hash = "sha256:766771ef5b60ebcba0a3bdb302dd92fda988552eb8508451ff6d97371eac38e5"}, - {file = "grpcio_tools-1.43.0-cp310-cp310-macosx_10_10_universal2.whl", hash = "sha256:178a881db5de0f89abf3aeeb260ecfd1116cc31f88fb600a45fb5b19c3323b33"}, - {file = "grpcio_tools-1.43.0-cp310-cp310-manylinux_2_17_aarch64.whl", hash = "sha256:019f55929e963214471825c7a4cdab7a57069109d5621b24e4db7b428b5fe47d"}, - {file = "grpcio_tools-1.43.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e6c0e1d1b47554c580882d392b739df91a55b6a8ec696b2b2e1bbc127d63df2c"}, - {file = "grpcio_tools-1.43.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c5c80098fa69593b828d119973744de03c3f9a6935df8a02e4329a39b7072f5"}, - {file = "grpcio_tools-1.43.0-cp310-cp310-win32.whl", hash = "sha256:53f7dcaa4218df1b64b39d0fc7236a8270e8ab2db4ab8cd1d2fda0e6d4544946"}, - {file = "grpcio_tools-1.43.0-cp310-cp310-win_amd64.whl", hash = "sha256:5be6d402b0cafef20ba3abb3baa37444961d9a9c4a6434d3d7c1f082f7697deb"}, - {file = "grpcio_tools-1.43.0-cp36-cp36m-linux_armv7l.whl", hash = "sha256:8953fdebef6905d7ff13a5a376b21b6fecd808d18bf4f0d3990ffe4a215d56eb"}, - {file = "grpcio_tools-1.43.0-cp36-cp36m-macosx_10_10_x86_64.whl", hash = "sha256:18870dcc8369ac4c37213e6796d8dc20494ea770670204f5e573f88e69eaaf0b"}, - {file = "grpcio_tools-1.43.0-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:010a4be6a2fccbd6741a4809c5da7f2e39a1e9e227745e6b495be567638bbeb9"}, - {file = "grpcio_tools-1.43.0-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:426f16b6b14d533ce61249a18fbcd1a23a4fa0c71a6d7ab347b1c7f862847bb8"}, - {file = "grpcio_tools-1.43.0-cp36-cp36m-manylinux_2_17_aarch64.whl", hash = "sha256:f974cb0bea88bac892c3ed16da92c6ac88cff0fea17f24bf0e1892eb4d27cd00"}, - {file = "grpcio_tools-1.43.0-cp36-cp36m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:55c2e604536e06248e2f81e549737fb3a180c8117832e494a0a8a81fbde44837"}, - {file = "grpcio_tools-1.43.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f97f9ffa49348fb24692751d2d4455ef2968bd07fe536d65597caaec14222629"}, - {file = "grpcio_tools-1.43.0-cp36-cp36m-win32.whl", hash = "sha256:6eaf97414237b8670ae9fa623879a26eabcc4c635b550c79a81e17eb600d6ae3"}, - {file = "grpcio_tools-1.43.0-cp36-cp36m-win_amd64.whl", hash = "sha256:04f100c1f6a7c72c537760c33582f6970070bd6fa6676b529bccfa31cc58bc79"}, - {file = "grpcio_tools-1.43.0-cp37-cp37m-linux_armv7l.whl", hash = "sha256:9dbb6d1f58f26d88ae689f1b49de84cfaf4786c81c01b9001d3ceea178116a07"}, - {file = "grpcio_tools-1.43.0-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:63862a441a77f6326ea9fe4bb005882f0e363441a5968d9cf8621c34d3dadc2b"}, - {file = "grpcio_tools-1.43.0-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:6dea0cb2e79b67593553ed8662f70e4310599fa8850fc0e056b19fcb63572b7f"}, - {file = "grpcio_tools-1.43.0-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:3eb4aa5b0e578c3d9d9da8e37a2ef73654287a498b8081543acd0db7f0ec1a9c"}, - {file = "grpcio_tools-1.43.0-cp37-cp37m-manylinux_2_17_aarch64.whl", hash = "sha256:09464c6b17663088144b7e6ea10e9465efdcee03d4b2ffefab39a799bd8360f8"}, - {file = "grpcio_tools-1.43.0-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2458d6b0404f83d95aef00cec01f310d30e9719564a25be50e39b259f6a2da5d"}, - {file = "grpcio_tools-1.43.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2e9bb5da437364b7dcd2d3c6850747081ecbec0ba645c96c6d471f7e21fdcadb"}, - {file = "grpcio_tools-1.43.0-cp37-cp37m-win32.whl", hash = "sha256:2737f749a6ab965748629e619b35f3e1cbe5820fc79e34c88f73cb99efc71dde"}, - {file = "grpcio_tools-1.43.0-cp37-cp37m-win_amd64.whl", hash = "sha256:c39cbe7b902bb92f9afaa035091f5e2b8be35acbac501fec8cb6a0be7d7cdbbd"}, - {file = "grpcio_tools-1.43.0-cp38-cp38-linux_armv7l.whl", hash = "sha256:05550ba473cff7c09e905fcfb2263fd1f7600389660194ec022b5d5a3802534b"}, - {file = "grpcio_tools-1.43.0-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:ce13a922db8f5f95c5041d3a4cbf04d942b353f0cba9b251a674f69a31a2d3a6"}, - {file = "grpcio_tools-1.43.0-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:f19d40690c97365c1c1bde81474e6f496d7ab76f87e6d2889c72ad01bac98f2d"}, - {file = "grpcio_tools-1.43.0-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:ba3da574eb08fcaed541b3fc97ce217360fd86d954fa9ad6a604803d57a2e049"}, - {file = "grpcio_tools-1.43.0-cp38-cp38-manylinux_2_17_aarch64.whl", hash = "sha256:efd1eb5880001f5189cfa3a774675cc9bbc8cc51586a3e90fe796394ac8626b8"}, - {file = "grpcio_tools-1.43.0-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:234c7a5af653357df5c616e013173eddda6193146c8ab38f3108c4784f66be26"}, - {file = "grpcio_tools-1.43.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7e3662f62d410b3f81823b5fa0f79c6e0e250977a1058e4131867b85138a661"}, - {file = "grpcio_tools-1.43.0-cp38-cp38-win32.whl", hash = "sha256:5f2e584d7644ef924e9e042fa151a3bb9f7c28ef1ae260ee6c9cb327982b5e94"}, - {file = "grpcio_tools-1.43.0-cp38-cp38-win_amd64.whl", hash = "sha256:98dcb5b756855110fb661ccd6a93a716610b7efcd5720a3aec01358a1a892c30"}, - {file = "grpcio_tools-1.43.0-cp39-cp39-linux_armv7l.whl", hash = "sha256:61ef6cb6ccf9b9c27bb85fffc5338194bcf444df502196c2ad0ff8df4706d41e"}, - {file = "grpcio_tools-1.43.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:1def9b68ac9e62674929bc6590a33d89635f1cf16016657d9e16a69f41aa5c36"}, - {file = "grpcio_tools-1.43.0-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:b68cc0c95a0f8c757e8d69b5fa46111d5c9d887ae62af28f827649b1d1b70fe1"}, - {file = "grpcio_tools-1.43.0-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:e956b5c3b586d7b27eae49fb06f544a26288596fe12e22ffec768109717276d1"}, - {file = "grpcio_tools-1.43.0-cp39-cp39-manylinux_2_17_aarch64.whl", hash = "sha256:671e61bbc91d8d568f12c3654bb5a91fce9f3fdfd5ec2cfc60c2d3a840449aa6"}, - {file = "grpcio_tools-1.43.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d7173ed19854d1066bce9bdc09f735ca9c13e74a25d47a1cc5d1fe803b53bffb"}, - {file = "grpcio_tools-1.43.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1adb0dbcc1c10b86dcda910b8f56e39210e401bcee923dba166ba923a5f4696a"}, - {file = "grpcio_tools-1.43.0-cp39-cp39-win32.whl", hash = "sha256:ebfb94ddb454a6dc3a505d9531dc81c948e6364e181b8795bfad3f3f479974dc"}, - {file = "grpcio_tools-1.43.0-cp39-cp39-win_amd64.whl", hash = "sha256:d21928b680e6e29538688cffbf53f3d5a53cff0ec8f0c33139641700045bdf1a"}, -] -identify = [ - {file = "identify-2.4.9-py2.py3-none-any.whl", hash = "sha256:bff7c4959d68510bc28b99d664b6a623e36c6eadc933f89a4e0a9ddff9b4fee4"}, - {file = "identify-2.4.9.tar.gz", hash = "sha256:e926ae3b3dc142b6a7a9c65433eb14ccac751b724ee255f7c2ed3b5970d764fb"}, -] -idna = [ - {file = "idna-3.3-py3-none-any.whl", hash = "sha256:84d9dd047ffa80596e0f246e2eab0b391788b0503584e8945f2368256d2735ff"}, - {file = "idna-3.3.tar.gz", hash = "sha256:9d643ff0a55b762d5cdb124b8eaa99c66322e2157b69160bc32796e824360e6d"}, -] -imagesize = [ - {file = "imagesize-1.3.0-py2.py3-none-any.whl", hash = "sha256:1db2f82529e53c3e929e8926a1fa9235aa82d0bd0c580359c67ec31b2fddaa8c"}, - {file = "imagesize-1.3.0.tar.gz", hash = "sha256:cd1750d452385ca327479d45b64d9c7729ecf0b3969a58148298c77092261f9d"}, -] -importlib-metadata = [ - {file = "importlib_metadata-4.11.0-py3-none-any.whl", hash = "sha256:6affcdb3aec542dd98df8211e730bba6c5f2bec8288d47bacacde898f548c9ad"}, - {file = "importlib_metadata-4.11.0.tar.gz", hash = "sha256:9e5e553bbba1843cb4a00823014b907616be46ee503d2b9ba001d214a8da218f"}, -] -importlib-resources = [ - {file = "importlib_resources-5.4.0-py3-none-any.whl", hash = "sha256:33a95faed5fc19b4bc16b29a6eeae248a3fe69dd55d4d229d2b480e23eeaad45"}, - {file = "importlib_resources-5.4.0.tar.gz", hash = "sha256:d756e2f85dd4de2ba89be0b21dba2a3bbec2e871a42a3a16719258a11f87506b"}, -] -iniconfig = [ - {file = "iniconfig-1.1.1-py2.py3-none-any.whl", hash = "sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3"}, - {file = "iniconfig-1.1.1.tar.gz", hash = "sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32"}, -] -ipykernel = [ - {file = "ipykernel-6.9.0-py3-none-any.whl", hash = "sha256:1626b91c50e4605555ac6e5b29f1e5206d299a4a4a21483770a181be97f0f0e0"}, - {file = "ipykernel-6.9.0.tar.gz", hash = "sha256:b556e292dc6fa223f24328b1c936b9c921fafcc2f420bb0d6cfdfc42eaa90225"}, -] -ipython = [ - {file = "ipython-7.31.1-py3-none-any.whl", hash = "sha256:55df3e0bd0f94e715abd968bedd89d4e8a7bce4bf498fb123fed4f5398fea874"}, - {file = "ipython-7.31.1.tar.gz", hash = "sha256:b5548ec5329a4bcf054a5deed5099b0f9622eb9ea51aaa7104d215fece201d8c"}, -] -ipython-genutils = [ - {file = "ipython_genutils-0.2.0-py2.py3-none-any.whl", hash = "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8"}, - {file = "ipython_genutils-0.2.0.tar.gz", hash = "sha256:eb2e116e75ecef9d4d228fdc66af54269afa26ab4463042e33785b887c628ba8"}, -] -isort = [ - {file = "isort-5.10.1-py3-none-any.whl", hash = "sha256:6f62d78e2f89b4500b080fe3a81690850cd254227f27f75c3a0c491a1f351ba7"}, - {file = "isort-5.10.1.tar.gz", hash = "sha256:e8443a5e7a020e9d7f97f1d7d9cd17c88bcb3bc7e218bf9cf5095fe550be2951"}, -] -isosurfaces = [ - {file = "isosurfaces-0.1.0-py3-none-any.whl", hash = "sha256:a3421f7e7115f72f8f1af538ac4723e5570b1aaa0ddfc6a86520d2d781f3e91f"}, - {file = "isosurfaces-0.1.0.tar.gz", hash = "sha256:fa1b44e5e59d2f429add49289ab89e36f8dcda49b7badd99e0beea273be331f4"}, -] -jedi = [ - {file = "jedi-0.18.1-py2.py3-none-any.whl", hash = "sha256:637c9635fcf47945ceb91cd7f320234a7be540ded6f3e99a50cb6febdfd1ba8d"}, - {file = "jedi-0.18.1.tar.gz", hash = "sha256:74137626a64a99c8eb6ae5832d99b3bdd7d29a3850fe2aa80a4126b2a7d949ab"}, -] -jinja2 = [ - {file = "Jinja2-3.0.3-py3-none-any.whl", hash = "sha256:077ce6014f7b40d03b47d1f1ca4b0fc8328a692bd284016f806ed0eaca390ad8"}, - {file = "Jinja2-3.0.3.tar.gz", hash = "sha256:611bb273cd68f3b993fabdc4064fc858c5b47a973cb5aa7999ec1ba405c87cd7"}, -] -json5 = [ - {file = "json5-0.9.6-py2.py3-none-any.whl", hash = "sha256:823e510eb355949bed817e1f3e2d682455dc6af9daf6066d5698d6a2ca4481c2"}, - {file = "json5-0.9.6.tar.gz", hash = "sha256:9175ad1bc248e22bb8d95a8e8d765958bf0008fef2fe8abab5bc04e0f1ac8302"}, -] -jsonschema = [ - {file = "jsonschema-4.4.0-py3-none-any.whl", hash = "sha256:77281a1f71684953ee8b3d488371b162419767973789272434bbc3f29d9c8823"}, - {file = "jsonschema-4.4.0.tar.gz", hash = "sha256:636694eb41b3535ed608fe04129f26542b59ed99808b4f688aa32dcf55317a83"}, -] -jupyter-client = [ - {file = "jupyter_client-7.1.2-py3-none-any.whl", hash = "sha256:d56f1c57bef42ff31e61b1185d3348a5b2bcde7c9a05523ae4dbe5ee0871797c"}, - {file = "jupyter_client-7.1.2.tar.gz", hash = "sha256:4ea61033726c8e579edb55626d8ee2e6bf0a83158ddf3751b8dd46b2c5cd1e96"}, -] -jupyter-core = [ - {file = "jupyter_core-4.9.1-py3-none-any.whl", hash = "sha256:1c091f3bbefd6f2a8782f2c1db662ca8478ac240e962ae2c66f0b87c818154ea"}, - {file = "jupyter_core-4.9.1.tar.gz", hash = "sha256:dce8a7499da5a53ae3afd5a9f4b02e5df1d57250cf48f3ad79da23b4778cd6fa"}, -] -jupyter-server = [ - {file = "jupyter_server-1.13.5-py3-none-any.whl", hash = "sha256:a3eb9d397df2de26134cb24fe7cb5da60ec28b4f8b292e0bdefd450b1f062dd3"}, - {file = "jupyter_server-1.13.5.tar.gz", hash = "sha256:9e3e9717eea3bffab8cfb2ff330011be6c8bbd9cdae5b71cef169fcece2f19d3"}, -] -jupyterlab = [ - {file = "jupyterlab-3.2.9-py3-none-any.whl", hash = "sha256:729d1f06e97733070badc04152aecf9fb2cd036783eebbd9123ff58aab83a8f5"}, - {file = "jupyterlab-3.2.9.tar.gz", hash = "sha256:65ddc34e5da1a764606e38c4f70cf9d4ac1c05182813cf0ab2dfea312c701124"}, -] -jupyterlab-pygments = [ - {file = "jupyterlab_pygments-0.1.2-py2.py3-none-any.whl", hash = "sha256:abfb880fd1561987efaefcb2d2ac75145d2a5d0139b1876d5be806e32f630008"}, - {file = "jupyterlab_pygments-0.1.2.tar.gz", hash = "sha256:cfcda0873626150932f438eccf0f8bf22bfa92345b814890ab360d666b254146"}, -] -jupyterlab-server = [ - {file = "jupyterlab_server-2.10.3-py3-none-any.whl", hash = "sha256:62f3c598f1d48dfb9b27729ed17772e38115cbe61e7d60fe68a853791bdf1038"}, - {file = "jupyterlab_server-2.10.3.tar.gz", hash = "sha256:3fb84a5813d6d836ceda773fb2d4e9ef3c7944dbc1b45a8d59d98641a80de80a"}, -] -kiwisolver = [ - {file = "kiwisolver-1.3.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:1d819553730d3c2724582124aee8a03c846ec4362ded1034c16fb3ef309264e6"}, - {file = "kiwisolver-1.3.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8d93a1095f83e908fc253f2fb569c2711414c0bfd451cab580466465b235b470"}, - {file = "kiwisolver-1.3.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c4550a359c5157aaf8507e6820d98682872b9100ce7607f8aa070b4b8af6c298"}, - {file = "kiwisolver-1.3.2-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2210f28778c7d2ee13f3c2a20a3a22db889e75f4ec13a21072eabb5693801e84"}, - {file = "kiwisolver-1.3.2-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:82f49c5a79d3839bc8f38cb5f4bfc87e15f04cbafa5fbd12fb32c941cb529cfb"}, - {file = "kiwisolver-1.3.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9661a04ca3c950a8ac8c47f53cbc0b530bce1b52f516a1e87b7736fec24bfff0"}, - {file = "kiwisolver-1.3.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2ddb500a2808c100e72c075cbb00bf32e62763c82b6a882d403f01a119e3f402"}, - {file = "kiwisolver-1.3.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:72be6ebb4e92520b9726d7146bc9c9b277513a57a38efcf66db0620aec0097e0"}, - {file = "kiwisolver-1.3.2-cp310-cp310-win32.whl", hash = "sha256:83d2c9db5dfc537d0171e32de160461230eb14663299b7e6d18ca6dca21e4977"}, - {file = "kiwisolver-1.3.2-cp310-cp310-win_amd64.whl", hash = "sha256:cba430db673c29376135e695c6e2501c44c256a81495da849e85d1793ee975ad"}, - {file = "kiwisolver-1.3.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:4116ba9a58109ed5e4cb315bdcbff9838f3159d099ba5259c7c7fb77f8537492"}, - {file = "kiwisolver-1.3.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:19554bd8d54cf41139f376753af1a644b63c9ca93f8f72009d50a2080f870f77"}, - {file = "kiwisolver-1.3.2-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a7a4cf5bbdc861987a7745aed7a536c6405256853c94abc9f3287c3fa401b174"}, - {file = "kiwisolver-1.3.2-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0007840186bacfaa0aba4466d5890334ea5938e0bb7e28078a0eb0e63b5b59d5"}, - {file = "kiwisolver-1.3.2-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ec2eba188c1906b05b9b49ae55aae4efd8150c61ba450e6721f64620c50b59eb"}, - {file = "kiwisolver-1.3.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:3dbb3cea20b4af4f49f84cffaf45dd5f88e8594d18568e0225e6ad9dec0e7967"}, - {file = "kiwisolver-1.3.2-cp37-cp37m-win32.whl", hash = "sha256:5326ddfacbe51abf9469fe668944bc2e399181a2158cb5d45e1d40856b2a0589"}, - {file = "kiwisolver-1.3.2-cp37-cp37m-win_amd64.whl", hash = "sha256:c6572c2dab23c86a14e82c245473d45b4c515314f1f859e92608dcafbd2f19b8"}, - {file = "kiwisolver-1.3.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b5074fb09429f2b7bc82b6fb4be8645dcbac14e592128beeff5461dcde0af09f"}, - {file = "kiwisolver-1.3.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:22521219ca739654a296eea6d4367703558fba16f98688bd8ce65abff36eaa84"}, - {file = "kiwisolver-1.3.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c358721aebd40c243894298f685a19eb0491a5c3e0b923b9f887ef1193ddf829"}, - {file = "kiwisolver-1.3.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ba5a1041480c6e0a8b11a9544d53562abc2d19220bfa14133e0cdd9967e97af"}, - {file = "kiwisolver-1.3.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:44e6adf67577dbdfa2d9f06db9fbc5639afefdb5bf2b4dfec25c3a7fbc619536"}, - {file = "kiwisolver-1.3.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1d45d1c74f88b9f41062716c727f78f2a59a5476ecbe74956fafb423c5c87a76"}, - {file = "kiwisolver-1.3.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:70adc3658138bc77a36ce769f5f183169bc0a2906a4f61f09673f7181255ac9b"}, - {file = "kiwisolver-1.3.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b6a5431940f28b6de123de42f0eb47b84a073ee3c3345dc109ad550a3307dd28"}, - {file = "kiwisolver-1.3.2-cp38-cp38-win32.whl", hash = "sha256:ee040a7de8d295dbd261ef2d6d3192f13e2b08ec4a954de34a6fb8ff6422e24c"}, - {file = "kiwisolver-1.3.2-cp38-cp38-win_amd64.whl", hash = "sha256:8dc3d842fa41a33fe83d9f5c66c0cc1f28756530cd89944b63b072281e852031"}, - {file = "kiwisolver-1.3.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:a498bcd005e8a3fedd0022bb30ee0ad92728154a8798b703f394484452550507"}, - {file = "kiwisolver-1.3.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:80efd202108c3a4150e042b269f7c78643420cc232a0a771743bb96b742f838f"}, - {file = "kiwisolver-1.3.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f8eb7b6716f5b50e9c06207a14172cf2de201e41912ebe732846c02c830455b9"}, - {file = "kiwisolver-1.3.2-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f441422bb313ab25de7b3dbfd388e790eceb76ce01a18199ec4944b369017009"}, - {file = "kiwisolver-1.3.2-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:30fa008c172355c7768159983a7270cb23838c4d7db73d6c0f6b60dde0d432c6"}, - {file = "kiwisolver-1.3.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2f8f6c8f4f1cff93ca5058d6ec5f0efda922ecb3f4c5fb76181f327decff98b8"}, - {file = "kiwisolver-1.3.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ba677bcaff9429fd1bf01648ad0901cea56c0d068df383d5f5856d88221fe75b"}, - {file = "kiwisolver-1.3.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7843b1624d6ccca403a610d1277f7c28ad184c5aa88a1750c1a999754e65b439"}, - {file = "kiwisolver-1.3.2-cp39-cp39-win32.whl", hash = "sha256:e6f5eb2f53fac7d408a45fbcdeda7224b1cfff64919d0f95473420a931347ae9"}, - {file = "kiwisolver-1.3.2-cp39-cp39-win_amd64.whl", hash = "sha256:eedd3b59190885d1ebdf6c5e0ca56828beb1949b4dfe6e5d0256a461429ac386"}, - {file = "kiwisolver-1.3.2-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:dedc71c8eb9c5096037766390172c34fb86ef048b8e8958b4e484b9e505d66bc"}, - {file = "kiwisolver-1.3.2-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:bf7eb45d14fc036514c09554bf983f2a72323254912ed0c3c8e697b62c4c158f"}, - {file = "kiwisolver-1.3.2-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:2b65bd35f3e06a47b5c30ea99e0c2b88f72c6476eedaf8cfbc8e66adb5479dcf"}, - {file = "kiwisolver-1.3.2-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:25405f88a37c5f5bcba01c6e350086d65e7465fd1caaf986333d2a045045a223"}, - {file = "kiwisolver-1.3.2-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:bcadb05c3d4794eb9eee1dddf1c24215c92fb7b55a80beae7a60530a91060560"}, - {file = "kiwisolver-1.3.2.tar.gz", hash = "sha256:fc4453705b81d03568d5b808ad8f09c77c47534f6ac2e72e733f9ca4714aa75c"}, -] -lazy-object-proxy = [ - {file = "lazy-object-proxy-1.7.1.tar.gz", hash = "sha256:d609c75b986def706743cdebe5e47553f4a5a1da9c5ff66d76013ef396b5a8a4"}, - {file = "lazy_object_proxy-1.7.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bb8c5fd1684d60a9902c60ebe276da1f2281a318ca16c1d0a96db28f62e9166b"}, - {file = "lazy_object_proxy-1.7.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a57d51ed2997e97f3b8e3500c984db50a554bb5db56c50b5dab1b41339b37e36"}, - {file = "lazy_object_proxy-1.7.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd45683c3caddf83abbb1249b653a266e7069a09f486daa8863fb0e7496a9fdb"}, - {file = "lazy_object_proxy-1.7.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:8561da8b3dd22d696244d6d0d5330618c993a215070f473b699e00cf1f3f6443"}, - {file = "lazy_object_proxy-1.7.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fccdf7c2c5821a8cbd0a9440a456f5050492f2270bd54e94360cac663398739b"}, - {file = "lazy_object_proxy-1.7.1-cp310-cp310-win32.whl", hash = "sha256:898322f8d078f2654d275124a8dd19b079080ae977033b713f677afcfc88e2b9"}, - {file = "lazy_object_proxy-1.7.1-cp310-cp310-win_amd64.whl", hash = "sha256:85b232e791f2229a4f55840ed54706110c80c0a210d076eee093f2b2e33e1bfd"}, - {file = "lazy_object_proxy-1.7.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:46ff647e76f106bb444b4533bb4153c7370cdf52efc62ccfc1a28bdb3cc95442"}, - {file = "lazy_object_proxy-1.7.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12f3bb77efe1367b2515f8cb4790a11cffae889148ad33adad07b9b55e0ab22c"}, - {file = "lazy_object_proxy-1.7.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c19814163728941bb871240d45c4c30d33b8a2e85972c44d4e63dd7107faba44"}, - {file = "lazy_object_proxy-1.7.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:e40f2013d96d30217a51eeb1db28c9ac41e9d0ee915ef9d00da639c5b63f01a1"}, - {file = "lazy_object_proxy-1.7.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:2052837718516a94940867e16b1bb10edb069ab475c3ad84fd1e1a6dd2c0fcfc"}, - {file = "lazy_object_proxy-1.7.1-cp36-cp36m-win32.whl", hash = "sha256:6a24357267aa976abab660b1d47a34aaf07259a0c3859a34e536f1ee6e76b5bb"}, - {file = "lazy_object_proxy-1.7.1-cp36-cp36m-win_amd64.whl", hash = "sha256:6aff3fe5de0831867092e017cf67e2750c6a1c7d88d84d2481bd84a2e019ec35"}, - {file = "lazy_object_proxy-1.7.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6a6e94c7b02641d1311228a102607ecd576f70734dc3d5e22610111aeacba8a0"}, - {file = "lazy_object_proxy-1.7.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4ce15276a1a14549d7e81c243b887293904ad2d94ad767f42df91e75fd7b5b6"}, - {file = "lazy_object_proxy-1.7.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e368b7f7eac182a59ff1f81d5f3802161932a41dc1b1cc45c1f757dc876b5d2c"}, - {file = "lazy_object_proxy-1.7.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:6ecbb350991d6434e1388bee761ece3260e5228952b1f0c46ffc800eb313ff42"}, - {file = "lazy_object_proxy-1.7.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:553b0f0d8dbf21890dd66edd771f9b1b5f51bd912fa5f26de4449bfc5af5e029"}, - {file = "lazy_object_proxy-1.7.1-cp37-cp37m-win32.whl", hash = "sha256:c7a683c37a8a24f6428c28c561c80d5f4fd316ddcf0c7cab999b15ab3f5c5c69"}, - {file = "lazy_object_proxy-1.7.1-cp37-cp37m-win_amd64.whl", hash = "sha256:df2631f9d67259dc9620d831384ed7732a198eb434eadf69aea95ad18c587a28"}, - {file = "lazy_object_proxy-1.7.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:07fa44286cda977bd4803b656ffc1c9b7e3bc7dff7d34263446aec8f8c96f88a"}, - {file = "lazy_object_proxy-1.7.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4dca6244e4121c74cc20542c2ca39e5c4a5027c81d112bfb893cf0790f96f57e"}, - {file = "lazy_object_proxy-1.7.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:91ba172fc5b03978764d1df5144b4ba4ab13290d7bab7a50f12d8117f8630c38"}, - {file = "lazy_object_proxy-1.7.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:043651b6cb706eee4f91854da4a089816a6606c1428fd391573ef8cb642ae4f7"}, - {file = "lazy_object_proxy-1.7.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:b9e89b87c707dd769c4ea91f7a31538888aad05c116a59820f28d59b3ebfe25a"}, - {file = "lazy_object_proxy-1.7.1-cp38-cp38-win32.whl", hash = "sha256:9d166602b525bf54ac994cf833c385bfcc341b364e3ee71e3bf5a1336e677b55"}, - {file = "lazy_object_proxy-1.7.1-cp38-cp38-win_amd64.whl", hash = "sha256:8f3953eb575b45480db6568306893f0bd9d8dfeeebd46812aa09ca9579595148"}, - {file = "lazy_object_proxy-1.7.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:dd7ed7429dbb6c494aa9bc4e09d94b778a3579be699f9d67da7e6804c422d3de"}, - {file = "lazy_object_proxy-1.7.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70ed0c2b380eb6248abdef3cd425fc52f0abd92d2b07ce26359fcbc399f636ad"}, - {file = "lazy_object_proxy-1.7.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7096a5e0c1115ec82641afbdd70451a144558ea5cf564a896294e346eb611be1"}, - {file = "lazy_object_proxy-1.7.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:f769457a639403073968d118bc70110e7dce294688009f5c24ab78800ae56dc8"}, - {file = "lazy_object_proxy-1.7.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:39b0e26725c5023757fc1ab2a89ef9d7ab23b84f9251e28f9cc114d5b59c1b09"}, - {file = "lazy_object_proxy-1.7.1-cp39-cp39-win32.whl", hash = "sha256:2130db8ed69a48a3440103d4a520b89d8a9405f1b06e2cc81640509e8bf6548f"}, - {file = "lazy_object_proxy-1.7.1-cp39-cp39-win_amd64.whl", hash = "sha256:677ea950bef409b47e51e733283544ac3d660b709cfce7b187f5ace137960d61"}, - {file = "lazy_object_proxy-1.7.1-pp37.pp38-none-any.whl", hash = "sha256:d66906d5785da8e0be7360912e99c9188b70f52c422f9fc18223347235691a84"}, -] -manimpango = [ - {file = "ManimPango-0.4.0.post2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:cebd954283da3ed36803bcca47ef49ed6f7587deddecd0a76e4ba6a947c22f25"}, - {file = "ManimPango-0.4.0.post2-cp310-cp310-win32.whl", hash = "sha256:9e8e881ac9d10bebb606ba490f0767755076996621b4e5ef2eb68313460d6853"}, - {file = "ManimPango-0.4.0.post2-cp310-cp310-win_amd64.whl", hash = "sha256:7cf92ce09d9154d0c078014882ca5d45eeace6c730ca1bde73f2aa505d9247b3"}, - {file = "ManimPango-0.4.0.post2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:916b01f3dd846243bcb42ae4443475fad04d8ef42ced22134c59ff613b5802fe"}, - {file = "ManimPango-0.4.0.post2-cp37-cp37m-win32.whl", hash = "sha256:8bdeafae9c112e91a29a107c3472ec7e00a2d536055a6446c804063eb0e2710c"}, - {file = "ManimPango-0.4.0.post2-cp37-cp37m-win_amd64.whl", hash = "sha256:2fa3591677d8eaf793e1b39904f8647c11776aeb669dbfee8ddda90061c53a90"}, - {file = "ManimPango-0.4.0.post2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9cf0cc4bca4d5fb5bc9c50356402a55a6d03d4cbfb83f07e36162010c2e5c836"}, - {file = "ManimPango-0.4.0.post2-cp38-cp38-win32.whl", hash = "sha256:cb02f1189e35a5d2b03d32b4e0b995afa326071dbbebb69ffd76d4cddb33d6a3"}, - {file = "ManimPango-0.4.0.post2-cp38-cp38-win_amd64.whl", hash = "sha256:a05e3764bd2c5cf2b1d2a35804eeec0efb5be98a835574f10ebdd1651bb42ec2"}, - {file = "ManimPango-0.4.0.post2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:6cf01df4fbdd7619e854a5455698638ff3f33df0bb461506f2508682fe005848"}, - {file = "ManimPango-0.4.0.post2-cp39-cp39-win32.whl", hash = "sha256:717dbab9b5030a60e141490e3286f8e92519a8aaffa402f7851cd2b657cccdc5"}, - {file = "ManimPango-0.4.0.post2-cp39-cp39-win_amd64.whl", hash = "sha256:db497fd2ac84232adf8d2773110a7f2dd53ebabb5c4a434d01cc3f075af96c21"}, - {file = "ManimPango-0.4.0.post2.tar.gz", hash = "sha256:1a8b1b2981bdb128f43defc702bf457b7fd1c8dbb5b0c0625421623716394b25"}, -] -mapbox-earcut = [ - {file = "mapbox_earcut-0.12.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:421dbfc321871e66afe9264165848c0d13a37b27156f8a42a642bf5820bafdda"}, - {file = "mapbox_earcut-0.12.11-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:3285f55acc7628cec1a61c551a7225b9c78c4f849c39417c768019b4408f8536"}, - {file = "mapbox_earcut-0.12.11-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1fdbca4b14564e636e5ffb4c83f49c739bacf49ec590db9ca2c25e9642feb490"}, - {file = "mapbox_earcut-0.12.11-cp310-cp310-win32.whl", hash = "sha256:d26621f4ca8eff937d4539d5d0e59142fd6466ea161791640ea17547394ffc18"}, - {file = "mapbox_earcut-0.12.11-cp310-cp310-win_amd64.whl", hash = "sha256:cbcd8c2831a8ce848842b3e710e57db00cfdd3d7753cc67b1cc61d0c7dd91ca8"}, - {file = "mapbox_earcut-0.12.11-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:4c4c55711d7877ea4d2f11d1422c46004121a2b1f4aab6c0b587eab2d87b3a6b"}, - {file = "mapbox_earcut-0.12.11-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4ebf5f1b3cc7ec0f90eb4f9479b8013da46ece2cf69c887fdfdee6bec1169eb6"}, - {file = "mapbox_earcut-0.12.11-cp36-cp36m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d438ef905fb3ec6cb1378c5b169888e0f36a7786354a9a2ae8b8d5e75fe5beee"}, - {file = "mapbox_earcut-0.12.11-cp36-cp36m-win32.whl", hash = "sha256:c9d8d4e61ad67ce5aeac7a948b4bb68bd2126d5fceccaaaf33a625b43225ba45"}, - {file = "mapbox_earcut-0.12.11-cp36-cp36m-win_amd64.whl", hash = "sha256:2357cc3402173b9ba601fe1d2abf55a2fc80a969680981e51fce3bd7524aab6f"}, - {file = "mapbox_earcut-0.12.11-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:83d6a8fc39ef55ddb1f47bd49523b11e7cf9f07292356b93ad18c58473282fd4"}, - {file = "mapbox_earcut-0.12.11-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2eb7b64ee5b003a71fd1108894fd7a579c87919e7cf5da9f865d5e9694934cd5"}, - {file = "mapbox_earcut-0.12.11-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:64ca3752284345416834e591d9029d50dfa06661208f45d8b7e91f58e2610864"}, - {file = "mapbox_earcut-0.12.11-cp37-cp37m-win32.whl", hash = "sha256:8a90b6773db060474bbc1062c972a18f9dc4ea6940a47fb39090e60f821a9239"}, - {file = "mapbox_earcut-0.12.11-cp37-cp37m-win_amd64.whl", hash = "sha256:d90adb110d45198dcfc2b546648bd23b98737a38c6f0dea0e5949aeae3fca3dd"}, - {file = "mapbox_earcut-0.12.11-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:cc3e8b1961f53f7bae3c6818ee7114ba0512aa3c0a8fb61818240ecd02fd22e4"}, - {file = "mapbox_earcut-0.12.11-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0a31f96bc080e2f12fd39172baf891c5050bd56e2f60608d45139fd0ce489f08"}, - {file = "mapbox_earcut-0.12.11-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dc4c69b2953b1267804f34044c483420f902514ab3cdf02fe454b4fd7192e6a2"}, - {file = "mapbox_earcut-0.12.11-cp38-cp38-win32.whl", hash = "sha256:30c2d30a00ad28d03026dba76de870b2e66fe01a7b340f3cb459b65a4c902ee5"}, - {file = "mapbox_earcut-0.12.11-cp38-cp38-win_amd64.whl", hash = "sha256:6e01b9a9bc15d85e7dcbec52148e9851760a67e097eb63e4bc354e551ab4ae6d"}, - {file = "mapbox_earcut-0.12.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f69ac829ce208bcf85d47e0bf6409b79fc81ae7ca390de3ce2c4e971693328d8"}, - {file = "mapbox_earcut-0.12.11-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4eff01f3dc0f62ad4ea38da0ef16a242d613aa4efa38eb924677d8427de2e20c"}, - {file = "mapbox_earcut-0.12.11-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:69da117d3716b5e1f052d7ffc93411a8651bb7c8a7cc41c4ed362e07a45eaae6"}, - {file = "mapbox_earcut-0.12.11-cp39-cp39-win32.whl", hash = "sha256:8faaa8239a6c6db67220a1908b232e0d673c4ba5d06e0943fce0e4d9908ca796"}, - {file = "mapbox_earcut-0.12.11-cp39-cp39-win_amd64.whl", hash = "sha256:4c7c297063c2cd3608d42b174303dfb32f3b9252cf115bed06eb3c64875d3458"}, - {file = "mapbox_earcut-0.12.11-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:96783c3f818f0844d9153a45312142b4e1bda9c284eb4828bba1a9e1fbeb268e"}, - {file = "mapbox_earcut-0.12.11-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:a39a27a205189476e6404a855652c834a1cef087207131d3515aff7ac06b1a1f"}, - {file = "mapbox_earcut-0.12.11-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:18cd01be27ec85357e2f9ea0bbe7ce2f71d593966568e5cf12a9b7e19bf0e8d1"}, - {file = "mapbox_earcut-0.12.11-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:6542cc54b330c876e62dad15e98dd4df18e2fd75ffb5b9c84d0629bd085ea123"}, - {file = "mapbox_earcut-0.12.11.tar.gz", hash = "sha256:2808757f8a95eb816d3ce225528c9cb15355afe175f3bcb6837eb7700972e0b9"}, -] -markupsafe = [ - {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d8446c54dc28c01e5a2dbac5a25f071f6653e6e40f3a8818e8b45d790fe6ef53"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:36bc903cbb393720fad60fc28c10de6acf10dc6cc883f3e24ee4012371399a38"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d7d807855b419fc2ed3e631034685db6079889a1f01d5d9dac950f764da3dad"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:add36cb2dbb8b736611303cd3bfcee00afd96471b09cda130da3581cbdc56a6d"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:168cd0a3642de83558a5153c8bd34f175a9a6e7f6dc6384b9655d2697312a646"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:4dc8f9fb58f7364b63fd9f85013b780ef83c11857ae79f2feda41e270468dd9b"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:20dca64a3ef2d6e4d5d615a3fd418ad3bde77a47ec8a23d984a12b5b4c74491a"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:cdfba22ea2f0029c9261a4bd07e830a8da012291fbe44dc794e488b6c9bb353a"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-win32.whl", hash = "sha256:99df47edb6bda1249d3e80fdabb1dab8c08ef3975f69aed437cb69d0a5de1e28"}, - {file = "MarkupSafe-2.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:e0f138900af21926a02425cf736db95be9f4af72ba1bb21453432a07f6082134"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:f9081981fe268bd86831e5c75f7de206ef275defcb82bc70740ae6dc507aee51"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:0955295dd5eec6cb6cc2fe1698f4c6d84af2e92de33fbcac4111913cd100a6ff"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:0446679737af14f45767963a1a9ef7620189912317d095f2d9ffa183a4d25d2b"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:f826e31d18b516f653fe296d967d700fddad5901ae07c622bb3705955e1faa94"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:fa130dd50c57d53368c9d59395cb5526eda596d3ffe36666cd81a44d56e48872"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:905fec760bd2fa1388bb5b489ee8ee5f7291d692638ea5f67982d968366bef9f"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bf5d821ffabf0ef3533c39c518f3357b171a1651c1ff6827325e4489b0e46c3c"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:0d4b31cc67ab36e3392bbf3862cfbadac3db12bdd8b02a2731f509ed5b829724"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:baa1a4e8f868845af802979fcdbf0bb11f94f1cb7ced4c4b8a351bb60d108145"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:deb993cacb280823246a026e3b2d81c493c53de6acfd5e6bfe31ab3402bb37dd"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:63f3268ba69ace99cab4e3e3b5840b03340efed0948ab8f78d2fd87ee5442a4f"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:8d206346619592c6200148b01a2142798c989edcb9c896f9ac9722a99d4e77e6"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-win32.whl", hash = "sha256:6c4ca60fa24e85fe25b912b01e62cb969d69a23a5d5867682dd3e80b5b02581d"}, - {file = "MarkupSafe-2.0.1-cp36-cp36m-win_amd64.whl", hash = "sha256:b2f4bf27480f5e5e8ce285a8c8fd176c0b03e93dcc6646477d4630e83440c6a9"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:0717a7390a68be14b8c793ba258e075c6f4ca819f15edfc2a3a027c823718567"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:6557b31b5e2c9ddf0de32a691f2312a32f77cd7681d8af66c2692efdbef84c18"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:49e3ceeabbfb9d66c3aef5af3a60cc43b85c33df25ce03d0031a608b0a8b2e3f"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:d7f9850398e85aba693bb640262d3611788b1f29a79f0c93c565694658f4071f"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:6a7fae0dd14cf60ad5ff42baa2e95727c3d81ded453457771d02b7d2b3f9c0c2"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:b7f2d075102dc8c794cbde1947378051c4e5180d52d276987b8d28a3bd58c17d"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e9936f0b261d4df76ad22f8fee3ae83b60d7c3e871292cd42f40b81b70afae85"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2a7d351cbd8cfeb19ca00de495e224dea7e7d919659c2841bbb7f420ad03e2d6"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:60bf42e36abfaf9aff1f50f52644b336d4f0a3fd6d8a60ca0d054ac9f713a864"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:d6c7ebd4e944c85e2c3421e612a7057a2f48d478d79e61800d81468a8d842207"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:f0567c4dc99f264f49fe27da5f735f414c4e7e7dd850cfd8e69f0862d7c74ea9"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:89c687013cb1cd489a0f0ac24febe8c7a666e6e221b783e53ac50ebf68e45d86"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-win32.whl", hash = "sha256:a30e67a65b53ea0a5e62fe23682cfe22712e01f453b95233b25502f7c61cb415"}, - {file = "MarkupSafe-2.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:611d1ad9a4288cf3e3c16014564df047fe08410e628f89805e475368bd304914"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:5bb28c636d87e840583ee3adeb78172efc47c8b26127267f54a9c0ec251d41a9"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:be98f628055368795d818ebf93da628541e10b75b41c559fdf36d104c5787066"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:1d609f577dc6e1aa17d746f8bd3c31aa4d258f4070d61b2aa5c4166c1539de35"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:7d91275b0245b1da4d4cfa07e0faedd5b0812efc15b702576d103293e252af1b"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:01a9b8ea66f1658938f65b93a85ebe8bc016e6769611be228d797c9d998dd298"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:47ab1e7b91c098ab893b828deafa1203de86d0bc6ab587b160f78fe6c4011f75"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:97383d78eb34da7e1fa37dd273c20ad4320929af65d156e35a5e2d89566d9dfb"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6fcf051089389abe060c9cd7caa212c707e58153afa2c649f00346ce6d260f1b"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5855f8438a7d1d458206a2466bf82b0f104a3724bf96a1c781ab731e4201731a"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3dd007d54ee88b46be476e293f48c85048603f5f516008bee124ddd891398ed6"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:aca6377c0cb8a8253e493c6b451565ac77e98c2951c45f913e0b52facdcff83f"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:04635854b943835a6ea959e948d19dcd311762c5c0c6e1f0e16ee57022669194"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:6300b8454aa6930a24b9618fbb54b5a68135092bc666f7b06901f897fa5c2fee"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-win32.whl", hash = "sha256:023cb26ec21ece8dc3907c0e8320058b2e0cb3c55cf9564da612bc325bed5e64"}, - {file = "MarkupSafe-2.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:984d76483eb32f1bcb536dc27e4ad56bba4baa70be32fa87152832cdd9db0833"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2ef54abee730b502252bcdf31b10dacb0a416229b72c18b19e24a4509f273d26"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3c112550557578c26af18a1ccc9e090bfe03832ae994343cfdacd287db6a6ae7"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:53edb4da6925ad13c07b6d26c2a852bd81e364f95301c66e930ab2aef5b5ddd8"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:f5653a225f31e113b152e56f154ccbe59eeb1c7487b39b9d9f9cdb58e6c79dc5"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:4efca8f86c54b22348a5467704e3fec767b2db12fc39c6d963168ab1d3fc9135"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:ab3ef638ace319fa26553db0624c4699e31a28bb2a835c5faca8f8acf6a5a902"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:f8ba0e8349a38d3001fae7eadded3f6606f0da5d748ee53cc1dab1d6527b9509"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c47adbc92fc1bb2b3274c4b3a43ae0e4573d9fbff4f54cd484555edbf030baf1"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:37205cac2a79194e3750b0af2a5720d95f786a55ce7df90c3af697bfa100eaac"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1f2ade76b9903f39aa442b4aadd2177decb66525062db244b35d71d0ee8599b6"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:4296f2b1ce8c86a6aea78613c34bb1a672ea0e3de9c6ba08a960efe0b0a09047"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:9f02365d4e99430a12647f09b6cc8bab61a6564363f313126f775eb4f6ef798e"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5b6d930f030f8ed98e3e6c98ffa0652bdb82601e7a016ec2ab5d7ff23baa78d1"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-win32.whl", hash = "sha256:10f82115e21dc0dfec9ab5c0223652f7197feb168c940f3ef61563fc2d6beb74"}, - {file = "MarkupSafe-2.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:693ce3f9e70a6cf7d2fb9e6c9d8b204b6b39897a2c4a1aa65728d5ac97dcc1d8"}, - {file = "MarkupSafe-2.0.1.tar.gz", hash = "sha256:594c67807fb16238b30c44bdf74f36c02cdf22d1c8cda91ef8a0ed8dabf5620a"}, -] -matplotlib = [ - {file = "matplotlib-3.5.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:456cc8334f6d1124e8ff856b42d2cc1c84335375a16448189999496549f7182b"}, - {file = "matplotlib-3.5.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:8a77906dc2ef9b67407cec0bdbf08e3971141e535db888974a915be5e1e3efc6"}, - {file = "matplotlib-3.5.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8e70ae6475cfd0fad3816dcbf6cac536dc6f100f7474be58d59fa306e6e768a4"}, - {file = "matplotlib-3.5.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:53273c5487d1c19c3bc03b9eb82adaf8456f243b97ed79d09dded747abaf1235"}, - {file = "matplotlib-3.5.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e3b6f3fd0d8ca37861c31e9a7cab71a0ef14c639b4c95654ea1dd153158bf0df"}, - {file = "matplotlib-3.5.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8c87cdaf06fd7b2477f68909838ff4176f105064a72ca9d24d3f2a29f73d393"}, - {file = "matplotlib-3.5.1-cp310-cp310-win32.whl", hash = "sha256:e2f28a07b4f82abb40267864ad7b3a4ed76f1b1663e81c7efc84a9b9248f672f"}, - {file = "matplotlib-3.5.1-cp310-cp310-win_amd64.whl", hash = "sha256:d70a32ee1f8b55eed3fd4e892f0286df8cccc7e0475c11d33b5d0a148f5c7599"}, - {file = "matplotlib-3.5.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:68fa30cec89b6139dc559ed6ef226c53fd80396da1919a1b5ef672c911aaa767"}, - {file = "matplotlib-3.5.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e3484d8455af3fdb0424eae1789af61f6a79da0c80079125112fd5c1b604218"}, - {file = "matplotlib-3.5.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e293b16cf303fe82995e41700d172a58a15efc5331125d08246b520843ef21ee"}, - {file = "matplotlib-3.5.1-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:e3520a274a0e054e919f5b3279ee5dbccf5311833819ccf3399dab7c83e90a25"}, - {file = "matplotlib-3.5.1-cp37-cp37m-win32.whl", hash = "sha256:2252bfac85cec7af4a67e494bfccf9080bcba8a0299701eab075f48847cca907"}, - {file = "matplotlib-3.5.1-cp37-cp37m-win_amd64.whl", hash = "sha256:abf67e05a1b7f86583f6ebd01f69b693b9c535276f4e943292e444855870a1b8"}, - {file = "matplotlib-3.5.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:6c094e4bfecd2fa7f9adffd03d8abceed7157c928c2976899de282f3600f0a3d"}, - {file = "matplotlib-3.5.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:506b210cc6e66a0d1c2bb765d055f4f6bc2745070fb1129203b67e85bbfa5c18"}, - {file = "matplotlib-3.5.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b04fc29bcef04d4e2d626af28d9d892be6aba94856cb46ed52bcb219ceac8943"}, - {file = "matplotlib-3.5.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:577ed20ec9a18d6bdedb4616f5e9e957b4c08563a9f985563a31fd5b10564d2a"}, - {file = "matplotlib-3.5.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e486f60db0cd1c8d68464d9484fd2a94011c1ac8593d765d0211f9daba2bd535"}, - {file = "matplotlib-3.5.1-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:b71f3a7ca935fc759f2aed7cec06cfe10bc3100fadb5dbd9c435b04e557971e1"}, - {file = "matplotlib-3.5.1-cp38-cp38-win32.whl", hash = "sha256:d24e5bb8028541ce25e59390122f5e48c8506b7e35587e5135efcb6471b4ac6c"}, - {file = "matplotlib-3.5.1-cp38-cp38-win_amd64.whl", hash = "sha256:778d398c4866d8e36ee3bf833779c940b5f57192fa0a549b3ad67bc4c822771b"}, - {file = "matplotlib-3.5.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bb1c613908f11bac270bc7494d68b1ef6e7c224b7a4204d5dacf3522a41e2bc3"}, - {file = "matplotlib-3.5.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:edf5e4e1d5fb22c18820e8586fb867455de3b109c309cb4fce3aaed85d9468d1"}, - {file = "matplotlib-3.5.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:40e0d7df05e8efe60397c69b467fc8f87a2affeb4d562fe92b72ff8937a2b511"}, - {file = "matplotlib-3.5.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7a350ca685d9f594123f652ba796ee37219bf72c8e0fc4b471473d87121d6d34"}, - {file = "matplotlib-3.5.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3e66497cd990b1a130e21919b004da2f1dc112132c01ac78011a90a0f9229778"}, - {file = "matplotlib-3.5.1-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:87900c67c0f1728e6db17c6809ec05c025c6624dcf96a8020326ea15378fe8e7"}, - {file = "matplotlib-3.5.1-cp39-cp39-win32.whl", hash = "sha256:b8a4fb2a0c5afbe9604f8a91d7d0f27b1832c3e0b5e365f95a13015822b4cd65"}, - {file = "matplotlib-3.5.1-cp39-cp39-win_amd64.whl", hash = "sha256:fe8d40c434a8e2c68d64c6d6a04e77f21791a93ff6afe0dce169597c110d3079"}, - {file = "matplotlib-3.5.1-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:34a1fc29f8f96e78ec57a5eff5e8d8b53d3298c3be6df61e7aa9efba26929522"}, - {file = "matplotlib-3.5.1-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:b19a761b948e939a9e20173aaae76070025f0024fc8f7ba08bef22a5c8573afc"}, - {file = "matplotlib-3.5.1-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:6803299cbf4665eca14428d9e886de62e24f4223ac31ab9c5d6d5339a39782c7"}, - {file = "matplotlib-3.5.1-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:14334b9902ec776461c4b8c6516e26b450f7ebe0b3ef8703bf5cdfbbaecf774a"}, - {file = "matplotlib-3.5.1.tar.gz", hash = "sha256:b2e9810e09c3a47b73ce9cab5a72243a1258f61e7900969097a817232246ce1c"}, -] -matplotlib-inline = [ - {file = "matplotlib-inline-0.1.3.tar.gz", hash = "sha256:a04bfba22e0d1395479f866853ec1ee28eea1485c1d69a6faf00dc3e24ff34ee"}, - {file = "matplotlib_inline-0.1.3-py3-none-any.whl", hash = "sha256:aed605ba3b72462d64d475a21a9296f400a19c4f74a31b59103d2a99ffd5aa5c"}, -] -mccabe = [ - {file = "mccabe-0.6.1-py2.py3-none-any.whl", hash = "sha256:ab8a6258860da4b6677da4bd2fe5dc2c659cff31b3ee4f7f5d64e79735b80d42"}, - {file = "mccabe-0.6.1.tar.gz", hash = "sha256:dd8d182285a0fe56bace7f45b5e7d1a6ebcbf524e8f3bd87eb0f125271b8831f"}, -] -mistune = [ - {file = "mistune-0.8.4-py2.py3-none-any.whl", hash = "sha256:88a1051873018da288eee8538d476dffe1262495144b33ecb586c4ab266bb8d4"}, - {file = "mistune-0.8.4.tar.gz", hash = "sha256:59a3429db53c50b5c6bcc8a07f8848cb00d7dc8bdb431a4ab41920d201d4756e"}, -] -moderngl = [ - {file = "moderngl-5.6.4-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_27_x86_64.whl", hash = "sha256:792ffe1ec233ed5fcfb0c14955a7f944d64c0d49713ff8b9c5fa3176d96f05c3"}, - {file = "moderngl-5.6.4-cp310-cp310-manylinux_2_24_x86_64.whl", hash = "sha256:1f9ed0bc0d706124a01be2ad59b5774bb3b023e61dcf39faf7c4c7ef4b9f4f75"}, - {file = "moderngl-5.6.4-cp310-cp310-win_amd64.whl", hash = "sha256:28b517fc56c9ab9eb1f5833f7d7b1274d3719b962f95f55ccd8a0f6db884a92b"}, - {file = "moderngl-5.6.4-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:bc3764d67f037b67051871345a1d0b7a3d2c19cb5c0c0af0a84c532e802d6642"}, - {file = "moderngl-5.6.4-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:90006d9dfd5333da604a7d26b2a5e70e1a570f291cd745b8bf80e4833d8821b6"}, - {file = "moderngl-5.6.4-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:af44437545380a840dafd09658eb56592831dbd4fb481d320249d0d42c591bae"}, - {file = "moderngl-5.6.4-cp35-cp35m-win32.whl", hash = "sha256:b5023633bcbfbab90be6a6f4edcde75f9c1e244d9acbda94678f3e3fb238b363"}, - {file = "moderngl-5.6.4-cp35-cp35m-win_amd64.whl", hash = "sha256:ffc48fc4deeb525ed33a828d13ca4c12c5af8e5cb0449011f1802e18b5fc3c25"}, - {file = "moderngl-5.6.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:331fd4bce60b10a08eed81a3ed4c70b7c297c38f981fdf3968d03a1c892af247"}, - {file = "moderngl-5.6.4-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:1bd864b5cc2fc1255785e33575cec98fa5ded698503c4f8f3fa9230abeaa3a04"}, - {file = "moderngl-5.6.4-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:b22534529f5bc52c1fe43336787c06d51123ae978fb56e74e47cabd85056c934"}, - {file = "moderngl-5.6.4-cp36-cp36m-win32.whl", hash = "sha256:ee5b1eced39d7f6dc68782c2abf01c1130a40b6d83d333d175ee71adbea7c721"}, - {file = "moderngl-5.6.4-cp36-cp36m-win_amd64.whl", hash = "sha256:52ee915a559762f0e992344961b35e0d241be32f8aa7464494e958f777e0534c"}, - {file = "moderngl-5.6.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:f83f6ab1fafdba2d9c06a7a1c8a4e460689ea1d514146606acc74f14e0831d93"}, - {file = "moderngl-5.6.4-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:c350e06affea9fabc636b2350cf6e58d83ee2e7264527eee0f5d142c167f5463"}, - {file = "moderngl-5.6.4-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:3eb65afc8ec4a1d4a4c48696fb0f4f6cf7a7ada6bef97818d717dbca73c57b11"}, - {file = "moderngl-5.6.4-cp37-cp37m-win32.whl", hash = "sha256:4fd721eb83e73d34c3f7b5a11aec656fef461b51bbe7503b07ea27370c593cbd"}, - {file = "moderngl-5.6.4-cp37-cp37m-win_amd64.whl", hash = "sha256:01c71d94dbd59b5d37ead463991e2998c0924426cffa393b9da2b8334551c998"}, - {file = "moderngl-5.6.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d2ec6ecd845f21ba44a08c11521cb71f2a9c2ea2ec189b7ed30d17837d392d70"}, - {file = "moderngl-5.6.4-cp38-cp38-manylinux1_i686.whl", hash = "sha256:40f74a2246e5302f93f2d46f76c0d2a26cbed1eb29731674c4052476f1e9c9ea"}, - {file = "moderngl-5.6.4-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:5e158e6881034c7e1d0c583d7c82ff608439606f2359dc6098e4be4fd93cef9d"}, - {file = "moderngl-5.6.4-cp38-cp38-win32.whl", hash = "sha256:a28dc741469eeb69549ee85b4ddbf8e9cfca6a2b19ce0406df9fde20f78082c8"}, - {file = "moderngl-5.6.4-cp38-cp38-win_amd64.whl", hash = "sha256:ce87962b91635d857cac4a753c5d5f647d94dc66dcb0f090bb8d758fd226c3e8"}, - {file = "moderngl-5.6.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3fb139bcdd25eae2c546e5788e9d8719f6c4b18a2ba68a9df31699b4ac57d62d"}, - {file = "moderngl-5.6.4-cp39-cp39-win32.whl", hash = "sha256:fc5cc1601a3df8f45f1901c6b9960731e0619d1781b0d036e12341fbf2ef55d3"}, - {file = "moderngl-5.6.4-cp39-cp39-win_amd64.whl", hash = "sha256:1c74b71c9acee9f0e69807a086d76e92f37c1960c3bb1d6a6e2472fd03f7be5b"}, - {file = "moderngl-5.6.4.tar.gz", hash = "sha256:8c6d04559f5e3bf75a18525cd46d213c0f3a8409363718978e6de691bdb551fb"}, -] -moderngl-window = [ - {file = "moderngl-window-2.4.1.tar.gz", hash = "sha256:691de764640b87af3d851257be544e1cafddb9cfa47cb144d0c1f1a0ed0a3936"}, - {file = "moderngl_window-2.4.1-py3-none-any.whl", hash = "sha256:5f2aaa6ae8d8a40fcd877febaf7494229c2bf1ef01d3fa9faa3a342075d4126a"}, -] -multipledispatch = [ - {file = "multipledispatch-0.6.0-py2-none-any.whl", hash = "sha256:407e6d8c5fa27075968ba07c4db3ef5f02bea4e871e959570eeb69ee39a6565b"}, - {file = "multipledispatch-0.6.0-py3-none-any.whl", hash = "sha256:a55c512128fb3f7c2efd2533f2550accb93c35f1045242ef74645fc92a2c3cba"}, - {file = "multipledispatch-0.6.0.tar.gz", hash = "sha256:a7ab1451fd0bf9b92cab3edbd7b205622fb767aeefb4fb536c2e3de9e0a38bea"}, -] -mypy = [ - {file = "mypy-0.931-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:3c5b42d0815e15518b1f0990cff7a705805961613e701db60387e6fb663fe78a"}, - {file = "mypy-0.931-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c89702cac5b302f0c5d33b172d2b55b5df2bede3344a2fbed99ff96bddb2cf00"}, - {file = "mypy-0.931-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:300717a07ad09525401a508ef5d105e6b56646f7942eb92715a1c8d610149714"}, - {file = "mypy-0.931-cp310-cp310-win_amd64.whl", hash = "sha256:7b3f6f557ba4afc7f2ce6d3215d5db279bcf120b3cfd0add20a5d4f4abdae5bc"}, - {file = "mypy-0.931-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:1bf752559797c897cdd2c65f7b60c2b6969ffe458417b8d947b8340cc9cec08d"}, - {file = "mypy-0.931-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:4365c60266b95a3f216a3047f1d8e3f895da6c7402e9e1ddfab96393122cc58d"}, - {file = "mypy-0.931-cp36-cp36m-win_amd64.whl", hash = "sha256:1b65714dc296a7991000b6ee59a35b3f550e0073411ac9d3202f6516621ba66c"}, - {file = "mypy-0.931-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e839191b8da5b4e5d805f940537efcaa13ea5dd98418f06dc585d2891d228cf0"}, - {file = "mypy-0.931-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:50c7346a46dc76a4ed88f3277d4959de8a2bd0a0fa47fa87a4cde36fe247ac05"}, - {file = "mypy-0.931-cp37-cp37m-win_amd64.whl", hash = "sha256:d8f1ff62f7a879c9fe5917b3f9eb93a79b78aad47b533911b853a757223f72e7"}, - {file = "mypy-0.931-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:f9fe20d0872b26c4bba1c1be02c5340de1019530302cf2dcc85c7f9fc3252ae0"}, - {file = "mypy-0.931-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1b06268df7eb53a8feea99cbfff77a6e2b205e70bf31743e786678ef87ee8069"}, - {file = "mypy-0.931-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8c11003aaeaf7cc2d0f1bc101c1cc9454ec4cc9cb825aef3cafff8a5fdf4c799"}, - {file = "mypy-0.931-cp38-cp38-win_amd64.whl", hash = "sha256:d9d2b84b2007cea426e327d2483238f040c49405a6bf4074f605f0156c91a47a"}, - {file = "mypy-0.931-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:ff3bf387c14c805ab1388185dd22d6b210824e164d4bb324b195ff34e322d166"}, - {file = "mypy-0.931-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5b56154f8c09427bae082b32275a21f500b24d93c88d69a5e82f3978018a0266"}, - {file = "mypy-0.931-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8ca7f8c4b1584d63c9a0f827c37ba7a47226c19a23a753d52e5b5eddb201afcd"}, - {file = "mypy-0.931-cp39-cp39-win_amd64.whl", hash = "sha256:74f7eccbfd436abe9c352ad9fb65872cc0f1f0a868e9d9c44db0893440f0c697"}, - {file = "mypy-0.931-py3-none-any.whl", hash = "sha256:1171f2e0859cfff2d366da2c7092b06130f232c636a3f7301e3feb8b41f6377d"}, - {file = "mypy-0.931.tar.gz", hash = "sha256:0038b21890867793581e4cb0d810829f5fd4441aa75796b53033af3aa30430ce"}, -] -mypy-extensions = [ - {file = "mypy_extensions-0.4.3-py2.py3-none-any.whl", hash = "sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d"}, - {file = "mypy_extensions-0.4.3.tar.gz", hash = "sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8"}, -] -nbclassic = [ - {file = "nbclassic-0.3.5-py3-none-any.whl", hash = "sha256:012d18efb4e24fe9af598add0dcaa621c1f8afbbbabb942fb583dd7fbb247fc8"}, - {file = "nbclassic-0.3.5.tar.gz", hash = "sha256:99444dd63103af23c788d9b5172992f12caf8c3098dd5a35c787f0df31490c29"}, -] -nbclient = [ - {file = "nbclient-0.5.10-py3-none-any.whl", hash = "sha256:5b582e21c8b464e6676a9d60acc6871d7fbc3b080f74bef265a9f90411b31f6f"}, - {file = "nbclient-0.5.10.tar.gz", hash = "sha256:b5fdea88d6fa52ca38de6c2361401cfe7aaa7cd24c74effc5e489cec04d79088"}, -] -nbconvert = [ - {file = "nbconvert-6.4.2-py3-none-any.whl", hash = "sha256:7b006ae9979af56200e7fa3db39d9d12c99e811e8843b05dbe518e5b754bcb2e"}, - {file = "nbconvert-6.4.2.tar.gz", hash = "sha256:eb2803db18f6facce6bf3b01b684fe47907994bd156d15eaccdf011e3d7f8164"}, -] -nbformat = [ - {file = "nbformat-5.1.3-py3-none-any.whl", hash = "sha256:eb8447edd7127d043361bc17f2f5a807626bc8e878c7709a1c647abda28a9171"}, - {file = "nbformat-5.1.3.tar.gz", hash = "sha256:b516788ad70771c6250977c1374fcca6edebe6126fd2adb5a69aa5c2356fd1c8"}, -] -nest-asyncio = [ - {file = "nest_asyncio-1.5.4-py3-none-any.whl", hash = "sha256:3fdd0d6061a2bb16f21fe8a9c6a7945be83521d81a0d15cff52e9edee50101d6"}, - {file = "nest_asyncio-1.5.4.tar.gz", hash = "sha256:f969f6013a16fadb4adcf09d11a68a4f617c6049d7af7ac2c676110169a63abd"}, -] -networkx = [ - {file = "networkx-2.6.3-py3-none-any.whl", hash = "sha256:80b6b89c77d1dfb64a4c7854981b60aeea6360ac02c6d4e4913319e0a313abef"}, - {file = "networkx-2.6.3.tar.gz", hash = "sha256:c0946ed31d71f1b732b5aaa6da5a0388a345019af232ce2f49c766e2d6795c51"}, -] -nodeenv = [ - {file = "nodeenv-1.6.0-py2.py3-none-any.whl", hash = "sha256:621e6b7076565ddcacd2db0294c0381e01fd28945ab36bcf00f41c5daf63bef7"}, - {file = "nodeenv-1.6.0.tar.gz", hash = "sha256:3ef13ff90291ba2a4a7a4ff9a979b63ffdd00a464dbe04acf0ea6471517a4c2b"}, -] -notebook = [ - {file = "notebook-6.4.8-py3-none-any.whl", hash = "sha256:3e702fcc54b8ae597533c3864793b7a1e971dec9e112f67235828d8a798fd654"}, - {file = "notebook-6.4.8.tar.gz", hash = "sha256:1e985c9dc6f678bdfffb9dc657306b5469bfa62d73e03f74e8defbf76d284312"}, -] -numpy = [ - {file = "numpy-1.21.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:301e408a052fdcda5cdcf03021ebafc3c6ea093021bf9d1aa47c54d48bdad166"}, - {file = "numpy-1.21.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a7e8f6216f180f3fd4efb73de5d1eaefb5f5a1ee5b645c67333033e39440e63a"}, - {file = "numpy-1.21.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fc7a7d7b0ed72589fd8b8486b9b42a564f10b8762be8bd4d9df94b807af4a089"}, - {file = "numpy-1.21.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:58ca1d7c8aef6e996112d0ce873ac9dfa1eaf4a1196b4ff7ff73880a09923ba7"}, - {file = "numpy-1.21.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc4b2fb01f1b4ddbe2453468ea0719f4dbb1f5caa712c8b21bb3dd1480cd30d9"}, - {file = "numpy-1.21.5-cp310-cp310-win_amd64.whl", hash = "sha256:cc1b30205d138d1005adb52087ff45708febbef0e420386f58664f984ef56954"}, - {file = "numpy-1.21.5-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:08de8472d9f7571f9d51b27b75e827f5296295fa78817032e84464be8bb905bc"}, - {file = "numpy-1.21.5-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4fe6a006557b87b352c04596a6e3f12a57d6e5f401d804947bd3188e6b0e0e76"}, - {file = "numpy-1.21.5-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:3d893b0871322eaa2f8c7072cdb552d8e2b27645b7875a70833c31e9274d4611"}, - {file = "numpy-1.21.5-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:341dddcfe3b7b6427a28a27baa59af5ad51baa59bfec3264f1ab287aa3b30b13"}, - {file = "numpy-1.21.5-cp37-cp37m-win32.whl", hash = "sha256:ca9c23848292c6fe0a19d212790e62f398fd9609aaa838859be8459bfbe558aa"}, - {file = "numpy-1.21.5-cp37-cp37m-win_amd64.whl", hash = "sha256:025b497014bc33fc23897859350f284323f32a2fff7654697f5a5fc2a19e9939"}, - {file = "numpy-1.21.5-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:3a5098df115340fb17fc93867317a947e1dcd978c3888c5ddb118366095851f8"}, - {file = "numpy-1.21.5-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:311283acf880cfcc20369201bd75da907909afc4666966c7895cbed6f9d2c640"}, - {file = "numpy-1.21.5-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b545ebadaa2b878c8630e5bcdb97fc4096e779f335fc0f943547c1c91540c815"}, - {file = "numpy-1.21.5-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c5562bcc1a9b61960fc8950ade44d00e3de28f891af0acc96307c73613d18f6e"}, - {file = "numpy-1.21.5-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:eed2afaa97ec33b4411995be12f8bdb95c87984eaa28d76cf628970c8a2d689a"}, - {file = "numpy-1.21.5-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:61bada43d494515d5b122f4532af226fdb5ee08fe5b5918b111279843dc6836a"}, - {file = "numpy-1.21.5-cp38-cp38-win32.whl", hash = "sha256:7b9d6b14fc9a4864b08d1ba57d732b248f0e482c7b2ff55c313137e3ed4d8449"}, - {file = "numpy-1.21.5-cp38-cp38-win_amd64.whl", hash = "sha256:dbce7adeb66b895c6aaa1fad796aaefc299ced597f6fbd9ceddb0dd735245354"}, - {file = "numpy-1.21.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:507c05c7a37b3683eb08a3ff993bd1ee1e6c752f77c2f275260533b265ecdb6c"}, - {file = "numpy-1.21.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:00c9fa73a6989895b8815d98300a20ac993c49ac36c8277e8ffeaa3631c0dbbb"}, - {file = "numpy-1.21.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:69a5a8d71c308d7ef33ef72371c2388a90e3495dbb7993430e674006f94797d5"}, - {file = "numpy-1.21.5-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:2d8adfca843bc46ac199a4645233f13abf2011a0b2f4affc5c37cd552626f27b"}, - {file = "numpy-1.21.5-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c293d3c0321996cd8ffe84215ffe5d269fd9d1d12c6f4ffe2b597a7c30d3e593"}, - {file = "numpy-1.21.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3c978544be9e04ed12016dd295a74283773149b48f507d69b36f91aa90a643e5"}, - {file = "numpy-1.21.5-cp39-cp39-win32.whl", hash = "sha256:2a9add27d7fc0fdb572abc3b2486eb3b1395da71e0254c5552b2aad2a18b5441"}, - {file = "numpy-1.21.5-cp39-cp39-win_amd64.whl", hash = "sha256:1964db2d4a00348b7a60ee9d013c8cb0c566644a589eaa80995126eac3b99ced"}, - {file = "numpy-1.21.5-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:a7c4b701ca418cd39e28ec3b496e6388fe06de83f5f0cb74794fa31cfa384c02"}, - {file = "numpy-1.21.5.zip", hash = "sha256:6a5928bc6241264dce5ed509e66f33676fc97f464e7a919edc672fb5532221ee"}, -] -packaging = [ - {file = "packaging-21.3-py3-none-any.whl", hash = "sha256:ef103e05f519cdc783ae24ea4e2e0f508a9c99b2d4969652eed6a2e1ea5bd522"}, - {file = "packaging-21.3.tar.gz", hash = "sha256:dd47c42927d89ab911e606518907cc2d3a1f38bbd026385970643f9c5b8ecfeb"}, -] -pandocfilters = [ - {file = "pandocfilters-1.5.0-py2.py3-none-any.whl", hash = "sha256:33aae3f25fd1a026079f5d27bdd52496f0e0803b3469282162bafdcbdf6ef14f"}, - {file = "pandocfilters-1.5.0.tar.gz", hash = "sha256:0b679503337d233b4339a817bfc8c50064e2eff681314376a47cb582305a7a38"}, -] -parso = [ - {file = "parso-0.8.3-py2.py3-none-any.whl", hash = "sha256:c001d4636cd3aecdaf33cbb40aebb59b094be2a74c556778ef5576c175e19e75"}, - {file = "parso-0.8.3.tar.gz", hash = "sha256:8c07be290bb59f03588915921e29e8a50002acaf2cdc5fa0e0114f91709fafa0"}, -] -pathspec = [ - {file = "pathspec-0.9.0-py2.py3-none-any.whl", hash = "sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a"}, - {file = "pathspec-0.9.0.tar.gz", hash = "sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1"}, -] -pexpect = [ - {file = "pexpect-4.8.0-py2.py3-none-any.whl", hash = "sha256:0b48a55dcb3c05f3329815901ea4fc1537514d6ba867a152b581d69ae3710937"}, - {file = "pexpect-4.8.0.tar.gz", hash = "sha256:fc65a43959d153d0114afe13997d439c22823a27cefceb5ff35c2178c6784c0c"}, -] -pickleshare = [ - {file = "pickleshare-0.7.5-py2.py3-none-any.whl", hash = "sha256:9649af414d74d4df115d5d718f82acb59c9d418196b7b4290ed47a12ce62df56"}, - {file = "pickleshare-0.7.5.tar.gz", hash = "sha256:87683d47965c1da65cdacaf31c8441d12b8044cdec9aca500cd78fc2c683afca"}, -] -pillow = [ - {file = "Pillow-9.0.1-1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a5d24e1d674dd9d72c66ad3ea9131322819ff86250b30dc5821cbafcfa0b96b4"}, - {file = "Pillow-9.0.1-1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2632d0f846b7c7600edf53c48f8f9f1e13e62f66a6dbc15191029d950bfed976"}, - {file = "Pillow-9.0.1-1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b9618823bd237c0d2575283f2939655f54d51b4527ec3972907a927acbcc5bfc"}, - {file = "Pillow-9.0.1-cp310-cp310-macosx_10_10_universal2.whl", hash = "sha256:9bfdb82cdfeccec50aad441afc332faf8606dfa5e8efd18a6692b5d6e79f00fd"}, - {file = "Pillow-9.0.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:5100b45a4638e3c00e4d2320d3193bdabb2d75e79793af7c3eb139e4f569f16f"}, - {file = "Pillow-9.0.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:528a2a692c65dd5cafc130de286030af251d2ee0483a5bf50c9348aefe834e8a"}, - {file = "Pillow-9.0.1-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0f29d831e2151e0b7b39981756d201f7108d3d215896212ffe2e992d06bfe049"}, - {file = "Pillow-9.0.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:855c583f268edde09474b081e3ddcd5cf3b20c12f26e0d434e1386cc5d318e7a"}, - {file = "Pillow-9.0.1-cp310-cp310-win32.whl", hash = "sha256:d9d7942b624b04b895cb95af03a23407f17646815495ce4547f0e60e0b06f58e"}, - {file = "Pillow-9.0.1-cp310-cp310-win_amd64.whl", hash = "sha256:81c4b81611e3a3cb30e59b0cf05b888c675f97e3adb2c8672c3154047980726b"}, - {file = "Pillow-9.0.1-cp37-cp37m-macosx_10_10_x86_64.whl", hash = "sha256:413ce0bbf9fc6278b2d63309dfeefe452835e1c78398efb431bab0672fe9274e"}, - {file = "Pillow-9.0.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:80fe64a6deb6fcfdf7b8386f2cf216d329be6f2781f7d90304351811fb591360"}, - {file = "Pillow-9.0.1-cp37-cp37m-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cef9c85ccbe9bee00909758936ea841ef12035296c748aaceee535969e27d31b"}, - {file = "Pillow-9.0.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d19397351f73a88904ad1aee421e800fe4bbcd1aeee6435fb62d0a05ccd1030"}, - {file = "Pillow-9.0.1-cp37-cp37m-win32.whl", hash = "sha256:d21237d0cd37acded35154e29aec853e945950321dd2ffd1a7d86fe686814669"}, - {file = "Pillow-9.0.1-cp37-cp37m-win_amd64.whl", hash = "sha256:ede5af4a2702444a832a800b8eb7f0a7a1c0eed55b644642e049c98d589e5092"}, - {file = "Pillow-9.0.1-cp38-cp38-macosx_10_10_x86_64.whl", hash = "sha256:b5b3f092fe345c03bca1e0b687dfbb39364b21ebb8ba90e3fa707374b7915204"}, - {file = "Pillow-9.0.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:335ace1a22325395c4ea88e00ba3dc89ca029bd66bd5a3c382d53e44f0ccd77e"}, - {file = "Pillow-9.0.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:db6d9fac65bd08cea7f3540b899977c6dee9edad959fa4eaf305940d9cbd861c"}, - {file = "Pillow-9.0.1-cp38-cp38-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f154d173286a5d1863637a7dcd8c3437bb557520b01bddb0be0258dcb72696b5"}, - {file = "Pillow-9.0.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:14d4b1341ac07ae07eb2cc682f459bec932a380c3b122f5540432d8977e64eae"}, - {file = "Pillow-9.0.1-cp38-cp38-win32.whl", hash = "sha256:effb7749713d5317478bb3acb3f81d9d7c7f86726d41c1facca068a04cf5bb4c"}, - {file = "Pillow-9.0.1-cp38-cp38-win_amd64.whl", hash = "sha256:7f7609a718b177bf171ac93cea9fd2ddc0e03e84d8fa4e887bdfc39671d46b00"}, - {file = "Pillow-9.0.1-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:80ca33961ced9c63358056bd08403ff866512038883e74f3a4bf88ad3eb66838"}, - {file = "Pillow-9.0.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1c3c33ac69cf059bbb9d1a71eeaba76781b450bc307e2291f8a4764d779a6b28"}, - {file = "Pillow-9.0.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:12875d118f21cf35604176872447cdb57b07126750a33748bac15e77f90f1f9c"}, - {file = "Pillow-9.0.1-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:514ceac913076feefbeaf89771fd6febde78b0c4c1b23aaeab082c41c694e81b"}, - {file = "Pillow-9.0.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3c5c79ab7dfce6d88f1ba639b77e77a17ea33a01b07b99840d6ed08031cb2a7"}, - {file = "Pillow-9.0.1-cp39-cp39-win32.whl", hash = "sha256:718856856ba31f14f13ba885ff13874be7fefc53984d2832458f12c38205f7f7"}, - {file = "Pillow-9.0.1-cp39-cp39-win_amd64.whl", hash = "sha256:f25ed6e28ddf50de7e7ea99d7a976d6a9c415f03adcaac9c41ff6ff41b6d86ac"}, - {file = "Pillow-9.0.1-pp37-pypy37_pp73-macosx_10_10_x86_64.whl", hash = "sha256:011233e0c42a4a7836498e98c1acf5e744c96a67dd5032a6f666cc1fb97eab97"}, - {file = "Pillow-9.0.1-pp37-pypy37_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:253e8a302a96df6927310a9d44e6103055e8fb96a6822f8b7f514bb7ef77de56"}, - {file = "Pillow-9.0.1-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6295f6763749b89c994fcb6d8a7f7ce03c3992e695f89f00b741b4580b199b7e"}, - {file = "Pillow-9.0.1-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:a9f44cd7e162ac6191491d7249cceb02b8116b0f7e847ee33f739d7cb1ea1f70"}, - {file = "Pillow-9.0.1.tar.gz", hash = "sha256:6c8bc8238a7dfdaf7a75f5ec5a663f4173f8c367e5a39f87e720495e1eed75fa"}, -] -platformdirs = [ - {file = "platformdirs-2.5.0-py3-none-any.whl", hash = "sha256:30671902352e97b1eafd74ade8e4a694782bd3471685e78c32d0fdfd3aa7e7bb"}, - {file = "platformdirs-2.5.0.tar.gz", hash = "sha256:8ec11dfba28ecc0715eb5fb0147a87b1bf325f349f3da9aab2cd6b50b96b692b"}, -] -pluggy = [ - {file = "pluggy-1.0.0-py2.py3-none-any.whl", hash = "sha256:74134bbf457f031a36d68416e1509f34bd5ccc019f0bcc952c7b909d06b37bd3"}, - {file = "pluggy-1.0.0.tar.gz", hash = "sha256:4224373bacce55f955a878bf9cfa763c1e360858e330072059e10bad68531159"}, -] -pre-commit = [ - {file = "pre_commit-2.17.0-py2.py3-none-any.whl", hash = "sha256:725fa7459782d7bec5ead072810e47351de01709be838c2ce1726b9591dad616"}, - {file = "pre_commit-2.17.0.tar.gz", hash = "sha256:c1a8040ff15ad3d648c70cc3e55b93e4d2d5b687320955505587fd79bbaed06a"}, -] -prometheus-client = [ - {file = "prometheus_client-0.13.1-py3-none-any.whl", hash = "sha256:357a447fd2359b0a1d2e9b311a0c5778c330cfbe186d880ad5a6b39884652316"}, - {file = "prometheus_client-0.13.1.tar.gz", hash = "sha256:ada41b891b79fca5638bd5cfe149efa86512eaa55987893becd2c6d8d0a5dfc5"}, -] -prompt-toolkit = [ - {file = "prompt_toolkit-3.0.28-py3-none-any.whl", hash = "sha256:30129d870dcb0b3b6a53efdc9d0a83ea96162ffd28ffe077e94215b233dc670c"}, - {file = "prompt_toolkit-3.0.28.tar.gz", hash = "sha256:9f1cd16b1e86c2968f2519d7fb31dd9d669916f515612c269d14e9ed52b51650"}, -] -protobuf = [ - {file = "protobuf-3.19.4-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:f51d5a9f137f7a2cec2d326a74b6e3fc79d635d69ffe1b036d39fc7d75430d37"}, - {file = "protobuf-3.19.4-cp310-cp310-manylinux2014_aarch64.whl", hash = "sha256:09297b7972da685ce269ec52af761743714996b4381c085205914c41fcab59fb"}, - {file = "protobuf-3.19.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:072fbc78d705d3edc7ccac58a62c4c8e0cec856987da7df8aca86e647be4e35c"}, - {file = "protobuf-3.19.4-cp310-cp310-win32.whl", hash = "sha256:7bb03bc2873a2842e5ebb4801f5c7ff1bfbdf426f85d0172f7644fcda0671ae0"}, - {file = "protobuf-3.19.4-cp310-cp310-win_amd64.whl", hash = "sha256:f358aa33e03b7a84e0d91270a4d4d8f5df6921abe99a377828839e8ed0c04e07"}, - {file = "protobuf-3.19.4-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:1c91ef4110fdd2c590effb5dca8fdbdcb3bf563eece99287019c4204f53d81a4"}, - {file = "protobuf-3.19.4-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c438268eebb8cf039552897d78f402d734a404f1360592fef55297285f7f953f"}, - {file = "protobuf-3.19.4-cp36-cp36m-win32.whl", hash = "sha256:835a9c949dc193953c319603b2961c5c8f4327957fe23d914ca80d982665e8ee"}, - {file = "protobuf-3.19.4-cp36-cp36m-win_amd64.whl", hash = "sha256:4276cdec4447bd5015453e41bdc0c0c1234eda08420b7c9a18b8d647add51e4b"}, - {file = "protobuf-3.19.4-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:6cbc312be5e71869d9d5ea25147cdf652a6781cf4d906497ca7690b7b9b5df13"}, - {file = "protobuf-3.19.4-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:54a1473077f3b616779ce31f477351a45b4fef8c9fd7892d6d87e287a38df368"}, - {file = "protobuf-3.19.4-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:435bb78b37fc386f9275a7035fe4fb1364484e38980d0dd91bc834a02c5ec909"}, - {file = "protobuf-3.19.4-cp37-cp37m-win32.whl", hash = "sha256:16f519de1313f1b7139ad70772e7db515b1420d208cb16c6d7858ea989fc64a9"}, - {file = "protobuf-3.19.4-cp37-cp37m-win_amd64.whl", hash = "sha256:cdc076c03381f5c1d9bb1abdcc5503d9ca8b53cf0a9d31a9f6754ec9e6c8af0f"}, - {file = "protobuf-3.19.4-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:69da7d39e39942bd52848438462674c463e23963a1fdaa84d88df7fbd7e749b2"}, - {file = "protobuf-3.19.4-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:48ed3877fa43e22bcacc852ca76d4775741f9709dd9575881a373bd3e85e54b2"}, - {file = "protobuf-3.19.4-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bd95d1dfb9c4f4563e6093a9aa19d9c186bf98fa54da5252531cc0d3a07977e7"}, - {file = "protobuf-3.19.4-cp38-cp38-win32.whl", hash = "sha256:b38057450a0c566cbd04890a40edf916db890f2818e8682221611d78dc32ae26"}, - {file = "protobuf-3.19.4-cp38-cp38-win_amd64.whl", hash = "sha256:7ca7da9c339ca8890d66958f5462beabd611eca6c958691a8fe6eccbd1eb0c6e"}, - {file = "protobuf-3.19.4-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:36cecbabbda242915529b8ff364f2263cd4de7c46bbe361418b5ed859677ba58"}, - {file = "protobuf-3.19.4-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:c1068287025f8ea025103e37d62ffd63fec8e9e636246b89c341aeda8a67c934"}, - {file = "protobuf-3.19.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96bd766831596d6014ca88d86dc8fe0fb2e428c0b02432fd9db3943202bf8c5e"}, - {file = "protobuf-3.19.4-cp39-cp39-win32.whl", hash = "sha256:84123274d982b9e248a143dadd1b9815049f4477dc783bf84efe6250eb4b836a"}, - {file = "protobuf-3.19.4-cp39-cp39-win_amd64.whl", hash = "sha256:3112b58aac3bac9c8be2b60a9daf6b558ca3f7681c130dcdd788ade7c9ffbdca"}, - {file = "protobuf-3.19.4-py2.py3-none-any.whl", hash = "sha256:8961c3a78ebfcd000920c9060a262f082f29838682b1f7201889300c1fbe0616"}, - {file = "protobuf-3.19.4.tar.gz", hash = "sha256:9df0c10adf3e83015ced42a9a7bd64e13d06c4cf45c340d2c63020ea04499d0a"}, -] -psutil = [ - {file = "psutil-5.9.0-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:55ce319452e3d139e25d6c3f85a1acf12d1607ddedea5e35fb47a552c051161b"}, - {file = "psutil-5.9.0-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:7336292a13a80eb93c21f36bde4328aa748a04b68c13d01dfddd67fc13fd0618"}, - {file = "psutil-5.9.0-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:cb8d10461c1ceee0c25a64f2dd54872b70b89c26419e147a05a10b753ad36ec2"}, - {file = "psutil-5.9.0-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:7641300de73e4909e5d148e90cc3142fb890079e1525a840cf0dfd39195239fd"}, - {file = "psutil-5.9.0-cp27-none-win32.whl", hash = "sha256:ea42d747c5f71b5ccaa6897b216a7dadb9f52c72a0fe2b872ef7d3e1eacf3ba3"}, - {file = "psutil-5.9.0-cp27-none-win_amd64.whl", hash = "sha256:ef216cc9feb60634bda2f341a9559ac594e2eeaadd0ba187a4c2eb5b5d40b91c"}, - {file = "psutil-5.9.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:90a58b9fcae2dbfe4ba852b57bd4a1dded6b990a33d6428c7614b7d48eccb492"}, - {file = "psutil-5.9.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff0d41f8b3e9ebb6b6110057e40019a432e96aae2008951121ba4e56040b84f3"}, - {file = "psutil-5.9.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:742c34fff804f34f62659279ed5c5b723bb0195e9d7bd9907591de9f8f6558e2"}, - {file = "psutil-5.9.0-cp310-cp310-win32.whl", hash = "sha256:8293942e4ce0c5689821f65ce6522ce4786d02af57f13c0195b40e1edb1db61d"}, - {file = "psutil-5.9.0-cp310-cp310-win_amd64.whl", hash = "sha256:9b51917c1af3fa35a3f2dabd7ba96a2a4f19df3dec911da73875e1edaf22a40b"}, - {file = "psutil-5.9.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:e9805fed4f2a81de98ae5fe38b75a74c6e6ad2df8a5c479594c7629a1fe35f56"}, - {file = "psutil-5.9.0-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c51f1af02334e4b516ec221ee26b8fdf105032418ca5a5ab9737e8c87dafe203"}, - {file = "psutil-5.9.0-cp36-cp36m-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32acf55cb9a8cbfb29167cd005951df81b567099295291bcfd1027365b36591d"}, - {file = "psutil-5.9.0-cp36-cp36m-win32.whl", hash = "sha256:e5c783d0b1ad6ca8a5d3e7b680468c9c926b804be83a3a8e95141b05c39c9f64"}, - {file = "psutil-5.9.0-cp36-cp36m-win_amd64.whl", hash = "sha256:d62a2796e08dd024b8179bd441cb714e0f81226c352c802fca0fd3f89eeacd94"}, - {file = "psutil-5.9.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3d00a664e31921009a84367266b35ba0aac04a2a6cad09c550a89041034d19a0"}, - {file = "psutil-5.9.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7779be4025c540d1d65a2de3f30caeacc49ae7a2152108adeaf42c7534a115ce"}, - {file = "psutil-5.9.0-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:072664401ae6e7c1bfb878c65d7282d4b4391f1bc9a56d5e03b5a490403271b5"}, - {file = "psutil-5.9.0-cp37-cp37m-win32.whl", hash = "sha256:df2c8bd48fb83a8408c8390b143c6a6fa10cb1a674ca664954de193fdcab36a9"}, - {file = "psutil-5.9.0-cp37-cp37m-win_amd64.whl", hash = "sha256:1d7b433519b9a38192dfda962dd8f44446668c009833e1429a52424624f408b4"}, - {file = "psutil-5.9.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:c3400cae15bdb449d518545cbd5b649117de54e3596ded84aacabfbb3297ead2"}, - {file = "psutil-5.9.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b2237f35c4bbae932ee98902a08050a27821f8f6dfa880a47195e5993af4702d"}, - {file = "psutil-5.9.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1070a9b287846a21a5d572d6dddd369517510b68710fca56b0e9e02fd24bed9a"}, - {file = "psutil-5.9.0-cp38-cp38-win32.whl", hash = "sha256:76cebf84aac1d6da5b63df11fe0d377b46b7b500d892284068bacccf12f20666"}, - {file = "psutil-5.9.0-cp38-cp38-win_amd64.whl", hash = "sha256:3151a58f0fbd8942ba94f7c31c7e6b310d2989f4da74fcbf28b934374e9bf841"}, - {file = "psutil-5.9.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:539e429da49c5d27d5a58e3563886057f8fc3868a5547b4f1876d9c0f007bccf"}, - {file = "psutil-5.9.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58c7d923dc209225600aec73aa2c4ae8ea33b1ab31bc11ef8a5933b027476f07"}, - {file = "psutil-5.9.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3611e87eea393f779a35b192b46a164b1d01167c9d323dda9b1e527ea69d697d"}, - {file = "psutil-5.9.0-cp39-cp39-win32.whl", hash = "sha256:4e2fb92e3aeae3ec3b7b66c528981fd327fb93fd906a77215200404444ec1845"}, - {file = "psutil-5.9.0-cp39-cp39-win_amd64.whl", hash = "sha256:7d190ee2eaef7831163f254dc58f6d2e2a22e27382b936aab51c835fc080c3d3"}, - {file = "psutil-5.9.0.tar.gz", hash = "sha256:869842dbd66bb80c3217158e629d6fceaecc3a3166d3d1faee515b05dd26ca25"}, -] -psutil-wheels = [ - {file = "psutil-wheels-5.8.0.tar.gz", hash = "sha256:9fb80725195402a66e5db947f239d032500cde75ca5d8625326d797a65341d6f"}, - {file = "psutil_wheels-5.8.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2cfbb317f3ee0c8ac9dd5d82e6913b0216222d2b22ea65cbc2f8072dabb167d4"}, - {file = "psutil_wheels-5.8.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ea1f7f6bcc536669a22c07429dde993bc707f45339137b085394faada25fc813"}, - {file = "psutil_wheels-5.8.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d13d705fb5026d3ae476c7988601430dfaa6143e695058a3182146adc0457b7f"}, - {file = "psutil_wheels-5.8.0-cp310-cp310-win_amd64.whl", hash = "sha256:3f0ca7c4c9031e04b18e52cd4c6f17e196bb7896071dd1eacaeb352948b47517"}, - {file = "psutil_wheels-5.8.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:902ab2a221529cd7c0d9fa2f865fdd22bc45df87db825437aeee0dcaeed9b787"}, - {file = "psutil_wheels-5.8.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:96838ad949609621e369d327834ade3b3e1b0fa3f450e0a7460855a3cf41a6d6"}, - {file = "psutil_wheels-5.8.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:933c4079c8121f8f0d3d1525671e3b6182d804d54c7819b6a7dddeac5605ba69"}, - {file = "psutil_wheels-5.8.0-cp38-cp38-win_amd64.whl", hash = "sha256:5dd57fb06b081bf2e3cebe89ca92f6ef606ecc5e50ac7ecb2dc7a68262d6cd91"}, - {file = "psutil_wheels-5.8.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:05a4b136c395273066ecd63d64200868fc57561c65f6dda988b28d08f4a60f69"}, - {file = "psutil_wheels-5.8.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:c7c13e8264fa26f0bde4ddc15f2959d04c2a8f7537c41541d1503dd159b01a86"}, - {file = "psutil_wheels-5.8.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:b07890d22db82a135b8d5149ba1736e0fde998605cfa73c4d030bbfc77e890b6"}, - {file = "psutil_wheels-5.8.0-cp39-cp39-win_amd64.whl", hash = "sha256:84bb63b669aa918b4a62226276b1c1f952e57a461debfb7b9eed848c41e7cbda"}, -] -ptyprocess = [ - {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"}, - {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"}, -] -py = [ - {file = "py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378"}, - {file = "py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719"}, -] -pycairo = [ - {file = "pycairo-1.20.1-cp310-cp310-win32.whl", hash = "sha256:736ffc618e851601e861a630293e5c910ef016b83b2d035a336f83a367bf56ab"}, - {file = "pycairo-1.20.1-cp310-cp310-win_amd64.whl", hash = "sha256:261c69850d4b2ec03346c9745bad2a835bb8124e4c6961b8ceac503d744eb3b3"}, - {file = "pycairo-1.20.1-cp36-cp36m-win32.whl", hash = "sha256:6db823a18e7be1eb2a29c28961f2f01e84d3b449f06be7338d05ac8f90592cd5"}, - {file = "pycairo-1.20.1-cp36-cp36m-win_amd64.whl", hash = "sha256:5525da2d8de912750dd157752aa96f1f0a42a437c5625e85b14c936b5c6305ae"}, - {file = "pycairo-1.20.1-cp37-cp37m-win32.whl", hash = "sha256:c8c2bb933974d91c5d19e54b846d964de177e7bf33433bf34ac34c85f9b30e94"}, - {file = "pycairo-1.20.1-cp37-cp37m-win_amd64.whl", hash = "sha256:9a32e4a3574a104aa876c35d5e71485dfd6986b18d045534c6ec510c44d5d6a7"}, - {file = "pycairo-1.20.1-cp38-cp38-win32.whl", hash = "sha256:0d7a6754d410d911a46f00396bee4be96500ccd3d178e7e98aef1140e3dd67ae"}, - {file = "pycairo-1.20.1-cp38-cp38-win_amd64.whl", hash = "sha256:b605151cdd23cedb31855b8666371b6e26b80f02753a52c8b8023a916b1df812"}, - {file = "pycairo-1.20.1-cp39-cp39-win32.whl", hash = "sha256:e800486b51fffeb11ed867b4f2220d446e2a60a81a73b7c377123e0cbb72f49d"}, - {file = "pycairo-1.20.1-cp39-cp39-win_amd64.whl", hash = "sha256:f123d3818e30b77b7209d70a6dcfd5b4e34885f9fa539d92dd7ff3e4e2037213"}, - {file = "pycairo-1.20.1.tar.gz", hash = "sha256:1ee72b035b21a475e1ed648e26541b04e5d7e753d75ca79de8c583b25785531b"}, -] -pycodestyle = [ - {file = "pycodestyle-2.7.0-py2.py3-none-any.whl", hash = "sha256:514f76d918fcc0b55c6680472f0a37970994e07bbb80725808c17089be302068"}, - {file = "pycodestyle-2.7.0.tar.gz", hash = "sha256:c389c1d06bf7904078ca03399a4816f974a1d590090fecea0c63ec26ebaf1cef"}, -] -pycparser = [ - {file = "pycparser-2.21-py2.py3-none-any.whl", hash = "sha256:8ee45429555515e1f6b185e78100aea234072576aa43ab53aefcae078162fca9"}, - {file = "pycparser-2.21.tar.gz", hash = "sha256:e644fdec12f7872f86c58ff790da456218b10f863970249516d60a5eaca77206"}, -] -pydocstyle = [ - {file = "pydocstyle-6.1.1-py3-none-any.whl", hash = "sha256:6987826d6775056839940041beef5c08cc7e3d71d63149b48e36727f70144dc4"}, - {file = "pydocstyle-6.1.1.tar.gz", hash = "sha256:1d41b7c459ba0ee6c345f2eb9ae827cab14a7533a88c5c6f7e94923f72df92dc"}, -] -pydub = [ - {file = "pydub-0.25.1-py2.py3-none-any.whl", hash = "sha256:65617e33033874b59d87db603aa1ed450633288aefead953b30bded59cb599a6"}, - {file = "pydub-0.25.1.tar.gz", hash = "sha256:980a33ce9949cab2a569606b65674d748ecbca4f0796887fd6f46173a7b0d30f"}, -] -pyflakes = [ - {file = "pyflakes-2.3.1-py2.py3-none-any.whl", hash = "sha256:7893783d01b8a89811dd72d7dfd4d84ff098e5eed95cfa8905b22bbffe52efc3"}, - {file = "pyflakes-2.3.1.tar.gz", hash = "sha256:f5bc8ecabc05bb9d291eb5203d6810b49040f6ff446a756326104746cc00c1db"}, -] -pygithub = [ - {file = "PyGithub-1.55-py3-none-any.whl", hash = "sha256:2caf0054ea079b71e539741ae56c5a95e073b81fa472ce222e81667381b9601b"}, - {file = "PyGithub-1.55.tar.gz", hash = "sha256:1bbfff9372047ff3f21d5cd8e07720f3dbfdaf6462fcaed9d815f528f1ba7283"}, -] -pyglet = [ - {file = "pyglet-1.5.21-py3-none-any.whl", hash = "sha256:11f11ddda4ee456284f2ddd1fe5c62fe29ba8c42074d3d9ae52d094abc2e1b7c"}, - {file = "pyglet-1.5.21.zip", hash = "sha256:5aaaddb06dc4b6f9ba08254d8d806a2bd2406925a9caf3a51fdffbd5d09728e2"}, -] -pygments = [ - {file = "Pygments-2.11.2-py3-none-any.whl", hash = "sha256:44238f1b60a76d78fc8ca0528ee429702aae011c265fe6a8dd8b63049ae41c65"}, - {file = "Pygments-2.11.2.tar.gz", hash = "sha256:4e426f72023d88d03b2fa258de560726ce890ff3b630f88c21cbb8b2503b8c6a"}, -] -pyjwt = [ - {file = "PyJWT-2.3.0-py3-none-any.whl", hash = "sha256:e0c4bb8d9f0af0c7f5b1ec4c5036309617d03d56932877f2f7a0beeb5318322f"}, - {file = "PyJWT-2.3.0.tar.gz", hash = "sha256:b888b4d56f06f6dcd777210c334e69c737be74755d3e5e9ee3fe67dc18a0ee41"}, -] -pylint = [ - {file = "pylint-2.12.2-py3-none-any.whl", hash = "sha256:daabda3f7ed9d1c60f52d563b1b854632fd90035bcf01443e234d3dc794e3b74"}, - {file = "pylint-2.12.2.tar.gz", hash = "sha256:9d945a73640e1fec07ee34b42f5669b770c759acd536ec7b16d7e4b87a9c9ff9"}, -] -pynacl = [ - {file = "PyNaCl-1.5.0-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1"}, - {file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92"}, - {file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394"}, - {file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d"}, - {file = "PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858"}, - {file = "PyNaCl-1.5.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b"}, - {file = "PyNaCl-1.5.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff"}, - {file = "PyNaCl-1.5.0-cp36-abi3-win32.whl", hash = "sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543"}, - {file = "PyNaCl-1.5.0-cp36-abi3-win_amd64.whl", hash = "sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93"}, - {file = "PyNaCl-1.5.0.tar.gz", hash = "sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba"}, -] -pyobjc-core = [ - {file = "pyobjc-core-8.2.tar.gz", hash = "sha256:6afb8ee1dd0647cbfaaf99906eca3b43ce045b27e3d4510462d04e7e5361c89b"}, - {file = "pyobjc_core-8.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:311e45556c3afa8831713b89017e0204562f51f35661d76c07ffe04985f44e1d"}, - {file = "pyobjc_core-8.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:711f361e83382e405e4273ff085178b0cf730901ccf6801f834e7037e50278f9"}, - {file = "pyobjc_core-8.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:bdd2e2960ec73214bcfe2d86bb4ca94f5f5119db86d129fa32d3c003b6532c50"}, - {file = "pyobjc_core-8.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b879f91fc614c399aafa1d08cf5e279c267510e904bad5c336c3a6064c0eb3aa"}, - {file = "pyobjc_core-8.2-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:b4ef4bdb99a330f5e15cc6273098964276fccbc432453cdba3c2963292bc066c"}, - {file = "pyobjc_core-8.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:fd8e5be0955790ff8f9d17a0f356b6eb7eb1ce4995e0c94355c462dd52d22d6d"}, -] -pyobjc-framework-cocoa = [ - {file = "pyobjc-framework-Cocoa-8.2.tar.gz", hash = "sha256:f0901998e2f18415ef6d1f8a12b083f69fc93bd56b3e88040002e3c09bd8c304"}, - {file = "pyobjc_framework_Cocoa-8.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:5af73f150e242542735e0663bb5504f88aabaec2a54c60e856cfca3ff6dd9712"}, - {file = "pyobjc_framework_Cocoa-8.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d1de3763ee01850c311da74de5c82c85ec199120e85ab45acaf203accc37a470"}, - {file = "pyobjc_framework_Cocoa-8.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:86d69bf667f99f3c43184d8830567195fff94c675fe7f60f899dd90553d9b265"}, - {file = "pyobjc_framework_Cocoa-8.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9dbadb22826392c48b00087359f66579f8404a4f4f77498f31f9869c54bb0fa9"}, - {file = "pyobjc_framework_Cocoa-8.2-cp38-cp38-macosx_11_0_universal2.whl", hash = "sha256:7adf8b57da1c1292c24375b8e74b6dd45f99a4d3c10ba925a9b38f63a97ba782"}, - {file = "pyobjc_framework_Cocoa-8.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bc8279c8c1544087d46a7e99324f093029df89b8c527c5da2a682bad4cb3197e"}, -] -pyparsing = [ - {file = "pyparsing-3.0.7-py3-none-any.whl", hash = "sha256:a6c06a88f252e6c322f65faf8f418b16213b51bdfaece0524c1c1bc30c63c484"}, - {file = "pyparsing-3.0.7.tar.gz", hash = "sha256:18ee9022775d270c55187733956460083db60b37d0d0fb357445f3094eed3eea"}, -] -pyrr = [ - {file = "pyrr-0.10.3-py3-none-any.whl", hash = "sha256:d8af23fb9bb29262405845e1c98f7339fbba5e49323b98528bd01160a75c65ac"}, - {file = "pyrr-0.10.3.tar.gz", hash = "sha256:3c0f7b20326e71f706a610d58f2190fff73af01eef60c19cb188b186f0ec7e1d"}, -] -pyrsistent = [ - {file = "pyrsistent-0.18.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:df46c854f490f81210870e509818b729db4488e1f30f2a1ce1698b2295a878d1"}, - {file = "pyrsistent-0.18.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d45866ececf4a5fff8742c25722da6d4c9e180daa7b405dc0a2a2790d668c26"}, - {file = "pyrsistent-0.18.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4ed6784ceac462a7d6fcb7e9b663e93b9a6fb373b7f43594f9ff68875788e01e"}, - {file = "pyrsistent-0.18.1-cp310-cp310-win32.whl", hash = "sha256:e4f3149fd5eb9b285d6bfb54d2e5173f6a116fe19172686797c056672689daf6"}, - {file = "pyrsistent-0.18.1-cp310-cp310-win_amd64.whl", hash = "sha256:636ce2dc235046ccd3d8c56a7ad54e99d5c1cd0ef07d9ae847306c91d11b5fec"}, - {file = "pyrsistent-0.18.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:e92a52c166426efbe0d1ec1332ee9119b6d32fc1f0bbfd55d5c1088070e7fc1b"}, - {file = "pyrsistent-0.18.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d7a096646eab884bf8bed965bad63ea327e0d0c38989fc83c5ea7b8a87037bfc"}, - {file = "pyrsistent-0.18.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cdfd2c361b8a8e5d9499b9082b501c452ade8bbf42aef97ea04854f4a3f43b22"}, - {file = "pyrsistent-0.18.1-cp37-cp37m-win32.whl", hash = "sha256:7ec335fc998faa4febe75cc5268a9eac0478b3f681602c1f27befaf2a1abe1d8"}, - {file = "pyrsistent-0.18.1-cp37-cp37m-win_amd64.whl", hash = "sha256:6455fc599df93d1f60e1c5c4fe471499f08d190d57eca040c0ea182301321286"}, - {file = "pyrsistent-0.18.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:fd8da6d0124efa2f67d86fa70c851022f87c98e205f0594e1fae044e7119a5a6"}, - {file = "pyrsistent-0.18.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7bfe2388663fd18bd8ce7db2c91c7400bf3e1a9e8bd7d63bf7e77d39051b85ec"}, - {file = "pyrsistent-0.18.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e3e1fcc45199df76053026a51cc59ab2ea3fc7c094c6627e93b7b44cdae2c8c"}, - {file = "pyrsistent-0.18.1-cp38-cp38-win32.whl", hash = "sha256:b568f35ad53a7b07ed9b1b2bae09eb15cdd671a5ba5d2c66caee40dbf91c68ca"}, - {file = "pyrsistent-0.18.1-cp38-cp38-win_amd64.whl", hash = "sha256:d1b96547410f76078eaf66d282ddca2e4baae8964364abb4f4dcdde855cd123a"}, - {file = "pyrsistent-0.18.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f87cc2863ef33c709e237d4b5f4502a62a00fab450c9e020892e8e2ede5847f5"}, - {file = "pyrsistent-0.18.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6bc66318fb7ee012071b2792024564973ecc80e9522842eb4e17743604b5e045"}, - {file = "pyrsistent-0.18.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:914474c9f1d93080338ace89cb2acee74f4f666fb0424896fcfb8d86058bf17c"}, - {file = "pyrsistent-0.18.1-cp39-cp39-win32.whl", hash = "sha256:1b34eedd6812bf4d33814fca1b66005805d3640ce53140ab8bbb1e2651b0d9bc"}, - {file = "pyrsistent-0.18.1-cp39-cp39-win_amd64.whl", hash = "sha256:e24a828f57e0c337c8d8bb9f6b12f09dfdf0273da25fda9e314f0b684b415a07"}, - {file = "pyrsistent-0.18.1.tar.gz", hash = "sha256:d4d61f8b993a7255ba714df3aca52700f8125289f84f704cf80916517c46eb96"}, -] -pytest = [ - {file = "pytest-6.2.5-py3-none-any.whl", hash = "sha256:7310f8d27bc79ced999e760ca304d69f6ba6c6649c0b60fb0e04a4a77cacc134"}, - {file = "pytest-6.2.5.tar.gz", hash = "sha256:131b36680866a76e6781d13f101efb86cf674ebb9762eb70d3082b6f29889e89"}, -] -pytest-cov = [ - {file = "pytest-cov-3.0.0.tar.gz", hash = "sha256:e7f0f5b1617d2210a2cabc266dfe2f4c75a8d32fb89eafb7ad9d06f6d076d470"}, - {file = "pytest_cov-3.0.0-py3-none-any.whl", hash = "sha256:578d5d15ac4a25e5f961c938b85a05b09fdaae9deef3bb6de9a6e766622ca7a6"}, -] -pytest-forked = [ - {file = "pytest-forked-1.4.0.tar.gz", hash = "sha256:8b67587c8f98cbbadfdd804539ed5455b6ed03802203485dd2f53c1422d7440e"}, - {file = "pytest_forked-1.4.0-py3-none-any.whl", hash = "sha256:bbbb6717efc886b9d64537b41fb1497cfaf3c9601276be8da2cccfea5a3c8ad8"}, -] -pytest-xdist = [ - {file = "pytest-xdist-2.5.0.tar.gz", hash = "sha256:4580deca3ff04ddb2ac53eba39d76cb5dd5edeac050cb6fbc768b0dd712b4edf"}, - {file = "pytest_xdist-2.5.0-py3-none-any.whl", hash = "sha256:6fe5c74fec98906deb8f2d2b616b5c782022744978e7bd4695d39c8f42d0ce65"}, -] -python-dateutil = [ - {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"}, -] -pytz = [ - {file = "pytz-2021.3-py2.py3-none-any.whl", hash = "sha256:3672058bc3453457b622aab7a1c3bfd5ab0bdae451512f6cf25f64ed37f5b87c"}, - {file = "pytz-2021.3.tar.gz", hash = "sha256:acad2d8b20a1af07d4e4c9d2e9285c5ed9104354062f275f3fcd88dcef4f1326"}, -] -pywin32 = [ - {file = "pywin32-303-cp310-cp310-win32.whl", hash = "sha256:6fed4af057039f309263fd3285d7b8042d41507343cd5fa781d98fcc5b90e8bb"}, - {file = "pywin32-303-cp310-cp310-win_amd64.whl", hash = "sha256:51cb52c5ec6709f96c3f26e7795b0bf169ee0d8395b2c1d7eb2c029a5008ed51"}, - {file = "pywin32-303-cp311-cp311-win32.whl", hash = "sha256:d9b5d87ca944eb3aa4cd45516203ead4b37ab06b8b777c54aedc35975dec0dee"}, - {file = "pywin32-303-cp311-cp311-win_amd64.whl", hash = "sha256:fcf44032f5b14fcda86028cdf49b6ebdaea091230eb0a757282aa656e4732439"}, - {file = "pywin32-303-cp36-cp36m-win32.whl", hash = "sha256:aad484d52ec58008ca36bd4ad14a71d7dd0a99db1a4ca71072213f63bf49c7d9"}, - {file = "pywin32-303-cp36-cp36m-win_amd64.whl", hash = "sha256:2a09632916b6bb231ba49983fe989f2f625cea237219530e81a69239cd0c4559"}, - {file = "pywin32-303-cp37-cp37m-win32.whl", hash = "sha256:b1675d82bcf6dbc96363fca747bac8bff6f6e4a447a4287ac652aa4b9adc796e"}, - {file = "pywin32-303-cp37-cp37m-win_amd64.whl", hash = "sha256:c268040769b48a13367221fced6d4232ed52f044ffafeda247bd9d2c6bdc29ca"}, - {file = "pywin32-303-cp38-cp38-win32.whl", hash = "sha256:5f9ec054f5a46a0f4dfd72af2ce1372f3d5a6e4052af20b858aa7df2df7d355b"}, - {file = "pywin32-303-cp38-cp38-win_amd64.whl", hash = "sha256:793bf74fce164bcffd9d57bb13c2c15d56e43c9542a7b9687b4fccf8f8a41aba"}, - {file = "pywin32-303-cp39-cp39-win32.whl", hash = "sha256:7d3271c98434617a11921c5ccf74615794d97b079e22ed7773790822735cc352"}, - {file = "pywin32-303-cp39-cp39-win_amd64.whl", hash = "sha256:79cbb862c11b9af19bcb682891c1b91942ec2ff7de8151e2aea2e175899cda34"}, -] -pywinpty = [ - {file = "pywinpty-1.1.6-cp310-none-win_amd64.whl", hash = "sha256:5f526f21b569b5610a61e3b6126259c76da979399598e5154498582df3736ade"}, - {file = "pywinpty-1.1.6-cp36-none-win_amd64.whl", hash = "sha256:7576e14f42b31fa98b62d24ded79754d2ea4625570c016b38eb347ce158a30f2"}, - {file = "pywinpty-1.1.6-cp37-none-win_amd64.whl", hash = "sha256:979ffdb9bdbe23db3f46fc7285fd6dbb86b80c12325a50582b211b3894072354"}, - {file = "pywinpty-1.1.6-cp38-none-win_amd64.whl", hash = "sha256:2308b1fc77545427610a705799d4ead5e7f00874af3fb148a03e202437456a7e"}, - {file = "pywinpty-1.1.6-cp39-none-win_amd64.whl", hash = "sha256:c703bf569a98ab7844b9daf37e88ab86f31862754ef6910a8b3824993a525c72"}, - {file = "pywinpty-1.1.6.tar.gz", hash = "sha256:8808f07350c709119cc4464144d6e749637f98e15acc1e5d3c37db1953d2eebc"}, -] -pyyaml = [ - {file = "PyYAML-6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:d4db7c7aef085872ef65a8fd7d6d09a14ae91f691dec3e87ee5ee0539d516f53"}, - {file = "PyYAML-6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9df7ed3b3d2e0ecfe09e14741b857df43adb5a3ddadc919a2d94fbdf78fea53c"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77f396e6ef4c73fdc33a9157446466f1cff553d979bd00ecb64385760c6babdc"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a80a78046a72361de73f8f395f1f1e49f956c6be882eed58505a15f3e430962b"}, - {file = "PyYAML-6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f84fbc98b019fef2ee9a1cb3ce93e3187a6df0b2538a651bfb890254ba9f90b5"}, - {file = "PyYAML-6.0-cp310-cp310-win32.whl", hash = "sha256:2cd5df3de48857ed0544b34e2d40e9fac445930039f3cfe4bcc592a1f836d513"}, - {file = "PyYAML-6.0-cp310-cp310-win_amd64.whl", hash = "sha256:daf496c58a8c52083df09b80c860005194014c3698698d1a57cbcfa182142a3a"}, - {file = "PyYAML-6.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:897b80890765f037df3403d22bab41627ca8811ae55e9a722fd0392850ec4d86"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50602afada6d6cbfad699b0c7bb50d5ccffa7e46a3d738092afddc1f9758427f"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:48c346915c114f5fdb3ead70312bd042a953a8ce5c7106d5bfb1a5254e47da92"}, - {file = "PyYAML-6.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:98c4d36e99714e55cfbaaee6dd5badbc9a1ec339ebfc3b1f52e293aee6bb71a4"}, - {file = "PyYAML-6.0-cp36-cp36m-win32.whl", hash = "sha256:0283c35a6a9fbf047493e3a0ce8d79ef5030852c51e9d911a27badfde0605293"}, - {file = "PyYAML-6.0-cp36-cp36m-win_amd64.whl", hash = "sha256:07751360502caac1c067a8132d150cf3d61339af5691fe9e87803040dbc5db57"}, - {file = "PyYAML-6.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:819b3830a1543db06c4d4b865e70ded25be52a2e0631ccd2f6a47a2822f2fd7c"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:473f9edb243cb1935ab5a084eb238d842fb8f404ed2193a915d1784b5a6b5fc0"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ce82d761c532fe4ec3f87fc45688bdd3a4c1dc5e0b4a19814b9009a29baefd4"}, - {file = "PyYAML-6.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:231710d57adfd809ef5d34183b8ed1eeae3f76459c18fb4a0b373ad56bedcdd9"}, - {file = "PyYAML-6.0-cp37-cp37m-win32.whl", hash = "sha256:c5687b8d43cf58545ade1fe3e055f70eac7a5a1a0bf42824308d868289a95737"}, - {file = "PyYAML-6.0-cp37-cp37m-win_amd64.whl", hash = "sha256:d15a181d1ecd0d4270dc32edb46f7cb7733c7c508857278d3d378d14d606db2d"}, - {file = "PyYAML-6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:0b4624f379dab24d3725ffde76559cff63d9ec94e1736b556dacdfebe5ab6d4b"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213c60cd50106436cc818accf5baa1aba61c0189ff610f64f4a3e8c6726218ba"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9fa600030013c4de8165339db93d182b9431076eb98eb40ee068700c9c813e34"}, - {file = "PyYAML-6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:277a0ef2981ca40581a47093e9e2d13b3f1fbbeffae064c1d21bfceba2030287"}, - {file = "PyYAML-6.0-cp38-cp38-win32.whl", hash = "sha256:d4eccecf9adf6fbcc6861a38015c2a64f38b9d94838ac1810a9023a0609e1b78"}, - {file = "PyYAML-6.0-cp38-cp38-win_amd64.whl", hash = "sha256:1e4747bc279b4f613a09eb64bba2ba602d8a6664c6ce6396a4d0cd413a50ce07"}, - {file = "PyYAML-6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:055d937d65826939cb044fc8c9b08889e8c743fdc6a32b33e2390f66013e449b"}, - {file = "PyYAML-6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e61ceaab6f49fb8bdfaa0f92c4b57bcfbea54c09277b1b4f7ac376bfb7a7c174"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d67d839ede4ed1b28a4e8909735fc992a923cdb84e618544973d7dfc71540803"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cba8c411ef271aa037d7357a2bc8f9ee8b58b9965831d9e51baf703280dc73d3"}, - {file = "PyYAML-6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:40527857252b61eacd1d9af500c3337ba8deb8fc298940291486c465c8b46ec0"}, - {file = "PyYAML-6.0-cp39-cp39-win32.whl", hash = "sha256:b5b9eccad747aabaaffbc6064800670f0c297e52c12754eb1d976c57e4f74dcb"}, - {file = "PyYAML-6.0-cp39-cp39-win_amd64.whl", hash = "sha256:b3d267842bf12586ba6c734f89d1f5b871df0273157918b0ccefa29deb05c21c"}, - {file = "PyYAML-6.0.tar.gz", hash = "sha256:68fb519c14306fec9720a2a5b45bc9f0c8d1b9c72adf45c37baedfcd949c35a2"}, -] -pyzmq = [ - {file = "pyzmq-22.3.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:6b217b8f9dfb6628f74b94bdaf9f7408708cb02167d644edca33f38746ca12dd"}, - {file = "pyzmq-22.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:2841997a0d85b998cbafecb4183caf51fd19c4357075dfd33eb7efea57e4c149"}, - {file = "pyzmq-22.3.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f89468059ebc519a7acde1ee50b779019535db8dcf9b8c162ef669257fef7a93"}, - {file = "pyzmq-22.3.0-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ea12133df25e3a6918718fbb9a510c6ee5d3fdd5a346320421aac3882f4feeea"}, - {file = "pyzmq-22.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:76c532fd68b93998aab92356be280deec5de8f8fe59cd28763d2cc8a58747b7f"}, - {file = "pyzmq-22.3.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:f907c7359ce8bf7f7e63c82f75ad0223384105f5126f313400b7e8004d9b33c3"}, - {file = "pyzmq-22.3.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:902319cfe23366595d3fa769b5b751e6ee6750a0a64c5d9f757d624b2ac3519e"}, - {file = "pyzmq-22.3.0-cp310-cp310-win32.whl", hash = "sha256:67db33bea0a29d03e6eeec55a8190e033318cee3cbc732ba8fd939617cbf762d"}, - {file = "pyzmq-22.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:7661fc1d5cb73481cf710a1418a4e1e301ed7d5d924f91c67ba84b2a1b89defd"}, - {file = "pyzmq-22.3.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:79244b9e97948eaf38695f4b8e6fc63b14b78cc37f403c6642ba555517ac1268"}, - {file = "pyzmq-22.3.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ab888624ed68930442a3f3b0b921ad7439c51ba122dbc8c386e6487a658e4a4e"}, - {file = "pyzmq-22.3.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:18cd854b423fce44951c3a4d3e686bac8f1243d954f579e120a1714096637cc0"}, - {file = "pyzmq-22.3.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:de8df0684398bd74ad160afdc2a118ca28384ac6f5e234eb0508858d8d2d9364"}, - {file = "pyzmq-22.3.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:62bcade20813796c426409a3e7423862d50ff0639f5a2a95be4b85b09a618666"}, - {file = "pyzmq-22.3.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:ea5a79e808baef98c48c884effce05c31a0698c1057de8fc1c688891043c1ce1"}, - {file = "pyzmq-22.3.0-cp36-cp36m-win32.whl", hash = "sha256:3c1895c95be92600233e476fe283f042e71cf8f0b938aabf21b7aafa62a8dac9"}, - {file = "pyzmq-22.3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:851977788b9caa8ed011f5f643d3ee8653af02c5fc723fa350db5125abf2be7b"}, - {file = "pyzmq-22.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:b4ebed0977f92320f6686c96e9e8dd29eed199eb8d066936bac991afc37cbb70"}, - {file = "pyzmq-22.3.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42abddebe2c6a35180ca549fadc7228d23c1e1f76167c5ebc8a936b5804ea2df"}, - {file = "pyzmq-22.3.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c1e41b32d6f7f9c26bc731a8b529ff592f31fc8b6ef2be9fa74abd05c8a342d7"}, - {file = "pyzmq-22.3.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:be4e0f229cf3a71f9ecd633566bd6f80d9fa6afaaff5489492be63fe459ef98c"}, - {file = "pyzmq-22.3.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:08c4e315a76ef26eb833511ebf3fa87d182152adf43dedee8d79f998a2162a0b"}, - {file = "pyzmq-22.3.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:badb868fff14cfd0e200eaa845887b1011146a7d26d579aaa7f966c203736b92"}, - {file = "pyzmq-22.3.0-cp37-cp37m-win32.whl", hash = "sha256:7c58f598d9fcc52772b89a92d72bf8829c12d09746a6d2c724c5b30076c1f11d"}, - {file = "pyzmq-22.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:2b97502c16a5ec611cd52410bdfaab264997c627a46b0f98d3f666227fd1ea2d"}, - {file = "pyzmq-22.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d728b08448e5ac3e4d886b165385a262883c34b84a7fe1166277fe675e1c197a"}, - {file = "pyzmq-22.3.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:480b9931bfb08bf8b094edd4836271d4d6b44150da051547d8c7113bf947a8b0"}, - {file = "pyzmq-22.3.0-cp38-cp38-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7dc09198e4073e6015d9a8ea093fc348d4e59de49382476940c3dd9ae156fba8"}, - {file = "pyzmq-22.3.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ca6cd58f62a2751728016d40082008d3b3412a7f28ddfb4a2f0d3c130f69e74"}, - {file = "pyzmq-22.3.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:468bd59a588e276961a918a3060948ae68f6ff5a7fa10bb2f9160c18fe341067"}, - {file = "pyzmq-22.3.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:c88fa7410e9fc471e0858638f403739ee869924dd8e4ae26748496466e27ac59"}, - {file = "pyzmq-22.3.0-cp38-cp38-win32.whl", hash = "sha256:c0f84360dcca3481e8674393bdf931f9f10470988f87311b19d23cda869bb6b7"}, - {file = "pyzmq-22.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:f762442bab706fd874064ca218b33a1d8e40d4938e96c24dafd9b12e28017f45"}, - {file = "pyzmq-22.3.0-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:954e73c9cd4d6ae319f1c936ad159072b6d356a92dcbbabfd6e6204b9a79d356"}, - {file = "pyzmq-22.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f43b4a2e6218371dd4f41e547bd919ceeb6ebf4abf31a7a0669cd11cd91ea973"}, - {file = "pyzmq-22.3.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:acebba1a23fb9d72b42471c3771b6f2f18dcd46df77482612054bd45c07dfa36"}, - {file = "pyzmq-22.3.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cf98fd7a6c8aaa08dbc699ffae33fd71175696d78028281bc7b832b26f00ca57"}, - {file = "pyzmq-22.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d072f7dfbdb184f0786d63bda26e8a0882041b1e393fbe98940395f7fab4c5e2"}, - {file = "pyzmq-22.3.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:53f4fd13976789ffafedd4d46f954c7bb01146121812b72b4ddca286034df966"}, - {file = "pyzmq-22.3.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:d1b5d457acbadcf8b27561deeaa386b0217f47626b29672fa7bd31deb6e91e1b"}, - {file = "pyzmq-22.3.0-cp39-cp39-win32.whl", hash = "sha256:e6a02cf7271ee94674a44f4e62aa061d2d049001c844657740e156596298b70b"}, - {file = "pyzmq-22.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:d3dcb5548ead4f1123851a5ced467791f6986d68c656bc63bfff1bf9e36671e2"}, - {file = "pyzmq-22.3.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:3a4c9886d61d386b2b493377d980f502186cd71d501fffdba52bd2a0880cef4f"}, - {file = "pyzmq-22.3.0-pp37-pypy37_pp73-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:80e043a89c6cadefd3a0712f8a1322038e819ebe9dbac7eca3bce1721bcb63bf"}, - {file = "pyzmq-22.3.0-pp37-pypy37_pp73-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1621e7a2af72cced1f6ec8ca8ca91d0f76ac236ab2e8828ac8fe909512d566cb"}, - {file = "pyzmq-22.3.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:d6157793719de168b199194f6b6173f0ccd3bf3499e6870fac17086072e39115"}, - {file = "pyzmq-22.3.0.tar.gz", hash = "sha256:8eddc033e716f8c91c6a2112f0a8ebc5e00532b4a6ae1eb0ccc48e027f9c671c"}, -] -recommonmark = [ - {file = "recommonmark-0.7.1-py2.py3-none-any.whl", hash = "sha256:1b1db69af0231efce3fa21b94ff627ea33dee7079a01dd0a7f8482c3da148b3f"}, - {file = "recommonmark-0.7.1.tar.gz", hash = "sha256:bdb4db649f2222dcd8d2d844f0006b958d627f732415d399791ee436a3686d67"}, -] -requests = [ - {file = "requests-2.27.1-py2.py3-none-any.whl", hash = "sha256:f22fa1e554c9ddfd16e6e41ac79759e17be9e492b3587efa038054674760e72d"}, - {file = "requests-2.27.1.tar.gz", hash = "sha256:68d7c56fd5a8999887728ef304a6d12edc7be74f1cfa47714fc8b414525c9a61"}, -] -restructuredtext-lint = [ - {file = "restructuredtext_lint-1.3.2.tar.gz", hash = "sha256:d3b10a1fe2ecac537e51ae6d151b223b78de9fafdd50e5eb6b08c243df173c80"}, -] -rich = [ - {file = "rich-11.2.0-py3-none-any.whl", hash = "sha256:d5f49ad91fb343efcae45a2b2df04a9755e863e50413623ab8c9e74f05aee52b"}, - {file = "rich-11.2.0.tar.gz", hash = "sha256:1a6266a5738115017bb64a66c59c717e7aa047b3ae49a011ede4abdeffc6536e"}, -] -scipy = [ - {file = "scipy-1.7.3-1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:c9e04d7e9b03a8a6ac2045f7c5ef741be86727d8f49c45db45f244bdd2bcff17"}, - {file = "scipy-1.7.3-1-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:b0e0aeb061a1d7dcd2ed59ea57ee56c9b23dd60100825f98238c06ee5cc4467e"}, - {file = "scipy-1.7.3-1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:b78a35c5c74d336f42f44106174b9851c783184a85a3fe3e68857259b37b9ffb"}, - {file = "scipy-1.7.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:173308efba2270dcd61cd45a30dfded6ec0085b4b6eb33b5eb11ab443005e088"}, - {file = "scipy-1.7.3-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:21b66200cf44b1c3e86495e3a436fc7a26608f92b8d43d344457c54f1c024cbc"}, - {file = "scipy-1.7.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ceebc3c4f6a109777c0053dfa0282fddb8893eddfb0d598574acfb734a926168"}, - {file = "scipy-1.7.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f7eaea089345a35130bc9a39b89ec1ff69c208efa97b3f8b25ea5d4c41d88094"}, - {file = "scipy-1.7.3-cp310-cp310-win_amd64.whl", hash = "sha256:304dfaa7146cffdb75fbf6bb7c190fd7688795389ad060b970269c8576d038e9"}, - {file = "scipy-1.7.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:033ce76ed4e9f62923e1f8124f7e2b0800db533828c853b402c7eec6e9465d80"}, - {file = "scipy-1.7.3-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:4d242d13206ca4302d83d8a6388c9dfce49fc48fdd3c20efad89ba12f785bf9e"}, - {file = "scipy-1.7.3-cp37-cp37m-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:8499d9dd1459dc0d0fe68db0832c3d5fc1361ae8e13d05e6849b358dc3f2c279"}, - {file = "scipy-1.7.3-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca36e7d9430f7481fc7d11e015ae16fbd5575615a8e9060538104778be84addf"}, - {file = "scipy-1.7.3-cp37-cp37m-win32.whl", hash = "sha256:e2c036492e673aad1b7b0d0ccdc0cb30a968353d2c4bf92ac8e73509e1bf212c"}, - {file = "scipy-1.7.3-cp37-cp37m-win_amd64.whl", hash = "sha256:866ada14a95b083dd727a845a764cf95dd13ba3dc69a16b99038001b05439709"}, - {file = "scipy-1.7.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:65bd52bf55f9a1071398557394203d881384d27b9c2cad7df9a027170aeaef93"}, - {file = "scipy-1.7.3-cp38-cp38-macosx_12_0_arm64.whl", hash = "sha256:f99d206db1f1ae735a8192ab93bd6028f3a42f6fa08467d37a14eb96c9dd34a3"}, - {file = "scipy-1.7.3-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:5f2cfc359379c56b3a41b17ebd024109b2049f878badc1e454f31418c3a18436"}, - {file = "scipy-1.7.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb7ae2c4dbdb3c9247e07acc532f91077ae6dbc40ad5bd5dca0bb5a176ee9bda"}, - {file = "scipy-1.7.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95c2d250074cfa76715d58830579c64dff7354484b284c2b8b87e5a38321672c"}, - {file = "scipy-1.7.3-cp38-cp38-win32.whl", hash = "sha256:87069cf875f0262a6e3187ab0f419f5b4280d3dcf4811ef9613c605f6e4dca95"}, - {file = "scipy-1.7.3-cp38-cp38-win_amd64.whl", hash = "sha256:7edd9a311299a61e9919ea4192dd477395b50c014cdc1a1ac572d7c27e2207fa"}, - {file = "scipy-1.7.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:eef93a446114ac0193a7b714ce67659db80caf940f3232bad63f4c7a81bc18df"}, - {file = "scipy-1.7.3-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:eb326658f9b73c07081300daba90a8746543b5ea177184daed26528273157294"}, - {file = "scipy-1.7.3-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:93378f3d14fff07572392ce6a6a2ceb3a1f237733bd6dcb9eb6a2b29b0d19085"}, - {file = "scipy-1.7.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:edad1cf5b2ce1912c4d8ddad20e11d333165552aba262c882e28c78bbc09dbf6"}, - {file = "scipy-1.7.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5d1cc2c19afe3b5a546ede7e6a44ce1ff52e443d12b231823268019f608b9b12"}, - {file = "scipy-1.7.3-cp39-cp39-win32.whl", hash = "sha256:2c56b820d304dffcadbbb6cbfbc2e2c79ee46ea291db17e288e73cd3c64fefa9"}, - {file = "scipy-1.7.3-cp39-cp39-win_amd64.whl", hash = "sha256:3f78181a153fa21c018d346f595edd648344751d7f03ab94b398be2ad083ed3e"}, - {file = "scipy-1.7.3.tar.gz", hash = "sha256:ab5875facfdef77e0a47d5fd39ea178b58e60e454a4c85aa1e52fcb80db7babf"}, -] -screeninfo = [ - {file = "screeninfo-0.8-py3-none-any.whl", hash = "sha256:dac455fbed79e82c481d59a00962f543e5a9bf3c2cc9f0e48e2714eb8d3cec23"}, - {file = "screeninfo-0.8.tar.gz", hash = "sha256:9501bf8b8458c7d1be4cb0ac9abddddfa80b932fb3f65bfcb54f5586434b1dc5"}, -] -send2trash = [ - {file = "Send2Trash-1.8.0-py3-none-any.whl", hash = "sha256:f20eaadfdb517eaca5ce077640cb261c7d2698385a6a0f072a4a5447fd49fa08"}, - {file = "Send2Trash-1.8.0.tar.gz", hash = "sha256:d2c24762fd3759860a0aff155e45871447ea58d2be6bdd39b5c8f966a0c99c2d"}, -] -setuptools-scm = [ - {file = "setuptools_scm-6.4.2-py3-none-any.whl", hash = "sha256:acea13255093849de7ccb11af9e1fb8bde7067783450cee9ef7a93139bddf6d4"}, - {file = "setuptools_scm-6.4.2.tar.gz", hash = "sha256:6833ac65c6ed9711a4d5d2266f8024cfa07c533a0e55f4c12f6eff280a5a9e30"}, -] -six = [ - {file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"}, - {file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"}, -] -skia-pathops = [ - {file = "skia-pathops-0.7.2.zip", hash = "sha256:19d85c9afefba15af92b13c8889964f77e6382f58f42c6040b4019eb28cba690"}, - {file = "skia_pathops-0.7.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8ce9ee85d53fff7c9e444f25ea98b817f87440694babde069df0112d37bf2ed4"}, - {file = "skia_pathops-0.7.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:754a37e32e06d0c0affdae3cd7f97496997a07a322d3aaa0964a0bfa0fe84bfc"}, - {file = "skia_pathops-0.7.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e4e6c792303419848ba8c035f3496faafcf4a23ec0b0c7596eda0c77b5d1500"}, - {file = "skia_pathops-0.7.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f6b518fca15b4456ddf99062f334c0333a5165be976fb0c9e071af29128583f7"}, - {file = "skia_pathops-0.7.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:44a3c57c9bcae38fcc438ac6b048ba0c50759994ab466c424c5d7f6812d3a222"}, - {file = "skia_pathops-0.7.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:e35b8962c5b9f10fb40f66708c18cc0bc17e0b0c98230e72514f780a1f42aac9"}, - {file = "skia_pathops-0.7.2-cp310-cp310-win32.whl", hash = "sha256:14172fc2817b7e51d3e6859b435d11c917db68beb11d441aad4b247113c902a8"}, - {file = "skia_pathops-0.7.2-cp310-cp310-win_amd64.whl", hash = "sha256:17ee7f807e434e66cf8398607b696c7d529f1a2416452135a5f327c4e54b511d"}, - {file = "skia_pathops-0.7.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:835b55899665b7fa14e51eb1f2eaa4c0e876bc5965dc92b7e89dc00519620f56"}, - {file = "skia_pathops-0.7.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a58fcde1010a58bd6f251c4f2af2e0a37e281b4e807e295c84dcfb3541fef78b"}, - {file = "skia_pathops-0.7.2-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d28060f7a64fa834b1a88fb053227da30b5c27699dc08aa347a985ac3eced9b5"}, - {file = "skia_pathops-0.7.2-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:1a8e7729f32ac87419467efd6858c375fe01da21eb62c8a553c43327ff1cf9d7"}, - {file = "skia_pathops-0.7.2-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:577371bc51a2b3efdee943b1c2f61af8765b7383bf2bf490968e61c7acb2204d"}, - {file = "skia_pathops-0.7.2-cp37-cp37m-win32.whl", hash = "sha256:bb8d25a0b5659cf1981c90c843b229c836ad0277808b8becbbb2a92972078cbf"}, - {file = "skia_pathops-0.7.2-cp37-cp37m-win_amd64.whl", hash = "sha256:6b61da9869d11b58bf471b851adc647fe989d625f0ddd02bc78d1cdcd3e0db60"}, - {file = "skia_pathops-0.7.2-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:56dbaea031aca9f9e219a42fc454f386b0816d011119da0b7d43d92110e48148"}, - {file = "skia_pathops-0.7.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7aa3ec93b5d7b6c4da607453b7b082770756ad6d5346af2dc6a4df061b786eed"}, - {file = "skia_pathops-0.7.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:18fa97eab0e20daf89f57951f2218a8ac42493c7455eee37793e7771c414e28b"}, - {file = "skia_pathops-0.7.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:172ddfc3bc573d994bf8d4a6ea1eb35a97976e3959831e306e4eca211c92392b"}, - {file = "skia_pathops-0.7.2-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:ab02f93bbad07cf249498271c4be885b27aea0b747b769cbfc255e7cb10cc689"}, - {file = "skia_pathops-0.7.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:24c7cb009ba379a0f4683e66801d752f87f3dcf1c76f57863155aec557042ed3"}, - {file = "skia_pathops-0.7.2-cp38-cp38-win32.whl", hash = "sha256:91c760e780bf99eac3be974d84ec7f61317794ed6deae54a28d2c8d5f61089b6"}, - {file = "skia_pathops-0.7.2-cp38-cp38-win_amd64.whl", hash = "sha256:a0ea795750d0d41c26b158b1018d94a60f78008a77e75f2c56f39e24d5541d68"}, - {file = "skia_pathops-0.7.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:f1a14fcaa6902e7f9ba8944e90e532e020b8f9554bd7443daed3caf9d9919cb8"}, - {file = "skia_pathops-0.7.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:462abfc5529fd42b433bf5ce88bd1cb1e3d589269f67600472b79feb2be3c081"}, - {file = "skia_pathops-0.7.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b6f3328815e6bcced0947df374937d51c6a386f260259c1732ff71b1cdd72c3d"}, - {file = "skia_pathops-0.7.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1932a387b14c9661f4a578cfd74a71b01436adcc4ef3d0f526b85b7d3f28f2a3"}, - {file = "skia_pathops-0.7.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:c261583734215751b59e12290323a177770002618819ad670acdb5b98b60dff6"}, - {file = "skia_pathops-0.7.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:50fc18167cbb93b2c57c151289e2773b1db9347ba56d82e35f6fed1bd79a9268"}, - {file = "skia_pathops-0.7.2-cp39-cp39-win32.whl", hash = "sha256:34a8eaace3386880303a564945e292961cfb1cadd06f178b1f959a6a0b8d6c40"}, - {file = "skia_pathops-0.7.2-cp39-cp39-win_amd64.whl", hash = "sha256:1e89d3cc2be2748ba09a06abc5cfe86743c0ec4a16366e34122d9e74e1276204"}, - {file = "skia_pathops-0.7.2-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8bf945cd0df19160c2eb3241db5773c6ca45404dfc661a64a825b93dd9517068"}, - {file = "skia_pathops-0.7.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b9cd88c5bde4a0889ce090d2788eb8db0a6a3ed23c01a77c49cb847739b1257a"}, -] -smmap = [ - {file = "smmap-5.0.0-py3-none-any.whl", hash = "sha256:2aba19d6a040e78d8b09de5c57e96207b09ed71d8e55ce0959eeee6c8e190d94"}, - {file = "smmap-5.0.0.tar.gz", hash = "sha256:c840e62059cd3be204b0c9c9f74be2c09d5648eddd4580d9314c3ecde0b30936"}, -] -sniffio = [ - {file = "sniffio-1.2.0-py3-none-any.whl", hash = "sha256:471b71698eac1c2112a40ce2752bb2f4a4814c22a54a3eed3676bc0f5ca9f663"}, - {file = "sniffio-1.2.0.tar.gz", hash = "sha256:c4666eecec1d3f50960c6bdf61ab7bc350648da6c126e3cf6898d8cd4ddcd3de"}, -] -snowballstemmer = [ - {file = "snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a"}, - {file = "snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1"}, -] -soupsieve = [ - {file = "soupsieve-2.3.1-py3-none-any.whl", hash = "sha256:1a3cca2617c6b38c0343ed661b1fa5de5637f257d4fe22bd9f1338010a1efefb"}, - {file = "soupsieve-2.3.1.tar.gz", hash = "sha256:b8d49b1cd4f037c7082a9683dfa1801aa2597fb11c3a1155b7a5b94829b4f1f9"}, -] -sphinx = [ - {file = "Sphinx-4.4.0-py3-none-any.whl", hash = "sha256:5da895959511473857b6d0200f56865ed62c31e8f82dd338063b84ec022701fe"}, - {file = "Sphinx-4.4.0.tar.gz", hash = "sha256:6caad9786055cb1fa22b4a365c1775816b876f91966481765d7d50e9f0dd35cc"}, -] -sphinx-copybutton = [ - {file = "sphinx-copybutton-0.4.0.tar.gz", hash = "sha256:8daed13a87afd5013c3a9af3575cc4d5bec052075ccd3db243f895c07a689386"}, - {file = "sphinx_copybutton-0.4.0-py3-none-any.whl", hash = "sha256:4340d33c169dac6dd82dce2c83333412aa786a42dd01a81a8decac3b130dc8b0"}, -] -sphinxcontrib-applehelp = [ - {file = "sphinxcontrib-applehelp-1.0.2.tar.gz", hash = "sha256:a072735ec80e7675e3f432fcae8610ecf509c5f1869d17e2eecff44389cdbc58"}, - {file = "sphinxcontrib_applehelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:806111e5e962be97c29ec4c1e7fe277bfd19e9652fb1a4392105b43e01af885a"}, -] -sphinxcontrib-devhelp = [ - {file = "sphinxcontrib-devhelp-1.0.2.tar.gz", hash = "sha256:ff7f1afa7b9642e7060379360a67e9c41e8f3121f2ce9164266f61b9f4b338e4"}, - {file = "sphinxcontrib_devhelp-1.0.2-py2.py3-none-any.whl", hash = "sha256:8165223f9a335cc1af7ffe1ed31d2871f325254c0423bc0c4c7cd1c1e4734a2e"}, -] -sphinxcontrib-htmlhelp = [ - {file = "sphinxcontrib-htmlhelp-2.0.0.tar.gz", hash = "sha256:f5f8bb2d0d629f398bf47d0d69c07bc13b65f75a81ad9e2f71a63d4b7a2f6db2"}, - {file = "sphinxcontrib_htmlhelp-2.0.0-py2.py3-none-any.whl", hash = "sha256:d412243dfb797ae3ec2b59eca0e52dac12e75a241bf0e4eb861e450d06c6ed07"}, -] -sphinxcontrib-jsmath = [ - {file = "sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8"}, - {file = "sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178"}, -] -sphinxcontrib-programoutput = [ - {file = "sphinxcontrib-programoutput-0.17.tar.gz", hash = "sha256:300ee9b8caee8355d25cc74b4d1c7efd12e608d2ad165e3141d31e6fbc152b7f"}, - {file = "sphinxcontrib_programoutput-0.17-py2.py3-none-any.whl", hash = "sha256:0ef1c1d9159dbe7103077748214305eb4e0138e861feb71c0c346afc5fe97f84"}, -] -sphinxcontrib-qthelp = [ - {file = "sphinxcontrib-qthelp-1.0.3.tar.gz", hash = "sha256:4c33767ee058b70dba89a6fc5c1892c0d57a54be67ddd3e7875a18d14cba5a72"}, - {file = "sphinxcontrib_qthelp-1.0.3-py2.py3-none-any.whl", hash = "sha256:bd9fc24bcb748a8d51fd4ecaade681350aa63009a347a8c14e637895444dfab6"}, -] -sphinxcontrib-serializinghtml = [ - {file = "sphinxcontrib-serializinghtml-1.1.5.tar.gz", hash = "sha256:aa5f6de5dfdf809ef505c4895e51ef5c9eac17d0f287933eb49ec495280b6952"}, - {file = "sphinxcontrib_serializinghtml-1.1.5-py2.py3-none-any.whl", hash = "sha256:352a9a00ae864471d3a7ead8d7d79f5fc0b57e8b3f95e9867eb9eb28999b92fd"}, -] -sphinxext-opengraph = [ - {file = "sphinxext-opengraph-0.5.1.tar.gz", hash = "sha256:78675a8a490c749a881892abc4f28ac3a2e8e65b066fe346fa7da882290906a5"}, - {file = "sphinxext_opengraph-0.5.1-py3-none-any.whl", hash = "sha256:3fd0df576ae11e55c710653413edd7c05db65a4fbf985d536127c5ac06f5d2cb"}, -] -srt = [ - {file = "srt-3.5.1.tar.gz", hash = "sha256:3116f816cf025f71c1668970cdac2b235daa2fb46dc11fd41b8326d337eff6ee"}, -] -terminado = [ - {file = "terminado-0.13.1-py3-none-any.whl", hash = "sha256:f446b522b50a7aa68b5def0a02893978fb48cb82298b0ebdae13003c6ee6f198"}, - {file = "terminado-0.13.1.tar.gz", hash = "sha256:5b82b5c6e991f0705a76f961f43262a7fb1e55b093c16dca83f16384a7f39b7b"}, -] -testpath = [ - {file = "testpath-0.5.0-py3-none-any.whl", hash = "sha256:8044f9a0bab6567fc644a3593164e872543bb44225b0e24846e2c89237937589"}, - {file = "testpath-0.5.0.tar.gz", hash = "sha256:1acf7a0bcd3004ae8357409fc33751e16d37ccc650921da1094a86581ad1e417"}, -] -toml = [ - {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"}, - {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"}, -] -tomli = [ - {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, - {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, -] -tornado = [ - {file = "tornado-6.1-cp35-cp35m-macosx_10_9_x86_64.whl", hash = "sha256:d371e811d6b156d82aa5f9a4e08b58debf97c302a35714f6f45e35139c332e32"}, - {file = "tornado-6.1-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:0d321a39c36e5f2c4ff12b4ed58d41390460f798422c4504e09eb5678e09998c"}, - {file = "tornado-6.1-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:9de9e5188a782be6b1ce866e8a51bc76a0fbaa0e16613823fc38e4fc2556ad05"}, - {file = "tornado-6.1-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:61b32d06ae8a036a6607805e6720ef00a3c98207038444ba7fd3d169cd998910"}, - {file = "tornado-6.1-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:3e63498f680547ed24d2c71e6497f24bca791aca2fe116dbc2bd0ac7f191691b"}, - {file = "tornado-6.1-cp35-cp35m-manylinux2014_aarch64.whl", hash = "sha256:6c77c9937962577a6a76917845d06af6ab9197702a42e1346d8ae2e76b5e3675"}, - {file = "tornado-6.1-cp35-cp35m-win32.whl", hash = "sha256:6286efab1ed6e74b7028327365cf7346b1d777d63ab30e21a0f4d5b275fc17d5"}, - {file = "tornado-6.1-cp35-cp35m-win_amd64.whl", hash = "sha256:fa2ba70284fa42c2a5ecb35e322e68823288a4251f9ba9cc77be04ae15eada68"}, - {file = "tornado-6.1-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:0a00ff4561e2929a2c37ce706cb8233b7907e0cdc22eab98888aca5dd3775feb"}, - {file = "tornado-6.1-cp36-cp36m-manylinux1_i686.whl", hash = "sha256:748290bf9112b581c525e6e6d3820621ff020ed95af6f17fedef416b27ed564c"}, - {file = "tornado-6.1-cp36-cp36m-manylinux1_x86_64.whl", hash = "sha256:e385b637ac3acaae8022e7e47dfa7b83d3620e432e3ecb9a3f7f58f150e50921"}, - {file = "tornado-6.1-cp36-cp36m-manylinux2010_i686.whl", hash = "sha256:25ad220258349a12ae87ede08a7b04aca51237721f63b1808d39bdb4b2164558"}, - {file = "tornado-6.1-cp36-cp36m-manylinux2010_x86_64.whl", hash = "sha256:65d98939f1a2e74b58839f8c4dab3b6b3c1ce84972ae712be02845e65391ac7c"}, - {file = "tornado-6.1-cp36-cp36m-manylinux2014_aarch64.whl", hash = "sha256:e519d64089b0876c7b467274468709dadf11e41d65f63bba207e04217f47c085"}, - {file = "tornado-6.1-cp36-cp36m-win32.whl", hash = "sha256:b87936fd2c317b6ee08a5741ea06b9d11a6074ef4cc42e031bc6403f82a32575"}, - {file = "tornado-6.1-cp36-cp36m-win_amd64.whl", hash = "sha256:cc0ee35043162abbf717b7df924597ade8e5395e7b66d18270116f8745ceb795"}, - {file = "tornado-6.1-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7250a3fa399f08ec9cb3f7b1b987955d17e044f1ade821b32e5f435130250d7f"}, - {file = "tornado-6.1-cp37-cp37m-manylinux1_i686.whl", hash = "sha256:ed3ad863b1b40cd1d4bd21e7498329ccaece75db5a5bf58cd3c9f130843e7102"}, - {file = "tornado-6.1-cp37-cp37m-manylinux1_x86_64.whl", hash = "sha256:dcef026f608f678c118779cd6591c8af6e9b4155c44e0d1bc0c87c036fb8c8c4"}, - {file = "tornado-6.1-cp37-cp37m-manylinux2010_i686.whl", hash = "sha256:70dec29e8ac485dbf57481baee40781c63e381bebea080991893cd297742b8fd"}, - {file = "tornado-6.1-cp37-cp37m-manylinux2010_x86_64.whl", hash = "sha256:d3f7594930c423fd9f5d1a76bee85a2c36fd8b4b16921cae7e965f22575e9c01"}, - {file = "tornado-6.1-cp37-cp37m-manylinux2014_aarch64.whl", hash = "sha256:3447475585bae2e77ecb832fc0300c3695516a47d46cefa0528181a34c5b9d3d"}, - {file = "tornado-6.1-cp37-cp37m-win32.whl", hash = "sha256:e7229e60ac41a1202444497ddde70a48d33909e484f96eb0da9baf8dc68541df"}, - {file = "tornado-6.1-cp37-cp37m-win_amd64.whl", hash = "sha256:cb5ec8eead331e3bb4ce8066cf06d2dfef1bfb1b2a73082dfe8a161301b76e37"}, - {file = "tornado-6.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:20241b3cb4f425e971cb0a8e4ffc9b0a861530ae3c52f2b0434e6c1b57e9fd95"}, - {file = "tornado-6.1-cp38-cp38-manylinux1_i686.whl", hash = "sha256:c77da1263aa361938476f04c4b6c8916001b90b2c2fdd92d8d535e1af48fba5a"}, - {file = "tornado-6.1-cp38-cp38-manylinux1_x86_64.whl", hash = "sha256:fba85b6cd9c39be262fcd23865652920832b61583de2a2ca907dbd8e8a8c81e5"}, - {file = "tornado-6.1-cp38-cp38-manylinux2010_i686.whl", hash = "sha256:1e8225a1070cd8eec59a996c43229fe8f95689cb16e552d130b9793cb570a288"}, - {file = "tornado-6.1-cp38-cp38-manylinux2010_x86_64.whl", hash = "sha256:d14d30e7f46a0476efb0deb5b61343b1526f73ebb5ed84f23dc794bdb88f9d9f"}, - {file = "tornado-6.1-cp38-cp38-manylinux2014_aarch64.whl", hash = "sha256:8f959b26f2634a091bb42241c3ed8d3cedb506e7c27b8dd5c7b9f745318ddbb6"}, - {file = "tornado-6.1-cp38-cp38-win32.whl", hash = "sha256:34ca2dac9e4d7afb0bed4677512e36a52f09caa6fded70b4e3e1c89dbd92c326"}, - {file = "tornado-6.1-cp38-cp38-win_amd64.whl", hash = "sha256:6196a5c39286cc37c024cd78834fb9345e464525d8991c21e908cc046d1cc02c"}, - {file = "tornado-6.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:f0ba29bafd8e7e22920567ce0d232c26d4d47c8b5cf4ed7b562b5db39fa199c5"}, - {file = "tornado-6.1-cp39-cp39-manylinux1_i686.whl", hash = "sha256:33892118b165401f291070100d6d09359ca74addda679b60390b09f8ef325ffe"}, - {file = "tornado-6.1-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:7da13da6f985aab7f6f28debab00c67ff9cbacd588e8477034c0652ac141feea"}, - {file = "tornado-6.1-cp39-cp39-manylinux2010_i686.whl", hash = "sha256:e0791ac58d91ac58f694d8d2957884df8e4e2f6687cdf367ef7eb7497f79eaa2"}, - {file = "tornado-6.1-cp39-cp39-manylinux2010_x86_64.whl", hash = "sha256:66324e4e1beede9ac79e60f88de548da58b1f8ab4b2f1354d8375774f997e6c0"}, - {file = "tornado-6.1-cp39-cp39-manylinux2014_aarch64.whl", hash = "sha256:a48900ecea1cbb71b8c71c620dee15b62f85f7c14189bdeee54966fbd9a0c5bd"}, - {file = "tornado-6.1-cp39-cp39-win32.whl", hash = "sha256:d3d20ea5782ba63ed13bc2b8c291a053c8d807a8fa927d941bd718468f7b950c"}, - {file = "tornado-6.1-cp39-cp39-win_amd64.whl", hash = "sha256:548430be2740e327b3fe0201abe471f314741efcb0067ec4f2d7dcfb4825f3e4"}, - {file = "tornado-6.1.tar.gz", hash = "sha256:33c6e81d7bd55b468d2e793517c909b139960b6c790a60b7991b9b6b76fb9791"}, -] -tqdm = [ - {file = "tqdm-4.62.3-py2.py3-none-any.whl", hash = "sha256:8dd278a422499cd6b727e6ae4061c40b48fce8b76d1ccbf5d34fca9b7f925b0c"}, - {file = "tqdm-4.62.3.tar.gz", hash = "sha256:d359de7217506c9851b7869f3708d8ee53ed70a1b8edbba4dbcb47442592920d"}, -] -traitlets = [ - {file = "traitlets-5.1.1-py3-none-any.whl", hash = "sha256:2d313cc50a42cd6c277e7d7dc8d4d7fedd06a2c215f78766ae7b1a66277e0033"}, - {file = "traitlets-5.1.1.tar.gz", hash = "sha256:059f456c5a7c1c82b98c2e8c799f39c9b8128f6d0d46941ee118daace9eb70c7"}, -] -typed-ast = [ - {file = "typed_ast-1.5.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:183b183b7771a508395d2cbffd6db67d6ad52958a5fdc99f450d954003900266"}, - {file = "typed_ast-1.5.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:676d051b1da67a852c0447621fdd11c4e104827417bf216092ec3e286f7da596"}, - {file = "typed_ast-1.5.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bc2542e83ac8399752bc16e0b35e038bdb659ba237f4222616b4e83fb9654985"}, - {file = "typed_ast-1.5.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:74cac86cc586db8dfda0ce65d8bcd2bf17b58668dfcc3652762f3ef0e6677e76"}, - {file = "typed_ast-1.5.2-cp310-cp310-win_amd64.whl", hash = "sha256:18fe320f354d6f9ad3147859b6e16649a0781425268c4dde596093177660e71a"}, - {file = "typed_ast-1.5.2-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:31d8c6b2df19a777bc8826770b872a45a1f30cfefcfd729491baa5237faae837"}, - {file = "typed_ast-1.5.2-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:963a0ccc9a4188524e6e6d39b12c9ca24cc2d45a71cfdd04a26d883c922b4b78"}, - {file = "typed_ast-1.5.2-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0eb77764ea470f14fcbb89d51bc6bbf5e7623446ac4ed06cbd9ca9495b62e36e"}, - {file = "typed_ast-1.5.2-cp36-cp36m-win_amd64.whl", hash = "sha256:294a6903a4d087db805a7656989f613371915fc45c8cc0ddc5c5a0a8ad9bea4d"}, - {file = "typed_ast-1.5.2-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:26a432dc219c6b6f38be20a958cbe1abffcc5492821d7e27f08606ef99e0dffd"}, - {file = "typed_ast-1.5.2-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7407cfcad702f0b6c0e0f3e7ab876cd1d2c13b14ce770e412c0c4b9728a0f88"}, - {file = "typed_ast-1.5.2-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f30ddd110634c2d7534b2d4e0e22967e88366b0d356b24de87419cc4410c41b7"}, - {file = "typed_ast-1.5.2-cp37-cp37m-win_amd64.whl", hash = "sha256:8c08d6625bb258179b6e512f55ad20f9dfef019bbfbe3095247401e053a3ea30"}, - {file = "typed_ast-1.5.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:90904d889ab8e81a956f2c0935a523cc4e077c7847a836abee832f868d5c26a4"}, - {file = "typed_ast-1.5.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:bbebc31bf11762b63bf61aaae232becb41c5bf6b3461b80a4df7e791fabb3aca"}, - {file = "typed_ast-1.5.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c29dd9a3a9d259c9fa19d19738d021632d673f6ed9b35a739f48e5f807f264fb"}, - {file = "typed_ast-1.5.2-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:58ae097a325e9bb7a684572d20eb3e1809802c5c9ec7108e85da1eb6c1a3331b"}, - {file = "typed_ast-1.5.2-cp38-cp38-win_amd64.whl", hash = "sha256:da0a98d458010bf4fe535f2d1e367a2e2060e105978873c04c04212fb20543f7"}, - {file = "typed_ast-1.5.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:33b4a19ddc9fc551ebabca9765d54d04600c4a50eda13893dadf67ed81d9a098"}, - {file = "typed_ast-1.5.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1098df9a0592dd4c8c0ccfc2e98931278a6c6c53cb3a3e2cf7e9ee3b06153344"}, - {file = "typed_ast-1.5.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42c47c3b43fe3a39ddf8de1d40dbbfca60ac8530a36c9b198ea5b9efac75c09e"}, - {file = "typed_ast-1.5.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:f290617f74a610849bd8f5514e34ae3d09eafd521dceaa6cf68b3f4414266d4e"}, - {file = "typed_ast-1.5.2-cp39-cp39-win_amd64.whl", hash = "sha256:df05aa5b241e2e8045f5f4367a9f6187b09c4cdf8578bb219861c4e27c443db5"}, - {file = "typed_ast-1.5.2.tar.gz", hash = "sha256:525a2d4088e70a9f75b08b3f87a51acc9cde640e19cc523c7e41aa355564ae27"}, -] -types-decorator = [ - {file = "types-decorator-0.1.7.tar.gz", hash = "sha256:1772c7a83d2846a09c90ae0549058baffb10d0dd01f9494e2032567d3b62ac5e"}, - {file = "types_decorator-0.1.7-py3-none-any.whl", hash = "sha256:b55f4c8c59bdd25bd1ecf835f0bc21d88b99be0f5bb51b1c0d73090be90f62db"}, -] -types-docutils = [ - {file = "types-docutils-0.17.5.tar.gz", hash = "sha256:4662e087f12ed30a63c7a104dcc458b73b76e6e764c5021267d196d78efaebdb"}, - {file = "types_docutils-0.17.5-py3-none-any.whl", hash = "sha256:9e60d7ef64a8eac972342c9071fbf0e3836484ac10f3d7ff3a8eeb4d2297a5dc"}, -] -types-pillow = [ - {file = "types-Pillow-8.3.11.tar.gz", hash = "sha256:aa96a739184f48f69e6f30218400623fc5a95f5fec199c447663a32538440405"}, - {file = "types_Pillow-8.3.11-py3-none-any.whl", hash = "sha256:998189334e616b1dd42c9634669efbf726184039e96e9a23ec95246e0ecff3fc"}, -] -types-protobuf = [ - {file = "types-protobuf-3.19.12.tar.gz", hash = "sha256:b022247347471219acbe2fe68d2f3623d788252e99e9b97358b7ab904d268a78"}, - {file = "types_protobuf-3.19.12-py3-none-any.whl", hash = "sha256:130bf00e688ae9376682ac8f3d6610be797d8a6072f102f530ca1d579b52e54b"}, -] -types-pygments = [ - {file = "types-Pygments-2.9.16.tar.gz", hash = "sha256:8a9a257b3cddbd4307da361bd1b493247906abc15aa9266b1e61aa11a0520547"}, - {file = "types_Pygments-2.9.16-py3-none-any.whl", hash = "sha256:4160656d4e6e683b3bf9b0176ba458c6327cfa7d99bd75430335eaf143906353"}, -] -types-requests = [ - {file = "types-requests-2.27.9.tar.gz", hash = "sha256:7368974534d297939492efdfdab232930440b11e2203f6df1f0c40e3242a87ea"}, - {file = "types_requests-2.27.9-py3-none-any.whl", hash = "sha256:74070045418faf710f3154403d6a16c9e67db50e5119906ca6955f1658d20f7b"}, -] -types-setuptools = [ - {file = "types-setuptools-57.4.9.tar.gz", hash = "sha256:536ef74744f8e1e4be4fc719887f886e74e4cf3c792b4a06984320be4df450b5"}, - {file = "types_setuptools-57.4.9-py3-none-any.whl", hash = "sha256:948dc6863373750e2cd0b223a84f1fb608414cde5e55cf38ea657b93aeb411d2"}, -] -types-urllib3 = [ - {file = "types-urllib3-1.26.9.tar.gz", hash = "sha256:abd2d4857837482b1834b4817f0587678dcc531dbc9abe4cde4da28cef3f522c"}, - {file = "types_urllib3-1.26.9-py3-none-any.whl", hash = "sha256:4a54f6274ab1c80968115634a55fb9341a699492b95e32104a7c513db9fe02e9"}, -] -typing-extensions = [ - {file = "typing_extensions-4.1.1-py3-none-any.whl", hash = "sha256:21c85e0fe4b9a155d0799430b0ad741cdce7e359660ccbd8b530613e8df88ce2"}, - {file = "typing_extensions-4.1.1.tar.gz", hash = "sha256:1a9462dcc3347a79b1f1c0271fbe79e844580bb598bafa1ed208b94da3cdcd42"}, -] -urllib3 = [ - {file = "urllib3-1.26.8-py2.py3-none-any.whl", hash = "sha256:000ca7f471a233c2251c6c7023ee85305721bfdf18621ebff4fd17a8653427ed"}, - {file = "urllib3-1.26.8.tar.gz", hash = "sha256:0e7c33d9a63e7ddfcb86780aac87befc2fbddf46c58dbb487e0855f7ceec283c"}, -] -virtualenv = [ - {file = "virtualenv-20.13.1-py2.py3-none-any.whl", hash = "sha256:45e1d053cad4cd453181ae877c4ffc053546ae99e7dd049b9ff1d9be7491abf7"}, - {file = "virtualenv-20.13.1.tar.gz", hash = "sha256:e0621bcbf4160e4e1030f05065c8834b4e93f4fcc223255db2a823440aca9c14"}, -] -watchdog = [ - {file = "watchdog-2.1.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:9693f35162dc6208d10b10ddf0458cc09ad70c30ba689d9206e02cd836ce28a3"}, - {file = "watchdog-2.1.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:aba5c812f8ee8a3ff3be51887ca2d55fb8e268439ed44110d3846e4229eb0e8b"}, - {file = "watchdog-2.1.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:4ae38bf8ba6f39d5b83f78661273216e7db5b00f08be7592062cb1fc8b8ba542"}, - {file = "watchdog-2.1.6-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:ad6f1796e37db2223d2a3f302f586f74c72c630b48a9872c1e7ae8e92e0ab669"}, - {file = "watchdog-2.1.6-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:922a69fa533cb0c793b483becaaa0845f655151e7256ec73630a1b2e9ebcb660"}, - {file = "watchdog-2.1.6-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:b2fcf9402fde2672545b139694284dc3b665fd1be660d73eca6805197ef776a3"}, - {file = "watchdog-2.1.6-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:3386b367e950a11b0568062b70cc026c6f645428a698d33d39e013aaeda4cc04"}, - {file = "watchdog-2.1.6-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:8f1c00aa35f504197561060ca4c21d3cc079ba29cf6dd2fe61024c70160c990b"}, - {file = "watchdog-2.1.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b52b88021b9541a60531142b0a451baca08d28b74a723d0c99b13c8c8d48d604"}, - {file = "watchdog-2.1.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:8047da932432aa32c515ec1447ea79ce578d0559362ca3605f8e9568f844e3c6"}, - {file = "watchdog-2.1.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e92c2d33858c8f560671b448205a268096e17870dcf60a9bb3ac7bfbafb7f5f9"}, - {file = "watchdog-2.1.6-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:b7d336912853d7b77f9b2c24eeed6a5065d0a0cc0d3b6a5a45ad6d1d05fb8cd8"}, - {file = "watchdog-2.1.6-py3-none-manylinux2014_aarch64.whl", hash = "sha256:cca7741c0fcc765568350cb139e92b7f9f3c9a08c4f32591d18ab0a6ac9e71b6"}, - {file = "watchdog-2.1.6-py3-none-manylinux2014_armv7l.whl", hash = "sha256:25fb5240b195d17de949588628fdf93032ebf163524ef08933db0ea1f99bd685"}, - {file = "watchdog-2.1.6-py3-none-manylinux2014_i686.whl", hash = "sha256:be9be735f827820a06340dff2ddea1fb7234561fa5e6300a62fe7f54d40546a0"}, - {file = "watchdog-2.1.6-py3-none-manylinux2014_ppc64.whl", hash = "sha256:d0d19fb2441947b58fbf91336638c2b9f4cc98e05e1045404d7a4cb7cddc7a65"}, - {file = "watchdog-2.1.6-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:3becdb380d8916c873ad512f1701f8a92ce79ec6978ffde92919fd18d41da7fb"}, - {file = "watchdog-2.1.6-py3-none-manylinux2014_s390x.whl", hash = "sha256:ae67501c95606072aafa865b6ed47343ac6484472a2f95490ba151f6347acfc2"}, - {file = "watchdog-2.1.6-py3-none-manylinux2014_x86_64.whl", hash = "sha256:e0f30db709c939cabf64a6dc5babb276e6d823fd84464ab916f9b9ba5623ca15"}, - {file = "watchdog-2.1.6-py3-none-win32.whl", hash = "sha256:e02794ac791662a5eafc6ffeaf9bcc149035a0e48eb0a9d40a8feb4622605a3d"}, - {file = "watchdog-2.1.6-py3-none-win_amd64.whl", hash = "sha256:bd9ba4f332cf57b2c1f698be0728c020399ef3040577cde2939f2e045b39c1e5"}, - {file = "watchdog-2.1.6-py3-none-win_ia64.whl", hash = "sha256:a0f1c7edf116a12f7245be06120b1852275f9506a7d90227648b250755a03923"}, - {file = "watchdog-2.1.6.tar.gz", hash = "sha256:a36e75df6c767cbf46f61a91c70b3ba71811dfa0aca4a324d9407a06a8b7a2e7"}, -] -wcwidth = [ - {file = "wcwidth-0.2.5-py2.py3-none-any.whl", hash = "sha256:beb4802a9cebb9144e99086eff703a642a13d6a0052920003a230f3294bbe784"}, - {file = "wcwidth-0.2.5.tar.gz", hash = "sha256:c4d647b99872929fdb7bdcaa4fbe7f01413ed3d98077df798530e5b04f116c83"}, -] -webencodings = [ - {file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"}, - {file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"}, -] -websocket-client = [ - {file = "websocket-client-1.2.3.tar.gz", hash = "sha256:1315816c0acc508997eb3ae03b9d3ff619c9d12d544c9a9b553704b1cc4f6af5"}, - {file = "websocket_client-1.2.3-py3-none-any.whl", hash = "sha256:2eed4cc58e4d65613ed6114af2f380f7910ff416fc8c46947f6e76b6815f56c0"}, -] -wrapt = [ - {file = "wrapt-1.13.3-cp27-cp27m-macosx_10_9_x86_64.whl", hash = "sha256:e05e60ff3b2b0342153be4d1b597bbcfd8330890056b9619f4ad6b8d5c96a81a"}, - {file = "wrapt-1.13.3-cp27-cp27m-manylinux1_i686.whl", hash = "sha256:85148f4225287b6a0665eef08a178c15097366d46b210574a658c1ff5b377489"}, - {file = "wrapt-1.13.3-cp27-cp27m-manylinux1_x86_64.whl", hash = "sha256:2dded5496e8f1592ec27079b28b6ad2a1ef0b9296d270f77b8e4a3a796cf6909"}, - {file = "wrapt-1.13.3-cp27-cp27m-manylinux2010_i686.whl", hash = "sha256:e94b7d9deaa4cc7bac9198a58a7240aaf87fe56c6277ee25fa5b3aa1edebd229"}, - {file = "wrapt-1.13.3-cp27-cp27m-manylinux2010_x86_64.whl", hash = "sha256:498e6217523111d07cd67e87a791f5e9ee769f9241fcf8a379696e25806965af"}, - {file = "wrapt-1.13.3-cp27-cp27mu-manylinux1_i686.whl", hash = "sha256:ec7e20258ecc5174029a0f391e1b948bf2906cd64c198a9b8b281b811cbc04de"}, - {file = "wrapt-1.13.3-cp27-cp27mu-manylinux1_x86_64.whl", hash = "sha256:87883690cae293541e08ba2da22cacaae0a092e0ed56bbba8d018cc486fbafbb"}, - {file = "wrapt-1.13.3-cp27-cp27mu-manylinux2010_i686.whl", hash = "sha256:f99c0489258086308aad4ae57da9e8ecf9e1f3f30fa35d5e170b4d4896554d80"}, - {file = "wrapt-1.13.3-cp27-cp27mu-manylinux2010_x86_64.whl", hash = "sha256:6a03d9917aee887690aa3f1747ce634e610f6db6f6b332b35c2dd89412912bca"}, - {file = "wrapt-1.13.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:936503cb0a6ed28dbfa87e8fcd0a56458822144e9d11a49ccee6d9a8adb2ac44"}, - {file = "wrapt-1.13.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:f9c51d9af9abb899bd34ace878fbec8bf357b3194a10c4e8e0a25512826ef056"}, - {file = "wrapt-1.13.3-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:220a869982ea9023e163ba915077816ca439489de6d2c09089b219f4e11b6785"}, - {file = "wrapt-1.13.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:0877fe981fd76b183711d767500e6b3111378ed2043c145e21816ee589d91096"}, - {file = "wrapt-1.13.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:43e69ffe47e3609a6aec0fe723001c60c65305784d964f5007d5b4fb1bc6bf33"}, - {file = "wrapt-1.13.3-cp310-cp310-win32.whl", hash = "sha256:78dea98c81915bbf510eb6a3c9c24915e4660302937b9ae05a0947164248020f"}, - {file = "wrapt-1.13.3-cp310-cp310-win_amd64.whl", hash = "sha256:ea3e746e29d4000cd98d572f3ee2a6050a4f784bb536f4ac1f035987fc1ed83e"}, - {file = "wrapt-1.13.3-cp35-cp35m-manylinux1_i686.whl", hash = "sha256:8c73c1a2ec7c98d7eaded149f6d225a692caa1bd7b2401a14125446e9e90410d"}, - {file = "wrapt-1.13.3-cp35-cp35m-manylinux1_x86_64.whl", hash = "sha256:086218a72ec7d986a3eddb7707c8c4526d677c7b35e355875a0fe2918b059179"}, - {file = "wrapt-1.13.3-cp35-cp35m-manylinux2010_i686.whl", hash = "sha256:e92d0d4fa68ea0c02d39f1e2f9cb5bc4b4a71e8c442207433d8db47ee79d7aa3"}, - {file = "wrapt-1.13.3-cp35-cp35m-manylinux2010_x86_64.whl", hash = "sha256:d4a5f6146cfa5c7ba0134249665acd322a70d1ea61732723c7d3e8cc0fa80755"}, - {file = "wrapt-1.13.3-cp35-cp35m-win32.whl", hash = "sha256:8aab36778fa9bba1a8f06a4919556f9f8c7b33102bd71b3ab307bb3fecb21851"}, - {file = "wrapt-1.13.3-cp35-cp35m-win_amd64.whl", hash = "sha256:944b180f61f5e36c0634d3202ba8509b986b5fbaf57db3e94df11abee244ba13"}, - {file = "wrapt-1.13.3-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:2ebdde19cd3c8cdf8df3fc165bc7827334bc4e353465048b36f7deeae8ee0918"}, - {file = "wrapt-1.13.3-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:610f5f83dd1e0ad40254c306f4764fcdc846641f120c3cf424ff57a19d5f7ade"}, - {file = "wrapt-1.13.3-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5601f44a0f38fed36cc07db004f0eedeaadbdcec90e4e90509480e7e6060a5bc"}, - {file = "wrapt-1.13.3-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:e6906d6f48437dfd80464f7d7af1740eadc572b9f7a4301e7dd3d65db285cacf"}, - {file = "wrapt-1.13.3-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:766b32c762e07e26f50d8a3468e3b4228b3736c805018e4b0ec8cc01ecd88125"}, - {file = "wrapt-1.13.3-cp36-cp36m-win32.whl", hash = "sha256:5f223101f21cfd41deec8ce3889dc59f88a59b409db028c469c9b20cfeefbe36"}, - {file = "wrapt-1.13.3-cp36-cp36m-win_amd64.whl", hash = "sha256:f122ccd12fdc69628786d0c947bdd9cb2733be8f800d88b5a37c57f1f1d73c10"}, - {file = "wrapt-1.13.3-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:46f7f3af321a573fc0c3586612db4decb7eb37172af1bc6173d81f5b66c2e068"}, - {file = "wrapt-1.13.3-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:778fd096ee96890c10ce96187c76b3e99b2da44e08c9e24d5652f356873f6709"}, - {file = "wrapt-1.13.3-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:0cb23d36ed03bf46b894cfec777eec754146d68429c30431c99ef28482b5c1df"}, - {file = "wrapt-1.13.3-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:96b81ae75591a795d8c90edc0bfaab44d3d41ffc1aae4d994c5aa21d9b8e19a2"}, - {file = "wrapt-1.13.3-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7dd215e4e8514004c8d810a73e342c536547038fb130205ec4bba9f5de35d45b"}, - {file = "wrapt-1.13.3-cp37-cp37m-win32.whl", hash = "sha256:47f0a183743e7f71f29e4e21574ad3fa95676136f45b91afcf83f6a050914829"}, - {file = "wrapt-1.13.3-cp37-cp37m-win_amd64.whl", hash = "sha256:fd76c47f20984b43d93de9a82011bb6e5f8325df6c9ed4d8310029a55fa361ea"}, - {file = "wrapt-1.13.3-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b73d4b78807bd299b38e4598b8e7bd34ed55d480160d2e7fdaabd9931afa65f9"}, - {file = "wrapt-1.13.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:ec9465dd69d5657b5d2fa6133b3e1e989ae27d29471a672416fd729b429eb554"}, - {file = "wrapt-1.13.3-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dd91006848eb55af2159375134d724032a2d1d13bcc6f81cd8d3ed9f2b8e846c"}, - {file = "wrapt-1.13.3-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:ae9de71eb60940e58207f8e71fe113c639da42adb02fb2bcbcaccc1ccecd092b"}, - {file = "wrapt-1.13.3-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:51799ca950cfee9396a87f4a1240622ac38973b6df5ef7a41e7f0b98797099ce"}, - {file = "wrapt-1.13.3-cp38-cp38-win32.whl", hash = "sha256:4b9c458732450ec42578b5642ac53e312092acf8c0bfce140ada5ca1ac556f79"}, - {file = "wrapt-1.13.3-cp38-cp38-win_amd64.whl", hash = "sha256:7dde79d007cd6dfa65afe404766057c2409316135cb892be4b1c768e3f3a11cb"}, - {file = "wrapt-1.13.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:981da26722bebb9247a0601e2922cedf8bb7a600e89c852d063313102de6f2cb"}, - {file = "wrapt-1.13.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:705e2af1f7be4707e49ced9153f8d72131090e52be9278b5dbb1498c749a1e32"}, - {file = "wrapt-1.13.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:25b1b1d5df495d82be1c9d2fad408f7ce5ca8a38085e2da41bb63c914baadff7"}, - {file = "wrapt-1.13.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:77416e6b17926d953b5c666a3cb718d5945df63ecf922af0ee576206d7033b5e"}, - {file = "wrapt-1.13.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:865c0b50003616f05858b22174c40ffc27a38e67359fa1495605f96125f76640"}, - {file = "wrapt-1.13.3-cp39-cp39-win32.whl", hash = "sha256:0a017a667d1f7411816e4bf214646d0ad5b1da2c1ea13dec6c162736ff25a374"}, - {file = "wrapt-1.13.3-cp39-cp39-win_amd64.whl", hash = "sha256:81bd7c90d28a4b2e1df135bfbd7c23aee3050078ca6441bead44c42483f9ebfb"}, - {file = "wrapt-1.13.3.tar.gz", hash = "sha256:1fea9cd438686e6682271d36f3481a9f3636195578bab9ca3382e2f5f01fc185"}, -] -zipp = [ - {file = "zipp-3.7.0-py3-none-any.whl", hash = "sha256:b47250dd24f92b7dd6a0a8fc5244da14608f3ca90a5efcd37a3b1642fac9a375"}, - {file = "zipp-3.7.0.tar.gz", hash = "sha256:9f50f446828eb9d45b267433fd3e9da8d801f614129124863f9c51ebceafb87d"}, -] diff --git a/pyproject.toml b/pyproject.toml index 84e8d1655f..12ff99a683 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,128 +1,128 @@ -[tool.poetry] +[project] name = "manim" -version = "0.15.1" +version = "0.19.0" description = "Animation engine for explanatory math videos." -authors = ["The Manim Community Developers ", "3b1b "] -license="MIT" -readme="README.md" -repository="https://github.com/manimcommunity/manim" -documentation="https://docs.manim.community/" -homepage="https://www.manim.community/" -classifiers= [ +authors = [ + {name = "The Manim Community Developers", email = "contact@manim.community"}, + {name = "Grant '3Blue1Brown' Sanderson", email = "grant@3blue1brown.com"}, +] +license = "MIT" +readme = "README.md" +classifiers = [ "Development Status :: 4 - Beta", "License :: OSI Approved :: MIT License", "Topic :: Scientific/Engineering", "Topic :: Multimedia :: Video", "Topic :: Multimedia :: Graphics", - "Programming Language :: Python :: 3.7", - "Programming Language :: Python :: 3.8", "Programming Language :: Python :: 3.9", "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", + "Programming Language :: Python :: 3.13", "Natural Language :: English", ] -exclude = ["scripts/","logo/","readme-assets/"] -packages = [ - { include = "manim" }, +requires-python = ">=3.9" +dependencies = [ + "audioop-lts>=0.2.1 ; python_full_version >= '3.13'", + "av>=9.0.0,<14.0.0", + "beautifulsoup4>=4.12", + "click>=8.0", + "cloup>=2.0.0", + "decorator>=4.3.2", + "importlib-metadata>=8.6.1 ; python_full_version < '3.10'", + "isosurfaces>=0.1.0", + "manimpango>=0.5.0,<1.0.0", + "mapbox-earcut>=1.0.0", + "moderngl-window>=2.0.0", + "moderngl>=5.0.0,<6.0.0", + "networkx>=2.6", + "numpy>=2.0", + "numpy>=2.1 ; python_full_version >= '3.10'", + "pillow>=9.1", + "pycairo>=1.13,<2.0.0", + "pydub>=0.20.0", + "pygments>=2.0.0", + "rich>=12.0.0", + "scipy>=1.13.0", + "scipy>=1.14.0 ; python_full_version >= '3.13'", + "screeninfo>=0.7", + "skia-pathops>=0.7.0", + "srt>=3.0.0", + "svgelements>=1.8.0", + "tqdm>=4.0.0", + "typing-extensions>=4.12.0", + "watchdog>=2.0.0", ] -[tool.poetry.dependencies] -python = ">=3.7,<3.11" -click = ">=7.1<=9.0" -click-default-group = "^1.2.2" -colour = "^0.1.5" -numpy = "^1.9" -Pillow = ">=8.4,<10.0" -scipy = "^1.7.3" -tqdm = "^4.62.3" -pydub = "^0.25.1" -rich = ">=6.0" -pycairo = "^1.19" -manimpango = "^0.4.0.post0" -networkx = "^2.5" -decorator = "^5.0.7" -importlib-metadata = { version = "^4.10.0", python = "<3.8" } -grpcio = { version = "^1.43.0", optional = true } -grpcio-tools = { version = "^1.43.0", optional = true } -watchdog = "^2.1.6" -jupyterlab = { version = "^3.0", optional = true } -moderngl = "^5.6.3" -moderngl-window = "^2.3.0" -mapbox-earcut = "^0.12.10" -cloup = "^0.7.0" -requests = "^2.26.0" -dearpygui = { version = "^1.3.1", optional = true } -skia-pathops = "^0.7.0" -isosurfaces = "0.1.0" -srt = "^3.5.0" -screeninfo = "^0.8" -Pygments = "^2.10.0" -"backports.cached-property" = "^1.0.1" - -[tool.poetry.extras] -webgl_renderer = ["grpcio","grpcio-tools"] -jupyterlab = ["jupyterlab"] -gui = ["dearpygui"] - -[tool.poetry.dev-dependencies] -pytest-cov = "^3.0.0" -pytest = "^6.0" -pylint = "^2.12.2" -Sphinx = "^4" -sphinx-copybutton = "^0.4.0" -sphinxext-opengraph = "^0.5.1" -furo = "^2021.11.23" -recommonmark = "^0.7.1" -matplotlib = "^3.3.2" -pre-commit = "^2.11.1" -gitpython = "^3" -pygithub = "^1" -flake8 = "^3.9.0" -isort = "^5.8.0" -pytest-xdist = "^2.2" -mypy = "^0.931" -types-requests = "^2.25.6" -types-protobuf = "^3.17.4" -types-decorator = "^0.1.7" -types-setuptools = "^57.0.2" -types-Pillow = "^8.3.3" -types-Pygments = "^2.9.2" -flake8-builtins = "^1.5.3" -flake8-bugbear = "^21.4.3" -flake8-docstrings = "^1.6.0" -flake8-rst-docstrings = "^0.2.3" -flake8-pytest-style = "^1.5.0" -flake8-simplify = "^0.14.1" -flake8-comprehensions = "^3.7.0" -sphinxcontrib-programoutput = "^0.17" -data-science-types = "^0.2.23" -psutil-wheels = {version = "5.8.0", python = ">=3.10"} -psutil = {version = "^5.8.0", python = "<3.10"} - - -[tool.poetry.urls] + +[project.scripts] +"manim" = "manim.__main__:main" +"manimce" = "manim.__main__:main" + +[project.urls] +repository = "https://github.com/manimcommunity/manim" +documentation = "https://docs.manim.community/" +homepage = "https://www.manim.community/" "Bug Tracker" = "https://github.com/ManimCommunity/manim/issues" "Changelog" = "https://docs.manim.community/en/stable/changelog.html" -"Twitter" = "https://twitter.com/manim_community" +"X / Twitter" = "https://x.com/manim_community" +"Bluesky" = "https://bsky.app/profile/manim.community" "Discord" = "https://www.manim.community/discord/" -[tool.poetry.dev-dependencies.black] -version = ">=20.8b1" -allow-prereleases = false -python = "^3.6" -markers = "platform_python_implementation == 'CPython'" +[project.optional-dependencies] +gui = [ + "dearpygui>=1.0.0", +] +jupyterlab = [ + "jupyterlab>=4.3.4", + "notebook>=7.3.2", +] + +[dependency-groups] +dev = [ + "furo>=2024.8.6", + "gitpython>=3.1.44", + "matplotlib>=3.9.4", + "myst-parser>=3.0.1", + "pre-commit>=4.1.0", + "pygithub>=2.5.0", + "pytest>=8.3.4", + "pytest-cov>=6.0.0", + "pytest-xdist>=2.2,<3.0", + "ruff>=0.9.3", + "sphinx>=7.4.7", + "sphinx-copybutton>=0.5.2", + "sphinx-design>=0.6.1", + "sphinx-reredirects>=0.1.5", + "sphinxcontrib-programoutput>=0.18", + "sphinxext-opengraph>=0.9.1", + "types-decorator>=5.1.8.20250121", + "types-pillow>=10.2.0.20240822", + "types-pygments>=2.19.0.20250107", + "psutil>=6.1.1", + "requests>=2.32.3", +] + +[build-system] +requires = ["hatchling"] +build-backend = "hatchling.build" + +[tool.hatch.build] +include = [ + "/manim" +] +exclude = [ + "/docker", + "/logo", + "/scripts", +] [tool.pytest.ini_options] markers = "slow: Mark the test as slow. Can be skipped with --skip_slow" -addopts = "--no-cov-on-fail --cov=manim --cov-report xml --cov-report term -n auto --dist=loadfile" +addopts = "--no-cov-on-fail --cov=manim --cov-report xml --cov-report term -n auto --dist=loadfile --durations=0" [tool.isort] -# from https://black.readthedocs.io/en/stable/compatible_configs.html -multi_line_output = 3 -include_trailing_comma = true -force_grid_wrap = 0 -use_parentheses = true -ensure_newline_before_comments = true -line_length = 88 +profile = "black" [tool.coverage.run] omit = ["*tests*"] @@ -130,11 +130,96 @@ omit = ["*tests*"] [tool.coverage.report] exclude_lines = ["pragma: no cover"] -[tool.poetry.plugins] -[tool.poetry.plugins."console_scripts"] -"manim" = "manim.__main__:main" -"manimce" = "manim.__main__:main" +[tool.ruff] +line-length = 88 +target-version = "py39" +extend-exclude = [ + ".github", + ".hg", + ".env", + "env", + "build", + "buck-out", + "media", +] +fix = true -[build-system] -requires = ["setuptools","poetry-core>=1.0.0"] -build-backend = "poetry.core.masonry.api" +[tool.ruff.lint] +select = [ + "A", + "B", + "C4", + "D", + "E", + "F", + "I", + "PGH", + "PT", + "SIM", + "UP", +] + +ignore = [ + # (sub)module shadows standard library module + "A005", + # mutable argument defaults (too many changes) + "B006", + # No function calls in defaults + # ignored because np.array() and straight_path() + "B008", + # docstring ignores - mostly stylistic + "D1", + "D203", + "D205", + "D212", + "D4", + # due to the import * used in manim + "F403", + "F405", + # Exception too broad (this would require lots of changes + re.escape) for little benefit + "PT011", + # as recommended by https://docs.astral.sh/ruff/formatter/#conflicting-lint-rules + "D206", + "D300", + "E111", + "E114", + "E117", + "E501", +] + +# Allow unused variables when underscore-prefixed. +dummy-variable-rgx = "^(_+|(_+[a-zA-Z0-9_]*[a-zA-Z0-9]+?))$" + +[tool.ruff.lint.per-file-ignores] +"tests/*" = [ + # flake8-builtins + "A", + # unused expression + "B018", + # unused variable + "F841", + # from __future__ import annotations + "I002", +] + +"example_scenes/*" = [ + "I002", +] + +"__init__.py" = [ + "F401", + "F403", +] + +[tool.ruff.lint.isort] +required-imports = ["from __future__ import annotations"] + +[tool.ruff.lint.flake8-pytest-style] +fixture-parentheses = false +mark-parentheses = false + +[tool.ruff.lint.pydocstyle] +convention = "numpy" + +[tool.ruff.format] +docstring-code-format = true diff --git a/scripts/dev_changelog.py b/scripts/dev_changelog.py index 97dc3e7cb8..af1fb6fc38 100755 --- a/scripts/dev_changelog.py +++ b/scripts/dev_changelog.py @@ -45,14 +45,14 @@ from __future__ import annotations +import concurrent.futures import datetime -import os import re from collections import defaultdict from pathlib import Path from textwrap import dedent, indent -import click +import cloup from git import Repo from github import Github from tqdm import tqdm @@ -64,10 +64,10 @@ PR_LABELS = { "breaking changes": "Breaking changes", "highlight": "Highlights", - "deprecation": "Deprecated classes and functions", + "pr:deprecation": "Deprecated classes and functions", "new feature": "New features", "enhancement": "Enhancements", - "bugfix": "Fixed bugs", + "pr:bugfix": "Fixed bugs", "documentation": "Documentation-related changes", "testing": "Changes concerning the testing system", "infrastructure": "Changes to our development infrastructure", @@ -83,16 +83,13 @@ def update_citation(version, date): - current_directory = os.path.dirname(__file__) - parent_directory = os.path.split(current_directory)[0] - with open(os.path.join(current_directory, "TEMPLATE.cff")) as a, open( - os.path.join(parent_directory, "CITATION.cff"), - "w", - ) as b: - contents = a.read() - contents = contents.replace("", version) - contents = contents.replace("", date) - b.write(contents) + current_directory = Path(__file__).parent + parent_directory = current_directory.parent + contents = (current_directory / "TEMPLATE.cff").read_text() + contents = contents.replace("", version) + contents = contents.replace("", date) + with (parent_directory / "CITATION.cff").open("w", newline="\n") as f: + f.write(contents) def process_pullrequests(lst, cur, github_repo, pr_nums): @@ -102,17 +99,23 @@ def process_pullrequests(lst, cur, github_repo, pr_nums): authors = set() reviewers = set() pr_by_labels = defaultdict(list) - for num in tqdm(pr_nums, desc="Processing PRs"): - pr = github_repo.get_pull(num) - authors.add(pr.user) - reviewers = reviewers.union(rev.user for rev in pr.get_reviews()) - pr_labels = [label.name for label in pr.labels] - for label in PR_LABELS.keys(): - if label in pr_labels: - pr_by_labels[label].append(pr) - break # ensure that PR is only added in one category - else: - pr_by_labels["unlabeled"].append(pr) + with concurrent.futures.ThreadPoolExecutor() as executor: + future_to_num = { + executor.submit(github_repo.get_pull, num): num for num in pr_nums + } + for future in tqdm( + concurrent.futures.as_completed(future_to_num), "Processing PRs" + ): + pr = future.result() + authors.add(pr.user) + reviewers = reviewers.union(rev.user for rev in pr.get_reviews()) + pr_labels = [label.name for label in pr.labels] + for label in PR_LABELS: + if label in pr_labels: + pr_by_labels[label].append(pr) + break # ensure that PR is only added in one category + else: + pr_by_labels["unlabeled"].append(pr) # identify first-time contributors: author_names = [] @@ -131,6 +134,10 @@ def process_pullrequests(lst, cur, github_repo, pr_nums): continue reviewer_names.append(name) + # Sort items in pr_by_labels + for i in pr_by_labels: + pr_by_labels[i] = sorted(pr_by_labels[i], key=lambda pr: pr.number) + return { "authors": sorted(author_names), "reviewers": sorted(reviewer_names), @@ -175,26 +182,25 @@ def get_summary(body): try: has_changelog_pattern = re.search(pattern, body) if has_changelog_pattern: - return has_changelog_pattern.group()[22:-21].strip() except Exception: print(f"Error parsing body for changelog: {body}") -@click.command( +@cloup.command( context_settings=CONTEXT_SETTINGS, epilog=EPILOG, ) -@click.argument("token") -@click.argument("prior") -@click.argument("tag") -@click.argument( +@cloup.argument("token") +@cloup.argument("prior") +@cloup.argument("tag") +@cloup.argument( "additional", nargs=-1, required=False, type=int, ) -@click.option( +@cloup.option( "-o", "--outfile", type=str, @@ -211,7 +217,6 @@ def main(token, prior, tag, additional, outfile): ADDITIONAL includes additional PR(s) that have not been recognized automatically. """ - lst_release, cur_release = prior, tag github = Github(token) @@ -239,7 +244,7 @@ def main(token, prior, tag, additional, outfile): else: outfile = Path(outfile).resolve() - with outfile.open("w", encoding="utf8") as f: + with outfile.open("w", encoding="utf8", newline="\n") as f: f.write("*" * len(tag) + "\n") f.write(f"{tag}\n") f.write("*" * len(tag) + "\n\n") @@ -285,7 +290,7 @@ def main(token, prior, tag, additional, outfile): ) pr_by_labels = contributions["PRs"] - for label in PR_LABELS.keys(): + for label in PR_LABELS: pr_of_label = pr_by_labels[label] if pr_of_label: @@ -295,7 +300,6 @@ def main(token, prior, tag, additional, outfile): for PR in pr_by_labels[label]: num = PR.number - url = PR.html_url title = PR.title label = PR.labels f.write(f"* :pr:`{num}`: {title}\n") diff --git a/scripts/extract_frames.py b/scripts/extract_frames.py new file mode 100644 index 0000000000..a8900de5c0 --- /dev/null +++ b/scripts/extract_frames.py @@ -0,0 +1,44 @@ +from __future__ import annotations + +import pathlib +import sys + +import numpy as np +from PIL import Image + + +def main(): + if len(sys.argv) != 3: + print_usage() + sys.exit(1) + npz_file = sys.argv[1] + output_folder = pathlib.Path(sys.argv[2]) + if not output_folder.exists(): + output_folder.mkdir(parents=True) + + data = np.load(npz_file) + if "frame_data" not in data: + print("The given file did not have frame_data.") + print("Are you sure this is from a Manim Graphical Unit Test?") + sys.exit(2) + frames = data["frame_data"] + for i, frame in enumerate(frames): + img = Image.fromarray(frame) + img.save(output_folder / f"frame{i}.png") + print(f"Saved {len(frames)} frames to {output_folder}") + + +def print_usage(): + print("Manim Graphical Test Frame Extractor") + print( + "This tool outputs the frames of a Graphical Unit Test " + "stored within a .npz file, typically found under " + r"//tests/test_graphical_units/control_data" + ) + print() + print("usage:") + print("python3 extract_frames.py npz_file output_directory") + + +if __name__ == "__main__": + main() diff --git a/scripts/make_and_open_docs.py b/scripts/make_and_open_docs.py index 11b9360edc..c6179384ba 100644 --- a/scripts/make_and_open_docs.py +++ b/scripts/make_and_open_docs.py @@ -1,12 +1,12 @@ from __future__ import annotations -import os +import subprocess import sys import webbrowser from pathlib import Path -path_makefile = Path(__file__).parents[1] / "docs" -os.system(f"cd {path_makefile} && make html") +path_makefile = Path(__file__).resolve().parents[1] / "docs" +subprocess.run(["make", "html"], cwd=path_makefile) website = (path_makefile / "build" / "html" / "index.html").absolute().as_uri() try: # Allows you to pass a custom browser if you want. diff --git a/scripts/simple_cors_http_server.py b/scripts/simple_cors_http_server.py deleted file mode 100755 index 8ade778c58..0000000000 --- a/scripts/simple_cors_http_server.py +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env python3 -from __future__ import annotations - -import sys -from http.server import HTTPServer, SimpleHTTPRequestHandler, test # type: ignore - - -class CORSRequestHandler(SimpleHTTPRequestHandler): - def end_headers(self): - self.send_header("Access-Control-Allow-Origin", "*") - super().end_headers() - - -if __name__ == "__main__": - test( - CORSRequestHandler, - HTTPServer, - port=int(sys.argv[1]) if len(sys.argv) > 1 else 8000, - ) diff --git a/scripts/template_docsting_with_example.py b/scripts/template_docsting_with_example.py index 4a8621b5eb..ce2466dbdc 100644 --- a/scripts/template_docsting_with_example.py +++ b/scripts/template_docsting_with_example.py @@ -13,7 +13,7 @@ class SomeClass: Parameters ---------- - scale_factor : :class:`float` + scale_factor The factor used for scaling. Returns diff --git a/scripts/update_protos.py b/scripts/update_protos.py deleted file mode 100755 index aed4b00559..0000000000 --- a/scripts/update_protos.py +++ /dev/null @@ -1,19 +0,0 @@ -#!/usr/bin/env python -""" -This is intended to be run from manim/grpc -""" - -from __future__ import annotations - -import os - -CMD_STRING = """ -poetry run python \ - -m grpc_tools.protoc \ - -I./proto \ - --python_out=./gen \ - --grpc_python_out=./gen \ - ./proto/frameserver.proto \ - ./proto/renderserver.proto -""" -os.system(CMD_STRING) diff --git a/tests/assert_utils.py b/tests/assert_utils.py index 4a08e6365e..0d7d2417f2 100644 --- a/tests/assert_utils.py +++ b/tests/assert_utils.py @@ -8,7 +8,7 @@ def assert_file_exists(filepath: str | os.PathLike) -> None: """Assert that filepath points to an existing file. Print all the elements (files and dir) of the parent dir of the given filepath. - This is mostly to have better assert message than using a raw assert os.path.isfile(filepath). + This is mostly to have better assert message than using a raw assert filepath.is_file(). Parameters ---------- @@ -22,7 +22,7 @@ def assert_file_exists(filepath: str | os.PathLike) -> None: """ path = Path(filepath) if not path.is_file(): - elems = pformat([path.name for path in list(path.parent.iterdir())]) + elems = pformat([path.name for path in path.parent.iterdir()]) message = f"{path.absolute()} is not a file. Other elements in the parent directory are \n{elems}" raise AssertionError(message) @@ -60,14 +60,14 @@ def assert_dir_filled(dirpath: str | os.PathLike) -> None: AssertionError If dirpath does not point to a directory (if the file does exist or it's a file) or the directory is empty. """ - if len(os.listdir(dirpath)) == 0: + if not any(Path(dirpath).iterdir()): raise AssertionError(f"{dirpath} is an empty directory.") def assert_file_not_exists(filepath: str | os.PathLike) -> None: """Assert that filepath does not point to an existing file. Print all the elements (files and dir) of the parent dir of the given filepath. - This is mostly to have better assert message than using a raw assert os.path.isfile(filepath). + This is mostly to have better assert message than using a raw assert filepath.is_file(). Parameters ---------- @@ -81,7 +81,7 @@ def assert_file_not_exists(filepath: str | os.PathLike) -> None: """ path = Path(filepath) if path.is_file(): - elems = pformat([path.name for path in list(path.parent.iterdir())]) + elems = pformat([path.name for path in path.parent.iterdir()]) message = f"{path.absolute()} is a file. Other elements in the parent directory are \n{elems}" raise AssertionError(message) diff --git a/tests/conftest.py b/tests/conftest.py index 05a4e0dcd7..4de34bbbc1 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -1,11 +1,32 @@ from __future__ import annotations -import os +import logging import sys +from pathlib import Path +import cairo +import moderngl import pytest -from manim import config, tempconfig +import manim + + +def pytest_report_header(config): + try: + ctx = moderngl.create_standalone_context() + info = ctx.info + ctx.release() + except Exception as e: + raise Exception("Error while creating moderngl context") from e + + return ( + f"\nCairo Version: {cairo.cairo_version()}", + "\nOpenGL information", + "------------------", + f"vendor: {info['GL_VENDOR'].strip()}", + f"renderer: {info['GL_RENDERER'].strip()}", + f"version: {info['GL_VERSION'].strip()}\n", + ) def pytest_addoption(parser): @@ -45,6 +66,41 @@ def pytest_collection_modifyitems(config, items): item.add_marker(slow_skip) +@pytest.fixture(autouse=True) +def temp_media_dir(tmpdir, monkeypatch, request): + if isinstance(request.node, pytest.DoctestItem): + monkeypatch.chdir(tmpdir) + yield tmpdir + else: + with manim.tempconfig({"media_dir": str(tmpdir)}): + assert manim.config.media_dir == str(tmpdir) + yield tmpdir + + +@pytest.fixture +def manim_caplog(caplog): + logger = logging.getLogger("manim") + logger.propagate = True + caplog.set_level(logging.INFO, logger="manim") + yield caplog + logger.propagate = False + + +@pytest.fixture +def config(): + saved = manim.config.copy() + manim.config.renderer = "cairo" + # we need to return the actual config so that tests + # using tempconfig pass + yield manim.config + manim.config.update(saved) + + +@pytest.fixture +def dry_run(config): + config.dry_run = True + + @pytest.fixture(scope="session") def python_version(): # use the same python executable as it is running currently @@ -55,19 +111,17 @@ def python_version(): @pytest.fixture def reset_cfg_file(): - cfgfilepath = os.path.join(os.path.dirname(__file__), "test_cli", "manim.cfg") - with open(cfgfilepath) as cfgfile: - original = cfgfile.read() + cfgfilepath = Path(__file__).parent / "test_cli" / "manim.cfg" + original = cfgfilepath.read_text() yield - with open(cfgfilepath, "w") as cfgfile: - cfgfile.write(original) + cfgfilepath.write_text(original) @pytest.fixture -def using_opengl_renderer(): +def using_opengl_renderer(config): """Standard fixture for running with opengl that makes tests use a standard_config.cfg with a temp dir.""" - with tempconfig({"renderer": "opengl"}): - yield + config.renderer = "opengl" + yield # as a special case needed to manually revert back to cairo # due to side effects of setting the renderer config.renderer = "cairo" diff --git a/tests/control_data/logs_data/bad_tex_scene_BadTex.txt b/tests/control_data/logs_data/bad_tex_scene_BadTex.txt index 06d833f1bf..02c8813969 100644 --- a/tests/control_data/logs_data/bad_tex_scene_BadTex.txt +++ b/tests/control_data/logs_data/bad_tex_scene_BadTex.txt @@ -1,8 +1,8 @@ {"levelname": "INFO", "module": "logger_utils", "message": "Log file will be saved in <>"} {"levelname": "INFO", "module": "tex_file_writing", "message": "Writing <> to <>"} {"levelname": "ERROR", "module": "tex_file_writing", "message": "LaTeX compilation error: LaTeX Error: File `notapackage.sty' not found.\n"} -{"levelname": "ERROR", "module": "tex_file_writing", "message": "Context of error: \n\\documentclass[preview]{standalone}\n-> \\usepackage{notapackage}\n\\begin{document}\n\n\\begin{center}\n"} +{"levelname": "ERROR", "module": "tex_file_writing", "message": "Context of error: \n\\documentclass[preview]{standalone}\n-> \\usepackage{notapackage}\n\\begin{document}\n\\begin{center}\n\\frac{1}{0}\n"} {"levelname": "INFO", "module": "tex_file_writing", "message": "You do not have package notapackage.sty installed."} {"levelname": "INFO", "module": "tex_file_writing", "message": "Install notapackage.sty it using your LaTeX package manager, or check for typos."} {"levelname": "ERROR", "module": "tex_file_writing", "message": "LaTeX compilation error: Emergency stop.\n"} -{"levelname": "ERROR", "module": "tex_file_writing", "message": "Context of error: \n\\documentclass[preview]{standalone}\n-> \\usepackage{notapackage}\n\\begin{document}\n\n\\begin{center}\n"} +{"levelname": "ERROR", "module": "tex_file_writing", "message": "Context of error: \n\\documentclass[preview]{standalone}\n-> \\usepackage{notapackage}\n\\begin{document}\n\\begin{center}\n\\frac{1}{0}\n"} diff --git a/tests/control_data/videos_data/InputFileViaCfg.json b/tests/control_data/videos_data/InputFileViaCfg.json index 37d9165674..7c945a390e 100644 --- a/tests/control_data/videos_data/InputFileViaCfg.json +++ b/tests/control_data/videos_data/InputFileViaCfg.json @@ -6,7 +6,8 @@ "height": 480, "avg_frame_rate": "15/1", "duration": "1.000000", - "nb_frames": "15" + "nb_frames": "15", + "pix_fmt": "yuv420p" }, "section_dir_layout": [], "section_index": [] diff --git a/tests/control_data/videos_data/SceneWithDisabledSections.json b/tests/control_data/videos_data/SceneWithDisabledSections.json index e524af09cb..355f4c3804 100644 --- a/tests/control_data/videos_data/SceneWithDisabledSections.json +++ b/tests/control_data/videos_data/SceneWithDisabledSections.json @@ -6,7 +6,8 @@ "height": 480, "avg_frame_rate": "15/1", "duration": "1.000000", - "nb_frames": "15" + "nb_frames": "15", + "pix_fmt": "yuv420p" }, "section_dir_layout": [], "section_index": [] diff --git a/tests/control_data/videos_data/SceneWithEnabledSections.json b/tests/control_data/videos_data/SceneWithEnabledSections.json index 7f0656b815..0b26f15ae4 100644 --- a/tests/control_data/videos_data/SceneWithEnabledSections.json +++ b/tests/control_data/videos_data/SceneWithEnabledSections.json @@ -6,24 +6,26 @@ "height": 480, "avg_frame_rate": "15/1", "duration": "1.000000", - "nb_frames": "15" + "nb_frames": "15", + "pix_fmt": "yuv420p" }, "section_dir_layout": [ "SquareToCircle.json", - "SquareToCircle_0000.mp4", + "SquareToCircle_0000_autocreated.mp4", "." ], "section_index": [ { "name": "autocreated", "type": "default.normal", - "video": "SquareToCircle_0000.mp4", + "video": "SquareToCircle_0000_autocreated.mp4", "codec_name": "h264", "width": 854, "height": 480, "avg_frame_rate": "15/1", "duration": "1.000000", - "nb_frames": "15" + "nb_frames": "15", + "pix_fmt": "yuv420p" } ] } diff --git a/tests/control_data/videos_data/SceneWithMultipleCallsWithNFlag.json b/tests/control_data/videos_data/SceneWithMultipleCallsWithNFlag.json index 6af344a8c7..8b662ba6e8 100644 --- a/tests/control_data/videos_data/SceneWithMultipleCallsWithNFlag.json +++ b/tests/control_data/videos_data/SceneWithMultipleCallsWithNFlag.json @@ -6,7 +6,8 @@ "height": 480, "avg_frame_rate": "15/1", "duration": "4.000000", - "nb_frames": "60" + "nb_frames": "60", + "pix_fmt": "yuv420p" }, "section_dir_layout": [], "section_index": [] diff --git a/tests/control_data/videos_data/SceneWithMultiplePlayCallsWithNFlag.json b/tests/control_data/videos_data/SceneWithMultiplePlayCallsWithNFlag.json index d7117145f0..194c196faf 100644 --- a/tests/control_data/videos_data/SceneWithMultiplePlayCallsWithNFlag.json +++ b/tests/control_data/videos_data/SceneWithMultiplePlayCallsWithNFlag.json @@ -6,7 +6,8 @@ "height": 480, "avg_frame_rate": "15/1", "duration": "7.000000", - "nb_frames": "105" + "nb_frames": "105", + "pix_fmt": "yuv420p" }, "section_dir_layout": [], "section_index": [] diff --git a/tests/control_data/videos_data/SceneWithMultipleWaitCallsWithNFlag.json b/tests/control_data/videos_data/SceneWithMultipleWaitCallsWithNFlag.json index 9640c3cc31..2fa413b5e6 100644 --- a/tests/control_data/videos_data/SceneWithMultipleWaitCallsWithNFlag.json +++ b/tests/control_data/videos_data/SceneWithMultipleWaitCallsWithNFlag.json @@ -6,7 +6,8 @@ "height": 480, "avg_frame_rate": "15/1", "duration": "5.000000", - "nb_frames": "75" + "nb_frames": "75", + "pix_fmt": "yuv420p" }, "section_dir_layout": [], "section_index": [] diff --git a/tests/control_data/videos_data/SceneWithSections.json b/tests/control_data/videos_data/SceneWithSections.json index 289558d2c9..5278526e57 100644 --- a/tests/control_data/videos_data/SceneWithSections.json +++ b/tests/control_data/videos_data/SceneWithSections.json @@ -6,72 +6,78 @@ "height": 480, "avg_frame_rate": "15/1", "duration": "7.000000", - "nb_frames": "105" + "nb_frames": "105", + "pix_fmt": "yuv420p" }, "section_dir_layout": [ "SceneWithSections.json", - "SceneWithSections_0004.mp4", - "SceneWithSections_0003.mp4", - "SceneWithSections_0002.mp4", - "SceneWithSections_0001.mp4", - "SceneWithSections_0000.mp4", + "SceneWithSections_0004_unnamed.mp4", + "SceneWithSections_0003_Prepare For Unforeseen Consequences..mp4", + "SceneWithSections_0002_test.mp4", + "SceneWithSections_0001_unnamed.mp4", + "SceneWithSections_0000_autocreated.mp4", "." ], "section_index": [ { "name": "autocreated", "type": "default.normal", - "video": "SceneWithSections_0000.mp4", + "video": "SceneWithSections_0000_autocreated.mp4", "codec_name": "h264", "width": 854, "height": 480, "avg_frame_rate": "15/1", "duration": "1.000000", - "nb_frames": "15" + "nb_frames": "15", + "pix_fmt": "yuv420p" }, { "name": "unnamed", "type": "default.normal", - "video": "SceneWithSections_0001.mp4", + "video": "SceneWithSections_0001_unnamed.mp4", "codec_name": "h264", "width": 854, "height": 480, "avg_frame_rate": "15/1", "duration": "2.000000", - "nb_frames": "30" + "nb_frames": "30", + "pix_fmt": "yuv420p" }, { "name": "test", "type": "default.normal", - "video": "SceneWithSections_0002.mp4", + "video": "SceneWithSections_0002_test.mp4", "codec_name": "h264", "width": 854, "height": 480, "avg_frame_rate": "15/1", "duration": "1.000000", - "nb_frames": "15" + "nb_frames": "15", + "pix_fmt": "yuv420p" }, { "name": "Prepare For Unforeseen Consequences.", "type": "default.normal", - "video": "SceneWithSections_0003.mp4", + "video": "SceneWithSections_0003_Prepare For Unforeseen Consequences..mp4", "codec_name": "h264", "width": 854, "height": 480, "avg_frame_rate": "15/1", "duration": "2.000000", - "nb_frames": "30" + "nb_frames": "30", + "pix_fmt": "yuv420p" }, { "name": "unnamed", "type": "presentation.skip", - "video": "SceneWithSections_0004.mp4", + "video": "SceneWithSections_0004_unnamed.mp4", "codec_name": "h264", "width": 854, "height": 480, "avg_frame_rate": "15/1", "duration": "1.000000", - "nb_frames": "15" + "nb_frames": "15", + "pix_fmt": "yuv420p" } ] } diff --git a/tests/control_data/videos_data/SceneWithSkipAnimations.json b/tests/control_data/videos_data/SceneWithSkipAnimations.json index 2dbb670d8d..71bb21abb3 100644 --- a/tests/control_data/videos_data/SceneWithSkipAnimations.json +++ b/tests/control_data/videos_data/SceneWithSkipAnimations.json @@ -6,48 +6,52 @@ "height": 480, "avg_frame_rate": "15/1", "duration": "6.000000", - "nb_frames": "90" + "nb_frames": "90", + "pix_fmt": "yuv420p" }, "section_dir_layout": [ "ElaborateSceneWithSections.json", - "ElaborateSceneWithSections_0003.mp4", - "ElaborateSceneWithSections_0001.mp4", - "ElaborateSceneWithSections_0000.mp4", + "ElaborateSceneWithSections_0003_fade out.mp4", + "ElaborateSceneWithSections_0001_transform to circle.mp4", + "ElaborateSceneWithSections_0000_create square.mp4", "." ], "section_index": [ { "name": "create square", "type": "default.normal", - "video": "ElaborateSceneWithSections_0000.mp4", + "video": "ElaborateSceneWithSections_0000_create square.mp4", "codec_name": "h264", "width": 854, "height": 480, "avg_frame_rate": "15/1", "duration": "2.000000", - "nb_frames": "30" + "nb_frames": "30", + "pix_fmt": "yuv420p" }, { "name": "transform to circle", "type": "default.normal", - "video": "ElaborateSceneWithSections_0001.mp4", + "video": "ElaborateSceneWithSections_0001_transform to circle.mp4", "codec_name": "h264", "width": 854, "height": 480, "avg_frame_rate": "15/1", "duration": "2.000000", - "nb_frames": "30" + "nb_frames": "30", + "pix_fmt": "yuv420p" }, { "name": "fade out", "type": "default.normal", - "video": "ElaborateSceneWithSections_0003.mp4", + "video": "ElaborateSceneWithSections_0003_fade out.mp4", "codec_name": "h264", "width": 854, "height": 480, "avg_frame_rate": "15/1", "duration": "2.000000", - "nb_frames": "30" + "nb_frames": "30", + "pix_fmt": "yuv420p" } ] } diff --git a/tests/control_data/videos_data/SquareToCircleWithDefaultValues.json b/tests/control_data/videos_data/SquareToCircleWithDefaultValues.json index 9625ff36ce..b9465a9412 100644 --- a/tests/control_data/videos_data/SquareToCircleWithDefaultValues.json +++ b/tests/control_data/videos_data/SquareToCircleWithDefaultValues.json @@ -6,7 +6,8 @@ "height": 1080, "avg_frame_rate": "60/1", "duration": "1.000000", - "nb_frames": "60" + "nb_frames": "60", + "pix_fmt": "yuv420p" }, "section_dir_layout": [], "section_index": [] diff --git a/tests/control_data/videos_data/SquareToCircleWithlFlag.json b/tests/control_data/videos_data/SquareToCircleWithlFlag.json index ce3ef93872..5e8763446e 100644 --- a/tests/control_data/videos_data/SquareToCircleWithlFlag.json +++ b/tests/control_data/videos_data/SquareToCircleWithlFlag.json @@ -6,7 +6,8 @@ "height": 480, "avg_frame_rate": "15/1", "duration": "1.000000", - "nb_frames": "15" + "nb_frames": "15", + "pix_fmt": "yuv420p" }, "section_dir_layout": [], "section_index": [] diff --git a/tests/helpers/graphical_units.py b/tests/helpers/graphical_units.py index 46b2303191..1395559e52 100644 --- a/tests/helpers/graphical_units.py +++ b/tests/helpers/graphical_units.py @@ -1,25 +1,27 @@ """Helpers functions for devs to set up new graphical-units data.""" - from __future__ import annotations -import os +import logging import tempfile +from pathlib import Path import numpy as np -from manim import config, logger +from manim.scene.scene import Scene + +logger = logging.getLogger("manim") -def set_test_scene(scene_object, module_name): +def set_test_scene(scene_object: type[Scene], module_name: str, config): """Function used to set up the test data for a new feature. This will basically set up a pre-rendered frame for a scene. This is meant to be used only when setting up tests. Please refer to the wiki. Parameters ---------- - scene_object : :class:`~.Scene` + scene_object The scene with which we want to set up a new test. - module_name : :class:`str` + module_name The name of the module in which the functionality tested is contained. For example, ``Write`` is contained in the module ``creation``. This will be used in the folder architecture of ``/tests_data``. @@ -37,25 +39,21 @@ def set_test_scene(scene_object, module_name): config["frame_rate"] = 15 with tempfile.TemporaryDirectory() as tmpdir: - os.makedirs(os.path.join(tmpdir, "tex")) - config["text_dir"] = os.path.join(tmpdir, "text") - config["tex_dir"] = os.path.join(tmpdir, "tex") + temp_path = Path(tmpdir) + config["text_dir"] = temp_path / "text" + config["tex_dir"] = temp_path / "tex" scene = scene_object(skip_animations=True) scene.render() data = scene.renderer.get_frame() assert not np.all( data == np.array([0, 0, 0, 255]), - ), f"Control data generated for {str(scene)} only contains empty pixels." + ), f"Control data generated for {scene!s} only contains empty pixels." assert data.shape == (480, 854, 4) - tests_directory = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - path_control_data = os.path.join( - tests_directory, - "control_data", - "graphical_units_data", - ) - path = os.path.join(path_control_data, module_name) - if not os.path.isdir(path): - os.makedirs(path) - np.savez_compressed(os.path.join(path, str(scene)), frame_data=data) + tests_directory = Path(__file__).absolute().parent.parent + path_control_data = Path(tests_directory) / "control_data" / "graphical_units_data" + path = Path(path_control_data) / module_name + if not path.is_dir(): + path.mkdir(parents=True) + np.savez_compressed(path / str(scene), frame_data=data) logger.info(f"Test data for {str(scene)} saved in {path}\n") diff --git a/tests/helpers/video_utils.py b/tests/helpers/video_utils.py index 54203215d1..cc96e9acfb 100644 --- a/tests/helpers/video_utils.py +++ b/tests/helpers/video_utils.py @@ -3,36 +3,35 @@ from __future__ import annotations import json -import os -import pathlib +from pathlib import Path from typing import Any from manim import get_dir_layout, get_video_metadata, logger -def get_section_dir_layout(dirpath: str) -> list[str]: +def get_section_dir_layout(dirpath: Path) -> list[str]: """Return a list of all files in the sections directory.""" # test if sections have been created in the first place, doesn't work with multiple scene but this isn't an issue with tests - if not os.path.isdir(dirpath): + if not dirpath.is_dir(): return [] - files = get_dir_layout(dirpath) + files = list(get_dir_layout(dirpath)) # indicate that the sections directory has been created files.append(".") return files -def get_section_index(metapath: str) -> list[dict[str, Any]]: +def get_section_index(metapath: Path) -> list[dict[str, Any]]: """Return content of sections index file.""" - parent_folder = pathlib.Path(metapath).parent.absolute() + parent_folder = metapath.parent.absolute() # test if sections have been created in the first place - if not os.path.isdir(parent_folder): + if not parent_folder.is_dir(): return [] - with open(metapath) as file: + with metapath.open() as file: index = json.load(file) return index -def save_control_data_from_video(path_to_video: str, name: str) -> None: +def save_control_data_from_video(path_to_video: Path, name: str) -> None: """Helper used to set up a new test that will compare videos. This will create a new ``.json`` file in ``control_data/videos_data`` that contains: @@ -44,35 +43,34 @@ def save_control_data_from_video(path_to_video: str, name: str) -> None: Parameters ---------- - path_to_video : :class:`str` + path_to_video Path to the video to extract information from. - name : :class:`str` + name Name of the test. The .json file will be named with it. See Also -------- + tests/utils/video_tester.py : read control data and compare with output of test """ - path_to_sections = os.path.join( - pathlib.Path(path_to_video).parent.absolute(), "sections" - ) - tests_directory = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - path_control_data = os.path.join(tests_directory, "control_data", "videos_data") + orig_path_to_sections = path_to_video + path_to_sections = orig_path_to_sections.parent.absolute() / "sections" + tests_directory = Path(__file__).absolute().parent.parent + path_control_data = Path(tests_directory) / "control_data" / "videos_data" # this is the name of the section used in the test, not the name of the test itself, it can be found as a parameter of this function - scene_name = "".join(os.path.basename(path_to_video).split(".")[:-1]) + scene_name = orig_path_to_sections.stem movie_metadata = get_video_metadata(path_to_video) section_dir_layout = get_section_dir_layout(path_to_sections) - section_index = get_section_index( - os.path.join(path_to_sections, f"{scene_name}.json") - ) + section_index = get_section_index(path_to_sections / f"{scene_name}.json") + data = { "name": name, "movie_metadata": movie_metadata, "section_dir_layout": section_dir_layout, "section_index": section_index, } - path_saved = os.path.join(path_control_data, f"{name}.json") - with open(path_saved, "w") as f: + path_saved = Path(path_control_data) / f"{name}.json" + with path_saved.open("w") as f: json.dump(data, f, indent=4) logger.info(f"Data for {name} saved in {path_saved}") diff --git a/tests/interface/test_commands.py b/tests/interface/test_commands.py new file mode 100644 index 0000000000..52007b71eb --- /dev/null +++ b/tests/interface/test_commands.py @@ -0,0 +1,153 @@ +from __future__ import annotations + +import shutil +import sys +from pathlib import Path +from textwrap import dedent +from unittest.mock import patch + +from click.testing import CliRunner + +from manim import __version__, capture +from manim.__main__ import main +from manim.cli.checkhealth.checks import HEALTH_CHECKS + + +def test_manim_version(): + command = [ + sys.executable, + "-m", + "manim", + "--version", + ] + out, err, exit_code = capture(command) + assert exit_code == 0, err + assert __version__ in out + + +def test_manim_cfg_subcommand(): + command = ["cfg"] + runner = CliRunner() + result = runner.invoke(main, command, prog_name="manim") + expected_output = f"""\ +Manim Community v{__version__} + +Usage: manim cfg [OPTIONS] COMMAND [ARGS]... + + Manages Manim configuration files. + +Options: + --help Show this message and exit. + +Commands: + export + show + write + +Made with <3 by Manim Community developers. +""" + assert dedent(expected_output) == result.stdout + + +def test_manim_plugins_subcommand(): + command = ["plugins"] + runner = CliRunner() + result = runner.invoke(main, command, prog_name="manim") + expected_output = f"""\ +Manim Community v{__version__} + +Usage: manim plugins [OPTIONS] + + Manages Manim plugins. + +Options: + -l, --list List available plugins. + --help Show this message and exit. + +Made with <3 by Manim Community developers. +""" + assert dedent(expected_output) == result.output + + +def test_manim_checkhealth_subcommand(): + command = ["checkhealth"] + runner = CliRunner() + result = runner.invoke(main, command) + output_lines = result.output.split("\n") + num_passed = len([line for line in output_lines if "PASSED" in line]) + assert num_passed == len(HEALTH_CHECKS), ( + f"Some checks failed! Full output:\n{result.output}" + ) + assert "No problems detected, your installation seems healthy!" in output_lines + + +def test_manim_checkhealth_failing_subcommand(): + command = ["checkhealth"] + runner = CliRunner() + true_f = shutil.which + + def mock_f(s): + if s == "latex": + return None + + return true_f(s) + + with patch.object(shutil, "which", new=mock_f): + result = runner.invoke(main, command) + + output_lines = result.output.split("\n") + assert "- Checking whether latex is available ... FAILED" in output_lines + assert "- Checking whether dvisvgm is available ... SKIPPED" in output_lines + + +def test_manim_init_subcommand(): + command = ["init"] + runner = CliRunner() + result = runner.invoke(main, command, prog_name="manim") + expected_output = f"""\ +Manim Community v{__version__} + +Usage: manim init [OPTIONS] COMMAND [ARGS]... + + Create a new project or insert a new scene. + +Options: + --help Show this message and exit. + +Commands: + project Creates a new project. + scene Inserts a SCENE to an existing FILE or creates a new FILE. + +Made with <3 by Manim Community developers. +""" + assert dedent(expected_output) == result.output + + +def test_manim_init_project(tmp_path): + command = ["init", "project", "--default", "testproject"] + runner = CliRunner() + with runner.isolated_filesystem(temp_dir=tmp_path) as tmp_dir: + result = runner.invoke(main, command, prog_name="manim", input="Default\n") + assert not result.exception + assert (Path(tmp_dir) / "testproject/main.py").exists() + assert (Path(tmp_dir) / "testproject/manim.cfg").exists() + + +def test_manim_init_scene(tmp_path): + command_named = ["init", "scene", "NamedFileTestScene", "my_awesome_file.py"] + command_unnamed = ["init", "scene", "DefaultFileTestScene"] + runner = CliRunner() + with runner.isolated_filesystem(temp_dir=tmp_path) as tmp_dir: + result = runner.invoke( + main, command_named, prog_name="manim", input="Default\n" + ) + assert not result.exception + assert (Path(tmp_dir) / "my_awesome_file.py").exists() + file_content = (Path(tmp_dir) / "my_awesome_file.py").read_text() + assert "NamedFileTestScene(Scene):" in file_content + result = runner.invoke( + main, command_unnamed, prog_name="manim", input="Default\n" + ) + assert (Path(tmp_dir) / "main.py").exists() + file_content = (Path(tmp_dir) / "main.py").read_text() + assert "DefaultFileTestScene(Scene):" in file_content diff --git a/tests/test_version.py b/tests/miscellaneous/test_version.py similarity index 50% rename from tests/test_version.py rename to tests/miscellaneous/test_version.py index 0ad87cd2d3..2becb1e3cd 100644 --- a/tests/test_version.py +++ b/tests/miscellaneous/test_version.py @@ -1,9 +1,9 @@ from __future__ import annotations -import pkg_resources +from importlib.metadata import version from manim import __name__, __version__ def test_version(): - assert __version__ == pkg_resources.get_distribution(__name__).version + assert __version__ == version(__name__) diff --git a/tests/test_animate.py b/tests/module/animation/test_animate.py similarity index 92% rename from tests/test_animate.py rename to tests/module/animation/test_animate.py index 4f39d85481..91d3b19dfd 100644 --- a/tests/test_animate.py +++ b/tests/module/animation/test_animate.py @@ -23,10 +23,8 @@ def test_chained_animate(): scale_factor = 2 direction = np.array((1, 1, 0)) anim = s.animate.scale(scale_factor).shift(direction).build() - assert ( - anim.mobject.target.width == scale_factor * s.width - and (anim.mobject.target.get_center() == direction).all() - ) + assert anim.mobject.target.width == scale_factor * s.width + assert (anim.mobject.target.get_center() == direction).all() def test_overridden_animate(): @@ -103,10 +101,8 @@ def test_chained_animate_with_args(): run_time = 2 anim = s.animate(run_time=run_time).scale(scale_factor).shift(direction).build() - assert ( - anim.mobject.target.width == scale_factor * s.width - and (anim.mobject.target.get_center() == direction).all() - ) + assert anim.mobject.target.width == scale_factor * s.width + assert (anim.mobject.target.get_center() == direction).all() assert anim.run_time == run_time diff --git a/tests/module/animation/test_animation.py b/tests/module/animation/test_animation.py new file mode 100644 index 0000000000..5991aab074 --- /dev/null +++ b/tests/module/animation/test_animation.py @@ -0,0 +1,57 @@ +from __future__ import annotations + +import pytest + +from manim import FadeIn, Scene + + +def test_animation_zero_total_run_time(): + test_scene = Scene() + with pytest.raises( + ValueError, match="The total run_time must be a positive number." + ): + test_scene.play(FadeIn(None, run_time=0)) + + +def test_single_animation_zero_run_time_with_more_animations(): + test_scene = Scene() + test_scene.play(FadeIn(None, run_time=0), FadeIn(None, run_time=1)) + + +def test_animation_negative_run_time(): + with pytest.raises(ValueError, match="The run_time of FadeIn cannot be negative."): + FadeIn(None, run_time=-1) + + +def test_animation_run_time_shorter_than_frame_rate(manim_caplog, config): + test_scene = Scene() + test_scene.play(FadeIn(None, run_time=1 / (config.frame_rate + 1))) + assert "too short for the current frame rate" in manim_caplog.text + + +@pytest.mark.parametrize("duration", [0, -1]) +def test_wait_invalid_duration(duration): + test_scene = Scene() + with pytest.raises(ValueError, match="The duration must be a positive number."): + test_scene.wait(duration) + + +@pytest.mark.parametrize("frozen_frame", [False, True]) +def test_wait_duration_shorter_than_frame_rate(manim_caplog, frozen_frame): + test_scene = Scene() + test_scene.wait(1e-9, frozen_frame=frozen_frame) + assert "too short for the current frame rate" in manim_caplog.text + + +@pytest.mark.parametrize("duration", [0, -1]) +def test_pause_invalid_duration(duration): + test_scene = Scene() + with pytest.raises(ValueError, match="The duration must be a positive number."): + test_scene.pause(duration) + + +@pytest.mark.parametrize("max_time", [0, -1]) +def test_wait_until_invalid_max_time(max_time): + test_scene = Scene() + with pytest.raises(ValueError, match="The max_time must be a positive number."): + test_scene.wait_until(lambda: True, max_time) diff --git a/tests/test_composition.py b/tests/module/animation/test_composition.py similarity index 78% rename from tests/test_composition.py rename to tests/module/animation/test_composition.py index 9f26474558..8c5f044b2a 100644 --- a/tests/test_composition.py +++ b/tests/module/animation/test_composition.py @@ -90,6 +90,26 @@ def test_succession_in_succession_timing(): assert nested_succession.active_animation is None +def test_timescaled_succession(): + s1, s2, s3 = Square(), Square(), Square() + anim = Succession( + FadeIn(s1, run_time=2), + FadeIn(s2), + FadeIn(s3), + ) + anim.scene = MagicMock() + anim.run_time = 42 + anim.begin() + anim.interpolate(0.2) + assert anim.active_index == 0 + anim.interpolate(0.4) + assert anim.active_index == 0 + anim.interpolate(0.6) + assert anim.active_index == 1 + anim.interpolate(0.8) + assert anim.active_index == 2 + + def test_animationbuilder_in_group(): sqr = Square() circ = Circle() @@ -108,11 +128,11 @@ def test_animationgroup_with_wait(): animation_group.begin() timings = animation_group.anims_with_timings - assert timings == [(wait, 0.0, 1.0), (sqr_anim, 1.0, 2.0)] + assert timings.tolist() == [(wait, 0.0, 1.0), (sqr_anim, 1.0, 2.0)] @pytest.mark.parametrize( - "animation_remover, animation_group_remover", + ("animation_remover", "animation_group_remover"), [(False, True), (True, False)], ) def test_animationgroup_is_passing_remover_to_animations( @@ -149,3 +169,31 @@ def test_animationgroup_is_passing_remover_to_nested_animationgroups(): assert sqr_animation.remover assert circ_animation.remover assert polygon_animation.remover + + +def test_animationgroup_calls_finish(): + class MyAnimation(Animation): + def __init__(self, mobject): + super().__init__(mobject) + self.finished = False + + def finish(self): + self.finished = True + + scene = Scene() + sqr_animation = MyAnimation(Square()) + circ_animation = MyAnimation(Circle()) + animation_group = AnimationGroup(sqr_animation, circ_animation) + scene.play(animation_group) + assert sqr_animation.finished + assert circ_animation.finished + + +def test_empty_animation_group_fails(): + with pytest.raises(ValueError, match="Please add at least one subanimation."): + AnimationGroup().begin() + + +def test_empty_succession_fails(): + with pytest.raises(ValueError, match="Please add at least one subanimation."): + Succession().begin() diff --git a/tests/module/animation/test_creation.py b/tests/module/animation/test_creation.py new file mode 100644 index 0000000000..d2a0b08666 --- /dev/null +++ b/tests/module/animation/test_creation.py @@ -0,0 +1,34 @@ +from __future__ import annotations + +import numpy as np +import pytest + +from manim import AddTextLetterByLetter, Text + + +def test_non_empty_text_creation(): + """Check if AddTextLetterByLetter works for non-empty text.""" + s = Text("Hello") + anim = AddTextLetterByLetter(s) + assert anim.mobject.text == "Hello" + + +def test_empty_text_creation(): + """Ensure ValueError is raised for empty text.""" + with pytest.raises(ValueError, match="does not seem to contain any characters"): + AddTextLetterByLetter(Text("")) + + +def test_whitespace_text_creation(): + """Ensure ValueError is raised for whitespace-only text, assuming the whitespace characters have no points.""" + with pytest.raises(ValueError, match="does not seem to contain any characters"): + AddTextLetterByLetter(Text(" ")) + + +def test_run_time_for_non_empty_text(config): + """Ensure the run_time is calculated correctly for non-empty text.""" + s = Text("Hello") + run_time_per_char = 0.1 + expected_run_time = np.max((1 / config.frame_rate, run_time_per_char)) * len(s.text) + anim = AddTextLetterByLetter(s, time_per_char=run_time_per_char) + assert anim.run_time == expected_run_time diff --git a/tests/test_override_animation.py b/tests/module/animation/test_override_animation.py similarity index 100% rename from tests/test_override_animation.py rename to tests/module/animation/test_override_animation.py diff --git a/tests/module/mobject/geometry/test_unit_geometry.py b/tests/module/mobject/geometry/test_unit_geometry.py new file mode 100644 index 0000000000..b8594260b6 --- /dev/null +++ b/tests/module/mobject/geometry/test_unit_geometry.py @@ -0,0 +1,144 @@ +from __future__ import annotations + +import logging + +import numpy as np + +from manim import ( + BackgroundRectangle, + Circle, + Polygram, + Sector, + Square, + SurroundingRectangle, +) + +logger = logging.getLogger(__name__) + + +def test_get_arc_center(): + np.testing.assert_array_equal( + Sector(arc_center=[1, 2, 0]).get_arc_center(), [1, 2, 0] + ) + + +def test_Polygram_get_vertex_groups(): + # Test that, once a Polygram polygram is created with some vertex groups, + # polygram.get_vertex_groups() (usually) returns the same vertex groups. + vertex_groups_arr = [ + # 2 vertex groups for polygram 1 + [ + # Group 1: Triangle + np.array( + [ + [2, 1, 0], + [0, 2, 0], + [-2, 1, 0], + ] + ), + # Group 2: Square + np.array( + [ + [1, 0, 0], + [0, 1, 0], + [-1, 0, 0], + [0, -1, 0], + ] + ), + ], + # 3 vertex groups for polygram 1 + [ + # Group 1: Quadrilateral + np.array( + [ + [2, 0, 0], + [0, -1, 0], + [0, 0, -2], + [0, 1, 0], + ] + ), + # Group 2: Triangle + np.array( + [ + [3, 1, 0], + [0, 0, 2], + [2, 0, 0], + ] + ), + # Group 3: Pentagon + np.array( + [ + [1, -1, 0], + [1, 1, 0], + [0, 2, 0], + [-1, 1, 0], + [-1, -1, 0], + ] + ), + ], + ] + + for vertex_groups in vertex_groups_arr: + polygram = Polygram(*vertex_groups) + poly_vertex_groups = polygram.get_vertex_groups() + for poly_group, group in zip(poly_vertex_groups, vertex_groups): + np.testing.assert_array_equal(poly_group, group) + + # If polygram is a Polygram of a vertex group containing the start vertex N times, + # then polygram.get_vertex_groups() splits it into N vertex groups. + splittable_vertex_group = np.array( + [ + [0, 1, 0], + [1, -2, 0], + [1, 2, 0], + [0, 1, 0], # same vertex as start + [-1, 2, 0], + [-1, -2, 0], + [0, 1, 0], # same vertex as start + [0.5, 2, 0], + [-0.5, 2, 0], + ] + ) + + polygram = Polygram(splittable_vertex_group) + assert len(polygram.get_vertex_groups()) == 3 + + +def test_SurroundingRectangle(): + circle = Circle() + square = Square() + sr = SurroundingRectangle(circle, square) + sr.set_style(fill_opacity=0.42) + assert sr.get_fill_opacity() == 0.42 + + +def test_BackgroundRectangle(manim_caplog): + circle = Circle() + square = Square() + bg = BackgroundRectangle(circle, square) + bg.set_style(fill_opacity=0.42) + assert bg.get_fill_opacity() == 0.42 + bg.set_style(fill_opacity=1, hello="world") + assert ( + "Argument {'hello': 'world'} is ignored in BackgroundRectangle.set_style." + in manim_caplog.text + ) + + +def test_Square_side_length_reflets_correct_width_and_height(): + sq = Square(side_length=1).scale(3) + assert sq.side_length == 3 + assert sq.height == 3 + assert sq.width == 3 + + +def test_changing_Square_side_length_updates_the_square_appropriately(): + sq = Square(side_length=1) + sq.side_length = 3 + assert sq.height == 3 + assert sq.width == 3 + + +def test_Square_side_length_consistent_after_scale_and_rotation(): + sq = Square(side_length=1).scale(3).rotate(np.pi / 4) + assert np.isclose(sq.side_length, 3) diff --git a/tests/test_axes_shift.py b/tests/module/mobject/graphing/test_axes_shift.py similarity index 67% rename from tests/test_axes_shift.py rename to tests/module/mobject/graphing/test_axes_shift.py index 6697f5d830..b733ffe507 100644 --- a/tests/test_axes_shift.py +++ b/tests/module/mobject/graphing/test_axes_shift.py @@ -8,8 +8,8 @@ def test_axes_origin_shift(): ax = Axes(x_range=(5, 10, 1), y_range=(40, 45, 0.5)) - assert np.allclose(ax.coords_to_point(5, 40), ax.x_axis.number_to_point(5)) - assert np.allclose(ax.coords_to_point(5, 40), ax.y_axis.number_to_point(40)) + np.testing.assert_allclose(ax.coords_to_point(5, 40), ax.x_axis.number_to_point(5)) + np.testing.assert_allclose(ax.coords_to_point(5, 40), ax.y_axis.number_to_point(40)) def test_axes_origin_shift_logbase(): @@ -19,19 +19,25 @@ def test_axes_origin_shift_logbase(): x_axis_config={"scaling": LogBase()}, y_axis_config={"scaling": LogBase()}, ) - assert np.allclose( + np.testing.assert_allclose( ax.coords_to_point(10**5, 10**3), ax.x_axis.number_to_point(10**5) ) - assert np.allclose( + np.testing.assert_allclose( ax.coords_to_point(10**5, 10**3), ax.y_axis.number_to_point(10**3) ) def test_3daxes_origin_shift(): ax = ThreeDAxes(x_range=(3, 9, 1), y_range=(6, 12, 1), z_range=(-1, 1, 0.5)) - assert np.allclose(ax.coords_to_point(3, 6, 0), ax.x_axis.number_to_point(3)) - assert np.allclose(ax.coords_to_point(3, 6, 0), ax.y_axis.number_to_point(6)) - assert np.allclose(ax.coords_to_point(3, 6, 0), ax.z_axis.number_to_point(0)) + np.testing.assert_allclose( + ax.coords_to_point(3, 6, 0), ax.x_axis.number_to_point(3) + ) + np.testing.assert_allclose( + ax.coords_to_point(3, 6, 0), ax.y_axis.number_to_point(6) + ) + np.testing.assert_allclose( + ax.coords_to_point(3, 6, 0), ax.z_axis.number_to_point(0) + ) def test_3daxes_origin_shift_logbase(): @@ -43,15 +49,15 @@ def test_3daxes_origin_shift_logbase(): y_axis_config={"scaling": LogBase()}, z_axis_config={"scaling": LogBase()}, ) - assert np.allclose( + np.testing.assert_allclose( ax.coords_to_point(10**3, 10**6, 10**2), ax.x_axis.number_to_point(10**3), ) - assert np.allclose( + np.testing.assert_allclose( ax.coords_to_point(10**3, 10**6, 10**2), ax.y_axis.number_to_point(10**6), ) - assert np.allclose( + np.testing.assert_allclose( ax.coords_to_point(10**3, 10**6, 10**2), ax.z_axis.number_to_point(10**2), ) diff --git a/tests/test_coordinate_system.py b/tests/module/mobject/graphing/test_coordinate_system.py similarity index 51% rename from tests/test_coordinate_system.py rename to tests/module/mobject/graphing/test_coordinate_system.py index 1695f5c549..470d9d0074 100644 --- a/tests/test_coordinate_system.py +++ b/tests/module/mobject/graphing/test_coordinate_system.py @@ -5,9 +5,22 @@ import numpy as np import pytest -from manim import LEFT, ORIGIN, PI, UR, Axes, Circle, ComplexPlane +from manim import ( + LEFT, + ORIGIN, + PI, + UR, + Axes, + Circle, + ComplexPlane, + Dot, + NumberPlane, + PolarPlane, + ThreeDAxes, + config, + tempconfig, +) from manim import CoordinateSystem as CS -from manim import NumberPlane, PolarPlane, ThreeDAxes, config, tempconfig def test_initial_config(): @@ -21,8 +34,8 @@ def test_initial_config(): assert cs.y_range[2] == 1.0 ax = Axes() - assert np.allclose(ax.get_center(), ORIGIN) - assert np.allclose(ax.y_axis_config["label_direction"], LEFT) + np.testing.assert_allclose(ax.get_center(), ORIGIN) + np.testing.assert_allclose(ax.y_axis_config["label_direction"], LEFT) with tempconfig({"frame_x_radius": 100, "frame_y_radius": 200}): cs = CS() @@ -43,7 +56,7 @@ def test_dimension(): def test_abstract_base_class(): """Check that CoordinateSystem has some abstract methods.""" - with pytest.raises(Exception): + with pytest.raises(NotImplementedError): CS().get_axes() @@ -55,19 +68,15 @@ def test_NumberPlane(): pos_y_range = (2, 6) neg_y_range = (-6, -2) - x_vals = [0, 1.5, 2, 2.8, 4, 6.25] - y_vals = [2, 5, 4.25, 6, 4.5, 2.75] - testing_data = [ - (pos_x_range, pos_y_range, x_vals, y_vals), - (pos_x_range, neg_y_range, x_vals, [-v for v in y_vals]), - (neg_x_range, pos_y_range, [-v for v in x_vals], y_vals), - (neg_x_range, neg_y_range, [-v for v in x_vals], [-v for v in y_vals]), + (pos_x_range, pos_y_range), + (pos_x_range, neg_y_range), + (neg_x_range, pos_y_range), + (neg_x_range, neg_y_range), ] for test_data in testing_data: - - x_range, y_range, x_vals, y_vals = test_data + x_range, y_range = test_data x_start, x_end = x_range y_start, y_end = y_range @@ -89,8 +98,11 @@ def test_NumberPlane(): assert len(plane.x_lines) == num_x_lines plane = NumberPlane((-5, 5, 0.5), (-8, 8, 2)) # <- test for different step values - assert len(plane.x_lines) == 8 - assert len(plane.y_lines) == 20 + # horizontal lines: -6 -4, -2, 0, 2, 4, 6 + assert len(plane.x_lines) == 7 + # vertical lines: 0, +-0.5, +-1, +-1.5, +-2, +-2.5, + # +-3, +-3.5, +-4, +-4.5 + assert len(plane.y_lines) == 19 def test_point_to_coords(): @@ -99,7 +111,20 @@ def test_point_to_coords(): # get the coordinates of the circle with respect to the axes coords = np.around(ax.point_to_coords(circ.get_right()), decimals=4) - assert np.array_equal(coords, (7.0833, 2.6667)) + np.testing.assert_array_equal(coords, (7.0833, 2.6667)) + + +def test_point_to_coords_vectorized(): + ax = Axes(x_range=[0, 10, 2]) + circ = Circle(radius=0.5).shift(UR * 2) + points = np.array( + [circ.get_right(), circ.get_left(), circ.get_bottom(), circ.get_top()] + ) + # get the coordinates of the circle with respect to the axes + expected = [np.around(ax.point_to_coords(point), decimals=4) for point in points] + actual = np.around(ax.point_to_coords(points), decimals=4) + + np.testing.assert_array_equal(expected, actual) def test_coords_to_point(): @@ -107,7 +132,50 @@ def test_coords_to_point(): # a point with respect to the axes c2p_coord = np.around(ax.coords_to_point(2, 2), decimals=4) - assert np.array_equal(c2p_coord, (1.7143, 1.5, 0)) + c2p_coord_matmul = np.around(ax @ (2, 2), decimals=4) + + expected = (1.7143, 1.5, 0) + + np.testing.assert_array_equal(c2p_coord, expected) + np.testing.assert_array_equal(c2p_coord_matmul, c2p_coord) + + mob = Dot().move_to((2, 2, 0)) + np.testing.assert_array_equal(np.around(ax @ mob, decimals=4), expected) + + +def test_coords_to_point_vectorized(): + plane = NumberPlane(x_range=[2, 4]) + + origin = plane.x_axis.number_to_point( + plane._origin_shift([plane.x_axis.x_min, plane.x_axis.x_max]), + ) + + def ref_func(*coords): + result = np.array(origin) + for axis, number in zip(plane.get_axes(), coords): + result += axis.number_to_point(number) - origin + return result + + coords = [[1], [1, 2], [2, 2], [3, 4]] + + print(f"\n\nTesting coords_to_point {coords}") + expected = np.round([ref_func(*coord) for coord in coords], 4) + actual1 = np.round([plane.coords_to_point(*coord) for coord in coords], 4) + coords[0] = [ + 1, + 0, + ] # Extend the first coord because you can't vectorize items with different dimensions + actual2 = np.round( + plane.coords_to_point(coords), 4 + ) # Test [x_0,y_0,z_0], [x_1,y_1,z_1], ... + actual3 = np.round( + plane.coords_to_point(*np.array(coords).T), 4 + ) # Test [x_0,x_1,...], [y_0,y_1,...], ... + print(actual3) + + np.testing.assert_array_equal(expected, actual1) + np.testing.assert_array_equal(expected, actual2) + np.testing.assert_array_equal(expected, actual3.T) def test_input_to_graph_point(): @@ -119,8 +187,8 @@ def test_input_to_graph_point(): # move a square to PI on the cosine curve. position = np.around(ax.input_to_graph_point(x=PI, graph=curve), decimals=4) - assert np.array_equal(position, (2.6928, -0.75, 0)) + np.testing.assert_array_equal(position, (2.6928, -0.75, 0)) # test the line_graph implementation position = np.around(ax.input_to_graph_point(x=PI, graph=line_graph), decimals=4) - assert np.array_equal(position, (2.6928, 1.2876, 0)) + np.testing.assert_array_equal(position, (2.6928, 1.2876, 0)) diff --git a/tests/test_number_line.py b/tests/module/mobject/graphing/test_number_line.py similarity index 52% rename from tests/test_number_line.py rename to tests/module/mobject/graphing/test_number_line.py index 4092e4bfd1..552b24ebb4 100644 --- a/tests/test_number_line.py +++ b/tests/module/mobject/graphing/test_number_line.py @@ -2,13 +2,14 @@ import numpy as np -from manim import NumberLine +from manim import DashedLine, NumberLine from manim.mobject.text.numbers import Integer def test_unit_vector(): """Check if the magnitude of unit vector along - the NumberLine is equal to its unit_size.""" + the NumberLine is equal to its unit_size. + """ axis1 = NumberLine(unit_size=0.4) axis2 = NumberLine(x_range=[-2, 5], length=12) for axis in (axis1, axis2): @@ -17,7 +18,8 @@ def test_unit_vector(): def test_decimal_determined_by_step(): """Checks that step size is considered when determining the number of decimal - places.""" + places. + """ axis = NumberLine(x_range=[-2, 2, 0.5]) expected_decimal_places = 1 actual_decimal_places = axis.decimal_number_config["num_decimal_places"] @@ -63,6 +65,68 @@ def test_add_labels(): dict(zip(list(range(-3, 3)), [Integer(m) for m in range(-1, 5)])), ) actual_label_length = len(num_line.labels) - assert ( - actual_label_length == expected_label_length - ), f"Expected a VGroup with {expected_label_length} integers but got {actual_label_length}." + assert actual_label_length == expected_label_length, ( + f"Expected a VGroup with {expected_label_length} integers but got {actual_label_length}." + ) + + +def test_number_to_point(): + line = NumberLine() + numbers = [1, 2, 3, 4, 5] + numbers_np = np.array(numbers) + expected = np.array( + [ + [1.0, 0.0, 0.0], + [2.0, 0.0, 0.0], + [3.0, 0.0, 0.0], + [4.0, 0.0, 0.0], + [5.0, 0.0, 0.0], + ] + ) + vec_1 = np.array([line.number_to_point(x) for x in numbers]) + vec_2 = line.number_to_point(numbers) + vec_3 = line.number_to_point(numbers_np) + + np.testing.assert_equal( + np.round(vec_1, 4), + np.round(expected, 4), + f"Expected {expected} but got {vec_1} with input as scalar", + ) + np.testing.assert_equal( + np.round(vec_2, 4), + np.round(expected, 4), + f"Expected {expected} but got {vec_2} with input as params", + ) + np.testing.assert_equal( + np.round(vec_2, 4), + np.round(expected, 4), + f"Expected {expected} but got {vec_3} with input as ndarray", + ) + + +def test_point_to_number(): + line = NumberLine() + points = [ + [1.0, 0.0, 0.0], + [2.0, 0.0, 0.0], + [3.0, 0.0, 0.0], + [4.0, 0.0, 0.0], + [5.0, 0.0, 0.0], + ] + points_np = np.array(points) + expected = [1, 2, 3, 4, 5] + + num_1 = [line.point_to_number(point) for point in points] + num_2 = line.point_to_number(points) + num_3 = line.point_to_number(points_np) + + np.testing.assert_array_equal(np.round(num_1, 4), np.round(expected, 4)) + np.testing.assert_array_equal(np.round(num_2, 4), np.round(expected, 4)) + np.testing.assert_array_equal(np.round(num_3, 4), np.round(expected, 4)) + + +def test_start_and_end_at_same_point(): + line = DashedLine(np.zeros(3), np.zeros(3)) + line.put_start_and_end_on(np.zeros(3), np.array([0, 0, 0])) + + np.testing.assert_array_equal(np.round(np.zeros(3), 4), np.round(line.points, 4)) diff --git a/tests/test_ticks.py b/tests/module/mobject/graphing/test_ticks.py similarity index 70% rename from tests/test_ticks.py rename to tests/module/mobject/graphing/test_ticks.py index eeac2ac0a1..e4bbcd3c67 100644 --- a/tests/test_ticks.py +++ b/tests/module/mobject/graphing/test_ticks.py @@ -13,6 +13,29 @@ def test_duplicate_ticks_removed_for_axes(): assert np.unique(ticks).size == ticks.size +def test_elongated_ticks_float_equality(): + nline = NumberLine( + x_range=[1 + 1e-5, 1 + 2e-5, 1e-6], + numbers_with_elongated_ticks=[ + 1 + 12e-6, + 1 + 17e-6, + ], # Elongate the 3rd and 8th tick + include_ticks=True, + ) + + tick_heights = {tick.height for tick in nline.ticks} + default_tick_height, elongated_tick_height = min(tick_heights), max(tick_heights) + + assert all( + ( + tick.height == elongated_tick_height + if ind in [2, 7] + else tick.height == default_tick_height + ) + for ind, tick in enumerate(nline.ticks) + ) + + def test_ticks_not_generated_on_origin_for_axes(): axes = Axes( x_range=[-10, 10], diff --git a/tests/test_copy.py b/tests/module/mobject/mobject/test_copy.py similarity index 95% rename from tests/test_copy.py rename to tests/module/mobject/mobject/test_copy.py index ce9f472f7e..39c6afd94c 100644 --- a/tests/test_copy.py +++ b/tests/module/mobject/mobject/test_copy.py @@ -2,7 +2,7 @@ from pathlib import Path -from manim import BraceLabel, Mobject, config +from manim import BraceLabel, Mobject def test_mobject_copy(): @@ -18,7 +18,7 @@ def test_mobject_copy(): assert orig.submobjects[i] is not copy.submobjects[i] -def test_bracelabel_copy(tmp_path): +def test_bracelabel_copy(tmp_path, config): """Test that a copy is a deepcopy.""" # For this test to work, we need to tweak some folders temporarily original_text_dir = config["text_dir"] diff --git a/tests/test_family.py b/tests/module/mobject/mobject/test_family.py similarity index 92% rename from tests/test_family.py rename to tests/module/mobject/mobject/test_family.py index 0e0c1e518b..08856b6533 100644 --- a/tests/test_family.py +++ b/tests/module/mobject/mobject/test_family.py @@ -40,7 +40,11 @@ def test_family(): def test_overlapping_family(): """Check that each member of the family is only gathered once.""" - mob, child1, child2, = ( + ( + mob, + child1, + child2, + ) = ( Mobject(), Mobject(), Mobject(), @@ -64,7 +68,11 @@ def test_shift_family(): """ # Note shift() needs the mobject to have a non-empty `points` attribute, so # we cannot use a plain Mobject or VMobject. We use Circle instead. - mob, child1, child2, = ( + ( + mob, + child1, + child2, + ) = ( Circle(), Circle(), Circle(), @@ -81,4 +89,4 @@ def test_shift_family(): positions_after = {m: m.get_center() for m in family} for m in family: - assert np.allclose(positions_before[m] + RIGHT, positions_after[m]) + np.testing.assert_allclose(positions_before[m] + RIGHT, positions_after[m]) diff --git a/tests/test_get_set.py b/tests/module/mobject/mobject/test_get_set.py similarity index 100% rename from tests/test_get_set.py rename to tests/module/mobject/mobject/test_get_set.py diff --git a/tests/module/mobject/mobject/test_mobject.py b/tests/module/mobject/mobject/test_mobject.py new file mode 100644 index 0000000000..89deea93c9 --- /dev/null +++ b/tests/module/mobject/mobject/test_mobject.py @@ -0,0 +1,170 @@ +from __future__ import annotations + +import numpy as np +import pytest + +from manim import DL, UR, Circle, Mobject, Rectangle, Square, VGroup + + +def test_mobject_add(): + """Test Mobject.add().""" + """Call this function with a Container instance to test its add() method.""" + # check that obj.submobjects is updated correctly + obj = Mobject() + assert len(obj.submobjects) == 0 + obj.add(Mobject()) + assert len(obj.submobjects) == 1 + obj.add(*(Mobject() for _ in range(10))) + assert len(obj.submobjects) == 11 + + # check that adding a mobject twice does not actually add it twice + repeated = Mobject() + obj.add(repeated) + assert len(obj.submobjects) == 12 + obj.add(repeated) + assert len(obj.submobjects) == 12 + + # check that Mobject.add() returns the Mobject (for chained calls) + assert obj.add(Mobject()) is obj + assert len(obj.submobjects) == 13 + + obj = Mobject() + + # a Mobject cannot contain itself + with pytest.raises(ValueError) as add_self_info: + obj.add(Mobject(), obj, Mobject()) + assert str(add_self_info.value) == ( + "Cannot add Mobject as a submobject of itself (at index 1)." + ) + assert len(obj.submobjects) == 0 + + # can only add Mobjects + with pytest.raises(TypeError) as add_str_info: + obj.add(Mobject(), Mobject(), "foo") + assert str(add_str_info.value) == ( + "Only values of type Mobject can be added as submobjects of Mobject, " + "but the value foo (at index 2) is of type str." + ) + assert len(obj.submobjects) == 0 + + +def test_mobject_remove(): + """Test Mobject.remove().""" + obj = Mobject() + to_remove = Mobject() + obj.add(to_remove) + obj.add(*(Mobject() for _ in range(10))) + assert len(obj.submobjects) == 11 + obj.remove(to_remove) + assert len(obj.submobjects) == 10 + obj.remove(to_remove) + assert len(obj.submobjects) == 10 + + assert obj.remove(Mobject()) is obj + + +def test_mobject_dimensions_single_mobject(): + # A Mobject with no points and no submobjects has no dimensions + empty = Mobject() + assert empty.width == 0 + assert empty.height == 0 + assert empty.depth == 0 + + has_points = Mobject() + has_points.points = np.array([[-1, -2, -3], [1, 3, 5]]) + assert has_points.width == 2 + assert has_points.height == 5 + assert has_points.depth == 8 + + rect = Rectangle(width=3, height=5) + + assert rect.width == 3 + assert rect.height == 5 + assert rect.depth == 0 + + # Dimensions should be recalculated after scaling + rect.scale(2.0) + assert rect.width == 6 + assert rect.height == 10 + assert rect.depth == 0 + + # Dimensions should not be dependent on location + rect.move_to([-3, -4, -5]) + assert rect.width == 6 + assert rect.height == 10 + assert rect.depth == 0 + + circ = Circle(radius=2) + + assert circ.width == 4 + assert circ.height == 4 + assert circ.depth == 0 + + +def is_close(x, y): + return abs(x - y) < 0.00001 + + +def test_mobject_dimensions_nested_mobjects(): + vg = VGroup() + + for x in range(-5, 8, 1): + row = VGroup() + vg += row + for y in range(-17, 2, 1): + for z in range(0, 10, 1): + s = Square().move_to([x, y, z / 10]) + row += s + + assert vg.width == 14.0, vg.width + assert vg.height == 20.0, vg.height + assert is_close(vg.depth, 0.9), vg.depth + + # Dimensions should be recalculated after scaling + vg.scale(0.5) + assert vg.width == 7.0, vg.width + assert vg.height == 10.0, vg.height + assert is_close(vg.depth, 0.45), vg.depth + + # Adding a mobject changes the bounds/dimensions + rect = Rectangle(width=3, height=5) + rect.move_to([9, 3, 1]) + vg += rect + assert vg.width == 13.0, vg.width + assert is_close(vg.height, 18.5), vg.height + assert is_close(vg.depth, 0.775), vg.depth + + +def test_mobject_dimensions_mobjects_with_no_points_are_at_origin(): + rect = Rectangle(width=2, height=3) + rect.move_to([-4, -5, 0]) + outer_group = VGroup(rect) + + # This is as one would expect + assert outer_group.width == 2 + assert outer_group.height == 3 + + # Adding a mobject with no points has a quirk of adding a "point" + # to [0, 0, 0] (the origin). This changes the size of the outer + # group because now the bottom left corner is at [-5, -6.5, 0] + # but the upper right corner is [0, 0, 0] instead of [-3, -3.5, 0] + outer_group.add(VGroup()) + assert outer_group.width == 5 + assert outer_group.height == 6.5 + + +def test_mobject_dimensions_has_points_and_children(): + outer_rect = Rectangle(width=3, height=6) + inner_rect = Rectangle(width=2, height=1) + inner_rect.align_to(outer_rect.get_corner(UR), DL) + outer_rect.add(inner_rect) + + # The width of a mobject should depend both on its points and + # the points of all children mobjects. + assert outer_rect.width == 5 # 3 from outer_rect, 2 from inner_rect + assert outer_rect.height == 7 # 6 from outer_rect, 1 from inner_rect + assert outer_rect.depth == 0 + + assert inner_rect.width == 2 + assert inner_rect.height == 1 + assert inner_rect.depth == 0 diff --git a/tests/module/mobject/mobject/test_opengl_metaclass.py b/tests/module/mobject/mobject/test_opengl_metaclass.py new file mode 100644 index 0000000000..930a5616da --- /dev/null +++ b/tests/module/mobject/mobject/test_opengl_metaclass.py @@ -0,0 +1,20 @@ +from __future__ import annotations + +from manim import Mobject +from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL +from manim.mobject.opengl.opengl_mobject import OpenGLMobject + + +def test_metaclass_registry(config): + class SomeTestMobject(Mobject, metaclass=ConvertToOpenGL): + pass + + assert SomeTestMobject in ConvertToOpenGL._converted_classes + + config.renderer = "opengl" + assert OpenGLMobject in SomeTestMobject.__bases__ + assert Mobject not in SomeTestMobject.__bases__ + + config.renderer = "cairo" + assert Mobject in SomeTestMobject.__bases__ + assert OpenGLMobject not in SomeTestMobject.__bases__ diff --git a/tests/test_set_attr.py b/tests/module/mobject/mobject/test_set_attr.py similarity index 69% rename from tests/test_set_attr.py rename to tests/module/mobject/mobject/test_set_attr.py index e04a2286f3..9edfb93bc4 100644 --- a/tests/test_set_attr.py +++ b/tests/module/mobject/mobject/test_set_attr.py @@ -2,25 +2,23 @@ import numpy as np -from manim import config from manim.constants import RIGHT from manim.mobject.geometry.polygram import Square -def test_Data(): - config.renderer = "opengl" +def test_Data(using_opengl_renderer): a = Square().move_to(RIGHT) data_bb = a.data["bounding_box"] - assert np.array_equal( + np.testing.assert_array_equal( data_bb, np.array([[0.0, -1.0, 0.0], [1.0, 0.0, 0.0], [2.0, 1.0, 0.0]]), ) # test that calling the attribute equals calling it from self.data - assert np.array_equal(a.bounding_box, data_bb) + np.testing.assert_array_equal(a.bounding_box, data_bb) # test that the array can be indexed - assert np.array_equal( + np.testing.assert_array_equal( a.bounding_box[1], np.array( [1.0, 0.0, 0.0], @@ -33,10 +31,9 @@ def test_Data(): # test that both the attr and self.data arrays match after adjusting a value data_bb = a.data["bounding_box"] - assert np.array_equal( + np.testing.assert_array_equal( data_bb, np.array([[0.0, -1.0, 0.0], [300.0, 300.0, 300.0], [2.0, 1.0, 0.0]]), ) - assert np.array_equal(a.bounding_box, data_bb) - config.renderer = "cairo" # needs to be here or else the following cairo tests fail + np.testing.assert_array_equal(a.bounding_box, data_bb) diff --git a/tests/module/mobject/svg/test_svg_mobject.py b/tests/module/mobject/svg/test_svg_mobject.py new file mode 100644 index 0000000000..764c4ee64a --- /dev/null +++ b/tests/module/mobject/svg/test_svg_mobject.py @@ -0,0 +1,204 @@ +from __future__ import annotations + +from manim import * +from tests.helpers.path_utils import get_svg_resource + + +def test_set_fill_color(): + expected_color = "#FF862F" + svg = SVGMobject(get_svg_resource("heart.svg"), fill_color=expected_color) + assert svg.fill_color.to_hex() == expected_color + + +def test_set_stroke_color(): + expected_color = "#FFFDDD" + svg = SVGMobject(get_svg_resource("heart.svg"), stroke_color=expected_color) + assert svg.stroke_color.to_hex() == expected_color + + +def test_set_color_sets_fill_and_stroke(): + expected_color = "#EEE777" + svg = SVGMobject(get_svg_resource("heart.svg"), color=expected_color) + assert svg.color.to_hex() == expected_color + assert svg.fill_color.to_hex() == expected_color + assert svg.stroke_color.to_hex() == expected_color + + +def test_set_fill_opacity(): + expected_opacity = 0.5 + svg = SVGMobject(get_svg_resource("heart.svg"), fill_opacity=expected_opacity) + assert svg.fill_opacity == expected_opacity + + +def test_stroke_opacity(): + expected_opacity = 0.4 + svg = SVGMobject(get_svg_resource("heart.svg"), stroke_opacity=expected_opacity) + assert svg.stroke_opacity == expected_opacity + + +def test_fill_overrides_color(): + expected_color = "#343434" + svg = SVGMobject( + get_svg_resource("heart.svg"), + color="#123123", + fill_color=expected_color, + ) + assert svg.fill_color.to_hex() == expected_color + + +def test_stroke_overrides_color(): + expected_color = "#767676" + svg = SVGMobject( + get_svg_resource("heart.svg"), + color="#334433", + stroke_color=expected_color, + ) + assert svg.stroke_color.to_hex() == expected_color + + +def test_single_path_turns_into_sequence_of_points(): + svg = SVGMobject( + get_svg_resource("cubic_and_lineto.svg"), + ) + assert len(svg.points) == 0, svg.points + assert len(svg.submobjects) == 1, svg.submobjects + path = svg.submobjects[0] + np.testing.assert_almost_equal( + path.points, + np.array( + [ + [-0.166666666666666, 0.66666666666666, 0.0], + [-0.166666666666666, 0.0, 0.0], + [0.5, 0.66666666666666, 0.0], + [0.5, 0.0, 0.0], + [0.5, 0.0, 0.0], + [-0.16666666666666666, 0.0, 0.0], + [0.5, -0.6666666666666666, 0.0], + [-0.166666666666666, -0.66666666666666, 0.0], + [-0.166666666666666, -0.66666666666666, 0.0], + [-0.27777777777777, -0.77777777777777, 0.0], + [-0.38888888888888, -0.88888888888888, 0.0], + [-0.5, -1.0, 0.0], + [-0.5, -1.0, 0.0], + [-0.5, -0.333333333333, 0.0], + [-0.5, 0.3333333333333, 0.0], + [-0.5, 1.0, 0.0], + [-0.5, 1.0, 0.0], + [-0.38888888888888, 0.8888888888888, 0.0], + [-0.27777777777777, 0.7777777777777, 0.0], + [-0.16666666666666, 0.6666666666666, 0.0], + ] + ), + decimal=5, + ) + + +def test_closed_path_does_not_have_extra_point(): + # This dash.svg is the output of a "-" as generated from LaTex. + # It ends back where it starts, so we shouldn't see a final line. + svg = SVGMobject( + get_svg_resource("dash.svg"), + ) + assert len(svg.points) == 0, svg.points + assert len(svg.submobjects) == 1, svg.submobjects + dash = svg.submobjects[0] + np.testing.assert_almost_equal( + dash.points, + np.array( + [ + [13.524988331417841, -1.0, 0], + [14.374988080480586, -1.0, 0], + [15.274984567359079, -1.0, 0], + [15.274984567359079, 0.0, 0.0], + [15.274984567359079, 0.0, 0.0], + [15.274984567359079, 1.0, 0.0], + [14.374988080480586, 1.0, 0.0], + [13.524988331417841, 1.0, 0.0], + [13.524988331417841, 1.0, 0.0], + [4.508331116720995, 1.0, 0], + [-4.508326097975995, 1.0, 0.0], + [-13.524983312672841, 1.0, 0.0], + [-13.524983312672841, 1.0, 0.0], + [-14.374983061735586, 1.0, 0.0], + [-15.274984567359079, 1.0, 0.0], + [-15.274984567359079, 0.0, 0.0], + [-15.274984567359079, 0.0, 0.0], + [-15.274984567359079, -1.0, 0], + [-14.374983061735586, -1.0, 0], + [-13.524983312672841, -1.0, 0], + [-13.524983312672841, -1.0, 0], + [-4.508326097975995, -1.0, 0], + [4.508331116720995, -1.0, 0], + [13.524988331417841, -1.0, 0], + ] + ), + decimal=5, + ) + + +def test_close_command_closes_last_move_not_the_starting_one(): + # This A.svg is the output of a Text("A") in some systems + # It contains a path that moves from the outer boundary of the A + # to the boundary of the inner triangle, and then closes the path + # which should close the inner triangle and not the outer boundary. + svg = SVGMobject( + get_svg_resource("A.svg"), + ) + assert len(svg.points) == 0, svg.points + assert len(svg.submobjects) == 1, svg.submobjects + capital_A = svg.submobjects[0] + + # The last point should not be the same as the first point + assert not all(capital_A.points[0] == capital_A.points[-1]) + np.testing.assert_almost_equal( + capital_A.points, + np.array( + [ + [-0.8380339075214888, -1.0, 1.2246467991473532e-16], + [-0.6132152047642527, -0.3333333333333336, 4.082155997157847e-17], + [-0.388396502007016, 0.3333333333333336, -4.082155997157847e-17], + [-0.16357779924977994, 1.0, -1.2246467991473532e-16], + [-0.16357779924977994, 1.0, -1.2246467991473532e-16], + [-0.05425733591657368, 1.0, -1.2246467991473532e-16], + [0.05506312741663405, 1.0, -1.2246467991473532e-16], + [0.16438359074984032, 1.0, -1.2246467991473532e-16], + [0.16438359074984032, 1.0, -1.2246467991473532e-16], + [0.3889336963403905, 0.3333333333333336, -4.082155997157847e-17], + [0.6134838019309422, -0.3333333333333336, 4.082155997157847e-17], + [0.8380339075214923, -1.0, 1.2246467991473532e-16], + [0.8380339075214923, -1.0, 1.2246467991473532e-16], + [0.744560897060354, -1.0, 1.2246467991473532e-16], + [0.6510878865992157, -1.0, 1.2246467991473532e-16], + [0.5576148761380774, -1.0, 1.2246467991473532e-16], + [0.5576148761380774, -1.0, 1.2246467991473532e-16], + [0.49717968849274957, -0.8138597980824822, 9.966907966764229e-17], + [0.4367445008474217, -0.6277195961649644, 7.687347942054928e-17], + [0.3763093132020939, -0.4415793942474466, 5.407787917345625e-17], + [0.3763093132020939, -0.4415793942474466, 5.407787917345625e-17], + [0.12167600863867864, -0.4415793942474466, 5.407787917345625e-17], + [-0.13295729592473662, -0.4415793942474466, 5.407787917345625e-17], + [-0.38759060048815186, -0.4415793942474466, 5.407787917345625e-17], + [-0.38759060048815186, -0.4415793942474466, 5.407787917345625e-17], + [-0.4480257881334797, -0.6277195961649644, 7.687347942054928e-17], + [-0.5084609757788076, -0.8138597980824822, 9.966907966764229e-17], + [-0.5688961634241354, -1.0, 1.2246467991473532e-16], + [-0.5688961634241354, -1.0, 1.2246467991473532e-16], + [-0.6586087447899202, -1.0, 1.2246467991473532e-16], + [-0.7483213261557048, -1.0, 1.2246467991473532e-16], + [-0.8380339075214888, -1.0, 1.2246467991473532e-16], + [0.3021757525699033, -0.21434317946653003, 2.6249468865275272e-17], + [0.1993017037512583, 0.09991949373745423, -1.2236608817799732e-17], + [0.09642765493261184, 0.4141821669414385, -5.072268650087473e-17], + [-0.006446393886033166, 0.7284448401454228, -8.920876418394973e-17], + [-0.006446393886033166, 0.7284448401454228, -8.920876418394973e-17], + [-0.10905185929034443, 0.4141821669414385, -5.072268650087473e-17], + [-0.2116573246946542, 0.09991949373745423, -1.2236608817799732e-17], + [-0.31426279009896546, -0.21434317946653003, 2.6249468865275272e-17], + [-0.31426279009896546, -0.21434317946653003, 2.6249468865275272e-17], + [-0.10878327587600921, -0.21434317946653003, 2.6249468865275272e-17], + [0.09669623834694704, -0.21434317946653003, 2.6249468865275272e-17], + [0.3021757525699033, -0.21434317946653003, 2.6249468865275272e-17], + ] + ), + decimal=5, + ) diff --git a/tests/test_boolean_ops.py b/tests/module/mobject/test_boolean_ops.py similarity index 92% rename from tests/test_boolean_ops.py rename to tests/module/mobject/test_boolean_ops.py index 30ea229062..b3560e87fa 100644 --- a/tests/test_boolean_ops.py +++ b/tests/module/mobject/test_boolean_ops.py @@ -8,7 +8,7 @@ @pytest.mark.parametrize( - "test_input,expected", + ("test_input", "expected"), [ ( [(1.0, 2.0), (3.0, 4.0)], @@ -55,4 +55,4 @@ def test_vmobject_to_skia_path_and_inverse(test_input): new_vmobject = a._convert_skia_path_to_vmobject(path) # for some reason there is an extra 4 points in new vmobject than original - assert np.where(np.isclose(new_vmobject.points[:-4], test_input.points)) + np.testing.assert_allclose(new_vmobject.points[:-4], test_input.points) diff --git a/tests/module/mobject/test_graph.py b/tests/module/mobject/test_graph.py new file mode 100644 index 0000000000..b23ccff622 --- /dev/null +++ b/tests/module/mobject/test_graph.py @@ -0,0 +1,180 @@ +from __future__ import annotations + +import pytest + +from manim import DiGraph, Graph, Scene, Text, tempconfig +from manim.mobject.graph import _layouts + + +def test_graph_creation(): + vertices = [1, 2, 3, 4] + edges = [(1, 2), (2, 3), (3, 4), (4, 1)] + layout = {1: [0, 0, 0], 2: [1, 1, 0], 3: [1, -1, 0], 4: [-1, 0, 0]} + G_manual = Graph(vertices=vertices, edges=edges, layout=layout) + assert str(G_manual) == "Undirected graph on 4 vertices and 4 edges" + G_spring = Graph(vertices=vertices, edges=edges) + assert str(G_spring) == "Undirected graph on 4 vertices and 4 edges" + G_directed = DiGraph(vertices=vertices, edges=edges) + assert str(G_directed) == "Directed graph on 4 vertices and 4 edges" + + +def test_graph_add_vertices(): + G = Graph([1, 2, 3], [(1, 2), (2, 3)]) + G.add_vertices(4) + assert str(G) == "Undirected graph on 4 vertices and 2 edges" + G.add_vertices(5, labels={5: Text("5")}) + assert str(G) == "Undirected graph on 5 vertices and 2 edges" + assert 5 in G._labels + assert 5 in G._vertex_config + G.add_vertices(6, 7, 8) + assert len(G.vertices) == 8 + assert len(G._graph.nodes()) == 8 + + +def test_graph_remove_vertices(): + G = Graph([1, 2, 3, 4, 5], [(1, 2), (2, 3), (3, 4), (4, 5)]) + removed_mobjects = G.remove_vertices(3) + assert len(removed_mobjects) == 3 + assert str(G) == "Undirected graph on 4 vertices and 2 edges" + assert list(G.vertices.keys()) == [1, 2, 4, 5] + assert list(G.edges.keys()) == [(1, 2), (4, 5)] + removed_mobjects = G.remove_vertices(4, 5) + assert len(removed_mobjects) == 3 + assert str(G) == "Undirected graph on 2 vertices and 1 edges" + assert list(G.vertices.keys()) == [1, 2] + assert list(G.edges.keys()) == [(1, 2)] + + +def test_graph_add_edges(): + G = Graph([1, 2, 3, 4, 5], [(1, 2), (2, 3)]) + added_mobjects = G.add_edges((1, 3)) + assert str(added_mobjects.submobjects) == "[Line]" + assert str(G) == "Undirected graph on 5 vertices and 3 edges" + assert set(G.vertices.keys()) == {1, 2, 3, 4, 5} + assert set(G.edges.keys()) == {(1, 2), (2, 3), (1, 3)} + + added_mobjects = G.add_edges((1, 42)) + assert str(added_mobjects.submobjects) == "[Dot, Line]" + assert str(G) == "Undirected graph on 6 vertices and 4 edges" + assert set(G.vertices.keys()) == {1, 2, 3, 4, 5, 42} + assert set(G.edges.keys()) == {(1, 2), (2, 3), (1, 3), (1, 42)} + + added_mobjects = G.add_edges((4, 5), (5, 6), (6, 7)) + assert len(added_mobjects) == 5 + assert str(G) == "Undirected graph on 8 vertices and 7 edges" + assert set(G.vertices.keys()) == {1, 2, 3, 4, 5, 42, 6, 7} + assert set(G._graph.nodes()) == set(G.vertices.keys()) + assert set(G.edges.keys()) == { + (1, 2), + (2, 3), + (1, 3), + (1, 42), + (4, 5), + (5, 6), + (6, 7), + } + assert set(G._graph.edges()) == set(G.edges.keys()) + + +def test_graph_remove_edges(): + G = Graph([1, 2, 3, 4, 5], [(1, 2), (2, 3), (3, 4), (4, 5), (1, 5)]) + removed_mobjects = G.remove_edges((1, 2)) + assert str(removed_mobjects.submobjects) == "[Line]" + assert str(G) == "Undirected graph on 5 vertices and 4 edges" + assert set(G.edges.keys()) == {(2, 3), (3, 4), (4, 5), (1, 5)} + assert set(G._graph.edges()) == set(G.edges.keys()) + + removed_mobjects = G.remove_edges((2, 3), (3, 4), (4, 5), (1, 5)) + assert len(removed_mobjects) == 4 + assert str(G) == "Undirected graph on 5 vertices and 0 edges" + assert set(G._graph.edges()) == set() + assert set(G.edges.keys()) == set() + + +def test_custom_animation_mobject_list(): + G = Graph([1, 2, 3], [(1, 2), (2, 3)]) + scene = Scene() + scene.add(G) + assert scene.mobjects == [G] + with tempconfig({"dry_run": True, "quality": "low_quality"}): + scene.play(G.animate.add_vertices(4)) + assert str(G) == "Undirected graph on 4 vertices and 2 edges" + assert scene.mobjects == [G] + scene.play(G.animate.remove_vertices(2)) + assert str(G) == "Undirected graph on 3 vertices and 0 edges" + assert scene.mobjects == [G] + + +def test_custom_graph_layout_dict(): + G = Graph( + [1, 2, 3], [(1, 2), (2, 3)], layout={1: [0, 0, 0], 2: [1, 1, 0], 3: [1, -1, 0]} + ) + assert str(G) == "Undirected graph on 3 vertices and 2 edges" + assert all(G.vertices[1].get_center() == [0, 0, 0]) + assert all(G.vertices[2].get_center() == [1, 1, 0]) + assert all(G.vertices[3].get_center() == [1, -1, 0]) + + +def test_graph_layouts(): + for layout in (layout for layout in _layouts if layout not in ["tree", "partite"]): + G = Graph([1, 2, 3], [(1, 2), (2, 3)], layout=layout) + assert str(G) == "Undirected graph on 3 vertices and 2 edges" + + +def test_tree_layout(): + G = Graph([1, 2, 3], [(1, 2), (2, 3)], layout="tree", root_vertex=1) + assert str(G) == "Undirected graph on 3 vertices and 2 edges" + + +def test_partite_layout(): + G = Graph( + [1, 2, 3, 4, 5], + [(1, 2), (2, 3), (3, 4), (4, 5)], + layout="partite", + partitions=[[1, 2], [3, 4, 5]], + ) + assert str(G) == "Undirected graph on 5 vertices and 4 edges" + + +def test_custom_graph_layout_function(): + def layout_func(graph, scale): + return {vertex: [vertex, vertex, 0] for vertex in graph} + + G = Graph([1, 2, 3], [(1, 2), (2, 3)], layout=layout_func) + assert all(G.vertices[1].get_center() == [1, 1, 0]) + assert all(G.vertices[2].get_center() == [2, 2, 0]) + assert all(G.vertices[3].get_center() == [3, 3, 0]) + + +def test_custom_graph_layout_function_with_kwargs(): + def layout_func(graph, scale, offset): + return { + vertex: [vertex * scale + offset, vertex * scale + offset, 0] + for vertex in graph + } + + G = Graph( + [1, 2, 3], [(1, 2), (2, 3)], layout=layout_func, layout_config={"offset": 1} + ) + assert all(G.vertices[1].get_center() == [3, 3, 0]) + assert all(G.vertices[2].get_center() == [5, 5, 0]) + assert all(G.vertices[3].get_center() == [7, 7, 0]) + + +def test_graph_change_layout(): + for layout in (layout for layout in _layouts if layout not in ["tree", "partite"]): + G = Graph([1, 2, 3], [(1, 2), (2, 3)]) + G.change_layout(layout=layout) + assert str(G) == "Undirected graph on 3 vertices and 2 edges" + + +def test_tree_layout_no_root_error(): + with pytest.raises(ValueError) as excinfo: + G = Graph([1, 2, 3], [(1, 2), (2, 3)], layout="tree") + assert str(excinfo.value) == "The tree layout requires the root_vertex parameter" + + +def test_tree_layout_not_tree_error(): + with pytest.raises(ValueError) as excinfo: + G = Graph([1, 2, 3], [(1, 2), (2, 3), (3, 1)], layout="tree", root_vertex=1) + assert str(excinfo.value) == "The tree layout must be used with trees" diff --git a/tests/module/mobject/test_image.py b/tests/module/mobject/test_image.py new file mode 100644 index 0000000000..a79fce5b8a --- /dev/null +++ b/tests/module/mobject/test_image.py @@ -0,0 +1,14 @@ +import numpy as np +import pytest + +from manim import ImageMobject + + +@pytest.mark.parametrize("dtype", [np.uint8, np.uint16]) +def test_invert_image(dtype): + array = (255 * np.random.rand(10, 10, 4)).astype(dtype) + image = ImageMobject(array, pixel_array_dtype=dtype, invert=True) + assert image.pixel_array.dtype == dtype + + array[:, :, :3] = np.iinfo(dtype).max - array[:, :, :3] + assert np.allclose(array, image.pixel_array) diff --git a/tests/test_value_tracker.py b/tests/module/mobject/test_value_tracker.py similarity index 100% rename from tests/test_value_tracker.py rename to tests/module/mobject/test_value_tracker.py diff --git a/tests/test_markup.py b/tests/module/mobject/text/test_markup.py similarity index 89% rename from tests/test_markup.py rename to tests/module/mobject/text/test_markup.py index abe1d9333b..d8cd0cafd5 100644 --- a/tests/test_markup.py +++ b/tests/module/mobject/text/test_markup.py @@ -22,9 +22,9 @@ def test_special_tags_markup(): success = True except ValueError: success = False - assert ( - success - ), '\'foo\' and \'foo\' should not fail validation' + assert success, ( + '\'foo\' and \'foo\' should not fail validation' + ) def test_unbalanced_tag_markup(): diff --git a/tests/test_numbers.py b/tests/module/mobject/text/test_numbers.py similarity index 86% rename from tests/test_numbers.py rename to tests/module/mobject/text/test_numbers.py index 350a527b3b..7e46e83dea 100644 --- a/tests/test_numbers.py +++ b/tests/module/mobject/text/test_numbers.py @@ -1,13 +1,12 @@ from __future__ import annotations -from colour import Color - from manim import RED, DecimalNumber, Integer def test_font_size(): """Test that DecimalNumber returns the correct font_size value - after being scaled.""" + after being scaled. + """ num = DecimalNumber(0).scale(0.3) assert round(num.font_size, 5) == 14.4 @@ -41,7 +40,10 @@ def test_set_value_size(): def test_color_when_number_of_digits_changes(): """Test that all digits of an Integer are colored correctly when - the number of digits changes.""" + the number of digits changes. + """ mob = Integer(color=RED) mob.set_value(42) - assert all([submob.stroke_color == Color(RED) for submob in mob.submobjects]) + assert all( + submob.stroke_color.to_hex() == RED.to_hex() for submob in mob.submobjects + ) diff --git a/tests/test_texmobject.py b/tests/module/mobject/text/test_texmobject.py similarity index 66% rename from tests/test_texmobject.py rename to tests/module/mobject/text/test_texmobject.py index 8e0420a230..ca8e635ea6 100644 --- a/tests/test_texmobject.py +++ b/tests/module/mobject/text/test_texmobject.py @@ -2,25 +2,24 @@ from pathlib import Path +import numpy as np import pytest -from manim import MathTex, SingleStringMathTex, Tex, TexTemplate, config -from manim.mobject.types.vectorized_mobject import VMobject -from manim.utils.color import RED +from manim import MathTex, SingleStringMathTex, Tex, TexTemplate, tempconfig -def test_MathTex(): +def test_MathTex(config): MathTex("a^2 + b^2 = c^2") - assert Path(config.media_dir, "Tex", "3879f6b03bc495cd.svg").exists() + assert Path(config.media_dir, "Tex", "e4be163a00cf424f.svg").exists() -def test_SingleStringMathTex(): +def test_SingleStringMathTex(config): SingleStringMathTex("test") - assert Path(config.media_dir, "Tex", "79822967f1fa1935.svg").exists() + assert Path(config.media_dir, "Tex", "8ce17c7f5013209f.svg").exists() @pytest.mark.parametrize( # : PT006 - "text_input,length_sub", + ("text_input", "length_sub"), [("{{ a }} + {{ b }} = {{ c }}", 5), (r"\frac{1}{a+b\sqrt{2}}", 1)], ) def test_double_braces_testing(text_input, length_sub): @@ -28,14 +27,27 @@ def test_double_braces_testing(text_input, length_sub): assert len(t1.submobjects) == length_sub -def test_tex(): +def test_tex(config): Tex("The horse does not eat cucumber salad.") - assert Path(config.media_dir, "Tex", "983949cac5bdd272.svg").exists() + assert Path(config.media_dir, "Tex", "c3945e23e546c95a.svg").exists() -def test_percent_char_rendering(): +def test_tex_temp_directory(tmpdir, monkeypatch): + # Adds a test for #3060 + # It's not possible to reproduce the issue normally, because we use + # tempconfig to change media directory to temporary directory by default + # we partially, revert that change here. + monkeypatch.chdir(tmpdir) + Path(tmpdir, "media").mkdir() + with tempconfig({"media_dir": "media"}): + Tex("The horse does not eat cucumber salad.") + assert Path("media", "Tex").exists() + assert Path("media", "Tex", "c3945e23e546c95a.svg").exists() + + +def test_percent_char_rendering(config): Tex(r"\%") - assert Path(config.media_dir, "Tex", "ce6e53f2d9c537bb.tex").exists() + assert Path(config.media_dir, "Tex", "4a583af4d19a3adf.tex").exists() def test_tex_whitespace_arg(): @@ -83,6 +95,23 @@ def test_tex_white_space_and_non_whitespace_args(): assert len(tex[3]) == len("".join(str_part_4.split())) +def test_multi_part_tex_with_empty_parts(): + """Check that if a Tex or MathTex Mobject with multiple + string arguments is created where some of the parts render + as empty SVGs, then the number of family members with points + should still be the same as the snipped in one singular part. + """ + tex_parts = ["(-1)", "^{", "0}"] + one_part_fomula = MathTex("".join(tex_parts)) + multi_part_formula = MathTex(*tex_parts) + + for one_part_glyph, multi_part_glyph in zip( + one_part_fomula.family_members_with_points(), + multi_part_formula.family_members_with_points(), + ): + np.testing.assert_allclose(one_part_glyph.points, multi_part_glyph.points) + + def test_tex_size(): """Check that the size of a :class:`Tex` string is not changed.""" text = Tex("what").center() @@ -94,7 +123,8 @@ def test_tex_size(): def test_font_size(): """Test that tex_mobject classes return - the correct font_size value after being scaled.""" + the correct font_size value after being scaled. + """ string = MathTex(0).scale(0.3) assert round(string.font_size, 5) == 14.4 @@ -165,9 +195,33 @@ def test_error_in_nested_context(capsys): \end{align} """ - with pytest.raises(ValueError) as err: + with pytest.raises(ValueError): Tex(invalid_tex) stdout = str(capsys.readouterr().out) # validate useless context is not included assert r"\begin{frame}" not in stdout + + +def test_tempconfig_resetting_tex_template(config): + my_template = TexTemplate() + my_template.preamble = "Custom preamble!" + with tempconfig({"tex_template": my_template}): + assert config.tex_template.preamble == "Custom preamble!" + + assert config.tex_template.preamble != "Custom preamble!" + + +def test_tex_garbage_collection(tmpdir, monkeypatch, config): + monkeypatch.chdir(tmpdir) + Path(tmpdir, "media").mkdir() + config.media_dir = "media" + + tex_without_log = Tex("Hello World!") # d771330b76d29ffb.tex + assert Path("media", "Tex", "d771330b76d29ffb.tex").exists() + assert not Path("media", "Tex", "d771330b76d29ffb.log").exists() + + config.no_latex_cleanup = True + + tex_with_log = Tex("Hello World, again!") # da27670a37b08799.tex + assert Path("media", "Tex", "da27670a37b08799.log").exists() diff --git a/tests/module/mobject/text/test_text_mobject.py b/tests/module/mobject/text/test_text_mobject.py new file mode 100644 index 0000000000..2e656b90ae --- /dev/null +++ b/tests/module/mobject/text/test_text_mobject.py @@ -0,0 +1,34 @@ +from __future__ import annotations + +from contextlib import redirect_stdout +from io import StringIO + +from manim.mobject.text.text_mobject import MarkupText, Text + + +def test_font_size(): + """Test that Text and MarkupText return the + correct font_size value after being scaled. + """ + text_string = Text("0").scale(0.3) + markuptext_string = MarkupText("0").scale(0.3) + + assert round(text_string.font_size, 5) == 14.4 + assert round(markuptext_string.font_size, 5) == 14.4 + + +def test_font_warnings(): + def warning_printed(font: str, **kwargs) -> bool: + io = StringIO() + with redirect_stdout(io): + Text("hi!", font=font, **kwargs) + txt = io.getvalue() + return "Font" in txt and "not in" in txt + + # check for normal fonts (no warning) + assert not warning_printed("System-ui", warn_missing_font=True) + # should be converted to sans before checking + assert not warning_printed("Sans-serif", warn_missing_font=True) + + # check random string (should be warning) + assert warning_printed("Manim!" * 3, warn_missing_font=True) diff --git a/tests/module/mobject/types/vectorized_mobject/test_stroke.py b/tests/module/mobject/types/vectorized_mobject/test_stroke.py new file mode 100644 index 0000000000..25c09cd294 --- /dev/null +++ b/tests/module/mobject/types/vectorized_mobject/test_stroke.py @@ -0,0 +1,63 @@ +from __future__ import annotations + +import manim.utils.color as C +from manim import VMobject +from manim.mobject.vector_field import StreamLines + + +def test_stroke_props_in_ctor(): + m = VMobject(stroke_color=C.ORANGE, stroke_width=10) + assert m.stroke_color.to_hex() == C.ORANGE.to_hex() + assert m.stroke_width == 10 + + +def test_set_stroke(): + m = VMobject() + m.set_stroke(color=C.ORANGE, width=2, opacity=0.8) + assert m.stroke_width == 2 + assert m.stroke_opacity == 0.8 + assert m.stroke_color.to_hex() == C.ORANGE.to_hex() + + +def test_set_background_stroke(): + m = VMobject() + m.set_stroke(color=C.ORANGE, width=2, opacity=0.8, background=True) + assert m.background_stroke_width == 2 + assert m.background_stroke_opacity == 0.8 + assert m.background_stroke_color.to_hex() == C.ORANGE.to_hex() + + +def test_streamline_attributes_for_single_color(): + vector_field = StreamLines( + lambda x: x, # It is not important what this function is. + x_range=[-1, 1, 0.1], + y_range=[-1, 1, 0.1], + padding=0.1, + stroke_width=1.0, + opacity=0.2, + color=C.BLUE_D, + ) + assert vector_field[0].stroke_width == 1.0 + assert vector_field[0].stroke_opacity == 0.2 + + +def test_stroke_scale(): + a = VMobject() + b = VMobject() + a.set_stroke(width=50) + b.set_stroke(width=50) + a.scale(0.5) + b.scale(0.5, scale_stroke=True) + assert a.get_stroke_width() == 50 + assert b.get_stroke_width() == 25 + + +def test_background_stroke_scale(): + a = VMobject() + b = VMobject() + a.set_stroke(width=50, background=True) + b.set_stroke(width=50, background=True) + a.scale(0.5) + b.scale(0.5, scale_stroke=True) + assert a.get_stroke_width(background=True) == 50 + assert b.get_stroke_width(background=True) == 25 diff --git a/tests/module/mobject/types/vectorized_mobject/test_vectorized_mobject.py b/tests/module/mobject/types/vectorized_mobject/test_vectorized_mobject.py new file mode 100644 index 0000000000..23d5e008d8 --- /dev/null +++ b/tests/module/mobject/types/vectorized_mobject/test_vectorized_mobject.py @@ -0,0 +1,528 @@ +from math import cos, sin + +import numpy as np +import pytest + +from manim import ( + Circle, + CurvesAsSubmobjects, + Line, + Mobject, + Polygon, + RegularPolygon, + Square, + VDict, + VGroup, + VMobject, +) +from manim.constants import PI + + +def test_vmobject_add(): + """Test the VMobject add method.""" + obj = VMobject() + assert len(obj.submobjects) == 0 + + obj.add(VMobject()) + assert len(obj.submobjects) == 1 + + # Can't add non-VMobject values to a VMobject. + with pytest.raises(TypeError) as add_int_info: + obj.add(3) + assert str(add_int_info.value) == ( + "Only values of type VMobject can be added as submobjects of VMobject, " + "but the value 3 (at index 0) is of type int." + ) + assert len(obj.submobjects) == 1 + + # Plain Mobjects can't be added to a VMobject if they're not + # VMobjects. Suggest adding them into a Group instead. + with pytest.raises(TypeError) as add_mob_info: + obj.add(Mobject()) + assert str(add_mob_info.value) == ( + "Only values of type VMobject can be added as submobjects of VMobject, " + "but the value Mobject (at index 0) is of type Mobject. You can try " + "adding this value into a Group instead." + ) + assert len(obj.submobjects) == 1 + + with pytest.raises(TypeError) as add_vmob_and_mob_info: + # If only one of the added objects is not an instance of VMobject, none of them should be added + obj.add(VMobject(), Mobject()) + assert str(add_vmob_and_mob_info.value) == ( + "Only values of type VMobject can be added as submobjects of VMobject, " + "but the value Mobject (at index 1) is of type Mobject. You can try " + "adding this value into a Group instead." + ) + assert len(obj.submobjects) == 1 + + # A VMobject or VGroup cannot contain itself. + with pytest.raises(ValueError) as add_self_info: + obj.add(obj) + assert str(add_self_info.value) == ( + "Cannot add VMobject as a submobject of itself (at index 0)." + ) + assert len(obj.submobjects) == 1 + + +def test_vmobject_add_points_as_corners(): + points = np.array( + [ + [2, 0, 0], + [1, 1, 0], + [-1, 1, 0], + [-2, 0, 0], + [-1, -1, 0], + [1, -1, 0], + [2, 0, 0], + ] + ) + + # Test that add_points_as_corners(points) is equivalent to calling + # add_line_to(point) for every point in points. + obj1 = VMobject().start_new_path(points[0]).add_points_as_corners(points[1:]) + obj2 = VMobject().start_new_path(points[0]) + for point in points[1:]: + obj2.add_line_to(point) + np.testing.assert_allclose(obj1.points, obj2.points) + + # Test that passing an array with no points does nothing. + obj3 = VMobject().start_new_path(points[0]) + points3_old = obj3.points.copy() + obj3.add_points_as_corners([]) + np.testing.assert_allclose(points3_old, obj3.points) + + obj3.add_points_as_corners(points[1:]).add_points_as_corners([]) + np.testing.assert_allclose(obj1.points, obj3.points) + + +def test_vmobject_point_from_proportion(): + obj = VMobject() + + # One long line, one short line + obj.set_points_as_corners( + [ + np.array([0, 0, 0]), + np.array([4, 0, 0]), + np.array([4, 2, 0]), + ], + ) + + # Total length of 6, so halfway along the object + # would be at length 3, which lands in the first, long line. + np.testing.assert_array_equal(obj.point_from_proportion(0.5), np.array([3, 0, 0])) + + with pytest.raises(ValueError, match="between 0 and 1"): + obj.point_from_proportion(2) + + obj.clear_points() + with pytest.raises(Exception, match="with no points"): + obj.point_from_proportion(0) + + +def test_curves_as_submobjects_point_from_proportion(): + obj = CurvesAsSubmobjects(VGroup()) + + with pytest.raises(ValueError, match="between 0 and 1"): + obj.point_from_proportion(2) + with pytest.raises(Exception, match="with no submobjects"): + obj.point_from_proportion(0) + + obj.add(VMobject()) + with pytest.raises(Exception, match="have no points"): + obj.point_from_proportion(0) + + # submobject[0] is a line of length 4 + obj.submobjects[0].set_points_as_corners( + [ + np.array([0, 0, 0]), + np.array([4, 0, 0]), + ], + ) + obj.add(VMobject()) + # submobject[1] is a line of length 2 + obj.submobjects[1].set_points_as_corners( + [ + np.array([4, 0, 0]), + np.array([4, 2, 0]), + ], + ) + + # point at proportion 0.5 should be at length 3, point [3, 0, 0] + np.testing.assert_array_equal(obj.point_from_proportion(0.5), np.array([3, 0, 0])) + + +def test_vgroup_init(): + """Test the VGroup instantiation.""" + VGroup() + VGroup(VMobject()) + VGroup(VMobject(), VMobject()) + + # A VGroup cannot contain non-VMobject values. + with pytest.raises(TypeError) as init_with_float_info: + VGroup(3.0) + assert str(init_with_float_info.value) == ( + "Only values of type VMobject can be added as submobjects of VGroup, " + "but the value 3.0 (at index 0 of parameter 0) is of type float." + ) + + with pytest.raises(TypeError) as init_with_mob_info: + VGroup(Mobject()) + assert str(init_with_mob_info.value) == ( + "Only values of type VMobject can be added as submobjects of VGroup, " + "but the value Mobject (at index 0 of parameter 0) is of type Mobject. You can try " + "adding this value into a Group instead." + ) + + with pytest.raises(TypeError) as init_with_vmob_and_mob_info: + VGroup(VMobject(), Mobject()) + assert str(init_with_vmob_and_mob_info.value) == ( + "Only values of type VMobject can be added as submobjects of VGroup, " + "but the value Mobject (at index 0 of parameter 1) is of type Mobject. You can try " + "adding this value into a Group instead." + ) + + +def test_vgroup_init_with_iterable(): + """Test VGroup instantiation with an iterable type.""" + + def type_generator(type_to_generate, n): + return (type_to_generate() for _ in range(n)) + + def mixed_type_generator(major_type, minor_type, minor_type_positions, n): + return ( + minor_type() if i in minor_type_positions else major_type() + for i in range(n) + ) + + obj = VGroup(VMobject()) + assert len(obj.submobjects) == 1 + + obj = VGroup(type_generator(VMobject, 38)) + assert len(obj.submobjects) == 38 + + obj = VGroup(VMobject(), [VMobject(), VMobject()], type_generator(VMobject, 38)) + assert len(obj.submobjects) == 41 + + # A VGroup cannot be initialised with an iterable containing a Mobject + with pytest.raises(TypeError) as init_with_mob_iterable: + VGroup(type_generator(Mobject, 5)) + assert str(init_with_mob_iterable.value) == ( + "Only values of type VMobject can be added as submobjects of VGroup, " + "but the value Mobject (at index 0 of parameter 0) is of type Mobject." + ) + + # A VGroup cannot be initialised with an iterable containing a Mobject in any position + with pytest.raises(TypeError) as init_with_mobs_and_vmobs_iterable: + VGroup(mixed_type_generator(VMobject, Mobject, [3, 5], 7)) + assert str(init_with_mobs_and_vmobs_iterable.value) == ( + "Only values of type VMobject can be added as submobjects of VGroup, " + "but the value Mobject (at index 3 of parameter 0) is of type Mobject." + ) + + # A VGroup cannot be initialised with an iterable containing non VMobject's in any position + with pytest.raises(TypeError) as init_with_float_and_vmobs_iterable: + VGroup(mixed_type_generator(VMobject, float, [6, 7], 9)) + assert str(init_with_float_and_vmobs_iterable.value) == ( + "Only values of type VMobject can be added as submobjects of VGroup, " + "but the value 0.0 (at index 6 of parameter 0) is of type float." + ) + + +def test_vgroup_add(): + """Test the VGroup add method.""" + obj = VGroup() + assert len(obj.submobjects) == 0 + + obj.add(VMobject()) + assert len(obj.submobjects) == 1 + + # Can't add non-VMobject values to a VMobject or VGroup. + with pytest.raises(TypeError) as add_int_info: + obj.add(3) + assert str(add_int_info.value) == ( + "Only values of type VMobject can be added as submobjects of VGroup, " + "but the value 3 (at index 0 of parameter 0) is of type int." + ) + assert len(obj.submobjects) == 1 + + # Plain Mobjects can't be added to a VMobject or VGroup if they're not + # VMobjects. Suggest adding them into a Group instead. + with pytest.raises(TypeError) as add_mob_info: + obj.add(Mobject()) + assert str(add_mob_info.value) == ( + "Only values of type VMobject can be added as submobjects of VGroup, " + "but the value Mobject (at index 0 of parameter 0) is of type Mobject. You can try " + "adding this value into a Group instead." + ) + assert len(obj.submobjects) == 1 + + with pytest.raises(TypeError) as add_vmob_and_mob_info: + # If only one of the added objects is not an instance of VMobject, none of them should be added + obj.add(VMobject(), Mobject()) + assert str(add_vmob_and_mob_info.value) == ( + "Only values of type VMobject can be added as submobjects of VGroup, " + "but the value Mobject (at index 0 of parameter 1) is of type Mobject. You can try " + "adding this value into a Group instead." + ) + assert len(obj.submobjects) == 1 + + # A VMobject or VGroup cannot contain itself. + with pytest.raises(ValueError) as add_self_info: + obj.add(obj) + assert str(add_self_info.value) == ( + "Cannot add VGroup as a submobject of itself (at index 0)." + ) + assert len(obj.submobjects) == 1 + + +def test_vgroup_add_dunder(): + """Test the VGroup __add__ magic method.""" + obj = VGroup() + assert len(obj.submobjects) == 0 + obj + VMobject() + assert len(obj.submobjects) == 0 + obj += VMobject() + assert len(obj.submobjects) == 1 + with pytest.raises(TypeError): + obj += Mobject() + assert len(obj.submobjects) == 1 + with pytest.raises(TypeError): + # If only one of the added object is not an instance of VMobject, none of them should be added + obj += (VMobject(), Mobject()) + assert len(obj.submobjects) == 1 + with pytest.raises(ValueError): + # a Mobject cannot contain itself + obj += obj + + +def test_vgroup_remove(): + """Test the VGroup remove method.""" + a = VMobject() + c = VMobject() + b = VGroup(c) + obj = VGroup(a, b) + assert len(obj.submobjects) == 2 + assert len(b.submobjects) == 1 + obj.remove(a) + b.remove(c) + assert len(obj.submobjects) == 1 + assert len(b.submobjects) == 0 + obj.remove(b) + assert len(obj.submobjects) == 0 + + +def test_vgroup_remove_dunder(): + """Test the VGroup __sub__ magic method.""" + a = VMobject() + c = VMobject() + b = VGroup(c) + obj = VGroup(a, b) + assert len(obj.submobjects) == 2 + assert len(b.submobjects) == 1 + assert len(obj - a) == 1 + assert len(obj.submobjects) == 2 + obj -= a + b -= c + assert len(obj.submobjects) == 1 + assert len(b.submobjects) == 0 + obj -= b + assert len(obj.submobjects) == 0 + + +def test_vmob_add_to_back(): + """Test the Mobject add_to_back method.""" + a = VMobject() + b = Line() + c = "text" + with pytest.raises(ValueError): + # Mobject cannot contain self + a.add_to_back(a) + with pytest.raises(TypeError): + # All submobjects must be of type Mobject + a.add_to_back(c) + + # No submobject gets added twice + a.add_to_back(b) + a.add_to_back(b, b) + assert len(a.submobjects) == 1 + a.submobjects.clear() + a.add_to_back(b, b, b) + a.add_to_back(b, b) + assert len(a.submobjects) == 1 + a.submobjects.clear() + + # Make sure the ordering has not changed + o1, o2, o3 = Square(), Line(), Circle() + a.add_to_back(o1, o2, o3) + assert a.submobjects.pop() == o3 + assert a.submobjects.pop() == o2 + assert a.submobjects.pop() == o1 + + +def test_vdict_init(): + """Test the VDict instantiation.""" + # Test empty VDict + VDict() + # Test VDict made from list of pairs + VDict([("a", VMobject()), ("b", VMobject()), ("c", VMobject())]) + # Test VDict made from a python dict + VDict({"a": VMobject(), "b": VMobject(), "c": VMobject()}) + # Test VDict made using zip + VDict(zip(["a", "b", "c"], [VMobject(), VMobject(), VMobject()])) + # If the value is of type Mobject, must raise a TypeError + with pytest.raises(TypeError): + VDict({"a": Mobject()}) + + +def test_vdict_add(): + """Test the VDict add method.""" + obj = VDict() + assert len(obj.submob_dict) == 0 + obj.add([("a", VMobject())]) + assert len(obj.submob_dict) == 1 + with pytest.raises(TypeError): + obj.add([("b", Mobject())]) + + +def test_vdict_remove(): + """Test the VDict remove method.""" + obj = VDict([("a", VMobject())]) + assert len(obj.submob_dict) == 1 + obj.remove("a") + assert len(obj.submob_dict) == 0 + with pytest.raises(KeyError): + obj.remove("a") + + +def test_vgroup_supports_item_assigment(): + """Test VGroup supports array-like assignment for VMObjects""" + a = VMobject() + b = VMobject() + vgroup = VGroup(a) + assert vgroup[0] == a + vgroup[0] = b + assert vgroup[0] == b + assert len(vgroup) == 1 + + +def test_vgroup_item_assignment_at_correct_position(): + """Test VGroup item-assignment adds to correct position for VMobjects""" + n_items = 10 + vgroup = VGroup() + for _i in range(n_items): + vgroup.add(VMobject()) + new_obj = VMobject() + vgroup[6] = new_obj + assert vgroup[6] == new_obj + assert len(vgroup) == n_items + + +def test_vgroup_item_assignment_only_allows_vmobjects(): + """Test VGroup item-assignment raises TypeError when invalid type is passed""" + vgroup = VGroup(VMobject()) + with pytest.raises(TypeError) as assign_str_info: + vgroup[0] = "invalid object" + assert str(assign_str_info.value) == ( + "Only values of type VMobject can be added as submobjects of VGroup, " + "but the value invalid object (at index 0) is of type str." + ) + + +def test_trim_dummy(): + o = VMobject() + o.start_new_path(np.array([0, 0, 0])) + o.add_line_to(np.array([1, 0, 0])) + o.add_line_to(np.array([2, 0, 0])) + o.add_line_to(np.array([2, 0, 0])) # Dummy point, will be stripped from points + o.start_new_path(np.array([0, 1, 0])) + o.add_line_to(np.array([1, 2, 0])) + + o2 = VMobject() + o2.start_new_path(np.array([0, 0, 0])) + o2.add_line_to(np.array([0, 1, 0])) + o2.start_new_path(np.array([1, 0, 0])) + o2.add_line_to(np.array([1, 1, 0])) + o2.add_line_to(np.array([1, 2, 0])) + + def path_length(p): + return len(p) // o.n_points_per_cubic_curve + + assert tuple(map(path_length, o.get_subpaths())) == (3, 1) + assert tuple(map(path_length, o2.get_subpaths())) == (1, 2) + + o.align_points(o2) + + assert tuple(map(path_length, o.get_subpaths())) == (2, 2) + assert tuple(map(path_length, o2.get_subpaths())) == (2, 2) + + +def test_bounded_become(): + """Tests that align_points generates a bounded number of points. + https://github.com/ManimCommunity/manim/issues/1959 + """ + o = VMobject() + + def draw_circle(m: VMobject, n_points, x=0, y=0, r=1): + center = np.array([x, y, 0]) + m.start_new_path(center + [r, 0, 0]) + for i in range(1, n_points + 1): + theta = 2 * PI * i / n_points + m.add_line_to(center + [cos(theta) * r, sin(theta) * r, 0]) + + # o must contain some points, or else become behaves differently + draw_circle(o, 2) + + for _ in range(20): + # Alternate between calls to become with different subpath sizes + a = VMobject() + draw_circle(a, 20) + o.become(a) + b = VMobject() + draw_circle(b, 15) + draw_circle(b, 15, x=3) + o.become(b) + + # The number of points should be similar to the size of a and b + assert len(o.points) <= (20 + 15 + 15) * 4 + + +def test_vmobject_same_points_become(): + a = Square() + b = Circle() + a.become(b) + np.testing.assert_array_equal(a.points, b.points) + assert len(a.submobjects) == len(b.submobjects) + + +def test_vmobject_same_num_submobjects_become(): + a = Square() + b = RegularPolygon(n=6) + a.become(b) + np.testing.assert_array_equal(a.points, b.points) + assert len(a.submobjects) == len(b.submobjects) + + +def test_vmobject_different_num_points_and_submobjects_become(): + a = Square() + b = VGroup(Circle(), Square()) + a.become(b) + np.testing.assert_array_equal(a.points, b.points) + assert len(a.submobjects) == len(b.submobjects) + + +def test_vmobject_point_at_angle(): + a = Circle() + p = a.point_at_angle(4 * PI) + np.testing.assert_array_equal(a.points[0], p) + + +def test_proportion_from_point(): + A = np.sqrt(3) * np.array([0, 1, 0]) + B = np.array([-1, 0, 0]) + C = np.array([1, 0, 0]) + abc = Polygon(A, B, C) + abc.shift(np.array([-1, 0, 0])) + abc.scale(0.8) + props = [abc.proportion_from_point(p) for p in abc.get_vertices()] + np.testing.assert_allclose(props, [0, 1 / 3, 2 / 3]) diff --git a/tests/test_auto_zoom.py b/tests/module/scene/test_auto_zoom.py similarity index 89% rename from tests/test_auto_zoom.py rename to tests/module/scene/test_auto_zoom.py index ad5da943ba..4c95ed83ca 100644 --- a/tests/test_auto_zoom.py +++ b/tests/module/scene/test_auto_zoom.py @@ -4,7 +4,6 @@ def test_zoom(): - s1 = Square() s1.set_x(-10) s2 = Square() @@ -17,6 +16,7 @@ def test_zoom(): assert scene.camera.frame_width == abs( s1.get_left()[0] - s2.get_right()[0], - ) and scene.camera.frame.get_center()[0] == ( + ) + assert scene.camera.frame.get_center()[0] == ( abs(s1.get_center()[0] + s2.get_center()[0]) / 2 ) diff --git a/tests/module/scene/test_scene.py b/tests/module/scene/test_scene.py new file mode 100644 index 0000000000..70ea9eaf2a --- /dev/null +++ b/tests/module/scene/test_scene.py @@ -0,0 +1,103 @@ +from __future__ import annotations + +import datetime + +import pytest + +from manim import Circle, FadeIn, Group, Mobject, Scene, Square +from manim.animation.animation import Wait + + +def test_scene_add_remove(dry_run): + scene = Scene() + assert len(scene.mobjects) == 0 + scene.add(Mobject()) + assert len(scene.mobjects) == 1 + scene.add(*(Mobject() for _ in range(10))) + assert len(scene.mobjects) == 11 + + # Check that adding a mobject twice does not actually add it twice + repeated = Mobject() + scene.add(repeated) + assert len(scene.mobjects) == 12 + scene.add(repeated) + assert len(scene.mobjects) == 12 + + # Check that Scene.add() returns the Scene (for chained calls) + assert scene.add(Mobject()) is scene + to_remove = Mobject() + scene = Scene() + scene.add(to_remove) + scene.add(*(Mobject() for _ in range(10))) + assert len(scene.mobjects) == 11 + scene.remove(to_remove) + assert len(scene.mobjects) == 10 + scene.remove(to_remove) + assert len(scene.mobjects) == 10 + + # Check that Scene.remove() returns the instance (for chained calls) + assert scene.add(Mobject()) is scene + + +def test_scene_time(dry_run): + scene = Scene() + assert scene.time == 0 + scene.wait(2) + assert scene.time == 2 + scene.play(FadeIn(Circle()), run_time=0.5) + assert pytest.approx(scene.time) == 2.5 + scene.renderer._original_skipping_status = True + scene.play(FadeIn(Square()), run_time=5) # this animation gets skipped. + assert pytest.approx(scene.time) == 7.5 + + +def test_subcaption(dry_run): + scene = Scene() + scene.add_subcaption("Testing add_subcaption", duration=1, offset=0) + scene.wait() + scene.play( + Wait(), + run_time=2, + subcaption="Testing Scene.play subcaption interface", + subcaption_duration=1.5, + subcaption_offset=0.5, + ) + subcaptions = scene.renderer.file_writer.subcaptions + assert len(subcaptions) == 2 + assert subcaptions[0].start == datetime.timedelta(seconds=0) + assert subcaptions[0].end == datetime.timedelta(seconds=1) + assert subcaptions[0].content == "Testing add_subcaption" + assert subcaptions[1].start == datetime.timedelta(seconds=1.5) + assert subcaptions[1].end == datetime.timedelta(seconds=3) + assert subcaptions[1].content == "Testing Scene.play subcaption interface" + + +def test_replace(dry_run): + def assert_names(mobjs, names): + assert len(mobjs) == len(names) + for i in range(0, len(mobjs)): + assert mobjs[i].name == names[i] + + scene = Scene() + + first = Mobject(name="first") + second = Mobject(name="second") + third = Mobject(name="third") + fourth = Mobject(name="fourth") + + scene.add(first) + scene.add(Group(second, third, name="group")) + scene.add(fourth) + assert_names(scene.mobjects, ["first", "group", "fourth"]) + assert_names(scene.mobjects[1], ["second", "third"]) + + alpha = Mobject(name="alpha") + beta = Mobject(name="beta") + + scene.replace(first, alpha) + assert_names(scene.mobjects, ["alpha", "group", "fourth"]) + assert_names(scene.mobjects[1], ["second", "third"]) + + scene.replace(second, beta) + assert_names(scene.mobjects, ["alpha", "group", "fourth"]) + assert_names(scene.mobjects[1], ["beta", "third"]) diff --git a/tests/module/scene/test_sound.py b/tests/module/scene/test_sound.py new file mode 100644 index 0000000000..cfa9a4da42 --- /dev/null +++ b/tests/module/scene/test_sound.py @@ -0,0 +1,21 @@ +from __future__ import annotations + +import struct +import wave +from pathlib import Path + +from manim import Scene + + +def test_add_sound(tmpdir): + # create sound file + sound_loc = Path(tmpdir, "noise.wav") + with wave.open(str(sound_loc), "w") as f: + f.setparams((2, 2, 44100, 0, "NONE", "not compressed")) + for _ in range(22050): # half a second of sound + packed_value = struct.pack("h", 14242) + f.writeframes(packed_value) + f.writeframes(packed_value) + + scene = Scene() + scene.add_sound(sound_loc) diff --git a/tests/test_threed_scene.py b/tests/module/scene/test_threed_scene.py similarity index 100% rename from tests/test_threed_scene.py rename to tests/module/scene/test_threed_scene.py diff --git a/tests/module/utils/_split_matrices.py b/tests/module/utils/_split_matrices.py new file mode 100644 index 0000000000..70c87497e6 --- /dev/null +++ b/tests/module/utils/_split_matrices.py @@ -0,0 +1,215 @@ +import numpy as np + +# Defined because pre-commit is inserting an unacceptable line-break +# between the "1" (or "2") and the "/ 3" +one_third = 1 / 3 +two_thirds = 2 / 3 + + +# Expected values for matrices in split_bezier +SPLIT_MATRICES = { + # For 0-degree Béziers + 0: { + 0: np.array([[1], [1]]), + one_third: np.array([[1], [1]]), + two_thirds: np.array([[1], [1]]), + 1: np.array([[1], [1]]), + }, + # For linear Béziers + 1: { + 0: np.array( + [ + [1, 0], + [1, 0], + [1, 0], + [0, 1], + ] + ), + one_third: np.array( + [ + [3, 0], + [2, 1], + [2, 1], + [0, 3], + ] + ) + / 3, + two_thirds: np.array( + [ + [3, 0], + [1, 2], + [1, 2], + [0, 3], + ] + ) + / 3, + 1: np.array( + [ + [1, 0], + [0, 1], + [0, 1], + [0, 1], + ] + ), + }, + # For quadratic Béziers + 2: { + 0: np.array( + [ + [1, 0, 0], + [1, 0, 0], + [1, 0, 0], + [1, 0, 0], + [0, 1, 0], + [0, 0, 1], + ] + ), + one_third: np.array( + [ + [9, 0, 0], + [6, 3, 0], + [4, 4, 1], + [4, 4, 1], + [0, 6, 3], + [0, 0, 9], + ] + ) + / 9, + two_thirds: np.array( + [ + [9, 0, 0], + [3, 6, 0], + [1, 4, 4], + [1, 4, 4], + [0, 3, 6], + [0, 0, 9], + ] + ) + / 9, + 1: np.array( + [ + [1, 0, 0], + [0, 1, 0], + [0, 0, 1], + [0, 0, 1], + [0, 0, 1], + [0, 0, 1], + ] + ), + }, + # For cubic Béziers + 3: { + 0: np.array( + [ + [1, 0, 0, 0], + [1, 0, 0, 0], + [1, 0, 0, 0], + [1, 0, 0, 0], + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [0, 0, 0, 1], + ] + ), + one_third: np.array( + [ + [27, 0, 0, 0], + [18, 9, 0, 0], + [12, 12, 3, 0], + [8, 12, 6, 1], + [8, 12, 6, 1], + [0, 12, 12, 3], + [0, 0, 18, 9], + [0, 0, 0, 27], + ] + ) + / 27, + two_thirds: np.array( + [ + [27, 0, 0, 0], + [9, 18, 0, 0], + [3, 12, 12, 0], + [1, 6, 12, 8], + [1, 6, 12, 8], + [0, 3, 12, 12], + [0, 0, 9, 18], + [0, 0, 0, 27], + ] + ) + / 27, + 1: np.array( + [ + [1, 0, 0, 0], + [0, 1, 0, 0], + [0, 0, 1, 0], + [0, 0, 0, 1], + [0, 0, 0, 1], + [0, 0, 0, 1], + [0, 0, 0, 1], + [0, 0, 0, 1], + ] + ), + }, + # Test case with a quartic Bézier + # to check if the fallback algorithms work + 4: { + 0: np.array( + [ + [1, 0, 0, 0, 0], + [1, 0, 0, 0, 0], + [1, 0, 0, 0, 0], + [1, 0, 0, 0, 0], + [1, 0, 0, 0, 0], + [1, 0, 0, 0, 0], + [0, 1, 0, 0, 0], + [0, 0, 1, 0, 0], + [0, 0, 0, 1, 0], + [0, 0, 0, 0, 1], + ] + ), + one_third: np.array( + [ + [81, 0, 0, 0, 0], + [54, 27, 0, 0, 0], + [36, 36, 9, 0, 0], + [24, 36, 18, 3, 0], + [16, 32, 24, 8, 1], + [16, 32, 24, 8, 1], + [0, 24, 36, 18, 3], + [0, 0, 36, 36, 9], + [0, 0, 0, 54, 27], + [0, 0, 0, 0, 81], + ] + ) + / 81, + two_thirds: np.array( + [ + [81, 0, 0, 0, 0], + [27, 54, 0, 0, 0], + [9, 36, 36, 0, 0], + [3, 18, 36, 24, 0], + [1, 8, 24, 32, 16], + [1, 8, 24, 32, 16], + [0, 3, 18, 36, 24], + [0, 0, 9, 36, 36], + [0, 0, 0, 27, 54], + [0, 0, 0, 0, 81], + ] + ) + / 81, + 1: np.array( + [ + [1, 0, 0, 0, 0], + [0, 1, 0, 0, 0], + [0, 0, 1, 0, 0], + [0, 0, 0, 1, 0], + [0, 0, 0, 0, 1], + [0, 0, 0, 0, 1], + [0, 0, 0, 0, 1], + [0, 0, 0, 0, 1], + [0, 0, 0, 0, 1], + [0, 0, 0, 0, 1], + ] + ), + }, +} diff --git a/tests/module/utils/_subdivision_matrices.py b/tests/module/utils/_subdivision_matrices.py new file mode 100644 index 0000000000..c020937dea --- /dev/null +++ b/tests/module/utils/_subdivision_matrices.py @@ -0,0 +1,167 @@ +import numpy as np + +# Expected values for matrices in subdivide_bezier and others +# Note that in bezier.py this is a list of dicts, +# not a dict of dicts! +SUBDIVISION_MATRICES = { + # For 0-degree Béziers + 0: { + 2: np.array([[1], [1]]), + 3: np.array([[1], [1], [1]]), + 4: np.array([[1], [1], [1], [1]]), + }, + # For linear Béziers + 1: { + 2: np.array( + [ + [2, 0], + [1, 1], + [1, 1], + [0, 2], + ] + ) + / 2, + 3: np.array( + [ + [3, 0], + [2, 1], + [2, 1], + [1, 2], + [1, 2], + [0, 3], + ] + ) + / 3, + 4: np.array( + [ + [4, 0], + [3, 1], + [3, 1], + [2, 2], + [2, 2], + [1, 3], + [1, 3], + [0, 4], + ] + ) + / 4, + }, + # For quadratic Béziers + 2: { + 2: np.array( + [ + [4, 0, 0], + [2, 2, 0], + [1, 2, 1], + [1, 2, 1], + [0, 2, 2], + [0, 0, 4], + ] + ) + / 4, + 3: np.array( + [ + [9, 0, 0], + [6, 3, 0], + [4, 4, 1], + [4, 4, 1], + [2, 5, 2], + [1, 4, 4], + [1, 4, 4], + [0, 3, 6], + [0, 0, 9], + ] + ) + / 9, + 4: np.array( + [ + [16, 0, 0], + [12, 4, 0], + [9, 6, 1], + [9, 6, 1], + [6, 8, 2], + [4, 8, 4], + [4, 8, 4], + [2, 8, 6], + [1, 6, 9], + [1, 6, 9], + [0, 4, 12], + [0, 0, 16], + ] + ) + / 16, + }, + # For cubic Béziers + 3: { + 2: np.array( + [ + [8, 0, 0, 0], + [4, 4, 0, 0], + [2, 4, 2, 0], + [1, 3, 3, 1], + [1, 3, 3, 1], + [0, 2, 4, 2], + [0, 0, 4, 4], + [0, 0, 0, 8], + ] + ) + / 8, + 3: np.array( + [ + [27, 0, 0, 0], + [18, 9, 0, 0], + [12, 12, 3, 0], + [8, 12, 6, 1], + [8, 12, 6, 1], + [4, 12, 9, 2], + [2, 9, 12, 4], + [1, 6, 12, 8], + [1, 6, 12, 8], + [0, 3, 12, 12], + [0, 0, 9, 18], + [0, 0, 0, 27], + ] + ) + / 27, + 4: np.array( + [ + [64, 0, 0, 0], + [48, 16, 0, 0], + [36, 24, 4, 0], + [27, 27, 9, 1], + [27, 27, 9, 1], + [18, 30, 14, 2], + [12, 28, 20, 4], + [8, 24, 24, 8], + [8, 24, 24, 8], + [4, 20, 28, 12], + [2, 14, 30, 18], + [1, 9, 27, 27], + [1, 9, 27, 27], + [0, 4, 24, 36], + [0, 0, 16, 48], + [0, 0, 0, 64], + ] + ) + / 64, + }, + # Test case with a quartic Bézier + # to check if the fallback algorithms work + 4: { + 2: np.array( + [ + [16, 0, 0, 0, 0], + [8, 8, 0, 0, 0], + [4, 8, 4, 0, 0], + [2, 6, 6, 2, 0], + [1, 4, 6, 4, 1], + [1, 4, 6, 4, 1], + [0, 2, 6, 6, 2], + [0, 0, 4, 8, 4], + [0, 0, 0, 8, 8], + [0, 0, 0, 0, 16], + ] + ) + / 16, + }, +} diff --git a/tests/module/utils/test_bezier.py b/tests/module/utils/test_bezier.py new file mode 100644 index 0000000000..19d3076ffb --- /dev/null +++ b/tests/module/utils/test_bezier.py @@ -0,0 +1,233 @@ +from __future__ import annotations + +import numpy as np +import numpy.testing as nt +from _split_matrices import SPLIT_MATRICES +from _subdivision_matrices import SUBDIVISION_MATRICES + +from manim.typing import ManimFloat +from manim.utils.bezier import ( + _get_subdivision_matrix, + get_quadratic_approximation_of_cubic, + get_smooth_cubic_bezier_handle_points, + interpolate, + partial_bezier_points, + split_bezier, + subdivide_bezier, +) + +QUARTIC_BEZIER = np.array( + [ + [-1, -1, 0], + [-1, 0, 0], + [0, 1, 0], + [1, 0, 0], + [1, -1, 0], + ], + dtype=float, +) + + +def test_partial_bezier_points() -> None: + """Test that :func:`partial_bezierpoints`, both in the + portion-matrix-building algorithm (degrees up to 3) and the + fallback algorithm (degree 4), works correctly. + """ + for degree, degree_dict in SUBDIVISION_MATRICES.items(): + n_points = degree + 1 + points = QUARTIC_BEZIER[:n_points] + for n_divisions, subdivision_matrix in degree_dict.items(): + for i in range(n_divisions): + a = i / n_divisions + b = (i + 1) / n_divisions + portion_matrix = subdivision_matrix[n_points * i : n_points * (i + 1)] + nt.assert_allclose( + partial_bezier_points(points, a, b), + portion_matrix @ points, + atol=1e-15, # Needed because of floating-point errors + ) + + +def test_split_bezier() -> None: + """Test that :func:`split_bezier`, both in the + split-matrix-building algorithm (degrees up to 3) and the + fallback algorithm (degree 4), works correctly. + """ + for degree, degree_dict in SPLIT_MATRICES.items(): + n_points = degree + 1 + points = QUARTIC_BEZIER[:n_points] + for t, split_matrix in degree_dict.items(): + nt.assert_allclose( + split_bezier(points, t), split_matrix @ points, atol=1e-15 + ) + + for degree, degree_dict in SUBDIVISION_MATRICES.items(): + n_points = degree + 1 + points = QUARTIC_BEZIER[:n_points] + # Split in half + split_matrix = degree_dict[2] + nt.assert_allclose( + split_bezier(points, 0.5), + split_matrix @ points, + ) + + +def test_get_subdivision_matrix() -> None: + """Test that the memos in .:meth:`_get_subdivision_matrix` + are being correctly generated. + """ + # Only for degrees up to 3! + for degree in range(4): + degree_dict = SUBDIVISION_MATRICES[degree] + for n_divisions, subdivision_matrix in degree_dict.items(): + nt.assert_allclose( + _get_subdivision_matrix(degree + 1, n_divisions), + subdivision_matrix, + ) + + +def test_subdivide_bezier() -> None: + """Test that :func:`subdivide_bezier`, both in the memoized cases + (degrees up to 3) and the fallback algorithm (degree 4), works + correctly. + """ + for degree, degree_dict in SUBDIVISION_MATRICES.items(): + n_points = degree + 1 + points = QUARTIC_BEZIER[:n_points] + for n_divisions, subdivision_matrix in degree_dict.items(): + nt.assert_allclose( + subdivide_bezier(points, n_divisions), + subdivision_matrix @ points, + ) + + +def test_get_smooth_cubic_bezier_handle_points() -> None: + """Test that :func:`.get_smooth_cubic_bezier_handle_points` returns the + correct handles, both for open and closed Bézier splines. + """ + open_curve_corners = np.array( + [ + [1, 1, 0], + [-1, 1, 1], + [-1, -1, 2], + [1, -1, 1], + ], + dtype=ManimFloat, + ) + h1, h2 = get_smooth_cubic_bezier_handle_points(open_curve_corners) + assert np.allclose( + h1, + np.array( + [ + [1 / 5, 11 / 9, 13 / 45], + [-7 / 5, 5 / 9, 64 / 45], + [-3 / 5, -13 / 9, 91 / 45], + ] + ), + ) + assert np.allclose( + h2, + np.array( + [ + [-3 / 5, 13 / 9, 26 / 45], + [-7 / 5, -5 / 9, 89 / 45], + [1 / 5, -11 / 9, 68 / 45], + ] + ), + ) + + closed_curve_corners = np.array( + [ + [1, 1, 0], + [-1, 1, 1], + [-1, -1, 2], + [1, -1, 1], + [1, 1, 0], + ], + dtype=ManimFloat, + ) + h1, h2 = get_smooth_cubic_bezier_handle_points(closed_curve_corners) + assert np.allclose( + h1, + np.array( + [ + [1 / 2, 3 / 2, 0], + [-3 / 2, 1 / 2, 3 / 2], + [-1 / 2, -3 / 2, 2], + [3 / 2, -1 / 2, 1 / 2], + ] + ), + ) + assert np.allclose( + h2, + np.array( + [ + [-1 / 2, 3 / 2, 1 / 2], + [-3 / 2, -1 / 2, 2], + [1 / 2, -3 / 2, 3 / 2], + [3 / 2, 1 / 2, 0], + ] + ), + ) + + +def test_get_quadratic_approximation_of_cubic() -> None: + C = np.array( + [ + [-5, 2, 0], + [-4, 2, 0], + [-3, 2, 0], + [-2, 2, 0], + [-2, 2, 0], + [-7 / 3, 4 / 3, 0], + [-8 / 3, 2 / 3, 0], + [-3, 0, 0], + [-3, 0, 0], + [-1 / 3, -1, 0], + [7 / 3, -2, 0], + [5, -3, 0], + ] + ) + a0, h0, h1, a1 = C[::4], C[1::4], C[2::4], C[3::4] + + Q = get_quadratic_approximation_of_cubic(a0, h0, h1, a1) + assert np.allclose( + Q, + np.array( + [ + [-5, 2, 0], + [-17 / 4, 2, 0], + [-7 / 2, 2, 0], + [-7 / 2, 2, 0], + [-11 / 4, 2, 0], + [-2, 2, 0], + [-2, 2, 0], + [-9 / 4, 3 / 2, 0], + [-5 / 2, 1, 0], + [-5 / 2, 1, 0], + [-11 / 4, 1 / 2, 0], + [-3, 0, 0], + [-3, 0, 0], + [-1, -3 / 4, 0], + [1, -3 / 2, 0], + [1, -3 / 2, 0], + [3, -9 / 4, 0], + [5, -3, 0], + ] + ), + ) + + +def test_interpolate() -> None: + """Test that :func:`interpolate` handles interpolation of both float and uint8 values.""" + start = 127.0 + end = 25.0 + alpha = 0.2 + val = interpolate(start, end, alpha) + assert np.allclose(val, 106.6000000) + + start = np.array(127, dtype=np.uint8) + end = np.array(25, dtype=np.uint8) + alpha = 0.09739 + val = interpolate(start, end, alpha) + assert np.allclose(val, np.array([117.06622])) diff --git a/tests/module/utils/test_color.py b/tests/module/utils/test_color.py new file mode 100644 index 0000000000..602f56460e --- /dev/null +++ b/tests/module/utils/test_color.py @@ -0,0 +1,57 @@ +from __future__ import annotations + +import numpy as np + +from manim import BLACK, RED, WHITE, ManimColor, Mobject, Scene, VMobject + + +def test_import_color(): + import manim.utils.color as C + + C.WHITE + + +def test_background_color(): + S = Scene() + S.camera.background_color = "#ff0000" + S.renderer.update_frame(S) + np.testing.assert_array_equal( + S.renderer.get_frame()[0, 0], np.array([255, 0, 0, 255]) + ) + + S.camera.background_color = "#436f80" + S.renderer.update_frame(S) + np.testing.assert_array_equal( + S.renderer.get_frame()[0, 0], np.array([67, 111, 128, 255]) + ) + + S.camera.background_color = "#ffffff" + S.renderer.update_frame(S) + np.testing.assert_array_equal( + S.renderer.get_frame()[0, 0], np.array([255, 255, 255, 255]) + ) + + S.camera.background_color = "#bbffbb" + S.camera.background_opacity = 0.5 + S.renderer.update_frame(S) + np.testing.assert_array_equal( + S.renderer.get_frame()[0, 0], np.array([187, 255, 187, 127]) + ) + + +def test_set_color(): + m = Mobject() + assert m.color.to_hex() == "#FFFFFF" + m.set_color(BLACK) + assert m.color.to_hex() == "#000000" + + m = VMobject() + assert m.color.to_hex() == "#FFFFFF" + m.set_color(BLACK) + assert m.color.to_hex() == "#000000" + + +def test_color_hash(): + assert hash(WHITE) == hash(ManimColor([1.0, 1.0, 1.0, 1.0])) + assert hash(WHITE) == hash("#FFFFFFFF") + assert hash(WHITE) != hash(RED) diff --git a/tests/test_deprecation.py b/tests/module/utils/test_deprecation.py similarity index 71% rename from tests/test_deprecation.py rename to tests/module/utils/test_deprecation.py index 9e587c1fd1..dcb766a464 100644 --- a/tests/test_deprecation.py +++ b/tests/module/utils/test_deprecation.py @@ -1,23 +1,13 @@ from __future__ import annotations -import logging - -import pytest - from manim.utils.deprecation import deprecated, deprecated_params -def _get_caplog_record_msg(warn_caplog_manim): - logger_name, level, message = warn_caplog_manim.record_tuples[0] +def _get_caplog_record_msg(manim_caplog): + logger_name, level, message = manim_caplog.record_tuples[0] return message -@pytest.fixture() -def warn_caplog_manim(caplog): - caplog.set_level(logging.WARNING, logger="manim") - yield caplog - - @deprecated class Foo: def __init__(self): @@ -74,14 +64,14 @@ def __init__(self): pass -doc_admonition = "\n\n.. admonition:: Deprecated\n :class: attention\n\n " +doc_admonition = "\n\n.. attention:: Deprecated\n " -def test_deprecate_class_no_args(warn_caplog_manim): +def test_deprecate_class_no_args(manim_caplog): """Test the deprecation of a class (decorator with no arguments).""" f = Foo() - assert len(warn_caplog_manim.record_tuples) == 1 - msg = _get_caplog_record_msg(warn_caplog_manim) + assert len(manim_caplog.record_tuples) == 1 + msg = _get_caplog_record_msg(manim_caplog) assert ( msg == "The class Foo has been deprecated and may be removed in a later version." @@ -89,11 +79,11 @@ def test_deprecate_class_no_args(warn_caplog_manim): assert f.__doc__ == f"{doc_admonition}{msg}" -def test_deprecate_class_since(warn_caplog_manim): +def test_deprecate_class_since(manim_caplog): """Test the deprecation of a class (decorator with since argument).""" b = Bar() - assert len(warn_caplog_manim.record_tuples) == 1 - msg = _get_caplog_record_msg(warn_caplog_manim) + assert len(manim_caplog.record_tuples) == 1 + msg = _get_caplog_record_msg(manim_caplog) assert ( msg == "The class Bar has been deprecated since v0.6.0 and may be removed in a later version." @@ -101,11 +91,11 @@ def test_deprecate_class_since(warn_caplog_manim): assert b.__doc__ == f"The Bar class.{doc_admonition}{msg}" -def test_deprecate_class_until(warn_caplog_manim): +def test_deprecate_class_until(manim_caplog): """Test the deprecation of a class (decorator with until argument).""" bz = Baz() - assert len(warn_caplog_manim.record_tuples) == 1 - msg = _get_caplog_record_msg(warn_caplog_manim) + assert len(manim_caplog.record_tuples) == 1 + msg = _get_caplog_record_msg(manim_caplog) assert ( msg == "The class Baz has been deprecated and is expected to be removed after 06/01/2021." @@ -113,11 +103,11 @@ def test_deprecate_class_until(warn_caplog_manim): assert bz.__doc__ == f"The Baz class.{doc_admonition}{msg}" -def test_deprecate_class_since_and_until(warn_caplog_manim): +def test_deprecate_class_since_and_until(manim_caplog): """Test the deprecation of a class (decorator with since and until arguments).""" qx = Qux() - assert len(warn_caplog_manim.record_tuples) == 1 - msg = _get_caplog_record_msg(warn_caplog_manim) + assert len(manim_caplog.record_tuples) == 1 + msg = _get_caplog_record_msg(manim_caplog) assert ( msg == "The class Qux has been deprecated since 0.7.0 and is expected to be removed after 0.9.0-rc2." @@ -125,11 +115,11 @@ def test_deprecate_class_since_and_until(warn_caplog_manim): assert qx.__doc__ == f"{doc_admonition}{msg}" -def test_deprecate_class_msg(warn_caplog_manim): +def test_deprecate_class_msg(manim_caplog): """Test the deprecation of a class (decorator with msg argument).""" qu = Quux() - assert len(warn_caplog_manim.record_tuples) == 1 - msg = _get_caplog_record_msg(warn_caplog_manim) + assert len(manim_caplog.record_tuples) == 1 + msg = _get_caplog_record_msg(manim_caplog) assert ( msg == "The class Quux has been deprecated and may be removed in a later version. Use something else." @@ -137,11 +127,11 @@ def test_deprecate_class_msg(warn_caplog_manim): assert qu.__doc__ == f"{doc_admonition}{msg}" -def test_deprecate_class_replacement(warn_caplog_manim): +def test_deprecate_class_replacement(manim_caplog): """Test the deprecation of a class (decorator with replacement argument).""" qz = Quuz() - assert len(warn_caplog_manim.record_tuples) == 1 - msg = _get_caplog_record_msg(warn_caplog_manim) + assert len(manim_caplog.record_tuples) == 1 + msg = _get_caplog_record_msg(manim_caplog) assert ( msg == "The class Quuz has been deprecated and may be removed in a later version. Use ReplaceQuuz instead." @@ -150,11 +140,11 @@ def test_deprecate_class_replacement(warn_caplog_manim): assert qz.__doc__ == f"{doc_admonition}{doc_msg}" -def test_deprecate_class_all(warn_caplog_manim): +def test_deprecate_class_all(manim_caplog): """Test the deprecation of a class (decorator with all arguments).""" qza = QuuzAll() - assert len(warn_caplog_manim.record_tuples) == 1 - msg = _get_caplog_record_msg(warn_caplog_manim) + assert len(manim_caplog.record_tuples) == 1 + msg = _get_caplog_record_msg(manim_caplog) assert ( msg == "The class QuuzAll has been deprecated since 0.7.0 and is expected to be removed after 1.2.1. Use ReplaceQuuz instead. Don't use this please." @@ -175,7 +165,6 @@ def __init__(self): @deprecated(since="0.8.0", message="This method is useless.") def mid_func(self): """Middle function in Top.""" - pass @deprecated(until="1.4.0", replacement="Top.NewNested") @@ -190,7 +179,6 @@ def __init__(self): @deprecated(since="1.0.0", until="12/25/2025") def nested_func(self): """Nested function in Top.NewNested.""" - pass class Bottom: @@ -232,20 +220,22 @@ def quux(self, **kwargs): @deprecated_params( redirections=[ - lambda point2D=1: {"x": point2D[0], "y": point2D[1]} - if isinstance(point2D, tuple) - else {"x": point2D, "y": point2D}, + lambda point2D=1: ( + {"x": point2D[0], "y": point2D[1]} + if isinstance(point2D, tuple) + else {"x": point2D, "y": point2D} + ), ], ) def quuz(self, **kwargs): return kwargs -def test_deprecate_func_no_args(warn_caplog_manim): +def test_deprecate_func_no_args(manim_caplog): """Test the deprecation of a method (decorator with no arguments).""" useless() - assert len(warn_caplog_manim.record_tuples) == 1 - msg = _get_caplog_record_msg(warn_caplog_manim) + assert len(manim_caplog.record_tuples) == 1 + msg = _get_caplog_record_msg(manim_caplog) assert ( msg == "The function useless has been deprecated and may be removed in a later version." @@ -253,12 +243,12 @@ def test_deprecate_func_no_args(warn_caplog_manim): assert useless.__doc__ == f"{doc_admonition}{msg}" -def test_deprecate_func_in_class_since_and_message(warn_caplog_manim): +def test_deprecate_func_in_class_since_and_message(manim_caplog): """Test the deprecation of a method within a class (decorator with since and message arguments).""" t = Top() t.mid_func() - assert len(warn_caplog_manim.record_tuples) == 1 - msg = _get_caplog_record_msg(warn_caplog_manim) + assert len(manim_caplog.record_tuples) == 1 + msg = _get_caplog_record_msg(manim_caplog) assert ( msg == "The method Top.mid_func has been deprecated since 0.8.0 and may be removed in a later version. This method is useless." @@ -266,11 +256,11 @@ def test_deprecate_func_in_class_since_and_message(warn_caplog_manim): assert t.mid_func.__doc__ == f"Middle function in Top.{doc_admonition}{msg}" -def test_deprecate_nested_class_until_and_replacement(warn_caplog_manim): +def test_deprecate_nested_class_until_and_replacement(manim_caplog): """Test the deprecation of a nested class (decorator with until and replacement arguments).""" n = Top().Nested() - assert len(warn_caplog_manim.record_tuples) == 1 - msg = _get_caplog_record_msg(warn_caplog_manim) + assert len(manim_caplog.record_tuples) == 1 + msg = _get_caplog_record_msg(manim_caplog) assert ( msg == "The class Top.Nested has been deprecated and is expected to be removed after 1.4.0. Use Top.NewNested instead." @@ -279,12 +269,12 @@ def test_deprecate_nested_class_until_and_replacement(warn_caplog_manim): assert n.__doc__ == f"{doc_admonition}{doc_msg}" -def test_deprecate_nested_class_func_since_and_until(warn_caplog_manim): +def test_deprecate_nested_class_func_since_and_until(manim_caplog): """Test the deprecation of a method within a nested class (decorator with since and until arguments).""" n = Top().NewNested() n.nested_func() - assert len(warn_caplog_manim.record_tuples) == 1 - msg = _get_caplog_record_msg(warn_caplog_manim) + assert len(manim_caplog.record_tuples) == 1 + msg = _get_caplog_record_msg(manim_caplog) assert ( msg == "The method Top.NewNested.nested_func has been deprecated since 1.0.0 and is expected to be removed after 12/25/2025." @@ -295,13 +285,13 @@ def test_deprecate_nested_class_func_since_and_until(warn_caplog_manim): ) -def test_deprecate_nested_func(warn_caplog_manim): +def test_deprecate_nested_func(manim_caplog): """Test the deprecation of a nested method (decorator with no arguments).""" b = Top().Bottom() answer = b.normal_func() answer(1) - assert len(warn_caplog_manim.record_tuples) == 1 - msg = _get_caplog_record_msg(warn_caplog_manim) + assert len(manim_caplog.record_tuples) == 1 + msg = _get_caplog_record_msg(manim_caplog) assert ( msg == "The method Top.Bottom.normal_func..nested_func has been deprecated and may be removed in a later version." @@ -309,36 +299,36 @@ def test_deprecate_nested_func(warn_caplog_manim): assert answer.__doc__ == f"{doc_admonition}{msg}" -def test_deprecate_func_params(warn_caplog_manim): +def test_deprecate_func_params(manim_caplog): """Test the deprecation of method parameters (decorator with params argument).""" t = Top() t.foo(a=2, b=3, z=4) - assert len(warn_caplog_manim.record_tuples) == 1 - msg = _get_caplog_record_msg(warn_caplog_manim) + assert len(manim_caplog.record_tuples) == 1 + msg = _get_caplog_record_msg(manim_caplog) assert ( msg == "The parameters a and b of method Top.foo have been deprecated and may be removed in a later version. Use something else." ) -def test_deprecate_func_single_param_since_and_until(warn_caplog_manim): +def test_deprecate_func_single_param_since_and_until(manim_caplog): """Test the deprecation of a single method parameter (decorator with since and until arguments).""" t = Top() t.bar(a=1, b=2) - assert len(warn_caplog_manim.record_tuples) == 1 - msg = _get_caplog_record_msg(warn_caplog_manim) + assert len(manim_caplog.record_tuples) == 1 + msg = _get_caplog_record_msg(manim_caplog) assert ( msg == "The parameter a of method Top.bar has been deprecated since v0.2 and is expected to be removed after v0.4." ) -def test_deprecate_func_param_redirect_tuple(warn_caplog_manim): +def test_deprecate_func_param_redirect_tuple(manim_caplog): """Test the deprecation of a method parameter and redirecting it to a new one using tuple.""" t = Top() obj = t.baz(x=1, old_param=2) - assert len(warn_caplog_manim.record_tuples) == 1 - msg = _get_caplog_record_msg(warn_caplog_manim) + assert len(manim_caplog.record_tuples) == 1 + msg = _get_caplog_record_msg(manim_caplog) assert ( msg == "The parameter old_param of method Top.baz has been deprecated and may be removed in a later version." @@ -346,12 +336,12 @@ def test_deprecate_func_param_redirect_tuple(warn_caplog_manim): assert obj == {"x": 1, "new_param": 2} -def test_deprecate_func_param_redirect_lambda(warn_caplog_manim): +def test_deprecate_func_param_redirect_lambda(manim_caplog): """Test the deprecation of a method parameter and redirecting it to a new one using lambda function.""" t = Top() obj = t.qux(runtime_in_ms=500) - assert len(warn_caplog_manim.record_tuples) == 1 - msg = _get_caplog_record_msg(warn_caplog_manim) + assert len(manim_caplog.record_tuples) == 1 + msg = _get_caplog_record_msg(manim_caplog) assert ( msg == "The parameter runtime_in_ms of method Top.qux has been deprecated and may be removed in a later version." @@ -359,12 +349,12 @@ def test_deprecate_func_param_redirect_lambda(warn_caplog_manim): assert obj == {"run_time": 0.5} -def test_deprecate_func_param_redirect_many_to_one(warn_caplog_manim): +def test_deprecate_func_param_redirect_many_to_one(manim_caplog): """Test the deprecation of multiple method parameters and redirecting them to one.""" t = Top() obj = t.quux(point2D_x=3, point2D_y=5) - assert len(warn_caplog_manim.record_tuples) == 1 - msg = _get_caplog_record_msg(warn_caplog_manim) + assert len(manim_caplog.record_tuples) == 1 + msg = _get_caplog_record_msg(manim_caplog) assert ( msg == "The parameters point2D_x and point2D_y of method Top.quux have been deprecated and may be removed in a later version." @@ -372,23 +362,23 @@ def test_deprecate_func_param_redirect_many_to_one(warn_caplog_manim): assert obj == {"point2D": (3, 5)} -def test_deprecate_func_param_redirect_one_to_many(warn_caplog_manim): +def test_deprecate_func_param_redirect_one_to_many(manim_caplog): """Test the deprecation of one method parameter and redirecting it to many.""" t = Top() obj1 = t.quuz(point2D=0) - assert len(warn_caplog_manim.record_tuples) == 1 - msg = _get_caplog_record_msg(warn_caplog_manim) + assert len(manim_caplog.record_tuples) == 1 + msg = _get_caplog_record_msg(manim_caplog) assert ( msg == "The parameter point2D of method Top.quuz has been deprecated and may be removed in a later version." ) assert obj1 == {"x": 0, "y": 0} - warn_caplog_manim.clear() + manim_caplog.clear() obj2 = t.quuz(point2D=(2, 3)) - assert len(warn_caplog_manim.record_tuples) == 1 - msg = _get_caplog_record_msg(warn_caplog_manim) + assert len(manim_caplog.record_tuples) == 1 + msg = _get_caplog_record_msg(manim_caplog) assert ( msg == "The parameter point2D of method Top.quuz has been deprecated and may be removed in a later version." diff --git a/tests/module/utils/test_file_ops.py b/tests/module/utils/test_file_ops.py new file mode 100644 index 0000000000..b56684eb0c --- /dev/null +++ b/tests/module/utils/test_file_ops.py @@ -0,0 +1,31 @@ +from __future__ import annotations + +from pathlib import Path + +from manim import * +from tests.assert_utils import assert_dir_exists, assert_file_not_exists +from tests.utils.video_tester import * + + +def test_guarantee_existence(tmp_path: Path): + test_dir = tmp_path / "test" + guarantee_existence(test_dir) + # test if file dir got created + assert_dir_exists(test_dir) + with (test_dir / "test.txt").open("x") as f: + pass + # test if file didn't get deleted + guarantee_existence(test_dir) + + +def test_guarantee_empty_existence(tmp_path: Path): + test_dir = tmp_path / "test" + test_dir.mkdir() + with (test_dir / "test.txt").open("x"): + pass + + guarantee_empty_existence(test_dir) + # test if dir got created + assert_dir_exists(test_dir) + # test if dir got cleaned + assert_file_not_exists(test_dir / "test.txt") diff --git a/tests/test_hashing.py b/tests/module/utils/test_hashing.py similarity index 100% rename from tests/test_hashing.py rename to tests/module/utils/test_hashing.py diff --git a/tests/module/utils/test_manim_color.py b/tests/module/utils/test_manim_color.py new file mode 100644 index 0000000000..4b169fd48e --- /dev/null +++ b/tests/module/utils/test_manim_color.py @@ -0,0 +1,226 @@ +from __future__ import annotations + +import colorsys + +import numpy as np +import numpy.testing as nt + +from manim.utils.color import ( + BLACK, + HSV, + RED, + WHITE, + YELLOW, + ManimColor, + ManimColorDType, +) +from manim.utils.color.XKCD import GREEN + + +def test_init_with_int() -> None: + color = ManimColor(0x123456, 0.5) + nt.assert_array_equal( + color._internal_value, + np.array([0x12, 0x34, 0x56, 0.5 * 255], dtype=ManimColorDType) / 255, + ) + color = BLACK + nt.assert_array_equal( + color._internal_value, np.array([0, 0, 0, 1.0], dtype=ManimColorDType) + ) + color = WHITE + nt.assert_array_equal( + color._internal_value, np.array([1.0, 1.0, 1.0, 1.0], dtype=ManimColorDType) + ) + + +def test_init_with_hex() -> None: + color = ManimColor("0xFF0000") + nt.assert_array_equal(color._internal_value, np.array([1, 0, 0, 1])) + color = ManimColor("0xFF000000") + nt.assert_array_equal(color._internal_value, np.array([1, 0, 0, 0])) + + color = ManimColor("#FF0000") + nt.assert_array_equal(color._internal_value, np.array([1, 0, 0, 1])) + color = ManimColor("#FF000000") + nt.assert_array_equal(color._internal_value, np.array([1, 0, 0, 0])) + + +def test_init_with_hex_short() -> None: + color = ManimColor("#F00") + nt.assert_array_equal(color._internal_value, np.array([1, 0, 0, 1])) + color = ManimColor("0xF00") + nt.assert_array_equal(color._internal_value, np.array([1, 0, 0, 1])) + + color = ManimColor("#F000") + nt.assert_array_equal(color._internal_value, np.array([1, 0, 0, 0])) + color = ManimColor("0xF000") + nt.assert_array_equal(color._internal_value, np.array([1, 0, 0, 0])) + + +def test_init_with_string() -> None: + color = ManimColor("BLACK") + nt.assert_array_equal(color._internal_value, BLACK._internal_value) + + +def test_init_with_tuple_int() -> None: + color = ManimColor((50, 10, 50)) + nt.assert_array_equal( + color._internal_value, np.array([50 / 255, 10 / 255, 50 / 255, 1.0]) + ) + + color = ManimColor((50, 10, 50, 50)) + nt.assert_array_equal( + color._internal_value, np.array([50 / 255, 10 / 255, 50 / 255, 50 / 255]) + ) + + +def test_init_with_tuple_float() -> None: + color = ManimColor((0.5, 0.6, 0.7)) + nt.assert_array_equal(color._internal_value, np.array([0.5, 0.6, 0.7, 1.0])) + + color = ManimColor((0.5, 0.6, 0.7, 0.1)) + nt.assert_array_equal(color._internal_value, np.array([0.5, 0.6, 0.7, 0.1])) + + +def test_to_integer() -> None: + color = ManimColor((0x1, 0x2, 0x3, 0x4)) + nt.assert_equal(color.to_integer(), 0x010203) + + +def test_to_rgb() -> None: + color = ManimColor((0x1, 0x2, 0x3, 0x4)) + nt.assert_array_equal(color.to_rgb(), (0x1 / 255, 0x2 / 255, 0x3 / 255)) + nt.assert_array_equal(color.to_int_rgb(), (0x1, 0x2, 0x3)) + nt.assert_array_equal(color.to_rgba(), (0x1 / 255, 0x2 / 255, 0x3 / 255, 0x4 / 255)) + nt.assert_array_equal(color.to_int_rgba(), (0x1, 0x2, 0x3, 0x4)) + nt.assert_array_equal( + color.to_rgba_with_alpha(0.5), (0x1 / 255, 0x2 / 255, 0x3 / 255, 0.5) + ) + nt.assert_array_equal( + color.to_int_rgba_with_alpha(0.5), (0x1, 0x2, 0x3, int(0.5 * 255)) + ) + + +def test_to_hex() -> None: + color = ManimColor((0x1, 0x2, 0x3, 0x4)) + nt.assert_equal(color.to_hex(), "#010203") + nt.assert_equal(color.to_hex(True), "#01020304") + + +def test_to_hsv() -> None: + color = ManimColor((0x1, 0x2, 0x3, 0x4)) + nt.assert_array_equal( + color.to_hsv(), colorsys.rgb_to_hsv(0x1 / 255, 0x2 / 255, 0x3 / 255) + ) + + +def test_to_hsl() -> None: + color = ManimColor((0x1, 0x2, 0x3, 0x4)) + hls = colorsys.rgb_to_hls(0x1 / 255, 0x2 / 255, 0x3 / 255) + + nt.assert_array_equal(color.to_hsl(), np.array([hls[0], hls[2], hls[1]])) + + +def test_from_hsl() -> None: + hls = colorsys.rgb_to_hls(0x1 / 255, 0x2 / 255, 0x3 / 255) + hsl = np.array([hls[0], hls[2], hls[1]]) + + color = ManimColor.from_hsl(hsl) + rgb = np.array([0x1 / 255, 0x2 / 255, 0x3 / 255]) + + nt.assert_allclose(color.to_rgb(), rgb) + + +def test_invert() -> None: + color = ManimColor((0x1, 0x2, 0x3, 0x4)) + rgba = color._internal_value + inverted = color.invert() + nt.assert_array_equal( + inverted._internal_value, (1 - rgba[0], 1 - rgba[1], 1 - rgba[2], rgba[3]) + ) + + +def test_invert_with_alpha() -> None: + color = ManimColor((0x1, 0x2, 0x3, 0x4)) + rgba = color._internal_value + inverted = color.invert(True) + nt.assert_array_equal( + inverted._internal_value, (1 - rgba[0], 1 - rgba[1], 1 - rgba[2], 1 - rgba[3]) + ) + + +def test_interpolate() -> None: + r1 = RED._internal_value + r2 = YELLOW._internal_value + nt.assert_array_equal( + RED.interpolate(YELLOW, 0.5)._internal_value, 0.5 * r1 + 0.5 * r2 + ) + + +def test_opacity() -> None: + nt.assert_equal(RED.opacity(0.5)._internal_value[3], 0.5) + + +def test_parse() -> None: + nt.assert_equal(ManimColor.parse([RED, YELLOW]), [RED, YELLOW]) + + +def test_mc_operators() -> None: + c1 = RED + c2 = GREEN + halfway1 = 0.5 * c1 + 0.5 * c2 + halfway2 = c1.interpolate(c2, 0.5) + nt.assert_equal(halfway1, halfway2) + nt.assert_array_equal((WHITE / 2.0)._internal_value, np.array([0.5, 0.5, 0.5, 0.5])) + + +def test_mc_from_functions() -> None: + color = ManimColor.from_hex("#ff00a0") + nt.assert_equal(color.to_hex(), "#FF00A0") + + color = ManimColor.from_rgb((1.0, 1.0, 0.0)) + nt.assert_equal(color.to_hex(), "#FFFF00") + + color = ManimColor.from_rgba((1.0, 1.0, 0.0, 1.0)) + nt.assert_equal(color.to_hex(True), "#FFFF00FF") + + color = ManimColor.from_hsv((1.0, 1.0, 1.0), alpha=0.0) + nt.assert_equal(color.to_hex(True), "#FF000000") + + +def test_hsv_init() -> None: + color = HSV((0.25, 1, 1)) + nt.assert_array_equal(color._internal_value, np.array([0.5, 1.0, 0.0, 1.0])) + + +def test_into_HSV() -> None: + nt.assert_equal(RED.into(HSV).into(ManimColor), RED) + + +def test_contrasting() -> None: + nt.assert_equal(BLACK.contrasting(), WHITE) + nt.assert_equal(WHITE.contrasting(), BLACK) + nt.assert_equal(RED.contrasting(0.1), BLACK) + nt.assert_equal(RED.contrasting(0.9), WHITE) + nt.assert_equal(BLACK.contrasting(dark=GREEN, light=RED), RED) + nt.assert_equal(WHITE.contrasting(dark=GREEN, light=RED), GREEN) + + +def test_lighter() -> None: + c = RED.opacity(0.42) + cl = c.lighter(0.2) + nt.assert_array_equal( + cl._internal_value[:3], + 0.8 * c._internal_value[:3] + 0.2 * WHITE._internal_value[:3], + ) + nt.assert_equal(cl[-1], c[-1]) + + +def test_darker() -> None: + c = RED.opacity(0.42) + cd = c.darker(0.2) + nt.assert_array_equal( + cd._internal_value[:3], + 0.8 * c._internal_value[:3] + 0.2 * BLACK._internal_value[:3], + ) + nt.assert_equal(cd[-1], c[-1]) diff --git a/tests/test_space_ops.py b/tests/module/utils/test_space_ops.py similarity index 63% rename from tests/test_space_ops.py rename to tests/module/utils/test_space_ops.py index 108f586e0c..13584c797d 100644 --- a/tests/test_space_ops.py +++ b/tests/module/utils/test_space_ops.py @@ -4,7 +4,7 @@ import pytest from manim.utils.space_ops import * -from manim.utils.space_ops import shoelace, shoelace_direction +from manim.utils.space_ops import shoelace def test_rotate_vector(): @@ -12,15 +12,15 @@ def test_rotate_vector(): rotated = rotate_vector(vec, np.pi / 2) assert np.round(rotated[0], 5) == -1.0 assert not np.round(rotated[1:], 5).any() - assert np.all(rotate_vector(np.zeros(3), np.pi / 4) == np.zeros(3)) + np.testing.assert_array_equal(rotate_vector(np.zeros(3), np.pi / 4), np.zeros(3)) def test_rotation_matrices(): ang = np.pi / 6 ax = np.array([1, 1, 1]) - assert np.all( - np.round(rotation_matrix(ang, ax, True), 5) - == np.round( + np.testing.assert_array_equal( + np.round(rotation_matrix(ang, ax, True), 5), + np.round( np.array( [ [0.91068, -0.24402, 0.33333, 0.0], @@ -30,27 +30,27 @@ def test_rotation_matrices(): ] ), 5, - ) + ), ) - assert np.all( - np.round(rotation_about_z(np.pi / 3), 5) - == np.array( + np.testing.assert_array_equal( + np.round(rotation_about_z(np.pi / 3), 5), + np.array( [ [0.5, -0.86603, 0.0], [0.86603, 0.5, 0.0], [0.0, 0.0, 1.0], ] - ) + ), ) - assert np.all( - np.round(z_to_vector(np.array([1, 2, 3])), 5) - == np.array( + np.testing.assert_array_equal( + np.round(z_to_vector(np.array([1, 2, 3])), 5), + np.array( [ [0.96362, 0.0, 0.26726], [-0.14825, 0.83205, 0.53452], [-0.22237, -0.5547, 0.80178], ] - ) + ), ) @@ -60,20 +60,28 @@ def test_angle_of_vector(): np.round(angle_between_vectors(np.array([1, 1, 1]), np.array([-1, 1, 1])), 5) == 1.23096 ) - assert angle_of_vector(np.zeros(3)) == 0.0 + np.testing.assert_equal(angle_of_vector(np.zeros(3)), 0.0) + + +def test_angle_of_vector_vectorized(): + vec = np.random.randn(4, 10) + ref = [np.angle(complex(*v[:2])) for v in vec.T] + np.testing.assert_array_equal(ref, angle_of_vector(vec)) def test_center_of_mass(): - assert np.all(center_of_mass([[0, 0, 0], [1, 2, 3]]) == np.array([0.5, 1.0, 1.5])) + np.testing.assert_array_equal( + center_of_mass([[0, 0, 0], [1, 2, 3]]), np.array([0.5, 1.0, 1.5]) + ) def test_line_intersection(): - assert np.all( + np.testing.assert_array_equal( line_intersection( [[0, 0, 0], [3, 3, 0]], [[0, 3, 0], [3, 0, 0]], - ) - == np.array([1.5, 1.5, 0.0]) + ), + np.array([1.5, 1.5, 0.0]), ) with pytest.raises(ValueError): line_intersection( # parallel lines @@ -90,12 +98,12 @@ def test_line_intersection(): [[2, 2, 0], [3, 1, 0]], [[2, 2, 0], [3, 1, 0]], ) - assert np.all( + np.testing.assert_array_equal( line_intersection( # lines with ends out of bounds [[0, 0, 0], [1, 1, 0]], [[0, 4, 0], [1, 3, 0]], - ) - == np.array([2, 2, 0]) + ), + np.array([2, 2, 0]), ) @@ -106,8 +114,10 @@ def test_shoelace(): def test_polar_coords(): a = np.array([1, 1, 0]) b = (2, np.pi / 2, np.pi / 2) - assert np.all( - np.round(cartesian_to_spherical(a), 4) - == np.round([2**0.5, np.pi / 4, np.pi / 2], 4), + np.testing.assert_array_equal( + np.round(cartesian_to_spherical(a), 4), + np.round([2**0.5, np.pi / 4, np.pi / 2], 4), + ) + np.testing.assert_array_equal( + np.round(spherical_to_cartesian(b), 4), np.array([0, 2, 0]) ) - assert np.all(np.round(spherical_to_cartesian(b), 4) == np.array([0, 2, 0])) diff --git a/tests/module/utils/test_tex.py b/tests/module/utils/test_tex.py new file mode 100644 index 0000000000..ad0093e097 --- /dev/null +++ b/tests/module/utils/test_tex.py @@ -0,0 +1,142 @@ +import pytest + +from manim.utils.tex import TexTemplate, _texcode_for_environment + +DEFAULT_BODY = r"""\documentclass[preview]{standalone} +\usepackage[english]{babel} +\usepackage{amsmath} +\usepackage{amssymb} +\begin{document} +YourTextHere +\end{document}""" + +BODY_WITH_ADDED_PREAMBLE = r"""\documentclass[preview]{standalone} +\usepackage[english]{babel} +\usepackage{amsmath} +\usepackage{amssymb} +\usepackage{testpackage} +\begin{document} +YourTextHere +\end{document}""" + +BODY_WITH_PREPENDED_PREAMBLE = r"""\documentclass[preview]{standalone} +\usepackage{testpackage} +\usepackage[english]{babel} +\usepackage{amsmath} +\usepackage{amssymb} +\begin{document} +YourTextHere +\end{document}""" + +BODY_WITH_ADDED_DOCUMENT = r"""\documentclass[preview]{standalone} +\usepackage[english]{babel} +\usepackage{amsmath} +\usepackage{amssymb} +\begin{document} +\boldmath +YourTextHere +\end{document}""" + +BODY_REPLACE = r"""\documentclass[preview]{standalone} +\usepackage[english]{babel} +\usepackage{amsmath} +\usepackage{amssymb} +\begin{document} +\sqrt{2} +\end{document}""" + +BODY_REPLACE_IN_ENV = r"""\documentclass[preview]{standalone} +\usepackage[english]{babel} +\usepackage{amsmath} +\usepackage{amssymb} +\begin{document} +\begin{align} +\sqrt{2} +\end{align} +\end{document}""" + + +def test_tex_template_default_body(): + template = TexTemplate() + assert template.body == DEFAULT_BODY + + +def test_tex_template_preamble(): + template = TexTemplate() + + template.add_to_preamble(r"\usepackage{testpackage}") + assert template.body == BODY_WITH_ADDED_PREAMBLE + + +def test_tex_template_preprend_preamble(): + template = TexTemplate() + + template.add_to_preamble(r"\usepackage{testpackage}", prepend=True) + assert template.body == BODY_WITH_PREPENDED_PREAMBLE + + +def test_tex_template_document(): + template = TexTemplate() + + template.add_to_document(r"\boldmath") + assert template.body == BODY_WITH_ADDED_DOCUMENT + + +def test_tex_template_texcode_for_expression(): + template = TexTemplate() + + assert template.get_texcode_for_expression(r"\sqrt{2}") == BODY_REPLACE + + +def test_tex_template_texcode_for_expression_in_env(): + template = TexTemplate() + + assert ( + template.get_texcode_for_expression_in_env(r"\sqrt{2}", environment="align") + == BODY_REPLACE_IN_ENV + ) + + +def test_tex_template_fixed_body(): + template = TexTemplate() + + # Usually set when calling `from_file` + template.body = "dummy" + + assert template.body == "dummy" + + with pytest.warns( + UserWarning, + match="This TeX template was created with a fixed body, trying to add text the preamble will have no effect.", + ): + template.add_to_preamble("dummys") + + with pytest.warns( + UserWarning, + match="This TeX template was created with a fixed body, trying to add text the document will have no effect.", + ): + template.add_to_document("dummy") + + +def test_texcode_for_environment(): + """Test that the environment is correctly extracted from the input""" + # environment without arguments + assert _texcode_for_environment("align*") == (r"\begin{align*}", r"\end{align*}") + assert _texcode_for_environment("{align*}") == (r"\begin{align*}", r"\end{align*}") + assert _texcode_for_environment(r"\begin{align*}") == ( + r"\begin{align*}", + r"\end{align*}", + ) + # environment with arguments + assert _texcode_for_environment("{tabular}[t]{cccl}") == ( + r"\begin{tabular}[t]{cccl}", + r"\end{tabular}", + ) + assert _texcode_for_environment("tabular}{cccl") == ( + r"\begin{tabular}{cccl}", + r"\end{tabular}", + ) + assert _texcode_for_environment(r"\begin{tabular}[t]{cccl}") == ( + r"\begin{tabular}[t]{cccl}", + r"\end{tabular}", + ) diff --git a/tests/test_units.py b/tests/module/utils/test_units.py similarity index 52% rename from tests/test_units.py rename to tests/module/utils/test_units.py index ff1ad78862..5f2995e626 100644 --- a/tests/test_units.py +++ b/tests/module/utils/test_units.py @@ -3,28 +3,29 @@ import numpy as np import pytest -from manim import PI, X_AXIS, Y_AXIS, Z_AXIS, config +from manim import PI, X_AXIS, Y_AXIS, Z_AXIS from manim.utils.unit import Degrees, Munits, Percent, Pixels -def test_units(): +def test_units(config): # make sure we are using the right frame geometry - assert config.pixel_width == 1920 - assert np.isclose(config.frame_height, 8.0) + config.pixel_width = 1920 + + np.testing.assert_allclose(config.frame_height, 8.0) # Munits should be equivalent to the internal logical units - assert np.isclose(8.0 * Munits, config.frame_height) + np.testing.assert_allclose(8.0 * Munits, config.frame_height) # Pixels should convert from pixels to Munits - assert np.isclose(1920 * Pixels, config.frame_width) + np.testing.assert_allclose(1920 * Pixels, config.frame_width) # Percent should give the fractional length of the frame - assert np.isclose(50 * Percent(X_AXIS), config.frame_width / 2) - assert np.isclose(50 * Percent(Y_AXIS), config.frame_height / 2) + np.testing.assert_allclose(50 * Percent(X_AXIS), config.frame_width / 2) + np.testing.assert_allclose(50 * Percent(Y_AXIS), config.frame_height / 2) # The length of the Z axis is not defined with pytest.raises(NotImplementedError): Percent(Z_AXIS) # Degrees should convert from degrees to radians - assert np.isclose(180 * Degrees, PI) + np.testing.assert_allclose(180 * Degrees, PI) diff --git a/tests/opengl/control_data/coordinate_system_opengl/gradient_line_graph_x_axis_using_opengl_renderer[None].npz b/tests/opengl/control_data/coordinate_system_opengl/gradient_line_graph_x_axis_using_opengl_renderer[None].npz new file mode 100644 index 0000000000..6efda8b2e0 Binary files /dev/null and b/tests/opengl/control_data/coordinate_system_opengl/gradient_line_graph_x_axis_using_opengl_renderer[None].npz differ diff --git a/tests/opengl/control_data/coordinate_system_opengl/gradient_line_graph_y_axis_using_opengl_renderer[None].npz b/tests/opengl/control_data/coordinate_system_opengl/gradient_line_graph_y_axis_using_opengl_renderer[None].npz new file mode 100644 index 0000000000..3c7afcda7d Binary files /dev/null and b/tests/opengl/control_data/coordinate_system_opengl/gradient_line_graph_y_axis_using_opengl_renderer[None].npz differ diff --git a/tests/opengl/test_animate_opengl.py b/tests/opengl/test_animate_opengl.py index 1243fcb212..b5cf21afa6 100644 --- a/tests/opengl/test_animate_opengl.py +++ b/tests/opengl/test_animate_opengl.py @@ -23,10 +23,8 @@ def test_chained_animate(using_opengl_renderer): scale_factor = 2 direction = np.array((1, 1, 0)) anim = s.animate.scale(scale_factor).shift(direction).build() - assert ( - anim.mobject.target.width == scale_factor * s.width - and (anim.mobject.target.get_center() == direction).all() - ) + assert anim.mobject.target.width == scale_factor * s.width + assert (anim.mobject.target.get_center() == direction).all() def test_overridden_animate(using_opengl_renderer): @@ -103,10 +101,8 @@ def test_chained_animate_with_args(using_opengl_renderer): run_time = 2 anim = s.animate(run_time=run_time).scale(scale_factor).shift(direction).build() - assert ( - anim.mobject.target.width == scale_factor * s.width - and (anim.mobject.target.get_center() == direction).all() - ) + assert anim.mobject.target.width == scale_factor * s.width + assert (anim.mobject.target.get_center() == direction).all() assert anim.run_time == run_time diff --git a/tests/opengl/test_axes_shift_opengl.py b/tests/opengl/test_axes_shift_opengl.py index 731db633f0..1ae58afff4 100644 --- a/tests/opengl/test_axes_shift_opengl.py +++ b/tests/opengl/test_axes_shift_opengl.py @@ -7,5 +7,9 @@ def test_axes_origin_shift(using_opengl_renderer): ax = Axes(x_range=(5, 10, 1), y_range=(40, 45, 0.5)) - assert np.allclose(ax.coords_to_point(5.0, 40.0), ax.x_axis.number_to_point(5)) - assert np.allclose(ax.coords_to_point(5.0, 40.0), ax.y_axis.number_to_point(40)) + np.testing.assert_allclose( + ax.coords_to_point(5.0, 40.0), ax.x_axis.number_to_point(5) + ) + np.testing.assert_allclose( + ax.coords_to_point(5.0, 40.0), ax.y_axis.number_to_point(40) + ) diff --git a/tests/opengl/test_color_opengl.py b/tests/opengl/test_color_opengl.py index e3f6940ac4..3aeb2d6021 100644 --- a/tests/opengl/test_color_opengl.py +++ b/tests/opengl/test_color_opengl.py @@ -1,7 +1,6 @@ from __future__ import annotations import numpy as np -from colour import Color from manim import BLACK, BLUE, GREEN, PURE_BLUE, PURE_GREEN, PURE_RED, Scene from manim.mobject.opengl.opengl_mobject import OpenGLMobject @@ -16,153 +15,159 @@ def test_import_color(using_opengl_renderer): def test_background_color(using_opengl_renderer): S = Scene() - S.renderer.background_color = "#ff0000" + S.renderer.background_color = "#FF0000" S.renderer.update_frame(S) - assert np.all(S.renderer.get_frame()[0, 0] == np.array([255, 0, 0, 255])) + np.testing.assert_array_equal( + S.renderer.get_frame()[0, 0], np.array([255, 0, 0, 255]) + ) - S.renderer.background_color = "#436f80" + S.renderer.background_color = "#436F80" S.renderer.update_frame(S) - assert np.all(S.renderer.get_frame()[0, 0] == np.array([67, 111, 128, 255])) + np.testing.assert_array_equal( + S.renderer.get_frame()[0, 0], np.array([67, 111, 128, 255]) + ) - S.renderer.background_color = "#fff" + S.renderer.background_color = "#FFFFFF" S.renderer.update_frame(S) - assert np.all(S.renderer.get_frame()[0, 0] == np.array([255, 255, 255, 255])) + np.testing.assert_array_equal( + S.renderer.get_frame()[0, 0], np.array([255, 255, 255, 255]) + ) def test_set_color(using_opengl_renderer): m = OpenGLMobject() - assert m.color.hex == "#fff" - np.alltrue(m.rgbas == np.array((0.0, 0.0, 0.0, 1.0))) + assert m.color.to_hex() == "#FFFFFF" + np.all(m.rgbas == np.array((0.0, 0.0, 0.0, 1.0))) m.set_color(BLACK) - assert m.color.hex == "#000" - np.alltrue(m.rgbas == np.array((1.0, 1.0, 1.0, 1.0))) + assert m.color.to_hex() == "#000000" + np.all(m.rgbas == np.array((1.0, 1.0, 1.0, 1.0))) m.set_color(PURE_GREEN, opacity=0.5) - assert m.color.hex == "#0f0" - np.alltrue(m.rgbas == np.array((0.0, 1.0, 0.0, 0.5))) + assert m.color.to_hex() == "#00FF00" + np.all(m.rgbas == np.array((0.0, 1.0, 0.0, 0.5))) m = OpenGLVMobject() - assert m.color.hex == "#fff" - np.alltrue(m.fill_rgba == np.array((0.0, 0.0, 0.0, 1.0))) - np.alltrue(m.stroke_rgba == np.array((0.0, 0.0, 0.0, 1.0))) + assert m.color.to_hex() == "#FFFFFF" + np.all(m.fill_rgba == np.array((0.0, 0.0, 0.0, 1.0))) + np.all(m.stroke_rgba == np.array((0.0, 0.0, 0.0, 1.0))) m.set_color(BLACK) - assert m.color.hex == "#000" - np.alltrue(m.fill_rgba == np.array((1.0, 1.0, 1.0, 1.0))) - np.alltrue(m.stroke_rgba == np.array((1.0, 1.0, 1.0, 1.0))) + assert m.color.to_hex() == "#000000" + np.all(m.fill_rgba == np.array((1.0, 1.0, 1.0, 1.0))) + np.all(m.stroke_rgba == np.array((1.0, 1.0, 1.0, 1.0))) m.set_color(PURE_GREEN, opacity=0.5) - assert m.color.hex == "#0f0" - np.alltrue(m.fill_rgba == np.array((0.0, 1.0, 0.0, 0.5))) - np.alltrue(m.stroke_rgba == np.array((0.0, 1.0, 0.0, 0.5))) + assert m.color.to_hex() == "#00FF00" + np.all(m.fill_rgba == np.array((0.0, 1.0, 0.0, 0.5))) + np.all(m.stroke_rgba == np.array((0.0, 1.0, 0.0, 0.5))) def test_set_fill_color(using_opengl_renderer): m = OpenGLVMobject() - assert m.fill_color.hex == "#fff" - np.alltrue(m.fill_rgba == np.array((0.0, 1.0, 0.0, 0.5))) + assert m.fill_color.to_hex() == "#FFFFFF" + np.all(m.fill_rgba == np.array((0.0, 1.0, 0.0, 0.5))) m.set_fill(BLACK) - assert m.fill_color.hex == "#000" - np.alltrue(m.fill_rgba == np.array((1.0, 1.0, 1.0, 1.0))) + assert m.fill_color.to_hex() == "#000000" + np.all(m.fill_rgba == np.array((1.0, 1.0, 1.0, 1.0))) m.set_fill(PURE_GREEN, opacity=0.5) - assert m.fill_color.hex == "#0f0" - np.alltrue(m.fill_rgba == np.array((0.0, 1.0, 0.0, 0.5))) + assert m.fill_color.to_hex() == "#00FF00" + np.all(m.fill_rgba == np.array((0.0, 1.0, 0.0, 0.5))) def test_set_stroke_color(using_opengl_renderer): m = OpenGLVMobject() - assert m.stroke_color.hex == "#fff" - np.alltrue(m.stroke_rgba == np.array((0.0, 1.0, 0.0, 0.5))) + assert m.stroke_color.to_hex() == "#FFFFFF" + np.all(m.stroke_rgba == np.array((0.0, 1.0, 0.0, 0.5))) m.set_stroke(BLACK) - assert m.stroke_color.hex == "#000" - np.alltrue(m.stroke_rgba == np.array((1.0, 1.0, 1.0, 1.0))) + assert m.stroke_color.to_hex() == "#000000" + np.all(m.stroke_rgba == np.array((1.0, 1.0, 1.0, 1.0))) m.set_stroke(PURE_GREEN, opacity=0.5) - assert m.stroke_color.hex == "#0f0" - np.alltrue(m.stroke_rgba == np.array((0.0, 1.0, 0.0, 0.5))) + assert m.stroke_color.to_hex() == "#00FF00" + np.all(m.stroke_rgba == np.array((0.0, 1.0, 0.0, 0.5))) def test_set_fill(using_opengl_renderer): m = OpenGLMobject() - assert m.color.hex == "#fff" + assert m.color.to_hex() == "#FFFFFF" m.set_color(BLACK) - assert m.color.hex == "#000" + assert m.color.to_hex() == "#000000" m = OpenGLVMobject() - assert m.color.hex == "#fff" + assert m.color.to_hex() == "#FFFFFF" m.set_color(BLACK) - assert m.color.hex == "#000" + assert m.color.to_hex() == "#000000" def test_set_color_handles_lists_of_strs(using_opengl_renderer): m = OpenGLVMobject() - assert m.color.hex == "#fff" + assert m.color.to_hex() == "#FFFFFF" m.set_color([BLACK, BLUE, GREEN]) - assert m.get_colors()[0] == Color(BLACK) - assert m.get_colors()[1] == Color(BLUE) - assert m.get_colors()[2] == Color(GREEN) + assert m.get_colors()[0] == BLACK + assert m.get_colors()[1] == BLUE + assert m.get_colors()[2] == GREEN - assert m.get_fill_colors()[0] == Color(BLACK) - assert m.get_fill_colors()[1] == Color(BLUE) - assert m.get_fill_colors()[2] == Color(GREEN) + assert m.get_fill_colors()[0] == BLACK + assert m.get_fill_colors()[1] == BLUE + assert m.get_fill_colors()[2] == GREEN - assert m.get_stroke_colors()[0] == Color(BLACK) - assert m.get_stroke_colors()[1] == Color(BLUE) - assert m.get_stroke_colors()[2] == Color(GREEN) + assert m.get_stroke_colors()[0] == BLACK + assert m.get_stroke_colors()[1] == BLUE + assert m.get_stroke_colors()[2] == GREEN def test_set_color_handles_lists_of_color_objects(using_opengl_renderer): m = OpenGLVMobject() - assert m.color.hex == "#fff" - m.set_color([Color(PURE_BLUE), Color(PURE_GREEN), Color(PURE_RED)]) - assert m.get_colors()[0].hex == "#00f" - assert m.get_colors()[1].hex == "#0f0" - assert m.get_colors()[2].hex == "#f00" + assert m.color.to_hex() == "#FFFFFF" + m.set_color([PURE_BLUE, PURE_GREEN, PURE_RED]) + assert m.get_colors()[0].to_hex() == "#0000FF" + assert m.get_colors()[1].to_hex() == "#00FF00" + assert m.get_colors()[2].to_hex() == "#FF0000" - assert m.get_fill_colors()[0].hex == "#00f" - assert m.get_fill_colors()[1].hex == "#0f0" - assert m.get_fill_colors()[2].hex == "#f00" + assert m.get_fill_colors()[0].to_hex() == "#0000FF" + assert m.get_fill_colors()[1].to_hex() == "#00FF00" + assert m.get_fill_colors()[2].to_hex() == "#FF0000" - assert m.get_stroke_colors()[0].hex == "#00f" - assert m.get_stroke_colors()[1].hex == "#0f0" - assert m.get_stroke_colors()[2].hex == "#f00" + assert m.get_stroke_colors()[0].to_hex() == "#0000FF" + assert m.get_stroke_colors()[1].to_hex() == "#00FF00" + assert m.get_stroke_colors()[2].to_hex() == "#FF0000" def test_set_fill_handles_lists_of_strs(using_opengl_renderer): m = OpenGLVMobject() - assert m.fill_color.hex == "#fff" - m.set_fill([BLACK, BLUE, GREEN]) - assert m.get_fill_colors()[0] == Color(BLACK) - assert m.get_fill_colors()[1] == Color(BLUE) - assert m.get_fill_colors()[2] == Color(GREEN) + assert m.fill_color.to_hex() == "#FFFFFF" + m.set_fill([BLACK.to_hex(), BLUE.to_hex(), GREEN.to_hex()]) + assert m.get_fill_colors()[0].to_hex() == BLACK.to_hex() + assert m.get_fill_colors()[1].to_hex() == BLUE.to_hex() + assert m.get_fill_colors()[2].to_hex() == GREEN.to_hex() def test_set_fill_handles_lists_of_color_objects(using_opengl_renderer): m = OpenGLVMobject() - assert m.fill_color.hex == "#fff" - m.set_fill([Color(PURE_BLUE), Color(PURE_GREEN), Color(PURE_RED)]) - assert m.get_fill_colors()[0].hex == "#00f" - assert m.get_fill_colors()[1].hex == "#0f0" - assert m.get_fill_colors()[2].hex == "#f00" + assert m.fill_color.to_hex() == "#FFFFFF" + m.set_fill([PURE_BLUE, PURE_GREEN, PURE_RED]) + assert m.get_fill_colors()[0].to_hex() == "#0000FF" + assert m.get_fill_colors()[1].to_hex() == "#00FF00" + assert m.get_fill_colors()[2].to_hex() == "#FF0000" def test_set_stroke_handles_lists_of_strs(using_opengl_renderer): m = OpenGLVMobject() - assert m.stroke_color.hex == "#fff" - m.set_stroke([BLACK, BLUE, GREEN]) - assert m.get_stroke_colors()[0] == Color(BLACK) - assert m.get_stroke_colors()[1] == Color(BLUE) - assert m.get_stroke_colors()[2] == Color(GREEN) + assert m.stroke_color.to_hex() == "#FFFFFF" + m.set_stroke([BLACK.to_hex(), BLUE.to_hex(), GREEN.to_hex()]) + assert m.get_stroke_colors()[0].to_hex() == BLACK.to_hex() + assert m.get_stroke_colors()[1].to_hex() == BLUE.to_hex() + assert m.get_stroke_colors()[2].to_hex() == GREEN.to_hex() def test_set_stroke_handles_lists_of_color_objects(using_opengl_renderer): m = OpenGLVMobject() - assert m.stroke_color.hex == "#fff" - m.set_stroke([Color(PURE_BLUE), Color(PURE_GREEN), Color(PURE_RED)]) - assert m.get_stroke_colors()[0].hex == "#00f" - assert m.get_stroke_colors()[1].hex == "#0f0" - assert m.get_stroke_colors()[2].hex == "#f00" + assert m.stroke_color.to_hex() == "#FFFFFF" + m.set_stroke([PURE_BLUE, PURE_GREEN, PURE_RED]) + assert m.get_stroke_colors()[0].to_hex() == "#0000FF" + assert m.get_stroke_colors()[1].to_hex() == "#00FF00" + assert m.get_stroke_colors()[2].to_hex() == "#FF0000" diff --git a/tests/opengl/test_composition_opengl.py b/tests/opengl/test_composition_opengl.py index 1bedc3edcf..c09cd691a1 100644 --- a/tests/opengl/test_composition_opengl.py +++ b/tests/opengl/test_composition_opengl.py @@ -104,4 +104,4 @@ def test_animationgroup_with_wait(using_opengl_renderer): animation_group.begin() timings = animation_group.anims_with_timings - assert timings == [(wait, 0.0, 1.0), (sqr_anim, 1.0, 2.0)] + assert timings.tolist() == [(wait, 0.0, 1.0), (sqr_anim, 1.0, 2.0)] diff --git a/tests/opengl/test_config_opengl.py b/tests/opengl/test_config_opengl.py index f3013800dc..d0ca0e5a81 100644 --- a/tests/opengl/test_config_opengl.py +++ b/tests/opengl/test_config_opengl.py @@ -5,10 +5,10 @@ import numpy as np -from manim import WHITE, Scene, Square, config, tempconfig +from manim import WHITE, Scene, Square, tempconfig -def test_tempconfig(using_opengl_renderer): +def test_tempconfig(config, using_opengl_renderer): """Test the tempconfig context manager.""" original = config.copy() @@ -26,7 +26,7 @@ def test_tempconfig(using_opengl_renderer): # check that config is correctly restored for k, v in original.items(): if isinstance(v, np.ndarray): - assert np.allclose(config[k], v) + np.testing.assert_allclose(config[k], v) else: assert config[k] == v @@ -37,19 +37,20 @@ def construct(self): self.wait(1) -def test_background_color(using_opengl_renderer): +def test_background_color(config, using_opengl_renderer, dry_run): """Test the 'background_color' config option.""" - with tempconfig({"background_color": WHITE, "verbosity": "ERROR", "dry_run": True}): - scene = MyScene() - scene.render() - frame = scene.renderer.get_frame() - assert np.allclose(frame[0, 0], [255, 255, 255, 255]) + config.background_color = WHITE + config.verbose = "ERROR" + scene = MyScene() + scene.render() + frame = scene.renderer.get_frame() + np.testing.assert_allclose(frame[0, 0], [255, 255, 255, 255]) -def test_digest_file(using_opengl_renderer, tmp_path): + +def test_digest_file(config, using_opengl_renderer, tmp_path): """Test that a config file can be digested programmatically.""" - with tempconfig({}): - tmp_cfg = tempfile.NamedTemporaryFile("w", dir=tmp_path, delete=False) + with tempfile.NamedTemporaryFile("w", dir=tmp_path, delete=False) as tmp_cfg: tmp_cfg.write( """ [CLI] @@ -58,38 +59,39 @@ def test_digest_file(using_opengl_renderer, tmp_path): frame_height = 10 """, ) - tmp_cfg.close() - config.digest_file(tmp_cfg.name) + config.digest_file(tmp_cfg.name) - assert config.get_dir("media_dir") == Path("this_is_my_favorite_path") - assert config.get_dir("video_dir") == Path("this_is_my_favorite_path/videos") + assert config.get_dir("media_dir") == Path("this_is_my_favorite_path") + assert config.get_dir("video_dir") == Path("this_is_my_favorite_path/videos") -def test_frame_size(using_opengl_renderer, tmp_path): +def test_frame_size(config, using_opengl_renderer, tmp_path): """Test that the frame size can be set via config file.""" - assert np.allclose(config.aspect_ratio, config.pixel_width / config.pixel_height) - assert np.allclose(config.frame_height, 8.0) + np.testing.assert_allclose( + config.aspect_ratio, config.pixel_width / config.pixel_height + ) + np.testing.assert_allclose(config.frame_height, 8.0) with tempconfig({}): - tmp_cfg = tempfile.NamedTemporaryFile("w", dir=tmp_path, delete=False) - tmp_cfg.write( - """ - [CLI] - pixel_height = 10 - pixel_width = 10 - """, - ) - tmp_cfg.close() + with tempfile.NamedTemporaryFile("w", dir=tmp_path, delete=False) as tmp_cfg: + tmp_cfg.write( + """ + [CLI] + pixel_height = 10 + pixel_width = 10 + """, + ) config.digest_file(tmp_cfg.name) # aspect ratio is set using pixel measurements - assert np.allclose(config.aspect_ratio, 1.0) + np.testing.assert_allclose(config.aspect_ratio, 1.0) # if not specified in the cfg file, frame_width is set using the aspect ratio - assert np.allclose(config.frame_height, 8.0) - assert np.allclose(config.frame_width, 8.0) + np.testing.assert_allclose(config.frame_height, 8.0) + np.testing.assert_allclose(config.frame_width, 8.0) - with tempconfig({}): - tmp_cfg = tempfile.NamedTemporaryFile("w", dir=tmp_path, delete=False) + +def test_frame_size_if_frame_width(config, using_opengl_renderer, tmp_path): + with tempfile.NamedTemporaryFile("w", dir=tmp_path, delete=False) as tmp_cfg: tmp_cfg.write( """ [CLI] @@ -99,16 +101,16 @@ def test_frame_size(using_opengl_renderer, tmp_path): frame_width = 10 """, ) - tmp_cfg.close() - config.digest_file(tmp_cfg.name) + tmp_cfg.close() + config.digest_file(tmp_cfg.name) - assert np.allclose(config.aspect_ratio, 1.0) - # if both are specified in the cfg file, the aspect ratio is ignored - assert np.allclose(config.frame_height, 10.0) - assert np.allclose(config.frame_width, 10.0) + np.testing.assert_allclose(config.aspect_ratio, 1.0) + # if both are specified in the cfg file, the aspect ratio is ignored + np.testing.assert_allclose(config.frame_height, 10.0) + np.testing.assert_allclose(config.frame_width, 10.0) -def test_temporary_dry_run(using_opengl_renderer): +def test_temporary_dry_run(config, using_opengl_renderer): """Test that tempconfig correctly restores after setting dry_run.""" assert config["write_to_movie"] assert not config["save_last_frame"] @@ -121,21 +123,20 @@ def test_temporary_dry_run(using_opengl_renderer): assert not config["save_last_frame"] -def test_dry_run_with_png_format(using_opengl_renderer): +def test_dry_run_with_png_format(config, using_opengl_renderer, dry_run): """Test that there are no exceptions when running a png without output""" - with tempconfig( - {"dry_run": True, "write_to_movie": False, "disable_caching": True} - ): - assert config["dry_run"] is True - scene = MyScene() - scene.render() + config.disable_caching = True + assert config["dry_run"] is True + scene = MyScene() + scene.render() -def test_dry_run_with_png_format_skipped_animations(using_opengl_renderer): +def test_dry_run_with_png_format_skipped_animations( + config, using_opengl_renderer, dry_run +): """Test that there are no exceptions when running a png without output and skipped animations""" - with tempconfig( - {"dry_run": True, "write_to_movie": False, "disable_caching": True} - ): - assert config["dry_run"] is True - scene = MyScene(skip_animations=True) - scene.render() + config.write_to_movie = False + config.disable_caching = True + assert config["dry_run"] is True + scene = MyScene(skip_animations=True) + scene.render() diff --git a/tests/opengl/test_coordinate_system_opengl.py b/tests/opengl/test_coordinate_system_opengl.py index 8e1d778e52..c9f5cc81b6 100644 --- a/tests/opengl/test_coordinate_system_opengl.py +++ b/tests/opengl/test_coordinate_system_opengl.py @@ -5,9 +5,25 @@ import numpy as np import pytest -from manim import LEFT, ORIGIN, PI, UR, Axes, Circle, ComplexPlane +from manim import ( + LEFT, + ORIGIN, + PI, + UR, + Axes, + Circle, + ComplexPlane, + NumberPlane, + PolarPlane, + ThreeDAxes, + config, + tempconfig, +) from manim import CoordinateSystem as CS -from manim import NumberPlane, PolarPlane, ThreeDAxes, config, tempconfig +from manim.utils.color import BLUE, GREEN, ORANGE, RED, YELLOW +from manim.utils.testing.frames_comparison import frames_comparison + +__module_test__ = "coordinate_system_opengl" def test_initial_config(using_opengl_renderer): @@ -21,8 +37,8 @@ def test_initial_config(using_opengl_renderer): assert cs.y_range[2] == 1.0 ax = Axes() - assert np.allclose(ax.get_center(), ORIGIN) - assert np.allclose(ax.y_axis_config["label_direction"], LEFT) + np.testing.assert_allclose(ax.get_center(), ORIGIN) + np.testing.assert_allclose(ax.y_axis_config["label_direction"], LEFT) with tempconfig({"frame_x_radius": 100, "frame_y_radius": 200}): cs = CS() @@ -43,7 +59,7 @@ def test_dimension(using_opengl_renderer): def test_abstract_base_class(using_opengl_renderer): """Check that CoordinateSystem has some abstract methods.""" - with pytest.raises(Exception): + with pytest.raises(NotImplementedError): CS().get_axes() @@ -69,7 +85,6 @@ def test_NumberPlane(using_opengl_renderer): ] for test_data in testing_data: - x_range, y_range, x_vals, y_vals = test_data x_start, x_end = x_range @@ -102,7 +117,7 @@ def test_point_to_coords(using_opengl_renderer): # get the coordinates of the circle with respect to the axes coords = np.around(ax.point_to_coords(circ.get_right()), decimals=4) - assert np.array_equal(coords, (7.0833, 2.6667)) + np.testing.assert_array_equal(coords, (7.0833, 2.6667)) def test_coords_to_point(using_opengl_renderer): @@ -110,7 +125,7 @@ def test_coords_to_point(using_opengl_renderer): # a point with respect to the axes c2p_coord = np.around(ax.coords_to_point(2, 2), decimals=4) - assert np.array_equal(c2p_coord, (1.7143, 1.5, 0)) + np.testing.assert_array_equal(c2p_coord, (1.7143, 1.5, 0)) def test_input_to_graph_point(using_opengl_renderer): @@ -122,8 +137,38 @@ def test_input_to_graph_point(using_opengl_renderer): # move a square to PI on the cosine curve. position = np.around(ax.input_to_graph_point(x=PI, graph=curve), decimals=4) - assert np.array_equal(position, (2.6928, -0.75, 0)) + np.testing.assert_array_equal(position, (2.6928, -0.75, 0)) # test the line_graph implementation position = np.around(ax.input_to_graph_point(x=PI, graph=line_graph), decimals=4) - assert np.array_equal(position, (2.6928, 1.2876, 0)) + np.testing.assert_array_equal(position, (2.6928, 1.2876, 0)) + + +@frames_comparison +def test_gradient_line_graph_x_axis(scene, using_opengl_renderer): + """Test that using `colorscale` generates a line whose gradient matches the y-axis""" + axes = Axes(x_range=[-3, 3], y_range=[-3, 3]) + + curve = axes.plot( + lambda x: 0.1 * x**3, + x_range=(-3, 3, 0.001), + colorscale=[BLUE, GREEN, YELLOW, ORANGE, RED], + colorscale_axis=0, + ) + + scene.add(axes, curve) + + +@frames_comparison +def test_gradient_line_graph_y_axis(scene, using_opengl_renderer): + """Test that using `colorscale` generates a line whose gradient matches the y-axis""" + axes = Axes(x_range=[-3, 3], y_range=[-3, 3]) + + curve = axes.plot( + lambda x: 0.1 * x**3, + x_range=(-3, 3, 0.001), + colorscale=[BLUE, GREEN, YELLOW, ORANGE, RED], + colorscale_axis=1, + ) + + scene.add(axes, curve) diff --git a/tests/opengl/test_copy_opengl.py b/tests/opengl/test_copy_opengl.py index db2e06dba4..504b7f26a5 100644 --- a/tests/opengl/test_copy_opengl.py +++ b/tests/opengl/test_copy_opengl.py @@ -2,7 +2,7 @@ from pathlib import Path -from manim import BraceLabel, config +from manim import BraceLabel from manim.mobject.opengl.opengl_mobject import OpenGLMobject @@ -19,7 +19,7 @@ def test_opengl_mobject_copy(using_opengl_renderer): assert orig.submobjects[i] is not copy.submobjects[i] -def test_bracelabel_copy(using_opengl_renderer, tmp_path): +def test_bracelabel_copy(config, using_opengl_renderer, tmp_path): """Test that a copy is a deepcopy.""" # For this test to work, we need to tweak some folders temporarily original_text_dir = config["text_dir"] diff --git a/tests/opengl/test_family_opengl.py b/tests/opengl/test_family_opengl.py index a7dd35e93b..f16d0e4756 100644 --- a/tests/opengl/test_family_opengl.py +++ b/tests/opengl/test_family_opengl.py @@ -41,7 +41,11 @@ def test_family(using_opengl_renderer): def test_overlapping_family(using_opengl_renderer): """Check that each member of the family is only gathered once.""" - mob, child1, child2, = ( + ( + mob, + child1, + child2, + ) = ( OpenGLMobject(), OpenGLMobject(), OpenGLMobject(), @@ -65,7 +69,11 @@ def test_shift_family(using_opengl_renderer): """ # Note shift() needs the OpenGLMobject to have a non-empty `points` attribute, so # we cannot use a plain OpenGLMobject or OpenGLVMobject. We use Circle instead. - mob, child1, child2, = ( + ( + mob, + child1, + child2, + ) = ( Circle(), Circle(), Circle(), @@ -82,4 +90,4 @@ def test_shift_family(using_opengl_renderer): positions_after = {m: m.get_center().copy() for m in family} for m in family: - assert np.allclose(positions_before[m] + RIGHT, positions_after[m]) + np.testing.assert_allclose(positions_before[m] + RIGHT, positions_after[m]) diff --git a/tests/opengl/test_graph_opengl.py b/tests/opengl/test_graph_opengl.py index 4c246eaca1..eb56935b9c 100644 --- a/tests/opengl/test_graph_opengl.py +++ b/tests/opengl/test_graph_opengl.py @@ -92,7 +92,7 @@ def test_graph_remove_edges(using_opengl_renderer): assert set(G.edges.keys()) == {(2, 3), (3, 4), (4, 5), (1, 5)} assert set(G._graph.edges()) == set(G.edges.keys()) - removed_mobjects = G.remove_edges((2, 3), (3, 4), (4, 5), (5, 1)) + removed_mobjects = G.remove_edges((2, 3), (3, 4), (4, 5), (1, 5)) assert len(removed_mobjects) == 4 assert len(G.vertices) == 5 assert len(G.edges) == 0 diff --git a/tests/opengl/test_ipython_magic_opengl.py b/tests/opengl/test_ipython_magic_opengl.py index ade725cbec..2d4617af0f 100644 --- a/tests/opengl/test_ipython_magic_opengl.py +++ b/tests/opengl/test_ipython_magic_opengl.py @@ -2,36 +2,29 @@ import re -from manim import config, tempconfig from manim.utils.ipython_magic import _generate_file_name -def test_jupyter_file_naming(): +def test_jupyter_file_naming(config, using_opengl_renderer): """Check the format of file names for jupyter""" scene_name = "SimpleScene" expected_pattern = r"[0-9a-zA-Z_]+[@_-]\d\d\d\d-\d\d-\d\d[@_-]\d\d-\d\d-\d\d" - current_renderer = config.renderer - with tempconfig({"scene_names": [scene_name], "renderer": "opengl"}): - file_name = _generate_file_name() - match = re.match(expected_pattern, file_name) - assert scene_name in file_name, ( - "Expected file to contain " + scene_name + " but got " + file_name - ) - assert match, "file name does not match expected pattern " + expected_pattern - # needs manually set back to avoid issues across tests - config.renderer = current_renderer + config.scene_names = [scene_name] + file_name = _generate_file_name() + match = re.match(expected_pattern, file_name) + assert scene_name in file_name, ( + "Expected file to contain " + scene_name + " but got " + file_name + ) + assert match, "file name does not match expected pattern " + expected_pattern -def test_jupyter_file_output(tmp_path): +def test_jupyter_file_output(tmp_path, config, using_opengl_renderer): """Check the jupyter file naming is valid and can be created""" scene_name = "SimpleScene" - current_renderer = config.renderer - with tempconfig({"scene_names": [scene_name], "renderer": "opengl"}): - file_name = _generate_file_name() - actual_path = tmp_path.with_name(file_name) - with open(actual_path, "w") as outfile: - outfile.write("") - assert actual_path.exists() - assert actual_path.is_file() - # needs manually set back to avoid issues across tests - config.renderer = current_renderer + config.scene_names = [scene_name] + file_name = _generate_file_name() + actual_path = tmp_path.with_name(file_name) + with actual_path.open("w") as outfile: + outfile.write("") + assert actual_path.exists() + assert actual_path.is_file() diff --git a/tests/opengl/test_markup_opengl.py b/tests/opengl/test_markup_opengl.py index b8a0e1c9fd..60c83c4304 100644 --- a/tests/opengl/test_markup_opengl.py +++ b/tests/opengl/test_markup_opengl.py @@ -22,9 +22,9 @@ def test_special_tags_markup(using_opengl_renderer): success = True except ValueError: success = False - assert ( - success - ), '\'foo\' and \'foo\' should not fail validation' + assert success, ( + '\'foo\' and \'foo\' should not fail validation' + ) def test_unbalanced_tag_markup(using_opengl_renderer): diff --git a/tests/opengl/test_number_line_opengl.py b/tests/opengl/test_number_line_opengl.py index 4092e4bfd1..6f9742e523 100644 --- a/tests/opengl/test_number_line_opengl.py +++ b/tests/opengl/test_number_line_opengl.py @@ -8,7 +8,8 @@ def test_unit_vector(): """Check if the magnitude of unit vector along - the NumberLine is equal to its unit_size.""" + the NumberLine is equal to its unit_size. + """ axis1 = NumberLine(unit_size=0.4) axis2 = NumberLine(x_range=[-2, 5], length=12) for axis in (axis1, axis2): @@ -17,7 +18,8 @@ def test_unit_vector(): def test_decimal_determined_by_step(): """Checks that step size is considered when determining the number of decimal - places.""" + places. + """ axis = NumberLine(x_range=[-2, 2, 0.5]) expected_decimal_places = 1 actual_decimal_places = axis.decimal_number_config["num_decimal_places"] @@ -63,6 +65,6 @@ def test_add_labels(): dict(zip(list(range(-3, 3)), [Integer(m) for m in range(-1, 5)])), ) actual_label_length = len(num_line.labels) - assert ( - actual_label_length == expected_label_length - ), f"Expected a VGroup with {expected_label_length} integers but got {actual_label_length}." + assert actual_label_length == expected_label_length, ( + f"Expected a VGroup with {expected_label_length} integers but got {actual_label_length}." + ) diff --git a/tests/opengl/test_numbers_opengl.py b/tests/opengl/test_numbers_opengl.py index 9bc2ddd13f..78cd4fac0d 100644 --- a/tests/opengl/test_numbers_opengl.py +++ b/tests/opengl/test_numbers_opengl.py @@ -5,7 +5,8 @@ def test_font_size(): """Test that DecimalNumber returns the correct font_size value - after being scaled.""" + after being scaled. + """ num = DecimalNumber(0).scale(0.3) assert round(num.font_size, 5) == 14.4 diff --git a/tests/opengl/test_opengl_mobject.py b/tests/opengl/test_opengl_mobject.py index f1a58fa6a3..d5bfac97f9 100644 --- a/tests/opengl/test_opengl_mobject.py +++ b/tests/opengl/test_opengl_mobject.py @@ -25,15 +25,26 @@ def test_opengl_mobject_add(using_opengl_renderer): # check that OpenGLMobject.add() returns the OpenGLMobject (for chained calls) assert obj.add(OpenGLMobject()) is obj + assert len(obj.submobjects) == 13 + obj = OpenGLMobject() - # a OpenGLMobject cannot contain itself - with pytest.raises(ValueError): - obj.add(obj) + # an OpenGLMobject cannot contain itself + with pytest.raises(ValueError) as add_self_info: + obj.add(OpenGLMobject(), obj, OpenGLMobject()) + assert str(add_self_info.value) == ( + "Cannot add OpenGLMobject as a submobject of itself (at index 1)." + ) + assert len(obj.submobjects) == 0 - # can only add OpenGLMobjects - with pytest.raises(TypeError): - obj.add("foo") + # can only add Mobjects + with pytest.raises(TypeError) as add_str_info: + obj.add(OpenGLMobject(), OpenGLMobject(), "foo") + assert str(add_str_info.value) == ( + "Only values of type OpenGLMobject can be added as submobjects of " + "OpenGLMobject, but the value foo (at index 2) is of type str." + ) + assert len(obj.submobjects) == 0 def test_opengl_mobject_remove(using_opengl_renderer): diff --git a/tests/opengl/test_opengl_surface.py b/tests/opengl/test_opengl_surface.py new file mode 100644 index 0000000000..d6897691d4 --- /dev/null +++ b/tests/opengl/test_opengl_surface.py @@ -0,0 +1,14 @@ +import numpy as np + +from manim.mobject.opengl.opengl_surface import OpenGLSurface +from manim.mobject.opengl.opengl_three_dimensions import OpenGLSurfaceMesh + + +def test_surface_initialization(using_opengl_renderer): + surface = OpenGLSurface( + lambda u, v: (u, v, u * np.sin(v) + v * np.cos(u)), + u_range=(-3, 3), + v_range=(-3, 3), + ) + + mesh = OpenGLSurfaceMesh(surface) diff --git a/tests/opengl/test_opengl_vectorized_mobject.py b/tests/opengl/test_opengl_vectorized_mobject.py index 64b53641c0..ae41f83b61 100644 --- a/tests/opengl/test_opengl_vectorized_mobject.py +++ b/tests/opengl/test_opengl_vectorized_mobject.py @@ -3,12 +3,59 @@ import numpy as np import pytest -from manim import Circle, Line, Square, VDict, VGroup +from manim import Circle, Line, Square, VDict, VGroup, VMobject from manim.mobject.opengl.opengl_mobject import OpenGLMobject from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject -def test_opengl_vmobject_point_from_propotion(using_opengl_renderer): +def test_opengl_vmobject_add(using_opengl_renderer): + """Test the OpenGLVMobject add method.""" + obj = OpenGLVMobject() + assert len(obj.submobjects) == 0 + + obj.add(OpenGLVMobject()) + assert len(obj.submobjects) == 1 + + # Can't add non-OpenGLVMobject values to a VMobject. + with pytest.raises(TypeError) as add_int_info: + obj.add(3) + assert str(add_int_info.value) == ( + "Only values of type OpenGLVMobject can be added as submobjects of " + "OpenGLVMobject, but the value 3 (at index 0) is of type int." + ) + assert len(obj.submobjects) == 1 + + # Plain OpenGLMobjects can't be added to a OpenGLVMobject if they're not + # OpenGLVMobjects. Suggest adding them into an OpenGLGroup instead. + with pytest.raises(TypeError) as add_mob_info: + obj.add(OpenGLMobject()) + assert str(add_mob_info.value) == ( + "Only values of type OpenGLVMobject can be added as submobjects of " + "OpenGLVMobject, but the value OpenGLMobject (at index 0) is of type " + "OpenGLMobject. You can try adding this value into a Group instead." + ) + assert len(obj.submobjects) == 1 + + with pytest.raises(TypeError) as add_vmob_and_mob_info: + # If only one of the added objects is not an instance of VMobject, none of them should be added + obj.add(OpenGLVMobject(), OpenGLMobject()) + assert str(add_vmob_and_mob_info.value) == ( + "Only values of type OpenGLVMobject can be added as submobjects of " + "OpenGLVMobject, but the value OpenGLMobject (at index 1) is of type " + "OpenGLMobject. You can try adding this value into a Group instead." + ) + assert len(obj.submobjects) == 1 + + # A VMobject or VGroup cannot contain itself. + with pytest.raises(ValueError) as add_self_info: + obj.add(obj) + assert str(add_self_info.value) == ( + "Cannot add OpenGLVMobject as a submobject of itself (at index 0)." + ) + assert len(obj.submobjects) == 1 + + +def test_opengl_vmobject_point_from_proportion(using_opengl_renderer): obj = OpenGLVMobject() # One long line, one short line @@ -22,7 +69,7 @@ def test_opengl_vmobject_point_from_propotion(using_opengl_renderer): # Total length of 6, so halfway along the object # would be at length 3, which lands in the first, long line. - assert np.all(obj.point_from_proportion(0.5) == np.array([3, 0, 0])) + np.testing.assert_array_equal(obj.point_from_proportion(0.5), np.array([3, 0, 0])) with pytest.raises(ValueError, match="between 0 and 1"): obj.point_from_proportion(2) @@ -37,28 +84,135 @@ def test_vgroup_init(using_opengl_renderer): VGroup() VGroup(OpenGLVMobject()) VGroup(OpenGLVMobject(), OpenGLVMobject()) - with pytest.raises(TypeError): + + # A VGroup cannot contain non-VMobject values. + with pytest.raises(TypeError) as init_with_float_info: + VGroup(3.0) + assert str(init_with_float_info.value) == ( + "Only values of type OpenGLVMobject can be added as submobjects of " + "VGroup, but the value 3.0 (at index 0 of parameter 0) is of type float." + ) + + with pytest.raises(TypeError) as init_with_mob_info: VGroup(OpenGLMobject()) - with pytest.raises(TypeError): - VGroup(OpenGLMobject(), OpenGLMobject()) + assert str(init_with_mob_info.value) == ( + "Only values of type OpenGLVMobject can be added as submobjects of " + "VGroup, but the value OpenGLMobject (at index 0 of parameter 0) is of type " + "OpenGLMobject. You can try adding this value into a Group instead." + ) + + with pytest.raises(TypeError) as init_with_vmob_and_mob_info: + VGroup(OpenGLVMobject(), OpenGLMobject()) + assert str(init_with_vmob_and_mob_info.value) == ( + "Only values of type OpenGLVMobject can be added as submobjects of " + "VGroup, but the value OpenGLMobject (at index 0 of parameter 1) is of type " + "OpenGLMobject. You can try adding this value into a Group instead." + ) + + +def test_vgroup_init_with_iterable(using_opengl_renderer): + """Test VGroup instantiation with an iterable type.""" + + def type_generator(type_to_generate, n): + return (type_to_generate() for _ in range(n)) + + def mixed_type_generator(major_type, minor_type, minor_type_positions, n): + return ( + minor_type() if i in minor_type_positions else major_type() + for i in range(n) + ) + + obj = VGroup(OpenGLVMobject()) + assert len(obj.submobjects) == 1 + + obj = VGroup(type_generator(OpenGLVMobject, 38)) + assert len(obj.submobjects) == 38 + + obj = VGroup( + OpenGLVMobject(), + [OpenGLVMobject(), OpenGLVMobject()], + type_generator(OpenGLVMobject, 38), + ) + assert len(obj.submobjects) == 41 + + # A VGroup cannot be initialised with an iterable containing a OpenGLMobject + with pytest.raises(TypeError) as init_with_mob_iterable: + VGroup(type_generator(OpenGLMobject, 5)) + assert str(init_with_mob_iterable.value) == ( + "Only values of type OpenGLVMobject can be added as submobjects of VGroup, " + "but the value OpenGLMobject (at index 0 of parameter 0) is of type OpenGLMobject." + ) + + # A VGroup cannot be initialised with an iterable containing a OpenGLMobject in any position + with pytest.raises(TypeError) as init_with_mobs_and_vmobs_iterable: + VGroup(mixed_type_generator(OpenGLVMobject, OpenGLMobject, [3, 5], 7)) + assert str(init_with_mobs_and_vmobs_iterable.value) == ( + "Only values of type OpenGLVMobject can be added as submobjects of VGroup, " + "but the value OpenGLMobject (at index 3 of parameter 0) is of type OpenGLMobject." + ) + + # A VGroup cannot be initialised with an iterable containing non OpenGLVMobject's in any position + with pytest.raises(TypeError) as init_with_float_and_vmobs_iterable: + VGroup(mixed_type_generator(OpenGLVMobject, float, [6, 7], 9)) + assert str(init_with_float_and_vmobs_iterable.value) == ( + "Only values of type OpenGLVMobject can be added as submobjects of VGroup, " + "but the value 0.0 (at index 6 of parameter 0) is of type float." + ) + + # A VGroup cannot be initialised with an iterable containing both OpenGLVMobject's and VMobject's + with pytest.raises(TypeError) as init_with_mobs_and_vmobs_iterable: + VGroup(mixed_type_generator(OpenGLVMobject, VMobject, [3, 5], 7)) + assert str(init_with_mobs_and_vmobs_iterable.value) == ( + "Only values of type OpenGLVMobject can be added as submobjects of VGroup, " + "but the value VMobject (at index 3 of parameter 0) is of type VMobject." + ) def test_vgroup_add(using_opengl_renderer): """Test the VGroup add method.""" obj = VGroup() assert len(obj.submobjects) == 0 + obj.add(OpenGLVMobject()) assert len(obj.submobjects) == 1 - with pytest.raises(TypeError): + + # Can't add non-OpenGLVMobject values to a VMobject. + with pytest.raises(TypeError) as add_int_info: + obj.add(3) + assert str(add_int_info.value) == ( + "Only values of type OpenGLVMobject can be added as submobjects of " + "VGroup, but the value 3 (at index 0 of parameter 0) is of type int." + ) + assert len(obj.submobjects) == 1 + + # Plain OpenGLMobjects can't be added to a OpenGLVMobject if they're not + # OpenGLVMobjects. Suggest adding them into an OpenGLGroup instead. + with pytest.raises(TypeError) as add_mob_info: obj.add(OpenGLMobject()) + assert str(add_mob_info.value) == ( + "Only values of type OpenGLVMobject can be added as submobjects of " + "VGroup, but the value OpenGLMobject (at index 0 of parameter 0) is of type " + "OpenGLMobject. You can try adding this value into a Group instead." + ) assert len(obj.submobjects) == 1 - with pytest.raises(TypeError): - # If only one of the added object is not an instance of OpenGLVMobject, none of them should be added + + with pytest.raises(TypeError) as add_vmob_and_mob_info: + # If only one of the added objects is not an instance of VMobject, none of them should be added obj.add(OpenGLVMobject(), OpenGLMobject()) + assert str(add_vmob_and_mob_info.value) == ( + "Only values of type OpenGLVMobject can be added as submobjects of " + "VGroup, but the value OpenGLMobject (at index 0 of parameter 1) is of type " + "OpenGLMobject. You can try adding this value into a Group instead." + ) assert len(obj.submobjects) == 1 - with pytest.raises(ValueError): - # a OpenGLMobject cannot contain itself + + # A VMobject or VGroup cannot contain itself. + with pytest.raises(ValueError) as add_self_info: obj.add(obj) + assert str(add_self_info.value) == ( + "Cannot add VGroup as a submobject of itself (at index 0)." + ) + assert len(obj.submobjects) == 1 def test_vgroup_add_dunder(using_opengl_renderer): @@ -192,7 +346,7 @@ def test_vgroup_supports_item_assigment(using_opengl_renderer): def test_vgroup_item_assignment_at_correct_position(using_opengl_renderer): - """Test VGroup item-assignment adds to correct position for OpenGLVMObjects""" + """Test VGroup item-assignment adds to correct position for OpenGLVMobjects""" n_items = 10 vgroup = VGroup() for _i in range(n_items): @@ -206,5 +360,9 @@ def test_vgroup_item_assignment_at_correct_position(using_opengl_renderer): def test_vgroup_item_assignment_only_allows_vmobjects(using_opengl_renderer): """Test VGroup item-assignment raises TypeError when invalid type is passed""" vgroup = VGroup(OpenGLVMobject()) - with pytest.raises(TypeError, match="All submobjects must be of type VMobject"): + with pytest.raises(TypeError) as assign_str_info: vgroup[0] = "invalid object" + assert str(assign_str_info.value) == ( + "Only values of type OpenGLVMobject can be added as submobjects of " + "VGroup, but the value invalid object (at index 0) is of type str." + ) diff --git a/tests/opengl/test_sound_opengl.py b/tests/opengl/test_sound_opengl.py index 40ec914de5..cc4ccceaec 100644 --- a/tests/opengl/test_sound_opengl.py +++ b/tests/opengl/test_sound_opengl.py @@ -13,14 +13,12 @@ def test_add_sound(using_opengl_renderer, tmpdir): # create sound file sound_loc = Path(tmpdir, "noise.wav") - f = wave.open(str(sound_loc), "w") - f.setparams((2, 2, 44100, 0, "NONE", "not compressed")) - for _ in range(22050): # half a second of sound - packed_value = struct.pack("h", 14242) - f.writeframes(packed_value) - f.writeframes(packed_value) - - f.close() + with wave.open(str(sound_loc), "w") as f: + f.setparams((2, 2, 44100, 0, "NONE", "not compressed")) + for _ in range(22050): # half a second of sound + packed_value = struct.pack("h", 14242) + f.writeframes(packed_value) + f.writeframes(packed_value) scene = Scene() scene.add_sound(sound_loc) diff --git a/tests/opengl/test_stroke_opengl.py b/tests/opengl/test_stroke_opengl.py index 7a18d5de27..d5eff1ac71 100644 --- a/tests/opengl/test_stroke_opengl.py +++ b/tests/opengl/test_stroke_opengl.py @@ -1,14 +1,12 @@ from __future__ import annotations -from colour import Color - import manim.utils.color as C from manim.mobject.opengl.opengl_vectorized_mobject import OpenGLVMobject def test_stroke_props_in_ctor(using_opengl_renderer): m = OpenGLVMobject(stroke_color=C.ORANGE, stroke_width=10) - assert m.stroke_color == Color(C.ORANGE) + assert m.stroke_color.to_hex() == C.ORANGE.to_hex() assert m.stroke_width == 10 @@ -17,4 +15,4 @@ def test_set_stroke(using_opengl_renderer): m.set_stroke(color=C.ORANGE, width=2, opacity=0.8) assert m.stroke_width == 2 assert m.stroke_opacity == 0.8 - assert m.stroke_color == Color(C.ORANGE) + assert m.stroke_color.to_hex() == C.ORANGE.to_hex() diff --git a/tests/opengl/test_svg_mobject_opengl.py b/tests/opengl/test_svg_mobject_opengl.py index c672055778..c1d11f42e5 100644 --- a/tests/opengl/test_svg_mobject_opengl.py +++ b/tests/opengl/test_svg_mobject_opengl.py @@ -1,7 +1,5 @@ from __future__ import annotations -from colour import Color - from manim import * from tests.helpers.path_utils import get_svg_resource @@ -9,21 +7,21 @@ def test_set_fill_color(using_opengl_renderer): expected_color = "#FF862F" svg = SVGMobject(get_svg_resource("heart.svg"), fill_color=expected_color) - assert svg.fill_color == Color(expected_color) + assert svg.fill_color.to_hex() == expected_color def test_set_stroke_color(using_opengl_renderer): expected_color = "#FFFDDD" svg = SVGMobject(get_svg_resource("heart.svg"), stroke_color=expected_color) - assert svg.stroke_color == Color(expected_color) + assert svg.stroke_color.to_hex() == expected_color def test_set_color_sets_fill_and_stroke(using_opengl_renderer): expected_color = "#EEE777" svg = SVGMobject(get_svg_resource("heart.svg"), color=expected_color) - assert svg.color == Color(expected_color) - assert svg.fill_color == Color(expected_color) - assert svg.stroke_color == Color(expected_color) + assert svg.color.to_hex() == expected_color + assert svg.fill_color.to_hex() == expected_color + assert svg.stroke_color.to_hex() == expected_color def test_set_fill_opacity(using_opengl_renderer): @@ -45,7 +43,7 @@ def test_fill_overrides_color(using_opengl_renderer): color="#123123", fill_color=expected_color, ) - assert svg.fill_color == Color(expected_color) + assert svg.fill_color.to_hex() == expected_color def test_stroke_overrides_color(using_opengl_renderer): @@ -55,4 +53,4 @@ def test_stroke_overrides_color(using_opengl_renderer): color="#334433", stroke_color=expected_color, ) - assert svg.stroke_color == Color(expected_color) + assert svg.stroke_color.to_hex() == expected_color diff --git a/tests/opengl/test_texmobject_opengl.py b/tests/opengl/test_texmobject_opengl.py index 7c2b0c5f2d..e9826f9d8f 100644 --- a/tests/opengl/test_texmobject_opengl.py +++ b/tests/opengl/test_texmobject_opengl.py @@ -4,21 +4,21 @@ import pytest -from manim import MathTex, SingleStringMathTex, Tex, config +from manim import MathTex, SingleStringMathTex, Tex -def test_MathTex(using_opengl_renderer): +def test_MathTex(config, using_opengl_renderer): MathTex("a^2 + b^2 = c^2") - assert Path(config.media_dir, "Tex", "3879f6b03bc495cd.svg").exists() + assert Path(config.media_dir, "Tex", "e4be163a00cf424f.svg").exists() -def test_SingleStringMathTex(using_opengl_renderer): +def test_SingleStringMathTex(config, using_opengl_renderer): SingleStringMathTex("test") - assert Path(config.media_dir, "Tex", "79822967f1fa1935.svg").exists() + assert Path(config.media_dir, "Tex", "8ce17c7f5013209f.svg").exists() @pytest.mark.parametrize( # : PT006 - "text_input,length_sub", + ("text_input", "length_sub"), [("{{ a }} + {{ b }} = {{ c }}", 5), (r"\frac{1}{a+b\sqrt{2}}", 1)], ) def test_double_braces_testing(using_opengl_renderer, text_input, length_sub): @@ -26,9 +26,9 @@ def test_double_braces_testing(using_opengl_renderer, text_input, length_sub): assert len(t1.submobjects) == length_sub -def test_tex(using_opengl_renderer): +def test_tex(config, using_opengl_renderer): Tex("The horse does not eat cucumber salad.") - assert Path(config.media_dir, "Tex", "983949cac5bdd272.svg").exists() + assert Path(config.media_dir, "Tex", "c3945e23e546c95a.svg").exists() def test_tex_whitespace_arg(using_opengl_renderer): @@ -87,7 +87,8 @@ def test_tex_size(using_opengl_renderer): def test_font_size(using_opengl_renderer): """Test that tex_mobject classes return - the correct font_size value after being scaled.""" + the correct font_size value after being scaled. + """ string = MathTex(0).scale(0.3) assert round(string.font_size, 5) == 14.4 diff --git a/tests/opengl/test_text_mobject_opengl.py b/tests/opengl/test_text_mobject_opengl.py index 9fa9415314..db6a6532f4 100644 --- a/tests/opengl/test_text_mobject_opengl.py +++ b/tests/opengl/test_text_mobject_opengl.py @@ -5,7 +5,8 @@ def test_font_size(using_opengl_renderer): """Test that Text and MarkupText return the - correct font_size value after being scaled.""" + correct font_size value after being scaled. + """ text_string = Text("0").scale(0.3) markuptext_string = MarkupText("0").scale(0.3) diff --git a/tests/opengl/test_unit_geometry_opengl.py b/tests/opengl/test_unit_geometry_opengl.py index c92b5978ce..f92bc9ff37 100644 --- a/tests/opengl/test_unit_geometry_opengl.py +++ b/tests/opengl/test_unit_geometry_opengl.py @@ -6,4 +6,6 @@ def test_get_arc_center(using_opengl_renderer): - assert np.all(Sector(arc_center=[1, 2, 0]).get_arc_center() == [1, 2, 0]) + np.testing.assert_array_equal( + Sector(arc_center=[1, 2, 0]).get_arc_center(), [1, 2, 0] + ) diff --git a/tests/test_camera.py b/tests/test_camera.py new file mode 100644 index 0000000000..44c54e7e4f --- /dev/null +++ b/tests/test_camera.py @@ -0,0 +1,11 @@ +from __future__ import annotations + +from manim import MovingCamera, Square + + +def test_movingcamera_auto_zoom(): + camera = MovingCamera() + square = Square() + margin = 0.5 + camera.auto_zoom([square], margin=margin, animate=False) + assert camera.frame.height == square.height + margin diff --git a/tests/test_code_mobject.py b/tests/test_code_mobject.py new file mode 100644 index 0000000000..c7135f8550 --- /dev/null +++ b/tests/test_code_mobject.py @@ -0,0 +1,31 @@ +from manim.mobject.text.code_mobject import Code +from manim.utils.color.core import ManimColor + + +def test_code_initialization_from_string(): + code_string = """from manim import Scene, Square + +class FadeInSquare(Scene): + def construct(self): + s = Square() + self.play(FadeIn(s)) + self.play(s.animate.scale(2)) + self.wait()""" + rendered_code = Code( + code_string=code_string, + language="python", + ) + num_lines = len(code_string.split("\n")) + assert len(rendered_code.code_lines) == num_lines + assert len(rendered_code.line_numbers) == num_lines + + +def test_code_initialization_from_file(): + rendered_code = Code( + code_file="tests/test_code_mobject.py", + language="python", + background="window", + background_config={"fill_color": "#101010"}, + ) + assert len(rendered_code.code_lines) == len(rendered_code.line_numbers) + assert rendered_code.background.fill_color == ManimColor("#101010") diff --git a/tests/test_color.py b/tests/test_color.py deleted file mode 100644 index 1a84052dff..0000000000 --- a/tests/test_color.py +++ /dev/null @@ -1,43 +0,0 @@ -from __future__ import annotations - -import numpy as np - -from manim import BLACK, Mobject, Scene, VMobject - - -def test_import_color(): - import manim.utils.color as C - - C.WHITE - - -def test_background_color(): - S = Scene() - S.camera.background_color = "#ff0000" - S.renderer.update_frame(S) - assert np.all(S.renderer.get_frame()[0, 0] == np.array([255, 0, 0, 255])) - - S.camera.background_color = "#436f80" - S.renderer.update_frame(S) - assert np.all(S.renderer.get_frame()[0, 0] == np.array([67, 111, 128, 255])) - - S.camera.background_color = "#fff" - S.renderer.update_frame(S) - assert np.all(S.renderer.get_frame()[0, 0] == np.array([255, 255, 255, 255])) - - S.camera.background_color = "#bbffbb" - S.camera.background_opacity = 0.5 - S.renderer.update_frame(S) - assert np.all(S.renderer.get_frame()[0, 0] == np.array([93, 127, 93, 127])) - - -def test_set_color(): - m = Mobject() - assert m.color.hex == "#fff" - m.set_color(BLACK) - assert m.color.hex == "#000" - - m = VMobject() - assert m.color.hex == "#fff" - m.set_color(BLACK) - assert m.color.hex == "#000" diff --git a/tests/test_commands.py b/tests/test_commands.py deleted file mode 100644 index ca284aa52a..0000000000 --- a/tests/test_commands.py +++ /dev/null @@ -1,120 +0,0 @@ -from __future__ import annotations - -import sys -from pathlib import Path -from textwrap import dedent - -from click.testing import CliRunner - -from manim import __version__, capture -from manim.__main__ import main - - -def test_manim_version(): - command = [ - sys.executable, - "-m", - "manim", - "--version", - ] - out, err, exit_code = capture(command) - assert exit_code == 0, err - assert __version__ in out - - -def test_manim_cfg_subcommand(): - command = ["cfg"] - runner = CliRunner() - result = runner.invoke(main, command, prog_name="manim") - expected_output = """\ -Usage: manim cfg [OPTIONS] COMMAND [ARGS]... - - Manages Manim configuration files. - -Options: - -h, --help Show this message and exit. - -Commands: - export - show - write - - Made with <3 by Manim Community developers. -""" - assert dedent(expected_output) == result.stdout - - -def test_manim_plugins_subcommand(): - command = ["plugins"] - runner = CliRunner() - result = runner.invoke(main, command, prog_name="manim") - expected_output = """\ -Usage: manim plugins [OPTIONS] - - Manages Manim plugins. - -Options: - -l, --list List available plugins. - -h, --help Show this message and exit. - - Made with <3 by Manim Community developers. -""" - assert dedent(expected_output) == result.output - - -def test_manim_init_subcommand(): - command = ["init"] - runner = CliRunner() - runner.invoke(main, command, prog_name="manim") - - expected_manim_cfg = "" - expected_main_py = "" - - with open( - Path.resolve(Path(__file__).parent.parent / "manim/templates/template.cfg"), - ) as f: - expected_manim_cfg = f.read() - - with open( - Path.resolve(Path(__file__).parent.parent / "manim/templates/Default.mtp"), - ) as f: - expected_main_py = f.read() - - manim_cfg_path = Path("manim.cfg") - manim_cfg_content = "" - main_py_path = Path("main.py") - main_py_content = "" - with open(manim_cfg_path) as f: - manim_cfg_content = f.read() - - with open(main_py_path) as f: - main_py_content = f.read() - - manim_cfg_path.unlink() - main_py_path.unlink() - - assert ( - dedent(expected_manim_cfg + "from manim import *\n" + expected_main_py) - == manim_cfg_content + main_py_content - ) - - -def test_manim_new_command(): - command = ["new"] - runner = CliRunner() - result = runner.invoke(main, command, prog_name="manim") - expected_output = """\ -Usage: manim new [OPTIONS] COMMAND [ARGS]... - - Create a new project or insert a new scene. - -Options: - -h, --help Show this message and exit. - -Commands: - project Creates a new project. - scene Inserts a SCENE to an existing FILE or creates a new FILE. - - Made with <3 by Manim Community developers. -""" - assert dedent(expected_output) == result.output diff --git a/tests/test_config.py b/tests/test_config.py index 9a3c15de03..0703b31bf4 100644 --- a/tests/test_config.py +++ b/tests/test_config.py @@ -1,16 +1,17 @@ from __future__ import annotations -import os import tempfile from pathlib import Path import numpy as np +import pytest -from manim import WHITE, Scene, Square, Tex, Text, config, tempconfig +from manim import WHITE, Scene, Square, Tex, Text, tempconfig +from manim._config.utils import ManimConfig from tests.assert_utils import assert_dir_exists, assert_dir_filled, assert_file_exists -def test_tempconfig(): +def test_tempconfig(config): """Test the tempconfig context manager.""" original = config.copy() @@ -28,11 +29,25 @@ def test_tempconfig(): # check that config is correctly restored for k, v in original.items(): if isinstance(v, np.ndarray): - assert np.allclose(config[k], v) + np.testing.assert_allclose(config[k], v) else: assert config[k] == v +@pytest.mark.parametrize( + ("format", "expected_file_extension"), + [ + ("mp4", ".mp4"), + ("webm", ".webm"), + ("mov", ".mov"), + ("gif", ".mp4"), + ], +) +def test_resolve_file_extensions(config, format, expected_file_extension): + config.format = format + assert config.movie_file_extension == expected_file_extension + + class MyScene(Scene): def construct(self): self.add(Square()) @@ -41,39 +56,51 @@ def construct(self): self.wait(1) -def test_transparent(): +def test_transparent(config): """Test the 'transparent' config option.""" - orig_verbosity = config["verbosity"] - config["verbosity"] = "ERROR" + config.verbosity = "ERROR" + config.dry_run = True - with tempconfig({"dry_run": True}): - scene = MyScene() - scene.render() - frame = scene.renderer.get_frame() - assert np.allclose(frame[0, 0], [0, 0, 0, 255]) + scene = MyScene() + scene.render() + frame = scene.renderer.get_frame() + np.testing.assert_allclose(frame[0, 0], [0, 0, 0, 255]) + + config.transparent = True - with tempconfig({"transparent": True, "dry_run": True}): - scene = MyScene() - scene.render() - frame = scene.renderer.get_frame() - assert np.allclose(frame[0, 0], [0, 0, 0, 0]) + scene = MyScene() + scene.render() + frame = scene.renderer.get_frame() + np.testing.assert_allclose(frame[0, 0], [0, 0, 0, 0]) - config["verbosity"] = orig_verbosity +def test_transparent_by_background_opacity(config, dry_run): + config.background_opacity = 0.5 + assert config.transparent is True -def test_background_color(): + scene = MyScene() + scene.render() + frame = scene.renderer.get_frame() + np.testing.assert_allclose(frame[0, 0], [0, 0, 0, 127]) + assert config.movie_file_extension == ".mov" + assert config.transparent is True + + +def test_background_color(config): """Test the 'background_color' config option.""" - with tempconfig({"background_color": WHITE, "verbosity": "ERROR", "dry_run": True}): - scene = MyScene() - scene.render() - frame = scene.renderer.get_frame() - assert np.allclose(frame[0, 0], [255, 255, 255, 255]) + config.background_color = WHITE + config.verbosity = "ERROR" + config.dry_run = True + scene = MyScene() + scene.render() + frame = scene.renderer.get_frame() + np.testing.assert_allclose(frame[0, 0], [255, 255, 255, 255]) -def test_digest_file(tmp_path): + +def test_digest_file(tmp_path, config): """Test that a config file can be digested programmatically.""" - with tempconfig({}): - tmp_cfg = tempfile.NamedTemporaryFile("w", dir=tmp_path, delete=False) + with tempfile.NamedTemporaryFile("w", dir=tmp_path, delete=False) as tmp_cfg: tmp_cfg.write( """ [CLI] @@ -83,64 +110,52 @@ def test_digest_file(tmp_path): frame_height = 10 """, ) - tmp_cfg.close() - config.digest_file(tmp_cfg.name) - - assert config.get_dir("media_dir") == Path("this_is_my_favorite_path") - assert config.get_dir("video_dir") == Path("this_is_my_favorite_path/videos") - assert config.get_dir("sections_dir", scene_name="test") == Path( - "this_is_my_favorite_path/test/prepare_for_unforeseen_consequences" - ) - - -def test_custom_dirs(tmp_path): - with tempconfig( - { - "media_dir": tmp_path, - "save_sections": True, - "frame_rate": 15, - "pixel_height": 854, - "pixel_width": 480, - "save_sections": True, - "sections_dir": "{media_dir}/test_sections", - "video_dir": "{media_dir}/test_video", - "partial_movie_dir": "{media_dir}/test_partial_movie_dir", - "images_dir": "{media_dir}/test_images", - "text_dir": "{media_dir}/test_text", - "tex_dir": "{media_dir}/test_tex", - } - ): - scene = MyScene() - scene.render() - - assert_dir_filled(os.path.join(tmp_path, "test_sections")) - assert_file_exists(os.path.join(tmp_path, "test_sections", "MyScene.json")) - - assert_dir_filled(os.path.join(tmp_path, "test_video")) - assert_file_exists(os.path.join(tmp_path, "test_video", "MyScene.mp4")) - - assert_dir_filled(os.path.join(tmp_path, "test_partial_movie_dir")) - assert_file_exists( - os.path.join( - tmp_path, "test_partial_movie_dir", "partial_movie_file_list.txt" - ) - ) - - # TODO: another example with image output would be nice - assert_dir_exists(os.path.join(tmp_path, "test_images")) - - assert_dir_filled(os.path.join(tmp_path, "test_text")) - assert_dir_filled(os.path.join(tmp_path, "test_tex")) - # TODO: testing the log dir would be nice but it doesn't get generated for some reason and test crashes when setting "log_to_file" to True - - -def test_frame_size(tmp_path): - """Test that the frame size can be set via config file.""" - assert np.allclose(config.aspect_ratio, config.pixel_width / config.pixel_height) - assert np.allclose(config.frame_height, 8.0) - - with tempconfig({}): - tmp_cfg = tempfile.NamedTemporaryFile("w", dir=tmp_path, delete=False) + config.digest_file(tmp_cfg.name) + + assert config.get_dir("media_dir") == Path("this_is_my_favorite_path") + assert config.get_dir("video_dir") == Path("this_is_my_favorite_path/videos") + assert config.get_dir("sections_dir", scene_name="test") == Path( + "this_is_my_favorite_path/test/prepare_for_unforeseen_consequences" + ) + + +def test_custom_dirs(tmp_path, config): + config.media_dir = tmp_path + config.save_sections = True + config.log_to_file = True + config.frame_rate = 15 + config.pixel_height = 854 + config.pixel_width = 480 + config.sections_dir = "{media_dir}/test_sections" + config.video_dir = "{media_dir}/test_video" + config.partial_movie_dir = "{media_dir}/test_partial_movie_dir" + config.images_dir = "{media_dir}/test_images" + config.text_dir = "{media_dir}/test_text" + config.tex_dir = "{media_dir}/test_tex" + config.log_dir = "{media_dir}/test_log" + + scene = MyScene() + scene.render() + tmp_path = Path(tmp_path) + assert_dir_filled(tmp_path / "test_sections") + assert_file_exists(tmp_path / "test_sections/MyScene.json") + + assert_dir_filled(tmp_path / "test_video") + assert_file_exists(tmp_path / "test_video/MyScene.mp4") + + assert_dir_filled(tmp_path / "test_partial_movie_dir") + assert_file_exists(tmp_path / "test_partial_movie_dir/partial_movie_file_list.txt") + + # TODO: another example with image output would be nice + assert_dir_exists(tmp_path / "test_images") + + assert_dir_filled(tmp_path / "test_text") + assert_dir_filled(tmp_path / "test_tex") + assert_dir_filled(tmp_path / "test_log") + + +def test_pixel_dimensions(tmp_path, config): + with tempfile.NamedTemporaryFile("w", dir=tmp_path, delete=False) as tmp_cfg: tmp_cfg.write( """ [CLI] @@ -148,17 +163,23 @@ def test_frame_size(tmp_path): pixel_width = 10 """, ) - tmp_cfg.close() - config.digest_file(tmp_cfg.name) + config.digest_file(tmp_cfg.name) + + # aspect ratio is set using pixel measurements + np.testing.assert_allclose(config.aspect_ratio, 1.0) + # if not specified in the cfg file, frame_width is set using the aspect ratio + np.testing.assert_allclose(config.frame_height, 8.0) + np.testing.assert_allclose(config.frame_width, 8.0) + - # aspect ratio is set using pixel measurements - assert np.allclose(config.aspect_ratio, 1.0) - # if not specified in the cfg file, frame_width is set using the aspect ratio - assert np.allclose(config.frame_height, 8.0) - assert np.allclose(config.frame_width, 8.0) +def test_frame_size(tmp_path, config): + """Test that the frame size can be set via config file.""" + np.testing.assert_allclose( + config.aspect_ratio, config.pixel_width / config.pixel_height + ) + np.testing.assert_allclose(config.frame_height, 8.0) - with tempconfig({}): - tmp_cfg = tempfile.NamedTemporaryFile("w", dir=tmp_path, delete=False) + with tempfile.NamedTemporaryFile("w", dir=tmp_path, delete=False) as tmp_cfg: tmp_cfg.write( """ [CLI] @@ -168,16 +189,15 @@ def test_frame_size(tmp_path): frame_width = 10 """, ) - tmp_cfg.close() - config.digest_file(tmp_cfg.name) + config.digest_file(tmp_cfg.name) - assert np.allclose(config.aspect_ratio, 1.0) - # if both are specified in the cfg file, the aspect ratio is ignored - assert np.allclose(config.frame_height, 10.0) - assert np.allclose(config.frame_width, 10.0) + np.testing.assert_allclose(config.aspect_ratio, 1.0) + # if both are specified in the cfg file, the aspect ratio is ignored + np.testing.assert_allclose(config.frame_height, 10.0) + np.testing.assert_allclose(config.frame_width, 10.0) -def test_temporary_dry_run(): +def test_temporary_dry_run(config): """Test that tempconfig correctly restores after setting dry_run.""" assert config["write_to_movie"] assert not config["save_last_frame"] @@ -190,21 +210,58 @@ def test_temporary_dry_run(): assert not config["save_last_frame"] -def test_dry_run_with_png_format(): +def test_dry_run_with_png_format(config, dry_run): """Test that there are no exceptions when running a png without output""" - with tempconfig( - {"dry_run": True, "write_to_movie": False, "disable_caching": True} - ): - assert config["dry_run"] is True - scene = MyScene() - scene.render() + config.write_to_movie = False + config.disable_caching = True + assert config.dry_run is True + scene = MyScene() + scene.render() -def test_dry_run_with_png_format_skipped_animations(): +def test_dry_run_with_png_format_skipped_animations(config, dry_run): """Test that there are no exceptions when running a png without output and skipped animations""" - with tempconfig( - {"dry_run": True, "write_to_movie": False, "disable_caching": True} - ): - assert config["dry_run"] is True - scene = MyScene(skip_animations=True) - scene.render() + config.write_to_movie = False + config.disable_caching = True + assert config["dry_run"] is True + scene = MyScene(skip_animations=True) + scene.render() + + +def test_tex_template_file(tmp_path): + """Test that a custom tex template file can be set from a config file.""" + tex_file = Path(tmp_path / "my_template.tex") + tex_file.write_text("Hello World!") + with tempfile.NamedTemporaryFile("w", dir=tmp_path, delete=False) as tmp_cfg: + tmp_cfg.write( + f""" + [CLI] + tex_template_file = {tex_file} + """, + ) + + custom_config = ManimConfig().digest_file(tmp_cfg.name) + + assert Path(custom_config.tex_template_file) == tex_file + assert custom_config.tex_template.body == "Hello World!" + + +def test_from_to_animations_only_first_animation(config): + config: ManimConfig + config.from_animation_number = 0 + config.upto_animation_number = 0 + + class SceneWithTwoAnimations(Scene): + def construct(self): + self.after_first_animation = False + s = Square() + self.add(s) + self.play(s.animate.scale(2)) + self.renderer.update_skipping_status() + self.after_first_animation = True + self.play(s.animate.scale(2)) + + scene = SceneWithTwoAnimations() + scene.render() + + assert scene.after_first_animation is False diff --git a/tests/test_file_ops.py b/tests/test_file_ops.py deleted file mode 100644 index 30c0f00f95..0000000000 --- a/tests/test_file_ops.py +++ /dev/null @@ -1,32 +0,0 @@ -from __future__ import annotations - -import os - -from manim import * - -from .assert_utils import assert_dir_exists, assert_file_not_exists -from .utils.video_tester import * - - -def test_guarantee_existence(tmp_path): - test_dir = os.path.join(tmp_path, "test") - guarantee_existence(test_dir) - # test if file dir got created - assert_dir_exists(test_dir) - with open(os.path.join(test_dir, "test.txt"), "x") as f: - pass - # test if file didn't get deleted - guarantee_existence(test_dir) - - -def test_guarantee_empty_existence(tmp_path): - test_dir = os.path.join(tmp_path, "test") - os.mkdir(test_dir) - with open(os.path.join(test_dir, "test.txt"), "x"): - pass - - guarantee_empty_existence(test_dir) - # test if dir got created - assert_dir_exists(test_dir) - # test if dir got cleaned - assert_file_not_exists(os.path.join(test_dir, "test.txt")) diff --git a/tests/test_graph.py b/tests/test_graph.py deleted file mode 100644 index 91b291b016..0000000000 --- a/tests/test_graph.py +++ /dev/null @@ -1,100 +0,0 @@ -from __future__ import annotations - -from manim import Graph, Scene, Text, tempconfig - - -def test_graph_creation(): - vertices = [1, 2, 3, 4] - edges = [(1, 2), (2, 3), (3, 4), (4, 1)] - layout = {1: [0, 0, 0], 2: [1, 1, 0], 3: [1, -1, 0], 4: [-1, 0, 0]} - G_manual = Graph(vertices=vertices, edges=edges, layout=layout) - assert str(G_manual) == "Graph on 4 vertices and 4 edges" - G_spring = Graph(vertices=vertices, edges=edges) - assert str(G_spring) == "Graph on 4 vertices and 4 edges" - - -def test_graph_add_vertices(): - G = Graph([1, 2, 3], [(1, 2), (2, 3)]) - G.add_vertices(4) - assert str(G) == "Graph on 4 vertices and 2 edges" - G.add_vertices(5, labels={5: Text("5")}) - assert str(G) == "Graph on 5 vertices and 2 edges" - assert 5 in G._labels - assert 5 in G._vertex_config - G.add_vertices(6, 7, 8) - assert len(G.vertices) == 8 - assert len(G._graph.nodes()) == 8 - - -def test_graph_remove_vertices(): - G = Graph([1, 2, 3, 4, 5], [(1, 2), (2, 3), (3, 4), (4, 5)]) - removed_mobjects = G.remove_vertices(3) - assert len(removed_mobjects) == 3 - assert str(G) == "Graph on 4 vertices and 2 edges" - assert list(G.vertices.keys()) == [1, 2, 4, 5] - assert list(G.edges.keys()) == [(1, 2), (4, 5)] - removed_mobjects = G.remove_vertices(4, 5) - assert len(removed_mobjects) == 3 - assert str(G) == "Graph on 2 vertices and 1 edges" - assert list(G.vertices.keys()) == [1, 2] - assert list(G.edges.keys()) == [(1, 2)] - - -def test_graph_add_edges(): - G = Graph([1, 2, 3, 4, 5], [(1, 2), (2, 3)]) - added_mobjects = G.add_edges((1, 3)) - assert str(added_mobjects.submobjects) == "[Line]" - assert str(G) == "Graph on 5 vertices and 3 edges" - assert set(G.vertices.keys()) == {1, 2, 3, 4, 5} - assert set(G.edges.keys()) == {(1, 2), (2, 3), (1, 3)} - - added_mobjects = G.add_edges((1, 42)) - assert str(added_mobjects.submobjects) == "[Dot, Line]" - assert str(G) == "Graph on 6 vertices and 4 edges" - assert set(G.vertices.keys()) == {1, 2, 3, 4, 5, 42} - assert set(G.edges.keys()) == {(1, 2), (2, 3), (1, 3), (1, 42)} - - added_mobjects = G.add_edges((4, 5), (5, 6), (6, 7)) - assert len(added_mobjects) == 5 - assert str(G) == "Graph on 8 vertices and 7 edges" - assert set(G.vertices.keys()) == {1, 2, 3, 4, 5, 42, 6, 7} - assert set(G._graph.nodes()) == set(G.vertices.keys()) - assert set(G.edges.keys()) == { - (1, 2), - (2, 3), - (1, 3), - (1, 42), - (4, 5), - (5, 6), - (6, 7), - } - assert set(G._graph.edges()) == set(G.edges.keys()) - - -def test_graph_remove_edges(): - G = Graph([1, 2, 3, 4, 5], [(1, 2), (2, 3), (3, 4), (4, 5), (1, 5)]) - removed_mobjects = G.remove_edges((1, 2)) - assert str(removed_mobjects.submobjects) == "[Line]" - assert str(G) == "Graph on 5 vertices and 4 edges" - assert set(G.edges.keys()) == {(2, 3), (3, 4), (4, 5), (1, 5)} - assert set(G._graph.edges()) == set(G.edges.keys()) - - removed_mobjects = G.remove_edges((2, 3), (3, 4), (4, 5), (5, 1)) - assert len(removed_mobjects) == 4 - assert str(G) == "Graph on 5 vertices and 0 edges" - assert set(G._graph.edges()) == set() - assert set(G.edges.keys()) == set() - - -def test_custom_animation_mobject_list(): - G = Graph([1, 2, 3], [(1, 2), (2, 3)]) - scene = Scene() - scene.add(G) - assert scene.mobjects == [G] - with tempconfig({"dry_run": True, "quality": "low_quality"}): - scene.play(G.animate.add_vertices(4)) - assert str(G) == "Graph on 4 vertices and 2 edges" - assert scene.mobjects == [G] - scene.play(G.animate.remove_vertices(2)) - assert str(G) == "Graph on 3 vertices and 0 edges" - assert scene.mobjects == [G] diff --git a/tests/test_graphical_units/conftest.py b/tests/test_graphical_units/conftest.py index 01bec579d8..3314541023 100644 --- a/tests/test_graphical_units/conftest.py +++ b/tests/test_graphical_units/conftest.py @@ -6,3 +6,8 @@ @pytest.fixture def show_diff(request): return request.config.getoption("show_diff") + + +@pytest.fixture(params=[True, False]) +def use_vectorized(request): + return request.param diff --git a/tests/test_graphical_units/control_data/boolean_ops/difference.npz b/tests/test_graphical_units/control_data/boolean_ops/difference.npz index 982144359e..0c38fce97b 100644 Binary files a/tests/test_graphical_units/control_data/boolean_ops/difference.npz and b/tests/test_graphical_units/control_data/boolean_ops/difference.npz differ diff --git a/tests/test_graphical_units/control_data/boolean_ops/exclusion.npz b/tests/test_graphical_units/control_data/boolean_ops/exclusion.npz index e5639abd2f..24ee6585a5 100644 Binary files a/tests/test_graphical_units/control_data/boolean_ops/exclusion.npz and b/tests/test_graphical_units/control_data/boolean_ops/exclusion.npz differ diff --git a/tests/test_graphical_units/control_data/boolean_ops/intersection.npz b/tests/test_graphical_units/control_data/boolean_ops/intersection.npz index cbce553eba..49090f29be 100644 Binary files a/tests/test_graphical_units/control_data/boolean_ops/intersection.npz and b/tests/test_graphical_units/control_data/boolean_ops/intersection.npz differ diff --git a/tests/test_graphical_units/control_data/boolean_ops/intersection_3_mobjects.npz b/tests/test_graphical_units/control_data/boolean_ops/intersection_3_mobjects.npz index 61a46e7c29..0ff330d33b 100644 Binary files a/tests/test_graphical_units/control_data/boolean_ops/intersection_3_mobjects.npz and b/tests/test_graphical_units/control_data/boolean_ops/intersection_3_mobjects.npz differ diff --git a/tests/test_graphical_units/control_data/boolean_ops/union.npz b/tests/test_graphical_units/control_data/boolean_ops/union.npz index 89679e6604..cfd0f00762 100644 Binary files a/tests/test_graphical_units/control_data/boolean_ops/union.npz and b/tests/test_graphical_units/control_data/boolean_ops/union.npz differ diff --git a/tests/test_graphical_units/control_data/brace/arcBrace.npz b/tests/test_graphical_units/control_data/brace/arcBrace.npz index 8fd91fd1bc..2415ee678c 100644 Binary files a/tests/test_graphical_units/control_data/brace/arcBrace.npz and b/tests/test_graphical_units/control_data/brace/arcBrace.npz differ diff --git a/tests/test_graphical_units/control_data/brace/braceTip.npz b/tests/test_graphical_units/control_data/brace/braceTip.npz index d9018a2e03..6299177442 100644 Binary files a/tests/test_graphical_units/control_data/brace/braceTip.npz and b/tests/test_graphical_units/control_data/brace/braceTip.npz differ diff --git a/tests/test_graphical_units/control_data/brace/brace_sharpness.npz b/tests/test_graphical_units/control_data/brace/brace_sharpness.npz index 59231e0ddd..fc12471b78 100644 Binary files a/tests/test_graphical_units/control_data/brace/brace_sharpness.npz and b/tests/test_graphical_units/control_data/brace/brace_sharpness.npz differ diff --git a/tests/test_graphical_units/control_data/composition/animationgroup_is_passing_remover_to_animations.npz b/tests/test_graphical_units/control_data/composition/animationgroup_is_passing_remover_to_animations.npz index f98436b2cc..204e542a8d 100644 Binary files a/tests/test_graphical_units/control_data/composition/animationgroup_is_passing_remover_to_animations.npz and b/tests/test_graphical_units/control_data/composition/animationgroup_is_passing_remover_to_animations.npz differ diff --git a/tests/test_graphical_units/control_data/composition/animationgroup_is_passing_remover_to_nested_animationgroups.npz b/tests/test_graphical_units/control_data/composition/animationgroup_is_passing_remover_to_nested_animationgroups.npz index f98436b2cc..204e542a8d 100644 Binary files a/tests/test_graphical_units/control_data/composition/animationgroup_is_passing_remover_to_nested_animationgroups.npz and b/tests/test_graphical_units/control_data/composition/animationgroup_is_passing_remover_to_nested_animationgroups.npz differ diff --git a/tests/test_graphical_units/control_data/coordinate_system/gradient_line_graph_x_axis.npz b/tests/test_graphical_units/control_data/coordinate_system/gradient_line_graph_x_axis.npz new file mode 100644 index 0000000000..6efda8b2e0 Binary files /dev/null and b/tests/test_graphical_units/control_data/coordinate_system/gradient_line_graph_x_axis.npz differ diff --git a/tests/test_graphical_units/control_data/coordinate_system/gradient_line_graph_y_axis.npz b/tests/test_graphical_units/control_data/coordinate_system/gradient_line_graph_y_axis.npz new file mode 100644 index 0000000000..3c7afcda7d Binary files /dev/null and b/tests/test_graphical_units/control_data/coordinate_system/gradient_line_graph_y_axis.npz differ diff --git a/tests/test_graphical_units/control_data/coordinate_system/implicit_graph.npz b/tests/test_graphical_units/control_data/coordinate_system/implicit_graph.npz index ae64c0d05d..838080847c 100644 Binary files a/tests/test_graphical_units/control_data/coordinate_system/implicit_graph.npz and b/tests/test_graphical_units/control_data/coordinate_system/implicit_graph.npz differ diff --git a/tests/test_graphical_units/control_data/coordinate_system/line_graph.npz b/tests/test_graphical_units/control_data/coordinate_system/line_graph.npz index ad2a00d360..394ae680cd 100644 Binary files a/tests/test_graphical_units/control_data/coordinate_system/line_graph.npz and b/tests/test_graphical_units/control_data/coordinate_system/line_graph.npz differ diff --git a/tests/test_graphical_units/control_data/coordinate_system/number_plane.npz b/tests/test_graphical_units/control_data/coordinate_system/number_plane.npz index 3ca51a4adf..e327fa76bf 100644 Binary files a/tests/test_graphical_units/control_data/coordinate_system/number_plane.npz and b/tests/test_graphical_units/control_data/coordinate_system/number_plane.npz differ diff --git a/tests/test_graphical_units/control_data/coordinate_system/number_plane_log.npz b/tests/test_graphical_units/control_data/coordinate_system/number_plane_log.npz index dc9c4f0a68..facc868282 100644 Binary files a/tests/test_graphical_units/control_data/coordinate_system/number_plane_log.npz and b/tests/test_graphical_units/control_data/coordinate_system/number_plane_log.npz differ diff --git a/tests/test_graphical_units/control_data/coordinate_system/plot_log_x_axis.npz b/tests/test_graphical_units/control_data/coordinate_system/plot_log_x_axis.npz index f215752d0d..a89bf90953 100644 Binary files a/tests/test_graphical_units/control_data/coordinate_system/plot_log_x_axis.npz and b/tests/test_graphical_units/control_data/coordinate_system/plot_log_x_axis.npz differ diff --git a/tests/test_graphical_units/control_data/coordinate_system/plot_log_x_axis_vectorized.npz b/tests/test_graphical_units/control_data/coordinate_system/plot_log_x_axis_vectorized.npz new file mode 100644 index 0000000000..a89bf90953 Binary files /dev/null and b/tests/test_graphical_units/control_data/coordinate_system/plot_log_x_axis_vectorized.npz differ diff --git a/tests/test_graphical_units/control_data/coordinate_system/plot_surface.npz b/tests/test_graphical_units/control_data/coordinate_system/plot_surface.npz new file mode 100644 index 0000000000..83697c1d58 Binary files /dev/null and b/tests/test_graphical_units/control_data/coordinate_system/plot_surface.npz differ diff --git a/tests/test_graphical_units/control_data/coordinate_system/plot_surface_colorscale.npz b/tests/test_graphical_units/control_data/coordinate_system/plot_surface_colorscale.npz new file mode 100644 index 0000000000..b26931bcc2 Binary files /dev/null and b/tests/test_graphical_units/control_data/coordinate_system/plot_surface_colorscale.npz differ diff --git a/tests/test_graphical_units/control_data/creation/DrawBorderThenFill.npz b/tests/test_graphical_units/control_data/creation/DrawBorderThenFill.npz index 3d74bcadf9..0450f67928 100644 Binary files a/tests/test_graphical_units/control_data/creation/DrawBorderThenFill.npz and b/tests/test_graphical_units/control_data/creation/DrawBorderThenFill.npz differ diff --git a/tests/test_graphical_units/control_data/creation/FadeIn.npz b/tests/test_graphical_units/control_data/creation/FadeIn.npz index fb6bf6a2b9..987eb319c5 100644 Binary files a/tests/test_graphical_units/control_data/creation/FadeIn.npz and b/tests/test_graphical_units/control_data/creation/FadeIn.npz differ diff --git a/tests/test_graphical_units/control_data/creation/FadeOut.npz b/tests/test_graphical_units/control_data/creation/FadeOut.npz index 299e80d1b0..8a8fae9c19 100644 Binary files a/tests/test_graphical_units/control_data/creation/FadeOut.npz and b/tests/test_graphical_units/control_data/creation/FadeOut.npz differ diff --git a/tests/test_graphical_units/control_data/creation/GrowFromCenter.npz b/tests/test_graphical_units/control_data/creation/GrowFromCenter.npz index b6fc1bbc44..59801cff84 100644 Binary files a/tests/test_graphical_units/control_data/creation/GrowFromCenter.npz and b/tests/test_graphical_units/control_data/creation/GrowFromCenter.npz differ diff --git a/tests/test_graphical_units/control_data/creation/GrowFromEdge.npz b/tests/test_graphical_units/control_data/creation/GrowFromEdge.npz index 601dd9cc44..a7bb050022 100644 Binary files a/tests/test_graphical_units/control_data/creation/GrowFromEdge.npz and b/tests/test_graphical_units/control_data/creation/GrowFromEdge.npz differ diff --git a/tests/test_graphical_units/control_data/creation/GrowFromPoint.npz b/tests/test_graphical_units/control_data/creation/GrowFromPoint.npz index 5e8f653e6e..d6085b4e99 100644 Binary files a/tests/test_graphical_units/control_data/creation/GrowFromPoint.npz and b/tests/test_graphical_units/control_data/creation/GrowFromPoint.npz differ diff --git a/tests/test_graphical_units/control_data/creation/ShrinkToCenter.npz b/tests/test_graphical_units/control_data/creation/ShrinkToCenter.npz index 1deac9bfaa..5bfc39f558 100644 Binary files a/tests/test_graphical_units/control_data/creation/ShrinkToCenter.npz and b/tests/test_graphical_units/control_data/creation/ShrinkToCenter.npz differ diff --git a/tests/test_graphical_units/control_data/creation/SpinInFromNothing.npz b/tests/test_graphical_units/control_data/creation/SpinInFromNothing.npz index 1c051cf522..0c1481dc9a 100644 Binary files a/tests/test_graphical_units/control_data/creation/SpinInFromNothing.npz and b/tests/test_graphical_units/control_data/creation/SpinInFromNothing.npz differ diff --git a/tests/test_graphical_units/control_data/creation/SpiralIn.npz b/tests/test_graphical_units/control_data/creation/SpiralIn.npz new file mode 100644 index 0000000000..6f531d7e32 Binary files /dev/null and b/tests/test_graphical_units/control_data/creation/SpiralIn.npz differ diff --git a/tests/test_graphical_units/control_data/creation/bring_to_back_introducer.npz b/tests/test_graphical_units/control_data/creation/bring_to_back_introducer.npz index 989a820e49..8b74ae1ee4 100644 Binary files a/tests/test_graphical_units/control_data/creation/bring_to_back_introducer.npz and b/tests/test_graphical_units/control_data/creation/bring_to_back_introducer.npz differ diff --git a/tests/test_graphical_units/control_data/creation/create.npz b/tests/test_graphical_units/control_data/creation/create.npz index 39e988076a..08de908122 100644 Binary files a/tests/test_graphical_units/control_data/creation/create.npz and b/tests/test_graphical_units/control_data/creation/create.npz differ diff --git a/tests/test_graphical_units/control_data/creation/uncreate.npz b/tests/test_graphical_units/control_data/creation/uncreate.npz index 2b21131183..edc2453670 100644 Binary files a/tests/test_graphical_units/control_data/creation/uncreate.npz and b/tests/test_graphical_units/control_data/creation/uncreate.npz differ diff --git a/tests/test_graphical_units/control_data/creation/uncreate_rate_func.npz b/tests/test_graphical_units/control_data/creation/uncreate_rate_func.npz new file mode 100644 index 0000000000..313705322d Binary files /dev/null and b/tests/test_graphical_units/control_data/creation/uncreate_rate_func.npz differ diff --git a/tests/test_graphical_units/control_data/creation/z_index_introducer.npz b/tests/test_graphical_units/control_data/creation/z_index_introducer.npz index cc87472d4b..54b5a1129b 100644 Binary files a/tests/test_graphical_units/control_data/creation/z_index_introducer.npz and b/tests/test_graphical_units/control_data/creation/z_index_introducer.npz differ diff --git a/tests/test_graphical_units/control_data/functions/FunctionGraph.npz b/tests/test_graphical_units/control_data/functions/FunctionGraph.npz index d33b2a3cef..84310cedb8 100644 Binary files a/tests/test_graphical_units/control_data/functions/FunctionGraph.npz and b/tests/test_graphical_units/control_data/functions/FunctionGraph.npz differ diff --git a/tests/test_graphical_units/control_data/functions/ImplicitFunction.npz b/tests/test_graphical_units/control_data/functions/ImplicitFunction.npz index b9dbe9ec96..3089087b5e 100644 Binary files a/tests/test_graphical_units/control_data/functions/ImplicitFunction.npz and b/tests/test_graphical_units/control_data/functions/ImplicitFunction.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/Angle.npz b/tests/test_graphical_units/control_data/geometry/Angle.npz index 96cab22432..8eade463df 100644 Binary files a/tests/test_graphical_units/control_data/geometry/Angle.npz and b/tests/test_graphical_units/control_data/geometry/Angle.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/AngledArrowTip.npz b/tests/test_graphical_units/control_data/geometry/AngledArrowTip.npz index 77a28aa9d0..72df53ea67 100644 Binary files a/tests/test_graphical_units/control_data/geometry/AngledArrowTip.npz and b/tests/test_graphical_units/control_data/geometry/AngledArrowTip.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/AnnotationDot.npz b/tests/test_graphical_units/control_data/geometry/AnnotationDot.npz index c73dd16948..7fa08f88e2 100644 Binary files a/tests/test_graphical_units/control_data/geometry/AnnotationDot.npz and b/tests/test_graphical_units/control_data/geometry/AnnotationDot.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/AnnularSector.npz b/tests/test_graphical_units/control_data/geometry/AnnularSector.npz index f229cc8528..05a57d810f 100644 Binary files a/tests/test_graphical_units/control_data/geometry/AnnularSector.npz and b/tests/test_graphical_units/control_data/geometry/AnnularSector.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/Annulus.npz b/tests/test_graphical_units/control_data/geometry/Annulus.npz index f7029ef064..2f0712c11e 100644 Binary files a/tests/test_graphical_units/control_data/geometry/Annulus.npz and b/tests/test_graphical_units/control_data/geometry/Annulus.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/Arc.npz b/tests/test_graphical_units/control_data/geometry/Arc.npz index 5bb130ad2f..a6521fb7d0 100644 Binary files a/tests/test_graphical_units/control_data/geometry/Arc.npz and b/tests/test_graphical_units/control_data/geometry/Arc.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/ArcBetweenPoints.npz b/tests/test_graphical_units/control_data/geometry/ArcBetweenPoints.npz index 0257f6bb93..31ab894f13 100644 Binary files a/tests/test_graphical_units/control_data/geometry/ArcBetweenPoints.npz and b/tests/test_graphical_units/control_data/geometry/ArcBetweenPoints.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/Arrange.npz b/tests/test_graphical_units/control_data/geometry/Arrange.npz index 2375320bb2..77867a91a6 100644 Binary files a/tests/test_graphical_units/control_data/geometry/Arrange.npz and b/tests/test_graphical_units/control_data/geometry/Arrange.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/Circle.npz b/tests/test_graphical_units/control_data/geometry/Circle.npz index 63b2b2f677..d942046171 100644 Binary files a/tests/test_graphical_units/control_data/geometry/Circle.npz and b/tests/test_graphical_units/control_data/geometry/Circle.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/CirclePoints.npz b/tests/test_graphical_units/control_data/geometry/CirclePoints.npz index 1ec3ceebb6..17cb51cb1b 100644 Binary files a/tests/test_graphical_units/control_data/geometry/CirclePoints.npz and b/tests/test_graphical_units/control_data/geometry/CirclePoints.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/ConvexHull.npz b/tests/test_graphical_units/control_data/geometry/ConvexHull.npz new file mode 100644 index 0000000000..6ccb415ee0 Binary files /dev/null and b/tests/test_graphical_units/control_data/geometry/ConvexHull.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/Coordinates.npz b/tests/test_graphical_units/control_data/geometry/Coordinates.npz index 3f0e04bee7..f21e1d5662 100644 Binary files a/tests/test_graphical_units/control_data/geometry/Coordinates.npz and b/tests/test_graphical_units/control_data/geometry/Coordinates.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/CurvedArrow.npz b/tests/test_graphical_units/control_data/geometry/CurvedArrow.npz index 8c86f738ce..6586c23adf 100644 Binary files a/tests/test_graphical_units/control_data/geometry/CurvedArrow.npz and b/tests/test_graphical_units/control_data/geometry/CurvedArrow.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/CurvedArrowCustomTip.npz b/tests/test_graphical_units/control_data/geometry/CurvedArrowCustomTip.npz index b6ca4008cd..ad9e2628d5 100644 Binary files a/tests/test_graphical_units/control_data/geometry/CurvedArrowCustomTip.npz and b/tests/test_graphical_units/control_data/geometry/CurvedArrowCustomTip.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/CustomDoubleArrow.npz b/tests/test_graphical_units/control_data/geometry/CustomDoubleArrow.npz index 720f5fd505..d93eafa8f4 100644 Binary files a/tests/test_graphical_units/control_data/geometry/CustomDoubleArrow.npz and b/tests/test_graphical_units/control_data/geometry/CustomDoubleArrow.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/DashedVMobject.npz b/tests/test_graphical_units/control_data/geometry/DashedVMobject.npz index ba4126c495..629f60e6be 100644 Binary files a/tests/test_graphical_units/control_data/geometry/DashedVMobject.npz and b/tests/test_graphical_units/control_data/geometry/DashedVMobject.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/Dot.npz b/tests/test_graphical_units/control_data/geometry/Dot.npz index 2adb2ccc4a..3746e3a492 100644 Binary files a/tests/test_graphical_units/control_data/geometry/Dot.npz and b/tests/test_graphical_units/control_data/geometry/Dot.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/DoubleArrow.npz b/tests/test_graphical_units/control_data/geometry/DoubleArrow.npz index 01739318a1..2b89ee9ffa 100644 Binary files a/tests/test_graphical_units/control_data/geometry/DoubleArrow.npz and b/tests/test_graphical_units/control_data/geometry/DoubleArrow.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/Elbow.npz b/tests/test_graphical_units/control_data/geometry/Elbow.npz index 7068f03a4a..68227a453c 100644 Binary files a/tests/test_graphical_units/control_data/geometry/Elbow.npz and b/tests/test_graphical_units/control_data/geometry/Elbow.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/Ellipse.npz b/tests/test_graphical_units/control_data/geometry/Ellipse.npz index f6a1ef43aa..74db91d67e 100644 Binary files a/tests/test_graphical_units/control_data/geometry/Ellipse.npz and b/tests/test_graphical_units/control_data/geometry/Ellipse.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/LabeledArrow.npz b/tests/test_graphical_units/control_data/geometry/LabeledArrow.npz new file mode 100644 index 0000000000..0c926cf299 Binary files /dev/null and b/tests/test_graphical_units/control_data/geometry/LabeledArrow.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/LabeledLine.npz b/tests/test_graphical_units/control_data/geometry/LabeledLine.npz new file mode 100644 index 0000000000..343ee5170a Binary files /dev/null and b/tests/test_graphical_units/control_data/geometry/LabeledLine.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/LabeledPolygram.npz b/tests/test_graphical_units/control_data/geometry/LabeledPolygram.npz new file mode 100644 index 0000000000..2a14d5f2be Binary files /dev/null and b/tests/test_graphical_units/control_data/geometry/LabeledPolygram.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/Line.npz b/tests/test_graphical_units/control_data/geometry/Line.npz index ae3d4bdf71..68ae41d8d3 100644 Binary files a/tests/test_graphical_units/control_data/geometry/Line.npz and b/tests/test_graphical_units/control_data/geometry/Line.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/Polygon.npz b/tests/test_graphical_units/control_data/geometry/Polygon.npz index 5488492734..6718f2a956 100644 Binary files a/tests/test_graphical_units/control_data/geometry/Polygon.npz and b/tests/test_graphical_units/control_data/geometry/Polygon.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/Polygram.npz b/tests/test_graphical_units/control_data/geometry/Polygram.npz index fdfc4ee061..e6e9445d86 100644 Binary files a/tests/test_graphical_units/control_data/geometry/Polygram.npz and b/tests/test_graphical_units/control_data/geometry/Polygram.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/Rectangle.npz b/tests/test_graphical_units/control_data/geometry/Rectangle.npz index d6cb95a7d8..38d71a56c0 100644 Binary files a/tests/test_graphical_units/control_data/geometry/Rectangle.npz and b/tests/test_graphical_units/control_data/geometry/Rectangle.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/RegularPolygram.npz b/tests/test_graphical_units/control_data/geometry/RegularPolygram.npz index 184e6120e2..b7a5ce1979 100644 Binary files a/tests/test_graphical_units/control_data/geometry/RegularPolygram.npz and b/tests/test_graphical_units/control_data/geometry/RegularPolygram.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/RightAngle.npz b/tests/test_graphical_units/control_data/geometry/RightAngle.npz index 3ea7a3be71..fefb186abb 100644 Binary files a/tests/test_graphical_units/control_data/geometry/RightAngle.npz and b/tests/test_graphical_units/control_data/geometry/RightAngle.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/RoundedRectangle.npz b/tests/test_graphical_units/control_data/geometry/RoundedRectangle.npz index f77b882212..4ba838524f 100644 Binary files a/tests/test_graphical_units/control_data/geometry/RoundedRectangle.npz and b/tests/test_graphical_units/control_data/geometry/RoundedRectangle.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/Sector.npz b/tests/test_graphical_units/control_data/geometry/Sector.npz index 3af257c26e..485c7dba2d 100644 Binary files a/tests/test_graphical_units/control_data/geometry/Sector.npz and b/tests/test_graphical_units/control_data/geometry/Sector.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/Star.npz b/tests/test_graphical_units/control_data/geometry/Star.npz index 8c4c938efe..0e9c83f811 100644 Binary files a/tests/test_graphical_units/control_data/geometry/Star.npz and b/tests/test_graphical_units/control_data/geometry/Star.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/Vector.npz b/tests/test_graphical_units/control_data/geometry/Vector.npz index 45421eb674..cd61507dcd 100644 Binary files a/tests/test_graphical_units/control_data/geometry/Vector.npz and b/tests/test_graphical_units/control_data/geometry/Vector.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/ZIndex.npz b/tests/test_graphical_units/control_data/geometry/ZIndex.npz index b109d8c169..166cd0d1f1 100644 Binary files a/tests/test_graphical_units/control_data/geometry/ZIndex.npz and b/tests/test_graphical_units/control_data/geometry/ZIndex.npz differ diff --git a/tests/test_graphical_units/control_data/geometry/three_points_Angle.npz b/tests/test_graphical_units/control_data/geometry/three_points_Angle.npz new file mode 100644 index 0000000000..68a055f5de Binary files /dev/null and b/tests/test_graphical_units/control_data/geometry/three_points_Angle.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/Arcs01.npz b/tests/test_graphical_units/control_data/img_and_svg/Arcs01.npz index 82fb79b078..f9bbd61597 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/Arcs01.npz and b/tests/test_graphical_units/control_data/img_and_svg/Arcs01.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/Arcs02.npz b/tests/test_graphical_units/control_data/img_and_svg/Arcs02.npz index 23040991a6..2339304080 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/Arcs02.npz and b/tests/test_graphical_units/control_data/img_and_svg/Arcs02.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/BrachistochroneCurve.npz b/tests/test_graphical_units/control_data/img_and_svg/BrachistochroneCurve.npz index 86d7587b97..738d672f5f 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/BrachistochroneCurve.npz and b/tests/test_graphical_units/control_data/img_and_svg/BrachistochroneCurve.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/ContiguousUSMap.npz b/tests/test_graphical_units/control_data/img_and_svg/ContiguousUSMap.npz index 3e67b429da..0c0d2737ca 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/ContiguousUSMap.npz and b/tests/test_graphical_units/control_data/img_and_svg/ContiguousUSMap.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/CubicAndLineto.npz b/tests/test_graphical_units/control_data/img_and_svg/CubicAndLineto.npz index 036827910d..affed6556f 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/CubicAndLineto.npz and b/tests/test_graphical_units/control_data/img_and_svg/CubicAndLineto.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/CubicPath.npz b/tests/test_graphical_units/control_data/img_and_svg/CubicPath.npz index c008af3735..7ec503926c 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/CubicPath.npz and b/tests/test_graphical_units/control_data/img_and_svg/CubicPath.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/DesmosGraph1.npz b/tests/test_graphical_units/control_data/img_and_svg/DesmosGraph1.npz index 3ed00b3077..07bdf75c98 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/DesmosGraph1.npz and b/tests/test_graphical_units/control_data/img_and_svg/DesmosGraph1.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/HalfEllipse.npz b/tests/test_graphical_units/control_data/img_and_svg/HalfEllipse.npz index 644b732447..7ff98b8855 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/HalfEllipse.npz and b/tests/test_graphical_units/control_data/img_and_svg/HalfEllipse.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/Heart.npz b/tests/test_graphical_units/control_data/img_and_svg/Heart.npz index 90a6f3a59f..3365ce23c3 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/Heart.npz and b/tests/test_graphical_units/control_data/img_and_svg/Heart.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/ImageInterpolation.npz b/tests/test_graphical_units/control_data/img_and_svg/ImageInterpolation.npz index fad18d7528..dec7b5f42d 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/ImageInterpolation.npz and b/tests/test_graphical_units/control_data/img_and_svg/ImageInterpolation.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/ImageMobject.npz b/tests/test_graphical_units/control_data/img_and_svg/ImageMobject.npz index 92adbfa2e5..aa28d6e139 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/ImageMobject.npz and b/tests/test_graphical_units/control_data/img_and_svg/ImageMobject.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/Inheritance.npz b/tests/test_graphical_units/control_data/img_and_svg/Inheritance.npz index f2395bdec2..1c33cd69d5 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/Inheritance.npz and b/tests/test_graphical_units/control_data/img_and_svg/Inheritance.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/Line.npz b/tests/test_graphical_units/control_data/img_and_svg/Line.npz index 30c355c8ce..fa684ca5b9 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/Line.npz and b/tests/test_graphical_units/control_data/img_and_svg/Line.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/ManimLogo.npz b/tests/test_graphical_units/control_data/img_and_svg/ManimLogo.npz index 618857d4e7..709993dd85 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/ManimLogo.npz and b/tests/test_graphical_units/control_data/img_and_svg/ManimLogo.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/MatrixTransform.npz b/tests/test_graphical_units/control_data/img_and_svg/MatrixTransform.npz index 9ae78cd405..24cba20273 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/MatrixTransform.npz and b/tests/test_graphical_units/control_data/img_and_svg/MatrixTransform.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/MultiPartPath.npz b/tests/test_graphical_units/control_data/img_and_svg/MultiPartPath.npz index 13779d26a2..cb9920b8a2 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/MultiPartPath.npz and b/tests/test_graphical_units/control_data/img_and_svg/MultiPartPath.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/MultipleTransform.npz b/tests/test_graphical_units/control_data/img_and_svg/MultipleTransform.npz index e7c1f70452..f65e50609b 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/MultipleTransform.npz and b/tests/test_graphical_units/control_data/img_and_svg/MultipleTransform.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/Penrose.npz b/tests/test_graphical_units/control_data/img_and_svg/Penrose.npz index b5fa1e02df..f0eba81584 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/Penrose.npz and b/tests/test_graphical_units/control_data/img_and_svg/Penrose.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/PixelizedText.npz b/tests/test_graphical_units/control_data/img_and_svg/PixelizedText.npz index ad38f70345..39249e3ac3 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/PixelizedText.npz and b/tests/test_graphical_units/control_data/img_and_svg/PixelizedText.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/QuadraticPath.npz b/tests/test_graphical_units/control_data/img_and_svg/QuadraticPath.npz index 48de2144d1..d793e41313 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/QuadraticPath.npz and b/tests/test_graphical_units/control_data/img_and_svg/QuadraticPath.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/Rhomboid.npz b/tests/test_graphical_units/control_data/img_and_svg/Rhomboid.npz index 769f500b10..45cdccac03 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/Rhomboid.npz and b/tests/test_graphical_units/control_data/img_and_svg/Rhomboid.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/RotateTransform.npz b/tests/test_graphical_units/control_data/img_and_svg/RotateTransform.npz index f78c653215..c8599abcf0 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/RotateTransform.npz and b/tests/test_graphical_units/control_data/img_and_svg/RotateTransform.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/ScaleTransform.npz b/tests/test_graphical_units/control_data/img_and_svg/ScaleTransform.npz index b464e1cb62..7357bf3fd1 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/ScaleTransform.npz and b/tests/test_graphical_units/control_data/img_and_svg/ScaleTransform.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/SingleUSState.npz b/tests/test_graphical_units/control_data/img_and_svg/SingleUSState.npz index 2840601fec..1c483f8bd1 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/SingleUSState.npz and b/tests/test_graphical_units/control_data/img_and_svg/SingleUSState.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/SkewXTransform.npz b/tests/test_graphical_units/control_data/img_and_svg/SkewXTransform.npz index 6f74fbc847..acbc9fe56d 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/SkewXTransform.npz and b/tests/test_graphical_units/control_data/img_and_svg/SkewXTransform.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/SkewYTransform.npz b/tests/test_graphical_units/control_data/img_and_svg/SkewYTransform.npz index 6f74fbc847..77c0aa8fce 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/SkewYTransform.npz and b/tests/test_graphical_units/control_data/img_and_svg/SkewYTransform.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/SmoothCurves.npz b/tests/test_graphical_units/control_data/img_and_svg/SmoothCurves.npz index f1f5fa5613..64f25d0e02 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/SmoothCurves.npz and b/tests/test_graphical_units/control_data/img_and_svg/SmoothCurves.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/TranslateTransform.npz b/tests/test_graphical_units/control_data/img_and_svg/TranslateTransform.npz index 7b318538a6..00a68d393d 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/TranslateTransform.npz and b/tests/test_graphical_units/control_data/img_and_svg/TranslateTransform.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/UKFlag.npz b/tests/test_graphical_units/control_data/img_and_svg/UKFlag.npz index fb29b5c5d8..9b78873653 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/UKFlag.npz and b/tests/test_graphical_units/control_data/img_and_svg/UKFlag.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/UseTagInheritance.npz b/tests/test_graphical_units/control_data/img_and_svg/UseTagInheritance.npz index 77bc5e6af4..75ddc44f88 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/UseTagInheritance.npz and b/tests/test_graphical_units/control_data/img_and_svg/UseTagInheritance.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/VideoIcon.npz b/tests/test_graphical_units/control_data/img_and_svg/VideoIcon.npz index cd8a9b125d..9a05ea7ec6 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/VideoIcon.npz and b/tests/test_graphical_units/control_data/img_and_svg/VideoIcon.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/WatchTheDecimals.npz b/tests/test_graphical_units/control_data/img_and_svg/WatchTheDecimals.npz index f98436b2cc..a09efcd163 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/WatchTheDecimals.npz and b/tests/test_graphical_units/control_data/img_and_svg/WatchTheDecimals.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/WeightSVG.npz b/tests/test_graphical_units/control_data/img_and_svg/WeightSVG.npz index 767083295b..611edb3b65 100644 Binary files a/tests/test_graphical_units/control_data/img_and_svg/WeightSVG.npz and b/tests/test_graphical_units/control_data/img_and_svg/WeightSVG.npz differ diff --git a/tests/test_graphical_units/control_data/img_and_svg/path_multiple_moves.npz b/tests/test_graphical_units/control_data/img_and_svg/path_multiple_moves.npz new file mode 100644 index 0000000000..f1411e2aa4 Binary files /dev/null and b/tests/test_graphical_units/control_data/img_and_svg/path_multiple_moves.npz differ diff --git a/tests/test_graphical_units/control_data/indication/ApplyWave.npz b/tests/test_graphical_units/control_data/indication/ApplyWave.npz index 13357b70c3..bdd154d2f2 100644 Binary files a/tests/test_graphical_units/control_data/indication/ApplyWave.npz and b/tests/test_graphical_units/control_data/indication/ApplyWave.npz differ diff --git a/tests/test_graphical_units/control_data/indication/Circumscribe.npz b/tests/test_graphical_units/control_data/indication/Circumscribe.npz index b926e12407..628f5f0b71 100644 Binary files a/tests/test_graphical_units/control_data/indication/Circumscribe.npz and b/tests/test_graphical_units/control_data/indication/Circumscribe.npz differ diff --git a/tests/test_graphical_units/control_data/indication/Flash.npz b/tests/test_graphical_units/control_data/indication/Flash.npz index ae14495768..168ed080a9 100644 Binary files a/tests/test_graphical_units/control_data/indication/Flash.npz and b/tests/test_graphical_units/control_data/indication/Flash.npz differ diff --git a/tests/test_graphical_units/control_data/indication/FocusOn.npz b/tests/test_graphical_units/control_data/indication/FocusOn.npz index 67055c2067..03dacd5230 100644 Binary files a/tests/test_graphical_units/control_data/indication/FocusOn.npz and b/tests/test_graphical_units/control_data/indication/FocusOn.npz differ diff --git a/tests/test_graphical_units/control_data/indication/Indicate.npz b/tests/test_graphical_units/control_data/indication/Indicate.npz index 44d6e7d1fb..0ffd52d396 100644 Binary files a/tests/test_graphical_units/control_data/indication/Indicate.npz and b/tests/test_graphical_units/control_data/indication/Indicate.npz differ diff --git a/tests/test_graphical_units/control_data/indication/ShowCreationThenFadeOut.npz b/tests/test_graphical_units/control_data/indication/ShowCreationThenFadeOut.npz deleted file mode 100644 index 8ce8c56c38..0000000000 Binary files a/tests/test_graphical_units/control_data/indication/ShowCreationThenFadeOut.npz and /dev/null differ diff --git a/tests/test_graphical_units/control_data/indication/ShowPassingFlash.npz b/tests/test_graphical_units/control_data/indication/ShowPassingFlash.npz index 1b16902ab6..dce1e65793 100644 Binary files a/tests/test_graphical_units/control_data/indication/ShowPassingFlash.npz and b/tests/test_graphical_units/control_data/indication/ShowPassingFlash.npz differ diff --git a/tests/test_graphical_units/control_data/indication/Wiggle.npz b/tests/test_graphical_units/control_data/indication/Wiggle.npz index 79898a8580..8e9826fd32 100644 Binary files a/tests/test_graphical_units/control_data/indication/Wiggle.npz and b/tests/test_graphical_units/control_data/indication/Wiggle.npz differ diff --git a/tests/test_graphical_units/control_data/logo/banner.npz b/tests/test_graphical_units/control_data/logo/banner.npz new file mode 100644 index 0000000000..4d6e2e399c Binary files /dev/null and b/tests/test_graphical_units/control_data/logo/banner.npz differ diff --git a/tests/test_graphical_units/control_data/mobjects/PointCloudDot.npz b/tests/test_graphical_units/control_data/mobjects/PointCloudDot.npz index 54f461e254..2e1295a0fc 100644 Binary files a/tests/test_graphical_units/control_data/mobjects/PointCloudDot.npz and b/tests/test_graphical_units/control_data/mobjects/PointCloudDot.npz differ diff --git a/tests/test_graphical_units/control_data/mobjects/become.npz b/tests/test_graphical_units/control_data/mobjects/become.npz index 4980e9d1d8..5a23d35569 100644 Binary files a/tests/test_graphical_units/control_data/mobjects/become.npz and b/tests/test_graphical_units/control_data/mobjects/become.npz differ diff --git a/tests/test_graphical_units/control_data/mobjects/become_no_color_linking.npz b/tests/test_graphical_units/control_data/mobjects/become_no_color_linking.npz new file mode 100644 index 0000000000..da9da189ad Binary files /dev/null and b/tests/test_graphical_units/control_data/mobjects/become_no_color_linking.npz differ diff --git a/tests/test_graphical_units/control_data/mobjects/match_style.npz b/tests/test_graphical_units/control_data/mobjects/match_style.npz index dcdad6d328..f555f60eac 100644 Binary files a/tests/test_graphical_units/control_data/mobjects/match_style.npz and b/tests/test_graphical_units/control_data/mobjects/match_style.npz differ diff --git a/tests/test_graphical_units/control_data/mobjects/vmobject_cap_styles.npz b/tests/test_graphical_units/control_data/mobjects/vmobject_cap_styles.npz new file mode 100644 index 0000000000..1dc9b0b0e8 Binary files /dev/null and b/tests/test_graphical_units/control_data/mobjects/vmobject_cap_styles.npz differ diff --git a/tests/test_graphical_units/control_data/mobjects/vmobject_joint_types.npz b/tests/test_graphical_units/control_data/mobjects/vmobject_joint_types.npz new file mode 100644 index 0000000000..26c23ecf90 Binary files /dev/null and b/tests/test_graphical_units/control_data/mobjects/vmobject_joint_types.npz differ diff --git a/tests/test_graphical_units/control_data/modifier_methods/Gradient.npz b/tests/test_graphical_units/control_data/modifier_methods/Gradient.npz index 435fa88780..3fa4102353 100644 Binary files a/tests/test_graphical_units/control_data/modifier_methods/Gradient.npz and b/tests/test_graphical_units/control_data/modifier_methods/Gradient.npz differ diff --git a/tests/test_graphical_units/control_data/modifier_methods/GradientRotation.npz b/tests/test_graphical_units/control_data/modifier_methods/GradientRotation.npz index b7d956dd77..f7bcd931a0 100644 Binary files a/tests/test_graphical_units/control_data/modifier_methods/GradientRotation.npz and b/tests/test_graphical_units/control_data/modifier_methods/GradientRotation.npz differ diff --git a/tests/test_graphical_units/control_data/movements/Homotopy.npz b/tests/test_graphical_units/control_data/movements/Homotopy.npz index 8d80b52042..223fb76fa7 100644 Binary files a/tests/test_graphical_units/control_data/movements/Homotopy.npz and b/tests/test_graphical_units/control_data/movements/Homotopy.npz differ diff --git a/tests/test_graphical_units/control_data/movements/MoveAlongPath.npz b/tests/test_graphical_units/control_data/movements/MoveAlongPath.npz index cc6f427524..f8f0570744 100644 Binary files a/tests/test_graphical_units/control_data/movements/MoveAlongPath.npz and b/tests/test_graphical_units/control_data/movements/MoveAlongPath.npz differ diff --git a/tests/test_graphical_units/control_data/movements/MoveTo.npz b/tests/test_graphical_units/control_data/movements/MoveTo.npz index 6a3268d11f..de7f30093f 100644 Binary files a/tests/test_graphical_units/control_data/movements/MoveTo.npz and b/tests/test_graphical_units/control_data/movements/MoveTo.npz differ diff --git a/tests/test_graphical_units/control_data/movements/PhaseFlow.npz b/tests/test_graphical_units/control_data/movements/PhaseFlow.npz index de58b1451e..8e087323d1 100644 Binary files a/tests/test_graphical_units/control_data/movements/PhaseFlow.npz and b/tests/test_graphical_units/control_data/movements/PhaseFlow.npz differ diff --git a/tests/test_graphical_units/control_data/movements/Rotate.npz b/tests/test_graphical_units/control_data/movements/Rotate.npz index f0b4956518..43e5b3afcd 100644 Binary files a/tests/test_graphical_units/control_data/movements/Rotate.npz and b/tests/test_graphical_units/control_data/movements/Rotate.npz differ diff --git a/tests/test_graphical_units/control_data/movements/Shift.npz b/tests/test_graphical_units/control_data/movements/Shift.npz index b7dfd8d980..2cd4fd992d 100644 Binary files a/tests/test_graphical_units/control_data/movements/Shift.npz and b/tests/test_graphical_units/control_data/movements/Shift.npz differ diff --git a/tests/test_graphical_units/control_data/numbers/set_value_with_updaters.npz b/tests/test_graphical_units/control_data/numbers/set_value_with_updaters.npz index f0cbfa5f65..9f2ab8ea37 100644 Binary files a/tests/test_graphical_units/control_data/numbers/set_value_with_updaters.npz and b/tests/test_graphical_units/control_data/numbers/set_value_with_updaters.npz differ diff --git a/tests/test_graphical_units/control_data/opengl/Circle.npz b/tests/test_graphical_units/control_data/opengl/Circle.npz index 5dd50f220e..8cc6e43c48 100644 Binary files a/tests/test_graphical_units/control_data/opengl/Circle.npz and b/tests/test_graphical_units/control_data/opengl/Circle.npz differ diff --git a/tests/test_graphical_units/control_data/opengl/FixedMobjects3D.npz b/tests/test_graphical_units/control_data/opengl/FixedMobjects3D.npz index 2371dbfaeb..204e542a8d 100644 Binary files a/tests/test_graphical_units/control_data/opengl/FixedMobjects3D.npz and b/tests/test_graphical_units/control_data/opengl/FixedMobjects3D.npz differ diff --git a/tests/test_graphical_units/control_data/plot/axes.npz b/tests/test_graphical_units/control_data/plot/axes.npz index 0895662cf8..f147d162af 100644 Binary files a/tests/test_graphical_units/control_data/plot/axes.npz and b/tests/test_graphical_units/control_data/plot/axes.npz differ diff --git a/tests/test_graphical_units/control_data/plot/axis_tip_custom_width_height.npz b/tests/test_graphical_units/control_data/plot/axis_tip_custom_width_height.npz new file mode 100644 index 0000000000..5ad14bff0c Binary files /dev/null and b/tests/test_graphical_units/control_data/plot/axis_tip_custom_width_height.npz differ diff --git a/tests/test_graphical_units/control_data/plot/axis_tip_default_width_height.npz b/tests/test_graphical_units/control_data/plot/axis_tip_default_width_height.npz new file mode 100644 index 0000000000..e244282735 Binary files /dev/null and b/tests/test_graphical_units/control_data/plot/axis_tip_default_width_height.npz differ diff --git a/tests/test_graphical_units/control_data/plot/custom_coordinates.npz b/tests/test_graphical_units/control_data/plot/custom_coordinates.npz index c189f89af6..978c10ce98 100644 Binary files a/tests/test_graphical_units/control_data/plot/custom_coordinates.npz and b/tests/test_graphical_units/control_data/plot/custom_coordinates.npz differ diff --git a/tests/test_graphical_units/control_data/plot/get_area.npz b/tests/test_graphical_units/control_data/plot/get_area.npz index 0a7a707856..8bcad7f126 100644 Binary files a/tests/test_graphical_units/control_data/plot/get_area.npz and b/tests/test_graphical_units/control_data/plot/get_area.npz differ diff --git a/tests/test_graphical_units/control_data/plot/get_area_with_boundary_and_few_plot_points.npz b/tests/test_graphical_units/control_data/plot/get_area_with_boundary_and_few_plot_points.npz index 282bbe1c40..4d25100e33 100644 Binary files a/tests/test_graphical_units/control_data/plot/get_area_with_boundary_and_few_plot_points.npz and b/tests/test_graphical_units/control_data/plot/get_area_with_boundary_and_few_plot_points.npz differ diff --git a/tests/test_graphical_units/control_data/plot/get_axis_labels.npz b/tests/test_graphical_units/control_data/plot/get_axis_labels.npz index 76da3ed568..1b784beb70 100644 Binary files a/tests/test_graphical_units/control_data/plot/get_axis_labels.npz and b/tests/test_graphical_units/control_data/plot/get_axis_labels.npz differ diff --git a/tests/test_graphical_units/control_data/plot/get_graph_label.npz b/tests/test_graphical_units/control_data/plot/get_graph_label.npz index c90a697a6d..d4964557d2 100644 Binary files a/tests/test_graphical_units/control_data/plot/get_graph_label.npz and b/tests/test_graphical_units/control_data/plot/get_graph_label.npz differ diff --git a/tests/test_graphical_units/control_data/plot/get_lines_to_point.npz b/tests/test_graphical_units/control_data/plot/get_lines_to_point.npz index d65208f03e..ac11b6d11f 100644 Binary files a/tests/test_graphical_units/control_data/plot/get_lines_to_point.npz and b/tests/test_graphical_units/control_data/plot/get_lines_to_point.npz differ diff --git a/tests/test_graphical_units/control_data/plot/get_riemann_rectangles.npz b/tests/test_graphical_units/control_data/plot/get_riemann_rectangles.npz deleted file mode 100644 index f756d25445..0000000000 Binary files a/tests/test_graphical_units/control_data/plot/get_riemann_rectangles.npz and /dev/null differ diff --git a/tests/test_graphical_units/control_data/plot/get_riemann_rectangles_use_vectorized[False].npz b/tests/test_graphical_units/control_data/plot/get_riemann_rectangles_use_vectorized[False].npz new file mode 100644 index 0000000000..f7b8a802bd Binary files /dev/null and b/tests/test_graphical_units/control_data/plot/get_riemann_rectangles_use_vectorized[False].npz differ diff --git a/tests/test_graphical_units/control_data/plot/get_riemann_rectangles_use_vectorized[True].npz b/tests/test_graphical_units/control_data/plot/get_riemann_rectangles_use_vectorized[True].npz new file mode 100644 index 0000000000..f7b8a802bd Binary files /dev/null and b/tests/test_graphical_units/control_data/plot/get_riemann_rectangles_use_vectorized[True].npz differ diff --git a/tests/test_graphical_units/control_data/plot/get_x_axis_label.npz b/tests/test_graphical_units/control_data/plot/get_x_axis_label.npz index c1f5a74e90..129f9fca71 100644 Binary files a/tests/test_graphical_units/control_data/plot/get_x_axis_label.npz and b/tests/test_graphical_units/control_data/plot/get_x_axis_label.npz differ diff --git a/tests/test_graphical_units/control_data/plot/get_y_axis_label.npz b/tests/test_graphical_units/control_data/plot/get_y_axis_label.npz index 804e2646df..63fa0cc73e 100644 Binary files a/tests/test_graphical_units/control_data/plot/get_y_axis_label.npz and b/tests/test_graphical_units/control_data/plot/get_y_axis_label.npz differ diff --git a/tests/test_graphical_units/control_data/plot/get_z_axis_label.npz b/tests/test_graphical_units/control_data/plot/get_z_axis_label.npz index d56d4761eb..becf62576a 100644 Binary files a/tests/test_graphical_units/control_data/plot/get_z_axis_label.npz and b/tests/test_graphical_units/control_data/plot/get_z_axis_label.npz differ diff --git a/tests/test_graphical_units/control_data/plot/log_scaling_graph.npz b/tests/test_graphical_units/control_data/plot/log_scaling_graph.npz index 2abf2c0e00..0be5a9b36a 100644 Binary files a/tests/test_graphical_units/control_data/plot/log_scaling_graph.npz and b/tests/test_graphical_units/control_data/plot/log_scaling_graph.npz differ diff --git a/tests/test_graphical_units/control_data/plot/plot.npz b/tests/test_graphical_units/control_data/plot/plot.npz deleted file mode 100644 index b886543329..0000000000 Binary files a/tests/test_graphical_units/control_data/plot/plot.npz and /dev/null differ diff --git a/tests/test_graphical_units/control_data/plot/plot_derivative_graph.npz b/tests/test_graphical_units/control_data/plot/plot_derivative_graph.npz deleted file mode 100644 index 7101141def..0000000000 Binary files a/tests/test_graphical_units/control_data/plot/plot_derivative_graph.npz and /dev/null differ diff --git a/tests/test_graphical_units/control_data/plot/plot_derivative_graph_use_vectorized[False].npz b/tests/test_graphical_units/control_data/plot/plot_derivative_graph_use_vectorized[False].npz new file mode 100644 index 0000000000..67aedce7f7 Binary files /dev/null and b/tests/test_graphical_units/control_data/plot/plot_derivative_graph_use_vectorized[False].npz differ diff --git a/tests/test_graphical_units/control_data/plot/plot_derivative_graph_use_vectorized[True].npz b/tests/test_graphical_units/control_data/plot/plot_derivative_graph_use_vectorized[True].npz new file mode 100644 index 0000000000..67aedce7f7 Binary files /dev/null and b/tests/test_graphical_units/control_data/plot/plot_derivative_graph_use_vectorized[True].npz differ diff --git a/tests/test_graphical_units/control_data/plot/plot_functions.npz b/tests/test_graphical_units/control_data/plot/plot_functions.npz deleted file mode 100644 index 1411fbf70d..0000000000 Binary files a/tests/test_graphical_units/control_data/plot/plot_functions.npz and /dev/null differ diff --git a/tests/test_graphical_units/control_data/plot/plot_functions_use_vectorized[False].npz b/tests/test_graphical_units/control_data/plot/plot_functions_use_vectorized[False].npz new file mode 100644 index 0000000000..c389c1f0b9 Binary files /dev/null and b/tests/test_graphical_units/control_data/plot/plot_functions_use_vectorized[False].npz differ diff --git a/tests/test_graphical_units/control_data/plot/plot_functions_use_vectorized[True].npz b/tests/test_graphical_units/control_data/plot/plot_functions_use_vectorized[True].npz new file mode 100644 index 0000000000..c389c1f0b9 Binary files /dev/null and b/tests/test_graphical_units/control_data/plot/plot_functions_use_vectorized[True].npz differ diff --git a/tests/test_graphical_units/control_data/plot/plot_line_graph.npz b/tests/test_graphical_units/control_data/plot/plot_line_graph.npz index a184d41bd1..32af24658f 100644 Binary files a/tests/test_graphical_units/control_data/plot/plot_line_graph.npz and b/tests/test_graphical_units/control_data/plot/plot_line_graph.npz differ diff --git a/tests/test_graphical_units/control_data/plot/plot_use_vectorized[False].npz b/tests/test_graphical_units/control_data/plot/plot_use_vectorized[False].npz new file mode 100644 index 0000000000..1b147b33fc Binary files /dev/null and b/tests/test_graphical_units/control_data/plot/plot_use_vectorized[False].npz differ diff --git a/tests/test_graphical_units/control_data/plot/plot_use_vectorized[True].npz b/tests/test_graphical_units/control_data/plot/plot_use_vectorized[True].npz new file mode 100644 index 0000000000..1b147b33fc Binary files /dev/null and b/tests/test_graphical_units/control_data/plot/plot_use_vectorized[True].npz differ diff --git a/tests/test_graphical_units/control_data/plot/polar_graph.npz b/tests/test_graphical_units/control_data/plot/polar_graph.npz index 18bd0f4775..a7417b84cb 100644 Binary files a/tests/test_graphical_units/control_data/plot/polar_graph.npz and b/tests/test_graphical_units/control_data/plot/polar_graph.npz differ diff --git a/tests/test_graphical_units/control_data/plot/t_label.npz b/tests/test_graphical_units/control_data/plot/t_label.npz index 4788950de5..c4a580d712 100644 Binary files a/tests/test_graphical_units/control_data/plot/t_label.npz and b/tests/test_graphical_units/control_data/plot/t_label.npz differ diff --git a/tests/test_graphical_units/control_data/polyhedra/ConvexHull3D.npz b/tests/test_graphical_units/control_data/polyhedra/ConvexHull3D.npz new file mode 100644 index 0000000000..eaa726b0fb Binary files /dev/null and b/tests/test_graphical_units/control_data/polyhedra/ConvexHull3D.npz differ diff --git a/tests/test_graphical_units/control_data/polyhedra/Dodecahedron.npz b/tests/test_graphical_units/control_data/polyhedra/Dodecahedron.npz index efcffa9be9..2fa5201715 100644 Binary files a/tests/test_graphical_units/control_data/polyhedra/Dodecahedron.npz and b/tests/test_graphical_units/control_data/polyhedra/Dodecahedron.npz differ diff --git a/tests/test_graphical_units/control_data/polyhedra/Icosahedron.npz b/tests/test_graphical_units/control_data/polyhedra/Icosahedron.npz index 5d92be49d0..ebefb34e9e 100644 Binary files a/tests/test_graphical_units/control_data/polyhedra/Icosahedron.npz and b/tests/test_graphical_units/control_data/polyhedra/Icosahedron.npz differ diff --git a/tests/test_graphical_units/control_data/polyhedra/Octahedron.npz b/tests/test_graphical_units/control_data/polyhedra/Octahedron.npz index 5693a51486..4f539d4064 100644 Binary files a/tests/test_graphical_units/control_data/polyhedra/Octahedron.npz and b/tests/test_graphical_units/control_data/polyhedra/Octahedron.npz differ diff --git a/tests/test_graphical_units/control_data/polyhedra/Tetrahedron.npz b/tests/test_graphical_units/control_data/polyhedra/Tetrahedron.npz index ac08a2e95d..6c13539971 100644 Binary files a/tests/test_graphical_units/control_data/polyhedra/Tetrahedron.npz and b/tests/test_graphical_units/control_data/polyhedra/Tetrahedron.npz differ diff --git a/tests/test_graphical_units/control_data/probability/advanced_customization.npz b/tests/test_graphical_units/control_data/probability/advanced_customization.npz index a099ebb5ce..c86f02f3e5 100644 Binary files a/tests/test_graphical_units/control_data/probability/advanced_customization.npz and b/tests/test_graphical_units/control_data/probability/advanced_customization.npz differ diff --git a/tests/test_graphical_units/control_data/probability/change_bar_values_negative.npz b/tests/test_graphical_units/control_data/probability/change_bar_values_negative.npz index 03945aae15..ac715e9dea 100644 Binary files a/tests/test_graphical_units/control_data/probability/change_bar_values_negative.npz and b/tests/test_graphical_units/control_data/probability/change_bar_values_negative.npz differ diff --git a/tests/test_graphical_units/control_data/probability/change_bar_values_some_vals.npz b/tests/test_graphical_units/control_data/probability/change_bar_values_some_vals.npz index bbd5b03264..e7cfb056b5 100644 Binary files a/tests/test_graphical_units/control_data/probability/change_bar_values_some_vals.npz and b/tests/test_graphical_units/control_data/probability/change_bar_values_some_vals.npz differ diff --git a/tests/test_graphical_units/control_data/probability/default_chart.npz b/tests/test_graphical_units/control_data/probability/default_chart.npz index 69ae700c83..972d32c79e 100644 Binary files a/tests/test_graphical_units/control_data/probability/default_chart.npz and b/tests/test_graphical_units/control_data/probability/default_chart.npz differ diff --git a/tests/test_graphical_units/control_data/probability/get_bar_labels.npz b/tests/test_graphical_units/control_data/probability/get_bar_labels.npz index 222c26f805..117c77ba5f 100644 Binary files a/tests/test_graphical_units/control_data/probability/get_bar_labels.npz and b/tests/test_graphical_units/control_data/probability/get_bar_labels.npz differ diff --git a/tests/test_graphical_units/control_data/probability/label_constructor.npz b/tests/test_graphical_units/control_data/probability/label_constructor.npz index 103876029f..4dbbe48d0f 100644 Binary files a/tests/test_graphical_units/control_data/probability/label_constructor.npz and b/tests/test_graphical_units/control_data/probability/label_constructor.npz differ diff --git a/tests/test_graphical_units/control_data/probability/negative_values.npz b/tests/test_graphical_units/control_data/probability/negative_values.npz index f50b1dfcf7..aeeb908a52 100644 Binary files a/tests/test_graphical_units/control_data/probability/negative_values.npz and b/tests/test_graphical_units/control_data/probability/negative_values.npz differ diff --git a/tests/test_graphical_units/control_data/specialized/Broadcast.npz b/tests/test_graphical_units/control_data/specialized/Broadcast.npz index ae511cfcbe..49b8d108f2 100644 Binary files a/tests/test_graphical_units/control_data/specialized/Broadcast.npz and b/tests/test_graphical_units/control_data/specialized/Broadcast.npz differ diff --git a/tests/test_graphical_units/control_data/speed/SpeedModifier.npz b/tests/test_graphical_units/control_data/speed/SpeedModifier.npz new file mode 100644 index 0000000000..10f1aa4ac8 Binary files /dev/null and b/tests/test_graphical_units/control_data/speed/SpeedModifier.npz differ diff --git a/tests/test_graphical_units/control_data/tables/DecimalTable.npz b/tests/test_graphical_units/control_data/tables/DecimalTable.npz index 1ad152996e..155224f2b4 100644 Binary files a/tests/test_graphical_units/control_data/tables/DecimalTable.npz and b/tests/test_graphical_units/control_data/tables/DecimalTable.npz differ diff --git a/tests/test_graphical_units/control_data/tables/IntegerTable.npz b/tests/test_graphical_units/control_data/tables/IntegerTable.npz index a05f0b48fb..d193a3c5bf 100644 Binary files a/tests/test_graphical_units/control_data/tables/IntegerTable.npz and b/tests/test_graphical_units/control_data/tables/IntegerTable.npz differ diff --git a/tests/test_graphical_units/control_data/tables/MathTable.npz b/tests/test_graphical_units/control_data/tables/MathTable.npz index dce2ae8dbf..aef53dd546 100644 Binary files a/tests/test_graphical_units/control_data/tables/MathTable.npz and b/tests/test_graphical_units/control_data/tables/MathTable.npz differ diff --git a/tests/test_graphical_units/control_data/tables/MobjectTable.npz b/tests/test_graphical_units/control_data/tables/MobjectTable.npz index 7662aa0686..0b39e4806a 100644 Binary files a/tests/test_graphical_units/control_data/tables/MobjectTable.npz and b/tests/test_graphical_units/control_data/tables/MobjectTable.npz differ diff --git a/tests/test_graphical_units/control_data/tables/Table.npz b/tests/test_graphical_units/control_data/tables/Table.npz index 008730faf3..e303ed473f 100644 Binary files a/tests/test_graphical_units/control_data/tables/Table.npz and b/tests/test_graphical_units/control_data/tables/Table.npz differ diff --git a/tests/test_graphical_units/control_data/tex_mobject/color_inheritance.npz b/tests/test_graphical_units/control_data/tex_mobject/color_inheritance.npz index 041b830772..9c2a1f5b11 100644 Binary files a/tests/test_graphical_units/control_data/tex_mobject/color_inheritance.npz and b/tests/test_graphical_units/control_data/tex_mobject/color_inheritance.npz differ diff --git a/tests/test_graphical_units/control_data/tex_mobject/set_opacity_by_tex.npz b/tests/test_graphical_units/control_data/tex_mobject/set_opacity_by_tex.npz new file mode 100644 index 0000000000..4e3b5f3889 Binary files /dev/null and b/tests/test_graphical_units/control_data/tex_mobject/set_opacity_by_tex.npz differ diff --git a/tests/test_graphical_units/control_data/text/Text2Color.npz b/tests/test_graphical_units/control_data/text/Text2Color.npz deleted file mode 100644 index 590b905174..0000000000 Binary files a/tests/test_graphical_units/control_data/text/Text2Color.npz and /dev/null differ diff --git a/tests/test_graphical_units/control_data/text/text_color_inheritance.npz b/tests/test_graphical_units/control_data/text/text_color_inheritance.npz deleted file mode 100644 index e453cc9a8c..0000000000 Binary files a/tests/test_graphical_units/control_data/text/text_color_inheritance.npz and /dev/null differ diff --git a/tests/test_graphical_units/control_data/threed/AddFixedInFrameMobjects.npz b/tests/test_graphical_units/control_data/threed/AddFixedInFrameMobjects.npz index 54d0d67bb1..c5dcaa4140 100644 Binary files a/tests/test_graphical_units/control_data/threed/AddFixedInFrameMobjects.npz and b/tests/test_graphical_units/control_data/threed/AddFixedInFrameMobjects.npz differ diff --git a/tests/test_graphical_units/control_data/threed/AmbientCameraMove.npz b/tests/test_graphical_units/control_data/threed/AmbientCameraMove.npz index f91b970ef8..356727d928 100644 Binary files a/tests/test_graphical_units/control_data/threed/AmbientCameraMove.npz and b/tests/test_graphical_units/control_data/threed/AmbientCameraMove.npz differ diff --git a/tests/test_graphical_units/control_data/threed/Arrow3D.npz b/tests/test_graphical_units/control_data/threed/Arrow3D.npz index d066e93223..1daefa59c1 100644 Binary files a/tests/test_graphical_units/control_data/threed/Arrow3D.npz and b/tests/test_graphical_units/control_data/threed/Arrow3D.npz differ diff --git a/tests/test_graphical_units/control_data/threed/Axes.npz b/tests/test_graphical_units/control_data/threed/Axes.npz index 9e4eb77bdf..a4af2e1475 100644 Binary files a/tests/test_graphical_units/control_data/threed/Axes.npz and b/tests/test_graphical_units/control_data/threed/Axes.npz differ diff --git a/tests/test_graphical_units/control_data/threed/CameraMove.npz b/tests/test_graphical_units/control_data/threed/CameraMove.npz index a884913567..5b688aba8e 100644 Binary files a/tests/test_graphical_units/control_data/threed/CameraMove.npz and b/tests/test_graphical_units/control_data/threed/CameraMove.npz differ diff --git a/tests/test_graphical_units/control_data/threed/CameraMoveAxes.npz b/tests/test_graphical_units/control_data/threed/CameraMoveAxes.npz index 5e0cdc0544..9a2a306ffb 100644 Binary files a/tests/test_graphical_units/control_data/threed/CameraMoveAxes.npz and b/tests/test_graphical_units/control_data/threed/CameraMoveAxes.npz differ diff --git a/tests/test_graphical_units/control_data/threed/Cone.npz b/tests/test_graphical_units/control_data/threed/Cone.npz index 50dc203646..00bd82a727 100644 Binary files a/tests/test_graphical_units/control_data/threed/Cone.npz and b/tests/test_graphical_units/control_data/threed/Cone.npz differ diff --git a/tests/test_graphical_units/control_data/threed/Cube.npz b/tests/test_graphical_units/control_data/threed/Cube.npz index a955b37eef..3a8f89fbce 100644 Binary files a/tests/test_graphical_units/control_data/threed/Cube.npz and b/tests/test_graphical_units/control_data/threed/Cube.npz differ diff --git a/tests/test_graphical_units/control_data/threed/Cylinder.npz b/tests/test_graphical_units/control_data/threed/Cylinder.npz index 094f808f8f..a818dc2285 100644 Binary files a/tests/test_graphical_units/control_data/threed/Cylinder.npz and b/tests/test_graphical_units/control_data/threed/Cylinder.npz differ diff --git a/tests/test_graphical_units/control_data/threed/Dot3D.npz b/tests/test_graphical_units/control_data/threed/Dot3D.npz index e946ae235b..248e716fd7 100644 Binary files a/tests/test_graphical_units/control_data/threed/Dot3D.npz and b/tests/test_graphical_units/control_data/threed/Dot3D.npz differ diff --git a/tests/test_graphical_units/control_data/threed/Line3D.npz b/tests/test_graphical_units/control_data/threed/Line3D.npz index 05d698208f..2ccac9335e 100644 Binary files a/tests/test_graphical_units/control_data/threed/Line3D.npz and b/tests/test_graphical_units/control_data/threed/Line3D.npz differ diff --git a/tests/test_graphical_units/control_data/threed/MovingVertices.npz b/tests/test_graphical_units/control_data/threed/MovingVertices.npz index 2da8e3a251..696e4ce004 100644 Binary files a/tests/test_graphical_units/control_data/threed/MovingVertices.npz and b/tests/test_graphical_units/control_data/threed/MovingVertices.npz differ diff --git a/tests/test_graphical_units/control_data/threed/Sphere.npz b/tests/test_graphical_units/control_data/threed/Sphere.npz index d45b68e896..58cd442676 100644 Binary files a/tests/test_graphical_units/control_data/threed/Sphere.npz and b/tests/test_graphical_units/control_data/threed/Sphere.npz differ diff --git a/tests/test_graphical_units/control_data/threed/SurfaceColorscale.npz b/tests/test_graphical_units/control_data/threed/SurfaceColorscale.npz index 2a2a6f7f73..319e3dbe7e 100644 Binary files a/tests/test_graphical_units/control_data/threed/SurfaceColorscale.npz and b/tests/test_graphical_units/control_data/threed/SurfaceColorscale.npz differ diff --git a/tests/test_graphical_units/control_data/threed/Torus.npz b/tests/test_graphical_units/control_data/threed/Torus.npz index f2a8fcaef9..940a2bdb28 100644 Binary files a/tests/test_graphical_units/control_data/threed/Torus.npz and b/tests/test_graphical_units/control_data/threed/Torus.npz differ diff --git a/tests/test_graphical_units/control_data/threed/Y_Direction.npz b/tests/test_graphical_units/control_data/threed/Y_Direction.npz index 540e7062ed..bf03fefe4d 100644 Binary files a/tests/test_graphical_units/control_data/threed/Y_Direction.npz and b/tests/test_graphical_units/control_data/threed/Y_Direction.npz differ diff --git a/tests/test_graphical_units/control_data/transform/AnimationBuilder.npz b/tests/test_graphical_units/control_data/transform/AnimationBuilder.npz index ac3eef3c15..ca5be8689b 100644 Binary files a/tests/test_graphical_units/control_data/transform/AnimationBuilder.npz and b/tests/test_graphical_units/control_data/transform/AnimationBuilder.npz differ diff --git a/tests/test_graphical_units/control_data/transform/ApplyComplexFunction.npz b/tests/test_graphical_units/control_data/transform/ApplyComplexFunction.npz index b0a7b61679..472a1206d1 100644 Binary files a/tests/test_graphical_units/control_data/transform/ApplyComplexFunction.npz and b/tests/test_graphical_units/control_data/transform/ApplyComplexFunction.npz differ diff --git a/tests/test_graphical_units/control_data/transform/ApplyFunction.npz b/tests/test_graphical_units/control_data/transform/ApplyFunction.npz index b957da88e3..646b505fb8 100644 Binary files a/tests/test_graphical_units/control_data/transform/ApplyFunction.npz and b/tests/test_graphical_units/control_data/transform/ApplyFunction.npz differ diff --git a/tests/test_graphical_units/control_data/transform/ApplyMatrix.npz b/tests/test_graphical_units/control_data/transform/ApplyMatrix.npz index 1350affd30..de5429db8a 100644 Binary files a/tests/test_graphical_units/control_data/transform/ApplyMatrix.npz and b/tests/test_graphical_units/control_data/transform/ApplyMatrix.npz differ diff --git a/tests/test_graphical_units/control_data/transform/ApplyPointwiseFunction.npz b/tests/test_graphical_units/control_data/transform/ApplyPointwiseFunction.npz index 54192f9bd1..e16514cc8b 100644 Binary files a/tests/test_graphical_units/control_data/transform/ApplyPointwiseFunction.npz and b/tests/test_graphical_units/control_data/transform/ApplyPointwiseFunction.npz differ diff --git a/tests/test_graphical_units/control_data/transform/ClockwiseTransform.npz b/tests/test_graphical_units/control_data/transform/ClockwiseTransform.npz index 61485d691c..db502a0d0d 100644 Binary files a/tests/test_graphical_units/control_data/transform/ClockwiseTransform.npz and b/tests/test_graphical_units/control_data/transform/ClockwiseTransform.npz differ diff --git a/tests/test_graphical_units/control_data/transform/CounterclockwiseTransform.npz b/tests/test_graphical_units/control_data/transform/CounterclockwiseTransform.npz index a143c4d0ad..71b8b28385 100644 Binary files a/tests/test_graphical_units/control_data/transform/CounterclockwiseTransform.npz and b/tests/test_graphical_units/control_data/transform/CounterclockwiseTransform.npz differ diff --git a/tests/test_graphical_units/control_data/transform/CyclicReplace.npz b/tests/test_graphical_units/control_data/transform/CyclicReplace.npz index cb93772e70..94c9c25040 100644 Binary files a/tests/test_graphical_units/control_data/transform/CyclicReplace.npz and b/tests/test_graphical_units/control_data/transform/CyclicReplace.npz differ diff --git a/tests/test_graphical_units/control_data/transform/FadeInAndOut.npz b/tests/test_graphical_units/control_data/transform/FadeInAndOut.npz index 1aae6976c9..72a390b118 100644 Binary files a/tests/test_graphical_units/control_data/transform/FadeInAndOut.npz and b/tests/test_graphical_units/control_data/transform/FadeInAndOut.npz differ diff --git a/tests/test_graphical_units/control_data/transform/FadeToColort.npz b/tests/test_graphical_units/control_data/transform/FadeToColort.npz index 2c595b651c..1225e0a0e9 100644 Binary files a/tests/test_graphical_units/control_data/transform/FadeToColort.npz and b/tests/test_graphical_units/control_data/transform/FadeToColort.npz differ diff --git a/tests/test_graphical_units/control_data/transform/FadeTransform.npz b/tests/test_graphical_units/control_data/transform/FadeTransform.npz new file mode 100644 index 0000000000..31ae40e781 Binary files /dev/null and b/tests/test_graphical_units/control_data/transform/FadeTransform.npz differ diff --git a/tests/test_graphical_units/control_data/transform/FadeTransformPieces.npz b/tests/test_graphical_units/control_data/transform/FadeTransformPieces.npz new file mode 100644 index 0000000000..9dd892f45d Binary files /dev/null and b/tests/test_graphical_units/control_data/transform/FadeTransformPieces.npz differ diff --git a/tests/test_graphical_units/control_data/transform/FadeTransform_TargetIsEmpty_FadesOutInPlace.npz b/tests/test_graphical_units/control_data/transform/FadeTransform_TargetIsEmpty_FadesOutInPlace.npz new file mode 100644 index 0000000000..41ed0379b0 Binary files /dev/null and b/tests/test_graphical_units/control_data/transform/FadeTransform_TargetIsEmpty_FadesOutInPlace.npz differ diff --git a/tests/test_graphical_units/control_data/transform/FullRotation.npz b/tests/test_graphical_units/control_data/transform/FullRotation.npz index f273625af4..a692059818 100644 Binary files a/tests/test_graphical_units/control_data/transform/FullRotation.npz and b/tests/test_graphical_units/control_data/transform/FullRotation.npz differ diff --git a/tests/test_graphical_units/control_data/transform/MatchPointsScene.npz b/tests/test_graphical_units/control_data/transform/MatchPointsScene.npz index 7e640bda05..d753586c63 100644 Binary files a/tests/test_graphical_units/control_data/transform/MatchPointsScene.npz and b/tests/test_graphical_units/control_data/transform/MatchPointsScene.npz differ diff --git a/tests/test_graphical_units/control_data/transform/MoveToTarget.npz b/tests/test_graphical_units/control_data/transform/MoveToTarget.npz index 936f7b402e..05fae9414c 100644 Binary files a/tests/test_graphical_units/control_data/transform/MoveToTarget.npz and b/tests/test_graphical_units/control_data/transform/MoveToTarget.npz differ diff --git a/tests/test_graphical_units/control_data/transform/ReplacementTransform.npz b/tests/test_graphical_units/control_data/transform/ReplacementTransform.npz index 0edf7f2f67..3ac6271892 100644 Binary files a/tests/test_graphical_units/control_data/transform/ReplacementTransform.npz and b/tests/test_graphical_units/control_data/transform/ReplacementTransform.npz differ diff --git a/tests/test_graphical_units/control_data/transform/Restore.npz b/tests/test_graphical_units/control_data/transform/Restore.npz index 263fbba575..83ed894b4f 100644 Binary files a/tests/test_graphical_units/control_data/transform/Restore.npz and b/tests/test_graphical_units/control_data/transform/Restore.npz differ diff --git a/tests/test_graphical_units/control_data/transform/ScaleInPlace.npz b/tests/test_graphical_units/control_data/transform/ScaleInPlace.npz index 982ba2a63c..3a1421c44e 100644 Binary files a/tests/test_graphical_units/control_data/transform/ScaleInPlace.npz and b/tests/test_graphical_units/control_data/transform/ScaleInPlace.npz differ diff --git a/tests/test_graphical_units/control_data/transform/ShrinkToCenter.npz b/tests/test_graphical_units/control_data/transform/ShrinkToCenter.npz index 1deac9bfaa..5bfc39f558 100644 Binary files a/tests/test_graphical_units/control_data/transform/ShrinkToCenter.npz and b/tests/test_graphical_units/control_data/transform/ShrinkToCenter.npz differ diff --git a/tests/test_graphical_units/control_data/transform/Transform.npz b/tests/test_graphical_units/control_data/transform/Transform.npz index 0d22936349..c19a48c951 100644 Binary files a/tests/test_graphical_units/control_data/transform/Transform.npz and b/tests/test_graphical_units/control_data/transform/Transform.npz differ diff --git a/tests/test_graphical_units/control_data/transform/TransformFromCopy.npz b/tests/test_graphical_units/control_data/transform/TransformFromCopy.npz index 0d22936349..c19a48c951 100644 Binary files a/tests/test_graphical_units/control_data/transform/TransformFromCopy.npz and b/tests/test_graphical_units/control_data/transform/TransformFromCopy.npz differ diff --git a/tests/test_graphical_units/control_data/transform/TransformWithConflictingPaths.npz b/tests/test_graphical_units/control_data/transform/TransformWithConflictingPaths.npz new file mode 100644 index 0000000000..8ecf8506fe Binary files /dev/null and b/tests/test_graphical_units/control_data/transform/TransformWithConflictingPaths.npz differ diff --git a/tests/test_graphical_units/control_data/transform/TransformWithPathArcCenters.npz b/tests/test_graphical_units/control_data/transform/TransformWithPathArcCenters.npz new file mode 100644 index 0000000000..880a9cc38d Binary files /dev/null and b/tests/test_graphical_units/control_data/transform/TransformWithPathArcCenters.npz differ diff --git a/tests/test_graphical_units/control_data/transform/TransformWithPathFunc.npz b/tests/test_graphical_units/control_data/transform/TransformWithPathFunc.npz new file mode 100644 index 0000000000..8ecf8506fe Binary files /dev/null and b/tests/test_graphical_units/control_data/transform/TransformWithPathFunc.npz differ diff --git a/tests/test_graphical_units/control_data/transform_matching_parts/TransformMatchingDisplaysCorrect.npz b/tests/test_graphical_units/control_data/transform_matching_parts/TransformMatchingDisplaysCorrect.npz new file mode 100644 index 0000000000..f5b4831b54 Binary files /dev/null and b/tests/test_graphical_units/control_data/transform_matching_parts/TransformMatchingDisplaysCorrect.npz differ diff --git a/tests/test_graphical_units/control_data/transform_matching_parts/TransformMatchingLeavesOneObject.npz b/tests/test_graphical_units/control_data/transform_matching_parts/TransformMatchingLeavesOneObject.npz new file mode 100644 index 0000000000..9bfe0cf464 Binary files /dev/null and b/tests/test_graphical_units/control_data/transform_matching_parts/TransformMatchingLeavesOneObject.npz differ diff --git a/tests/test_graphical_units/control_data/transform_matching_parts/TransformMatchingTex.npz b/tests/test_graphical_units/control_data/transform_matching_parts/TransformMatchingTex.npz new file mode 100644 index 0000000000..e990c3b86d Binary files /dev/null and b/tests/test_graphical_units/control_data/transform_matching_parts/TransformMatchingTex.npz differ diff --git a/tests/test_graphical_units/control_data/transform_matching_parts/TransformMatchingTex_FadeTransformMismatches.npz b/tests/test_graphical_units/control_data/transform_matching_parts/TransformMatchingTex_FadeTransformMismatches.npz new file mode 100644 index 0000000000..fd157f6145 Binary files /dev/null and b/tests/test_graphical_units/control_data/transform_matching_parts/TransformMatchingTex_FadeTransformMismatches.npz differ diff --git a/tests/test_graphical_units/control_data/transform_matching_parts/TransformMatchingTex_FadeTransformMismatches_NothingToFade.npz b/tests/test_graphical_units/control_data/transform_matching_parts/TransformMatchingTex_FadeTransformMismatches_NothingToFade.npz new file mode 100644 index 0000000000..cad0524fa9 Binary files /dev/null and b/tests/test_graphical_units/control_data/transform_matching_parts/TransformMatchingTex_FadeTransformMismatches_NothingToFade.npz differ diff --git a/tests/test_graphical_units/control_data/transform_matching_parts/TransformMatchingTex_TransformMismatches.npz b/tests/test_graphical_units/control_data/transform_matching_parts/TransformMatchingTex_TransformMismatches.npz new file mode 100644 index 0000000000..55f834cb22 Binary files /dev/null and b/tests/test_graphical_units/control_data/transform_matching_parts/TransformMatchingTex_TransformMismatches.npz differ diff --git a/tests/test_graphical_units/control_data/updaters/LastFrameWhenCleared.npz b/tests/test_graphical_units/control_data/updaters/LastFrameWhenCleared.npz index 00a07ff8d8..e216c4378f 100644 Binary files a/tests/test_graphical_units/control_data/updaters/LastFrameWhenCleared.npz and b/tests/test_graphical_units/control_data/updaters/LastFrameWhenCleared.npz differ diff --git a/tests/test_graphical_units/control_data/updaters/UpdateSceneDuringAnimation.npz b/tests/test_graphical_units/control_data/updaters/UpdateSceneDuringAnimation.npz index 1613809ec2..0cbc604b47 100644 Binary files a/tests/test_graphical_units/control_data/updaters/UpdateSceneDuringAnimation.npz and b/tests/test_graphical_units/control_data/updaters/UpdateSceneDuringAnimation.npz differ diff --git a/tests/test_graphical_units/control_data/updaters/Updater.npz b/tests/test_graphical_units/control_data/updaters/Updater.npz index ff24a30297..45b98e0a87 100644 Binary files a/tests/test_graphical_units/control_data/updaters/Updater.npz and b/tests/test_graphical_units/control_data/updaters/Updater.npz differ diff --git a/tests/test_graphical_units/control_data/updaters/ValueTracker.npz b/tests/test_graphical_units/control_data/updaters/ValueTracker.npz index 6fe743b5a5..584242426e 100644 Binary files a/tests/test_graphical_units/control_data/updaters/ValueTracker.npz and b/tests/test_graphical_units/control_data/updaters/ValueTracker.npz differ diff --git a/tests/test_graphical_units/control_data/utils/pixel_error_threshold.npz b/tests/test_graphical_units/control_data/utils/pixel_error_threshold.npz new file mode 100644 index 0000000000..204e542a8d Binary files /dev/null and b/tests/test_graphical_units/control_data/utils/pixel_error_threshold.npz differ diff --git a/tests/test_graphical_units/control_data/vector_scene/vector_to_coords.npz b/tests/test_graphical_units/control_data/vector_scene/vector_to_coords.npz index 0ec1724363..8cec4d850a 100644 Binary files a/tests/test_graphical_units/control_data/vector_scene/vector_to_coords.npz and b/tests/test_graphical_units/control_data/vector_scene/vector_to_coords.npz differ diff --git a/tests/test_graphical_units/img_svg_resources/A.svg b/tests/test_graphical_units/img_svg_resources/A.svg new file mode 100644 index 0000000000..b8a0bafab4 --- /dev/null +++ b/tests/test_graphical_units/img_svg_resources/A.svg @@ -0,0 +1,13 @@ + + + + + + + + + + + + + diff --git a/tests/test_graphical_units/img_svg_resources/curve.svg b/tests/test_graphical_units/img_svg_resources/curve.svg index 6aba8bdc20..049d480e90 100644 --- a/tests/test_graphical_units/img_svg_resources/curve.svg +++ b/tests/test_graphical_units/img_svg_resources/curve.svg @@ -46,7 +46,7 @@ 7.65*(t-sin(t)), 7.65*(cos(t)-1) - + + + + + + + + + + diff --git a/tests/test_graphical_units/img_svg_resources/half_ellipse.svg b/tests/test_graphical_units/img_svg_resources/half_ellipse.svg index ce98f0afd1..b6af29ad03 100644 --- a/tests/test_graphical_units/img_svg_resources/half_ellipse.svg +++ b/tests/test_graphical_units/img_svg_resources/half_ellipse.svg @@ -1,3 +1,3 @@ - + diff --git a/tests/test_graphical_units/img_svg_resources/path_multiple_moves.svg b/tests/test_graphical_units/img_svg_resources/path_multiple_moves.svg new file mode 100644 index 0000000000..9f12c30590 --- /dev/null +++ b/tests/test_graphical_units/img_svg_resources/path_multiple_moves.svg @@ -0,0 +1,71 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/tests/test_graphical_units/img_svg_resources/states_map.svg b/tests/test_graphical_units/img_svg_resources/states_map.svg index 6eb24adc90..e58df6a01c 100644 --- a/tests/test_graphical_units/img_svg_resources/states_map.svg +++ b/tests/test_graphical_units/img_svg_resources/states_map.svg @@ -2,7 +2,7 @@ Blank map of the United States, territories not included - + Alabama diff --git a/tests/test_graphical_units/test_animation.py b/tests/test_graphical_units/test_animation.py new file mode 100644 index 0000000000..3758e4985b --- /dev/null +++ b/tests/test_graphical_units/test_animation.py @@ -0,0 +1,16 @@ +from manim import * +from manim.animation.animation import DEFAULT_ANIMATION_RUN_TIME + +__module_test__ = "animation" + + +def test_animation_set_default(): + s = Square() + Rotate.set_default(run_time=100) + anim = Rotate(s) + assert anim.run_time == 100 + anim = Rotate(s, run_time=5) + assert anim.run_time == 5 + Rotate.set_default() + anim = Rotate(s) + assert anim.run_time == DEFAULT_ANIMATION_RUN_TIME diff --git a/tests/test_graphical_units/test_axes.py b/tests/test_graphical_units/test_axes.py index 0683a46825..2e06300e46 100644 --- a/tests/test_graphical_units/test_axes.py +++ b/tests/test_graphical_units/test_axes.py @@ -14,15 +14,16 @@ def test_axes(scene): x_length=6, y_length=6, color=WHITE, + y_axis_config={"tip_shape": StealthTip}, ) labels = graph.get_axis_labels() scene.add(graph, labels) @frames_comparison -def test_plot_functions(scene): +def test_plot_functions(scene, use_vectorized): ax = Axes(x_range=(-10, 10.3), y_range=(-1.5, 1.5)) - graph = ax.plot(lambda x: x**2) + graph = ax.plot(lambda x: x**2, use_vectorized=use_vectorized) scene.add(ax, graph) @@ -68,18 +69,42 @@ def test_get_y_axis_label(scene): @frames_comparison -def test_plot_derivative_graph(scene): +def test_axis_tip_default_width_height(scene): + ax = Axes( + x_range=(0, 4), + y_range=(0, 4), + axis_config={"include_numbers": True, "include_tip": True}, + ) + + scene.add(ax) + + +@frames_comparison +def test_axis_tip_custom_width_height(scene): + ax = Axes( + x_range=(0, 4), + y_range=(0, 4), + axis_config={"include_numbers": True, "include_tip": True}, + x_axis_config={"tip_width": 1, "tip_height": 0.1}, + y_axis_config={"tip_width": 0.1, "tip_height": 1}, + ) + + scene.add(ax) + + +@frames_comparison +def test_plot_derivative_graph(scene, use_vectorized): ax = NumberPlane(y_range=[-1, 7], background_line_style={"stroke_opacity": 0.4}) - curve_1 = ax.plot(lambda x: x**2, color=PURPLE_B) - curve_2 = ax.plot_derivative_graph(curve_1) - curve_3 = ax.plot_antiderivative_graph(curve_1) + curve_1 = ax.plot(lambda x: x**2, color=PURPLE_B, use_vectorized=use_vectorized) + curve_2 = ax.plot_derivative_graph(curve_1, use_vectorized=use_vectorized) + curve_3 = ax.plot_antiderivative_graph(curve_1, use_vectorized=use_vectorized) curves = VGroup(curve_1, curve_2, curve_3) scene.add(ax, curves) @frames_comparison -def test_plot(scene): +def test_plot(scene, use_vectorized): # construct the axes ax_1 = Axes( x_range=[0.001, 6], @@ -102,15 +127,22 @@ def log_func(x): return np.log(x) # a curve without adjustments; poor interpolation. - curve_1 = ax_1.plot(log_func, color=PURE_RED) + curve_1 = ax_1.plot(log_func, color=PURE_RED, use_vectorized=use_vectorized) # disabling interpolation makes the graph look choppy as not enough # inputs are available - curve_2 = ax_2.plot(log_func, use_smoothing=False, color=ORANGE) + curve_2 = ax_2.plot( + log_func, use_smoothing=False, color=ORANGE, use_vectorized=use_vectorized + ) # taking more inputs of the curve by specifying a step for the # x_range yields expected results, but increases rendering time. - curve_3 = ax_3.plot(log_func, x_range=(0.001, 6, 0.001), color=PURE_GREEN) + curve_3 = ax_3.plot( + log_func, + x_range=(0.001, 6, 0.001), + color=PURE_GREEN, + use_vectorized=use_vectorized, + ) curves = VGroup(curve_1, curve_2, curve_3) @@ -214,9 +246,9 @@ def test_get_area_with_boundary_and_few_plot_points(scene): @frames_comparison -def test_get_riemann_rectangles(scene): +def test_get_riemann_rectangles(scene, use_vectorized): ax = Axes(y_range=[-2, 10]) - quadratic = ax.plot(lambda x: 0.5 * x**2 - 0.5) + quadratic = ax.plot(lambda x: 0.5 * x**2 - 0.5, use_vectorized=use_vectorized) # the rectangles are constructed from their top right corner. # passing an iterable to `color` produces a gradient @@ -261,7 +293,10 @@ def test_get_z_axis_label(scene): @frames_comparison def test_polar_graph(scene): polar = PolarPlane() - r = lambda theta: 4 * np.sin(theta * 4) + + def r(theta): + return 4 * np.sin(theta * 4) + polar_graph = polar.plot_polar_graph(r) scene.add(polar, polar_graph) diff --git a/tests/test_graphical_units/test_banner.py b/tests/test_graphical_units/test_banner.py new file mode 100644 index 0000000000..97363dff7d --- /dev/null +++ b/tests/test_graphical_units/test_banner.py @@ -0,0 +1,13 @@ +from __future__ import annotations + +from manim import ManimBanner +from manim.utils.testing.frames_comparison import frames_comparison + +__module_test__ = "logo" + + +@frames_comparison(last_frame=False) +def test_banner(scene): + banner = ManimBanner() + scene.play(banner.create(), run_time=0.5) + scene.play(banner.expand(), run_time=0.5) diff --git a/tests/test_graphical_units/test_coordinate_systems.py b/tests/test_graphical_units/test_coordinate_systems.py index 3a62b31072..7d6dad67af 100644 --- a/tests/test_graphical_units/test_coordinate_systems.py +++ b/tests/test_graphical_units/test_coordinate_systems.py @@ -37,6 +37,46 @@ def test_line_graph(scene): scene.add(plane, first_line, second_line) +@frames_comparison(base_scene=ThreeDScene) +def test_plot_surface(scene): + axes = ThreeDAxes(x_range=(-5, 5, 1), y_range=(-5, 5, 1), z_range=(-5, 5, 1)) + + def param_trig(u, v): + x = u + y = v + z = 2 * np.sin(x) + 2 * np.cos(y) + return z + + trig_plane = axes.plot_surface( + param_trig, + u_range=(-5, 5), + v_range=(-5, 5), + color=BLUE, + ) + + scene.add(axes, trig_plane) + + +@frames_comparison(base_scene=ThreeDScene) +def test_plot_surface_colorscale(scene): + axes = ThreeDAxes(x_range=(-3, 3, 1), y_range=(-3, 3, 1), z_range=(-5, 5, 1)) + + def param_trig(u, v): + x = u + y = v + z = 2 * np.sin(x) + 2 * np.cos(y) + return z + + trig_plane = axes.plot_surface( + param_trig, + u_range=(-3, 3), + v_range=(-3, 3), + colorscale=[BLUE, GREEN, YELLOW, ORANGE, RED], + ) + + scene.add(axes, trig_plane) + + @frames_comparison def test_implicit_graph(scene): ax = Axes() @@ -56,6 +96,20 @@ def test_plot_log_x_axis(scene): scene.add(ax, graph) +@frames_comparison +def test_plot_log_x_axis_vectorized(scene): + ax = Axes( + x_range=[-1, 4], + y_range=[0, 3], + x_axis_config={"scaling": LogBase()}, + ) + + graph = ax.plot( + lambda x: np.where(x < 10, 2, 1), x_range=[-1, 4], use_vectorized=True + ) + scene.add(ax, graph) + + @frames_comparison def test_number_plane_log(scene): """Test that NumberPlane generates its lines properly with a LogBase""" @@ -87,3 +141,33 @@ def test_number_plane_log(scene): ) scene.add(VGroup(plane1, plane2).arrange()) + + +@frames_comparison +def test_gradient_line_graph_x_axis(scene): + """Test that using `colorscale` generates a line whose gradient matches the y-axis""" + axes = Axes(x_range=[-3, 3], y_range=[-3, 3]) + + curve = axes.plot( + lambda x: 0.1 * x**3, + x_range=(-3, 3, 0.001), + colorscale=[BLUE, GREEN, YELLOW, ORANGE, RED], + colorscale_axis=0, + ) + + scene.add(axes, curve) + + +@frames_comparison +def test_gradient_line_graph_y_axis(scene): + """Test that using `colorscale` generates a line whose gradient matches the y-axis""" + axes = Axes(x_range=[-3, 3], y_range=[-3, 3]) + + curve = axes.plot( + lambda x: 0.1 * x**3, + x_range=(-3, 3, 0.001), + colorscale=[BLUE, GREEN, YELLOW, ORANGE, RED], + colorscale_axis=1, + ) + + scene.add(axes, curve) diff --git a/tests/test_graphical_units/test_creation.py b/tests/test_graphical_units/test_creation.py index c6ce35ba13..bcab0bafa4 100644 --- a/tests/test_graphical_units/test_creation.py +++ b/tests/test_graphical_units/test_creation.py @@ -19,6 +19,13 @@ def test_uncreate(scene): scene.play(Uncreate(square)) +@frames_comparison(last_frame=False) +def test_uncreate_rate_func(scene): + square = Square() + scene.add(square) + scene.play(Uncreate(square), rate_func=linear) + + @frames_comparison(last_frame=False) def test_DrawBorderThenFill(scene): square = Square(fill_opacity=1) @@ -87,3 +94,11 @@ def test_z_index_introducer(scene): b.set_z_index(-1) scene.play(Create(b)) scene.wait() + + +@frames_comparison(last_frame=False) +def test_SpiralIn(scene): + circle = Circle().shift(LEFT) + square = Square().shift(UP) + shapes = VGroup(circle, square) + scene.play(SpiralIn(shapes)) diff --git a/tests/test_graphical_units/test_geometry.py b/tests/test_graphical_units/test_geometry.py index 51e6817d74..fef2ca0951 100644 --- a/tests/test_graphical_units/test_geometry.py +++ b/tests/test_graphical_units/test_geometry.py @@ -138,6 +138,20 @@ def test_RoundedRectangle(scene): scene.add(a) +@frames_comparison +def test_ConvexHull(scene): + a = ConvexHull( + *[ + [-2.7, -0.6, 0], + [0.2, -1.7, 0], + [1.9, 1.2, 0], + [-2.7, 0.9, 0], + [1.6, 2.2, 0], + ] + ) + scene.add(a) + + @frames_comparison def test_Arrange(scene): s1 = Square() @@ -168,6 +182,35 @@ def test_Angle(scene): scene.add(a) +@frames_comparison +def test_three_points_Angle(scene): + # acute angle + acute = Angle.from_three_points( + np.array([10, 0, 0]), np.array([0, 0, 0]), np.array([10, 10, 0]) + ) + # obtuse angle + obtuse = Angle.from_three_points( + np.array([-10, 1, 0]), np.array([0, 0, 0]), np.array([10, 1, 0]) + ) + # quadrant 1 angle + q1 = Angle.from_three_points( + np.array([10, 10, 0]), np.array([0, 0, 0]), np.array([10, 1, 0]) + ) + # quadrant 2 angle + q2 = Angle.from_three_points( + np.array([-10, 1, 0]), np.array([0, 0, 0]), np.array([-1, 10, 0]) + ) + # quadrant 3 angle + q3 = Angle.from_three_points( + np.array([-10, -1, 0]), np.array([0, 0, 0]), np.array([-1, -10, 0]) + ) + # quadrant 4 angle + q4 = Angle.from_three_points( + np.array([10, -1, 0]), np.array([0, 0, 0]), np.array([1, -10, 0]) + ) + scene.add(VGroup(acute, obtuse, q1, q2, q3, q4).arrange(RIGHT)) + + @frames_comparison def test_RightAngle(scene): l1 = Line(ORIGIN, RIGHT) @@ -218,3 +261,44 @@ def test_CurvedArrowCustomTip(scene): tip_shape_end=ArrowSquareFilledTip, ) scene.add(arrow, double_arrow) + + +@frames_comparison +def test_LabeledLine(scene): + line = LabeledLine( + label="0.5", + label_position=0.8, + label_config={"font_size": 20}, + start=LEFT + DOWN, + end=RIGHT + UP, + ) + scene.add(line) + + +@frames_comparison +def test_LabeledArrow(scene): + l_arrow = LabeledArrow( + label="0.5", + label_position=0.5, + label_config={"font_size": 15}, + start=LEFT * 3, + end=RIGHT * 3 + UP * 2, + ) + scene.add(l_arrow) + + +@frames_comparison +def test_LabeledPolygram(scene): + polygram = LabeledPolygram( + [ + [-2.5, -2.5, 0], + [2.5, -2.5, 0], + [2.5, 2.5, 0], + [-2.5, 2.5, 0], + [-2.5, -2.5, 0], + ], + [[-1, -1, 0], [0.5, -1, 0], [0.5, 0.5, 0], [-1, 0.5, 0], [-1, -1, 0]], + [[1, 1, 0], [2, 1, 0], [2, 2, 0], [1, 2, 0], [1, 1, 0]], + label="C", + ) + scene.add(polygram) diff --git a/tests/test_graphical_units/test_img_and_svg.py b/tests/test_graphical_units/test_img_and_svg.py index 1a94ddcf2a..b2ae820cb6 100644 --- a/tests/test_graphical_units/test_img_and_svg.py +++ b/tests/test_graphical_units/test_img_and_svg.py @@ -242,6 +242,17 @@ def test_RotateTransform(scene): scene.wait() +@frames_comparison +def test_path_multiple_moves(scene): + svg_obj = SVGMobject( + get_svg_resource("path_multiple_moves.svg"), + fill_color=WHITE, + stroke_color=WHITE, + stroke_width=3, + ) + scene.add(svg_obj) + + @frames_comparison def test_ImageMobject(scene): file_path = get_svg_resource("tree_img_640x351.png") @@ -273,3 +284,20 @@ def test_ImageInterpolation(scene): scene.add(img1, img2, img3, img4, img5) [s.shift(4 * LEFT + pos * 2 * RIGHT) for pos, s in enumerate(scene.mobjects)] scene.wait() + + +def test_ImageMobject_points_length(): + file_path = get_svg_resource("tree_img_640x351.png") + im1 = ImageMobject(file_path) + assert len(im1.points) == 4 + + +def test_ImageMobject_rotation(): + # see https://github.com/ManimCommunity/manim/issues/3067 + # rotating an image to and from the same angle should not change the image + file_path = get_svg_resource("tree_img_640x351.png") + im1 = ImageMobject(file_path) + im2 = im1.copy() + im1.rotate(PI / 2) + im1.rotate(-PI / 2) + np.testing.assert_array_equal(im1.points, im2.points) diff --git a/tests/test_graphical_units/test_indication.py b/tests/test_graphical_units/test_indication.py index f134f4e9c3..592cf5fb38 100644 --- a/tests/test_graphical_units/test_indication.py +++ b/tests/test_graphical_units/test_indication.py @@ -42,13 +42,6 @@ def test_ShowPassingFlash(scene): scene.play(ShowPassingFlash(square.copy())) -@frames_comparison(last_frame=False) -def test_ShowCreationThenFadeOut(scene): - square = Square() - scene.add(square) - scene.play(ShowCreationThenFadeOut(square.copy())) - - @frames_comparison(last_frame=False) def test_ApplyWave(scene): square = Square() @@ -61,3 +54,14 @@ def test_Wiggle(scene): square = Square() scene.add(square) scene.play(Wiggle(square)) + + +def test_Wiggle_custom_about_points(): + square = Square() + wiggle = Wiggle( + square, + scale_about_point=[1.0, 2.0, 3.0], + rotate_about_point=[4.0, 5.0, 6.0], + ) + assert wiggle.get_scale_about_point() == [1.0, 2.0, 3.0] + assert wiggle.get_rotate_about_point() == [4.0, 5.0, 6.0] diff --git a/tests/test_graphical_units/test_mobjects.py b/tests/test_graphical_units/test_mobjects.py index e5c531842d..c76c8599d7 100644 --- a/tests/test_graphical_units/test_mobjects.py +++ b/tests/test_graphical_units/test_mobjects.py @@ -15,18 +15,29 @@ def test_PointCloudDot(scene): @frames_comparison def test_become(scene): s = Rectangle(width=2, height=1, color=RED).shift(UP) - d1, d2, d3 = (Dot() for _ in range(3)) + d = Dot() - s1 = s.copy().become(d1, match_width=True).set_opacity(0.25).set_color(BLUE) + s1 = s.copy().become(d, match_width=True).set_opacity(0.25).set_color(BLUE) s2 = ( s.copy() - .become(d2, match_height=True, match_center=True) + .become(d, match_height=True, match_center=True) .set_opacity(0.25) .set_color(GREEN) ) - s3 = s.copy().become(d3, stretch=True).set_opacity(0.25).set_color(YELLOW) + s3 = s.copy().become(d, stretch=True).set_opacity(0.25).set_color(YELLOW) - scene.add(s, d1, d2, d3, s1, s2, s3) + scene.add(s, d, s1, s2, s3) + + +@frames_comparison +def test_become_no_color_linking(scene): + a = Circle() + b = Square() + scene.add(a) + scene.add(b) + b.become(a) + b.shift(1 * RIGHT) + b.set_stroke(YELLOW, opacity=1) @frames_comparison @@ -36,3 +47,39 @@ def test_match_style(scene): VGroup(square, circle).arrange() circle.match_style(square) scene.add(square, circle) + + +@frames_comparison +def test_vmobject_joint_types(scene): + angled_line = VMobject(stroke_width=20, color=GREEN).set_points_as_corners( + [ + np.array([-2, 0, 0]), + np.array([0, 0, 0]), + np.array([-2, 1, 0]), + ] + ) + lines = VGroup(*[angled_line.copy() for _ in range(len(LineJointType))]) + for line, joint_type in zip(lines, LineJointType): + line.joint_type = joint_type + + lines.arrange(RIGHT, buff=1) + scene.add(lines) + + +@frames_comparison +def test_vmobject_cap_styles(scene): + arcs = VGroup( + *[ + Arc( + radius=1, + start_angle=0, + angle=TAU / 4, + stroke_width=20, + color=GREEN, + cap_style=cap_style, + ) + for cap_style in CapStyleType + ] + ) + arcs.arrange(RIGHT, buff=1) + scene.add(arcs) diff --git a/tests/test_graphical_units/test_polyhedra.py b/tests/test_graphical_units/test_polyhedra.py index bc13676fde..9679bed3a1 100644 --- a/tests/test_graphical_units/test_polyhedra.py +++ b/tests/test_graphical_units/test_polyhedra.py @@ -24,3 +24,17 @@ def test_Icosahedron(scene): @frames_comparison def test_Dodecahedron(scene): scene.add(Dodecahedron()) + + +@frames_comparison +def test_ConvexHull3D(scene): + a = ConvexHull3D( + *[ + [-2.7, -0.6, 3.5], + [0.2, -1.7, -2.8], + [1.9, 1.2, 0.7], + [-2.7, 0.9, 1.9], + [1.6, 2.2, -4.2], + ] + ) + scene.add(a) diff --git a/tests/test_graphical_units/test_speed.py b/tests/test_graphical_units/test_speed.py new file mode 100644 index 0000000000..c95064ccaa --- /dev/null +++ b/tests/test_graphical_units/test_speed.py @@ -0,0 +1,36 @@ +from __future__ import annotations + +from manim import * +from manim.utils.testing.frames_comparison import frames_comparison + +__module_test__ = "speed" + + +@frames_comparison(last_frame=False) +def test_SpeedModifier(scene): + a = Dot().shift(LEFT * 2 + 0.5 * UP) + b = Dot().shift(LEFT * 2 + 0.5 * DOWN) + c = Dot().shift(2 * RIGHT) + ChangeSpeed.add_updater(c, lambda x, dt: x.rotate_about_origin(PI / 3.7 * dt)) + scene.add(a, b, c) + scene.play(ChangeSpeed(Wait(0.5), speedinfo={0.3: 1, 0.4: 0.1, 0.6: 0.1, 1: 1})) + scene.play( + ChangeSpeed( + AnimationGroup( + a.animate(run_time=0.5, rate_func=linear).shift(RIGHT * 4), + b.animate(run_time=0.5, rate_func=rush_from).shift(RIGHT * 4), + ), + speedinfo={0.3: 1, 0.4: 0.1, 0.6: 0.1, 1: 1}, + affects_speed_updaters=False, + ), + ) + scene.play( + ChangeSpeed( + AnimationGroup( + a.animate(run_time=0.5, rate_func=linear).shift(LEFT * 4), + b.animate(run_time=0.5, rate_func=rush_into).shift(LEFT * 4), + ), + speedinfo={0.3: 1, 0.4: 0.1, 0.6: 0.1, 1: 1}, + rate_func=there_and_back, + ), + ) diff --git a/tests/test_graphical_units/test_tex_mobject.py b/tests/test_graphical_units/test_tex_mobject.py index 82eb72b066..aabc8e01f9 100644 --- a/tests/test_graphical_units/test_tex_mobject.py +++ b/tests/test_graphical_units/test_tex_mobject.py @@ -1,5 +1,3 @@ -import pytest - from manim import * from manim.utils.testing.frames_comparison import frames_comparison @@ -9,8 +7,8 @@ @frames_comparison def test_color_inheritance(scene): """Test that Text and MarkupText correctly inherit colour from - their parent class.""" - + their parent class. + """ VMobject.set_default(color=RED) tex = Tex("test color inheritance") mathtex = MathTex("test color inheritance") @@ -18,3 +16,41 @@ def test_color_inheritance(scene): VMobject.set_default() scene.add(vgr) + + +@frames_comparison +def test_set_opacity_by_tex(scene): + """Test that set_opacity_by_tex works correctly.""" + tex = MathTex("f(x) = y", substrings_to_isolate=["f(x)"]) + tex.set_opacity_by_tex("f(x)", 0.2, 0.5) + scene.add(tex) + + +def test_preserve_tex_color(): + """Test that Tex preserves original tex colors.""" + template = TexTemplate(preamble=r"\usepackage{xcolor}") + Tex.set_default(tex_template=template) + + txt = Tex(r"\textcolor{red}{Hello} World") + assert len(txt[0].submobjects) == 10 + assert all(char.fill_color.to_hex() == "#FF0000" for char in txt[0][:5]) # "Hello" + assert all( + char.fill_color.to_hex() == WHITE.to_hex() for char in txt[0][-5:] + ) # "World" + + txt = Tex(r"\textcolor{red}{Hello} World", color=BLUE) + assert len(txt[0].submobjects) == 10 + assert all(char.fill_color.to_hex() == "#FF0000" for char in txt[0][:5]) # "Hello" + assert all( + char.fill_color.to_hex() == BLUE.to_hex() for char in txt[0][-5:] + ) # "World" + + Tex.set_default(color=GREEN) + txt = Tex(r"\textcolor{red}{Hello} World") + assert len(txt[0].submobjects) == 10 + assert all(char.fill_color.to_hex() == "#FF0000" for char in txt[0][:5]) # "Hello" + assert all( + char.fill_color.to_hex() == GREEN.to_hex() for char in txt[0][-5:] + ) # "World" + + Tex.set_default() diff --git a/tests/test_graphical_units/test_text.py b/tests/test_graphical_units/test_text.py index 4d319a27bd..7c75f8b995 100644 --- a/tests/test_graphical_units/test_text.py +++ b/tests/test_graphical_units/test_text.py @@ -1,35 +1,34 @@ -import pytest - -from manim import * -from manim.utils.testing.frames_comparison import frames_comparison +from manim import RED, MarkupText, Text, VMobject __module_test__ = "text" -@pytest.mark.skipif( - not sys.platform.startswith("linux"), - reason="MacOS and Windows render fonts differently, so they need separate comparison data.", -) -@frames_comparison -def test_Text2Color(scene): - scene.add(Text("this is a text with spaces!", t2c={"spaces": RED})) +def test_Text2Color(): + txt = Text( + "this is a text with spaces!", + t2c={"spaces": RED}, + stroke_width=1, + disable_ligatures=True, + ) + assert len(txt.submobjects) == 29 + assert all(char.fill_color.to_hex() == "#FFFFFF" for char in txt[:4]) # "this" + assert all( + char.fill_color.to_hex() == RED.to_hex() for char in txt[-7:-1] + ) # "spaces" + assert txt[-1].fill_color.to_hex() == "#FFFFFF" # "!" -@pytest.mark.skipif( - not sys.platform.startswith("linux"), - reason="MacOS and Windows render fonts differently, so they need separate comparison data.", -) -@frames_comparison -def test_text_color_inheritance(scene): +def test_text_color_inheritance(): """Test that Text and MarkupText correctly inherit colour from - their parent class.""" + their parent class. + """ VMobject.set_default(color=RED) # set both to a singular font so that the tests agree. - text = Text("test_color_inheritance", font="Dejavu Sans") - markup_text = MarkupText("test_color_inheritance", font="Dejavu Sans") - vgr = VGroup(text, markup_text).arrange() + text = Text("test_color_inheritance", font="Sans") + markup_text = MarkupText("test_color_inheritance", font="Sans") + + assert all(char.fill_color.to_hex() == RED.to_hex() for char in text) + assert all(char.fill_color.to_hex() == RED.to_hex() for char in markup_text) # reset the default color so that future tests aren't affected by this change. VMobject.set_default() - - scene.add(vgr) diff --git a/tests/test_graphical_units/test_threed.py b/tests/test_graphical_units/test_threed.py index 719f0374b1..dc52b0dd9e 100644 --- a/tests/test_graphical_units/test_threed.py +++ b/tests/test_graphical_units/test_threed.py @@ -30,7 +30,19 @@ def test_Dot3D(scene): @frames_comparison(base_scene=ThreeDScene) def test_Cone(scene): - scene.add(Cone()) + scene.add(Cone(resolution=16)) + + +def test_Cone_get_start_and_get_end(): + cone = Cone().shift(RIGHT).rotate(PI / 4, about_point=ORIGIN, about_edge=OUT) + start = [0.70710678, 0.70710678, -1.0] + end = [0.70710678, 0.70710678, 0.0] + assert np.allclose(cone.get_start(), start, atol=0.01), ( + "start points of Cone do not match" + ) + assert np.allclose(cone.get_end(), end, atol=0.01), ( + "end points of Cone do not match" + ) @frames_comparison(base_scene=ThreeDScene) @@ -40,15 +52,16 @@ def test_Cylinder(scene): @frames_comparison(base_scene=ThreeDScene) def test_Line3D(scene): - line1, line2 = Line3D().shift(LEFT * 2), Line3D().shift(RIGHT * 2) - perp_line = Line3D.perpendicular_to(line1, UP + OUT) - parallel_line = Line3D.parallel_to(line2, DOWN + IN) + line1 = Line3D(resolution=16).shift(LEFT * 2) + line2 = Line3D(resolution=16).shift(RIGHT * 2) + perp_line = Line3D.perpendicular_to(line1, UP + OUT, resolution=16) + parallel_line = Line3D.parallel_to(line2, DOWN + IN, resolution=16) scene.add(line1, line2, perp_line, parallel_line) @frames_comparison(base_scene=ThreeDScene) def test_Arrow3D(scene): - scene.add(Arrow3D()) + scene.add(Arrow3D(resolution=16)) @frames_comparison(base_scene=ThreeDScene) @@ -103,7 +116,7 @@ def test_MovingVertices(scene): @frames_comparison(base_scene=ThreeDScene) def test_SurfaceColorscale(scene): - resolution_fa = 50 + resolution_fa = 16 scene.set_camera_orientation(phi=75 * DEGREES, theta=-30 * DEGREES) axes = ThreeDAxes(x_range=(-3, 3, 1), y_range=(-3, 3, 1), z_range=(-4, 4, 1)) @@ -119,13 +132,15 @@ def param_trig(u, v): v_range=[-3, 3], u_range=[-3, 3], ) - trig_plane.set_fill_by_value(axes=axes, colors=[BLUE, GREEN, YELLOW, ORANGE, RED]) + trig_plane.set_fill_by_value( + axes=axes, colorscale=[BLUE, GREEN, YELLOW, ORANGE, RED] + ) scene.add(axes, trig_plane) @frames_comparison(base_scene=ThreeDScene) def test_Y_Direction(scene): - resolution_fa = 42 + resolution_fa = 16 scene.set_camera_orientation(phi=75 * DEGREES, theta=-120 * DEGREES) axes = ThreeDAxes(x_range=(0, 5, 1), y_range=(0, 5, 1), z_range=(-1, 1, 0.5)) @@ -143,6 +158,17 @@ def param_surface(u, v): ) surface_plane.set_style(fill_opacity=1) surface_plane.set_fill_by_value( - axes=axes, colors=[(RED, -0.4), (YELLOW, 0), (GREEN, 0.4)], axis=1 + axes=axes, colorscale=[(RED, -0.4), (YELLOW, 0), (GREEN, 0.4)], axis=1 ) scene.add(axes, surface_plane) + + +def test_get_start_and_end_Arrow3d(): + start, end = ORIGIN, np.array([2, 1, 0]) + arrow = Arrow3D(start, end) + assert np.allclose(arrow.get_start(), start, atol=0.01), ( + "start points of Arrow3D do not match" + ) + assert np.allclose(arrow.get_end(), end, atol=0.01), ( + "end points of Arrow3D do not match" + ) diff --git a/tests/test_graphical_units/test_transform.py b/tests/test_graphical_units/test_transform.py index aa13c3dcc9..b2a34af5c2 100644 --- a/tests/test_graphical_units/test_transform.py +++ b/tests/test_graphical_units/test_transform.py @@ -159,7 +159,100 @@ def test_AnimationBuilder(scene): @frames_comparison(last_frame=False) def test_ReplacementTransform(scene): - v1 = Vector() - v2 = Vector() - v3 = Line() - scene.play(ReplacementTransform(VGroup(v1, v2), v3)) + yellow = Square(fill_opacity=1.0, fill_color=YELLOW) + yellow.move_to([0, 0.75, 0]) + + green = Square(fill_opacity=1.0, fill_color=GREEN) + green.move_to([-0.75, 0, 0]) + + blue = Square(fill_opacity=1.0, fill_color=BLUE) + blue.move_to([0.75, 0, 0]) + + orange = Square(fill_opacity=1.0, fill_color=ORANGE) + orange.move_to([0, -0.75, 0]) + + scene.add(yellow) + scene.add(VGroup(green, blue)) + scene.add(orange) + + purple = Circle(fill_opacity=1.0, fill_color=PURPLE) + purple.move_to(green) + + scene.play(ReplacementTransform(green, purple)) + # This pause is important to verify the purple circle remains behind + # the blue and orange squares, and the blue square remains behind the + # orange square after the transform fully completes. + scene.pause() + + +@frames_comparison(last_frame=False) +def test_TransformWithPathFunc(scene): + dots_start = VGroup(*[Dot(LEFT, color=BLUE), Dot(3 * RIGHT, color=RED)]) + dots_end = VGroup(*[Dot(LEFT + 2 * DOWN, color=BLUE), Dot(2 * UP, color=RED)]) + scene.play(Transform(dots_start, dots_end, path_func=clockwise_path())) + + +@frames_comparison(last_frame=False) +def test_TransformWithPathArcCenters(scene): + dots_start = VGroup(*[Dot(LEFT, color=BLUE), Dot(3 * RIGHT, color=RED)]) + dots_end = VGroup(*[Dot(LEFT + 2 * DOWN, color=BLUE), Dot(2 * UP, color=RED)]) + scene.play( + Transform( + dots_start, + dots_end, + path_arc=2 * PI, + path_arc_centers=ORIGIN, + ) + ) + + +@frames_comparison(last_frame=False) +def test_TransformWithConflictingPaths(scene): + dots_start = VGroup(*[Dot(LEFT, color=BLUE), Dot(3 * RIGHT, color=RED)]) + dots_end = VGroup(*[Dot(LEFT + 2 * DOWN, color=BLUE), Dot(2 * UP, color=RED)]) + scene.play( + Transform( + dots_start, + dots_end, + path_func=clockwise_path(), + path_arc=2 * PI, + path_arc_centers=ORIGIN, + ) + ) + + +@frames_comparison(last_frame=False) +def test_FadeTransformPieces(scene): + src = VGroup(Square(), Circle().shift(LEFT + UP)) + src.shift(3 * LEFT) + + target = VGroup(Circle(), Triangle().shift(RIGHT + DOWN)) + target.shift(3 * RIGHT) + + scene.add(src) + scene.play(FadeTransformPieces(src, target)) + + +@frames_comparison(last_frame=False) +def test_FadeTransform(scene): + src = Square(fill_opacity=1.0) + src.shift(3 * LEFT) + + target = Circle(fill_opacity=1.0, color=ORANGE) + target.shift(3 * RIGHT) + + scene.add(src) + scene.play(FadeTransform(src, target)) + + +@frames_comparison(last_frame=False) +def test_FadeTransform_TargetIsEmpty_FadesOutInPlace(scene): + # https://github.com/ManimCommunity/manim/issues/2845 + src = Square(fill_opacity=1.0) + src.shift(3 * LEFT) + + target = VGroup() + target.shift(3 * RIGHT) + + scene.add(src) + scene.play(FadeTransform(src, target)) diff --git a/tests/test_graphical_units/test_transform_matching_parts.py b/tests/test_graphical_units/test_transform_matching_parts.py new file mode 100644 index 0000000000..3694f51bee --- /dev/null +++ b/tests/test_graphical_units/test_transform_matching_parts.py @@ -0,0 +1,65 @@ +from __future__ import annotations + +from manim import * +from manim.utils.testing.frames_comparison import frames_comparison + +__module_test__ = "transform_matching_parts" + + +@frames_comparison(last_frame=True) +def test_TransformMatchingLeavesOneObject(scene): + square = Square() + circle = Circle().shift(RIGHT) + scene.add(square) + scene.play(TransformMatchingShapes(square, circle)) + assert len(scene.mobjects) == 1 + assert isinstance(scene.mobjects[0], Circle) + + +@frames_comparison(last_frame=False) +def test_TransformMatchingDisplaysCorrect(scene): + square = Square() + circle = Circle().shift(RIGHT) + scene.add(square) + scene.play(TransformMatchingShapes(square, circle)) + # Wait to make sure object isn't missing in-between animations + scene.wait(0.5) + # Shift to make sure object isn't duplicated if moved + scene.play(circle.animate.shift(DOWN)) + + +@frames_comparison(last_frame=False) +def test_TransformMatchingTex(scene): + start = MathTex("A", "+", "B", "=", "C") + end = MathTex("C", "=", "B", "-", "A") + + scene.add(start) + scene.play(TransformMatchingTex(start, end)) + + +@frames_comparison(last_frame=False) +def test_TransformMatchingTex_FadeTransformMismatches(scene): + start = MathTex("A", "+", "B", "=", "C") + end = MathTex("C", "=", "B", "-", "A") + + scene.add(start) + scene.play(TransformMatchingTex(start, end, fade_transform_mismatches=True)) + + +@frames_comparison(last_frame=False) +def test_TransformMatchingTex_TransformMismatches(scene): + start = MathTex("A", "+", "B", "=", "C") + end = MathTex("C", "=", "B", "-", "A") + + scene.add(start) + scene.play(TransformMatchingTex(start, end, transform_mismatches=True)) + + +@frames_comparison(last_frame=False) +def test_TransformMatchingTex_FadeTransformMismatches_NothingToFade(scene): + # https://github.com/ManimCommunity/manim/issues/2845 + start = MathTex("A", r"\to", "B") + end = MathTex("B", r"\to", "A") + + scene.add(start) + scene.play(TransformMatchingTex(start, end, fade_transform_mismatches=True)) diff --git a/tests/test_graphical_units/test_utils.py b/tests/test_graphical_units/test_utils.py new file mode 100644 index 0000000000..12ed860bc1 --- /dev/null +++ b/tests/test_graphical_units/test_utils.py @@ -0,0 +1,11 @@ +from __future__ import annotations + +from manim.utils.testing.frames_comparison import frames_comparison + +__module_test__ = "utils" + + +@frames_comparison +def test_pixel_error_threshold(scene): + """Scene produces black frame, control data has 11 modified pixel values.""" + pass diff --git a/tests/test_graphical_units/test_vector_scene.py b/tests/test_graphical_units/test_vector_scene.py index 59dfda44a9..75bc1806d1 100644 --- a/tests/test_graphical_units/test_vector_scene.py +++ b/tests/test_graphical_units/test_vector_scene.py @@ -1,6 +1,6 @@ from __future__ import annotations -from manim.scene.vector_space_scene import VectorScene +from manim.scene.vector_space_scene import LinearTransformationScene, VectorScene from manim.utils.testing.frames_comparison import frames_comparison __module_test__ = "vector_scene" @@ -14,3 +14,13 @@ def test_vector_to_coords(scene): scene.add(basis) scene.vector_to_coords(vector=vector) scene.wait() + + +def test_apply_matrix(): + scene = LinearTransformationScene(include_background_plane=False) + scene.setup() + matrix = [[-1, 1], [1, 1]] + # use short runtimes to speed up animation rendering + scene.apply_matrix(matrix, run_time=0.01) + scene.wait() + scene.apply_inverse(matrix, run_time=0.01) diff --git a/tests/test_ipython_magic.py b/tests/test_ipython_magic.py index b3bff2450c..6452d58de5 100644 --- a/tests/test_ipython_magic.py +++ b/tests/test_ipython_magic.py @@ -2,30 +2,29 @@ import re -from manim import tempconfig from manim.utils.ipython_magic import _generate_file_name -def test_jupyter_file_naming(): +def test_jupyter_file_naming(config): """Check the format of file names for jupyter""" scene_name = "SimpleScene" expected_pattern = r"[0-9a-zA-Z_]+[@_-]\d\d\d\d-\d\d-\d\d[@_-]\d\d-\d\d-\d\d" - with tempconfig({"scene_names": [scene_name]}): - file_name = _generate_file_name() - match = re.match(expected_pattern, file_name) - assert scene_name in file_name, ( - "Expected file to contain " + scene_name + " but got " + file_name - ) - assert match, "file name does not match expected pattern " + expected_pattern + config.scene_names = [scene_name] + file_name = _generate_file_name() + match = re.match(expected_pattern, file_name) + assert scene_name in file_name, ( + "Expected file to contain " + scene_name + " but got " + file_name + ) + assert match, "file name does not match expected pattern " + expected_pattern -def test_jupyter_file_output(tmp_path): +def test_jupyter_file_output(tmp_path, config): """Check the jupyter file naming is valid and can be created""" scene_name = "SimpleScene" - with tempconfig({"scene_names": [scene_name]}): - file_name = _generate_file_name() - actual_path = tmp_path.with_name(file_name) - with open(actual_path, "w") as outfile: - outfile.write("") - assert actual_path.exists() - assert actual_path.is_file() + config.scene_names = [scene_name] + file_name = _generate_file_name() + actual_path = tmp_path.with_name(file_name) + with actual_path.open("w") as outfile: + outfile.write("") + assert actual_path.exists() + assert actual_path.is_file() diff --git a/tests/test_linear_transformation_scene.py b/tests/test_linear_transformation_scene.py new file mode 100644 index 0000000000..d0592b8f44 --- /dev/null +++ b/tests/test_linear_transformation_scene.py @@ -0,0 +1,25 @@ +from manim import RIGHT, UP, LinearTransformationScene, Vector, VGroup + +__module_test__ = "vector_space_scene" + + +def test_ghost_vectors_len_and_types(): + scene = LinearTransformationScene() + scene.leave_ghost_vectors = True + + # prepare vectors (they require a vmobject as their target) + v1, v2 = Vector(RIGHT), Vector(RIGHT) + v1.target, v2.target = Vector(UP), Vector(UP) + + # ghost_vector addition is in this method + scene.get_piece_movement((v1, v2)) + + ghosts = scene.get_ghost_vectors() + assert len(ghosts) == 1 + # check if there are two vectors in the ghost vector VGroup + assert len(ghosts[0]) == 2 + + # check types of ghost vectors + assert isinstance(ghosts, VGroup) + assert isinstance(ghosts[0], VGroup) + assert all(isinstance(x, Vector) for x in ghosts[0]) diff --git a/tests/test_logging/test_logging.py b/tests/test_logging/test_logging.py index e56c01a69e..397573a51e 100644 --- a/tests/test_logging/test_logging.py +++ b/tests/test_logging/test_logging.py @@ -1,6 +1,5 @@ from __future__ import annotations -import os from pathlib import Path from manim import capture @@ -10,14 +9,10 @@ @logs_comparison( "BasicSceneLoggingTest.txt", - os.path.join("logs", "basic_scenes_square_to_circle_SquareToCircle.log"), + "logs/basic_scenes_square_to_circle_SquareToCircle.log", ) def test_logging_to_file(tmp_path, python_version): - path_basic_scene = os.path.join( - "tests", - "test_logging", - "basic_scenes_square_to_circle.py", - ) + path_basic_scene = Path("tests/test_logging/basic_scenes_square_to_circle.py") command = [ python_version, "-m", @@ -28,39 +23,13 @@ def test_logging_to_file(tmp_path, python_version): "--log_to_file", "--media_dir", str(tmp_path), - path_basic_scene, + str(path_basic_scene), "SquareToCircle", ] _, err, exitcode = capture(command) assert exitcode == 0, err -@logs_comparison( - "BasicSceneLoggingTest.txt", - os.path.join("logs", "basic_scenes_square_to_circle.log"), -) -def test_logging_when_scene_is_not_specified(tmp_path, python_version): - path_basic_scene = os.path.join( - "tests", - "test_logging", - "basic_scenes_square_to_circle.py", - ) - command = [ - python_version, - "-m", - "manim", - "-ql", - "-v", - "DEBUG", - "--log_to_file", - "--media_dir", - str(tmp_path), - path_basic_scene, - ] - _, err, exitcode = capture(command) - assert exitcode == 0, err - - def test_error_logging(tmp_path, python_version): path_error_scene = Path("tests/test_logging/basic_scenes_error.py") @@ -74,16 +43,19 @@ def test_error_logging(tmp_path, python_version): str(path_error_scene), ] - _, err, exitcode = capture(command) - assert exitcode != 0 and len(err) > 0 + out, err, exitcode = capture(command) + if err is None: + err = out + assert exitcode != 0 + assert "Traceback (most recent call last)" in err @logs_comparison( "bad_tex_scene_BadTex.txt", - Path("logs/bad_tex_scene_BadTex.log"), + "logs/bad_tex_scene_BadTex.log", ) def test_tex_error_logs(tmp_path, python_version): - bad_tex_scene = os.path.join("tests", "test_logging", "bad_tex_scene.py") + bad_tex_scene = Path("tests/test_logging/bad_tex_scene.py") command = [ python_version, "-m", @@ -94,8 +66,9 @@ def test_tex_error_logs(tmp_path, python_version): "INFO", "--media_dir", str(tmp_path), - bad_tex_scene, + str(bad_tex_scene), "BadTex", ] _, err, exitcode = capture(command) - assert exitcode != 0 and len(err) > 0 + assert exitcode != 0 + assert len(err) > 0 diff --git a/tests/test_mobject.py b/tests/test_mobject.py deleted file mode 100644 index 7ce936c029..0000000000 --- a/tests/test_mobject.py +++ /dev/null @@ -1,51 +0,0 @@ -from __future__ import annotations - -import pytest - -from manim import Mobject - - -def test_mobject_add(): - """Test Mobject.add().""" - """Call this function with a Container instance to test its add() method.""" - # check that obj.submobjects is updated correctly - obj = Mobject() - assert len(obj.submobjects) == 0 - obj.add(Mobject()) - assert len(obj.submobjects) == 1 - obj.add(*(Mobject() for _ in range(10))) - assert len(obj.submobjects) == 11 - - # check that adding a mobject twice does not actually add it twice - repeated = Mobject() - obj.add(repeated) - assert len(obj.submobjects) == 12 - obj.add(repeated) - assert len(obj.submobjects) == 12 - - # check that Mobject.add() returns the Mobject (for chained calls) - assert obj.add(Mobject()) is obj - obj = Mobject() - - # a Mobject cannot contain itself - with pytest.raises(ValueError): - obj.add(obj) - - # can only add Mobjects - with pytest.raises(TypeError): - obj.add("foo") - - -def test_mobject_remove(): - """Test Mobject.remove().""" - obj = Mobject() - to_remove = Mobject() - obj.add(to_remove) - obj.add(*(Mobject() for _ in range(10))) - assert len(obj.submobjects) == 11 - obj.remove(to_remove) - assert len(obj.submobjects) == 10 - obj.remove(to_remove) - assert len(obj.submobjects) == 10 - - assert obj.remove(Mobject()) is obj diff --git a/tests/test_opengl_metaclass.py b/tests/test_opengl_metaclass.py deleted file mode 100644 index bc172bfa38..0000000000 --- a/tests/test_opengl_metaclass.py +++ /dev/null @@ -1,20 +0,0 @@ -from __future__ import annotations - -from manim import Mobject, config, tempconfig -from manim.mobject.opengl.opengl_compatibility import ConvertToOpenGL -from manim.mobject.opengl.opengl_mobject import OpenGLMobject - - -def test_metaclass_registry(): - class SomeTestMobject(Mobject, metaclass=ConvertToOpenGL): - pass - - assert SomeTestMobject in ConvertToOpenGL._converted_classes - - with tempconfig({"renderer": "opengl"}): - assert OpenGLMobject in SomeTestMobject.__bases__ - assert Mobject not in SomeTestMobject.__bases__ - - config.renderer = "cairo" - assert Mobject in SomeTestMobject.__bases__ - assert OpenGLMobject not in SomeTestMobject.__bases__ diff --git a/tests/test_plugins/simple_scenes.py b/tests/test_plugins/simple_scenes.py index 1562196119..e22085123e 100644 --- a/tests/test_plugins/simple_scenes.py +++ b/tests/test_plugins/simple_scenes.py @@ -8,17 +8,3 @@ def construct(self): square = Square() circle = Circle() self.play(Transform(square, circle)) - - -class FunctionLikeTest(Scene): - def construct(self): - assert "FunctionLike" in globals() - a = FunctionLike() - self.play(FadeIn(a)) - - -class WithAllTest(Scene): - def construct(self): - assert "WithAll" in globals() - a = WithAll() - self.play(FadeIn(a)) diff --git a/tests/test_plugins/test_plugins.py b/tests/test_plugins/test_plugins.py index 149d705410..d5fc0a01f2 100644 --- a/tests/test_plugins/test_plugins.py +++ b/tests/test_plugins/test_plugins.py @@ -2,7 +2,6 @@ import random import string -import tempfile import textwrap from pathlib import Path @@ -12,21 +11,19 @@ plugin_pyproject_template = textwrap.dedent( """\ - [tool.poetry] + [project] name = "{plugin_name}" - authors = ["ManimCE Test Suite"] + authors = [{name = "ManimCE Test Suite"},] version = "0.1.0" - description = "" + description = "A fantastic Manim plugin" + requires-python = ">=3.9" - [tool.poetry.dependencies] - python = "^3.7" - - [tool.poetry.plugins."manim.plugins"] + [project.entry-points."manim.plugins"] "{plugin_name}" = "{plugin_entrypoint}" [build-system] - requires = ["poetry-core>=1.0.0"] - build-backend = "poetry.core.masonry.api" + requires = ["hatchling"] + build-backend = "hatchling.build" """, ) @@ -60,13 +57,12 @@ def {function_name}(): @pytest.fixture def simple_scenes_path(): - yield str(Path(__file__).parent / "simple_scenes.py") + return Path(__file__).parent / "simple_scenes.py" def cfg_file_create(cfg_file_contents, path): file_loc = (path / "manim.cfg").absolute() - with open(file_loc, "w") as f: - f.write(cfg_file_contents) + file_loc.write_text(cfg_file_contents) return file_loc @@ -75,7 +71,7 @@ def random_string(): all_letters = string.ascii_lowercase a = random.Random() final_letters = [a.choice(all_letters) for _ in range(8)] - yield "".join(final_letters) + return "".join(final_letters) def test_plugin_warning(tmp_path, python_version, simple_scenes_path): @@ -93,7 +89,7 @@ def test_plugin_warning(tmp_path, python_version, simple_scenes_path): str(cfg_file.parent), "--config_file", str(cfg_file), - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command, cwd=str(cfg_file.parent)) @@ -110,21 +106,19 @@ def _create_plugin(entry_point, class_name, function_name, all_dec=""): entry_point = entry_point.format(plugin_name=plugin_name) module_dir = plugin_dir / plugin_name module_dir.mkdir(parents=True) - with open(module_dir / "__init__.py", "w") as f: - f.write( - plugin_init_template.format( - class_name=class_name, - function_name=function_name, - all_dec=all_dec, - ), - ) - with open(plugin_dir / "pyproject.toml", "w") as f: - f.write( - plugin_pyproject_template.format( - plugin_name=plugin_name, - plugin_entrypoint=entry_point, - ), - ) + (module_dir / "__init__.py").write_text( + plugin_init_template.format( + class_name=class_name, + function_name=function_name, + all_dec=all_dec, + ), + ) + (plugin_dir / "pyproject.toml").write_text( + plugin_pyproject_template.format( + plugin_name=plugin_name, + plugin_entrypoint=entry_point, + ), + ) command = [ python_version, "-m", @@ -145,116 +139,3 @@ def _create_plugin(entry_point, class_name, function_name, all_dec=""): out, err, exit_code = capture(command) print(out) assert exit_code == 0, err - - -@pytest.mark.slow -def test_plugin_function_like( - tmp_path, - create_plugin, - python_version, - simple_scenes_path, -): - function_like_plugin = create_plugin( - "{plugin_name}.__init__:import_all", - "FunctionLike", - "import_all", - ) - cfg_file = cfg_file_create( - cfg_file_contents.format(plugin_name=function_like_plugin["plugin_name"]), - tmp_path, - ) - scene_name = "FunctionLikeTest" - command = [ - python_version, - "-m", - "manim", - "-ql", - "--media_dir", - str(cfg_file.parent), - "--config_file", - str(cfg_file), - simple_scenes_path, - scene_name, - ] - out, err, exit_code = capture(command, cwd=str(cfg_file.parent)) - print(out) - print(err) - assert exit_code == 0, err - - -@pytest.mark.slow -def test_plugin_no_all(tmp_path, create_plugin, python_version): - create_plugin = create_plugin("{plugin_name}", "NoAll", "import_all") - plugin_name = create_plugin["plugin_name"] - cfg_file = cfg_file_create( - cfg_file_contents.format(plugin_name=plugin_name), - tmp_path, - ) - test_class = textwrap.dedent( - f"""\ - from manim import * - class NoAllTest(Scene): - def construct(self): - assert "{plugin_name}" in globals() - a = {plugin_name}.NoAll() - self.play(FadeIn(a)) - """, - ) - - with tempfile.NamedTemporaryFile( - mode="w", - encoding="utf-8", - suffix=".py", - delete=False, - ) as tmpfile: - tmpfile.write(test_class) - scene_name = "NoAllTest" - command = [ - python_version, - "-m", - "manim", - "-ql", - "--media_dir", - str(cfg_file.parent), - "--config_file", - str(cfg_file), - tmpfile.name, - scene_name, - ] - out, err, exit_code = capture(command, cwd=str(cfg_file.parent)) - print(out) - print(err) - assert exit_code == 0, err - Path(tmpfile.name).unlink() - - -@pytest.mark.slow -def test_plugin_with_all(tmp_path, create_plugin, python_version, simple_scenes_path): - create_plugin = create_plugin( - "{plugin_name}", - "WithAll", - "import_all", - all_dec="__all__=['WithAll']", - ) - plugin_name = create_plugin["plugin_name"] - cfg_file = cfg_file_create( - cfg_file_contents.format(plugin_name=plugin_name), - tmp_path, - ) - scene_name = "WithAllTest" - command = [ - python_version, - "-m", - "manim", - "-ql", - "--media_dir", - str(cfg_file.parent), - "--config_file", - str(cfg_file), - simple_scenes_path, - scene_name, - ] - out, err, exit_code = capture(command, cwd=str(cfg_file.parent)) - print(out) - print(err) - assert exit_code == 0, err diff --git a/tests/test_scene.py b/tests/test_scene.py deleted file mode 100644 index b62f0cd24c..0000000000 --- a/tests/test_scene.py +++ /dev/null @@ -1,75 +0,0 @@ -from __future__ import annotations - -import datetime - -import pytest - -from manim import Circle, FadeIn, Mobject, Scene, Square, tempconfig -from manim.animation.animation import Wait - - -def test_scene_add_remove(): - with tempconfig({"dry_run": True}): - scene = Scene() - assert len(scene.mobjects) == 0 - scene.add(Mobject()) - assert len(scene.mobjects) == 1 - scene.add(*(Mobject() for _ in range(10))) - assert len(scene.mobjects) == 11 - - # Check that adding a mobject twice does not actually add it twice - repeated = Mobject() - scene.add(repeated) - assert len(scene.mobjects) == 12 - scene.add(repeated) - assert len(scene.mobjects) == 12 - - # Check that Scene.add() returns the Scene (for chained calls) - assert scene.add(Mobject()) is scene - to_remove = Mobject() - scene = Scene() - scene.add(to_remove) - scene.add(*(Mobject() for _ in range(10))) - assert len(scene.mobjects) == 11 - scene.remove(to_remove) - assert len(scene.mobjects) == 10 - scene.remove(to_remove) - assert len(scene.mobjects) == 10 - - # Check that Scene.remove() returns the instance (for chained calls) - assert scene.add(Mobject()) is scene - - -def test_scene_time(): - with tempconfig({"dry_run": True}): - scene = Scene() - assert scene.renderer.time == 0 - scene.wait(2) - assert scene.renderer.time == 2 - scene.play(FadeIn(Circle()), run_time=0.5) - assert pytest.approx(scene.renderer.time) == 2.5 - scene.renderer._original_skipping_status = True - scene.play(FadeIn(Square()), run_time=5) # this animation gets skipped. - assert pytest.approx(scene.renderer.time) == 7.5 - - -def test_subcaption(): - with tempconfig({"dry_run": True}): - scene = Scene() - scene.add_subcaption("Testing add_subcaption", duration=1, offset=0) - scene.wait() - scene.play( - Wait(), - run_time=2, - subcaption="Testing Scene.play subcaption interface", - subcaption_duration=1.5, - subcaption_offset=0.5, - ) - subcaptions = scene.renderer.file_writer.subcaptions - assert len(subcaptions) == 2 - assert subcaptions[0].start == datetime.timedelta(seconds=0) - assert subcaptions[0].end == datetime.timedelta(seconds=1) - assert subcaptions[0].content == "Testing add_subcaption" - assert subcaptions[1].start == datetime.timedelta(seconds=1.5) - assert subcaptions[1].end == datetime.timedelta(seconds=3) - assert subcaptions[1].content == "Testing Scene.play subcaption interface" diff --git a/tests/test_scene_rendering/click.mp3 b/tests/test_scene_rendering/click.mp3 new file mode 100644 index 0000000000..8abc5221dd Binary files /dev/null and b/tests/test_scene_rendering/click.mp3 differ diff --git a/tests/test_scene_rendering/conftest.py b/tests/test_scene_rendering/conftest.py index 9748edab03..7263a3f37c 100644 --- a/tests/test_scene_rendering/conftest.py +++ b/tests/test_scene_rendering/conftest.py @@ -4,64 +4,51 @@ import pytest -from manim import config, tempconfig - @pytest.fixture def manim_cfg_file(): - return str(Path(__file__).parent / "manim.cfg") + return Path(__file__).parent / "manim.cfg" @pytest.fixture def simple_scenes_path(): - return str(Path(__file__).parent / "simple_scenes.py") + return Path(__file__).parent / "simple_scenes.py" @pytest.fixture -def using_temp_config(tmpdir): - """Standard fixture that makes tests use a standard_config.cfg with a temp dir.""" - with tempconfig( - config.digest_file(Path(__file__).parent.parent / "standard_config.cfg"), - ): - config.media_dir = tmpdir - yield +def standard_config(config): + return config.digest_file(Path(__file__).parent.parent / "standard_config.cfg") @pytest.fixture -def using_temp_opengl_config(tmpdir): +def using_temp_config(tmpdir, standard_config): """Standard fixture that makes tests use a standard_config.cfg with a temp dir.""" - with tempconfig( - config.digest_file(Path(__file__).parent.parent / "standard_config.cfg"), - ): - config.media_dir = tmpdir - config.renderer = "opengl" - yield + standard_config.media_dir = tmpdir @pytest.fixture -def disabling_caching(): - with tempconfig({"disable_caching": True}): - yield +def using_temp_opengl_config(tmpdir, standard_config, using_opengl_renderer): + """Standard fixture that makes tests use a standard_config.cfg with a temp dir.""" + standard_config.media_dir = tmpdir @pytest.fixture -def infallible_scenes_path(): - return str(Path(__file__).parent / "infallible_scenes.py") +def disabling_caching(config): + config.disable_caching = True @pytest.fixture -def use_opengl_renderer(enable_preview): - with tempconfig({"renderer": "opengl", "preview": enable_preview}): - yield +def infallible_scenes_path(): + return Path(__file__).parent / "infallible_scenes.py" @pytest.fixture -def force_window_config_write_to_movie(): - with tempconfig({"force_window": True, "write_to_movie": True}): - yield +def force_window_config_write_to_movie(config): + config.force_window = True + config.write_to_movie = True @pytest.fixture -def force_window_config_pngs(): - with tempconfig({"force_window": True, "format": "png"}): - yield +def force_window_config_pngs(config): + config.force_window = True + config.format = "png" diff --git a/tests/test_scene_rendering/infallible_scenes.py b/tests/test_scene_rendering/infallible_scenes.py index b9f1e1ca0a..07290128ae 100644 --- a/tests/test_scene_rendering/infallible_scenes.py +++ b/tests/test_scene_rendering/infallible_scenes.py @@ -1,6 +1,6 @@ from __future__ import annotations -from manim import * +from manim import Scene, Square class Wait1(Scene): @@ -9,5 +9,10 @@ def construct(self): class Wait2(Scene): + def construct(self): + self.add(Square()) + + +class Wait3(Scene): def construct(self): self.wait(2) diff --git a/tests/test_scene_rendering/opengl/test_caching_related_opengl.py b/tests/test_scene_rendering/opengl/test_caching_related_opengl.py index 3bc5179574..c9c82a449b 100644 --- a/tests/test_scene_rendering/opengl/test_caching_related_opengl.py +++ b/tests/test_scene_rendering/opengl/test_caching_related_opengl.py @@ -29,7 +29,7 @@ def test_wait_skip(tmp_path, manim_cfg_file, simple_scenes_path): str(tmp_path), "-n", "3", - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) @@ -56,7 +56,7 @@ def test_play_skip(tmp_path, manim_cfg_file, simple_scenes_path): str(tmp_path), "-n", "3", - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) diff --git a/tests/test_scene_rendering/opengl/test_cli_flags_opengl.py b/tests/test_scene_rendering/opengl/test_cli_flags_opengl.py index 2d38bc58b5..17f6f35e38 100644 --- a/tests/test_scene_rendering/opengl/test_cli_flags_opengl.py +++ b/tests/test_scene_rendering/opengl/test_cli_flags_opengl.py @@ -1,6 +1,5 @@ from __future__ import annotations -import os import sys import numpy as np @@ -9,7 +8,7 @@ from PIL import Image from manim import capture, get_video_metadata -from manim.__main__ import main +from manim.__main__ import __version__, main from manim.utils.file_ops import add_version_before_extension from tests.utils.video_tester import video_comparison @@ -30,7 +29,7 @@ def test_basic_scene_with_default_values(tmp_path, manim_cfg_file, simple_scenes "--write_to_movie", "--media_dir", str(tmp_path), - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) @@ -51,7 +50,7 @@ def test_resolution_flag(tmp_path, manim_cfg_file, simple_scenes_path): # (800, 600, ";"), ] - for (width, height, separator) in resolutions: + for width, height, separator in resolutions: command = [ sys.executable, "-m", @@ -91,7 +90,7 @@ def test_basic_scene_l_flag(tmp_path, manim_cfg_file, simple_scenes_path): "--write_to_movie", "--media_dir", str(tmp_path), - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) @@ -116,7 +115,7 @@ def test_n_flag(tmp_path, simple_scenes_path): "-n 3,6", "--media_dir", str(tmp_path), - simple_scenes_path, + str(simple_scenes_path), scene_name, ] _, err, exit_code = capture(command) @@ -136,7 +135,7 @@ def test_s_flag_no_animations(tmp_path, manim_cfg_file, simple_scenes_path): "-s", "--media_dir", str(tmp_path), - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) @@ -161,7 +160,7 @@ def test_image_output_for_static_scene(tmp_path, manim_cfg_file, simple_scenes_p "-ql", "--media_dir", str(tmp_path), - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) @@ -189,7 +188,7 @@ def test_no_image_output_with_interactive_embed( "-ql", "--media_dir", str(tmp_path), - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) @@ -198,10 +197,10 @@ def test_no_image_output_with_interactive_embed( exists = (tmp_path / "videos").exists() assert not exists, "running manim with static scene rendered a video" - is_empty = len(os.listdir(tmp_path / "images" / "simple_scenes")) == 0 - assert ( - is_empty - ), "running manim static scene with interactive embed rendered an image" + is_empty = not any((tmp_path / "images" / "simple_scenes").iterdir()) + assert is_empty, ( + "running manim static scene with interactive embed rendered an image" + ) @pytest.mark.slow @@ -218,7 +217,7 @@ def test_no_default_image_output_with_non_static_scene( "-ql", "--media_dir", str(tmp_path), - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) @@ -227,10 +226,10 @@ def test_no_default_image_output_with_non_static_scene( exists = (tmp_path / "videos").exists() assert not exists, "running manim with static scene rendered a video" - is_empty = len(os.listdir(tmp_path / "images" / "simple_scenes")) == 0 - assert ( - is_empty - ), "running manim static scene with interactive embed rendered an image" + is_empty = not any((tmp_path / "images" / "simple_scenes").iterdir()) + assert is_empty, ( + "running manim static scene with interactive embed rendered an image" + ) @pytest.mark.slow @@ -248,14 +247,14 @@ def test_image_output_for_static_scene_with_write_to_movie( "-ql", "--media_dir", str(tmp_path), - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) assert exit_code == 0, err - exists = len(os.listdir(tmp_path / "videos")) == 0 - assert not exists, "running manim with static scene rendered a video" + is_empty = not any((tmp_path / "videos").iterdir()) + assert not is_empty, "running manim with static scene rendered a video" is_empty = not any((tmp_path / "images" / "simple_scenes").iterdir()) assert not is_empty, "running manim without animations did not render an image" @@ -274,7 +273,7 @@ def test_s_flag(tmp_path, manim_cfg_file, simple_scenes_path): "-s", "--media_dir", str(tmp_path), - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) @@ -302,7 +301,7 @@ def test_r_flag(tmp_path, manim_cfg_file, simple_scenes_path): str(tmp_path), "-r", "200,100", - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) @@ -330,7 +329,7 @@ def test_a_flag(tmp_path, manim_cfg_file, infallible_scenes_path): "--media_dir", str(tmp_path), "-a", - infallible_scenes_path, + str(infallible_scenes_path), ] out, err, exit_code = capture(command) assert exit_code == 0, err @@ -341,11 +340,18 @@ def test_a_flag(tmp_path, manim_cfg_file, infallible_scenes_path): assert one_is_not_empty, "running manim with -a flag did not render the first scene" two_is_not_empty = ( - tmp_path / "videos" / "infallible_scenes" / "480p15" / "Wait2.mp4" + tmp_path / "images" / "infallible_scenes" / f"Wait2_ManimCE_v{__version__}.png" ).is_file() - assert ( - two_is_not_empty - ), "running manim with -a flag did not render the second scene" + assert two_is_not_empty, ( + "running manim with -a flag did not render an image, possible leak of the config dictionary" + ) + + three_is_not_empty = ( + tmp_path / "videos" / "infallible_scenes" / "480p15" / "Wait3.mp4" + ).is_file() + assert three_is_not_empty, ( + "running manim with -a flag did not render the second scene" + ) @pytest.mark.slow @@ -362,7 +368,7 @@ def test_custom_folders(tmp_path, manim_cfg_file, simple_scenes_path): "--media_dir", str(tmp_path), "--custom_folders", - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) @@ -416,7 +422,7 @@ def test_gif_format_output(tmp_path, manim_cfg_file, simple_scenes_path): str(tmp_path), "--format", "gif", - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) @@ -429,12 +435,8 @@ def test_gif_format_output(tmp_path, manim_cfg_file, simple_scenes_path): unexpected_mp4_path, ) - expected_gif_path = ( - tmp_path - / "videos" - / "simple_scenes" - / "480p15" - / add_version_before_extension("SquareToCircle.gif") + expected_gif_path = add_version_before_extension( + tmp_path / "videos" / "simple_scenes" / "480p15" / "SquareToCircle.gif" ) assert expected_gif_path.exists(), "gif file not found at " + str(expected_gif_path) @@ -454,18 +456,14 @@ def test_mp4_format_output(tmp_path, manim_cfg_file, simple_scenes_path): str(tmp_path), "--format", "mp4", - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) assert exit_code == 0, err - unexpected_gif_path = ( - tmp_path - / "videos" - / "simple_scenes" - / "480p15" - / add_version_before_extension("SquareToCircle.gif") + unexpected_gif_path = add_version_before_extension( + tmp_path / "videos" / "simple_scenes" / "480p15" / "SquareToCircle.gif" ) assert not unexpected_gif_path.exists(), "unexpected gif file found at " + str( unexpected_gif_path, @@ -498,18 +496,14 @@ def test_videos_not_created_when_png_format_set( str(tmp_path), "--format", "png", - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) assert exit_code == 0, err - unexpected_gif_path = ( - tmp_path - / "videos" - / "simple_scenes" - / "480p15" - / add_version_before_extension("SquareToCircle.gif") + unexpected_gif_path = add_version_before_extension( + tmp_path / "videos" / "simple_scenes" / "480p15" / "SquareToCircle.gif" ) assert not unexpected_gif_path.exists(), "unexpected gif file found at " + str( unexpected_gif_path, @@ -542,7 +536,7 @@ def test_images_are_created_when_png_format_set( str(tmp_path), "--format", "png", - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) @@ -573,7 +567,7 @@ def test_images_are_zero_padded_when_zero_pad_set( "png", "--zero_pad", "3", - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) @@ -603,7 +597,7 @@ def test_webm_format_output(tmp_path, manim_cfg_file, simple_scenes_path): str(tmp_path), "--format", "webm", - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) @@ -643,7 +637,7 @@ def test_default_format_output_for_transparent_flag( "--media_dir", str(tmp_path), "-t", - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) @@ -679,7 +673,7 @@ def test_mov_can_be_set_as_output_format(tmp_path, manim_cfg_file, simple_scenes str(tmp_path), "--format", "mov", - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) diff --git a/tests/test_scene_rendering/opengl/test_opengl_renderer.py b/tests/test_scene_rendering/opengl/test_opengl_renderer.py index 188bbb58a3..f2236cb04d 100644 --- a/tests/test_scene_rendering/opengl/test_opengl_renderer.py +++ b/tests/test_scene_rendering/opengl/test_opengl_renderer.py @@ -1,7 +1,9 @@ from __future__ import annotations +import platform from unittest.mock import Mock +import numpy as np import pytest from manim.renderer.opengl_renderer import OpenGLRenderer @@ -9,18 +11,21 @@ from tests.test_scene_rendering.simple_scenes import * -def test_write_to_movie_disables_window(using_temp_opengl_config, disabling_caching): +def test_write_to_movie_disables_window( + config, using_temp_opengl_config, disabling_caching +): """write_to_movie should disable window by default""" scene = SquareToCircle() renderer = scene.renderer renderer.update_frame = Mock(wraps=renderer.update_frame) scene.render() assert renderer.window is None - assert_file_exists(config["output_file"]) + assert_file_exists(config.output_file) -@pytest.mark.skip(msg="Temporarily skip due to failing in Windows CI") # type: ignore +@pytest.mark.skip(reason="Temporarily skip due to failing in Windows CI") def test_force_window_opengl_render_with_movies( + config, using_temp_opengl_config, force_window_config_write_to_movie, disabling_caching, @@ -35,6 +40,9 @@ def test_force_window_opengl_render_with_movies( renderer.window.close() +@pytest.mark.skipif( + platform.processor() == "aarch64", reason="Fails on Linux-ARM runners" +) def test_force_window_opengl_render_with_format( using_temp_opengl_config, force_window_config_pngs, @@ -49,9 +57,10 @@ def test_force_window_opengl_render_with_format( renderer.window.close() -@pytest.mark.parametrize("enable_preview", [False]) -def test_get_frame_with_preview_disabled(use_opengl_renderer): +def test_get_frame_with_preview_disabled(config, using_opengl_renderer): """Get frame is able to fetch frame with the correct dimensions when preview is disabled""" + config.preview = False + scene = SquareToCircle() assert isinstance(scene.renderer, OpenGLRenderer) assert not config.preview @@ -66,9 +75,10 @@ def test_get_frame_with_preview_disabled(use_opengl_renderer): @pytest.mark.slow -@pytest.mark.parametrize("enable_preview", [True]) -def test_get_frame_with_preview_enabled(use_opengl_renderer): +def test_get_frame_with_preview_enabled(config, using_opengl_renderer): """Get frame is able to fetch frame with the correct dimensions when preview is enabled""" + config.preview = True + scene = SquareToCircle() assert isinstance(scene.renderer, OpenGLRenderer) assert config.preview is True @@ -82,8 +92,9 @@ def test_get_frame_with_preview_enabled(use_opengl_renderer): assert renderer.get_pixel_shape()[1] == frame.shape[0] -@pytest.mark.parametrize("enable_preview", [True]) -def test_pixel_coords_to_space_coords(use_opengl_renderer): +def test_pixel_coords_to_space_coords(config, using_opengl_renderer): + config.preview = True + scene = SquareToCircle() assert isinstance(scene.renderer, OpenGLRenderer) diff --git a/tests/test_scene_rendering/opengl/test_play_logic_opengl.py b/tests/test_scene_rendering/opengl/test_play_logic_opengl.py index 4a3f634ed5..64c4c39204 100644 --- a/tests/test_scene_rendering/opengl/test_play_logic_opengl.py +++ b/tests/test_scene_rendering/opengl/test_play_logic_opengl.py @@ -1,11 +1,15 @@ from __future__ import annotations +import sys from unittest.mock import Mock import pytest -from manim import * -from manim import config +from manim import ( + Scene, + ValueTracker, + np, +) from ..simple_scenes import ( SceneForFrozenFrameTests, @@ -22,7 +26,7 @@ reason="Mock object has a different implementation in python 3.7, which makes it broken with this logic.", ) @pytest.mark.parametrize("frame_rate", argvalues=[15, 30, 60]) -def test_t_values(using_temp_opengl_config, disabling_caching, frame_rate): +def test_t_values(config, using_temp_opengl_config, disabling_caching, frame_rate): """Test that the framerate corresponds to the number of t values generated""" config.frame_rate = frame_rate scene = SquareToCircle() @@ -35,10 +39,6 @@ def test_t_values(using_temp_opengl_config, disabling_caching, frame_rate): ) -@pytest.mark.skipif( - sys.version_info < (3, 8), - reason="Mock object has a different implementation in python 3.7, which makes it broken with this logic.", -) def test_t_values_with_skip_animations(using_temp_opengl_config, disabling_caching): """Test the behaviour of scene.skip_animations""" scene = SquareToCircle() @@ -94,10 +94,26 @@ def test_t_values_with_cached_data(using_temp_opengl_config): @pytest.mark.xfail(reason="Not currently handled correctly for opengl") -def test_t_values_save_last_frame(using_temp_opengl_config): +def test_t_values_save_last_frame(config, using_temp_opengl_config): """Test that there is only one t value handled when only saving the last frame""" config.save_last_frame = True scene = SquareToCircle() scene.update_to_time = Mock() scene.render() scene.update_to_time.assert_called_once_with(1) + + +def test_animate_with_changed_custom_attribute(using_temp_opengl_config): + """Test that animating the change of a custom attribute + using the animate syntax works correctly. + """ + + class CustomAnimateScene(Scene): + def construct(self): + vt = ValueTracker(0) + vt.custom_attribute = "hello" + self.play(vt.animate.set_value(42).set(custom_attribute="world")) + assert vt.get_value() == 42 + assert vt.custom_attribute == "world" + + CustomAnimateScene().render() diff --git a/tests/test_scene_rendering/simple_scenes.py b/tests/test_scene_rendering/simple_scenes.py index 8dd2b706e0..7f626ffbe2 100644 --- a/tests/test_scene_rendering/simple_scenes.py +++ b/tests/test_scene_rendering/simple_scenes.py @@ -1,7 +1,24 @@ from __future__ import annotations +from enum import Enum + from manim import * +__all__ = [ + "SquareToCircle", + "SceneWithMultipleCalls", + "SceneWithMultipleWaitCalls", + "NoAnimations", + "SceneWithStaticWait", + "SceneWithSceneUpdater", + "SceneForFrozenFrameTests", + "SceneWithNonStaticWait", + "StaticScene", + "InteractiveStaticScene", + "SceneWithSections", + "ElaborateSceneWithSections", +] + class SquareToCircle(Scene): def construct(self): @@ -118,7 +135,7 @@ class PresentationSectionType(str, Enum): ) self.wait(2) - self.next_section(type=PresentationSectionType.SKIP) + self.next_section(section_type=PresentationSectionType.SKIP) self.wait() self.next_section( diff --git a/tests/test_scene_rendering/test_caching_related.py b/tests/test_scene_rendering/test_caching_related.py index ae5b9a5c17..af2bb1ff9e 100644 --- a/tests/test_scene_rendering/test_caching_related.py +++ b/tests/test_scene_rendering/test_caching_related.py @@ -26,7 +26,7 @@ def test_wait_skip(tmp_path, manim_cfg_file, simple_scenes_path): str(tmp_path), "-n", "3", - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) @@ -50,7 +50,7 @@ def test_play_skip(tmp_path, manim_cfg_file, simple_scenes_path): str(tmp_path), "-n", "3", - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) diff --git a/tests/test_scene_rendering/test_cli_flags.py b/tests/test_scene_rendering/test_cli_flags.py index f1d0f4382a..e938ff8d20 100644 --- a/tests/test_scene_rendering/test_cli_flags.py +++ b/tests/test_scene_rendering/test_cli_flags.py @@ -1,6 +1,5 @@ from __future__ import annotations -import os import sys import numpy as np @@ -9,7 +8,7 @@ from PIL import Image from manim import capture, get_video_metadata -from manim.__main__ import main +from manim.__main__ import __version__, main from manim.utils.file_ops import add_version_before_extension from ..utils.video_tester import video_comparison @@ -28,7 +27,7 @@ def test_basic_scene_with_default_values(tmp_path, manim_cfg_file, simple_scenes "manim", "--media_dir", str(tmp_path), - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) @@ -49,7 +48,7 @@ def test_resolution_flag(tmp_path, manim_cfg_file, simple_scenes_path): # (800, 600, ";"), ] - for (width, height, separator) in resolutions: + for width, height, separator in resolutions: command = [ sys.executable, "-m", @@ -86,7 +85,7 @@ def test_basic_scene_l_flag(tmp_path, manim_cfg_file, simple_scenes_path): "-ql", "--media_dir", str(tmp_path), - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) @@ -108,7 +107,7 @@ def test_n_flag(tmp_path, simple_scenes_path): "-n 3,6", "--media_dir", str(tmp_path), - simple_scenes_path, + str(simple_scenes_path), scene_name, ] _, err, exit_code = capture(command) @@ -126,7 +125,7 @@ def test_s_flag_no_animations(tmp_path, manim_cfg_file, simple_scenes_path): "-s", "--media_dir", str(tmp_path), - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) @@ -150,7 +149,7 @@ def test_s_flag(tmp_path, manim_cfg_file, simple_scenes_path): "-s", "--media_dir", str(tmp_path), - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) @@ -176,7 +175,7 @@ def test_s_flag_opengl_renderer(tmp_path, manim_cfg_file, simple_scenes_path): "opengl", "--media_dir", str(tmp_path), - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) @@ -202,7 +201,7 @@ def test_r_flag(tmp_path, manim_cfg_file, simple_scenes_path): str(tmp_path), "-r", "200,100", - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) @@ -227,9 +226,9 @@ def test_a_flag(tmp_path, manim_cfg_file, infallible_scenes_path): "--media_dir", str(tmp_path), "-a", - infallible_scenes_path, + str(infallible_scenes_path), ] - out, err, exit_code = capture(command) + _, err, exit_code = capture(command) assert exit_code == 0, err one_is_not_empty = ( @@ -238,11 +237,18 @@ def test_a_flag(tmp_path, manim_cfg_file, infallible_scenes_path): assert one_is_not_empty, "running manim with -a flag did not render the first scene" two_is_not_empty = ( - tmp_path / "videos" / "infallible_scenes" / "480p15" / "Wait2.mp4" + tmp_path / "images" / "infallible_scenes" / f"Wait2_ManimCE_v{__version__}.png" ).is_file() - assert ( - two_is_not_empty - ), "running manim with -a flag did not render the second scene" + assert two_is_not_empty, ( + "running manim with -a flag did not render an image, possible leak of the config dictionary." + ) + + three_is_not_empty = ( + tmp_path / "videos" / "infallible_scenes" / "480p15" / "Wait3.mp4" + ).is_file() + assert three_is_not_empty, ( + "running manim with -a flag did not render the second scene" + ) @pytest.mark.slow @@ -257,7 +263,7 @@ def test_custom_folders(tmp_path, manim_cfg_file, simple_scenes_path): "--media_dir", str(tmp_path), "--custom_folders", - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) @@ -284,18 +290,14 @@ def test_custom_output_name_gif(tmp_path, simple_scenes_path): "--format=gif", "-o", custom_name, - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) assert exit_code == 0, err - wrong_gif_path = ( - tmp_path - / "videos" - / "simple_scenes" - / "480p15" - / add_version_before_extension(scene_name + ".gif") + wrong_gif_path = add_version_before_extension( + tmp_path / "videos" / "simple_scenes" / "480p15" / f"{scene_name}.gif" ) assert not wrong_gif_path.exists(), ( @@ -330,7 +332,7 @@ def test_custom_output_name_mp4(tmp_path, simple_scenes_path): str(tmp_path), "-o", custom_name, - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) @@ -344,12 +346,8 @@ def test_custom_output_name_mp4(tmp_path, simple_scenes_path): "The mp4 file does not respect the custom name: " + custom_name + ".mp4" ) - unexpected_gif_path = ( - tmp_path - / "videos" - / "simple_scenes" - / "480p15" - / add_version_before_extension(custom_name + ".gif") + unexpected_gif_path = add_version_before_extension( + tmp_path / "videos" / "simple_scenes" / "480p15" / f"{custom_name}.gif" ) assert not unexpected_gif_path.exists(), "Found an unexpected gif file at " + str( unexpected_gif_path @@ -399,7 +397,7 @@ def test_gif_format_output(tmp_path, manim_cfg_file, simple_scenes_path): str(tmp_path), "--format", "gif", - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) @@ -412,12 +410,8 @@ def test_gif_format_output(tmp_path, manim_cfg_file, simple_scenes_path): unexpected_mp4_path, ) - expected_gif_path = ( - tmp_path - / "videos" - / "simple_scenes" - / "480p15" - / add_version_before_extension("SquareToCircle.gif") + expected_gif_path = add_version_before_extension( + tmp_path / "videos" / "simple_scenes" / "480p15" / "SquareToCircle.gif" ) assert expected_gif_path.exists(), "gif file not found at " + str(expected_gif_path) @@ -435,18 +429,14 @@ def test_mp4_format_output(tmp_path, manim_cfg_file, simple_scenes_path): str(tmp_path), "--format", "mp4", - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) assert exit_code == 0, err - unexpected_gif_path = ( - tmp_path - / "videos" - / "simple_scenes" - / "480p15" - / add_version_before_extension("SquareToCircle.gif") + unexpected_gif_path = add_version_before_extension( + tmp_path / "videos" / "simple_scenes" / "480p15" / "SquareToCircle.gif" ) assert not unexpected_gif_path.exists(), "unexpected gif file found at " + str( unexpected_gif_path, @@ -477,18 +467,14 @@ def test_videos_not_created_when_png_format_set( str(tmp_path), "--format", "png", - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) assert exit_code == 0, err - unexpected_gif_path = ( - tmp_path - / "videos" - / "simple_scenes" - / "480p15" - / add_version_before_extension("SquareToCircle.gif") + unexpected_gif_path = add_version_before_extension( + tmp_path / "videos" / "simple_scenes" / "480p15" / "SquareToCircle.gif" ) assert not unexpected_gif_path.exists(), "unexpected gif file found at " + str( unexpected_gif_path, @@ -519,7 +505,7 @@ def test_images_are_created_when_png_format_set( str(tmp_path), "--format", "png", - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) @@ -548,7 +534,7 @@ def test_images_are_created_when_png_format_set_for_opengl( str(tmp_path), "--format", "png", - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) @@ -577,7 +563,7 @@ def test_images_are_zero_padded_when_zero_pad_set( "png", "--zero_pad", "3", - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) @@ -613,7 +599,7 @@ def test_images_are_zero_padded_when_zero_pad_set_for_opengl( "png", "--zero_pad", "3", - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) @@ -641,7 +627,7 @@ def test_webm_format_output(tmp_path, manim_cfg_file, simple_scenes_path): str(tmp_path), "--format", "webm", - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) @@ -678,7 +664,7 @@ def test_default_format_output_for_transparent_flag( "--media_dir", str(tmp_path), "-t", - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) @@ -712,7 +698,7 @@ def test_mov_can_be_set_as_output_format(tmp_path, manim_cfg_file, simple_scenes str(tmp_path), "--format", "mov", - simple_scenes_path, + str(simple_scenes_path), scene_name, ] out, err, exit_code = capture(command) @@ -740,13 +726,12 @@ def test_mov_can_be_set_as_output_format(tmp_path, manim_cfg_file, simple_scenes ) def test_input_file_via_cfg(tmp_path, manim_cfg_file, simple_scenes_path): scene_name = "SquareToCircle" - with open(os.path.join(tmp_path, "manim.cfg"), "w") as file: - file.write( - f""" + (tmp_path / "manim.cfg").write_text( + f""" [CLI] input_file = {simple_scenes_path} - """ - ) + """ + ) command = [ sys.executable, diff --git a/tests/test_scene_rendering/test_file_writer.py b/tests/test_scene_rendering/test_file_writer.py index f7ead0d483..0065547709 100644 --- a/tests/test_scene_rendering/test_file_writer.py +++ b/tests/test_scene_rendering/test_file_writer.py @@ -1,12 +1,165 @@ import sys +from fractions import Fraction +from pathlib import Path +import av +import numpy as np import pytest -from manim.utils.commands import capture +from manim import DR, Circle, Create, Scene, Star, tempconfig +from manim.scene.scene_file_writer import to_av_frame_rate +from manim.utils.commands import capture, get_video_metadata + + +class StarScene(Scene): + def construct(self): + circle = Circle(fill_opacity=1, color="#ff0000") + circle.to_corner(DR).shift(DR) + self.add(circle) + star = Star() + self.play(Create(star)) + click_path = ( + Path(__file__).parent.parent.parent + / "docs" + / "source" + / "_static" + / "click.wav" + ) + self.add_sound(click_path) + self.wait() + + +@pytest.mark.slow +@pytest.mark.parametrize( + "transparent", + [False, True], +) +def test_gif_writing(config, tmp_path, transparent): + output_filename = f"gif_{'transparent' if transparent else 'opaque'}" + with tempconfig( + { + "media_dir": tmp_path, + "quality": "low_quality", + "format": "gif", + "transparent": transparent, + "output_file": output_filename, + } + ): + StarScene().render() + + video_path = tmp_path / "videos" / "480p15" / f"{output_filename}.gif" + assert video_path.exists() + metadata = get_video_metadata(video_path) + # reported duration + avg_frame_rate is slightly off for gifs + del metadata["duration"], metadata["avg_frame_rate"] + target_metadata = { + "width": 854, + "height": 480, + "nb_frames": "30", + "codec_name": "gif", + "pix_fmt": "bgra", + } + assert metadata == target_metadata + + with av.open(video_path) as container: + first_frame = next(container.decode(video=0)) + frame_format = "argb" if transparent else "rgb24" + first_frame = first_frame.to_ndarray(format=frame_format) + + target_rgba_corner = ( + np.array([0, 255, 255, 255], dtype=np.uint8) + if transparent + else np.array([0, 0, 0], dtype=np.uint8) + ) + np.testing.assert_array_equal(first_frame[0, 0], target_rgba_corner) + + target_rgba_center = ( + np.array([255, 255, 0, 0]) # components (A, R, G, B) + if transparent + else np.array([255, 0, 0], dtype=np.uint8) + ) + np.testing.assert_allclose(first_frame[-1, -1], target_rgba_center, atol=5) @pytest.mark.slow -def test_unicode_partial_movie(tmpdir, simple_scenes_path): +@pytest.mark.parametrize( + ("format", "transparent", "codec", "pixel_format"), + [ + ("mp4", False, "h264", "yuv420p"), + ("mov", False, "h264", "yuv420p"), + ("mov", True, "qtrle", "argb"), + ("webm", False, "vp9", "yuv420p"), + ("webm", True, "vp9", "yuv420p"), + ], +) +def test_codecs(config, tmp_path, format, transparent, codec, pixel_format): + output_filename = f"codec_{format}_{'transparent' if transparent else 'opaque'}" + with tempconfig( + { + "media_dir": tmp_path, + "quality": "low_quality", + "format": format, + "transparent": transparent, + "output_file": output_filename, + } + ): + StarScene().render() + + video_path = tmp_path / "videos" / "480p15" / f"{output_filename}.{format}" + assert video_path.exists() + metadata = get_video_metadata(video_path) + target_metadata = { + "width": 854, + "height": 480, + "nb_frames": "30", + "duration": "2.000000", + "avg_frame_rate": "15/1", + "codec_name": codec, + "pix_fmt": pixel_format, + } + assert metadata == target_metadata + + with av.open(video_path) as container: + if transparent and format == "webm": + from av.codec.context import CodecContext + + context = CodecContext.create("libvpx-vp9", "r") + packet = next(container.demux(video=0)) + first_frame = context.decode(packet)[0].to_ndarray(format="argb") + else: + first_frame = next(container.decode(video=0)).to_ndarray() + + has_samples = [ + np.any(frame.to_ndarray()) for frame in container.decode(audio=0) + ] + assert any(has_samples), "All audio samples are zero, this is not intended" + + target_rgba_corner = ( + np.array([0, 0, 0, 0]) if transparent else np.array(16, dtype=np.uint8) + ) + np.testing.assert_array_equal(first_frame[0, 0], target_rgba_corner) + + target_rgba_center = ( + np.array([255, 255, 0, 0]) # components (A, R, G, B) + if transparent + else np.array(240, dtype=np.uint8) + ) + np.testing.assert_allclose(first_frame[-1, -1], target_rgba_center, atol=5) + + +def test_scene_with_non_raw_or_wav_audio(config, manim_caplog): + class SceneWithMP3(Scene): + def construct(self): + file_path = Path(__file__).parent / "click.mp3" + self.add_sound(file_path) + self.wait() + + SceneWithMP3().render() + assert "click.mp3 to .wav" in manim_caplog.text + + +@pytest.mark.slow +def test_unicode_partial_movie(config, tmpdir, simple_scenes_path): # Characters that failed for a user on Windows # due to its weird default encoding. unicode_str = "三角函数" @@ -18,9 +171,17 @@ def test_unicode_partial_movie(tmpdir, simple_scenes_path): "manim", "--media_dir", str(tmpdir / unicode_str), - simple_scenes_path, + str(simple_scenes_path), scene_name, ] _, err, exit_code = capture(command) assert exit_code == 0, err + + +def test_frame_rates(): + assert to_av_frame_rate(25) == Fraction(25, 1) + assert to_av_frame_rate(24.0) == Fraction(24, 1) + assert to_av_frame_rate(23.976) == Fraction(24 * 1000, 1001) + assert to_av_frame_rate(23.98) == Fraction(24 * 1000, 1001) + assert to_av_frame_rate(59.94) == Fraction(60 * 1000, 1001) diff --git a/tests/test_scene_rendering/test_play_logic.py b/tests/test_scene_rendering/test_play_logic.py index 7f996ff3f3..4aaae3c8ad 100644 --- a/tests/test_scene_rendering/test_play_logic.py +++ b/tests/test_scene_rendering/test_play_logic.py @@ -5,8 +5,14 @@ import pytest -from manim import * -from manim import config +from manim import ( + Dot, + Mobject, + Scene, + ValueTracker, + Wait, + np, +) from .simple_scenes import ( SceneForFrozenFrameTests, @@ -18,12 +24,8 @@ ) -@pytest.mark.skipif( - sys.version_info < (3, 8), - reason="Mock object has a different implementation in python 3.7, which makes it broken with this logic.", -) @pytest.mark.parametrize("frame_rate", argvalues=[15, 30, 60]) -def test_t_values(using_temp_config, disabling_caching, frame_rate): +def test_t_values(config, using_temp_config, disabling_caching, frame_rate): """Test that the framerate corresponds to the number of t values generated""" config.frame_rate = frame_rate scene = SquareToCircle() @@ -73,6 +75,22 @@ def test_non_static_wait_detection(using_temp_config, disabling_caching): assert not scene.is_current_animation_frozen_frame() +def test_wait_with_stop_condition(using_temp_config, disabling_caching): + class TestScene(Scene): + def construct(self): + self.wait_until(lambda: self.time >= 1) + assert self.time >= 1 + d = Dot() + d.add_updater(lambda mobj, dt: self.add(Mobject())) + self.add(d) + self.play(Wait(run_time=5, stop_condition=lambda: len(self.mobjects) > 5)) + assert len(self.mobjects) > 5 + assert self.time < 2 + + scene = TestScene() + scene.render() + + def test_frozen_frame(using_temp_config, disabling_caching): scene = SceneForFrozenFrameTests() scene.render() @@ -94,10 +112,26 @@ def test_t_values_with_cached_data(using_temp_config): assert scene.update_to_time.call_count == 10 -def test_t_values_save_last_frame(using_temp_config): +def test_t_values_save_last_frame(config, using_temp_config): """Test that there is only one t value handled when only saving the last frame""" config.save_last_frame = True scene = SquareToCircle() scene.update_to_time = Mock() scene.render() scene.update_to_time.assert_called_once_with(1) + + +def test_animate_with_changed_custom_attribute(using_temp_config): + """Test that animating the change of a custom attribute + using the animate syntax works correctly. + """ + + class CustomAnimateScene(Scene): + def construct(self): + vt = ValueTracker(0) + vt.custom_attribute = "hello" + self.play(vt.animate.set_value(42).set(custom_attribute="world")) + assert vt.get_value() == 42 + assert vt.custom_attribute == "world" + + CustomAnimateScene().render() diff --git a/tests/test_scene_rendering/test_sections.py b/tests/test_scene_rendering/test_sections.py index 4291154dfc..049802f3cb 100644 --- a/tests/test_scene_rendering/test_sections.py +++ b/tests/test_scene_rendering/test_sections.py @@ -1,6 +1,5 @@ from __future__ import annotations -import os import sys import pytest @@ -25,15 +24,15 @@ def test_no_sections(tmp_path, manim_cfg_file, simple_scenes_path): "-ql", "--media_dir", str(tmp_path), - simple_scenes_path, + str(simple_scenes_path), scene_name, ] _, err, exit_code = capture(command) assert exit_code == 0, err - scene_dir = os.path.join(tmp_path, "videos", "simple_scenes", "480p15") + scene_dir = tmp_path / "videos" / "simple_scenes" / "480p15" assert_dir_exists(scene_dir) - assert_dir_not_exists(os.path.join(scene_dir, "sections")) + assert_dir_not_exists(scene_dir / "sections") @pytest.mark.slow @@ -51,15 +50,15 @@ def test_sections(tmp_path, manim_cfg_file, simple_scenes_path): "--save_sections", "--media_dir", str(tmp_path), - simple_scenes_path, + str(simple_scenes_path), scene_name, ] _, err, exit_code = capture(command) assert exit_code == 0, err - scene_dir = os.path.join(tmp_path, "videos", "simple_scenes", "480p15") + scene_dir = tmp_path / "videos" / "simple_scenes" / "480p15" assert_dir_exists(scene_dir) - assert_dir_exists(os.path.join(scene_dir, "sections")) + assert_dir_exists(scene_dir / "sections") @pytest.mark.slow @@ -77,7 +76,7 @@ def test_many_sections(tmp_path, manim_cfg_file, simple_scenes_path): "--save_sections", "--media_dir", str(tmp_path), - simple_scenes_path, + str(simple_scenes_path), scene_name, ] _, err, exit_code = capture(command) @@ -99,7 +98,7 @@ def test_skip_animations(tmp_path, manim_cfg_file, simple_scenes_path): "--save_sections", "--media_dir", str(tmp_path), - simple_scenes_path, + str(simple_scenes_path), scene_name, ] _, err, exit_code = capture(command) diff --git a/tests/test_sound.py b/tests/test_sound.py deleted file mode 100644 index cfd67ed2df..0000000000 --- a/tests/test_sound.py +++ /dev/null @@ -1,23 +0,0 @@ -from __future__ import annotations - -import struct -import wave -from pathlib import Path - -from manim import Scene - - -def test_add_sound(tmpdir): - # create sound file - sound_loc = Path(tmpdir, "noise.wav") - f = wave.open(str(sound_loc), "w") - f.setparams((2, 2, 44100, 0, "NONE", "not compressed")) - for _ in range(22050): # half a second of sound - packed_value = struct.pack("h", 14242) - f.writeframes(packed_value) - f.writeframes(packed_value) - - f.close() - - scene = Scene() - scene.add_sound(sound_loc) diff --git a/tests/test_stroke.py b/tests/test_stroke.py deleted file mode 100644 index 5a25f34661..0000000000 --- a/tests/test_stroke.py +++ /dev/null @@ -1,28 +0,0 @@ -from __future__ import annotations - -from colour import Color - -import manim.utils.color as C -from manim import VMobject - - -def test_stroke_props_in_ctor(): - m = VMobject(stroke_color=C.ORANGE, stroke_width=10) - assert m.stroke_color == Color(C.ORANGE) - assert m.stroke_width == 10 - - -def test_set_stroke(): - m = VMobject() - m.set_stroke(color=C.ORANGE, width=2, opacity=0.8) - assert m.stroke_width == 2 - assert m.stroke_opacity == 0.8 - assert m.stroke_color == Color(C.ORANGE) - - -def test_set_background_stroke(): - m = VMobject() - m.set_stroke(color=C.ORANGE, width=2, opacity=0.8, background=True) - assert m.background_stroke_width == 2 - assert m.background_stroke_opacity == 0.8 - assert m.background_stroke_color == C.ORANGE diff --git a/tests/test_svg_mobject.py b/tests/test_svg_mobject.py deleted file mode 100644 index 41c6e15dc6..0000000000 --- a/tests/test_svg_mobject.py +++ /dev/null @@ -1,79 +0,0 @@ -from __future__ import annotations - -from colour import Color - -from manim import * -from manim.mobject.svg.svg_path import string_to_numbers -from tests.helpers.path_utils import get_svg_resource - - -def test_set_fill_color(): - expected_color = "#FF862F" - svg = SVGMobject(get_svg_resource("heart.svg"), fill_color=expected_color) - assert svg.fill_color == Color(expected_color) - - -def test_set_stroke_color(): - expected_color = "#FFFDDD" - svg = SVGMobject(get_svg_resource("heart.svg"), stroke_color=expected_color) - assert svg.stroke_color == Color(expected_color) - - -def test_set_color_sets_fill_and_stroke(): - expected_color = "#EEE777" - svg = SVGMobject(get_svg_resource("heart.svg"), color=expected_color) - assert svg.color == Color(expected_color) - assert svg.fill_color == Color(expected_color) - assert svg.stroke_color == Color(expected_color) - - -def test_set_fill_opacity(): - expected_opacity = 0.5 - svg = SVGMobject(get_svg_resource("heart.svg"), fill_opacity=expected_opacity) - assert svg.fill_opacity == expected_opacity - - -def test_stroke_opacity(): - expected_opacity = 0.4 - svg = SVGMobject(get_svg_resource("heart.svg"), stroke_opacity=expected_opacity) - assert svg.stroke_opacity == expected_opacity - - -def test_fill_overrides_color(): - expected_color = "#343434" - svg = SVGMobject( - get_svg_resource("heart.svg"), - color="#123123", - fill_color=expected_color, - ) - assert svg.fill_color == Color(expected_color) - - -def test_stroke_overrides_color(): - expected_color = "#767676" - svg = SVGMobject( - get_svg_resource("heart.svg"), - color="#334433", - stroke_color=expected_color, - ) - assert svg.stroke_color == Color(expected_color) - - -def test_string_to_numbers(): - cases = { - "3, 14, 159": [3.0, 14.0, 159.0], - "2.7 1828-1828": [2.7, 1828.0, -1828.0], - "1-.618.033": [1.0, -0.618, 0.033], - # this one is a real-world example! - "1.5938,1.5938,0,0,1-.1559.6874": [ - 1.5938, - 1.5938, - 0.0, - 0.0, - 1.0, - -0.1559, - 0.6874, - ], - } - for case, result in cases.items(): - assert string_to_numbers(case) == result diff --git a/tests/test_text_mobject.py b/tests/test_text_mobject.py deleted file mode 100644 index 79542163d1..0000000000 --- a/tests/test_text_mobject.py +++ /dev/null @@ -1,23 +0,0 @@ -from __future__ import annotations - -from colour import Color - -from manim.mobject.text.text_mobject import MarkupText, Text - - -def test_font_size(): - """Test that Text and MarkupText return the - correct font_size value after being scaled.""" - text_string = Text("0").scale(0.3) - markuptext_string = MarkupText("0").scale(0.3) - - assert round(text_string.font_size, 5) == 14.4 - assert round(markuptext_string.font_size, 5) == 14.4 - - -def test_non_str_color(): - """Test that the Text and MarkupText can accept non_str color values - i.e. colour.Color(red).""" - - text = Text("test_color_inheritance", color=Color("blue")) - markup_text = MarkupText("test_color_inheritance", color=Color("blue")) diff --git a/tests/test_unit_geometry.py b/tests/test_unit_geometry.py deleted file mode 100644 index b85cc08056..0000000000 --- a/tests/test_unit_geometry.py +++ /dev/null @@ -1,9 +0,0 @@ -from __future__ import annotations - -import numpy as np - -from manim import Sector - - -def test_get_arc_center(): - assert np.all(Sector(arc_center=[1, 2, 0]).get_arc_center() == [1, 2, 0]) diff --git a/tests/test_vectorized_mobject.py b/tests/test_vectorized_mobject.py deleted file mode 100644 index b6013c92fe..0000000000 --- a/tests/test_vectorized_mobject.py +++ /dev/null @@ -1,297 +0,0 @@ -from math import cos, sin - -import numpy as np -import pytest - -from manim import Circle, Line, Mobject, RegularPolygon, Square, VDict, VGroup, VMobject -from manim.constants import PI - - -def test_vmobject_point_from_propotion(): - obj = VMobject() - - # One long line, one short line - obj.set_points_as_corners( - [ - np.array([0, 0, 0]), - np.array([4, 0, 0]), - np.array([4, 2, 0]), - ], - ) - - # Total length of 6, so halfway along the object - # would be at length 3, which lands in the first, long line. - assert np.all(obj.point_from_proportion(0.5) == np.array([3, 0, 0])) - - with pytest.raises(ValueError, match="between 0 and 1"): - obj.point_from_proportion(2) - - obj.clear_points() - with pytest.raises(Exception, match="with no points"): - obj.point_from_proportion(0) - - -def test_vgroup_init(): - """Test the VGroup instantiation.""" - VGroup() - VGroup(VMobject()) - VGroup(VMobject(), VMobject()) - with pytest.raises(TypeError): - VGroup(Mobject()) - with pytest.raises(TypeError): - VGroup(Mobject(), Mobject()) - - -def test_vgroup_add(): - """Test the VGroup add method.""" - obj = VGroup() - assert len(obj.submobjects) == 0 - obj.add(VMobject()) - assert len(obj.submobjects) == 1 - with pytest.raises(TypeError): - obj.add(Mobject()) - assert len(obj.submobjects) == 1 - with pytest.raises(TypeError): - # If only one of the added object is not an instance of VMobject, none of them should be added - obj.add(VMobject(), Mobject()) - assert len(obj.submobjects) == 1 - with pytest.raises(ValueError): - # a Mobject cannot contain itself - obj.add(obj) - - -def test_vgroup_add_dunder(): - """Test the VGroup __add__ magic method.""" - obj = VGroup() - assert len(obj.submobjects) == 0 - obj + VMobject() - assert len(obj.submobjects) == 0 - obj += VMobject() - assert len(obj.submobjects) == 1 - with pytest.raises(TypeError): - obj += Mobject() - assert len(obj.submobjects) == 1 - with pytest.raises(TypeError): - # If only one of the added object is not an instance of VMobject, none of them should be added - obj += (VMobject(), Mobject()) - assert len(obj.submobjects) == 1 - with pytest.raises(ValueError): - # a Mobject cannot contain itself - obj += obj - - -def test_vgroup_remove(): - """Test the VGroup remove method.""" - a = VMobject() - c = VMobject() - b = VGroup(c) - obj = VGroup(a, b) - assert len(obj.submobjects) == 2 - assert len(b.submobjects) == 1 - obj.remove(a) - b.remove(c) - assert len(obj.submobjects) == 1 - assert len(b.submobjects) == 0 - obj.remove(b) - assert len(obj.submobjects) == 0 - - -def test_vgroup_remove_dunder(): - """Test the VGroup __sub__ magic method.""" - a = VMobject() - c = VMobject() - b = VGroup(c) - obj = VGroup(a, b) - assert len(obj.submobjects) == 2 - assert len(b.submobjects) == 1 - assert len(obj - a) == 1 - assert len(obj.submobjects) == 2 - obj -= a - b -= c - assert len(obj.submobjects) == 1 - assert len(b.submobjects) == 0 - obj -= b - assert len(obj.submobjects) == 0 - - -def test_vmob_add_to_back(): - """Test the Mobject add_to_back method.""" - a = VMobject() - b = Line() - c = "text" - with pytest.raises(ValueError): - # Mobject cannot contain self - a.add_to_back(a) - with pytest.raises(TypeError): - # All submobjects must be of type Mobject - a.add_to_back(c) - - # No submobject gets added twice - a.add_to_back(b) - a.add_to_back(b, b) - assert len(a.submobjects) == 1 - a.submobjects.clear() - a.add_to_back(b, b, b) - a.add_to_back(b, b) - assert len(a.submobjects) == 1 - a.submobjects.clear() - - # Make sure the ordering has not changed - o1, o2, o3 = Square(), Line(), Circle() - a.add_to_back(o1, o2, o3) - assert a.submobjects.pop() == o3 - assert a.submobjects.pop() == o2 - assert a.submobjects.pop() == o1 - - -def test_vdict_init(): - """Test the VDict instantiation.""" - # Test empty VDict - VDict() - # Test VDict made from list of pairs - VDict([("a", VMobject()), ("b", VMobject()), ("c", VMobject())]) - # Test VDict made from a python dict - VDict({"a": VMobject(), "b": VMobject(), "c": VMobject()}) - # Test VDict made using zip - VDict(zip(["a", "b", "c"], [VMobject(), VMobject(), VMobject()])) - # If the value is of type Mobject, must raise a TypeError - with pytest.raises(TypeError): - VDict({"a": Mobject()}) - - -def test_vdict_add(): - """Test the VDict add method.""" - obj = VDict() - assert len(obj.submob_dict) == 0 - obj.add([("a", VMobject())]) - assert len(obj.submob_dict) == 1 - with pytest.raises(TypeError): - obj.add([("b", Mobject())]) - - -def test_vdict_remove(): - """Test the VDict remove method.""" - obj = VDict([("a", VMobject())]) - assert len(obj.submob_dict) == 1 - obj.remove("a") - assert len(obj.submob_dict) == 0 - with pytest.raises(KeyError): - obj.remove("a") - - -def test_vgroup_supports_item_assigment(): - """Test VGroup supports array-like assignment for VMObjects""" - a = VMobject() - b = VMobject() - vgroup = VGroup(a) - assert vgroup[0] == a - vgroup[0] = b - assert vgroup[0] == b - assert len(vgroup) == 1 - - -def test_vgroup_item_assignment_at_correct_position(): - """Test VGroup item-assignment adds to correct position for VMObjects""" - n_items = 10 - vgroup = VGroup() - for _i in range(n_items): - vgroup.add(VMobject()) - new_obj = VMobject() - vgroup[6] = new_obj - assert vgroup[6] == new_obj - assert len(vgroup) == n_items - - -def test_vgroup_item_assignment_only_allows_vmobjects(): - """Test VGroup item-assignment raises TypeError when invalid type is passed""" - vgroup = VGroup(VMobject()) - with pytest.raises(TypeError, match="All submobjects must be of type VMobject"): - vgroup[0] = "invalid object" - - -def test_trim_dummy(): - o = VMobject() - o.start_new_path(np.array([0, 0, 0])) - o.add_line_to(np.array([1, 0, 0])) - o.add_line_to(np.array([2, 0, 0])) - o.add_line_to(np.array([2, 0, 0])) # Dummy point, will be stripped from points - o.start_new_path(np.array([0, 1, 0])) - o.add_line_to(np.array([1, 2, 0])) - - o2 = VMobject() - o2.start_new_path(np.array([0, 0, 0])) - o2.add_line_to(np.array([0, 1, 0])) - o2.start_new_path(np.array([1, 0, 0])) - o2.add_line_to(np.array([1, 1, 0])) - o2.add_line_to(np.array([1, 2, 0])) - - def path_length(p): - return len(p) // o.n_points_per_cubic_curve - - assert tuple(map(path_length, o.get_subpaths())) == (3, 1) - assert tuple(map(path_length, o2.get_subpaths())) == (1, 2) - - o.align_points(o2) - - assert tuple(map(path_length, o.get_subpaths())) == (2, 2) - assert tuple(map(path_length, o2.get_subpaths())) == (2, 2) - - -def test_bounded_become(): - """Tests that align_points generates a bounded number of points. - https://github.com/ManimCommunity/manim/issues/1959 - """ - o = VMobject() - - def draw_circle(m: VMobject, n_points, x=0, y=0, r=1): - center = np.array([x, y, 0]) - m.start_new_path(center + [r, 0, 0]) - for i in range(1, n_points + 1): - theta = 2 * PI * i / n_points - m.add_line_to(center + [cos(theta) * r, sin(theta) * r, 0]) - - # o must contain some points, or else become behaves differently - draw_circle(o, 2) - - for _ in range(20): - # Alternate between calls to become with different subpath sizes - a = VMobject() - draw_circle(a, 20) - o.become(a) - b = VMobject() - draw_circle(b, 15) - draw_circle(b, 15, x=3) - o.become(b) - - # The number of points should be similar to the size of a and b - assert len(o.points) <= (20 + 15 + 15) * 4 - - -def test_vmobject_same_points_become(): - a = Square() - b = Circle() - a.become(b) - assert np.array_equal(a.points, b.points) - assert len(a.submobjects) == len(b.submobjects) - - -def test_vmobject_same_num_submobjects_become(): - a = Square() - b = RegularPolygon(n=6) - a.become(b) - assert np.array_equal(a.points, b.points) - assert len(a.submobjects) == len(b.submobjects) - - -def test_vmobject_different_num_points_and_submobjects_become(): - a = Square() - b = VGroup(Circle(), Square()) - a.become(b) - assert np.array_equal(a.points, b.points) - assert len(a.submobjects) == len(b.submobjects) - - -def test_vmobject_point_at_angle(): - a = Circle() - p = a.point_at_angle(4 * PI) - assert np.array_equal(a.points[0], p) diff --git a/tests/utils/GraphicalUnitTester.py b/tests/utils/GraphicalUnitTester.py deleted file mode 100644 index 1e86c88bee..0000000000 --- a/tests/utils/GraphicalUnitTester.py +++ /dev/null @@ -1,149 +0,0 @@ -from __future__ import annotations - -import logging -import os - -import numpy as np - -from manim import config, tempconfig -from manim.renderer.opengl_renderer import OpenGLRenderer - - -class GraphicalUnitTester: - """Class used to test the animations. - - Parameters - ---------- - scene_class : :class:`~.Scene` - The scene to be tested - config_scene : :class:`dict` - The configuration of the scene - module_tested : :class:`str` - The name of the module tested. i.e if we are testing functions of creation.py, the module will be "creation" - - Attributes - ----------- - path_tests_medias_cache : : class:`str` - Path to 'media' folder generated by manim. This folder contains cached data used by some tests. - path_control_data : :class:`str` - Path to the data used for the tests (i.e the pre-rendered frames). - scene : :class:`Scene` - The scene tested - """ - - def __init__(self, scene_class, module_tested, tmpdir, rgb_atol=0): - # Disable the the logs, (--quiet is broken) TODO - logging.disable(logging.CRITICAL) - tests_directory = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) - self.path_tests_medias_cache = os.path.join( - tmpdir, - "test_graphical_units", - "tests_cache", - module_tested, - scene_class.__name__, - ) - self.path_control_data = os.path.join( - tests_directory, - "control_data", - "graphical_units_data", - module_tested, - ) - self.rgb_atol = rgb_atol - - # IMPORTANT NOTE : The graphical units tests don't use for now any - # custom manim.cfg, since it is impossible to manually select a - # manim.cfg from a python file. (see issue #293) - config["text_dir"] = os.path.join(self.path_tests_medias_cache, "Text") - config["tex_dir"] = os.path.join(self.path_tests_medias_cache, "Tex") - - config["disable_caching"] = True - config["quality"] = "low_quality" - - for dir_temp in [ - self.path_tests_medias_cache, - config["text_dir"], - config["tex_dir"], - ]: - os.makedirs(dir_temp) - - with tempconfig({"dry_run": True}): - if config["renderer"] == "opengl": - self.scene = scene_class(renderer=OpenGLRenderer()) - else: - self.scene = scene_class(skip_animations=True) - self.scene.render() - - def _load_data(self): - """Load the np.array of the last frame of a pre-rendered scene. If not found, throw FileNotFoundError. - - Returns - ------- - :class:`numpy.array` - The pre-rendered frame. - """ - frame_data_path = os.path.join( - os.path.join(self.path_control_data, f"{self.scene}.npz"), - ) - return np.load(frame_data_path)["frame_data"] - - def _show_diff_helper(self, frame_data, expected_frame_data): - """Will visually display with matplotlib differences between frame generated and the one expected.""" - import matplotlib.gridspec as gridspec # type: ignore - import matplotlib.pyplot as plt - - gs = gridspec.GridSpec(2, 2) - fig = plt.figure() - fig.suptitle(f"Test for {str(self.scene).replace('Test', '')}", fontsize=16) - - ax = fig.add_subplot(gs[0, 0]) - ax.imshow(frame_data) - ax.set_title("Generated :") - - ax = fig.add_subplot(gs[0, 1]) - ax.imshow(expected_frame_data) - ax.set_title("Expected :") - - ax = fig.add_subplot(gs[1, :]) - diff_im = expected_frame_data.copy() - diff_im = np.where( - frame_data != np.array([0, 0, 0, 255]), - np.array([0, 255, 0, 255], dtype="uint8"), - np.array([0, 0, 0, 255], dtype="uint8"), - ) # Set any non-black pixels to green - np.putmask( - diff_im, - expected_frame_data != frame_data, - np.array([255, 0, 0, 255], dtype="uint8"), - ) # Set any different pixels to red - ax.imshow(diff_im, interpolation="nearest") - ax.set_title("Differences summary : (green = same, red = different)") - - plt.show() - plt.savefig(f"{self.scene}.png") - - def test(self, show_diff=False): - """Compare pre-rendered frame to the frame rendered during the test.""" - frame_data = self.scene.renderer.get_frame() - expected_frame_data = self._load_data() - - assert frame_data.shape == expected_frame_data.shape, ( - "The frames have different shape:" - + f"\nexpected_frame_data.shape = {expected_frame_data.shape}" - + f"\nframe_data.shape = {frame_data.shape}" - ) - - mismatches = np.logical_not( - np.isclose(frame_data, expected_frame_data, atol=self.rgb_atol, rtol=0), - ) - if mismatches.any(): - incorrect_indices = np.argwhere(mismatches) - first_incorrect_index = incorrect_indices[0][:2] - first_incorrect_point = frame_data[tuple(first_incorrect_index)] - expected_point = expected_frame_data[tuple(first_incorrect_index)] - if show_diff: - self._show_diff_helper(frame_data, expected_frame_data) - assert not mismatches.any(), ( - f"The frames don't match. {str(self.scene).replace('Test', '')} has been modified." - + "\nPlease ignore if it was intended." - + f"\nFirst unmatched index is at {first_incorrect_index}: {first_incorrect_point} != {expected_point}" - ) diff --git a/tests/utils/logging_tester.py b/tests/utils/logging_tester.py index 5e40f42195..1fd8b4b165 100644 --- a/tests/utils/logging_tester.py +++ b/tests/utils/logging_tester.py @@ -4,16 +4,16 @@ import json import os from functools import wraps +from pathlib import Path import pytest -def _check_logs(reference_logfile, generated_logfile): - with open(reference_logfile) as reference_logs, open( - generated_logfile, - ) as generated_logs: - reference_logs = reference_logs.readlines() - generated_logs = generated_logs.readlines() +def _check_logs(reference_logfile_path: Path, generated_logfile_path: Path) -> None: + with reference_logfile_path.open() as reference_logfile: + reference_logs = reference_logfile.readlines() + with generated_logfile_path.open() as generated_logfile: + generated_logs = generated_logfile.readlines() diff = abs(len(reference_logs) - len(generated_logs)) if len(reference_logs) != len(generated_logs): msg_assert = "" @@ -26,7 +26,7 @@ def _check_logs(reference_logfile, generated_logfile): for log in generated_logs[len(reference_logs) :]: msg_assert += log msg_assert += f"\nPath of reference log: {reference_logfile}\nPath of generated logs: {generated_logfile}" - pytest.fail(msg_assert + reference_logfile + " " + generated_logfile) + pytest.fail(msg_assert) for index, ref, gen in zip(itertools.count(), reference_logs, generated_logs): # As they are string, we only need to check if they are equal. If they are not, we then compute a more precise difference, to debug. @@ -46,17 +46,19 @@ def _check_logs(reference_logfile, generated_logfile): ) -def logs_comparison(control_data_file, log_path_from_media_dir): +def logs_comparison( + control_data_file: str | os.PathLike, log_path_from_media_dir: str | os.PathLike +): """Decorator used for any test that needs to check logs. Parameters ---------- - control_data_file : :class:`str` + control_data_file Name of the control data file, i.e. .log that will be compared to the outputted logs. .. warning:: You don't have to pass the path here. .. example:: "SquareToCircleWithLFlag.log" - log_path_from_media_dir : :class:`str` + log_path_from_media_dir The path of the .log generated, from the media dir. Example: /logs/Square.log. Returns @@ -64,6 +66,8 @@ def logs_comparison(control_data_file, log_path_from_media_dir): Callable[[Any], Any] The test wrapped with which we are going to make the comparison. """ + control_data_file = Path(control_data_file) + log_path_from_media_dir = Path(log_path_from_media_dir) def decorator(f): @wraps(f) @@ -71,25 +75,20 @@ def wrapper(*args, **kwargs): # NOTE : Every args goes seemingly in kwargs instead of args; this is perhaps Pytest. result = f(*args, **kwargs) tmp_path = kwargs["tmp_path"] - tests_directory = os.path.dirname( - os.path.dirname(os.path.abspath(__file__)), - ) - control_data_path = os.path.join( - tests_directory, - "control_data", - "logs_data", - control_data_file, + tests_directory = Path(__file__).absolute().parent.parent + control_data_path = ( + tests_directory / "control_data" / "logs_data" / control_data_file ) path_log_generated = tmp_path / log_path_from_media_dir # The following will say precisely which subdir does not exist. - if not os.path.exists(path_log_generated): + if not path_log_generated.exists(): for parent in reversed(path_log_generated.parents): if not parent.exists(): pytest.fail( f"'{parent.name}' does not exist in '{parent.parent}' (which exists). ", ) break - _check_logs(control_data_path, str(path_log_generated)) + _check_logs(control_data_path, path_log_generated) return result return wrapper diff --git a/tests/utils/testing_utils.py b/tests/utils/testing_utils.py index 8c4729742f..f87dda4d7e 100644 --- a/tests/utils/testing_utils.py +++ b/tests/utils/testing_utils.py @@ -4,12 +4,12 @@ import sys -def get_scenes_to_test(module_name): +def get_scenes_to_test(module_name: str): """Get all Test classes of the module from which it is called. Used to fetch all the SceneTest of the module. Parameters ---------- - module_name : :class:`str` + module_name The name of the module tested. Returns diff --git a/tests/utils/video_tester.py b/tests/utils/video_tester.py index ec3308006f..21b136b305 100644 --- a/tests/utils/video_tester.py +++ b/tests/utils/video_tester.py @@ -2,8 +2,9 @@ import json import os -import pathlib from functools import wraps +from pathlib import Path +from typing import Any from manim import get_video_metadata @@ -11,12 +12,12 @@ from ..helpers.video_utils import get_section_dir_layout, get_section_index -def load_control_data(path_to_data): - with open(path_to_data) as f: +def load_control_data(path_to_data: Path) -> Any: + with path_to_data.open() as f: return json.load(f) -def check_video_data(path_control_data, path_video_gen): +def check_video_data(path_control_data: Path, path_video_gen: Path) -> None: """Compare control data with generated output. Used abbreviations: exp -> expected @@ -25,10 +26,7 @@ def check_video_data(path_control_data, path_video_gen): meta -> metadata """ # movie file specification - path_sec_gen = os.path.join( - pathlib.Path(path_video_gen).parent.absolute(), - "sections", - ) + path_sec_gen = path_video_gen.parent.absolute() / "sections" control_data = load_control_data(path_control_data) movie_meta_gen = get_video_metadata(path_video_gen) movie_meta_exp = control_data["movie_metadata"] @@ -51,8 +49,8 @@ def check_video_data(path_control_data, path_video_gen): raise AssertionError(f"Sections don't match:\n{mismatch}") # sections index file - scene_name = "".join(os.path.basename(path_video_gen).split(".")[:-1]) - path_sec_index_gen = os.path.join(path_sec_gen, f"{scene_name}.json") + scene_name = path_video_gen.stem + path_sec_index_gen = path_sec_gen / f"{scene_name}.json" sec_index_gen = get_section_index(path_sec_index_gen) sec_index_exp = control_data["section_index"] @@ -70,7 +68,9 @@ def check_video_data(path_control_data, path_video_gen): ) -def video_comparison(control_data_file, scene_path_from_media_dir): +def video_comparison( + control_data_file: str | os.PathLike, scene_path_from_media_dir: str | os.PathLike +): """Decorator used for any test that needs to check a rendered scene/video. .. warning:: @@ -79,17 +79,19 @@ def video_comparison(control_data_file, scene_path_from_media_dir): Parameters ---------- - control_data_file : :class:`str` + control_data_file Name of the control data file, i.e. the .json containing all the pre-rendered references of the scene tested. .. warning:: You don't have to pass the path here. - scene_path_from_media_dir : :class:`str` + scene_path_from_media_dir The path of the scene generated, from the media dir. Example: /videos/1080p60/SquareToCircle.mp4. See Also -------- tests/helpers/video_utils.py : create control data """ + control_data_file = Path(control_data_file) + scene_path_from_media_dir = Path(scene_path_from_media_dir) def decorator(f): @wraps(f) @@ -97,25 +99,20 @@ def wrapper(*args, **kwargs): # NOTE : Every args goes seemingly in kwargs instead of args; this is perhaps Pytest. result = f(*args, **kwargs) tmp_path = kwargs["tmp_path"] - tests_directory = os.path.dirname( - os.path.dirname(os.path.abspath(__file__)), - ) - path_control_data = os.path.join( - tests_directory, - "control_data", - "videos_data", - control_data_file, + tests_directory = Path(__file__).absolute().parent.parent + path_control_data = ( + tests_directory / "control_data" / "videos_data" / control_data_file ) path_video_gen = tmp_path / scene_path_from_media_dir - if not os.path.exists(path_video_gen): + if not path_video_gen.exists(): for parent in reversed(path_video_gen.parents): if not parent.exists(): raise AssertionError( f"'{parent.name}' does not exist in '{parent.parent}' (which exists). ", ) # TODO: use when pytest --set_test option - # save_control_data_from_video(path_video_gen, control_data_file[:-5]) - check_video_data(path_control_data, str(path_video_gen)) + # save_control_data_from_video(path_video_gen, control_data_file.stem) + check_video_data(path_control_data, path_video_gen) return result return wrapper diff --git a/uv.lock b/uv.lock new file mode 100644 index 0000000000..64a81f1c26 --- /dev/null +++ b/uv.lock @@ -0,0 +1,3854 @@ +version = 1 +requires-python = ">=3.9" +resolution-markers = [ + "python_full_version < '3.10'", + "python_full_version >= '3.10' and python_full_version < '3.13'", + "python_full_version >= '3.13'", +] + +[[package]] +name = "alabaster" +version = "0.7.16" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c9/3e/13dd8e5ed9094e734ac430b5d0eb4f2bb001708a8b7856cbf8e084e001ba/alabaster-0.7.16.tar.gz", hash = "sha256:75a8b99c28a5dad50dd7f8ccdd447a121ddb3892da9e53d1ca5cca3106d58d65", size = 23776 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/34/d4e1c02d3bee589efb5dfa17f88ea08bdb3e3eac12bc475462aec52ed223/alabaster-0.7.16-py3-none-any.whl", hash = "sha256:b46733c07dce03ae4e150330b975c75737fa60f0a7c591b6c8bf4928a28e2c92", size = 13511 }, +] + +[[package]] +name = "anyio" +version = "4.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "idna" }, + { name = "sniffio" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a3/73/199a98fc2dae33535d6b8e8e6ec01f8c1d76c9adb096c6b7d64823038cde/anyio-4.8.0.tar.gz", hash = "sha256:1d9fe889df5212298c0c0723fa20479d1b94883a2df44bd3897aa91083316f7a", size = 181126 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/eb/e7f063ad1fec6b3178a3cd82d1a3c4de82cccf283fc42746168188e1cdd5/anyio-4.8.0-py3-none-any.whl", hash = "sha256:b5011f270ab5eb0abf13385f851315585cc37ef330dd88e27ec3d34d651fd47a", size = 96041 }, +] + +[[package]] +name = "appnope" +version = "0.1.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/35/5d/752690df9ef5b76e169e68d6a129fa6d08a7100ca7f754c89495db3c6019/appnope-0.1.4.tar.gz", hash = "sha256:1de3860566df9caf38f01f86f65e0e13e379af54f9e4bee1e66b48f2efffd1ee", size = 4170 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/29/5ecc3a15d5a33e31b26c11426c45c501e439cb865d0bff96315d86443b78/appnope-0.1.4-py2.py3-none-any.whl", hash = "sha256:502575ee11cd7a28c0205f379b525beefebab9d161b7c964670864014ed7213c", size = 4321 }, +] + +[[package]] +name = "argon2-cffi" +version = "23.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "argon2-cffi-bindings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/31/fa/57ec2c6d16ecd2ba0cf15f3c7d1c3c2e7b5fcb83555ff56d7ab10888ec8f/argon2_cffi-23.1.0.tar.gz", hash = "sha256:879c3e79a2729ce768ebb7d36d4609e3a78a4ca2ec3a9f12286ca057e3d0db08", size = 42798 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a4/6a/e8a041599e78b6b3752da48000b14c8d1e8a04ded09c88c714ba047f34f5/argon2_cffi-23.1.0-py3-none-any.whl", hash = "sha256:c670642b78ba29641818ab2e68bd4e6a78ba53b7eff7b4c3815ae16abf91c7ea", size = 15124 }, +] + +[[package]] +name = "argon2-cffi-bindings" +version = "21.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b9/e9/184b8ccce6683b0aa2fbb7ba5683ea4b9c5763f1356347f1312c32e3c66e/argon2-cffi-bindings-21.2.0.tar.gz", hash = "sha256:bb89ceffa6c791807d1305ceb77dbfacc5aa499891d2c55661c6459651fc39e3", size = 1779911 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d4/13/838ce2620025e9666aa8f686431f67a29052241692a3dd1ae9d3692a89d3/argon2_cffi_bindings-21.2.0-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:ccb949252cb2ab3a08c02024acb77cfb179492d5701c7cbdbfd776124d4d2367", size = 29658 }, + { url = "https://files.pythonhosted.org/packages/b3/02/f7f7bb6b6af6031edb11037639c697b912e1dea2db94d436e681aea2f495/argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9524464572e12979364b7d600abf96181d3541da11e23ddf565a32e70bd4dc0d", size = 80583 }, + { url = "https://files.pythonhosted.org/packages/ec/f7/378254e6dd7ae6f31fe40c8649eea7d4832a42243acaf0f1fff9083b2bed/argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b746dba803a79238e925d9046a63aa26bf86ab2a2fe74ce6b009a1c3f5c8f2ae", size = 86168 }, + { url = "https://files.pythonhosted.org/packages/74/f6/4a34a37a98311ed73bb80efe422fed95f2ac25a4cacc5ae1d7ae6a144505/argon2_cffi_bindings-21.2.0-cp36-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:58ed19212051f49a523abb1dbe954337dc82d947fb6e5a0da60f7c8471a8476c", size = 82709 }, + { url = "https://files.pythonhosted.org/packages/74/2b/73d767bfdaab25484f7e7901379d5f8793cccbb86c6e0cbc4c1b96f63896/argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:bd46088725ef7f58b5a1ef7ca06647ebaf0eb4baff7d1d0d177c6cc8744abd86", size = 83613 }, + { url = "https://files.pythonhosted.org/packages/4f/fd/37f86deef67ff57c76f137a67181949c2d408077e2e3dd70c6c42912c9bf/argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_i686.whl", hash = "sha256:8cd69c07dd875537a824deec19f978e0f2078fdda07fd5c42ac29668dda5f40f", size = 84583 }, + { url = "https://files.pythonhosted.org/packages/6f/52/5a60085a3dae8fded8327a4f564223029f5f54b0cb0455a31131b5363a01/argon2_cffi_bindings-21.2.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:f1152ac548bd5b8bcecfb0b0371f082037e47128653df2e8ba6e914d384f3c3e", size = 88475 }, + { url = "https://files.pythonhosted.org/packages/8b/95/143cd64feb24a15fa4b189a3e1e7efbaeeb00f39a51e99b26fc62fbacabd/argon2_cffi_bindings-21.2.0-cp36-abi3-win32.whl", hash = "sha256:603ca0aba86b1349b147cab91ae970c63118a0f30444d4bc80355937c950c082", size = 27698 }, + { url = "https://files.pythonhosted.org/packages/37/2c/e34e47c7dee97ba6f01a6203e0383e15b60fb85d78ac9a15cd066f6fe28b/argon2_cffi_bindings-21.2.0-cp36-abi3-win_amd64.whl", hash = "sha256:b2ef1c30440dbbcba7a5dc3e319408b59676e2e039e2ae11a8775ecf482b192f", size = 30817 }, + { url = "https://files.pythonhosted.org/packages/5a/e4/bf8034d25edaa495da3c8a3405627d2e35758e44ff6eaa7948092646fdcc/argon2_cffi_bindings-21.2.0-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e415e3f62c8d124ee16018e491a009937f8cf7ebf5eb430ffc5de21b900dad93", size = 53104 }, +] + +[[package]] +name = "arrow" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "python-dateutil" }, + { name = "types-python-dateutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2e/00/0f6e8fcdb23ea632c866620cc872729ff43ed91d284c866b515c6342b173/arrow-1.3.0.tar.gz", hash = "sha256:d4540617648cb5f895730f1ad8c82a65f2dad0166f57b75f3ca54759c4d67a85", size = 131960 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/ed/e97229a566617f2ae958a6b13e7cc0f585470eac730a73e9e82c32a3cdd2/arrow-1.3.0-py3-none-any.whl", hash = "sha256:c728b120ebc00eb84e01882a6f5e7927a53960aa990ce7dd2b10f39005a67f80", size = 66419 }, +] + +[[package]] +name = "asttokens" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4a/e7/82da0a03e7ba5141f05cce0d302e6eed121ae055e0456ca228bf693984bc/asttokens-3.0.0.tar.gz", hash = "sha256:0dcd8baa8d62b0c1d118b399b2ddba3c4aff271d0d7a9e0d4c1681c79035bbc7", size = 61978 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/25/8a/c46dcc25341b5bce5472c718902eb3d38600a903b14fa6aeecef3f21a46f/asttokens-3.0.0-py3-none-any.whl", hash = "sha256:e3078351a059199dd5138cb1c706e6430c05eff2ff136af5eb4790f9d28932e2", size = 26918 }, +] + +[[package]] +name = "async-lru" +version = "2.0.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/80/e2/2b4651eff771f6fd900d233e175ddc5e2be502c7eb62c0c42f975c6d36cd/async-lru-2.0.4.tar.gz", hash = "sha256:b8a59a5df60805ff63220b2a0c5b5393da5521b113cd5465a44eb037d81a5627", size = 10019 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fa/9f/3c3503693386c4b0f245eaf5ca6198e3b28879ca0a40bde6b0e319793453/async_lru-2.0.4-py3-none-any.whl", hash = "sha256:ff02944ce3c288c5be660c42dbcca0742b32c3b279d6dceda655190240b99224", size = 6111 }, +] + +[[package]] +name = "attrs" +version = "25.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/49/7c/fdf464bcc51d23881d110abd74b512a42b3d5d376a55a831b44c603ae17f/attrs-25.1.0.tar.gz", hash = "sha256:1c97078a80c814273a76b2a298a932eb681c87415c11dee0a6921de7f1b02c3e", size = 810562 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fc/30/d4986a882011f9df997a55e6becd864812ccfcd821d64aac8570ee39f719/attrs-25.1.0-py3-none-any.whl", hash = "sha256:c75a69e28a550a7e93789579c22aa26b0f5b83b75dc4e08fe092980051e1090a", size = 63152 }, +] + +[[package]] +name = "audioop-lts" +version = "0.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/dd/3b/69ff8a885e4c1c42014c2765275c4bd91fe7bc9847e9d8543dbcbb09f820/audioop_lts-0.2.1.tar.gz", hash = "sha256:e81268da0baa880431b68b1308ab7257eb33f356e57a5f9b1f915dfb13dd1387", size = 30204 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/01/91/a219253cc6e92db2ebeaf5cf8197f71d995df6f6b16091d1f3ce62cb169d/audioop_lts-0.2.1-cp313-abi3-macosx_10_13_universal2.whl", hash = "sha256:fd1345ae99e17e6910f47ce7d52673c6a1a70820d78b67de1b7abb3af29c426a", size = 46252 }, + { url = "https://files.pythonhosted.org/packages/ec/f6/3cb21e0accd9e112d27cee3b1477cd04dafe88675c54ad8b0d56226c1e0b/audioop_lts-0.2.1-cp313-abi3-macosx_10_13_x86_64.whl", hash = "sha256:e175350da05d2087e12cea8e72a70a1a8b14a17e92ed2022952a4419689ede5e", size = 27183 }, + { url = "https://files.pythonhosted.org/packages/ea/7e/f94c8a6a8b2571694375b4cf94d3e5e0f529e8e6ba280fad4d8c70621f27/audioop_lts-0.2.1-cp313-abi3-macosx_11_0_arm64.whl", hash = "sha256:4a8dd6a81770f6ecf019c4b6d659e000dc26571b273953cef7cd1d5ce2ff3ae6", size = 26726 }, + { url = "https://files.pythonhosted.org/packages/ef/f8/a0e8e7a033b03fae2b16bc5aa48100b461c4f3a8a38af56d5ad579924a3a/audioop_lts-0.2.1-cp313-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1cd3c0b6f2ca25c7d2b1c3adeecbe23e65689839ba73331ebc7d893fcda7ffe", size = 80718 }, + { url = "https://files.pythonhosted.org/packages/8f/ea/a98ebd4ed631c93b8b8f2368862cd8084d75c77a697248c24437c36a6f7e/audioop_lts-0.2.1-cp313-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ff3f97b3372c97782e9c6d3d7fdbe83bce8f70de719605bd7ee1839cd1ab360a", size = 88326 }, + { url = "https://files.pythonhosted.org/packages/33/79/e97a9f9daac0982aa92db1199339bd393594d9a4196ad95ae088635a105f/audioop_lts-0.2.1-cp313-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a351af79edefc2a1bd2234bfd8b339935f389209943043913a919df4b0f13300", size = 80539 }, + { url = "https://files.pythonhosted.org/packages/b2/d3/1051d80e6f2d6f4773f90c07e73743a1e19fcd31af58ff4e8ef0375d3a80/audioop_lts-0.2.1-cp313-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2aeb6f96f7f6da80354330470b9134d81b4cf544cdd1c549f2f45fe964d28059", size = 78577 }, + { url = "https://files.pythonhosted.org/packages/7a/1d/54f4c58bae8dc8c64a75071c7e98e105ddaca35449376fcb0180f6e3c9df/audioop_lts-0.2.1-cp313-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c589f06407e8340e81962575fcffbba1e92671879a221186c3d4662de9fe804e", size = 82074 }, + { url = "https://files.pythonhosted.org/packages/36/89/2e78daa7cebbea57e72c0e1927413be4db675548a537cfba6a19040d52fa/audioop_lts-0.2.1-cp313-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fbae5d6925d7c26e712f0beda5ed69ebb40e14212c185d129b8dfbfcc335eb48", size = 84210 }, + { url = "https://files.pythonhosted.org/packages/a5/57/3ff8a74df2ec2fa6d2ae06ac86e4a27d6412dbb7d0e0d41024222744c7e0/audioop_lts-0.2.1-cp313-abi3-musllinux_1_2_i686.whl", hash = "sha256:d2d5434717f33117f29b5691fbdf142d36573d751716249a288fbb96ba26a281", size = 85664 }, + { url = "https://files.pythonhosted.org/packages/16/01/21cc4e5878f6edbc8e54be4c108d7cb9cb6202313cfe98e4ece6064580dd/audioop_lts-0.2.1-cp313-abi3-musllinux_1_2_ppc64le.whl", hash = "sha256:f626a01c0a186b08f7ff61431c01c055961ee28769591efa8800beadd27a2959", size = 93255 }, + { url = "https://files.pythonhosted.org/packages/3e/28/7f7418c362a899ac3b0bf13b1fde2d4ffccfdeb6a859abd26f2d142a1d58/audioop_lts-0.2.1-cp313-abi3-musllinux_1_2_s390x.whl", hash = "sha256:05da64e73837f88ee5c6217d732d2584cf638003ac72df124740460531e95e47", size = 87760 }, + { url = "https://files.pythonhosted.org/packages/6d/d8/577a8be87dc7dd2ba568895045cee7d32e81d85a7e44a29000fe02c4d9d4/audioop_lts-0.2.1-cp313-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:56b7a0a4dba8e353436f31a932f3045d108a67b5943b30f85a5563f4d8488d77", size = 84992 }, + { url = "https://files.pythonhosted.org/packages/ef/9a/4699b0c4fcf89936d2bfb5425f55f1a8b86dff4237cfcc104946c9cd9858/audioop_lts-0.2.1-cp313-abi3-win32.whl", hash = "sha256:6e899eb8874dc2413b11926b5fb3857ec0ab55222840e38016a6ba2ea9b7d5e3", size = 26059 }, + { url = "https://files.pythonhosted.org/packages/3a/1c/1f88e9c5dd4785a547ce5fd1eb83fff832c00cc0e15c04c1119b02582d06/audioop_lts-0.2.1-cp313-abi3-win_amd64.whl", hash = "sha256:64562c5c771fb0a8b6262829b9b4f37a7b886c01b4d3ecdbae1d629717db08b4", size = 30412 }, + { url = "https://files.pythonhosted.org/packages/c4/e9/c123fd29d89a6402ad261516f848437472ccc602abb59bba522af45e281b/audioop_lts-0.2.1-cp313-abi3-win_arm64.whl", hash = "sha256:c45317debeb64002e980077642afbd977773a25fa3dfd7ed0c84dccfc1fafcb0", size = 23578 }, + { url = "https://files.pythonhosted.org/packages/7a/99/bb664a99561fd4266687e5cb8965e6ec31ba4ff7002c3fce3dc5ef2709db/audioop_lts-0.2.1-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:3827e3fce6fee4d69d96a3d00cd2ab07f3c0d844cb1e44e26f719b34a5b15455", size = 46827 }, + { url = "https://files.pythonhosted.org/packages/c4/e3/f664171e867e0768ab982715e744430cf323f1282eb2e11ebfb6ee4c4551/audioop_lts-0.2.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:161249db9343b3c9780ca92c0be0d1ccbfecdbccac6844f3d0d44b9c4a00a17f", size = 27479 }, + { url = "https://files.pythonhosted.org/packages/a6/0d/2a79231ff54eb20e83b47e7610462ad6a2bea4e113fae5aa91c6547e7764/audioop_lts-0.2.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:5b7b4ff9de7a44e0ad2618afdc2ac920b91f4a6d3509520ee65339d4acde5abf", size = 27056 }, + { url = "https://files.pythonhosted.org/packages/86/46/342471398283bb0634f5a6df947806a423ba74b2e29e250c7ec0e3720e4f/audioop_lts-0.2.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:72e37f416adb43b0ced93419de0122b42753ee74e87070777b53c5d2241e7fab", size = 87802 }, + { url = "https://files.pythonhosted.org/packages/56/44/7a85b08d4ed55517634ff19ddfbd0af05bf8bfd39a204e4445cd0e6f0cc9/audioop_lts-0.2.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:534ce808e6bab6adb65548723c8cbe189a3379245db89b9d555c4210b4aaa9b6", size = 95016 }, + { url = "https://files.pythonhosted.org/packages/a8/2a/45edbca97ea9ee9e6bbbdb8d25613a36e16a4d1e14ae01557392f15cc8d3/audioop_lts-0.2.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d2de9b6fb8b1cf9f03990b299a9112bfdf8b86b6987003ca9e8a6c4f56d39543", size = 87394 }, + { url = "https://files.pythonhosted.org/packages/14/ae/832bcbbef2c510629593bf46739374174606e25ac7d106b08d396b74c964/audioop_lts-0.2.1-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f24865991b5ed4b038add5edbf424639d1358144f4e2a3e7a84bc6ba23e35074", size = 84874 }, + { url = "https://files.pythonhosted.org/packages/26/1c/8023c3490798ed2f90dfe58ec3b26d7520a243ae9c0fc751ed3c9d8dbb69/audioop_lts-0.2.1-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bdb3b7912ccd57ea53197943f1bbc67262dcf29802c4a6df79ec1c715d45a78", size = 88698 }, + { url = "https://files.pythonhosted.org/packages/2c/db/5379d953d4918278b1f04a5a64b2c112bd7aae8f81021009da0dcb77173c/audioop_lts-0.2.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:120678b208cca1158f0a12d667af592e067f7a50df9adc4dc8f6ad8d065a93fb", size = 90401 }, + { url = "https://files.pythonhosted.org/packages/99/6e/3c45d316705ab1aec2e69543a5b5e458d0d112a93d08994347fafef03d50/audioop_lts-0.2.1-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:54cd4520fc830b23c7d223693ed3e1b4d464997dd3abc7c15dce9a1f9bd76ab2", size = 91864 }, + { url = "https://files.pythonhosted.org/packages/08/58/6a371d8fed4f34debdb532c0b00942a84ebf3e7ad368e5edc26931d0e251/audioop_lts-0.2.1-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:d6bd20c7a10abcb0fb3d8aaa7508c0bf3d40dfad7515c572014da4b979d3310a", size = 98796 }, + { url = "https://files.pythonhosted.org/packages/ee/77/d637aa35497e0034ff846fd3330d1db26bc6fd9dd79c406e1341188b06a2/audioop_lts-0.2.1-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:f0ed1ad9bd862539ea875fb339ecb18fcc4148f8d9908f4502df28f94d23491a", size = 94116 }, + { url = "https://files.pythonhosted.org/packages/1a/60/7afc2abf46bbcf525a6ebc0305d85ab08dc2d1e2da72c48dbb35eee5b62c/audioop_lts-0.2.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e1af3ff32b8c38a7d900382646e91f2fc515fd19dea37e9392275a5cbfdbff63", size = 91520 }, + { url = "https://files.pythonhosted.org/packages/65/6d/42d40da100be1afb661fd77c2b1c0dfab08af1540df57533621aea3db52a/audioop_lts-0.2.1-cp313-cp313t-win32.whl", hash = "sha256:f51bb55122a89f7a0817d7ac2319744b4640b5b446c4c3efcea5764ea99ae509", size = 26482 }, + { url = "https://files.pythonhosted.org/packages/01/09/f08494dca79f65212f5b273aecc5a2f96691bf3307cac29acfcf84300c01/audioop_lts-0.2.1-cp313-cp313t-win_amd64.whl", hash = "sha256:f0f2f336aa2aee2bce0b0dcc32bbba9178995454c7b979cf6ce086a8801e14c7", size = 30780 }, + { url = "https://files.pythonhosted.org/packages/5d/35/be73b6015511aa0173ec595fc579133b797ad532996f2998fd6b8d1bbe6b/audioop_lts-0.2.1-cp313-cp313t-win_arm64.whl", hash = "sha256:78bfb3703388c780edf900be66e07de5a3d4105ca8e8720c5c4d67927e0b15d0", size = 23918 }, +] + +[[package]] +name = "av" +version = "13.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0c/9d/486d31e76784cc0ad943f420c5e05867263b32b37e2f4b0f7f22fdc1ca3a/av-13.1.0.tar.gz", hash = "sha256:d3da736c55847d8596eb8c26c60e036f193001db3bc5c10da8665622d906c17e", size = 3957908 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/d6/1c4a8056a88e006681ac6a3d5ac6082f0a48e52bd565bfd350bfc7c6a37d/av-13.1.0-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:a2af44fae6d16c3a40dd1c85bda41b449be08a2c172d8f44fb63395ccf6e6fb4", size = 24260057 }, + { url = "https://files.pythonhosted.org/packages/23/be/cf89545117172d75a0c48066e6f368403237df623b2e3e93590fdeaef8bf/av-13.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:0fea71fe06fd0dfe90a089200eb6468034797f860a321fa2d62e07d619c74749", size = 19475039 }, + { url = "https://files.pythonhosted.org/packages/4b/d0/8e261547f7763f320a4f5f68e139fea5f31814fddfe5503c8372123ebb8b/av-13.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:756997810dcca11811b598d209561cabd2071e5b472b867c295bb3e7022eecde", size = 31289005 }, + { url = "https://files.pythonhosted.org/packages/82/a3/00cacfe80ebbe0664876dd26558fb23b65d034ffd2ce0ddb12f1c746e7cb/av-13.1.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7f432102edaec4ee90087a675acf486bff0c81b47d98b85eb3218afe84575b60", size = 30705668 }, + { url = "https://files.pythonhosted.org/packages/d7/37/faa98dca1a8f6c2e3f4ad3a935037872aff49a679b76918c5258cf5a1c70/av-13.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1d568c4d7a36df52c0774d52e6d730148775ead16daed81c10dafc2569b5a38d", size = 33122108 }, + { url = "https://files.pythonhosted.org/packages/25/81/c3a842477b558e23c7249f81cf723764c193636b6523267c2c02321da6b0/av-13.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:aa6f76e7c5e77bc5f99a27ada29f78c64fd4e0d42da2c4d203badc650bc0a686", size = 25775920 }, + { url = "https://files.pythonhosted.org/packages/39/54/c4227080c9700384db90072ace70d89b6a288b3748bd2ec0e32580a49e7f/av-13.1.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:867385e6701464a5c95903e24d2e0df1c7e0dbf211ed91d0ce639cd687373e10", size = 24255112 }, + { url = "https://files.pythonhosted.org/packages/32/4a/eb9348231655ca99b200b380f4edbceff7358c927a285badcc84b18fb1c9/av-13.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:cb7a3f319401a46b0017771268ff4928501e77cf00b1a2aa0721e20b2fd1146e", size = 19467930 }, + { url = "https://files.pythonhosted.org/packages/14/c7/48c80252bdbc3a75a54dd205a7fab8f613914009b9e5416202757208e040/av-13.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad904f860147bceaca65b0d3174a8153f35c570d465161d210f1879970b15559", size = 32207671 }, + { url = "https://files.pythonhosted.org/packages/f9/66/3332c7fa8c43b65680a94f279ea3e832b5500de3a1392bac6112881e984b/av-13.1.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a906e017b29d0eb80d9ccf7a98d19268122da792dbb68eb741cfebba156e6aed", size = 31520911 }, + { url = "https://files.pythonhosted.org/packages/e5/bb/2e03acb9b27591d97f700a3a6c27cfd1bc53fa148177747eda8a70cca1e9/av-13.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ce894d7847897da7be63277a0875bd93c51327134ac226c67978de014c7979f", size = 34048399 }, + { url = "https://files.pythonhosted.org/packages/85/44/527aa3b65947d42cfe829326026edf0cd1a8c459390076034be275616c36/av-13.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:384bcdb5fc3238a263a5a25cc9efc690859fa4148cc4b07e00fae927178db22a", size = 25779569 }, + { url = "https://files.pythonhosted.org/packages/9b/aa/4bdd8ce59173574fc6e0c282c71ee6f96fca82643d97bf172bc4cb5a5674/av-13.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:261dbc3f4b55f4f8f3375b10b2258fca7f2ab7a6365c01bc65e77a0d5327a195", size = 24268674 }, + { url = "https://files.pythonhosted.org/packages/17/b4/b267dd5bad99eed49ec6731827c6bcb5ab03864bf732a7ebb81e3df79911/av-13.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:83d259ef86b9054eb914bc7c6a7f6092a6d75cb939295e70ee979cfd92a67b99", size = 19475617 }, + { url = "https://files.pythonhosted.org/packages/68/32/4209e51f54d7b54a1feb576d309c671ed1ff437b54fcc4ec68c239199e0a/av-13.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f3b4d3ca159eceab97e3c0fb08fe756520fb95508417f76e48198fda2a5b0806", size = 32468873 }, + { url = "https://files.pythonhosted.org/packages/b6/d8/c174da5f06b24f3c9e36f91fd02a7411c39da9ce792c17964260d4be675e/av-13.1.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40e8f757e373b73a2dc4640852a00cce4a4a92ef19b2e642a96d6994cd1fffbf", size = 31818484 }, + { url = "https://files.pythonhosted.org/packages/7f/22/0dd8d1d5cad415772bb707d16aea8b81cf75d340d11d3668eea43468c730/av-13.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8aaec2c0bfd024359db3821d679009d4e637e1bee0321d20f61c54ed6b20f41", size = 34398652 }, + { url = "https://files.pythonhosted.org/packages/7b/ff/48fa68888b8d5bae36d915556ff18f9e5fdc6b5ff5ae23dc4904c9713168/av-13.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:5ea0deab0e6a739cb742fba2a3983d8102f7516a3cdf3c46669f3cac0ed1f351", size = 25781343 }, + { url = "https://files.pythonhosted.org/packages/82/6e/cdce12e534570df37d3fdcb3a74851d39e9ab79d388f3174dea9785a011a/av-13.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:47642ebaebfe20519b2391bd5b7c38b596efcd052bfd09c8d33058f94ddd0fd6", size = 24229340 }, + { url = "https://files.pythonhosted.org/packages/7c/88/5359aeada9ea509426f2db63b6531833824a1b02470667b103479ddea7ae/av-13.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2f079c2daa3ae06557b3f6e9bed4fb9c876e8012175bec645ccd007199a302db", size = 19436445 }, + { url = "https://files.pythonhosted.org/packages/b4/d4/64995e5b800476c86dae4ea1444a0eac44e2c4985fac6401b08401e2df11/av-13.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f0de8252deeeb1887637e88d4d9d18514e5cfe276bdb9e6ca8e9eef89d1667a", size = 32120549 }, + { url = "https://files.pythonhosted.org/packages/68/76/9910694cf87d2d308d851f5b2b5c5b20f7f55411f596e2c158fb13bf84a3/av-13.1.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9ad0024f4def11b0cedfeee478fa6c6fd7ed3955e13387e0f27261fdda6121b4", size = 31495305 }, + { url = "https://files.pythonhosted.org/packages/6a/a8/cd92de947b9595a0eb2c64e6f7ba295aac2687972050ae092173c2f6ea0c/av-13.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb88e2590eaed45233eb117f1dfab1a43ed9a997b2c46da9f08468dd00f14895", size = 34065325 }, + { url = "https://files.pythonhosted.org/packages/9d/d0/9869fcbd66422df2033d4b78a663e3c64aa6fe7eb9189c811d60f69d9871/av-13.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:c927e4fa4f6aeed4340b3e3b16b237d7cb743e5c1a55b92307407590ca4112aa", size = 25754728 }, + { url = "https://files.pythonhosted.org/packages/c7/0c/472d0448442bc915f69df16034ac98986263b25b8122a7bf28be79c9faf5/av-13.1.0-cp39-cp39-macosx_10_13_x86_64.whl", hash = "sha256:fa398f0e0579bdeca4f0c31eb46e88c29562988e135e44972f73bb7525d1454e", size = 24289660 }, + { url = "https://files.pythonhosted.org/packages/f5/d4/2f3c94c9a7461012158409f786e2281cede49b83ee3c6224287abdfa42b9/av-13.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cd38601a0e83061af90106e5a312649cd04b1f0bba508f3895ac8dc7930bcf68", size = 19502324 }, + { url = "https://files.pythonhosted.org/packages/36/25/5d6e57634218fb30d078209d33289c53ee1f21de4b547fe4014994a2076c/av-13.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a18b67c5b4ad725c5cd4d0d6cd825d91e39f50654e4148cb179a02913b6bd42", size = 31443373 }, + { url = "https://files.pythonhosted.org/packages/5a/ee/893efbd7fcda2bf63ba3efcb6dd1a7dff6aeee4b8962ccb6a71eda0c08e1/av-13.1.0-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c53917f326e460e784cf599da3e2b4d5c76c02c9fd2d32c4b8e24b86b159b6ba", size = 30853824 }, + { url = "https://files.pythonhosted.org/packages/b8/24/d199453f4b66f106d9cf80f0c102985dc0b27f230e3fabf9364dbc40ecf8/av-13.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e5bc5e8a5f3811dab471c412c50b7850912d85c804f500b75358b6af93e8ee8b", size = 33267218 }, + { url = "https://files.pythonhosted.org/packages/d8/51/0389ff1c47471bb8d110d41e902cef2e2b149803692e6ad769fec6a8715c/av-13.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:6d7ae8510ff011fb4df0e0a6c50ef495a980d70968db17d138a7ccca322896cd", size = 25799430 }, + { url = "https://files.pythonhosted.org/packages/63/62/09859d91bc2309918d548ac4585973c53e7db27010c432d050f02206f9bd/av-13.1.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:fc5118f78ee712b2c396f345e4c51e60e61e28f1f606adbd4060c4dc44b0b652", size = 23861117 }, + { url = "https://files.pythonhosted.org/packages/c7/43/f186435a0acad3a2bdf271ce51d3af97ac3153a410e54a623529d39a1818/av-13.1.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:81bcbd3545e523e7a350613be1866b515a5ee3fafa1d9d257d7ed02531fc2636", size = 19115008 }, + { url = "https://files.pythonhosted.org/packages/31/eb/a1b4af95a615ba73dfc3cfcb9387e40826c92d7d6d383a1b68685a7ef920/av-13.1.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83b2bc641e8e16bbf058de35f1ba79ebed358ac6fe3cb5a665366294774fdb18", size = 22852637 }, + { url = "https://files.pythonhosted.org/packages/0b/a6/94a34aa672af7fef2939e4a5d6c4c6c28e33da0c623aaa9485d977eeaa95/av-13.1.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d956ae3e68fabdc45eb2b986c2e842a31df084d8cfc90336509f07a727a9df62", size = 22703888 }, + { url = "https://files.pythonhosted.org/packages/b9/69/08a72ceed2c8a6e689dea2ef8e941df9469cbe144a600b83d45f821477fc/av-13.1.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ef076fcdf172aafcb21ea3ef7bd68cc9151b050016a8ace13b3dae3d08a4427", size = 24657784 }, + { url = "https://files.pythonhosted.org/packages/b7/8c/c20894580a4341a76c7c74b59c43e26e6652b0fc60f7248f2c1bc5fdbb5e/av-13.1.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:bbf90397b7a466ff2879bd0944d55f796ad76c073fce50304315b83ad00113bd", size = 25562492 }, + { url = "https://files.pythonhosted.org/packages/a5/43/b5d80bc40327f763f864d92dd475e4ccd59d4202c40449e03fccb5dd01ed/av-13.1.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:3804b57d04dc512c7ae15da9499373f37b8af7a80631899a9b3afd4c9007433b", size = 23857632 }, + { url = "https://files.pythonhosted.org/packages/c7/1e/f4bb5947654354456c3cca76272b49c3fdc967241f0e72c50303384031f2/av-13.1.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:1b94ee5ee160794c9874b4977e5c4d76d7250b2fd6f27202c66a4df4ad23e822", size = 19111206 }, + { url = "https://files.pythonhosted.org/packages/c2/6f/9b6560e47463729dec795ec989bf7e099b9bd09c3d326420ec844d7faea9/av-13.1.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6073ff4202e4a0c3aecab35ef99f84a3c4b4414c4b8ae771c965a2b52394148c", size = 22847916 }, + { url = "https://files.pythonhosted.org/packages/4e/e3/fc3bd6957f8763ed21dcf0ce00969eda46670355bbd33ed2f47680e21d42/av-13.1.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c5ab17663b783e112837fb1c5f67098a561627e4a542cdf5bf1524f48478b897", size = 22699046 }, + { url = "https://files.pythonhosted.org/packages/83/1d/7f77560ede9da71851aac2bdb8880fac3d5b8f6fd811920e5ae61d9790de/av-13.1.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f422360f801a6f878d73aee4d404110ee6bb8f04846bf8815edb218da83bec49", size = 24653351 }, + { url = "https://files.pythonhosted.org/packages/f1/0e/349a7b9dbc5b617d5708dba427f52fbd80985721f2ac73e65bc73d7fb1e6/av-13.1.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:799cf56dc9399a1696e0445dcee6e17dfa67e2a76030934d678cfa7d7ae40172", size = 25561212 }, +] + +[[package]] +name = "babel" +version = "2.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2a/74/f1bc80f23eeba13393b7222b11d95ca3af2c1e28edca18af487137eefed9/babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316", size = 9348104 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ed/20/bc79bc575ba2e2a7f70e8a1155618bb1301eaa5132a8271373a6903f73f8/babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b", size = 9587599 }, +] + +[[package]] +name = "beautifulsoup4" +version = "4.12.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "soupsieve" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b3/ca/824b1195773ce6166d388573fc106ce56d4a805bd7427b624e063596ec58/beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051", size = 581181 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b1/fe/e8c672695b37eecc5cbf43e1d0638d88d66ba3a44c4d321c796f4e59167f/beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed", size = 147925 }, +] + +[[package]] +name = "bleach" +version = "6.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "webencodings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/76/9a/0e33f5054c54d349ea62c277191c020c2d6ef1d65ab2cb1993f91ec846d1/bleach-6.2.0.tar.gz", hash = "sha256:123e894118b8a599fd80d3ec1a6d4cc7ce4e5882b1317a7e1ba69b56e95f991f", size = 203083 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fc/55/96142937f66150805c25c4d0f31ee4132fd33497753400734f9dfdcbdc66/bleach-6.2.0-py3-none-any.whl", hash = "sha256:117d9c6097a7c3d22fd578fcd8d35ff1e125df6736f554da4e432fdd63f31e5e", size = 163406 }, +] + +[package.optional-dependencies] +css = [ + { name = "tinycss2" }, +] + +[[package]] +name = "certifi" +version = "2024.12.14" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/bd/1d41ee578ce09523c81a15426705dd20969f5abf006d1afe8aeff0dd776a/certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db", size = 166010 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a5/32/8f6669fc4798494966bf446c8c4a162e0b5d893dff088afddf76414f70e1/certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56", size = 164927 }, +] + +[[package]] +name = "cffi" +version = "1.17.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pycparser" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/90/07/f44ca684db4e4f08a3fdc6eeb9a0d15dc6883efc7b8c90357fdbf74e186c/cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14", size = 182191 }, + { url = "https://files.pythonhosted.org/packages/08/fd/cc2fedbd887223f9f5d170c96e57cbf655df9831a6546c1727ae13fa977a/cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67", size = 178592 }, + { url = "https://files.pythonhosted.org/packages/de/cc/4635c320081c78d6ffc2cab0a76025b691a91204f4aa317d568ff9280a2d/cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382", size = 426024 }, + { url = "https://files.pythonhosted.org/packages/b6/7b/3b2b250f3aab91abe5f8a51ada1b717935fdaec53f790ad4100fe2ec64d1/cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702", size = 448188 }, + { url = "https://files.pythonhosted.org/packages/d3/48/1b9283ebbf0ec065148d8de05d647a986c5f22586b18120020452fff8f5d/cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3", size = 455571 }, + { url = "https://files.pythonhosted.org/packages/40/87/3b8452525437b40f39ca7ff70276679772ee7e8b394934ff60e63b7b090c/cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6", size = 436687 }, + { url = "https://files.pythonhosted.org/packages/8d/fb/4da72871d177d63649ac449aec2e8a29efe0274035880c7af59101ca2232/cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17", size = 446211 }, + { url = "https://files.pythonhosted.org/packages/ab/a0/62f00bcb411332106c02b663b26f3545a9ef136f80d5df746c05878f8c4b/cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8", size = 461325 }, + { url = "https://files.pythonhosted.org/packages/36/83/76127035ed2e7e27b0787604d99da630ac3123bfb02d8e80c633f218a11d/cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e", size = 438784 }, + { url = "https://files.pythonhosted.org/packages/21/81/a6cd025db2f08ac88b901b745c163d884641909641f9b826e8cb87645942/cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be", size = 461564 }, + { url = "https://files.pythonhosted.org/packages/f8/fe/4d41c2f200c4a457933dbd98d3cf4e911870877bd94d9656cc0fcb390681/cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c", size = 171804 }, + { url = "https://files.pythonhosted.org/packages/d1/b6/0b0f5ab93b0df4acc49cae758c81fe4e5ef26c3ae2e10cc69249dfd8b3ab/cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15", size = 181299 }, + { url = "https://files.pythonhosted.org/packages/6b/f4/927e3a8899e52a27fa57a48607ff7dc91a9ebe97399b357b85a0c7892e00/cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401", size = 182264 }, + { url = "https://files.pythonhosted.org/packages/6c/f5/6c3a8efe5f503175aaddcbea6ad0d2c96dad6f5abb205750d1b3df44ef29/cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf", size = 178651 }, + { url = "https://files.pythonhosted.org/packages/94/dd/a3f0118e688d1b1a57553da23b16bdade96d2f9bcda4d32e7d2838047ff7/cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4", size = 445259 }, + { url = "https://files.pythonhosted.org/packages/2e/ea/70ce63780f096e16ce8588efe039d3c4f91deb1dc01e9c73a287939c79a6/cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41", size = 469200 }, + { url = "https://files.pythonhosted.org/packages/1c/a0/a4fa9f4f781bda074c3ddd57a572b060fa0df7655d2a4247bbe277200146/cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1", size = 477235 }, + { url = "https://files.pythonhosted.org/packages/62/12/ce8710b5b8affbcdd5c6e367217c242524ad17a02fe5beec3ee339f69f85/cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6", size = 459721 }, + { url = "https://files.pythonhosted.org/packages/ff/6b/d45873c5e0242196f042d555526f92aa9e0c32355a1be1ff8c27f077fd37/cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d", size = 467242 }, + { url = "https://files.pythonhosted.org/packages/1a/52/d9a0e523a572fbccf2955f5abe883cfa8bcc570d7faeee06336fbd50c9fc/cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6", size = 477999 }, + { url = "https://files.pythonhosted.org/packages/44/74/f2a2460684a1a2d00ca799ad880d54652841a780c4c97b87754f660c7603/cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f", size = 454242 }, + { url = "https://files.pythonhosted.org/packages/f8/4a/34599cac7dfcd888ff54e801afe06a19c17787dfd94495ab0c8d35fe99fb/cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b", size = 478604 }, + { url = "https://files.pythonhosted.org/packages/34/33/e1b8a1ba29025adbdcda5fb3a36f94c03d771c1b7b12f726ff7fef2ebe36/cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655", size = 171727 }, + { url = "https://files.pythonhosted.org/packages/3d/97/50228be003bb2802627d28ec0627837ac0bf35c90cf769812056f235b2d1/cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0", size = 181400 }, + { url = "https://files.pythonhosted.org/packages/5a/84/e94227139ee5fb4d600a7a4927f322e1d4aea6fdc50bd3fca8493caba23f/cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4", size = 183178 }, + { url = "https://files.pythonhosted.org/packages/da/ee/fb72c2b48656111c4ef27f0f91da355e130a923473bf5ee75c5643d00cca/cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c", size = 178840 }, + { url = "https://files.pythonhosted.org/packages/cc/b6/db007700f67d151abadf508cbfd6a1884f57eab90b1bb985c4c8c02b0f28/cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36", size = 454803 }, + { url = "https://files.pythonhosted.org/packages/1a/df/f8d151540d8c200eb1c6fba8cd0dfd40904f1b0682ea705c36e6c2e97ab3/cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5", size = 478850 }, + { url = "https://files.pythonhosted.org/packages/28/c0/b31116332a547fd2677ae5b78a2ef662dfc8023d67f41b2a83f7c2aa78b1/cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff", size = 485729 }, + { url = "https://files.pythonhosted.org/packages/91/2b/9a1ddfa5c7f13cab007a2c9cc295b70fbbda7cb10a286aa6810338e60ea1/cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99", size = 471256 }, + { url = "https://files.pythonhosted.org/packages/b2/d5/da47df7004cb17e4955df6a43d14b3b4ae77737dff8bf7f8f333196717bf/cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93", size = 479424 }, + { url = "https://files.pythonhosted.org/packages/0b/ac/2a28bcf513e93a219c8a4e8e125534f4f6db03e3179ba1c45e949b76212c/cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3", size = 484568 }, + { url = "https://files.pythonhosted.org/packages/d4/38/ca8a4f639065f14ae0f1d9751e70447a261f1a30fa7547a828ae08142465/cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8", size = 488736 }, + { url = "https://files.pythonhosted.org/packages/86/c5/28b2d6f799ec0bdecf44dced2ec5ed43e0eb63097b0f58c293583b406582/cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65", size = 172448 }, + { url = "https://files.pythonhosted.org/packages/50/b9/db34c4755a7bd1cb2d1603ac3863f22bcecbd1ba29e5ee841a4bc510b294/cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903", size = 181976 }, + { url = "https://files.pythonhosted.org/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989 }, + { url = "https://files.pythonhosted.org/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802 }, + { url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792 }, + { url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893 }, + { url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810 }, + { url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200 }, + { url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447 }, + { url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358 }, + { url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469 }, + { url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475 }, + { url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009 }, + { url = "https://files.pythonhosted.org/packages/b9/ea/8bb50596b8ffbc49ddd7a1ad305035daa770202a6b782fc164647c2673ad/cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16", size = 182220 }, + { url = "https://files.pythonhosted.org/packages/ae/11/e77c8cd24f58285a82c23af484cf5b124a376b32644e445960d1a4654c3a/cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36", size = 178605 }, + { url = "https://files.pythonhosted.org/packages/ed/65/25a8dc32c53bf5b7b6c2686b42ae2ad58743f7ff644844af7cdb29b49361/cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8", size = 424910 }, + { url = "https://files.pythonhosted.org/packages/42/7a/9d086fab7c66bd7c4d0f27c57a1b6b068ced810afc498cc8c49e0088661c/cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576", size = 447200 }, + { url = "https://files.pythonhosted.org/packages/da/63/1785ced118ce92a993b0ec9e0d0ac8dc3e5dbfbcaa81135be56c69cabbb6/cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87", size = 454565 }, + { url = "https://files.pythonhosted.org/packages/74/06/90b8a44abf3556599cdec107f7290277ae8901a58f75e6fe8f970cd72418/cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0", size = 435635 }, + { url = "https://files.pythonhosted.org/packages/bd/62/a1f468e5708a70b1d86ead5bab5520861d9c7eacce4a885ded9faa7729c3/cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3", size = 445218 }, + { url = "https://files.pythonhosted.org/packages/5b/95/b34462f3ccb09c2594aa782d90a90b045de4ff1f70148ee79c69d37a0a5a/cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595", size = 460486 }, + { url = "https://files.pythonhosted.org/packages/fc/fc/a1e4bebd8d680febd29cf6c8a40067182b64f00c7d105f8f26b5bc54317b/cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a", size = 437911 }, + { url = "https://files.pythonhosted.org/packages/e6/c3/21cab7a6154b6a5ea330ae80de386e7665254835b9e98ecc1340b3a7de9a/cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e", size = 460632 }, + { url = "https://files.pythonhosted.org/packages/cb/b5/fd9f8b5a84010ca169ee49f4e4ad6f8c05f4e3545b72ee041dbbcb159882/cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7", size = 171820 }, + { url = "https://files.pythonhosted.org/packages/8c/52/b08750ce0bce45c143e1b5d7357ee8c55341b52bdef4b0f081af1eb248c2/cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662", size = 181290 }, +] + +[[package]] +name = "cfgv" +version = "3.4.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/11/74/539e56497d9bd1d484fd863dd69cbbfa653cd2aa27abfe35653494d85e94/cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560", size = 7114 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/55/51844dd50c4fc7a33b653bfaba4c2456f06955289ca770a5dbd5fd267374/cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9", size = 7249 }, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/16/b0/572805e227f01586461c80e0fd25d65a2115599cc9dad142fee4b747c357/charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3", size = 123188 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0d/58/5580c1716040bc89206c77d8f74418caf82ce519aae06450393ca73475d1/charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de", size = 198013 }, + { url = "https://files.pythonhosted.org/packages/d0/11/00341177ae71c6f5159a08168bcb98c6e6d196d372c94511f9f6c9afe0c6/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176", size = 141285 }, + { url = "https://files.pythonhosted.org/packages/01/09/11d684ea5819e5a8f5100fb0b38cf8d02b514746607934134d31233e02c8/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037", size = 151449 }, + { url = "https://files.pythonhosted.org/packages/08/06/9f5a12939db324d905dc1f70591ae7d7898d030d7662f0d426e2286f68c9/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f", size = 143892 }, + { url = "https://files.pythonhosted.org/packages/93/62/5e89cdfe04584cb7f4d36003ffa2936681b03ecc0754f8e969c2becb7e24/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a", size = 146123 }, + { url = "https://files.pythonhosted.org/packages/a9/ac/ab729a15c516da2ab70a05f8722ecfccc3f04ed7a18e45c75bbbaa347d61/charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a", size = 147943 }, + { url = "https://files.pythonhosted.org/packages/03/d2/3f392f23f042615689456e9a274640c1d2e5dd1d52de36ab8f7955f8f050/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247", size = 142063 }, + { url = "https://files.pythonhosted.org/packages/f2/e3/e20aae5e1039a2cd9b08d9205f52142329f887f8cf70da3650326670bddf/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408", size = 150578 }, + { url = "https://files.pythonhosted.org/packages/8d/af/779ad72a4da0aed925e1139d458adc486e61076d7ecdcc09e610ea8678db/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb", size = 153629 }, + { url = "https://files.pythonhosted.org/packages/c2/b6/7aa450b278e7aa92cf7732140bfd8be21f5f29d5bf334ae987c945276639/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d", size = 150778 }, + { url = "https://files.pythonhosted.org/packages/39/f4/d9f4f712d0951dcbfd42920d3db81b00dd23b6ab520419626f4023334056/charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807", size = 146453 }, + { url = "https://files.pythonhosted.org/packages/49/2b/999d0314e4ee0cff3cb83e6bc9aeddd397eeed693edb4facb901eb8fbb69/charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f", size = 95479 }, + { url = "https://files.pythonhosted.org/packages/2d/ce/3cbed41cff67e455a386fb5e5dd8906cdda2ed92fbc6297921f2e4419309/charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f", size = 102790 }, + { url = "https://files.pythonhosted.org/packages/72/80/41ef5d5a7935d2d3a773e3eaebf0a9350542f2cab4eac59a7a4741fbbbbe/charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125", size = 194995 }, + { url = "https://files.pythonhosted.org/packages/7a/28/0b9fefa7b8b080ec492110af6d88aa3dea91c464b17d53474b6e9ba5d2c5/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1", size = 139471 }, + { url = "https://files.pythonhosted.org/packages/71/64/d24ab1a997efb06402e3fc07317e94da358e2585165930d9d59ad45fcae2/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3", size = 149831 }, + { url = "https://files.pythonhosted.org/packages/37/ed/be39e5258e198655240db5e19e0b11379163ad7070962d6b0c87ed2c4d39/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd", size = 142335 }, + { url = "https://files.pythonhosted.org/packages/88/83/489e9504711fa05d8dde1574996408026bdbdbd938f23be67deebb5eca92/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00", size = 143862 }, + { url = "https://files.pythonhosted.org/packages/c6/c7/32da20821cf387b759ad24627a9aca289d2822de929b8a41b6241767b461/charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12", size = 145673 }, + { url = "https://files.pythonhosted.org/packages/68/85/f4288e96039abdd5aeb5c546fa20a37b50da71b5cf01e75e87f16cd43304/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77", size = 140211 }, + { url = "https://files.pythonhosted.org/packages/28/a3/a42e70d03cbdabc18997baf4f0227c73591a08041c149e710045c281f97b/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146", size = 148039 }, + { url = "https://files.pythonhosted.org/packages/85/e4/65699e8ab3014ecbe6f5c71d1a55d810fb716bbfd74f6283d5c2aa87febf/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd", size = 151939 }, + { url = "https://files.pythonhosted.org/packages/b1/82/8e9fe624cc5374193de6860aba3ea8070f584c8565ee77c168ec13274bd2/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6", size = 149075 }, + { url = "https://files.pythonhosted.org/packages/3d/7b/82865ba54c765560c8433f65e8acb9217cb839a9e32b42af4aa8e945870f/charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8", size = 144340 }, + { url = "https://files.pythonhosted.org/packages/b5/b6/9674a4b7d4d99a0d2df9b215da766ee682718f88055751e1e5e753c82db0/charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b", size = 95205 }, + { url = "https://files.pythonhosted.org/packages/1e/ab/45b180e175de4402dcf7547e4fb617283bae54ce35c27930a6f35b6bef15/charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76", size = 102441 }, + { url = "https://files.pythonhosted.org/packages/0a/9a/dd1e1cdceb841925b7798369a09279bd1cf183cef0f9ddf15a3a6502ee45/charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545", size = 196105 }, + { url = "https://files.pythonhosted.org/packages/d3/8c/90bfabf8c4809ecb648f39794cf2a84ff2e7d2a6cf159fe68d9a26160467/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7", size = 140404 }, + { url = "https://files.pythonhosted.org/packages/ad/8f/e410d57c721945ea3b4f1a04b74f70ce8fa800d393d72899f0a40526401f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757", size = 150423 }, + { url = "https://files.pythonhosted.org/packages/f0/b8/e6825e25deb691ff98cf5c9072ee0605dc2acfca98af70c2d1b1bc75190d/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa", size = 143184 }, + { url = "https://files.pythonhosted.org/packages/3e/a2/513f6cbe752421f16d969e32f3583762bfd583848b763913ddab8d9bfd4f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d", size = 145268 }, + { url = "https://files.pythonhosted.org/packages/74/94/8a5277664f27c3c438546f3eb53b33f5b19568eb7424736bdc440a88a31f/charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616", size = 147601 }, + { url = "https://files.pythonhosted.org/packages/7c/5f/6d352c51ee763623a98e31194823518e09bfa48be2a7e8383cf691bbb3d0/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b", size = 141098 }, + { url = "https://files.pythonhosted.org/packages/78/d4/f5704cb629ba5ab16d1d3d741396aec6dc3ca2b67757c45b0599bb010478/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d", size = 149520 }, + { url = "https://files.pythonhosted.org/packages/c5/96/64120b1d02b81785f222b976c0fb79a35875457fa9bb40827678e54d1bc8/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a", size = 152852 }, + { url = "https://files.pythonhosted.org/packages/84/c9/98e3732278a99f47d487fd3468bc60b882920cef29d1fa6ca460a1fdf4e6/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9", size = 150488 }, + { url = "https://files.pythonhosted.org/packages/13/0e/9c8d4cb99c98c1007cc11eda969ebfe837bbbd0acdb4736d228ccaabcd22/charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1", size = 146192 }, + { url = "https://files.pythonhosted.org/packages/b2/21/2b6b5b860781a0b49427309cb8670785aa543fb2178de875b87b9cc97746/charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35", size = 95550 }, + { url = "https://files.pythonhosted.org/packages/21/5b/1b390b03b1d16c7e382b561c5329f83cc06623916aab983e8ab9239c7d5c/charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f", size = 102785 }, + { url = "https://files.pythonhosted.org/packages/38/94/ce8e6f63d18049672c76d07d119304e1e2d7c6098f0841b51c666e9f44a0/charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda", size = 195698 }, + { url = "https://files.pythonhosted.org/packages/24/2e/dfdd9770664aae179a96561cc6952ff08f9a8cd09a908f259a9dfa063568/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313", size = 140162 }, + { url = "https://files.pythonhosted.org/packages/24/4e/f646b9093cff8fc86f2d60af2de4dc17c759de9d554f130b140ea4738ca6/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9", size = 150263 }, + { url = "https://files.pythonhosted.org/packages/5e/67/2937f8d548c3ef6e2f9aab0f6e21001056f692d43282b165e7c56023e6dd/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b", size = 142966 }, + { url = "https://files.pythonhosted.org/packages/52/ed/b7f4f07de100bdb95c1756d3a4d17b90c1a3c53715c1a476f8738058e0fa/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11", size = 144992 }, + { url = "https://files.pythonhosted.org/packages/96/2c/d49710a6dbcd3776265f4c923bb73ebe83933dfbaa841c5da850fe0fd20b/charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f", size = 147162 }, + { url = "https://files.pythonhosted.org/packages/b4/41/35ff1f9a6bd380303dea55e44c4933b4cc3c4850988927d4082ada230273/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd", size = 140972 }, + { url = "https://files.pythonhosted.org/packages/fb/43/c6a0b685fe6910d08ba971f62cd9c3e862a85770395ba5d9cad4fede33ab/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2", size = 149095 }, + { url = "https://files.pythonhosted.org/packages/4c/ff/a9a504662452e2d2878512115638966e75633519ec11f25fca3d2049a94a/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886", size = 152668 }, + { url = "https://files.pythonhosted.org/packages/6c/71/189996b6d9a4b932564701628af5cee6716733e9165af1d5e1b285c530ed/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601", size = 150073 }, + { url = "https://files.pythonhosted.org/packages/e4/93/946a86ce20790e11312c87c75ba68d5f6ad2208cfb52b2d6a2c32840d922/charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd", size = 145732 }, + { url = "https://files.pythonhosted.org/packages/cd/e5/131d2fb1b0dddafc37be4f3a2fa79aa4c037368be9423061dccadfd90091/charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407", size = 95391 }, + { url = "https://files.pythonhosted.org/packages/27/f2/4f9a69cc7712b9b5ad8fdb87039fd89abba997ad5cbe690d1835d40405b0/charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971", size = 102702 }, + { url = "https://files.pythonhosted.org/packages/7f/c0/b913f8f02836ed9ab32ea643c6fe4d3325c3d8627cf6e78098671cafff86/charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41", size = 197867 }, + { url = "https://files.pythonhosted.org/packages/0f/6c/2bee440303d705b6fb1e2ec789543edec83d32d258299b16eed28aad48e0/charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f", size = 141385 }, + { url = "https://files.pythonhosted.org/packages/3d/04/cb42585f07f6f9fd3219ffb6f37d5a39b4fd2db2355b23683060029c35f7/charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2", size = 151367 }, + { url = "https://files.pythonhosted.org/packages/54/54/2412a5b093acb17f0222de007cc129ec0e0df198b5ad2ce5699355269dfe/charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770", size = 143928 }, + { url = "https://files.pythonhosted.org/packages/5a/6d/e2773862b043dcf8a221342954f375392bb2ce6487bcd9f2c1b34e1d6781/charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4", size = 146203 }, + { url = "https://files.pythonhosted.org/packages/b9/f8/ca440ef60d8f8916022859885f231abb07ada3c347c03d63f283bec32ef5/charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537", size = 148082 }, + { url = "https://files.pythonhosted.org/packages/04/d2/42fd330901aaa4b805a1097856c2edf5095e260a597f65def493f4b8c833/charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496", size = 142053 }, + { url = "https://files.pythonhosted.org/packages/9e/af/3a97a4fa3c53586f1910dadfc916e9c4f35eeada36de4108f5096cb7215f/charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78", size = 150625 }, + { url = "https://files.pythonhosted.org/packages/26/ae/23d6041322a3556e4da139663d02fb1b3c59a23ab2e2b56432bd2ad63ded/charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7", size = 153549 }, + { url = "https://files.pythonhosted.org/packages/94/22/b8f2081c6a77cb20d97e57e0b385b481887aa08019d2459dc2858ed64871/charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6", size = 150945 }, + { url = "https://files.pythonhosted.org/packages/c7/0b/c5ec5092747f801b8b093cdf5610e732b809d6cb11f4c51e35fc28d1d389/charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294", size = 146595 }, + { url = "https://files.pythonhosted.org/packages/0c/5a/0b59704c38470df6768aa154cc87b1ac7c9bb687990a1559dc8765e8627e/charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5", size = 95453 }, + { url = "https://files.pythonhosted.org/packages/85/2d/a9790237cb4d01a6d57afadc8573c8b73c609ade20b80f4cda30802009ee/charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765", size = 102811 }, + { url = "https://files.pythonhosted.org/packages/0e/f6/65ecc6878a89bb1c23a086ea335ad4bf21a588990c3f535a227b9eea9108/charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85", size = 49767 }, +] + +[[package]] +name = "click" +version = "8.1.8" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188 }, +] + +[[package]] +name = "cloup" +version = "3.0.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cf/71/608e4546208e5a421ef00b484f582e58ce0f17da05459b915c8ba22dfb78/cloup-3.0.5.tar.gz", hash = "sha256:c92b261c7bb7e13004930f3fb4b3edad8de2d1f12994dcddbe05bc21990443c5", size = 225806 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/96/1a/5a2a4fbf6c95f11b079f02d7b191377ea4509f5e442887e4c7c026bc56d3/cloup-3.0.5-py2.py3-none-any.whl", hash = "sha256:bf122036066584eb0db113561167c29969cc015972b7b7ee03158d9bc7de87f8", size = 54431 }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, +] + +[[package]] +name = "comm" +version = "0.2.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e9/a8/fb783cb0abe2b5fded9f55e5703015cdf1c9c85b3669087c538dd15a6a86/comm-0.2.2.tar.gz", hash = "sha256:3fd7a84065306e07bea1773df6eb8282de51ba82f77c72f9c85716ab11fe980e", size = 6210 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e6/75/49e5bfe642f71f272236b5b2d2691cf915a7283cc0ceda56357b61daa538/comm-0.2.2-py3-none-any.whl", hash = "sha256:e6fb86cb70ff661ee8c9c14e7d36d6de3b4066f1441be4063df9c5009f0a64d3", size = 7180 }, +] + +[[package]] +name = "contourpy" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", version = "2.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, + { name = "numpy", version = "2.2.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f5/f6/31a8f28b4a2a4fa0e01085e542f3081ab0588eff8e589d39d775172c9792/contourpy-1.3.0.tar.gz", hash = "sha256:7ffa0db17717a8ffb127efd0c95a4362d996b892c2904db72428d5b52e1938a4", size = 13464370 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6c/e0/be8dcc796cfdd96708933e0e2da99ba4bb8f9b2caa9d560a50f3f09a65f3/contourpy-1.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:880ea32e5c774634f9fcd46504bf9f080a41ad855f4fef54f5380f5133d343c7", size = 265366 }, + { url = "https://files.pythonhosted.org/packages/50/d6/c953b400219443535d412fcbbc42e7a5e823291236bc0bb88936e3cc9317/contourpy-1.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:76c905ef940a4474a6289c71d53122a4f77766eef23c03cd57016ce19d0f7b42", size = 249226 }, + { url = "https://files.pythonhosted.org/packages/6f/b4/6fffdf213ffccc28483c524b9dad46bb78332851133b36ad354b856ddc7c/contourpy-1.3.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92f8557cbb07415a4d6fa191f20fd9d2d9eb9c0b61d1b2f52a8926e43c6e9af7", size = 308460 }, + { url = "https://files.pythonhosted.org/packages/cf/6c/118fc917b4050f0afe07179a6dcbe4f3f4ec69b94f36c9e128c4af480fb8/contourpy-1.3.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:36f965570cff02b874773c49bfe85562b47030805d7d8360748f3eca570f4cab", size = 347623 }, + { url = "https://files.pythonhosted.org/packages/f9/a4/30ff110a81bfe3abf7b9673284d21ddce8cc1278f6f77393c91199da4c90/contourpy-1.3.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cacd81e2d4b6f89c9f8a5b69b86490152ff39afc58a95af002a398273e5ce589", size = 317761 }, + { url = "https://files.pythonhosted.org/packages/99/e6/d11966962b1aa515f5586d3907ad019f4b812c04e4546cc19ebf62b5178e/contourpy-1.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:69375194457ad0fad3a839b9e29aa0b0ed53bb54db1bfb6c3ae43d111c31ce41", size = 322015 }, + { url = "https://files.pythonhosted.org/packages/4d/e3/182383743751d22b7b59c3c753277b6aee3637049197624f333dac5b4c80/contourpy-1.3.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:7a52040312b1a858b5e31ef28c2e865376a386c60c0e248370bbea2d3f3b760d", size = 1262672 }, + { url = "https://files.pythonhosted.org/packages/78/53/974400c815b2e605f252c8fb9297e2204347d1755a5374354ee77b1ea259/contourpy-1.3.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3faeb2998e4fcb256542e8a926d08da08977f7f5e62cf733f3c211c2a5586223", size = 1321688 }, + { url = "https://files.pythonhosted.org/packages/52/29/99f849faed5593b2926a68a31882af98afbeac39c7fdf7de491d9c85ec6a/contourpy-1.3.0-cp310-cp310-win32.whl", hash = "sha256:36e0cff201bcb17a0a8ecc7f454fe078437fa6bda730e695a92f2d9932bd507f", size = 171145 }, + { url = "https://files.pythonhosted.org/packages/a9/97/3f89bba79ff6ff2b07a3cbc40aa693c360d5efa90d66e914f0ff03b95ec7/contourpy-1.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:87ddffef1dbe5e669b5c2440b643d3fdd8622a348fe1983fad7a0f0ccb1cd67b", size = 216019 }, + { url = "https://files.pythonhosted.org/packages/b3/1f/9375917786cb39270b0ee6634536c0e22abf225825602688990d8f5c6c19/contourpy-1.3.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0fa4c02abe6c446ba70d96ece336e621efa4aecae43eaa9b030ae5fb92b309ad", size = 266356 }, + { url = "https://files.pythonhosted.org/packages/05/46/9256dd162ea52790c127cb58cfc3b9e3413a6e3478917d1f811d420772ec/contourpy-1.3.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:834e0cfe17ba12f79963861e0f908556b2cedd52e1f75e6578801febcc6a9f49", size = 250915 }, + { url = "https://files.pythonhosted.org/packages/e1/5d/3056c167fa4486900dfbd7e26a2fdc2338dc58eee36d490a0ed3ddda5ded/contourpy-1.3.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dbc4c3217eee163fa3984fd1567632b48d6dfd29216da3ded3d7b844a8014a66", size = 310443 }, + { url = "https://files.pythonhosted.org/packages/ca/c2/1a612e475492e07f11c8e267ea5ec1ce0d89971be496c195e27afa97e14a/contourpy-1.3.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4865cd1d419e0c7a7bf6de1777b185eebdc51470800a9f42b9e9decf17762081", size = 348548 }, + { url = "https://files.pythonhosted.org/packages/45/cf/2c2fc6bb5874158277b4faf136847f0689e1b1a1f640a36d76d52e78907c/contourpy-1.3.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:303c252947ab4b14c08afeb52375b26781ccd6a5ccd81abcdfc1fafd14cf93c1", size = 319118 }, + { url = "https://files.pythonhosted.org/packages/03/33/003065374f38894cdf1040cef474ad0546368eea7e3a51d48b8a423961f8/contourpy-1.3.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:637f674226be46f6ba372fd29d9523dd977a291f66ab2a74fbeb5530bb3f445d", size = 323162 }, + { url = "https://files.pythonhosted.org/packages/42/80/e637326e85e4105a802e42959f56cff2cd39a6b5ef68d5d9aee3ea5f0e4c/contourpy-1.3.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:76a896b2f195b57db25d6b44e7e03f221d32fe318d03ede41f8b4d9ba1bff53c", size = 1265396 }, + { url = "https://files.pythonhosted.org/packages/7c/3b/8cbd6416ca1bbc0202b50f9c13b2e0b922b64be888f9d9ee88e6cfabfb51/contourpy-1.3.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e1fd23e9d01591bab45546c089ae89d926917a66dceb3abcf01f6105d927e2cb", size = 1324297 }, + { url = "https://files.pythonhosted.org/packages/4d/2c/021a7afaa52fe891f25535506cc861c30c3c4e5a1c1ce94215e04b293e72/contourpy-1.3.0-cp311-cp311-win32.whl", hash = "sha256:d402880b84df3bec6eab53cd0cf802cae6a2ef9537e70cf75e91618a3801c20c", size = 171808 }, + { url = "https://files.pythonhosted.org/packages/8d/2f/804f02ff30a7fae21f98198828d0857439ec4c91a96e20cf2d6c49372966/contourpy-1.3.0-cp311-cp311-win_amd64.whl", hash = "sha256:6cb6cc968059db9c62cb35fbf70248f40994dfcd7aa10444bbf8b3faeb7c2d67", size = 217181 }, + { url = "https://files.pythonhosted.org/packages/c9/92/8e0bbfe6b70c0e2d3d81272b58c98ac69ff1a4329f18c73bd64824d8b12e/contourpy-1.3.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:570ef7cf892f0afbe5b2ee410c507ce12e15a5fa91017a0009f79f7d93a1268f", size = 267838 }, + { url = "https://files.pythonhosted.org/packages/e3/04/33351c5d5108460a8ce6d512307690b023f0cfcad5899499f5c83b9d63b1/contourpy-1.3.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:da84c537cb8b97d153e9fb208c221c45605f73147bd4cadd23bdae915042aad6", size = 251549 }, + { url = "https://files.pythonhosted.org/packages/51/3d/aa0fe6ae67e3ef9f178389e4caaaa68daf2f9024092aa3c6032e3d174670/contourpy-1.3.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0be4d8425bfa755e0fd76ee1e019636ccc7c29f77a7c86b4328a9eb6a26d0639", size = 303177 }, + { url = "https://files.pythonhosted.org/packages/56/c3/c85a7e3e0cab635575d3b657f9535443a6f5d20fac1a1911eaa4bbe1aceb/contourpy-1.3.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9c0da700bf58f6e0b65312d0a5e695179a71d0163957fa381bb3c1f72972537c", size = 341735 }, + { url = "https://files.pythonhosted.org/packages/dd/8d/20f7a211a7be966a53f474bc90b1a8202e9844b3f1ef85f3ae45a77151ee/contourpy-1.3.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:eb8b141bb00fa977d9122636b16aa67d37fd40a3d8b52dd837e536d64b9a4d06", size = 314679 }, + { url = "https://files.pythonhosted.org/packages/6e/be/524e377567defac0e21a46e2a529652d165fed130a0d8a863219303cee18/contourpy-1.3.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3634b5385c6716c258d0419c46d05c8aa7dc8cb70326c9a4fb66b69ad2b52e09", size = 320549 }, + { url = "https://files.pythonhosted.org/packages/0f/96/fdb2552a172942d888915f3a6663812e9bc3d359d53dafd4289a0fb462f0/contourpy-1.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0dce35502151b6bd35027ac39ba6e5a44be13a68f55735c3612c568cac3805fd", size = 1263068 }, + { url = "https://files.pythonhosted.org/packages/2a/25/632eab595e3140adfa92f1322bf8915f68c932bac468e89eae9974cf1c00/contourpy-1.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:aea348f053c645100612b333adc5983d87be69acdc6d77d3169c090d3b01dc35", size = 1322833 }, + { url = "https://files.pythonhosted.org/packages/73/e3/69738782e315a1d26d29d71a550dbbe3eb6c653b028b150f70c1a5f4f229/contourpy-1.3.0-cp312-cp312-win32.whl", hash = "sha256:90f73a5116ad1ba7174341ef3ea5c3150ddf20b024b98fb0c3b29034752c8aeb", size = 172681 }, + { url = "https://files.pythonhosted.org/packages/0c/89/9830ba00d88e43d15e53d64931e66b8792b46eb25e2050a88fec4a0df3d5/contourpy-1.3.0-cp312-cp312-win_amd64.whl", hash = "sha256:b11b39aea6be6764f84360fce6c82211a9db32a7c7de8fa6dd5397cf1d079c3b", size = 218283 }, + { url = "https://files.pythonhosted.org/packages/53/a1/d20415febfb2267af2d7f06338e82171824d08614084714fb2c1dac9901f/contourpy-1.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3e1c7fa44aaae40a2247e2e8e0627f4bea3dd257014764aa644f319a5f8600e3", size = 267879 }, + { url = "https://files.pythonhosted.org/packages/aa/45/5a28a3570ff6218d8bdfc291a272a20d2648104815f01f0177d103d985e1/contourpy-1.3.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:364174c2a76057feef647c802652f00953b575723062560498dc7930fc9b1cb7", size = 251573 }, + { url = "https://files.pythonhosted.org/packages/39/1c/d3f51540108e3affa84f095c8b04f0aa833bb797bc8baa218a952a98117d/contourpy-1.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:32b238b3b3b649e09ce9aaf51f0c261d38644bdfa35cbaf7b263457850957a84", size = 303184 }, + { url = "https://files.pythonhosted.org/packages/00/56/1348a44fb6c3a558c1a3a0cd23d329d604c99d81bf5a4b58c6b71aab328f/contourpy-1.3.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d51fca85f9f7ad0b65b4b9fe800406d0d77017d7270d31ec3fb1cc07358fdea0", size = 340262 }, + { url = "https://files.pythonhosted.org/packages/2b/23/00d665ba67e1bb666152131da07e0f24c95c3632d7722caa97fb61470eca/contourpy-1.3.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:732896af21716b29ab3e988d4ce14bc5133733b85956316fb0c56355f398099b", size = 313806 }, + { url = "https://files.pythonhosted.org/packages/5a/42/3cf40f7040bb8362aea19af9a5fb7b32ce420f645dd1590edcee2c657cd5/contourpy-1.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d73f659398a0904e125280836ae6f88ba9b178b2fed6884f3b1f95b989d2c8da", size = 319710 }, + { url = "https://files.pythonhosted.org/packages/05/32/f3bfa3fc083b25e1a7ae09197f897476ee68e7386e10404bdf9aac7391f0/contourpy-1.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c6c7c2408b7048082932cf4e641fa3b8ca848259212f51c8c59c45aa7ac18f14", size = 1264107 }, + { url = "https://files.pythonhosted.org/packages/1c/1e/1019d34473a736664f2439542b890b2dc4c6245f5c0d8cdfc0ccc2cab80c/contourpy-1.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f317576606de89da6b7e0861cf6061f6146ead3528acabff9236458a6ba467f8", size = 1322458 }, + { url = "https://files.pythonhosted.org/packages/22/85/4f8bfd83972cf8909a4d36d16b177f7b8bdd942178ea4bf877d4a380a91c/contourpy-1.3.0-cp313-cp313-win32.whl", hash = "sha256:31cd3a85dbdf1fc002280c65caa7e2b5f65e4a973fcdf70dd2fdcb9868069294", size = 172643 }, + { url = "https://files.pythonhosted.org/packages/cc/4a/fb3c83c1baba64ba90443626c228ca14f19a87c51975d3b1de308dd2cf08/contourpy-1.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:4553c421929ec95fb07b3aaca0fae668b2eb5a5203d1217ca7c34c063c53d087", size = 218301 }, + { url = "https://files.pythonhosted.org/packages/76/65/702f4064f397821fea0cb493f7d3bc95a5d703e20954dce7d6d39bacf378/contourpy-1.3.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:345af746d7766821d05d72cb8f3845dfd08dd137101a2cb9b24de277d716def8", size = 278972 }, + { url = "https://files.pythonhosted.org/packages/80/85/21f5bba56dba75c10a45ec00ad3b8190dbac7fd9a8a8c46c6116c933e9cf/contourpy-1.3.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3bb3808858a9dc68f6f03d319acd5f1b8a337e6cdda197f02f4b8ff67ad2057b", size = 263375 }, + { url = "https://files.pythonhosted.org/packages/0a/64/084c86ab71d43149f91ab3a4054ccf18565f0a8af36abfa92b1467813ed6/contourpy-1.3.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:420d39daa61aab1221567b42eecb01112908b2cab7f1b4106a52caaec8d36973", size = 307188 }, + { url = "https://files.pythonhosted.org/packages/3d/ff/d61a4c288dc42da0084b8d9dc2aa219a850767165d7d9a9c364ff530b509/contourpy-1.3.0-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4d63ee447261e963af02642ffcb864e5a2ee4cbfd78080657a9880b8b1868e18", size = 345644 }, + { url = "https://files.pythonhosted.org/packages/ca/aa/00d2313d35ec03f188e8f0786c2fc61f589306e02fdc158233697546fd58/contourpy-1.3.0-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:167d6c890815e1dac9536dca00828b445d5d0df4d6a8c6adb4a7ec3166812fa8", size = 317141 }, + { url = "https://files.pythonhosted.org/packages/8d/6a/b5242c8cb32d87f6abf4f5e3044ca397cb1a76712e3fa2424772e3ff495f/contourpy-1.3.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:710a26b3dc80c0e4febf04555de66f5fd17e9cf7170a7b08000601a10570bda6", size = 323469 }, + { url = "https://files.pythonhosted.org/packages/6f/a6/73e929d43028a9079aca4bde107494864d54f0d72d9db508a51ff0878593/contourpy-1.3.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:75ee7cb1a14c617f34a51d11fa7524173e56551646828353c4af859c56b766e2", size = 1260894 }, + { url = "https://files.pythonhosted.org/packages/2b/1e/1e726ba66eddf21c940821df8cf1a7d15cb165f0682d62161eaa5e93dae1/contourpy-1.3.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:33c92cdae89ec5135d036e7218e69b0bb2851206077251f04a6c4e0e21f03927", size = 1314829 }, + { url = "https://files.pythonhosted.org/packages/b3/e3/b9f72758adb6ef7397327ceb8b9c39c75711affb220e4f53c745ea1d5a9a/contourpy-1.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a11077e395f67ffc2c44ec2418cfebed032cd6da3022a94fc227b6faf8e2acb8", size = 265518 }, + { url = "https://files.pythonhosted.org/packages/ec/22/19f5b948367ab5260fb41d842c7a78dae645603881ea6bc39738bcfcabf6/contourpy-1.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e8134301d7e204c88ed7ab50028ba06c683000040ede1d617298611f9dc6240c", size = 249350 }, + { url = "https://files.pythonhosted.org/packages/26/76/0c7d43263dd00ae21a91a24381b7e813d286a3294d95d179ef3a7b9fb1d7/contourpy-1.3.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e12968fdfd5bb45ffdf6192a590bd8ddd3ba9e58360b29683c6bb71a7b41edca", size = 309167 }, + { url = "https://files.pythonhosted.org/packages/96/3b/cadff6773e89f2a5a492c1a8068e21d3fccaf1a1c1df7d65e7c8e3ef60ba/contourpy-1.3.0-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fd2a0fc506eccaaa7595b7e1418951f213cf8255be2600f1ea1b61e46a60c55f", size = 348279 }, + { url = "https://files.pythonhosted.org/packages/e1/86/158cc43aa549d2081a955ab11c6bdccc7a22caacc2af93186d26f5f48746/contourpy-1.3.0-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4cfb5c62ce023dfc410d6059c936dcf96442ba40814aefbfa575425a3a7f19dc", size = 318519 }, + { url = "https://files.pythonhosted.org/packages/05/11/57335544a3027e9b96a05948c32e566328e3a2f84b7b99a325b7a06d2b06/contourpy-1.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68a32389b06b82c2fdd68276148d7b9275b5f5cf13e5417e4252f6d1a34f72a2", size = 321922 }, + { url = "https://files.pythonhosted.org/packages/0b/e3/02114f96543f4a1b694333b92a6dcd4f8eebbefcc3a5f3bbb1316634178f/contourpy-1.3.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:94e848a6b83da10898cbf1311a815f770acc9b6a3f2d646f330d57eb4e87592e", size = 1258017 }, + { url = "https://files.pythonhosted.org/packages/f3/3b/bfe4c81c6d5881c1c643dde6620be0b42bf8aab155976dd644595cfab95c/contourpy-1.3.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:d78ab28a03c854a873787a0a42254a0ccb3cb133c672f645c9f9c8f3ae9d0800", size = 1316773 }, + { url = "https://files.pythonhosted.org/packages/f1/17/c52d2970784383cafb0bd918b6fb036d98d96bbf0bc1befb5d1e31a07a70/contourpy-1.3.0-cp39-cp39-win32.whl", hash = "sha256:81cb5ed4952aae6014bc9d0421dec7c5835c9c8c31cdf51910b708f548cf58e5", size = 171353 }, + { url = "https://files.pythonhosted.org/packages/53/23/db9f69676308e094d3c45f20cc52e12d10d64f027541c995d89c11ad5c75/contourpy-1.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:14e262f67bd7e6eb6880bc564dcda30b15e351a594657e55b7eec94b6ef72843", size = 211817 }, + { url = "https://files.pythonhosted.org/packages/d1/09/60e486dc2b64c94ed33e58dcfb6f808192c03dfc5574c016218b9b7680dc/contourpy-1.3.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:fe41b41505a5a33aeaed2a613dccaeaa74e0e3ead6dd6fd3a118fb471644fd6c", size = 261886 }, + { url = "https://files.pythonhosted.org/packages/19/20/b57f9f7174fcd439a7789fb47d764974ab646fa34d1790551de386457a8e/contourpy-1.3.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eca7e17a65f72a5133bdbec9ecf22401c62bcf4821361ef7811faee695799779", size = 311008 }, + { url = "https://files.pythonhosted.org/packages/74/fc/5040d42623a1845d4f17a418e590fd7a79ae8cb2bad2b2f83de63c3bdca4/contourpy-1.3.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:1ec4dc6bf570f5b22ed0d7efba0dfa9c5b9e0431aeea7581aa217542d9e809a4", size = 215690 }, + { url = "https://files.pythonhosted.org/packages/2b/24/dc3dcd77ac7460ab7e9d2b01a618cb31406902e50e605a8d6091f0a8f7cc/contourpy-1.3.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:00ccd0dbaad6d804ab259820fa7cb0b8036bda0686ef844d24125d8287178ce0", size = 261894 }, + { url = "https://files.pythonhosted.org/packages/b1/db/531642a01cfec39d1682e46b5457b07cf805e3c3c584ec27e2a6223f8f6c/contourpy-1.3.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ca947601224119117f7c19c9cdf6b3ab54c5726ef1d906aa4a69dfb6dd58102", size = 311099 }, + { url = "https://files.pythonhosted.org/packages/38/1e/94bda024d629f254143a134eead69e21c836429a2a6ce82209a00ddcb79a/contourpy-1.3.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:c6ec93afeb848a0845a18989da3beca3eec2c0f852322efe21af1931147d12cb", size = 215838 }, +] + +[[package]] +name = "coverage" +version = "7.6.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/84/ba/ac14d281f80aab516275012e8875991bb06203957aa1e19950139238d658/coverage-7.6.10.tar.gz", hash = "sha256:7fb105327c8f8f0682e29843e2ff96af9dcbe5bab8eeb4b398c6a33a16d80a23", size = 803868 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/12/2a2a923edf4ddabdffed7ad6da50d96a5c126dae7b80a33df7310e329a1e/coverage-7.6.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5c912978f7fbf47ef99cec50c4401340436d200d41d714c7a4766f377c5b7b78", size = 207982 }, + { url = "https://files.pythonhosted.org/packages/ca/49/6985dbca9c7be3f3cb62a2e6e492a0c88b65bf40579e16c71ae9c33c6b23/coverage-7.6.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a01ec4af7dfeb96ff0078ad9a48810bb0cc8abcb0115180c6013a6b26237626c", size = 208414 }, + { url = "https://files.pythonhosted.org/packages/35/93/287e8f1d1ed2646f4e0b2605d14616c9a8a2697d0d1b453815eb5c6cebdb/coverage-7.6.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3b204c11e2b2d883946fe1d97f89403aa1811df28ce0447439178cc7463448a", size = 236860 }, + { url = "https://files.pythonhosted.org/packages/de/e1/cfdb5627a03567a10031acc629b75d45a4ca1616e54f7133ca1fa366050a/coverage-7.6.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32ee6d8491fcfc82652a37109f69dee9a830e9379166cb73c16d8dc5c2915165", size = 234758 }, + { url = "https://files.pythonhosted.org/packages/6d/85/fc0de2bcda3f97c2ee9fe8568f7d48f7279e91068958e5b2cc19e0e5f600/coverage-7.6.10-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675cefc4c06e3b4c876b85bfb7c59c5e2218167bbd4da5075cbe3b5790a28988", size = 235920 }, + { url = "https://files.pythonhosted.org/packages/79/73/ef4ea0105531506a6f4cf4ba571a214b14a884630b567ed65b3d9c1975e1/coverage-7.6.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f4f620668dbc6f5e909a0946a877310fb3d57aea8198bde792aae369ee1c23b5", size = 234986 }, + { url = "https://files.pythonhosted.org/packages/c6/4d/75afcfe4432e2ad0405c6f27adeb109ff8976c5e636af8604f94f29fa3fc/coverage-7.6.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:4eea95ef275de7abaef630c9b2c002ffbc01918b726a39f5a4353916ec72d2f3", size = 233446 }, + { url = "https://files.pythonhosted.org/packages/86/5b/efee56a89c16171288cafff022e8af44f8f94075c2d8da563c3935212871/coverage-7.6.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e2f0280519e42b0a17550072861e0bc8a80a0870de260f9796157d3fca2733c5", size = 234566 }, + { url = "https://files.pythonhosted.org/packages/f2/db/67770cceb4a64d3198bf2aa49946f411b85ec6b0a9b489e61c8467a4253b/coverage-7.6.10-cp310-cp310-win32.whl", hash = "sha256:bc67deb76bc3717f22e765ab3e07ee9c7a5e26b9019ca19a3b063d9f4b874244", size = 210675 }, + { url = "https://files.pythonhosted.org/packages/8d/27/e8bfc43f5345ec2c27bc8a1fa77cdc5ce9dcf954445e11f14bb70b889d14/coverage-7.6.10-cp310-cp310-win_amd64.whl", hash = "sha256:0f460286cb94036455e703c66988851d970fdfd8acc2a1122ab7f4f904e4029e", size = 211518 }, + { url = "https://files.pythonhosted.org/packages/85/d2/5e175fcf6766cf7501a8541d81778fd2f52f4870100e791f5327fd23270b/coverage-7.6.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ea3c8f04b3e4af80e17bab607c386a830ffc2fb88a5484e1df756478cf70d1d3", size = 208088 }, + { url = "https://files.pythonhosted.org/packages/4b/6f/06db4dc8fca33c13b673986e20e466fd936235a6ec1f0045c3853ac1b593/coverage-7.6.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:507a20fc863cae1d5720797761b42d2d87a04b3e5aeb682ef3b7332e90598f43", size = 208536 }, + { url = "https://files.pythonhosted.org/packages/0d/62/c6a0cf80318c1c1af376d52df444da3608eafc913b82c84a4600d8349472/coverage-7.6.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d37a84878285b903c0fe21ac8794c6dab58150e9359f1aaebbeddd6412d53132", size = 240474 }, + { url = "https://files.pythonhosted.org/packages/a3/59/750adafc2e57786d2e8739a46b680d4fb0fbc2d57fbcb161290a9f1ecf23/coverage-7.6.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a534738b47b0de1995f85f582d983d94031dffb48ab86c95bdf88dc62212142f", size = 237880 }, + { url = "https://files.pythonhosted.org/packages/2c/f8/ef009b3b98e9f7033c19deb40d629354aab1d8b2d7f9cfec284dbedf5096/coverage-7.6.10-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d7a2bf79378d8fb8afaa994f91bfd8215134f8631d27eba3e0e2c13546ce994", size = 239750 }, + { url = "https://files.pythonhosted.org/packages/a6/e2/6622f3b70f5f5b59f705e680dae6db64421af05a5d1e389afd24dae62e5b/coverage-7.6.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6713ba4b4ebc330f3def51df1d5d38fad60b66720948112f114968feb52d3f99", size = 238642 }, + { url = "https://files.pythonhosted.org/packages/2d/10/57ac3f191a3c95c67844099514ff44e6e19b2915cd1c22269fb27f9b17b6/coverage-7.6.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ab32947f481f7e8c763fa2c92fd9f44eeb143e7610c4ca9ecd6a36adab4081bd", size = 237266 }, + { url = "https://files.pythonhosted.org/packages/ee/2d/7016f4ad9d553cabcb7333ed78ff9d27248ec4eba8dd21fa488254dff894/coverage-7.6.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7bbd8c8f1b115b892e34ba66a097b915d3871db7ce0e6b9901f462ff3a975377", size = 238045 }, + { url = "https://files.pythonhosted.org/packages/a7/fe/45af5c82389a71e0cae4546413266d2195c3744849669b0bab4b5f2c75da/coverage-7.6.10-cp311-cp311-win32.whl", hash = "sha256:299e91b274c5c9cdb64cbdf1b3e4a8fe538a7a86acdd08fae52301b28ba297f8", size = 210647 }, + { url = "https://files.pythonhosted.org/packages/db/11/3f8e803a43b79bc534c6a506674da9d614e990e37118b4506faf70d46ed6/coverage-7.6.10-cp311-cp311-win_amd64.whl", hash = "sha256:489a01f94aa581dbd961f306e37d75d4ba16104bbfa2b0edb21d29b73be83609", size = 211508 }, + { url = "https://files.pythonhosted.org/packages/86/77/19d09ea06f92fdf0487499283b1b7af06bc422ea94534c8fe3a4cd023641/coverage-7.6.10-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:27c6e64726b307782fa5cbe531e7647aee385a29b2107cd87ba7c0105a5d3853", size = 208281 }, + { url = "https://files.pythonhosted.org/packages/b6/67/5479b9f2f99fcfb49c0d5cf61912a5255ef80b6e80a3cddba39c38146cf4/coverage-7.6.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c56e097019e72c373bae32d946ecf9858fda841e48d82df7e81c63ac25554078", size = 208514 }, + { url = "https://files.pythonhosted.org/packages/15/d1/febf59030ce1c83b7331c3546d7317e5120c5966471727aa7ac157729c4b/coverage-7.6.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7827a5bc7bdb197b9e066cdf650b2887597ad124dd99777332776f7b7c7d0d0", size = 241537 }, + { url = "https://files.pythonhosted.org/packages/4b/7e/5ac4c90192130e7cf8b63153fe620c8bfd9068f89a6d9b5f26f1550f7a26/coverage-7.6.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:204a8238afe787323a8b47d8be4df89772d5c1e4651b9ffa808552bdf20e1d50", size = 238572 }, + { url = "https://files.pythonhosted.org/packages/dc/03/0334a79b26ecf59958f2fe9dd1f5ab3e2f88db876f5071933de39af09647/coverage-7.6.10-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e67926f51821b8e9deb6426ff3164870976fe414d033ad90ea75e7ed0c2e5022", size = 240639 }, + { url = "https://files.pythonhosted.org/packages/d7/45/8a707f23c202208d7b286d78ad6233f50dcf929319b664b6cc18a03c1aae/coverage-7.6.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e78b270eadb5702938c3dbe9367f878249b5ef9a2fcc5360ac7bff694310d17b", size = 240072 }, + { url = "https://files.pythonhosted.org/packages/66/02/603ce0ac2d02bc7b393279ef618940b4a0535b0868ee791140bda9ecfa40/coverage-7.6.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:714f942b9c15c3a7a5fe6876ce30af831c2ad4ce902410b7466b662358c852c0", size = 238386 }, + { url = "https://files.pythonhosted.org/packages/04/62/4e6887e9be060f5d18f1dd58c2838b2d9646faf353232dec4e2d4b1c8644/coverage-7.6.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:abb02e2f5a3187b2ac4cd46b8ced85a0858230b577ccb2c62c81482ca7d18852", size = 240054 }, + { url = "https://files.pythonhosted.org/packages/5c/74/83ae4151c170d8bd071924f212add22a0e62a7fe2b149edf016aeecad17c/coverage-7.6.10-cp312-cp312-win32.whl", hash = "sha256:55b201b97286cf61f5e76063f9e2a1d8d2972fc2fcfd2c1272530172fd28c359", size = 210904 }, + { url = "https://files.pythonhosted.org/packages/c3/54/de0893186a221478f5880283119fc40483bc460b27c4c71d1b8bba3474b9/coverage-7.6.10-cp312-cp312-win_amd64.whl", hash = "sha256:e4ae5ac5e0d1e4edfc9b4b57b4cbecd5bc266a6915c500f358817a8496739247", size = 211692 }, + { url = "https://files.pythonhosted.org/packages/25/6d/31883d78865529257bf847df5789e2ae80e99de8a460c3453dbfbe0db069/coverage-7.6.10-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05fca8ba6a87aabdd2d30d0b6c838b50510b56cdcfc604d40760dae7153b73d9", size = 208308 }, + { url = "https://files.pythonhosted.org/packages/70/22/3f2b129cc08de00c83b0ad6252e034320946abfc3e4235c009e57cfeee05/coverage-7.6.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9e80eba8801c386f72e0712a0453431259c45c3249f0009aff537a517b52942b", size = 208565 }, + { url = "https://files.pythonhosted.org/packages/97/0a/d89bc2d1cc61d3a8dfe9e9d75217b2be85f6c73ebf1b9e3c2f4e797f4531/coverage-7.6.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a372c89c939d57abe09e08c0578c1d212e7a678135d53aa16eec4430adc5e690", size = 241083 }, + { url = "https://files.pythonhosted.org/packages/4c/81/6d64b88a00c7a7aaed3a657b8eaa0931f37a6395fcef61e53ff742b49c97/coverage-7.6.10-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec22b5e7fe7a0fa8509181c4aac1db48f3dd4d3a566131b313d1efc102892c18", size = 238235 }, + { url = "https://files.pythonhosted.org/packages/9a/0b/7797d4193f5adb4b837207ed87fecf5fc38f7cc612b369a8e8e12d9fa114/coverage-7.6.10-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26bcf5c4df41cad1b19c84af71c22cbc9ea9a547fc973f1f2cc9a290002c8b3c", size = 240220 }, + { url = "https://files.pythonhosted.org/packages/65/4d/6f83ca1bddcf8e51bf8ff71572f39a1c73c34cf50e752a952c34f24d0a60/coverage-7.6.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e4630c26b6084c9b3cb53b15bd488f30ceb50b73c35c5ad7871b869cb7365fd", size = 239847 }, + { url = "https://files.pythonhosted.org/packages/30/9d/2470df6aa146aff4c65fee0f87f58d2164a67533c771c9cc12ffcdb865d5/coverage-7.6.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2396e8116db77789f819d2bc8a7e200232b7a282c66e0ae2d2cd84581a89757e", size = 237922 }, + { url = "https://files.pythonhosted.org/packages/08/dd/723fef5d901e6a89f2507094db66c091449c8ba03272861eaefa773ad95c/coverage-7.6.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:79109c70cc0882e4d2d002fe69a24aa504dec0cc17169b3c7f41a1d341a73694", size = 239783 }, + { url = "https://files.pythonhosted.org/packages/3d/f7/64d3298b2baf261cb35466000628706ce20a82d42faf9b771af447cd2b76/coverage-7.6.10-cp313-cp313-win32.whl", hash = "sha256:9e1747bab246d6ff2c4f28b4d186b205adced9f7bd9dc362051cc37c4a0c7bd6", size = 210965 }, + { url = "https://files.pythonhosted.org/packages/d5/58/ec43499a7fc681212fe7742fe90b2bc361cdb72e3181ace1604247a5b24d/coverage-7.6.10-cp313-cp313-win_amd64.whl", hash = "sha256:254f1a3b1eef5f7ed23ef265eaa89c65c8c5b6b257327c149db1ca9d4a35f25e", size = 211719 }, + { url = "https://files.pythonhosted.org/packages/ab/c9/f2857a135bcff4330c1e90e7d03446b036b2363d4ad37eb5e3a47bbac8a6/coverage-7.6.10-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2ccf240eb719789cedbb9fd1338055de2761088202a9a0b73032857e53f612fe", size = 209050 }, + { url = "https://files.pythonhosted.org/packages/aa/b3/f840e5bd777d8433caa9e4a1eb20503495709f697341ac1a8ee6a3c906ad/coverage-7.6.10-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0c807ca74d5a5e64427c8805de15b9ca140bba13572d6d74e262f46f50b13273", size = 209321 }, + { url = "https://files.pythonhosted.org/packages/85/7d/125a5362180fcc1c03d91850fc020f3831d5cda09319522bcfa6b2b70be7/coverage-7.6.10-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bcfa46d7709b5a7ffe089075799b902020b62e7ee56ebaed2f4bdac04c508d8", size = 252039 }, + { url = "https://files.pythonhosted.org/packages/a9/9c/4358bf3c74baf1f9bddd2baf3756b54c07f2cfd2535f0a47f1e7757e54b3/coverage-7.6.10-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e0de1e902669dccbf80b0415fb6b43d27edca2fbd48c74da378923b05316098", size = 247758 }, + { url = "https://files.pythonhosted.org/packages/cf/c7/de3eb6fc5263b26fab5cda3de7a0f80e317597a4bad4781859f72885f300/coverage-7.6.10-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f7b444c42bbc533aaae6b5a2166fd1a797cdb5eb58ee51a92bee1eb94a1e1cb", size = 250119 }, + { url = "https://files.pythonhosted.org/packages/3e/e6/43de91f8ba2ec9140c6a4af1102141712949903dc732cf739167cfa7a3bc/coverage-7.6.10-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b330368cb99ef72fcd2dc3ed260adf67b31499584dc8a20225e85bfe6f6cfed0", size = 249597 }, + { url = "https://files.pythonhosted.org/packages/08/40/61158b5499aa2adf9e37bc6d0117e8f6788625b283d51e7e0c53cf340530/coverage-7.6.10-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:9a7cfb50515f87f7ed30bc882f68812fd98bc2852957df69f3003d22a2aa0abf", size = 247473 }, + { url = "https://files.pythonhosted.org/packages/50/69/b3f2416725621e9f112e74e8470793d5b5995f146f596f133678a633b77e/coverage-7.6.10-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f93531882a5f68c28090f901b1d135de61b56331bba82028489bc51bdd818d2", size = 248737 }, + { url = "https://files.pythonhosted.org/packages/3c/6e/fe899fb937657db6df31cc3e61c6968cb56d36d7326361847440a430152e/coverage-7.6.10-cp313-cp313t-win32.whl", hash = "sha256:89d76815a26197c858f53c7f6a656686ec392b25991f9e409bcef020cd532312", size = 211611 }, + { url = "https://files.pythonhosted.org/packages/1c/55/52f5e66142a9d7bc93a15192eba7a78513d2abf6b3558d77b4ca32f5f424/coverage-7.6.10-cp313-cp313t-win_amd64.whl", hash = "sha256:54a5f0f43950a36312155dae55c505a76cd7f2b12d26abeebbe7a0b36dbc868d", size = 212781 }, + { url = "https://files.pythonhosted.org/packages/40/41/473617aadf9a1c15bc2d56be65d90d7c29bfa50a957a67ef96462f7ebf8e/coverage-7.6.10-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:656c82b8a0ead8bba147de9a89bda95064874c91a3ed43a00e687f23cc19d53a", size = 207978 }, + { url = "https://files.pythonhosted.org/packages/10/f6/480586607768b39a30e6910a3c4522139094ac0f1677028e1f4823688957/coverage-7.6.10-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ccc2b70a7ed475c68ceb548bf69cec1e27305c1c2606a5eb7c3afff56a1b3b27", size = 208415 }, + { url = "https://files.pythonhosted.org/packages/f1/af/439bb760f817deff6f4d38fe7da08d9dd7874a560241f1945bc3b4446550/coverage-7.6.10-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5e37dc41d57ceba70956fa2fc5b63c26dba863c946ace9705f8eca99daecdc4", size = 236452 }, + { url = "https://files.pythonhosted.org/packages/d0/13/481f4ceffcabe29ee2332e60efb52e4694f54a402f3ada2bcec10bb32e43/coverage-7.6.10-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0aa9692b4fdd83a4647eeb7db46410ea1322b5ed94cd1715ef09d1d5922ba87f", size = 234374 }, + { url = "https://files.pythonhosted.org/packages/c5/59/4607ea9d6b1b73e905c7656da08d0b00cdf6e59f2293ec259e8914160025/coverage-7.6.10-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aa744da1820678b475e4ba3dfd994c321c5b13381d1041fe9c608620e6676e25", size = 235505 }, + { url = "https://files.pythonhosted.org/packages/85/60/d66365723b9b7f29464b11d024248ed3523ce5aab958e4ad8c43f3f4148b/coverage-7.6.10-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:c0b1818063dc9e9d838c09e3a473c1422f517889436dd980f5d721899e66f315", size = 234616 }, + { url = "https://files.pythonhosted.org/packages/74/f8/2cf7a38e7d81b266f47dfcf137fecd8fa66c7bdbd4228d611628d8ca3437/coverage-7.6.10-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:59af35558ba08b758aec4d56182b222976330ef8d2feacbb93964f576a7e7a90", size = 233099 }, + { url = "https://files.pythonhosted.org/packages/50/2b/bff6c1c6b63c4396ea7ecdbf8db1788b46046c681b8fcc6ec77db9f4ea49/coverage-7.6.10-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7ed2f37cfce1ce101e6dffdfd1c99e729dd2ffc291d02d3e2d0af8b53d13840d", size = 234089 }, + { url = "https://files.pythonhosted.org/packages/bf/b5/baace1c754d546a67779358341aa8d2f7118baf58cac235db457e1001d1b/coverage-7.6.10-cp39-cp39-win32.whl", hash = "sha256:4bcc276261505d82f0ad426870c3b12cb177752834a633e737ec5ee79bbdff18", size = 210701 }, + { url = "https://files.pythonhosted.org/packages/b1/bf/9e1e95b8b20817398ecc5a1e8d3e05ff404e1b9fb2185cd71561698fe2a2/coverage-7.6.10-cp39-cp39-win_amd64.whl", hash = "sha256:457574f4599d2b00f7f637a0700a6422243b3565509457b2dbd3f50703e11f59", size = 211482 }, + { url = "https://files.pythonhosted.org/packages/a1/70/de81bfec9ed38a64fc44a77c7665e20ca507fc3265597c28b0d989e4082e/coverage-7.6.10-pp39.pp310-none-any.whl", hash = "sha256:fd34e7b3405f0cc7ab03d54a334c17a9e802897580d964bd8c2001f4b9fd488f", size = 200223 }, +] + +[package.optional-dependencies] +toml = [ + { name = "tomli", marker = "python_full_version <= '3.11'" }, +] + +[[package]] +name = "cryptography" +version = "44.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi", marker = "platform_python_implementation != 'PyPy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/91/4c/45dfa6829acffa344e3967d6006ee4ae8be57af746ae2eba1c431949b32c/cryptography-44.0.0.tar.gz", hash = "sha256:cd4e834f340b4293430701e772ec543b0fbe6c2dea510a5286fe0acabe153a02", size = 710657 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/55/09/8cc67f9b84730ad330b3b72cf867150744bf07ff113cda21a15a1c6d2c7c/cryptography-44.0.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:84111ad4ff3f6253820e6d3e58be2cc2a00adb29335d4cacb5ab4d4d34f2a123", size = 6541833 }, + { url = "https://files.pythonhosted.org/packages/7e/5b/3759e30a103144e29632e7cb72aec28cedc79e514b2ea8896bb17163c19b/cryptography-44.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15492a11f9e1b62ba9d73c210e2416724633167de94607ec6069ef724fad092", size = 3922710 }, + { url = "https://files.pythonhosted.org/packages/5f/58/3b14bf39f1a0cfd679e753e8647ada56cddbf5acebffe7db90e184c76168/cryptography-44.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:831c3c4d0774e488fdc83a1923b49b9957d33287de923d58ebd3cec47a0ae43f", size = 4137546 }, + { url = "https://files.pythonhosted.org/packages/98/65/13d9e76ca19b0ba5603d71ac8424b5694415b348e719db277b5edc985ff5/cryptography-44.0.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:761817a3377ef15ac23cd7834715081791d4ec77f9297ee694ca1ee9c2c7e5eb", size = 3915420 }, + { url = "https://files.pythonhosted.org/packages/b1/07/40fe09ce96b91fc9276a9ad272832ead0fddedcba87f1190372af8e3039c/cryptography-44.0.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3c672a53c0fb4725a29c303be906d3c1fa99c32f58abe008a82705f9ee96f40b", size = 4154498 }, + { url = "https://files.pythonhosted.org/packages/75/ea/af65619c800ec0a7e4034207aec543acdf248d9bffba0533342d1bd435e1/cryptography-44.0.0-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:4ac4c9f37eba52cb6fbeaf5b59c152ea976726b865bd4cf87883a7e7006cc543", size = 3932569 }, + { url = "https://files.pythonhosted.org/packages/c7/af/d1deb0c04d59612e3d5e54203159e284d3e7a6921e565bb0eeb6269bdd8a/cryptography-44.0.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ed3534eb1090483c96178fcb0f8893719d96d5274dfde98aa6add34614e97c8e", size = 4016721 }, + { url = "https://files.pythonhosted.org/packages/bd/69/7ca326c55698d0688db867795134bdfac87136b80ef373aaa42b225d6dd5/cryptography-44.0.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f3f6fdfa89ee2d9d496e2c087cebef9d4fcbb0ad63c40e821b39f74bf48d9c5e", size = 4240915 }, + { url = "https://files.pythonhosted.org/packages/ef/d4/cae11bf68c0f981e0413906c6dd03ae7fa864347ed5fac40021df1ef467c/cryptography-44.0.0-cp37-abi3-win32.whl", hash = "sha256:eb33480f1bad5b78233b0ad3e1b0be21e8ef1da745d8d2aecbb20671658b9053", size = 2757925 }, + { url = "https://files.pythonhosted.org/packages/64/b1/50d7739254d2002acae64eed4fc43b24ac0cc44bf0a0d388d1ca06ec5bb1/cryptography-44.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:abc998e0c0eee3c8a1904221d3f67dcfa76422b23620173e28c11d3e626c21bd", size = 3202055 }, + { url = "https://files.pythonhosted.org/packages/11/18/61e52a3d28fc1514a43b0ac291177acd1b4de00e9301aaf7ef867076ff8a/cryptography-44.0.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:660cb7312a08bc38be15b696462fa7cc7cd85c3ed9c576e81f4dc4d8b2b31591", size = 6542801 }, + { url = "https://files.pythonhosted.org/packages/1a/07/5f165b6c65696ef75601b781a280fc3b33f1e0cd6aa5a92d9fb96c410e97/cryptography-44.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1923cb251c04be85eec9fda837661c67c1049063305d6be5721643c22dd4e2b7", size = 3922613 }, + { url = "https://files.pythonhosted.org/packages/28/34/6b3ac1d80fc174812486561cf25194338151780f27e438526f9c64e16869/cryptography-44.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:404fdc66ee5f83a1388be54300ae978b2efd538018de18556dde92575e05defc", size = 4137925 }, + { url = "https://files.pythonhosted.org/packages/d0/c7/c656eb08fd22255d21bc3129625ed9cd5ee305f33752ef2278711b3fa98b/cryptography-44.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:c5eb858beed7835e5ad1faba59e865109f3e52b3783b9ac21e7e47dc5554e289", size = 3915417 }, + { url = "https://files.pythonhosted.org/packages/ef/82/72403624f197af0db6bac4e58153bc9ac0e6020e57234115db9596eee85d/cryptography-44.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f53c2c87e0fb4b0c00fa9571082a057e37690a8f12233306161c8f4b819960b7", size = 4155160 }, + { url = "https://files.pythonhosted.org/packages/a2/cd/2f3c440913d4329ade49b146d74f2e9766422e1732613f57097fea61f344/cryptography-44.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:9e6fc8a08e116fb7c7dd1f040074c9d7b51d74a8ea40d4df2fc7aa08b76b9e6c", size = 3932331 }, + { url = "https://files.pythonhosted.org/packages/7f/df/8be88797f0a1cca6e255189a57bb49237402b1880d6e8721690c5603ac23/cryptography-44.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:d2436114e46b36d00f8b72ff57e598978b37399d2786fd39793c36c6d5cb1c64", size = 4017372 }, + { url = "https://files.pythonhosted.org/packages/af/36/5ccc376f025a834e72b8e52e18746b927f34e4520487098e283a719c205e/cryptography-44.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a01956ddfa0a6790d594f5b34fc1bfa6098aca434696a03cfdbe469b8ed79285", size = 4239657 }, + { url = "https://files.pythonhosted.org/packages/46/b0/f4f7d0d0bcfbc8dd6296c1449be326d04217c57afb8b2594f017eed95533/cryptography-44.0.0-cp39-abi3-win32.whl", hash = "sha256:eca27345e1214d1b9f9490d200f9db5a874479be914199194e746c893788d417", size = 2758672 }, + { url = "https://files.pythonhosted.org/packages/97/9b/443270b9210f13f6ef240eff73fd32e02d381e7103969dc66ce8e89ee901/cryptography-44.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:708ee5f1bafe76d041b53a4f95eb28cdeb8d18da17e597d46d7833ee59b97ede", size = 3202071 }, + { url = "https://files.pythonhosted.org/packages/77/d4/fea74422326388bbac0c37b7489a0fcb1681a698c3b875959430ba550daa/cryptography-44.0.0-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:37d76e6863da3774cd9db5b409a9ecfd2c71c981c38788d3fcfaf177f447b731", size = 3338857 }, + { url = "https://files.pythonhosted.org/packages/1a/aa/ba8a7467c206cb7b62f09b4168da541b5109838627f582843bbbe0235e8e/cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:f677e1268c4e23420c3acade68fac427fffcb8d19d7df95ed7ad17cdef8404f4", size = 3850615 }, + { url = "https://files.pythonhosted.org/packages/89/fa/b160e10a64cc395d090105be14f399b94e617c879efd401188ce0fea39ee/cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:f5e7cb1e5e56ca0933b4873c0220a78b773b24d40d186b6738080b73d3d0a756", size = 4081622 }, + { url = "https://files.pythonhosted.org/packages/47/8f/20ff0656bb0cf7af26ec1d01f780c5cfbaa7666736063378c5f48558b515/cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:8b3e6eae66cf54701ee7d9c83c30ac0a1e3fa17be486033000f2a73a12ab507c", size = 3867546 }, + { url = "https://files.pythonhosted.org/packages/38/d9/28edf32ee2fcdca587146bcde90102a7319b2f2c690edfa627e46d586050/cryptography-44.0.0-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:be4ce505894d15d5c5037167ffb7f0ae90b7be6f2a98f9a5c3442395501c32fa", size = 4090937 }, + { url = "https://files.pythonhosted.org/packages/cc/9d/37e5da7519de7b0b070a3fedd4230fe76d50d2a21403e0f2153d70ac4163/cryptography-44.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:62901fb618f74d7d81bf408c8719e9ec14d863086efe4185afd07c352aee1d2c", size = 3128774 }, +] + +[[package]] +name = "cycler" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/95/a3dbbb5028f35eafb79008e7522a75244477d2838f38cbb722248dabc2a8/cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c", size = 7615 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321 }, +] + +[[package]] +name = "cython" +version = "3.0.11" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/84/4d/b720d6000f4ca77f030bd70f12550820f0766b568e43f11af7f7ad9061aa/cython-3.0.11.tar.gz", hash = "sha256:7146dd2af8682b4ca61331851e6aebce9fe5158e75300343f80c07ca80b1faff", size = 2755544 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/13/7f/ab5796a0951328d7818b771c36fe7e1a2077cffa28c917d9fa4a642728c3/Cython-3.0.11-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:44292aae17524abb4b70a25111fe7dec1a0ad718711d47e3786a211d5408fdaa", size = 3100879 }, + { url = "https://files.pythonhosted.org/packages/f8/73/e55be864199cd674cb3426a052726c205589b1ac66fb0090e7fe793b60b3/Cython-3.0.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:75ba1c70b6deeaffbac123856b8d35f253da13552207aa969078611c197377e4", size = 3113599 }, + { url = "https://files.pythonhosted.org/packages/58/50/fbb23239efe2183e4eaf76689270d6f5b3bbcf9be9ad1eb97cc34349e6fc/Cython-3.0.11-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:11996c40c32abf843ba652a6d53cb15944c88d91f91fc4e6f0028f5df8a8f8a1", size = 3141274 }, + { url = "https://files.pythonhosted.org/packages/eb/19/1d7164b724f62b67c59aa3531a2be8ed1a0c7e4e80afcc6502d8409c4ee3/Cython-3.0.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:4341d6a64d47112884e0bcf31e6c075268220ee4cd02223047182d4dda94d637", size = 3134881 }, + { url = "https://files.pythonhosted.org/packages/c5/dc/b1354a36c7460083b38baceb7ce62a1cb667e72308321f1232b26a7f1c90/Cython-3.0.11-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:0fc6fdd6fa493be7bdda22355689d5446ac944cd71286f6f44a14b0d67ee3ff5", size = 3107281 }, + { url = "https://files.pythonhosted.org/packages/43/39/bdbec9142bc46605b54d674bf158a78b191c2b75be527c6dcf3e6dfe90b8/Cython-3.0.11-py2.py3-none-any.whl", hash = "sha256:0e25f6425ad4a700d7f77cd468da9161e63658837d1bc34861a9861a4ef6346d", size = 1171267 }, +] + +[[package]] +name = "dearpygui" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/79/6d/c76d935a972593fc62532c684cb92844d990228e09e34e849392930456e5/dearpygui-2.0.0-cp310-cp310-macosx_10_6_x86_64.whl", hash = "sha256:6126eec4217de6dfbe0aef4b96a0f4b385f85dab538ee806d51c5f9a5ba77c6b", size = 2222991 }, + { url = "https://files.pythonhosted.org/packages/c4/87/55ec86076fe2d2706f523023da503429a07b76aac2c63133adff8d5c6812/dearpygui-2.0.0-cp310-cp310-macosx_13_0_arm64.whl", hash = "sha256:340ddc3884740aabcddf696f984c1ff2a06b91050bf5030ab264dc9908f1329a", size = 1873606 }, + { url = "https://files.pythonhosted.org/packages/ed/32/03b21f232abeeb88d40e3e8d53ba08c300f441ce2f6d076df09767ce3c38/dearpygui-2.0.0-cp310-cp310-manylinux1_x86_64.whl", hash = "sha256:68f749fcd36ffc9cef399fb64b0dab5a4075c63574150a163208f8204f778859", size = 2636754 }, + { url = "https://files.pythonhosted.org/packages/21/5d/0556472c7c40e53b0af2d5897239bd2c2e8a447a108fcf694c6006ca2b93/dearpygui-2.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:d287233603338a811b59da0af8194ff7cd7b8da768c1d056fe17b6d8a7b36a6f", size = 1813983 }, + { url = "https://files.pythonhosted.org/packages/99/3a/36d33f51bbcd44c26c8a9888caf6f185f563dfceedd0d18118a4c2e13e1f/dearpygui-2.0.0-cp311-cp311-macosx_10_6_x86_64.whl", hash = "sha256:ee81dd58b06161b5098e11fce5514f621f1fe7670c63711a4397cb1bc108dfe5", size = 2222890 }, + { url = "https://files.pythonhosted.org/packages/58/39/a4bb4b6b73ba41da8957cc6ef8f4d9fb05a8ea207afaaf208872cbac12c4/dearpygui-2.0.0-cp311-cp311-macosx_13_0_arm64.whl", hash = "sha256:5802886d4c44362764882b9339a0dbe85f9b445a98560f791acb164febc4df32", size = 1873561 }, + { url = "https://files.pythonhosted.org/packages/19/03/8a0536d201fbe0f60aa4b024f6d6712f7ff45427b52f03999fbe904850a2/dearpygui-2.0.0-cp311-cp311-manylinux1_x86_64.whl", hash = "sha256:8d5049aa54835a51cc304752a0831ad71a6ca05ee7a33e0b82f7e7e8c8ecda21", size = 2636754 }, + { url = "https://files.pythonhosted.org/packages/57/cd/272fbac4c404aaac2ca219889b8dbc5be7d5f3d7836392a1c3d8d4707e68/dearpygui-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:73643b3528dd4b03cb22ad64afe960dc8ddd3023f211fd405eabb861fc4dd129", size = 1813888 }, + { url = "https://files.pythonhosted.org/packages/00/dc/aac3b7e5789408096f34616f2c3b3c000332970a9eea0b3362239a1c35bd/dearpygui-2.0.0-cp312-cp312-macosx_10_6_x86_64.whl", hash = "sha256:f0383d74f628ae4622863afff84ab262c9f5163a769836eb470c7243dc9ced0c", size = 2223499 }, + { url = "https://files.pythonhosted.org/packages/e5/ca/fa3e58376f8c8486f38b7266c69566c1b965072eabc59b4da95b10a114e0/dearpygui-2.0.0-cp312-cp312-macosx_13_0_arm64.whl", hash = "sha256:52c32da6911881564b6cbd95e110d6956095f7a417d2e0c12dcda8274c4fbe72", size = 1873678 }, + { url = "https://files.pythonhosted.org/packages/6f/a1/427d18fbaa578890507bd8c864262a5f1f1eaa6e10ae2ea75ba9f0a5b5a3/dearpygui-2.0.0-cp312-cp312-manylinux1_x86_64.whl", hash = "sha256:d27f7e64a282c7f0c1387003ec3b247b2c3c1583aea9427283633ad508aa2da6", size = 2636459 }, + { url = "https://files.pythonhosted.org/packages/35/ad/dd978c8eb4df7c59756d5325d18d28e97b39d3bcd54275f075c1c3c34b17/dearpygui-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:29881d01e5d0cce0980a8d8b9761c74ff2f30d16aa800e6002a244bbc894b34e", size = 1814293 }, + { url = "https://files.pythonhosted.org/packages/79/58/4e1744d2af72a3aa432fd82aeb97dcbc43351b17f837d879b4c4926bd16c/dearpygui-2.0.0-cp313-cp313-macosx_10_6_x86_64.whl", hash = "sha256:3bf0aa19baedb4f130b8de636d4644740ffd9b7008481794c574bf59240808dc", size = 2223494 }, + { url = "https://files.pythonhosted.org/packages/70/e0/09885f99df476d03e573183a755dc515cd88565cdbf036c385f0dda41dbb/dearpygui-2.0.0-cp313-cp313-macosx_13_0_arm64.whl", hash = "sha256:ae6fc9aa3390b29387c2bc2bf3ac7a92c10eae2b479818171864fc29a7de344e", size = 1873562 }, + { url = "https://files.pythonhosted.org/packages/d6/2b/0714feed9e072377d575cb8801ac13a909f7880ca51c9dd6f2d768bcd1ba/dearpygui-2.0.0-cp313-cp313-manylinux1_x86_64.whl", hash = "sha256:f02b0ab56700a775d7e6446e3c424d5bed3386efe721a04518d02461851daadf", size = 2636153 }, + { url = "https://files.pythonhosted.org/packages/55/9e/a957ffc21d12a1fb66d611f82871944565112b44afa0856bb15c6ece77d5/dearpygui-2.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:e3d52057f49773b10808962806711c3b3119e829d36407afb84ad50522edc9b0", size = 1814308 }, + { url = "https://files.pythonhosted.org/packages/c4/e4/f7b52cbe2d0f9838fa2c143e21dc88053fa4e56bd49cf5efab33f61f11f3/dearpygui-2.0.0-cp39-cp39-macosx_10_6_x86_64.whl", hash = "sha256:751f58355631924b17b543db1c366d69ca056f050556952c23e051ebd1a8ac76", size = 2222996 }, + { url = "https://files.pythonhosted.org/packages/d5/6f/f22e6561a2d34b63c368eda577ab9cff0503017bf6c820c0890ca0185a15/dearpygui-2.0.0-cp39-cp39-manylinux1_x86_64.whl", hash = "sha256:9a3f0562d47e664c044bcb75868d7f3cc22456866f32f6b4bad22e377d4eef3a", size = 2636714 }, + { url = "https://files.pythonhosted.org/packages/ef/52/938bfdecb527f46615d282ce4dac0a8158f535e0e53401f6a141613868c4/dearpygui-2.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:ffe10b14f836cea82881fb9f66e464877429ce3ff2fbc3e33d239881cd52bada", size = 1813932 }, +] + +[[package]] +name = "debugpy" +version = "1.8.12" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/68/25/c74e337134edf55c4dfc9af579eccb45af2393c40960e2795a94351e8140/debugpy-1.8.12.tar.gz", hash = "sha256:646530b04f45c830ceae8e491ca1c9320a2d2f0efea3141487c82130aba70dce", size = 1641122 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/56/19/dd58334c0a1ec07babf80bf29fb8daf1a7ca4c1a3bbe61548e40616ac087/debugpy-1.8.12-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:a2ba7ffe58efeae5b8fad1165357edfe01464f9aef25e814e891ec690e7dd82a", size = 2076091 }, + { url = "https://files.pythonhosted.org/packages/4c/37/bde1737da15f9617d11ab7b8d5267165f1b7dae116b2585a6643e89e1fa2/debugpy-1.8.12-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cbbd4149c4fc5e7d508ece083e78c17442ee13b0e69bfa6bd63003e486770f45", size = 3560717 }, + { url = "https://files.pythonhosted.org/packages/d9/ca/bc67f5a36a7de072908bc9e1156c0f0b272a9a2224cf21540ab1ffd71a1f/debugpy-1.8.12-cp310-cp310-win32.whl", hash = "sha256:b202f591204023b3ce62ff9a47baa555dc00bb092219abf5caf0e3718ac20e7c", size = 5180672 }, + { url = "https://files.pythonhosted.org/packages/c1/b9/e899c0a80dfa674dbc992f36f2b1453cd1ee879143cdb455bc04fce999da/debugpy-1.8.12-cp310-cp310-win_amd64.whl", hash = "sha256:9649eced17a98ce816756ce50433b2dd85dfa7bc92ceb60579d68c053f98dff9", size = 5212702 }, + { url = "https://files.pythonhosted.org/packages/af/9f/5b8af282253615296264d4ef62d14a8686f0dcdebb31a669374e22fff0a4/debugpy-1.8.12-cp311-cp311-macosx_14_0_universal2.whl", hash = "sha256:36f4829839ef0afdfdd208bb54f4c3d0eea86106d719811681a8627ae2e53dd5", size = 2174643 }, + { url = "https://files.pythonhosted.org/packages/ef/31/f9274dcd3b0f9f7d1e60373c3fa4696a585c55acb30729d313bb9d3bcbd1/debugpy-1.8.12-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a28ed481d530e3138553be60991d2d61103ce6da254e51547b79549675f539b7", size = 3133457 }, + { url = "https://files.pythonhosted.org/packages/ab/ca/6ee59e9892e424477e0c76e3798046f1fd1288040b927319c7a7b0baa484/debugpy-1.8.12-cp311-cp311-win32.whl", hash = "sha256:4ad9a94d8f5c9b954e0e3b137cc64ef3f579d0df3c3698fe9c3734ee397e4abb", size = 5106220 }, + { url = "https://files.pythonhosted.org/packages/d5/1a/8ab508ab05ede8a4eae3b139bbc06ea3ca6234f9e8c02713a044f253be5e/debugpy-1.8.12-cp311-cp311-win_amd64.whl", hash = "sha256:4703575b78dd697b294f8c65588dc86874ed787b7348c65da70cfc885efdf1e1", size = 5130481 }, + { url = "https://files.pythonhosted.org/packages/ba/e6/0f876ecfe5831ebe4762b19214364753c8bc2b357d28c5d739a1e88325c7/debugpy-1.8.12-cp312-cp312-macosx_14_0_universal2.whl", hash = "sha256:7e94b643b19e8feb5215fa508aee531387494bf668b2eca27fa769ea11d9f498", size = 2500846 }, + { url = "https://files.pythonhosted.org/packages/19/64/33f41653a701f3cd2cbff8b41ebaad59885b3428b5afd0d93d16012ecf17/debugpy-1.8.12-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:086b32e233e89a2740c1615c2f775c34ae951508b28b308681dbbb87bba97d06", size = 4222181 }, + { url = "https://files.pythonhosted.org/packages/32/a6/02646cfe50bfacc9b71321c47dc19a46e35f4e0aceea227b6d205e900e34/debugpy-1.8.12-cp312-cp312-win32.whl", hash = "sha256:2ae5df899732a6051b49ea2632a9ea67f929604fd2b036613a9f12bc3163b92d", size = 5227017 }, + { url = "https://files.pythonhosted.org/packages/da/a6/10056431b5c47103474312cf4a2ec1001f73e0b63b1216706d5fef2531eb/debugpy-1.8.12-cp312-cp312-win_amd64.whl", hash = "sha256:39dfbb6fa09f12fae32639e3286112fc35ae976114f1f3d37375f3130a820969", size = 5267555 }, + { url = "https://files.pythonhosted.org/packages/cf/4d/7c3896619a8791effd5d8c31f0834471fc8f8fb3047ec4f5fc69dd1393dd/debugpy-1.8.12-cp313-cp313-macosx_14_0_universal2.whl", hash = "sha256:696d8ae4dff4cbd06bf6b10d671e088b66669f110c7c4e18a44c43cf75ce966f", size = 2485246 }, + { url = "https://files.pythonhosted.org/packages/99/46/bc6dcfd7eb8cc969a5716d858e32485eb40c72c6a8dc88d1e3a4d5e95813/debugpy-1.8.12-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:898fba72b81a654e74412a67c7e0a81e89723cfe2a3ea6fcd3feaa3395138ca9", size = 4218616 }, + { url = "https://files.pythonhosted.org/packages/03/dd/d7fcdf0381a9b8094da1f6a1c9f19fed493a4f8576a2682349b3a8b20ec7/debugpy-1.8.12-cp313-cp313-win32.whl", hash = "sha256:22a11c493c70413a01ed03f01c3c3a2fc4478fc6ee186e340487b2edcd6f4180", size = 5226540 }, + { url = "https://files.pythonhosted.org/packages/25/bd/ecb98f5b5fc7ea0bfbb3c355bc1dd57c198a28780beadd1e19915bf7b4d9/debugpy-1.8.12-cp313-cp313-win_amd64.whl", hash = "sha256:fdb3c6d342825ea10b90e43d7f20f01535a72b3a1997850c0c3cefa5c27a4a2c", size = 5267134 }, + { url = "https://files.pythonhosted.org/packages/89/37/a3333c5b69c086465ea3c073424ef2775e52a6c17276f642f64209c4a082/debugpy-1.8.12-cp39-cp39-macosx_14_0_x86_64.whl", hash = "sha256:b5c6c967d02fee30e157ab5227706f965d5c37679c687b1e7bbc5d9e7128bd41", size = 2077275 }, + { url = "https://files.pythonhosted.org/packages/50/1d/99f6a0a78b4b513ff2b0d0e44c1e705f7ee34e3aba0e8add617d339d97dc/debugpy-1.8.12-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88a77f422f31f170c4b7e9ca58eae2a6c8e04da54121900651dfa8e66c29901a", size = 3555956 }, + { url = "https://files.pythonhosted.org/packages/b8/86/c624665aaa807d065da2016b05e9f2fb4fa56872d67a5fbd7751e77f7f88/debugpy-1.8.12-cp39-cp39-win32.whl", hash = "sha256:a4042edef80364239f5b7b5764e55fd3ffd40c32cf6753da9bda4ff0ac466018", size = 5181535 }, + { url = "https://files.pythonhosted.org/packages/72/c7/d59a0f845ce1677b5c2bb170f08cc1cc3531625a5fdce9c67bd31116540a/debugpy-1.8.12-cp39-cp39-win_amd64.whl", hash = "sha256:f30b03b0f27608a0b26c75f0bb8a880c752c0e0b01090551b9d87c7d783e2069", size = 5213601 }, + { url = "https://files.pythonhosted.org/packages/38/c4/5120ad36405c3008f451f94b8f92ef1805b1e516f6ff870f331ccb3c4cc0/debugpy-1.8.12-py2.py3-none-any.whl", hash = "sha256:274b6a2040349b5c9864e475284bce5bb062e63dce368a394b8cc865ae3b00c6", size = 5229490 }, +] + +[[package]] +name = "decorator" +version = "5.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/66/0c/8d907af351aa16b42caae42f9d6aa37b900c67308052d10fdce809f8d952/decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330", size = 35016 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d5/50/83c593b07763e1161326b3b8c6686f0f4b0f24d5526546bee538c89837d6/decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186", size = 9073 }, +] + +[[package]] +name = "defusedxml" +version = "0.7.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/d5/c66da9b79e5bdb124974bfe172b4daf3c984ebd9c2a06e2b8a4dc7331c72/defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69", size = 75520 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61", size = 25604 }, +] + +[[package]] +name = "deprecated" +version = "1.2.17" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "wrapt" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2f/20/caa25c084ebad492360bf28ba5cb74f27b50fc6f3df965fd0add2b5b5993/deprecated-1.2.17.tar.gz", hash = "sha256:0114a10f0bbb750b90b2c2296c90cf7e9eaeb0abb5cf06c80de2c60138de0a82", size = 2928237 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/90/89be9a665bf63d3baaba6f34d9a514655abb42be2cc129f31c96df2cef51/Deprecated-1.2.17-py2.py3-none-any.whl", hash = "sha256:69cdc0a751671183f569495e2efb14baee4344b0236342eec29f1fde25d61818", size = 9140 }, +] + +[[package]] +name = "distlib" +version = "0.3.9" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0d/dd/1bec4c5ddb504ca60fc29472f3d27e8d4da1257a854e1d96742f15c1d02d/distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403", size = 613923 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/91/a1/cf2472db20f7ce4a6be1253a81cfdf85ad9c7885ffbed7047fb72c24cf87/distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87", size = 468973 }, +] + +[[package]] +name = "docutils" +version = "0.21.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ae/ed/aefcc8cd0ba62a0560c3c18c33925362d46c6075480bfa4df87b28e169a9/docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f", size = 2204444 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8f/d7/9322c609343d929e75e7e5e6255e614fcc67572cfd083959cdef3b7aad79/docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2", size = 587408 }, +] + +[[package]] +name = "exceptiongroup" +version = "1.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", size = 28883 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453 }, +] + +[[package]] +name = "execnet" +version = "2.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bb/ff/b4c0dc78fbe20c3e59c0c7334de0c27eb4001a2b2017999af398bf730817/execnet-2.1.1.tar.gz", hash = "sha256:5189b52c6121c24feae288166ab41b32549c7e2348652736540b9e6e7d4e72e3", size = 166524 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/09/2aea36ff60d16dd8879bdb2f5b3ee0ba8d08cbbdcdfe870e695ce3784385/execnet-2.1.1-py3-none-any.whl", hash = "sha256:26dee51f1b80cebd6d0ca8e74dd8745419761d3bef34163928cbebbdc4749fdc", size = 40612 }, +] + +[[package]] +name = "executing" +version = "2.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/91/50/a9d80c47ff289c611ff12e63f7c5d13942c65d68125160cefd768c73e6e4/executing-2.2.0.tar.gz", hash = "sha256:5d108c028108fe2551d1a7b2e8b713341e2cb4fc0aa7dcf966fa4327a5226755", size = 978693 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/8f/c4d9bafc34ad7ad5d8dc16dd1347ee0e507a52c3adb6bfa8887e1c6a26ba/executing-2.2.0-py2.py3-none-any.whl", hash = "sha256:11387150cad388d62750327a53d3339fad4888b39a6fe233c3afbb54ecffd3aa", size = 26702 }, +] + +[[package]] +name = "fastjsonschema" +version = "2.21.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8b/50/4b769ce1ac4071a1ef6d86b1a3fb56cdc3a37615e8c5519e1af96cdac366/fastjsonschema-2.21.1.tar.gz", hash = "sha256:794d4f0a58f848961ba16af7b9c85a3e88cd360df008c59aac6fc5ae9323b5d4", size = 373939 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/90/2b/0817a2b257fe88725c25589d89aec060581aabf668707a8d03b2e9e0cb2a/fastjsonschema-2.21.1-py3-none-any.whl", hash = "sha256:c9e5b7e908310918cf494a434eeb31384dd84a98b57a30bcb1f535015b554667", size = 23924 }, +] + +[[package]] +name = "filelock" +version = "3.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/dc/9c/0b15fb47b464e1b663b1acd1253a062aa5feecb07d4e597daea542ebd2b5/filelock-3.17.0.tar.gz", hash = "sha256:ee4e77401ef576ebb38cd7f13b9b28893194acc20a8e68e18730ba9c0e54660e", size = 18027 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/ec/00d68c4ddfedfe64159999e5f8a98fb8442729a63e2077eb9dcd89623d27/filelock-3.17.0-py3-none-any.whl", hash = "sha256:533dc2f7ba78dc2f0f531fc6c4940addf7b70a481e269a5a3b93be94ffbe8338", size = 16164 }, +] + +[[package]] +name = "fonttools" +version = "4.55.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/49/2e/0b11e907b90665253dbad425479e874e38a9e81ced397a4e3312b9116935/fonttools-4.55.6.tar.gz", hash = "sha256:1beb4647a0df5ceaea48015656525eb8081af226fe96554089fd3b274d239ef0", size = 3500677 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/05/8c1a6ab8c443525c1cedee94d0371ec45cbcd11e4b01328ff10dcc483134/fonttools-4.55.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:57d55fc965e5dd20c8a60d880e0f43bafb506be87af0b650bdc42591e41e0d0d", size = 2774906 }, + { url = "https://files.pythonhosted.org/packages/cd/53/de15cea829b49d50a0d0942d75bc71ca680536265abed03ce873ae71787b/fonttools-4.55.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:127999618afe3a2490fad54bab0650c5fbeab1f8109bdc0205f6ad34306deb8b", size = 2303345 }, + { url = "https://files.pythonhosted.org/packages/d2/23/90159149cc907ea2da0ca7b7baf5ad783c902de219ecb28bca3f789b82c3/fonttools-4.55.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3226d40cb92787e09dcc3730f54b3779dfe56bdfea624e263685ba17a6faac4", size = 4584790 }, + { url = "https://files.pythonhosted.org/packages/26/db/8d33a4575efe7ecd0487d4a53369d086ab7d879069e4c62d3687dec53941/fonttools-4.55.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e82772f70b84e17aa36e9f236feb2a4f73cb686ec1e162557a36cf759d1acd58", size = 4627464 }, + { url = "https://files.pythonhosted.org/packages/a3/c9/e90342b5eebce21ba2b04ce879c66e0316a5faaa7337498dfb5032953055/fonttools-4.55.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a632f85bd73e002b771bcbcdc512038fa5d2e09bb18c03a22fb8d400ea492ddf", size = 4581741 }, + { url = "https://files.pythonhosted.org/packages/e1/98/f4297b65849f15f6b49349a1ffc21e93d1859fa3579d0d5cb1590317060c/fonttools-4.55.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:791e0cf862cdd3a252df395f1bb5f65e3a760f1da3c7ce184d0f7998c266614d", size = 4751195 }, + { url = "https://files.pythonhosted.org/packages/63/73/9dcf4040edbdc5e33cc23d2b7d6a6d4bb50605efd5686d6b782815f4a818/fonttools-4.55.6-cp310-cp310-win32.whl", hash = "sha256:94f7f2c5c5f3a6422e954ecb6d37cc363e27d6f94050a7ed3f79f12157af6bb2", size = 2178422 }, + { url = "https://files.pythonhosted.org/packages/45/f0/ec0ce63f910db60a566201a550c06205595c10c980f6c74885f53cdf512b/fonttools-4.55.6-cp310-cp310-win_amd64.whl", hash = "sha256:2d15e02b93a46982a8513a208e8f89148bca8297640527365625be56151687d0", size = 2222886 }, + { url = "https://files.pythonhosted.org/packages/53/42/e6cb653675fcf2bed7814b5d688c95a1b6d136ad26e4ed1523c18d6dbb28/fonttools-4.55.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:0879f99eabbf2171dfadd9c8c75cec2b7b3aa9cd1f3955dd799c69d60a5189ef", size = 2776041 }, + { url = "https://files.pythonhosted.org/packages/58/b6/d54d71a59498def2b58d5ec5f8baad35add4a076edb1968d645b7a95759a/fonttools-4.55.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:d77d83ca77a4c3156a2f4cbc7f09f5a8503795da658fa255b987ad433a191266", size = 2304268 }, + { url = "https://files.pythonhosted.org/packages/fe/ed/0743c21126fc3442a710b8c880355e381dd750a18bfe10097d663a1838c5/fonttools-4.55.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:07478132407736ee5e54f9f534e73923ae28e9bb6dba17764a35e3caf7d7fea3", size = 4891976 }, + { url = "https://files.pythonhosted.org/packages/0d/73/8f7a0084bc0b3591e281fdcef7e704ad3817244d35ca98b444de5acf0f47/fonttools-4.55.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1c06fbc2fd76b9bab03eddfd8aa9fb7c0981d314d780e763c80aa76be1c9982", size = 4921223 }, + { url = "https://files.pythonhosted.org/packages/ad/75/b47d792d4c4f65ff488d9f25d59f8bb6382c74efd6169bd3c0341320ac76/fonttools-4.55.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:09ed667c4753e1270994e5398cce8703e6423c41702a55b08f843b2907b1be65", size = 4900418 }, + { url = "https://files.pythonhosted.org/packages/88/70/f821dce8121b6c4bccd10ca28499df2e0e9811e2a711deeb270b9065fcd9/fonttools-4.55.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0ee6ed68af8d57764d69da099db163aaf37d62ba246cfd42f27590e3e6724b55", size = 5068531 }, + { url = "https://files.pythonhosted.org/packages/76/6e/6b7c919c4f985042fe02fe9cbd3d956e2e85a6db8575737ff600aa24c42c/fonttools-4.55.6-cp311-cp311-win32.whl", hash = "sha256:9f99e7876518b2d059a9cc67c506168aebf9c71ac8d81006d75e684222f291d2", size = 2177287 }, + { url = "https://files.pythonhosted.org/packages/1e/10/26a4123227fa1ab9fa8ec062f4f2b980f43483d58ec261d502bfe49af6c2/fonttools-4.55.6-cp311-cp311-win_amd64.whl", hash = "sha256:3aa6c684007723895aade9b2fe76d07008c9dc90fd1ef6c310b3ca9c8566729f", size = 2223807 }, + { url = "https://files.pythonhosted.org/packages/f7/c0/b9c7308f925545702a2ecc696bb59ed0cab544aa53b3abd6c0f3ab1186e2/fonttools-4.55.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:51120695ee13001533e50abd40eec32c01b9c6f44c5567db38a7acd3eedcd19d", size = 2770475 }, + { url = "https://files.pythonhosted.org/packages/9c/ec/bc7baa296dbbfb58fee00458285006a00deeedbbdeae2b88ca477d662170/fonttools-4.55.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:76ac5a595f86892b49ba86ba2e46185adc76328ce6eff0583b30e5c3ab02a914", size = 2301727 }, + { url = "https://files.pythonhosted.org/packages/dd/73/75e0c47f5bc8805419499a016691e388d92ab4dc607ef5e9ace86c466829/fonttools-4.55.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b7535a5ac386e549e2b00b34c59b53f805e2423000676723b6867df3c10df04", size = 4806704 }, + { url = "https://files.pythonhosted.org/packages/ff/de/932d68e198dc386c7fb055416822834b1b3a21cd376eeb7cc2d6fdc5ad14/fonttools-4.55.6-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c42009177d3690894288082d5e3dac6bdc9f5d38e25054535e341a19cf5183a4", size = 4877824 }, + { url = "https://files.pythonhosted.org/packages/01/cd/e6249ce95a0fa7d2950524400a524fb6860c688776b53a3635f3d3c2d3f4/fonttools-4.55.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:88f74bc19dbab3dee6a00ca67ca54bb4793e44ff0c4dcf1fa61d68651ae3fa0a", size = 4785213 }, + { url = "https://files.pythonhosted.org/packages/67/85/db2ac44e066043451542d9845969e2e9a3545b8a77e9d0e35484ebe95227/fonttools-4.55.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:bc6f58976ffc19fe1630119a2736153b66151d023c6f30065f31c9e8baed1303", size = 5012806 }, + { url = "https://files.pythonhosted.org/packages/66/ec/6dca43eb8d6555503b6e454edf42688464d0e744b089a757afc7c513f8a9/fonttools-4.55.6-cp312-cp312-win32.whl", hash = "sha256:4259159715142c10b0f4d121ef14da3fa6eafc719289d9efa4b20c15e57fef82", size = 2165760 }, + { url = "https://files.pythonhosted.org/packages/39/5d/99a164057dd1fc345027113909022877e5fd1b649b2357d18a2a03c50d8b/fonttools-4.55.6-cp312-cp312-win_amd64.whl", hash = "sha256:d91fce2e9a87cc0db9f8042281b6458f99854df810cfefab2baf6ab2acc0f4b4", size = 2212601 }, + { url = "https://files.pythonhosted.org/packages/da/ce/65ea137cdc6d7682c8133931944dec81d2cf9f0276665e4a8292efeb262a/fonttools-4.55.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:9394813cc73fa22c5413ec1c5745c0a16f68dd2b890f7c55eaba5cb40187ed55", size = 2757836 }, + { url = "https://files.pythonhosted.org/packages/d1/39/671f6e5af29235bf598a14eb060bfa2a1dd5010cafefe39fc9648ace3a3c/fonttools-4.55.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ac817559a7d245454231374e194b4e457dca6fefa5b52af466ab0516e9a09c6e", size = 2295238 }, + { url = "https://files.pythonhosted.org/packages/31/68/c41d6fe8c3132db492d054c39e043672d1739055f1aa531e4141541e1a4a/fonttools-4.55.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:34405f1314f1e88b1877a9f9e497fe45190e8c4b29a6c7cd85ed7f666a57d702", size = 4785136 }, + { url = "https://files.pythonhosted.org/packages/1a/85/591b8f36af1f36d78a9d3f24a95912a70ca899d037e43bb41dba19088d05/fonttools-4.55.6-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af5469bbf555047efd8752d85faeb2a3510916ddc6c50dd6fb168edf1677408f", size = 4857158 }, + { url = "https://files.pythonhosted.org/packages/27/1b/a8bccde7c0f88e6ccd8b2c80b112f7b363a2d1f600fb29f8654bf14bdf5f/fonttools-4.55.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:8a8004a19195eb8a8a13de69e26ec9ed60a5bc1fde336d0021b47995b368fac9", size = 4765517 }, + { url = "https://files.pythonhosted.org/packages/1c/d4/9b24f3563325e396810191240ed8efa0b093ea7a3e5971cc97515da42ceb/fonttools-4.55.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:73a4aaf672e7b2265c6354a69cbbadf71b7f3133ecb74e98fec4c67c366698a3", size = 4986460 }, + { url = "https://files.pythonhosted.org/packages/30/01/874a26eaad82ab5e469766cb4532a3a7d65262d443023507bd5cd6247cce/fonttools-4.55.6-cp313-cp313-win32.whl", hash = "sha256:73bdff9c44d36c57ea84766afc20517eda0c9bb1571b4a09876646264bd5ff3b", size = 2163789 }, + { url = "https://files.pythonhosted.org/packages/59/94/f1b35883172676e71c259dfdf5dddab9cffa650b503f4dd2535dce726a06/fonttools-4.55.6-cp313-cp313-win_amd64.whl", hash = "sha256:132fa22be8a99784de8cb171b30425a581f04a40ec1c05183777fb2b1fe3bac9", size = 2209586 }, + { url = "https://files.pythonhosted.org/packages/2a/a6/d61c836270f7be4251ab2e699dcbbdc8d4262816b6d476a11a7939b98c22/fonttools-4.55.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:61aa1997c520bee4cde14ffabe81efc4708c500c8c81dce37831551627a2be56", size = 2777603 }, + { url = "https://files.pythonhosted.org/packages/ad/7a/75085997b6ed3e27a8ca4dfcaff6b30c05bfa530e10dcd5cc03e9773eed5/fonttools-4.55.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7954ea66a8d835f279c17d8474597a001ddd65a2c1ca97e223041bfbbe11f65e", size = 2304604 }, + { url = "https://files.pythonhosted.org/packages/eb/bf/d6675455d41acef8c697460acb66b0f665edee5d605427c8e1627253a244/fonttools-4.55.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f4e88f15f5ed4d2e4bdfcc98540bb3987ae25904f9be304be9a604e7a7050a1", size = 4590378 }, + { url = "https://files.pythonhosted.org/packages/c3/c8/0b156c02bf751a78f6ecb2a008e9d626d54f77c270573800a035eab164c4/fonttools-4.55.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2d419483a6295e83cabddb56f1c7b7bfdc8169de2fcb5c68d622bd11140355f9", size = 4635372 }, + { url = "https://files.pythonhosted.org/packages/90/c6/10569414395c92c0c06f5c754f185699f812fbdfc135e02d592d7a1cf40f/fonttools-4.55.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:acc74884afddc2656bffc50100945ff407574538c152931c402fccddc46f0abc", size = 4583853 }, + { url = "https://files.pythonhosted.org/packages/25/6b/def6d14e8e2c69d8ded463d260ff4e753d4722c415aa13cd8a5d7a72f890/fonttools-4.55.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:a55489c7e9d5ea69690a2afad06723c3d0c48c6d276a25391ea97cb31a16b37c", size = 4754144 }, + { url = "https://files.pythonhosted.org/packages/6e/15/33987cdc9b340b60aa6768c326ecfc655c6c0b0628ab67ad078488f554a2/fonttools-4.55.6-cp39-cp39-win32.whl", hash = "sha256:8c9de8d16d02ecc8b65e3f3d2d1e3002be2c4a3f094d580faf76d7f768bd45fe", size = 2178974 }, + { url = "https://files.pythonhosted.org/packages/09/ff/28916026008f3d26ba44f55b7ab92c749da967a2298e8731ae1adaffd031/fonttools-4.55.6-cp39-cp39-win_amd64.whl", hash = "sha256:471961af7a4b8461fac0c8ee044b4986e6fe3746d4c83a1aacbdd85b4eb53f93", size = 2223414 }, + { url = "https://files.pythonhosted.org/packages/1e/6a/6afc55d75036b8d3fe5ceaea2e8da2c04e8f3b298325de73a35f098cb9a8/fonttools-4.55.6-py3-none-any.whl", hash = "sha256:d20ab5a78d0536c26628eaadba661e7ae2427b1e5c748a0a510a44d914e1b155", size = 1112524 }, +] + +[[package]] +name = "fqdn" +version = "1.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/30/3e/a80a8c077fd798951169626cde3e239adeba7dab75deb3555716415bd9b0/fqdn-1.5.1.tar.gz", hash = "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f", size = 6015 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl", hash = "sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014", size = 9121 }, +] + +[[package]] +name = "furo" +version = "2024.8.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "beautifulsoup4" }, + { name = "pygments" }, + { name = "sphinx" }, + { name = "sphinx-basic-ng" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a0/e2/d351d69a9a9e4badb4a5be062c2d0e87bd9e6c23b5e57337fef14bef34c8/furo-2024.8.6.tar.gz", hash = "sha256:b63e4cee8abfc3136d3bc03a3d45a76a850bada4d6374d24c1716b0e01394a01", size = 1661506 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/48/e791a7ed487dbb9729ef32bb5d1af16693d8925f4366befef54119b2e576/furo-2024.8.6-py3-none-any.whl", hash = "sha256:6cd97c58b47813d3619e63e9081169880fbe331f0ca883c871ff1f3f11814f5c", size = 341333 }, +] + +[[package]] +name = "gitdb" +version = "4.0.12" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "smmap" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/72/94/63b0fc47eb32792c7ba1fe1b694daec9a63620db1e313033d18140c2320a/gitdb-4.0.12.tar.gz", hash = "sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571", size = 394684 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl", hash = "sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf", size = 62794 }, +] + +[[package]] +name = "gitpython" +version = "3.1.44" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "gitdb" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/89/37df0b71473153574a5cdef8f242de422a0f5d26d7a9e231e6f169b4ad14/gitpython-3.1.44.tar.gz", hash = "sha256:c87e30b26253bf5418b01b0660f818967f3c503193838337fe5e573331249269", size = 214196 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1d/9a/4114a9057db2f1462d5c8f8390ab7383925fe1ac012eaa42402ad65c2963/GitPython-3.1.44-py3-none-any.whl", hash = "sha256:9e0e10cda9bed1ee64bc9a6de50e7e38a9c9943241cd7f585f6df3ed28011110", size = 207599 }, +] + +[[package]] +name = "glcontext" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3a/80/8238a0e6e972292061176141c1028b5e670aa8c94cf4c2f819bd730d314e/glcontext-3.0.0.tar.gz", hash = "sha256:57168edcd38df2fc0d70c318edf6f7e59091fba1cd3dadb289d0aa50449211ef", size = 16422 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/44/f605689047cca15d5e5d31c0a4b9ca87dd1d52bfabf3c3a05d70a4636c08/glcontext-3.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b154c25a57e16dbb073478d0cbe2c0090649d135c4c9f87e753b6181b97ec848", size = 9329 }, + { url = "https://files.pythonhosted.org/packages/10/fd/461c9e37ad50514dac82fda04a7a0aabb1a5e6b0f76476538caa4e74a25a/glcontext-3.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:fa5a14778d13ecf4a0dd60a7825427bf6ac0383eacb3b8b1a9c23e4976aa0c8c", size = 9735 }, + { url = "https://files.pythonhosted.org/packages/db/86/c879bf61d4f52d8b0cd702db5f7180b5eae8804d29a798de8da0568a64b2/glcontext-3.0.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7c229290a3a33004a59799b94a50bc5e6f8addd1b5bc5039ef9e78f86d888b31", size = 50476 }, + { url = "https://files.pythonhosted.org/packages/d6/c4/8b45b1c910f4a9b4df1ee3449b4c1aaa798fc25d86390e8eb2a18bc59669/glcontext-3.0.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1445a03d8795113034e1f9ffa662f795df65ae69ee21b26ed3b1d66100ba3f8c", size = 51480 }, + { url = "https://files.pythonhosted.org/packages/91/00/159f7df65554f30e0cc6f7fb78869e95717ed5319729f386dcc81ae9ee3d/glcontext-3.0.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:09247011c09c37b8d30eca9aa24659288de2febaeaa6a817b33b1498b5ef164c", size = 44902 }, + { url = "https://files.pythonhosted.org/packages/91/85/21d2b619576690d48e4967dce37fabe616aeee06b7c6a6c6ceb48d99d3ef/glcontext-3.0.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:c8c1223f1cbcfc0b88428e1717baca829ee863ed5d88e9b5574c7ed6598249cd", size = 47035 }, + { url = "https://files.pythonhosted.org/packages/5e/99/6c200c6d16b55d19dfd13bfed1ed5794e17e49ea8ccf9e4fab52e2d0e2d0/glcontext-3.0.0-cp310-cp310-win32.whl", hash = "sha256:c13dedb3636328b133c4d53c047ce69040ae784095e8f239432ad74d6f921712", size = 12218 }, + { url = "https://files.pythonhosted.org/packages/93/36/8a8f25366ab80dc4e6c9ded7b21f11152bba65fd6b8c0f28641ef3e133f5/glcontext-3.0.0-cp310-cp310-win_amd64.whl", hash = "sha256:4817f4cd52c7fe5410c92ca12b6712435548918719373882ade76f8f75d80abd", size = 12973 }, + { url = "https://files.pythonhosted.org/packages/01/36/3d0d09f7352b179a7ecc5fc3322beb85c8995c66db780acf791853e49043/glcontext-3.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3a9e56fa3597cc709cfd0fdf2ae682cda36510a13faac2b3142f401e823b64f4", size = 9328 }, + { url = "https://files.pythonhosted.org/packages/44/9d/0c8fd9c660db000071ebace14a40bd381a41775c10faa262fedfae8227e3/glcontext-3.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a0484308af75e04b0e56066dc2324a8fb9f1443b76ddb98833439982322b2a39", size = 9738 }, + { url = "https://files.pythonhosted.org/packages/78/cf/7bcadb995830cdd6a1a31f0527a52b2c441a499feabed9749106f7e41e67/glcontext-3.0.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:983231394396aa2a1e2b96df49404cc8f8aa729d462ed40e605a74b079c46342", size = 50663 }, + { url = "https://files.pythonhosted.org/packages/43/fb/646c2773cb097b914afe1f06c95e65deb8a544d770389bf29c76a8f3a8fd/glcontext-3.0.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7fa413f4420abff2bbb5aa5770a3e1deffcdc13e0ef2f459b145fa79c36909e7", size = 51680 }, + { url = "https://files.pythonhosted.org/packages/89/b7/04aac6c50071b858cfd02a9bccafb42a21f567992fa448c8ad8aa62939b9/glcontext-3.0.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:7d0ac35ac07fc91eccea093beb9d1c1a4eae250bc33836047deff01a3b5f4757", size = 45063 }, + { url = "https://files.pythonhosted.org/packages/3c/6e/6e398492b55f3c453cc6a2ecc2886a01b2a465623aa0c476d3e115be85c4/glcontext-3.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7145d17a70adc5784ca59ebbe19a56435ba21816070b8b433f43aa2dfb8be71a", size = 47281 }, + { url = "https://files.pythonhosted.org/packages/b5/fd/4f59118e5067a3c88217862d8672463aff29f29c1ea9f47971f8ca67e83c/glcontext-3.0.0-cp311-cp311-win32.whl", hash = "sha256:b31808ca2517fedcac8ca5b296ff46c8af012911eaa2080889a1f244d329ef9a", size = 12222 }, + { url = "https://files.pythonhosted.org/packages/20/1b/f402574ae4644e7fb389b9534de9d1be575b8a4da901a9023d1cec72c4aa/glcontext-3.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:ef4b4ec35e2b720f4cd250bb92cf6417add445490bf780345596da5a796a0e6f", size = 12975 }, + { url = "https://files.pythonhosted.org/packages/6e/61/d8f77d44bbf477b235ecbff8d421a5511d4b4f6dc676dacd84d012348516/glcontext-3.0.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:848f870a2bc72a29de7ab6756b9e8f2e6ce052e17873ebc6b3f25129b6e0d58a", size = 9360 }, + { url = "https://files.pythonhosted.org/packages/de/46/680a97d974cfe7af798542918b65bd8e65a5f8f7647edfd9fdb91a95df6c/glcontext-3.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4b3b12a66f57379566dd4d36899ac265abdbe040f3fc3293f50cd6678a1dcc9b", size = 9733 }, + { url = "https://files.pythonhosted.org/packages/74/2c/be188c4eb63b4d0cc74c644a1519b5e3a37488da3cbda724570cd5fed8d3/glcontext-3.0.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:449eaefd89c0519900715b8363ead59ac4aa32457722ca521ce01297441edb34", size = 50409 }, + { url = "https://files.pythonhosted.org/packages/32/ba/9ccb80650e5bd61e739f16f33aec3bb290a80f314631be8f7dc0a2b22b5f/glcontext-3.0.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:04921720740438ceea8fb8a38b5665963520c7c8f27bef03df8aeb3ea3cfbfb6", size = 51440 }, + { url = "https://files.pythonhosted.org/packages/c0/99/f6c9a0e614809ba5b83bd8403c475b788bd574d694bd5bc6b6ae2e2cefdf/glcontext-3.0.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:25538bdb106f673638d70e8a16a0c037a92a24c4cf40a05f0d3fa14b483d6194", size = 44820 }, + { url = "https://files.pythonhosted.org/packages/a2/29/fdbb94e4c9374390639b741774384f7413efcd7634cc9c4baacc2cf00a1f/glcontext-3.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:d11f7701b900a5a34c994e1d91c547be1cc469b73f881471460fd905f69f9e4c", size = 47055 }, + { url = "https://files.pythonhosted.org/packages/5d/fe/25b5348fe5e856697dacad34fc07e80f48eecfb38bd09806679fe0e62769/glcontext-3.0.0-cp312-cp312-win32.whl", hash = "sha256:5d2b567eaf34adb016aadce81fd2f1d4c8e4a39e3d6f2a395ce528e2a350dd3f", size = 12219 }, + { url = "https://files.pythonhosted.org/packages/17/d3/6619693ddad97011ca1c9aaeb82216ab2bfd54757be752b12f4e9a2fc489/glcontext-3.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:e80bb37ba727bd20c192f2754aea40c437a7665005c1001c10752f91913964e9", size = 12971 }, + { url = "https://files.pythonhosted.org/packages/12/be/0ef6a6710164fde818040238b041b02a082a2b9d210f18632ab2354d863e/glcontext-3.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5bd37089570d3cdb01c6c0b315c49ce8a4dcdab2c431f5ba9f37a8b633cebfdf", size = 9366 }, + { url = "https://files.pythonhosted.org/packages/b9/d7/c3220898d72fbf938660ba5789c19cf245d21b45802a5d86cbcc67d66413/glcontext-3.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:857fd83e60f15580afd369dfb651a10d84a70ec35995622d253551bfb3ff9477", size = 9735 }, + { url = "https://files.pythonhosted.org/packages/74/c1/2d57062d2f2f6e55c58b12bdeab2a39b209f959df32039d099ecdfe96bf7/glcontext-3.0.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:93fda9b378ce6d91f366e83e71ebdafdd167280a9834d1d6341ce6457c4e42ed", size = 50166 }, + { url = "https://files.pythonhosted.org/packages/03/4d/7fee00c76d678b06529e939ab6f3e3190af30208fe2e984526899026a437/glcontext-3.0.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89ad50d34aa62f03f6aaf6ae39fc27afd1b0eaefb0281aac51f686dc5672d473", size = 51186 }, + { url = "https://files.pythonhosted.org/packages/f0/58/dc9a56192b889587e51ea511804bad5dec816de81ce16831db9fe19d5c40/glcontext-3.0.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2634d5e9647a6d7b0c5a5c0c57e91ac98aa79759bffb42459af4374b049fab01", size = 44658 }, + { url = "https://files.pythonhosted.org/packages/aa/ed/acb12e67589deaa96ad29d6994c2b9383afd18700f4f2a42ff342628aac5/glcontext-3.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0140c5df37cb48271527355062d35589dc3e1e7e73b51adf9962ed5048115f69", size = 46882 }, + { url = "https://files.pythonhosted.org/packages/e0/6d/033ba23466d596c945f5f31f5c4e50cba3bc6664fdee58f6ceab54b76f4b/glcontext-3.0.0-cp313-cp313-win32.whl", hash = "sha256:6678e0552b516fa8fe62f500ef2b953bec991e82a003be2a9840d16556d03d2e", size = 12220 }, + { url = "https://files.pythonhosted.org/packages/53/b4/f0e0860526b8661ec6ae2b25a15b61100e551f57f488613c564752173a56/glcontext-3.0.0-cp313-cp313-win_amd64.whl", hash = "sha256:18aa4b1df50e8c8ea39bd0f775f39bcc987521f92c4ed019ec7d70078471354d", size = 12971 }, + { url = "https://files.pythonhosted.org/packages/89/11/d32b4e14782c3f26e2f222d28a7a915304d98ee1d4cef4b8c8157f4fedf2/glcontext-3.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7043f59d126feb26896a6419ebfeecc78c07ffefced2a2f59104dd7a2f71ebb5", size = 9325 }, + { url = "https://files.pythonhosted.org/packages/32/1a/3328aa0ea9f84cb054a846c0b1965ec172c87980cd67ea58952df1015254/glcontext-3.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4a2972f92da9a6fb06860e117de05f5b8adc2e2d827bbc0ccc7acbe7325acd1e", size = 9728 }, + { url = "https://files.pythonhosted.org/packages/d3/9f/0707f4e0ca63efb9d44169fc1e7b54e29cca59415926c9760deaa6bd511a/glcontext-3.0.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fb2eb1c455d589005567b36642db8059b31bb1752f0525c6dbe70ceeeb0131d5", size = 49942 }, + { url = "https://files.pythonhosted.org/packages/c8/62/c4ecc314437ba922a03a1c5f3df42946a1d51ee50b891b7e3c41c6115a33/glcontext-3.0.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdd81e8b580e43c1fe1c48c0fc3909e6c1f37ee4cfd8c990c03b2df3b463bd37", size = 50982 }, + { url = "https://files.pythonhosted.org/packages/51/52/6f52a5e8197c46a745daf3aff557e16afc8423e5d50a32504ab71fb7f511/glcontext-3.0.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:64eb425f0f0c54c60527e1b112465d4d69b010af42a3b0e69f22317fffd8faea", size = 44437 }, + { url = "https://files.pythonhosted.org/packages/6a/fe/f508e1578bfa1dfd2a9f8c8961bd48bfd8e7698930d30335c429e60d2580/glcontext-3.0.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:def2b9956fbd3da94b4cadeb85d947a6321582ddfea2e58c4134178bfabce0f8", size = 46592 }, + { url = "https://files.pythonhosted.org/packages/3e/e4/82b4e0907dc2464c9ef3b8e852328317738f96b7bcfaadd53d1e2ca3b679/glcontext-3.0.0-cp39-cp39-win32.whl", hash = "sha256:cfdc763adffcd20509b9e6ac964a9abf7b2a898bb32d7bd4efce9db8af2caaf5", size = 12216 }, + { url = "https://files.pythonhosted.org/packages/0c/53/068807ec322165090d9374d784e8230783a447a5f9567b52127383d1d7e3/glcontext-3.0.0-cp39-cp39-win_amd64.whl", hash = "sha256:12c2abef8efabb8ab7e35d16785968de888ae7349d1b83c765080f35fcd3c6e5", size = 12983 }, + { url = "https://files.pythonhosted.org/packages/ee/84/8f6ca5b8005ec58adbf51e2e6c3b5a20f234ea8f7a2e1df52835c9b23274/glcontext-3.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:f4e285e5d40e7a9bafeb0651c3d8f1a7c822525dec7091e97109ba87a70dbd1e", size = 9272 }, + { url = "https://files.pythonhosted.org/packages/39/a2/a0d1e7492f14727682820120062717a118f0196cda8cf6c1a6e6c4ab6d12/glcontext-3.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:96d1bbe62c5bc5315ca2f84a2abae6fa7b7d645dd368415a0cd1ee5ba6f3f8f7", size = 9581 }, + { url = "https://files.pythonhosted.org/packages/07/ba/2f093542218c9c38b293df0f501509fdfeb5dad975135a5467431aa9a774/glcontext-3.0.0-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3a190b1cdb39110c7b56c33857dbff493a364633bfd0ff402a1ce205956c94ca", size = 17842 }, + { url = "https://files.pythonhosted.org/packages/01/e5/5209be64858f9d7f9861f03ed5662491642d8d31b51a6a8495f084869386/glcontext-3.0.0-pp310-pypy310_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d467cce2dac8c3928847e90310eb6bdfdfa69f8df39b76a74734046faa15e688", size = 17226 }, + { url = "https://files.pythonhosted.org/packages/06/cb/0995eef99e56394b93bea3aa20bc269ae09125b66c0b7c1e3338f44c93cb/glcontext-3.0.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2b0c5240125d75498a8f14596484233e4effe98a6a035f566872dd2fdf472ceb", size = 12988 }, + { url = "https://files.pythonhosted.org/packages/90/8c/5aa059180e34e7222960e4570914d60bcc52bd86fe63d771c166a5a7ef9b/glcontext-3.0.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:cf5af894228b4357b088a6e26761438d799c2af907e33f17935072fe46903c2d", size = 9273 }, + { url = "https://files.pythonhosted.org/packages/a0/f2/2ff96dd4e95835eb306f79d8ea9a7c0ec345c66707fd2fa541016c51c84d/glcontext-3.0.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:1712d7a7216b687b181291098e5117e5fae1f1df466583b4290dc2e80d9a72c8", size = 9574 }, + { url = "https://files.pythonhosted.org/packages/37/ee/0c99857054ad659d826459cb228286255f7f90f09d9054685e62cbe34cec/glcontext-3.0.0-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:07980350ba2aac9f793185f90c4f561ae1aa03cc11b58cce4b51e20a70e8c6e3", size = 17837 }, + { url = "https://files.pythonhosted.org/packages/8e/ad/fc484a51638e41ab82429fa5cd69b809938ffa80badc9887357e006476f2/glcontext-3.0.0-pp39-pypy39_pp73-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed5135fdb0da5e0decea1cb26ca10a279188aa0bc4462f1c77e214d6f956a710", size = 17226 }, + { url = "https://files.pythonhosted.org/packages/60/94/d4c9cdf99ac89c673454c3dbf385cb48385d05df8394784902e5f0e00801/glcontext-3.0.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:c3648e13478d77128a74dd25baa98faf9ddb9cbcba5af39775ef3a496f71fd10", size = 12995 }, +] + +[[package]] +name = "h11" +version = "0.14.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259 }, +] + +[[package]] +name = "httpcore" +version = "1.0.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "h11" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6a/41/d7d0a89eb493922c37d343b607bc1b5da7f5be7e383740b4753ad8943e90/httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c", size = 85196 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/87/f5/72347bc88306acb359581ac4d52f23c0ef445b57157adedb9aee0cd689d2/httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd", size = 78551 }, +] + +[[package]] +name = "httpx" +version = "0.28.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "certifi" }, + { name = "httpcore" }, + { name = "idna" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517 }, +] + +[[package]] +name = "identify" +version = "2.6.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/82/bf/c68c46601bacd4c6fb4dd751a42b6e7087240eaabc6487f2ef7a48e0e8fc/identify-2.6.6.tar.gz", hash = "sha256:7bec12768ed44ea4761efb47806f0a41f86e7c0a5fdf5950d4648c90eca7e251", size = 99217 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/74/a1/68a395c17eeefb04917034bd0a1bfa765e7654fa150cca473d669aa3afb5/identify-2.6.6-py2.py3-none-any.whl", hash = "sha256:cbd1810bce79f8b671ecb20f53ee0ae8e86ae84b557de31d89709dc2a48ba881", size = 99083 }, +] + +[[package]] +name = "idna" +version = "3.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 }, +] + +[[package]] +name = "imagesize" +version = "1.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a7/84/62473fb57d61e31fef6e36d64a179c8781605429fd927b5dd608c997be31/imagesize-1.4.1.tar.gz", hash = "sha256:69150444affb9cb0d5cc5a92b3676f0b2fb7cd9ae39e947a5e11a36b4497cd4a", size = 1280026 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ff/62/85c4c919272577931d407be5ba5d71c20f0b616d31a0befe0ae45bb79abd/imagesize-1.4.1-py2.py3-none-any.whl", hash = "sha256:0d8d18d08f840c19d0ee7ca1fd82490fdc3729b7ac93f49870406ddde8ef8d8b", size = 8769 }, +] + +[[package]] +name = "importlib-metadata" +version = "8.6.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "zipp", marker = "python_full_version < '3.10'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/33/08/c1395a292bb23fd03bdf572a1357c5a733d3eecbab877641ceacab23db6e/importlib_metadata-8.6.1.tar.gz", hash = "sha256:310b41d755445d74569f993ccfc22838295d9fe005425094fad953d7f15c8580", size = 55767 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/79/9d/0fb148dc4d6fa4a7dd1d8378168d9b4cd8d4560a6fbf6f0121c5fc34eb68/importlib_metadata-8.6.1-py3-none-any.whl", hash = "sha256:02a89390c1e15fdfdc0d7c6b25cb3e62650d0494005c97d6f148bf5b9787525e", size = 26971 }, +] + +[[package]] +name = "importlib-resources" +version = "6.5.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "zipp", marker = "python_full_version < '3.10'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cf/8c/f834fbf984f691b4f7ff60f50b514cc3de5cc08abfc3295564dd89c5e2e7/importlib_resources-6.5.2.tar.gz", hash = "sha256:185f87adef5bcc288449d98fb4fba07cea78bc036455dd44c5fc4a2fe78fed2c", size = 44693 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a4/ed/1f1afb2e9e7f38a545d628f864d562a5ae64fe6f7a10e28ffb9b185b4e89/importlib_resources-6.5.2-py3-none-any.whl", hash = "sha256:789cfdc3ed28c78b67a06acb8126751ced69a3d5f79c095a98298cd8a760ccec", size = 37461 }, +] + +[[package]] +name = "iniconfig" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 }, +] + +[[package]] +name = "ipykernel" +version = "6.29.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "appnope", marker = "sys_platform == 'darwin'" }, + { name = "comm" }, + { name = "debugpy" }, + { name = "ipython" }, + { name = "jupyter-client" }, + { name = "jupyter-core" }, + { name = "matplotlib-inline" }, + { name = "nest-asyncio" }, + { name = "packaging" }, + { name = "psutil" }, + { name = "pyzmq" }, + { name = "tornado" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e9/5c/67594cb0c7055dc50814b21731c22a601101ea3b1b50a9a1b090e11f5d0f/ipykernel-6.29.5.tar.gz", hash = "sha256:f093a22c4a40f8828f8e330a9c297cb93dcab13bd9678ded6de8e5cf81c56215", size = 163367 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/5c/368ae6c01c7628438358e6d337c19b05425727fbb221d2a3c4303c372f42/ipykernel-6.29.5-py3-none-any.whl", hash = "sha256:afdb66ba5aa354b09b91379bac28ae4afebbb30e8b39510c9690afb7a10421b5", size = 117173 }, +] + +[[package]] +name = "ipython" +version = "8.18.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "decorator" }, + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "jedi" }, + { name = "matplotlib-inline" }, + { name = "pexpect", marker = "sys_platform != 'win32'" }, + { name = "prompt-toolkit" }, + { name = "pygments" }, + { name = "stack-data" }, + { name = "traitlets" }, + { name = "typing-extensions", marker = "python_full_version < '3.10'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/b9/3ba6c45a6df813c09a48bac313c22ff83efa26cbb55011218d925a46e2ad/ipython-8.18.1.tar.gz", hash = "sha256:ca6f079bb33457c66e233e4580ebfc4128855b4cf6370dddd73842a9563e8a27", size = 5486330 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/47/6b/d9fdcdef2eb6a23f391251fde8781c38d42acd82abe84d054cb74f7863b0/ipython-8.18.1-py3-none-any.whl", hash = "sha256:e8267419d72d81955ec1177f8a29aaa90ac80ad647499201119e2f05e99aa397", size = 808161 }, +] + +[[package]] +name = "isoduration" +version = "20.11.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "arrow" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7c/1a/3c8edc664e06e6bd06cce40c6b22da5f1429aa4224d0c590f3be21c91ead/isoduration-20.11.0.tar.gz", hash = "sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9", size = 11649 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl", hash = "sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042", size = 11321 }, +] + +[[package]] +name = "isosurfaces" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", version = "2.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, + { name = "numpy", version = "2.2.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/da/cf/bd7e70bb7b8dfd77afdc79aba8d83afd4a9263f045861cd4ddd34b7f6a12/isosurfaces-0.1.2.tar.gz", hash = "sha256:fa51ebe864ea9355b26830e27fdd6a41d5a58b419fa8d4b47e3b8b80718d6e21", size = 11348 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b1/68/d5e9e6e0d6e43107d8393d2ee3d231dbb597bf93052c6f3117b313724980/isosurfaces-0.1.2-py3-none-any.whl", hash = "sha256:525a49ba93f4dbc35303cd2faf30976af0f99d9274cfa2787aec016b8ef96c64", size = 11649 }, +] + +[[package]] +name = "jedi" +version = "0.19.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "parso" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/72/3a/79a912fbd4d8dd6fbb02bf69afd3bb72cf0c729bb3063c6f4498603db17a/jedi-0.19.2.tar.gz", hash = "sha256:4770dc3de41bde3966b02eb84fbcf557fb33cce26ad23da12c742fb50ecb11f0", size = 1231287 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c0/5a/9cac0c82afec3d09ccd97c8b6502d48f165f9124db81b4bcb90b4af974ee/jedi-0.19.2-py2.py3-none-any.whl", hash = "sha256:a8ef22bde8490f57fe5c7681a3c83cb58874daf72b4784de3cce5b6ef6edb5b9", size = 1572278 }, +] + +[[package]] +name = "jinja2" +version = "3.1.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/af/92/b3130cbbf5591acf9ade8708c365f3238046ac7cb8ccba6e81abccb0ccff/jinja2-3.1.5.tar.gz", hash = "sha256:8fefff8dc3034e27bb80d67c671eb8a9bc424c0ef4c0826edbff304cceff43bb", size = 244674 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bd/0f/2ba5fbcd631e3e88689309dbe978c5769e883e4b84ebfe7da30b43275c5a/jinja2-3.1.5-py3-none-any.whl", hash = "sha256:aba0f4dc9ed8013c424088f68a5c226f7d6097ed89b246d7749c2ec4175c6adb", size = 134596 }, +] + +[[package]] +name = "json5" +version = "0.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/85/3d/bbe62f3d0c05a689c711cff57b2e3ac3d3e526380adb7c781989f075115c/json5-0.10.0.tar.gz", hash = "sha256:e66941c8f0a02026943c52c2eb34ebeb2a6f819a0be05920a6f5243cd30fd559", size = 48202 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/aa/42/797895b952b682c3dafe23b1834507ee7f02f4d6299b65aaa61425763278/json5-0.10.0-py3-none-any.whl", hash = "sha256:19b23410220a7271e8377f81ba8aacba2fdd56947fbb137ee5977cbe1f5e8dfa", size = 34049 }, +] + +[[package]] +name = "jsonpointer" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6a/0a/eebeb1fa92507ea94016a2a790b93c2ae41a7e18778f85471dc54475ed25/jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef", size = 9114 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942", size = 7595 }, +] + +[[package]] +name = "jsonschema" +version = "4.23.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "jsonschema-specifications" }, + { name = "referencing" }, + { name = "rpds-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/38/2e/03362ee4034a4c917f697890ccd4aec0800ccf9ded7f511971c75451deec/jsonschema-4.23.0.tar.gz", hash = "sha256:d71497fef26351a33265337fa77ffeb82423f3ea21283cd9467bb03999266bc4", size = 325778 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/4a/4f9dbeb84e8850557c02365a0eee0649abe5eb1d84af92a25731c6c0f922/jsonschema-4.23.0-py3-none-any.whl", hash = "sha256:fbadb6f8b144a8f8cf9f0b89ba94501d143e50411a1278633f56a7acf7fd5566", size = 88462 }, +] + +[package.optional-dependencies] +format-nongpl = [ + { name = "fqdn" }, + { name = "idna" }, + { name = "isoduration" }, + { name = "jsonpointer" }, + { name = "rfc3339-validator" }, + { name = "rfc3986-validator" }, + { name = "uri-template" }, + { name = "webcolors" }, +] + +[[package]] +name = "jsonschema-specifications" +version = "2024.10.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "referencing" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/10/db/58f950c996c793472e336ff3655b13fbcf1e3b359dcf52dcf3ed3b52c352/jsonschema_specifications-2024.10.1.tar.gz", hash = "sha256:0f38b83639958ce1152d02a7f062902c41c8fd20d558b0c34344292d417ae272", size = 15561 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/0f/8910b19ac0670a0f80ce1008e5e751c4a57e14d2c4c13a482aa6079fa9d6/jsonschema_specifications-2024.10.1-py3-none-any.whl", hash = "sha256:a09a0680616357d9a0ecf05c12ad234479f549239d0f5b55f3deea67475da9bf", size = 18459 }, +] + +[[package]] +name = "jupyter-client" +version = "8.6.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "importlib-metadata", marker = "python_full_version < '3.10'" }, + { name = "jupyter-core" }, + { name = "python-dateutil" }, + { name = "pyzmq" }, + { name = "tornado" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/71/22/bf9f12fdaeae18019a468b68952a60fe6dbab5d67cd2a103cac7659b41ca/jupyter_client-8.6.3.tar.gz", hash = "sha256:35b3a0947c4a6e9d589eb97d7d4cd5e90f910ee73101611f01283732bd6d9419", size = 342019 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/11/85/b0394e0b6fcccd2c1eeefc230978a6f8cb0c5df1e4cd3e7625735a0d7d1e/jupyter_client-8.6.3-py3-none-any.whl", hash = "sha256:e8a19cc986cc45905ac3362915f410f3af85424b4c0905e94fa5f2cb08e8f23f", size = 106105 }, +] + +[[package]] +name = "jupyter-core" +version = "5.7.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "platformdirs" }, + { name = "pywin32", marker = "platform_python_implementation != 'PyPy' and sys_platform == 'win32'" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/00/11/b56381fa6c3f4cc5d2cf54a7dbf98ad9aa0b339ef7a601d6053538b079a7/jupyter_core-5.7.2.tar.gz", hash = "sha256:aa5f8d32bbf6b431ac830496da7392035d6f61b4f54872f15c4bd2a9c3f536d9", size = 87629 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c9/fb/108ecd1fe961941959ad0ee4e12ee7b8b1477247f30b1fdfd83ceaf017f0/jupyter_core-5.7.2-py3-none-any.whl", hash = "sha256:4f7315d2f6b4bcf2e3e7cb6e46772eba760ae459cd1f59d29eb57b0a01bd7409", size = 28965 }, +] + +[[package]] +name = "jupyter-events" +version = "0.11.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jsonschema", extra = ["format-nongpl"] }, + { name = "python-json-logger" }, + { name = "pyyaml" }, + { name = "referencing" }, + { name = "rfc3339-validator" }, + { name = "rfc3986-validator" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f4/65/5791c8a979b5646ca29ea50e42b6708908b789f7ff389d1a03c1b93a1c54/jupyter_events-0.11.0.tar.gz", hash = "sha256:c0bc56a37aac29c1fbc3bcfbddb8c8c49533f9cf11f1c4e6adadba936574ab90", size = 62039 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/8c/9b65cb2cd4ea32d885993d5542244641590530836802a2e8c7449a4c61c9/jupyter_events-0.11.0-py3-none-any.whl", hash = "sha256:36399b41ce1ca45fe8b8271067d6a140ffa54cec4028e95491c93b78a855cacf", size = 19423 }, +] + +[[package]] +name = "jupyter-lsp" +version = "2.2.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "importlib-metadata", marker = "python_full_version < '3.10'" }, + { name = "jupyter-server" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/85/b4/3200b0b09c12bc3b72d943d923323c398eff382d1dcc7c0dbc8b74630e40/jupyter-lsp-2.2.5.tar.gz", hash = "sha256:793147a05ad446f809fd53ef1cd19a9f5256fd0a2d6b7ce943a982cb4f545001", size = 48741 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/e0/7bd7cff65594fd9936e2f9385701e44574fc7d721331ff676ce440b14100/jupyter_lsp-2.2.5-py3-none-any.whl", hash = "sha256:45fbddbd505f3fbfb0b6cb2f1bc5e15e83ab7c79cd6e89416b248cb3c00c11da", size = 69146 }, +] + +[[package]] +name = "jupyter-server" +version = "2.15.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio" }, + { name = "argon2-cffi" }, + { name = "jinja2" }, + { name = "jupyter-client" }, + { name = "jupyter-core" }, + { name = "jupyter-events" }, + { name = "jupyter-server-terminals" }, + { name = "nbconvert" }, + { name = "nbformat" }, + { name = "overrides" }, + { name = "packaging" }, + { name = "prometheus-client" }, + { name = "pywinpty", marker = "os_name == 'nt'" }, + { name = "pyzmq" }, + { name = "send2trash" }, + { name = "terminado" }, + { name = "tornado" }, + { name = "traitlets" }, + { name = "websocket-client" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/61/8c/df09d4ab646141f130f9977b32b206ba8615d1969b2eba6a2e84b7f89137/jupyter_server-2.15.0.tar.gz", hash = "sha256:9d446b8697b4f7337a1b7cdcac40778babdd93ba614b6d68ab1c0c918f1c4084", size = 725227 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e2/a2/89eeaf0bb954a123a909859fa507fa86f96eb61b62dc30667b60dbd5fdaf/jupyter_server-2.15.0-py3-none-any.whl", hash = "sha256:872d989becf83517012ee669f09604aa4a28097c0bd90b2f424310156c2cdae3", size = 385826 }, +] + +[[package]] +name = "jupyter-server-terminals" +version = "0.5.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pywinpty", marker = "os_name == 'nt'" }, + { name = "terminado" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fc/d5/562469734f476159e99a55426d697cbf8e7eb5efe89fb0e0b4f83a3d3459/jupyter_server_terminals-0.5.3.tar.gz", hash = "sha256:5ae0295167220e9ace0edcfdb212afd2b01ee8d179fe6f23c899590e9b8a5269", size = 31430 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/2d/2b32cdbe8d2a602f697a649798554e4f072115438e92249624e532e8aca6/jupyter_server_terminals-0.5.3-py3-none-any.whl", hash = "sha256:41ee0d7dc0ebf2809c668e0fc726dfaf258fcd3e769568996ca731b6194ae9aa", size = 13656 }, +] + +[[package]] +name = "jupyterlab" +version = "4.3.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "async-lru" }, + { name = "httpx" }, + { name = "importlib-metadata", marker = "python_full_version < '3.10'" }, + { name = "ipykernel" }, + { name = "jinja2" }, + { name = "jupyter-core" }, + { name = "jupyter-lsp" }, + { name = "jupyter-server" }, + { name = "jupyterlab-server" }, + { name = "notebook-shim" }, + { name = "packaging" }, + { name = "setuptools" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "tornado" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a7/45/1052f842e066902b1d78126df7e2269b1b9408991e1344e167b2e429f9e1/jupyterlab-4.3.4.tar.gz", hash = "sha256:f0bb9b09a04766e3423cccc2fc23169aa2ffedcdf8713e9e0fb33cac0b6859d0", size = 21797583 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/61/48/af57263e53cfc220e522de047aa0993f53bab734fe812af1e03e33ac6d7c/jupyterlab-4.3.4-py3-none-any.whl", hash = "sha256:b754c2601c5be6adf87cb5a1d8495d653ffb945f021939f77776acaa94dae952", size = 11665373 }, +] + +[[package]] +name = "jupyterlab-pygments" +version = "0.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/90/51/9187be60d989df97f5f0aba133fa54e7300f17616e065d1ada7d7646b6d6/jupyterlab_pygments-0.3.0.tar.gz", hash = "sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d", size = 512900 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl", hash = "sha256:841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780", size = 15884 }, +] + +[[package]] +name = "jupyterlab-server" +version = "2.27.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "babel" }, + { name = "importlib-metadata", marker = "python_full_version < '3.10'" }, + { name = "jinja2" }, + { name = "json5" }, + { name = "jsonschema" }, + { name = "jupyter-server" }, + { name = "packaging" }, + { name = "requests" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0a/c9/a883ce65eb27905ce77ace410d83587c82ea64dc85a48d1f7ed52bcfa68d/jupyterlab_server-2.27.3.tar.gz", hash = "sha256:eb36caca59e74471988f0ae25c77945610b887f777255aa21f8065def9e51ed4", size = 76173 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/09/2032e7d15c544a0e3cd831c51d77a8ca57f7555b2e1b2922142eddb02a84/jupyterlab_server-2.27.3-py3-none-any.whl", hash = "sha256:e697488f66c3db49df675158a77b3b017520d772c6e1548c7d9bcc5df7944ee4", size = 59700 }, +] + +[[package]] +name = "kiwisolver" +version = "1.4.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/85/4d/2255e1c76304cbd60b48cee302b66d1dde4468dc5b1160e4b7cb43778f2a/kiwisolver-1.4.7.tar.gz", hash = "sha256:9893ff81bd7107f7b685d3017cc6583daadb4fc26e4a888350df530e41980a60", size = 97286 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/97/14/fc943dd65268a96347472b4fbe5dcc2f6f55034516f80576cd0dd3a8930f/kiwisolver-1.4.7-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:8a9c83f75223d5e48b0bc9cb1bf2776cf01563e00ade8775ffe13b0b6e1af3a6", size = 122440 }, + { url = "https://files.pythonhosted.org/packages/1e/46/e68fed66236b69dd02fcdb506218c05ac0e39745d696d22709498896875d/kiwisolver-1.4.7-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:58370b1ffbd35407444d57057b57da5d6549d2d854fa30249771775c63b5fe17", size = 65758 }, + { url = "https://files.pythonhosted.org/packages/ef/fa/65de49c85838681fc9cb05de2a68067a683717321e01ddafb5b8024286f0/kiwisolver-1.4.7-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:aa0abdf853e09aff551db11fce173e2177d00786c688203f52c87ad7fcd91ef9", size = 64311 }, + { url = "https://files.pythonhosted.org/packages/42/9c/cc8d90f6ef550f65443bad5872ffa68f3dee36de4974768628bea7c14979/kiwisolver-1.4.7-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:8d53103597a252fb3ab8b5845af04c7a26d5e7ea8122303dd7a021176a87e8b9", size = 1637109 }, + { url = "https://files.pythonhosted.org/packages/55/91/0a57ce324caf2ff5403edab71c508dd8f648094b18cfbb4c8cc0fde4a6ac/kiwisolver-1.4.7-cp310-cp310-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:88f17c5ffa8e9462fb79f62746428dd57b46eb931698e42e990ad63103f35e6c", size = 1617814 }, + { url = "https://files.pythonhosted.org/packages/12/5d/c36140313f2510e20207708adf36ae4919416d697ee0236b0ddfb6fd1050/kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88a9ca9c710d598fd75ee5de59d5bda2684d9db36a9f50b6125eaea3969c2599", size = 1400881 }, + { url = "https://files.pythonhosted.org/packages/56/d0/786e524f9ed648324a466ca8df86298780ef2b29c25313d9a4f16992d3cf/kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f4d742cb7af1c28303a51b7a27aaee540e71bb8e24f68c736f6f2ffc82f2bf05", size = 1512972 }, + { url = "https://files.pythonhosted.org/packages/67/5a/77851f2f201e6141d63c10a0708e996a1363efaf9e1609ad0441b343763b/kiwisolver-1.4.7-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e28c7fea2196bf4c2f8d46a0415c77a1c480cc0724722f23d7410ffe9842c407", size = 1444787 }, + { url = "https://files.pythonhosted.org/packages/06/5f/1f5eaab84355885e224a6fc8d73089e8713dc7e91c121f00b9a1c58a2195/kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e968b84db54f9d42046cf154e02911e39c0435c9801681e3fc9ce8a3c4130278", size = 2199212 }, + { url = "https://files.pythonhosted.org/packages/b5/28/9152a3bfe976a0ae21d445415defc9d1cd8614b2910b7614b30b27a47270/kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:0c18ec74c0472de033e1bebb2911c3c310eef5649133dd0bedf2a169a1b269e5", size = 2346399 }, + { url = "https://files.pythonhosted.org/packages/26/f6/453d1904c52ac3b400f4d5e240ac5fec25263716723e44be65f4d7149d13/kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:8f0ea6da6d393d8b2e187e6a5e3fb81f5862010a40c3945e2c6d12ae45cfb2ad", size = 2308688 }, + { url = "https://files.pythonhosted.org/packages/5a/9a/d4968499441b9ae187e81745e3277a8b4d7c60840a52dc9d535a7909fac3/kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:f106407dda69ae456dd1227966bf445b157ccc80ba0dff3802bb63f30b74e895", size = 2445493 }, + { url = "https://files.pythonhosted.org/packages/07/c9/032267192e7828520dacb64dfdb1d74f292765f179e467c1cba97687f17d/kiwisolver-1.4.7-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:84ec80df401cfee1457063732d90022f93951944b5b58975d34ab56bb150dfb3", size = 2262191 }, + { url = "https://files.pythonhosted.org/packages/6c/ad/db0aedb638a58b2951da46ddaeecf204be8b4f5454df020d850c7fa8dca8/kiwisolver-1.4.7-cp310-cp310-win32.whl", hash = "sha256:71bb308552200fb2c195e35ef05de12f0c878c07fc91c270eb3d6e41698c3bcc", size = 46644 }, + { url = "https://files.pythonhosted.org/packages/12/ca/d0f7b7ffbb0be1e7c2258b53554efec1fd652921f10d7d85045aff93ab61/kiwisolver-1.4.7-cp310-cp310-win_amd64.whl", hash = "sha256:44756f9fd339de0fb6ee4f8c1696cfd19b2422e0d70b4cefc1cc7f1f64045a8c", size = 55877 }, + { url = "https://files.pythonhosted.org/packages/97/6c/cfcc128672f47a3e3c0d918ecb67830600078b025bfc32d858f2e2d5c6a4/kiwisolver-1.4.7-cp310-cp310-win_arm64.whl", hash = "sha256:78a42513018c41c2ffd262eb676442315cbfe3c44eed82385c2ed043bc63210a", size = 48347 }, + { url = "https://files.pythonhosted.org/packages/e9/44/77429fa0a58f941d6e1c58da9efe08597d2e86bf2b2cce6626834f49d07b/kiwisolver-1.4.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:d2b0e12a42fb4e72d509fc994713d099cbb15ebf1103545e8a45f14da2dfca54", size = 122442 }, + { url = "https://files.pythonhosted.org/packages/e5/20/8c75caed8f2462d63c7fd65e16c832b8f76cda331ac9e615e914ee80bac9/kiwisolver-1.4.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2a8781ac3edc42ea4b90bc23e7d37b665d89423818e26eb6df90698aa2287c95", size = 65762 }, + { url = "https://files.pythonhosted.org/packages/f4/98/fe010f15dc7230f45bc4cf367b012d651367fd203caaa992fd1f5963560e/kiwisolver-1.4.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:46707a10836894b559e04b0fd143e343945c97fd170d69a2d26d640b4e297935", size = 64319 }, + { url = "https://files.pythonhosted.org/packages/8b/1b/b5d618f4e58c0675654c1e5051bcf42c776703edb21c02b8c74135541f60/kiwisolver-1.4.7-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ef97b8df011141c9b0f6caf23b29379f87dd13183c978a30a3c546d2c47314cb", size = 1334260 }, + { url = "https://files.pythonhosted.org/packages/b8/01/946852b13057a162a8c32c4c8d2e9ed79f0bb5d86569a40c0b5fb103e373/kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3ab58c12a2cd0fc769089e6d38466c46d7f76aced0a1f54c77652446733d2d02", size = 1426589 }, + { url = "https://files.pythonhosted.org/packages/70/d1/c9f96df26b459e15cf8a965304e6e6f4eb291e0f7a9460b4ad97b047561e/kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:803b8e1459341c1bb56d1c5c010406d5edec8a0713a0945851290a7930679b51", size = 1541080 }, + { url = "https://files.pythonhosted.org/packages/d3/73/2686990eb8b02d05f3de759d6a23a4ee7d491e659007dd4c075fede4b5d0/kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f9a9e8a507420fe35992ee9ecb302dab68550dedc0da9e2880dd88071c5fb052", size = 1470049 }, + { url = "https://files.pythonhosted.org/packages/a7/4b/2db7af3ed3af7c35f388d5f53c28e155cd402a55432d800c543dc6deb731/kiwisolver-1.4.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18077b53dc3bb490e330669a99920c5e6a496889ae8c63b58fbc57c3d7f33a18", size = 1426376 }, + { url = "https://files.pythonhosted.org/packages/05/83/2857317d04ea46dc5d115f0df7e676997bbd968ced8e2bd6f7f19cfc8d7f/kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6af936f79086a89b3680a280c47ea90b4df7047b5bdf3aa5c524bbedddb9e545", size = 2222231 }, + { url = "https://files.pythonhosted.org/packages/0d/b5/866f86f5897cd4ab6d25d22e403404766a123f138bd6a02ecb2cdde52c18/kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:3abc5b19d24af4b77d1598a585b8a719beb8569a71568b66f4ebe1fb0449460b", size = 2368634 }, + { url = "https://files.pythonhosted.org/packages/c1/ee/73de8385403faba55f782a41260210528fe3273d0cddcf6d51648202d6d0/kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:933d4de052939d90afbe6e9d5273ae05fb836cc86c15b686edd4b3560cc0ee36", size = 2329024 }, + { url = "https://files.pythonhosted.org/packages/a1/e7/cd101d8cd2cdfaa42dc06c433df17c8303d31129c9fdd16c0ea37672af91/kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:65e720d2ab2b53f1f72fb5da5fb477455905ce2c88aaa671ff0a447c2c80e8e3", size = 2468484 }, + { url = "https://files.pythonhosted.org/packages/e1/72/84f09d45a10bc57a40bb58b81b99d8f22b58b2040c912b7eb97ebf625bf2/kiwisolver-1.4.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3bf1ed55088f214ba6427484c59553123fdd9b218a42bbc8c6496d6754b1e523", size = 2284078 }, + { url = "https://files.pythonhosted.org/packages/d2/d4/71828f32b956612dc36efd7be1788980cb1e66bfb3706e6dec9acad9b4f9/kiwisolver-1.4.7-cp311-cp311-win32.whl", hash = "sha256:4c00336b9dd5ad96d0a558fd18a8b6f711b7449acce4c157e7343ba92dd0cf3d", size = 46645 }, + { url = "https://files.pythonhosted.org/packages/a1/65/d43e9a20aabcf2e798ad1aff6c143ae3a42cf506754bcb6a7ed8259c8425/kiwisolver-1.4.7-cp311-cp311-win_amd64.whl", hash = "sha256:929e294c1ac1e9f615c62a4e4313ca1823ba37326c164ec720a803287c4c499b", size = 56022 }, + { url = "https://files.pythonhosted.org/packages/35/b3/9f75a2e06f1b4ca00b2b192bc2b739334127d27f1d0625627ff8479302ba/kiwisolver-1.4.7-cp311-cp311-win_arm64.whl", hash = "sha256:e33e8fbd440c917106b237ef1a2f1449dfbb9b6f6e1ce17c94cd6a1e0d438376", size = 48536 }, + { url = "https://files.pythonhosted.org/packages/97/9c/0a11c714cf8b6ef91001c8212c4ef207f772dd84540104952c45c1f0a249/kiwisolver-1.4.7-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:5360cc32706dab3931f738d3079652d20982511f7c0ac5711483e6eab08efff2", size = 121808 }, + { url = "https://files.pythonhosted.org/packages/f2/d8/0fe8c5f5d35878ddd135f44f2af0e4e1d379e1c7b0716f97cdcb88d4fd27/kiwisolver-1.4.7-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:942216596dc64ddb25adb215c3c783215b23626f8d84e8eff8d6d45c3f29f75a", size = 65531 }, + { url = "https://files.pythonhosted.org/packages/80/c5/57fa58276dfdfa612241d640a64ca2f76adc6ffcebdbd135b4ef60095098/kiwisolver-1.4.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:48b571ecd8bae15702e4f22d3ff6a0f13e54d3d00cd25216d5e7f658242065ee", size = 63894 }, + { url = "https://files.pythonhosted.org/packages/8b/e9/26d3edd4c4ad1c5b891d8747a4f81b1b0aba9fb9721de6600a4adc09773b/kiwisolver-1.4.7-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ad42ba922c67c5f219097b28fae965e10045ddf145d2928bfac2eb2e17673640", size = 1369296 }, + { url = "https://files.pythonhosted.org/packages/b6/67/3f4850b5e6cffb75ec40577ddf54f7b82b15269cc5097ff2e968ee32ea7d/kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:612a10bdae23404a72941a0fc8fa2660c6ea1217c4ce0dbcab8a8f6543ea9e7f", size = 1461450 }, + { url = "https://files.pythonhosted.org/packages/52/be/86cbb9c9a315e98a8dc6b1d23c43cffd91d97d49318854f9c37b0e41cd68/kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9e838bba3a3bac0fe06d849d29772eb1afb9745a59710762e4ba3f4cb8424483", size = 1579168 }, + { url = "https://files.pythonhosted.org/packages/0f/00/65061acf64bd5fd34c1f4ae53f20b43b0a017a541f242a60b135b9d1e301/kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:22f499f6157236c19f4bbbd472fa55b063db77a16cd74d49afe28992dff8c258", size = 1507308 }, + { url = "https://files.pythonhosted.org/packages/21/e4/c0b6746fd2eb62fe702118b3ca0cb384ce95e1261cfada58ff693aeec08a/kiwisolver-1.4.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:693902d433cf585133699972b6d7c42a8b9f8f826ebcaf0132ff55200afc599e", size = 1464186 }, + { url = "https://files.pythonhosted.org/packages/0a/0f/529d0a9fffb4d514f2782c829b0b4b371f7f441d61aa55f1de1c614c4ef3/kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4e77f2126c3e0b0d055f44513ed349038ac180371ed9b52fe96a32aa071a5107", size = 2247877 }, + { url = "https://files.pythonhosted.org/packages/d1/e1/66603ad779258843036d45adcbe1af0d1a889a07af4635f8b4ec7dccda35/kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:657a05857bda581c3656bfc3b20e353c232e9193eb167766ad2dc58b56504948", size = 2404204 }, + { url = "https://files.pythonhosted.org/packages/8d/61/de5fb1ca7ad1f9ab7970e340a5b833d735df24689047de6ae71ab9d8d0e7/kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4bfa75a048c056a411f9705856abfc872558e33c055d80af6a380e3658766038", size = 2352461 }, + { url = "https://files.pythonhosted.org/packages/ba/d2/0edc00a852e369827f7e05fd008275f550353f1f9bcd55db9363d779fc63/kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:34ea1de54beef1c104422d210c47c7d2a4999bdecf42c7b5718fbe59a4cac383", size = 2501358 }, + { url = "https://files.pythonhosted.org/packages/84/15/adc15a483506aec6986c01fb7f237c3aec4d9ed4ac10b756e98a76835933/kiwisolver-1.4.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:90da3b5f694b85231cf93586dad5e90e2d71b9428f9aad96952c99055582f520", size = 2314119 }, + { url = "https://files.pythonhosted.org/packages/36/08/3a5bb2c53c89660863a5aa1ee236912269f2af8762af04a2e11df851d7b2/kiwisolver-1.4.7-cp312-cp312-win32.whl", hash = "sha256:18e0cca3e008e17fe9b164b55735a325140a5a35faad8de92dd80265cd5eb80b", size = 46367 }, + { url = "https://files.pythonhosted.org/packages/19/93/c05f0a6d825c643779fc3c70876bff1ac221f0e31e6f701f0e9578690d70/kiwisolver-1.4.7-cp312-cp312-win_amd64.whl", hash = "sha256:58cb20602b18f86f83a5c87d3ee1c766a79c0d452f8def86d925e6c60fbf7bfb", size = 55884 }, + { url = "https://files.pythonhosted.org/packages/d2/f9/3828d8f21b6de4279f0667fb50a9f5215e6fe57d5ec0d61905914f5b6099/kiwisolver-1.4.7-cp312-cp312-win_arm64.whl", hash = "sha256:f5a8b53bdc0b3961f8b6125e198617c40aeed638b387913bf1ce78afb1b0be2a", size = 48528 }, + { url = "https://files.pythonhosted.org/packages/c4/06/7da99b04259b0f18b557a4effd1b9c901a747f7fdd84cf834ccf520cb0b2/kiwisolver-1.4.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:2e6039dcbe79a8e0f044f1c39db1986a1b8071051efba3ee4d74f5b365f5226e", size = 121913 }, + { url = "https://files.pythonhosted.org/packages/97/f5/b8a370d1aa593c17882af0a6f6755aaecd643640c0ed72dcfd2eafc388b9/kiwisolver-1.4.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a1ecf0ac1c518487d9d23b1cd7139a6a65bc460cd101ab01f1be82ecf09794b6", size = 65627 }, + { url = "https://files.pythonhosted.org/packages/2a/fc/6c0374f7503522539e2d4d1b497f5ebad3f8ed07ab51aed2af988dd0fb65/kiwisolver-1.4.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7ab9ccab2b5bd5702ab0803676a580fffa2aa178c2badc5557a84cc943fcf750", size = 63888 }, + { url = "https://files.pythonhosted.org/packages/bf/3e/0b7172793d0f41cae5c923492da89a2ffcd1adf764c16159ca047463ebd3/kiwisolver-1.4.7-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f816dd2277f8d63d79f9c8473a79fe54047bc0467754962840782c575522224d", size = 1369145 }, + { url = "https://files.pythonhosted.org/packages/77/92/47d050d6f6aced2d634258123f2688fbfef8ded3c5baf2c79d94d91f1f58/kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf8bcc23ceb5a1b624572a1623b9f79d2c3b337c8c455405ef231933a10da379", size = 1461448 }, + { url = "https://files.pythonhosted.org/packages/9c/1b/8f80b18e20b3b294546a1adb41701e79ae21915f4175f311a90d042301cf/kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dea0bf229319828467d7fca8c7c189780aa9ff679c94539eed7532ebe33ed37c", size = 1578750 }, + { url = "https://files.pythonhosted.org/packages/a4/fe/fe8e72f3be0a844f257cadd72689c0848c6d5c51bc1d60429e2d14ad776e/kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c06a4c7cf15ec739ce0e5971b26c93638730090add60e183530d70848ebdd34", size = 1507175 }, + { url = "https://files.pythonhosted.org/packages/39/fa/cdc0b6105d90eadc3bee525fecc9179e2b41e1ce0293caaf49cb631a6aaf/kiwisolver-1.4.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:913983ad2deb14e66d83c28b632fd35ba2b825031f2fa4ca29675e665dfecbe1", size = 1463963 }, + { url = "https://files.pythonhosted.org/packages/6e/5c/0c03c4e542720c6177d4f408e56d1c8315899db72d46261a4e15b8b33a41/kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:5337ec7809bcd0f424c6b705ecf97941c46279cf5ed92311782c7c9c2026f07f", size = 2248220 }, + { url = "https://files.pythonhosted.org/packages/3d/ee/55ef86d5a574f4e767df7da3a3a7ff4954c996e12d4fbe9c408170cd7dcc/kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4c26ed10c4f6fa6ddb329a5120ba3b6db349ca192ae211e882970bfc9d91420b", size = 2404463 }, + { url = "https://files.pythonhosted.org/packages/0f/6d/73ad36170b4bff4825dc588acf4f3e6319cb97cd1fb3eb04d9faa6b6f212/kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c619b101e6de2222c1fcb0531e1b17bbffbe54294bfba43ea0d411d428618c27", size = 2352842 }, + { url = "https://files.pythonhosted.org/packages/0b/16/fa531ff9199d3b6473bb4d0f47416cdb08d556c03b8bc1cccf04e756b56d/kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:073a36c8273647592ea332e816e75ef8da5c303236ec0167196793eb1e34657a", size = 2501635 }, + { url = "https://files.pythonhosted.org/packages/78/7e/aa9422e78419db0cbe75fb86d8e72b433818f2e62e2e394992d23d23a583/kiwisolver-1.4.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:3ce6b2b0231bda412463e152fc18335ba32faf4e8c23a754ad50ffa70e4091ee", size = 2314556 }, + { url = "https://files.pythonhosted.org/packages/a8/b2/15f7f556df0a6e5b3772a1e076a9d9f6c538ce5f05bd590eca8106508e06/kiwisolver-1.4.7-cp313-cp313-win32.whl", hash = "sha256:f4c9aee212bc89d4e13f58be11a56cc8036cabad119259d12ace14b34476fd07", size = 46364 }, + { url = "https://files.pythonhosted.org/packages/0b/db/32e897e43a330eee8e4770bfd2737a9584b23e33587a0812b8e20aac38f7/kiwisolver-1.4.7-cp313-cp313-win_amd64.whl", hash = "sha256:8a3ec5aa8e38fc4c8af308917ce12c536f1c88452ce554027e55b22cbbfbff76", size = 55887 }, + { url = "https://files.pythonhosted.org/packages/c8/a4/df2bdca5270ca85fd25253049eb6708d4127be2ed0e5c2650217450b59e9/kiwisolver-1.4.7-cp313-cp313-win_arm64.whl", hash = "sha256:76c8094ac20ec259471ac53e774623eb62e6e1f56cd8690c67ce6ce4fcb05650", size = 48530 }, + { url = "https://files.pythonhosted.org/packages/11/88/37ea0ea64512997b13d69772db8dcdc3bfca5442cda3a5e4bb943652ee3e/kiwisolver-1.4.7-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:3f9362ecfca44c863569d3d3c033dbe8ba452ff8eed6f6b5806382741a1334bd", size = 122449 }, + { url = "https://files.pythonhosted.org/packages/4e/45/5a5c46078362cb3882dcacad687c503089263c017ca1241e0483857791eb/kiwisolver-1.4.7-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:e8df2eb9b2bac43ef8b082e06f750350fbbaf2887534a5be97f6cf07b19d9583", size = 65757 }, + { url = "https://files.pythonhosted.org/packages/8a/be/a6ae58978772f685d48dd2e84460937761c53c4bbd84e42b0336473d9775/kiwisolver-1.4.7-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:f32d6edbc638cde7652bd690c3e728b25332acbadd7cad670cc4a02558d9c417", size = 64312 }, + { url = "https://files.pythonhosted.org/packages/f4/04/18ef6f452d311e1e1eb180c9bf5589187fa1f042db877e6fe443ef10099c/kiwisolver-1.4.7-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:e2e6c39bd7b9372b0be21456caab138e8e69cc0fc1190a9dfa92bd45a1e6e904", size = 1626966 }, + { url = "https://files.pythonhosted.org/packages/21/b1/40655f6c3fa11ce740e8a964fa8e4c0479c87d6a7944b95af799c7a55dfe/kiwisolver-1.4.7-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:dda56c24d869b1193fcc763f1284b9126550eaf84b88bbc7256e15028f19188a", size = 1607044 }, + { url = "https://files.pythonhosted.org/packages/fd/93/af67dbcfb9b3323bbd2c2db1385a7139d8f77630e4a37bb945b57188eb2d/kiwisolver-1.4.7-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79849239c39b5e1fd906556c474d9b0439ea6792b637511f3fe3a41158d89ca8", size = 1391879 }, + { url = "https://files.pythonhosted.org/packages/40/6f/d60770ef98e77b365d96061d090c0cd9e23418121c55fff188fa4bdf0b54/kiwisolver-1.4.7-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5e3bc157fed2a4c02ec468de4ecd12a6e22818d4f09cde2c31ee3226ffbefab2", size = 1504751 }, + { url = "https://files.pythonhosted.org/packages/fa/3a/5f38667d313e983c432f3fcd86932177519ed8790c724e07d77d1de0188a/kiwisolver-1.4.7-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3da53da805b71e41053dc670f9a820d1157aae77b6b944e08024d17bcd51ef88", size = 1436990 }, + { url = "https://files.pythonhosted.org/packages/cb/3b/1520301a47326e6a6043b502647e42892be33b3f051e9791cc8bb43f1a32/kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:8705f17dfeb43139a692298cb6637ee2e59c0194538153e83e9ee0c75c2eddde", size = 2191122 }, + { url = "https://files.pythonhosted.org/packages/cf/c4/eb52da300c166239a2233f1f9c4a1b767dfab98fae27681bfb7ea4873cb6/kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:82a5c2f4b87c26bb1a0ef3d16b5c4753434633b83d365cc0ddf2770c93829e3c", size = 2338126 }, + { url = "https://files.pythonhosted.org/packages/1a/cb/42b92fd5eadd708dd9107c089e817945500685f3437ce1fd387efebc6d6e/kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ce8be0466f4c0d585cdb6c1e2ed07232221df101a4c6f28821d2aa754ca2d9e2", size = 2298313 }, + { url = "https://files.pythonhosted.org/packages/4f/eb/be25aa791fe5fc75a8b1e0c965e00f942496bc04635c9aae8035f6b76dcd/kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:409afdfe1e2e90e6ee7fc896f3df9a7fec8e793e58bfa0d052c8a82f99c37abb", size = 2437784 }, + { url = "https://files.pythonhosted.org/packages/c5/22/30a66be7f3368d76ff95689e1c2e28d382383952964ab15330a15d8bfd03/kiwisolver-1.4.7-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5b9c3f4ee0b9a439d2415012bd1b1cc2df59e4d6a9939f4d669241d30b414327", size = 2253988 }, + { url = "https://files.pythonhosted.org/packages/35/d3/5f2ecb94b5211c8a04f218a76133cc8d6d153b0f9cd0b45fad79907f0689/kiwisolver-1.4.7-cp39-cp39-win32.whl", hash = "sha256:a79ae34384df2b615eefca647a2873842ac3b596418032bef9a7283675962644", size = 46980 }, + { url = "https://files.pythonhosted.org/packages/ef/17/cd10d020578764ea91740204edc6b3236ed8106228a46f568d716b11feb2/kiwisolver-1.4.7-cp39-cp39-win_amd64.whl", hash = "sha256:cf0438b42121a66a3a667de17e779330fc0f20b0d97d59d2f2121e182b0505e4", size = 55847 }, + { url = "https://files.pythonhosted.org/packages/91/84/32232502020bd78d1d12be7afde15811c64a95ed1f606c10456db4e4c3ac/kiwisolver-1.4.7-cp39-cp39-win_arm64.whl", hash = "sha256:764202cc7e70f767dab49e8df52c7455e8de0df5d858fa801a11aa0d882ccf3f", size = 48494 }, + { url = "https://files.pythonhosted.org/packages/ac/59/741b79775d67ab67ced9bb38552da688c0305c16e7ee24bba7a2be253fb7/kiwisolver-1.4.7-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:94252291e3fe68001b1dd747b4c0b3be12582839b95ad4d1b641924d68fd4643", size = 59491 }, + { url = "https://files.pythonhosted.org/packages/58/cc/fb239294c29a5656e99e3527f7369b174dd9cc7c3ef2dea7cb3c54a8737b/kiwisolver-1.4.7-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:5b7dfa3b546da08a9f622bb6becdb14b3e24aaa30adba66749d38f3cc7ea9706", size = 57648 }, + { url = "https://files.pythonhosted.org/packages/3b/ef/2f009ac1f7aab9f81efb2d837301d255279d618d27b6015780115ac64bdd/kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd3de6481f4ed8b734da5df134cd5a6a64fe32124fe83dde1e5b5f29fe30b1e6", size = 84257 }, + { url = "https://files.pythonhosted.org/packages/81/e1/c64f50987f85b68b1c52b464bb5bf73e71570c0f7782d626d1eb283ad620/kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a91b5f9f1205845d488c928e8570dcb62b893372f63b8b6e98b863ebd2368ff2", size = 80906 }, + { url = "https://files.pythonhosted.org/packages/fd/71/1687c5c0a0be2cee39a5c9c389e546f9c6e215e46b691d00d9f646892083/kiwisolver-1.4.7-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40fa14dbd66b8b8f470d5fc79c089a66185619d31645f9b0773b88b19f7223c4", size = 79951 }, + { url = "https://files.pythonhosted.org/packages/ea/8b/d7497df4a1cae9367adf21665dd1f896c2a7aeb8769ad77b662c5e2bcce7/kiwisolver-1.4.7-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:eb542fe7933aa09d8d8f9d9097ef37532a7df6497819d16efe4359890a2f417a", size = 55715 }, + { url = "https://files.pythonhosted.org/packages/d5/df/ce37d9b26f07ab90880923c94d12a6ff4d27447096b4c849bfc4339ccfdf/kiwisolver-1.4.7-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:8b01aac285f91ca889c800042c35ad3b239e704b150cfd3382adfc9dcc780e39", size = 58666 }, + { url = "https://files.pythonhosted.org/packages/b0/d3/e4b04f43bc629ac8e186b77b2b1a251cdfa5b7610fa189dc0db622672ce6/kiwisolver-1.4.7-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:48be928f59a1f5c8207154f935334d374e79f2b5d212826307d072595ad76a2e", size = 57088 }, + { url = "https://files.pythonhosted.org/packages/30/1c/752df58e2d339e670a535514d2db4fe8c842ce459776b8080fbe08ebb98e/kiwisolver-1.4.7-pp39-pypy39_pp73-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f37cfe618a117e50d8c240555331160d73d0411422b59b5ee217843d7b693608", size = 84321 }, + { url = "https://files.pythonhosted.org/packages/f0/f8/fe6484e847bc6e238ec9f9828089fb2c0bb53f2f5f3a79351fde5b565e4f/kiwisolver-1.4.7-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:599b5c873c63a1f6ed7eead644a8a380cfbdf5db91dcb6f85707aaab213b1674", size = 80776 }, + { url = "https://files.pythonhosted.org/packages/9b/57/d7163c0379f250ef763aba85330a19feefb5ce6cb541ade853aaba881524/kiwisolver-1.4.7-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:801fa7802e5cfabe3ab0c81a34c323a319b097dfb5004be950482d882f3d7225", size = 79984 }, + { url = "https://files.pythonhosted.org/packages/8c/95/4a103776c265d13b3d2cd24fb0494d4e04ea435a8ef97e1b2c026d43250b/kiwisolver-1.4.7-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:0c6c43471bc764fad4bc99c5c2d6d16a676b1abf844ca7c8702bdae92df01ee0", size = 55811 }, +] + +[[package]] +name = "manim" +version = "0.19.0" +source = { editable = "." } +dependencies = [ + { name = "audioop-lts", marker = "python_full_version >= '3.13'" }, + { name = "av" }, + { name = "beautifulsoup4" }, + { name = "click" }, + { name = "cloup" }, + { name = "decorator" }, + { name = "importlib-metadata", marker = "python_full_version < '3.10'" }, + { name = "isosurfaces" }, + { name = "manimpango" }, + { name = "mapbox-earcut" }, + { name = "moderngl" }, + { name = "moderngl-window" }, + { name = "networkx" }, + { name = "numpy", version = "2.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, + { name = "numpy", version = "2.2.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "pillow" }, + { name = "pycairo" }, + { name = "pydub" }, + { name = "pygments" }, + { name = "rich" }, + { name = "scipy", version = "1.13.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.13'" }, + { name = "scipy", version = "1.15.1", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.13'" }, + { name = "screeninfo" }, + { name = "skia-pathops" }, + { name = "srt" }, + { name = "svgelements" }, + { name = "tqdm" }, + { name = "typing-extensions" }, + { name = "watchdog" }, +] + +[package.optional-dependencies] +gui = [ + { name = "dearpygui" }, +] +jupyterlab = [ + { name = "jupyterlab" }, + { name = "notebook" }, +] + +[package.dev-dependencies] +dev = [ + { name = "furo" }, + { name = "gitpython" }, + { name = "matplotlib" }, + { name = "myst-parser" }, + { name = "pre-commit" }, + { name = "psutil" }, + { name = "pygithub" }, + { name = "pytest" }, + { name = "pytest-cov" }, + { name = "pytest-xdist" }, + { name = "requests" }, + { name = "ruff" }, + { name = "sphinx" }, + { name = "sphinx-copybutton" }, + { name = "sphinx-design" }, + { name = "sphinx-reredirects" }, + { name = "sphinxcontrib-programoutput" }, + { name = "sphinxext-opengraph" }, + { name = "types-decorator" }, + { name = "types-pillow" }, + { name = "types-pygments" }, +] + +[package.metadata] +requires-dist = [ + { name = "audioop-lts", marker = "python_full_version >= '3.13'", specifier = ">=0.2.1" }, + { name = "av", specifier = ">=9.0.0,<14.0.0" }, + { name = "beautifulsoup4", specifier = ">=4.12" }, + { name = "click", specifier = ">=8.0" }, + { name = "cloup", specifier = ">=2.0.0" }, + { name = "dearpygui", marker = "extra == 'gui'", specifier = ">=1.0.0" }, + { name = "decorator", specifier = ">=4.3.2" }, + { name = "importlib-metadata", marker = "python_full_version < '3.10'", specifier = ">=8.6.1" }, + { name = "isosurfaces", specifier = ">=0.1.0" }, + { name = "jupyterlab", marker = "extra == 'jupyterlab'", specifier = ">=4.3.4" }, + { name = "manimpango", specifier = ">=0.5.0,<1.0.0" }, + { name = "mapbox-earcut", specifier = ">=1.0.0" }, + { name = "moderngl", specifier = ">=5.0.0,<6.0.0" }, + { name = "moderngl-window", specifier = ">=2.0.0" }, + { name = "networkx", specifier = ">=2.6" }, + { name = "notebook", marker = "extra == 'jupyterlab'", specifier = ">=7.3.2" }, + { name = "numpy", specifier = ">=2.0" }, + { name = "numpy", marker = "python_full_version >= '3.10'", specifier = ">=2.1" }, + { name = "pillow", specifier = ">=9.1" }, + { name = "pycairo", specifier = ">=1.13,<2.0.0" }, + { name = "pydub", specifier = ">=0.20.0" }, + { name = "pygments", specifier = ">=2.0.0" }, + { name = "rich", specifier = ">=12.0.0" }, + { name = "scipy", specifier = ">=1.13.0" }, + { name = "scipy", marker = "python_full_version >= '3.13'", specifier = ">=1.14.0" }, + { name = "screeninfo", specifier = ">=0.7" }, + { name = "skia-pathops", specifier = ">=0.7.0" }, + { name = "srt", specifier = ">=3.0.0" }, + { name = "svgelements", specifier = ">=1.8.0" }, + { name = "tqdm", specifier = ">=4.0.0" }, + { name = "typing-extensions", specifier = ">=4.12.0" }, + { name = "watchdog", specifier = ">=2.0.0" }, +] + +[package.metadata.requires-dev] +dev = [ + { name = "furo", specifier = ">=2024.8.6" }, + { name = "gitpython", specifier = ">=3.1.44" }, + { name = "matplotlib", specifier = ">=3.9.4" }, + { name = "myst-parser", specifier = ">=3.0.1" }, + { name = "pre-commit", specifier = ">=4.1.0" }, + { name = "psutil", specifier = ">=6.1.1" }, + { name = "pygithub", specifier = ">=2.5.0" }, + { name = "pytest", specifier = ">=8.3.4" }, + { name = "pytest-cov", specifier = ">=6.0.0" }, + { name = "pytest-xdist", specifier = ">=2.2,<3.0" }, + { name = "requests", specifier = ">=2.32.3" }, + { name = "ruff", specifier = ">=0.9.3" }, + { name = "sphinx", specifier = ">=7.4.7" }, + { name = "sphinx-copybutton", specifier = ">=0.5.2" }, + { name = "sphinx-design", specifier = ">=0.6.1" }, + { name = "sphinx-reredirects", specifier = ">=0.1.5" }, + { name = "sphinxcontrib-programoutput", specifier = ">=0.18" }, + { name = "sphinxext-opengraph", specifier = ">=0.9.1" }, + { name = "types-decorator", specifier = ">=5.1.8.20250121" }, + { name = "types-pillow", specifier = ">=10.2.0.20240822" }, + { name = "types-pygments", specifier = ">=2.19.0.20250107" }, +] + +[[package]] +name = "manimpango" +version = "0.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2a/8e/7f7a49d4bbe2c6dbef4a82c58e15fc5a35eedcf97a8f7c67ce5fa9a8c827/manimpango-0.6.0.tar.gz", hash = "sha256:d959708e5c05e87317b37df5f6c5258aa9d1ed694a0b25b19d6a4f861841e191", size = 4080822 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8f/55/6cf7142897a5d2b4cc918061de0e1dc3bf7e5936ffcdd92b93da46627e20/ManimPango-0.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:025605af4e789dad2d8895b0c820d4e5c8001929a2998a4a694518869f32e5f8", size = 7471987 }, + { url = "https://files.pythonhosted.org/packages/dc/c2/be6564a0970a492959771ba002d0e084b83a6684c5246c917ce49a1b5652/ManimPango-0.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:72d70b8110f1fb5641fe0d1c9483d10aa7cd190c099490ce809acfab3dce6b69", size = 6802723 }, + { url = "https://files.pythonhosted.org/packages/41/93/38f4f14ca49c2168db916efbc955eb90ab002db249770f2eed3269eb7a04/ManimPango-0.6.0-cp310-cp310-win32.whl", hash = "sha256:287205a4c82e35b84c259a5f03068295d544b105d387457cb670c167e2a13598", size = 3533195 }, + { url = "https://files.pythonhosted.org/packages/98/4e/41ce1db7821d798621461ae8a937df84ddee9bd55be317dfcef14b7d5816/ManimPango-0.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:b1e1a86ed9e814cdd230958f7c9bb874400f6808bff29e6b76abc55faa9b4899", size = 4101674 }, + { url = "https://files.pythonhosted.org/packages/29/a5/dfa1c7eefc3fc790ab0ef6ce04e1b70bb24dc63e0bd4e1ce4a8f0bf2d787/ManimPango-0.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:af1f631bc8fd925db351e0c9498aec8bf6639dcd3ad99ca5fce73766ad137640", size = 7472060 }, + { url = "https://files.pythonhosted.org/packages/29/87/41ba1a0878fe23dcafcc72ccd869d1abed0213e9ab7b765e7db65d7579fe/ManimPango-0.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:92d4c20845eb5920f5487e0929ac3dab517f623d1093ef1524ab7679b01b11fb", size = 6802540 }, + { url = "https://files.pythonhosted.org/packages/50/69/e41e0b5db2c39884ac29705d906dcfbaf4684d60cbb4d68bca2ed05b1d9c/ManimPango-0.6.0-cp311-cp311-win32.whl", hash = "sha256:f6ba4d65bbc157705a92cb7f07bad0d8a82a392cec8b23347fa2e2f756793fbb", size = 3534771 }, + { url = "https://files.pythonhosted.org/packages/8a/71/a5fdb9cd985a38077c12c30a3f2af3303ea6d1081394c95c56dcc7acf9b0/ManimPango-0.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:386c4ea41cfbab2d68b1ccc982510cdd2a9aef25e63c92f6ac7d0dee48e3513b", size = 4101089 }, + { url = "https://files.pythonhosted.org/packages/e3/e6/e4e5cce79d4c8e4eeb3447349e32cf41494197732cfac01c60a6b521ed62/ManimPango-0.6.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:9d10bf902dbb66c98f28909ac9327296da141eaa696986a59b3459e3358d9a34", size = 7473096 }, + { url = "https://files.pythonhosted.org/packages/48/14/787e62bf78d92e5aef5b797db442ba5b4bed95ab25b76a9be352f6736bbc/ManimPango-0.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6ab751239d82233d9c9ea1aa8f9cb23257733ee0607e82a76abc0cd75dde66e5", size = 6803404 }, + { url = "https://files.pythonhosted.org/packages/56/6b/1927deee84e5883f1e4c49d3d48814d7c0b4bdb026bfa5a5d81eacd7aa3b/ManimPango-0.6.0-cp312-cp312-win32.whl", hash = "sha256:7a8e2c164e7f03e2152e94fd5bf597e977ef67fbbf1031c72f2254479fc892af", size = 3530620 }, + { url = "https://files.pythonhosted.org/packages/b7/e7/6355b4da8e8fd9e7160e36af0c280c17d02997a5d5eebeabd70bfa8cf5c8/ManimPango-0.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:061fd61a9f27df0c8ed75beb1fa4e5c06d5186eb37a5830a852aa3ac0737fcfe", size = 4098777 }, + { url = "https://files.pythonhosted.org/packages/d0/a5/14daa990d391981582ebfaabac93aeb9abbd83b3fac98800e5fe06ace653/ManimPango-0.6.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5156dc1fa2a6321f64a4110aa9dbe0c5ba507839f947fa3dfc72b5c63d729c88", size = 7470477 }, + { url = "https://files.pythonhosted.org/packages/a1/63/fccfcd6b6748c3e50e0319cc976d27762543ac3f634c20d712b463677f41/ManimPango-0.6.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:67809f65ec10397361a2650069ccac9fcf64babf75daf58eb38d9bcfb49e968b", size = 6801196 }, + { url = "https://files.pythonhosted.org/packages/ae/65/ea52fa1db9cf59f48b4726a1e6655ce2a2271f35ea4f11f0f2d497914624/ManimPango-0.6.0-cp313-cp313-win32.whl", hash = "sha256:ba6279fd087ac3ac0a64c24a8b47fa0bdf0c8351c177cd07e3e793252899bd2d", size = 3530715 }, + { url = "https://files.pythonhosted.org/packages/46/a7/cc2a049245b1bfd99989319e660732b18c1190c1c429c6b5dd04e79ea415/ManimPango-0.6.0-cp313-cp313-win_amd64.whl", hash = "sha256:bb13f56a41ba251f70fd57643dc42cee689a1ebbec5eaf305722c7100008e253", size = 4097763 }, + { url = "https://files.pythonhosted.org/packages/98/e8/03cdf8c516fab20a7c92d675f73c7078fb397da626d1907864fca9ed7eca/ManimPango-0.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c88297f21091fb4031173f66bc55ea4e11d1df4412ba4edf3a5ccdb06dbf2c0f", size = 7471977 }, + { url = "https://files.pythonhosted.org/packages/b3/9b/9155941ca713458353e90c35c85dd83699c0b426df805a10360d1da6e473/ManimPango-0.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:5c0c1bb36588d4951d5560ce1ee6831f23f0f7d22c93b4fd9dcf0752908d9d57", size = 6802712 }, + { url = "https://files.pythonhosted.org/packages/9b/6d/bffa80142277dbdff613425d1b9896fbe04a6dab1a1be3b2029648ce3b45/ManimPango-0.6.0-cp39-cp39-win32.whl", hash = "sha256:ff9e515f9a79f7010c68efd9da19d5c11ba33bd139d1c53b0a18b73d9f20ce7d", size = 3534832 }, + { url = "https://files.pythonhosted.org/packages/a8/e4/f70e1d39d8f24278b47bcf02623d10419002634844e6e2ae6ba27e337ceb/ManimPango-0.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:93ae1b0f2fd4b4f1774dd5b2f4a3b834043d5ee42efc3dfb351755f4f548059d", size = 4100918 }, +] + +[[package]] +name = "mapbox-earcut" +version = "1.0.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", version = "2.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, + { name = "numpy", version = "2.2.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8d/70/0a322197c1178f47941e5e6e13b0a4adeaaa7c465c18e3b4ead3eba49860/mapbox_earcut-1.0.3.tar.gz", hash = "sha256:b6bac5d519d9947a6321a699c15d58e0b5740da61b9210ed229e05ad207c1c04", size = 24029 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f1/0a/da73cb98a03e28ebf806df15b4154e1b1956bd9d2eae17b70a54298db85c/mapbox_earcut-1.0.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5f999a8651bdb3ae8805c9a7cf91337bbb5e858d7724811f3b5baa79bfa3c61a", size = 69723 }, + { url = "https://files.pythonhosted.org/packages/3e/a1/be2258d38215ecd00febebf808d50d56840c059123ea52b9cc1e655d8eab/mapbox_earcut-1.0.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a59cc707fc0d47f778f912ede6b21e8798e7d82829d772cf2ebaea216cb04828", size = 64037 }, + { url = "https://files.pythonhosted.org/packages/3d/8c/0573fce0e72335695f2d9c42014b716b700170850323074b4c9026d762b7/mapbox_earcut-1.0.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:30923be0a1080a4d6815b3a0f9d43e2fcc2b2c3fabd4ce3b1fe858c676e449ff", size = 95478 }, + { url = "https://files.pythonhosted.org/packages/93/ff/08815aac9ac1ef0a0972a3c020238c2218f11e21afc4308981d78b12fd86/mapbox_earcut-1.0.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d105c10a2b849191b4bc72debbc386595c42a2d65a39dbcda05497475066c1a4", size = 1069535 }, + { url = "https://files.pythonhosted.org/packages/0e/a5/0b8effbe0a4bcb019bc4e1726ce0bf6f77a5e405b424cb0d562396f0dd05/mapbox_earcut-1.0.3-cp310-cp310-win32.whl", hash = "sha256:6906cfc9fe5778c8efcdae425df52a414de5e75cb0ebe31175fbfaa038dec0d9", size = 63950 }, + { url = "https://files.pythonhosted.org/packages/af/fe/593275fa703161d0c28388f20f26f02c5c34adf532250506fb2058a59101/mapbox_earcut-1.0.3-cp310-cp310-win_amd64.whl", hash = "sha256:624b99bb7bba37bcf889c84d338516cdbbfaa612a03e6bc48d2ebdfbadddddfc", size = 71246 }, + { url = "https://files.pythonhosted.org/packages/61/d7/b37a45c248100e7285a40de87a8b1808ca4ca10228e265f2d0c320702d96/mapbox_earcut-1.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bbf24029e7447eb0351000f4fd3185327a00dac5ed756b07330b0bdaed6932db", size = 71057 }, + { url = "https://files.pythonhosted.org/packages/1b/df/2b63eb0d3a24e14f67adc816de18c2e09f3eb0997c512ace84dd59c3ed96/mapbox_earcut-1.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:998e2f1e3769538f7656a34296d08a37cb71ce57aa8cf4387572bc00029b52ce", size = 65300 }, + { url = "https://files.pythonhosted.org/packages/87/37/9dd9575f5c00e35d480e7150e5bb315a35d9cf5642bfb75ca628a31e1341/mapbox_earcut-1.0.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:df2382d84d6d168f73479673d297753e37440772f233cc03ebb54d150e37b174", size = 96965 }, + { url = "https://files.pythonhosted.org/packages/3b/91/5708233941b5bf73149ba35f7aa32c6ee2cf4a33cd33069e7dba69d4129f/mapbox_earcut-1.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3ccddb4bb04f11beab62943eb5a1bcd52c5a71d236bfce0ecc03e45e97fdb24b", size = 1070953 }, + { url = "https://files.pythonhosted.org/packages/2a/fe/b35b999ba786aa17ddc47bc04231de076665eb511e1cd58cf6fef3581172/mapbox_earcut-1.0.3-cp311-cp311-win32.whl", hash = "sha256:f19b2bcf6475bc591f48437d3214691a6730f39b1f6dfd7505b69c4345485b0c", size = 65245 }, + { url = "https://files.pythonhosted.org/packages/11/81/18ac08b0bb0c22dd9028c7ecb31ae4086d31128b13fb3903e717331072ac/mapbox_earcut-1.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:811a64ad5e6ecf09b96af533e5c169299ba173e53eb4ff0209de1adcfae314be", size = 72356 }, + { url = "https://files.pythonhosted.org/packages/96/7c/707a4ce96e078f7d382cc32b4a6c2326eca68d77ead5e990f5f940d16140/mapbox_earcut-1.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5be71b7ec2180a27ce1178d53933430a3292b6ac3f94f2144513ee51d9034007", size = 70333 }, + { url = "https://files.pythonhosted.org/packages/fb/47/ba2a14732f6e197b0ed879a1992b4d85054294b23627ad681b4fb1251d16/mapbox_earcut-1.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:eb874f7562a49ae0fb7bd47bcc9b4854cc53e3e4f7f26674f02f3cadb006ce16", size = 64697 }, + { url = "https://files.pythonhosted.org/packages/e7/68/59a514811da76c3c801207bd6d7094ea5ba75648c2e7f15d4cb98b08216f/mapbox_earcut-1.0.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:73b9f06f2f8a795d835342aa80e021cfceda78fdca7bc07dc1a0b4aca90239f3", size = 96182 }, + { url = "https://files.pythonhosted.org/packages/3f/79/97bf509ade0f9aeb5b5f94b1aff86393c2f584379a80e392fdfcbea434ae/mapbox_earcut-1.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fdc55574ef7b613004874a459d2d59c07e1ef45cebb83f86c4958f7d3e2d6069", size = 1070584 }, + { url = "https://files.pythonhosted.org/packages/de/7a/5a6e205bab9ff49d1dae392f6179a444f820880d8985f26080816fa6c7ba/mapbox_earcut-1.0.3-cp312-cp312-win32.whl", hash = "sha256:790f52c67a0bd81032eaf61ebc181b1825b8b6daf01cb69e9eaa38521dd07aeb", size = 65375 }, + { url = "https://files.pythonhosted.org/packages/7a/59/674a67f92772563d5a943ce2c4ed834ed341e3a0fd77b8eb4b79057f5193/mapbox_earcut-1.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:cc1bbf35be0d9853dd448374330684ddbd0112497dee7d21b7417b0ab6236ac7", size = 72575 }, + { url = "https://files.pythonhosted.org/packages/ff/0c/33d1fe1df098d33fce673fe153a52a7ef482bae19afcc295aa36bfdd7d33/mapbox_earcut-1.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:22859490a83a614750dee24c08502fbe14f01a808c0f0f8626261b43ec186762", size = 70373 }, + { url = "https://files.pythonhosted.org/packages/9f/f0/3c7d62f1e0aea0285da578ea1c98686c8d915143df17ff5ed37b04882cac/mapbox_earcut-1.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ad9b97512b7e917cec9af399a344f8844b0ca6c074f354a5b06f58c393c4d9b0", size = 64755 }, + { url = "https://files.pythonhosted.org/packages/13/9a/9eb83efbe87ebf41d1a78efe3c0d906212e5dd91c8f24a9fc7491908ccd5/mapbox_earcut-1.0.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:05de0accc70431c2270dbb13fd75b6f10b19624d42f26b377995b1fb46ac5844", size = 96198 }, + { url = "https://files.pythonhosted.org/packages/8b/4a/24182a96ad4bb086b04fff5d14c9f62fc3b89000bea2f05240aa6128bd03/mapbox_earcut-1.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2d25c856a1ee6c69f51b82df5a06ea6cea66ce3a7c6043a602edfc5c2fe33e32", size = 1070844 }, + { url = "https://files.pythonhosted.org/packages/67/9d/edc1f0bb03079293a28f7d1e5d496ee0da16822908c09268b049aa056288/mapbox_earcut-1.0.3-cp313-cp313-win32.whl", hash = "sha256:9ec67d2dc733c7235114e5fa93baae4aa2de8c6210e01e8efd85e5b9cc0deb53", size = 65431 }, + { url = "https://files.pythonhosted.org/packages/93/f1/e6987c97bb4bac6daf0084e72f457d5214bc8b054d465363060364121a9b/mapbox_earcut-1.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:473012494fd7a51c424a6835fb03c9ee461c540df87492f0ee9bb2f56c456c0c", size = 72586 }, + { url = "https://files.pythonhosted.org/packages/70/af/db832933502fe34ac02f8d201fc19cbd25cc23de213e77e37d3af59e3003/mapbox_earcut-1.0.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:177eecc8aef4a91171a0a862878a6e93e6aa28648501ef84df283646d7a15dff", size = 69784 }, + { url = "https://files.pythonhosted.org/packages/6b/78/a4e3a19051235e945ae895e8844d2c2e8b144064a08c58bca79c25701aa4/mapbox_earcut-1.0.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:27f9d62be4586cba39022203adf13407f0c3ca06300ed9589feb0da3a9d075ed", size = 64120 }, + { url = "https://files.pythonhosted.org/packages/4c/59/7e04d677b12f7a908c38809f79138409c211f88c13f77de0e3c194644154/mapbox_earcut-1.0.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1eb495cb897c1b52df7f1244b21798b815560845215a0d9d87db82a191aa2db2", size = 95653 }, + { url = "https://files.pythonhosted.org/packages/bc/2a/abf79d57ddaa1cb07968a1ccbfb6d95f50cf450a37cd039badbf51f86ad1/mapbox_earcut-1.0.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:6f22662c363128b8503f3ab1906e551b49f409b755db4cec32b68d50a563c669", size = 1069439 }, + { url = "https://files.pythonhosted.org/packages/60/55/9f28a001233e3ec6da93c348c8b6dc6f8d7aa2aa904c5bbed47c28ea1f0e/mapbox_earcut-1.0.3-cp39-cp39-win32.whl", hash = "sha256:163146fd9ed252972625aabb56df91cc89f384e458f8819cf673f3f02885252e", size = 64163 }, + { url = "https://files.pythonhosted.org/packages/5d/8a/158ed5c7cf9728811f32df64736c33b623319a11af200c82ee24018b3996/mapbox_earcut-1.0.3-cp39-cp39-win_amd64.whl", hash = "sha256:2b531f4094c1643cab7ff96f296bb27277acac7204ff9415e099274299c56988", size = 71326 }, + { url = "https://files.pythonhosted.org/packages/c8/14/8b58520cb6fe393a064e4e681abe7afcb9d7861b4f56be0cf4a72f9143f1/mapbox_earcut-1.0.3-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:17cdd6f14d1161839eea67a0ce796a09bcb3183903dc7b213011f38907b71279", size = 70105 }, + { url = "https://files.pythonhosted.org/packages/35/e3/83b76439cdb8ad790ad4ddefd5025b7509e4a94ec120333d0c387acb4c81/mapbox_earcut-1.0.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:ae5aab4b8b3e418c4690da17b3aa50e7fc540b08a0d0d43a4eff4fa21ecb51b3", size = 64231 }, + { url = "https://files.pythonhosted.org/packages/65/af/06ddfda61d8ff4e7c182185e13f2eae65935eb33e185098d1fed67a4f9fa/mapbox_earcut-1.0.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ab51cd69c768c15114da8ba8f43bcda1dea681167e6eadd067fda34837a639d", size = 95920 }, + { url = "https://files.pythonhosted.org/packages/d6/77/edb2f8e0026b5419feb92c7c30a33dc1df0de0790c90e0a1770690725375/mapbox_earcut-1.0.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:97f9bcbcd897db68b02228f20255d56b269248883d1ac51686e3de15a83bec7d", size = 71300 }, + { url = "https://files.pythonhosted.org/packages/ef/8e/663cf3fb6077af9d42fa7b7a3439a37d096e70f2d63d099d9844968c3ffc/mapbox_earcut-1.0.3-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:016b0cef0ab502291ae3dc498d182f2ec04c79e4362524f1c44a53cf0f8ed271", size = 70094 }, + { url = "https://files.pythonhosted.org/packages/f7/ce/877ade6cfc49f6048faa0622106f0ac2ed9d474c059e591ca9c37cd84616/mapbox_earcut-1.0.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:911a661b245b63bbe0fb2c6432423c50173de35a20bbc9e5b4404d4f3cd4f1c0", size = 64225 }, + { url = "https://files.pythonhosted.org/packages/4a/40/4e0357f5074d3bc119825df728043e01ef2aae7a7151ca1639325a453533/mapbox_earcut-1.0.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fbcadc28d68a3939b90eeab35193ae94b99296996b081fc3b22434740294e4f9", size = 95984 }, + { url = "https://files.pythonhosted.org/packages/33/2b/505870d581e5b7bcce73aabf1e16b2f8c4fd74eae1c68ee0d7aea6cae2d2/mapbox_earcut-1.0.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:032ef45e8278d092e875abd27615e66ef1573672bc63ae30ae00abbcf35b833f", size = 71287 }, +] + +[[package]] +name = "markdown-it-py" +version = "3.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/38/71/3b932df36c1a044d397a1f92d1cf91ee0a503d91e470cbd670aa66b07ed0/markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb", size = 74596 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/42/d7/1ec15b46af6af88f19b8e5ffea08fa375d433c998b8a7639e76935c14f1f/markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1", size = 87528 }, +] + +[[package]] +name = "markupsafe" +version = "3.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/90/d08277ce111dd22f77149fd1a5d4653eeb3b3eaacbdfcbae5afb2600eebd/MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8", size = 14357 }, + { url = "https://files.pythonhosted.org/packages/04/e1/6e2194baeae0bca1fae6629dc0cbbb968d4d941469cbab11a3872edff374/MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158", size = 12393 }, + { url = "https://files.pythonhosted.org/packages/1d/69/35fa85a8ece0a437493dc61ce0bb6d459dcba482c34197e3efc829aa357f/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579", size = 21732 }, + { url = "https://files.pythonhosted.org/packages/22/35/137da042dfb4720b638d2937c38a9c2df83fe32d20e8c8f3185dbfef05f7/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d", size = 20866 }, + { url = "https://files.pythonhosted.org/packages/29/28/6d029a903727a1b62edb51863232152fd335d602def598dade38996887f0/MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb", size = 20964 }, + { url = "https://files.pythonhosted.org/packages/cc/cd/07438f95f83e8bc028279909d9c9bd39e24149b0d60053a97b2bc4f8aa51/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b", size = 21977 }, + { url = "https://files.pythonhosted.org/packages/29/01/84b57395b4cc062f9c4c55ce0df7d3108ca32397299d9df00fedd9117d3d/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c", size = 21366 }, + { url = "https://files.pythonhosted.org/packages/bd/6e/61ebf08d8940553afff20d1fb1ba7294b6f8d279df9fd0c0db911b4bbcfd/MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171", size = 21091 }, + { url = "https://files.pythonhosted.org/packages/11/23/ffbf53694e8c94ebd1e7e491de185124277964344733c45481f32ede2499/MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50", size = 15065 }, + { url = "https://files.pythonhosted.org/packages/44/06/e7175d06dd6e9172d4a69a72592cb3f7a996a9c396eee29082826449bbc3/MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a", size = 15514 }, + { url = "https://files.pythonhosted.org/packages/6b/28/bbf83e3f76936960b850435576dd5e67034e200469571be53f69174a2dfd/MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d", size = 14353 }, + { url = "https://files.pythonhosted.org/packages/6c/30/316d194b093cde57d448a4c3209f22e3046c5bb2fb0820b118292b334be7/MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93", size = 12392 }, + { url = "https://files.pythonhosted.org/packages/f2/96/9cdafba8445d3a53cae530aaf83c38ec64c4d5427d975c974084af5bc5d2/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832", size = 23984 }, + { url = "https://files.pythonhosted.org/packages/f1/a4/aefb044a2cd8d7334c8a47d3fb2c9f328ac48cb349468cc31c20b539305f/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84", size = 23120 }, + { url = "https://files.pythonhosted.org/packages/8d/21/5e4851379f88f3fad1de30361db501300d4f07bcad047d3cb0449fc51f8c/MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca", size = 23032 }, + { url = "https://files.pythonhosted.org/packages/00/7b/e92c64e079b2d0d7ddf69899c98842f3f9a60a1ae72657c89ce2655c999d/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798", size = 24057 }, + { url = "https://files.pythonhosted.org/packages/f9/ac/46f960ca323037caa0a10662ef97d0a4728e890334fc156b9f9e52bcc4ca/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e", size = 23359 }, + { url = "https://files.pythonhosted.org/packages/69/84/83439e16197337b8b14b6a5b9c2105fff81d42c2a7c5b58ac7b62ee2c3b1/MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4", size = 23306 }, + { url = "https://files.pythonhosted.org/packages/9a/34/a15aa69f01e2181ed8d2b685c0d2f6655d5cca2c4db0ddea775e631918cd/MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d", size = 15094 }, + { url = "https://files.pythonhosted.org/packages/da/b8/3a3bd761922d416f3dc5d00bfbed11f66b1ab89a0c2b6e887240a30b0f6b/MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b", size = 15521 }, + { url = "https://files.pythonhosted.org/packages/22/09/d1f21434c97fc42f09d290cbb6350d44eb12f09cc62c9476effdb33a18aa/MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf", size = 14274 }, + { url = "https://files.pythonhosted.org/packages/6b/b0/18f76bba336fa5aecf79d45dcd6c806c280ec44538b3c13671d49099fdd0/MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225", size = 12348 }, + { url = "https://files.pythonhosted.org/packages/e0/25/dd5c0f6ac1311e9b40f4af06c78efde0f3b5cbf02502f8ef9501294c425b/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028", size = 24149 }, + { url = "https://files.pythonhosted.org/packages/f3/f0/89e7aadfb3749d0f52234a0c8c7867877876e0a20b60e2188e9850794c17/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8", size = 23118 }, + { url = "https://files.pythonhosted.org/packages/d5/da/f2eeb64c723f5e3777bc081da884b414671982008c47dcc1873d81f625b6/MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c", size = 22993 }, + { url = "https://files.pythonhosted.org/packages/da/0e/1f32af846df486dce7c227fe0f2398dc7e2e51d4a370508281f3c1c5cddc/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557", size = 24178 }, + { url = "https://files.pythonhosted.org/packages/c4/f6/bb3ca0532de8086cbff5f06d137064c8410d10779c4c127e0e47d17c0b71/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22", size = 23319 }, + { url = "https://files.pythonhosted.org/packages/a2/82/8be4c96ffee03c5b4a034e60a31294daf481e12c7c43ab8e34a1453ee48b/MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48", size = 23352 }, + { url = "https://files.pythonhosted.org/packages/51/ae/97827349d3fcffee7e184bdf7f41cd6b88d9919c80f0263ba7acd1bbcb18/MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30", size = 15097 }, + { url = "https://files.pythonhosted.org/packages/c1/80/a61f99dc3a936413c3ee4e1eecac96c0da5ed07ad56fd975f1a9da5bc630/MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87", size = 15601 }, + { url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274 }, + { url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352 }, + { url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122 }, + { url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085 }, + { url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978 }, + { url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208 }, + { url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357 }, + { url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344 }, + { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101 }, + { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603 }, + { url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510 }, + { url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486 }, + { url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480 }, + { url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914 }, + { url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796 }, + { url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473 }, + { url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114 }, + { url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098 }, + { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208 }, + { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739 }, + { url = "https://files.pythonhosted.org/packages/a7/ea/9b1530c3fdeeca613faeb0fb5cbcf2389d816072fab72a71b45749ef6062/MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a", size = 14344 }, + { url = "https://files.pythonhosted.org/packages/4b/c2/fbdbfe48848e7112ab05e627e718e854d20192b674952d9042ebd8c9e5de/MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff", size = 12389 }, + { url = "https://files.pythonhosted.org/packages/f0/25/7a7c6e4dbd4f867d95d94ca15449e91e52856f6ed1905d58ef1de5e211d0/MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13", size = 21607 }, + { url = "https://files.pythonhosted.org/packages/53/8f/f339c98a178f3c1e545622206b40986a4c3307fe39f70ccd3d9df9a9e425/MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144", size = 20728 }, + { url = "https://files.pythonhosted.org/packages/1a/03/8496a1a78308456dbd50b23a385c69b41f2e9661c67ea1329849a598a8f9/MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29", size = 20826 }, + { url = "https://files.pythonhosted.org/packages/e6/cf/0a490a4bd363048c3022f2f475c8c05582179bb179defcee4766fb3dcc18/MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0", size = 21843 }, + { url = "https://files.pythonhosted.org/packages/19/a3/34187a78613920dfd3cdf68ef6ce5e99c4f3417f035694074beb8848cd77/MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0", size = 21219 }, + { url = "https://files.pythonhosted.org/packages/17/d8/5811082f85bb88410ad7e452263af048d685669bbbfb7b595e8689152498/MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178", size = 20946 }, + { url = "https://files.pythonhosted.org/packages/7c/31/bd635fb5989440d9365c5e3c47556cfea121c7803f5034ac843e8f37c2f2/MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f", size = 15063 }, + { url = "https://files.pythonhosted.org/packages/b3/73/085399401383ce949f727afec55ec3abd76648d04b9f22e1c0e99cb4bec3/MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a", size = 15506 }, +] + +[[package]] +name = "matplotlib" +version = "3.9.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "contourpy" }, + { name = "cycler" }, + { name = "fonttools" }, + { name = "importlib-resources", marker = "python_full_version < '3.10'" }, + { name = "kiwisolver" }, + { name = "numpy", version = "2.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, + { name = "numpy", version = "2.2.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "packaging" }, + { name = "pillow" }, + { name = "pyparsing" }, + { name = "python-dateutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/17/1747b4154034befd0ed33b52538f5eb7752d05bb51c5e2a31470c3bc7d52/matplotlib-3.9.4.tar.gz", hash = "sha256:1e00e8be7393cbdc6fedfa8a6fba02cf3e83814b285db1c60b906a023ba41bc3", size = 36106529 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/94/27d2e2c30d54b56c7b764acc1874a909e34d1965a427fc7092bb6a588b63/matplotlib-3.9.4-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:c5fdd7abfb706dfa8d307af64a87f1a862879ec3cd8d0ec8637458f0885b9c50", size = 7885089 }, + { url = "https://files.pythonhosted.org/packages/c6/25/828273307e40a68eb8e9df832b6b2aaad075864fdc1de4b1b81e40b09e48/matplotlib-3.9.4-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:d89bc4e85e40a71d1477780366c27fb7c6494d293e1617788986f74e2a03d7ff", size = 7770600 }, + { url = "https://files.pythonhosted.org/packages/f2/65/f841a422ec994da5123368d76b126acf4fc02ea7459b6e37c4891b555b83/matplotlib-3.9.4-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ddf9f3c26aae695c5daafbf6b94e4c1a30d6cd617ba594bbbded3b33a1fcfa26", size = 8200138 }, + { url = "https://files.pythonhosted.org/packages/07/06/272aca07a38804d93b6050813de41ca7ab0e29ba7a9dd098e12037c919a9/matplotlib-3.9.4-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18ebcf248030173b59a868fda1fe42397253f6698995b55e81e1f57431d85e50", size = 8312711 }, + { url = "https://files.pythonhosted.org/packages/98/37/f13e23b233c526b7e27ad61be0a771894a079e0f7494a10d8d81557e0e9a/matplotlib-3.9.4-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:974896ec43c672ec23f3f8c648981e8bc880ee163146e0312a9b8def2fac66f5", size = 9090622 }, + { url = "https://files.pythonhosted.org/packages/4f/8c/b1f5bd2bd70e60f93b1b54c4d5ba7a992312021d0ddddf572f9a1a6d9348/matplotlib-3.9.4-cp310-cp310-win_amd64.whl", hash = "sha256:4598c394ae9711cec135639374e70871fa36b56afae17bdf032a345be552a88d", size = 7828211 }, + { url = "https://files.pythonhosted.org/packages/74/4b/65be7959a8fa118a3929b49a842de5b78bb55475236fcf64f3e308ff74a0/matplotlib-3.9.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d4dd29641d9fb8bc4492420c5480398dd40a09afd73aebe4eb9d0071a05fbe0c", size = 7894430 }, + { url = "https://files.pythonhosted.org/packages/e9/18/80f70d91896e0a517b4a051c3fd540daa131630fd75e02e250365353b253/matplotlib-3.9.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30e5b22e8bcfb95442bf7d48b0d7f3bdf4a450cbf68986ea45fca3d11ae9d099", size = 7780045 }, + { url = "https://files.pythonhosted.org/packages/a2/73/ccb381026e3238c5c25c3609ba4157b2d1a617ec98d65a8b4ee4e1e74d02/matplotlib-3.9.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bb0030d1d447fd56dcc23b4c64a26e44e898f0416276cac1ebc25522e0ac249", size = 8209906 }, + { url = "https://files.pythonhosted.org/packages/ab/33/1648da77b74741c89f5ea95cbf42a291b4b364f2660b316318811404ed97/matplotlib-3.9.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:aca90ed222ac3565d2752b83dbb27627480d27662671e4d39da72e97f657a423", size = 8322873 }, + { url = "https://files.pythonhosted.org/packages/57/d3/8447ba78bc6593c9044c372d1609f8ea10fb1e071e7a9e0747bea74fc16c/matplotlib-3.9.4-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a181b2aa2906c608fcae72f977a4a2d76e385578939891b91c2550c39ecf361e", size = 9099566 }, + { url = "https://files.pythonhosted.org/packages/23/e1/4f0e237bf349c02ff9d1b6e7109f1a17f745263809b9714a8576dc17752b/matplotlib-3.9.4-cp311-cp311-win_amd64.whl", hash = "sha256:1f6882828231eca17f501c4dcd98a05abb3f03d157fbc0769c6911fe08b6cfd3", size = 7838065 }, + { url = "https://files.pythonhosted.org/packages/1a/2b/c918bf6c19d6445d1cefe3d2e42cb740fb997e14ab19d4daeb6a7ab8a157/matplotlib-3.9.4-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:dfc48d67e6661378a21c2983200a654b72b5c5cdbd5d2cf6e5e1ece860f0cc70", size = 7891131 }, + { url = "https://files.pythonhosted.org/packages/c1/e5/b4e8fc601ca302afeeabf45f30e706a445c7979a180e3a978b78b2b681a4/matplotlib-3.9.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:47aef0fab8332d02d68e786eba8113ffd6f862182ea2999379dec9e237b7e483", size = 7776365 }, + { url = "https://files.pythonhosted.org/packages/99/06/b991886c506506476e5d83625c5970c656a491b9f80161458fed94597808/matplotlib-3.9.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fba1f52c6b7dc764097f52fd9ab627b90db452c9feb653a59945de16752e965f", size = 8200707 }, + { url = "https://files.pythonhosted.org/packages/c3/e2/556b627498cb27e61026f2d1ba86a78ad1b836fef0996bef5440e8bc9559/matplotlib-3.9.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:173ac3748acaac21afcc3fa1633924609ba1b87749006bc25051c52c422a5d00", size = 8313761 }, + { url = "https://files.pythonhosted.org/packages/58/ff/165af33ec766ff818306ea88e91f9f60d2a6ed543be1eb122a98acbf3b0d/matplotlib-3.9.4-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:320edea0cadc07007765e33f878b13b3738ffa9745c5f707705692df70ffe0e0", size = 9095284 }, + { url = "https://files.pythonhosted.org/packages/9f/8b/3d0c7a002db3b1ed702731c2a9a06d78d035f1f2fb0fb936a8e43cc1e9f4/matplotlib-3.9.4-cp312-cp312-win_amd64.whl", hash = "sha256:a4a4cfc82330b27042a7169533da7991e8789d180dd5b3daeaee57d75cd5a03b", size = 7841160 }, + { url = "https://files.pythonhosted.org/packages/49/b1/999f89a7556d101b23a2f0b54f1b6e140d73f56804da1398f2f0bc0924bc/matplotlib-3.9.4-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:37eeffeeca3c940985b80f5b9a7b95ea35671e0e7405001f249848d2b62351b6", size = 7891499 }, + { url = "https://files.pythonhosted.org/packages/87/7b/06a32b13a684977653396a1bfcd34d4e7539c5d55c8cbfaa8ae04d47e4a9/matplotlib-3.9.4-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3e7465ac859ee4abcb0d836137cd8414e7bb7ad330d905abced457217d4f0f45", size = 7776802 }, + { url = "https://files.pythonhosted.org/packages/65/87/ac498451aff739e515891bbb92e566f3c7ef31891aaa878402a71f9b0910/matplotlib-3.9.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f4c12302c34afa0cf061bea23b331e747e5e554b0fa595c96e01c7b75bc3b858", size = 8200802 }, + { url = "https://files.pythonhosted.org/packages/f8/6b/9eb761c00e1cb838f6c92e5f25dcda3f56a87a52f6cb8fdfa561e6cf6a13/matplotlib-3.9.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2b8c97917f21b75e72108b97707ba3d48f171541a74aa2a56df7a40626bafc64", size = 8313880 }, + { url = "https://files.pythonhosted.org/packages/d7/a2/c8eaa600e2085eec7e38cbbcc58a30fc78f8224939d31d3152bdafc01fd1/matplotlib-3.9.4-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0229803bd7e19271b03cb09f27db76c918c467aa4ce2ae168171bc67c3f508df", size = 9094637 }, + { url = "https://files.pythonhosted.org/packages/71/1f/c6e1daea55b7bfeb3d84c6cb1abc449f6a02b181e7e2a5e4db34c3afb793/matplotlib-3.9.4-cp313-cp313-win_amd64.whl", hash = "sha256:7c0d8ef442ebf56ff5e206f8083d08252ee738e04f3dc88ea882853a05488799", size = 7841311 }, + { url = "https://files.pythonhosted.org/packages/c0/3a/2757d3f7d388b14dd48f5a83bea65b6d69f000e86b8f28f74d86e0d375bd/matplotlib-3.9.4-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a04c3b00066a688834356d196136349cb32f5e1003c55ac419e91585168b88fb", size = 7919989 }, + { url = "https://files.pythonhosted.org/packages/24/28/f5077c79a4f521589a37fe1062d6a6ea3534e068213f7357e7cfffc2e17a/matplotlib-3.9.4-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:04c519587f6c210626741a1e9a68eefc05966ede24205db8982841826af5871a", size = 7809417 }, + { url = "https://files.pythonhosted.org/packages/36/c8/c523fd2963156692916a8eb7d4069084cf729359f7955cf09075deddfeaf/matplotlib-3.9.4-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:308afbf1a228b8b525fcd5cec17f246bbbb63b175a3ef6eb7b4d33287ca0cf0c", size = 8226258 }, + { url = "https://files.pythonhosted.org/packages/f6/88/499bf4b8fa9349b6f5c0cf4cead0ebe5da9d67769129f1b5651e5ac51fbc/matplotlib-3.9.4-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddb3b02246ddcffd3ce98e88fed5b238bc5faff10dbbaa42090ea13241d15764", size = 8335849 }, + { url = "https://files.pythonhosted.org/packages/b8/9f/20a4156b9726188646a030774ee337d5ff695a965be45ce4dbcb9312c170/matplotlib-3.9.4-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8a75287e9cb9eee48cb79ec1d806f75b29c0fde978cb7223a1f4c5848d696041", size = 9102152 }, + { url = "https://files.pythonhosted.org/packages/10/11/237f9c3a4e8d810b1759b67ff2da7c32c04f9c80aa475e7beb36ed43a8fb/matplotlib-3.9.4-cp313-cp313t-win_amd64.whl", hash = "sha256:488deb7af140f0ba86da003e66e10d55ff915e152c78b4b66d231638400b1965", size = 7896987 }, + { url = "https://files.pythonhosted.org/packages/56/eb/501b465c9fef28f158e414ea3a417913dc2ac748564c7ed41535f23445b4/matplotlib-3.9.4-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:3c3724d89a387ddf78ff88d2a30ca78ac2b4c89cf37f2db4bd453c34799e933c", size = 7885919 }, + { url = "https://files.pythonhosted.org/packages/da/36/236fbd868b6c91309a5206bd90c3f881f4f44b2d997cd1d6239ef652f878/matplotlib-3.9.4-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:d5f0a8430ffe23d7e32cfd86445864ccad141797f7d25b7c41759a5b5d17cfd7", size = 7771486 }, + { url = "https://files.pythonhosted.org/packages/e0/4b/105caf2d54d5ed11d9f4335398f5103001a03515f2126c936a752ccf1461/matplotlib-3.9.4-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6bb0141a21aef3b64b633dc4d16cbd5fc538b727e4958be82a0e1c92a234160e", size = 8201838 }, + { url = "https://files.pythonhosted.org/packages/5d/a7/bb01188fb4013d34d274caf44a2f8091255b0497438e8b6c0a7c1710c692/matplotlib-3.9.4-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:57aa235109e9eed52e2c2949db17da185383fa71083c00c6c143a60e07e0888c", size = 8314492 }, + { url = "https://files.pythonhosted.org/packages/33/19/02e1a37f7141fc605b193e927d0a9cdf9dc124a20b9e68793f4ffea19695/matplotlib-3.9.4-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:b18c600061477ccfdd1e6fd050c33d8be82431700f3452b297a56d9ed7037abb", size = 9092500 }, + { url = "https://files.pythonhosted.org/packages/57/68/c2feb4667adbf882ffa4b3e0ac9967f848980d9f8b5bebd86644aa67ce6a/matplotlib-3.9.4-cp39-cp39-win_amd64.whl", hash = "sha256:ef5f2d1b67d2d2145ff75e10f8c008bfbf71d45137c4b648c87193e7dd053eac", size = 7822962 }, + { url = "https://files.pythonhosted.org/packages/0c/22/2ef6a364cd3f565442b0b055e0599744f1e4314ec7326cdaaa48a4d864d7/matplotlib-3.9.4-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:44e0ed786d769d85bc787b0606a53f2d8d2d1d3c8a2608237365e9121c1a338c", size = 7877995 }, + { url = "https://files.pythonhosted.org/packages/87/b8/2737456e566e9f4d94ae76b8aa0d953d9acb847714f9a7ad80184474f5be/matplotlib-3.9.4-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:09debb9ce941eb23ecdbe7eab972b1c3e0276dcf01688073faff7b0f61d6c6ca", size = 7769300 }, + { url = "https://files.pythonhosted.org/packages/b2/1f/e709c6ec7b5321e6568769baa288c7178e60a93a9da9e682b39450da0e29/matplotlib-3.9.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bcc53cf157a657bfd03afab14774d54ba73aa84d42cfe2480c91bd94873952db", size = 8313423 }, + { url = "https://files.pythonhosted.org/packages/5e/b6/5a1f868782cd13f053a679984e222007ecff654a9bfbac6b27a65f4eeb05/matplotlib-3.9.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:ad45da51be7ad02387801fd154ef74d942f49fe3fcd26a64c94842ba7ec0d865", size = 7854624 }, +] + +[[package]] +name = "matplotlib-inline" +version = "0.1.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/99/5b/a36a337438a14116b16480db471ad061c36c3694df7c2084a0da7ba538b7/matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90", size = 8159 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8f/8e/9ad090d3553c280a8060fbf6e24dc1c0c29704ee7d1c372f0c174aa59285/matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca", size = 9899 }, +] + +[[package]] +name = "mdit-py-plugins" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/03/a2ecab526543b152300717cf232bb4bb8605b6edb946c845016fa9c9c9fd/mdit_py_plugins-0.4.2.tar.gz", hash = "sha256:5f2cd1fdb606ddf152d37ec30e46101a60512bc0e5fa1a7002c36647b09e26b5", size = 43542 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a7/f7/7782a043553ee469c1ff49cfa1cdace2d6bf99a1f333cf38676b3ddf30da/mdit_py_plugins-0.4.2-py3-none-any.whl", hash = "sha256:0c673c3f889399a33b95e88d2f0d111b4447bdfea7f237dab2d488f459835636", size = 55316 }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979 }, +] + +[[package]] +name = "mistune" +version = "3.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/79/6e/96fc7cb3288666c5de2c396eb0e338dc95f7a8e4920e43e38783a22d0084/mistune-3.1.0.tar.gz", hash = "sha256:dbcac2f78292b9dc066cd03b7a3a26b62d85f8159f2ea5fd28e55df79908d667", size = 94401 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b4/b3/743ffc3f59da380da504d84ccd1faf9a857a1445991ff19bf2ec754163c2/mistune-3.1.0-py3-none-any.whl", hash = "sha256:b05198cf6d671b3deba6c87ec6cf0d4eb7b72c524636eddb6dbf13823b52cee1", size = 53694 }, +] + +[[package]] +name = "moderngl" +version = "5.12.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "glcontext" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/da/52/540e2f8c45060bb2709f56eb5a44ae828dfcc97ccecb342c1a7deb467889/moderngl-5.12.0.tar.gz", hash = "sha256:52936a98ccb2f2e1d6e3cb18528b2919f6831e7e3f924e788b5873badce5129b", size = 193232 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/4b/988c5f4ef55bf0c62a0b63a4b32fe6d6dd755d12f5951e8fd56e8a30d3f6/moderngl-5.12.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:105cdee2ee29a7e6ebbc76cf178941503656a185c6945933bc7ef395ba8e65a7", size = 111803 }, + { url = "https://files.pythonhosted.org/packages/97/40/272d38d9d096d591db08e4aa1c983a8ed34cd1717b6524a88539b0df4341/moderngl-5.12.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:18deb8bebd0a4277d92c76dbedf8e4b4b68bf0a8a878404c6b26aed750890d3b", size = 109223 }, + { url = "https://files.pythonhosted.org/packages/e4/5c/a6f2743c8ae1c95cd6531510bf76fa6be650a5e0a1dffdf138b5ed186f61/moderngl-5.12.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f0c4f7c42425177168938386a4fabd734ca3bbb5de2d1fd1176cfa6f980fc13", size = 291432 }, + { url = "https://files.pythonhosted.org/packages/2b/2d/b6bfc4fe7df343a4f410030dbd8261566282049e56e9ffc3cbd2e626656e/moderngl-5.12.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:878cdf593204d85c020305f21d306f979353a67c932b9df58ea936f6e5ad13e7", size = 265422 }, + { url = "https://files.pythonhosted.org/packages/3a/ae/35f8f4c833aca90870110509dddad641f5adf9597da15b3c9e7c75db319f/moderngl-5.12.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:00d94f9cb485d87c85088edad624201e152d8ac401793a024b16cd9e2bc4dbf6", size = 1342266 }, + { url = "https://files.pythonhosted.org/packages/b9/4b/2e0b6d0e8a5273da93ed82c8eb91b54a37413b1b9d65bb223d67b595fc96/moderngl-5.12.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:edd91057b8d76beebac0d7b0c741466ee8f37eaf3c07856785c2872afe0b35ac", size = 1270055 }, + { url = "https://files.pythonhosted.org/packages/48/2f/b590f86d42630fbbaffd83f1890ef6278ec12d5cb336b6a2efcbb3c2ca21/moderngl-5.12.0-cp310-cp310-win32.whl", hash = "sha256:3d066eae2eb44e81bd7addf565adebc041bdee119e7ac6e4f95831d6f327a938", size = 101044 }, + { url = "https://files.pythonhosted.org/packages/9c/6d/f9b77797d3a0f3e5b67a75092c6c63b26360042fd8e43be017c706e308a8/moderngl-5.12.0-cp310-cp310-win_amd64.whl", hash = "sha256:76d966194d51852f48c42a6e786a4520f1e1be5f93e2626423d673663422d559", size = 108272 }, + { url = "https://files.pythonhosted.org/packages/a5/ea/569c2c08bfef84f4acf633a8e6d956f4f75cfaa8832d7d812dbf2ff6843a/moderngl-5.12.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:28cdba5dcf2d03c89bb25dc3b2f5770ac4104470ed5bbe680a15494fa52a537d", size = 111802 }, + { url = "https://files.pythonhosted.org/packages/00/ef/98f36133ab010ce9831b75a16e75a627c12a4c1d6ef2e353eca1769a1e09/moderngl-5.12.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:dad93893e3fcb2410bfd31e854f20e1370b4fbafa07a737f1046f5fbd29ba0f4", size = 109227 }, + { url = "https://files.pythonhosted.org/packages/c2/bb/ab371acacd2497bddb5f02b209e3bfae452b2be59d0cf8fa728a3b87de1f/moderngl-5.12.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7fc0f8788bc84433d2124e9a4893adbe40f93c7d213abb8ad7b909540cb0161f", size = 293468 }, + { url = "https://files.pythonhosted.org/packages/0d/9e/7ebf2b98da310c90c2b295e91b6c25f864f0f5583ce86bee72d387cb577a/moderngl-5.12.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6efd3fe0d2c9652af21e2c1f5a936a2b971abac5bdd777da7182a54962466cab", size = 267348 }, + { url = "https://files.pythonhosted.org/packages/61/0a/87fb24f4cd2aa07150b84fbf400edf4d8a8f71784cbf064f1ed92b756fea/moderngl-5.12.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:6f3bd2d534fc081cde30545b84ebca63aef847ba8bd533217b9a37f565614ade", size = 1343953 }, + { url = "https://files.pythonhosted.org/packages/83/42/11b0306e630d9a38b8bac20563b326f6d5fba4dfc45cc90b0666ed3e7141/moderngl-5.12.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:eaa3de9446c6febec4d5f888e6f1a4e9398bc5a5ea70b1570ea447213641d4a6", size = 1271832 }, + { url = "https://files.pythonhosted.org/packages/6b/dd/74d300275fe4834e63b8d70450801f206d005f2047898d4eb2a30efc3913/moderngl-5.12.0-cp311-cp311-win32.whl", hash = "sha256:9fdb76f1fd890db67727c8cdee4db2ee6319068c7ce92be0308366f8745e28ab", size = 101043 }, + { url = "https://files.pythonhosted.org/packages/7f/08/5f615a4605d343cd5c1112d2b175270e6a5586008bc10a85b822c340cf86/moderngl-5.12.0-cp311-cp311-win_amd64.whl", hash = "sha256:0c210e8d52a60025f6586ca015c39feb1e57e6dc792c3ff44800f6493a541b1a", size = 108279 }, + { url = "https://files.pythonhosted.org/packages/3c/66/31161e81bc85ca3cdbb9d94f703f21575e4ae9a2919e9d1af98fc7fdb1ba/moderngl-5.12.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2750547707c1ec3790dfbeb9c90fb808672ff13f61cac392c706ba09fda10db0", size = 112101 }, + { url = "https://files.pythonhosted.org/packages/84/b2/7229a89a40d33a95119a7c64c7ee36a6a6e376c57c39fb577ea513602f37/moderngl-5.12.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c5c2a5fe06c7021183d9274df798f25516409c8d55898c324dae8a0b2de10144", size = 109377 }, + { url = "https://files.pythonhosted.org/packages/d7/96/bcb5141eae24474d80b8157b0c3055d25fa75f9804d4abb4a514695bbba9/moderngl-5.12.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b6c4972f3ddd10a3de6c30311da2c25bc493d023796e16c5d4e0f8bd6d5770be", size = 296394 }, + { url = "https://files.pythonhosted.org/packages/b8/79/a9998ddf6757f4f15888b0a106d80a64a8c8991a8ce5c14047830704b9e6/moderngl-5.12.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a4d497ec6a3f6afa9ebd0be816d9bfe2fe20fec2105acfb88d956619c3ed8eb4", size = 270548 }, + { url = "https://files.pythonhosted.org/packages/17/f4/313dc301db936b231035b961e004f1914c2954bdcdf4985e24bff15e7ed5/moderngl-5.12.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:2f3d240e9bc5d83257378bae59f8f35638b89d22bb003cf674b88fd7932161ce", size = 1345817 }, + { url = "https://files.pythonhosted.org/packages/8c/6f/7b3587e7e3ae633b8c85038f035dfeb348ebf805de4beb01241c59c6b97c/moderngl-5.12.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6fa667d560d842e778e2a5968305fb78f9781616a11b1b93acd2562f97262ccf", size = 1274968 }, + { url = "https://files.pythonhosted.org/packages/4f/e8/0f3b3cd1be7b0a93f33dc613f76a42021d1393b4949c5b6a1ca2a01c6772/moderngl-5.12.0-cp312-cp312-win32.whl", hash = "sha256:0a02fddd54dccee1ca6060bfed75a2e6a17dd3ee06920fac418506d8a8233849", size = 101221 }, + { url = "https://files.pythonhosted.org/packages/56/85/35498b1821cf31c731b1882168db8924207ff3c06d8f0da53e1cc373a89d/moderngl-5.12.0-cp312-cp312-win_amd64.whl", hash = "sha256:8698a59ad03539a2982125b7998efc1c107ba31d5d03437b6fcd72cb2c226922", size = 108525 }, + { url = "https://files.pythonhosted.org/packages/39/13/cf493bdc3cb4f7a6b4fb357e683404dc8a97d19f53d501e4afdd679538e2/moderngl-5.12.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f6efb432f5164f871471d1da36e3a4be9dc3efd7a1e48d0ac6b751e556af5d02", size = 112118 }, + { url = "https://files.pythonhosted.org/packages/a9/1f/1d84bba5f42fb19ce240d08d5434fe8e2f34341e68bb9fa89336b6cbdcfc/moderngl-5.12.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9b09d8d15b2eaab41c8646a664429ec86af225fa25096758497cd212489d2e1e", size = 109371 }, + { url = "https://files.pythonhosted.org/packages/be/ae/bda0b95878e2b36eac66f64d88c08e6c8ea759607f7d40e843a21c2f4f32/moderngl-5.12.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:071042dd4846e58cbe204cf49341b62cd209fdcb6d48018feb5a61c66707fcb2", size = 296206 }, + { url = "https://files.pythonhosted.org/packages/28/bc/93dc73251bcdb9c0f6f5c9a1d97ec2134672c307c68e6106948eab1f73d4/moderngl-5.12.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:91db8302ac7f5d7a82a967388677e1378ff078f1e16d05da37ce77f4633b93b1", size = 270443 }, + { url = "https://files.pythonhosted.org/packages/2e/a1/bd72c788b16c2392d3e1ebb570e56d7f871eaa1854f57917c0f131acb365/moderngl-5.12.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:51971d65ec96a212a814350c8b324ae0754353e1b61826d1a06aa2d060df170e", size = 1345675 }, + { url = "https://files.pythonhosted.org/packages/b2/ec/6aff8fa267d9f80e4d32b7a606fdf9f0563103441a7dbaa4f53e272a4ada/moderngl-5.12.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d56827360c19e831e986243b5daaf6a51006f1ec0d5372084ad446308763d19f", size = 1274906 }, + { url = "https://files.pythonhosted.org/packages/9f/4d/dc3ff763c125080e71b1095875f5dcc80949402019abc073bdfdbed1f4c2/moderngl-5.12.0-cp313-cp313-win32.whl", hash = "sha256:caa432c12b138a6c9571719075c4d103bdc2504cd31aeda38a00ad10fcf268cb", size = 101215 }, + { url = "https://files.pythonhosted.org/packages/2c/8b/0a264732e0ee49fca109e98ec28f4d0c326ffc31466aa6e9668e8961aabb/moderngl-5.12.0-cp313-cp313-win_amd64.whl", hash = "sha256:e34d1cd38f7998258f76a08bb5e87f351ec653b7ea1928b2711f8719c10cefd1", size = 108514 }, + { url = "https://files.pythonhosted.org/packages/3c/02/0a206f5db9e149d8978b71f6021e1d7286eea6c6903b821f416328ad187b/moderngl-5.12.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:49a6e27abafacef104c7ca336f6790f91c69617a1d752ead4a017b706d632b55", size = 111798 }, + { url = "https://files.pythonhosted.org/packages/05/58/18774a3b249538deb361d078c7364e6e3af6da5d4e11df71a29c376ff44c/moderngl-5.12.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:7146c6fec3b2d7e8d11fa2504046b186d396520c0c2f7ef3aed40d8456dbebfc", size = 109225 }, + { url = "https://files.pythonhosted.org/packages/63/3e/14f8bd1ffb01e922f31d6c7af9817d950a30b84af98b1a82659298b0b7fd/moderngl-5.12.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28b9eb3574ffc6e303173ca0a419b63d8b12cd67f924289c02d127c4d17cdca5", size = 289945 }, + { url = "https://files.pythonhosted.org/packages/b9/27/45d17a612cab85bcbe714c0d5a96fd2cb255cfd313f91427bedab411aac1/moderngl-5.12.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6948237626f9f0d9f931faa3b123d53613d5723679bc70b8db2590924795203f", size = 264314 }, + { url = "https://files.pythonhosted.org/packages/2e/93/93d7fed4c110d4fee41557b1579980b42c3cd1ce093a2bb7634adac149e8/moderngl-5.12.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3c6b4342b7508d75744f1091868cf184cae0be85d37be858fba32eb20d799695", size = 1341312 }, + { url = "https://files.pythonhosted.org/packages/92/51/dc296c5d46846979ed1fe51651bbd5ec22e9192274c146bed69b0dd8ff6b/moderngl-5.12.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:13fec30855d346c4e69eff437e56f2bdd9953d22e80b7c5a319bccac7024e463", size = 1268878 }, + { url = "https://files.pythonhosted.org/packages/60/23/a8227fb03fe21621f8443b394f6a84f37da7e30c874420a8219fa5c2205e/moderngl-5.12.0-cp39-cp39-win32.whl", hash = "sha256:878f249505785cde8cc39d6016e62e74b46acbf3bb6d5a86341c86a7da7e7531", size = 101212 }, + { url = "https://files.pythonhosted.org/packages/b4/4b/854009a4c37882e000b90e355684a091e97318e0336fdccd39d171013d14/moderngl-5.12.0-cp39-cp39-win_amd64.whl", hash = "sha256:e801cd0d35b4e3e99fc6a6f15eb193ce907bfa78127afa5825f1fad24c700c0e", size = 108545 }, +] + +[[package]] +name = "moderngl-window" +version = "3.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "moderngl" }, + { name = "numpy", version = "2.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, + { name = "numpy", version = "2.2.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10'" }, + { name = "pillow" }, + { name = "pyglet" }, + { name = "pyglm" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/90/02/92e235891300c901f59647112a0267a07454f58aeb2041aa44f6b85f9cb3/moderngl_window-3.1.1.tar.gz", hash = "sha256:29c2827505f87399f3461d480b2778910fddeebe44ea803301215cf212a6c1bc", size = 353495 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/23/41/d3503f07de8ad3597165f88b07e1064629f82e65385c4307875b2f6b137f/moderngl_window-3.1.1-py3-none-any.whl", hash = "sha256:e3b3ac2b4e23afcbfdac1971318a4db893bed3ba6a8fbde3367b1226af39b2e5", size = 382381 }, +] + +[[package]] +name = "myst-parser" +version = "3.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "docutils" }, + { name = "jinja2" }, + { name = "markdown-it-py" }, + { name = "mdit-py-plugins" }, + { name = "pyyaml" }, + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/49/64/e2f13dac02f599980798c01156393b781aec983b52a6e4057ee58f07c43a/myst_parser-3.0.1.tar.gz", hash = "sha256:88f0cb406cb363b077d176b51c476f62d60604d68a8dcdf4832e080441301a87", size = 92392 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e2/de/21aa8394f16add8f7427f0a1326ccd2b3a2a8a3245c9252bc5ac034c6155/myst_parser-3.0.1-py3-none-any.whl", hash = "sha256:6457aaa33a5d474aca678b8ead9b3dc298e89c68e67012e73146ea6fd54babf1", size = 83163 }, +] + +[[package]] +name = "nbclient" +version = "0.10.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-client" }, + { name = "jupyter-core" }, + { name = "nbformat" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/87/66/7ffd18d58eae90d5721f9f39212327695b749e23ad44b3881744eaf4d9e8/nbclient-0.10.2.tar.gz", hash = "sha256:90b7fc6b810630db87a6d0c2250b1f0ab4cf4d3c27a299b0cde78a4ed3fd9193", size = 62424 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/34/6d/e7fa07f03a4a7b221d94b4d586edb754a9b0dc3c9e2c93353e9fa4e0d117/nbclient-0.10.2-py3-none-any.whl", hash = "sha256:4ffee11e788b4a27fabeb7955547e4318a5298f34342a4bfd01f2e1faaeadc3d", size = 25434 }, +] + +[[package]] +name = "nbconvert" +version = "7.16.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "beautifulsoup4" }, + { name = "bleach", extra = ["css"] }, + { name = "defusedxml" }, + { name = "importlib-metadata", marker = "python_full_version < '3.10'" }, + { name = "jinja2" }, + { name = "jupyter-core" }, + { name = "jupyterlab-pygments" }, + { name = "markupsafe" }, + { name = "mistune" }, + { name = "nbclient" }, + { name = "nbformat" }, + { name = "packaging" }, + { name = "pandocfilters" }, + { name = "pygments" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/46/2c/d026c0367f2be2463d4c2f5b538e28add2bc67bc13730abb7f364ae4eb8b/nbconvert-7.16.5.tar.gz", hash = "sha256:c83467bb5777fdfaac5ebbb8e864f300b277f68692ecc04d6dab72f2d8442344", size = 856367 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8f/9e/2dcc9fe00cf55d95a8deae69384e9cea61816126e345754f6c75494d32ec/nbconvert-7.16.5-py3-none-any.whl", hash = "sha256:e12eac052d6fd03040af4166c563d76e7aeead2e9aadf5356db552a1784bd547", size = 258061 }, +] + +[[package]] +name = "nbformat" +version = "5.10.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "fastjsonschema" }, + { name = "jsonschema" }, + { name = "jupyter-core" }, + { name = "traitlets" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6d/fd/91545e604bc3dad7dca9ed03284086039b294c6b3d75c0d2fa45f9e9caf3/nbformat-5.10.4.tar.gz", hash = "sha256:322168b14f937a5d11362988ecac2a4952d3d8e3a2cbeb2319584631226d5b3a", size = 142749 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl", hash = "sha256:3b48d6c8fbca4b299bf3982ea7db1af21580e4fec269ad087b9e81588891200b", size = 78454 }, +] + +[[package]] +name = "nest-asyncio" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/83/f8/51569ac65d696c8ecbee95938f89d4abf00f47d58d48f6fbabfe8f0baefe/nest_asyncio-1.6.0.tar.gz", hash = "sha256:6f172d5449aca15afd6c646851f4e31e02c598d553a667e38cafa997cfec55fe", size = 7418 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/c4/c2971a3ba4c6103a3d10c4b0f24f461ddc027f0f09763220cf35ca1401b3/nest_asyncio-1.6.0-py3-none-any.whl", hash = "sha256:87af6efd6b5e897c81050477ef65c62e2b2f35d51703cae01aff2905b1852e1c", size = 5195 }, +] + +[[package]] +name = "networkx" +version = "3.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c4/80/a84676339aaae2f1cfdf9f418701dd634aef9cc76f708ef55c36ff39c3ca/networkx-3.2.1.tar.gz", hash = "sha256:9f1bb5cf3409bf324e0a722c20bdb4c20ee39bf1c30ce8ae499c8502b0b5e0c6", size = 2073928 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d5/f0/8fbc882ca80cf077f1b246c0e3c3465f7f415439bdea6b899f6b19f61f70/networkx-3.2.1-py3-none-any.whl", hash = "sha256:f18c69adc97877c42332c170849c96cefa91881c99a7cb3e95b7c659ebdc1ec2", size = 1647772 }, +] + +[[package]] +name = "nodeenv" +version = "1.9.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/16/fc88b08840de0e0a72a2f9d8c6bae36be573e475a6326ae854bcc549fc45/nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f", size = 47437 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/1d/1b658dbd2b9fa9c4c9f32accbfc0205d532c8c6194dc0f2a4c0428e7128a/nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9", size = 22314 }, +] + +[[package]] +name = "notebook" +version = "7.3.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-server" }, + { name = "jupyterlab" }, + { name = "jupyterlab-server" }, + { name = "notebook-shim" }, + { name = "tornado" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ea/04/ac488379d5afef43402b3fb4be2857db1a09804fecf98b9b714c741b225b/notebook-7.3.2.tar.gz", hash = "sha256:705e83a1785f45b383bf3ee13cb76680b92d24f56fb0c7d2136fe1d850cd3ca8", size = 12781804 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/9b/76e50ee18f183ea5fe1784a9eeaa50f2c71802e4740d6e959592b0993298/notebook-7.3.2-py3-none-any.whl", hash = "sha256:e5f85fc59b69d3618d73cf27544418193ff8e8058d5bf61d315ce4f473556288", size = 13163630 }, +] + +[[package]] +name = "notebook-shim" +version = "0.2.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-server" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/54/d2/92fa3243712b9a3e8bafaf60aac366da1cada3639ca767ff4b5b3654ec28/notebook_shim-0.2.4.tar.gz", hash = "sha256:b4b2cfa1b65d98307ca24361f5b30fe785b53c3fd07b7a47e89acb5e6ac638cb", size = 13167 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/33/bd5b9137445ea4b680023eb0469b2bb969d61303dedb2aac6560ff3d14a1/notebook_shim-0.2.4-py3-none-any.whl", hash = "sha256:411a5be4e9dc882a074ccbcae671eda64cceb068767e9a3419096986560e1cef", size = 13307 }, +] + +[[package]] +name = "numpy" +version = "2.0.2" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.10'", +] +sdist = { url = "https://files.pythonhosted.org/packages/a9/75/10dd1f8116a8b796cb2c737b674e02d02e80454bda953fa7e65d8c12b016/numpy-2.0.2.tar.gz", hash = "sha256:883c987dee1880e2a864ab0dc9892292582510604156762362d9326444636e78", size = 18902015 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/21/91/3495b3237510f79f5d81f2508f9f13fea78ebfdf07538fc7444badda173d/numpy-2.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:51129a29dbe56f9ca83438b706e2e69a39892b5eda6cedcb6b0c9fdc9b0d3ece", size = 21165245 }, + { url = "https://files.pythonhosted.org/packages/05/33/26178c7d437a87082d11019292dce6d3fe6f0e9026b7b2309cbf3e489b1d/numpy-2.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:f15975dfec0cf2239224d80e32c3170b1d168335eaedee69da84fbe9f1f9cd04", size = 13738540 }, + { url = "https://files.pythonhosted.org/packages/ec/31/cc46e13bf07644efc7a4bf68df2df5fb2a1a88d0cd0da9ddc84dc0033e51/numpy-2.0.2-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:8c5713284ce4e282544c68d1c3b2c7161d38c256d2eefc93c1d683cf47683e66", size = 5300623 }, + { url = "https://files.pythonhosted.org/packages/6e/16/7bfcebf27bb4f9d7ec67332ffebee4d1bf085c84246552d52dbb548600e7/numpy-2.0.2-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:becfae3ddd30736fe1889a37f1f580e245ba79a5855bff5f2a29cb3ccc22dd7b", size = 6901774 }, + { url = "https://files.pythonhosted.org/packages/f9/a3/561c531c0e8bf082c5bef509d00d56f82e0ea7e1e3e3a7fc8fa78742a6e5/numpy-2.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2da5960c3cf0df7eafefd806d4e612c5e19358de82cb3c343631188991566ccd", size = 13907081 }, + { url = "https://files.pythonhosted.org/packages/fa/66/f7177ab331876200ac7563a580140643d1179c8b4b6a6b0fc9838de2a9b8/numpy-2.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:496f71341824ed9f3d2fd36cf3ac57ae2e0165c143b55c3a035ee219413f3318", size = 19523451 }, + { url = "https://files.pythonhosted.org/packages/25/7f/0b209498009ad6453e4efc2c65bcdf0ae08a182b2b7877d7ab38a92dc542/numpy-2.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:a61ec659f68ae254e4d237816e33171497e978140353c0c2038d46e63282d0c8", size = 19927572 }, + { url = "https://files.pythonhosted.org/packages/3e/df/2619393b1e1b565cd2d4c4403bdd979621e2c4dea1f8532754b2598ed63b/numpy-2.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d731a1c6116ba289c1e9ee714b08a8ff882944d4ad631fd411106a30f083c326", size = 14400722 }, + { url = "https://files.pythonhosted.org/packages/22/ad/77e921b9f256d5da36424ffb711ae79ca3f451ff8489eeca544d0701d74a/numpy-2.0.2-cp310-cp310-win32.whl", hash = "sha256:984d96121c9f9616cd33fbd0618b7f08e0cfc9600a7ee1d6fd9b239186d19d97", size = 6472170 }, + { url = "https://files.pythonhosted.org/packages/10/05/3442317535028bc29cf0c0dd4c191a4481e8376e9f0db6bcf29703cadae6/numpy-2.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:c7b0be4ef08607dd04da4092faee0b86607f111d5ae68036f16cc787e250a131", size = 15905558 }, + { url = "https://files.pythonhosted.org/packages/8b/cf/034500fb83041aa0286e0fb16e7c76e5c8b67c0711bb6e9e9737a717d5fe/numpy-2.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:49ca4decb342d66018b01932139c0961a8f9ddc7589611158cb3c27cbcf76448", size = 21169137 }, + { url = "https://files.pythonhosted.org/packages/4a/d9/32de45561811a4b87fbdee23b5797394e3d1504b4a7cf40c10199848893e/numpy-2.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:11a76c372d1d37437857280aa142086476136a8c0f373b2e648ab2c8f18fb195", size = 13703552 }, + { url = "https://files.pythonhosted.org/packages/c1/ca/2f384720020c7b244d22508cb7ab23d95f179fcfff33c31a6eeba8d6c512/numpy-2.0.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:807ec44583fd708a21d4a11d94aedf2f4f3c3719035c76a2bbe1fe8e217bdc57", size = 5298957 }, + { url = "https://files.pythonhosted.org/packages/0e/78/a3e4f9fb6aa4e6fdca0c5428e8ba039408514388cf62d89651aade838269/numpy-2.0.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:8cafab480740e22f8d833acefed5cc87ce276f4ece12fdaa2e8903db2f82897a", size = 6905573 }, + { url = "https://files.pythonhosted.org/packages/a0/72/cfc3a1beb2caf4efc9d0b38a15fe34025230da27e1c08cc2eb9bfb1c7231/numpy-2.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a15f476a45e6e5a3a79d8a14e62161d27ad897381fecfa4a09ed5322f2085669", size = 13914330 }, + { url = "https://files.pythonhosted.org/packages/ba/a8/c17acf65a931ce551fee11b72e8de63bf7e8a6f0e21add4c937c83563538/numpy-2.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:13e689d772146140a252c3a28501da66dfecd77490b498b168b501835041f951", size = 19534895 }, + { url = "https://files.pythonhosted.org/packages/ba/86/8767f3d54f6ae0165749f84648da9dcc8cd78ab65d415494962c86fac80f/numpy-2.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9ea91dfb7c3d1c56a0e55657c0afb38cf1eeae4544c208dc465c3c9f3a7c09f9", size = 19937253 }, + { url = "https://files.pythonhosted.org/packages/df/87/f76450e6e1c14e5bb1eae6836478b1028e096fd02e85c1c37674606ab752/numpy-2.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c1c9307701fec8f3f7a1e6711f9089c06e6284b3afbbcd259f7791282d660a15", size = 14414074 }, + { url = "https://files.pythonhosted.org/packages/5c/ca/0f0f328e1e59f73754f06e1adfb909de43726d4f24c6a3f8805f34f2b0fa/numpy-2.0.2-cp311-cp311-win32.whl", hash = "sha256:a392a68bd329eafac5817e5aefeb39038c48b671afd242710b451e76090e81f4", size = 6470640 }, + { url = "https://files.pythonhosted.org/packages/eb/57/3a3f14d3a759dcf9bf6e9eda905794726b758819df4663f217d658a58695/numpy-2.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:286cd40ce2b7d652a6f22efdfc6d1edf879440e53e76a75955bc0c826c7e64dc", size = 15910230 }, + { url = "https://files.pythonhosted.org/packages/45/40/2e117be60ec50d98fa08c2f8c48e09b3edea93cfcabd5a9ff6925d54b1c2/numpy-2.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:df55d490dea7934f330006d0f81e8551ba6010a5bf035a249ef61a94f21c500b", size = 20895803 }, + { url = "https://files.pythonhosted.org/packages/46/92/1b8b8dee833f53cef3e0a3f69b2374467789e0bb7399689582314df02651/numpy-2.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8df823f570d9adf0978347d1f926b2a867d5608f434a7cff7f7908c6570dcf5e", size = 13471835 }, + { url = "https://files.pythonhosted.org/packages/7f/19/e2793bde475f1edaea6945be141aef6c8b4c669b90c90a300a8954d08f0a/numpy-2.0.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:9a92ae5c14811e390f3767053ff54eaee3bf84576d99a2456391401323f4ec2c", size = 5038499 }, + { url = "https://files.pythonhosted.org/packages/e3/ff/ddf6dac2ff0dd50a7327bcdba45cb0264d0e96bb44d33324853f781a8f3c/numpy-2.0.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:a842d573724391493a97a62ebbb8e731f8a5dcc5d285dfc99141ca15a3302d0c", size = 6633497 }, + { url = "https://files.pythonhosted.org/packages/72/21/67f36eac8e2d2cd652a2e69595a54128297cdcb1ff3931cfc87838874bd4/numpy-2.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c05e238064fc0610c840d1cf6a13bf63d7e391717d247f1bf0318172e759e692", size = 13621158 }, + { url = "https://files.pythonhosted.org/packages/39/68/e9f1126d757653496dbc096cb429014347a36b228f5a991dae2c6b6cfd40/numpy-2.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0123ffdaa88fa4ab64835dcbde75dcdf89c453c922f18dced6e27c90d1d0ec5a", size = 19236173 }, + { url = "https://files.pythonhosted.org/packages/d1/e9/1f5333281e4ebf483ba1c888b1d61ba7e78d7e910fdd8e6499667041cc35/numpy-2.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:96a55f64139912d61de9137f11bf39a55ec8faec288c75a54f93dfd39f7eb40c", size = 19634174 }, + { url = "https://files.pythonhosted.org/packages/71/af/a469674070c8d8408384e3012e064299f7a2de540738a8e414dcfd639996/numpy-2.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ec9852fb39354b5a45a80bdab5ac02dd02b15f44b3804e9f00c556bf24b4bded", size = 14099701 }, + { url = "https://files.pythonhosted.org/packages/d0/3d/08ea9f239d0e0e939b6ca52ad403c84a2bce1bde301a8eb4888c1c1543f1/numpy-2.0.2-cp312-cp312-win32.whl", hash = "sha256:671bec6496f83202ed2d3c8fdc486a8fc86942f2e69ff0e986140339a63bcbe5", size = 6174313 }, + { url = "https://files.pythonhosted.org/packages/b2/b5/4ac39baebf1fdb2e72585c8352c56d063b6126be9fc95bd2bb5ef5770c20/numpy-2.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:cfd41e13fdc257aa5778496b8caa5e856dc4896d4ccf01841daee1d96465467a", size = 15606179 }, + { url = "https://files.pythonhosted.org/packages/43/c1/41c8f6df3162b0c6ffd4437d729115704bd43363de0090c7f913cfbc2d89/numpy-2.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9059e10581ce4093f735ed23f3b9d283b9d517ff46009ddd485f1747eb22653c", size = 21169942 }, + { url = "https://files.pythonhosted.org/packages/39/bc/fd298f308dcd232b56a4031fd6ddf11c43f9917fbc937e53762f7b5a3bb1/numpy-2.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:423e89b23490805d2a5a96fe40ec507407b8ee786d66f7328be214f9679df6dd", size = 13711512 }, + { url = "https://files.pythonhosted.org/packages/96/ff/06d1aa3eeb1c614eda245c1ba4fb88c483bee6520d361641331872ac4b82/numpy-2.0.2-cp39-cp39-macosx_14_0_arm64.whl", hash = "sha256:2b2955fa6f11907cf7a70dab0d0755159bca87755e831e47932367fc8f2f2d0b", size = 5306976 }, + { url = "https://files.pythonhosted.org/packages/2d/98/121996dcfb10a6087a05e54453e28e58694a7db62c5a5a29cee14c6e047b/numpy-2.0.2-cp39-cp39-macosx_14_0_x86_64.whl", hash = "sha256:97032a27bd9d8988b9a97a8c4d2c9f2c15a81f61e2f21404d7e8ef00cb5be729", size = 6906494 }, + { url = "https://files.pythonhosted.org/packages/15/31/9dffc70da6b9bbf7968f6551967fc21156207366272c2a40b4ed6008dc9b/numpy-2.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e795a8be3ddbac43274f18588329c72939870a16cae810c2b73461c40718ab1", size = 13912596 }, + { url = "https://files.pythonhosted.org/packages/b9/14/78635daab4b07c0930c919d451b8bf8c164774e6a3413aed04a6d95758ce/numpy-2.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f26b258c385842546006213344c50655ff1555a9338e2e5e02a0756dc3e803dd", size = 19526099 }, + { url = "https://files.pythonhosted.org/packages/26/4c/0eeca4614003077f68bfe7aac8b7496f04221865b3a5e7cb230c9d055afd/numpy-2.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:5fec9451a7789926bcf7c2b8d187292c9f93ea30284802a0ab3f5be8ab36865d", size = 19932823 }, + { url = "https://files.pythonhosted.org/packages/f1/46/ea25b98b13dccaebddf1a803f8c748680d972e00507cd9bc6dcdb5aa2ac1/numpy-2.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:9189427407d88ff25ecf8f12469d4d39d35bee1db5d39fc5c168c6f088a6956d", size = 14404424 }, + { url = "https://files.pythonhosted.org/packages/c8/a6/177dd88d95ecf07e722d21008b1b40e681a929eb9e329684d449c36586b2/numpy-2.0.2-cp39-cp39-win32.whl", hash = "sha256:905d16e0c60200656500c95b6b8dca5d109e23cb24abc701d41c02d74c6b3afa", size = 6476809 }, + { url = "https://files.pythonhosted.org/packages/ea/2b/7fc9f4e7ae5b507c1a3a21f0f15ed03e794c1242ea8a242ac158beb56034/numpy-2.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:a3f4ab0caa7f053f6797fcd4e1e25caee367db3112ef2b6ef82d749530768c73", size = 15911314 }, + { url = "https://files.pythonhosted.org/packages/8f/3b/df5a870ac6a3be3a86856ce195ef42eec7ae50d2a202be1f5a4b3b340e14/numpy-2.0.2-pp39-pypy39_pp73-macosx_10_9_x86_64.whl", hash = "sha256:7f0a0c6f12e07fa94133c8a67404322845220c06a9e80e85999afe727f7438b8", size = 21025288 }, + { url = "https://files.pythonhosted.org/packages/2c/97/51af92f18d6f6f2d9ad8b482a99fb74e142d71372da5d834b3a2747a446e/numpy-2.0.2-pp39-pypy39_pp73-macosx_14_0_x86_64.whl", hash = "sha256:312950fdd060354350ed123c0e25a71327d3711584beaef30cdaa93320c392d4", size = 6762793 }, + { url = "https://files.pythonhosted.org/packages/12/46/de1fbd0c1b5ccaa7f9a005b66761533e2f6a3e560096682683a223631fe9/numpy-2.0.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26df23238872200f63518dd2aa984cfca675d82469535dc7162dc2ee52d9dd5c", size = 19334885 }, + { url = "https://files.pythonhosted.org/packages/cc/dc/d330a6faefd92b446ec0f0dfea4c3207bb1fef3c4771d19cf4543efd2c78/numpy-2.0.2-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a46288ec55ebbd58947d31d72be2c63cbf839f0a63b49cb755022310792a3385", size = 15828784 }, +] + +[[package]] +name = "numpy" +version = "2.2.2" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.10' and python_full_version < '3.13'", + "python_full_version >= '3.13'", +] +sdist = { url = "https://files.pythonhosted.org/packages/ec/d0/c12ddfd3a02274be06ffc71f3efc6d0e457b0409c4481596881e748cb264/numpy-2.2.2.tar.gz", hash = "sha256:ed6906f61834d687738d25988ae117683705636936cc605be0bb208b23df4d8f", size = 20233295 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/70/2a/69033dc22d981ad21325314f8357438078f5c28310a6d89fb3833030ec8a/numpy-2.2.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:7079129b64cb78bdc8d611d1fd7e8002c0a2565da6a47c4df8062349fee90e3e", size = 21215825 }, + { url = "https://files.pythonhosted.org/packages/31/2c/39f91e00bbd3d5639b027ac48c55dc5f2992bd2b305412d26be4c830862a/numpy-2.2.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:2ec6c689c61df613b783aeb21f945c4cbe6c51c28cb70aae8430577ab39f163e", size = 14354996 }, + { url = "https://files.pythonhosted.org/packages/0a/2c/d468ebd253851af10de5b3e8f3418ebabfaab5f0337a75299fbeb8b8c17a/numpy-2.2.2-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:40c7ff5da22cd391944a28c6a9c638a5eef77fcf71d6e3a79e1d9d9e82752715", size = 5393621 }, + { url = "https://files.pythonhosted.org/packages/7f/f4/3d8a5a0da297034106c5de92be881aca7079cde6058934215a1de91334f6/numpy-2.2.2-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:995f9e8181723852ca458e22de5d9b7d3ba4da3f11cc1cb113f093b271d7965a", size = 6928931 }, + { url = "https://files.pythonhosted.org/packages/47/a7/029354ab56edd43dd3f5efbfad292b8844f98b93174f322f82353fa46efa/numpy-2.2.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b78ea78450fd96a498f50ee096f69c75379af5138f7881a51355ab0e11286c97", size = 14333157 }, + { url = "https://files.pythonhosted.org/packages/e3/d7/11fc594838d35c43519763310c316d4fd56f8600d3fc80a8e13e325b5c5c/numpy-2.2.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3fbe72d347fbc59f94124125e73fc4976a06927ebc503ec5afbfb35f193cd957", size = 16381794 }, + { url = "https://files.pythonhosted.org/packages/af/d4/dd9b19cd4aff9c79d3f54d17f8be815407520d3116004bc574948336981b/numpy-2.2.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:8e6da5cffbbe571f93588f562ed130ea63ee206d12851b60819512dd3e1ba50d", size = 15543990 }, + { url = "https://files.pythonhosted.org/packages/30/97/ab96b7650f27f684a9b1e46757a7294ecc50cab27701d05f146e9f779627/numpy-2.2.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:09d6a2032faf25e8d0cadde7fd6145118ac55d2740132c1d845f98721b5ebcfd", size = 18170896 }, + { url = "https://files.pythonhosted.org/packages/81/9b/bae9618cab20db67a2ca9d711795cad29b2ca4b73034dd3b5d05b962070a/numpy-2.2.2-cp310-cp310-win32.whl", hash = "sha256:159ff6ee4c4a36a23fe01b7c3d07bd8c14cc433d9720f977fcd52c13c0098160", size = 6573458 }, + { url = "https://files.pythonhosted.org/packages/92/9b/95678092febd14070cfb7906ea7932e71e9dd5a6ab3ee948f9ed975e905d/numpy-2.2.2-cp310-cp310-win_amd64.whl", hash = "sha256:64bd6e1762cd7f0986a740fee4dff927b9ec2c5e4d9a28d056eb17d332158014", size = 12915812 }, + { url = "https://files.pythonhosted.org/packages/21/67/32c68756eed84df181c06528ff57e09138f893c4653448c4967311e0f992/numpy-2.2.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:642199e98af1bd2b6aeb8ecf726972d238c9877b0f6e8221ee5ab945ec8a2189", size = 21220002 }, + { url = "https://files.pythonhosted.org/packages/3b/89/f43bcad18f2b2e5814457b1c7f7b0e671d0db12c8c0e43397ab8cb1831ed/numpy-2.2.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6d9fc9d812c81e6168b6d405bf00b8d6739a7f72ef22a9214c4241e0dc70b323", size = 14391215 }, + { url = "https://files.pythonhosted.org/packages/9c/e6/efb8cd6122bf25e86e3dd89d9dbfec9e6861c50e8810eed77d4be59b51c6/numpy-2.2.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:c7d1fd447e33ee20c1f33f2c8e6634211124a9aabde3c617687d8b739aa69eac", size = 5391918 }, + { url = "https://files.pythonhosted.org/packages/47/e2/fccf89d64d9b47ffb242823d4e851fc9d36fa751908c9aac2807924d9b4e/numpy-2.2.2-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:451e854cfae0febe723077bd0cf0a4302a5d84ff25f0bfece8f29206c7bed02e", size = 6933133 }, + { url = "https://files.pythonhosted.org/packages/34/22/5ece749c0e5420a9380eef6fbf83d16a50010bd18fef77b9193d80a6760e/numpy-2.2.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd249bc894af67cbd8bad2c22e7cbcd46cf87ddfca1f1289d1e7e54868cc785c", size = 14338187 }, + { url = "https://files.pythonhosted.org/packages/5b/86/caec78829311f62afa6fa334c8dfcd79cffb4d24bcf96ee02ae4840d462b/numpy-2.2.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:02935e2c3c0c6cbe9c7955a8efa8908dd4221d7755644c59d1bba28b94fd334f", size = 16393429 }, + { url = "https://files.pythonhosted.org/packages/c8/4e/0c25f74c88239a37924577d6ad780f3212a50f4b4b5f54f5e8c918d726bd/numpy-2.2.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a972cec723e0563aa0823ee2ab1df0cb196ed0778f173b381c871a03719d4826", size = 15559103 }, + { url = "https://files.pythonhosted.org/packages/d4/bd/d557f10fa50dc4d5871fb9606af563249b66af2fc6f99041a10e8757c6f1/numpy-2.2.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d6d6a0910c3b4368d89dde073e630882cdb266755565155bc33520283b2d9df8", size = 18182967 }, + { url = "https://files.pythonhosted.org/packages/30/e9/66cc0f66386d78ed89e45a56e2a1d051e177b6e04477c4a41cd590ef4017/numpy-2.2.2-cp311-cp311-win32.whl", hash = "sha256:860fd59990c37c3ef913c3ae390b3929d005243acca1a86facb0773e2d8d9e50", size = 6571499 }, + { url = "https://files.pythonhosted.org/packages/66/a3/4139296b481ae7304a43581046b8f0a20da6a0dfe0ee47a044cade796603/numpy-2.2.2-cp311-cp311-win_amd64.whl", hash = "sha256:da1eeb460ecce8d5b8608826595c777728cdf28ce7b5a5a8c8ac8d949beadcf2", size = 12919805 }, + { url = "https://files.pythonhosted.org/packages/0c/e6/847d15770ab7a01e807bdfcd4ead5bdae57c0092b7dc83878171b6af97bb/numpy-2.2.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ac9bea18d6d58a995fac1b2cb4488e17eceeac413af014b1dd26170b766d8467", size = 20912636 }, + { url = "https://files.pythonhosted.org/packages/d1/af/f83580891577b13bd7e261416120e036d0d8fb508c8a43a73e38928b794b/numpy-2.2.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:23ae9f0c2d889b7b2d88a3791f6c09e2ef827c2446f1c4a3e3e76328ee4afd9a", size = 14098403 }, + { url = "https://files.pythonhosted.org/packages/2b/86/d019fb60a9d0f1d4cf04b014fe88a9135090adfadcc31c1fadbb071d7fa7/numpy-2.2.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:3074634ea4d6df66be04f6728ee1d173cfded75d002c75fac79503a880bf3825", size = 5128938 }, + { url = "https://files.pythonhosted.org/packages/7a/1b/50985edb6f1ec495a1c36452e860476f5b7ecdc3fc59ea89ccad3c4926c5/numpy-2.2.2-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:8ec0636d3f7d68520afc6ac2dc4b8341ddb725039de042faf0e311599f54eb37", size = 6661937 }, + { url = "https://files.pythonhosted.org/packages/f4/1b/17efd94cad1b9d605c3f8907fb06bcffc4ce4d1d14d46b95316cccccf2b9/numpy-2.2.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2ffbb1acd69fdf8e89dd60ef6182ca90a743620957afb7066385a7bbe88dc748", size = 14049518 }, + { url = "https://files.pythonhosted.org/packages/5b/73/65d2f0b698df1731e851e3295eb29a5ab8aa06f763f7e4188647a809578d/numpy-2.2.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0349b025e15ea9d05c3d63f9657707a4e1d471128a3b1d876c095f328f8ff7f0", size = 16099146 }, + { url = "https://files.pythonhosted.org/packages/d5/69/308f55c0e19d4b5057b5df286c5433822e3c8039ede06d4051d96f1c2c4e/numpy-2.2.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:463247edcee4a5537841d5350bc87fe8e92d7dd0e8c71c995d2c6eecb8208278", size = 15246336 }, + { url = "https://files.pythonhosted.org/packages/f0/d8/d8d333ad0d8518d077a21aeea7b7c826eff766a2b1ce1194dea95ca0bacf/numpy-2.2.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9dd47ff0cb2a656ad69c38da850df3454da88ee9a6fde0ba79acceee0e79daba", size = 17863507 }, + { url = "https://files.pythonhosted.org/packages/82/6e/0b84ad3103ffc16d6673e63b5acbe7901b2af96c2837174c6318c98e27ab/numpy-2.2.2-cp312-cp312-win32.whl", hash = "sha256:4525b88c11906d5ab1b0ec1f290996c0020dd318af8b49acaa46f198b1ffc283", size = 6276491 }, + { url = "https://files.pythonhosted.org/packages/fc/84/7f801a42a67b9772a883223a0a1e12069a14626c81a732bd70aac57aebc1/numpy-2.2.2-cp312-cp312-win_amd64.whl", hash = "sha256:5acea83b801e98541619af398cc0109ff48016955cc0818f478ee9ef1c5c3dcb", size = 12616372 }, + { url = "https://files.pythonhosted.org/packages/e1/fe/df5624001f4f5c3e0b78e9017bfab7fdc18a8d3b3d3161da3d64924dd659/numpy-2.2.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:b208cfd4f5fe34e1535c08983a1a6803fdbc7a1e86cf13dd0c61de0b51a0aadc", size = 20899188 }, + { url = "https://files.pythonhosted.org/packages/a9/80/d349c3b5ed66bd3cb0214be60c27e32b90a506946857b866838adbe84040/numpy-2.2.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d0bbe7dd86dca64854f4b6ce2ea5c60b51e36dfd597300057cf473d3615f2369", size = 14113972 }, + { url = "https://files.pythonhosted.org/packages/9d/50/949ec9cbb28c4b751edfa64503f0913cbfa8d795b4a251e7980f13a8a655/numpy-2.2.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:22ea3bb552ade325530e72a0c557cdf2dea8914d3a5e1fecf58fa5dbcc6f43cd", size = 5114294 }, + { url = "https://files.pythonhosted.org/packages/8d/f3/399c15629d5a0c68ef2aa7621d430b2be22034f01dd7f3c65a9c9666c445/numpy-2.2.2-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:128c41c085cab8a85dc29e66ed88c05613dccf6bc28b3866cd16050a2f5448be", size = 6648426 }, + { url = "https://files.pythonhosted.org/packages/2c/03/c72474c13772e30e1bc2e558cdffd9123c7872b731263d5648b5c49dd459/numpy-2.2.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:250c16b277e3b809ac20d1f590716597481061b514223c7badb7a0f9993c7f84", size = 14045990 }, + { url = "https://files.pythonhosted.org/packages/83/9c/96a9ab62274ffafb023f8ee08c88d3d31ee74ca58869f859db6845494fa6/numpy-2.2.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e0c8854b09bc4de7b041148d8550d3bd712b5c21ff6a8ed308085f190235d7ff", size = 16096614 }, + { url = "https://files.pythonhosted.org/packages/d5/34/cd0a735534c29bec7093544b3a509febc9b0df77718a9b41ffb0809c9f46/numpy-2.2.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b6fb9c32a91ec32a689ec6410def76443e3c750e7cfc3fb2206b985ffb2b85f0", size = 15242123 }, + { url = "https://files.pythonhosted.org/packages/5e/6d/541717a554a8f56fa75e91886d9b79ade2e595918690eb5d0d3dbd3accb9/numpy-2.2.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:57b4012e04cc12b78590a334907e01b3a85efb2107df2b8733ff1ed05fce71de", size = 17859160 }, + { url = "https://files.pythonhosted.org/packages/b9/a5/fbf1f2b54adab31510728edd06a05c1b30839f37cf8c9747cb85831aaf1b/numpy-2.2.2-cp313-cp313-win32.whl", hash = "sha256:4dbd80e453bd34bd003b16bd802fac70ad76bd463f81f0c518d1245b1c55e3d9", size = 6273337 }, + { url = "https://files.pythonhosted.org/packages/56/e5/01106b9291ef1d680f82bc47d0c5b5e26dfed15b0754928e8f856c82c881/numpy-2.2.2-cp313-cp313-win_amd64.whl", hash = "sha256:5a8c863ceacae696aff37d1fd636121f1a512117652e5dfb86031c8d84836369", size = 12609010 }, + { url = "https://files.pythonhosted.org/packages/9f/30/f23d9876de0f08dceb707c4dcf7f8dd7588266745029debb12a3cdd40be6/numpy-2.2.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:b3482cb7b3325faa5f6bc179649406058253d91ceda359c104dac0ad320e1391", size = 20924451 }, + { url = "https://files.pythonhosted.org/packages/6a/ec/6ea85b2da9d5dfa1dbb4cb3c76587fc8ddcae580cb1262303ab21c0926c4/numpy-2.2.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:9491100aba630910489c1d0158034e1c9a6546f0b1340f716d522dc103788e39", size = 14122390 }, + { url = "https://files.pythonhosted.org/packages/68/05/bfbdf490414a7dbaf65b10c78bc243f312c4553234b6d91c94eb7c4b53c2/numpy-2.2.2-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:41184c416143defa34cc8eb9d070b0a5ba4f13a0fa96a709e20584638254b317", size = 5156590 }, + { url = "https://files.pythonhosted.org/packages/f7/ec/fe2e91b2642b9d6544518388a441bcd65c904cea38d9ff998e2e8ebf808e/numpy-2.2.2-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:7dca87ca328f5ea7dafc907c5ec100d187911f94825f8700caac0b3f4c384b49", size = 6671958 }, + { url = "https://files.pythonhosted.org/packages/b1/6f/6531a78e182f194d33ee17e59d67d03d0d5a1ce7f6be7343787828d1bd4a/numpy-2.2.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bc61b307655d1a7f9f4b043628b9f2b721e80839914ede634e3d485913e1fb2", size = 14019950 }, + { url = "https://files.pythonhosted.org/packages/e1/fb/13c58591d0b6294a08cc40fcc6b9552d239d773d520858ae27f39997f2ae/numpy-2.2.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9fad446ad0bc886855ddf5909cbf8cb5d0faa637aaa6277fb4b19ade134ab3c7", size = 16079759 }, + { url = "https://files.pythonhosted.org/packages/2c/f2/f2f8edd62abb4b289f65a7f6d1f3650273af00b91b7267a2431be7f1aec6/numpy-2.2.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:149d1113ac15005652e8d0d3f6fd599360e1a708a4f98e43c9c77834a28238cb", size = 15226139 }, + { url = "https://files.pythonhosted.org/packages/aa/29/14a177f1a90b8ad8a592ca32124ac06af5eff32889874e53a308f850290f/numpy-2.2.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:106397dbbb1896f99e044efc90360d098b3335060375c26aa89c0d8a97c5f648", size = 17856316 }, + { url = "https://files.pythonhosted.org/packages/95/03/242ae8d7b97f4e0e4ab8dd51231465fb23ed5e802680d629149722e3faf1/numpy-2.2.2-cp313-cp313t-win32.whl", hash = "sha256:0eec19f8af947a61e968d5429f0bd92fec46d92b0008d0a6685b40d6adf8a4f4", size = 6329134 }, + { url = "https://files.pythonhosted.org/packages/80/94/cd9e9b04012c015cb6320ab3bf43bc615e248dddfeb163728e800a5d96f0/numpy-2.2.2-cp313-cp313t-win_amd64.whl", hash = "sha256:97b974d3ba0fb4612b77ed35d7627490e8e3dff56ab41454d9e8b23448940576", size = 12696208 }, + { url = "https://files.pythonhosted.org/packages/96/7e/1dd770ee68916ed358991ab62c2cc353ffd98d0b75b901d52183ca28e8bb/numpy-2.2.2-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b0531f0b0e07643eb089df4c509d30d72c9ef40defa53e41363eca8a8cc61495", size = 21047291 }, + { url = "https://files.pythonhosted.org/packages/d1/3c/ccd08578dc532a8e6927952339d4a02682b776d5e85be49ed0760308433e/numpy-2.2.2-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:e9e82dcb3f2ebbc8cb5ce1102d5f1c5ed236bf8a11730fb45ba82e2841ec21df", size = 6792494 }, + { url = "https://files.pythonhosted.org/packages/7c/28/8754b9aee4f97199f9a047f73bb644b5a2014994a6d7b061ba67134a42de/numpy-2.2.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e0d4142eb40ca6f94539e4db929410f2a46052a0fe7a2c1c59f6179c39938d2a", size = 16197312 }, + { url = "https://files.pythonhosted.org/packages/26/96/deb93f871f401045a684ca08a009382b247d14996d7a94fea6aa43c67b94/numpy-2.2.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:356ca982c188acbfa6af0d694284d8cf20e95b1c3d0aefa8929376fea9146f60", size = 12822674 }, +] + +[[package]] +name = "overrides" +version = "7.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/36/86/b585f53236dec60aba864e050778b25045f857e17f6e5ea0ae95fe80edd2/overrides-7.7.0.tar.gz", hash = "sha256:55158fa3d93b98cc75299b1e67078ad9003ca27945c76162c1c0766d6f91820a", size = 22812 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/ab/fc8290c6a4c722e5514d80f62b2dc4c4df1a68a41d1364e625c35990fcf3/overrides-7.7.0-py3-none-any.whl", hash = "sha256:c7ed9d062f78b8e4c1a7b70bd8796b35ead4d9f510227ef9c5dc7626c60d7e49", size = 17832 }, +] + +[[package]] +name = "packaging" +version = "24.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 }, +] + +[[package]] +name = "pandocfilters" +version = "1.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/70/6f/3dd4940bbe001c06a65f88e36bad298bc7a0de5036115639926b0c5c0458/pandocfilters-1.5.1.tar.gz", hash = "sha256:002b4a555ee4ebc03f8b66307e287fa492e4a77b4ea14d3f934328297bb4939e", size = 8454 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/af/4fbc8cab944db5d21b7e2a5b8e9211a03a79852b1157e2c102fcc61ac440/pandocfilters-1.5.1-py2.py3-none-any.whl", hash = "sha256:93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc", size = 8663 }, +] + +[[package]] +name = "parso" +version = "0.8.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/66/94/68e2e17afaa9169cf6412ab0f28623903be73d1b32e208d9e8e541bb086d/parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d", size = 400609 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c6/ac/dac4a63f978e4dcb3c6d3a78c4d8e0192a113d288502a1216950c41b1027/parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18", size = 103650 }, +] + +[[package]] +name = "pexpect" +version = "4.9.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ptyprocess" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", size = 63772 }, +] + +[[package]] +name = "pillow" +version = "11.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/af/c097e544e7bd278333db77933e535098c259609c4eb3b85381109602fb5b/pillow-11.1.0.tar.gz", hash = "sha256:368da70808b36d73b4b390a8ffac11069f8a5c85f29eff1f1b01bcf3ef5b2a20", size = 46742715 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/50/1c/2dcea34ac3d7bc96a1fd1bd0a6e06a57c67167fec2cff8d95d88229a8817/pillow-11.1.0-cp310-cp310-macosx_10_10_x86_64.whl", hash = "sha256:e1abe69aca89514737465752b4bcaf8016de61b3be1397a8fc260ba33321b3a8", size = 3229983 }, + { url = "https://files.pythonhosted.org/packages/14/ca/6bec3df25e4c88432681de94a3531cc738bd85dea6c7aa6ab6f81ad8bd11/pillow-11.1.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c640e5a06869c75994624551f45e5506e4256562ead981cce820d5ab39ae2192", size = 3101831 }, + { url = "https://files.pythonhosted.org/packages/d4/2c/668e18e5521e46eb9667b09e501d8e07049eb5bfe39d56be0724a43117e6/pillow-11.1.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a07dba04c5e22824816b2615ad7a7484432d7f540e6fa86af60d2de57b0fcee2", size = 4314074 }, + { url = "https://files.pythonhosted.org/packages/02/80/79f99b714f0fc25f6a8499ecfd1f810df12aec170ea1e32a4f75746051ce/pillow-11.1.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e267b0ed063341f3e60acd25c05200df4193e15a4a5807075cd71225a2386e26", size = 4394933 }, + { url = "https://files.pythonhosted.org/packages/81/aa/8d4ad25dc11fd10a2001d5b8a80fdc0e564ac33b293bdfe04ed387e0fd95/pillow-11.1.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:bd165131fd51697e22421d0e467997ad31621b74bfc0b75956608cb2906dda07", size = 4353349 }, + { url = "https://files.pythonhosted.org/packages/84/7a/cd0c3eaf4a28cb2a74bdd19129f7726277a7f30c4f8424cd27a62987d864/pillow-11.1.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:abc56501c3fd148d60659aae0af6ddc149660469082859fa7b066a298bde9482", size = 4476532 }, + { url = "https://files.pythonhosted.org/packages/8f/8b/a907fdd3ae8f01c7670dfb1499c53c28e217c338b47a813af8d815e7ce97/pillow-11.1.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:54ce1c9a16a9561b6d6d8cb30089ab1e5eb66918cb47d457bd996ef34182922e", size = 4279789 }, + { url = "https://files.pythonhosted.org/packages/6f/9a/9f139d9e8cccd661c3efbf6898967a9a337eb2e9be2b454ba0a09533100d/pillow-11.1.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:73ddde795ee9b06257dac5ad42fcb07f3b9b813f8c1f7f870f402f4dc54b5269", size = 4413131 }, + { url = "https://files.pythonhosted.org/packages/a8/68/0d8d461f42a3f37432203c8e6df94da10ac8081b6d35af1c203bf3111088/pillow-11.1.0-cp310-cp310-win32.whl", hash = "sha256:3a5fe20a7b66e8135d7fd617b13272626a28278d0e578c98720d9ba4b2439d49", size = 2291213 }, + { url = "https://files.pythonhosted.org/packages/14/81/d0dff759a74ba87715509af9f6cb21fa21d93b02b3316ed43bda83664db9/pillow-11.1.0-cp310-cp310-win_amd64.whl", hash = "sha256:b6123aa4a59d75f06e9dd3dac5bf8bc9aa383121bb3dd9a7a612e05eabc9961a", size = 2625725 }, + { url = "https://files.pythonhosted.org/packages/ce/1f/8d50c096a1d58ef0584ddc37e6f602828515219e9d2428e14ce50f5ecad1/pillow-11.1.0-cp310-cp310-win_arm64.whl", hash = "sha256:a76da0a31da6fcae4210aa94fd779c65c75786bc9af06289cd1c184451ef7a65", size = 2375213 }, + { url = "https://files.pythonhosted.org/packages/dd/d6/2000bfd8d5414fb70cbbe52c8332f2283ff30ed66a9cde42716c8ecbe22c/pillow-11.1.0-cp311-cp311-macosx_10_10_x86_64.whl", hash = "sha256:e06695e0326d05b06833b40b7ef477e475d0b1ba3a6d27da1bb48c23209bf457", size = 3229968 }, + { url = "https://files.pythonhosted.org/packages/d9/45/3fe487010dd9ce0a06adf9b8ff4f273cc0a44536e234b0fad3532a42c15b/pillow-11.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:96f82000e12f23e4f29346e42702b6ed9a2f2fea34a740dd5ffffcc8c539eb35", size = 3101806 }, + { url = "https://files.pythonhosted.org/packages/e3/72/776b3629c47d9d5f1c160113158a7a7ad177688d3a1159cd3b62ded5a33a/pillow-11.1.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3cd561ded2cf2bbae44d4605837221b987c216cff94f49dfeed63488bb228d2", size = 4322283 }, + { url = "https://files.pythonhosted.org/packages/e4/c2/e25199e7e4e71d64eeb869f5b72c7ddec70e0a87926398785ab944d92375/pillow-11.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f189805c8be5ca5add39e6f899e6ce2ed824e65fb45f3c28cb2841911da19070", size = 4402945 }, + { url = "https://files.pythonhosted.org/packages/c1/ed/51d6136c9d5911f78632b1b86c45241c712c5a80ed7fa7f9120a5dff1eba/pillow-11.1.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:dd0052e9db3474df30433f83a71b9b23bd9e4ef1de13d92df21a52c0303b8ab6", size = 4361228 }, + { url = "https://files.pythonhosted.org/packages/48/a4/fbfe9d5581d7b111b28f1d8c2762dee92e9821bb209af9fa83c940e507a0/pillow-11.1.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:837060a8599b8f5d402e97197d4924f05a2e0d68756998345c829c33186217b1", size = 4484021 }, + { url = "https://files.pythonhosted.org/packages/39/db/0b3c1a5018117f3c1d4df671fb8e47d08937f27519e8614bbe86153b65a5/pillow-11.1.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:aa8dd43daa836b9a8128dbe7d923423e5ad86f50a7a14dc688194b7be5c0dea2", size = 4287449 }, + { url = "https://files.pythonhosted.org/packages/d9/58/bc128da7fea8c89fc85e09f773c4901e95b5936000e6f303222490c052f3/pillow-11.1.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0a2f91f8a8b367e7a57c6e91cd25af510168091fb89ec5146003e424e1558a96", size = 4419972 }, + { url = "https://files.pythonhosted.org/packages/5f/bb/58f34379bde9fe197f51841c5bbe8830c28bbb6d3801f16a83b8f2ad37df/pillow-11.1.0-cp311-cp311-win32.whl", hash = "sha256:c12fc111ef090845de2bb15009372175d76ac99969bdf31e2ce9b42e4b8cd88f", size = 2291201 }, + { url = "https://files.pythonhosted.org/packages/3a/c6/fce9255272bcf0c39e15abd2f8fd8429a954cf344469eaceb9d0d1366913/pillow-11.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:fbd43429d0d7ed6533b25fc993861b8fd512c42d04514a0dd6337fb3ccf22761", size = 2625686 }, + { url = "https://files.pythonhosted.org/packages/c8/52/8ba066d569d932365509054859f74f2a9abee273edcef5cd75e4bc3e831e/pillow-11.1.0-cp311-cp311-win_arm64.whl", hash = "sha256:f7955ecf5609dee9442cbface754f2c6e541d9e6eda87fad7f7a989b0bdb9d71", size = 2375194 }, + { url = "https://files.pythonhosted.org/packages/95/20/9ce6ed62c91c073fcaa23d216e68289e19d95fb8188b9fb7a63d36771db8/pillow-11.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:2062ffb1d36544d42fcaa277b069c88b01bb7298f4efa06731a7fd6cc290b81a", size = 3226818 }, + { url = "https://files.pythonhosted.org/packages/b9/d8/f6004d98579a2596c098d1e30d10b248798cceff82d2b77aa914875bfea1/pillow-11.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a85b653980faad27e88b141348707ceeef8a1186f75ecc600c395dcac19f385b", size = 3101662 }, + { url = "https://files.pythonhosted.org/packages/08/d9/892e705f90051c7a2574d9f24579c9e100c828700d78a63239676f960b74/pillow-11.1.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9409c080586d1f683df3f184f20e36fb647f2e0bc3988094d4fd8c9f4eb1b3b3", size = 4329317 }, + { url = "https://files.pythonhosted.org/packages/8c/aa/7f29711f26680eab0bcd3ecdd6d23ed6bce180d82e3f6380fb7ae35fcf3b/pillow-11.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7fdadc077553621911f27ce206ffcbec7d3f8d7b50e0da39f10997e8e2bb7f6a", size = 4412999 }, + { url = "https://files.pythonhosted.org/packages/c8/c4/8f0fe3b9e0f7196f6d0bbb151f9fba323d72a41da068610c4c960b16632a/pillow-11.1.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:93a18841d09bcdd774dcdc308e4537e1f867b3dec059c131fde0327899734aa1", size = 4368819 }, + { url = "https://files.pythonhosted.org/packages/38/0d/84200ed6a871ce386ddc82904bfadc0c6b28b0c0ec78176871a4679e40b3/pillow-11.1.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:9aa9aeddeed452b2f616ff5507459e7bab436916ccb10961c4a382cd3e03f47f", size = 4496081 }, + { url = "https://files.pythonhosted.org/packages/84/9c/9bcd66f714d7e25b64118e3952d52841a4babc6d97b6d28e2261c52045d4/pillow-11.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3cdcdb0b896e981678eee140d882b70092dac83ac1cdf6b3a60e2216a73f2b91", size = 4296513 }, + { url = "https://files.pythonhosted.org/packages/db/61/ada2a226e22da011b45f7104c95ebda1b63dcbb0c378ad0f7c2a710f8fd2/pillow-11.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:36ba10b9cb413e7c7dfa3e189aba252deee0602c86c309799da5a74009ac7a1c", size = 4431298 }, + { url = "https://files.pythonhosted.org/packages/e7/c4/fc6e86750523f367923522014b821c11ebc5ad402e659d8c9d09b3c9d70c/pillow-11.1.0-cp312-cp312-win32.whl", hash = "sha256:cfd5cd998c2e36a862d0e27b2df63237e67273f2fc78f47445b14e73a810e7e6", size = 2291630 }, + { url = "https://files.pythonhosted.org/packages/08/5c/2104299949b9d504baf3f4d35f73dbd14ef31bbd1ddc2c1b66a5b7dfda44/pillow-11.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:a697cd8ba0383bba3d2d3ada02b34ed268cb548b369943cd349007730c92bddf", size = 2626369 }, + { url = "https://files.pythonhosted.org/packages/37/f3/9b18362206b244167c958984b57c7f70a0289bfb59a530dd8af5f699b910/pillow-11.1.0-cp312-cp312-win_arm64.whl", hash = "sha256:4dd43a78897793f60766563969442020e90eb7847463eca901e41ba186a7d4a5", size = 2375240 }, + { url = "https://files.pythonhosted.org/packages/b3/31/9ca79cafdce364fd5c980cd3416c20ce1bebd235b470d262f9d24d810184/pillow-11.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ae98e14432d458fc3de11a77ccb3ae65ddce70f730e7c76140653048c71bfcbc", size = 3226640 }, + { url = "https://files.pythonhosted.org/packages/ac/0f/ff07ad45a1f172a497aa393b13a9d81a32e1477ef0e869d030e3c1532521/pillow-11.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:cc1331b6d5a6e144aeb5e626f4375f5b7ae9934ba620c0ac6b3e43d5e683a0f0", size = 3101437 }, + { url = "https://files.pythonhosted.org/packages/08/2f/9906fca87a68d29ec4530be1f893149e0cb64a86d1f9f70a7cfcdfe8ae44/pillow-11.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:758e9d4ef15d3560214cddbc97b8ef3ef86ce04d62ddac17ad39ba87e89bd3b1", size = 4326605 }, + { url = "https://files.pythonhosted.org/packages/b0/0f/f3547ee15b145bc5c8b336401b2d4c9d9da67da9dcb572d7c0d4103d2c69/pillow-11.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b523466b1a31d0dcef7c5be1f20b942919b62fd6e9a9be199d035509cbefc0ec", size = 4411173 }, + { url = "https://files.pythonhosted.org/packages/b1/df/bf8176aa5db515c5de584c5e00df9bab0713548fd780c82a86cba2c2fedb/pillow-11.1.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:9044b5e4f7083f209c4e35aa5dd54b1dd5b112b108648f5c902ad586d4f945c5", size = 4369145 }, + { url = "https://files.pythonhosted.org/packages/de/7c/7433122d1cfadc740f577cb55526fdc39129a648ac65ce64db2eb7209277/pillow-11.1.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:3764d53e09cdedd91bee65c2527815d315c6b90d7b8b79759cc48d7bf5d4f114", size = 4496340 }, + { url = "https://files.pythonhosted.org/packages/25/46/dd94b93ca6bd555588835f2504bd90c00d5438fe131cf01cfa0c5131a19d/pillow-11.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:31eba6bbdd27dde97b0174ddf0297d7a9c3a507a8a1480e1e60ef914fe23d352", size = 4296906 }, + { url = "https://files.pythonhosted.org/packages/a8/28/2f9d32014dfc7753e586db9add35b8a41b7a3b46540e965cb6d6bc607bd2/pillow-11.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b5d658fbd9f0d6eea113aea286b21d3cd4d3fd978157cbf2447a6035916506d3", size = 4431759 }, + { url = "https://files.pythonhosted.org/packages/33/48/19c2cbe7403870fbe8b7737d19eb013f46299cdfe4501573367f6396c775/pillow-11.1.0-cp313-cp313-win32.whl", hash = "sha256:f86d3a7a9af5d826744fabf4afd15b9dfef44fe69a98541f666f66fbb8d3fef9", size = 2291657 }, + { url = "https://files.pythonhosted.org/packages/3b/ad/285c556747d34c399f332ba7c1a595ba245796ef3e22eae190f5364bb62b/pillow-11.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:593c5fd6be85da83656b93ffcccc2312d2d149d251e98588b14fbc288fd8909c", size = 2626304 }, + { url = "https://files.pythonhosted.org/packages/e5/7b/ef35a71163bf36db06e9c8729608f78dedf032fc8313d19bd4be5c2588f3/pillow-11.1.0-cp313-cp313-win_arm64.whl", hash = "sha256:11633d58b6ee5733bde153a8dafd25e505ea3d32e261accd388827ee987baf65", size = 2375117 }, + { url = "https://files.pythonhosted.org/packages/79/30/77f54228401e84d6791354888549b45824ab0ffde659bafa67956303a09f/pillow-11.1.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:70ca5ef3b3b1c4a0812b5c63c57c23b63e53bc38e758b37a951e5bc466449861", size = 3230060 }, + { url = "https://files.pythonhosted.org/packages/ce/b1/56723b74b07dd64c1010fee011951ea9c35a43d8020acd03111f14298225/pillow-11.1.0-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:8000376f139d4d38d6851eb149b321a52bb8893a88dae8ee7d95840431977081", size = 3106192 }, + { url = "https://files.pythonhosted.org/packages/e1/cd/7bf7180e08f80a4dcc6b4c3a0aa9e0b0ae57168562726a05dc8aa8fa66b0/pillow-11.1.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ee85f0696a17dd28fbcfceb59f9510aa71934b483d1f5601d1030c3c8304f3c", size = 4446805 }, + { url = "https://files.pythonhosted.org/packages/97/42/87c856ea30c8ed97e8efbe672b58c8304dee0573f8c7cab62ae9e31db6ae/pillow-11.1.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:dd0e081319328928531df7a0e63621caf67652c8464303fd102141b785ef9547", size = 4530623 }, + { url = "https://files.pythonhosted.org/packages/ff/41/026879e90c84a88e33fb00cc6bd915ac2743c67e87a18f80270dfe3c2041/pillow-11.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:e63e4e5081de46517099dc30abe418122f54531a6ae2ebc8680bcd7096860eab", size = 4465191 }, + { url = "https://files.pythonhosted.org/packages/e5/fb/a7960e838bc5df57a2ce23183bfd2290d97c33028b96bde332a9057834d3/pillow-11.1.0-cp313-cp313t-win32.whl", hash = "sha256:dda60aa465b861324e65a78c9f5cf0f4bc713e4309f83bc387be158b077963d9", size = 2295494 }, + { url = "https://files.pythonhosted.org/packages/d7/6c/6ec83ee2f6f0fda8d4cf89045c6be4b0373ebfc363ba8538f8c999f63fcd/pillow-11.1.0-cp313-cp313t-win_amd64.whl", hash = "sha256:ad5db5781c774ab9a9b2c4302bbf0c1014960a0a7be63278d13ae6fdf88126fe", size = 2631595 }, + { url = "https://files.pythonhosted.org/packages/cf/6c/41c21c6c8af92b9fea313aa47c75de49e2f9a467964ee33eb0135d47eb64/pillow-11.1.0-cp313-cp313t-win_arm64.whl", hash = "sha256:67cd427c68926108778a9005f2a04adbd5e67c442ed21d95389fe1d595458756", size = 2377651 }, + { url = "https://files.pythonhosted.org/packages/9a/1f/9df5ac77491fddd2e36c352d16976dc11fbe6ab842f5df85fd7e31b847b9/pillow-11.1.0-cp39-cp39-macosx_10_10_x86_64.whl", hash = "sha256:bf902d7413c82a1bfa08b06a070876132a5ae6b2388e2712aab3a7cbc02205c6", size = 3229995 }, + { url = "https://files.pythonhosted.org/packages/a6/62/c7b359e924dca274173b04922ac06aa63614f7e934d132f2fe1d852509aa/pillow-11.1.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c1eec9d950b6fe688edee07138993e54ee4ae634c51443cfb7c1e7613322718e", size = 3101890 }, + { url = "https://files.pythonhosted.org/packages/7b/63/136f21340a434de895b62bcf2c386005a8aa24066c4facd619f5e0e9f283/pillow-11.1.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e275ee4cb11c262bd108ab2081f750db2a1c0b8c12c1897f27b160c8bd57bbc", size = 4310366 }, + { url = "https://files.pythonhosted.org/packages/f6/46/0bd0ca03d9d1164a7fa33d285ef6d1c438e963d0c8770e4c5b3737ef5abe/pillow-11.1.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4db853948ce4e718f2fc775b75c37ba2efb6aaea41a1a5fc57f0af59eee774b2", size = 4391582 }, + { url = "https://files.pythonhosted.org/packages/0c/55/f182db572b28bd833b8e806f933f782ceb2df64c40e4d8bd3d4226a46eca/pillow-11.1.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:ab8a209b8485d3db694fa97a896d96dd6533d63c22829043fd9de627060beade", size = 4350278 }, + { url = "https://files.pythonhosted.org/packages/75/fb/e330fdbbcbc4744214b5f53b84d9d8a9f4ffbebc2e9c2ac10475386e3296/pillow-11.1.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:54251ef02a2309b5eec99d151ebf5c9904b77976c8abdcbce7891ed22df53884", size = 4471768 }, + { url = "https://files.pythonhosted.org/packages/eb/51/20ee6c4da4448d7a67ffb720a5fcdb965115a78e211a1f58f9845ae15f86/pillow-11.1.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:5bb94705aea800051a743aa4874bb1397d4695fb0583ba5e425ee0328757f196", size = 4276549 }, + { url = "https://files.pythonhosted.org/packages/37/f2/a25c0bdaa6d6fd5cc3d4a6f65b5a7ea46e7af58bee00a98efe0a5af79c58/pillow-11.1.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:89dbdb3e6e9594d512780a5a1c42801879628b38e3efc7038094430844e271d8", size = 4409350 }, + { url = "https://files.pythonhosted.org/packages/12/a7/06687947604cd3e47abeea1b78b65d34ffce7feab03cfe0dd985f115dca3/pillow-11.1.0-cp39-cp39-win32.whl", hash = "sha256:e5449ca63da169a2e6068dd0e2fcc8d91f9558aba89ff6d02121ca8ab11e79e5", size = 2291271 }, + { url = "https://files.pythonhosted.org/packages/21/a6/f51d47675940b5c63b08ff0575b3518428b4acb891f88526fa4ee1edab6f/pillow-11.1.0-cp39-cp39-win_amd64.whl", hash = "sha256:3362c6ca227e65c54bf71a5f88b3d4565ff1bcbc63ae72c34b07bbb1cc59a43f", size = 2625783 }, + { url = "https://files.pythonhosted.org/packages/95/56/97750bd33e68648fa432dfadcb8ede7624bd905822d42262d34bcebdd9d7/pillow-11.1.0-cp39-cp39-win_arm64.whl", hash = "sha256:b20be51b37a75cc54c2c55def3fa2c65bb94ba859dde241cd0a4fd302de5ae0a", size = 2375193 }, + { url = "https://files.pythonhosted.org/packages/fa/c5/389961578fb677b8b3244fcd934f720ed25a148b9a5cc81c91bdf59d8588/pillow-11.1.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:8c730dc3a83e5ac137fbc92dfcfe1511ce3b2b5d7578315b63dbbb76f7f51d90", size = 3198345 }, + { url = "https://files.pythonhosted.org/packages/c4/fa/803c0e50ffee74d4b965229e816af55276eac1d5806712de86f9371858fd/pillow-11.1.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:7d33d2fae0e8b170b6a6c57400e077412240f6f5bb2a342cf1ee512a787942bb", size = 3072938 }, + { url = "https://files.pythonhosted.org/packages/dc/67/2a3a5f8012b5d8c63fe53958ba906c1b1d0482ebed5618057ef4d22f8076/pillow-11.1.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a8d65b38173085f24bc07f8b6c505cbb7418009fa1a1fcb111b1f4961814a442", size = 3400049 }, + { url = "https://files.pythonhosted.org/packages/e5/a0/514f0d317446c98c478d1872497eb92e7cde67003fed74f696441e647446/pillow-11.1.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:015c6e863faa4779251436db398ae75051469f7c903b043a48f078e437656f83", size = 3422431 }, + { url = "https://files.pythonhosted.org/packages/cd/00/20f40a935514037b7d3f87adfc87d2c538430ea625b63b3af8c3f5578e72/pillow-11.1.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:d44ff19eea13ae4acdaaab0179fa68c0c6f2f45d66a4d8ec1eda7d6cecbcc15f", size = 3446208 }, + { url = "https://files.pythonhosted.org/packages/28/3c/7de681727963043e093c72e6c3348411b0185eab3263100d4490234ba2f6/pillow-11.1.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:d3d8da4a631471dfaf94c10c85f5277b1f8e42ac42bade1ac67da4b4a7359b73", size = 3509746 }, + { url = "https://files.pythonhosted.org/packages/41/67/936f9814bdd74b2dfd4822f1f7725ab5d8ff4103919a1664eb4874c58b2f/pillow-11.1.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:4637b88343166249fe8aa94e7c4a62a180c4b3898283bb5d3d2fd5fe10d8e4e0", size = 2626353 }, +] + +[[package]] +name = "platformdirs" +version = "4.3.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/13/fc/128cc9cb8f03208bdbf93d3aa862e16d376844a14f9a0ce5cf4507372de4/platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907", size = 21302 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/a6/bc1012356d8ece4d66dd75c4b9fc6c1f6650ddd5991e421177d9f8f671be/platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb", size = 18439 }, +] + +[[package]] +name = "pluggy" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 }, +] + +[[package]] +name = "pre-commit" +version = "4.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cfgv" }, + { name = "identify" }, + { name = "nodeenv" }, + { name = "pyyaml" }, + { name = "virtualenv" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2a/13/b62d075317d8686071eb843f0bb1f195eb332f48869d3c31a4c6f1e063ac/pre_commit-4.1.0.tar.gz", hash = "sha256:ae3f018575a588e30dfddfab9a05448bfbd6b73d78709617b5a2b853549716d4", size = 193330 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/b3/df14c580d82b9627d173ceea305ba898dca135feb360b6d84019d0803d3b/pre_commit-4.1.0-py2.py3-none-any.whl", hash = "sha256:d29e7cb346295bcc1cc75fc3e92e343495e3ea0196c9ec6ba53f49f10ab6ae7b", size = 220560 }, +] + +[[package]] +name = "prometheus-client" +version = "0.21.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/62/14/7d0f567991f3a9af8d1cd4f619040c93b68f09a02b6d0b6ab1b2d1ded5fe/prometheus_client-0.21.1.tar.gz", hash = "sha256:252505a722ac04b0456be05c05f75f45d760c2911ffc45f2a06bcaed9f3ae3fb", size = 78551 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ff/c2/ab7d37426c179ceb9aeb109a85cda8948bb269b7561a0be870cc656eefe4/prometheus_client-0.21.1-py3-none-any.whl", hash = "sha256:594b45c410d6f4f8888940fe80b5cc2521b305a1fafe1c58609ef715a001f301", size = 54682 }, +] + +[[package]] +name = "prompt-toolkit" +version = "3.0.50" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "wcwidth" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a1/e1/bd15cb8ffdcfeeb2bdc215de3c3cffca11408d829e4b8416dcfe71ba8854/prompt_toolkit-3.0.50.tar.gz", hash = "sha256:544748f3860a2623ca5cd6d2795e7a14f3d0e1c3c9728359013f79877fc89bab", size = 429087 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e4/ea/d836f008d33151c7a1f62caf3d8dd782e4d15f6a43897f64480c2b8de2ad/prompt_toolkit-3.0.50-py3-none-any.whl", hash = "sha256:9b6427eb19e479d98acff65196a307c555eb567989e6d88ebbb1b509d9779198", size = 387816 }, +] + +[[package]] +name = "psutil" +version = "6.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1f/5a/07871137bb752428aa4b659f910b399ba6f291156bdea939be3e96cae7cb/psutil-6.1.1.tar.gz", hash = "sha256:cf8496728c18f2d0b45198f06895be52f36611711746b7f30c464b422b50e2f5", size = 508502 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/61/99/ca79d302be46f7bdd8321089762dd4476ee725fce16fc2b2e1dbba8cac17/psutil-6.1.1-cp36-abi3-macosx_10_9_x86_64.whl", hash = "sha256:fc0ed7fe2231a444fc219b9c42d0376e0a9a1a72f16c5cfa0f68d19f1a0663e8", size = 247511 }, + { url = "https://files.pythonhosted.org/packages/0b/6b/73dbde0dd38f3782905d4587049b9be64d76671042fdcaf60e2430c6796d/psutil-6.1.1-cp36-abi3-macosx_11_0_arm64.whl", hash = "sha256:0bdd4eab935276290ad3cb718e9809412895ca6b5b334f5a9111ee6d9aff9377", size = 248985 }, + { url = "https://files.pythonhosted.org/packages/17/38/c319d31a1d3f88c5b79c68b3116c129e5133f1822157dd6da34043e32ed6/psutil-6.1.1-cp36-abi3-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b6e06c20c05fe95a3d7302d74e7097756d4ba1247975ad6905441ae1b5b66003", size = 284488 }, + { url = "https://files.pythonhosted.org/packages/9c/39/0f88a830a1c8a3aba27fededc642da37613c57cbff143412e3536f89784f/psutil-6.1.1-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97f7cb9921fbec4904f522d972f0c0e1f4fabbdd4e0287813b21215074a0f160", size = 287477 }, + { url = "https://files.pythonhosted.org/packages/47/da/99f4345d4ddf2845cb5b5bd0d93d554e84542d116934fde07a0c50bd4e9f/psutil-6.1.1-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:33431e84fee02bc84ea36d9e2c4a6d395d479c9dd9bba2376c1f6ee8f3a4e0b3", size = 289017 }, + { url = "https://files.pythonhosted.org/packages/38/53/bd755c2896f4461fd4f36fa6a6dcb66a88a9e4b9fd4e5b66a77cf9d4a584/psutil-6.1.1-cp37-abi3-win32.whl", hash = "sha256:eaa912e0b11848c4d9279a93d7e2783df352b082f40111e078388701fd479e53", size = 250602 }, + { url = "https://files.pythonhosted.org/packages/7b/d7/7831438e6c3ebbfa6e01a927127a6cb42ad3ab844247f3c5b96bea25d73d/psutil-6.1.1-cp37-abi3-win_amd64.whl", hash = "sha256:f35cfccb065fff93529d2afb4a2e89e363fe63ca1e4a5da22b603a85833c2649", size = 254444 }, +] + +[[package]] +name = "ptyprocess" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/20/e5/16ff212c1e452235a90aeb09066144d0c5a6a8c0834397e03f5224495c4e/ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220", size = 70762 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", size = 13993 }, +] + +[[package]] +name = "pure-eval" +version = "0.2.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cd/05/0a34433a064256a578f1783a10da6df098ceaa4a57bbeaa96a6c0352786b/pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42", size = 19752 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0", size = 11842 }, +] + +[[package]] +name = "py" +version = "1.11.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/98/ff/fec109ceb715d2a6b4c4a85a61af3b40c723a961e8828319fbcb15b868dc/py-1.11.0.tar.gz", hash = "sha256:51c75c4126074b472f746a24399ad32f6053d1b34b68d2fa41e558e6f4a98719", size = 207796 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f6/f0/10642828a8dfb741e5f3fbaac830550a518a775c7fff6f04a007259b0548/py-1.11.0-py2.py3-none-any.whl", hash = "sha256:607c53218732647dff4acdfcd50cb62615cedf612e72d1724fb1a0cc6405b378", size = 98708 }, +] + +[[package]] +name = "pycairo" +version = "1.27.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/07/4a/42b26390181a7517718600fa7d98b951da20be982a50cd4afb3d46c2e603/pycairo-1.27.0.tar.gz", hash = "sha256:5cb21e7a00a2afcafea7f14390235be33497a2cce53a98a19389492a60628430", size = 661450 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a9/00/bfc1a76728a5e7be0fc3c666babf4e9d916834080551d2b1ba4a32732592/pycairo-1.27.0-cp310-cp310-win32.whl", hash = "sha256:e20f431244634cf244ab6b4c3a2e540e65746eed1324573cf291981c3e65fc05", size = 749759 }, + { url = "https://files.pythonhosted.org/packages/fc/ca/6fa943f96fcee3655bdbf571e788927487f18fb6fef4787040473151b153/pycairo-1.27.0-cp310-cp310-win_amd64.whl", hash = "sha256:03bf570e3919901572987bc69237b648fe0de242439980be3e606b396e3318c9", size = 844071 }, + { url = "https://files.pythonhosted.org/packages/3b/4b/d7887904e10673ff8d99aaa2e63f82b245441261ea29136254576ac1c730/pycairo-1.27.0-cp311-cp311-win32.whl", hash = "sha256:9a9b79f92a434dae65c34c830bb9abdbd92654195e73d52663cbe45af1ad14b2", size = 749772 }, + { url = "https://files.pythonhosted.org/packages/90/d2/ae7c781ceaac315e7c80381f83dc779a591bde6892e3498c7b5f42ec6cb8/pycairo-1.27.0-cp311-cp311-win_amd64.whl", hash = "sha256:d40a6d80b15dacb3672dc454df4bc4ab3988c6b3f36353b24a255dc59a1c8aea", size = 844101 }, + { url = "https://files.pythonhosted.org/packages/1c/65/7664fe3d9928572b7804c651a99cfd6113338eee7436d5b25401c9382619/pycairo-1.27.0-cp312-cp312-win32.whl", hash = "sha256:e2239b9bb6c05edae5f3be97128e85147a155465e644f4d98ea0ceac7afc04ee", size = 750005 }, + { url = "https://files.pythonhosted.org/packages/f4/bd/114597b9f79fbdb4eb0a4bf4aa54e70246d87f512a880e66a85c1e2ff407/pycairo-1.27.0-cp312-cp312-win_amd64.whl", hash = "sha256:27cb4d3a80e3b9990af552818515a8e466e0317063a6e61585533f1a86f1b7d5", size = 844100 }, + { url = "https://files.pythonhosted.org/packages/93/76/35d2feef50584cb00d2b4d2215337b0bc765508f8856735a41bfedcb4699/pycairo-1.27.0-cp313-cp313-win32.whl", hash = "sha256:01505c138a313df2469f812405963532fc2511fb9bca9bdc8e0ab94c55d1ced8", size = 750001 }, + { url = "https://files.pythonhosted.org/packages/9c/e7/92d6e57deee53229bb8b3f7df6d02c503585be7bdd69cb9e54f34aab089b/pycairo-1.27.0-cp313-cp313-win_amd64.whl", hash = "sha256:b0349d744c068b6644ae23da6ada111c8a8a7e323b56cbce3707cba5bdb474cc", size = 844102 }, + { url = "https://files.pythonhosted.org/packages/4a/b0/304a04ee7b6d2aef031c70e8f732151b4cbef3c3b6e2881283b2d68de17a/pycairo-1.27.0-cp39-cp39-win32.whl", hash = "sha256:f9ca8430751f1fdcd3f072377560c9e15608b9a42d61375469db853566993c9b", size = 750003 }, + { url = "https://files.pythonhosted.org/packages/36/b1/d0cd9de2faf57d3ec6299ab0f80fd06e7bd94869356773d87045ef25ddcb/pycairo-1.27.0-cp39-cp39-win_amd64.whl", hash = "sha256:1b1321652a6e27c4de3069709b1cae22aed2707fd8c5e889c04a95669228af2a", size = 844526 }, +] + +[[package]] +name = "pycparser" +version = "2.22" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552 }, +] + +[[package]] +name = "pydub" +version = "0.25.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fe/9a/e6bca0eed82db26562c73b5076539a4a08d3cffd19c3cc5913a3e61145fd/pydub-0.25.1.tar.gz", hash = "sha256:980a33ce9949cab2a569606b65674d748ecbca4f0796887fd6f46173a7b0d30f", size = 38326 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a6/53/d78dc063216e62fc55f6b2eebb447f6a4b0a59f55c8406376f76bf959b08/pydub-0.25.1-py2.py3-none-any.whl", hash = "sha256:65617e33033874b59d87db603aa1ed450633288aefead953b30bded59cb599a6", size = 32327 }, +] + +[[package]] +name = "pygithub" +version = "2.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "deprecated" }, + { name = "pyjwt", extra = ["crypto"] }, + { name = "pynacl" }, + { name = "requests" }, + { name = "typing-extensions" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/16/ce/aa91d30040d9552c274e7ea8bd10a977600d508d579a4bb262b95eccf961/pygithub-2.5.0.tar.gz", hash = "sha256:e1613ac508a9be710920d26eb18b1905ebd9926aa49398e88151c1b526aad3cf", size = 3552804 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/37/05/bfbdbbc5d8aafd8dae9b3b6877edca561fccd8528ef5edc4e7b6d23721b5/PyGithub-2.5.0-py3-none-any.whl", hash = "sha256:b0b635999a658ab8e08720bdd3318893ff20e2275f6446fcf35bf3f44f2c0fd2", size = 375935 }, +] + +[[package]] +name = "pyglet" +version = "2.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ea/4b/44b4dc01ffac9f8950d540c99159f83e2c398df2a600394feb6d2dbf7340/pyglet-2.1.2.tar.gz", hash = "sha256:6fc1fed55eb6dc80c87a7a45ac62c2a61be08cd31114b27abef8619959be7845", size = 6515611 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/aa/edc16d04f6de8e833b4cba3068185fd2aad9e6f3a22fbc89afec36414f12/pyglet-2.1.2-py3-none-any.whl", hash = "sha256:2819fa9d66ead4b1682d1b7fa7170692d46277e1a6661b329bdba3e65288c036", size = 961981 }, +] + +[[package]] +name = "pyglm" +version = "2.7.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fe/a1/123daa472f20022785b18d6cdf6c71e30272aae03584a8ab861fa5fa01a5/pyglm-2.7.3.tar.gz", hash = "sha256:4ccb6c027622b948aebc501cd8c3c23690293115dc98108f8ed3b7fd533b398f", size = 483055 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fc/12/4f2d76d5865ef2fd41a86c06d85d9fc9f5c53f84b681363df70fe18e1828/PyGLM-2.7.3-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:36ce22f992af9da9a780f6232d184c9e2269be7e5e13f2fd35bb781536c31b9c", size = 1594703 }, + { url = "https://files.pythonhosted.org/packages/81/9d/b23408826f86c2c8204676effb744f998daf0a9141a56a80f4b289e6f609/PyGLM-2.7.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c52d06037ea1b0b24274e8a4ade49c9d82902e317e10e3233db7e67ddd2ded1d", size = 1312976 }, + { url = "https://files.pythonhosted.org/packages/91/51/8542ee787afe4939e74aa634ada05e650896688fdaf4d7d0869f4dfc4711/PyGLM-2.7.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f642ba2f52a8256c4d555486e9eab33d9417145cc2b68be237f4f10cbde08ade", size = 10804971 }, + { url = "https://files.pythonhosted.org/packages/73/60/62b7305670658058db4b166a780bf8062ecab57501f8b52e3197abb92fbb/PyGLM-2.7.3-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3e5d38c5c39961e7cc704e4ea0c6cc4eb86e9879420fa13a51158a95e1ebfcec", size = 10217683 }, + { url = "https://files.pythonhosted.org/packages/b3/af/52539e9fd3c16c7aa095a8ddd7a5542a69e6f5eef63f217b51074e54763f/PyGLM-2.7.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:da1d6526e718940994721fce85caeb7d3ab01e395d5652a0beb89b38add554eb", size = 11275150 }, + { url = "https://files.pythonhosted.org/packages/ca/df/c4fb4c4247ba37fe9b24b189c76dd1c0ad7d51e238cf86be8beca54f1f06/PyGLM-2.7.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cd51aa7207f4c2ce4d16c221bf6d50f3c1043aea44dd28ee3a94eddba43ccaa7", size = 11356698 }, + { url = "https://files.pythonhosted.org/packages/c5/bd/3bd9b00f7fd54efb50b538a692ec5253fb10861c388d5345a24dd1a8fb53/PyGLM-2.7.3-cp310-cp310-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7ab0e13efbf076c8eb35f2f8d52a549fe3251a650e21e6e00f4adddd3e71c6e5", size = 10506554 }, + { url = "https://files.pythonhosted.org/packages/49/35/1f8097be67f9295147191a06437401636c83ca07a02de8ff113a6da6f1f6/PyGLM-2.7.3-cp310-cp310-manylinux_2_27_s390x.manylinux_2_28_s390x.whl", hash = "sha256:72a2fa3b37ad52d36ff4dfd6bc5476ed4ee8cd167543c283b583ea8618b283a7", size = 10988175 }, + { url = "https://files.pythonhosted.org/packages/f6/0d/059e6d1c9835899a00dab42aa59d007f4297b62d513f4105b4b3ffad2cbb/PyGLM-2.7.3-cp310-cp310-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:011d4d67240362b7e22af2ce57b216be8e3caa19dfd546e31d41b9a38612989f", size = 10986722 }, + { url = "https://files.pythonhosted.org/packages/0a/68/7aedd919ba820db0076628b6bcae9d9c2e60e7371ec73316dbf9ad8a30bc/PyGLM-2.7.3-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:629ee77eaffc340a4bac722cd2621b076d8eb83809b74a27e13be7624d78df2b", size = 11926971 }, + { url = "https://files.pythonhosted.org/packages/51/f6/6d46eb631ff565ee6b71f23faed95947d7f87bec516fed4bd9f3d43910cf/PyGLM-2.7.3-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:119fc3be9db079c98e48978677b917616d3b9e058b791ec258c5b57eea4d11bb", size = 11137194 }, + { url = "https://files.pythonhosted.org/packages/d7/f4/7399f841697b280e729092e761b6e9f87bde7ff246465e4bbf919bd8b74b/PyGLM-2.7.3-cp310-cp310-musllinux_1_1_s390x.whl", hash = "sha256:75dc188457f99cdd4e621d3b932b0e844688135c5b0aefb42c46efcfce7b7270", size = 12518098 }, + { url = "https://files.pythonhosted.org/packages/36/59/fb221c984c69b8ae2457d0299d716dbf043be030d1064ff37cd382f3ebfb/PyGLM-2.7.3-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:26a0abd806408eebcada608d3eaebfec73f7b2500ea645ff2fd7d9db470ba565", size = 12492448 }, + { url = "https://files.pythonhosted.org/packages/8c/c5/a606c515783bac676c1e2a16a3daedea084a5f5b829e3b754f8be885b28c/PyGLM-2.7.3-cp310-cp310-win32.whl", hash = "sha256:37e2501434465c945f0d87626d6c2157bd2aef3e3bf65c37ab953d914428c488", size = 1238322 }, + { url = "https://files.pythonhosted.org/packages/c5/51/97163a307573a32f1895a35cf011cf22fb923c6c506c47454aebafab943d/PyGLM-2.7.3-cp310-cp310-win_amd64.whl", hash = "sha256:27731736bd37cada8a7e975030d5bcfbd0f448162a607a2c53d088512a106f82", size = 1574242 }, + { url = "https://files.pythonhosted.org/packages/d2/5c/a1302a1fe3342d442574403eb767dd58aa0c7c32892c192d8f42bc33f88e/PyGLM-2.7.3-cp310-cp310-win_arm64.whl", hash = "sha256:bc60ad3da261d2866826dcd9e7ee55bb0dc5e1160d8226b2b7f1e431ae7c6200", size = 1127905 }, + { url = "https://files.pythonhosted.org/packages/31/4f/601a3fab33fd169f27d0a2890468854fa425dc00c71f0fbdfcede13a350e/PyGLM-2.7.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2ad68211a45b02f8d5d47f067153aa1084c6ab4026b8f84eb6e8b5165a7394ad", size = 1594785 }, + { url = "https://files.pythonhosted.org/packages/23/78/58e0a21f214ac1383c23af8b01da54b750c474d6489c4b519c36bd2620f9/PyGLM-2.7.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93b65bab6525e3098ff99c933cccc635716acf45a8c4bdf27ad432f183a33923", size = 1312861 }, + { url = "https://files.pythonhosted.org/packages/7d/40/699c7f49d2233a7b77e3b6f1e29689f85d0df2a532980599c38b55184589/PyGLM-2.7.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2422a8119a85500546fc3b95d0a035bb768b0002376070e4ef91015b8bf4e01", size = 11358375 }, + { url = "https://files.pythonhosted.org/packages/71/e5/4b352e838e9aa17ca21cbc34f614c60e48504384fd0a4ac783bccd27cdce/PyGLM-2.7.3-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e9504dac2ca742b0b5199ad3ab0ffcf56759c8c1a9ca0f9252258784163ef3b", size = 10756411 }, + { url = "https://files.pythonhosted.org/packages/84/d3/efa05c0d127762cd0c28eaef7cd3c1f1e578af3143862920a8d916caf978/PyGLM-2.7.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c75eb893c0f2c08b75f8b0aa5f2fd382cca65e9bd907e858e10fd2341110e2de", size = 11865911 }, + { url = "https://files.pythonhosted.org/packages/f7/d1/558cf41caae368ec049ef87f5051a442e8da0224b248ea5ffd490aa927e7/PyGLM-2.7.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4df26b2e793b90a12e8cd9ddd81e715889e7760b202f6307d221144022bd3a68", size = 11888452 }, + { url = "https://files.pythonhosted.org/packages/4b/95/c44e8fb1260447a9895fbcc090f8fb6c39a29609bf26ae2bf6938c6f6995/PyGLM-2.7.3-cp311-cp311-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c803fa9624be0498d37ee035c496e0b5ce3f720cbb6c6a33b14a5c318f01bbc5", size = 10923140 }, + { url = "https://files.pythonhosted.org/packages/aa/0b/5309d7bc160d3a839baa4ce43a039fb55e995fb82f495576b21a8096f648/PyGLM-2.7.3-cp311-cp311-manylinux_2_27_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7bef6e2db2242613ce594d8dbe88eefd74da94fb141f8943abbdbcea2d905249", size = 11433783 }, + { url = "https://files.pythonhosted.org/packages/97/80/c71a5c4527b95fc56edf68467cf9e73dd350ed1f12eb3aa544b3e0e29050/PyGLM-2.7.3-cp311-cp311-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a7d925dbadaf642a2aa9674081ce2df6193c45519f38bc09a6f9f9861a202e60", size = 11386478 }, + { url = "https://files.pythonhosted.org/packages/8e/d7/992d64305fcc0ab05750f053fed43093ce6e7ed1ad8ef3274a913a831a93/PyGLM-2.7.3-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff169abe8923c7f9eaca21b744fca58ce29e611cd1b09025d7e65aaa8f4149a5", size = 12323849 }, + { url = "https://files.pythonhosted.org/packages/d8/55/4f14328b193e14de2eb0fe800872e4f42ef821729ac2b300d8d40c2c9ae0/PyGLM-2.7.3-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:02338dfec947cd661e9969d316ba6e7500afcb86f0a0722dd4f5709a8557e570", size = 11479101 }, + { url = "https://files.pythonhosted.org/packages/90/cd/d0a3ba7f8ccc35364814206e1aa66ce1b2254fa59034ecf1ec6978a957ac/PyGLM-2.7.3-cp311-cp311-musllinux_1_1_s390x.whl", hash = "sha256:f4d902a22f3643da2d375140c9ebe69c9a6ef33aca518f64671540ae7fb37149", size = 12910056 }, + { url = "https://files.pythonhosted.org/packages/ea/c5/d6cf4f614a39644dd54e734840ebab4386c84c5f04b753c08aa074ad5be3/PyGLM-2.7.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:ea99eb075c47bb1f0c7e405b0d7dda966d5c880246e93191a73aed22d3aa04e8", size = 12839756 }, + { url = "https://files.pythonhosted.org/packages/0e/a2/9227cba820aa3f0820179638b910413ca7e707677e6e4d7ef438b2898e54/PyGLM-2.7.3-cp311-cp311-win32.whl", hash = "sha256:823ed2564064c863d03753e40fdd840703726b072a53f61c0a0441643e1ec56c", size = 1254781 }, + { url = "https://files.pythonhosted.org/packages/57/f8/096a5d7dc690a731875060f1c56bb2a01cd52d8996b5836f94f1005c1b81/PyGLM-2.7.3-cp311-cp311-win_amd64.whl", hash = "sha256:e6472feddcce4138caf19dd25a948530460823bdaa7c8d87caa3bc8a1bb1089a", size = 1590373 }, + { url = "https://files.pythonhosted.org/packages/09/8e/493bbfedbd72269b31e743f5039fd2171c89e47b18bd5fc83fcd9bd6d6fa/PyGLM-2.7.3-cp311-cp311-win_arm64.whl", hash = "sha256:313a05afc0d151e56d5536db7da695e7bba5943a3f96b71ef213f4bc59715c93", size = 1142317 }, + { url = "https://files.pythonhosted.org/packages/08/31/8fb5f31eee897daf8b579410c52c275c72be80245cd6ac83a0d86b1ac1c9/PyGLM-2.7.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5bfebc0caaa0a0096957d984416081a503b1cbd2ba79a0cd0add64e741144247", size = 1586946 }, + { url = "https://files.pythonhosted.org/packages/dd/e3/c8486e4f82b6f88381e405f3fdae36dfd822c726b42da8251bca87fcdb61/PyGLM-2.7.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:265827ca2eecc7f50d1a37c412b6ed8118ec909f4a5198b2c0a7a914bc33c4a0", size = 1319015 }, + { url = "https://files.pythonhosted.org/packages/b1/55/bc257f2ad7d499ed0c267e744d8c2e838600dff98efb9d43a7cc8752a93a/PyGLM-2.7.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:243890559980131351281007e308e2db0dc52f5dedf1ce0f21383d32cbd3f367", size = 11441393 }, + { url = "https://files.pythonhosted.org/packages/73/8c/2055c41930860d0b2294059fd0d820e6b376e8cecd1459b0a5f7f9632ca6/PyGLM-2.7.3-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78bb3f32fc92bf0f86527e8143ea861365fdecc05725932eef424346a1948b5b", size = 10820017 }, + { url = "https://files.pythonhosted.org/packages/0f/eb/efac9990e7f95838ce00fedebc1a9713a273fa0f9580eb816ef7d291d489/PyGLM-2.7.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b9b193cf4d16b2f43d3458aeaaa29d6cad4f5f2518a3562f3c9b6e361d2d2623", size = 11971119 }, + { url = "https://files.pythonhosted.org/packages/5a/c9/39bb3a16e4402dd6f24a0a923d3a581cde086d7ea4d5cccb9672bf370e03/PyGLM-2.7.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15a26ac12fb7728b71a45ca9535e6c96cff5a9a1e5beae306ece37073513d519", size = 11968086 }, + { url = "https://files.pythonhosted.org/packages/47/bc/0e7c58847c2ab8f4fa62c6b7c4995c94c9ef50e7803b5aa65cfd9861fcd5/PyGLM-2.7.3-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bec15034f7c21b2c3c1b70d878f0590aad6a445a0e1290172cc90dccc7a71afb", size = 11009953 }, + { url = "https://files.pythonhosted.org/packages/45/e5/7d1fd80c1554cae210aed2df37524b4c2ad76b67fb069d5012d585a41196/PyGLM-2.7.3-cp312-cp312-manylinux_2_27_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a8253002a1732622bbd8c605baf7ac03b9e1629cfe1136261e651b82204e31d7", size = 11537659 }, + { url = "https://files.pythonhosted.org/packages/59/eb/093167bfdd143f2920869f1ff1ee85f3d1c7f51ebe8d9cd8cf587de9bf84/PyGLM-2.7.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5846787ae297623fe2a09e2a94814f1ca71a80ab929edc5bae93fcbefab7b559", size = 11463684 }, + { url = "https://files.pythonhosted.org/packages/c5/0c/6dea0ceecdee3e7b9479bc44da6a3927f80921280d2e0d0994d6d3b70a19/PyGLM-2.7.3-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:598404cdfc3fe5bbd6429a1c7879bc6516057827c9e6c2879b22167948854ec6", size = 12404908 }, + { url = "https://files.pythonhosted.org/packages/af/a7/1fa292957b290e4cf2cc62d42edb76545d4773034e4e5a2fb1cfe84c350d/PyGLM-2.7.3-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:a71de9de8bf2c585777fdfdde877082722582651a65cb6ab1e6be48299cbdd56", size = 11655722 }, + { url = "https://files.pythonhosted.org/packages/93/87/e01a1f6c3ef40cb5266199a896b756d3d7bc0bd34a24613da213a572772a/PyGLM-2.7.3-cp312-cp312-musllinux_1_1_s390x.whl", hash = "sha256:a49f073a52ca26bf7672aa0685a75f0cb41201e84094ef8aa08c7d9432436bf5", size = 13180552 }, + { url = "https://files.pythonhosted.org/packages/e0/8d/ef84ef6eda2c25a8429233637d54db543721fb7a255b6f885c649dec992b/PyGLM-2.7.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:e37cf83588ff9bc0e8019612c667c4b45a2b1cb195e3890a4609056fa2eda8b4", size = 12959912 }, + { url = "https://files.pythonhosted.org/packages/e8/c3/5259f4c683d4fdfe552229c572750802d4cc630a2283d0320e66785d3cb4/PyGLM-2.7.3-cp312-cp312-win32.whl", hash = "sha256:8b2cf3857dfe598e8f7210aba3990b6b3bc73cb7ee43d422ef8920b1e28aba52", size = 1255103 }, + { url = "https://files.pythonhosted.org/packages/f3/25/2bb4ae6ef04bbd4b4129b63497757e5c72f94805b6f09dc8cc085816ebf9/PyGLM-2.7.3-cp312-cp312-win_amd64.whl", hash = "sha256:4018fbdf125b95d6295e2e3e9f6b1306a204df751d70736f78144cdde07cd721", size = 1592827 }, + { url = "https://files.pythonhosted.org/packages/9b/b0/c145525c037b3f9e88803dd45f33aaa718b00d598c0a57db6b9f7763c4b8/PyGLM-2.7.3-cp312-cp312-win_arm64.whl", hash = "sha256:5465b95bc92d0807a5289559bede5e18f084a6940a8d607f4fbe2457ba21989e", size = 1142855 }, + { url = "https://files.pythonhosted.org/packages/ea/0a/12ea6f3ef6c0ccec95126d639e02cbe74954e54447b3fad27c808db90004/PyGLM-2.7.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:d38d3e15098458f7c13db98c3bed936aa6313f7d20eb83968ee2b4c36a7722d6", size = 1586959 }, + { url = "https://files.pythonhosted.org/packages/92/48/2cb33a89245ea0235578905d89dbe633decb1005a4364068ca82b797be83/PyGLM-2.7.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8fe12b0b048e9c5d35647f05ee7fa6c0aebedbc1cb6d4b4f75df5d7b9c16ab3", size = 1319020 }, + { url = "https://files.pythonhosted.org/packages/8f/3b/3bed2074836bfd311362f6c2b5809297e1848aa8c33ad7ed878aaaa265ee/PyGLM-2.7.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1928999a93ce156665f72b3c799c66a539f114025f4bcae894d46f09ff0ec39c", size = 11443463 }, + { url = "https://files.pythonhosted.org/packages/57/39/4e22b584ae28a99a36057883492eb63f453cf4fa07b7f65d04a4ebd77385/PyGLM-2.7.3-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7b846eec69f21faf17310562bf7aa3163b2e6dad391c2ddc22e76d3dded8b2e5", size = 10820269 }, + { url = "https://files.pythonhosted.org/packages/c2/48/4ec974cadb1781a45ff3e281f32062057db51aecf43f82c88e8eb10d9809/PyGLM-2.7.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5af9ca9802d588910d8f72706690dcd276a82256a828a17f1a4bf898f84da82b", size = 11971271 }, + { url = "https://files.pythonhosted.org/packages/18/ff/28d76e80f8b609465ac91170edb913a9c8351db1fbf5432b429eb43198da/PyGLM-2.7.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d9d1d471cffee49dc2256f1c9f43600224e10a88a128dfd398b2af2e2104277c", size = 11968742 }, + { url = "https://files.pythonhosted.org/packages/76/8a/4708401d2c9bfae750c3017ffe9d1bd024bc3ebfadcb72783c85205a5a16/PyGLM-2.7.3-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a415d83a20021a2544276cc122fbea4540493f7a30f9e08da7d185d04e9ca71d", size = 11011544 }, + { url = "https://files.pythonhosted.org/packages/eb/32/237e544cb5d7800064c1affbad551f281de0de5302e11f9216ee0e1781bd/PyGLM-2.7.3-cp313-cp313-manylinux_2_27_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fe0451bc8973260fa9e029773a57d4095c5e08a9f88a979f9699dfe196a956d7", size = 11538130 }, + { url = "https://files.pythonhosted.org/packages/1f/8b/58b6917eab49167c9b7e955067c17b8f12d8974a13a158d06a2a8dc23290/PyGLM-2.7.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f8143b81200d9c9d26442a7ba1614d64aeb319363057bec12d9330591c4f8cf5", size = 11465061 }, + { url = "https://files.pythonhosted.org/packages/58/51/609b1788dace10b720074548c09c2a41f1e4a33ceab7651ad5b108919044/PyGLM-2.7.3-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:5c3425a3118924e0d148b9ee6dcf6f001fc55326e9f2bbed8360c5d71575e28e", size = 12406002 }, + { url = "https://files.pythonhosted.org/packages/ec/51/e5e20232bb1a667fdc5590a9841df79a2756cb4dffd3d7fb254885587bfd/PyGLM-2.7.3-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:5dfb81078d4f9bc5c86be7939f1ab6265192ed16d18ab06fd062c6fcbe649195", size = 11655425 }, + { url = "https://files.pythonhosted.org/packages/b1/c6/29053e449bff3c7417928fbc21b67569c00109ceb3a105fb5c1c8666431e/PyGLM-2.7.3-cp313-cp313-musllinux_1_1_s390x.whl", hash = "sha256:a27c0e0594592f44a3eeebc628974f27095751398184050e333d07884c0f0176", size = 13180433 }, + { url = "https://files.pythonhosted.org/packages/31/f7/92e89e3eb761788a823e0fa863b93ab2ae3c927b27c2eea8c90c607d06c0/PyGLM-2.7.3-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:8e9f88e62962685f1b0ac4aed8d77aabdf5fa95c6bc4894ea15ac9dc79842ad3", size = 12960300 }, + { url = "https://files.pythonhosted.org/packages/b0/1c/8944d4bd6a8e30d253893a15a4aa71e46da46a870d9c971431a75f12d728/PyGLM-2.7.3-cp313-cp313-win32.whl", hash = "sha256:c9048d98d622e8a95601482bd892a76c8da152bcfcef5d16d279c5bb507a09a7", size = 1255109 }, + { url = "https://files.pythonhosted.org/packages/96/e4/701cf1d5f724b2f9681aa5f6eb8924afd808ca359a29d9795c87b6c22162/PyGLM-2.7.3-cp313-cp313-win_amd64.whl", hash = "sha256:68167968ee91ab176bf9a6e6afaadf4c0c65417c29fecc9f32c6da698ad028db", size = 1592861 }, + { url = "https://files.pythonhosted.org/packages/03/ec/23be89423aa474d521791c3ae7c52e1dcaff9887406fb953f053585e11eb/PyGLM-2.7.3-cp313-cp313-win_arm64.whl", hash = "sha256:24622c249eb315588c042df3b960d3bd90ab6e01caf52009b546b526575d5e91", size = 1142911 }, + { url = "https://files.pythonhosted.org/packages/16/70/be4a9f6ab40c04ab05df794646f7b74d903dc0a4cce00a7316bc6051541b/PyGLM-2.7.3-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:23fdbe27e16b03206d8635dbb842fae6a470a7342af7c2395509c20607fe0251", size = 1592823 }, + { url = "https://files.pythonhosted.org/packages/48/a0/b63e3571e3cce58287a3c4c437d1c04645706062f0075a8e427f7b1362f4/PyGLM-2.7.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:6467e217ebb6fc9356ae77c2e6c807d9e4470b5db59006dd553eee5888815538", size = 1311765 }, + { url = "https://files.pythonhosted.org/packages/79/12/f218f42410a8c511ad77cd3114e11977fb5af5d58ef7cf55355e4edcd44e/PyGLM-2.7.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fcc4d575e20118c938bc451bbf7d69e50440e298e1be4359d2a1a4c8568866fa", size = 10431908 }, + { url = "https://files.pythonhosted.org/packages/9b/29/1581ee3bc6d29c0164f331f0d683009b6319d32adf134733ca08ef0b2425/PyGLM-2.7.3-cp39-cp39-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:11250311e3b0813f924147333c28658aa00c93a4ecc173ccbe95c145e4ade14c", size = 9881555 }, + { url = "https://files.pythonhosted.org/packages/ec/a6/4f5e415e7cde34d0721c3d06522ec8c84a0b37b364c14424b9d0f59ca17d/PyGLM-2.7.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:45e66c96d0b11587b4e21ed72bb0dd2a27bb4d12f75f26dc9e08f6d019c6b5ba", size = 10908813 }, + { url = "https://files.pythonhosted.org/packages/8f/91/ef745ba80a7f492e12698aa78d69c24b034dc0cc6295997a1cbb68f44c80/PyGLM-2.7.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0906751e15c003428c2099a8230f9b7173ef1e0c89abd92d278e28600f0a0277", size = 10985969 }, + { url = "https://files.pythonhosted.org/packages/de/56/9b966a93eaa5f889a738de0f95ac90a55afd9750cd363960ed461f661ab2/PyGLM-2.7.3-cp39-cp39-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7c663673842b0aa0747aa1b26b584dfdffc3eb3a7611563eb546be44bbb9c98c", size = 10119855 }, + { url = "https://files.pythonhosted.org/packages/d2/71/649dafb573b08caf10b74bd50dcc9c7f3bc755848cc490af035e38379bc1/PyGLM-2.7.3-cp39-cp39-manylinux_2_27_s390x.manylinux_2_28_s390x.whl", hash = "sha256:9f37b1f19114cbe64fb11ab8c559fe6cc7af143b8f1e77bb812dd74212cb4e6b", size = 10612737 }, + { url = "https://files.pythonhosted.org/packages/17/68/2d027d49a2dd965ae15052aab9463a69e589dc9fc6fa99a4d6c8c8cda50b/PyGLM-2.7.3-cp39-cp39-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b2a4a21ec5c79e0f5e8fa460520f9e1ac453f6d0804ca6acd679067aec3b06fc", size = 10588558 }, + { url = "https://files.pythonhosted.org/packages/d5/4e/9b6dabb71665ca18835956a1ad2acb73ec0178750c786e04c34cfe5da7bc/PyGLM-2.7.3-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:3408cda39d1181ccf37a3171298df4acd1930b7335b20835ae8ad405ae902100", size = 11515438 }, + { url = "https://files.pythonhosted.org/packages/16/95/9d5766080ecb438e52a20f4208ed21f2705218e6714ed0a0bc98f721d71b/PyGLM-2.7.3-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:8f6c24c2072f6898b6a2f64ffec16a08243451bee9e969344659f2323efcd4af", size = 10753617 }, + { url = "https://files.pythonhosted.org/packages/a6/ab/ee1860f6a43b8f66825be3fc9162791d50c0b1e6e83e15399e1961759f87/PyGLM-2.7.3-cp39-cp39-musllinux_1_1_s390x.whl", hash = "sha256:472d92fbbeac5647a91adfb5d1b71a8368ced8b6cd92654822290a34de87a2ef", size = 12097968 }, + { url = "https://files.pythonhosted.org/packages/3e/13/3c600a3533da83168438d344af31f186f52d31022c69456fb93512f4f99a/PyGLM-2.7.3-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:29dd15a559df75acdab74b941ace809f81f20d655d6d616c09b85d2ffc66b5cd", size = 12057911 }, + { url = "https://files.pythonhosted.org/packages/1b/31/220b1102f374acccfdb6800c5393ad1238fcfc43d657e3855881701f2eb5/PyGLM-2.7.3-cp39-cp39-win32.whl", hash = "sha256:868b455946ca659d7d2344afffdcf3f4b6b57270b43b7428848661976dba8803", size = 1249064 }, + { url = "https://files.pythonhosted.org/packages/cf/78/f6c8723c525f30eed41a4b5585f76c9a1f6c29d435f39e0fb166a921fc8d/PyGLM-2.7.3-cp39-cp39-win_amd64.whl", hash = "sha256:1689cbc0aec27107b933b9afbece524469257da6ef2ab78891cb77902e47259b", size = 1580716 }, + { url = "https://files.pythonhosted.org/packages/83/9a/ea3cc49009505cddf7a16f6f42827428eac37e7f976a29f1455939d46916/PyGLM-2.7.3-cp39-cp39-win_arm64.whl", hash = "sha256:6a60f3a3f89af1428cded8e56f19c012dd331c3bd860923d542ba4837418a5d0", size = 1126703 }, +] + +[[package]] +name = "pygments" +version = "2.19.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7c/2d/c3338d48ea6cc0feb8446d8e6937e1408088a72a39937982cc6111d17f84/pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", size = 4968581 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/0b/9fcc47d19c48b59121088dd6da2488a49d5f72dacf8262e2790a1d2c7d15/pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c", size = 1225293 }, +] + +[[package]] +name = "pyjwt" +version = "2.10.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/46/bd74733ff231675599650d3e47f361794b22ef3e3770998dda30d3b63726/pyjwt-2.10.1.tar.gz", hash = "sha256:3cc5772eb20009233caf06e9d8a0577824723b44e6648ee0a2aedb6cf9381953", size = 87785 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/61/ad/689f02752eeec26aed679477e80e632ef1b682313be70793d798c1d5fc8f/PyJWT-2.10.1-py3-none-any.whl", hash = "sha256:dcdd193e30abefd5debf142f9adfcdd2b58004e644f25406ffaebd50bd98dacb", size = 22997 }, +] + +[package.optional-dependencies] +crypto = [ + { name = "cryptography" }, +] + +[[package]] +name = "pynacl" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a7/22/27582568be639dfe22ddb3902225f91f2f17ceff88ce80e4db396c8986da/PyNaCl-1.5.0.tar.gz", hash = "sha256:8ac7448f09ab85811607bdd21ec2464495ac8b7c66d146bf545b0f08fb9220ba", size = 3392854 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ce/75/0b8ede18506041c0bf23ac4d8e2971b4161cd6ce630b177d0a08eb0d8857/PyNaCl-1.5.0-cp36-abi3-macosx_10_10_universal2.whl", hash = "sha256:401002a4aaa07c9414132aaed7f6836ff98f59277a234704ff66878c2ee4a0d1", size = 349920 }, + { url = "https://files.pythonhosted.org/packages/59/bb/fddf10acd09637327a97ef89d2a9d621328850a72f1fdc8c08bdf72e385f/PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_24_aarch64.whl", hash = "sha256:52cb72a79269189d4e0dc537556f4740f7f0a9ec41c1322598799b0bdad4ef92", size = 601722 }, + { url = "https://files.pythonhosted.org/packages/5d/70/87a065c37cca41a75f2ce113a5a2c2aa7533be648b184ade58971b5f7ccc/PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a36d4a9dda1f19ce6e03c9a784a2921a4b726b02e1c736600ca9c22029474394", size = 680087 }, + { url = "https://files.pythonhosted.org/packages/ee/87/f1bb6a595f14a327e8285b9eb54d41fef76c585a0edef0a45f6fc95de125/PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_24_x86_64.whl", hash = "sha256:0c84947a22519e013607c9be43706dd42513f9e6ae5d39d3613ca1e142fba44d", size = 856678 }, + { url = "https://files.pythonhosted.org/packages/66/28/ca86676b69bf9f90e710571b67450508484388bfce09acf8a46f0b8c785f/PyNaCl-1.5.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06b8f6fa7f5de8d5d2f7573fe8c863c051225a27b61e6860fd047b1775807858", size = 1133660 }, + { url = "https://files.pythonhosted.org/packages/3d/85/c262db650e86812585e2bc59e497a8f59948a005325a11bbbc9ecd3fe26b/PyNaCl-1.5.0-cp36-abi3-musllinux_1_1_aarch64.whl", hash = "sha256:a422368fc821589c228f4c49438a368831cb5bbc0eab5ebe1d7fac9dded6567b", size = 663824 }, + { url = "https://files.pythonhosted.org/packages/fd/1a/cc308a884bd299b651f1633acb978e8596c71c33ca85e9dc9fa33a5399b9/PyNaCl-1.5.0-cp36-abi3-musllinux_1_1_x86_64.whl", hash = "sha256:61f642bf2378713e2c2e1de73444a3778e5f0a38be6fee0fe532fe30060282ff", size = 1117912 }, + { url = "https://files.pythonhosted.org/packages/25/2d/b7df6ddb0c2a33afdb358f8af6ea3b8c4d1196ca45497dd37a56f0c122be/PyNaCl-1.5.0-cp36-abi3-win32.whl", hash = "sha256:e46dae94e34b085175f8abb3b0aaa7da40767865ac82c928eeb9e57e1ea8a543", size = 204624 }, + { url = "https://files.pythonhosted.org/packages/5e/22/d3db169895faaf3e2eda892f005f433a62db2decbcfbc2f61e6517adfa87/PyNaCl-1.5.0-cp36-abi3-win_amd64.whl", hash = "sha256:20f42270d27e1b6a29f54032090b972d97f0a1b0948cc52392041ef7831fee93", size = 212141 }, +] + +[[package]] +name = "pyobjc-core" +version = "11.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5c/94/a111239b98260869780a5767e5d74bfd3a8c13a40457f479c28dcd91f89d/pyobjc_core-11.0.tar.gz", hash = "sha256:63bced211cb8a8fb5c8ff46473603da30e51112861bd02c438fbbbc8578d9a70", size = 994931 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bc/21/ccc992b38670176a615fb67686d709e03be989511da687f6f49ddc4ff6c8/pyobjc_core-11.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:10866b3a734d47caf48e456eea0d4815c2c9b21856157db5917b61dee06893a1", size = 732162 }, + { url = "https://files.pythonhosted.org/packages/52/05/fa97309c3b1bc1ec90d701db89902e0bd5e1024023aa2c5387b889458b1b/pyobjc_core-11.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:50675c0bb8696fe960a28466f9baf6943df2928a1fd85625d678fa2f428bd0bd", size = 727295 }, + { url = "https://files.pythonhosted.org/packages/56/ce/bf3ff9a9347721a398c3dfb83e29b43fb166b7ef590f3f7b7ddcd283df39/pyobjc_core-11.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:a03061d4955c62ddd7754224a80cdadfdf17b6b5f60df1d9169a3b1b02923f0b", size = 739750 }, + { url = "https://files.pythonhosted.org/packages/72/16/0c468e73dbecb821e3da8819236fe832dfc53eb5f66a11775b055a7589ea/pyobjc_core-11.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c338c1deb7ab2e9436d4175d1127da2eeed4a1b564b3d83b9f3ae4844ba97e86", size = 743900 }, + { url = "https://files.pythonhosted.org/packages/f3/88/cecec88fd51f62a6cd7775cc4fb6bfde16652f97df88d28c84fb77ca0c18/pyobjc_core-11.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b4e9dc4296110f251a4033ff3f40320b35873ea7f876bd29a1c9705bb5e08c59", size = 791905 }, + { url = "https://files.pythonhosted.org/packages/14/ba/1c459d0f1fc4c80314040ea6efea433c0641adffa6701679ec3a917b51a3/pyobjc_core-11.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:02406ece449d0f41b31e579e47ca77ced3eb57533df955281bfcecc99da74fba", size = 732648 }, +] + +[[package]] +name = "pyobjc-framework-cocoa" +version = "11.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyobjc-core" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c5/32/53809096ad5fc3e7a2c5ddea642590a5f2cb5b81d0ad6ea67fdb2263d9f9/pyobjc_framework_cocoa-11.0.tar.gz", hash = "sha256:00346a8cb81ad7b017b32ff7bf596000f9faa905807b1bd234644ebd47f692c5", size = 6173848 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/37/16/905a32c5241848ddd91d94bae346342750f28f49fadb3746e9e796f929f3/pyobjc_framework_Cocoa-11.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:fbc65f260d617d5463c7fb9dbaaffc23c9a4fabfe3b1a50b039b61870b8daefd", size = 385509 }, + { url = "https://files.pythonhosted.org/packages/23/97/81fd41ad90e9c241172110aa635a6239d56f50d75923aaedbbe351828580/pyobjc_framework_Cocoa-11.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:3ea7be6e6dd801b297440de02d312ba3fa7fd3c322db747ae1cb237e975f5d33", size = 385534 }, + { url = "https://files.pythonhosted.org/packages/5b/8d/0e2558447c26b3ba64f7c9776a5a6c9d2ae8abf9d34308b174ae0934402e/pyobjc_framework_Cocoa-11.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:280a577b83c68175a28b2b7138d1d2d3111f2b2b66c30e86f81a19c2b02eae71", size = 385811 }, + { url = "https://files.pythonhosted.org/packages/1d/a5/609281a7e89efefbef9db1d8fe66bc0458c3b4e74e2227c644f9c18926fa/pyobjc_framework_Cocoa-11.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:15b2bd977ed340074f930f1330f03d42912d5882b697d78bd06f8ebe263ef92e", size = 385889 }, + { url = "https://files.pythonhosted.org/packages/93/f6/2d5a863673ef7b85a3cba875c43e6c495fb1307427a6801001ae94bb5e54/pyobjc_framework_Cocoa-11.0-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:5750001db544e67f2b66f02067d8f0da96bb2ef71732bde104f01b8628f9d7ea", size = 389831 }, + { url = "https://files.pythonhosted.org/packages/27/29/459cacd815c2e13de60b919c0af3d1056f74ff52172a4841684b5b946492/pyobjc_framework_Cocoa-11.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:ddff25b0755d59873d186e1e07d6aaddb19d55e3ae890d69ff2d9babf8627657", size = 385407 }, +] + +[[package]] +name = "pyparsing" +version = "3.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/8b/1a/3544f4f299a47911c2ab3710f534e52fea62a633c96806995da5d25be4b2/pyparsing-3.2.1.tar.gz", hash = "sha256:61980854fd66de3a90028d679a954d5f2623e83144b5afe5ee86f43d762e5f0a", size = 1067694 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1c/a7/c8a2d361bf89c0d9577c934ebb7421b25dc84bf3a8e3ac0a40aed9acc547/pyparsing-3.2.1-py3-none-any.whl", hash = "sha256:506ff4f4386c4cec0590ec19e6302d3aedb992fdc02c761e90416f158dacf8e1", size = 107716 }, +] + +[[package]] +name = "pytest" +version = "8.3.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/05/35/30e0d83068951d90a01852cb1cef56e5d8a09d20c7f511634cc2f7e0372a/pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761", size = 1445919 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/11/92/76a1c94d3afee238333bc0a42b82935dd8f9cf8ce9e336ff87ee14d9e1cf/pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6", size = 343083 }, +] + +[[package]] +name = "pytest-cov" +version = "6.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "coverage", extra = ["toml"] }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/be/45/9b538de8cef30e17c7b45ef42f538a94889ed6a16f2387a6c89e73220651/pytest-cov-6.0.0.tar.gz", hash = "sha256:fde0b595ca248bb8e2d76f020b465f3b107c9632e6a1d1705f17834c89dcadc0", size = 66945 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/36/3b/48e79f2cd6a61dbbd4807b4ed46cb564b4fd50a76166b1c4ea5c1d9e2371/pytest_cov-6.0.0-py3-none-any.whl", hash = "sha256:eee6f1b9e61008bd34975a4d5bab25801eb31898b032dd55addc93e96fcaaa35", size = 22949 }, +] + +[[package]] +name = "pytest-forked" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "py" }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8c/c9/93ad2ba2413057ee694884b88cf7467a46c50c438977720aeac26e73fdb7/pytest-forked-1.6.0.tar.gz", hash = "sha256:4dafd46a9a600f65d822b8f605133ecf5b3e1941ebb3588e943b4e3eb71a5a3f", size = 9977 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/af/9c0bda43e486a3c9bf1e0f876d0f241bc3f229d7d65d09331a0868db9629/pytest_forked-1.6.0-py3-none-any.whl", hash = "sha256:810958f66a91afb1a1e2ae83089d8dc1cd2437ac96b12963042fbb9fb4d16af0", size = 4897 }, +] + +[[package]] +name = "pytest-xdist" +version = "2.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "execnet" }, + { name = "pytest" }, + { name = "pytest-forked" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5d/43/9dbc32d297d6eae85d6c05dc8e8d3371061bd6cbe56a2f645d9ea4b53d9b/pytest-xdist-2.5.0.tar.gz", hash = "sha256:4580deca3ff04ddb2ac53eba39d76cb5dd5edeac050cb6fbc768b0dd712b4edf", size = 72455 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/21/08/b1945d4b4986eb1aa10cf84efc5293bba39da80a2f95db3573dd90678408/pytest_xdist-2.5.0-py3-none-any.whl", hash = "sha256:6fe5c74fec98906deb8f2d2b616b5c782022744978e7bd4695d39c8f42d0ce65", size = 41698 }, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892 }, +] + +[[package]] +name = "python-json-logger" +version = "3.2.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.10'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e3/c4/358cd13daa1d912ef795010897a483ab2f0b41c9ea1b35235a8b2f7d15a7/python_json_logger-3.2.1.tar.gz", hash = "sha256:8eb0554ea17cb75b05d2848bc14fb02fbdbd9d6972120781b974380bfa162008", size = 16287 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4b/72/2f30cf26664fcfa0bd8ec5ee62ec90c03bd485e4a294d92aabc76c5203a5/python_json_logger-3.2.1-py3-none-any.whl", hash = "sha256:cdc17047eb5374bd311e748b42f99d71223f3b0e186f4206cc5d52aefe85b090", size = 14924 }, +] + +[[package]] +name = "pywin32" +version = "308" +source = { registry = "https://pypi.org/simple" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/72/a6/3e9f2c474895c1bb61b11fa9640be00067b5c5b363c501ee9c3fa53aec01/pywin32-308-cp310-cp310-win32.whl", hash = "sha256:796ff4426437896550d2981b9c2ac0ffd75238ad9ea2d3bfa67a1abd546d262e", size = 5927028 }, + { url = "https://files.pythonhosted.org/packages/d9/b4/84e2463422f869b4b718f79eb7530a4c1693e96b8a4e5e968de38be4d2ba/pywin32-308-cp310-cp310-win_amd64.whl", hash = "sha256:4fc888c59b3c0bef905ce7eb7e2106a07712015ea1c8234b703a088d46110e8e", size = 6558484 }, + { url = "https://files.pythonhosted.org/packages/9f/8f/fb84ab789713f7c6feacaa08dad3ec8105b88ade8d1c4f0f0dfcaaa017d6/pywin32-308-cp310-cp310-win_arm64.whl", hash = "sha256:a5ab5381813b40f264fa3495b98af850098f814a25a63589a8e9eb12560f450c", size = 7971454 }, + { url = "https://files.pythonhosted.org/packages/eb/e2/02652007469263fe1466e98439831d65d4ca80ea1a2df29abecedf7e47b7/pywin32-308-cp311-cp311-win32.whl", hash = "sha256:5d8c8015b24a7d6855b1550d8e660d8daa09983c80e5daf89a273e5c6fb5095a", size = 5928156 }, + { url = "https://files.pythonhosted.org/packages/48/ef/f4fb45e2196bc7ffe09cad0542d9aff66b0e33f6c0954b43e49c33cad7bd/pywin32-308-cp311-cp311-win_amd64.whl", hash = "sha256:575621b90f0dc2695fec346b2d6302faebd4f0f45c05ea29404cefe35d89442b", size = 6559559 }, + { url = "https://files.pythonhosted.org/packages/79/ef/68bb6aa865c5c9b11a35771329e95917b5559845bd75b65549407f9fc6b4/pywin32-308-cp311-cp311-win_arm64.whl", hash = "sha256:100a5442b7332070983c4cd03f2e906a5648a5104b8a7f50175f7906efd16bb6", size = 7972495 }, + { url = "https://files.pythonhosted.org/packages/00/7c/d00d6bdd96de4344e06c4afbf218bc86b54436a94c01c71a8701f613aa56/pywin32-308-cp312-cp312-win32.whl", hash = "sha256:587f3e19696f4bf96fde9d8a57cec74a57021ad5f204c9e627e15c33ff568897", size = 5939729 }, + { url = "https://files.pythonhosted.org/packages/21/27/0c8811fbc3ca188f93b5354e7c286eb91f80a53afa4e11007ef661afa746/pywin32-308-cp312-cp312-win_amd64.whl", hash = "sha256:00b3e11ef09ede56c6a43c71f2d31857cf7c54b0ab6e78ac659497abd2834f47", size = 6543015 }, + { url = "https://files.pythonhosted.org/packages/9d/0f/d40f8373608caed2255781a3ad9a51d03a594a1248cd632d6a298daca693/pywin32-308-cp312-cp312-win_arm64.whl", hash = "sha256:9b4de86c8d909aed15b7011182c8cab38c8850de36e6afb1f0db22b8959e3091", size = 7976033 }, + { url = "https://files.pythonhosted.org/packages/a9/a4/aa562d8935e3df5e49c161b427a3a2efad2ed4e9cf81c3de636f1fdddfd0/pywin32-308-cp313-cp313-win32.whl", hash = "sha256:1c44539a37a5b7b21d02ab34e6a4d314e0788f1690d65b48e9b0b89f31abbbed", size = 5938579 }, + { url = "https://files.pythonhosted.org/packages/c7/50/b0efb8bb66210da67a53ab95fd7a98826a97ee21f1d22949863e6d588b22/pywin32-308-cp313-cp313-win_amd64.whl", hash = "sha256:fd380990e792eaf6827fcb7e187b2b4b1cede0585e3d0c9e84201ec27b9905e4", size = 6542056 }, + { url = "https://files.pythonhosted.org/packages/26/df/2b63e3e4f2df0224f8aaf6d131f54fe4e8c96400eb9df563e2aae2e1a1f9/pywin32-308-cp313-cp313-win_arm64.whl", hash = "sha256:ef313c46d4c18dfb82a2431e3051ac8f112ccee1a34f29c263c583c568db63cd", size = 7974986 }, + { url = "https://files.pythonhosted.org/packages/a8/41/ead05a7657ffdbb1edabb954ab80825c4f87a3de0285d59f8290457f9016/pywin32-308-cp39-cp39-win32.whl", hash = "sha256:7873ca4dc60ab3287919881a7d4f88baee4a6e639aa6962de25a98ba6b193341", size = 5991824 }, + { url = "https://files.pythonhosted.org/packages/e4/cd/0838c9a6063bff2e9bac2388ae36524c26c50288b5d7b6aebb6cdf8d375d/pywin32-308-cp39-cp39-win_amd64.whl", hash = "sha256:71b3322d949b4cc20776436a9c9ba0eeedcbc9c650daa536df63f0ff111bb920", size = 6640327 }, +] + +[[package]] +name = "pywinpty" +version = "2.0.14" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f1/82/90f8750423cba4b9b6c842df227609fb60704482d7abf6dd47e2babc055a/pywinpty-2.0.14.tar.gz", hash = "sha256:18bd9529e4a5daf2d9719aa17788ba6013e594ae94c5a0c27e83df3278b0660e", size = 27769 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/09/56376af256eab8cc5f8982a3b138d387136eca27fa1a8a68660e8ed59e4b/pywinpty-2.0.14-cp310-none-win_amd64.whl", hash = "sha256:0b149c2918c7974f575ba79f5a4aad58bd859a52fa9eb1296cc22aa412aa411f", size = 1397115 }, + { url = "https://files.pythonhosted.org/packages/be/e2/af1a99c0432e4e58c9ac8e334ee191790ec9793d33559189b9d2069bdc1d/pywinpty-2.0.14-cp311-none-win_amd64.whl", hash = "sha256:cf2a43ac7065b3e0dc8510f8c1f13a75fb8fde805efa3b8cff7599a1ef497bc7", size = 1397223 }, + { url = "https://files.pythonhosted.org/packages/ad/79/759ae767a3b78d340446efd54dd1fe4f7dafa4fc7be96ed757e44bcdba54/pywinpty-2.0.14-cp312-none-win_amd64.whl", hash = "sha256:55dad362ef3e9408ade68fd173e4f9032b3ce08f68cfe7eacb2c263ea1179737", size = 1397207 }, + { url = "https://files.pythonhosted.org/packages/7d/34/b77b3c209bf2eaa6455390c8d5449241637f5957f41636a2204065d52bfa/pywinpty-2.0.14-cp313-none-win_amd64.whl", hash = "sha256:074fb988a56ec79ca90ed03a896d40707131897cefb8f76f926e3834227f2819", size = 1396698 }, + { url = "https://files.pythonhosted.org/packages/d8/ef/85e1b0ef7864fa2c579b1c1efce92c5f6fa238c8e73cf9f53deee08f8605/pywinpty-2.0.14-cp39-none-win_amd64.whl", hash = "sha256:5725fd56f73c0531ec218663bd8c8ff5acc43c78962fab28564871b5fce053fd", size = 1397396 }, +] + +[[package]] +name = "pyyaml" +version = "6.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9b/95/a3fac87cb7158e231b5a6012e438c647e1a87f09f8e0d123acec8ab8bf71/PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086", size = 184199 }, + { url = "https://files.pythonhosted.org/packages/c7/7a/68bd47624dab8fd4afbfd3c48e3b79efe09098ae941de5b58abcbadff5cb/PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf", size = 171758 }, + { url = "https://files.pythonhosted.org/packages/49/ee/14c54df452143b9ee9f0f29074d7ca5516a36edb0b4cc40c3f280131656f/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237", size = 718463 }, + { url = "https://files.pythonhosted.org/packages/4d/61/de363a97476e766574650d742205be468921a7b532aa2499fcd886b62530/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b", size = 719280 }, + { url = "https://files.pythonhosted.org/packages/6b/4e/1523cb902fd98355e2e9ea5e5eb237cbc5f3ad5f3075fa65087aa0ecb669/PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed", size = 751239 }, + { url = "https://files.pythonhosted.org/packages/b7/33/5504b3a9a4464893c32f118a9cc045190a91637b119a9c881da1cf6b7a72/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180", size = 695802 }, + { url = "https://files.pythonhosted.org/packages/5c/20/8347dcabd41ef3a3cdc4f7b7a2aff3d06598c8779faa189cdbf878b626a4/PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68", size = 720527 }, + { url = "https://files.pythonhosted.org/packages/be/aa/5afe99233fb360d0ff37377145a949ae258aaab831bde4792b32650a4378/PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99", size = 144052 }, + { url = "https://files.pythonhosted.org/packages/b5/84/0fa4b06f6d6c958d207620fc60005e241ecedceee58931bb20138e1e5776/PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e", size = 161774 }, + { url = "https://files.pythonhosted.org/packages/f8/aa/7af4e81f7acba21a4c6be026da38fd2b872ca46226673c89a758ebdc4fd2/PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", size = 184612 }, + { url = "https://files.pythonhosted.org/packages/8b/62/b9faa998fd185f65c1371643678e4d58254add437edb764a08c5a98fb986/PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", size = 172040 }, + { url = "https://files.pythonhosted.org/packages/ad/0c/c804f5f922a9a6563bab712d8dcc70251e8af811fce4524d57c2c0fd49a4/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", size = 736829 }, + { url = "https://files.pythonhosted.org/packages/51/16/6af8d6a6b210c8e54f1406a6b9481febf9c64a3109c541567e35a49aa2e7/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", size = 764167 }, + { url = "https://files.pythonhosted.org/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", size = 762952 }, + { url = "https://files.pythonhosted.org/packages/9b/97/ecc1abf4a823f5ac61941a9c00fe501b02ac3ab0e373c3857f7d4b83e2b6/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4", size = 735301 }, + { url = "https://files.pythonhosted.org/packages/45/73/0f49dacd6e82c9430e46f4a027baa4ca205e8b0a9dce1397f44edc23559d/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", size = 756638 }, + { url = "https://files.pythonhosted.org/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", size = 143850 }, + { url = "https://files.pythonhosted.org/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", size = 161980 }, + { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873 }, + { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302 }, + { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154 }, + { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223 }, + { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542 }, + { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164 }, + { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611 }, + { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591 }, + { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338 }, + { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309 }, + { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679 }, + { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428 }, + { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361 }, + { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523 }, + { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660 }, + { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597 }, + { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527 }, + { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446 }, + { url = "https://files.pythonhosted.org/packages/65/d8/b7a1db13636d7fb7d4ff431593c510c8b8fca920ade06ca8ef20015493c5/PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d", size = 184777 }, + { url = "https://files.pythonhosted.org/packages/0a/02/6ec546cd45143fdf9840b2c6be8d875116a64076218b61d68e12548e5839/PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f", size = 172318 }, + { url = "https://files.pythonhosted.org/packages/0e/9a/8cc68be846c972bda34f6c2a93abb644fb2476f4dcc924d52175786932c9/PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290", size = 720891 }, + { url = "https://files.pythonhosted.org/packages/e9/6c/6e1b7f40181bc4805e2e07f4abc10a88ce4648e7e95ff1abe4ae4014a9b2/PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12", size = 722614 }, + { url = "https://files.pythonhosted.org/packages/3d/32/e7bd8535d22ea2874cef6a81021ba019474ace0d13a4819c2a4bce79bd6a/PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19", size = 737360 }, + { url = "https://files.pythonhosted.org/packages/d7/12/7322c1e30b9be969670b672573d45479edef72c9a0deac3bb2868f5d7469/PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e", size = 699006 }, + { url = "https://files.pythonhosted.org/packages/82/72/04fcad41ca56491995076630c3ec1e834be241664c0c09a64c9a2589b507/PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725", size = 723577 }, + { url = "https://files.pythonhosted.org/packages/ed/5e/46168b1f2757f1fcd442bc3029cd8767d88a98c9c05770d8b420948743bb/PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631", size = 144593 }, + { url = "https://files.pythonhosted.org/packages/19/87/5124b1c1f2412bb95c59ec481eaf936cd32f0fe2a7b16b97b81c4c017a6a/PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8", size = 162312 }, +] + +[[package]] +name = "pyzmq" +version = "26.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi", marker = "implementation_name == 'pypy'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fd/05/bed626b9f7bb2322cdbbf7b4bd8f54b1b617b0d2ab2d3547d6e39428a48e/pyzmq-26.2.0.tar.gz", hash = "sha256:070672c258581c8e4f640b5159297580a9974b026043bd4ab0470be9ed324f1f", size = 271975 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1f/a8/9837c39aba390eb7d01924ace49d761c8dbe7bc2d6082346d00c8332e431/pyzmq-26.2.0-cp310-cp310-macosx_10_15_universal2.whl", hash = "sha256:ddf33d97d2f52d89f6e6e7ae66ee35a4d9ca6f36eda89c24591b0c40205a3629", size = 1340058 }, + { url = "https://files.pythonhosted.org/packages/a2/1f/a006f2e8e4f7d41d464272012695da17fb95f33b54342612a6890da96ff6/pyzmq-26.2.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dacd995031a01d16eec825bf30802fceb2c3791ef24bcce48fa98ce40918c27b", size = 1008818 }, + { url = "https://files.pythonhosted.org/packages/b6/09/b51b6683fde5ca04593a57bbe81788b6b43114d8f8ee4e80afc991e14760/pyzmq-26.2.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:89289a5ee32ef6c439086184529ae060c741334b8970a6855ec0b6ad3ff28764", size = 673199 }, + { url = "https://files.pythonhosted.org/packages/c9/78/486f3e2e824f3a645238332bf5a4c4b4477c3063033a27c1e4052358dee2/pyzmq-26.2.0-cp310-cp310-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5506f06d7dc6ecf1efacb4a013b1f05071bb24b76350832c96449f4a2d95091c", size = 911762 }, + { url = "https://files.pythonhosted.org/packages/5e/3b/2eb1667c9b866f53e76ee8b0c301b0469745a23bd5a87b7ee3d5dd9eb6e5/pyzmq-26.2.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8ea039387c10202ce304af74def5021e9adc6297067f3441d348d2b633e8166a", size = 868773 }, + { url = "https://files.pythonhosted.org/packages/16/29/ca99b4598a9dc7e468b5417eda91f372b595be1e3eec9b7cbe8e5d3584e8/pyzmq-26.2.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:a2224fa4a4c2ee872886ed00a571f5e967c85e078e8e8c2530a2fb01b3309b88", size = 868834 }, + { url = "https://files.pythonhosted.org/packages/ad/e5/9efaeb1d2f4f8c50da04144f639b042bc52869d3a206d6bf672ab3522163/pyzmq-26.2.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:28ad5233e9c3b52d76196c696e362508959741e1a005fb8fa03b51aea156088f", size = 1202861 }, + { url = "https://files.pythonhosted.org/packages/c3/62/c721b5608a8ac0a69bb83cbb7d07a56f3ff00b3991a138e44198a16f94c7/pyzmq-26.2.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:1c17211bc037c7d88e85ed8b7d8f7e52db6dc8eca5590d162717c654550f7282", size = 1515304 }, + { url = "https://files.pythonhosted.org/packages/87/84/e8bd321aa99b72f48d4606fc5a0a920154125bd0a4608c67eab742dab087/pyzmq-26.2.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b8f86dd868d41bea9a5f873ee13bf5551c94cf6bc51baebc6f85075971fe6eea", size = 1414712 }, + { url = "https://files.pythonhosted.org/packages/cd/cd/420e3fd1ac6977b008b72e7ad2dae6350cc84d4c5027fc390b024e61738f/pyzmq-26.2.0-cp310-cp310-win32.whl", hash = "sha256:46a446c212e58456b23af260f3d9fb785054f3e3653dbf7279d8f2b5546b21c2", size = 578113 }, + { url = "https://files.pythonhosted.org/packages/5c/57/73930d56ed45ae0cb4946f383f985c855c9b3d4063f26416998f07523c0e/pyzmq-26.2.0-cp310-cp310-win_amd64.whl", hash = "sha256:49d34ab71db5a9c292a7644ce74190b1dd5a3475612eefb1f8be1d6961441971", size = 641631 }, + { url = "https://files.pythonhosted.org/packages/61/d2/ae6ac5c397f1ccad59031c64beaafce7a0d6182e0452cc48f1c9c87d2dd0/pyzmq-26.2.0-cp310-cp310-win_arm64.whl", hash = "sha256:bfa832bfa540e5b5c27dcf5de5d82ebc431b82c453a43d141afb1e5d2de025fa", size = 543528 }, + { url = "https://files.pythonhosted.org/packages/12/20/de7442172f77f7c96299a0ac70e7d4fb78cd51eca67aa2cf552b66c14196/pyzmq-26.2.0-cp311-cp311-macosx_10_15_universal2.whl", hash = "sha256:8f7e66c7113c684c2b3f1c83cdd3376103ee0ce4c49ff80a648643e57fb22218", size = 1340639 }, + { url = "https://files.pythonhosted.org/packages/98/4d/5000468bd64c7910190ed0a6c76a1ca59a68189ec1f007c451dc181a22f4/pyzmq-26.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3a495b30fc91db2db25120df5847d9833af237546fd59170701acd816ccc01c4", size = 1008710 }, + { url = "https://files.pythonhosted.org/packages/e1/bf/c67fd638c2f9fbbab8090a3ee779370b97c82b84cc12d0c498b285d7b2c0/pyzmq-26.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:77eb0968da535cba0470a5165468b2cac7772cfb569977cff92e240f57e31bef", size = 673129 }, + { url = "https://files.pythonhosted.org/packages/86/94/99085a3f492aa538161cbf27246e8886ff850e113e0c294a5b8245f13b52/pyzmq-26.2.0-cp311-cp311-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6ace4f71f1900a548f48407fc9be59c6ba9d9aaf658c2eea6cf2779e72f9f317", size = 910107 }, + { url = "https://files.pythonhosted.org/packages/31/1d/346809e8a9b999646d03f21096428453465b1bca5cd5c64ecd048d9ecb01/pyzmq-26.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:92a78853d7280bffb93df0a4a6a2498cba10ee793cc8076ef797ef2f74d107cf", size = 867960 }, + { url = "https://files.pythonhosted.org/packages/ab/68/6fb6ae5551846ad5beca295b7bca32bf0a7ce19f135cb30e55fa2314e6b6/pyzmq-26.2.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:689c5d781014956a4a6de61d74ba97b23547e431e9e7d64f27d4922ba96e9d6e", size = 869204 }, + { url = "https://files.pythonhosted.org/packages/0f/f9/18417771dee223ccf0f48e29adf8b4e25ba6d0e8285e33bcbce078070bc3/pyzmq-26.2.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:0aca98bc423eb7d153214b2df397c6421ba6373d3397b26c057af3c904452e37", size = 1203351 }, + { url = "https://files.pythonhosted.org/packages/e0/46/f13e67fe0d4f8a2315782cbad50493de6203ea0d744610faf4d5f5b16e90/pyzmq-26.2.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:1f3496d76b89d9429a656293744ceca4d2ac2a10ae59b84c1da9b5165f429ad3", size = 1514204 }, + { url = "https://files.pythonhosted.org/packages/50/11/ddcf7343b7b7a226e0fc7b68cbf5a5bb56291fac07f5c3023bb4c319ebb4/pyzmq-26.2.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:5c2b3bfd4b9689919db068ac6c9911f3fcb231c39f7dd30e3138be94896d18e6", size = 1414339 }, + { url = "https://files.pythonhosted.org/packages/01/14/1c18d7d5b7be2708f513f37c61bfadfa62161c10624f8733f1c8451b3509/pyzmq-26.2.0-cp311-cp311-win32.whl", hash = "sha256:eac5174677da084abf378739dbf4ad245661635f1600edd1221f150b165343f4", size = 576928 }, + { url = "https://files.pythonhosted.org/packages/3b/1b/0a540edd75a41df14ec416a9a500b9fec66e554aac920d4c58fbd5756776/pyzmq-26.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:5a509df7d0a83a4b178d0f937ef14286659225ef4e8812e05580776c70e155d5", size = 642317 }, + { url = "https://files.pythonhosted.org/packages/98/77/1cbfec0358078a4c5add529d8a70892db1be900980cdb5dd0898b3d6ab9d/pyzmq-26.2.0-cp311-cp311-win_arm64.whl", hash = "sha256:c0e6091b157d48cbe37bd67233318dbb53e1e6327d6fc3bb284afd585d141003", size = 543834 }, + { url = "https://files.pythonhosted.org/packages/28/2f/78a766c8913ad62b28581777ac4ede50c6d9f249d39c2963e279524a1bbe/pyzmq-26.2.0-cp312-cp312-macosx_10_15_universal2.whl", hash = "sha256:ded0fc7d90fe93ae0b18059930086c51e640cdd3baebdc783a695c77f123dcd9", size = 1343105 }, + { url = "https://files.pythonhosted.org/packages/b7/9c/4b1e2d3d4065be715e007fe063ec7885978fad285f87eae1436e6c3201f4/pyzmq-26.2.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:17bf5a931c7f6618023cdacc7081f3f266aecb68ca692adac015c383a134ca52", size = 1008365 }, + { url = "https://files.pythonhosted.org/packages/4f/ef/5a23ec689ff36d7625b38d121ef15abfc3631a9aecb417baf7a4245e4124/pyzmq-26.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55cf66647e49d4621a7e20c8d13511ef1fe1efbbccf670811864452487007e08", size = 665923 }, + { url = "https://files.pythonhosted.org/packages/ae/61/d436461a47437d63c6302c90724cf0981883ec57ceb6073873f32172d676/pyzmq-26.2.0-cp312-cp312-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4661c88db4a9e0f958c8abc2b97472e23061f0bc737f6f6179d7a27024e1faa5", size = 903400 }, + { url = "https://files.pythonhosted.org/packages/47/42/fc6d35ecefe1739a819afaf6f8e686f7f02a4dd241c78972d316f403474c/pyzmq-26.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea7f69de383cb47522c9c208aec6dd17697db7875a4674c4af3f8cfdac0bdeae", size = 860034 }, + { url = "https://files.pythonhosted.org/packages/07/3b/44ea6266a6761e9eefaa37d98fabefa112328808ac41aa87b4bbb668af30/pyzmq-26.2.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:7f98f6dfa8b8ccaf39163ce872bddacca38f6a67289116c8937a02e30bbe9711", size = 860579 }, + { url = "https://files.pythonhosted.org/packages/38/6f/4df2014ab553a6052b0e551b37da55166991510f9e1002c89cab7ce3b3f2/pyzmq-26.2.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e3e0210287329272539eea617830a6a28161fbbd8a3271bf4150ae3e58c5d0e6", size = 1196246 }, + { url = "https://files.pythonhosted.org/packages/38/9d/ee240fc0c9fe9817f0c9127a43238a3e28048795483c403cc10720ddef22/pyzmq-26.2.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:6b274e0762c33c7471f1a7471d1a2085b1a35eba5cdc48d2ae319f28b6fc4de3", size = 1507441 }, + { url = "https://files.pythonhosted.org/packages/85/4f/01711edaa58d535eac4a26c294c617c9a01f09857c0ce191fd574d06f359/pyzmq-26.2.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:29c6a4635eef69d68a00321e12a7d2559fe2dfccfa8efae3ffb8e91cd0b36a8b", size = 1406498 }, + { url = "https://files.pythonhosted.org/packages/07/18/907134c85c7152f679ed744e73e645b365f3ad571f38bdb62e36f347699a/pyzmq-26.2.0-cp312-cp312-win32.whl", hash = "sha256:989d842dc06dc59feea09e58c74ca3e1678c812a4a8a2a419046d711031f69c7", size = 575533 }, + { url = "https://files.pythonhosted.org/packages/ce/2c/a6f4a20202a4d3c582ad93f95ee78d79bbdc26803495aec2912b17dbbb6c/pyzmq-26.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:2a50625acdc7801bc6f74698c5c583a491c61d73c6b7ea4dee3901bb99adb27a", size = 637768 }, + { url = "https://files.pythonhosted.org/packages/5f/0e/eb16ff731632d30554bf5af4dbba3ffcd04518219d82028aea4ae1b02ca5/pyzmq-26.2.0-cp312-cp312-win_arm64.whl", hash = "sha256:4d29ab8592b6ad12ebbf92ac2ed2bedcfd1cec192d8e559e2e099f648570e19b", size = 540675 }, + { url = "https://files.pythonhosted.org/packages/04/a7/0f7e2f6c126fe6e62dbae0bc93b1bd3f1099cf7fea47a5468defebe3f39d/pyzmq-26.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9dd8cd1aeb00775f527ec60022004d030ddc51d783d056e3e23e74e623e33726", size = 1006564 }, + { url = "https://files.pythonhosted.org/packages/31/b6/a187165c852c5d49f826a690857684333a6a4a065af0a6015572d2284f6a/pyzmq-26.2.0-cp313-cp313-macosx_10_15_universal2.whl", hash = "sha256:28c812d9757fe8acecc910c9ac9dafd2ce968c00f9e619db09e9f8f54c3a68a3", size = 1340447 }, + { url = "https://files.pythonhosted.org/packages/68/ba/f4280c58ff71f321602a6e24fd19879b7e79793fb8ab14027027c0fb58ef/pyzmq-26.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d80b1dd99c1942f74ed608ddb38b181b87476c6a966a88a950c7dee118fdf50", size = 665485 }, + { url = "https://files.pythonhosted.org/packages/77/b5/c987a5c53c7d8704216f29fc3d810b32f156bcea488a940e330e1bcbb88d/pyzmq-26.2.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8c997098cc65e3208eca09303630e84d42718620e83b733d0fd69543a9cab9cb", size = 903484 }, + { url = "https://files.pythonhosted.org/packages/29/c9/07da157d2db18c72a7eccef8e684cefc155b712a88e3d479d930aa9eceba/pyzmq-26.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ad1bc8d1b7a18497dda9600b12dc193c577beb391beae5cd2349184db40f187", size = 859981 }, + { url = "https://files.pythonhosted.org/packages/43/09/e12501bd0b8394b7d02c41efd35c537a1988da67fc9c745cae9c6c776d31/pyzmq-26.2.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:bea2acdd8ea4275e1278350ced63da0b166421928276c7c8e3f9729d7402a57b", size = 860334 }, + { url = "https://files.pythonhosted.org/packages/eb/ff/f5ec1d455f8f7385cc0a8b2acd8c807d7fade875c14c44b85c1bddabae21/pyzmq-26.2.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:23f4aad749d13698f3f7b64aad34f5fc02d6f20f05999eebc96b89b01262fb18", size = 1196179 }, + { url = "https://files.pythonhosted.org/packages/ec/8a/bb2ac43295b1950fe436a81fc5b298be0b96ac76fb029b514d3ed58f7b27/pyzmq-26.2.0-cp313-cp313-musllinux_1_1_i686.whl", hash = "sha256:a4f96f0d88accc3dbe4a9025f785ba830f968e21e3e2c6321ccdfc9aef755115", size = 1507668 }, + { url = "https://files.pythonhosted.org/packages/a9/49/dbc284ebcfd2dca23f6349227ff1616a7ee2c4a35fe0a5d6c3deff2b4fed/pyzmq-26.2.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ced65e5a985398827cc9276b93ef6dfabe0273c23de8c7931339d7e141c2818e", size = 1406539 }, + { url = "https://files.pythonhosted.org/packages/00/68/093cdce3fe31e30a341d8e52a1ad86392e13c57970d722c1f62a1d1a54b6/pyzmq-26.2.0-cp313-cp313-win32.whl", hash = "sha256:31507f7b47cc1ead1f6e86927f8ebb196a0bab043f6345ce070f412a59bf87b5", size = 575567 }, + { url = "https://files.pythonhosted.org/packages/92/ae/6cc4657148143412b5819b05e362ae7dd09fb9fe76e2a539dcff3d0386bc/pyzmq-26.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:70fc7fcf0410d16ebdda9b26cbd8bf8d803d220a7f3522e060a69a9c87bf7bad", size = 637551 }, + { url = "https://files.pythonhosted.org/packages/6c/67/fbff102e201688f97c8092e4c3445d1c1068c2f27bbd45a578df97ed5f94/pyzmq-26.2.0-cp313-cp313-win_arm64.whl", hash = "sha256:c3789bd5768ab5618ebf09cef6ec2b35fed88709b104351748a63045f0ff9797", size = 540378 }, + { url = "https://files.pythonhosted.org/packages/3f/fe/2d998380b6e0122c6c4bdf9b6caf490831e5f5e2d08a203b5adff060c226/pyzmq-26.2.0-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:034da5fc55d9f8da09015d368f519478a52675e558c989bfcb5cf6d4e16a7d2a", size = 1007378 }, + { url = "https://files.pythonhosted.org/packages/4a/f4/30d6e7157f12b3a0390bde94d6a8567cdb88846ed068a6e17238a4ccf600/pyzmq-26.2.0-cp313-cp313t-macosx_10_15_universal2.whl", hash = "sha256:c92d73464b886931308ccc45b2744e5968cbaade0b1d6aeb40d8ab537765f5bc", size = 1329532 }, + { url = "https://files.pythonhosted.org/packages/82/86/3fe917870e15ee1c3ad48229a2a64458e36036e64b4afa9659045d82bfa8/pyzmq-26.2.0-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:794a4562dcb374f7dbbfb3f51d28fb40123b5a2abadee7b4091f93054909add5", size = 653242 }, + { url = "https://files.pythonhosted.org/packages/50/2d/242e7e6ef6c8c19e6cb52d095834508cd581ffb925699fd3c640cdc758f1/pyzmq-26.2.0-cp313-cp313t-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aee22939bb6075e7afededabad1a56a905da0b3c4e3e0c45e75810ebe3a52672", size = 888404 }, + { url = "https://files.pythonhosted.org/packages/ac/11/7270566e1f31e4ea73c81ec821a4b1688fd551009a3d2bab11ec66cb1e8f/pyzmq-26.2.0-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ae90ff9dad33a1cfe947d2c40cb9cb5e600d759ac4f0fd22616ce6540f72797", size = 845858 }, + { url = "https://files.pythonhosted.org/packages/91/d5/72b38fbc69867795c8711bdd735312f9fef1e3d9204e2f63ab57085434b9/pyzmq-26.2.0-cp313-cp313t-manylinux_2_28_x86_64.whl", hash = "sha256:43a47408ac52647dfabbc66a25b05b6a61700b5165807e3fbd40063fcaf46386", size = 847375 }, + { url = "https://files.pythonhosted.org/packages/dd/9a/10ed3c7f72b4c24e719c59359fbadd1a27556a28b36cdf1cd9e4fb7845d5/pyzmq-26.2.0-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:25bf2374a2a8433633c65ccb9553350d5e17e60c8eb4de4d92cc6bd60f01d306", size = 1183489 }, + { url = "https://files.pythonhosted.org/packages/72/2d/8660892543fabf1fe41861efa222455811adac9f3c0818d6c3170a1153e3/pyzmq-26.2.0-cp313-cp313t-musllinux_1_1_i686.whl", hash = "sha256:007137c9ac9ad5ea21e6ad97d3489af654381324d5d3ba614c323f60dab8fae6", size = 1492932 }, + { url = "https://files.pythonhosted.org/packages/7b/d6/32fd69744afb53995619bc5effa2a405ae0d343cd3e747d0fbc43fe894ee/pyzmq-26.2.0-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:470d4a4f6d48fb34e92d768b4e8a5cc3780db0d69107abf1cd7ff734b9766eb0", size = 1392485 }, + { url = "https://files.pythonhosted.org/packages/ac/9e/ad5fbbe1bcc7a9d1e8c5f4f7de48f2c1dc481e151ef80cc1ce9a7fe67b55/pyzmq-26.2.0-cp39-cp39-macosx_10_15_universal2.whl", hash = "sha256:b1d464cb8d72bfc1a3adc53305a63a8e0cac6bc8c5a07e8ca190ab8d3faa43c2", size = 1341256 }, + { url = "https://files.pythonhosted.org/packages/4c/d9/d7a8022108c214803a82b0b69d4885cee00933d21928f1f09dca371cf4bf/pyzmq-26.2.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:4da04c48873a6abdd71811c5e163bd656ee1b957971db7f35140a2d573f6949c", size = 1009385 }, + { url = "https://files.pythonhosted.org/packages/ed/69/0529b59ac667ea8bfe8796ac71796b688fbb42ff78e06525dabfed3bc7ae/pyzmq-26.2.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:d049df610ac811dcffdc147153b414147428567fbbc8be43bb8885f04db39d98", size = 908009 }, + { url = "https://files.pythonhosted.org/packages/6e/bd/3ff3e1172f12f55769793a3a334e956ec2886805ebfb2f64756b6b5c6a1a/pyzmq-26.2.0-cp39-cp39-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:05590cdbc6b902101d0e65d6a4780af14dc22914cc6ab995d99b85af45362cc9", size = 862078 }, + { url = "https://files.pythonhosted.org/packages/c3/ec/ab13585c3a1f48e2874253844c47b194d56eb25c94718691349c646f336f/pyzmq-26.2.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c811cfcd6a9bf680236c40c6f617187515269ab2912f3d7e8c0174898e2519db", size = 673756 }, + { url = "https://files.pythonhosted.org/packages/1e/be/febcd4b04dd50ee6d514dfbc33a3d5d9cb38ec9516e02bbfc929baa0f141/pyzmq-26.2.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:6835dd60355593de10350394242b5757fbbd88b25287314316f266e24c61d073", size = 1203684 }, + { url = "https://files.pythonhosted.org/packages/16/28/304150e71afd2df3b82f52f66c0d8ab9ac6fe1f1ffdf92bad4c8cc91d557/pyzmq-26.2.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:bc6bee759a6bddea5db78d7dcd609397449cb2d2d6587f48f3ca613b19410cfc", size = 1515864 }, + { url = "https://files.pythonhosted.org/packages/18/89/8d48d8cd505c12a1f5edee597cc32ffcedc65fd8d2603aebaaedc38a7041/pyzmq-26.2.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c530e1eecd036ecc83c3407f77bb86feb79916d4a33d11394b8234f3bd35b940", size = 1415383 }, + { url = "https://files.pythonhosted.org/packages/d4/7e/43a60c3b179f7da0cbc2b649bd2702fd6a39bff5f72aa38d6e1aeb00256d/pyzmq-26.2.0-cp39-cp39-win32.whl", hash = "sha256:367b4f689786fca726ef7a6c5ba606958b145b9340a5e4808132cc65759abd44", size = 578540 }, + { url = "https://files.pythonhosted.org/packages/3a/55/8841dcd28f783ad06674c8fe8d7d72794b548d0bff8829aaafeb72e8b44d/pyzmq-26.2.0-cp39-cp39-win_amd64.whl", hash = "sha256:e6fa2e3e683f34aea77de8112f6483803c96a44fd726d7358b9888ae5bb394ec", size = 642147 }, + { url = "https://files.pythonhosted.org/packages/b4/78/b3c31ccfcfcdd6ea50b6abc8f46a2a7aadb9c3d40531d1b908d834aaa12e/pyzmq-26.2.0-cp39-cp39-win_arm64.whl", hash = "sha256:7445be39143a8aa4faec43b076e06944b8f9d0701b669df4af200531b21e40bb", size = 543903 }, + { url = "https://files.pythonhosted.org/packages/53/fb/36b2b2548286e9444e52fcd198760af99fd89102b5be50f0660fcfe902df/pyzmq-26.2.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:706e794564bec25819d21a41c31d4df2d48e1cc4b061e8d345d7fb4dd3e94072", size = 906955 }, + { url = "https://files.pythonhosted.org/packages/77/8f/6ce54f8979a01656e894946db6299e2273fcee21c8e5fa57c6295ef11f57/pyzmq-26.2.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b435f2753621cd36e7c1762156815e21c985c72b19135dac43a7f4f31d28dd1", size = 565701 }, + { url = "https://files.pythonhosted.org/packages/ee/1c/bf8cd66730a866b16db8483286078892b7f6536f8c389fb46e4beba0a970/pyzmq-26.2.0-pp310-pypy310_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:160c7e0a5eb178011e72892f99f918c04a131f36056d10d9c1afb223fc952c2d", size = 794312 }, + { url = "https://files.pythonhosted.org/packages/71/43/91fa4ff25bbfdc914ab6bafa0f03241d69370ef31a761d16bb859f346582/pyzmq-26.2.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2c4a71d5d6e7b28a47a394c0471b7e77a0661e2d651e7ae91e0cab0a587859ca", size = 752775 }, + { url = "https://files.pythonhosted.org/packages/ec/d2/3b2ab40f455a256cb6672186bea95cd97b459ce4594050132d71e76f0d6f/pyzmq-26.2.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:90412f2db8c02a3864cbfc67db0e3dcdbda336acf1c469526d3e869394fe001c", size = 550762 }, + { url = "https://files.pythonhosted.org/packages/6c/78/3096d72581365dfb0081ac9512a3b53672fa69854aa174d78636510c4db8/pyzmq-26.2.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:cdeabcff45d1c219636ee2e54d852262e5c2e085d6cb476d938aee8d921356b3", size = 906945 }, + { url = "https://files.pythonhosted.org/packages/da/f2/8054574d77c269c31d055d4daf3d8407adf61ea384a50c8d14b158551d09/pyzmq-26.2.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35cffef589bcdc587d06f9149f8d5e9e8859920a071df5a2671de2213bef592a", size = 565698 }, + { url = "https://files.pythonhosted.org/packages/77/21/c3ad93236d1d60eea10b67528f55e7db115a9d32e2bf163fcf601f85e9cc/pyzmq-26.2.0-pp39-pypy39_pp73-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:18c8dc3b7468d8b4bdf60ce9d7141897da103c7a4690157b32b60acb45e333e6", size = 794307 }, + { url = "https://files.pythonhosted.org/packages/6a/49/e95b491724500fcb760178ce8db39b923429e328e57bcf9162e32c2c187c/pyzmq-26.2.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7133d0a1677aec369d67dd78520d3fa96dd7f3dcec99d66c1762870e5ea1a50a", size = 752769 }, + { url = "https://files.pythonhosted.org/packages/9b/a9/50c9c06762b30792f71aaad8d1886748d39c4bffedc1171fbc6ad2b92d67/pyzmq-26.2.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:6a96179a24b14fa6428cbfc08641c779a53f8fcec43644030328f44034c7f1f4", size = 751338 }, + { url = "https://files.pythonhosted.org/packages/ca/63/27e6142b4f67a442ee480986ca5b88edb01462dd2319843057683a5148bd/pyzmq-26.2.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:4f78c88905461a9203eac9faac157a2a0dbba84a0fd09fd29315db27be40af9f", size = 550757 }, +] + +[[package]] +name = "referencing" +version = "0.36.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs" }, + { name = "rpds-py" }, + { name = "typing-extensions", marker = "python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2f/db/98b5c277be99dd18bfd91dd04e1b759cad18d1a338188c936e92f921c7e2/referencing-0.36.2.tar.gz", hash = "sha256:df2e89862cd09deabbdba16944cc3f10feb6b3e6f18e902f7cc25609a34775aa", size = 74744 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/b1/3baf80dc6d2b7bc27a95a67752d0208e410351e3feb4eb78de5f77454d8d/referencing-0.36.2-py3-none-any.whl", hash = "sha256:e8699adbbf8b5c7de96d8ffa0eb5c158b3beafce084968e2ea8bb08c6794dcd0", size = 26775 }, +] + +[[package]] +name = "requests" +version = "2.32.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi" }, + { name = "charset-normalizer" }, + { name = "idna" }, + { name = "urllib3" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/63/70/2bf7780ad2d390a8d301ad0b550f1581eadbd9a20f896afe06353c2a2913/requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760", size = 131218 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/9b/335f9764261e915ed497fcdeb11df5dfd6f7bf257d4a6a2a686d80da4d54/requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6", size = 64928 }, +] + +[[package]] +name = "rfc3339-validator" +version = "0.1.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/28/ea/a9387748e2d111c3c2b275ba970b735e04e15cdb1eb30693b6b5708c4dbd/rfc3339_validator-0.1.4.tar.gz", hash = "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b", size = 5513 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl", hash = "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa", size = 3490 }, +] + +[[package]] +name = "rfc3986-validator" +version = "0.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/da/88/f270de456dd7d11dcc808abfa291ecdd3f45ff44e3b549ffa01b126464d0/rfc3986_validator-0.1.1.tar.gz", hash = "sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055", size = 6760 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl", hash = "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9", size = 4242 }, +] + +[[package]] +name = "rich" +version = "13.9.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py" }, + { name = "pygments" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ab/3a/0316b28d0761c6734d6bc14e770d85506c986c85ffb239e688eeaab2c2bc/rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098", size = 223149 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/19/71/39c7c0d87f8d4e6c020a393182060eaefeeae6c01dab6a84ec346f2567df/rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90", size = 242424 }, +] + +[[package]] +name = "rpds-py" +version = "0.22.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/01/80/cce854d0921ff2f0a9fa831ba3ad3c65cee3a46711addf39a2af52df2cfd/rpds_py-0.22.3.tar.gz", hash = "sha256:e32fee8ab45d3c2db6da19a5323bc3362237c8b653c70194414b892fd06a080d", size = 26771 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/42/2a/ead1d09e57449b99dcc190d8d2323e3a167421d8f8fdf0f217c6f6befe47/rpds_py-0.22.3-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:6c7b99ca52c2c1752b544e310101b98a659b720b21db00e65edca34483259967", size = 359514 }, + { url = "https://files.pythonhosted.org/packages/8f/7e/1254f406b7793b586c68e217a6a24ec79040f85e030fff7e9049069284f4/rpds_py-0.22.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:be2eb3f2495ba669d2a985f9b426c1797b7d48d6963899276d22f23e33d47e37", size = 349031 }, + { url = "https://files.pythonhosted.org/packages/aa/da/17c6a2c73730d426df53675ff9cc6653ac7a60b6438d03c18e1c822a576a/rpds_py-0.22.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:70eb60b3ae9245ddea20f8a4190bd79c705a22f8028aaf8bbdebe4716c3fab24", size = 381485 }, + { url = "https://files.pythonhosted.org/packages/aa/13/2dbacd820466aa2a3c4b747afb18d71209523d353cf865bf8f4796c969ea/rpds_py-0.22.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:4041711832360a9b75cfb11b25a6a97c8fb49c07b8bd43d0d02b45d0b499a4ff", size = 386794 }, + { url = "https://files.pythonhosted.org/packages/6d/62/96905d0a35ad4e4bc3c098b2f34b2e7266e211d08635baa690643d2227be/rpds_py-0.22.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:64607d4cbf1b7e3c3c8a14948b99345eda0e161b852e122c6bb71aab6d1d798c", size = 423523 }, + { url = "https://files.pythonhosted.org/packages/eb/1b/d12770f2b6a9fc2c3ec0d810d7d440f6d465ccd8b7f16ae5385952c28b89/rpds_py-0.22.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:81e69b0a0e2537f26d73b4e43ad7bc8c8efb39621639b4434b76a3de50c6966e", size = 446695 }, + { url = "https://files.pythonhosted.org/packages/4d/cf/96f1fd75512a017f8e07408b6d5dbeb492d9ed46bfe0555544294f3681b3/rpds_py-0.22.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc27863442d388870c1809a87507727b799c8460573cfbb6dc0eeaef5a11b5ec", size = 381959 }, + { url = "https://files.pythonhosted.org/packages/ab/f0/d1c5b501c8aea85aeb938b555bfdf7612110a2f8cdc21ae0482c93dd0c24/rpds_py-0.22.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e79dd39f1e8c3504be0607e5fc6e86bb60fe3584bec8b782578c3b0fde8d932c", size = 410420 }, + { url = "https://files.pythonhosted.org/packages/33/3b/45b6c58fb6aad5a569ae40fb890fc494c6b02203505a5008ee6dc68e65f7/rpds_py-0.22.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:e0fa2d4ec53dc51cf7d3bb22e0aa0143966119f42a0c3e4998293a3dd2856b09", size = 557620 }, + { url = "https://files.pythonhosted.org/packages/83/62/3fdd2d3d47bf0bb9b931c4c73036b4ab3ec77b25e016ae26fab0f02be2af/rpds_py-0.22.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:fda7cb070f442bf80b642cd56483b5548e43d366fe3f39b98e67cce780cded00", size = 584202 }, + { url = "https://files.pythonhosted.org/packages/04/f2/5dced98b64874b84ca824292f9cee2e3f30f3bcf231d15a903126684f74d/rpds_py-0.22.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cff63a0272fcd259dcc3be1657b07c929c466b067ceb1c20060e8d10af56f5bf", size = 552787 }, + { url = "https://files.pythonhosted.org/packages/67/13/2273dea1204eda0aea0ef55145da96a9aa28b3f88bb5c70e994f69eda7c3/rpds_py-0.22.3-cp310-cp310-win32.whl", hash = "sha256:9bd7228827ec7bb817089e2eb301d907c0d9827a9e558f22f762bb690b131652", size = 220088 }, + { url = "https://files.pythonhosted.org/packages/4e/80/8c8176b67ad7f4a894967a7a4014ba039626d96f1d4874d53e409b58d69f/rpds_py-0.22.3-cp310-cp310-win_amd64.whl", hash = "sha256:9beeb01d8c190d7581a4d59522cd3d4b6887040dcfc744af99aa59fef3e041a8", size = 231737 }, + { url = "https://files.pythonhosted.org/packages/15/ad/8d1ddf78f2805a71253fcd388017e7b4a0615c22c762b6d35301fef20106/rpds_py-0.22.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d20cfb4e099748ea39e6f7b16c91ab057989712d31761d3300d43134e26e165f", size = 359773 }, + { url = "https://files.pythonhosted.org/packages/c8/75/68c15732293a8485d79fe4ebe9045525502a067865fa4278f178851b2d87/rpds_py-0.22.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:68049202f67380ff9aa52f12e92b1c30115f32e6895cd7198fa2a7961621fc5a", size = 349214 }, + { url = "https://files.pythonhosted.org/packages/3c/4c/7ce50f3070083c2e1b2bbd0fb7046f3da55f510d19e283222f8f33d7d5f4/rpds_py-0.22.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fb4f868f712b2dd4bcc538b0a0c1f63a2b1d584c925e69a224d759e7070a12d5", size = 380477 }, + { url = "https://files.pythonhosted.org/packages/9a/e9/835196a69cb229d5c31c13b8ae603bd2da9a6695f35fe4270d398e1db44c/rpds_py-0.22.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bc51abd01f08117283c5ebf64844a35144a0843ff7b2983e0648e4d3d9f10dbb", size = 386171 }, + { url = "https://files.pythonhosted.org/packages/f9/8e/33fc4eba6683db71e91e6d594a2cf3a8fbceb5316629f0477f7ece5e3f75/rpds_py-0.22.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0f3cec041684de9a4684b1572fe28c7267410e02450f4561700ca5a3bc6695a2", size = 422676 }, + { url = "https://files.pythonhosted.org/packages/37/47/2e82d58f8046a98bb9497a8319604c92b827b94d558df30877c4b3c6ccb3/rpds_py-0.22.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7ef9d9da710be50ff6809fed8f1963fecdfecc8b86656cadfca3bc24289414b0", size = 446152 }, + { url = "https://files.pythonhosted.org/packages/e1/78/79c128c3e71abbc8e9739ac27af11dc0f91840a86fce67ff83c65d1ba195/rpds_py-0.22.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:59f4a79c19232a5774aee369a0c296712ad0e77f24e62cad53160312b1c1eaa1", size = 381300 }, + { url = "https://files.pythonhosted.org/packages/c9/5b/2e193be0e8b228c1207f31fa3ea79de64dadb4f6a4833111af8145a6bc33/rpds_py-0.22.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a60bce91f81ddaac922a40bbb571a12c1070cb20ebd6d49c48e0b101d87300d", size = 409636 }, + { url = "https://files.pythonhosted.org/packages/c2/3f/687c7100b762d62186a1c1100ffdf99825f6fa5ea94556844bbbd2d0f3a9/rpds_py-0.22.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:e89391e6d60251560f0a8f4bd32137b077a80d9b7dbe6d5cab1cd80d2746f648", size = 556708 }, + { url = "https://files.pythonhosted.org/packages/8c/a2/c00cbc4b857e8b3d5e7f7fc4c81e23afd8c138b930f4f3ccf9a41a23e9e4/rpds_py-0.22.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e3fb866d9932a3d7d0c82da76d816996d1667c44891bd861a0f97ba27e84fc74", size = 583554 }, + { url = "https://files.pythonhosted.org/packages/d0/08/696c9872cf56effdad9ed617ac072f6774a898d46b8b8964eab39ec562d2/rpds_py-0.22.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:1352ae4f7c717ae8cba93421a63373e582d19d55d2ee2cbb184344c82d2ae55a", size = 552105 }, + { url = "https://files.pythonhosted.org/packages/18/1f/4df560be1e994f5adf56cabd6c117e02de7c88ee238bb4ce03ed50da9d56/rpds_py-0.22.3-cp311-cp311-win32.whl", hash = "sha256:b0b4136a252cadfa1adb705bb81524eee47d9f6aab4f2ee4fa1e9d3cd4581f64", size = 220199 }, + { url = "https://files.pythonhosted.org/packages/b8/1b/c29b570bc5db8237553002788dc734d6bd71443a2ceac2a58202ec06ef12/rpds_py-0.22.3-cp311-cp311-win_amd64.whl", hash = "sha256:8bd7c8cfc0b8247c8799080fbff54e0b9619e17cdfeb0478ba7295d43f635d7c", size = 231775 }, + { url = "https://files.pythonhosted.org/packages/75/47/3383ee3bd787a2a5e65a9b9edc37ccf8505c0a00170e3a5e6ea5fbcd97f7/rpds_py-0.22.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:27e98004595899949bd7a7b34e91fa7c44d7a97c40fcaf1d874168bb652ec67e", size = 352334 }, + { url = "https://files.pythonhosted.org/packages/40/14/aa6400fa8158b90a5a250a77f2077c0d0cd8a76fce31d9f2b289f04c6dec/rpds_py-0.22.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1978d0021e943aae58b9b0b196fb4895a25cc53d3956b8e35e0b7682eefb6d56", size = 342111 }, + { url = "https://files.pythonhosted.org/packages/7d/06/395a13bfaa8a28b302fb433fb285a67ce0ea2004959a027aea8f9c52bad4/rpds_py-0.22.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:655ca44a831ecb238d124e0402d98f6212ac527a0ba6c55ca26f616604e60a45", size = 384286 }, + { url = "https://files.pythonhosted.org/packages/43/52/d8eeaffab047e6b7b7ef7f00d5ead074a07973968ffa2d5820fa131d7852/rpds_py-0.22.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:feea821ee2a9273771bae61194004ee2fc33f8ec7db08117ef9147d4bbcbca8e", size = 391739 }, + { url = "https://files.pythonhosted.org/packages/83/31/52dc4bde85c60b63719610ed6f6d61877effdb5113a72007679b786377b8/rpds_py-0.22.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:22bebe05a9ffc70ebfa127efbc429bc26ec9e9b4ee4d15a740033efda515cf3d", size = 427306 }, + { url = "https://files.pythonhosted.org/packages/70/d5/1bab8e389c2261dba1764e9e793ed6830a63f830fdbec581a242c7c46bda/rpds_py-0.22.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3af6e48651c4e0d2d166dc1b033b7042ea3f871504b6805ba5f4fe31581d8d38", size = 442717 }, + { url = "https://files.pythonhosted.org/packages/82/a1/a45f3e30835b553379b3a56ea6c4eb622cf11e72008229af840e4596a8ea/rpds_py-0.22.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e67ba3c290821343c192f7eae1d8fd5999ca2dc99994114643e2f2d3e6138b15", size = 385721 }, + { url = "https://files.pythonhosted.org/packages/a6/27/780c942de3120bdd4d0e69583f9c96e179dfff082f6ecbb46b8d6488841f/rpds_py-0.22.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:02fbb9c288ae08bcb34fb41d516d5eeb0455ac35b5512d03181d755d80810059", size = 415824 }, + { url = "https://files.pythonhosted.org/packages/94/0b/aa0542ca88ad20ea719b06520f925bae348ea5c1fdf201b7e7202d20871d/rpds_py-0.22.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:f56a6b404f74ab372da986d240e2e002769a7d7102cc73eb238a4f72eec5284e", size = 561227 }, + { url = "https://files.pythonhosted.org/packages/0d/92/3ed77d215f82c8f844d7f98929d56cc321bb0bcfaf8f166559b8ec56e5f1/rpds_py-0.22.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0a0461200769ab3b9ab7e513f6013b7a97fdeee41c29b9db343f3c5a8e2b9e61", size = 587424 }, + { url = "https://files.pythonhosted.org/packages/09/42/cacaeb047a22cab6241f107644f230e2935d4efecf6488859a7dd82fc47d/rpds_py-0.22.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8633e471c6207a039eff6aa116e35f69f3156b3989ea3e2d755f7bc41754a4a7", size = 555953 }, + { url = "https://files.pythonhosted.org/packages/e6/52/c921dc6d5f5d45b212a456c1f5b17df1a471127e8037eb0972379e39dff4/rpds_py-0.22.3-cp312-cp312-win32.whl", hash = "sha256:593eba61ba0c3baae5bc9be2f5232430453fb4432048de28399ca7376de9c627", size = 221339 }, + { url = "https://files.pythonhosted.org/packages/f2/c7/f82b5be1e8456600395366f86104d1bd8d0faed3802ad511ef6d60c30d98/rpds_py-0.22.3-cp312-cp312-win_amd64.whl", hash = "sha256:d115bffdd417c6d806ea9069237a4ae02f513b778e3789a359bc5856e0404cc4", size = 235786 }, + { url = "https://files.pythonhosted.org/packages/d0/bf/36d5cc1f2c609ae6e8bf0fc35949355ca9d8790eceb66e6385680c951e60/rpds_py-0.22.3-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:ea7433ce7e4bfc3a85654aeb6747babe3f66eaf9a1d0c1e7a4435bbdf27fea84", size = 351657 }, + { url = "https://files.pythonhosted.org/packages/24/2a/f1e0fa124e300c26ea9382e59b2d582cba71cedd340f32d1447f4f29fa4e/rpds_py-0.22.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6dd9412824c4ce1aca56c47b0991e65bebb7ac3f4edccfd3f156150c96a7bf25", size = 341829 }, + { url = "https://files.pythonhosted.org/packages/cf/c2/0da1231dd16953845bed60d1a586fcd6b15ceaeb965f4d35cdc71f70f606/rpds_py-0.22.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20070c65396f7373f5df4005862fa162db5d25d56150bddd0b3e8214e8ef45b4", size = 384220 }, + { url = "https://files.pythonhosted.org/packages/c7/73/a4407f4e3a00a9d4b68c532bf2d873d6b562854a8eaff8faa6133b3588ec/rpds_py-0.22.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0b09865a9abc0ddff4e50b5ef65467cd94176bf1e0004184eb915cbc10fc05c5", size = 391009 }, + { url = "https://files.pythonhosted.org/packages/a9/c3/04b7353477ab360fe2563f5f0b176d2105982f97cd9ae80a9c5a18f1ae0f/rpds_py-0.22.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3453e8d41fe5f17d1f8e9c383a7473cd46a63661628ec58e07777c2fff7196dc", size = 426989 }, + { url = "https://files.pythonhosted.org/packages/8d/e6/e4b85b722bcf11398e17d59c0f6049d19cd606d35363221951e6d625fcb0/rpds_py-0.22.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f5d36399a1b96e1a5fdc91e0522544580dbebeb1f77f27b2b0ab25559e103b8b", size = 441544 }, + { url = "https://files.pythonhosted.org/packages/27/fc/403e65e56f65fff25f2973216974976d3f0a5c3f30e53758589b6dc9b79b/rpds_py-0.22.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:009de23c9c9ee54bf11303a966edf4d9087cd43a6003672e6aa7def643d06518", size = 385179 }, + { url = "https://files.pythonhosted.org/packages/57/9b/2be9ff9700d664d51fd96b33d6595791c496d2778cb0b2a634f048437a55/rpds_py-0.22.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1aef18820ef3e4587ebe8b3bc9ba6e55892a6d7b93bac6d29d9f631a3b4befbd", size = 415103 }, + { url = "https://files.pythonhosted.org/packages/bb/a5/03c2ad8ca10994fcf22dd2150dd1d653bc974fa82d9a590494c84c10c641/rpds_py-0.22.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f60bd8423be1d9d833f230fdbccf8f57af322d96bcad6599e5a771b151398eb2", size = 560916 }, + { url = "https://files.pythonhosted.org/packages/ba/2e/be4fdfc8b5b576e588782b56978c5b702c5a2307024120d8aeec1ab818f0/rpds_py-0.22.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:62d9cfcf4948683a18a9aff0ab7e1474d407b7bab2ca03116109f8464698ab16", size = 587062 }, + { url = "https://files.pythonhosted.org/packages/67/e0/2034c221937709bf9c542603d25ad43a68b4b0a9a0c0b06a742f2756eb66/rpds_py-0.22.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9253fc214112405f0afa7db88739294295f0e08466987f1d70e29930262b4c8f", size = 555734 }, + { url = "https://files.pythonhosted.org/packages/ea/ce/240bae07b5401a22482b58e18cfbabaa392409b2797da60223cca10d7367/rpds_py-0.22.3-cp313-cp313-win32.whl", hash = "sha256:fb0ba113b4983beac1a2eb16faffd76cb41e176bf58c4afe3e14b9c681f702de", size = 220663 }, + { url = "https://files.pythonhosted.org/packages/cb/f0/d330d08f51126330467edae2fa4efa5cec8923c87551a79299380fdea30d/rpds_py-0.22.3-cp313-cp313-win_amd64.whl", hash = "sha256:c58e2339def52ef6b71b8f36d13c3688ea23fa093353f3a4fee2556e62086ec9", size = 235503 }, + { url = "https://files.pythonhosted.org/packages/f7/c4/dbe1cc03df013bf2feb5ad00615038050e7859f381e96fb5b7b4572cd814/rpds_py-0.22.3-cp313-cp313t-macosx_10_12_x86_64.whl", hash = "sha256:f82a116a1d03628a8ace4859556fb39fd1424c933341a08ea3ed6de1edb0283b", size = 347698 }, + { url = "https://files.pythonhosted.org/packages/a4/3a/684f66dd6b0f37499cad24cd1c0e523541fd768576fa5ce2d0a8799c3cba/rpds_py-0.22.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3dfcbc95bd7992b16f3f7ba05af8a64ca694331bd24f9157b49dadeeb287493b", size = 337330 }, + { url = "https://files.pythonhosted.org/packages/82/eb/e022c08c2ce2e8f7683baa313476492c0e2c1ca97227fe8a75d9f0181e95/rpds_py-0.22.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59259dc58e57b10e7e18ce02c311804c10c5a793e6568f8af4dead03264584d1", size = 380022 }, + { url = "https://files.pythonhosted.org/packages/e4/21/5a80e653e4c86aeb28eb4fea4add1f72e1787a3299687a9187105c3ee966/rpds_py-0.22.3-cp313-cp313t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5725dd9cc02068996d4438d397e255dcb1df776b7ceea3b9cb972bdb11260a83", size = 390754 }, + { url = "https://files.pythonhosted.org/packages/37/a4/d320a04ae90f72d080b3d74597074e62be0a8ecad7d7321312dfe2dc5a6a/rpds_py-0.22.3-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:99b37292234e61325e7a5bb9689e55e48c3f5f603af88b1642666277a81f1fbd", size = 423840 }, + { url = "https://files.pythonhosted.org/packages/87/70/674dc47d93db30a6624279284e5631be4c3a12a0340e8e4f349153546728/rpds_py-0.22.3-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:27b1d3b3915a99208fee9ab092b8184c420f2905b7d7feb4aeb5e4a9c509b8a1", size = 438970 }, + { url = "https://files.pythonhosted.org/packages/3f/64/9500f4d66601d55cadd21e90784cfd5d5f4560e129d72e4339823129171c/rpds_py-0.22.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f612463ac081803f243ff13cccc648578e2279295048f2a8d5eb430af2bae6e3", size = 383146 }, + { url = "https://files.pythonhosted.org/packages/4d/45/630327addb1d17173adcf4af01336fd0ee030c04798027dfcb50106001e0/rpds_py-0.22.3-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f73d3fef726b3243a811121de45193c0ca75f6407fe66f3f4e183c983573e130", size = 408294 }, + { url = "https://files.pythonhosted.org/packages/5f/ef/8efb3373cee54ea9d9980b772e5690a0c9e9214045a4e7fa35046e399fee/rpds_py-0.22.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:3f21f0495edea7fdbaaa87e633a8689cd285f8f4af5c869f27bc8074638ad69c", size = 556345 }, + { url = "https://files.pythonhosted.org/packages/54/01/151d3b9ef4925fc8f15bfb131086c12ec3c3d6dd4a4f7589c335bf8e85ba/rpds_py-0.22.3-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:1e9663daaf7a63ceccbbb8e3808fe90415b0757e2abddbfc2e06c857bf8c5e2b", size = 582292 }, + { url = "https://files.pythonhosted.org/packages/30/89/35fc7a6cdf3477d441c7aca5e9bbf5a14e0f25152aed7f63f4e0b141045d/rpds_py-0.22.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:a76e42402542b1fae59798fab64432b2d015ab9d0c8c47ba7addddbaf7952333", size = 553855 }, + { url = "https://files.pythonhosted.org/packages/8f/e0/830c02b2457c4bd20a8c5bb394d31d81f57fbefce2dbdd2e31feff4f7003/rpds_py-0.22.3-cp313-cp313t-win32.whl", hash = "sha256:69803198097467ee7282750acb507fba35ca22cc3b85f16cf45fb01cb9097730", size = 219100 }, + { url = "https://files.pythonhosted.org/packages/f8/30/7ac943f69855c2db77407ae363484b915d861702dbba1aa82d68d57f42be/rpds_py-0.22.3-cp313-cp313t-win_amd64.whl", hash = "sha256:f5cf2a0c2bdadf3791b5c205d55a37a54025c6e18a71c71f82bb536cf9a454bf", size = 233794 }, + { url = "https://files.pythonhosted.org/packages/db/0f/a8ad17ddac7c880f48d5da50733dd25bfc35ba2be1bec9f23453e8c7a123/rpds_py-0.22.3-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:378753b4a4de2a7b34063d6f95ae81bfa7b15f2c1a04a9518e8644e81807ebea", size = 359735 }, + { url = "https://files.pythonhosted.org/packages/0c/41/430903669397ea3ee76865e0b53ea236e8dc0ffbecde47b2c4c783ad6759/rpds_py-0.22.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:3445e07bf2e8ecfeef6ef67ac83de670358abf2996916039b16a218e3d95e97e", size = 348724 }, + { url = "https://files.pythonhosted.org/packages/c9/5c/3496f4f0ee818297544f2d5f641c49dde8ae156392e6834b79c0609ba006/rpds_py-0.22.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b2513ba235829860b13faa931f3b6846548021846ac808455301c23a101689d", size = 381782 }, + { url = "https://files.pythonhosted.org/packages/b6/dc/db0523ce0cd16ce579185cc9aa9141992de956d0a9c469ecfd1fb5d54ddc/rpds_py-0.22.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:eaf16ae9ae519a0e237a0f528fd9f0197b9bb70f40263ee57ae53c2b8d48aeb3", size = 387036 }, + { url = "https://files.pythonhosted.org/packages/85/2a/9525c2427d2c257f877348918136a5d4e1b945c205a256e53bec61e54551/rpds_py-0.22.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:583f6a1993ca3369e0f80ba99d796d8e6b1a3a2a442dd4e1a79e652116413091", size = 424566 }, + { url = "https://files.pythonhosted.org/packages/b9/1c/f8c012a39794b84069635709f559c0309103d5d74b3f5013916e6ca4f174/rpds_py-0.22.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4617e1915a539a0d9a9567795023de41a87106522ff83fbfaf1f6baf8e85437e", size = 447203 }, + { url = "https://files.pythonhosted.org/packages/93/f5/c1c772364570d35b98ba64f36ec90c3c6d0b932bc4d8b9b4efef6dc64b07/rpds_py-0.22.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0c150c7a61ed4a4f4955a96626574e9baf1adf772c2fb61ef6a5027e52803543", size = 382283 }, + { url = "https://files.pythonhosted.org/packages/10/06/f94f61313f94fc75c3c3aa74563f80bbd990e5b25a7c1a38cee7d5d0309b/rpds_py-0.22.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2fa4331c200c2521512595253f5bb70858b90f750d39b8cbfd67465f8d1b596d", size = 410022 }, + { url = "https://files.pythonhosted.org/packages/3f/b0/37ab416a9528419920dfb64886c220f58fcbd66b978e0a91b66e9ee9a993/rpds_py-0.22.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:214b7a953d73b5e87f0ebece4a32a5bd83c60a3ecc9d4ec8f1dca968a2d91e99", size = 557817 }, + { url = "https://files.pythonhosted.org/packages/2c/5d/9daa18adcd676dd3b2817c8a7cec3f3ebeeb0ce0d05a1b63bf994fc5114f/rpds_py-0.22.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:f47ad3d5f3258bd7058d2d506852217865afefe6153a36eb4b6928758041d831", size = 585099 }, + { url = "https://files.pythonhosted.org/packages/41/3f/ad4e58035d3f848410aa3d59857b5f238bafab81c8b4a844281f80445d62/rpds_py-0.22.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f276b245347e6e36526cbd4a266a417796fc531ddf391e43574cf6466c492520", size = 552818 }, + { url = "https://files.pythonhosted.org/packages/b8/19/123acae8f4cab3c9463097c3ced3cc87c46f405056e249c874940e045309/rpds_py-0.22.3-cp39-cp39-win32.whl", hash = "sha256:bbb232860e3d03d544bc03ac57855cd82ddf19c7a07651a7c0fdb95e9efea8b9", size = 220246 }, + { url = "https://files.pythonhosted.org/packages/8b/8d/9db93e48d96ace1f6713c71ce72e2d94b71d82156c37b6a54e0930486f00/rpds_py-0.22.3-cp39-cp39-win_amd64.whl", hash = "sha256:cfbc454a2880389dbb9b5b398e50d439e2e58669160f27b60e5eca11f68ae17c", size = 231932 }, + { url = "https://files.pythonhosted.org/packages/8b/63/e29f8ee14fcf383574f73b6bbdcbec0fbc2e5fc36b4de44d1ac389b1de62/rpds_py-0.22.3-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:d48424e39c2611ee1b84ad0f44fb3b2b53d473e65de061e3f460fc0be5f1939d", size = 360786 }, + { url = "https://files.pythonhosted.org/packages/d3/e0/771ee28b02a24e81c8c0e645796a371350a2bb6672753144f36ae2d2afc9/rpds_py-0.22.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:24e8abb5878e250f2eb0d7859a8e561846f98910326d06c0d51381fed59357bd", size = 350589 }, + { url = "https://files.pythonhosted.org/packages/cf/49/abad4c4a1e6f3adf04785a99c247bfabe55ed868133e2d1881200aa5d381/rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b232061ca880db21fa14defe219840ad9b74b6158adb52ddf0e87bead9e8493", size = 381848 }, + { url = "https://files.pythonhosted.org/packages/3a/7d/f4bc6d6fbe6af7a0d2b5f2ee77079efef7c8528712745659ec0026888998/rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ac0a03221cdb5058ce0167ecc92a8c89e8d0decdc9e99a2ec23380793c4dcb96", size = 387879 }, + { url = "https://files.pythonhosted.org/packages/13/b0/575c797377fdcd26cedbb00a3324232e4cb2c5d121f6e4b0dbf8468b12ef/rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eb0c341fa71df5a4595f9501df4ac5abfb5a09580081dffbd1ddd4654e6e9123", size = 423916 }, + { url = "https://files.pythonhosted.org/packages/54/78/87157fa39d58f32a68d3326f8a81ad8fb99f49fe2aa7ad9a1b7d544f9478/rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bf9db5488121b596dbfc6718c76092fda77b703c1f7533a226a5a9f65248f8ad", size = 448410 }, + { url = "https://files.pythonhosted.org/packages/59/69/860f89996065a88be1b6ff2d60e96a02b920a262d8aadab99e7903986597/rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b8db6b5b2d4491ad5b6bdc2bc7c017eec108acbf4e6785f42a9eb0ba234f4c9", size = 382841 }, + { url = "https://files.pythonhosted.org/packages/bd/d7/bc144e10d27e3cb350f98df2492a319edd3caaf52ddfe1293f37a9afbfd7/rpds_py-0.22.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b3d504047aba448d70cf6fa22e06cb09f7cbd761939fdd47604f5e007675c24e", size = 409662 }, + { url = "https://files.pythonhosted.org/packages/14/2a/6bed0b05233c291a94c7e89bc76ffa1c619d4e1979fbfe5d96024020c1fb/rpds_py-0.22.3-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:e61b02c3f7a1e0b75e20c3978f7135fd13cb6cf551bf4a6d29b999a88830a338", size = 558221 }, + { url = "https://files.pythonhosted.org/packages/11/23/cd8f566de444a137bc1ee5795e47069a947e60810ba4152886fe5308e1b7/rpds_py-0.22.3-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:e35ba67d65d49080e8e5a1dd40101fccdd9798adb9b050ff670b7d74fa41c566", size = 583780 }, + { url = "https://files.pythonhosted.org/packages/8d/63/79c3602afd14d501f751e615a74a59040328da5ef29ed5754ae80d236b84/rpds_py-0.22.3-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:26fd7cac7dd51011a245f29a2cc6489c4608b5a8ce8d75661bb4a1066c52dfbe", size = 553619 }, + { url = "https://files.pythonhosted.org/packages/9f/2e/c5c1689e80298d4e94c75b70faada4c25445739d91b94c211244a3ed7ed1/rpds_py-0.22.3-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:177c7c0fce2855833819c98e43c262007f42ce86651ffbb84f37883308cb0e7d", size = 233338 }, + { url = "https://files.pythonhosted.org/packages/bc/b7/d2c205723e3b4d75b03215694f0297a1b4b395bf834cb5896ad9bbb90f90/rpds_py-0.22.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:bb47271f60660803ad11f4c61b42242b8c1312a31c98c578f79ef9387bbde21c", size = 360594 }, + { url = "https://files.pythonhosted.org/packages/d8/8f/c3515f5234cf6055046d4cfe9c80a3742a20acfa7d0b1b290f0d7f56a8db/rpds_py-0.22.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:70fb28128acbfd264eda9bf47015537ba3fe86e40d046eb2963d75024be4d055", size = 349594 }, + { url = "https://files.pythonhosted.org/packages/6b/98/5b487cb06afc484befe350c87fda37f4ce11333f04f3380aba43dcf5bce2/rpds_py-0.22.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:44d61b4b7d0c2c9ac019c314e52d7cbda0ae31078aabd0f22e583af3e0d79723", size = 381138 }, + { url = "https://files.pythonhosted.org/packages/5e/3a/12308d2c51b3fdfc173619943b7dc5ba41b4850c47112eeda38d9c54ed12/rpds_py-0.22.3-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5f0e260eaf54380380ac3808aa4ebe2d8ca28b9087cf411649f96bad6900c728", size = 387828 }, + { url = "https://files.pythonhosted.org/packages/17/b2/c242241ab5a2a206e093f24ccbfa519c4bbf10a762ac90bffe1766c225e0/rpds_py-0.22.3-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b25bc607423935079e05619d7de556c91fb6adeae9d5f80868dde3468657994b", size = 424634 }, + { url = "https://files.pythonhosted.org/packages/d5/c7/52a1b15012139f3ba740f291f1d03c6b632938ba61bc605f24c101952493/rpds_py-0.22.3-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fb6116dfb8d1925cbdb52595560584db42a7f664617a1f7d7f6e32f138cdf37d", size = 447862 }, + { url = "https://files.pythonhosted.org/packages/55/3e/4d3ed8fd01bad77e8ed101116fe63b03f1011940d9596a8f4d82ac80cacd/rpds_py-0.22.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a63cbdd98acef6570c62b92a1e43266f9e8b21e699c363c0fef13bd530799c11", size = 382506 }, + { url = "https://files.pythonhosted.org/packages/30/78/df59d6f92470a84369a3757abeae1cfd7f7239c8beb6d948949bf78317d2/rpds_py-0.22.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2b8f60e1b739a74bab7e01fcbe3dddd4657ec685caa04681df9d562ef15b625f", size = 410534 }, + { url = "https://files.pythonhosted.org/packages/38/97/ea45d1edd9b753b20084b52dd5db6ee5e1ac3e036a27149972398a413858/rpds_py-0.22.3-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:2e8b55d8517a2fda8d95cb45d62a5a8bbf9dd0ad39c5b25c8833efea07b880ca", size = 557453 }, + { url = "https://files.pythonhosted.org/packages/08/cd/3a1b35eb9da27ffbb981cfffd32a01c7655c4431ccb278cb3064f8887462/rpds_py-0.22.3-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:2de29005e11637e7a2361fa151f780ff8eb2543a0da1413bb951e9f14b699ef3", size = 584412 }, + { url = "https://files.pythonhosted.org/packages/87/91/31d1c5aeb1606f71188259e0ba6ed6f5c21a3c72f58b51db6a8bd0aa2b5d/rpds_py-0.22.3-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:666ecce376999bf619756a24ce15bb14c5bfaf04bf00abc7e663ce17c3f34fe7", size = 553446 }, + { url = "https://files.pythonhosted.org/packages/e7/ad/03b5ccd1ab492c9dece85b3bf1c96453ab8c47983936fae6880f688f60b3/rpds_py-0.22.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:5246b14ca64a8675e0a7161f7af68fe3e910e6b90542b4bfb5439ba752191df6", size = 233013 }, +] + +[[package]] +name = "ruff" +version = "0.9.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1e/7f/60fda2eec81f23f8aa7cbbfdf6ec2ca11eb11c273827933fb2541c2ce9d8/ruff-0.9.3.tar.gz", hash = "sha256:8293f89985a090ebc3ed1064df31f3b4b56320cdfcec8b60d3295bddb955c22a", size = 3586740 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/77/4fb790596d5d52c87fd55b7160c557c400e90f6116a56d82d76e95d9374a/ruff-0.9.3-py3-none-linux_armv6l.whl", hash = "sha256:7f39b879064c7d9670197d91124a75d118d00b0990586549949aae80cdc16624", size = 11656815 }, + { url = "https://files.pythonhosted.org/packages/a2/a8/3338ecb97573eafe74505f28431df3842c1933c5f8eae615427c1de32858/ruff-0.9.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:a187171e7c09efa4b4cc30ee5d0d55a8d6c5311b3e1b74ac5cb96cc89bafc43c", size = 11594821 }, + { url = "https://files.pythonhosted.org/packages/8e/89/320223c3421962762531a6b2dd58579b858ca9916fb2674874df5e97d628/ruff-0.9.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:c59ab92f8e92d6725b7ded9d4a31be3ef42688a115c6d3da9457a5bda140e2b4", size = 11040475 }, + { url = "https://files.pythonhosted.org/packages/b2/bd/1d775eac5e51409535804a3a888a9623e87a8f4b53e2491580858a083692/ruff-0.9.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2dc153c25e715be41bb228bc651c1e9b1a88d5c6e5ed0194fa0dfea02b026439", size = 11856207 }, + { url = "https://files.pythonhosted.org/packages/7f/c6/3e14e09be29587393d188454064a4aa85174910d16644051a80444e4fd88/ruff-0.9.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:646909a1e25e0dc28fbc529eab8eb7bb583079628e8cbe738192853dbbe43af5", size = 11420460 }, + { url = "https://files.pythonhosted.org/packages/ef/42/b7ca38ffd568ae9b128a2fa76353e9a9a3c80ef19746408d4ce99217ecc1/ruff-0.9.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5a5a46e09355695fbdbb30ed9889d6cf1c61b77b700a9fafc21b41f097bfbba4", size = 12605472 }, + { url = "https://files.pythonhosted.org/packages/a6/a1/3167023f23e3530fde899497ccfe239e4523854cb874458ac082992d206c/ruff-0.9.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c4bb09d2bbb394e3730d0918c00276e79b2de70ec2a5231cd4ebb51a57df9ba1", size = 13243123 }, + { url = "https://files.pythonhosted.org/packages/d0/b4/3c600758e320f5bf7de16858502e849f4216cb0151f819fa0d1154874802/ruff-0.9.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:96a87ec31dc1044d8c2da2ebbed1c456d9b561e7d087734336518181b26b3aa5", size = 12744650 }, + { url = "https://files.pythonhosted.org/packages/be/38/266fbcbb3d0088862c9bafa8b1b99486691d2945a90b9a7316336a0d9a1b/ruff-0.9.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9bb7554aca6f842645022fe2d301c264e6925baa708b392867b7a62645304df4", size = 14458585 }, + { url = "https://files.pythonhosted.org/packages/63/a6/47fd0e96990ee9b7a4abda62de26d291bd3f7647218d05b7d6d38af47c30/ruff-0.9.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cabc332b7075a914ecea912cd1f3d4370489c8018f2c945a30bcc934e3bc06a6", size = 12419624 }, + { url = "https://files.pythonhosted.org/packages/84/5d/de0b7652e09f7dda49e1a3825a164a65f4998175b6486603c7601279baad/ruff-0.9.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:33866c3cc2a575cbd546f2cd02bdd466fed65118e4365ee538a3deffd6fcb730", size = 11843238 }, + { url = "https://files.pythonhosted.org/packages/9e/be/3f341ceb1c62b565ec1fb6fd2139cc40b60ae6eff4b6fb8f94b1bb37c7a9/ruff-0.9.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:006e5de2621304c8810bcd2ee101587712fa93b4f955ed0985907a36c427e0c2", size = 11484012 }, + { url = "https://files.pythonhosted.org/packages/a3/c8/ff8acbd33addc7e797e702cf00bfde352ab469723720c5607b964491d5cf/ruff-0.9.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:ba6eea4459dbd6b1be4e6bfc766079fb9b8dd2e5a35aff6baee4d9b1514ea519", size = 12038494 }, + { url = "https://files.pythonhosted.org/packages/73/b1/8d9a2c0efbbabe848b55f877bc10c5001a37ab10aca13c711431673414e5/ruff-0.9.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:90230a6b8055ad47d3325e9ee8f8a9ae7e273078a66401ac66df68943ced029b", size = 12473639 }, + { url = "https://files.pythonhosted.org/packages/cb/44/a673647105b1ba6da9824a928634fe23186ab19f9d526d7bdf278cd27bc3/ruff-0.9.3-py3-none-win32.whl", hash = "sha256:eabe5eb2c19a42f4808c03b82bd313fc84d4e395133fb3fc1b1516170a31213c", size = 9834353 }, + { url = "https://files.pythonhosted.org/packages/c3/01/65cadb59bf8d4fbe33d1a750103e6883d9ef302f60c28b73b773092fbde5/ruff-0.9.3-py3-none-win_amd64.whl", hash = "sha256:040ceb7f20791dfa0e78b4230ee9dce23da3b64dd5848e40e3bf3ab76468dcf4", size = 10821444 }, + { url = "https://files.pythonhosted.org/packages/69/cb/b3fe58a136a27d981911cba2f18e4b29f15010623b79f0f2510fd0d31fd3/ruff-0.9.3-py3-none-win_arm64.whl", hash = "sha256:800d773f6d4d33b0a3c60e2c6ae8f4c202ea2de056365acfa519aa48acf28e0b", size = 10038168 }, +] + +[[package]] +name = "scipy" +version = "1.13.1" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version < '3.10'", + "python_full_version >= '3.10' and python_full_version < '3.13'", +] +dependencies = [ + { name = "numpy", version = "2.0.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version < '3.10'" }, + { name = "numpy", version = "2.2.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.10' and python_full_version < '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ae/00/48c2f661e2816ccf2ecd77982f6605b2950afe60f60a52b4cbbc2504aa8f/scipy-1.13.1.tar.gz", hash = "sha256:095a87a0312b08dfd6a6155cbbd310a8c51800fc931b8c0b84003014b874ed3c", size = 57210720 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/33/59/41b2529908c002ade869623b87eecff3e11e3ce62e996d0bdcb536984187/scipy-1.13.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:20335853b85e9a49ff7572ab453794298bcf0354d8068c5f6775a0eabf350aca", size = 39328076 }, + { url = "https://files.pythonhosted.org/packages/d5/33/f1307601f492f764062ce7dd471a14750f3360e33cd0f8c614dae208492c/scipy-1.13.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:d605e9c23906d1994f55ace80e0125c587f96c020037ea6aa98d01b4bd2e222f", size = 30306232 }, + { url = "https://files.pythonhosted.org/packages/c0/66/9cd4f501dd5ea03e4a4572ecd874936d0da296bd04d1c45ae1a4a75d9c3a/scipy-1.13.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cfa31f1def5c819b19ecc3a8b52d28ffdcc7ed52bb20c9a7589669dd3c250989", size = 33743202 }, + { url = "https://files.pythonhosted.org/packages/a3/ba/7255e5dc82a65adbe83771c72f384d99c43063648456796436c9a5585ec3/scipy-1.13.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f26264b282b9da0952a024ae34710c2aff7d27480ee91a2e82b7b7073c24722f", size = 38577335 }, + { url = "https://files.pythonhosted.org/packages/49/a5/bb9ded8326e9f0cdfdc412eeda1054b914dfea952bda2097d174f8832cc0/scipy-1.13.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:eccfa1906eacc02de42d70ef4aecea45415f5be17e72b61bafcfd329bdc52e94", size = 38820728 }, + { url = "https://files.pythonhosted.org/packages/12/30/df7a8fcc08f9b4a83f5f27cfaaa7d43f9a2d2ad0b6562cced433e5b04e31/scipy-1.13.1-cp310-cp310-win_amd64.whl", hash = "sha256:2831f0dc9c5ea9edd6e51e6e769b655f08ec6db6e2e10f86ef39bd32eb11da54", size = 46210588 }, + { url = "https://files.pythonhosted.org/packages/b4/15/4a4bb1b15bbd2cd2786c4f46e76b871b28799b67891f23f455323a0cdcfb/scipy-1.13.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:27e52b09c0d3a1d5b63e1105f24177e544a222b43611aaf5bc44d4a0979e32f9", size = 39333805 }, + { url = "https://files.pythonhosted.org/packages/ba/92/42476de1af309c27710004f5cdebc27bec62c204db42e05b23a302cb0c9a/scipy-1.13.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:54f430b00f0133e2224c3ba42b805bfd0086fe488835effa33fa291561932326", size = 30317687 }, + { url = "https://files.pythonhosted.org/packages/80/ba/8be64fe225360a4beb6840f3cbee494c107c0887f33350d0a47d55400b01/scipy-1.13.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e89369d27f9e7b0884ae559a3a956e77c02114cc60a6058b4e5011572eea9299", size = 33694638 }, + { url = "https://files.pythonhosted.org/packages/36/07/035d22ff9795129c5a847c64cb43c1fa9188826b59344fee28a3ab02e283/scipy-1.13.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a78b4b3345f1b6f68a763c6e25c0c9a23a9fd0f39f5f3d200efe8feda560a5fa", size = 38569931 }, + { url = "https://files.pythonhosted.org/packages/d9/10/f9b43de37e5ed91facc0cfff31d45ed0104f359e4f9a68416cbf4e790241/scipy-1.13.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:45484bee6d65633752c490404513b9ef02475b4284c4cfab0ef946def50b3f59", size = 38838145 }, + { url = "https://files.pythonhosted.org/packages/4a/48/4513a1a5623a23e95f94abd675ed91cfb19989c58e9f6f7d03990f6caf3d/scipy-1.13.1-cp311-cp311-win_amd64.whl", hash = "sha256:5713f62f781eebd8d597eb3f88b8bf9274e79eeabf63afb4a737abc6c84ad37b", size = 46196227 }, + { url = "https://files.pythonhosted.org/packages/f2/7b/fb6b46fbee30fc7051913068758414f2721003a89dd9a707ad49174e3843/scipy-1.13.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5d72782f39716b2b3509cd7c33cdc08c96f2f4d2b06d51e52fb45a19ca0c86a1", size = 39357301 }, + { url = "https://files.pythonhosted.org/packages/dc/5a/2043a3bde1443d94014aaa41e0b50c39d046dda8360abd3b2a1d3f79907d/scipy-1.13.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:017367484ce5498445aade74b1d5ab377acdc65e27095155e448c88497755a5d", size = 30363348 }, + { url = "https://files.pythonhosted.org/packages/e7/cb/26e4a47364bbfdb3b7fb3363be6d8a1c543bcd70a7753ab397350f5f189a/scipy-1.13.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:949ae67db5fa78a86e8fa644b9a6b07252f449dcf74247108c50e1d20d2b4627", size = 33406062 }, + { url = "https://files.pythonhosted.org/packages/88/ab/6ecdc526d509d33814835447bbbeedbebdec7cca46ef495a61b00a35b4bf/scipy-1.13.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de3ade0e53bc1f21358aa74ff4830235d716211d7d077e340c7349bc3542e884", size = 38218311 }, + { url = "https://files.pythonhosted.org/packages/0b/00/9f54554f0f8318100a71515122d8f4f503b1a2c4b4cfab3b4b68c0eb08fa/scipy-1.13.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:2ac65fb503dad64218c228e2dc2d0a0193f7904747db43014645ae139c8fad16", size = 38442493 }, + { url = "https://files.pythonhosted.org/packages/3e/df/963384e90733e08eac978cd103c34df181d1fec424de383cdc443f418dd4/scipy-1.13.1-cp312-cp312-win_amd64.whl", hash = "sha256:cdd7dacfb95fea358916410ec61bbc20440f7860333aee6d882bb8046264e949", size = 45910955 }, + { url = "https://files.pythonhosted.org/packages/7f/29/c2ea58c9731b9ecb30b6738113a95d147e83922986b34c685b8f6eefde21/scipy-1.13.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:436bbb42a94a8aeef855d755ce5a465479c721e9d684de76bf61a62e7c2b81d5", size = 39352927 }, + { url = "https://files.pythonhosted.org/packages/5c/c0/e71b94b20ccf9effb38d7147c0064c08c622309fd487b1b677771a97d18c/scipy-1.13.1-cp39-cp39-macosx_12_0_arm64.whl", hash = "sha256:8335549ebbca860c52bf3d02f80784e91a004b71b059e3eea9678ba994796a24", size = 30324538 }, + { url = "https://files.pythonhosted.org/packages/6d/0f/aaa55b06d474817cea311e7b10aab2ea1fd5d43bc6a2861ccc9caec9f418/scipy-1.13.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d533654b7d221a6a97304ab63c41c96473ff04459e404b83275b60aa8f4b7004", size = 33732190 }, + { url = "https://files.pythonhosted.org/packages/35/f5/d0ad1a96f80962ba65e2ce1de6a1e59edecd1f0a7b55990ed208848012e0/scipy-1.13.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:637e98dcf185ba7f8e663e122ebf908c4702420477ae52a04f9908707456ba4d", size = 38612244 }, + { url = "https://files.pythonhosted.org/packages/8d/02/1165905f14962174e6569076bcc3315809ae1291ed14de6448cc151eedfd/scipy-1.13.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a014c2b3697bde71724244f63de2476925596c24285c7a637364761f8710891c", size = 38845637 }, + { url = "https://files.pythonhosted.org/packages/3e/77/dab54fe647a08ee4253963bcd8f9cf17509c8ca64d6335141422fe2e2114/scipy-1.13.1-cp39-cp39-win_amd64.whl", hash = "sha256:392e4ec766654852c25ebad4f64e4e584cf19820b980bc04960bca0b0cd6eaa2", size = 46227440 }, +] + +[[package]] +name = "scipy" +version = "1.15.1" +source = { registry = "https://pypi.org/simple" } +resolution-markers = [ + "python_full_version >= '3.13'", +] +dependencies = [ + { name = "numpy", version = "2.2.2", source = { registry = "https://pypi.org/simple" }, marker = "python_full_version >= '3.13'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/76/c6/8eb0654ba0c7d0bb1bf67bf8fbace101a8e4f250f7722371105e8b6f68fc/scipy-1.15.1.tar.gz", hash = "sha256:033a75ddad1463970c96a88063a1df87ccfddd526437136b6ee81ff0312ebdf6", size = 59407493 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/86/53/b204ce5a4433f1864001b9d16f103b9c25f5002a602ae83585d0ea5f9c4a/scipy-1.15.1-cp310-cp310-macosx_10_13_x86_64.whl", hash = "sha256:c64ded12dcab08afff9e805a67ff4480f5e69993310e093434b10e85dc9d43e1", size = 41414518 }, + { url = "https://files.pythonhosted.org/packages/c7/fc/54ffa7a8847f7f303197a6ba65a66104724beba2e38f328135a78f0dc480/scipy-1.15.1-cp310-cp310-macosx_12_0_arm64.whl", hash = "sha256:5b190b935e7db569960b48840e5bef71dc513314cc4e79a1b7d14664f57fd4ff", size = 32519265 }, + { url = "https://files.pythonhosted.org/packages/f1/77/a98b8ba03d6f371dc31a38719affd53426d4665729dcffbed4afe296784a/scipy-1.15.1-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:4b17d4220df99bacb63065c76b0d1126d82bbf00167d1730019d2a30d6ae01ea", size = 24792859 }, + { url = "https://files.pythonhosted.org/packages/a7/78/70bb9f0df7444b18b108580934bfef774822e28fd34a68e5c263c7d2828a/scipy-1.15.1-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:63b9b6cd0333d0eb1a49de6f834e8aeaefe438df8f6372352084535ad095219e", size = 27886506 }, + { url = "https://files.pythonhosted.org/packages/14/a7/f40f6033e06de4176ddd6cc8c3ae9f10a226c3bca5d6b4ab883bc9914a14/scipy-1.15.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9f151e9fb60fbf8e52426132f473221a49362091ce7a5e72f8aa41f8e0da4f25", size = 38375041 }, + { url = "https://files.pythonhosted.org/packages/17/03/390a1c5c61fd76b0fa4b3c5aa3bdd7e60f6c46f712924f1a9df5705ec046/scipy-1.15.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:21e10b1dd56ce92fba3e786007322542361984f8463c6d37f6f25935a5a6ef52", size = 40597556 }, + { url = "https://files.pythonhosted.org/packages/4e/70/fa95b3ae026b97eeca58204a90868802e5155ac71b9d7bdee92b68115dd3/scipy-1.15.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:5dff14e75cdbcf07cdaa1c7707db6017d130f0af9ac41f6ce443a93318d6c6e0", size = 42938505 }, + { url = "https://files.pythonhosted.org/packages/d6/07/427859116bdd71847c898180f01802691f203c3e2455a1eb496130ff07c5/scipy-1.15.1-cp310-cp310-win_amd64.whl", hash = "sha256:f82fcf4e5b377f819542fbc8541f7b5fbcf1c0017d0df0bc22c781bf60abc4d8", size = 43909663 }, + { url = "https://files.pythonhosted.org/packages/8e/2e/7b71312da9c2dabff53e7c9a9d08231bc34d9d8fdabe88a6f1155b44591c/scipy-1.15.1-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:5bd8d27d44e2c13d0c1124e6a556454f52cd3f704742985f6b09e75e163d20d2", size = 41424362 }, + { url = "https://files.pythonhosted.org/packages/81/8c/ab85f1aa1cc200c796532a385b6ebf6a81089747adc1da7482a062acc46c/scipy-1.15.1-cp311-cp311-macosx_12_0_arm64.whl", hash = "sha256:be3deeb32844c27599347faa077b359584ba96664c5c79d71a354b80a0ad0ce0", size = 32535910 }, + { url = "https://files.pythonhosted.org/packages/3b/9c/6f4b787058daa8d8da21ddff881b4320e28de4704a65ec147adb50cb2230/scipy-1.15.1-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:5eb0ca35d4b08e95da99a9f9c400dc9f6c21c424298a0ba876fdc69c7afacedf", size = 24809398 }, + { url = "https://files.pythonhosted.org/packages/16/2b/949460a796df75fc7a1ee1becea202cf072edbe325ebe29f6d2029947aa7/scipy-1.15.1-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:74bb864ff7640dea310a1377d8567dc2cb7599c26a79ca852fc184cc851954ac", size = 27918045 }, + { url = "https://files.pythonhosted.org/packages/5f/36/67fe249dd7ccfcd2a38b25a640e3af7e59d9169c802478b6035ba91dfd6d/scipy-1.15.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:667f950bf8b7c3a23b4199db24cb9bf7512e27e86d0e3813f015b74ec2c6e3df", size = 38332074 }, + { url = "https://files.pythonhosted.org/packages/fc/da/452e1119e6f720df3feb588cce3c42c5e3d628d4bfd4aec097bd30b7de0c/scipy-1.15.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:395be70220d1189756068b3173853029a013d8c8dd5fd3d1361d505b2aa58fa7", size = 40588469 }, + { url = "https://files.pythonhosted.org/packages/7f/71/5f94aceeac99a4941478af94fe9f459c6752d497035b6b0761a700f5f9ff/scipy-1.15.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ce3a000cd28b4430426db2ca44d96636f701ed12e2b3ca1f2b1dd7abdd84b39a", size = 42965214 }, + { url = "https://files.pythonhosted.org/packages/af/25/caa430865749d504271757cafd24066d596217e83326155993980bc22f97/scipy-1.15.1-cp311-cp311-win_amd64.whl", hash = "sha256:3fe1d95944f9cf6ba77aa28b82dd6bb2a5b52f2026beb39ecf05304b8392864b", size = 43896034 }, + { url = "https://files.pythonhosted.org/packages/d8/6e/a9c42d0d39e09ed7fd203d0ac17adfea759cba61ab457671fe66e523dbec/scipy-1.15.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c09aa9d90f3500ea4c9b393ee96f96b0ccb27f2f350d09a47f533293c78ea776", size = 41478318 }, + { url = "https://files.pythonhosted.org/packages/04/ee/e3e535c81828618878a7433992fecc92fa4df79393f31a8fea1d05615091/scipy-1.15.1-cp312-cp312-macosx_12_0_arm64.whl", hash = "sha256:0ac102ce99934b162914b1e4a6b94ca7da0f4058b6d6fd65b0cef330c0f3346f", size = 32596696 }, + { url = "https://files.pythonhosted.org/packages/c4/5e/b1b0124be8e76f87115f16b8915003eec4b7060298117715baf13f51942c/scipy-1.15.1-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:09c52320c42d7f5c7748b69e9f0389266fd4f82cf34c38485c14ee976cb8cb04", size = 24870366 }, + { url = "https://files.pythonhosted.org/packages/14/36/c00cb73eefda85946172c27913ab995c6ad4eee00fa4f007572e8c50cd51/scipy-1.15.1-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:cdde8414154054763b42b74fe8ce89d7f3d17a7ac5dd77204f0e142cdc9239e9", size = 28007461 }, + { url = "https://files.pythonhosted.org/packages/68/94/aff5c51b3799349a9d1e67a056772a0f8a47db371e83b498d43467806557/scipy-1.15.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c9d8fc81d6a3b6844235e6fd175ee1d4c060163905a2becce8e74cb0d7554ce", size = 38068174 }, + { url = "https://files.pythonhosted.org/packages/b0/3c/0de11ca154e24a57b579fb648151d901326d3102115bc4f9a7a86526ce54/scipy-1.15.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0fb57b30f0017d4afa5fe5f5b150b8f807618819287c21cbe51130de7ccdaed2", size = 40249869 }, + { url = "https://files.pythonhosted.org/packages/15/09/472e8d0a6b33199d1bb95e49bedcabc0976c3724edd9b0ef7602ccacf41e/scipy-1.15.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:491d57fe89927fa1aafbe260f4cfa5ffa20ab9f1435025045a5315006a91b8f5", size = 42629068 }, + { url = "https://files.pythonhosted.org/packages/ff/ba/31c7a8131152822b3a2cdeba76398ffb404d81d640de98287d236da90c49/scipy-1.15.1-cp312-cp312-win_amd64.whl", hash = "sha256:900f3fa3db87257510f011c292a5779eb627043dd89731b9c461cd16ef76ab3d", size = 43621992 }, + { url = "https://files.pythonhosted.org/packages/2b/bf/dd68965a4c5138a630eeed0baec9ae96e5d598887835bdde96cdd2fe4780/scipy-1.15.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:100193bb72fbff37dbd0bf14322314fc7cbe08b7ff3137f11a34d06dc0ee6b85", size = 41441136 }, + { url = "https://files.pythonhosted.org/packages/ef/5e/4928581312922d7e4d416d74c416a660addec4dd5ea185401df2269ba5a0/scipy-1.15.1-cp313-cp313-macosx_12_0_arm64.whl", hash = "sha256:2114a08daec64980e4b4cbdf5bee90935af66d750146b1d2feb0d3ac30613692", size = 32533699 }, + { url = "https://files.pythonhosted.org/packages/32/90/03f99c43041852837686898c66767787cd41c5843d7a1509c39ffef683e9/scipy-1.15.1-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:6b3e71893c6687fc5e29208d518900c24ea372a862854c9888368c0b267387ab", size = 24807289 }, + { url = "https://files.pythonhosted.org/packages/9d/52/bfe82b42ae112eaba1af2f3e556275b8727d55ac6e4932e7aef337a9d9d4/scipy-1.15.1-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:837299eec3d19b7e042923448d17d95a86e43941104d33f00da7e31a0f715d3c", size = 27929844 }, + { url = "https://files.pythonhosted.org/packages/f6/77/54ff610bad600462c313326acdb035783accc6a3d5f566d22757ad297564/scipy-1.15.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82add84e8a9fb12af5c2c1a3a3f1cb51849d27a580cb9e6bd66226195142be6e", size = 38031272 }, + { url = "https://files.pythonhosted.org/packages/f1/26/98585cbf04c7cf503d7eb0a1966df8a268154b5d923c5fe0c1ed13154c49/scipy-1.15.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:070d10654f0cb6abd295bc96c12656f948e623ec5f9a4eab0ddb1466c000716e", size = 40210217 }, + { url = "https://files.pythonhosted.org/packages/fd/3f/3d2285eb6fece8bc5dbb2f9f94d61157d61d155e854fd5fea825b8218f12/scipy-1.15.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:55cc79ce4085c702ac31e49b1e69b27ef41111f22beafb9b49fea67142b696c4", size = 42587785 }, + { url = "https://files.pythonhosted.org/packages/48/7d/5b5251984bf0160d6533695a74a5fddb1fa36edd6f26ffa8c871fbd4782a/scipy-1.15.1-cp313-cp313-win_amd64.whl", hash = "sha256:c352c1b6d7cac452534517e022f8f7b8d139cd9f27e6fbd9f3cbd0bfd39f5bef", size = 43640439 }, + { url = "https://files.pythonhosted.org/packages/e7/b8/0e092f592d280496de52e152582030f8a270b194f87f890e1a97c5599b81/scipy-1.15.1-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:0458839c9f873062db69a03de9a9765ae2e694352c76a16be44f93ea45c28d2b", size = 41619862 }, + { url = "https://files.pythonhosted.org/packages/f6/19/0b6e1173aba4db9e0b7aa27fe45019857fb90d6904038b83927cbe0a6c1d/scipy-1.15.1-cp313-cp313t-macosx_12_0_arm64.whl", hash = "sha256:af0b61c1de46d0565b4b39c6417373304c1d4f5220004058bdad3061c9fa8a95", size = 32610387 }, + { url = "https://files.pythonhosted.org/packages/e7/02/754aae3bd1fa0f2479ade3cfdf1732ecd6b05853f63eee6066a32684563a/scipy-1.15.1-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:71ba9a76c2390eca6e359be81a3e879614af3a71dfdabb96d1d7ab33da6f2364", size = 24883814 }, + { url = "https://files.pythonhosted.org/packages/1f/ac/d7906201604a2ea3b143bb0de51b3966f66441ba50b7dc182c4505b3edf9/scipy-1.15.1-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:14eaa373c89eaf553be73c3affb11ec6c37493b7eaaf31cf9ac5dffae700c2e0", size = 27944865 }, + { url = "https://files.pythonhosted.org/packages/84/9d/8f539002b5e203723af6a6f513a45e0a7671e9dabeedb08f417ac17e4edc/scipy-1.15.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f735bc41bd1c792c96bc426dece66c8723283695f02df61dcc4d0a707a42fc54", size = 39883261 }, + { url = "https://files.pythonhosted.org/packages/97/c0/62fd3bab828bcccc9b864c5997645a3b86372a35941cdaf677565c25c98d/scipy-1.15.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2722a021a7929d21168830790202a75dbb20b468a8133c74a2c0230c72626b6c", size = 42093299 }, + { url = "https://files.pythonhosted.org/packages/e4/1f/5d46a8d94e9f6d2c913cbb109e57e7eed914de38ea99e2c4d69a9fc93140/scipy-1.15.1-cp313-cp313t-win_amd64.whl", hash = "sha256:bc7136626261ac1ed988dca56cfc4ab5180f75e0ee52e58f1e6aa74b5f3eacd5", size = 43181730 }, +] + +[[package]] +name = "screeninfo" +version = "0.8.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cython", marker = "sys_platform == 'darwin'" }, + { name = "pyobjc-framework-cocoa", marker = "sys_platform == 'darwin'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ec/bb/e69e5e628d43f118e0af4fc063c20058faa8635c95a1296764acc8167e27/screeninfo-0.8.1.tar.gz", hash = "sha256:9983076bcc7e34402a1a9e4d7dabf3729411fd2abb3f3b4be7eba73519cd2ed1", size = 10666 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6e/bf/c5205d480307bef660e56544b9e3d7ff687da776abb30c9cb3f330887570/screeninfo-0.8.1-py3-none-any.whl", hash = "sha256:e97d6b173856edcfa3bd282f81deb528188aff14b11ec3e195584e7641be733c", size = 12907 }, +] + +[[package]] +name = "send2trash" +version = "1.8.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fd/3a/aec9b02217bb79b87bbc1a21bc6abc51e3d5dcf65c30487ac96c0908c722/Send2Trash-1.8.3.tar.gz", hash = "sha256:b18e7a3966d99871aefeb00cfbcfdced55ce4871194810fc71f4aa484b953abf", size = 17394 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/b0/4562db6223154aa4e22f939003cb92514c79f3d4dccca3444253fd17f902/Send2Trash-1.8.3-py3-none-any.whl", hash = "sha256:0c31227e0bd08961c7665474a3d1ef7193929fedda4233843689baa056be46c9", size = 18072 }, +] + +[[package]] +name = "setuptools" +version = "75.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/92/ec/089608b791d210aec4e7f97488e67ab0d33add3efccb83a056cbafe3a2a6/setuptools-75.8.0.tar.gz", hash = "sha256:c5afc8f407c626b8313a86e10311dd3f661c6cd9c09d4bf8c15c0e11f9f2b0e6", size = 1343222 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/8a/b9dc7678803429e4a3bc9ba462fa3dd9066824d3c607490235c6a796be5a/setuptools-75.8.0-py3-none-any.whl", hash = "sha256:e3982f444617239225d675215d51f6ba05f845d4eec313da4418fdbb56fb27e3", size = 1228782 }, +] + +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 }, +] + +[[package]] +name = "skia-pathops" +version = "0.8.0.post2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e5/85/4c6ce1f1f3e8d3888165f2830adcf340922416c155647b12ebac2dcc423e/skia_pathops-0.8.0.post2.zip", hash = "sha256:9e252cdeb6c4d162e82986d31dbd89c675d1677cb8019c2e13e6295d4a557269", size = 66956087 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/0e/402ae71072679fc170a10fd225142f8beeaf842dcc5cfa86e46b4452a737/skia_pathops-0.8.0.post2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7cd3722709dd186bfe1934f40c1d135252017c516c9cfc11b8c35139aaa4a167", size = 3002022 }, + { url = "https://files.pythonhosted.org/packages/1a/90/869c47ef648a48bc0655db2a79210394500ad5a68d1948ac49526da53f06/skia_pathops-0.8.0.post2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:150c9b935c3fc9ca8c259ca8c08f5677863d6c70326f3bea48811caeaef49127", size = 1626106 }, + { url = "https://files.pythonhosted.org/packages/b0/9d/86edb024675441d029df76df802bfa346b19d600bf760dc4454ac3610ac9/skia_pathops-0.8.0.post2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1b4e59e9cb89c1feb8b95052e746b6501430d5f117a39014d0a1168373fcf54", size = 3119482 }, + { url = "https://files.pythonhosted.org/packages/70/07/c821dc6d43fe2ef8486d6ecf41515efef25bdbc403b971ae6e58624c979d/skia_pathops-0.8.0.post2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67dabd89b8ab7c9efddde540c0f16c762039c7f3cf6d4cc89ab94a359fe312fd", size = 3310852 }, + { url = "https://files.pythonhosted.org/packages/2a/f7/2b0b529516d2689f9d1f8a672648eaa312b22fa474af6e0dde55595bd334/skia_pathops-0.8.0.post2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:7b6bb38173a023f3232a76aa1c700a2f034b6edd1cc44693c76cf7926d941fe3", size = 4229778 }, + { url = "https://files.pythonhosted.org/packages/ae/83/efddbcbabcf7d8621b4c48628d745dc39a043b75d7f9a14e60d12840455e/skia_pathops-0.8.0.post2-cp310-cp310-win32.whl", hash = "sha256:e5e04a1818380e6ae9186a7ef41c2edcc14b2521b6c6fcfdde53b28be7a71068", size = 2333671 }, + { url = "https://files.pythonhosted.org/packages/a8/fa/d7621d7e0ebe5eeb4ffce8b56792ee86e14025eb3aa1e5263a9c456cd772/skia_pathops-0.8.0.post2-cp310-cp310-win_amd64.whl", hash = "sha256:767e1893fed727096bca20e2725c12f46a95c350b6b3cefc9ab67e55442908e4", size = 2918417 }, + { url = "https://files.pythonhosted.org/packages/93/c7/e0290393e576243f64098c7406e5713b51db9037b2d83330d5e1a267a49c/skia_pathops-0.8.0.post2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ada3230a64ccf458e5b47b05b92ad6404ae641b54784d140a02d159b01db8db1", size = 3007817 }, + { url = "https://files.pythonhosted.org/packages/34/85/9d188c73cbf0866345d0221a1396b2523cc14b796eec6b999283da09740d/skia_pathops-0.8.0.post2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8a577e6146a4edfb4dc29d973a9f42fa979aee4d498471933bac5a11fc5686d6", size = 1630046 }, + { url = "https://files.pythonhosted.org/packages/9d/fb/c1bd907d2e640a495441b61e716f7bb97052844c8407209130b39f04cc3d/skia_pathops-0.8.0.post2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ec5d532eaa341aef9b09bf7c06783803abadc8822056e44830be08285ad3c870", size = 3240720 }, + { url = "https://files.pythonhosted.org/packages/15/47/2781d154607d158174e9484ea8f0adeef89c557b6c484609c3463e6b51d4/skia_pathops-0.8.0.post2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4ce6bbdfec398ba6da48323947a8c72796a36903b8f96f6c87f9623172755c14", size = 3428850 }, + { url = "https://files.pythonhosted.org/packages/ed/d2/e156da38080011586de589a5edf83a5411aef3fba90957bc91cf2d0df3ed/skia_pathops-0.8.0.post2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f1e46df0bc41420e0271900b9c7d01104c7a5b1c33ec2d7d1759db82bc9efeab", size = 4366211 }, + { url = "https://files.pythonhosted.org/packages/4a/33/3dfbee6ee7713a2b269bf3db15ce0999c50fbf76f242208328af86b55f60/skia_pathops-0.8.0.post2-cp311-cp311-win32.whl", hash = "sha256:4435eca08149bdd1e177e172f26d65f50c8c6814e2477abc5a4e2fab44b6972e", size = 2334850 }, + { url = "https://files.pythonhosted.org/packages/52/cf/d112525535e181ee9fd9bbcf6a3a1ad886a8f6a482c417fc11212a65081c/skia_pathops-0.8.0.post2-cp311-cp311-win_amd64.whl", hash = "sha256:c7c9a17a67dcf270c3595d806a8c5996acdd09e7c966f8ed971d40f8511bbd5c", size = 2920570 }, + { url = "https://files.pythonhosted.org/packages/78/11/44eda0936802b0e5c03e8464802c148bb6951e78de7182e9b0d5a87da911/skia_pathops-0.8.0.post2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:aa11950fda8d390fe074cb0a83ac0d8a95f72087b0a38add30b9f22c3591554e", size = 3005903 }, + { url = "https://files.pythonhosted.org/packages/f8/c9/a79b33aab717860474442e07af19af3db544abd46770678942a94df2aafe/skia_pathops-0.8.0.post2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:496def3492582161ce95a43b2c539af8b219c60fba223b25e8eef1ac8f9ee3d7", size = 1628147 }, + { url = "https://files.pythonhosted.org/packages/ab/09/84dc64eea93a143fc69e979c2cbbc12321e041b8c60d64fbb5c363bfe9ba/skia_pathops-0.8.0.post2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d4f3da50b749141caf6f17f032d2e3aae5faec96e39ed9c94e6b55e6e3a3a1c7", size = 3183562 }, + { url = "https://files.pythonhosted.org/packages/18/ce/1f209dcd78696ce2c7b35f546f076d8e8290aad0c7f07556ed6050c616f0/skia_pathops-0.8.0.post2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:89f82f2273208f72403da8dc7457d64fbd3f7d8f1f7f54cb8483eeda00747933", size = 3381577 }, + { url = "https://files.pythonhosted.org/packages/8b/d3/158d818a16140a39cf004f3182c400fb00292bbcf0f28df03636897ccae0/skia_pathops-0.8.0.post2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:153055698053539b439720643a045ec3a50c35ea66bca7d89977e66a0d68282a", size = 4467350 }, + { url = "https://files.pythonhosted.org/packages/03/2a/dc0f09610a0edcc299f539980e4a2aba57d114ba3ae4ab7295412cd4d2e3/skia_pathops-0.8.0.post2-cp312-cp312-win32.whl", hash = "sha256:575061162264edd3c707e375c0fca85e7f72f5fada2e42c26853a6551c47e076", size = 2331316 }, + { url = "https://files.pythonhosted.org/packages/3c/4c/c489eab40cd0f43c1b84b3053835c268b782d565d09197ad37bf723a2ff7/skia_pathops-0.8.0.post2-cp312-cp312-win_amd64.whl", hash = "sha256:6f2f60feceb7213a80ab7824f0c7e41de3c26a29a3a1ab8a1f60ec750292b444", size = 2916619 }, + { url = "https://files.pythonhosted.org/packages/ee/bd/3036a1229952b8d96e1a5c32626d9aa0fa4cdfc9d2868829c2ab93828f75/skia_pathops-0.8.0.post2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:4059d5c54dc4d2686e3b54c347fa1aad48ef6a0bc12ca75a27a260b291a98238", size = 3001951 }, + { url = "https://files.pythonhosted.org/packages/db/30/51a5e15e05d56278393666ab6ca5e43a7fc6822f2372d565f71e247af0bb/skia_pathops-0.8.0.post2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:c0db10dfb00a1093a72e56827c172e3ca4922762f4c321d6ccc0703bc201b966", size = 1626535 }, + { url = "https://files.pythonhosted.org/packages/22/f3/78f942c0fdabb6da1c16b1a415c98efd256caa2191838045c9e7317218cb/skia_pathops-0.8.0.post2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ddb5b52fae729ea456e777e715d17f25940e53bbd0ca0fad8b1e6268c7f493be", size = 3177784 }, + { url = "https://files.pythonhosted.org/packages/6a/ff/0095a0313416c68df090c29f250c900f4dba4d68b4750bcd463f9ca1c52a/skia_pathops-0.8.0.post2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7db6b12d5cd85d0dec27f8f4ff41f8e2befa76a40170cda9715f98d2002d0da1", size = 3375866 }, + { url = "https://files.pythonhosted.org/packages/12/56/a5ef7bb7fac2bbddb0937187cf1283deaee33002056bed8304d499534ea6/skia_pathops-0.8.0.post2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ae0a7937f6160247515a272f36598e35abb700ae4f1b5adec2e8119fcd535dcb", size = 4463385 }, + { url = "https://files.pythonhosted.org/packages/25/21/ab107c2cf99f047c77a01ef9b564f393a6ada8585d3337b1dcdd8488abee/skia_pathops-0.8.0.post2-cp313-cp313-win32.whl", hash = "sha256:20e759441ce209e0fe026900057ac846e6912e7112b81229c330a6ad1e550efb", size = 2330817 }, + { url = "https://files.pythonhosted.org/packages/db/ca/cf1b0938a249d02f0b9245a3105faa1a01dd909e7cafee50c2d50899051b/skia_pathops-0.8.0.post2-cp313-cp313-win_amd64.whl", hash = "sha256:1753fd7b4151c9ae3e5f198227ab39598a60be90c7ccc5c796a6ca5ef26d24d6", size = 2916031 }, + { url = "https://files.pythonhosted.org/packages/54/99/48ce2febf47d38f14aea0ec33495634b17bbaced62a282460fa6cca4d432/skia_pathops-0.8.0.post2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:2ef2e8892083bf91de0914615f25c5d0b2392c25fad5a06df3ff39e56b933130", size = 3002645 }, + { url = "https://files.pythonhosted.org/packages/98/d6/4fb390ea31a2953cd06e0aec8dc79127ed6b6343d10c327937f08f74f84c/skia_pathops-0.8.0.post2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:d3306e4adc525ecc8e8847e52086df1fb990444de2af79b0ec1ccc2c59f2919c", size = 1626505 }, + { url = "https://files.pythonhosted.org/packages/b0/a7/670a0136283c0342858b11747a7a34ce3b0b6fc1bb74c6a4273ce3e7bb64/skia_pathops-0.8.0.post2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b7ce8b2b9f3417b20a83fb9194b40ea32dc4aeb50ba7d59ff23ef889406cd35b", size = 3120579 }, + { url = "https://files.pythonhosted.org/packages/a1/19/78ede09db0e7015439dcd436820d39aab33fe022adbda69c9ff0c222aac2/skia_pathops-0.8.0.post2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:96bf52955047e00cafb2899725d0585b19a6ce07fe8f566d7d736262843f8b34", size = 3310866 }, + { url = "https://files.pythonhosted.org/packages/31/ac/b1a307d7111e2f625ad8d7550fb6608523dc146562f1c56c1105efb9693c/skia_pathops-0.8.0.post2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c576a0d077eeb319e8f95d6043bccfbc3c1b320ec809a79b56f3c66e35a563a8", size = 4229826 }, + { url = "https://files.pythonhosted.org/packages/11/8a/e7fcdbb6bc0c491d7a69677f62c4efd42019fdd8ebbb8e242a390b9d970c/skia_pathops-0.8.0.post2-cp39-cp39-win32.whl", hash = "sha256:343a2c83c07d5764f28233d8bda7cf07b444586d748e5560b45e295465cf05c1", size = 2333816 }, + { url = "https://files.pythonhosted.org/packages/c0/42/8da52ae5a0228f7a550d98d4c4d9ffb4909041b4e3b4c82068778d368845/skia_pathops-0.8.0.post2-cp39-cp39-win_amd64.whl", hash = "sha256:4c486a4d800e3685974a0cc8f5fd0486a01edfd355a5c2327e796b6e48f269c7", size = 2918657 }, + { url = "https://files.pythonhosted.org/packages/89/44/7405af0f71dbd66f2728cbaab6bac5d26e767e309156abe561eb174fbf7b/skia_pathops-0.8.0.post2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ee98a3affee6bb13998828f5565cbb9fd7c52120b71310098bd2764cbd4fa6ad", size = 2286478 }, + { url = "https://files.pythonhosted.org/packages/f5/16/d7b5bcd3b01398380abbe1c7bbaf7ff5562441462464786044cb6ce748ed/skia_pathops-0.8.0.post2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8983fba1b163a65438c51a3fb34c95e27652aad92d900d348bcc81babff3434", size = 2286366 }, +] + +[[package]] +name = "smmap" +version = "5.0.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/44/cd/a040c4b3119bbe532e5b0732286f805445375489fceaec1f48306068ee3b/smmap-5.0.2.tar.gz", hash = "sha256:26ea65a03958fa0c8a1c7e8c7a58fdc77221b8910f6be2131affade476898ad5", size = 22329 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/be/d09147ad1ec7934636ad912901c5fd7667e1c858e19d355237db0d0cd5e4/smmap-5.0.2-py3-none-any.whl", hash = "sha256:b30115f0def7d7531d22a0fb6502488d879e75b260a9db4d0819cfb25403af5e", size = 24303 }, +] + +[[package]] +name = "sniffio" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 }, +] + +[[package]] +name = "snowballstemmer" +version = "2.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/44/7b/af302bebf22c749c56c9c3e8ae13190b5b5db37a33d9068652e8f73b7089/snowballstemmer-2.2.0.tar.gz", hash = "sha256:09b16deb8547d3412ad7b590689584cd0fe25ec8db3be37788be3810cbf19cb1", size = 86699 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ed/dc/c02e01294f7265e63a7315fe086dd1df7dacb9f840a804da846b96d01b96/snowballstemmer-2.2.0-py2.py3-none-any.whl", hash = "sha256:c8e1716e83cc398ae16824e5572ae04e0d9fc2c6b985fb0f900f5f0c96ecba1a", size = 93002 }, +] + +[[package]] +name = "soupsieve" +version = "2.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/ce/fbaeed4f9fb8b2daa961f90591662df6a86c1abf25c548329a86920aedfb/soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb", size = 101569 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/c2/fe97d779f3ef3b15f05c94a2f1e3d21732574ed441687474db9d342a7315/soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9", size = 36186 }, +] + +[[package]] +name = "sphinx" +version = "7.4.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "alabaster" }, + { name = "babel" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "docutils" }, + { name = "imagesize" }, + { name = "importlib-metadata", marker = "python_full_version < '3.10'" }, + { name = "jinja2" }, + { name = "packaging" }, + { name = "pygments" }, + { name = "requests" }, + { name = "snowballstemmer" }, + { name = "sphinxcontrib-applehelp" }, + { name = "sphinxcontrib-devhelp" }, + { name = "sphinxcontrib-htmlhelp" }, + { name = "sphinxcontrib-jsmath" }, + { name = "sphinxcontrib-qthelp" }, + { name = "sphinxcontrib-serializinghtml" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5b/be/50e50cb4f2eff47df05673d361095cafd95521d2a22521b920c67a372dcb/sphinx-7.4.7.tar.gz", hash = "sha256:242f92a7ea7e6c5b406fdc2615413890ba9f699114a9c09192d7dfead2ee9cfe", size = 8067911 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0d/ef/153f6803c5d5f8917dbb7f7fcf6d34a871ede3296fa89c2c703f5f8a6c8e/sphinx-7.4.7-py3-none-any.whl", hash = "sha256:c2419e2135d11f1951cd994d6eb18a1835bd8fdd8429f9ca375dc1f3281bd239", size = 3401624 }, +] + +[[package]] +name = "sphinx-basic-ng" +version = "1.0.0b2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/98/0b/a866924ded68efec7a1759587a4e478aec7559d8165fac8b2ad1c0e774d6/sphinx_basic_ng-1.0.0b2.tar.gz", hash = "sha256:9ec55a47c90c8c002b5960c57492ec3021f5193cb26cebc2dc4ea226848651c9", size = 20736 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/dd/018ce05c532a22007ac58d4f45232514cd9d6dd0ee1dc374e309db830983/sphinx_basic_ng-1.0.0b2-py3-none-any.whl", hash = "sha256:eb09aedbabfb650607e9b4b68c9d240b90b1e1be221d6ad71d61c52e29f7932b", size = 22496 }, +] + +[[package]] +name = "sphinx-copybutton" +version = "0.5.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fc/2b/a964715e7f5295f77509e59309959f4125122d648f86b4fe7d70ca1d882c/sphinx-copybutton-0.5.2.tar.gz", hash = "sha256:4cf17c82fb9646d1bc9ca92ac280813a3b605d8c421225fd9913154103ee1fbd", size = 23039 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/48/1ea60e74949eecb12cdd6ac43987f9fd331156388dcc2319b45e2ebb81bf/sphinx_copybutton-0.5.2-py3-none-any.whl", hash = "sha256:fb543fd386d917746c9a2c50360c7905b605726b9355cd26e9974857afeae06e", size = 13343 }, +] + +[[package]] +name = "sphinx-design" +version = "0.6.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2b/69/b34e0cb5336f09c6866d53b4a19d76c227cdec1bbc7ac4de63ca7d58c9c7/sphinx_design-0.6.1.tar.gz", hash = "sha256:b44eea3719386d04d765c1a8257caca2b3e6f8421d7b3a5e742c0fd45f84e632", size = 2193689 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c6/43/65c0acbd8cc6f50195a3a1fc195c404988b15c67090e73c7a41a9f57d6bd/sphinx_design-0.6.1-py3-none-any.whl", hash = "sha256:b11f37db1a802a183d61b159d9a202314d4d2fe29c163437001324fe2f19549c", size = 2215338 }, +] + +[[package]] +name = "sphinx-reredirects" +version = "0.1.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f9/1d/b1229d825a418738ce1a03930629a7b873cd6a0ff05953493604de35a3d5/sphinx_reredirects-0.1.5.tar.gz", hash = "sha256:cfa753b441020a22708ce8eb17d4fd553a28fc87a609330092917ada2a6da0d8", size = 7095 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/34/97/1f8143f87330f4c9ccc2c08ae9cd3cb1ce2944c51e98dd7ff141154fbcc7/sphinx_reredirects-0.1.5-py3-none-any.whl", hash = "sha256:444ae1438fba4418242ca76d6a6de3eaee82aaf0d8f2b0cac71a15d32ce6eba2", size = 5673 }, +] + +[[package]] +name = "sphinxcontrib-applehelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ba/6e/b837e84a1a704953c62ef8776d45c3e8d759876b4a84fe14eba2859106fe/sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1", size = 20053 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5", size = 119300 }, +] + +[[package]] +name = "sphinxcontrib-devhelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/d2/5beee64d3e4e747f316bae86b55943f51e82bb86ecd325883ef65741e7da/sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad", size = 12967 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/35/7a/987e583882f985fe4d7323774889ec58049171828b58c2217e7f79cdf44e/sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2", size = 82530 }, +] + +[[package]] +name = "sphinxcontrib-htmlhelp" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/93/983afd9aa001e5201eab16b5a444ed5b9b0a7a010541e0ddfbbfd0b2470c/sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9", size = 22617 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0a/7b/18a8c0bcec9182c05a0b3ec2a776bba4ead82750a55ff798e8d406dae604/sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8", size = 98705 }, +] + +[[package]] +name = "sphinxcontrib-jsmath" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/e8/9ed3830aeed71f17c026a07a5097edcf44b692850ef215b161b8ad875729/sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8", size = 5787 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/42/4c8646762ee83602e3fb3fbe774c2fac12f317deb0b5dbeeedd2d3ba4b77/sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178", size = 5071 }, +] + +[[package]] +name = "sphinxcontrib-programoutput" +version = "0.18" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3f/c0/834af2290f8477213ec0dd60e90104f5644aa0c37b1a0d6f0a2b5efe03c4/sphinxcontrib_programoutput-0.18.tar.gz", hash = "sha256:09e68b6411d937a80b6085f4fdeaa42e0dc5555480385938465f410589d2eed8", size = 26333 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/2c/7aec6e0580f666d4f61474a50c4995a98abfff27d827f0e7bc8c4fa528f5/sphinxcontrib_programoutput-0.18-py3-none-any.whl", hash = "sha256:8a651bc85de69a808a064ff0e48d06c12b9347da4fe5fdb1e94914b01e1b0c36", size = 20346 }, +] + +[[package]] +name = "sphinxcontrib-qthelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/68/bc/9104308fc285eb3e0b31b67688235db556cd5b0ef31d96f30e45f2e51cae/sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab", size = 17165 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb", size = 88743 }, +] + +[[package]] +name = "sphinxcontrib-serializinghtml" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3b/44/6716b257b0aa6bfd51a1b31665d1c205fb12cb5ad56de752dfa15657de2f/sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d", size = 16080 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331", size = 92072 }, +] + +[[package]] +name = "sphinxext-opengraph" +version = "0.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1c/5b/4302fe33c88dbfb572e2c1cad26735164c23f16fb8dba94ddb1867d0ef06/sphinxext-opengraph-0.9.1.tar.gz", hash = "sha256:dd2868a1e7c9497977fbbf44cc0844a42af39ca65fe1bb0272518af225d06fc5", size = 1034511 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/92/0a/970b80b4fa1feeb6deb6f2e22d4cb14e388b27b315a1afdb9db930ff91a4/sphinxext_opengraph-0.9.1-py3-none-any.whl", hash = "sha256:b3b230cc6a5b5189139df937f0d9c7b23c7c204493b22646273687969dcb760e", size = 1005241 }, +] + +[[package]] +name = "srt" +version = "3.5.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/66/b7/4a1bc231e0681ebf339337b0cd05b91dc6a0d701fa852bb812e244b7a030/srt-3.5.3.tar.gz", hash = "sha256:4884315043a4f0740fd1f878ed6caa376ac06d70e135f306a6dc44632eed0cc0", size = 28296 } + +[[package]] +name = "stack-data" +version = "0.6.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "asttokens" }, + { name = "executing" }, + { name = "pure-eval" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/28/e3/55dcc2cfbc3ca9c29519eb6884dd1415ecb53b0e934862d3559ddcb7e20b/stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9", size = 44707 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521 }, +] + +[[package]] +name = "svgelements" +version = "1.9.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5d/29/1c93c94a2289675ba2ff898612f9c9a03f46d69f253bdf4da0dfc08a599d/svgelements-1.9.6.tar.gz", hash = "sha256:7c02ad6404cd3d1771fd50e40fbfc0550b0893933466f86a6eb815f3ba3f37f7", size = 162145 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/2c/6c9bb53db56c8a12a736d2158a8b842a5993b96daabc29d90a098e840280/svgelements-1.9.6-py2.py3-none-any.whl", hash = "sha256:8a5cf2cc066d98e713d5b875b1d6e5eeb9b92e855e835ebd7caab2713ae1dcad", size = 137856 }, +] + +[[package]] +name = "terminado" +version = "0.18.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ptyprocess", marker = "os_name != 'nt'" }, + { name = "pywinpty", marker = "os_name == 'nt'" }, + { name = "tornado" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8a/11/965c6fd8e5cc254f1fe142d547387da17a8ebfd75a3455f637c663fb38a0/terminado-0.18.1.tar.gz", hash = "sha256:de09f2c4b85de4765f7714688fff57d3e75bad1f909b589fde880460c753fd2e", size = 32701 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/9e/2064975477fdc887e47ad42157e214526dcad8f317a948dee17e1659a62f/terminado-0.18.1-py3-none-any.whl", hash = "sha256:a4468e1b37bb318f8a86514f65814e1afc977cf29b3992a4500d9dd305dcceb0", size = 14154 }, +] + +[[package]] +name = "tinycss2" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "webencodings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7a/fd/7a5ee21fd08ff70d3d33a5781c255cbe779659bd03278feb98b19ee550f4/tinycss2-1.4.0.tar.gz", hash = "sha256:10c0972f6fc0fbee87c3edb76549357415e94548c1ae10ebccdea16fb404a9b7", size = 87085 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e6/34/ebdc18bae6aa14fbee1a08b63c015c72b64868ff7dae68808ab500c492e2/tinycss2-1.4.0-py3-none-any.whl", hash = "sha256:3a49cf47b7675da0b15d0c6e1df8df4ebd96e9394bb905a5775adb0d884c5289", size = 26610 }, +] + +[[package]] +name = "tomli" +version = "2.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077 }, + { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429 }, + { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067 }, + { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030 }, + { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898 }, + { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894 }, + { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319 }, + { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273 }, + { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310 }, + { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309 }, + { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762 }, + { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453 }, + { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486 }, + { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349 }, + { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159 }, + { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243 }, + { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645 }, + { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584 }, + { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875 }, + { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418 }, + { url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708 }, + { url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582 }, + { url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543 }, + { url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691 }, + { url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170 }, + { url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530 }, + { url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666 }, + { url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954 }, + { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724 }, + { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383 }, + { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257 }, +] + +[[package]] +name = "tornado" +version = "6.4.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/59/45/a0daf161f7d6f36c3ea5fc0c2de619746cc3dd4c76402e9db545bd920f63/tornado-6.4.2.tar.gz", hash = "sha256:92bad5b4746e9879fd7bf1eb21dce4e3fc5128d71601f80005afa39237ad620b", size = 501135 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/26/7e/71f604d8cea1b58f82ba3590290b66da1e72d840aeb37e0d5f7291bd30db/tornado-6.4.2-cp38-abi3-macosx_10_9_universal2.whl", hash = "sha256:e828cce1123e9e44ae2a50a9de3055497ab1d0aeb440c5ac23064d9e44880da1", size = 436299 }, + { url = "https://files.pythonhosted.org/packages/96/44/87543a3b99016d0bf54fdaab30d24bf0af2e848f1d13d34a3a5380aabe16/tornado-6.4.2-cp38-abi3-macosx_10_9_x86_64.whl", hash = "sha256:072ce12ada169c5b00b7d92a99ba089447ccc993ea2143c9ede887e0937aa803", size = 434253 }, + { url = "https://files.pythonhosted.org/packages/cb/fb/fdf679b4ce51bcb7210801ef4f11fdac96e9885daa402861751353beea6e/tornado-6.4.2-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a017d239bd1bb0919f72af256a970624241f070496635784d9bf0db640d3fec", size = 437602 }, + { url = "https://files.pythonhosted.org/packages/4f/3b/e31aeffffc22b475a64dbeb273026a21b5b566f74dee48742817626c47dc/tornado-6.4.2-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c36e62ce8f63409301537222faffcef7dfc5284f27eec227389f2ad11b09d946", size = 436972 }, + { url = "https://files.pythonhosted.org/packages/22/55/b78a464de78051a30599ceb6983b01d8f732e6f69bf37b4ed07f642ac0fc/tornado-6.4.2-cp38-abi3-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bca9eb02196e789c9cb5c3c7c0f04fb447dc2adffd95265b2c7223a8a615ccbf", size = 437173 }, + { url = "https://files.pythonhosted.org/packages/79/5e/be4fb0d1684eb822c9a62fb18a3e44a06188f78aa466b2ad991d2ee31104/tornado-6.4.2-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:304463bd0772442ff4d0f5149c6f1c2135a1fae045adf070821c6cdc76980634", size = 437892 }, + { url = "https://files.pythonhosted.org/packages/f5/33/4f91fdd94ea36e1d796147003b490fe60a0215ac5737b6f9c65e160d4fe0/tornado-6.4.2-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:c82c46813ba483a385ab2a99caeaedf92585a1f90defb5693351fa7e4ea0bf73", size = 437334 }, + { url = "https://files.pythonhosted.org/packages/2b/ae/c1b22d4524b0e10da2f29a176fb2890386f7bd1f63aacf186444873a88a0/tornado-6.4.2-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:932d195ca9015956fa502c6b56af9eb06106140d844a335590c1ec7f5277d10c", size = 437261 }, + { url = "https://files.pythonhosted.org/packages/b5/25/36dbd49ab6d179bcfc4c6c093a51795a4f3bed380543a8242ac3517a1751/tornado-6.4.2-cp38-abi3-win32.whl", hash = "sha256:2876cef82e6c5978fde1e0d5b1f919d756968d5b4282418f3146b79b58556482", size = 438463 }, + { url = "https://files.pythonhosted.org/packages/61/cc/58b1adeb1bb46228442081e746fcdbc4540905c87e8add7c277540934edb/tornado-6.4.2-cp38-abi3-win_amd64.whl", hash = "sha256:908b71bf3ff37d81073356a5fadcc660eb10c1476ee6e2725588626ce7e5ca38", size = 438907 }, +] + +[[package]] +name = "tqdm" +version = "4.67.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a8/4b/29b4ef32e036bb34e4ab51796dd745cdba7ed47ad142a9f4a1eb8e0c744d/tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2", size = 169737 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/30/dc54f88dd4a2b5dc8a0279bdd7270e735851848b762aeb1c1184ed1f6b14/tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2", size = 78540 }, +] + +[[package]] +name = "traitlets" +version = "5.14.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/eb/79/72064e6a701c2183016abbbfedaba506d81e30e232a68c9f0d6f6fcd1574/traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7", size = 161621 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/00/c0/8f5d070730d7836adc9c9b6408dec68c6ced86b304a9b26a14df072a6e8c/traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f", size = 85359 }, +] + +[[package]] +name = "types-decorator" +version = "5.1.8.20250121" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f4/e6/88de14bb1d1073495b9d9459f90fbb78fe93d89beefcf0af94b871993a56/types_decorator-5.1.8.20250121.tar.gz", hash = "sha256:1b89bb1c481a1d3399e28f1aa3459366b76dde951490992ae8475ba91287cd04", size = 8496 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/0e/59b9637fa66fbe419886b17d59b90e5e4256325c01f94f81dcc44fbeda53/types_decorator-5.1.8.20250121-py3-none-any.whl", hash = "sha256:6bfd5f4464f444a1ee0aea92705ed8466d74c0ddd7ade4bbd003c235db51d21a", size = 8078 }, +] + +[[package]] +name = "types-docutils" +version = "0.21.0.20241128" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/dd/df/64e7ab01a4fc5ce46895dc94e31cffc8b8087c8d91ee54c45ac2d8d82445/types_docutils-0.21.0.20241128.tar.gz", hash = "sha256:4dd059805b83ac6ec5a223699195c4e9eeb0446a4f7f2aeff1759a4a7cc17473", size = 26739 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/59/b6/10ba95739f2cbb9c5bd2f6568148d62b468afe01a94c633e8892a2936d8a/types_docutils-0.21.0.20241128-py3-none-any.whl", hash = "sha256:e0409204009639e9b0bf4521eeabe58b5e574ce9c0db08421c2ac26c32be0039", size = 34677 }, +] + +[[package]] +name = "types-pillow" +version = "10.2.0.20240822" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/4a/4495264dddaa600d65d68bcedb64dcccf9d9da61adff51f7d2ffd8e4c9ce/types-Pillow-10.2.0.20240822.tar.gz", hash = "sha256:559fb52a2ef991c326e4a0d20accb3bb63a7ba8d40eb493e0ecb0310ba52f0d3", size = 35389 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/66/23/e81a5354859831fcf54d488d33b80ba6133ea84f874a9c0ec40a4881e133/types_Pillow-10.2.0.20240822-py3-none-any.whl", hash = "sha256:d9dab025aba07aeb12fd50a6799d4eac52a9603488eca09d7662543983f16c5d", size = 54354 }, +] + +[[package]] +name = "types-pygments" +version = "2.19.0.20250107" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "types-docutils" }, + { name = "types-setuptools" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3c/d8/9e0ed97a3ca6143c74347bc32a2499809bc83039b115d0138e502679f4e8/types_pygments-2.19.0.20250107.tar.gz", hash = "sha256:94de72c7f09b956c518f566e056812c698272a7a03a9cd81f0065576c6bd3219", size = 18309 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/e2/0777eed72b5cec191168b37522fbbe831c8353fe6655c3f29a0454f73498/types_Pygments-2.19.0.20250107-py3-none-any.whl", hash = "sha256:34a555ed327f249daed18c6309e6e62770cdb8b9c321029ba7fd852d10b16f10", size = 25548 }, +] + +[[package]] +name = "types-python-dateutil" +version = "2.9.0.20241206" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/60/47d92293d9bc521cd2301e423a358abfac0ad409b3a1606d8fbae1321961/types_python_dateutil-2.9.0.20241206.tar.gz", hash = "sha256:18f493414c26ffba692a72369fea7a154c502646301ebfe3d56a04b3767284cb", size = 13802 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0f/b3/ca41df24db5eb99b00d97f89d7674a90cb6b3134c52fb8121b6d8d30f15c/types_python_dateutil-2.9.0.20241206-py3-none-any.whl", hash = "sha256:e248a4bc70a486d3e3ec84d0dc30eec3a5f979d6e7ee4123ae043eedbb987f53", size = 14384 }, +] + +[[package]] +name = "types-setuptools" +version = "75.8.0.20250110" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f7/42/5713e90d4f9683f2301d900f33e4fc2405ad8ac224dda30f6cb7f4cd215b/types_setuptools-75.8.0.20250110.tar.gz", hash = "sha256:96f7ec8bbd6e0a54ea180d66ad68ad7a1d7954e7281a710ea2de75e355545271", size = 48185 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cf/a3/dbfd106751b11c728cec21cc62cbfe7ff7391b935c4b6e8f0bdc2e6fd541/types_setuptools-75.8.0.20250110-py3-none-any.whl", hash = "sha256:a9f12980bbf9bcdc23ecd80755789085bad6bfce4060c2275bc2b4ca9f2bc480", size = 71521 }, +] + +[[package]] +name = "typing-extensions" +version = "4.12.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 }, +] + +[[package]] +name = "uri-template" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/31/c7/0336f2bd0bcbada6ccef7aaa25e443c118a704f828a0620c6fa0207c1b64/uri-template-1.3.0.tar.gz", hash = "sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7", size = 21678 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl", hash = "sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363", size = 11140 }, +] + +[[package]] +name = "urllib3" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/aa/63/e53da845320b757bf29ef6a9062f5c669fe997973f966045cb019c3f4b66/urllib3-2.3.0.tar.gz", hash = "sha256:f8c5449b3cf0861679ce7e0503c7b44b5ec981bec0d1d3795a07f1ba96f0204d", size = 307268 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c8/19/4ec628951a74043532ca2cf5d97b7b14863931476d117c471e8e2b1eb39f/urllib3-2.3.0-py3-none-any.whl", hash = "sha256:1cee9ad369867bfdbbb48b7dd50374c0967a0bb7710050facf0dd6911440e3df", size = 128369 }, +] + +[[package]] +name = "virtualenv" +version = "20.29.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "distlib" }, + { name = "filelock" }, + { name = "platformdirs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a7/ca/f23dcb02e161a9bba141b1c08aa50e8da6ea25e6d780528f1d385a3efe25/virtualenv-20.29.1.tar.gz", hash = "sha256:b8b8970138d32fb606192cb97f6cd4bb644fa486be9308fb9b63f81091b5dc35", size = 7658028 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/9b/599bcfc7064fbe5740919e78c5df18e5dceb0887e676256a1061bb5ae232/virtualenv-20.29.1-py3-none-any.whl", hash = "sha256:4e4cb403c0b0da39e13b46b1b2476e505cb0046b25f242bee80f62bf990b2779", size = 4282379 }, +] + +[[package]] +name = "watchdog" +version = "6.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", size = 131220 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/56/90994d789c61df619bfc5ce2ecdabd5eeff564e1eb47512bd01b5e019569/watchdog-6.0.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:d1cdb490583ebd691c012b3d6dae011000fe42edb7a82ece80965b42abd61f26", size = 96390 }, + { url = "https://files.pythonhosted.org/packages/55/46/9a67ee697342ddf3c6daa97e3a587a56d6c4052f881ed926a849fcf7371c/watchdog-6.0.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bc64ab3bdb6a04d69d4023b29422170b74681784ffb9463ed4870cf2f3e66112", size = 88389 }, + { url = "https://files.pythonhosted.org/packages/44/65/91b0985747c52064d8701e1075eb96f8c40a79df889e59a399453adfb882/watchdog-6.0.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c897ac1b55c5a1461e16dae288d22bb2e412ba9807df8397a635d88f671d36c3", size = 89020 }, + { url = "https://files.pythonhosted.org/packages/e0/24/d9be5cd6642a6aa68352ded4b4b10fb0d7889cb7f45814fb92cecd35f101/watchdog-6.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6eb11feb5a0d452ee41f824e271ca311a09e250441c262ca2fd7ebcf2461a06c", size = 96393 }, + { url = "https://files.pythonhosted.org/packages/63/7a/6013b0d8dbc56adca7fdd4f0beed381c59f6752341b12fa0886fa7afc78b/watchdog-6.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2", size = 88392 }, + { url = "https://files.pythonhosted.org/packages/d1/40/b75381494851556de56281e053700e46bff5b37bf4c7267e858640af5a7f/watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c", size = 89019 }, + { url = "https://files.pythonhosted.org/packages/39/ea/3930d07dafc9e286ed356a679aa02d777c06e9bfd1164fa7c19c288a5483/watchdog-6.0.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948", size = 96471 }, + { url = "https://files.pythonhosted.org/packages/12/87/48361531f70b1f87928b045df868a9fd4e253d9ae087fa4cf3f7113be363/watchdog-6.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860", size = 88449 }, + { url = "https://files.pythonhosted.org/packages/5b/7e/8f322f5e600812e6f9a31b75d242631068ca8f4ef0582dd3ae6e72daecc8/watchdog-6.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0", size = 89054 }, + { url = "https://files.pythonhosted.org/packages/68/98/b0345cabdce2041a01293ba483333582891a3bd5769b08eceb0d406056ef/watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c", size = 96480 }, + { url = "https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134", size = 88451 }, + { url = "https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b", size = 89057 }, + { url = "https://files.pythonhosted.org/packages/05/52/7223011bb760fce8ddc53416beb65b83a3ea6d7d13738dde75eeb2c89679/watchdog-6.0.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:e6f0e77c9417e7cd62af82529b10563db3423625c5fce018430b249bf977f9e8", size = 96390 }, + { url = "https://files.pythonhosted.org/packages/9c/62/d2b21bc4e706d3a9d467561f487c2938cbd881c69f3808c43ac1ec242391/watchdog-6.0.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:90c8e78f3b94014f7aaae121e6b909674df5b46ec24d6bebc45c44c56729af2a", size = 88386 }, + { url = "https://files.pythonhosted.org/packages/ea/22/1c90b20eda9f4132e4603a26296108728a8bfe9584b006bd05dd94548853/watchdog-6.0.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e7631a77ffb1f7d2eefa4445ebbee491c720a5661ddf6df3498ebecae5ed375c", size = 89017 }, + { url = "https://files.pythonhosted.org/packages/30/ad/d17b5d42e28a8b91f8ed01cb949da092827afb9995d4559fd448d0472763/watchdog-6.0.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:c7ac31a19f4545dd92fc25d200694098f42c9a8e391bc00bdd362c5736dbf881", size = 87902 }, + { url = "https://files.pythonhosted.org/packages/5c/ca/c3649991d140ff6ab67bfc85ab42b165ead119c9e12211e08089d763ece5/watchdog-6.0.0-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:9513f27a1a582d9808cf21a07dae516f0fab1cf2d7683a742c498b93eedabb11", size = 88380 }, + { url = "https://files.pythonhosted.org/packages/5b/79/69f2b0e8d3f2afd462029031baafb1b75d11bb62703f0e1022b2e54d49ee/watchdog-6.0.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:7a0e56874cfbc4b9b05c60c8a1926fedf56324bb08cfbc188969777940aef3aa", size = 87903 }, + { url = "https://files.pythonhosted.org/packages/e2/2b/dc048dd71c2e5f0f7ebc04dd7912981ec45793a03c0dc462438e0591ba5d/watchdog-6.0.0-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:e6439e374fc012255b4ec786ae3c4bc838cd7309a540e5fe0952d03687d8804e", size = 88381 }, + { url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079 }, + { url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078 }, + { url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076 }, + { url = "https://files.pythonhosted.org/packages/ab/cc/da8422b300e13cb187d2203f20b9253e91058aaf7db65b74142013478e66/watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f", size = 79077 }, + { url = "https://files.pythonhosted.org/packages/2c/3b/b8964e04ae1a025c44ba8e4291f86e97fac443bca31de8bd98d3263d2fcf/watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26", size = 79078 }, + { url = "https://files.pythonhosted.org/packages/62/ae/a696eb424bedff7407801c257d4b1afda455fe40821a2be430e173660e81/watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c", size = 79077 }, + { url = "https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2", size = 79078 }, + { url = "https://files.pythonhosted.org/packages/07/f6/d0e5b343768e8bcb4cda79f0f2f55051bf26177ecd5651f84c07567461cf/watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a", size = 79065 }, + { url = "https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680", size = 79070 }, + { url = "https://files.pythonhosted.org/packages/33/e8/e40370e6d74ddba47f002a32919d91310d6074130fe4e17dabcafc15cbf1/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", size = 79067 }, +] + +[[package]] +name = "wcwidth" +version = "0.2.13" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6c/63/53559446a878410fc5a5974feb13d31d78d752eb18aeba59c7fef1af7598/wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5", size = 101301 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fd/84/fd2ba7aafacbad3c4201d395674fc6348826569da3c0937e75505ead3528/wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", size = 34166 }, +] + +[[package]] +name = "webcolors" +version = "24.11.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7b/29/061ec845fb58521848f3739e466efd8250b4b7b98c1b6c5bf4d40b419b7e/webcolors-24.11.1.tar.gz", hash = "sha256:ecb3d768f32202af770477b8b65f318fa4f566c22948673a977b00d589dd80f6", size = 45064 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/e8/c0e05e4684d13459f93d312077a9a2efbe04d59c393bc2b8802248c908d4/webcolors-24.11.1-py3-none-any.whl", hash = "sha256:515291393b4cdf0eb19c155749a096f779f7d909f7cceea072791cb9095b92e9", size = 14934 }, +] + +[[package]] +name = "webencodings" +version = "0.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0b/02/ae6ceac1baeda530866a85075641cec12989bd8d31af6d5ab4a3e8c92f47/webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923", size = 9721 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", size = 11774 }, +] + +[[package]] +name = "websocket-client" +version = "1.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e6/30/fba0d96b4b5fbf5948ed3f4681f7da2f9f64512e1d303f94b4cc174c24a5/websocket_client-1.8.0.tar.gz", hash = "sha256:3239df9f44da632f96012472805d40a23281a991027ce11d2f45a6f24ac4c3da", size = 54648 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/84/44687a29792a70e111c5c477230a72c4b957d88d16141199bf9acb7537a3/websocket_client-1.8.0-py3-none-any.whl", hash = "sha256:17b44cc997f5c498e809b22cdf2d9c7a9e71c02c8cc2b6c56e7c2d1239bfa526", size = 58826 }, +] + +[[package]] +name = "wrapt" +version = "1.17.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/fc/e91cc220803d7bc4db93fb02facd8461c37364151b8494762cc88b0fbcef/wrapt-1.17.2.tar.gz", hash = "sha256:41388e9d4d1522446fe79d3213196bd9e3b301a336965b9e27ca2788ebd122f3", size = 55531 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/d1/1daec934997e8b160040c78d7b31789f19b122110a75eca3d4e8da0049e1/wrapt-1.17.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:3d57c572081fed831ad2d26fd430d565b76aa277ed1d30ff4d40670b1c0dd984", size = 53307 }, + { url = "https://files.pythonhosted.org/packages/1b/7b/13369d42651b809389c1a7153baa01d9700430576c81a2f5c5e460df0ed9/wrapt-1.17.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:b5e251054542ae57ac7f3fba5d10bfff615b6c2fb09abeb37d2f1463f841ae22", size = 38486 }, + { url = "https://files.pythonhosted.org/packages/62/bf/e0105016f907c30b4bd9e377867c48c34dc9c6c0c104556c9c9126bd89ed/wrapt-1.17.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:80dd7db6a7cb57ffbc279c4394246414ec99537ae81ffd702443335a61dbf3a7", size = 38777 }, + { url = "https://files.pythonhosted.org/packages/27/70/0f6e0679845cbf8b165e027d43402a55494779295c4b08414097b258ac87/wrapt-1.17.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0a6e821770cf99cc586d33833b2ff32faebdbe886bd6322395606cf55153246c", size = 83314 }, + { url = "https://files.pythonhosted.org/packages/0f/77/0576d841bf84af8579124a93d216f55d6f74374e4445264cb378a6ed33eb/wrapt-1.17.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b60fb58b90c6d63779cb0c0c54eeb38941bae3ecf7a73c764c52c88c2dcb9d72", size = 74947 }, + { url = "https://files.pythonhosted.org/packages/90/ec/00759565518f268ed707dcc40f7eeec38637d46b098a1f5143bff488fe97/wrapt-1.17.2-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b870b5df5b71d8c3359d21be8f0d6c485fa0ebdb6477dda51a1ea54a9b558061", size = 82778 }, + { url = "https://files.pythonhosted.org/packages/f8/5a/7cffd26b1c607b0b0c8a9ca9d75757ad7620c9c0a9b4a25d3f8a1480fafc/wrapt-1.17.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:4011d137b9955791f9084749cba9a367c68d50ab8d11d64c50ba1688c9b457f2", size = 81716 }, + { url = "https://files.pythonhosted.org/packages/7e/09/dccf68fa98e862df7e6a60a61d43d644b7d095a5fc36dbb591bbd4a1c7b2/wrapt-1.17.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:1473400e5b2733e58b396a04eb7f35f541e1fb976d0c0724d0223dd607e0f74c", size = 74548 }, + { url = "https://files.pythonhosted.org/packages/b7/8e/067021fa3c8814952c5e228d916963c1115b983e21393289de15128e867e/wrapt-1.17.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:3cedbfa9c940fdad3e6e941db7138e26ce8aad38ab5fe9dcfadfed9db7a54e62", size = 81334 }, + { url = "https://files.pythonhosted.org/packages/4b/0d/9d4b5219ae4393f718699ca1c05f5ebc0c40d076f7e65fd48f5f693294fb/wrapt-1.17.2-cp310-cp310-win32.whl", hash = "sha256:582530701bff1dec6779efa00c516496968edd851fba224fbd86e46cc6b73563", size = 36427 }, + { url = "https://files.pythonhosted.org/packages/72/6a/c5a83e8f61aec1e1aeef939807602fb880e5872371e95df2137142f5c58e/wrapt-1.17.2-cp310-cp310-win_amd64.whl", hash = "sha256:58705da316756681ad3c9c73fd15499aa4d8c69f9fd38dc8a35e06c12468582f", size = 38774 }, + { url = "https://files.pythonhosted.org/packages/cd/f7/a2aab2cbc7a665efab072344a8949a71081eed1d2f451f7f7d2b966594a2/wrapt-1.17.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ff04ef6eec3eee8a5efef2401495967a916feaa353643defcc03fc74fe213b58", size = 53308 }, + { url = "https://files.pythonhosted.org/packages/50/ff/149aba8365fdacef52b31a258c4dc1c57c79759c335eff0b3316a2664a64/wrapt-1.17.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4db983e7bca53819efdbd64590ee96c9213894272c776966ca6306b73e4affda", size = 38488 }, + { url = "https://files.pythonhosted.org/packages/65/46/5a917ce85b5c3b490d35c02bf71aedaa9f2f63f2d15d9949cc4ba56e8ba9/wrapt-1.17.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9abc77a4ce4c6f2a3168ff34b1da9b0f311a8f1cfd694ec96b0603dff1c79438", size = 38776 }, + { url = "https://files.pythonhosted.org/packages/ca/74/336c918d2915a4943501c77566db41d1bd6e9f4dbc317f356b9a244dfe83/wrapt-1.17.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b929ac182f5ace000d459c59c2c9c33047e20e935f8e39371fa6e3b85d56f4a", size = 83776 }, + { url = "https://files.pythonhosted.org/packages/09/99/c0c844a5ccde0fe5761d4305485297f91d67cf2a1a824c5f282e661ec7ff/wrapt-1.17.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f09b286faeff3c750a879d336fb6d8713206fc97af3adc14def0cdd349df6000", size = 75420 }, + { url = "https://files.pythonhosted.org/packages/b4/b0/9fc566b0fe08b282c850063591a756057c3247b2362b9286429ec5bf1721/wrapt-1.17.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7ed2d9d039bd41e889f6fb9364554052ca21ce823580f6a07c4ec245c1f5d6", size = 83199 }, + { url = "https://files.pythonhosted.org/packages/9d/4b/71996e62d543b0a0bd95dda485219856def3347e3e9380cc0d6cf10cfb2f/wrapt-1.17.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:129a150f5c445165ff941fc02ee27df65940fcb8a22a61828b1853c98763a64b", size = 82307 }, + { url = "https://files.pythonhosted.org/packages/39/35/0282c0d8789c0dc9bcc738911776c762a701f95cfe113fb8f0b40e45c2b9/wrapt-1.17.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1fb5699e4464afe5c7e65fa51d4f99e0b2eadcc176e4aa33600a3df7801d6662", size = 75025 }, + { url = "https://files.pythonhosted.org/packages/4f/6d/90c9fd2c3c6fee181feecb620d95105370198b6b98a0770cba090441a828/wrapt-1.17.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9a2bce789a5ea90e51a02dfcc39e31b7f1e662bc3317979aa7e5538e3a034f72", size = 81879 }, + { url = "https://files.pythonhosted.org/packages/8f/fa/9fb6e594f2ce03ef03eddbdb5f4f90acb1452221a5351116c7c4708ac865/wrapt-1.17.2-cp311-cp311-win32.whl", hash = "sha256:4afd5814270fdf6380616b321fd31435a462019d834f83c8611a0ce7484c7317", size = 36419 }, + { url = "https://files.pythonhosted.org/packages/47/f8/fb1773491a253cbc123c5d5dc15c86041f746ed30416535f2a8df1f4a392/wrapt-1.17.2-cp311-cp311-win_amd64.whl", hash = "sha256:acc130bc0375999da18e3d19e5a86403667ac0c4042a094fefb7eec8ebac7cf3", size = 38773 }, + { url = "https://files.pythonhosted.org/packages/a1/bd/ab55f849fd1f9a58ed7ea47f5559ff09741b25f00c191231f9f059c83949/wrapt-1.17.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d5e2439eecc762cd85e7bd37161d4714aa03a33c5ba884e26c81559817ca0925", size = 53799 }, + { url = "https://files.pythonhosted.org/packages/53/18/75ddc64c3f63988f5a1d7e10fb204ffe5762bc663f8023f18ecaf31a332e/wrapt-1.17.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3fc7cb4c1c744f8c05cd5f9438a3caa6ab94ce8344e952d7c45a8ed59dd88392", size = 38821 }, + { url = "https://files.pythonhosted.org/packages/48/2a/97928387d6ed1c1ebbfd4efc4133a0633546bec8481a2dd5ec961313a1c7/wrapt-1.17.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8fdbdb757d5390f7c675e558fd3186d590973244fab0c5fe63d373ade3e99d40", size = 38919 }, + { url = "https://files.pythonhosted.org/packages/73/54/3bfe5a1febbbccb7a2f77de47b989c0b85ed3a6a41614b104204a788c20e/wrapt-1.17.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bb1d0dbf99411f3d871deb6faa9aabb9d4e744d67dcaaa05399af89d847a91d", size = 88721 }, + { url = "https://files.pythonhosted.org/packages/25/cb/7262bc1b0300b4b64af50c2720ef958c2c1917525238d661c3e9a2b71b7b/wrapt-1.17.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d18a4865f46b8579d44e4fe1e2bcbc6472ad83d98e22a26c963d46e4c125ef0b", size = 80899 }, + { url = "https://files.pythonhosted.org/packages/2a/5a/04cde32b07a7431d4ed0553a76fdb7a61270e78c5fd5a603e190ac389f14/wrapt-1.17.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc570b5f14a79734437cb7b0500376b6b791153314986074486e0b0fa8d71d98", size = 89222 }, + { url = "https://files.pythonhosted.org/packages/09/28/2e45a4f4771fcfb109e244d5dbe54259e970362a311b67a965555ba65026/wrapt-1.17.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6d9187b01bebc3875bac9b087948a2bccefe464a7d8f627cf6e48b1bbae30f82", size = 86707 }, + { url = "https://files.pythonhosted.org/packages/c6/d2/dcb56bf5f32fcd4bd9aacc77b50a539abdd5b6536872413fd3f428b21bed/wrapt-1.17.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:9e8659775f1adf02eb1e6f109751268e493c73716ca5761f8acb695e52a756ae", size = 79685 }, + { url = "https://files.pythonhosted.org/packages/80/4e/eb8b353e36711347893f502ce91c770b0b0929f8f0bed2670a6856e667a9/wrapt-1.17.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e8b2816ebef96d83657b56306152a93909a83f23994f4b30ad4573b00bd11bb9", size = 87567 }, + { url = "https://files.pythonhosted.org/packages/17/27/4fe749a54e7fae6e7146f1c7d914d28ef599dacd4416566c055564080fe2/wrapt-1.17.2-cp312-cp312-win32.whl", hash = "sha256:468090021f391fe0056ad3e807e3d9034e0fd01adcd3bdfba977b6fdf4213ea9", size = 36672 }, + { url = "https://files.pythonhosted.org/packages/15/06/1dbf478ea45c03e78a6a8c4be4fdc3c3bddea5c8de8a93bc971415e47f0f/wrapt-1.17.2-cp312-cp312-win_amd64.whl", hash = "sha256:ec89ed91f2fa8e3f52ae53cd3cf640d6feff92ba90d62236a81e4e563ac0e991", size = 38865 }, + { url = "https://files.pythonhosted.org/packages/ce/b9/0ffd557a92f3b11d4c5d5e0c5e4ad057bd9eb8586615cdaf901409920b14/wrapt-1.17.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6ed6ffac43aecfe6d86ec5b74b06a5be33d5bb9243d055141e8cabb12aa08125", size = 53800 }, + { url = "https://files.pythonhosted.org/packages/c0/ef/8be90a0b7e73c32e550c73cfb2fa09db62234227ece47b0e80a05073b375/wrapt-1.17.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:35621ae4c00e056adb0009f8e86e28eb4a41a4bfa8f9bfa9fca7d343fe94f998", size = 38824 }, + { url = "https://files.pythonhosted.org/packages/36/89/0aae34c10fe524cce30fe5fc433210376bce94cf74d05b0d68344c8ba46e/wrapt-1.17.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a604bf7a053f8362d27eb9fefd2097f82600b856d5abe996d623babd067b1ab5", size = 38920 }, + { url = "https://files.pythonhosted.org/packages/3b/24/11c4510de906d77e0cfb5197f1b1445d4fec42c9a39ea853d482698ac681/wrapt-1.17.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cbabee4f083b6b4cd282f5b817a867cf0b1028c54d445b7ec7cfe6505057cf8", size = 88690 }, + { url = "https://files.pythonhosted.org/packages/71/d7/cfcf842291267bf455b3e266c0c29dcb675b5540ee8b50ba1699abf3af45/wrapt-1.17.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49703ce2ddc220df165bd2962f8e03b84c89fee2d65e1c24a7defff6f988f4d6", size = 80861 }, + { url = "https://files.pythonhosted.org/packages/d5/66/5d973e9f3e7370fd686fb47a9af3319418ed925c27d72ce16b791231576d/wrapt-1.17.2-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8112e52c5822fc4253f3901b676c55ddf288614dc7011634e2719718eaa187dc", size = 89174 }, + { url = "https://files.pythonhosted.org/packages/a7/d3/8e17bb70f6ae25dabc1aaf990f86824e4fd98ee9cadf197054e068500d27/wrapt-1.17.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:9fee687dce376205d9a494e9c121e27183b2a3df18037f89d69bd7b35bcf59e2", size = 86721 }, + { url = "https://files.pythonhosted.org/packages/6f/54/f170dfb278fe1c30d0ff864513cff526d624ab8de3254b20abb9cffedc24/wrapt-1.17.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:18983c537e04d11cf027fbb60a1e8dfd5190e2b60cc27bc0808e653e7b218d1b", size = 79763 }, + { url = "https://files.pythonhosted.org/packages/4a/98/de07243751f1c4a9b15c76019250210dd3486ce098c3d80d5f729cba029c/wrapt-1.17.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:703919b1633412ab54bcf920ab388735832fdcb9f9a00ae49387f0fe67dad504", size = 87585 }, + { url = "https://files.pythonhosted.org/packages/f9/f0/13925f4bd6548013038cdeb11ee2cbd4e37c30f8bfd5db9e5a2a370d6e20/wrapt-1.17.2-cp313-cp313-win32.whl", hash = "sha256:abbb9e76177c35d4e8568e58650aa6926040d6a9f6f03435b7a522bf1c487f9a", size = 36676 }, + { url = "https://files.pythonhosted.org/packages/bf/ae/743f16ef8c2e3628df3ddfd652b7d4c555d12c84b53f3d8218498f4ade9b/wrapt-1.17.2-cp313-cp313-win_amd64.whl", hash = "sha256:69606d7bb691b50a4240ce6b22ebb319c1cfb164e5f6569835058196e0f3a845", size = 38871 }, + { url = "https://files.pythonhosted.org/packages/3d/bc/30f903f891a82d402ffb5fda27ec1d621cc97cb74c16fea0b6141f1d4e87/wrapt-1.17.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:4a721d3c943dae44f8e243b380cb645a709ba5bd35d3ad27bc2ed947e9c68192", size = 56312 }, + { url = "https://files.pythonhosted.org/packages/8a/04/c97273eb491b5f1c918857cd26f314b74fc9b29224521f5b83f872253725/wrapt-1.17.2-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:766d8bbefcb9e00c3ac3b000d9acc51f1b399513f44d77dfe0eb026ad7c9a19b", size = 40062 }, + { url = "https://files.pythonhosted.org/packages/4e/ca/3b7afa1eae3a9e7fefe499db9b96813f41828b9fdb016ee836c4c379dadb/wrapt-1.17.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e496a8ce2c256da1eb98bd15803a79bee00fc351f5dfb9ea82594a3f058309e0", size = 40155 }, + { url = "https://files.pythonhosted.org/packages/89/be/7c1baed43290775cb9030c774bc53c860db140397047cc49aedaf0a15477/wrapt-1.17.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40d615e4fe22f4ad3528448c193b218e077656ca9ccb22ce2cb20db730f8d306", size = 113471 }, + { url = "https://files.pythonhosted.org/packages/32/98/4ed894cf012b6d6aae5f5cc974006bdeb92f0241775addad3f8cd6ab71c8/wrapt-1.17.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a5aaeff38654462bc4b09023918b7f21790efb807f54c000a39d41d69cf552cb", size = 101208 }, + { url = "https://files.pythonhosted.org/packages/ea/fd/0c30f2301ca94e655e5e057012e83284ce8c545df7661a78d8bfca2fac7a/wrapt-1.17.2-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a7d15bbd2bc99e92e39f49a04653062ee6085c0e18b3b7512a4f2fe91f2d681", size = 109339 }, + { url = "https://files.pythonhosted.org/packages/75/56/05d000de894c4cfcb84bcd6b1df6214297b8089a7bd324c21a4765e49b14/wrapt-1.17.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:e3890b508a23299083e065f435a492b5435eba6e304a7114d2f919d400888cc6", size = 110232 }, + { url = "https://files.pythonhosted.org/packages/53/f8/c3f6b2cf9b9277fb0813418e1503e68414cd036b3b099c823379c9575e6d/wrapt-1.17.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:8c8b293cd65ad716d13d8dd3624e42e5a19cc2a2f1acc74b30c2c13f15cb61a6", size = 100476 }, + { url = "https://files.pythonhosted.org/packages/a7/b1/0bb11e29aa5139d90b770ebbfa167267b1fc548d2302c30c8f7572851738/wrapt-1.17.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4c82b8785d98cdd9fed4cac84d765d234ed3251bd6afe34cb7ac523cb93e8b4f", size = 106377 }, + { url = "https://files.pythonhosted.org/packages/6a/e1/0122853035b40b3f333bbb25f1939fc1045e21dd518f7f0922b60c156f7c/wrapt-1.17.2-cp313-cp313t-win32.whl", hash = "sha256:13e6afb7fe71fe7485a4550a8844cc9ffbe263c0f1a1eea569bc7091d4898555", size = 37986 }, + { url = "https://files.pythonhosted.org/packages/09/5e/1655cf481e079c1f22d0cabdd4e51733679932718dc23bf2db175f329b76/wrapt-1.17.2-cp313-cp313t-win_amd64.whl", hash = "sha256:eaf675418ed6b3b31c7a989fd007fa7c3be66ce14e5c3b27336383604c9da85c", size = 40750 }, + { url = "https://files.pythonhosted.org/packages/8a/f4/6ed2b8f6f1c832933283974839b88ec7c983fd12905e01e97889dadf7559/wrapt-1.17.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:99039fa9e6306880572915728d7f6c24a86ec57b0a83f6b2491e1d8ab0235b9a", size = 53308 }, + { url = "https://files.pythonhosted.org/packages/a2/a9/712a53f8f4f4545768ac532619f6e56d5d0364a87b2212531685e89aeef8/wrapt-1.17.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2696993ee1eebd20b8e4ee4356483c4cb696066ddc24bd70bcbb80fa56ff9061", size = 38489 }, + { url = "https://files.pythonhosted.org/packages/fa/9b/e172c8f28a489a2888df18f953e2f6cb8d33b1a2e78c9dfc52d8bf6a5ead/wrapt-1.17.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:612dff5db80beef9e649c6d803a8d50c409082f1fedc9dbcdfde2983b2025b82", size = 38776 }, + { url = "https://files.pythonhosted.org/packages/cf/cb/7a07b51762dcd59bdbe07aa97f87b3169766cadf240f48d1cbe70a1be9db/wrapt-1.17.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62c2caa1585c82b3f7a7ab56afef7b3602021d6da34fbc1cf234ff139fed3cd9", size = 83050 }, + { url = "https://files.pythonhosted.org/packages/a5/51/a42757dd41032afd6d8037617aa3bc6803ba971850733b24dfb7d5c627c4/wrapt-1.17.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c958bcfd59bacc2d0249dcfe575e71da54f9dcf4a8bdf89c4cb9a68a1170d73f", size = 74718 }, + { url = "https://files.pythonhosted.org/packages/bf/bb/d552bfe47db02fcfc950fc563073a33500f8108efa5f7b41db2f83a59028/wrapt-1.17.2-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc78a84e2dfbc27afe4b2bd7c80c8db9bca75cc5b85df52bfe634596a1da846b", size = 82590 }, + { url = "https://files.pythonhosted.org/packages/77/99/77b06b3c3c410dbae411105bf22496facf03a5496bfaca8fbcf9da381889/wrapt-1.17.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:ba0f0eb61ef00ea10e00eb53a9129501f52385c44853dbd6c4ad3f403603083f", size = 81462 }, + { url = "https://files.pythonhosted.org/packages/2d/21/cf0bd85ae66f92600829ea1de8e1da778e5e9f6e574ccbe74b66db0d95db/wrapt-1.17.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:1e1fe0e6ab7775fd842bc39e86f6dcfc4507ab0ffe206093e76d61cde37225c8", size = 74309 }, + { url = "https://files.pythonhosted.org/packages/6d/16/112d25e9092398a0dd6fec50ab7ac1b775a0c19b428f049785096067ada9/wrapt-1.17.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:c86563182421896d73858e08e1db93afdd2b947a70064b813d515d66549e15f9", size = 81081 }, + { url = "https://files.pythonhosted.org/packages/2b/49/364a615a0cc0872685646c495c7172e4fc7bf1959e3b12a1807a03014e05/wrapt-1.17.2-cp39-cp39-win32.whl", hash = "sha256:f393cda562f79828f38a819f4788641ac7c4085f30f1ce1a68672baa686482bb", size = 36423 }, + { url = "https://files.pythonhosted.org/packages/00/ad/5d2c1b34ba3202cd833d9221833e74d6500ce66730974993a8dc9a94fb8c/wrapt-1.17.2-cp39-cp39-win_amd64.whl", hash = "sha256:36ccae62f64235cf8ddb682073a60519426fdd4725524ae38874adf72b5f2aeb", size = 38772 }, + { url = "https://files.pythonhosted.org/packages/2d/82/f56956041adef78f849db6b289b282e72b55ab8045a75abad81898c28d19/wrapt-1.17.2-py3-none-any.whl", hash = "sha256:b18f2d1533a71f069c7f82d524a52599053d4c7166e9dd374ae2136b7f40f7c8", size = 23594 }, +] + +[[package]] +name = "zipp" +version = "3.21.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3f/50/bad581df71744867e9468ebd0bcd6505de3b275e06f202c2cb016e3ff56f/zipp-3.21.0.tar.gz", hash = "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4", size = 24545 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/1a/7e4798e9339adc931158c9d69ecc34f5e6791489d469f5e50ec15e35f458/zipp-3.21.0-py3-none-any.whl", hash = "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931", size = 9630 }, +]