From 95f129ddcc3950d0b6a21581a3b60fe3138c9893 Mon Sep 17 00:00:00 2001 From: coordt Date: Fri, 15 Dec 2023 16:33:02 +0000 Subject: [PATCH] deploy: d5d02e2709d87ff200683b6c6f404cd35a674c1d --- _modules/bumpversion/aliases.html | 63 ++- _modules/bumpversion/autocast.html | 66 ++- _modules/bumpversion/bump.html | 84 ++-- _modules/bumpversion/config.html | 65 ++- _modules/bumpversion/config/files.html | 225 +++------ _modules/bumpversion/config/files_legacy.html | 424 +++++++++++++++++ _modules/bumpversion/config/models.html | 173 +++++-- _modules/bumpversion/config/utils.html | 65 +-- _modules/bumpversion/exceptions.html | 91 ++-- _modules/bumpversion/files.html | 345 ++++++++------ _modules/bumpversion/functions.html | 82 ++-- _modules/bumpversion/indented_logger.html | 385 +++++++++++++++ _modules/bumpversion/scm.html | 197 +++++--- _modules/bumpversion/show.html | 76 +-- _modules/bumpversion/ui.html | 78 +-- _modules/bumpversion/utils.html | 81 ++-- _modules/bumpversion/version_part.html | 166 +++++-- _modules/bumpversion/yaml_dump.html | 117 +++-- _modules/index.html | 48 +- .../bumpversion/bumpversion.aliases.md.txt | 2 +- .../bumpversion/bumpversion.bump.md.txt | 2 +- .../bumpversion/bumpversion.cli.md.txt | 2 +- .../bumpversion.config.files.md.txt | 26 +- .../bumpversion.config.files_legacy.md.txt | 64 +++ .../bumpversion/bumpversion.config.md.txt | 5 +- .../bumpversion.config.models.md.txt | 125 +++-- .../bumpversion.config.utils.md.txt | 4 +- .../bumpversion/bumpversion.files.md.txt | 44 +- .../bumpversion/bumpversion.functions.md.txt | 2 +- .../bumpversion.indented_logger.md.txt | 112 +++++ .../reference/bumpversion/bumpversion.md.txt | 17 +- .../bumpversion/bumpversion.scm.md.txt | 2 +- .../bumpversion/bumpversion.ui.md.txt | 13 +- .../bumpversion.version_part.md.txt | 4 +- .../bumpversion/bumpversion.yaml_dump.md.txt | 12 +- _static/basic.css | 22 + _static/documentation_options.js | 3 +- _static/pygments.css | 3 + _static/searchtools.js | 26 +- _static/sphinx_highlight.js | 16 +- _static/styles/furo.css | 2 +- _static/styles/furo.css.map | 2 +- changelog.html | 439 ++++++++--------- contributing.html | 86 ++-- explanation/index.html | 54 ++- genindex.html | 144 ++++-- howtos/avoid-incorrect-replacements.html | 62 +-- howtos/custom-version-formats-by-file.html | 62 +-- howtos/index.html | 48 +- howtos/multiple-replacements.html | 58 +-- index.html | 89 ++-- objects.inv | Bin 5721 -> 5965 bytes py-modindex.html | 58 ++- readme.html | 72 +-- .../bumpversion/bumpversion.__main__.html | 58 +-- .../bumpversion/bumpversion.aliases.html | 67 +-- .../bumpversion/bumpversion.autocast.html | 72 +-- reference/bumpversion/bumpversion.bump.html | 72 +-- reference/bumpversion/bumpversion.cli.html | 78 +-- .../bumpversion/bumpversion.config.files.html | 114 ++--- .../bumpversion.config.files_legacy.html | 405 ++++++++++++++++ reference/bumpversion/bumpversion.config.html | 77 +-- .../bumpversion.config.models.html | 252 ++++++---- .../bumpversion/bumpversion.config.utils.html | 66 +-- .../bumpversion/bumpversion.exceptions.html | 80 ++-- reference/bumpversion/bumpversion.files.html | 154 +++--- .../bumpversion/bumpversion.functions.html | 86 ++-- reference/bumpversion/bumpversion.html | 80 ++-- .../bumpversion.indented_logger.html | 446 ++++++++++++++++++ reference/bumpversion/bumpversion.scm.html | 154 +++--- reference/bumpversion/bumpversion.show.html | 76 +-- reference/bumpversion/bumpversion.ui.html | 98 ++-- reference/bumpversion/bumpversion.utils.html | 74 +-- .../bumpversion/bumpversion.version_part.html | 116 ++--- .../bumpversion/bumpversion.yaml_dump.html | 102 ++-- reference/cli.html | 210 +++++---- reference/configuration.html | 166 +++---- reference/formatting-context.html | 58 +-- reference/index.html | 68 +-- reference/search-and-replace-config.html | 80 ++-- reference/version-parts.html | 110 ++--- search.html | 44 +- searchindex.js | 2 +- tutorials/index.html | 48 +- tutorials/semantic-versioning-example.html | 52 +- usage.html | 58 +-- 86 files changed, 5303 insertions(+), 2833 deletions(-) create mode 100644 _modules/bumpversion/config/files_legacy.html create mode 100644 _modules/bumpversion/indented_logger.html create mode 100644 _sources/reference/bumpversion/bumpversion.config.files_legacy.md.txt create mode 100644 _sources/reference/bumpversion/bumpversion.indented_logger.md.txt create mode 100644 reference/bumpversion/bumpversion.config.files_legacy.html create mode 100644 reference/bumpversion/bumpversion.indented_logger.html diff --git a/_modules/bumpversion/aliases.html b/_modules/bumpversion/aliases.html index 459c10da..ba448f5d 100644 --- a/_modules/bumpversion/aliases.html +++ b/_modules/bumpversion/aliases.html @@ -1,16 +1,16 @@ - + - + bumpversion.aliases - Bump My Version 0.13.0 - - - - - + + + + + @@ -177,25 +177,27 @@
  • Search and replace configuration
  • bumpversion
  • @@ -249,14 +251,18 @@

    Source code for bumpversion.aliases

     from bumpversion.ui import print_warning
     
     
    -
    [docs]class AliasedGroup(RichGroup): +
    +[docs] +class AliasedGroup(RichGroup): """ This following example implements a subclass of Group that accepts a prefix for a command. If there were a command called ``push``, it would accept ``pus`` as an alias (so long as it was unique) """ -
    [docs] def get_command(self, ctx: Context, cmd_name: str) -> Optional[click.Command]: +
    +[docs] + def get_command(self, ctx: Context, cmd_name: str) -> Optional[click.Command]: """Given a context and a command name, this returns a Command object if it exists or returns None.""" rv = click.Group.get_command(self, ctx, cmd_name) if rv is not None: @@ -270,7 +276,10 @@

    Source code for bumpversion.aliases

                 return click.Group.get_command(self, ctx, matches[0])
             ctx.fail(f"Too many matches: {', '.join(sorted(matches))}")
    -
    [docs] def resolve_command(self, ctx: Context, args: List[str]) -> tuple: + +
    +[docs] + def resolve_command(self, ctx: Context, args: List[str]) -> tuple: """Find the command and make sure the full command name is returned.""" # always return the full command name original_args = args[:] @@ -285,7 +294,9 @@

    Source code for bumpversion.aliases

                         "Please use `bump-my-version bump` instead"
                     )
                 return cmd.name, cmd, original_args
    -        return cmd.name, cmd, args
    + return cmd.name, cmd, args
    +
    +
    @@ -325,11 +336,11 @@

    Source code for bumpversion.aliases

           
         
       
    - - - - - - + + + + + + \ No newline at end of file diff --git a/_modules/bumpversion/autocast.html b/_modules/bumpversion/autocast.html index 35649f7d..05e9c45a 100644 --- a/_modules/bumpversion/autocast.html +++ b/_modules/bumpversion/autocast.html @@ -1,16 +1,16 @@ - + - + bumpversion.autocast - Bump My Version 0.13.0 - - - - - + + + + + @@ -177,25 +177,27 @@
  • Search and replace configuration
  • bumpversion
  • @@ -249,7 +251,9 @@

    Source code for bumpversion.autocast

     from typing import Any
     
     
    -
    [docs]def boolify(s: str) -> bool: +
    +[docs] +def boolify(s: str) -> bool: """Convert a string to a boolean.""" if s in {"True", "true"}: return True @@ -258,14 +262,20 @@

    Source code for bumpversion.autocast

         raise ValueError("Not Boolean Value!")
    -
    [docs]def noneify(s: str) -> None: + +
    +[docs] +def noneify(s: str) -> None: """Convert a string to None.""" if s == "None": return None raise ValueError("Not None Value!")
    -
    [docs]def listify(s: str) -> list: + +
    +[docs] +def listify(s: str) -> list: """ Convert a string representation of a list into list of homogenous basic types. @@ -300,7 +310,10 @@

    Source code for bumpversion.autocast

             raise TypeError("Autocasted list must be all same type") from e
    -
    [docs]def autocast_value(var: Any) -> Any: + +
    +[docs] +def autocast_value(var: Any) -> Any: """ Guess the string representation of the variable's type. @@ -319,6 +332,7 @@

    Source code for bumpversion.autocast

                 return caster(var)  # type: ignore[operator]
     
         return var
    +
    @@ -358,11 +372,11 @@

    Source code for bumpversion.autocast

           
         
       
    - - - - - - + + + + + + \ No newline at end of file diff --git a/_modules/bumpversion/bump.html b/_modules/bumpversion/bump.html index d1163e48..356fe1bd 100644 --- a/_modules/bumpversion/bump.html +++ b/_modules/bumpversion/bump.html @@ -1,16 +1,16 @@ - + - + bumpversion.bump - Bump My Version 0.13.0 - - - - - + + + + + @@ -177,25 +177,27 @@
  • Search and replace configuration
  • bumpversion
  • @@ -240,7 +242,6 @@

    Source code for bumpversion.bump

     """Version changing methods."""
    -import logging
     import shlex
     from pathlib import Path
     from typing import TYPE_CHECKING, ChainMap, List, Optional
    @@ -250,14 +251,18 @@ 

    Source code for bumpversion.bump

         from bumpversion.version_part import Version
     
     from bumpversion.config import Config
    -from bumpversion.config.files import update_config_file, update_ini_config_file
    +from bumpversion.config.files import update_config_file
    +from bumpversion.config.files_legacy import update_ini_config_file
     from bumpversion.exceptions import ConfigurationError
    +from bumpversion.ui import get_indented_logger
     from bumpversion.utils import get_context, key_val_string
     
    -logger = logging.getLogger("bumpversion")
    +logger = get_indented_logger(__name__)
     
     
    -
    [docs]def get_next_version( +
    +[docs] +def get_next_version( current_version: "Version", config: Config, version_part: Optional[str], new_version: Optional[str] ) -> "Version": """ @@ -276,18 +281,25 @@

    Source code for bumpversion.bump

             ConfigurationError: If it can't generate the next version.
         """
         if new_version:
    +        logger.info("Attempting to set new version '%s'", new_version)
    +        logger.indent()
             next_version = config.version_config.parse(new_version)
         elif version_part:
             logger.info("Attempting to increment part '%s'", version_part)
    +        logger.indent()
             next_version = current_version.bump(version_part, config.version_config.order)
         else:
             raise ConfigurationError("Unable to get the next version.")
     
         logger.info("Values are now: %s", key_val_string(next_version.values))
    +    logger.dedent()
         return next_version
    -
    [docs]def do_bump( + +
    +[docs] +def do_bump( version_part: Optional[str], new_version: Optional[str], config: Config, @@ -306,8 +318,13 @@

    Source code for bumpversion.bump

         """
         from bumpversion.files import modify_files, resolve_file_config
     
    +    logger.indent()
    +
         ctx = get_context(config)
    +    logger.info("Parsing current version '%s'", config.current_version)
    +    logger.indent()
         version = config.version_config.parse(config.current_version)
    +    logger.dedent()
         next_version = get_next_version(version, config, version_part, new_version)
         next_version_str = config.version_config.serialize(next_version, ctx)
         logger.info("New version will be '%s'", next_version_str)
    @@ -316,6 +333,8 @@ 

    Source code for bumpversion.bump

             logger.info("Version is already '%s'", next_version_str)
             return
     
    +    logger.dedent()
    +
         if dry_run:
             logger.info("Dry run active, won't touch any files.")
     
    @@ -330,10 +349,14 @@ 

    Source code for bumpversion.bump

     
         ctx = get_context(config, version, next_version)
         ctx["new_version"] = next_version_str
    -    commit_and_tag(config, config_file, configured_files, ctx, dry_run)
    + commit_and_tag(config, config_file, configured_files, ctx, dry_run) + logger.info("Done.")
    -
    [docs]def commit_and_tag( + +
    +[docs] +def commit_and_tag( config: Config, config_file: Optional[Path], configured_files: List["ConfiguredFile"], @@ -355,12 +378,13 @@

    Source code for bumpversion.bump

     
         extra_args = shlex.split(config.commit_args) if config.commit_args else []
     
    -    commit_files = {f.path for f in configured_files}
    +    commit_files = {f.file_change.filename for f in configured_files}
         if config_file:
             commit_files |= {str(config_file)}
     
         config.scm_info.tool.commit_to_scm(list(commit_files), config, ctx, extra_args, dry_run)
         config.scm_info.tool.tag_in_scm(config, ctx, dry_run)
    +
    @@ -400,11 +424,11 @@

    Source code for bumpversion.bump

           
         
       
    - - - - - - + + + + + + \ No newline at end of file diff --git a/_modules/bumpversion/config.html b/_modules/bumpversion/config.html index 8b9c53fa..8d22a6d2 100644 --- a/_modules/bumpversion/config.html +++ b/_modules/bumpversion/config.html @@ -1,16 +1,16 @@ - + - + bumpversion.config - Bump My Version 0.13.0 - - - - - + + + + + @@ -177,25 +177,27 @@
  • Search and replace configuration
  • bumpversion
  • @@ -242,17 +244,17 @@

    Source code for bumpversion.config

     """Configuration management."""
     from __future__ import annotations
     
    -import logging
     from typing import TYPE_CHECKING, Union
     
     from bumpversion.config.files import read_config_file
     from bumpversion.config.models import Config
     from bumpversion.exceptions import ConfigurationError
    +from bumpversion.ui import get_indented_logger
     
     if TYPE_CHECKING:  # pragma: no-coverage
         from pathlib import Path
     
    -logger = logging.getLogger(__name__)
    +logger = get_indented_logger(__name__)
     
     DEFAULTS = {
         "current_version": None,
    @@ -276,7 +278,9 @@ 

    Source code for bumpversion.config

     }
     
     
    -
    [docs]def get_configuration(config_file: Union[str, Path, None] = None, **overrides) -> Config: +
    +[docs] +def get_configuration(config_file: Union[str, Path, None] = None, **overrides) -> Config: """ Return the configuration based on any configuration files and overrides. @@ -290,6 +294,9 @@

    Source code for bumpversion.config

         from bumpversion.config.utils import get_all_file_configs, get_all_part_configs
         from bumpversion.scm import SCMInfo, SourceCodeManager, get_scm_info  # noqa: F401
     
    +    logger.info("Reading configuration")
    +    logger.indent()
    +
         config_dict = DEFAULTS.copy()
         parsed_config = read_config_file(config_file) if config_file else {}
     
    @@ -316,10 +323,15 @@ 

    Source code for bumpversion.config

         # Update and verify the current_version
         config.current_version = check_current_version(config)
     
    +    logger.dedent()
    +
         return config
    -
    [docs]def check_current_version(config: Config) -> str: + +
    +[docs] +def check_current_version(config: Config) -> str: """ Returns the current version. @@ -351,6 +363,7 @@

    Source code for bumpversion.config

             return current_version
     
         raise ConfigurationError("Unable to determine the current version.")
    +
    @@ -390,11 +403,11 @@

    Source code for bumpversion.config

           
         
       
    -
    - - - - - +
    + + + + + \ No newline at end of file diff --git a/_modules/bumpversion/config/files.html b/_modules/bumpversion/config/files.html index d1b1ab7d..53e831a2 100644 --- a/_modules/bumpversion/config/files.html +++ b/_modules/bumpversion/config/files.html @@ -1,16 +1,16 @@ - + - + bumpversion.config.files - Bump My Version 0.13.0 - - - - - + + + + + @@ -177,25 +177,27 @@
  • Search and replace configuration
  • bumpversion
  • @@ -243,29 +245,29 @@

    Source code for bumpversion.config.files

     
     from __future__ import annotations
     
    -import logging
    -import re
    -from difflib import context_diff
     from pathlib import Path
     from typing import TYPE_CHECKING, Any, Dict, MutableMapping, Union
     
    -from bumpversion.ui import print_warning
    +from bumpversion.config.files_legacy import read_ini_file
    +from bumpversion.ui import get_indented_logger, print_warning
     
     if TYPE_CHECKING:  # pragma: no-coverage
         from bumpversion.config.models import Config
         from bumpversion.version_part import Version
     
    -logger = logging.getLogger(__name__)
    +logger = get_indented_logger(__name__)
     
     CONFIG_FILE_SEARCH_ORDER = (
    -    Path(".bumpversion.cfg"),
    -    Path(".bumpversion.toml"),
    -    Path("setup.cfg"),
    -    Path("pyproject.toml"),
    +    ".bumpversion.cfg",
    +    ".bumpversion.toml",
    +    "setup.cfg",
    +    "pyproject.toml",
     )
     
     
    -
    [docs]def find_config_file(explicit_file: Union[str, Path, None] = None) -> Union[Path, None]: +
    +[docs] +def find_config_file(explicit_file: Union[str, Path, None] = None) -> Union[Path, None]: """ Find the configuration file, if it exists. @@ -278,14 +280,19 @@

    Source code for bumpversion.config.files

         Returns:
             The configuration file path
         """
    -    search_paths = [Path(explicit_file)] if explicit_file else CONFIG_FILE_SEARCH_ORDER
    +    search_paths = (
    +        [Path(explicit_file)] if explicit_file else [Path.cwd().joinpath(path) for path in CONFIG_FILE_SEARCH_ORDER]
    +    )
         return next(
             (cfg_file for cfg_file in search_paths if cfg_file.exists() and "bumpversion]" in cfg_file.read_text()),
             None,
         )
    -
    [docs]def read_config_file(config_file: Union[str, Path, None] = None) -> Dict[str, Any]: + +
    +[docs] +def read_config_file(config_file: Union[str, Path, None] = None) -> Dict[str, Any]: """ Read the configuration file, if it exists. @@ -302,80 +309,27 @@

    Source code for bumpversion.config.files

             logger.info("No configuration file found.")
             return {}
     
    -    logger.info("Reading config file %s:", config_file)
         config_path = Path(config_file)
    +    if not config_path.exists():
    +        logger.info("Configuration file not found: %s.", config_path)
    +        return {}
    +
    +    logger.info("Reading config file: %s", config_file)
    +
         if config_path.suffix == ".cfg":
             print_warning("The .cfg file format is deprecated. Please use .toml instead.")
             return read_ini_file(config_path)
         elif config_path.suffix == ".toml":
             return read_toml_file(config_path)
    -    return {}
    - + else: + logger.info("Unknown config file suffix: %s. Using defaults.", config_path.suffix) + return {}
    -
    [docs]def read_ini_file(file_path: Path) -> Dict[str, Any]: # noqa: C901 - """ - Parse an INI file and return a dictionary of sections and their options. - Args: - file_path: The path to the INI file. - Returns: - dict: A dictionary of sections and their options. - """ - import configparser - - from bumpversion import autocast - - # Create a ConfigParser object and read the INI file - config_parser = configparser.RawConfigParser() - if file_path.name == "setup.cfg": - config_parser = configparser.ConfigParser() - - config_parser.read(file_path) - - # Create an empty dictionary to hold the parsed sections and options - bumpversion_options: Dict[str, Any] = {"files": [], "parts": {}} - - # Loop through each section in the INI file - for section_name in config_parser.sections(): - if not section_name.startswith("bumpversion"): - continue - - section_parts = section_name.split(":") - num_parts = len(section_parts) - options = {key: autocast.autocast_value(val) for key, val in config_parser.items(section_name)} - - if num_parts == 1: # bumpversion section - bumpversion_options.update(options) - serialize = bumpversion_options.get("serialize", []) - if "message" in bumpversion_options and isinstance(bumpversion_options["message"], list): - bumpversion_options["message"] = ",".join(bumpversion_options["message"]) - if not isinstance(serialize, list): - bumpversion_options["serialize"] = [serialize] - elif num_parts > 1 and section_parts[1].startswith("file"): - file_options = { - "filename": section_parts[2], - } - file_options.update(options) - if "replace" in file_options and isinstance(file_options["replace"], list): - file_options["replace"] = "\n".join(file_options["replace"]) - bumpversion_options["files"].append(file_options) - elif num_parts > 1 and section_parts[1].startswith("glob"): - file_options = { - "glob": section_parts[2], - } - file_options.update(options) - if "replace" in file_options and isinstance(file_options["replace"], list): - file_options["replace"] = "\n".join(file_options["replace"]) - bumpversion_options["files"].append(file_options) - elif num_parts > 1 and section_parts[1].startswith("part"): - bumpversion_options["parts"][section_parts[2]] = options - - # Return the dictionary of sections and options - return bumpversion_options
    - - -
    [docs]def read_toml_file(file_path: Path) -> Dict[str, Any]: +
    +[docs] +def read_toml_file(file_path: Path) -> Dict[str, Any]: """ Parse a TOML file and return the `bumpversion` section. @@ -393,7 +347,10 @@

    Source code for bumpversion.config.files

         return toml_data.get("tool", {}).get("bumpversion", {})
    -
    [docs]def update_config_file( + +
    +[docs] +def update_config_file( config_file: Union[str, Path], config: Config, current_version: Version, @@ -412,20 +369,22 @@

    Source code for bumpversion.config.files

             context: The context to use for serialization.
             dry_run: True if the update should be a dry run.
         """
    -    from bumpversion.config.models import FileConfig
    +    from bumpversion.config.models import FileChange
         from bumpversion.files import DataFileUpdater
     
         if not config_file:
    -        logger.info("No configuration file found to update.")
    +        logger.info("\n%sNo configuration file found to update.", logger.indent_str)
             return
    -
    +    else:
    +        logger.info("\n%sProcessing config file: %s", logger.indent_str, config_file)
    +    logger.indent()
         config_path = Path(config_file)
         if config_path.suffix != ".toml":
    -        logger.info("Could not find the current version in the config file: %s.", config_path)
    +        logger.info("You must have a `.toml` suffix to update the config file: %s.", config_path)
             return
     
         # TODO: Eventually this should be transformed into another default "files_to_modify" entry
    -    datafile_config = FileConfig(
    +    datafile_config = FileChange(
             filename=str(config_path),
             key_path="tool.bumpversion.current_version",
             search=config.search,
    @@ -437,61 +396,9 @@ 

    Source code for bumpversion.config.files

         )
     
         updater = DataFileUpdater(datafile_config, config.version_config.part_configs)
    -    updater.update_file(current_version, new_version, context, dry_run)
    - - -
    [docs]def update_ini_config_file( - config_file: Union[str, Path], current_version: str, new_version: str, dry_run: bool = False -) -> None: - """ - Update the current_version key in the configuration file. - - Instead of parsing and re-writing the config file with new information, it will use - a regular expression to just replace the current_version value. The idea is it will - avoid unintentional changes (like formatting) to the config file. - - Args: - config_file: The configuration file to explicitly use. - current_version: The serialized current version. - new_version: The serialized new version. - dry_run: True if the update should be a dry run. - """ - cfg_current_version_regex = re.compile( - f"(?P<section_prefix>\\[bumpversion]\n[^[]*current_version\\s*=\\s*)(?P<version>{current_version})", - re.MULTILINE, - ) - - config_path = Path(config_file) - existing_config = config_path.read_text() - if config_path.suffix == ".cfg" and cfg_current_version_regex.search(existing_config): - sub_str = f"\\g<section_prefix>{new_version}" - new_config = cfg_current_version_regex.sub(sub_str, existing_config) - else: - logger.info("Could not find the current version in the config file: %s.", config_path) - return - - logger.info( - "%s to config file %s:", - "Would write" if dry_run else "Writing", - config_path, - ) - - logger.info( - "\n".join( - list( - context_diff( - existing_config.splitlines(), - new_config.splitlines(), - fromfile=f"before {config_path}", - tofile=f"after {config_path}", - lineterm="", - ) - ) - ) - ) + updater.update_file(current_version, new_version, context, dry_run) + logger.dedent()
    - if not dry_run: - config_path.write_text(new_config)
    @@ -531,11 +438,11 @@

    Source code for bumpversion.config.files

           
         
       
    - - - - - - + + + + + + \ No newline at end of file diff --git a/_modules/bumpversion/config/files_legacy.html b/_modules/bumpversion/config/files_legacy.html new file mode 100644 index 00000000..3a65ba9d --- /dev/null +++ b/_modules/bumpversion/config/files_legacy.html @@ -0,0 +1,424 @@ + + + + + + + + bumpversion.config.files_legacy - Bump My Version 0.13.0 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark mode + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    + +
    +
    + +
    + +
    +
    + +
    +
    +
    + + + + + Back to top + +
    +
    + +
    + +
    +
    +

    Source code for bumpversion.config.files_legacy

    +"""This module handles the legacy config file format."""
    +from __future__ import annotations
    +
    +import re
    +from difflib import context_diff
    +from pathlib import Path
    +from typing import Any, Dict, Union
    +
    +from bumpversion.ui import get_indented_logger
    +
    +logger = get_indented_logger(__name__)
    +
    +
    +
    +[docs] +def read_ini_file(file_path: Path) -> Dict[str, Any]: # noqa: C901 + """ + Parse an INI file and return a dictionary of sections and their options. + + Args: + file_path: The path to the INI file. + + Returns: + dict: A dictionary of sections and their options. + """ + import configparser + + from bumpversion import autocast + + # Create a ConfigParser object and read the INI file + config_parser = configparser.RawConfigParser() + if file_path.name == "setup.cfg": + config_parser = configparser.ConfigParser() + + config_parser.read(file_path) + + # Create an empty dictionary to hold the parsed sections and options + bumpversion_options: Dict[str, Any] = {"files": [], "parts": {}} + + # Loop through each section in the INI file + for section_name in config_parser.sections(): + if not section_name.startswith("bumpversion"): + continue + + section_parts = section_name.split(":") + num_parts = len(section_parts) + options = {key: autocast.autocast_value(val) for key, val in config_parser.items(section_name)} + + if num_parts == 1: # bumpversion section + bumpversion_options.update(options) + serialize = bumpversion_options.get("serialize", []) + if "message" in bumpversion_options and isinstance(bumpversion_options["message"], list): + bumpversion_options["message"] = ",".join(bumpversion_options["message"]) + if not isinstance(serialize, list): + bumpversion_options["serialize"] = [serialize] + elif num_parts > 1 and section_parts[1].startswith("file"): + file_options = { + "filename": section_parts[2], + } + file_options.update(options) + if "replace" in file_options and isinstance(file_options["replace"], list): + file_options["replace"] = "\n".join(file_options["replace"]) + bumpversion_options["files"].append(file_options) + elif num_parts > 1 and section_parts[1].startswith("glob"): + file_options = { + "glob": section_parts[2], + } + file_options.update(options) + if "replace" in file_options and isinstance(file_options["replace"], list): + file_options["replace"] = "\n".join(file_options["replace"]) + bumpversion_options["files"].append(file_options) + elif num_parts > 1 and section_parts[1].startswith("part"): + bumpversion_options["parts"][section_parts[2]] = options + + # Return the dictionary of sections and options + return bumpversion_options
    + + + +
    +[docs] +def update_ini_config_file( + config_file: Union[str, Path], current_version: str, new_version: str, dry_run: bool = False +) -> None: + """ + Update the current_version key in the configuration file. + + Instead of parsing and re-writing the config file with new information, it will use + a regular expression to just replace the current_version value. The idea is it will + avoid unintentional changes (like formatting) to the config file. + + Args: + config_file: The configuration file to explicitly use. + current_version: The serialized current version. + new_version: The serialized new version. + dry_run: True if the update should be a dry run. + """ + cfg_current_version_regex = re.compile( + f"(?P<section_prefix>\\[bumpversion]\n[^[]*current_version\\s*=\\s*)(?P<version>{current_version})", + re.MULTILINE, + ) + + config_path = Path(config_file) + existing_config = config_path.read_text() + if config_path.suffix == ".cfg" and cfg_current_version_regex.search(existing_config): + sub_str = f"\\g<section_prefix>{new_version}" + new_config = cfg_current_version_regex.sub(sub_str, existing_config) + else: + logger.info("Could not find the current version in the config file: %s.", config_path) + return + + logger.info( + "%s to config file %s:", + "Would write" if dry_run else "Writing", + config_path, + ) + + logger.info( + "\n".join( + list( + context_diff( + existing_config.splitlines(), + new_config.splitlines(), + fromfile=f"before {config_path}", + tofile=f"after {config_path}", + lineterm="", + ) + ) + ) + ) + + if not dry_run: + config_path.write_text(new_config)
    + +
    +
    +
    + +
    + +
    +
    + + + + + + + \ No newline at end of file diff --git a/_modules/bumpversion/config/models.html b/_modules/bumpversion/config/models.html index c1f306d7..31344864 100644 --- a/_modules/bumpversion/config/models.html +++ b/_modules/bumpversion/config/models.html @@ -1,16 +1,16 @@ - + - + bumpversion.config.models - Bump My Version 0.13.0 - - - - - + + + + + @@ -177,25 +177,27 @@
  • Search and replace configuration
  • bumpversion
  • @@ -242,17 +244,26 @@

    Source code for bumpversion.config.models

     """Bump My Version configuration models."""
     from __future__ import annotations
     
    -from typing import TYPE_CHECKING, Dict, List, Optional, Union
    +import re
    +from collections import defaultdict
    +from itertools import chain
    +from typing import TYPE_CHECKING, Dict, List, MutableMapping, Optional, Tuple, Union
     
     from pydantic import BaseModel, Field
     from pydantic_settings import BaseSettings, SettingsConfigDict
     
    +from bumpversion.ui import get_indented_logger
    +
     if TYPE_CHECKING:
         from bumpversion.scm import SCMInfo
         from bumpversion.version_part import VersionConfig
     
    +logger = get_indented_logger(__name__)
    +
     
    -
    [docs]class VersionPartConfig(BaseModel): +
    +[docs] +class VersionPartConfig(BaseModel): """Configuration of a part of the version.""" values: Optional[list] = None # Optional. Numeric is used if missing or no items in list @@ -262,26 +273,77 @@

    Source code for bumpversion.config.models

         independent: bool = False
    -
    [docs]class FileConfig(BaseModel): - """Search and replace file config.""" + +
    +[docs] +class FileChange(BaseModel): + """A change to make to a file.""" parse: str - serialize: List[str] + serialize: tuple search: str replace: str regex: bool ignore_missing_version: bool filename: Optional[str] = None glob: Optional[str] = None # Conflicts with filename. If both are specified, glob wins - key_path: Optional[str] = None # If specified, and has an appropriate extension, will be treated as a data file
    + key_path: Optional[str] = None # If specified, and has an appropriate extension, will be treated as a data file + +
    +[docs] + def __hash__(self): + """Return a hash of the model.""" + return hash(tuple(sorted(self.model_dump().items())))
    + + +
    +[docs] + def get_search_pattern(self, context: MutableMapping) -> Tuple[re.Pattern, str]: + """ + Render the search pattern and return the compiled regex pattern and the raw pattern. + + Args: + context: The context to use for rendering the search pattern + + Returns: + A tuple of the compiled regex pattern and the raw pattern as a string. + """ + logger.debug("Rendering search pattern with context") + logger.indent() + # the default search pattern is escaped, so we can still use it in a regex + raw_pattern = self.search.format(**context) + default = re.compile(re.escape(raw_pattern), re.MULTILINE | re.DOTALL) + if not self.regex: + logger.debug("No RegEx flag detected. Searching for the default pattern: '%s'", default.pattern) + logger.dedent() + return default, raw_pattern + + re_context = {key: re.escape(str(value)) for key, value in context.items()} + regex_pattern = self.search.format(**re_context) + try: + search_for_re = re.compile(regex_pattern, re.MULTILINE | re.DOTALL) + logger.debug("Searching for the regex: '%s'", search_for_re.pattern) + logger.dedent() + return search_for_re, raw_pattern + except re.error as e: + logger.error("Invalid regex '%s': %s.", default, e) + logger.debug("Invalid regex. Searching for the default pattern: '%s'", raw_pattern) + logger.dedent() -
    [docs]class Config(BaseSettings): + return default, raw_pattern
    +
    + + + +
    +[docs] +class Config(BaseSettings): """Bump Version configuration.""" current_version: Optional[str] parse: str - serialize: List[str] = Field(min_length=1) + serialize: tuple = Field(min_length=1) search: str replace: str regex: bool @@ -296,19 +358,21 @@

    Source code for bumpversion.config.models

         commit_args: Optional[str]
         scm_info: Optional["SCMInfo"]
         parts: Dict[str, VersionPartConfig]
    -    files: List[FileConfig]
    +    files: List[FileChange] = Field(default_factory=list)
         included_paths: List[str] = Field(default_factory=list)
         excluded_paths: List[str] = Field(default_factory=list)
         model_config = SettingsConfigDict(env_prefix="bumpversion_")
    +    _resolved_filemap: Optional[Dict[str, List[FileChange]]] = None
     
    -
    [docs] def add_files(self, filename: Union[str, List[str]]) -> None: +
    +[docs] + def add_files(self, filename: Union[str, List[str]]) -> None: """Add a filename to the list of files.""" filenames = [filename] if isinstance(filename, str) else filename + files = set(self.files) for name in filenames: - if name in self.resolved_filemap: - continue - self.files.append( - FileConfig( + files.add( + FileChange( filename=name, glob=None, key_path=None, @@ -319,13 +383,26 @@

    Source code for bumpversion.config.models

                         regex=self.regex,
                         ignore_missing_version=self.ignore_missing_version,
                     )
    -            )
    + ) + self.files = list(files) + + self._resolved_filemap = None
    + @property - def resolved_filemap(self) -> Dict[str, FileConfig]: + def resolved_filemap(self) -> Dict[str, List[FileChange]]: + """Return the cached resolved filemap.""" + if self._resolved_filemap is None: + self._resolved_filemap = self._resolve_filemap() + return self._resolved_filemap + +
    +[docs] + def _resolve_filemap(self) -> Dict[str, List[FileChange]]: """Return a map of filenames to file configs, expanding any globs.""" from bumpversion.config.utils import resolve_glob_files + output = defaultdict(list) new_files = [] for file_cfg in self.files: if file_cfg.glob: @@ -333,18 +410,21 @@

    Source code for bumpversion.config.models

                 else:
                     new_files.append(file_cfg)
     
    -        return {file_cfg.filename: file_cfg for file_cfg in new_files}
    +        for file_cfg in new_files:
    +            output[file_cfg.filename].append(file_cfg)
    +        return output
    + @property - def files_to_modify(self) -> List[FileConfig]: + def files_to_modify(self) -> List[FileChange]: """Return a list of files to modify.""" - files_not_excluded = [ - file_cfg.filename - for file_cfg in self.resolved_filemap.values() - if file_cfg.filename not in self.excluded_paths - ] + files_not_excluded = [filename for filename in self.resolved_filemap if filename not in self.excluded_paths] inclusion_set = set(self.included_paths) | set(files_not_excluded) - return [file_cfg for file_cfg in self.resolved_filemap.values() if file_cfg.filename in inclusion_set] + return list( + chain.from_iterable( + file_cfg_list for key, file_cfg_list in self.resolved_filemap.items() if key in inclusion_set + ) + ) @property def version_config(self) -> "VersionConfig": @@ -352,6 +432,7 @@

    Source code for bumpversion.config.models

             from bumpversion.version_part import VersionConfig
     
             return VersionConfig(self.parse, self.serialize, self.search, self.replace, self.parts)
    +
    @@ -391,11 +472,11 @@

    Source code for bumpversion.config.models

           
         
       
    -
    - - - - - +
    + + + + + \ No newline at end of file diff --git a/_modules/bumpversion/config/utils.html b/_modules/bumpversion/config/utils.html index 9d24123d..f7ffa8d6 100644 --- a/_modules/bumpversion/config/utils.html +++ b/_modules/bumpversion/config/utils.html @@ -1,16 +1,16 @@ - + - + bumpversion.config.utils - Bump My Version 0.13.0 - - - - - + + + + + @@ -177,25 +177,27 @@
  • Search and replace configuration
  • bumpversion
  • @@ -246,11 +248,13 @@

    Source code for bumpversion.config.utils

     import itertools
     from typing import Dict, List
     
    -from bumpversion.config.models import FileConfig, VersionPartConfig
    +from bumpversion.config.models import FileChange, VersionPartConfig
     from bumpversion.utils import labels_for_format
     
     
    -
    [docs]def get_all_file_configs(config_dict: dict) -> List[FileConfig]: +
    +[docs] +def get_all_file_configs(config_dict: dict) -> List[FileChange]: """Make sure all version parts are included.""" defaults = { "parse": config_dict["parse"], @@ -263,10 +267,13 @@

    Source code for bumpversion.config.utils

         files = [{k: v for k, v in filecfg.items() if v is not None} for filecfg in config_dict["files"]]
         for f in files:
             f.update({k: v for k, v in defaults.items() if k not in f})
    -    return [FileConfig(**f) for f in files]
    + return [FileChange(**f) for f in files]
    + -
    [docs]def get_all_part_configs(config_dict: dict) -> Dict[str, VersionPartConfig]: +
    +[docs] +def get_all_part_configs(config_dict: dict) -> Dict[str, VersionPartConfig]: """Make sure all version parts are included.""" serialize = config_dict["serialize"] parts = config_dict["parts"] @@ -277,7 +284,10 @@

    Source code for bumpversion.config.utils

         }
    -
    [docs]def resolve_glob_files(file_cfg: FileConfig) -> List[FileConfig]: + +
    +[docs] +def resolve_glob_files(file_cfg: FileChange) -> List[FileChange]: """ Return a list of file configurations that match the glob pattern. @@ -294,6 +304,7 @@

    Source code for bumpversion.config.utils

             new_file_cfg.glob = None
             files.append(new_file_cfg)
         return files
    +
    @@ -333,11 +344,11 @@

    Source code for bumpversion.config.utils

           
         
       
    -
    - - - - - + + + + + + \ No newline at end of file diff --git a/_modules/bumpversion/exceptions.html b/_modules/bumpversion/exceptions.html index 302f6fe0..396ceab8 100644 --- a/_modules/bumpversion/exceptions.html +++ b/_modules/bumpversion/exceptions.html @@ -1,16 +1,16 @@ - + - + bumpversion.exceptions - Bump My Version 0.13.0 - - - - - + + + + + @@ -177,25 +177,27 @@
  • Search and replace configuration
  • bumpversion
  • @@ -245,7 +247,9 @@

    Source code for bumpversion.exceptions

     from click import Context, UsageError
     
     
    -
    [docs]class BumpVersionError(UsageError): +
    +[docs] +class BumpVersionError(UsageError): """Custom base class for all BumpVersion exception types.""" def __init__(self, message: str, ctx: Optional[Context] = None): @@ -253,52 +257,77 @@

    Source code for bumpversion.exceptions

             self.ctx = ctx
    -
    [docs]class FormattingError(BumpVersionError): + +
    +[docs] +class FormattingError(BumpVersionError): """We are unable to represent a version required by a format.""" pass
    -
    [docs]class MissingValueError(BumpVersionError): + +
    +[docs] +class MissingValueError(BumpVersionError): """A part required for a version format is empty.""" pass
    -
    [docs]class DirtyWorkingDirectoryError(BumpVersionError): + +
    +[docs] +class DirtyWorkingDirectoryError(BumpVersionError): """The working directory is dirty, and it is not allowed.""" pass
    -
    [docs]class SignedTagsError(BumpVersionError): + +
    +[docs] +class SignedTagsError(BumpVersionError): """The VCS does not support signed tags.""" pass
    -
    [docs]class VersionNotFoundError(BumpVersionError): + +
    +[docs] +class VersionNotFoundError(BumpVersionError): """A version number was not found in a source file.""" pass
    -
    [docs]class InvalidVersionPartError(BumpVersionError): + +
    +[docs] +class InvalidVersionPartError(BumpVersionError): """The specified part (e.g. 'bugfix') was not found.""" pass
    -
    [docs]class ConfigurationError(BumpVersionError): + +
    +[docs] +class ConfigurationError(BumpVersionError): """A configuration key-value is missing or in the wrong type.""" pass
    -
    [docs]class BadInputError(BumpVersionError): + +
    +[docs] +class BadInputError(BumpVersionError): """User input was bad.""" pass
    +
    @@ -338,11 +367,11 @@

    Source code for bumpversion.exceptions

           
         
       
    - - - - - - + + + + + + \ No newline at end of file diff --git a/_modules/bumpversion/files.html b/_modules/bumpversion/files.html index d8e0a979..c79611f6 100644 --- a/_modules/bumpversion/files.html +++ b/_modules/bumpversion/files.html @@ -1,16 +1,16 @@ - + - + bumpversion.files - Bump My Version 0.13.0 - - - - - + + + + + @@ -177,25 +177,27 @@
  • Search and replace configuration
  • bumpversion
  • @@ -240,53 +242,23 @@

    Source code for bumpversion.files

     """Methods for changing files."""
    -import logging
     import re
     from copy import deepcopy
     from difflib import context_diff
     from pathlib import Path
    -from typing import Dict, List, MutableMapping, Optional, Tuple
    +from typing import Dict, List, MutableMapping, Optional
     
    -from bumpversion.config.models import FileConfig, VersionPartConfig
    +from bumpversion.config.models import FileChange, VersionPartConfig
     from bumpversion.exceptions import VersionNotFoundError
    +from bumpversion.ui import get_indented_logger
     from bumpversion.version_part import Version, VersionConfig
     
    -logger = logging.getLogger(__name__)
    -
    -
    -
    [docs]def get_search_pattern(search_str: str, context: MutableMapping, use_regex: bool = False) -> Tuple[re.Pattern, str]: - """ - Render the search pattern and return the compiled regex pattern and the raw pattern. +logger = get_indented_logger(__name__) - Args: - search_str: A string containing the search pattern as a format string - context: The context to use for rendering the search pattern - use_regex: If True, the search pattern is treated as a regex pattern - Returns: - A tuple of the compiled regex pattern and the raw pattern as a string. - """ - # the default search pattern is escaped, so we can still use it in a regex - raw_pattern = search_str.format(**context) - default = re.compile(re.escape(raw_pattern), re.MULTILINE | re.DOTALL) - if not use_regex: - logger.debug("No RegEx flag detected. Searching for the default pattern: '%s'", default.pattern) - return default, raw_pattern - - re_context = {key: re.escape(str(value)) for key, value in context.items()} - regex_pattern = search_str.format(**re_context) - try: - search_for_re = re.compile(regex_pattern, re.MULTILINE | re.DOTALL) - logger.debug("Searching for the regex: '%s'", search_for_re.pattern) - return search_for_re, raw_pattern - except re.error as e: - logger.error("Invalid regex '%s': %s.", default, e) - - logger.debug("Invalid regex. Searching for the default pattern: '%s'", raw_pattern) - return default, raw_pattern
    - - -
    [docs]def contains_pattern(search: re.Pattern, contents: str) -> bool: +
    +[docs] +def contains_pattern(search: re.Pattern, contents: str) -> bool: """Does the search pattern match any part of the contents?""" if not search or not contents: return False @@ -295,7 +267,7 @@

    Source code for bumpversion.files

             line_no = contents.count("\n", 0, m.start(0)) + 1
             logger.info(
                 "Found '%s' at line %s: %s",
    -            search,
    +            search.pattern,
                 line_no,
                 m.string[m.start() : m.end(0)],
             )
    @@ -303,7 +275,10 @@ 

    Source code for bumpversion.files

         return False
    -
    [docs]def log_changes(file_path: str, file_content_before: str, file_content_after: str, dry_run: bool = False) -> None: + +
    +[docs] +def log_changes(file_path: str, file_content_before: str, file_content_after: str, dry_run: bool = False) -> None: """ Log the changes that would be made to the file. @@ -315,8 +290,11 @@

    Source code for bumpversion.files

         """
         if file_content_before != file_content_after:
             logger.info("%s file %s:", "Would change" if dry_run else "Changing", file_path)
    +        logger.indent()
    +        indent_str = logger.indent_str
    +
             logger.info(
    -            "\n".join(
    +            f"\n{indent_str}".join(
                     list(
                         context_diff(
                             file_content_before.splitlines(),
    @@ -326,55 +304,79 @@ 

    Source code for bumpversion.files

                             lineterm="",
                         )
                     )
    -            )
    +            ),
             )
    +        logger.dedent()
         else:
             logger.info("%s file %s", "Would not change" if dry_run else "Not changing", file_path)
    -
    [docs]class ConfiguredFile: + +
    +[docs] +class ConfiguredFile: """A file to modify in a configured way.""" def __init__( self, - file_cfg: FileConfig, + file_change: FileChange, version_config: VersionConfig, search: Optional[str] = None, replace: Optional[str] = None, ) -> None: - self.path = file_cfg.filename - self.parse = file_cfg.parse or version_config.parse_regex.pattern - self.serialize = file_cfg.serialize or version_config.serialize_formats - self.search = search or file_cfg.search or version_config.search - self.replace = replace or file_cfg.replace or version_config.replace - self.regex = file_cfg.regex or False - self.ignore_missing_version = file_cfg.ignore_missing_version or False + self.file_change = FileChange( + parse=file_change.parse or version_config.parse_regex.pattern, + serialize=file_change.serialize or version_config.serialize_formats, + search=search or file_change.search or version_config.search, + replace=replace or file_change.replace or version_config.replace, + regex=file_change.regex or False, + ignore_missing_version=file_change.ignore_missing_version or False, + filename=file_change.filename, + glob=file_change.glob, + key_path=file_change.key_path, + ) self.version_config = VersionConfig( - self.parse, self.serialize, self.search, self.replace, version_config.part_configs + self.file_change.parse, + self.file_change.serialize, + self.file_change.search, + self.file_change.replace, + version_config.part_configs, ) self._newlines: Optional[str] = None -
    [docs] def get_file_contents(self) -> str: +
    +[docs] + def get_file_contents(self) -> str: """Return the contents of the file.""" - with open(self.path, "rt", encoding="utf-8") as f: + with open(self.file_change.filename, "rt", encoding="utf-8") as f: contents = f.read() self._newlines = f.newlines[0] if isinstance(f.newlines, tuple) else f.newlines return contents
    -
    [docs] def write_file_contents(self, contents: str) -> None: + +
    +[docs] + def write_file_contents(self, contents: str) -> None: """Write the contents of the file.""" if self._newlines is None: _ = self.get_file_contents() - with open(self.path, "wt", encoding="utf-8", newline=self._newlines) as f: + with open(self.file_change.filename, "wt", encoding="utf-8", newline=self._newlines) as f: f.write(contents)
    -
    [docs] def contains_version(self, version: Version, context: MutableMapping) -> bool: + +
    +[docs] + def _contains_change_pattern( + self, search_expression: re.Pattern, raw_search_expression: str, version: Version, context: MutableMapping + ) -> bool: """ - Check whether the version is present in the file. + Does the file contain the change pattern? Args: - version: The version to check + search_expression: The compiled search expression + raw_search_expression: The raw search expression + version: The version to check, in case it's not the same as the original context: The context to use Raises: @@ -383,18 +385,16 @@

    Source code for bumpversion.files

             Returns:
                 True if the version number is in fact present.
             """
    -        search_expression, raw_search_expression = get_search_pattern(self.search, context, self.regex)
             file_contents = self.get_file_contents()
             if contains_pattern(search_expression, file_contents):
                 return True
     
    -        # the `search` pattern did not match, but the original supplied
    +        # The `search` pattern did not match, but the original supplied
             # version number (representing the same version part values) might
    -        # match instead.
    +        # match instead. This is probably the case if environment variables are used.
     
    -        # check whether `search` isn't customized, i.e. should match only
    -        # very specific parts of the file
    -        search_pattern_is_default = self.search == self.version_config.search
    +        # check whether `search` isn't customized
    +        search_pattern_is_default = self.file_change.search == self.version_config.search
     
             if search_pattern_is_default and contains_pattern(re.compile(re.escape(version.original)), file_contents):
                 # The original version is present, and we're not looking for something
    @@ -402,45 +402,75 @@ 

    Source code for bumpversion.files

                 return True
     
             # version not found
    -        if self.ignore_missing_version:
    +        if self.file_change.ignore_missing_version:
                 return False
    -        raise VersionNotFoundError(f"Did not find '{raw_search_expression}' in file: '{self.path}'")
    + raise VersionNotFoundError(f"Did not find '{raw_search_expression}' in file: '{self.file_change.filename}'")
    + -
    [docs] def replace_version( +
    +[docs] + def make_file_change( self, current_version: Version, new_version: Version, context: MutableMapping, dry_run: bool = False ) -> None: - """Replace the current version with the new version.""" - file_content_before = self.get_file_contents() - + """Make the change to the file.""" + logger.info( + "\n%sFile %s: replace `%s` with `%s`", + logger.indent_str, + self.file_change.filename, + self.file_change.search, + self.file_change.replace, + ) + logger.indent() + logger.debug("Serializing the current version") + logger.indent() context["current_version"] = self.version_config.serialize(current_version, context) + logger.dedent() if new_version: + logger.debug("Serializing the new version") + logger.indent() context["new_version"] = self.version_config.serialize(new_version, context) + logger.dedent() - search_for, raw_search_pattern = get_search_pattern(self.search, context, self.regex) + search_for, raw_search_pattern = self.file_change.get_search_pattern(context) replace_with = self.version_config.replace.format(**context) + if not self._contains_change_pattern(search_for, raw_search_pattern, current_version, context): + return + + file_content_before = self.get_file_contents() + file_content_after = search_for.sub(replace_with, file_content_before) if file_content_before == file_content_after and current_version.original: og_context = deepcopy(context) og_context["current_version"] = current_version.original - search_for_og, og_raw_search_pattern = get_search_pattern(self.search, og_context, self.regex) + search_for_og, og_raw_search_pattern = self.file_change.get_search_pattern(og_context) file_content_after = search_for_og.sub(replace_with, file_content_before) - log_changes(self.path, file_content_before, file_content_after, dry_run) - + log_changes(self.file_change.filename, file_content_before, file_content_after, dry_run) + logger.dedent() if not dry_run: # pragma: no-coverage self.write_file_contents(file_content_after)
    -
    [docs] def __str__(self) -> str: # pragma: no-coverage - return self.path
    -
    [docs] def __repr__(self) -> str: # pragma: no-coverage - return f"<bumpversion.ConfiguredFile:{self.path}>"
    +
    +[docs] + def __str__(self) -> str: # pragma: no-coverage + return self.file_change.filename
    + + +
    +[docs] + def __repr__(self) -> str: # pragma: no-coverage + return f"<bumpversion.ConfiguredFile:{self.file_change.filename}>"
    +
    -
    [docs]def resolve_file_config( - files: List[FileConfig], version_config: VersionConfig, search: Optional[str] = None, replace: Optional[str] = None + +
    +[docs] +def resolve_file_config( + files: List[FileChange], version_config: VersionConfig, search: Optional[str] = None, replace: Optional[str] = None ) -> List[ConfiguredFile]: """ Resolve the files, searching and replacing values according to the FileConfig. @@ -457,7 +487,10 @@

    Source code for bumpversion.files

         return [ConfiguredFile(file_cfg, version_config, search, replace) for file_cfg in files]
    -
    [docs]def modify_files( + +
    +[docs] +def modify_files( files: List[ConfiguredFile], current_version: Version, new_version: Version, @@ -474,86 +507,95 @@

    Source code for bumpversion.files

             context: The context used for rendering the version
             dry_run: True if this should be a report-only job
         """
    -    _check_files_contain_version(files, current_version, context)
    +    # _check_files_contain_version(files, current_version, context)
         for f in files:
    -        f.replace_version(current_version, new_version, context, dry_run)
    + f.make_file_change(current_version, new_version, context, dry_run)
    -
    [docs]def _check_files_contain_version( - files: List[ConfiguredFile], current_version: Version, context: MutableMapping -) -> None: - """Make sure files exist and contain version string.""" - logger.info( - "Asserting files %s contain the version string...", - ", ".join({str(f.path) for f in files}), - ) - for f in files: - context["current_version"] = f.version_config.serialize(current_version, context) - f.contains_version(current_version, context)
    - -
    [docs]class FileUpdater: +
    +[docs] +class FileUpdater: """A class to handle updating files.""" def __init__( self, - file_cfg: FileConfig, + file_change: FileChange, version_config: VersionConfig, search: Optional[str] = None, replace: Optional[str] = None, ) -> None: - self.path = file_cfg.filename - self.version_config = version_config - self.parse = file_cfg.parse or version_config.parse_regex.pattern - self.serialize = file_cfg.serialize or version_config.serialize_formats - self.search = search or file_cfg.search or version_config.search - self.replace = replace or file_cfg.replace or version_config.replace - self.regex = file_cfg.regex or False - self.ignore_missing_version = file_cfg.ignore_missing_version or False + self.file_change = FileChange( + parse=file_change.parse or version_config.parse_regex.pattern, + serialize=file_change.serialize or version_config.serialize_formats, + search=search or file_change.search or version_config.search, + replace=replace or file_change.replace or version_config.replace, + regex=file_change.regex or False, + ignore_missing_version=file_change.ignore_missing_version or False, + filename=file_change.filename, + glob=file_change.glob, + key_path=file_change.key_path, + ) self.version_config = VersionConfig( - self.parse, self.serialize, self.search, self.replace, version_config.part_configs + self.file_change.parse, + self.file_change.serialize, + self.file_change.search, + self.file_change.replace, + version_config.part_configs, ) self._newlines: Optional[str] = None -
    [docs] def update_file( +
    +[docs] + def update_file( self, current_version: Version, new_version: Version, context: MutableMapping, dry_run: bool = False ) -> None: """Update the files.""" # TODO: Implement this - pass
    + pass
    +
    -
    [docs]class DataFileUpdater: + +
    +[docs] +class DataFileUpdater: """A class to handle updating files.""" def __init__( self, - file_cfg: FileConfig, + file_change: FileChange, version_part_configs: Dict[str, VersionPartConfig], ) -> None: - self.path = Path(file_cfg.filename) - self.key_path = file_cfg.key_path - self.search = file_cfg.search - self.replace = file_cfg.replace - self.regex = file_cfg.regex - self.ignore_missing_version = file_cfg.ignore_missing_version + self.file_change = file_change self.version_config = VersionConfig( - file_cfg.parse, file_cfg.serialize, file_cfg.search, file_cfg.replace, version_part_configs + self.file_change.parse, + self.file_change.serialize, + self.file_change.search, + self.file_change.replace, + version_part_configs, ) + self.path = Path(self.file_change.filename) + self._newlines: Optional[str] = None -
    [docs] def update_file( +
    +[docs] + def update_file( self, current_version: Version, new_version: Version, context: MutableMapping, dry_run: bool = False ) -> None: """Update the files.""" new_context = deepcopy(context) new_context["current_version"] = self.version_config.serialize(current_version, context) new_context["new_version"] = self.version_config.serialize(new_version, context) - search_for, raw_search_pattern = get_search_pattern(self.search, new_context, self.regex) - replace_with = self.replace.format(**new_context) + search_for, raw_search_pattern = self.file_change.get_search_pattern(new_context) + replace_with = self.file_change.replace.format(**new_context) if self.path.suffix == ".toml": self._update_toml_file(search_for, raw_search_pattern, replace_with, dry_run)
    -
    [docs] def _update_toml_file( + +
    +[docs] + def _update_toml_file( self, search_for: re.Pattern, raw_search_pattern: str, replace_with: str, dry_run: bool = False ) -> None: """Update a TOML file.""" @@ -561,23 +603,26 @@

    Source code for bumpversion.files

             import tomlkit
     
             toml_data = tomlkit.parse(self.path.read_text())
    -        value_before = dotted.get(toml_data, self.key_path)
    +        value_before = dotted.get(toml_data, self.file_change.key_path)
     
             if value_before is None:
    -            raise KeyError(f"Key path '{self.key_path}' does not exist in {self.path}")
    -        elif not contains_pattern(search_for, value_before) and not self.ignore_missing_version:
    +            raise KeyError(f"Key path '{self.file_change.key_path}' does not exist in {self.path}")
    +        elif not contains_pattern(search_for, value_before) and not self.file_change.ignore_missing_version:
                 raise ValueError(
    -                f"Key '{self.key_path}' in {self.path} does not contain the correct contents: {raw_search_pattern}"
    +                f"Key '{self.file_change.key_path}' in {self.path} does not contain the correct contents: "
    +                f"{raw_search_pattern}"
                 )
     
             new_value = search_for.sub(replace_with, value_before)
    -        log_changes(f"{self.path}:{self.key_path}", value_before, new_value, dry_run)
    +        log_changes(f"{self.path}:{self.file_change.key_path}", value_before, new_value, dry_run)
     
             if dry_run:
                 return
     
    -        dotted.update(toml_data, self.key_path, new_value)
    -        self.path.write_text(tomlkit.dumps(toml_data))
    + dotted.update(toml_data, self.file_change.key_path, new_value) + self.path.write_text(tomlkit.dumps(toml_data))
    +
    +
    @@ -617,11 +662,11 @@

    Source code for bumpversion.files

           
         
       
    - - - - - - + + + + + + \ No newline at end of file diff --git a/_modules/bumpversion/functions.html b/_modules/bumpversion/functions.html index c08deb73..833d38fb 100644 --- a/_modules/bumpversion/functions.html +++ b/_modules/bumpversion/functions.html @@ -1,16 +1,16 @@ - + - + bumpversion.functions - Bump My Version 0.13.0 - - - - - + + + + + @@ -177,25 +177,27 @@
  • Search and replace configuration
  • bumpversion
  • @@ -244,19 +246,27 @@

    Source code for bumpversion.functions

     from typing import List, Optional, Union
     
     
    -
    [docs]class PartFunction: +
    +[docs] +class PartFunction: """Base class for a version part function.""" first_value: str optional_value: str independent: bool -
    [docs] def bump(self, value: str) -> str: +
    +[docs] + def bump(self, value: str) -> str: """Increase the value.""" - raise NotImplementedError
    + raise NotImplementedError
    +
    + -
    [docs]class NumericFunction(PartFunction): +
    +[docs] +class NumericFunction(PartFunction): """ This is a class that provides a numeric function for version parts. @@ -279,7 +289,9 @@

    Source code for bumpversion.functions

             self.first_value = str(first_value or 0)
             self.optional_value = str(optional_value or self.first_value)
     
    -
    [docs] def bump(self, value: Union[str, int]) -> str: +
    +[docs] + def bump(self, value: Union[str, int]) -> str: """Increase the first numerical value by one.""" match = self.FIRST_NUMERIC.search(str(value)) if not match: @@ -287,10 +299,14 @@

    Source code for bumpversion.functions

             part_prefix, part_numeric, part_suffix = match.groups()
             bumped_numeric = int(part_numeric) + 1
     
    -        return "".join([part_prefix, str(bumped_numeric), part_suffix])
    + return "".join([part_prefix, str(bumped_numeric), part_suffix])
    +
    + -
    [docs]class ValuesFunction(PartFunction): +
    +[docs] +class ValuesFunction(PartFunction): """ This is a class that provides a values list based function for version parts. @@ -331,14 +347,18 @@

    Source code for bumpversion.functions

     
             self.first_value = first_value
     
    -
    [docs] def bump(self, value: str) -> str: +
    +[docs] + def bump(self, value: str) -> str: """Return the item after ``value`` in the list.""" try: return self._values[self._values.index(value) + 1] except IndexError as e: raise ValueError( f"The part has already the maximum value among {self._values} and cannot be bumped." - ) from e
    + ) from e
    +
    +
    @@ -378,11 +398,11 @@

    Source code for bumpversion.functions

           
         
       
    - - - - - - + + + + + + \ No newline at end of file diff --git a/_modules/bumpversion/indented_logger.html b/_modules/bumpversion/indented_logger.html new file mode 100644 index 00000000..bcfb0990 --- /dev/null +++ b/_modules/bumpversion/indented_logger.html @@ -0,0 +1,385 @@ + + + + + + + + bumpversion.indented_logger - Bump My Version 0.13.0 + + + + + + + + + + + + + + + + + + Contents + + + + + + Menu + + + + + + + + Expand + + + + + + Light mode + + + + + + + + + + + + + + Dark mode + + + + + + + Auto light/dark mode + + + + + + + + + + + + + + + + + + + +
    +
    +
    + +
    + +
    +
    + +
    + +
    +
    + +
    +
    +
    + + + + + Back to top + +
    +
    + +
    + +
    +
    +

    Source code for bumpversion.indented_logger

    +"""A logger adapter that adds an indent to the beginning of each message."""
    +import logging
    +from contextvars import ContextVar
    +from typing import Any, MutableMapping, Optional, Tuple
    +
    +CURRENT_INDENT = ContextVar("current_indent", default=0)
    +
    +
    +
    +[docs] +class IndentedLoggerAdapter(logging.LoggerAdapter): + """ + Logger adapter that adds an indent to the beginning of each message. + + Parameters: + logger: The logger to adapt. + extra: Extra values to add to the logging context. + depth: The number of `indent_char` to generate for each indent level. + indent_char: The character or string to use for indenting. + reset: `True` if the indent level should be reset to zero. + """ + + def __init__( + self, + logger: logging.Logger, + extra: Optional[dict] = None, + depth: int = 2, + indent_char: str = " ", + reset: bool = False, + ): + super().__init__(logger, extra or {}) + self._depth = depth + self._indent_char = indent_char + if reset: + self.reset() + + @property + def current_indent(self) -> int: + """ + The current indent level. + """ + return CURRENT_INDENT.get() + +
    +[docs] + def indent(self, amount: int = 1) -> None: + """ + Increase the indent level by `amount`. + """ + CURRENT_INDENT.set(CURRENT_INDENT.get() + amount)
    + + +
    +[docs] + def dedent(self, amount: int = 1) -> None: + """ + Decrease the indent level by `amount`. + """ + CURRENT_INDENT.set(max(0, CURRENT_INDENT.get() - amount))
    + + +
    +[docs] + def reset(self) -> None: + """ + Reset the indent level to zero. + """ + CURRENT_INDENT.set(0)
    + + + @property + def indent_str(self) -> str: + """ + The indent string. + """ + return (self._indent_char * self._depth) * CURRENT_INDENT.get() + +
    +[docs] + def process(self, msg: str, kwargs: Optional[MutableMapping[str, Any]]) -> Tuple[str, MutableMapping[str, Any]]: + """ + Process the message and add the indent. + + Args: + msg: The logging message. + kwargs: Keyword arguments passed to the logger. + + Returns: + A tuple containing the message and keyword arguments. + """ + msg = self.indent_str + msg + + return msg, kwargs
    +
    + +
    +
    +
    + +
    + +
    +
    + + + + + + + \ No newline at end of file diff --git a/_modules/bumpversion/scm.html b/_modules/bumpversion/scm.html index 90a378d5..c64bfd01 100644 --- a/_modules/bumpversion/scm.html +++ b/_modules/bumpversion/scm.html @@ -1,16 +1,16 @@ - + - + bumpversion.scm - Bump My Version 0.13.0 - - - - - + + + + + @@ -177,25 +177,27 @@
  • Search and replace configuration
  • bumpversion
  • @@ -241,7 +243,6 @@

    Source code for bumpversion.scm

     """Version control system management."""
     
    -import logging
     import os
     import re
     import subprocess
    @@ -250,6 +251,7 @@ 

    Source code for bumpversion.scm

     from tempfile import NamedTemporaryFile
     from typing import TYPE_CHECKING, ClassVar, List, MutableMapping, Optional, Type, Union
     
    +from bumpversion.ui import get_indented_logger
     from bumpversion.utils import extract_regex_flags
     
     if TYPE_CHECKING:  # pragma: no-coverage
    @@ -257,10 +259,12 @@ 

    Source code for bumpversion.scm

     
     from bumpversion.exceptions import DirtyWorkingDirectoryError, SignedTagsError
     
    -logger = logging.getLogger(__name__)
    +logger = get_indented_logger(__name__)
     
     
    -
    [docs]@dataclass +
    +[docs] +@dataclass class SCMInfo: """Information about the current source code manager and state.""" @@ -272,26 +276,37 @@

    Source code for bumpversion.scm

         short_branch_name: Optional[str] = None
         dirty: Optional[bool] = None
     
    -
    [docs] def __str__(self): +
    +[docs] + def __str__(self): return self.__repr__()
    -
    [docs] def __repr__(self): + +
    +[docs] + def __repr__(self): tool_name = self.tool.__name__ if self.tool else "No SCM tool" return ( f"SCMInfo(tool={tool_name}, commit_sha={self.commit_sha}, " f"distance_to_latest_tag={self.distance_to_latest_tag}, current_version={self.current_version}, " f"dirty={self.dirty})" - )
    + )
    +
    + -
    [docs]class SourceCodeManager: +
    +[docs] +class SourceCodeManager: """Base class for version control systems.""" _TEST_USABLE_COMMAND: ClassVar[List[str]] = [] _COMMIT_COMMAND: ClassVar[List[str]] = [] _ALL_TAGS_COMMAND: ClassVar[List[str]] = [] -
    [docs] @classmethod +
    +[docs] + @classmethod def commit(cls, message: str, current_version: str, new_version: str, extra_args: Optional[list] = None) -> None: """Commit the changes.""" extra_args = extra_args or [] @@ -314,7 +329,10 @@

    Source code for bumpversion.scm

             finally:
                 os.unlink(f.name)
    -
    [docs] @classmethod + +
    +[docs] + @classmethod def is_usable(cls) -> bool: """Is the VCS implementation usable.""" try: @@ -323,27 +341,42 @@

    Source code for bumpversion.scm

             except (FileNotFoundError, PermissionError, NotADirectoryError, subprocess.CalledProcessError):
                 return False
    -
    [docs] @classmethod + +
    +[docs] + @classmethod def assert_nondirty(cls) -> None: """Assert that the working directory is not dirty.""" raise NotImplementedError()
    -
    [docs] @classmethod + +
    +[docs] + @classmethod def latest_tag_info(cls, tag_name: str, parse_pattern: str) -> SCMInfo: """Return information about the latest tag.""" raise NotImplementedError()
    -
    [docs] @classmethod + +
    +[docs] + @classmethod def add_path(cls, path: Union[str, Path]) -> None: """Add a path to the VCS.""" raise NotImplementedError()
    -
    [docs] @classmethod + +
    +[docs] + @classmethod def tag(cls, name: str, sign: bool = False, message: Optional[str] = None) -> None: """Create a tag of the new_version in VCS.""" raise NotImplementedError
    -
    [docs] @classmethod + +
    +[docs] + @classmethod def get_all_tags(cls) -> List[str]: """Return all tags in VCS.""" try: @@ -352,7 +385,10 @@

    Source code for bumpversion.scm

             except (FileNotFoundError, PermissionError, NotADirectoryError, subprocess.CalledProcessError):
                 return []
    -
    [docs] @classmethod + +
    +[docs] + @classmethod def get_version_from_tag(cls, tag: str, tag_name: str, parse_pattern: str) -> Optional[str]: """Return the version from a tag.""" version_pattern = parse_pattern.replace("\\\\", "\\") @@ -362,7 +398,10 @@

    Source code for bumpversion.scm

             tag_regex = re.compile(rep)
             return match["current_version"] if (match := tag_regex.match(tag)) else None
    -
    [docs] @classmethod + +
    +[docs] + @classmethod def commit_to_scm( cls, files: List[Union[str, Path]], @@ -386,6 +425,7 @@

    Source code for bumpversion.scm

                 "Preparing" if do_commit else "Would prepare",
                 cls.__name__,
             )
    +        logger.indent()
             for path in files:
                 logger.info(
                     "%s changes in file '%s' to %s",
    @@ -411,9 +451,13 @@ 

    Source code for bumpversion.scm

                     current_version=context["current_version"],
                     new_version=context["new_version"],
                     extra_args=extra_args,
    -            )
    + ) + logger.dedent()
    + -
    [docs] @classmethod +
    +[docs] + @classmethod def tag_in_scm(cls, config: "Config", context: MutableMapping, dry_run: bool = False) -> None: """Tag the current commit in the source code management system.""" if not config.commit: @@ -443,21 +487,33 @@

    Source code for bumpversion.scm

             if do_tag:
                 cls.tag(tag_name, sign_tags, tag_message)
    -
    [docs] def __str__(self): + +
    +[docs] + def __str__(self): return self.__repr__()
    -
    [docs] def __repr__(self): - return f"{self.__class__.__name__}"
    + +
    +[docs] + def __repr__(self): + return f"{self.__class__.__name__}"
    +
    + -
    [docs]class Git(SourceCodeManager): +
    +[docs] +class Git(SourceCodeManager): """Git implementation.""" _TEST_USABLE_COMMAND: ClassVar[List[str]] = ["git", "rev-parse", "--git-dir"] _COMMIT_COMMAND: ClassVar[List[str]] = ["git", "commit", "-F"] _ALL_TAGS_COMMAND: ClassVar[List[str]] = ["git", "tag", "--list"] -
    [docs] @classmethod +
    +[docs] + @classmethod def assert_nondirty(cls) -> None: """Assert that the working directory is not dirty.""" lines = [ @@ -470,7 +526,10 @@

    Source code for bumpversion.scm

                 joined_lines = b"\n".join(lines).decode()
                 raise DirtyWorkingDirectoryError(f"Git working directory is not clean:\n\n{joined_lines}")
    -
    [docs] @classmethod + +
    +[docs] + @classmethod def latest_tag_info(cls, tag_name: str, parse_pattern: str) -> SCMInfo: """Return information about the latest tag.""" try: @@ -517,12 +576,18 @@

    Source code for bumpversion.scm

     
             return info
    -
    [docs] @classmethod + +
    +[docs] + @classmethod def add_path(cls, path: Union[str, Path]) -> None: """Add a path to the VCS.""" subprocess.check_output(["git", "add", "--update", str(path)]) # noqa: S603, S607
    -
    [docs] @classmethod + +
    +[docs] + @classmethod def tag(cls, name: str, sign: bool = False, message: Optional[str] = None) -> None: """ Create a tag of the new_version in VCS. @@ -540,17 +605,23 @@

    Source code for bumpversion.scm

                 command += ["--sign"]
             if message:
                 command += ["--message", message]
    -        subprocess.check_output(command)  # noqa: S603
    + subprocess.check_output(command) # noqa: S603
    +
    + -
    [docs]class Mercurial(SourceCodeManager): +
    +[docs] +class Mercurial(SourceCodeManager): """Mercurial implementation.""" _TEST_USABLE_COMMAND: ClassVar[List[str]] = ["hg", "root"] _COMMIT_COMMAND: ClassVar[List[str]] = ["hg", "commit", "--logfile"] _ALL_TAGS_COMMAND: ClassVar[List[str]] = ["hg", "log", '--rev="tag()"', '--template="{tags}\n"'] -
    [docs] @classmethod +
    +[docs] + @classmethod def latest_tag_info(cls, tag_name: str, parse_pattern: str) -> SCMInfo: """Return information about the latest tag.""" current_version = None @@ -570,7 +641,10 @@

    Source code for bumpversion.scm

             is_dirty = len(subprocess.check_output(["hg", "status", "-mard"])) != 0  # noqa: S603, S607
             return SCMInfo(tool=cls, current_version=current_version, dirty=is_dirty)
    -
    [docs] @classmethod + +
    +[docs] + @classmethod def assert_nondirty(cls) -> None: """Assert that the working directory is clean.""" lines = [ @@ -583,12 +657,18 @@

    Source code for bumpversion.scm

                 joined_lines = b"\n".join(lines).decode()
                 raise DirtyWorkingDirectoryError(f"Mercurial working directory is not clean:\n{joined_lines}")
    -
    [docs] @classmethod + +
    +[docs] + @classmethod def add_path(cls, path: Union[str, Path]) -> None: """Add a path to the VCS.""" pass
    -
    [docs] @classmethod + +
    +[docs] + @classmethod def tag(cls, name: str, sign: bool = False, message: Optional[str] = None) -> None: """ Create a tag of the new_version in VCS. @@ -609,10 +689,14 @@

    Source code for bumpversion.scm

                 raise SignedTagsError("Mercurial does not support signed tags.")
             if message:
                 command += ["--message", message]
    -        subprocess.check_output(command)  # noqa: S603
    + subprocess.check_output(command) # noqa: S603
    +
    -
    [docs]def get_scm_info(tag_name: str, parse_pattern: str) -> SCMInfo: + +
    +[docs] +def get_scm_info(tag_name: str, parse_pattern: str) -> SCMInfo: """Return a dict with the latest source code management info.""" if Git.is_usable(): return Git.latest_tag_info(tag_name, parse_pattern) @@ -620,6 +704,7 @@

    Source code for bumpversion.scm

             return Mercurial.latest_tag_info(tag_name, parse_pattern)
         else:
             return SCMInfo()
    +
    @@ -659,11 +744,11 @@

    Source code for bumpversion.scm

           
         
       
    -
    - - - - - + + + + + + \ No newline at end of file diff --git a/_modules/bumpversion/show.html b/_modules/bumpversion/show.html index c37c2ebc..776b3538 100644 --- a/_modules/bumpversion/show.html +++ b/_modules/bumpversion/show.html @@ -1,16 +1,16 @@ - + - + bumpversion.show - Bump My Version 0.13.0 - - - - - + + + + + @@ -177,25 +177,27 @@
  • Search and replace configuration
  • bumpversion
  • @@ -252,7 +254,9 @@

    Source code for bumpversion.show

     from bumpversion.utils import get_context, recursive_sort_dict
     
     
    -
    [docs]def output_default(value: dict) -> None: +
    +[docs] +def output_default(value: dict) -> None: """Output the value with key=value or just value if there is only one item.""" if len(value) == 1: print_info(next(iter(value.values()))) @@ -262,14 +266,20 @@

    Source code for bumpversion.show

             print_info(buffer.getvalue())
    -
    [docs]def output_yaml(value: dict) -> None: + +
    +[docs] +def output_yaml(value: dict) -> None: """Output the value as yaml.""" from bumpversion.yaml_dump import dump print_info(dump(recursive_sort_dict(value)))
    -
    [docs]def output_json(value: dict) -> None: + +
    +[docs] +def output_json(value: dict) -> None: """Output the value as json.""" import json @@ -283,6 +293,7 @@

    Source code for bumpversion.show

         print_info(json.dumps(value, sort_keys=True, indent=2, default=default_encoder))
    + OUTPUTTERS = { "yaml": output_yaml, "json": output_json, @@ -290,7 +301,9 @@

    Source code for bumpversion.show

     }
     
     
    -
    [docs]def resolve_name(obj: Any, name: str, default: Any = None, err_on_missing: bool = False) -> Any: +
    +[docs] +def resolve_name(obj: Any, name: str, default: Any = None, err_on_missing: bool = False) -> Any: """ Get a key or attr ``name`` from obj or default value. @@ -348,7 +361,10 @@

    Source code for bumpversion.show

                 return default
    -
    [docs]def log_list(config: Config, version_part: Optional[str], new_version: Optional[str]) -> None: + +
    +[docs] +def log_list(config: Config, version_part: Optional[str], new_version: Optional[str]) -> None: """Output configuration with new version.""" ctx = get_context(config) if version_part: @@ -363,7 +379,10 @@

    Source code for bumpversion.show

             print_info(f"{key}={value}")
    -
    [docs]def do_show(*args, config: Config, format_: str = "default", increment: Optional[str] = None) -> None: + +
    +[docs] +def do_show(*args, config: Config, format_: str = "default", increment: Optional[str] = None) -> None: """Show current version or configuration information.""" config_dict = config.model_dump() ctx = get_context(config) @@ -383,6 +402,7 @@

    Source code for bumpversion.show

             OUTPUTTERS.get(format_, OUTPUTTERS["default"])(show_items)
         except BadInputError as e:
             print_error(e.message)
    +
    @@ -422,11 +442,11 @@

    Source code for bumpversion.show

           
         
       
    -
    - - - - - +
    + + + + + \ No newline at end of file diff --git a/_modules/bumpversion/ui.html b/_modules/bumpversion/ui.html index a1b026cd..f22faad2 100644 --- a/_modules/bumpversion/ui.html +++ b/_modules/bumpversion/ui.html @@ -1,16 +1,16 @@ - + - + bumpversion.ui - Bump My Version 0.13.0 - - - - - + + + + + @@ -177,25 +177,27 @@
  • Search and replace configuration
  • bumpversion
  • @@ -246,6 +248,8 @@

    Source code for bumpversion.ui

     from click import UsageError, secho
     from rich.logging import RichHandler
     
    +from bumpversion.indented_logger import IndentedLoggerAdapter
    +
     logger = logging.getLogger("bumpversion")
     
     VERBOSITY = {
    @@ -255,7 +259,17 @@ 

    Source code for bumpversion.ui

     }
     
     
    -
    [docs]def setup_logging(verbose: int = 0) -> None: +
    +[docs] +def get_indented_logger(name: str) -> "IndentedLoggerAdapter": + """Get a logger with indentation.""" + return IndentedLoggerAdapter(logging.getLogger(name))
    + + + +
    +[docs] +def setup_logging(verbose: int = 0) -> None: """Configure the logging.""" logging.basicConfig( level=VERBOSITY.get(verbose, logging.DEBUG), @@ -267,23 +281,33 @@

    Source code for bumpversion.ui

                 )
             ],
         )
    -    root_logger = logging.getLogger("")
    +    root_logger = get_indented_logger("")
         root_logger.setLevel(VERBOSITY.get(verbose, logging.DEBUG))
    -
    @@ -323,11 +347,11 @@

    Source code for bumpversion.ui

           
         
       
    -
    - - - - - +
    + + + + + \ No newline at end of file diff --git a/_modules/bumpversion/utils.html b/_modules/bumpversion/utils.html index a2836318..60137dd4 100644 --- a/_modules/bumpversion/utils.html +++ b/_modules/bumpversion/utils.html @@ -1,16 +1,16 @@ - + - + bumpversion.utils - Bump My Version 0.13.0 - - - - - + + + + + @@ -177,25 +177,27 @@
  • Search and replace configuration
  • bumpversion
  • @@ -250,7 +252,9 @@

    Source code for bumpversion.utils

         from bumpversion.version_part import Version
     
     
    -
    [docs]def extract_regex_flags(regex_pattern: str) -> Tuple[str, str]: +
    +[docs] +def extract_regex_flags(regex_pattern: str) -> Tuple[str, str]: """ Extract the regex flags from the regex pattern. @@ -267,7 +271,10 @@

    Source code for bumpversion.utils

         return (regex_pattern, "") if len(bits) == 1 else (bits[2], bits[1])
    -
    [docs]def recursive_sort_dict(input_value: Any) -> Any: + +
    +[docs] +def recursive_sort_dict(input_value: Any) -> Any: """Sort a dictionary recursively.""" if not isinstance(input_value, dict): return input_value @@ -275,24 +282,36 @@

    Source code for bumpversion.utils

         return {key: recursive_sort_dict(input_value[key]) for key in sorted(input_value.keys())}
    -
    [docs]def key_val_string(d: dict) -> str: + +
    +[docs] +def key_val_string(d: dict) -> str: """Render the dictionary as a comma-delimited key=value string.""" return ", ".join(f"{k}={v}" for k, v in sorted(d.items()))
    -
    [docs]def prefixed_environ() -> dict: + +
    +[docs] +def prefixed_environ() -> dict: """Return a dict of the environment with keys wrapped in `${}`.""" import os return {f"${key}": value for key, value in os.environ.items()}
    -
    [docs]def labels_for_format(serialize_format: str) -> List[str]: + +
    +[docs] +def labels_for_format(serialize_format: str) -> List[str]: """Return a list of labels for the given serialize_format.""" return [item[1] for item in string.Formatter().parse(serialize_format) if item[1]]
    -
    [docs]def get_context( + +
    +[docs] +def get_context( config: "Config", current_version: Optional["Version"] = None, new_version: Optional["Version"] = None ) -> ChainMap: """Return the context for rendering messages and tags.""" @@ -312,9 +331,13 @@

    Source code for bumpversion.utils

         return ctx
    -
    [docs]def get_overrides(**kwargs) -> dict: + +
    +[docs] +def get_overrides(**kwargs) -> dict: """Return a dictionary containing only the overridden key-values.""" return {key: val for key, val in kwargs.items() if val is not None}
    +
    @@ -354,11 +377,11 @@

    Source code for bumpversion.utils

           
         
       
    - - - - - - + + + + + + \ No newline at end of file diff --git a/_modules/bumpversion/version_part.html b/_modules/bumpversion/version_part.html index aa0cba34..23a69699 100644 --- a/_modules/bumpversion/version_part.html +++ b/_modules/bumpversion/version_part.html @@ -1,16 +1,16 @@ - + - + bumpversion.version_part - Bump My Version 0.13.0 - - - - - + + + + + @@ -177,25 +177,27 @@
  • Search and replace configuration
  • bumpversion
  • @@ -240,23 +242,25 @@

    Source code for bumpversion.version_part

     """Module for managing Versions and their internal parts."""
    -import logging
     import re
     import string
     from copy import copy
    -from typing import Any, Dict, List, MutableMapping, Optional, Union
    +from typing import Any, Dict, List, MutableMapping, Optional, Tuple, Union
     
     from click import UsageError
     
     from bumpversion.config.models import VersionPartConfig
     from bumpversion.exceptions import FormattingError, InvalidVersionPartError, MissingValueError
     from bumpversion.functions import NumericFunction, PartFunction, ValuesFunction
    +from bumpversion.ui import get_indented_logger
     from bumpversion.utils import key_val_string, labels_for_format
     
    -logger = logging.getLogger(__name__)
    +logger = get_indented_logger(__name__)
     
     
    -
    [docs]class VersionPart: +
    +[docs] +class VersionPart: """ Represent part of a version number. @@ -281,18 +285,27 @@

    Source code for bumpversion.version_part

             """Return the value of the part."""
             return self._value or self.func.optional_value
     
    -
    [docs] def copy(self) -> "VersionPart": +
    +[docs] + def copy(self) -> "VersionPart": """Return a copy of the part.""" return VersionPart(self.config, self._value)
    -
    [docs] def bump(self) -> "VersionPart": + +
    +[docs] + def bump(self) -> "VersionPart": """Return a part with bumped value.""" return VersionPart(self.config, self.func.bump(self.value))
    -
    [docs] def null(self) -> "VersionPart": + +
    +[docs] + def null(self) -> "VersionPart": """Return a part with first value.""" return VersionPart(self.config, self.func.first_value)
    + @property def is_optional(self) -> bool: """Is the part optional?""" @@ -303,7 +316,9 @@

    Source code for bumpversion.version_part

             """Is the part independent of the other parts?"""
             return self.config.independent
     
    -
    [docs] def __format__(self, format_spec: str) -> str: +
    +[docs] + def __format__(self, format_spec: str) -> str: try: val = int(self.value) except ValueError: @@ -311,40 +326,67 @@

    Source code for bumpversion.version_part

             else:
                 return int.__format__(val, format_spec)
    -
    [docs] def __repr__(self) -> str: + +
    +[docs] + def __repr__(self) -> str: return f"<bumpversion.VersionPart:{self.func.__class__.__name__}:{self.value}>"
    -
    [docs] def __eq__(self, other: Any) -> bool: - return self.value == other.value if isinstance(other, VersionPart) else False
    + +
    +[docs] + def __eq__(self, other: Any) -> bool: + return self.value == other.value if isinstance(other, VersionPart) else False
    +
    + -
    [docs]class Version: +
    +[docs] +class Version: """The specification of a version and its parts.""" def __init__(self, values: Dict[str, VersionPart], original: Optional[str] = None): self.values = values self.original = original -
    [docs] def __getitem__(self, key: str) -> VersionPart: +
    +[docs] + def __getitem__(self, key: str) -> VersionPart: return self.values[key]
    -
    [docs] def __len__(self) -> int: + +
    +[docs] + def __len__(self) -> int: return len(self.values)
    -
    [docs] def __iter__(self): + +
    +[docs] + def __iter__(self): return iter(self.values)
    -
    [docs] def __repr__(self): + +
    +[docs] + def __repr__(self): return f"<bumpversion.Version:{key_val_string(self.values)}>"
    -
    [docs] def __eq__(self, other: Any) -> bool: + +
    +[docs] + def __eq__(self, other: Any) -> bool: return ( all(value == other.values[key] for key, value in self.values.items()) if isinstance(other, Version) else False )
    -
    [docs] def bump(self, part_name: str, order: List[str]) -> "Version": + +
    +[docs] + def bump(self, part_name: str, order: List[str]) -> "Version": """Increase the value of the given part.""" bumped = False @@ -364,10 +406,14 @@

    Source code for bumpversion.version_part

             if not bumped:
                 raise InvalidVersionPartError(f"No part named {part_name!r}")
     
    -        return Version(new_values)
    + return Version(new_values)
    +
    + -
    [docs]class VersionConfig: +
    +[docs] +class VersionConfig: """ Hold a complete representation of a version string. """ @@ -375,7 +421,7 @@

    Source code for bumpversion.version_part

         def __init__(
             self,
             parse: str,
    -        serialize: List[str],
    +        serialize: Tuple[str],
             search: str,
             replace: str,
             part_configs: Optional[Dict[str, VersionPartConfig]] = None,
    @@ -404,7 +450,9 @@ 

    Source code for bumpversion.version_part

             """
             return labels_for_format(self.serialize_formats[0])
     
    -
    [docs] def parse(self, version_string: Optional[str] = None) -> Optional[Version]: +
    +[docs] + def parse(self, version_string: Optional[str] = None) -> Optional[Version]: """ Parse a version string into a Version object. @@ -424,6 +472,7 @@

    Source code for bumpversion.version_part

                 version_string,
                 regexp_one_line,
             )
    +        logger.indent()
     
             match = self.parse_regex.search(version_string)
     
    @@ -443,10 +492,14 @@ 

    Source code for bumpversion.version_part

             v = Version(_parsed, version_string)
     
             logger.info("Parsed the following values: %s", key_val_string(v.values))
    +        logger.dedent()
     
             return v
    -
    [docs] def _serialize( + +
    +[docs] + def _serialize( self, version: Version, serialize_format: str, context: MutableMapping, raise_if_incomplete: bool = False ) -> str: """ @@ -506,11 +559,14 @@

    Source code for bumpversion.version_part

     
             return serialized
    -
    [docs] def _choose_serialize_format(self, version: Version, context: MutableMapping) -> str: - chosen = None - logger.debug("Available serialization formats: '%s'", "', '".join(self.serialize_formats)) +
    +[docs] + def _choose_serialize_format(self, version: Version, context: MutableMapping) -> str: + chosen = None + logger.debug("Evaluating serialization formats") + logger.indent() for serialize_format in self.serialize_formats: try: self._serialize(version, serialize_format, context, raise_if_incomplete=True) @@ -532,12 +588,15 @@

    Source code for bumpversion.version_part

     
             if not chosen:
                 raise KeyError("Did not find suitable serialization format")
    -
    +        logger.dedent()
             logger.debug("Selected serialization format '%s'", chosen)
     
             return chosen
    -
    [docs] def serialize(self, version: Version, context: MutableMapping) -> str: + +
    +[docs] + def serialize(self, version: Version, context: MutableMapping) -> str: """ Serialize a version to a string. @@ -548,9 +607,14 @@

    Source code for bumpversion.version_part

             Returns:
                 The serialized version as a string
             """
    +        logger.debug("Serializing version '%s'", version)
    +        logger.indent()
             serialized = self._serialize(version, self._choose_serialize_format(version, context), context)
             logger.debug("Serialized to '%s'", serialized)
    -        return serialized
    + logger.dedent() + return serialized
    +
    +
    @@ -590,11 +654,11 @@

    Source code for bumpversion.version_part

           
         
       
    - - - - - - + + + + + + \ No newline at end of file diff --git a/_modules/bumpversion/yaml_dump.html b/_modules/bumpversion/yaml_dump.html index 3d0f0691..57a376ee 100644 --- a/_modules/bumpversion/yaml_dump.html +++ b/_modules/bumpversion/yaml_dump.html @@ -1,16 +1,16 @@ - + - + bumpversion.yaml_dump - Bump My Version 0.13.0 - - - - - + + + + + @@ -177,25 +177,27 @@
  • Search and replace configuration
  • bumpversion
  • @@ -244,17 +246,23 @@

    Source code for bumpversion.yaml_dump

     from collections import UserDict
     from io import StringIO
     from textwrap import indent
    -from typing import Any, Callable
    +from typing import Any, Callable, Union
     
     DumperFunc = Callable[[Any], str]
     
     
    -
    [docs]class YAMLDumpers(UserDict): +
    +[docs] +class YAMLDumpers(UserDict): """Registry of YAML dumpers.""" -
    [docs] def add_dumper(self, data_type: type, dumper: DumperFunc) -> None: +
    +[docs] + def add_dumper(self, data_type: type, dumper: DumperFunc) -> None: """Add a YAML dumper.""" - self.data[data_type] = dumper
    + self.data[data_type] = dumper
    +
    + YAML_DUMPERS = YAMLDumpers() @@ -262,7 +270,9 @@

    Source code for bumpversion.yaml_dump

     INDENT = "  "
     
     
    -
    [docs]def dump(data: Any) -> str: +
    +[docs] +def dump(data: Any) -> str: """Dump a value to a string buffer.""" data_types = type(data).__mro__ for data_type in data_types: @@ -272,24 +282,33 @@

    Source code for bumpversion.yaml_dump

         return YAML_DUMPERS[str](str(data))
    -
    [docs]def format_str(val: str) -> str: + +
    +[docs] +def format_str(val: str) -> str: """Return a YAML representation of a string.""" val = val.replace("\\", "\\\\").replace("\n", "\\n") return f'"{val}"'
    + YAML_DUMPERS.add_dumper(str, format_str) -
    [docs]def format_int(val: int) -> str: +
    +[docs] +def format_int(val: int) -> str: """Return a YAML representation of an int.""" return str(val)
    + YAML_DUMPERS.add_dumper(int, format_int) -
    [docs]def format_float(data: float) -> str: +
    +[docs] +def format_float(data: float) -> str: """Return a YAML representation of a float.""" inf_value = 1e300 @@ -313,24 +332,30 @@

    Source code for bumpversion.yaml_dump

         return str(value)
    + YAML_DUMPERS.add_dumper(float, format_float) -
    [docs]def format_bool(val: bool) -> str: +
    +[docs] +def format_bool(val: bool) -> str: """Return a YAML representation of a bool.""" return "true" if val else "false"
    + YAML_DUMPERS.add_dumper(bool, format_bool) -
    [docs]def format_dict(val: dict) -> str: +
    +[docs] +def format_dict(val: dict) -> str: """Return a YAML representation of a dict.""" buffer = StringIO() for key, value in sorted(val.items()): rendered_value = dump(value).strip() - if isinstance(value, (dict, list)): + if isinstance(value, (dict, list, tuple)): rendered_value = f"\n{indent(rendered_value, INDENT)}" else: rendered_value = f" {rendered_value}" @@ -339,10 +364,13 @@

    Source code for bumpversion.yaml_dump

         return buffer.getvalue()
    + YAML_DUMPERS.add_dumper(dict, format_dict) -
    [docs]def format_list(val: list) -> str: +
    +[docs] +def format_sequence(val: Union[list, tuple]) -> str: """Return a string representation of a value.""" buffer = StringIO() @@ -351,7 +379,7 @@

    Source code for bumpversion.yaml_dump

             if isinstance(item, dict):
                 rendered_value = indent(rendered_value, INDENT).strip()
     
    -        if isinstance(item, list):
    +        if isinstance(item, (list, tuple)):
                 rendered_value = f"\n{indent(rendered_value, INDENT)}"
             else:
                 rendered_value = f" {rendered_value}"
    @@ -360,30 +388,41 @@ 

    Source code for bumpversion.yaml_dump

         return buffer.getvalue()
    -YAML_DUMPERS.add_dumper(list, format_list) + +YAML_DUMPERS.add_dumper(list, format_sequence) +YAML_DUMPERS.add_dumper(tuple, format_sequence) -
    [docs]def format_none(_: None) -> str: +
    +[docs] +def format_none(_: None) -> str: """Return a YAML representation of None.""" return "null"
    + YAML_DUMPERS.add_dumper(type(None), format_none) -
    [docs]def format_date(val: datetime.date) -> str: +
    +[docs] +def format_date(val: datetime.date) -> str: """Return a YAML representation of a date.""" return val.isoformat()
    + YAML_DUMPERS.add_dumper(datetime.date, format_date) -
    [docs]def format_datetime(val: datetime.datetime) -> str: +
    +[docs] +def format_datetime(val: datetime.datetime) -> str: """Return a string representation of a value.""" return val.isoformat(" ")
    + YAML_DUMPERS.add_dumper(datetime.datetime, format_datetime)
    @@ -424,11 +463,11 @@

    Source code for bumpversion.yaml_dump

           
         
       
    -
    - - - - - +
    + + + + + \ No newline at end of file diff --git a/_modules/index.html b/_modules/index.html index 2f8c6fcd..8920f851 100644 --- a/_modules/index.html +++ b/_modules/index.html @@ -1,16 +1,16 @@ - + - + Overview: module code - Bump My Version 0.13.0 - - - - - + + + + + @@ -177,25 +177,27 @@
  • Search and replace configuration
  • bumpversion
  • @@ -244,11 +246,13 @@

    All modules for which code is available

  • bumpversion.bump
  • bumpversion.config
  • bumpversion.exceptions
  • bumpversion.files
  • bumpversion.functions
  • +
  • bumpversion.indented_logger
  • bumpversion.scm
  • bumpversion.show
  • bumpversion.ui
  • @@ -294,11 +298,11 @@

    All modules for which code is available

    -
    - - - - - +
    + + + + + \ No newline at end of file diff --git a/_sources/reference/bumpversion/bumpversion.aliases.md.txt b/_sources/reference/bumpversion/bumpversion.aliases.md.txt index 97cec39b..579c985b 100644 --- a/_sources/reference/bumpversion/bumpversion.aliases.md.txt +++ b/_sources/reference/bumpversion/bumpversion.aliases.md.txt @@ -23,7 +23,7 @@ ### API -`````{py:class} AliasedGroup(name: typing.Optional[str] = None, commands: typing.Optional[typing.Union[typing.Dict[str, click.core.Command], typing.Sequence[click.core.Command]]] = None, **attrs: typing.Any) +`````{py:class} AliasedGroup(*args: typing.Any, **kwargs: typing.Any) :canonical: bumpversion.aliases.AliasedGroup Bases: {py:obj}`rich_click.rich_group.RichGroup` diff --git a/_sources/reference/bumpversion/bumpversion.bump.md.txt b/_sources/reference/bumpversion/bumpversion.bump.md.txt index b42e31c7..8e765bb1 100644 --- a/_sources/reference/bumpversion/bumpversion.bump.md.txt +++ b/_sources/reference/bumpversion/bumpversion.bump.md.txt @@ -46,7 +46,7 @@ ````{py:data} logger :canonical: bumpversion.bump.logger :value: > - None + 'get_indented_logger(...)' ```{autodoc2-docstring} bumpversion.bump.logger ``` diff --git a/_sources/reference/bumpversion/bumpversion.cli.md.txt b/_sources/reference/bumpversion/bumpversion.cli.md.txt index db794c4c..5c9a18b2 100644 --- a/_sources/reference/bumpversion/bumpversion.cli.md.txt +++ b/_sources/reference/bumpversion/bumpversion.cli.md.txt @@ -50,7 +50,7 @@ ````{py:data} logger :canonical: bumpversion.cli.logger :value: > - None + 'get_indented_logger(...)' ```{autodoc2-docstring} bumpversion.cli.logger ``` diff --git a/_sources/reference/bumpversion/bumpversion.config.files.md.txt b/_sources/reference/bumpversion/bumpversion.config.files.md.txt index 395d62db..9beb1c4e 100644 --- a/_sources/reference/bumpversion/bumpversion.config.files.md.txt +++ b/_sources/reference/bumpversion/bumpversion.config.files.md.txt @@ -23,10 +23,6 @@ - ```{autodoc2-docstring} bumpversion.config.files.read_config_file :summary: ``` -* - {py:obj}`read_ini_file ` - - ```{autodoc2-docstring} bumpversion.config.files.read_ini_file - :summary: - ``` * - {py:obj}`read_toml_file ` - ```{autodoc2-docstring} bumpversion.config.files.read_toml_file :summary: @@ -35,10 +31,6 @@ - ```{autodoc2-docstring} bumpversion.config.files.update_config_file :summary: ``` -* - {py:obj}`update_ini_config_file ` - - ```{autodoc2-docstring} bumpversion.config.files.update_ini_config_file - :summary: - ``` ```` ### Data @@ -62,7 +54,7 @@ ````{py:data} logger :canonical: bumpversion.config.files.logger :value: > - None + 'get_indented_logger(...)' ```{autodoc2-docstring} bumpversion.config.files.logger ``` @@ -72,7 +64,7 @@ ````{py:data} CONFIG_FILE_SEARCH_ORDER :canonical: bumpversion.config.files.CONFIG_FILE_SEARCH_ORDER :value: > - () + ('.bumpversion.cfg', '.bumpversion.toml', 'setup.cfg', 'pyproject.toml') ```{autodoc2-docstring} bumpversion.config.files.CONFIG_FILE_SEARCH_ORDER ``` @@ -93,13 +85,6 @@ ``` ```` -````{py:function} read_ini_file(file_path: pathlib.Path) -> typing.Dict[str, typing.Any] -:canonical: bumpversion.config.files.read_ini_file - -```{autodoc2-docstring} bumpversion.config.files.read_ini_file -``` -```` - ````{py:function} read_toml_file(file_path: pathlib.Path) -> typing.Dict[str, typing.Any] :canonical: bumpversion.config.files.read_toml_file @@ -113,10 +98,3 @@ ```{autodoc2-docstring} bumpversion.config.files.update_config_file ``` ```` - -````{py:function} update_ini_config_file(config_file: typing.Union[str, pathlib.Path], current_version: str, new_version: str, dry_run: bool = False) -> None -:canonical: bumpversion.config.files.update_ini_config_file - -```{autodoc2-docstring} bumpversion.config.files.update_ini_config_file -``` -```` diff --git a/_sources/reference/bumpversion/bumpversion.config.files_legacy.md.txt b/_sources/reference/bumpversion/bumpversion.config.files_legacy.md.txt new file mode 100644 index 00000000..1b856036 --- /dev/null +++ b/_sources/reference/bumpversion/bumpversion.config.files_legacy.md.txt @@ -0,0 +1,64 @@ +# {py:mod}`bumpversion.config.files_legacy` + +```{py:module} bumpversion.config.files_legacy +``` + +```{autodoc2-docstring} bumpversion.config.files_legacy +:allowtitles: +``` + +## Module Contents + +### Functions + +````{list-table} +:class: autosummary longtable +:align: left + +* - {py:obj}`read_ini_file ` + - ```{autodoc2-docstring} bumpversion.config.files_legacy.read_ini_file + :summary: + ``` +* - {py:obj}`update_ini_config_file ` + - ```{autodoc2-docstring} bumpversion.config.files_legacy.update_ini_config_file + :summary: + ``` +```` + +### Data + +````{list-table} +:class: autosummary longtable +:align: left + +* - {py:obj}`logger ` + - ```{autodoc2-docstring} bumpversion.config.files_legacy.logger + :summary: + ``` +```` + +### API + +````{py:data} logger +:canonical: bumpversion.config.files_legacy.logger +:value: > + 'get_indented_logger(...)' + +```{autodoc2-docstring} bumpversion.config.files_legacy.logger +``` + +```` + +````{py:function} read_ini_file(file_path: pathlib.Path) -> typing.Dict[str, typing.Any] +:canonical: bumpversion.config.files_legacy.read_ini_file + +```{autodoc2-docstring} bumpversion.config.files_legacy.read_ini_file +``` +```` + +````{py:function} update_ini_config_file(config_file: typing.Union[str, pathlib.Path], current_version: str, new_version: str, dry_run: bool = False) -> None +:canonical: bumpversion.config.files_legacy.update_ini_config_file + +```{autodoc2-docstring} bumpversion.config.files_legacy.update_ini_config_file +``` +```` diff --git a/_sources/reference/bumpversion/bumpversion.config.md.txt b/_sources/reference/bumpversion/bumpversion.config.md.txt index 6d58c28d..ede08dd6 100644 --- a/_sources/reference/bumpversion/bumpversion.config.md.txt +++ b/_sources/reference/bumpversion/bumpversion.config.md.txt @@ -13,9 +13,10 @@ :titlesonly: :maxdepth: 1 -bumpversion.config.models +bumpversion.config.files_legacy bumpversion.config.files bumpversion.config.utils +bumpversion.config.models ``` ## Package Contents @@ -57,7 +58,7 @@ bumpversion.config.utils ````{py:data} logger :canonical: bumpversion.config.logger :value: > - None + 'get_indented_logger(...)' ```{autodoc2-docstring} bumpversion.config.logger ``` diff --git a/_sources/reference/bumpversion/bumpversion.config.models.md.txt b/_sources/reference/bumpversion/bumpversion.config.models.md.txt index a3535342..b670f76f 100644 --- a/_sources/reference/bumpversion/bumpversion.config.models.md.txt +++ b/_sources/reference/bumpversion/bumpversion.config.models.md.txt @@ -19,8 +19,8 @@ - ```{autodoc2-docstring} bumpversion.config.models.VersionPartConfig :summary: ``` -* - {py:obj}`FileConfig ` - - ```{autodoc2-docstring} bumpversion.config.models.FileConfig +* - {py:obj}`FileChange ` + - ```{autodoc2-docstring} bumpversion.config.models.FileChange :summary: ``` * - {py:obj}`Config ` @@ -29,8 +29,30 @@ ``` ```` +### Data + +````{list-table} +:class: autosummary longtable +:align: left + +* - {py:obj}`logger ` + - ```{autodoc2-docstring} bumpversion.config.models.logger + :summary: + ``` +```` + ### API +````{py:data} logger +:canonical: bumpversion.config.models.logger +:value: > + 'get_indented_logger(...)' + +```{autodoc2-docstring} bumpversion.config.models.logger +``` + +```` + `````{py:class} VersionPartConfig(**data: typing.Any) :canonical: bumpversion.config.models.VersionPartConfig @@ -91,115 +113,131 @@ Bases: {py:obj}`pydantic.BaseModel` ````` -`````{py:class} FileConfig(**data: typing.Any) -:canonical: bumpversion.config.models.FileConfig +`````{py:class} FileChange(**data: typing.Any) +:canonical: bumpversion.config.models.FileChange Bases: {py:obj}`pydantic.BaseModel` -```{autodoc2-docstring} bumpversion.config.models.FileConfig +```{autodoc2-docstring} bumpversion.config.models.FileChange ``` ```{rubric} Initialization ``` -```{autodoc2-docstring} bumpversion.config.models.FileConfig.__init__ +```{autodoc2-docstring} bumpversion.config.models.FileChange.__init__ ``` ````{py:attribute} parse -:canonical: bumpversion.config.models.FileConfig.parse +:canonical: bumpversion.config.models.FileChange.parse :type: str :value: > None -```{autodoc2-docstring} bumpversion.config.models.FileConfig.parse +```{autodoc2-docstring} bumpversion.config.models.FileChange.parse ``` ```` ````{py:attribute} serialize -:canonical: bumpversion.config.models.FileConfig.serialize -:type: typing.List[str] +:canonical: bumpversion.config.models.FileChange.serialize +:type: tuple :value: > None -```{autodoc2-docstring} bumpversion.config.models.FileConfig.serialize +```{autodoc2-docstring} bumpversion.config.models.FileChange.serialize ``` ```` ````{py:attribute} search -:canonical: bumpversion.config.models.FileConfig.search +:canonical: bumpversion.config.models.FileChange.search :type: str :value: > None -```{autodoc2-docstring} bumpversion.config.models.FileConfig.search +```{autodoc2-docstring} bumpversion.config.models.FileChange.search ``` ```` ````{py:attribute} replace -:canonical: bumpversion.config.models.FileConfig.replace +:canonical: bumpversion.config.models.FileChange.replace :type: str :value: > None -```{autodoc2-docstring} bumpversion.config.models.FileConfig.replace +```{autodoc2-docstring} bumpversion.config.models.FileChange.replace ``` ```` ````{py:attribute} regex -:canonical: bumpversion.config.models.FileConfig.regex +:canonical: bumpversion.config.models.FileChange.regex :type: bool :value: > None -```{autodoc2-docstring} bumpversion.config.models.FileConfig.regex +```{autodoc2-docstring} bumpversion.config.models.FileChange.regex ``` ```` ````{py:attribute} ignore_missing_version -:canonical: bumpversion.config.models.FileConfig.ignore_missing_version +:canonical: bumpversion.config.models.FileChange.ignore_missing_version :type: bool :value: > None -```{autodoc2-docstring} bumpversion.config.models.FileConfig.ignore_missing_version +```{autodoc2-docstring} bumpversion.config.models.FileChange.ignore_missing_version ``` ```` ````{py:attribute} filename -:canonical: bumpversion.config.models.FileConfig.filename +:canonical: bumpversion.config.models.FileChange.filename :type: typing.Optional[str] :value: > None -```{autodoc2-docstring} bumpversion.config.models.FileConfig.filename +```{autodoc2-docstring} bumpversion.config.models.FileChange.filename ``` ```` ````{py:attribute} glob -:canonical: bumpversion.config.models.FileConfig.glob +:canonical: bumpversion.config.models.FileChange.glob :type: typing.Optional[str] :value: > None -```{autodoc2-docstring} bumpversion.config.models.FileConfig.glob +```{autodoc2-docstring} bumpversion.config.models.FileChange.glob ``` ```` ````{py:attribute} key_path -:canonical: bumpversion.config.models.FileConfig.key_path +:canonical: bumpversion.config.models.FileChange.key_path :type: typing.Optional[str] :value: > None -```{autodoc2-docstring} bumpversion.config.models.FileConfig.key_path +```{autodoc2-docstring} bumpversion.config.models.FileChange.key_path +``` + +```` + +````{py:method} __hash__() +:canonical: bumpversion.config.models.FileChange.__hash__ + +```{autodoc2-docstring} bumpversion.config.models.FileChange.__hash__ +``` + +```` + +````{py:method} get_search_pattern(context: typing.MutableMapping) -> typing.Tuple[re.Pattern, str] +:canonical: bumpversion.config.models.FileChange.get_search_pattern + +```{autodoc2-docstring} bumpversion.config.models.FileChange.get_search_pattern ``` ```` @@ -244,9 +282,9 @@ Bases: {py:obj}`pydantic_settings.BaseSettings` ````{py:attribute} serialize :canonical: bumpversion.config.models.Config.serialize -:type: typing.List[str] +:type: tuple :value: > - None + 'Field(...)' ```{autodoc2-docstring} bumpversion.config.models.Config.serialize ``` @@ -409,9 +447,9 @@ Bases: {py:obj}`pydantic_settings.BaseSettings` ````{py:attribute} files :canonical: bumpversion.config.models.Config.files -:type: typing.List[bumpversion.config.models.FileConfig] +:type: typing.List[bumpversion.config.models.FileChange] :value: > - None + 'Field(...)' ```{autodoc2-docstring} bumpversion.config.models.Config.files ``` @@ -422,7 +460,7 @@ Bases: {py:obj}`pydantic_settings.BaseSettings` :canonical: bumpversion.config.models.Config.included_paths :type: typing.List[str] :value: > - None + 'Field(...)' ```{autodoc2-docstring} bumpversion.config.models.Config.included_paths ``` @@ -433,7 +471,7 @@ Bases: {py:obj}`pydantic_settings.BaseSettings` :canonical: bumpversion.config.models.Config.excluded_paths :type: typing.List[str] :value: > - None + 'Field(...)' ```{autodoc2-docstring} bumpversion.config.models.Config.excluded_paths ``` @@ -443,13 +481,24 @@ Bases: {py:obj}`pydantic_settings.BaseSettings` ````{py:attribute} model_config :canonical: bumpversion.config.models.Config.model_config :value: > - None + 'SettingsConfigDict(...)' ```{autodoc2-docstring} bumpversion.config.models.Config.model_config ``` ```` +````{py:attribute} _resolved_filemap +:canonical: bumpversion.config.models.Config._resolved_filemap +:type: typing.Optional[typing.Dict[str, typing.List[bumpversion.config.models.FileChange]]] +:value: > + None + +```{autodoc2-docstring} bumpversion.config.models.Config._resolved_filemap +``` + +```` + ````{py:method} add_files(filename: typing.Union[str, typing.List[str]]) -> None :canonical: bumpversion.config.models.Config.add_files @@ -460,16 +509,24 @@ Bases: {py:obj}`pydantic_settings.BaseSettings` ````{py:property} resolved_filemap :canonical: bumpversion.config.models.Config.resolved_filemap -:type: typing.Dict[str, bumpversion.config.models.FileConfig] +:type: typing.Dict[str, typing.List[bumpversion.config.models.FileChange]] ```{autodoc2-docstring} bumpversion.config.models.Config.resolved_filemap ``` ```` +````{py:method} _resolve_filemap() -> typing.Dict[str, typing.List[bumpversion.config.models.FileChange]] +:canonical: bumpversion.config.models.Config._resolve_filemap + +```{autodoc2-docstring} bumpversion.config.models.Config._resolve_filemap +``` + +```` + ````{py:property} files_to_modify :canonical: bumpversion.config.models.Config.files_to_modify -:type: typing.List[bumpversion.config.models.FileConfig] +:type: typing.List[bumpversion.config.models.FileChange] ```{autodoc2-docstring} bumpversion.config.models.Config.files_to_modify ``` diff --git a/_sources/reference/bumpversion/bumpversion.config.utils.md.txt b/_sources/reference/bumpversion/bumpversion.config.utils.md.txt index cd6473d4..9d7e45e9 100644 --- a/_sources/reference/bumpversion/bumpversion.config.utils.md.txt +++ b/_sources/reference/bumpversion/bumpversion.config.utils.md.txt @@ -31,7 +31,7 @@ ### API -````{py:function} get_all_file_configs(config_dict: dict) -> typing.List[bumpversion.config.models.FileConfig] +````{py:function} get_all_file_configs(config_dict: dict) -> typing.List[bumpversion.config.models.FileChange] :canonical: bumpversion.config.utils.get_all_file_configs ```{autodoc2-docstring} bumpversion.config.utils.get_all_file_configs @@ -45,7 +45,7 @@ ``` ```` -````{py:function} resolve_glob_files(file_cfg: bumpversion.config.models.FileConfig) -> typing.List[bumpversion.config.models.FileConfig] +````{py:function} resolve_glob_files(file_cfg: bumpversion.config.models.FileChange) -> typing.List[bumpversion.config.models.FileChange] :canonical: bumpversion.config.utils.resolve_glob_files ```{autodoc2-docstring} bumpversion.config.utils.resolve_glob_files diff --git a/_sources/reference/bumpversion/bumpversion.files.md.txt b/_sources/reference/bumpversion/bumpversion.files.md.txt index 023a1590..2257aeeb 100644 --- a/_sources/reference/bumpversion/bumpversion.files.md.txt +++ b/_sources/reference/bumpversion/bumpversion.files.md.txt @@ -35,10 +35,6 @@ :class: autosummary longtable :align: left -* - {py:obj}`get_search_pattern ` - - ```{autodoc2-docstring} bumpversion.files.get_search_pattern - :summary: - ``` * - {py:obj}`contains_pattern ` - ```{autodoc2-docstring} bumpversion.files.contains_pattern :summary: @@ -55,10 +51,6 @@ - ```{autodoc2-docstring} bumpversion.files.modify_files :summary: ``` -* - {py:obj}`_check_files_contain_version ` - - ```{autodoc2-docstring} bumpversion.files._check_files_contain_version - :summary: - ``` ```` ### Data @@ -78,20 +70,13 @@ ````{py:data} logger :canonical: bumpversion.files.logger :value: > - None + 'get_indented_logger(...)' ```{autodoc2-docstring} bumpversion.files.logger ``` ```` -````{py:function} get_search_pattern(search_str: str, context: typing.MutableMapping, use_regex: bool = False) -> typing.Tuple[re.Pattern, str] -:canonical: bumpversion.files.get_search_pattern - -```{autodoc2-docstring} bumpversion.files.get_search_pattern -``` -```` - ````{py:function} contains_pattern(search: re.Pattern, contents: str) -> bool :canonical: bumpversion.files.contains_pattern @@ -106,7 +91,7 @@ ``` ```` -`````{py:class} ConfiguredFile(file_cfg: bumpversion.config.models.FileConfig, version_config: bumpversion.version_part.VersionConfig, search: typing.Optional[str] = None, replace: typing.Optional[str] = None) +`````{py:class} ConfiguredFile(file_change: bumpversion.config.models.FileChange, version_config: bumpversion.version_part.VersionConfig, search: typing.Optional[str] = None, replace: typing.Optional[str] = None) :canonical: bumpversion.files.ConfiguredFile ```{autodoc2-docstring} bumpversion.files.ConfiguredFile @@ -134,18 +119,18 @@ ```` -````{py:method} contains_version(version: bumpversion.version_part.Version, context: typing.MutableMapping) -> bool -:canonical: bumpversion.files.ConfiguredFile.contains_version +````{py:method} _contains_change_pattern(search_expression: re.Pattern, raw_search_expression: str, version: bumpversion.version_part.Version, context: typing.MutableMapping) -> bool +:canonical: bumpversion.files.ConfiguredFile._contains_change_pattern -```{autodoc2-docstring} bumpversion.files.ConfiguredFile.contains_version +```{autodoc2-docstring} bumpversion.files.ConfiguredFile._contains_change_pattern ``` ```` -````{py:method} replace_version(current_version: bumpversion.version_part.Version, new_version: bumpversion.version_part.Version, context: typing.MutableMapping, dry_run: bool = False) -> None -:canonical: bumpversion.files.ConfiguredFile.replace_version +````{py:method} make_file_change(current_version: bumpversion.version_part.Version, new_version: bumpversion.version_part.Version, context: typing.MutableMapping, dry_run: bool = False) -> None +:canonical: bumpversion.files.ConfiguredFile.make_file_change -```{autodoc2-docstring} bumpversion.files.ConfiguredFile.replace_version +```{autodoc2-docstring} bumpversion.files.ConfiguredFile.make_file_change ``` ```` @@ -162,7 +147,7 @@ ````` -````{py:function} resolve_file_config(files: typing.List[bumpversion.config.models.FileConfig], version_config: bumpversion.version_part.VersionConfig, search: typing.Optional[str] = None, replace: typing.Optional[str] = None) -> typing.List[bumpversion.files.ConfiguredFile] +````{py:function} resolve_file_config(files: typing.List[bumpversion.config.models.FileChange], version_config: bumpversion.version_part.VersionConfig, search: typing.Optional[str] = None, replace: typing.Optional[str] = None) -> typing.List[bumpversion.files.ConfiguredFile] :canonical: bumpversion.files.resolve_file_config ```{autodoc2-docstring} bumpversion.files.resolve_file_config @@ -176,14 +161,7 @@ ``` ```` -````{py:function} _check_files_contain_version(files: typing.List[bumpversion.files.ConfiguredFile], current_version: bumpversion.version_part.Version, context: typing.MutableMapping) -> None -:canonical: bumpversion.files._check_files_contain_version - -```{autodoc2-docstring} bumpversion.files._check_files_contain_version -``` -```` - -`````{py:class} FileUpdater(file_cfg: bumpversion.config.models.FileConfig, version_config: bumpversion.version_part.VersionConfig, search: typing.Optional[str] = None, replace: typing.Optional[str] = None) +`````{py:class} FileUpdater(file_change: bumpversion.config.models.FileChange, version_config: bumpversion.version_part.VersionConfig, search: typing.Optional[str] = None, replace: typing.Optional[str] = None) :canonical: bumpversion.files.FileUpdater ```{autodoc2-docstring} bumpversion.files.FileUpdater @@ -205,7 +183,7 @@ ````` -`````{py:class} DataFileUpdater(file_cfg: bumpversion.config.models.FileConfig, version_part_configs: typing.Dict[str, bumpversion.config.models.VersionPartConfig]) +`````{py:class} DataFileUpdater(file_change: bumpversion.config.models.FileChange, version_part_configs: typing.Dict[str, bumpversion.config.models.VersionPartConfig]) :canonical: bumpversion.files.DataFileUpdater ```{autodoc2-docstring} bumpversion.files.DataFileUpdater diff --git a/_sources/reference/bumpversion/bumpversion.functions.md.txt b/_sources/reference/bumpversion/bumpversion.functions.md.txt index cc58da32..04e75998 100644 --- a/_sources/reference/bumpversion/bumpversion.functions.md.txt +++ b/_sources/reference/bumpversion/bumpversion.functions.md.txt @@ -98,7 +98,7 @@ Bases: {py:obj}`bumpversion.functions.PartFunction` ````{py:attribute} FIRST_NUMERIC :canonical: bumpversion.functions.NumericFunction.FIRST_NUMERIC :value: > - None + 'compile(...)' ```{autodoc2-docstring} bumpversion.functions.NumericFunction.FIRST_NUMERIC ``` diff --git a/_sources/reference/bumpversion/bumpversion.indented_logger.md.txt b/_sources/reference/bumpversion/bumpversion.indented_logger.md.txt new file mode 100644 index 00000000..40e0b412 --- /dev/null +++ b/_sources/reference/bumpversion/bumpversion.indented_logger.md.txt @@ -0,0 +1,112 @@ +# {py:mod}`bumpversion.indented_logger` + +```{py:module} bumpversion.indented_logger +``` + +```{autodoc2-docstring} bumpversion.indented_logger +:allowtitles: +``` + +## Module Contents + +### Classes + +````{list-table} +:class: autosummary longtable +:align: left + +* - {py:obj}`IndentedLoggerAdapter ` + - ```{autodoc2-docstring} bumpversion.indented_logger.IndentedLoggerAdapter + :summary: + ``` +```` + +### Data + +````{list-table} +:class: autosummary longtable +:align: left + +* - {py:obj}`CURRENT_INDENT ` + - ```{autodoc2-docstring} bumpversion.indented_logger.CURRENT_INDENT + :summary: + ``` +```` + +### API + +````{py:data} CURRENT_INDENT +:canonical: bumpversion.indented_logger.CURRENT_INDENT +:value: > + 'ContextVar(...)' + +```{autodoc2-docstring} bumpversion.indented_logger.CURRENT_INDENT +``` + +```` + +`````{py:class} IndentedLoggerAdapter(logger: logging.Logger, extra: typing.Optional[dict] = None, depth: int = 2, indent_char: str = ' ', reset: bool = False) +:canonical: bumpversion.indented_logger.IndentedLoggerAdapter + +Bases: {py:obj}`logging.LoggerAdapter` + +```{autodoc2-docstring} bumpversion.indented_logger.IndentedLoggerAdapter +``` + +```{rubric} Initialization +``` + +```{autodoc2-docstring} bumpversion.indented_logger.IndentedLoggerAdapter.__init__ +``` + +````{py:property} current_indent +:canonical: bumpversion.indented_logger.IndentedLoggerAdapter.current_indent +:type: int + +```{autodoc2-docstring} bumpversion.indented_logger.IndentedLoggerAdapter.current_indent +``` + +```` + +````{py:method} indent(amount: int = 1) -> None +:canonical: bumpversion.indented_logger.IndentedLoggerAdapter.indent + +```{autodoc2-docstring} bumpversion.indented_logger.IndentedLoggerAdapter.indent +``` + +```` + +````{py:method} dedent(amount: int = 1) -> None +:canonical: bumpversion.indented_logger.IndentedLoggerAdapter.dedent + +```{autodoc2-docstring} bumpversion.indented_logger.IndentedLoggerAdapter.dedent +``` + +```` + +````{py:method} reset() -> None +:canonical: bumpversion.indented_logger.IndentedLoggerAdapter.reset + +```{autodoc2-docstring} bumpversion.indented_logger.IndentedLoggerAdapter.reset +``` + +```` + +````{py:property} indent_str +:canonical: bumpversion.indented_logger.IndentedLoggerAdapter.indent_str +:type: str + +```{autodoc2-docstring} bumpversion.indented_logger.IndentedLoggerAdapter.indent_str +``` + +```` + +````{py:method} process(msg: str, kwargs: typing.Optional[typing.MutableMapping[str, typing.Any]]) -> typing.Tuple[str, typing.MutableMapping[str, typing.Any]] +:canonical: bumpversion.indented_logger.IndentedLoggerAdapter.process + +```{autodoc2-docstring} bumpversion.indented_logger.IndentedLoggerAdapter.process +``` + +```` + +````` diff --git a/_sources/reference/bumpversion/bumpversion.md.txt b/_sources/reference/bumpversion/bumpversion.md.txt index cea842f1..9f102d12 100644 --- a/_sources/reference/bumpversion/bumpversion.md.txt +++ b/_sources/reference/bumpversion/bumpversion.md.txt @@ -22,20 +22,21 @@ bumpversion.config :titlesonly: :maxdepth: 1 +bumpversion.exceptions +bumpversion.files +bumpversion.ui +bumpversion.utils +bumpversion.bump +bumpversion.autocast bumpversion.yaml_dump bumpversion.aliases -bumpversion.files +bumpversion.cli bumpversion.scm bumpversion.show -bumpversion.autocast -bumpversion.exceptions -bumpversion.utils -bumpversion.bump -bumpversion.functions +bumpversion.indented_logger bumpversion.version_part -bumpversion.cli +bumpversion.functions bumpversion.__main__ -bumpversion.ui ``` ## Package Contents diff --git a/_sources/reference/bumpversion/bumpversion.scm.md.txt b/_sources/reference/bumpversion/bumpversion.scm.md.txt index d725970e..1d6c8599 100644 --- a/_sources/reference/bumpversion/bumpversion.scm.md.txt +++ b/_sources/reference/bumpversion/bumpversion.scm.md.txt @@ -62,7 +62,7 @@ ````{py:data} logger :canonical: bumpversion.scm.logger :value: > - None + 'get_indented_logger(...)' ```{autodoc2-docstring} bumpversion.scm.logger ``` diff --git a/_sources/reference/bumpversion/bumpversion.ui.md.txt b/_sources/reference/bumpversion/bumpversion.ui.md.txt index 9de1e681..85ed5321 100644 --- a/_sources/reference/bumpversion/bumpversion.ui.md.txt +++ b/_sources/reference/bumpversion/bumpversion.ui.md.txt @@ -15,6 +15,10 @@ :class: autosummary longtable :align: left +* - {py:obj}`get_indented_logger ` + - ```{autodoc2-docstring} bumpversion.ui.get_indented_logger + :summary: + ``` * - {py:obj}`setup_logging ` - ```{autodoc2-docstring} bumpversion.ui.setup_logging :summary: @@ -54,7 +58,7 @@ ````{py:data} logger :canonical: bumpversion.ui.logger :value: > - None + 'getLogger(...)' ```{autodoc2-docstring} bumpversion.ui.logger ``` @@ -71,6 +75,13 @@ ```` +````{py:function} get_indented_logger(name: str) -> bumpversion.indented_logger.IndentedLoggerAdapter +:canonical: bumpversion.ui.get_indented_logger + +```{autodoc2-docstring} bumpversion.ui.get_indented_logger +``` +```` + ````{py:function} setup_logging(verbose: int = 0) -> None :canonical: bumpversion.ui.setup_logging diff --git a/_sources/reference/bumpversion/bumpversion.version_part.md.txt b/_sources/reference/bumpversion/bumpversion.version_part.md.txt index 1891561e..f599fc9b 100644 --- a/_sources/reference/bumpversion/bumpversion.version_part.md.txt +++ b/_sources/reference/bumpversion/bumpversion.version_part.md.txt @@ -46,7 +46,7 @@ ````{py:data} logger :canonical: bumpversion.version_part.logger :value: > - None + 'get_indented_logger(...)' ```{autodoc2-docstring} bumpversion.version_part.logger ``` @@ -189,7 +189,7 @@ ````` -`````{py:class} VersionConfig(parse: str, serialize: typing.List[str], search: str, replace: str, part_configs: typing.Optional[typing.Dict[str, bumpversion.config.models.VersionPartConfig]] = None) +`````{py:class} VersionConfig(parse: str, serialize: typing.Tuple[str], search: str, replace: str, part_configs: typing.Optional[typing.Dict[str, bumpversion.config.models.VersionPartConfig]] = None) :canonical: bumpversion.version_part.VersionConfig ```{autodoc2-docstring} bumpversion.version_part.VersionConfig diff --git a/_sources/reference/bumpversion/bumpversion.yaml_dump.md.txt b/_sources/reference/bumpversion/bumpversion.yaml_dump.md.txt index d89eafc1..68b4eb8f 100644 --- a/_sources/reference/bumpversion/bumpversion.yaml_dump.md.txt +++ b/_sources/reference/bumpversion/bumpversion.yaml_dump.md.txt @@ -51,8 +51,8 @@ - ```{autodoc2-docstring} bumpversion.yaml_dump.format_dict :summary: ``` -* - {py:obj}`format_list ` - - ```{autodoc2-docstring} bumpversion.yaml_dump.format_list +* - {py:obj}`format_sequence ` + - ```{autodoc2-docstring} bumpversion.yaml_dump.format_sequence :summary: ``` * - {py:obj}`format_none ` @@ -128,7 +128,7 @@ Bases: {py:obj}`collections.UserDict` ````{py:data} YAML_DUMPERS :canonical: bumpversion.yaml_dump.YAML_DUMPERS :value: > - None + 'YAMLDumpers(...)' ```{autodoc2-docstring} bumpversion.yaml_dump.YAML_DUMPERS ``` @@ -187,10 +187,10 @@ Bases: {py:obj}`collections.UserDict` ``` ```` -````{py:function} format_list(val: list) -> str -:canonical: bumpversion.yaml_dump.format_list +````{py:function} format_sequence(val: typing.Union[list, tuple]) -> str +:canonical: bumpversion.yaml_dump.format_sequence -```{autodoc2-docstring} bumpversion.yaml_dump.format_list +```{autodoc2-docstring} bumpversion.yaml_dump.format_sequence ``` ```` diff --git a/_static/basic.css b/_static/basic.css index 7577acb1..30fee9d0 100644 --- a/_static/basic.css +++ b/_static/basic.css @@ -237,6 +237,10 @@ a.headerlink { visibility: hidden; } +a:visited { + color: #551A8B; +} + h1:hover > a.headerlink, h2:hover > a.headerlink, h3:hover > a.headerlink, @@ -670,6 +674,16 @@ dd { margin-left: 30px; } +.sig dd { + margin-top: 0px; + margin-bottom: 0px; +} + +.sig dl { + margin-top: 0px; + margin-bottom: 0px; +} + dl > dd:last-child, dl > dd:last-child > :last-child { margin-bottom: 0; @@ -738,6 +752,14 @@ abbr, acronym { cursor: help; } +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + /* -- code displays --------------------------------------------------------- */ pre { diff --git a/_static/documentation_options.js b/_static/documentation_options.js index 00c110d5..cbac5110 100644 --- a/_static/documentation_options.js +++ b/_static/documentation_options.js @@ -1,5 +1,4 @@ -var DOCUMENTATION_OPTIONS = { - URL_ROOT: document.getElementById("documentation_options").getAttribute('data-url_root'), +const DOCUMENTATION_OPTIONS = { VERSION: '0.13.0', LANGUAGE: 'en', COLLAPSE_INDEX: false, diff --git a/_static/pygments.css b/_static/pygments.css index d9a83a7b..c2e07c71 100644 --- a/_static/pygments.css +++ b/_static/pygments.css @@ -22,6 +22,7 @@ .highlight .cs { color: #8f5902; font-style: italic } /* Comment.Special */ .highlight .gd { color: #a40000 } /* Generic.Deleted */ .highlight .ge { color: #000000; font-style: italic } /* Generic.Emph */ +.highlight .ges { color: #000000; font-weight: bold; font-style: italic } /* Generic.EmphStrong */ .highlight .gr { color: #ef2929 } /* Generic.Error */ .highlight .gh { color: #000080; font-weight: bold } /* Generic.Heading */ .highlight .gi { color: #00A000 } /* Generic.Inserted */ @@ -107,6 +108,7 @@ body[data-theme="dark"] .highlight .c1 { color: #ababab; font-style: italic } /* body[data-theme="dark"] .highlight .cs { color: #e50808; font-weight: bold; background-color: #520000 } /* Comment.Special */ body[data-theme="dark"] .highlight .gd { color: #d22323 } /* Generic.Deleted */ body[data-theme="dark"] .highlight .ge { color: #d0d0d0; font-style: italic } /* Generic.Emph */ +body[data-theme="dark"] .highlight .ges { color: #d0d0d0; font-weight: bold; font-style: italic } /* Generic.EmphStrong */ body[data-theme="dark"] .highlight .gr { color: #d22323 } /* Generic.Error */ body[data-theme="dark"] .highlight .gh { color: #ffffff; font-weight: bold } /* Generic.Heading */ body[data-theme="dark"] .highlight .gi { color: #589819 } /* Generic.Inserted */ @@ -192,6 +194,7 @@ body:not([data-theme="light"]) .highlight .c1 { color: #ababab; font-style: ital body:not([data-theme="light"]) .highlight .cs { color: #e50808; font-weight: bold; background-color: #520000 } /* Comment.Special */ body:not([data-theme="light"]) .highlight .gd { color: #d22323 } /* Generic.Deleted */ body:not([data-theme="light"]) .highlight .ge { color: #d0d0d0; font-style: italic } /* Generic.Emph */ +body:not([data-theme="light"]) .highlight .ges { color: #d0d0d0; font-weight: bold; font-style: italic } /* Generic.EmphStrong */ body:not([data-theme="light"]) .highlight .gr { color: #d22323 } /* Generic.Error */ body:not([data-theme="light"]) .highlight .gh { color: #ffffff; font-weight: bold } /* Generic.Heading */ body:not([data-theme="light"]) .highlight .gi { color: #589819 } /* Generic.Inserted */ diff --git a/_static/searchtools.js b/_static/searchtools.js index 97d56a74..7918c3fa 100644 --- a/_static/searchtools.js +++ b/_static/searchtools.js @@ -57,12 +57,12 @@ const _removeChildren = (element) => { const _escapeRegExp = (string) => string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string -const _displayItem = (item, searchTerms) => { +const _displayItem = (item, searchTerms, highlightTerms) => { const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; - const docUrlRoot = DOCUMENTATION_OPTIONS.URL_ROOT; const docFileSuffix = DOCUMENTATION_OPTIONS.FILE_SUFFIX; const docLinkSuffix = DOCUMENTATION_OPTIONS.LINK_SUFFIX; const showSearchSummary = DOCUMENTATION_OPTIONS.SHOW_SEARCH_SUMMARY; + const contentRoot = document.documentElement.dataset.content_root; const [docName, title, anchor, descr, score, _filename] = item; @@ -75,20 +75,24 @@ const _displayItem = (item, searchTerms) => { if (dirname.match(/\/index\/$/)) dirname = dirname.substring(0, dirname.length - 6); else if (dirname === "index/") dirname = ""; - requestUrl = docUrlRoot + dirname; + requestUrl = contentRoot + dirname; linkUrl = requestUrl; } else { // normal html builders - requestUrl = docUrlRoot + docName + docFileSuffix; + requestUrl = contentRoot + docName + docFileSuffix; linkUrl = docName + docLinkSuffix; } let linkEl = listItem.appendChild(document.createElement("a")); linkEl.href = linkUrl + anchor; linkEl.dataset.score = score; linkEl.innerHTML = title; - if (descr) + if (descr) { listItem.appendChild(document.createElement("span")).innerHTML = " (" + descr + ")"; + // highlight search terms in the description + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); + } else if (showSearchSummary) fetch(requestUrl) .then((responseData) => responseData.text()) @@ -97,6 +101,9 @@ const _displayItem = (item, searchTerms) => { listItem.appendChild( Search.makeSearchSummary(data, searchTerms) ); + // highlight search terms in the summary + if (SPHINX_HIGHLIGHT_ENABLED) // set in sphinx_highlight.js + highlightTerms.forEach((term) => _highlightText(listItem, term, "highlighted")); }); Search.output.appendChild(listItem); }; @@ -115,14 +122,15 @@ const _finishSearch = (resultCount) => { const _displayNextItem = ( results, resultCount, - searchTerms + searchTerms, + highlightTerms, ) => { // results left, load the summary and display it // this is intended to be dynamic (don't sub resultsCount) if (results.length) { - _displayItem(results.pop(), searchTerms); + _displayItem(results.pop(), searchTerms, highlightTerms); setTimeout( - () => _displayNextItem(results, resultCount, searchTerms), + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), 5 ); } @@ -360,7 +368,7 @@ const Search = { // console.info("search results:", Search.lastresults); // print the results - _displayNextItem(results, results.length, searchTerms); + _displayNextItem(results, results.length, searchTerms, highlightTerms); }, /** diff --git a/_static/sphinx_highlight.js b/_static/sphinx_highlight.js index aae669d7..8a96c69a 100644 --- a/_static/sphinx_highlight.js +++ b/_static/sphinx_highlight.js @@ -29,14 +29,19 @@ const _highlight = (node, addItems, text, className) => { } span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); parent.insertBefore( span, parent.insertBefore( - document.createTextNode(val.substr(pos + text.length)), + rest, node.nextSibling ) ); node.nodeValue = val.substr(0, pos); + /* There may be more occurrences of search term in this node. So call this + * function recursively on the remaining fragment. + */ + _highlight(rest, addItems, text, className); if (isInSVG) { const rect = document.createElementNS( @@ -140,5 +145,10 @@ const SphinxHighlight = { }, }; -_ready(SphinxHighlight.highlightSearchWords); -_ready(SphinxHighlight.initEscapeListener); +_ready(() => { + /* Do not call highlightSearchWords() when we are on the search page. + * It will highlight words from the *previous* search query. + */ + if (typeof Search === "undefined") SphinxHighlight.highlightSearchWords(); + SphinxHighlight.initEscapeListener(); +}); diff --git a/_static/styles/furo.css b/_static/styles/furo.css index f8535503..3d29a218 100644 --- a/_static/styles/furo.css +++ b/_static/styles/furo.css @@ -1,2 +1,2 @@ -/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{-webkit-text-size-adjust:100%;line-height:1.15}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}[hidden],template{display:none}@media print{.content-icon-container,.headerlink,.mobile-header,.related-pages{display:none!important}.highlight{border:.1pt solid var(--color-foreground-border)}a,blockquote,dl,ol,pre,table,ul{page-break-inside:avoid}caption,figure,h1,h2,h3,h4,h5,h6,img{page-break-after:avoid;page-break-inside:avoid}dl,ol,ul{page-break-before:avoid}}.visually-hidden{clip:rect(0,0,0,0)!important;border:0!important;height:1px!important;margin:-1px!important;overflow:hidden!important;padding:0!important;position:absolute!important;white-space:nowrap!important;width:1px!important}:-moz-focusring{outline:auto}body{--font-stack:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji;--font-stack--monospace:"SFMono-Regular",Menlo,Consolas,Monaco,Liberation Mono,Lucida Console,monospace;--font-size--normal:100%;--font-size--small:87.5%;--font-size--small--2:81.25%;--font-size--small--3:75%;--font-size--small--4:62.5%;--sidebar-caption-font-size:var(--font-size--small--2);--sidebar-item-font-size:var(--font-size--small);--sidebar-search-input-font-size:var(--font-size--small);--toc-font-size:var(--font-size--small--3);--toc-font-size--mobile:var(--font-size--normal);--toc-title-font-size:var(--font-size--small--4);--admonition-font-size:0.8125rem;--admonition-title-font-size:0.8125rem;--code-font-size:var(--font-size--small--2);--api-font-size:var(--font-size--small);--header-height:calc(var(--sidebar-item-line-height) + var(--sidebar-item-spacing-vertical)*4);--header-padding:0.5rem;--sidebar-tree-space-above:1.5rem;--sidebar-caption-space-above:1rem;--sidebar-item-line-height:1rem;--sidebar-item-spacing-vertical:0.5rem;--sidebar-item-spacing-horizontal:1rem;--sidebar-item-height:calc(var(--sidebar-item-line-height) + var(--sidebar-item-spacing-vertical)*2);--sidebar-expander-width:var(--sidebar-item-height);--sidebar-search-space-above:0.5rem;--sidebar-search-input-spacing-vertical:0.5rem;--sidebar-search-input-spacing-horizontal:0.5rem;--sidebar-search-input-height:1rem;--sidebar-search-icon-size:var(--sidebar-search-input-height);--toc-title-padding:0.25rem 0;--toc-spacing-vertical:1.5rem;--toc-spacing-horizontal:1.5rem;--toc-item-spacing-vertical:0.4rem;--toc-item-spacing-horizontal:1rem;--icon-search:url('data:image/svg+xml;charset=utf-8,');--icon-pencil:url('data:image/svg+xml;charset=utf-8,');--icon-abstract:url('data:image/svg+xml;charset=utf-8,');--icon-info:url('data:image/svg+xml;charset=utf-8,');--icon-flame:url('data:image/svg+xml;charset=utf-8,');--icon-question:url('data:image/svg+xml;charset=utf-8,');--icon-warning:url('data:image/svg+xml;charset=utf-8,');--icon-failure:url('data:image/svg+xml;charset=utf-8,');--icon-spark:url('data:image/svg+xml;charset=utf-8,');--color-admonition-title--caution:#ff9100;--color-admonition-title-background--caution:rgba(255,145,0,.2);--color-admonition-title--warning:#ff9100;--color-admonition-title-background--warning:rgba(255,145,0,.2);--color-admonition-title--danger:#ff5252;--color-admonition-title-background--danger:rgba(255,82,82,.2);--color-admonition-title--attention:#ff5252;--color-admonition-title-background--attention:rgba(255,82,82,.2);--color-admonition-title--error:#ff5252;--color-admonition-title-background--error:rgba(255,82,82,.2);--color-admonition-title--hint:#00c852;--color-admonition-title-background--hint:rgba(0,200,82,.2);--color-admonition-title--tip:#00c852;--color-admonition-title-background--tip:rgba(0,200,82,.2);--color-admonition-title--important:#00bfa5;--color-admonition-title-background--important:rgba(0,191,165,.2);--color-admonition-title--note:#00b0ff;--color-admonition-title-background--note:rgba(0,176,255,.2);--color-admonition-title--seealso:#448aff;--color-admonition-title-background--seealso:rgba(68,138,255,.2);--color-admonition-title--admonition-todo:grey;--color-admonition-title-background--admonition-todo:hsla(0,0%,50%,.2);--color-admonition-title:#651fff;--color-admonition-title-background:rgba(101,31,255,.2);--icon-admonition-default:var(--icon-abstract);--color-topic-title:#14b8a6;--color-topic-title-background:rgba(20,184,166,.2);--icon-topic-default:var(--icon-pencil);--color-problematic:#b30000;--color-foreground-primary:#000;--color-foreground-secondary:#5a5c63;--color-foreground-muted:#646776;--color-foreground-border:#878787;--color-background-primary:#fff;--color-background-secondary:#f8f9fb;--color-background-hover:#efeff4;--color-background-hover--transparent:#efeff400;--color-background-border:#eeebee;--color-background-item:#ccc;--color-announcement-background:#000000dd;--color-announcement-text:#eeebee;--color-brand-primary:#2962ff;--color-brand-content:#2a5adf;--color-api-background:var(--color-background-hover--transparent);--color-api-background-hover:var(--color-background-hover);--color-api-overall:var(--color-foreground-secondary);--color-api-name:var(--color-problematic);--color-api-pre-name:var(--color-problematic);--color-api-paren:var(--color-foreground-secondary);--color-api-keyword:var(--color-foreground-primary);--color-highlight-on-target:#ffc;--color-inline-code-background:var(--color-background-secondary);--color-highlighted-background:#def;--color-highlighted-text:var(--color-foreground-primary);--color-guilabel-background:#ddeeff80;--color-guilabel-border:#bedaf580;--color-guilabel-text:var(--color-foreground-primary);--color-admonition-background:transparent;--color-table-header-background:var(--color-background-secondary);--color-table-border:var(--color-background-border);--color-card-border:var(--color-background-secondary);--color-card-background:transparent;--color-card-marginals-background:var(--color-background-secondary);--color-header-background:var(--color-background-primary);--color-header-border:var(--color-background-border);--color-header-text:var(--color-foreground-primary);--color-sidebar-background:var(--color-background-secondary);--color-sidebar-background-border:var(--color-background-border);--color-sidebar-brand-text:var(--color-foreground-primary);--color-sidebar-caption-text:var(--color-foreground-muted);--color-sidebar-link-text:var(--color-foreground-secondary);--color-sidebar-link-text--top-level:var(--color-brand-primary);--color-sidebar-item-background:var(--color-sidebar-background);--color-sidebar-item-background--current:var( --color-sidebar-item-background );--color-sidebar-item-background--hover:linear-gradient(90deg,var(--color-background-hover--transparent) 0%,var(--color-background-hover) var(--sidebar-item-spacing-horizontal),var(--color-background-hover) 100%);--color-sidebar-item-expander-background:transparent;--color-sidebar-item-expander-background--hover:var( --color-background-hover );--color-sidebar-search-text:var(--color-foreground-primary);--color-sidebar-search-background:var(--color-background-secondary);--color-sidebar-search-background--focus:var(--color-background-primary);--color-sidebar-search-border:var(--color-background-border);--color-sidebar-search-icon:var(--color-foreground-muted);--color-toc-background:var(--color-background-primary);--color-toc-title-text:var(--color-foreground-muted);--color-toc-item-text:var(--color-foreground-secondary);--color-toc-item-text--hover:var(--color-foreground-primary);--color-toc-item-text--active:var(--color-brand-primary);--color-content-foreground:var(--color-foreground-primary);--color-content-background:transparent;--color-link:var(--color-brand-content);--color-link--hover:var(--color-brand-content);--color-link-underline:var(--color-background-border);--color-link-underline--hover:var(--color-foreground-border)}.only-light{display:block!important}html body .only-dark{display:none!important}@media not print{body[data-theme=dark]{--color-problematic:#ee5151;--color-foreground-primary:#ffffffcc;--color-foreground-secondary:#9ca0a5;--color-foreground-muted:#81868d;--color-foreground-border:#666;--color-background-primary:#131416;--color-background-secondary:#1a1c1e;--color-background-hover:#1e2124;--color-background-hover--transparent:#1e212400;--color-background-border:#303335;--color-background-item:#444;--color-announcement-background:#000000dd;--color-announcement-text:#eeebee;--color-brand-primary:#2b8cee;--color-brand-content:#368ce2;--color-highlighted-background:#083563;--color-guilabel-background:#08356380;--color-guilabel-border:#13395f80;--color-api-keyword:var(--color-foreground-secondary);--color-highlight-on-target:#330;--color-admonition-background:#18181a;--color-card-border:var(--color-background-secondary);--color-card-background:#18181a;--color-card-marginals-background:var(--color-background-hover)}html body[data-theme=dark] .only-light{display:none!important}body[data-theme=dark] .only-dark{display:block!important}@media(prefers-color-scheme:dark){body:not([data-theme=light]){--color-problematic:#ee5151;--color-foreground-primary:#ffffffcc;--color-foreground-secondary:#9ca0a5;--color-foreground-muted:#81868d;--color-foreground-border:#666;--color-background-primary:#131416;--color-background-secondary:#1a1c1e;--color-background-hover:#1e2124;--color-background-hover--transparent:#1e212400;--color-background-border:#303335;--color-background-item:#444;--color-announcement-background:#000000dd;--color-announcement-text:#eeebee;--color-brand-primary:#2b8cee;--color-brand-content:#368ce2;--color-highlighted-background:#083563;--color-guilabel-background:#08356380;--color-guilabel-border:#13395f80;--color-api-keyword:var(--color-foreground-secondary);--color-highlight-on-target:#330;--color-admonition-background:#18181a;--color-card-border:var(--color-background-secondary);--color-card-background:#18181a;--color-card-marginals-background:var(--color-background-hover)}html body:not([data-theme=light]) .only-light{display:none!important}body:not([data-theme=light]) .only-dark{display:block!important}}}body[data-theme=auto] .theme-toggle svg.theme-icon-when-auto,body[data-theme=dark] .theme-toggle svg.theme-icon-when-dark,body[data-theme=light] .theme-toggle svg.theme-icon-when-light{display:block}body{font-family:var(--font-stack)}code,kbd,pre,samp{font-family:var(--font-stack--monospace)}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}article{line-height:1.5}h1,h2,h3,h4,h5,h6{border-radius:.5rem;font-weight:700;line-height:1.25;margin:.5rem -.5rem;padding-left:.5rem;padding-right:.5rem}h1+p,h2+p,h3+p,h4+p,h5+p,h6+p{margin-top:0}h1{font-size:2.5em;margin-bottom:1rem}h1,h2{margin-top:1.75rem}h2{font-size:2em}h3{font-size:1.5em}h4{font-size:1.25em}h5{font-size:1.125em}h6{font-size:1em}small{font-size:80%;opacity:75%}p{margin-bottom:.75rem;margin-top:.5rem}hr.docutils{background-color:var(--color-background-border);border:0;height:1px;margin:2rem 0;padding:0}.centered{text-align:center}a{color:var(--color-link);text-decoration:underline;text-decoration-color:var(--color-link-underline)}a:hover{color:var(--color-link--hover);text-decoration-color:var(--color-link-underline--hover)}a.muted-link{color:inherit}a.muted-link:hover{color:var(--color-link);text-decoration-color:var(--color-link-underline--hover)}html{overflow-x:hidden;overflow-y:scroll;scroll-behavior:smooth}.sidebar-scroll,.toc-scroll,article[role=main] *{scrollbar-color:var(--color-foreground-border) transparent;scrollbar-width:thin}.sidebar-scroll::-webkit-scrollbar,.toc-scroll::-webkit-scrollbar,article[role=main] ::-webkit-scrollbar{height:.25rem;width:.25rem}.sidebar-scroll::-webkit-scrollbar-thumb,.toc-scroll::-webkit-scrollbar-thumb,article[role=main] ::-webkit-scrollbar-thumb{background-color:var(--color-foreground-border);border-radius:.125rem}body,html{background:var(--color-background-primary);color:var(--color-foreground-primary);height:100%}article{background:var(--color-content-background);color:var(--color-content-foreground)}.page{display:flex;min-height:100%}.mobile-header{background-color:var(--color-header-background);border-bottom:1px solid var(--color-header-border);color:var(--color-header-text);display:none;height:var(--header-height);width:100%;z-index:10}.mobile-header.scrolled{border-bottom:none;box-shadow:0 0 .2rem rgba(0,0,0,.1),0 .2rem .4rem rgba(0,0,0,.2)}.mobile-header .header-center a{color:var(--color-header-text);text-decoration:none}.main{display:flex;flex:1}.sidebar-drawer{background:var(--color-sidebar-background);border-right:1px solid var(--color-sidebar-background-border);box-sizing:border-box;display:flex;justify-content:flex-end;min-width:15em;width:calc(50% - 26em)}.sidebar-container,.toc-drawer{box-sizing:border-box;width:15em}.toc-drawer{background:var(--color-toc-background);padding-right:1rem}.sidebar-sticky,.toc-sticky{display:flex;flex-direction:column;height:min(100%,100vh);height:100vh;position:sticky;top:0}.sidebar-scroll,.toc-scroll{flex-grow:1;flex-shrink:1;overflow:auto;scroll-behavior:smooth}.content{display:flex;flex-direction:column;justify-content:space-between;padding:0 3em;width:46em}.icon{display:inline-block;height:1rem;width:1rem}.icon svg{height:100%;width:100%}.announcement{align-items:center;background-color:var(--color-announcement-background);color:var(--color-announcement-text);display:flex;height:var(--header-height);overflow-x:auto}.announcement+.page{min-height:calc(100% - var(--header-height))}.announcement-content{box-sizing:border-box;min-width:100%;padding:.5rem;text-align:center;white-space:nowrap}.announcement-content a{color:var(--color-announcement-text);text-decoration-color:var(--color-announcement-text)}.announcement-content a:hover{color:var(--color-announcement-text);text-decoration-color:var(--color-link--hover)}.no-js .theme-toggle-container{display:none}.theme-toggle-container{vertical-align:middle}.theme-toggle{background:transparent;border:none;cursor:pointer;padding:0}.theme-toggle svg{color:var(--color-foreground-primary);display:none;height:1rem;vertical-align:middle;width:1rem}.theme-toggle-header{float:left;padding:1rem .5rem}.nav-overlay-icon,.toc-overlay-icon{cursor:pointer;display:none}.nav-overlay-icon .icon,.toc-overlay-icon .icon{color:var(--color-foreground-secondary);height:1rem;width:1rem}.nav-overlay-icon,.toc-header-icon{align-items:center;justify-content:center}.toc-content-icon{height:1.5rem;width:1.5rem}.content-icon-container{display:flex;float:right;gap:.5rem;margin-bottom:1rem;margin-left:1rem;margin-top:1.5rem}.content-icon-container .edit-this-page svg{color:inherit;height:1rem;width:1rem}.sidebar-toggle{display:none;position:absolute}.sidebar-toggle[name=__toc]{left:20px}.sidebar-toggle:checked{left:40px}.overlay{background-color:rgba(0,0,0,.54);height:0;opacity:0;position:fixed;top:0;transition:width 0ms,height 0ms,opacity .25s ease-out;width:0}.sidebar-overlay{z-index:20}.toc-overlay{z-index:40}.sidebar-drawer{transition:left .25s ease-in-out;z-index:30}.toc-drawer{transition:right .25s ease-in-out;z-index:50}#__navigation:checked~.sidebar-overlay{height:100%;opacity:1;width:100%}#__navigation:checked~.page .sidebar-drawer{left:0;top:0}#__toc:checked~.toc-overlay{height:100%;opacity:1;width:100%}#__toc:checked~.page .toc-drawer{right:0;top:0}.back-to-top{background:var(--color-background-primary);border-radius:1rem;box-shadow:0 .2rem .5rem rgba(0,0,0,.05),0 0 1px 0 hsla(220,9%,46%,.502);display:none;font-size:.8125rem;left:0;margin-left:50%;padding:.5rem .75rem .5rem .5rem;position:fixed;text-decoration:none;top:1rem;transform:translateX(-50%);z-index:10}.back-to-top svg{fill:currentColor;display:inline-block;height:1rem;width:1rem}.back-to-top span{margin-left:.25rem}.show-back-to-top .back-to-top{align-items:center;display:flex}@media(min-width:97em){html{font-size:110%}}@media(max-width:82em){.toc-content-icon{display:flex}.toc-drawer{border-left:1px solid var(--color-background-muted);height:100vh;position:fixed;right:-15em;top:0}.toc-tree{border-left:none;font-size:var(--toc-font-size--mobile)}.sidebar-drawer{width:calc(50% - 18.5em)}}@media(max-width:67em){.nav-overlay-icon{display:flex}.sidebar-drawer{height:100vh;left:-15em;position:fixed;top:0;width:15em}.toc-header-icon{display:flex}.theme-toggle-content,.toc-content-icon{display:none}.theme-toggle-header{display:block}.mobile-header{align-items:center;display:flex;justify-content:space-between;position:sticky;top:0}.mobile-header .header-left,.mobile-header .header-right{display:flex;height:var(--header-height);padding:0 var(--header-padding)}.mobile-header .header-left label,.mobile-header .header-right label{height:100%;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:100%}.nav-overlay-icon .icon,.theme-toggle svg{height:1.25rem;width:1.25rem}:target{scroll-margin-top:var(--header-height)}.back-to-top{top:calc(var(--header-height) + .5rem)}.page{flex-direction:column;justify-content:center}.content{margin-left:auto;margin-right:auto}}@media(max-width:52em){.content{overflow-x:auto;width:100%}}@media(max-width:46em){.content{padding:0 1em}article aside.sidebar{float:none;margin:1rem 0;width:100%}}.admonition,.topic{background:var(--color-admonition-background);border-radius:.2rem;box-shadow:0 .2rem .5rem rgba(0,0,0,.05),0 0 .0625rem rgba(0,0,0,.1);font-size:var(--admonition-font-size);margin:1rem auto;overflow:hidden;padding:0 .5rem .5rem;page-break-inside:avoid}.admonition>:nth-child(2),.topic>:nth-child(2){margin-top:0}.admonition>:last-child,.topic>:last-child{margin-bottom:0}p.admonition-title,p.topic-title{font-size:var(--admonition-title-font-size);font-weight:500;line-height:1.3;margin:0 -.5rem .5rem;padding:.4rem .5rem .4rem 2rem;position:relative}p.admonition-title:before,p.topic-title:before{content:"";height:1rem;left:.5rem;position:absolute;width:1rem}p.admonition-title{background-color:var(--color-admonition-title-background)}p.admonition-title:before{background-color:var(--color-admonition-title);-webkit-mask-image:var(--icon-admonition-default);mask-image:var(--icon-admonition-default);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}p.topic-title{background-color:var(--color-topic-title-background)}p.topic-title:before{background-color:var(--color-topic-title);-webkit-mask-image:var(--icon-topic-default);mask-image:var(--icon-topic-default);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.admonition{border-left:.2rem solid var(--color-admonition-title)}.admonition.caution{border-left-color:var(--color-admonition-title--caution)}.admonition.caution>.admonition-title{background-color:var(--color-admonition-title-background--caution)}.admonition.caution>.admonition-title:before{background-color:var(--color-admonition-title--caution);-webkit-mask-image:var(--icon-spark);mask-image:var(--icon-spark)}.admonition.warning{border-left-color:var(--color-admonition-title--warning)}.admonition.warning>.admonition-title{background-color:var(--color-admonition-title-background--warning)}.admonition.warning>.admonition-title:before{background-color:var(--color-admonition-title--warning);-webkit-mask-image:var(--icon-warning);mask-image:var(--icon-warning)}.admonition.danger{border-left-color:var(--color-admonition-title--danger)}.admonition.danger>.admonition-title{background-color:var(--color-admonition-title-background--danger)}.admonition.danger>.admonition-title:before{background-color:var(--color-admonition-title--danger);-webkit-mask-image:var(--icon-spark);mask-image:var(--icon-spark)}.admonition.attention{border-left-color:var(--color-admonition-title--attention)}.admonition.attention>.admonition-title{background-color:var(--color-admonition-title-background--attention)}.admonition.attention>.admonition-title:before{background-color:var(--color-admonition-title--attention);-webkit-mask-image:var(--icon-warning);mask-image:var(--icon-warning)}.admonition.error{border-left-color:var(--color-admonition-title--error)}.admonition.error>.admonition-title{background-color:var(--color-admonition-title-background--error)}.admonition.error>.admonition-title:before{background-color:var(--color-admonition-title--error);-webkit-mask-image:var(--icon-failure);mask-image:var(--icon-failure)}.admonition.hint{border-left-color:var(--color-admonition-title--hint)}.admonition.hint>.admonition-title{background-color:var(--color-admonition-title-background--hint)}.admonition.hint>.admonition-title:before{background-color:var(--color-admonition-title--hint);-webkit-mask-image:var(--icon-question);mask-image:var(--icon-question)}.admonition.tip{border-left-color:var(--color-admonition-title--tip)}.admonition.tip>.admonition-title{background-color:var(--color-admonition-title-background--tip)}.admonition.tip>.admonition-title:before{background-color:var(--color-admonition-title--tip);-webkit-mask-image:var(--icon-info);mask-image:var(--icon-info)}.admonition.important{border-left-color:var(--color-admonition-title--important)}.admonition.important>.admonition-title{background-color:var(--color-admonition-title-background--important)}.admonition.important>.admonition-title:before{background-color:var(--color-admonition-title--important);-webkit-mask-image:var(--icon-flame);mask-image:var(--icon-flame)}.admonition.note{border-left-color:var(--color-admonition-title--note)}.admonition.note>.admonition-title{background-color:var(--color-admonition-title-background--note)}.admonition.note>.admonition-title:before{background-color:var(--color-admonition-title--note);-webkit-mask-image:var(--icon-pencil);mask-image:var(--icon-pencil)}.admonition.seealso{border-left-color:var(--color-admonition-title--seealso)}.admonition.seealso>.admonition-title{background-color:var(--color-admonition-title-background--seealso)}.admonition.seealso>.admonition-title:before{background-color:var(--color-admonition-title--seealso);-webkit-mask-image:var(--icon-info);mask-image:var(--icon-info)}.admonition.admonition-todo{border-left-color:var(--color-admonition-title--admonition-todo)}.admonition.admonition-todo>.admonition-title{background-color:var(--color-admonition-title-background--admonition-todo)}.admonition.admonition-todo>.admonition-title:before{background-color:var(--color-admonition-title--admonition-todo);-webkit-mask-image:var(--icon-pencil);mask-image:var(--icon-pencil)}.admonition-todo>.admonition-title{text-transform:uppercase}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dd{margin-left:2rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dd>:first-child{margin-top:.125rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list,dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dd>:last-child{margin-bottom:.75rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list>dt{font-size:var(--font-size--small);text-transform:uppercase}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list dd:empty{margin-bottom:.5rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list dd>ul{margin-left:-1.2rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list dd>ul>li>p:nth-child(2){margin-top:0}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list dd>ul>li>p+p:last-child:empty{margin-bottom:0;margin-top:0}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt{color:var(--color-api-overall)}.sig:not(.sig-inline){background:var(--color-api-background);border-radius:.25rem;font-family:var(--font-stack--monospace);font-size:var(--api-font-size);font-weight:700;margin-left:-.25rem;margin-right:-.25rem;padding:.25rem .5rem .25rem 3em;text-indent:-2.5em;transition:background .1s ease-out}.sig:not(.sig-inline):hover{background:var(--color-api-background-hover)}.sig:not(.sig-inline) a.reference .viewcode-link{font-weight:400;width:3.5rem}.sig:not(.sig-inline) span.pre{overflow-wrap:anywhere}em.property{font-style:normal}em.property:first-child{color:var(--color-api-keyword)}.sig-name{color:var(--color-api-name)}.sig-prename{color:var(--color-api-pre-name);font-weight:400}.sig-paren{color:var(--color-api-paren)}.sig-param{font-style:normal}.versionmodified{font-style:italic}div.deprecated p,div.versionadded p,div.versionchanged p{margin-bottom:.125rem;margin-top:.125rem}.viewcode-back,.viewcode-link{float:right;text-align:right}.line-block{margin-bottom:.75rem;margin-top:.5rem}.line-block .line-block{margin-bottom:0;margin-top:0;padding-left:1rem}.code-block-caption,article p.caption,table>caption{font-size:var(--font-size--small);text-align:center}.toctree-wrapper.compound .caption,.toctree-wrapper.compound :not(.caption)>.caption-text{font-size:var(--font-size--small);margin-bottom:0;text-align:initial;text-transform:uppercase}.toctree-wrapper.compound>ul{margin-bottom:0;margin-top:0}.sig-inline,code.literal{background:var(--color-inline-code-background);border-radius:.2em;font-size:var(--font-size--small--2);overflow-wrap:break-word;padding:.1em .2em}p .sig-inline,p code.literal{border:1px solid var(--color-background-border)}.sig-inline{font-family:var(--font-stack--monospace)}div[class*=" highlight-"],div[class^=highlight-]{display:flex;margin:1em 0}div[class*=" highlight-"] .table-wrapper,div[class^=highlight-] .table-wrapper,pre{margin:0;padding:0}pre{overflow:auto}article[role=main] .highlight pre{line-height:1.5}.highlight pre,pre.literal-block{font-size:var(--code-font-size);padding:.625rem .875rem}pre.literal-block{background-color:var(--color-code-background);border-radius:.2rem;color:var(--color-code-foreground);margin-bottom:1rem;margin-top:1rem}.highlight{border-radius:.2rem;width:100%}.highlight .gp,.highlight span.linenos{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.highlight .hll{display:block;margin-left:-.875rem;margin-right:-.875rem;padding-left:.875rem;padding-right:.875rem}.code-block-caption{background-color:var(--color-code-background);border-bottom:1px solid;border-radius:.25rem;border-bottom-left-radius:0;border-bottom-right-radius:0;border-color:var(--color-background-border);color:var(--color-code-foreground);display:flex;font-weight:300;padding:.625rem .875rem}.code-block-caption+div[class]{margin-top:0}.code-block-caption+div[class] pre{border-top-left-radius:0;border-top-right-radius:0}.highlighttable{display:block;width:100%}.highlighttable tbody{display:block}.highlighttable tr{display:flex}.highlighttable td.linenos{background-color:var(--color-code-background);border-bottom-left-radius:.2rem;border-top-left-radius:.2rem;color:var(--color-code-foreground);padding:.625rem 0 .625rem .875rem}.highlighttable .linenodiv{box-shadow:-.0625rem 0 var(--color-foreground-border) inset;font-size:var(--code-font-size);padding-right:.875rem}.highlighttable td.code{display:block;flex:1;overflow:hidden;padding:0}.highlighttable td.code .highlight{border-bottom-left-radius:0;border-top-left-radius:0}.highlight span.linenos{box-shadow:-.0625rem 0 var(--color-foreground-border) inset;display:inline-block;margin-right:.875rem;padding-left:0;padding-right:.875rem}.footnote-reference{font-size:var(--font-size--small--4);vertical-align:super}dl.footnote.brackets{color:var(--color-foreground-secondary);display:grid;font-size:var(--font-size--small);grid-template-columns:max-content auto}dl.footnote.brackets dt{margin:0}dl.footnote.brackets dt>.fn-backref{margin-left:.25rem}dl.footnote.brackets dt:after{content:":"}dl.footnote.brackets dt .brackets:before{content:"["}dl.footnote.brackets dt .brackets:after{content:"]"}dl.footnote.brackets dd{margin:0;padding:0 1rem}aside.footnote{color:var(--color-foreground-secondary);font-size:var(--font-size--small)}aside.footnote>span,div.citation>span{float:left;font-weight:500;padding-right:.25rem}aside.footnote>p,div.citation>p{margin-left:2rem}img{box-sizing:border-box;height:auto;max-width:100%}article .figure,article figure{border-radius:.2rem;margin:0}article .figure :last-child,article figure :last-child{margin-bottom:0}article .align-left{clear:left;float:left;margin:0 1rem 1rem}article .align-right{clear:right;float:right;margin:0 1rem 1rem}article .align-center,article .align-default{display:block;margin-left:auto;margin-right:auto;text-align:center}article table.align-default{display:table;text-align:initial}.domainindex-jumpbox,.genindex-jumpbox{border-bottom:1px solid var(--color-background-border);border-top:1px solid var(--color-background-border);padding:.25rem}.domainindex-section h2,.genindex-section h2{margin-bottom:.5rem;margin-top:.75rem}.domainindex-section ul,.genindex-section ul{margin-bottom:0;margin-top:0}ol,ul{margin-bottom:1rem;margin-top:1rem;padding-left:1.2rem}ol li>p:first-child,ul li>p:first-child{margin-bottom:.25rem;margin-top:.25rem}ol li>p:last-child,ul li>p:last-child{margin-top:.25rem}ol li>ol,ol li>ul,ul li>ol,ul li>ul{margin-bottom:.5rem;margin-top:.5rem}ol.arabic{list-style:decimal}ol.loweralpha{list-style:lower-alpha}ol.upperalpha{list-style:upper-alpha}ol.lowerroman{list-style:lower-roman}ol.upperroman{list-style:upper-roman}.simple li>ol,.simple li>ul,.toctree-wrapper li>ol,.toctree-wrapper li>ul{margin-bottom:0;margin-top:0}.field-list dt,.option-list dt,dl.footnote dt,dl.glossary dt,dl.simple dt,dl:not([class]) dt{font-weight:500;margin-top:.25rem}.field-list dt+dt,.option-list dt+dt,dl.footnote dt+dt,dl.glossary dt+dt,dl.simple dt+dt,dl:not([class]) dt+dt{margin-top:0}.field-list dt .classifier:before,.option-list dt .classifier:before,dl.footnote dt .classifier:before,dl.glossary dt .classifier:before,dl.simple dt .classifier:before,dl:not([class]) dt .classifier:before{content:":";margin-left:.2rem;margin-right:.2rem}.field-list dd ul,.field-list dd>p:first-child,.option-list dd ul,.option-list dd>p:first-child,dl.footnote dd ul,dl.footnote dd>p:first-child,dl.glossary dd ul,dl.glossary dd>p:first-child,dl.simple dd ul,dl.simple dd>p:first-child,dl:not([class]) dd ul,dl:not([class]) dd>p:first-child{margin-top:.125rem}.field-list dd ul,.option-list dd ul,dl.footnote dd ul,dl.glossary dd ul,dl.simple dd ul,dl:not([class]) dd ul{margin-bottom:.125rem}.math-wrapper{overflow-x:auto;width:100%}div.math{position:relative;text-align:center}div.math .headerlink,div.math:focus .headerlink{display:none}div.math:hover .headerlink{display:inline-block}div.math span.eqno{position:absolute;right:.5rem;top:50%;transform:translateY(-50%);z-index:1}abbr[title]{cursor:help}.problematic{color:var(--color-problematic)}kbd:not(.compound){background-color:var(--color-background-secondary);border:1px solid var(--color-foreground-border);border-radius:.2rem;box-shadow:0 .0625rem 0 rgba(0,0,0,.2),inset 0 0 0 .125rem var(--color-background-primary);color:var(--color-foreground-primary);display:inline-block;font-size:var(--font-size--small--3);margin:0 .2rem;padding:0 .2rem;vertical-align:text-bottom}blockquote{background:var(--color-background-secondary);border-left:4px solid var(--color-background-border);margin-left:0;margin-right:0;padding:.5rem 1rem}blockquote .attribution{font-weight:600;text-align:right}blockquote.highlights,blockquote.pull-quote{font-size:1.25em}blockquote.epigraph,blockquote.pull-quote{border-left-width:0;border-radius:.5rem}blockquote.highlights{background:transparent;border-left-width:0}p .reference img{vertical-align:middle}p.rubric{font-size:1.125em;font-weight:700;line-height:1.25}dd p.rubric{font-size:var(--font-size--small);font-weight:inherit;line-height:inherit;text-transform:uppercase}article .sidebar{background-color:var(--color-background-secondary);border:1px solid var(--color-background-border);border-radius:.2rem;clear:right;float:right;margin-left:1rem;margin-right:0;width:30%}article .sidebar>*{padding-left:1rem;padding-right:1rem}article .sidebar>ol,article .sidebar>ul{padding-left:2.2rem}article .sidebar .sidebar-title{border-bottom:1px solid var(--color-background-border);font-weight:500;margin:0;padding:.5rem 1rem}.table-wrapper{margin-bottom:.5rem;margin-top:1rem;overflow-x:auto;padding:.2rem .2rem .75rem;width:100%}table.docutils{border-collapse:collapse;border-radius:.2rem;border-spacing:0;box-shadow:0 .2rem .5rem rgba(0,0,0,.05),0 0 .0625rem rgba(0,0,0,.1)}table.docutils th{background:var(--color-table-header-background)}table.docutils td,table.docutils th{border-bottom:1px solid var(--color-table-border);border-left:1px solid var(--color-table-border);border-right:1px solid var(--color-table-border);padding:0 .25rem}table.docutils td p,table.docutils th p{margin:.25rem}table.docutils td:first-child,table.docutils th:first-child{border-left:none}table.docutils td:last-child,table.docutils th:last-child{border-right:none}table.docutils td.text-left,table.docutils th.text-left{text-align:left}table.docutils td.text-right,table.docutils th.text-right{text-align:right}table.docutils td.text-center,table.docutils th.text-center{text-align:center}:target{scroll-margin-top:.5rem}@media(max-width:67em){:target{scroll-margin-top:calc(.5rem + var(--header-height))}section>span:target{scroll-margin-top:calc(.8rem + var(--header-height))}}.headerlink{font-weight:100;-webkit-user-select:none;-moz-user-select:none;user-select:none}.code-block-caption>.headerlink,dl dt>.headerlink,figcaption p>.headerlink,h1>.headerlink,h2>.headerlink,h3>.headerlink,h4>.headerlink,h5>.headerlink,h6>.headerlink,p.caption>.headerlink,table>caption>.headerlink{margin-left:.5rem;visibility:hidden}.code-block-caption:hover>.headerlink,dl dt:hover>.headerlink,figcaption p:hover>.headerlink,h1:hover>.headerlink,h2:hover>.headerlink,h3:hover>.headerlink,h4:hover>.headerlink,h5:hover>.headerlink,h6:hover>.headerlink,p.caption:hover>.headerlink,table>caption:hover>.headerlink{visibility:visible}.code-block-caption>.toc-backref,dl dt>.toc-backref,figcaption p>.toc-backref,h1>.toc-backref,h2>.toc-backref,h3>.toc-backref,h4>.toc-backref,h5>.toc-backref,h6>.toc-backref,p.caption>.toc-backref,table>caption>.toc-backref{color:inherit;text-decoration-line:none}figure:hover>figcaption>p>.headerlink,table:hover>caption>.headerlink{visibility:visible}:target>h1:first-of-type,:target>h2:first-of-type,:target>h3:first-of-type,:target>h4:first-of-type,:target>h5:first-of-type,:target>h6:first-of-type,span:target~h1:first-of-type,span:target~h2:first-of-type,span:target~h3:first-of-type,span:target~h4:first-of-type,span:target~h5:first-of-type,span:target~h6:first-of-type{background-color:var(--color-highlight-on-target)}:target>h1:first-of-type code.literal,:target>h2:first-of-type code.literal,:target>h3:first-of-type code.literal,:target>h4:first-of-type code.literal,:target>h5:first-of-type code.literal,:target>h6:first-of-type code.literal,span:target~h1:first-of-type code.literal,span:target~h2:first-of-type code.literal,span:target~h3:first-of-type code.literal,span:target~h4:first-of-type code.literal,span:target~h5:first-of-type code.literal,span:target~h6:first-of-type code.literal{background-color:transparent}.literal-block-wrapper:target .code-block-caption,.this-will-duplicate-information-and-it-is-still-useful-here li :target,figure:target,table:target>caption{background-color:var(--color-highlight-on-target)}dt:target{background-color:var(--color-highlight-on-target)!important}.footnote-reference:target,.footnote>dt:target+dd{background-color:var(--color-highlight-on-target)}.guilabel{background-color:var(--color-guilabel-background);border:1px solid var(--color-guilabel-border);border-radius:.5em;color:var(--color-guilabel-text);font-size:.9em;padding:0 .3em}footer{display:flex;flex-direction:column;font-size:var(--font-size--small);margin-top:2rem}.bottom-of-page{align-items:center;border-top:1px solid var(--color-background-border);color:var(--color-foreground-secondary);display:flex;justify-content:space-between;line-height:1.5;margin-top:1rem;padding-bottom:1rem;padding-top:1rem}@media(max-width:46em){.bottom-of-page{flex-direction:column-reverse;gap:.25rem;text-align:center}}.bottom-of-page .left-details{font-size:var(--font-size--small)}.bottom-of-page .right-details{display:flex;flex-direction:column;gap:.25rem;text-align:right}.bottom-of-page .icons{display:flex;font-size:1rem;gap:.25rem;justify-content:flex-end}.bottom-of-page .icons a{text-decoration:none}.bottom-of-page .icons img,.bottom-of-page .icons svg{font-size:1.125rem;height:1em;width:1em}.related-pages a{align-items:center;display:flex;text-decoration:none}.related-pages a:hover .page-info .title{color:var(--color-link);text-decoration:underline;text-decoration-color:var(--color-link-underline)}.related-pages a svg.furo-related-icon,.related-pages a svg.furo-related-icon>use{color:var(--color-foreground-border);flex-shrink:0;height:.75rem;margin:0 .5rem;width:.75rem}.related-pages a.next-page{clear:right;float:right;max-width:50%;text-align:right}.related-pages a.prev-page{clear:left;float:left;max-width:50%}.related-pages a.prev-page svg{transform:rotate(180deg)}.page-info{display:flex;flex-direction:column;overflow-wrap:anywhere}.next-page .page-info{align-items:flex-end}.page-info .context{align-items:center;color:var(--color-foreground-muted);display:flex;font-size:var(--font-size--small);padding-bottom:.1rem;text-decoration:none}ul.search{list-style:none;padding-left:0}ul.search li{border-bottom:1px solid var(--color-background-border);padding:1rem 0}[role=main] .highlighted{background-color:var(--color-highlighted-background);color:var(--color-highlighted-text)}.sidebar-brand{display:flex;flex-direction:column;flex-shrink:0;padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal);text-decoration:none}.sidebar-brand-text{color:var(--color-sidebar-brand-text);font-size:1.5rem;overflow-wrap:break-word}.sidebar-brand-text,.sidebar-logo-container{margin:var(--sidebar-item-spacing-vertical) 0}.sidebar-logo{display:block;margin:0 auto;max-width:100%}.sidebar-search-container{align-items:center;background:var(--color-sidebar-search-background);display:flex;margin-top:var(--sidebar-search-space-above);position:relative}.sidebar-search-container:focus-within,.sidebar-search-container:hover{background:var(--color-sidebar-search-background--focus)}.sidebar-search-container:before{background-color:var(--color-sidebar-search-icon);content:"";height:var(--sidebar-search-icon-size);left:var(--sidebar-item-spacing-horizontal);-webkit-mask-image:var(--icon-search);mask-image:var(--icon-search);position:absolute;width:var(--sidebar-search-icon-size)}.sidebar-search{background:transparent;border:none;border-bottom:1px solid var(--color-sidebar-search-border);border-top:1px solid var(--color-sidebar-search-border);box-sizing:border-box;color:var(--color-sidebar-search-foreground);padding:var(--sidebar-search-input-spacing-vertical) var(--sidebar-search-input-spacing-horizontal) var(--sidebar-search-input-spacing-vertical) calc(var(--sidebar-item-spacing-horizontal) + var(--sidebar-search-input-spacing-horizontal) + var(--sidebar-search-icon-size));width:100%;z-index:10}.sidebar-search:focus{outline:none}.sidebar-search::-moz-placeholder{font-size:var(--sidebar-search-input-font-size)}.sidebar-search::placeholder{font-size:var(--sidebar-search-input-font-size)}#searchbox .highlight-link{margin:0;padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal) 0;text-align:center}#searchbox .highlight-link a{color:var(--color-sidebar-search-icon);font-size:var(--font-size--small--2)}.sidebar-tree{font-size:var(--sidebar-item-font-size);margin-bottom:var(--sidebar-item-spacing-vertical);margin-top:var(--sidebar-tree-space-above)}.sidebar-tree ul{display:flex;flex-direction:column;list-style:none;margin-bottom:0;margin-top:0;padding:0}.sidebar-tree li{margin:0;position:relative}.sidebar-tree li>ul{margin-left:var(--sidebar-item-spacing-horizontal)}.sidebar-tree .icon,.sidebar-tree .reference{color:var(--color-sidebar-link-text)}.sidebar-tree .reference{box-sizing:border-box;display:inline-block;height:100%;line-height:var(--sidebar-item-line-height);overflow-wrap:anywhere;padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal);text-decoration:none;width:100%}.sidebar-tree .reference:hover{background:var(--color-sidebar-item-background--hover)}.sidebar-tree .reference.external:after{color:var(--color-sidebar-link-text);content:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='12' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' stroke-width='1.5' stroke='%23607D8B' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M0 0h24v24H0z' stroke='none'/%3E%3Cpath d='M11 7H6a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2-2v-5M10 14 20 4M15 4h5v5'/%3E%3C/svg%3E");margin:0 .25rem;vertical-align:middle}.sidebar-tree .current-page>.reference{font-weight:700}.sidebar-tree label{align-items:center;cursor:pointer;display:flex;height:var(--sidebar-item-height);justify-content:center;position:absolute;right:0;top:0;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:var(--sidebar-expander-width)}.sidebar-tree .caption,.sidebar-tree :not(.caption)>.caption-text{color:var(--color-sidebar-caption-text);font-size:var(--sidebar-caption-font-size);font-weight:700;margin:var(--sidebar-caption-space-above) 0 0 0;padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal);text-transform:uppercase}.sidebar-tree li.has-children>.reference{padding-right:var(--sidebar-expander-width)}.sidebar-tree .toctree-l1>.reference,.sidebar-tree .toctree-l1>label .icon{color:var(--color-sidebar-link-text--top-level)}.sidebar-tree label{background:var(--color-sidebar-item-expander-background)}.sidebar-tree label:hover{background:var(--color-sidebar-item-expander-background--hover)}.sidebar-tree .current>.reference{background:var(--color-sidebar-item-background--current)}.sidebar-tree .current>.reference:hover{background:var(--color-sidebar-item-background--hover)}.toctree-checkbox{display:none;position:absolute}.toctree-checkbox~ul{display:none}.toctree-checkbox~label .icon svg{transform:rotate(90deg)}.toctree-checkbox:checked~ul{display:block}.toctree-checkbox:checked~label .icon svg{transform:rotate(-90deg)}.toc-title-container{padding:var(--toc-title-padding);padding-top:var(--toc-spacing-vertical)}.toc-title{color:var(--color-toc-title-text);font-size:var(--toc-title-font-size);padding-left:var(--toc-spacing-horizontal);text-transform:uppercase}.no-toc{display:none}.toc-tree-container{padding-bottom:var(--toc-spacing-vertical)}.toc-tree{border-left:1px solid var(--color-background-border);font-size:var(--toc-font-size);line-height:1.3;padding-left:calc(var(--toc-spacing-horizontal) - var(--toc-item-spacing-horizontal))}.toc-tree>ul>li:first-child{padding-top:0}.toc-tree>ul>li:first-child>ul{padding-left:0}.toc-tree>ul>li:first-child>a{display:none}.toc-tree ul{list-style-type:none;margin-bottom:0;margin-top:0;padding-left:var(--toc-item-spacing-horizontal)}.toc-tree li{padding-top:var(--toc-item-spacing-vertical)}.toc-tree li.scroll-current>.reference{color:var(--color-toc-item-text--active);font-weight:700}.toc-tree .reference{color:var(--color-toc-item-text);overflow-wrap:anywhere;text-decoration:none}.toc-scroll{max-height:100vh;overflow-y:scroll}.contents:not(.this-will-duplicate-information-and-it-is-still-useful-here){background:rgba(255,0,0,.25);color:var(--color-problematic)}.contents:not(.this-will-duplicate-information-and-it-is-still-useful-here):before{content:"ERROR: Adding a table of contents in Furo-based documentation is unnecessary, and does not work well with existing styling.Add a 'this-will-duplicate-information-and-it-is-still-useful-here' class, if you want an escape hatch."}.text-align\:left>p{text-align:left}.text-align\:center>p{text-align:center}.text-align\:right>p{text-align:right} +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{-webkit-text-size-adjust:100%;line-height:1.15}body{margin:0}main{display:block}h1{font-size:2em;margin:.67em 0}hr{box-sizing:content-box;height:0;overflow:visible}pre{font-family:monospace,monospace;font-size:1em}a{background-color:transparent}abbr[title]{border-bottom:none;text-decoration:underline;text-decoration:underline dotted}b,strong{font-weight:bolder}code,kbd,samp{font-family:monospace,monospace;font-size:1em}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sub{bottom:-.25em}sup{top:-.5em}img{border-style:none}button,input,optgroup,select,textarea{font-family:inherit;font-size:100%;line-height:1.15;margin:0}button,input{overflow:visible}button,select{text-transform:none}[type=button],[type=reset],[type=submit],button{-webkit-appearance:button}[type=button]::-moz-focus-inner,[type=reset]::-moz-focus-inner,[type=submit]::-moz-focus-inner,button::-moz-focus-inner{border-style:none;padding:0}[type=button]:-moz-focusring,[type=reset]:-moz-focusring,[type=submit]:-moz-focusring,button:-moz-focusring{outline:1px dotted ButtonText}fieldset{padding:.35em .75em .625em}legend{box-sizing:border-box;color:inherit;display:table;max-width:100%;padding:0;white-space:normal}progress{vertical-align:baseline}textarea{overflow:auto}[type=checkbox],[type=radio]{box-sizing:border-box;padding:0}[type=number]::-webkit-inner-spin-button,[type=number]::-webkit-outer-spin-button{height:auto}[type=search]{-webkit-appearance:textfield;outline-offset:-2px}[type=search]::-webkit-search-decoration{-webkit-appearance:none}::-webkit-file-upload-button{-webkit-appearance:button;font:inherit}details{display:block}summary{display:list-item}[hidden],template{display:none}@media print{.content-icon-container,.headerlink,.mobile-header,.related-pages{display:none!important}.highlight{border:.1pt solid var(--color-foreground-border)}a,blockquote,dl,ol,pre,table,ul{page-break-inside:avoid}caption,figure,h1,h2,h3,h4,h5,h6,img{page-break-after:avoid;page-break-inside:avoid}dl,ol,ul{page-break-before:avoid}}.visually-hidden{clip:rect(0,0,0,0)!important;border:0!important;height:1px!important;margin:-1px!important;overflow:hidden!important;padding:0!important;position:absolute!important;white-space:nowrap!important;width:1px!important}:-moz-focusring{outline:auto}body{--font-stack:-apple-system,BlinkMacSystemFont,Segoe UI,Helvetica,Arial,sans-serif,Apple Color Emoji,Segoe UI Emoji;--font-stack--monospace:"SFMono-Regular",Menlo,Consolas,Monaco,Liberation Mono,Lucida Console,monospace;--font-size--normal:100%;--font-size--small:87.5%;--font-size--small--2:81.25%;--font-size--small--3:75%;--font-size--small--4:62.5%;--sidebar-caption-font-size:var(--font-size--small--2);--sidebar-item-font-size:var(--font-size--small);--sidebar-search-input-font-size:var(--font-size--small);--toc-font-size:var(--font-size--small--3);--toc-font-size--mobile:var(--font-size--normal);--toc-title-font-size:var(--font-size--small--4);--admonition-font-size:0.8125rem;--admonition-title-font-size:0.8125rem;--code-font-size:var(--font-size--small--2);--api-font-size:var(--font-size--small);--header-height:calc(var(--sidebar-item-line-height) + var(--sidebar-item-spacing-vertical)*4);--header-padding:0.5rem;--sidebar-tree-space-above:1.5rem;--sidebar-caption-space-above:1rem;--sidebar-item-line-height:1rem;--sidebar-item-spacing-vertical:0.5rem;--sidebar-item-spacing-horizontal:1rem;--sidebar-item-height:calc(var(--sidebar-item-line-height) + var(--sidebar-item-spacing-vertical)*2);--sidebar-expander-width:var(--sidebar-item-height);--sidebar-search-space-above:0.5rem;--sidebar-search-input-spacing-vertical:0.5rem;--sidebar-search-input-spacing-horizontal:0.5rem;--sidebar-search-input-height:1rem;--sidebar-search-icon-size:var(--sidebar-search-input-height);--toc-title-padding:0.25rem 0;--toc-spacing-vertical:1.5rem;--toc-spacing-horizontal:1.5rem;--toc-item-spacing-vertical:0.4rem;--toc-item-spacing-horizontal:1rem;--icon-search:url('data:image/svg+xml;charset=utf-8,');--icon-pencil:url('data:image/svg+xml;charset=utf-8,');--icon-abstract:url('data:image/svg+xml;charset=utf-8,');--icon-info:url('data:image/svg+xml;charset=utf-8,');--icon-flame:url('data:image/svg+xml;charset=utf-8,');--icon-question:url('data:image/svg+xml;charset=utf-8,');--icon-warning:url('data:image/svg+xml;charset=utf-8,');--icon-failure:url('data:image/svg+xml;charset=utf-8,');--icon-spark:url('data:image/svg+xml;charset=utf-8,');--color-admonition-title--caution:#ff9100;--color-admonition-title-background--caution:rgba(255,145,0,.2);--color-admonition-title--warning:#ff9100;--color-admonition-title-background--warning:rgba(255,145,0,.2);--color-admonition-title--danger:#ff5252;--color-admonition-title-background--danger:rgba(255,82,82,.2);--color-admonition-title--attention:#ff5252;--color-admonition-title-background--attention:rgba(255,82,82,.2);--color-admonition-title--error:#ff5252;--color-admonition-title-background--error:rgba(255,82,82,.2);--color-admonition-title--hint:#00c852;--color-admonition-title-background--hint:rgba(0,200,82,.2);--color-admonition-title--tip:#00c852;--color-admonition-title-background--tip:rgba(0,200,82,.2);--color-admonition-title--important:#00bfa5;--color-admonition-title-background--important:rgba(0,191,165,.2);--color-admonition-title--note:#00b0ff;--color-admonition-title-background--note:rgba(0,176,255,.2);--color-admonition-title--seealso:#448aff;--color-admonition-title-background--seealso:rgba(68,138,255,.2);--color-admonition-title--admonition-todo:grey;--color-admonition-title-background--admonition-todo:hsla(0,0%,50%,.2);--color-admonition-title:#651fff;--color-admonition-title-background:rgba(101,31,255,.2);--icon-admonition-default:var(--icon-abstract);--color-topic-title:#14b8a6;--color-topic-title-background:rgba(20,184,166,.2);--icon-topic-default:var(--icon-pencil);--color-problematic:#b30000;--color-foreground-primary:#000;--color-foreground-secondary:#5a5c63;--color-foreground-muted:#646776;--color-foreground-border:#878787;--color-background-primary:#fff;--color-background-secondary:#f8f9fb;--color-background-hover:#efeff4;--color-background-hover--transparent:#efeff400;--color-background-border:#eeebee;--color-background-item:#ccc;--color-announcement-background:#000000dd;--color-announcement-text:#eeebee;--color-brand-primary:#2962ff;--color-brand-content:#2a5adf;--color-api-background:var(--color-background-hover--transparent);--color-api-background-hover:var(--color-background-hover);--color-api-overall:var(--color-foreground-secondary);--color-api-name:var(--color-problematic);--color-api-pre-name:var(--color-problematic);--color-api-paren:var(--color-foreground-secondary);--color-api-keyword:var(--color-foreground-primary);--color-highlight-on-target:#ffc;--color-inline-code-background:var(--color-background-secondary);--color-highlighted-background:#def;--color-highlighted-text:var(--color-foreground-primary);--color-guilabel-background:#ddeeff80;--color-guilabel-border:#bedaf580;--color-guilabel-text:var(--color-foreground-primary);--color-admonition-background:transparent;--color-table-header-background:var(--color-background-secondary);--color-table-border:var(--color-background-border);--color-card-border:var(--color-background-secondary);--color-card-background:transparent;--color-card-marginals-background:var(--color-background-secondary);--color-header-background:var(--color-background-primary);--color-header-border:var(--color-background-border);--color-header-text:var(--color-foreground-primary);--color-sidebar-background:var(--color-background-secondary);--color-sidebar-background-border:var(--color-background-border);--color-sidebar-brand-text:var(--color-foreground-primary);--color-sidebar-caption-text:var(--color-foreground-muted);--color-sidebar-link-text:var(--color-foreground-secondary);--color-sidebar-link-text--top-level:var(--color-brand-primary);--color-sidebar-item-background:var(--color-sidebar-background);--color-sidebar-item-background--current:var( --color-sidebar-item-background );--color-sidebar-item-background--hover:linear-gradient(90deg,var(--color-background-hover--transparent) 0%,var(--color-background-hover) var(--sidebar-item-spacing-horizontal),var(--color-background-hover) 100%);--color-sidebar-item-expander-background:transparent;--color-sidebar-item-expander-background--hover:var( --color-background-hover );--color-sidebar-search-text:var(--color-foreground-primary);--color-sidebar-search-background:var(--color-background-secondary);--color-sidebar-search-background--focus:var(--color-background-primary);--color-sidebar-search-border:var(--color-background-border);--color-sidebar-search-icon:var(--color-foreground-muted);--color-toc-background:var(--color-background-primary);--color-toc-title-text:var(--color-foreground-muted);--color-toc-item-text:var(--color-foreground-secondary);--color-toc-item-text--hover:var(--color-foreground-primary);--color-toc-item-text--active:var(--color-brand-primary);--color-content-foreground:var(--color-foreground-primary);--color-content-background:transparent;--color-link:var(--color-brand-content);--color-link--hover:var(--color-brand-content);--color-link-underline:var(--color-background-border);--color-link-underline--hover:var(--color-foreground-border)}.only-light{display:block!important}html body .only-dark{display:none!important}@media not print{body[data-theme=dark]{--color-problematic:#ee5151;--color-foreground-primary:#ffffffcc;--color-foreground-secondary:#9ca0a5;--color-foreground-muted:#81868d;--color-foreground-border:#666;--color-background-primary:#131416;--color-background-secondary:#1a1c1e;--color-background-hover:#1e2124;--color-background-hover--transparent:#1e212400;--color-background-border:#303335;--color-background-item:#444;--color-announcement-background:#000000dd;--color-announcement-text:#eeebee;--color-brand-primary:#2b8cee;--color-brand-content:#368ce2;--color-highlighted-background:#083563;--color-guilabel-background:#08356380;--color-guilabel-border:#13395f80;--color-api-keyword:var(--color-foreground-secondary);--color-highlight-on-target:#330;--color-admonition-background:#18181a;--color-card-border:var(--color-background-secondary);--color-card-background:#18181a;--color-card-marginals-background:var(--color-background-hover)}html body[data-theme=dark] .only-light{display:none!important}body[data-theme=dark] .only-dark{display:block!important}@media(prefers-color-scheme:dark){body:not([data-theme=light]){--color-problematic:#ee5151;--color-foreground-primary:#ffffffcc;--color-foreground-secondary:#9ca0a5;--color-foreground-muted:#81868d;--color-foreground-border:#666;--color-background-primary:#131416;--color-background-secondary:#1a1c1e;--color-background-hover:#1e2124;--color-background-hover--transparent:#1e212400;--color-background-border:#303335;--color-background-item:#444;--color-announcement-background:#000000dd;--color-announcement-text:#eeebee;--color-brand-primary:#2b8cee;--color-brand-content:#368ce2;--color-highlighted-background:#083563;--color-guilabel-background:#08356380;--color-guilabel-border:#13395f80;--color-api-keyword:var(--color-foreground-secondary);--color-highlight-on-target:#330;--color-admonition-background:#18181a;--color-card-border:var(--color-background-secondary);--color-card-background:#18181a;--color-card-marginals-background:var(--color-background-hover)}html body:not([data-theme=light]) .only-light{display:none!important}body:not([data-theme=light]) .only-dark{display:block!important}}}body[data-theme=auto] .theme-toggle svg.theme-icon-when-auto,body[data-theme=dark] .theme-toggle svg.theme-icon-when-dark,body[data-theme=light] .theme-toggle svg.theme-icon-when-light{display:block}body{font-family:var(--font-stack)}code,kbd,pre,samp{font-family:var(--font-stack--monospace)}body{-webkit-font-smoothing:antialiased;-moz-osx-font-smoothing:grayscale}article{line-height:1.5}h1,h2,h3,h4,h5,h6{border-radius:.5rem;font-weight:700;line-height:1.25;margin:.5rem -.5rem;padding-left:.5rem;padding-right:.5rem}h1+p,h2+p,h3+p,h4+p,h5+p,h6+p{margin-top:0}h1{font-size:2.5em;margin-bottom:1rem}h1,h2{margin-top:1.75rem}h2{font-size:2em}h3{font-size:1.5em}h4{font-size:1.25em}h5{font-size:1.125em}h6{font-size:1em}small{font-size:80%;opacity:75%}p{margin-bottom:.75rem;margin-top:.5rem}hr.docutils{background-color:var(--color-background-border);border:0;height:1px;margin:2rem 0;padding:0}.centered{text-align:center}a{color:var(--color-link);text-decoration:underline;text-decoration-color:var(--color-link-underline)}a:hover{color:var(--color-link--hover);text-decoration-color:var(--color-link-underline--hover)}a.muted-link{color:inherit}a.muted-link:hover{color:var(--color-link);text-decoration-color:var(--color-link-underline--hover)}html{overflow-x:hidden;overflow-y:scroll;scroll-behavior:smooth}.sidebar-scroll,.toc-scroll,article[role=main] *{scrollbar-color:var(--color-foreground-border) transparent;scrollbar-width:thin}.sidebar-scroll::-webkit-scrollbar,.toc-scroll::-webkit-scrollbar,article[role=main] ::-webkit-scrollbar{height:.25rem;width:.25rem}.sidebar-scroll::-webkit-scrollbar-thumb,.toc-scroll::-webkit-scrollbar-thumb,article[role=main] ::-webkit-scrollbar-thumb{background-color:var(--color-foreground-border);border-radius:.125rem}body,html{background:var(--color-background-primary);color:var(--color-foreground-primary);height:100%}article{background:var(--color-content-background);color:var(--color-content-foreground);overflow-wrap:break-word}.page{display:flex;min-height:100%}.mobile-header{background-color:var(--color-header-background);border-bottom:1px solid var(--color-header-border);color:var(--color-header-text);display:none;height:var(--header-height);width:100%;z-index:10}.mobile-header.scrolled{border-bottom:none;box-shadow:0 0 .2rem rgba(0,0,0,.1),0 .2rem .4rem rgba(0,0,0,.2)}.mobile-header .header-center a{color:var(--color-header-text);text-decoration:none}.main{display:flex;flex:1}.sidebar-drawer{background:var(--color-sidebar-background);border-right:1px solid var(--color-sidebar-background-border);box-sizing:border-box;display:flex;justify-content:flex-end;min-width:15em;width:calc(50% - 26em)}.sidebar-container,.toc-drawer{box-sizing:border-box;width:15em}.toc-drawer{background:var(--color-toc-background);padding-right:1rem}.sidebar-sticky,.toc-sticky{display:flex;flex-direction:column;height:min(100%,100vh);height:100vh;position:sticky;top:0}.sidebar-scroll,.toc-scroll{flex-grow:1;flex-shrink:1;overflow:auto;scroll-behavior:smooth}.content{display:flex;flex-direction:column;justify-content:space-between;padding:0 3em;width:46em}.icon{display:inline-block;height:1rem;width:1rem}.icon svg{height:100%;width:100%}.announcement{align-items:center;background-color:var(--color-announcement-background);color:var(--color-announcement-text);display:flex;height:var(--header-height);overflow-x:auto}.announcement+.page{min-height:calc(100% - var(--header-height))}.announcement-content{box-sizing:border-box;min-width:100%;padding:.5rem;text-align:center;white-space:nowrap}.announcement-content a{color:var(--color-announcement-text);text-decoration-color:var(--color-announcement-text)}.announcement-content a:hover{color:var(--color-announcement-text);text-decoration-color:var(--color-link--hover)}.no-js .theme-toggle-container{display:none}.theme-toggle-container{vertical-align:middle}.theme-toggle{background:transparent;border:none;cursor:pointer;padding:0}.theme-toggle svg{color:var(--color-foreground-primary);display:none;height:1rem;vertical-align:middle;width:1rem}.theme-toggle-header{float:left;padding:1rem .5rem}.nav-overlay-icon,.toc-overlay-icon{cursor:pointer;display:none}.nav-overlay-icon .icon,.toc-overlay-icon .icon{color:var(--color-foreground-secondary);height:1rem;width:1rem}.nav-overlay-icon,.toc-header-icon{align-items:center;justify-content:center}.toc-content-icon{height:1.5rem;width:1.5rem}.content-icon-container{display:flex;float:right;gap:.5rem;margin-bottom:1rem;margin-left:1rem;margin-top:1.5rem}.content-icon-container .edit-this-page svg{color:inherit;height:1rem;width:1rem}.sidebar-toggle{display:none;position:absolute}.sidebar-toggle[name=__toc]{left:20px}.sidebar-toggle:checked{left:40px}.overlay{background-color:rgba(0,0,0,.54);height:0;opacity:0;position:fixed;top:0;transition:width 0ms,height 0ms,opacity .25s ease-out;width:0}.sidebar-overlay{z-index:20}.toc-overlay{z-index:40}.sidebar-drawer{transition:left .25s ease-in-out;z-index:30}.toc-drawer{transition:right .25s ease-in-out;z-index:50}#__navigation:checked~.sidebar-overlay{height:100%;opacity:1;width:100%}#__navigation:checked~.page .sidebar-drawer{left:0;top:0}#__toc:checked~.toc-overlay{height:100%;opacity:1;width:100%}#__toc:checked~.page .toc-drawer{right:0;top:0}.back-to-top{background:var(--color-background-primary);border-radius:1rem;box-shadow:0 .2rem .5rem rgba(0,0,0,.05),0 0 1px 0 hsla(220,9%,46%,.502);display:none;font-size:.8125rem;left:0;margin-left:50%;padding:.5rem .75rem .5rem .5rem;position:fixed;text-decoration:none;top:1rem;transform:translateX(-50%);z-index:10}.back-to-top svg{fill:currentColor;display:inline-block;height:1rem;width:1rem}.back-to-top span{margin-left:.25rem}.show-back-to-top .back-to-top{align-items:center;display:flex}@media(min-width:97em){html{font-size:110%}}@media(max-width:82em){.toc-content-icon{display:flex}.toc-drawer{border-left:1px solid var(--color-background-muted);height:100vh;position:fixed;right:-15em;top:0}.toc-tree{border-left:none;font-size:var(--toc-font-size--mobile)}.sidebar-drawer{width:calc(50% - 18.5em)}}@media(max-width:67em){.nav-overlay-icon{display:flex}.sidebar-drawer{height:100vh;left:-15em;position:fixed;top:0;width:15em}.toc-header-icon{display:flex}.theme-toggle-content,.toc-content-icon{display:none}.theme-toggle-header{display:block}.mobile-header{align-items:center;display:flex;justify-content:space-between;position:sticky;top:0}.mobile-header .header-left,.mobile-header .header-right{display:flex;height:var(--header-height);padding:0 var(--header-padding)}.mobile-header .header-left label,.mobile-header .header-right label{height:100%;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:100%}.nav-overlay-icon .icon,.theme-toggle svg{height:1.25rem;width:1.25rem}:target{scroll-margin-top:var(--header-height)}.back-to-top{top:calc(var(--header-height) + .5rem)}.page{flex-direction:column;justify-content:center}.content{margin-left:auto;margin-right:auto}}@media(max-width:52em){.content{overflow-x:auto;width:100%}}@media(max-width:46em){.content{padding:0 1em}article aside.sidebar{float:none;margin:1rem 0;width:100%}}.admonition,.topic{background:var(--color-admonition-background);border-radius:.2rem;box-shadow:0 .2rem .5rem rgba(0,0,0,.05),0 0 .0625rem rgba(0,0,0,.1);font-size:var(--admonition-font-size);margin:1rem auto;overflow:hidden;padding:0 .5rem .5rem;page-break-inside:avoid}.admonition>:nth-child(2),.topic>:nth-child(2){margin-top:0}.admonition>:last-child,.topic>:last-child{margin-bottom:0}.admonition p.admonition-title,p.topic-title{font-size:var(--admonition-title-font-size);font-weight:500;line-height:1.3;margin:0 -.5rem .5rem;padding:.4rem .5rem .4rem 2rem;position:relative}.admonition p.admonition-title:before,p.topic-title:before{content:"";height:1rem;left:.5rem;position:absolute;width:1rem}p.admonition-title{background-color:var(--color-admonition-title-background)}p.admonition-title:before{background-color:var(--color-admonition-title);-webkit-mask-image:var(--icon-admonition-default);mask-image:var(--icon-admonition-default);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}p.topic-title{background-color:var(--color-topic-title-background)}p.topic-title:before{background-color:var(--color-topic-title);-webkit-mask-image:var(--icon-topic-default);mask-image:var(--icon-topic-default);-webkit-mask-repeat:no-repeat;mask-repeat:no-repeat}.admonition{border-left:.2rem solid var(--color-admonition-title)}.admonition.caution{border-left-color:var(--color-admonition-title--caution)}.admonition.caution>.admonition-title{background-color:var(--color-admonition-title-background--caution)}.admonition.caution>.admonition-title:before{background-color:var(--color-admonition-title--caution);-webkit-mask-image:var(--icon-spark);mask-image:var(--icon-spark)}.admonition.warning{border-left-color:var(--color-admonition-title--warning)}.admonition.warning>.admonition-title{background-color:var(--color-admonition-title-background--warning)}.admonition.warning>.admonition-title:before{background-color:var(--color-admonition-title--warning);-webkit-mask-image:var(--icon-warning);mask-image:var(--icon-warning)}.admonition.danger{border-left-color:var(--color-admonition-title--danger)}.admonition.danger>.admonition-title{background-color:var(--color-admonition-title-background--danger)}.admonition.danger>.admonition-title:before{background-color:var(--color-admonition-title--danger);-webkit-mask-image:var(--icon-spark);mask-image:var(--icon-spark)}.admonition.attention{border-left-color:var(--color-admonition-title--attention)}.admonition.attention>.admonition-title{background-color:var(--color-admonition-title-background--attention)}.admonition.attention>.admonition-title:before{background-color:var(--color-admonition-title--attention);-webkit-mask-image:var(--icon-warning);mask-image:var(--icon-warning)}.admonition.error{border-left-color:var(--color-admonition-title--error)}.admonition.error>.admonition-title{background-color:var(--color-admonition-title-background--error)}.admonition.error>.admonition-title:before{background-color:var(--color-admonition-title--error);-webkit-mask-image:var(--icon-failure);mask-image:var(--icon-failure)}.admonition.hint{border-left-color:var(--color-admonition-title--hint)}.admonition.hint>.admonition-title{background-color:var(--color-admonition-title-background--hint)}.admonition.hint>.admonition-title:before{background-color:var(--color-admonition-title--hint);-webkit-mask-image:var(--icon-question);mask-image:var(--icon-question)}.admonition.tip{border-left-color:var(--color-admonition-title--tip)}.admonition.tip>.admonition-title{background-color:var(--color-admonition-title-background--tip)}.admonition.tip>.admonition-title:before{background-color:var(--color-admonition-title--tip);-webkit-mask-image:var(--icon-info);mask-image:var(--icon-info)}.admonition.important{border-left-color:var(--color-admonition-title--important)}.admonition.important>.admonition-title{background-color:var(--color-admonition-title-background--important)}.admonition.important>.admonition-title:before{background-color:var(--color-admonition-title--important);-webkit-mask-image:var(--icon-flame);mask-image:var(--icon-flame)}.admonition.note{border-left-color:var(--color-admonition-title--note)}.admonition.note>.admonition-title{background-color:var(--color-admonition-title-background--note)}.admonition.note>.admonition-title:before{background-color:var(--color-admonition-title--note);-webkit-mask-image:var(--icon-pencil);mask-image:var(--icon-pencil)}.admonition.seealso{border-left-color:var(--color-admonition-title--seealso)}.admonition.seealso>.admonition-title{background-color:var(--color-admonition-title-background--seealso)}.admonition.seealso>.admonition-title:before{background-color:var(--color-admonition-title--seealso);-webkit-mask-image:var(--icon-info);mask-image:var(--icon-info)}.admonition.admonition-todo{border-left-color:var(--color-admonition-title--admonition-todo)}.admonition.admonition-todo>.admonition-title{background-color:var(--color-admonition-title-background--admonition-todo)}.admonition.admonition-todo>.admonition-title:before{background-color:var(--color-admonition-title--admonition-todo);-webkit-mask-image:var(--icon-pencil);mask-image:var(--icon-pencil)}.admonition-todo>.admonition-title{text-transform:uppercase}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dd{margin-left:2rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dd>:first-child{margin-top:.125rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list,dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) dd>:last-child{margin-bottom:.75rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list>dt{font-size:var(--font-size--small);text-transform:uppercase}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list dd:empty{margin-bottom:.5rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list dd>ul{margin-left:-1.2rem}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list dd>ul>li>p:nth-child(2){margin-top:0}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple) .field-list dd>ul>li>p+p:last-child:empty{margin-bottom:0;margin-top:0}dl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)>dt{color:var(--color-api-overall)}.sig:not(.sig-inline){background:var(--color-api-background);border-radius:.25rem;font-family:var(--font-stack--monospace);font-size:var(--api-font-size);font-weight:700;margin-left:-.25rem;margin-right:-.25rem;padding:.25rem .5rem .25rem 3em;text-indent:-2.5em;transition:background .1s ease-out}.sig:not(.sig-inline):hover{background:var(--color-api-background-hover)}.sig:not(.sig-inline) a.reference .viewcode-link{font-weight:400;width:3.5rem}em.property{font-style:normal}em.property:first-child{color:var(--color-api-keyword)}.sig-name{color:var(--color-api-name)}.sig-prename{color:var(--color-api-pre-name);font-weight:400}.sig-paren{color:var(--color-api-paren)}.sig-param{font-style:normal}.versionmodified{font-style:italic}div.deprecated p,div.versionadded p,div.versionchanged p{margin-bottom:.125rem;margin-top:.125rem}.viewcode-back,.viewcode-link{float:right;text-align:right}.line-block{margin-bottom:.75rem;margin-top:.5rem}.line-block .line-block{margin-bottom:0;margin-top:0;padding-left:1rem}.code-block-caption,article p.caption,table>caption{font-size:var(--font-size--small);text-align:center}.toctree-wrapper.compound .caption,.toctree-wrapper.compound :not(.caption)>.caption-text{font-size:var(--font-size--small);margin-bottom:0;text-align:initial;text-transform:uppercase}.toctree-wrapper.compound>ul{margin-bottom:0;margin-top:0}.sig-inline,code.literal{background:var(--color-inline-code-background);border-radius:.2em;font-size:var(--font-size--small--2);padding:.1em .2em}pre.literal-block .sig-inline,pre.literal-block code.literal{font-size:inherit;padding:0}p .sig-inline,p code.literal{border:1px solid var(--color-background-border)}.sig-inline{font-family:var(--font-stack--monospace)}div[class*=" highlight-"],div[class^=highlight-]{display:flex;margin:1em 0}div[class*=" highlight-"] .table-wrapper,div[class^=highlight-] .table-wrapper,pre{margin:0;padding:0}pre{overflow:auto}article[role=main] .highlight pre{line-height:1.5}.highlight pre,pre.literal-block{font-size:var(--code-font-size);padding:.625rem .875rem}pre.literal-block{background-color:var(--color-code-background);border-radius:.2rem;color:var(--color-code-foreground);margin-bottom:1rem;margin-top:1rem}.highlight{border-radius:.2rem;width:100%}.highlight .gp,.highlight span.linenos{pointer-events:none;-webkit-user-select:none;-moz-user-select:none;user-select:none}.highlight .hll{display:block;margin-left:-.875rem;margin-right:-.875rem;padding-left:.875rem;padding-right:.875rem}.code-block-caption{background-color:var(--color-code-background);border-bottom:1px solid;border-radius:.25rem;border-bottom-left-radius:0;border-bottom-right-radius:0;border-color:var(--color-background-border);color:var(--color-code-foreground);display:flex;font-weight:300;padding:.625rem .875rem}.code-block-caption+div[class]{margin-top:0}.code-block-caption+div[class] pre{border-top-left-radius:0;border-top-right-radius:0}.highlighttable{display:block;width:100%}.highlighttable tbody{display:block}.highlighttable tr{display:flex}.highlighttable td.linenos{background-color:var(--color-code-background);border-bottom-left-radius:.2rem;border-top-left-radius:.2rem;color:var(--color-code-foreground);padding:.625rem 0 .625rem .875rem}.highlighttable .linenodiv{box-shadow:-.0625rem 0 var(--color-foreground-border) inset;font-size:var(--code-font-size);padding-right:.875rem}.highlighttable td.code{display:block;flex:1;overflow:hidden;padding:0}.highlighttable td.code .highlight{border-bottom-left-radius:0;border-top-left-radius:0}.highlight span.linenos{box-shadow:-.0625rem 0 var(--color-foreground-border) inset;display:inline-block;margin-right:.875rem;padding-left:0;padding-right:.875rem}.footnote-reference{font-size:var(--font-size--small--4);vertical-align:super}dl.footnote.brackets{color:var(--color-foreground-secondary);display:grid;font-size:var(--font-size--small);grid-template-columns:max-content auto}dl.footnote.brackets dt{margin:0}dl.footnote.brackets dt>.fn-backref{margin-left:.25rem}dl.footnote.brackets dt:after{content:":"}dl.footnote.brackets dt .brackets:before{content:"["}dl.footnote.brackets dt .brackets:after{content:"]"}dl.footnote.brackets dd{margin:0;padding:0 1rem}aside.footnote{color:var(--color-foreground-secondary);font-size:var(--font-size--small)}aside.footnote>span,div.citation>span{float:left;font-weight:500;padding-right:.25rem}aside.footnote>p,div.citation>p{margin-left:2rem}img{box-sizing:border-box;height:auto;max-width:100%}article .figure,article figure{border-radius:.2rem;margin:0}article .figure :last-child,article figure :last-child{margin-bottom:0}article .align-left{clear:left;float:left;margin:0 1rem 1rem}article .align-right{clear:right;float:right;margin:0 1rem 1rem}article .align-center,article .align-default{display:block;margin-left:auto;margin-right:auto;text-align:center}article table.align-default{display:table;text-align:initial}.domainindex-jumpbox,.genindex-jumpbox{border-bottom:1px solid var(--color-background-border);border-top:1px solid var(--color-background-border);padding:.25rem}.domainindex-section h2,.genindex-section h2{margin-bottom:.5rem;margin-top:.75rem}.domainindex-section ul,.genindex-section ul{margin-bottom:0;margin-top:0}ol,ul{margin-bottom:1rem;margin-top:1rem;padding-left:1.2rem}ol li>p:first-child,ul li>p:first-child{margin-bottom:.25rem;margin-top:.25rem}ol li>p:last-child,ul li>p:last-child{margin-top:.25rem}ol li>ol,ol li>ul,ul li>ol,ul li>ul{margin-bottom:.5rem;margin-top:.5rem}ol.arabic{list-style:decimal}ol.loweralpha{list-style:lower-alpha}ol.upperalpha{list-style:upper-alpha}ol.lowerroman{list-style:lower-roman}ol.upperroman{list-style:upper-roman}.simple li>ol,.simple li>ul,.toctree-wrapper li>ol,.toctree-wrapper li>ul{margin-bottom:0;margin-top:0}.field-list dt,.option-list dt,dl.footnote dt,dl.glossary dt,dl.simple dt,dl:not([class]) dt{font-weight:500;margin-top:.25rem}.field-list dt+dt,.option-list dt+dt,dl.footnote dt+dt,dl.glossary dt+dt,dl.simple dt+dt,dl:not([class]) dt+dt{margin-top:0}.field-list dt .classifier:before,.option-list dt .classifier:before,dl.footnote dt .classifier:before,dl.glossary dt .classifier:before,dl.simple dt .classifier:before,dl:not([class]) dt .classifier:before{content:":";margin-left:.2rem;margin-right:.2rem}.field-list dd ul,.field-list dd>p:first-child,.option-list dd ul,.option-list dd>p:first-child,dl.footnote dd ul,dl.footnote dd>p:first-child,dl.glossary dd ul,dl.glossary dd>p:first-child,dl.simple dd ul,dl.simple dd>p:first-child,dl:not([class]) dd ul,dl:not([class]) dd>p:first-child{margin-top:.125rem}.field-list dd ul,.option-list dd ul,dl.footnote dd ul,dl.glossary dd ul,dl.simple dd ul,dl:not([class]) dd ul{margin-bottom:.125rem}.math-wrapper{overflow-x:auto;width:100%}div.math{position:relative;text-align:center}div.math .headerlink,div.math:focus .headerlink{display:none}div.math:hover .headerlink{display:inline-block}div.math span.eqno{position:absolute;right:.5rem;top:50%;transform:translateY(-50%);z-index:1}abbr[title]{cursor:help}.problematic{color:var(--color-problematic)}kbd:not(.compound){background-color:var(--color-background-secondary);border:1px solid var(--color-foreground-border);border-radius:.2rem;box-shadow:0 .0625rem 0 rgba(0,0,0,.2),inset 0 0 0 .125rem var(--color-background-primary);color:var(--color-foreground-primary);display:inline-block;font-size:var(--font-size--small--3);margin:0 .2rem;padding:0 .2rem;vertical-align:text-bottom}blockquote{background:var(--color-background-secondary);border-left:4px solid var(--color-background-border);margin-left:0;margin-right:0;padding:.5rem 1rem}blockquote .attribution{font-weight:600;text-align:right}blockquote.highlights,blockquote.pull-quote{font-size:1.25em}blockquote.epigraph,blockquote.pull-quote{border-left-width:0;border-radius:.5rem}blockquote.highlights{background:transparent;border-left-width:0}p .reference img{vertical-align:middle}p.rubric{font-size:1.125em;font-weight:700;line-height:1.25}dd p.rubric{font-size:var(--font-size--small);font-weight:inherit;line-height:inherit;text-transform:uppercase}article .sidebar{background-color:var(--color-background-secondary);border:1px solid var(--color-background-border);border-radius:.2rem;clear:right;float:right;margin-left:1rem;margin-right:0;width:30%}article .sidebar>*{padding-left:1rem;padding-right:1rem}article .sidebar>ol,article .sidebar>ul{padding-left:2.2rem}article .sidebar .sidebar-title{border-bottom:1px solid var(--color-background-border);font-weight:500;margin:0;padding:.5rem 1rem}.table-wrapper{margin-bottom:.5rem;margin-top:1rem;overflow-x:auto;padding:.2rem .2rem .75rem;width:100%}table.docutils{border-collapse:collapse;border-radius:.2rem;border-spacing:0;box-shadow:0 .2rem .5rem rgba(0,0,0,.05),0 0 .0625rem rgba(0,0,0,.1)}table.docutils th{background:var(--color-table-header-background)}table.docutils td,table.docutils th{border-bottom:1px solid var(--color-table-border);border-left:1px solid var(--color-table-border);border-right:1px solid var(--color-table-border);padding:0 .25rem}table.docutils td p,table.docutils th p{margin:.25rem}table.docutils td:first-child,table.docutils th:first-child{border-left:none}table.docutils td:last-child,table.docutils th:last-child{border-right:none}table.docutils td.text-left,table.docutils th.text-left{text-align:left}table.docutils td.text-right,table.docutils th.text-right{text-align:right}table.docutils td.text-center,table.docutils th.text-center{text-align:center}:target{scroll-margin-top:.5rem}@media(max-width:67em){:target{scroll-margin-top:calc(.5rem + var(--header-height))}section>span:target{scroll-margin-top:calc(.8rem + var(--header-height))}}.headerlink{font-weight:100;-webkit-user-select:none;-moz-user-select:none;user-select:none}.code-block-caption>.headerlink,dl dt>.headerlink,figcaption p>.headerlink,h1>.headerlink,h2>.headerlink,h3>.headerlink,h4>.headerlink,h5>.headerlink,h6>.headerlink,p.caption>.headerlink,table>caption>.headerlink{margin-left:.5rem;visibility:hidden}.code-block-caption:hover>.headerlink,dl dt:hover>.headerlink,figcaption p:hover>.headerlink,h1:hover>.headerlink,h2:hover>.headerlink,h3:hover>.headerlink,h4:hover>.headerlink,h5:hover>.headerlink,h6:hover>.headerlink,p.caption:hover>.headerlink,table>caption:hover>.headerlink{visibility:visible}.code-block-caption>.toc-backref,dl dt>.toc-backref,figcaption p>.toc-backref,h1>.toc-backref,h2>.toc-backref,h3>.toc-backref,h4>.toc-backref,h5>.toc-backref,h6>.toc-backref,p.caption>.toc-backref,table>caption>.toc-backref{color:inherit;text-decoration-line:none}figure:hover>figcaption>p>.headerlink,table:hover>caption>.headerlink{visibility:visible}:target>h1:first-of-type,:target>h2:first-of-type,:target>h3:first-of-type,:target>h4:first-of-type,:target>h5:first-of-type,:target>h6:first-of-type,span:target~h1:first-of-type,span:target~h2:first-of-type,span:target~h3:first-of-type,span:target~h4:first-of-type,span:target~h5:first-of-type,span:target~h6:first-of-type{background-color:var(--color-highlight-on-target)}:target>h1:first-of-type code.literal,:target>h2:first-of-type code.literal,:target>h3:first-of-type code.literal,:target>h4:first-of-type code.literal,:target>h5:first-of-type code.literal,:target>h6:first-of-type code.literal,span:target~h1:first-of-type code.literal,span:target~h2:first-of-type code.literal,span:target~h3:first-of-type code.literal,span:target~h4:first-of-type code.literal,span:target~h5:first-of-type code.literal,span:target~h6:first-of-type code.literal{background-color:transparent}.literal-block-wrapper:target .code-block-caption,.this-will-duplicate-information-and-it-is-still-useful-here li :target,figure:target,table:target>caption{background-color:var(--color-highlight-on-target)}dt:target{background-color:var(--color-highlight-on-target)!important}.footnote-reference:target,.footnote>dt:target+dd{background-color:var(--color-highlight-on-target)}.guilabel{background-color:var(--color-guilabel-background);border:1px solid var(--color-guilabel-border);border-radius:.5em;color:var(--color-guilabel-text);font-size:.9em;padding:0 .3em}footer{display:flex;flex-direction:column;font-size:var(--font-size--small);margin-top:2rem}.bottom-of-page{align-items:center;border-top:1px solid var(--color-background-border);color:var(--color-foreground-secondary);display:flex;justify-content:space-between;line-height:1.5;margin-top:1rem;padding-bottom:1rem;padding-top:1rem}@media(max-width:46em){.bottom-of-page{flex-direction:column-reverse;gap:.25rem;text-align:center}}.bottom-of-page .left-details{font-size:var(--font-size--small)}.bottom-of-page .right-details{display:flex;flex-direction:column;gap:.25rem;text-align:right}.bottom-of-page .icons{display:flex;font-size:1rem;gap:.25rem;justify-content:flex-end}.bottom-of-page .icons a{text-decoration:none}.bottom-of-page .icons img,.bottom-of-page .icons svg{font-size:1.125rem;height:1em;width:1em}.related-pages a{align-items:center;display:flex;text-decoration:none}.related-pages a:hover .page-info .title{color:var(--color-link);text-decoration:underline;text-decoration-color:var(--color-link-underline)}.related-pages a svg.furo-related-icon,.related-pages a svg.furo-related-icon>use{color:var(--color-foreground-border);flex-shrink:0;height:.75rem;margin:0 .5rem;width:.75rem}.related-pages a.next-page{clear:right;float:right;max-width:50%;text-align:right}.related-pages a.prev-page{clear:left;float:left;max-width:50%}.related-pages a.prev-page svg{transform:rotate(180deg)}.page-info{display:flex;flex-direction:column;overflow-wrap:anywhere}.next-page .page-info{align-items:flex-end}.page-info .context{align-items:center;color:var(--color-foreground-muted);display:flex;font-size:var(--font-size--small);padding-bottom:.1rem;text-decoration:none}ul.search{list-style:none;padding-left:0}ul.search li{border-bottom:1px solid var(--color-background-border);padding:1rem 0}[role=main] .highlighted{background-color:var(--color-highlighted-background);color:var(--color-highlighted-text)}.sidebar-brand{display:flex;flex-direction:column;flex-shrink:0;padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal);text-decoration:none}.sidebar-brand-text{color:var(--color-sidebar-brand-text);font-size:1.5rem;overflow-wrap:break-word}.sidebar-brand-text,.sidebar-logo-container{margin:var(--sidebar-item-spacing-vertical) 0}.sidebar-logo{display:block;margin:0 auto;max-width:100%}.sidebar-search-container{align-items:center;background:var(--color-sidebar-search-background);display:flex;margin-top:var(--sidebar-search-space-above);position:relative}.sidebar-search-container:focus-within,.sidebar-search-container:hover{background:var(--color-sidebar-search-background--focus)}.sidebar-search-container:before{background-color:var(--color-sidebar-search-icon);content:"";height:var(--sidebar-search-icon-size);left:var(--sidebar-item-spacing-horizontal);-webkit-mask-image:var(--icon-search);mask-image:var(--icon-search);position:absolute;width:var(--sidebar-search-icon-size)}.sidebar-search{background:transparent;border:none;border-bottom:1px solid var(--color-sidebar-search-border);border-top:1px solid var(--color-sidebar-search-border);box-sizing:border-box;color:var(--color-sidebar-search-foreground);padding:var(--sidebar-search-input-spacing-vertical) var(--sidebar-search-input-spacing-horizontal) var(--sidebar-search-input-spacing-vertical) calc(var(--sidebar-item-spacing-horizontal) + var(--sidebar-search-input-spacing-horizontal) + var(--sidebar-search-icon-size));width:100%;z-index:10}.sidebar-search:focus{outline:none}.sidebar-search::-moz-placeholder{font-size:var(--sidebar-search-input-font-size)}.sidebar-search::placeholder{font-size:var(--sidebar-search-input-font-size)}#searchbox .highlight-link{margin:0;padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal) 0;text-align:center}#searchbox .highlight-link a{color:var(--color-sidebar-search-icon);font-size:var(--font-size--small--2)}.sidebar-tree{font-size:var(--sidebar-item-font-size);margin-bottom:var(--sidebar-item-spacing-vertical);margin-top:var(--sidebar-tree-space-above)}.sidebar-tree ul{display:flex;flex-direction:column;list-style:none;margin-bottom:0;margin-top:0;padding:0}.sidebar-tree li{margin:0;position:relative}.sidebar-tree li>ul{margin-left:var(--sidebar-item-spacing-horizontal)}.sidebar-tree .icon,.sidebar-tree .reference{color:var(--color-sidebar-link-text)}.sidebar-tree .reference{box-sizing:border-box;display:inline-block;height:100%;line-height:var(--sidebar-item-line-height);overflow-wrap:anywhere;padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal);text-decoration:none;width:100%}.sidebar-tree .reference:hover{background:var(--color-sidebar-item-background--hover)}.sidebar-tree .reference.external:after{color:var(--color-sidebar-link-text);content:url("data:image/svg+xml;charset=utf-8,%3Csvg width='12' height='12' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 24 24' stroke-width='1.5' stroke='%23607D8B' fill='none' stroke-linecap='round' stroke-linejoin='round'%3E%3Cpath d='M0 0h24v24H0z' stroke='none'/%3E%3Cpath d='M11 7H6a2 2 0 0 0-2 2v9a2 2 0 0 0 2 2h9a2 2 0 0 0 2-2v-5M10 14 20 4M15 4h5v5'/%3E%3C/svg%3E");margin:0 .25rem;vertical-align:middle}.sidebar-tree .current-page>.reference{font-weight:700}.sidebar-tree label{align-items:center;cursor:pointer;display:flex;height:var(--sidebar-item-height);justify-content:center;position:absolute;right:0;top:0;-webkit-user-select:none;-moz-user-select:none;user-select:none;width:var(--sidebar-expander-width)}.sidebar-tree .caption,.sidebar-tree :not(.caption)>.caption-text{color:var(--color-sidebar-caption-text);font-size:var(--sidebar-caption-font-size);font-weight:700;margin:var(--sidebar-caption-space-above) 0 0 0;padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal);text-transform:uppercase}.sidebar-tree li.has-children>.reference{padding-right:var(--sidebar-expander-width)}.sidebar-tree .toctree-l1>.reference,.sidebar-tree .toctree-l1>label .icon{color:var(--color-sidebar-link-text--top-level)}.sidebar-tree label{background:var(--color-sidebar-item-expander-background)}.sidebar-tree label:hover{background:var(--color-sidebar-item-expander-background--hover)}.sidebar-tree .current>.reference{background:var(--color-sidebar-item-background--current)}.sidebar-tree .current>.reference:hover{background:var(--color-sidebar-item-background--hover)}.toctree-checkbox{display:none;position:absolute}.toctree-checkbox~ul{display:none}.toctree-checkbox~label .icon svg{transform:rotate(90deg)}.toctree-checkbox:checked~ul{display:block}.toctree-checkbox:checked~label .icon svg{transform:rotate(-90deg)}.toc-title-container{padding:var(--toc-title-padding);padding-top:var(--toc-spacing-vertical)}.toc-title{color:var(--color-toc-title-text);font-size:var(--toc-title-font-size);padding-left:var(--toc-spacing-horizontal);text-transform:uppercase}.no-toc{display:none}.toc-tree-container{padding-bottom:var(--toc-spacing-vertical)}.toc-tree{border-left:1px solid var(--color-background-border);font-size:var(--toc-font-size);line-height:1.3;padding-left:calc(var(--toc-spacing-horizontal) - var(--toc-item-spacing-horizontal))}.toc-tree>ul>li:first-child{padding-top:0}.toc-tree>ul>li:first-child>ul{padding-left:0}.toc-tree>ul>li:first-child>a{display:none}.toc-tree ul{list-style-type:none;margin-bottom:0;margin-top:0;padding-left:var(--toc-item-spacing-horizontal)}.toc-tree li{padding-top:var(--toc-item-spacing-vertical)}.toc-tree li.scroll-current>.reference{color:var(--color-toc-item-text--active);font-weight:700}.toc-tree .reference{color:var(--color-toc-item-text);overflow-wrap:anywhere;text-decoration:none}.toc-scroll{max-height:100vh;overflow-y:scroll}.contents:not(.this-will-duplicate-information-and-it-is-still-useful-here){background:rgba(255,0,0,.25);color:var(--color-problematic)}.contents:not(.this-will-duplicate-information-and-it-is-still-useful-here):before{content:"ERROR: Adding a table of contents in Furo-based documentation is unnecessary, and does not work well with existing styling.Add a 'this-will-duplicate-information-and-it-is-still-useful-here' class, if you want an escape hatch."}.text-align\:left>p{text-align:left}.text-align\:center>p{text-align:center}.text-align\:right>p{text-align:right} /*# sourceMappingURL=furo.css.map*/ \ No newline at end of file diff --git a/_static/styles/furo.css.map b/_static/styles/furo.css.map index 997200ae..d1dfb109 100644 --- a/_static/styles/furo.css.map +++ b/_static/styles/furo.css.map @@ -1 +1 @@ -{"version":3,"file":"styles/furo.css","mappings":"AAAA,2EAA2E,CAU3E,KAEE,6BAA8B,CAD9B,gBAEF,CASA,KACE,QACF,CAMA,KACE,aACF,CAOA,GACE,aAAc,CACd,cACF,CAUA,GACE,sBAAuB,CACvB,QAAS,CACT,gBACF,CAOA,IACE,+BAAiC,CACjC,aACF,CASA,EACE,4BACF,CAOA,YACE,kBAAmB,CACnB,yBAA0B,CAC1B,gCACF,CAMA,SAEE,kBACF,CAOA,cAGE,+BAAiC,CACjC,aACF,CAeA,QAEE,aAAc,CACd,aAAc,CACd,iBAAkB,CAClB,uBACF,CAEA,IACE,aACF,CAEA,IACE,SACF,CASA,IACE,iBACF,CAUA,sCAKE,mBAAoB,CACpB,cAAe,CACf,gBAAiB,CACjB,QACF,CAOA,aAEE,gBACF,CAOA,cAEE,mBACF,CAMA,gDAIE,yBACF,CAMA,wHAIE,iBAAkB,CAClB,SACF,CAMA,4GAIE,6BACF,CAMA,SACE,0BACF,CASA,OACE,qBAAsB,CACtB,aAAc,CACd,aAAc,CACd,cAAe,CACf,SAAU,CACV,kBACF,CAMA,SACE,uBACF,CAMA,SACE,aACF,CAOA,6BAEE,qBAAsB,CACtB,SACF,CAMA,kFAEE,WACF,CAOA,cACE,4BAA6B,CAC7B,mBACF,CAMA,yCACE,uBACF,CAOA,6BACE,yBAA0B,CAC1B,YACF,CASA,QACE,aACF,CAMA,QACE,iBACF,CAiBA,kBACE,YACF,CCvVA,aAcE,kEACE,uBAOF,WACE,iDAMF,gCACE,wBAEF,qCAEE,uBADA,uBACA,CAEF,SACE,wBAtBA,CCpBJ,iBAOE,6BAEA,mBANA,qBAEA,sBACA,0BAFA,oBAHA,4BAOA,6BANA,mBAOA,CAEF,gBACE,aCPF,KCGE,mHAEA,wGAGA,wBAAyB,CACzB,wBAAyB,CACzB,4BAA6B,CAC7B,yBAA0B,CAC1B,2BAA4B,CAG5B,sDAAuD,CACvD,gDAAiD,CACjD,wDAAyD,CAGzD,0CAA2C,CAC3C,gDAAiD,CACjD,gDAAiD,CAKjD,gCAAiC,CACjC,sCAAuC,CAGvC,2CAA4C,CAG5C,uCAAwC,CChCxC,+FAGA,uBAAwB,CAGxB,iCAAkC,CAClC,kCAAmC,CAEnC,+BAAgC,CAChC,sCAAuC,CACvC,sCAAuC,CACvC,qGAIA,mDAAoD,CAEpD,mCAAoC,CACpC,8CAA+C,CAC/C,gDAAiD,CACjD,kCAAmC,CACnC,6DAA8D,CAG9D,6BAA8B,CAC9B,6BAA8B,CAC9B,+BAAgC,CAChC,kCAAmC,CACnC,kCAAmC,CCPjC,ukBCYA,srCAZF,kaCVA,mLAOA,oTAWA,2UAaA,0CACA,gEACA,0CAGA,gEAUA,yCACA,+DAGA,4CACA,CACA,iEAGA,sGACA,uCACA,4DAGA,sCACA,2DAEA,4CACA,kEACA,oGACA,CAEA,0GACA,+CAGA,+MAOA,+EACA,wCAIA,4DACA,sEACA,kEACA,sEACA,gDAGA,+DACA,0CACA,gEACA,gGACA,CAGA,2DACA,qDAGA,0CACA,8CACA,oDACA,oDL7GF,iCAEA,iEAME,oCKyGA,yDAIA,sCACA,kCACA,sDAGA,0CACA,kEACA,oDAEA,sDAGA,oCACA,oEAIA,CAGA,yDAGA,qDACA,oDAGA,6DAIA,iEAGA,2DAEA,2DL9IE,4DAEA,gEAIF,gEKgGA,gFAIA,oNAOA,qDAEA,gFAIA,4DAIA,oEAMA,yEAIA,6DACA,0DAGA,uDAGA,qDAEA,wDLpII,6DAEA,yDACE,2DAMN,uCAIA,yCACE,8CAGF,sDMjDA,6DAKA,oCAIA,4CACA,kBAGF,sBAMA,2BAME,qCAGA,qCAEA,iCAEA,+BAEA,mCAEA,qCAIA,CACA,gCACA,gDAKA,kCAIA,6BAEA,0CAQA,kCAIF,8BAGE,8BACA,uCAGF,sCAKE,kCAEA,sDAGA,iCACE,CACA,2FAGA,gCACE,CACA,+DCzEJ,wCAEA,sBAEF,yDAEE,mCACA,wDAGA,2GAGA,wIACE,gDAMJ,kCAGE,6BACA,0CAGA,gEACA,8BAGA,uCAKA,sCAEA,wFAEA,iCAIA,sCAMA,sDAEE,gGAKE,+CAON,sBACE,yCAEA,0BAUF,yLAKA,aACE,mCAEA,mBAEF,wCAGE,MACA,kCACA,kCAGA,SAEF,kCAME,mBAGF,CAJE,eACA,CAHA,gBAEA,CASA,mBACA,mBAEF,oBACE,+BAGA,YACE,mBACA,CAMF,yBADF,kBAEE,CADA,gBACA,uCAEA,qBACA,iBACA,OACA,aACA,CAFA,WAEA,GACE,qBADF,gBACE,aAGF,+CAEA,SACA,CANE,WAEJ,aACE,CADF,SAIE,4BACA,GAGE,wBADF,yBACE,kDACA,uCAEA,yDAEE,+CAKN,uBACE,yDAKF,uBACE,CACA,iBACA,uBACA,kDAMA,0DAGF,CALE,oBAKF,0GAWE,sJAOA,+CAGF,sBAEE,WAKA,0CAEA,CALF,qCAGE,CAHF,WAKE,SAGA,0CAEE,CALF,qCAKE,OACA,YAEJ,gBACE,gBAIA,+CAKF,CAGE,kDAGA,CANF,8BAGE,CAGA,YAEA,CAdF,2BACE,CAHA,UAEF,CAYE,UAEA,CACA,0CACF,iEAOE,iCACA,8BAGA,wCAIA,wBAKE,0CAKF,CARE,6DAGA,CALF,qBAEE,CASA,YACA,yBAGA,CAEE,cAKN,CAPI,sBAOJ,gCAGE,qBAEA,WACA,aACA,sCAEA,mBACA,6BAGA,uEADA,qBACA,6BAIA,yBACA,qCAEE,UAEA,YACA,sBAEF,8BAGA,CAPE,aACA,WAMF,4BACE,sBACA,WAMJ,uBACE,cAYE,mBAXA,qDAKA,qCAGA,CAEA,YACA,CAHA,2BAEA,CACA,oCAEA,4CACA,uBAIA,oCAEJ,CAFI,cAIF,iBACE,CAHJ,kBAGI,yBAEA,oCAIA,qDAMF,mEAEA,CACE,8CAKA,gCAEA,qCAGA,oCAGE,sBACA,CAJF,WAEE,CAFF,eAEE,SAEA,mBACA,qCACE,aACA,CAFF,YADA,qBACA,WAEE,sBACA,kEAEN,2BAEE,iDAKA,uCAGF,CACE,0DAKA,kBACF,CAFE,sBAGA,mBACA,0BAEJ,yBAII,aADA,WACA,CAMF,UAFE,kBAEF,CAJF,gBACE,CAHE,iBAMF,6CC7ZF,yBACE,WACA,iBAEA,aAFA,iBAEA,6BAEA,kCACA,mBAKA,gCAGA,CARA,QAEA,CAGA,UALA,qBAEA,qDAGA,CALA,OAQA,4BACE,cAGF,2BACE,gCAEJ,CAHE,UAGF,aACE,iCAEA,CAHF,UAGE,wCAEA,WACA,WADA,UACA,6CAGA,yCAIA,kEAGE,QADA,KACA,cAQA,0CACA,CAFF,kBACE,CACA,wEACA,CALJ,YACE,CAEE,mBAFF,OAIE,gBAJF,gCACA,CADA,eALE,oBAIJ,CACE,SAIE,0BAEJ,CAFI,UAEJ,CACE,kCACA,qBACE,CAFF,sBAEE,qEACA,uDACA,8DAMF,yBAII,oDAJJ,YAGE,CAHF,eAGE,iBACE,WACA,uDACE,yCACA,2CACE,yCACA,YADA,eACA,uFALJ,+CACA,gBACE,kBACA,CADA,2CADF,eACE,MACA,0DACE,yCACA,qGALJ,oCACA,uCACE,CAFF,UAEE,uEACA,+CACE,oDACA,6DANN,kCACE,kCACA,gBADA,UACA,yBACE,wDACA,cADA,UACA,qBACE,6CACA,yFALJ,sCACA,CAEE,gBACE,CAHJ,gBAGI,sBAHJ,uBACE,4DACA,4CACE,iDAJJ,2CACA,CADA,gBAEE,gBAGE,sBALJ,+BAII,iBAFF,gDACA,WACE,YADF,uCACE,6EACA,2BANN,8CACE,kDACA,0CACE,8BACA,yFACE,sBACA,sFALJ,mEACA,sBACE,kEACA,6EACE,uCACA,kEALJ,qGAEE,kEACA,6EACE,uCACA,kEALJ,8CACA,uDACE,sEACA,2EACE,sCACA,iEALJ,mGACA,qCACE,oDACA,0DACE,6GACA,gDAGR,yDCpEA,sEACE,CACA,6GACE,gEACF,iGAIF,wFACE,qDAGA,mGAEE,2CAEF,4FACE,gCACF,wGACE,8DAEE,6FAIA,iJAKN,6GACE,gDAKF,yDACA,qCAGA,6BACA,kBACA,qDAKA,oCAEA,+DAGA,2CAGE,oDAIA,oEAEE,qBAGJ,wDAIA,uCAEE,kEAEF,CACF,6CAEE,uDAEA,oCAIF,4BACE,6BAEA,gEAEE,+CAIF,0EC9FA,sDAGE,+DCLJ,sCAGE,8BAKA,wJAIE,gBACA,yGCZF,mBAQA,2MAIA,oBAOF,wGAKE,iCAEE,CAFF,wBAEE,8GAWF,mBAEE,2GAMA,mBAEA,6HAOF,YAGA,mIAOE,gBADA,YACA,4FAOF,8BACA,uBAYA,sCAEE,CAFF,qBARA,wCAEA,CAHA,8BACA,CAFA,eACA,CAGA,mBAEA,sBAEA,kDAEA,CAEE,kCACE,6BACA,4CAMJ,kDAGA,eAIA,6CACE,mCACA,0CACA,8BAEA,sCACA,cAEF,+BACE,CAHA,eAGA,YACA,4BACA,gEAGF,0DAME,sBAFA,kBAGE,+BACA,4BAIJ,aACE,oBACA,CAFF,gBAEE,yBAEA,eACA,CApHsB,YAmHtB,CACA,sECpIF,mDACA,2FAMA,iCAGA,CACA,eACE,CAFF,kBACA,CADA,wBAEE,CACA,6BACE,eAEF,CAHA,YAGA,wEAIE,mBACE,qCACF,CAGJ,wBACE,CAJE,iBAIF,8BAIJ,+CAEE,qDAEF,kDAIE,YAEF,CAFE,YAEF,CCjCE,mFAJA,QACA,UAIE,CADF,iBACE,mCAGA,iDACE,+BAGF,wBAEA,mBAKA,6CAEF,CAHE,mBACA,CAEF,kCAIE,CARA,kBACA,CAFF,eASE,YACA,mBAGF,CAJE,UAIF,wCCjCA,oBDmCE,wBCpCJ,uCACE,8BACA,4CACA,oBAGA,2CCAA,6CAGE,CAPF,uBAIA,CDGA,gDACE,6BCVJ,CAWM,2CAEF,CAJA,kCAEE,CDJF,aCLF,gBDKE,uBCMA,gCAGA,gDAGE,wBAGJ,0BAEA,iBACE,aACF,CADE,UACF,uBACE,aACF,oBACE,YACF,4BACE,6CAMA,CAYF,6DAZE,mCAGE,iCASJ,4BAGE,4DADA,+BACA,CAFA,qBAEA,yBACE,aAEF,wBAHA,SAGA,iHACE,2DAKF,CANA,yCACE,CADF,oCAMA,uSAIA,sGACE,oDChEJ,WAEF,yBACE,QACA,eAEA,gBAEE,uCAGA,CALF,iCAKE,uCAGA,0BACA,CACA,oBACA,iCClBJ,gBACE,KAGF,qBACE,YAGF,CAHE,cAGF,gCAEE,mBACA,iEAEA,oCACA,wCAEA,sBACA,WAEA,CAFA,YAEA,8EAEA,mCAFA,iBAEA,6BAIA,wEAKA,sDAIE,CARF,mDAIA,CAIE,cAEF,8CAIA,oBAFE,iBAEF,8CAGE,eAEF,CAFE,YAEF,OAEE,kBAGJ,CAJI,eACA,CAFF,mBAKF,yCCjDE,oBACA,CAFA,iBAEA,uCAKE,iBACA,qCAGA,mBCZJ,CDWI,gBCXJ,6BAEE,eACA,sBAGA,eAEA,sBACA,oDACA,iGAMA,gBAFE,YAEF,8FAME,iJClBF,YACA,gNAUE,6BAEF,oTAcI,kBACF,gHAIA,qBACE,eACF,qDACE,kBACF,6DACE,4BCxCJ,oBAEF,qCAEI,+CAGF,uBACE,uDAGJ,oBAkBE,mDAhBA,+CAaA,CAbA,oBAaA,0FAEE,CAFF,gGAbA,+BAaA,0BAGA,mQAIA,oNAEE,iBAGJ,CAHI,gBADA,gBAIJ,8CAYI,CAZJ,wCAYI,sVACE,iCAGA,uEAHA,QAGA,qXAKJ,iDAGF,CARM,+CACE,iDAIN,CALI,gBAQN,mHACE,gBAGF,2DACE,0EAOA,0EAKA,6EC/EA,iDACA,gCACA,oDAGA,qBACA,oDCFA,cACA,eAEA,yBAGF,sBAEE,iBACA,sNAWA,iBACE,kBACA,wRAgBA,kBAEA,iOAgBA,uCACE,uEAEA,kBAEF,qUAuBE,iDAIJ,CACA,geCxFF,4BAEE,CAQA,6JACA,iDAIA,sEAGA,mDAOF,iDAGE,4DAIA,8CACA,qDAEE,eAFF,cAEE,oBAEF,uBAFE,kCAGA,eACA,iBACA,mBAIA,mDACA,CAHA,uCAEA,CAJA,0CACA,CAIA,gBAJA,gBACA,oBADA,gBAIA,wBAEJ,gBAGE,6BACA,YAHA,iBAGA,gCACA,iEAEA,6CACA,sDACA,0BADA,wBACA,0BACA,oIAIA,mBAFA,YAEA,qBACA,0CAIE,uBAEF,CAHA,yBACE,CAEF,iDACE,mFAKJ,oCACE,CANE,aAKJ,CACE,qEAIA,YAFA,WAEA,CAHA,aACA,CAEA,gBACE,4BACA,sBADA,aACA,gCAMF,oCACA,yDACA,2CAEA,qBAGE,kBAEA,CACA,mCAIF,CARE,YACA,CAOF,iCAEE,CAPA,oBACA,CAQA,oBACE,uDAEJ,sDAGA,CAHA,cAGA,0BACE,oDAIA,oCACA,4BACA,sBAGA,cAEA,oFAGA,sBAEA,yDACE,CAIA,iBAJA,wBAIA,6CAJA,6CAOA,4BAGJ,CAHI,cAGJ,yCAGA,kBACE,CAIA,iDAEA,CATA,YAEF,CACE,4CAGA,kBAIA,wEAEA,wDAIF,kCAOE,iDACA,CARF,WAIE,sCAGA,CANA,2CACA,CAMA,oEARF,iBACE,CACA,qCAMA,iBAuBE,uBAlBF,YAKA,2DALA,uDAKA,CALA,sBAiBA,4CACE,CALA,gRAIF,YACE,UAEN,uBACE,YACA,mCAOE,+CAGA,8BAGF,+CAGA,4BCjNA,SDiNA,qFCjNA,gDAGA,sCACA,qCACA,sDAIF,CAIE,kDAGA,CAPF,0CAOE,kBAEA,kDAEA,CAHA,eACA,CAFA,YACA,CADA,SAIA,mHAIE,CAGA,6CAFA,oCAeE,CAbF,yBACE,qBAEJ,CAGE,oBACA,CAEA,YAFA,2CACF,CACE,uBAEA,mFAEE,CALJ,oBACE,CAEA,UAEE,gCAGF,sDAEA,yCC7CJ,oCAGA,CD6CE,yXAQE,sCCrDJ,wCAGA,oCACE","sources":["webpack:///./node_modules/normalize.css/normalize.css","webpack:///./src/furo/assets/styles/base/_print.sass","webpack:///./src/furo/assets/styles/base/_screen-readers.sass","webpack:///./src/furo/assets/styles/base/_theme.sass","webpack:///./src/furo/assets/styles/variables/_fonts.scss","webpack:///./src/furo/assets/styles/variables/_spacing.scss","webpack:///./src/furo/assets/styles/variables/_icons.scss","webpack:///./src/furo/assets/styles/variables/_admonitions.scss","webpack:///./src/furo/assets/styles/variables/_colors.scss","webpack:///./src/furo/assets/styles/base/_typography.sass","webpack:///./src/furo/assets/styles/_scaffold.sass","webpack:///./src/furo/assets/styles/content/_admonitions.sass","webpack:///./src/furo/assets/styles/content/_api.sass","webpack:///./src/furo/assets/styles/content/_blocks.sass","webpack:///./src/furo/assets/styles/content/_captions.sass","webpack:///./src/furo/assets/styles/content/_code.sass","webpack:///./src/furo/assets/styles/content/_footnotes.sass","webpack:///./src/furo/assets/styles/content/_images.sass","webpack:///./src/furo/assets/styles/content/_indexes.sass","webpack:///./src/furo/assets/styles/content/_lists.sass","webpack:///./src/furo/assets/styles/content/_math.sass","webpack:///./src/furo/assets/styles/content/_misc.sass","webpack:///./src/furo/assets/styles/content/_rubrics.sass","webpack:///./src/furo/assets/styles/content/_sidebar.sass","webpack:///./src/furo/assets/styles/content/_tables.sass","webpack:///./src/furo/assets/styles/content/_target.sass","webpack:///./src/furo/assets/styles/content/_gui-labels.sass","webpack:///./src/furo/assets/styles/components/_footer.sass","webpack:///./src/furo/assets/styles/components/_sidebar.sass","webpack:///./src/furo/assets/styles/components/_table_of_contents.sass","webpack:///./src/furo/assets/styles/_shame.sass"],"sourcesContent":["/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */\n\n/* Document\n ========================================================================== */\n\n/**\n * 1. Correct the line height in all browsers.\n * 2. Prevent adjustments of font size after orientation changes in iOS.\n */\n\nhtml {\n line-height: 1.15; /* 1 */\n -webkit-text-size-adjust: 100%; /* 2 */\n}\n\n/* Sections\n ========================================================================== */\n\n/**\n * Remove the margin in all browsers.\n */\n\nbody {\n margin: 0;\n}\n\n/**\n * Render the `main` element consistently in IE.\n */\n\nmain {\n display: block;\n}\n\n/**\n * Correct the font size and margin on `h1` elements within `section` and\n * `article` contexts in Chrome, Firefox, and Safari.\n */\n\nh1 {\n font-size: 2em;\n margin: 0.67em 0;\n}\n\n/* Grouping content\n ========================================================================== */\n\n/**\n * 1. Add the correct box sizing in Firefox.\n * 2. Show the overflow in Edge and IE.\n */\n\nhr {\n box-sizing: content-box; /* 1 */\n height: 0; /* 1 */\n overflow: visible; /* 2 */\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\npre {\n font-family: monospace, monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/* Text-level semantics\n ========================================================================== */\n\n/**\n * Remove the gray background on active links in IE 10.\n */\n\na {\n background-color: transparent;\n}\n\n/**\n * 1. Remove the bottom border in Chrome 57-\n * 2. Add the correct text decoration in Chrome, Edge, IE, Opera, and Safari.\n */\n\nabbr[title] {\n border-bottom: none; /* 1 */\n text-decoration: underline; /* 2 */\n text-decoration: underline dotted; /* 2 */\n}\n\n/**\n * Add the correct font weight in Chrome, Edge, and Safari.\n */\n\nb,\nstrong {\n font-weight: bolder;\n}\n\n/**\n * 1. Correct the inheritance and scaling of font size in all browsers.\n * 2. Correct the odd `em` font sizing in all browsers.\n */\n\ncode,\nkbd,\nsamp {\n font-family: monospace, monospace; /* 1 */\n font-size: 1em; /* 2 */\n}\n\n/**\n * Add the correct font size in all browsers.\n */\n\nsmall {\n font-size: 80%;\n}\n\n/**\n * Prevent `sub` and `sup` elements from affecting the line height in\n * all browsers.\n */\n\nsub,\nsup {\n font-size: 75%;\n line-height: 0;\n position: relative;\n vertical-align: baseline;\n}\n\nsub {\n bottom: -0.25em;\n}\n\nsup {\n top: -0.5em;\n}\n\n/* Embedded content\n ========================================================================== */\n\n/**\n * Remove the border on images inside links in IE 10.\n */\n\nimg {\n border-style: none;\n}\n\n/* Forms\n ========================================================================== */\n\n/**\n * 1. Change the font styles in all browsers.\n * 2. Remove the margin in Firefox and Safari.\n */\n\nbutton,\ninput,\noptgroup,\nselect,\ntextarea {\n font-family: inherit; /* 1 */\n font-size: 100%; /* 1 */\n line-height: 1.15; /* 1 */\n margin: 0; /* 2 */\n}\n\n/**\n * Show the overflow in IE.\n * 1. Show the overflow in Edge.\n */\n\nbutton,\ninput { /* 1 */\n overflow: visible;\n}\n\n/**\n * Remove the inheritance of text transform in Edge, Firefox, and IE.\n * 1. Remove the inheritance of text transform in Firefox.\n */\n\nbutton,\nselect { /* 1 */\n text-transform: none;\n}\n\n/**\n * Correct the inability to style clickable types in iOS and Safari.\n */\n\nbutton,\n[type=\"button\"],\n[type=\"reset\"],\n[type=\"submit\"] {\n -webkit-appearance: button;\n}\n\n/**\n * Remove the inner border and padding in Firefox.\n */\n\nbutton::-moz-focus-inner,\n[type=\"button\"]::-moz-focus-inner,\n[type=\"reset\"]::-moz-focus-inner,\n[type=\"submit\"]::-moz-focus-inner {\n border-style: none;\n padding: 0;\n}\n\n/**\n * Restore the focus styles unset by the previous rule.\n */\n\nbutton:-moz-focusring,\n[type=\"button\"]:-moz-focusring,\n[type=\"reset\"]:-moz-focusring,\n[type=\"submit\"]:-moz-focusring {\n outline: 1px dotted ButtonText;\n}\n\n/**\n * Correct the padding in Firefox.\n */\n\nfieldset {\n padding: 0.35em 0.75em 0.625em;\n}\n\n/**\n * 1. Correct the text wrapping in Edge and IE.\n * 2. Correct the color inheritance from `fieldset` elements in IE.\n * 3. Remove the padding so developers are not caught out when they zero out\n * `fieldset` elements in all browsers.\n */\n\nlegend {\n box-sizing: border-box; /* 1 */\n color: inherit; /* 2 */\n display: table; /* 1 */\n max-width: 100%; /* 1 */\n padding: 0; /* 3 */\n white-space: normal; /* 1 */\n}\n\n/**\n * Add the correct vertical alignment in Chrome, Firefox, and Opera.\n */\n\nprogress {\n vertical-align: baseline;\n}\n\n/**\n * Remove the default vertical scrollbar in IE 10+.\n */\n\ntextarea {\n overflow: auto;\n}\n\n/**\n * 1. Add the correct box sizing in IE 10.\n * 2. Remove the padding in IE 10.\n */\n\n[type=\"checkbox\"],\n[type=\"radio\"] {\n box-sizing: border-box; /* 1 */\n padding: 0; /* 2 */\n}\n\n/**\n * Correct the cursor style of increment and decrement buttons in Chrome.\n */\n\n[type=\"number\"]::-webkit-inner-spin-button,\n[type=\"number\"]::-webkit-outer-spin-button {\n height: auto;\n}\n\n/**\n * 1. Correct the odd appearance in Chrome and Safari.\n * 2. Correct the outline style in Safari.\n */\n\n[type=\"search\"] {\n -webkit-appearance: textfield; /* 1 */\n outline-offset: -2px; /* 2 */\n}\n\n/**\n * Remove the inner padding in Chrome and Safari on macOS.\n */\n\n[type=\"search\"]::-webkit-search-decoration {\n -webkit-appearance: none;\n}\n\n/**\n * 1. Correct the inability to style clickable types in iOS and Safari.\n * 2. Change font properties to `inherit` in Safari.\n */\n\n::-webkit-file-upload-button {\n -webkit-appearance: button; /* 1 */\n font: inherit; /* 2 */\n}\n\n/* Interactive\n ========================================================================== */\n\n/*\n * Add the correct display in Edge, IE 10+, and Firefox.\n */\n\ndetails {\n display: block;\n}\n\n/*\n * Add the correct display in all browsers.\n */\n\nsummary {\n display: list-item;\n}\n\n/* Misc\n ========================================================================== */\n\n/**\n * Add the correct display in IE 10+.\n */\n\ntemplate {\n display: none;\n}\n\n/**\n * Add the correct display in IE 10.\n */\n\n[hidden] {\n display: none;\n}\n","// This file contains styles for managing print media.\n\n////////////////////////////////////////////////////////////////////////////////\n// Hide elements not relevant to print media.\n////////////////////////////////////////////////////////////////////////////////\n@media print\n // Hide icon container.\n .content-icon-container\n display: none !important\n\n // Hide showing header links if hovering over when printing.\n .headerlink\n display: none !important\n\n // Hide mobile header.\n .mobile-header\n display: none !important\n\n // Hide navigation links.\n .related-pages\n display: none !important\n\n////////////////////////////////////////////////////////////////////////////////\n// Tweaks related to decolorization.\n////////////////////////////////////////////////////////////////////////////////\n@media print\n // Apply a border around code which no longer have a color background.\n .highlight\n border: 0.1pt solid var(--color-foreground-border)\n\n////////////////////////////////////////////////////////////////////////////////\n// Avoid page break in some relevant cases.\n////////////////////////////////////////////////////////////////////////////////\n@media print\n ul, ol, dl, a, table, pre, blockquote\n page-break-inside: avoid\n\n h1, h2, h3, h4, h5, h6, img, figure, caption\n page-break-inside: avoid\n page-break-after: avoid\n\n ul, ol, dl\n page-break-before: avoid\n",".visually-hidden\n position: absolute !important\n width: 1px !important\n height: 1px !important\n padding: 0 !important\n margin: -1px !important\n overflow: hidden !important\n clip: rect(0,0,0,0) !important\n white-space: nowrap !important\n border: 0 !important\n\n:-moz-focusring\n outline: auto\n","// This file serves as the \"skeleton\" of the theming logic.\n//\n// This contains the bulk of the logic for handling dark mode, color scheme\n// toggling and the handling of color-scheme-specific hiding of elements.\n\nbody\n @include fonts\n @include spacing\n @include icons\n @include admonitions\n @include default-admonition(#651fff, \"abstract\")\n @include default-topic(#14B8A6, \"pencil\")\n\n @include colors\n\n.only-light\n display: block !important\nhtml body .only-dark\n display: none !important\n\n// Ignore dark-mode hints if print media.\n@media not print\n // Enable dark-mode, if requested.\n body[data-theme=\"dark\"]\n @include colors-dark\n\n html & .only-light\n display: none !important\n .only-dark\n display: block !important\n\n // Enable dark mode, unless explicitly told to avoid.\n @media (prefers-color-scheme: dark)\n body:not([data-theme=\"light\"])\n @include colors-dark\n\n html & .only-light\n display: none !important\n .only-dark\n display: block !important\n\n//\n// Theme toggle presentation\n//\nbody[data-theme=\"auto\"]\n .theme-toggle svg.theme-icon-when-auto\n display: block\n\nbody[data-theme=\"dark\"]\n .theme-toggle svg.theme-icon-when-dark\n display: block\n\nbody[data-theme=\"light\"]\n .theme-toggle svg.theme-icon-when-light\n display: block\n","// Fonts used by this theme.\n//\n// There are basically two things here -- using the system font stack and\n// defining sizes for various elements in %ages. We could have also used `em`\n// but %age is easier to reason about for me.\n\n@mixin fonts {\n // These are adapted from https://systemfontstack.com/\n --font-stack: -apple-system, BlinkMacSystemFont, Segoe UI, Helvetica, Arial,\n sans-serif, Apple Color Emoji, Segoe UI Emoji;\n --font-stack--monospace: \"SFMono-Regular\", Menlo, Consolas, Monaco,\n Liberation Mono, Lucida Console, monospace;\n\n --font-size--normal: 100%;\n --font-size--small: 87.5%;\n --font-size--small--2: 81.25%;\n --font-size--small--3: 75%;\n --font-size--small--4: 62.5%;\n\n // Sidebar\n --sidebar-caption-font-size: var(--font-size--small--2);\n --sidebar-item-font-size: var(--font-size--small);\n --sidebar-search-input-font-size: var(--font-size--small);\n\n // Table of Contents\n --toc-font-size: var(--font-size--small--3);\n --toc-font-size--mobile: var(--font-size--normal);\n --toc-title-font-size: var(--font-size--small--4);\n\n // Admonitions\n //\n // These aren't defined in terms of %ages, since nesting these is permitted.\n --admonition-font-size: 0.8125rem;\n --admonition-title-font-size: 0.8125rem;\n\n // Code\n --code-font-size: var(--font-size--small--2);\n\n // API\n --api-font-size: var(--font-size--small);\n}\n","// Spacing for various elements on the page\n//\n// If the user wants to tweak things in a certain way, they are permitted to.\n// They also have to deal with the consequences though!\n\n@mixin spacing {\n // Header!\n --header-height: calc(\n var(--sidebar-item-line-height) + 4 * #{var(--sidebar-item-spacing-vertical)}\n );\n --header-padding: 0.5rem;\n\n // Sidebar\n --sidebar-tree-space-above: 1.5rem;\n --sidebar-caption-space-above: 1rem;\n\n --sidebar-item-line-height: 1rem;\n --sidebar-item-spacing-vertical: 0.5rem;\n --sidebar-item-spacing-horizontal: 1rem;\n --sidebar-item-height: calc(\n var(--sidebar-item-line-height) + 2 *#{var(--sidebar-item-spacing-vertical)}\n );\n\n --sidebar-expander-width: var(--sidebar-item-height); // be square\n\n --sidebar-search-space-above: 0.5rem;\n --sidebar-search-input-spacing-vertical: 0.5rem;\n --sidebar-search-input-spacing-horizontal: 0.5rem;\n --sidebar-search-input-height: 1rem;\n --sidebar-search-icon-size: var(--sidebar-search-input-height);\n\n // Table of Contents\n --toc-title-padding: 0.25rem 0;\n --toc-spacing-vertical: 1.5rem;\n --toc-spacing-horizontal: 1.5rem;\n --toc-item-spacing-vertical: 0.4rem;\n --toc-item-spacing-horizontal: 1rem;\n}\n","// Expose theme icons as CSS variables.\n\n$icons: (\n // Adapted from tabler-icons\n // url: https://tablericons.com/\n \"search\":\n url('data:image/svg+xml;charset=utf-8,'),\n // Factored out from mkdocs-material on 24-Aug-2020.\n // url: https://squidfunk.github.io/mkdocs-material/reference/admonitions/\n \"pencil\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"abstract\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"info\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"flame\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"question\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"warning\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"failure\":\n url('data:image/svg+xml;charset=utf-8,'),\n \"spark\":\n url('data:image/svg+xml;charset=utf-8,')\n);\n\n@mixin icons {\n @each $name, $glyph in $icons {\n --icon-#{$name}: #{$glyph};\n }\n}\n","// Admonitions\n\n// Structure of these is:\n// admonition-class: color \"icon-name\";\n//\n// The colors are translated into CSS variables below. The icons are\n// used directly in the main declarations to set the `mask-image` in\n// the title.\n\n// prettier-ignore\n$admonitions: (\n // Each of these has an reST directives for it.\n \"caution\": #ff9100 \"spark\",\n \"warning\": #ff9100 \"warning\",\n \"danger\": #ff5252 \"spark\",\n \"attention\": #ff5252 \"warning\",\n \"error\": #ff5252 \"failure\",\n \"hint\": #00c852 \"question\",\n \"tip\": #00c852 \"info\",\n \"important\": #00bfa5 \"flame\",\n \"note\": #00b0ff \"pencil\",\n \"seealso\": #448aff \"info\",\n \"admonition-todo\": #808080 \"pencil\"\n);\n\n@mixin default-admonition($color, $icon-name) {\n --color-admonition-title: #{$color};\n --color-admonition-title-background: #{rgba($color, 0.2)};\n\n --icon-admonition-default: var(--icon-#{$icon-name});\n}\n\n@mixin default-topic($color, $icon-name) {\n --color-topic-title: #{$color};\n --color-topic-title-background: #{rgba($color, 0.2)};\n\n --icon-topic-default: var(--icon-#{$icon-name});\n}\n\n@mixin admonitions {\n @each $name, $values in $admonitions {\n --color-admonition-title--#{$name}: #{nth($values, 1)};\n --color-admonition-title-background--#{$name}: #{rgba(\n nth($values, 1),\n 0.2\n )};\n }\n}\n","// Colors used throughout this theme.\n//\n// The aim is to give the user more control. Thus, instead of hard-coding colors\n// in various parts of the stylesheet, the approach taken is to define all\n// colors as CSS variables and reusing them in all the places.\n//\n// `colors-dark` depends on `colors` being included at a lower specificity.\n\n@mixin colors {\n --color-problematic: #b30000;\n\n // Base Colors\n --color-foreground-primary: black; // for main text and headings\n --color-foreground-secondary: #5a5c63; // for secondary text\n --color-foreground-muted: #646776; // for muted text\n --color-foreground-border: #878787; // for content borders\n\n --color-background-primary: white; // for content\n --color-background-secondary: #f8f9fb; // for navigation + ToC\n --color-background-hover: #efeff4ff; // for navigation-item hover\n --color-background-hover--transparent: #efeff400;\n --color-background-border: #eeebee; // for UI borders\n --color-background-item: #ccc; // for \"background\" items (eg: copybutton)\n\n // Announcements\n --color-announcement-background: #000000dd;\n --color-announcement-text: #eeebee;\n\n // Brand colors\n --color-brand-primary: #2962ff;\n --color-brand-content: #2a5adf;\n\n // API documentation\n --color-api-background: var(--color-background-hover--transparent);\n --color-api-background-hover: var(--color-background-hover);\n --color-api-overall: var(--color-foreground-secondary);\n --color-api-name: var(--color-problematic);\n --color-api-pre-name: var(--color-problematic);\n --color-api-paren: var(--color-foreground-secondary);\n --color-api-keyword: var(--color-foreground-primary);\n --color-highlight-on-target: #ffffcc;\n\n // Inline code background\n --color-inline-code-background: var(--color-background-secondary);\n\n // Highlighted text (search)\n --color-highlighted-background: #ddeeff;\n --color-highlighted-text: var(--color-foreground-primary);\n\n // GUI Labels\n --color-guilabel-background: #ddeeff80;\n --color-guilabel-border: #bedaf580;\n --color-guilabel-text: var(--color-foreground-primary);\n\n // Admonitions!\n --color-admonition-background: transparent;\n\n //////////////////////////////////////////////////////////////////////////////\n // Everything below this should be one of:\n // - var(...)\n // - *-gradient(...)\n // - special literal values (eg: transparent, none)\n //////////////////////////////////////////////////////////////////////////////\n\n // Tables\n --color-table-header-background: var(--color-background-secondary);\n --color-table-border: var(--color-background-border);\n\n // Cards\n --color-card-border: var(--color-background-secondary);\n --color-card-background: transparent;\n --color-card-marginals-background: var(--color-background-secondary);\n\n // Header\n --color-header-background: var(--color-background-primary);\n --color-header-border: var(--color-background-border);\n --color-header-text: var(--color-foreground-primary);\n\n // Sidebar (left)\n --color-sidebar-background: var(--color-background-secondary);\n --color-sidebar-background-border: var(--color-background-border);\n\n --color-sidebar-brand-text: var(--color-foreground-primary);\n --color-sidebar-caption-text: var(--color-foreground-muted);\n --color-sidebar-link-text: var(--color-foreground-secondary);\n --color-sidebar-link-text--top-level: var(--color-brand-primary);\n\n --color-sidebar-item-background: var(--color-sidebar-background);\n --color-sidebar-item-background--current: var(\n --color-sidebar-item-background\n );\n --color-sidebar-item-background--hover: linear-gradient(\n 90deg,\n var(--color-background-hover--transparent) 0%,\n var(--color-background-hover) var(--sidebar-item-spacing-horizontal),\n var(--color-background-hover) 100%\n );\n\n --color-sidebar-item-expander-background: transparent;\n --color-sidebar-item-expander-background--hover: var(\n --color-background-hover\n );\n\n --color-sidebar-search-text: var(--color-foreground-primary);\n --color-sidebar-search-background: var(--color-background-secondary);\n --color-sidebar-search-background--focus: var(--color-background-primary);\n --color-sidebar-search-border: var(--color-background-border);\n --color-sidebar-search-icon: var(--color-foreground-muted);\n\n // Table of Contents (right)\n --color-toc-background: var(--color-background-primary);\n --color-toc-title-text: var(--color-foreground-muted);\n --color-toc-item-text: var(--color-foreground-secondary);\n --color-toc-item-text--hover: var(--color-foreground-primary);\n --color-toc-item-text--active: var(--color-brand-primary);\n\n // Actual page contents\n --color-content-foreground: var(--color-foreground-primary);\n --color-content-background: transparent;\n\n // Links\n --color-link: var(--color-brand-content);\n --color-link--hover: var(--color-brand-content);\n --color-link-underline: var(--color-background-border);\n --color-link-underline--hover: var(--color-foreground-border);\n}\n\n@mixin colors-dark {\n --color-problematic: #ee5151;\n\n // Base Colors\n --color-foreground-primary: #ffffffcc; // for main text and headings\n --color-foreground-secondary: #9ca0a5; // for secondary text\n --color-foreground-muted: #81868d; // for muted text\n --color-foreground-border: #666666; // for content borders\n\n --color-background-primary: #131416; // for content\n --color-background-secondary: #1a1c1e; // for navigation + ToC\n --color-background-hover: #1e2124ff; // for navigation-item hover\n --color-background-hover--transparent: #1e212400;\n --color-background-border: #303335; // for UI borders\n --color-background-item: #444; // for \"background\" items (eg: copybutton)\n\n // Announcements\n --color-announcement-background: #000000dd;\n --color-announcement-text: #eeebee;\n\n // Brand colors\n --color-brand-primary: #2b8cee;\n --color-brand-content: #368ce2;\n\n // Highlighted text (search)\n --color-highlighted-background: #083563;\n\n // GUI Labels\n --color-guilabel-background: #08356380;\n --color-guilabel-border: #13395f80;\n\n // API documentation\n --color-api-keyword: var(--color-foreground-secondary);\n --color-highlight-on-target: #333300;\n\n // Admonitions\n --color-admonition-background: #18181a;\n\n // Cards\n --color-card-border: var(--color-background-secondary);\n --color-card-background: #18181a;\n --color-card-marginals-background: var(--color-background-hover);\n}\n","// This file contains the styling for making the content throughout the page,\n// including fonts, paragraphs, headings and spacing among these elements.\n\nbody\n font-family: var(--font-stack)\npre,\ncode,\nkbd,\nsamp\n font-family: var(--font-stack--monospace)\n\n// Make fonts look slightly nicer.\nbody\n -webkit-font-smoothing: antialiased\n -moz-osx-font-smoothing: grayscale\n\n// Line height from Bootstrap 4.1\narticle\n line-height: 1.5\n\n//\n// Headings\n//\nh1,\nh2,\nh3,\nh4,\nh5,\nh6\n line-height: 1.25\n font-weight: bold\n\n border-radius: 0.5rem\n margin-top: 0.5rem\n margin-bottom: 0.5rem\n margin-left: -0.5rem\n margin-right: -0.5rem\n padding-left: 0.5rem\n padding-right: 0.5rem\n\n + p\n margin-top: 0\n\nh1\n font-size: 2.5em\n margin-top: 1.75rem\n margin-bottom: 1rem\nh2\n font-size: 2em\n margin-top: 1.75rem\nh3\n font-size: 1.5em\nh4\n font-size: 1.25em\nh5\n font-size: 1.125em\nh6\n font-size: 1em\n\nsmall\n opacity: 75%\n font-size: 80%\n\n// Paragraph\np\n margin-top: 0.5rem\n margin-bottom: 0.75rem\n\n// Horizontal rules\nhr.docutils\n height: 1px\n padding: 0\n margin: 2rem 0\n background-color: var(--color-background-border)\n border: 0\n\n.centered\n text-align: center\n\n// Links\na\n text-decoration: underline\n\n color: var(--color-link)\n text-decoration-color: var(--color-link-underline)\n\n &:hover\n color: var(--color-link--hover)\n text-decoration-color: var(--color-link-underline--hover)\n &.muted-link\n color: inherit\n &:hover\n color: var(--color-link)\n text-decoration-color: var(--color-link-underline--hover)\n","// This file contains the styles for the overall layouting of the documentation\n// skeleton, including the responsive changes as well as sidebar toggles.\n//\n// This is implemented as a mobile-last design, which isn't ideal, but it is\n// reasonably good-enough and I got pretty tired by the time I'd finished this\n// to move the rules around to fix this. Shouldn't take more than 3-4 hours,\n// if you know what you're doing tho.\n\n// HACK: Not all browsers account for the scrollbar width in media queries.\n// This results in horizontal scrollbars in the breakpoint where we go\n// from displaying everything to hiding the ToC. We accomodate for this by\n// adding a bit of padding to the TOC drawer, disabling the horizontal\n// scrollbar and allowing the scrollbars to cover the padding.\n// https://www.456bereastreet.com/archive/201301/media_query_width_and_vertical_scrollbars/\n\n// HACK: Always having the scrollbar visible, prevents certain browsers from\n// causing the content to stutter horizontally between taller-than-viewport and\n// not-taller-than-viewport pages.\n\nhtml\n overflow-x: hidden\n overflow-y: scroll\n scroll-behavior: smooth\n\n.sidebar-scroll, .toc-scroll, article[role=main] *\n // Override Firefox scrollbar style\n scrollbar-width: thin\n scrollbar-color: var(--color-foreground-border) transparent\n\n // Override Chrome scrollbar styles\n &::-webkit-scrollbar\n width: 0.25rem\n height: 0.25rem\n &::-webkit-scrollbar-thumb\n background-color: var(--color-foreground-border)\n border-radius: 0.125rem\n\n//\n// Overalls\n//\nhtml,\nbody\n height: 100%\n color: var(--color-foreground-primary)\n background: var(--color-background-primary)\n\narticle\n color: var(--color-content-foreground)\n background: var(--color-content-background)\n\n.page\n display: flex\n // fill the viewport for pages with little content.\n min-height: 100%\n\n.mobile-header\n width: 100%\n height: var(--header-height)\n background-color: var(--color-header-background)\n color: var(--color-header-text)\n border-bottom: 1px solid var(--color-header-border)\n\n // Looks like sub-script/super-script have this, and we need this to\n // be \"on top\" of those.\n z-index: 10\n\n // We don't show the header on large screens.\n display: none\n\n // Add shadow when scrolled\n &.scrolled\n border-bottom: none\n box-shadow: 0 0 0.2rem rgba(0, 0, 0, 0.1), 0 0.2rem 0.4rem rgba(0, 0, 0, 0.2)\n\n .header-center\n a\n color: var(--color-header-text)\n text-decoration: none\n\n.main\n display: flex\n flex: 1\n\n// Sidebar (left) also covers the entire left portion of screen.\n.sidebar-drawer\n box-sizing: border-box\n\n border-right: 1px solid var(--color-sidebar-background-border)\n background: var(--color-sidebar-background)\n\n display: flex\n justify-content: flex-end\n // These next two lines took me two days to figure out.\n width: calc((100% - #{$full-width}) / 2 + #{$sidebar-width})\n min-width: $sidebar-width\n\n// Scroll-along sidebars\n.sidebar-container,\n.toc-drawer\n box-sizing: border-box\n width: $sidebar-width\n\n.toc-drawer\n background: var(--color-toc-background)\n // See HACK described on top of this document\n padding-right: 1rem\n\n.sidebar-sticky,\n.toc-sticky\n position: sticky\n top: 0\n height: min(100%, 100vh)\n height: 100vh\n\n display: flex\n flex-direction: column\n\n.sidebar-scroll,\n.toc-scroll\n flex-grow: 1\n flex-shrink: 1\n\n overflow: auto\n scroll-behavior: smooth\n\n// Central items.\n.content\n padding: 0 $content-padding\n width: $content-width\n\n display: flex\n flex-direction: column\n justify-content: space-between\n\n.icon\n display: inline-block\n height: 1rem\n width: 1rem\n svg\n width: 100%\n height: 100%\n\n//\n// Accommodate announcement banner\n//\n.announcement\n background-color: var(--color-announcement-background)\n color: var(--color-announcement-text)\n\n height: var(--header-height)\n display: flex\n align-items: center\n overflow-x: auto\n & + .page\n min-height: calc(100% - var(--header-height))\n\n.announcement-content\n box-sizing: border-box\n padding: 0.5rem\n min-width: 100%\n white-space: nowrap\n text-align: center\n\n a\n color: var(--color-announcement-text)\n text-decoration-color: var(--color-announcement-text)\n\n &:hover\n color: var(--color-announcement-text)\n text-decoration-color: var(--color-link--hover)\n\n////////////////////////////////////////////////////////////////////////////////\n// Toggles for theme\n////////////////////////////////////////////////////////////////////////////////\n.no-js .theme-toggle-container // don't show theme toggle if there's no JS\n display: none\n\n.theme-toggle-container\n vertical-align: middle\n\n.theme-toggle\n cursor: pointer\n border: none\n padding: 0\n background: transparent\n\n.theme-toggle svg\n vertical-align: middle\n height: 1rem\n width: 1rem\n color: var(--color-foreground-primary)\n display: none\n\n.theme-toggle-header\n float: left\n padding: 1rem 0.5rem\n\n////////////////////////////////////////////////////////////////////////////////\n// Toggles for elements\n////////////////////////////////////////////////////////////////////////////////\n.toc-overlay-icon, .nav-overlay-icon\n display: none\n cursor: pointer\n\n .icon\n color: var(--color-foreground-secondary)\n height: 1rem\n width: 1rem\n\n.toc-header-icon, .nav-overlay-icon\n // for when we set display: flex\n justify-content: center\n align-items: center\n\n.toc-content-icon\n height: 1.5rem\n width: 1.5rem\n\n.content-icon-container\n float: right\n display: flex\n margin-top: 1.5rem\n margin-left: 1rem\n margin-bottom: 1rem\n gap: 0.5rem\n\n .edit-this-page svg\n color: inherit\n height: 1rem\n width: 1rem\n\n.sidebar-toggle\n position: absolute\n display: none\n// \n.sidebar-toggle[name=\"__toc\"]\n left: 20px\n.sidebar-toggle:checked\n left: 40px\n// \n\n.overlay\n position: fixed\n top: 0\n width: 0\n height: 0\n\n transition: width 0ms, height 0ms, opacity 250ms ease-out\n\n opacity: 0\n background-color: rgba(0, 0, 0, 0.54)\n.sidebar-overlay\n z-index: 20\n.toc-overlay\n z-index: 40\n\n// Keep things on top and smooth.\n.sidebar-drawer\n z-index: 30\n transition: left 250ms ease-in-out\n.toc-drawer\n z-index: 50\n transition: right 250ms ease-in-out\n\n// Show the Sidebar\n#__navigation:checked\n & ~ .sidebar-overlay\n width: 100%\n height: 100%\n opacity: 1\n & ~ .page\n .sidebar-drawer\n top: 0\n left: 0\n // Show the toc sidebar\n#__toc:checked\n & ~ .toc-overlay\n width: 100%\n height: 100%\n opacity: 1\n & ~ .page\n .toc-drawer\n top: 0\n right: 0\n\n////////////////////////////////////////////////////////////////////////////////\n// Back to top\n////////////////////////////////////////////////////////////////////////////////\n.back-to-top\n text-decoration: none\n\n display: none\n position: fixed\n left: 0\n top: 1rem\n padding: 0.5rem\n padding-right: 0.75rem\n border-radius: 1rem\n font-size: 0.8125rem\n\n background: var(--color-background-primary)\n box-shadow: 0 0.2rem 0.5rem rgba(0, 0, 0, 0.05), #6b728080 0px 0px 1px 0px\n\n z-index: 10\n\n margin-left: 50%\n transform: translateX(-50%)\n svg\n height: 1rem\n width: 1rem\n fill: currentColor\n display: inline-block\n\n span\n margin-left: 0.25rem\n\n .show-back-to-top &\n display: flex\n align-items: center\n\n////////////////////////////////////////////////////////////////////////////////\n// Responsive layouting\n////////////////////////////////////////////////////////////////////////////////\n// Make things a bit bigger on bigger screens.\n@media (min-width: $full-width + $sidebar-width)\n html\n font-size: 110%\n\n@media (max-width: $full-width)\n // Collapse \"toc\" into the icon.\n .toc-content-icon\n display: flex\n .toc-drawer\n position: fixed\n height: 100vh\n top: 0\n right: -$sidebar-width\n border-left: 1px solid var(--color-background-muted)\n .toc-tree\n border-left: none\n font-size: var(--toc-font-size--mobile)\n\n // Accomodate for a changed content width.\n .sidebar-drawer\n width: calc((100% - #{$full-width - $sidebar-width}) / 2 + #{$sidebar-width})\n\n@media (max-width: $full-width - $sidebar-width)\n // Collapse \"navigation\".\n .nav-overlay-icon\n display: flex\n .sidebar-drawer\n position: fixed\n height: 100vh\n width: $sidebar-width\n\n top: 0\n left: -$sidebar-width\n\n // Swap which icon is visible.\n .toc-header-icon\n display: flex\n .toc-content-icon, .theme-toggle-content\n display: none\n .theme-toggle-header\n display: block\n\n // Show the header.\n .mobile-header\n position: sticky\n top: 0\n display: flex\n justify-content: space-between\n align-items: center\n\n .header-left,\n .header-right\n display: flex\n height: var(--header-height)\n padding: 0 var(--header-padding)\n label\n height: 100%\n width: 100%\n user-select: none\n\n .nav-overlay-icon .icon,\n .theme-toggle svg\n height: 1.25rem\n width: 1.25rem\n\n // Add a scroll margin for the content\n :target\n scroll-margin-top: var(--header-height)\n\n // Show back-to-top below the header\n .back-to-top\n top: calc(var(--header-height) + 0.5rem)\n\n // Center the page, and accommodate for the header.\n .page\n flex-direction: column\n justify-content: center\n .content\n margin-left: auto\n margin-right: auto\n\n@media (max-width: $content-width + 2* $content-padding)\n // Content should respect window limits.\n .content\n width: 100%\n overflow-x: auto\n\n@media (max-width: $content-width)\n .content\n padding: 0 $content-padding--small\n // Don't float sidebars to the right.\n article aside.sidebar\n float: none\n width: 100%\n margin: 1rem 0\n","//\n// The design here is strongly inspired by mkdocs-material.\n.admonition, .topic\n margin: 1rem auto\n padding: 0 0.5rem 0.5rem 0.5rem\n\n background: var(--color-admonition-background)\n\n border-radius: 0.2rem\n box-shadow: 0 0.2rem 0.5rem rgba(0, 0, 0, 0.05), 0 0 0.0625rem rgba(0, 0, 0, 0.1)\n\n font-size: var(--admonition-font-size)\n\n overflow: hidden\n page-break-inside: avoid\n\n // First element should have no margin, since the title has it.\n > :nth-child(2)\n margin-top: 0\n\n // Last item should have no margin, since we'll control that w/ padding\n > :last-child\n margin-bottom: 0\n\np.admonition-title, p.topic-title\n position: relative\n margin: 0 -0.5rem 0.5rem\n padding-left: 2rem\n padding-right: .5rem\n padding-top: .4rem\n padding-bottom: .4rem\n\n font-weight: 500\n font-size: var(--admonition-title-font-size)\n line-height: 1.3\n\n // Our fancy icon\n &::before\n content: \"\"\n position: absolute\n left: 0.5rem\n width: 1rem\n height: 1rem\n\n// Default styles\np.admonition-title\n background-color: var(--color-admonition-title-background)\n &::before\n background-color: var(--color-admonition-title)\n mask-image: var(--icon-admonition-default)\n mask-repeat: no-repeat\n\np.topic-title\n background-color: var(--color-topic-title-background)\n &::before\n background-color: var(--color-topic-title)\n mask-image: var(--icon-topic-default)\n mask-repeat: no-repeat\n\n//\n// Variants\n//\n.admonition\n border-left: 0.2rem solid var(--color-admonition-title)\n\n @each $type, $value in $admonitions\n &.#{$type}\n border-left-color: var(--color-admonition-title--#{$type})\n > .admonition-title\n background-color: var(--color-admonition-title-background--#{$type})\n &::before\n background-color: var(--color-admonition-title--#{$type})\n mask-image: var(--icon-#{nth($value, 2)})\n\n.admonition-todo > .admonition-title\n text-transform: uppercase\n","// This file stylizes the API documentation (stuff generated by autodoc). It's\n// deeply nested due to how autodoc structures the HTML without enough classes\n// to select the relevant items.\n\n// API docs!\ndl[class]:not(.option-list):not(.field-list):not(.footnote):not(.glossary):not(.simple)\n // Tweak the spacing of all the things!\n dd\n margin-left: 2rem\n > :first-child\n margin-top: 0.125rem\n > :last-child\n margin-bottom: 0.75rem\n\n // This is used for the arguments\n .field-list\n margin-bottom: 0.75rem\n\n // \"Headings\" (like \"Parameters\" and \"Return\")\n > dt\n text-transform: uppercase\n font-size: var(--font-size--small)\n\n dd:empty\n margin-bottom: 0.5rem\n dd > ul\n margin-left: -1.2rem\n > li\n > p:nth-child(2)\n margin-top: 0\n // When the last-empty-paragraph follows a paragraph, it doesn't need\n // to augument the existing spacing.\n > p + p:last-child:empty\n margin-top: 0\n margin-bottom: 0\n\n // Colorize the elements\n > dt\n color: var(--color-api-overall)\n\n.sig:not(.sig-inline)\n font-weight: bold\n\n font-size: var(--api-font-size)\n font-family: var(--font-stack--monospace)\n\n margin-left: -0.25rem\n margin-right: -0.25rem\n padding-top: 0.25rem\n padding-bottom: 0.25rem\n padding-right: 0.5rem\n\n // These are intentionally em, to properly match the font size.\n padding-left: 3em\n text-indent: -2.5em\n\n border-radius: 0.25rem\n\n background: var(--color-api-background)\n transition: background 100ms ease-out\n\n &:hover\n background: var(--color-api-background-hover)\n\n // adjust the size of the [source] link on the right.\n a.reference\n .viewcode-link\n font-weight: normal\n width: 3.5rem\n\n // Break words when they're too long\n span.pre\n overflow-wrap: anywhere\n\nem.property\n font-style: normal\n &:first-child\n color: var(--color-api-keyword)\n.sig-name\n color: var(--color-api-name)\n.sig-prename\n font-weight: normal\n color: var(--color-api-pre-name)\n.sig-paren\n color: var(--color-api-paren)\n.sig-param\n font-style: normal\n\n.versionmodified\n font-style: italic\ndiv.versionadded, div.versionchanged, div.deprecated\n p\n margin-top: 0.125rem\n margin-bottom: 0.125rem\n\n// Align the [docs] and [source] to the right.\n.viewcode-link, .viewcode-back\n float: right\n text-align: right\n",".line-block\n margin-top: 0.5rem\n margin-bottom: 0.75rem\n .line-block\n margin-top: 0rem\n margin-bottom: 0rem\n padding-left: 1rem\n","// Captions\narticle p.caption,\ntable > caption,\n.code-block-caption\n font-size: var(--font-size--small)\n text-align: center\n\n// Caption above a TOCTree\n.toctree-wrapper.compound\n .caption, :not(.caption) > .caption-text\n font-size: var(--font-size--small)\n text-transform: uppercase\n\n text-align: initial\n margin-bottom: 0\n\n > ul\n margin-top: 0\n margin-bottom: 0\n","// Inline code\ncode.literal, .sig-inline\n background: var(--color-inline-code-background)\n border-radius: 0.2em\n // Make the font smaller, and use padding to recover.\n font-size: var(--font-size--small--2)\n padding: 0.1em 0.2em\n\n overflow-wrap: break-word\n\n p &\n border: 1px solid var(--color-background-border)\n\n.sig-inline\n font-family: var(--font-stack--monospace)\n\n// Code and Literal Blocks\n$code-spacing-vertical: 0.625rem\n$code-spacing-horizontal: 0.875rem\n\n// Wraps every literal block + line numbers.\ndiv[class*=\" highlight-\"],\ndiv[class^=\"highlight-\"]\n margin: 1em 0\n display: flex\n\n .table-wrapper\n margin: 0\n padding: 0\n\npre\n margin: 0\n padding: 0\n overflow: auto\n\n // Needed to have more specificity than pygments' \"pre\" selector. :(\n article[role=\"main\"] .highlight &\n line-height: 1.5\n\n &.literal-block,\n .highlight &\n font-size: var(--code-font-size)\n padding: $code-spacing-vertical $code-spacing-horizontal\n\n // Make it look like all the other blocks.\n &.literal-block\n margin-top: 1rem\n margin-bottom: 1rem\n\n border-radius: 0.2rem\n background-color: var(--color-code-background)\n color: var(--color-code-foreground)\n\n// All code is always contained in this.\n.highlight\n width: 100%\n border-radius: 0.2rem\n\n // Make line numbers and prompts un-selectable.\n .gp, span.linenos\n user-select: none\n pointer-events: none\n\n // Expand the line-highlighting.\n .hll\n display: block\n margin-left: -$code-spacing-horizontal\n margin-right: -$code-spacing-horizontal\n padding-left: $code-spacing-horizontal\n padding-right: $code-spacing-horizontal\n\n/* Make code block captions be nicely integrated */\n.code-block-caption\n display: flex\n padding: $code-spacing-vertical $code-spacing-horizontal\n\n border-radius: 0.25rem\n border-bottom-left-radius: 0\n border-bottom-right-radius: 0\n font-weight: 300\n border-bottom: 1px solid\n\n background-color: var(--color-code-background)\n color: var(--color-code-foreground)\n border-color: var(--color-background-border)\n\n + div[class]\n margin-top: 0\n pre\n border-top-left-radius: 0\n border-top-right-radius: 0\n\n// When `html_codeblock_linenos_style` is table.\n.highlighttable\n width: 100%\n display: block\n tbody\n display: block\n\n tr\n display: flex\n\n // Line numbers\n td.linenos\n background-color: var(--color-code-background)\n color: var(--color-code-foreground)\n padding: $code-spacing-vertical $code-spacing-horizontal\n padding-right: 0\n border-top-left-radius: 0.2rem\n border-bottom-left-radius: 0.2rem\n\n .linenodiv\n padding-right: $code-spacing-horizontal\n font-size: var(--code-font-size)\n box-shadow: -0.0625rem 0 var(--color-foreground-border) inset\n\n // Actual code\n td.code\n padding: 0\n display: block\n flex: 1\n overflow: hidden\n\n .highlight\n border-top-left-radius: 0\n border-bottom-left-radius: 0\n\n// When `html_codeblock_linenos_style` is inline.\n.highlight\n span.linenos\n display: inline-block\n padding-left: 0\n padding-right: $code-spacing-horizontal\n margin-right: $code-spacing-horizontal\n box-shadow: -0.0625rem 0 var(--color-foreground-border) inset\n","// Inline Footnote Reference\n.footnote-reference\n font-size: var(--font-size--small--4)\n vertical-align: super\n\n// Definition list, listing the content of each note.\n// docutils <= 0.17\ndl.footnote.brackets\n font-size: var(--font-size--small)\n color: var(--color-foreground-secondary)\n\n display: grid\n grid-template-columns: max-content auto\n dt\n margin: 0\n > .fn-backref\n margin-left: 0.25rem\n\n &:after\n content: \":\"\n\n .brackets\n &:before\n content: \"[\"\n &:after\n content: \"]\"\n\n dd\n margin: 0\n padding: 0 1rem\n\n// docutils >= 0.18\naside.footnote\n font-size: var(--font-size--small)\n color: var(--color-foreground-secondary)\n\naside.footnote > span,\ndiv.citation > span\n float: left\n font-weight: 500\n padding-right: 0.25rem\n\naside.footnote > p,\ndiv.citation > p\n margin-left: 2rem\n","//\n// Figures\n//\nimg\n box-sizing: border-box\n max-width: 100%\n height: auto\n\narticle\n figure, .figure\n border-radius: 0.2rem\n\n margin: 0\n :last-child\n margin-bottom: 0\n\n .align-left\n float: left\n clear: left\n margin: 0 1rem 1rem\n\n .align-right\n float: right\n clear: right\n margin: 0 1rem 1rem\n\n .align-default,\n .align-center\n display: block\n text-align: center\n margin-left: auto\n margin-right: auto\n\n // WELL, table needs to be stylised like a table.\n table.align-default\n display: table\n text-align: initial\n",".genindex-jumpbox, .domainindex-jumpbox\n border-top: 1px solid var(--color-background-border)\n border-bottom: 1px solid var(--color-background-border)\n padding: 0.25rem\n\n.genindex-section, .domainindex-section\n h2\n margin-top: 0.75rem\n margin-bottom: 0.5rem\n ul\n margin-top: 0\n margin-bottom: 0\n","ul,\nol\n padding-left: 1.2rem\n\n // Space lists out like paragraphs\n margin-top: 1rem\n margin-bottom: 1rem\n // reduce margins within li.\n li\n > p:first-child\n margin-top: 0.25rem\n margin-bottom: 0.25rem\n\n > p:last-child\n margin-top: 0.25rem\n\n > ul,\n > ol\n margin-top: 0.5rem\n margin-bottom: 0.5rem\n\nol\n &.arabic\n list-style: decimal\n &.loweralpha\n list-style: lower-alpha\n &.upperalpha\n list-style: upper-alpha\n &.lowerroman\n list-style: lower-roman\n &.upperroman\n list-style: upper-roman\n\n// Don't space lists out when they're \"simple\" or in a `.. toctree::`\n.simple,\n.toctree-wrapper\n li\n > ul,\n > ol\n margin-top: 0\n margin-bottom: 0\n\n// Definition Lists\n.field-list,\n.option-list,\ndl:not([class]),\ndl.simple,\ndl.footnote,\ndl.glossary\n dt\n font-weight: 500\n margin-top: 0.25rem\n + dt\n margin-top: 0\n\n .classifier::before\n content: \":\"\n margin-left: 0.2rem\n margin-right: 0.2rem\n\n dd\n > p:first-child,\n ul\n margin-top: 0.125rem\n\n ul\n margin-bottom: 0.125rem\n",".math-wrapper\n width: 100%\n overflow-x: auto\n\ndiv.math\n position: relative\n text-align: center\n\n .headerlink,\n &:focus .headerlink\n display: none\n\n &:hover .headerlink\n display: inline-block\n\n span.eqno\n position: absolute\n right: 0.5rem\n top: 50%\n transform: translate(0, -50%)\n z-index: 1\n","// Abbreviations\nabbr[title]\n cursor: help\n\n// \"Problematic\" content, as identified by Sphinx\n.problematic\n color: var(--color-problematic)\n\n// Keyboard / Mouse \"instructions\"\nkbd:not(.compound)\n margin: 0 0.2rem\n padding: 0 0.2rem\n border-radius: 0.2rem\n border: 1px solid var(--color-foreground-border)\n color: var(--color-foreground-primary)\n vertical-align: text-bottom\n\n font-size: var(--font-size--small--3)\n display: inline-block\n\n box-shadow: 0 0.0625rem 0 rgba(0, 0, 0, 0.2), inset 0 0 0 0.125rem var(--color-background-primary)\n\n background-color: var(--color-background-secondary)\n\n// Blockquote\nblockquote\n border-left: 4px solid var(--color-background-border)\n background: var(--color-background-secondary)\n\n margin-left: 0\n margin-right: 0\n padding: 0.5rem 1rem\n\n .attribution\n font-weight: 600\n text-align: right\n\n &.pull-quote,\n &.highlights\n font-size: 1.25em\n\n &.epigraph,\n &.pull-quote\n border-left-width: 0\n border-radius: 0.5rem\n\n &.highlights\n border-left-width: 0\n background: transparent\n\n// Center align embedded-in-text images\np .reference img\n vertical-align: middle\n","p.rubric\n line-height: 1.25\n font-weight: bold\n font-size: 1.125em\n\n // For Numpy-style documentation that's got rubrics within it.\n // https://github.com/pradyunsg/furo/discussions/505\n dd &\n line-height: inherit\n font-weight: inherit\n\n font-size: var(--font-size--small)\n text-transform: uppercase\n","article .sidebar\n float: right\n clear: right\n width: 30%\n\n margin-left: 1rem\n margin-right: 0\n\n border-radius: 0.2rem\n background-color: var(--color-background-secondary)\n border: var(--color-background-border) 1px solid\n\n > *\n padding-left: 1rem\n padding-right: 1rem\n\n > ul, > ol // lists need additional padding, because bullets.\n padding-left: 2.2rem\n\n .sidebar-title\n margin: 0\n padding: 0.5rem 1rem\n border-bottom: var(--color-background-border) 1px solid\n\n font-weight: 500\n\n// TODO: subtitle\n// TODO: dedicated variables?\n",".table-wrapper\n width: 100%\n overflow-x: auto\n margin-top: 1rem\n margin-bottom: 0.5rem\n padding: 0.2rem 0.2rem 0.75rem\n\ntable.docutils\n border-radius: 0.2rem\n border-spacing: 0\n border-collapse: collapse\n\n box-shadow: 0 0.2rem 0.5rem rgba(0, 0, 0, 0.05), 0 0 0.0625rem rgba(0, 0, 0, 0.1)\n\n th\n background: var(--color-table-header-background)\n\n td,\n th\n // Space things out properly\n padding: 0 0.25rem\n\n // Get the borders looking just-right.\n border-left: 1px solid var(--color-table-border)\n border-right: 1px solid var(--color-table-border)\n border-bottom: 1px solid var(--color-table-border)\n\n p\n margin: 0.25rem\n\n &:first-child\n border-left: none\n &:last-child\n border-right: none\n\n // MyST-parser tables set these classes for control of column alignment\n &.text-left\n text-align: left\n &.text-right\n text-align: right\n &.text-center\n text-align: center\n",":target\n scroll-margin-top: 0.5rem\n\n@media (max-width: $full-width - $sidebar-width)\n :target\n scroll-margin-top: calc(0.5rem + var(--header-height))\n\n // When a heading is selected\n section > span:target\n scroll-margin-top: calc(0.8rem + var(--header-height))\n\n// Permalinks\n.headerlink\n font-weight: 100\n user-select: none\n\nh1,\nh2,\nh3,\nh4,\nh5,\nh6,\ndl dt,\np.caption,\nfigcaption p,\ntable > caption,\n.code-block-caption\n > .headerlink\n margin-left: 0.5rem\n visibility: hidden\n &:hover > .headerlink\n visibility: visible\n\n // Don't change to link-like, if someone adds the contents directive.\n > .toc-backref\n color: inherit\n text-decoration-line: none\n\n// Figure and table captions are special.\nfigure:hover > figcaption > p > .headerlink,\ntable:hover > caption > .headerlink\n visibility: visible\n\n:target >, // Regular section[id] style anchors\nspan:target ~ // Non-regular span[id] style \"extra\" anchors\n h1,\n h2,\n h3,\n h4,\n h5,\n h6\n &:nth-of-type(1)\n background-color: var(--color-highlight-on-target)\n // .headerlink\n // visibility: visible\n code.literal\n background-color: transparent\n\ntable:target > caption,\nfigure:target\n background-color: var(--color-highlight-on-target)\n\n// Inline page contents\n.this-will-duplicate-information-and-it-is-still-useful-here li :target\n background-color: var(--color-highlight-on-target)\n\n// Code block permalinks\n.literal-block-wrapper:target .code-block-caption\n background-color: var(--color-highlight-on-target)\n\n// When a definition list item is selected\n//\n// There isn't really an alternative to !important here, due to the\n// high-specificity of API documentation's selector.\ndt:target\n background-color: var(--color-highlight-on-target) !important\n\n// When a footnote reference is selected\n.footnote > dt:target + dd,\n.footnote-reference:target\n background-color: var(--color-highlight-on-target)\n",".guilabel\n background-color: var(--color-guilabel-background)\n border: 1px solid var(--color-guilabel-border)\n color: var(--color-guilabel-text)\n\n padding: 0 0.3em\n border-radius: 0.5em\n font-size: 0.9em\n","// This file contains the styles used for stylizing the footer that's shown\n// below the content.\n\nfooter\n font-size: var(--font-size--small)\n display: flex\n flex-direction: column\n\n margin-top: 2rem\n\n// Bottom of page information\n.bottom-of-page\n display: flex\n align-items: center\n justify-content: space-between\n\n margin-top: 1rem\n padding-top: 1rem\n padding-bottom: 1rem\n\n color: var(--color-foreground-secondary)\n border-top: 1px solid var(--color-background-border)\n\n line-height: 1.5\n\n @media (max-width: $content-width)\n text-align: center\n flex-direction: column-reverse\n gap: 0.25rem\n\n .left-details\n font-size: var(--font-size--small)\n\n .right-details\n display: flex\n flex-direction: column\n gap: 0.25rem\n text-align: right\n\n .icons\n display: flex\n justify-content: flex-end\n gap: 0.25rem\n font-size: 1rem\n\n a\n text-decoration: none\n\n svg,\n img\n font-size: 1.125rem\n height: 1em\n width: 1em\n\n// Next/Prev page information\n.related-pages\n a\n display: flex\n align-items: center\n\n text-decoration: none\n &:hover .page-info .title\n text-decoration: underline\n color: var(--color-link)\n text-decoration-color: var(--color-link-underline)\n\n svg.furo-related-icon,\n svg.furo-related-icon > use\n flex-shrink: 0\n\n color: var(--color-foreground-border)\n\n width: 0.75rem\n height: 0.75rem\n margin: 0 0.5rem\n\n &.next-page\n max-width: 50%\n\n float: right\n clear: right\n text-align: right\n\n &.prev-page\n max-width: 50%\n\n float: left\n clear: left\n\n svg\n transform: rotate(180deg)\n\n.page-info\n display: flex\n flex-direction: column\n overflow-wrap: anywhere\n\n .next-page &\n align-items: flex-end\n\n .context\n display: flex\n align-items: center\n\n padding-bottom: 0.1rem\n\n color: var(--color-foreground-muted)\n font-size: var(--font-size--small)\n text-decoration: none\n","// This file contains the styles for the contents of the left sidebar, which\n// contains the navigation tree, logo, search etc.\n\n////////////////////////////////////////////////////////////////////////////////\n// Brand on top of the scrollable tree.\n////////////////////////////////////////////////////////////////////////////////\n.sidebar-brand\n display: flex\n flex-direction: column\n flex-shrink: 0\n\n padding: var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal)\n text-decoration: none\n\n.sidebar-brand-text\n color: var(--color-sidebar-brand-text)\n overflow-wrap: break-word\n margin: var(--sidebar-item-spacing-vertical) 0\n font-size: 1.5rem\n\n.sidebar-logo-container\n margin: var(--sidebar-item-spacing-vertical) 0\n\n.sidebar-logo\n margin: 0 auto\n display: block\n max-width: 100%\n\n////////////////////////////////////////////////////////////////////////////////\n// Search\n////////////////////////////////////////////////////////////////////////////////\n.sidebar-search-container\n display: flex\n align-items: center\n margin-top: var(--sidebar-search-space-above)\n\n position: relative\n\n background: var(--color-sidebar-search-background)\n &:hover,\n &:focus-within\n background: var(--color-sidebar-search-background--focus)\n\n &::before\n content: \"\"\n position: absolute\n left: var(--sidebar-item-spacing-horizontal)\n width: var(--sidebar-search-icon-size)\n height: var(--sidebar-search-icon-size)\n\n background-color: var(--color-sidebar-search-icon)\n mask-image: var(--icon-search)\n\n.sidebar-search\n box-sizing: border-box\n\n border: none\n border-top: 1px solid var(--color-sidebar-search-border)\n border-bottom: 1px solid var(--color-sidebar-search-border)\n\n padding-top: var(--sidebar-search-input-spacing-vertical)\n padding-bottom: var(--sidebar-search-input-spacing-vertical)\n padding-right: var(--sidebar-search-input-spacing-horizontal)\n padding-left: calc(var(--sidebar-item-spacing-horizontal) + var(--sidebar-search-input-spacing-horizontal) + var(--sidebar-search-icon-size))\n\n width: 100%\n\n color: var(--color-sidebar-search-foreground)\n background: transparent\n z-index: 10\n\n &:focus\n outline: none\n\n &::placeholder\n font-size: var(--sidebar-search-input-font-size)\n\n//\n// Hide Search Matches link\n//\n#searchbox .highlight-link\n padding: var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal) 0\n margin: 0\n text-align: center\n\n a\n color: var(--color-sidebar-search-icon)\n font-size: var(--font-size--small--2)\n\n////////////////////////////////////////////////////////////////////////////////\n// Structure/Skeleton of the navigation tree (left)\n////////////////////////////////////////////////////////////////////////////////\n.sidebar-tree\n font-size: var(--sidebar-item-font-size)\n margin-top: var(--sidebar-tree-space-above)\n margin-bottom: var(--sidebar-item-spacing-vertical)\n\n ul\n padding: 0\n margin-top: 0\n margin-bottom: 0\n\n display: flex\n flex-direction: column\n\n list-style: none\n\n li\n position: relative\n margin: 0\n\n > ul\n margin-left: var(--sidebar-item-spacing-horizontal)\n\n .icon\n color: var(--color-sidebar-link-text)\n\n .reference\n box-sizing: border-box\n color: var(--color-sidebar-link-text)\n\n // Fill the parent.\n display: inline-block\n line-height: var(--sidebar-item-line-height)\n text-decoration: none\n\n // Don't allow long words to cause wrapping.\n overflow-wrap: anywhere\n\n height: 100%\n width: 100%\n\n padding: var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal)\n\n &:hover\n background: var(--color-sidebar-item-background--hover)\n\n // Add a nice little \"external-link\" arrow here.\n &.external::after\n content: url('data:image/svg+xml,')\n margin: 0 0.25rem\n vertical-align: middle\n color: var(--color-sidebar-link-text)\n\n // Make the current page reference bold.\n .current-page > .reference\n font-weight: bold\n\n label\n position: absolute\n top: 0\n right: 0\n height: var(--sidebar-item-height)\n width: var(--sidebar-expander-width)\n\n cursor: pointer\n user-select: none\n\n display: flex\n justify-content: center\n align-items: center\n\n .caption, :not(.caption) > .caption-text\n font-size: var(--sidebar-caption-font-size)\n color: var(--color-sidebar-caption-text)\n\n font-weight: bold\n text-transform: uppercase\n\n margin: var(--sidebar-caption-space-above) 0 0 0\n padding: var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal)\n\n // If it has children, add a bit more padding to wrap the content to avoid\n // overlapping with the
    -

    Changelog#

    -
    -

    Unreleased (2023-12-06)#

    +

    Changelog#

    +
    +

    Unreleased (2023-12-09)#

    +

    Compare the full difference.

    +
    +
    +

    0.13.0 (2023-12-06)#

    Compare the full difference.

    -

    Fixes#

    +

    Fixes#

    • Fixed import of extract_regex_flags. a980670

    • Fixed logging and regex regression in 3.11. cae12dc

    • @@ -262,7 +268,7 @@

      Fixes#

    -

    New#

    +

    New#

    • Added key_path to FileConfig. e160b40

        @@ -272,7 +278,7 @@

        New#

    -

    Other#

    +

    Other#

    -

    Updates#

    +

    Updates#

    + + + + + \ No newline at end of file diff --git a/contributing.html b/contributing.html index 899a0227..35754975 100644 --- a/contributing.html +++ b/contributing.html @@ -1,17 +1,17 @@ - + - + Contributing to Bump My Version - Bump My Version 0.13.0 - - - - - + + + + + @@ -178,25 +178,27 @@
  • Search and replace configuration
  • bumpversion
  • @@ -241,7 +243,7 @@
    -

    Contributing to Bump My Version#

    +

    Contributing to Bump My Version#

    First off, thanks for taking the time to contribute! ❤️

    All types of contributions are encouraged and valued. See the Table of Contents for different ways to help and details about how this project handles them. Please make sure to read the relevant section before making your contribution. It will make it much easier for us maintainers and smooth out the experience for all involved. The community looks forward to your contributions. 🎉

    @@ -254,7 +256,7 @@

    Contributing to Bump My Version -

    Table of Contents#

    +

    Table of Contents#

    -

    I Have a Question#

    +

    I Have a Question#

    If you want to ask a question, we assume that you have read the available Documentation.

    @@ -288,9 +290,9 @@

    I Have a Question -

    Reporting Bugs#

    +

    Reporting Bugs#

    -

    Before Submitting a Bug Report#

    +

    Before Submitting a Bug Report#

    A good bug report shouldn’t leave others needing to chase you up for more information. Therefore, we ask you to investigate carefully, collect information, and describe the issue in detail in your report. Please complete the following steps in advance to help us fix any potential bug as fast as possible.

    • Make sure that you are using the latest version.

    • @@ -309,7 +311,7 @@

      Before Submitting a Bug Report -

      How Do I Submit a Good Bug Report?#

      +

      How Do I Submit a Good Bug Report?#

      You must never report security-related issues, vulnerabilities, or bugs that include sensitive information to the issue tracker or elsewhere in public. Instead, sensitive bugs must be sent by email to coreyoordt@gmail.com.

      @@ -329,10 +331,10 @@

      How Do I Submit a Good Bug Report? -

      Suggesting Enhancements#

      +

      Suggesting Enhancements#

      This section guides you through submitting an enhancement suggestion for Bump My Version, including completely new features and minor improvements to existing functionality. Following these guidelines will help maintainers and the community to understand your suggestion and find related suggestions.

      -

      Before Submitting an Enhancement#

      +

      Before Submitting an Enhancement#

      • Make sure that you are using the latest version.

      • Read the documentation carefully and find out if the functionality is already covered, maybe by an individual configuration.

      • @@ -341,7 +343,7 @@

        Before Submitting an Enhancement -

        How Do I Submit a Good Enhancement Suggestion?#

        +

        How Do I Submit a Good Enhancement Suggestion?#

        Enhancement suggestions are tracked as GitHub issues.

        • Use a clear and descriptive title for the issue to identify the suggestion.

        • @@ -354,13 +356,13 @@

          How Do I Submit a Good Enhancement Suggestion? -

          Your First Code Contribution#

          +

          Your First Code Contribution#

          When contributing to this project, you must agree that you have authored 100% of the content, that you have the necessary rights to the content and that the content you contribute may be provided under the project license.

          -

          Setup#

          +

          Setup#

          There are several ways to create an isolated Python development environment. This is the default method.

          Run the following in a terminal:

          # Clone the repository
          @@ -379,14 +381,14 @@ 

          Setup#

          -

          Run tests#

          +

          Run tests#

          Once setup, you should be able to run tests:

          pytest
           
          -

          Install Pre-commit Hooks#

          +

          Install Pre-commit Hooks#

          Pre-commit hooks are scripts that run every time you make a commit. If any of the scripts fail, it stops the commit. You can see a listing of the checks in the .pre-commit-config.yaml file.

          pre-commit install
           
          @@ -394,17 +396,17 @@

          Install Pre-commit Hooks -

          Improving The Documentation#

          +

          Improving The Documentation#

          Please, please help us here.

          -

          Styleguides#

          +

          Styleguides#

          -

          Coding Style#

          +

          Coding Style#

          All of the basic coding styles are configured into tools for fixing and checking them. Pre-commit is used to automate the process.

          -

          Commit Messages#

          +

          Commit Messages#

          Commit messages are used to generate the change log.

          New changes

          Commit messages are categorized as “new” if the commit message starts with:

          @@ -450,11 +452,11 @@

          Commit Messages -

          Join The Project Team#

          +

          Join The Project Team#

          If you would like to be a maintainer, reach out to coreyoordt@gmail.com.

          -

          Attribution#

          +

          Attribution#

          This guide is based on the contributing-gen. Make your own!

          @@ -560,11 +562,11 @@

          Attribution - - - - - +

    + + + + + \ No newline at end of file diff --git a/explanation/index.html b/explanation/index.html index fb1115bf..8c40ee57 100644 --- a/explanation/index.html +++ b/explanation/index.html @@ -1,17 +1,17 @@ - + - + - + Explanation - Bump My Version 0.13.0 - - - - - + + + + + @@ -178,25 +178,27 @@
  • Search and replace configuration
  • bumpversion
  • @@ -241,7 +243,7 @@
    + + + + + \ No newline at end of file diff --git a/genindex.html b/genindex.html index ad4efb36..667931c3 100644 --- a/genindex.html +++ b/genindex.html @@ -1,15 +1,15 @@ - + - Index - Bump My Version 0.13.0 - - - - - + Index - Bump My Version 0.13.0 + + + + + @@ -176,25 +176,27 @@
  • Search and replace configuration
  • bumpversion
  • @@ -539,6 +541,8 @@

    _

  • __format__() (bumpversion.version_part.VersionPart method)
  • __getitem__() (bumpversion.version_part.Version method) +
  • +
  • __hash__() (bumpversion.config.models.FileChange method)
  • __iter__() (bumpversion.version_part.Version method)
  • @@ -576,8 +580,6 @@

    _

  • (bumpversion.scm.SourceCodeManager attribute)
  • -
  • _check_files_contain_version() (in module bumpversion.files) -
  • _choose_serialize_format() (bumpversion.version_part.VersionConfig method)
  • _COMMIT_COMMAND (bumpversion.scm.Git attribute) @@ -588,6 +590,12 @@

    _

  • (bumpversion.scm.SourceCodeManager attribute)
  • +
  • _contains_change_pattern() (bumpversion.files.ConfiguredFile method) +
  • +
  • _resolve_filemap() (bumpversion.config.models.Config method) +
  • +
  • _resolved_filemap (bumpversion.config.models.Config attribute) +
  • _serialize() (bumpversion.version_part.VersionConfig method)
  • _TEST_USABLE_COMMAND (bumpversion.scm.Git attribute) @@ -859,6 +867,13 @@

    B

  • +
  • + bumpversion.config.files_legacy + +
  • @@ -894,6 +909,13 @@

    B

  • +
  • + bumpversion.indented_logger + +
  • @@ -964,10 +986,10 @@

    C

  • commit_to_scm() (bumpversion.scm.SourceCodeManager class method)
  • - - +