Skip to content

tags: - developer - classes description: Core class descriptions for the core classes of Supernotify for Home Assistant


Core Classes

Info

See the Class Diagram for how these relate to each other.

custom_components.supernotify.transport.Transport

Base class for delivery transports.

Sub classes integrste with Home Assistant notification services or alternative notification mechanisms.

METHOD DESCRIPTION
deliver

Delivery implementation

initialize

Async post-construction initialization

simplify

Simplify text for delivery transports with speaking or plain text interfaces

validate_action

Override in subclass if transport has fixed action or doesn't require one

deliver(envelope, debug_trace=None) abstractmethod async

Delivery implementation


envelope (Envelope): envelope to be delivered
debug_trace (DebugTrace): debug info collector

initialize() async

Async post-construction initialization

simplify(text, strip_urls=False)

Simplify text for delivery transports with speaking or plain text interfaces

validate_action(action)

Override in subclass if transport has fixed action or doesn't require one

custom_components.supernotify.notification.Notification

Bases: ArchivableObject


              flowchart TD
              custom_components.supernotify.notification.Notification[Notification]
              custom_components.supernotify.archive.ArchivableObject[ArchivableObject]

                              custom_components.supernotify.archive.ArchivableObject --> custom_components.supernotify.notification.Notification
                


              click custom_components.supernotify.notification.Notification href "" "custom_components.supernotify.notification.Notification"
              click custom_components.supernotify.archive.ArchivableObject href "" "custom_components.supernotify.archive.ArchivableObject"
            
METHOD DESCRIPTION
apply_enabled_scenarios

Set media and action_groups from scenario if defined, first come first applied

base_filename

ArchiveableObject implementation

contents

ArchiveableObject implementation

initialize

Async post-construction initialization

media_requirements

If no media defined, look for iOS / Android actions that have media defined

record_result

Debugging (and unit test) support for notifications that failed or were skipped

apply_enabled_scenarios()

Set media and action_groups from scenario if defined, first come first applied

base_filename()

ArchiveableObject implementation

contents(minimal=False, **_kwargs)

ArchiveableObject implementation

initialize() async

Async post-construction initialization

media_requirements(data)

If no media defined, look for iOS / Android actions that have media defined

Example is the Frigate blueprint, which generates image, video etc in the data section, that can also be used for email attachments

record_result(delivery, envelope=None, targets=None, suppression_reason=None)

Debugging (and unit test) support for notifications that failed or were skipped

custom_components.supernotify.envelope.Envelope

Bases: DupeCheckable


              flowchart TD
              custom_components.supernotify.envelope.Envelope[Envelope]
              custom_components.supernotify.common.DupeCheckable[DupeCheckable]

                              custom_components.supernotify.common.DupeCheckable --> custom_components.supernotify.envelope.Envelope
                


              click custom_components.supernotify.envelope.Envelope href "" "custom_components.supernotify.envelope.Envelope"
              click custom_components.supernotify.common.DupeCheckable href "" "custom_components.supernotify.common.DupeCheckable"
            

Wrap a notification with a specific set of targets and service data possibly customized for those targets

METHOD DESCRIPTION
__eq__

Specialized equality check for subset of attributes

__repr__

Return a concise string representation of the Envelope.

core_action_data

Build the core set of service_data dict to pass to underlying notify service

grab_image

Grab an image from a camera, snapshot URL, MQTT Image etc

hash

Alpha hash to reduce noise from messages with timestamps or incrementing counts

__eq__(other)

Specialized equality check for subset of attributes

__repr__()

Return a concise string representation of the Envelope.

The returned string includes the envelope's message, title, and delivery name in the form: Envelope(message=,title=,delivery=<delivery_name>).</p> <p>Primarily intended for debugging and logging; note that attribute values are inserted directly and may not be quoted or escaped.</p> </div> </div> <div class="doc doc-object doc-function"> <h3 id=custom_components.supernotify.envelope.Envelope.core_action_data class="doc doc-heading"> <code class="highlight language-python"><span class=n>core_action_data</span><span class=p>(</span><span class=n>force_message</span><span class=o>=</span><span class=kc>True</span><span class=p>)</span></code> <a href=#custom_components.supernotify.envelope.Envelope.core_action_data class=headerlink title="Permanent link">¶</a></h3> <div class="doc doc-contents "> <p>Build the core set of <code>service_data</code> dict to pass to underlying notify service</p> </div> </div> <div class="doc doc-object doc-function"> <h3 id=custom_components.supernotify.envelope.Envelope.grab_image class="doc doc-heading"> <code class="highlight language-python"><span class=n>grab_image</span><span class=p>()</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href=#custom_components.supernotify.envelope.Envelope.grab_image class=headerlink title="Permanent link">¶</a></h3> <div class="doc doc-contents "> <p>Grab an image from a camera, snapshot URL, MQTT Image etc</p> </div> </div> <div class="doc doc-object doc-function"> <h3 id=custom_components.supernotify.envelope.Envelope.hash class="doc doc-heading"> <code class="highlight language-python"><span class=nb>hash</span><span class=p>()</span></code> <a href=#custom_components.supernotify.envelope.Envelope.hash class=headerlink title="Permanent link">¶</a></h3> <div class="doc doc-contents "> <p>Alpha hash to reduce noise from messages with timestamps or incrementing counts</p> </div> </div> </div> </div> </div> <div class="doc doc-object doc-class"> <h2 id=custom_components.supernotify.scenario.Scenario class="doc doc-heading"> <code>custom_components.supernotify.scenario.Scenario</code> <a href=#custom_components.supernotify.scenario.Scenario class=headerlink title="Permanent link">¶</a></h2> <div class="doc doc-contents first"> <table> <thead> <tr> <th><span class=doc-section-title>METHOD</span></th> <th><span>DESCRIPTION</span></th> </tr> </thead> <tbody> <tr class=doc-section-item> <td><code><a class="autorefs autorefs-internal" title="attributes(include_condition=True, include_trace=False) (custom_components.supernotify.scenario.Scenario.attributes)" href=#custom_components.supernotify.scenario.Scenario.attributes>attributes</a></code></td> <td class=doc-function-details> <div class=doc-md-description> <p>Return scenario attributes</p> </div> </td> </tr> <tr class=doc-section-item> <td><code><a class="autorefs autorefs-internal" title="contents(minimal=False, **_kwargs) (custom_components.supernotify.scenario.Scenario.contents)" href=#custom_components.supernotify.scenario.Scenario.contents>contents</a></code></td> <td class=doc-function-details> <div class=doc-md-description> <p>Archive friendly view of scenario</p> </div> </td> </tr> <tr class=doc-section-item> <td><code><a class="autorefs autorefs-internal" title="evaluate(condition_variables) (custom_components.supernotify.scenario.Scenario.evaluate)" href=#custom_components.supernotify.scenario.Scenario.evaluate>evaluate</a></code></td> <td class=doc-function-details> <div class=doc-md-description> <p>Evaluate scenario conditions</p> </div> </td> </tr> <tr class=doc-section-item> <td><code><a class="autorefs autorefs-internal" title="trace(condition_variables) async (custom_components.supernotify.scenario.Scenario.trace)" href=#custom_components.supernotify.scenario.Scenario.trace>trace</a></code></td> <td class=doc-function-details> <div class=doc-md-description> <p>Trace scenario condition execution</p> </div> </td> </tr> <tr class=doc-section-item> <td><code><a class="autorefs autorefs-internal" title="validate(valid_action_group_names=None) async (custom_components.supernotify.scenario.Scenario.validate)" href=#custom_components.supernotify.scenario.Scenario.validate>validate</a></code></td> <td class=doc-function-details> <div class=doc-md-description> <p>Validate Home Assistant conditiion definition at initiation</p> </div> </td> </tr> </tbody> </table> <div class="doc doc-children"> <div class="doc doc-object doc-function"> <h3 id=custom_components.supernotify.scenario.Scenario.attributes class="doc doc-heading"> <code class="highlight language-python"><span class=n>attributes</span><span class=p>(</span><span class=n>include_condition</span><span class=o>=</span><span class=kc>True</span><span class=p>,</span> <span class=n>include_trace</span><span class=o>=</span><span class=kc>False</span><span class=p>)</span></code> <a href=#custom_components.supernotify.scenario.Scenario.attributes class=headerlink title="Permanent link">¶</a></h3> <div class="doc doc-contents "> <p>Return scenario attributes</p> </div> </div> <div class="doc doc-object doc-function"> <h3 id=custom_components.supernotify.scenario.Scenario.contents class="doc doc-heading"> <code class="highlight language-python"><span class=n>contents</span><span class=p>(</span><span class=n>minimal</span><span class=o>=</span><span class=kc>False</span><span class=p>,</span> <span class=o>**</span><span class=n>_kwargs</span><span class=p>)</span></code> <a href=#custom_components.supernotify.scenario.Scenario.contents class=headerlink title="Permanent link">¶</a></h3> <div class="doc doc-contents "> <p>Archive friendly view of scenario</p> </div> </div> <div class="doc doc-object doc-function"> <h3 id=custom_components.supernotify.scenario.Scenario.evaluate class="doc doc-heading"> <code class="highlight language-python"><span class=n>evaluate</span><span class=p>(</span><span class=n>condition_variables</span><span class=p>)</span></code> <a href=#custom_components.supernotify.scenario.Scenario.evaluate class=headerlink title="Permanent link">¶</a></h3> <div class="doc doc-contents "> <p>Evaluate scenario conditions</p> </div> </div> <div class="doc doc-object doc-function"> <h3 id=custom_components.supernotify.scenario.Scenario.trace class="doc doc-heading"> <code class="highlight language-python"><span class=n>trace</span><span class=p>(</span><span class=n>condition_variables</span><span class=p>)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href=#custom_components.supernotify.scenario.Scenario.trace class=headerlink title="Permanent link">¶</a></h3> <div class="doc doc-contents "> <p>Trace scenario condition execution</p> </div> </div> <div class="doc doc-object doc-function"> <h3 id=custom_components.supernotify.scenario.Scenario.validate class="doc doc-heading"> <code class="highlight language-python"><span class=n>validate</span><span class=p>(</span><span class=n>valid_action_group_names</span><span class=o>=</span><span class=kc>None</span><span class=p>)</span></code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-async"><code>async</code></small> </span> <a href=#custom_components.supernotify.scenario.Scenario.validate class=headerlink title="Permanent link">¶</a></h3> <div class="doc doc-contents "> <p>Validate Home Assistant conditiion definition at initiation</p> </div> </div> </div> </div> </div> <div class="doc doc-object doc-class"> <h2 id=custom_components.supernotify.model.Target class="doc doc-heading"> <code>custom_components.supernotify.model.Target</code> <a href=#custom_components.supernotify.model.Target class=headerlink title="Permanent link">¶</a></h2> <div class="doc doc-contents first"> <table> <thead> <tr> <th><span class=doc-section-title>METHOD</span></th> <th><span>DESCRIPTION</span></th> </tr> </thead> <tbody> <tr class=doc-section-item> <td><code><a class="autorefs autorefs-internal" title="__add__(other) (custom_components.supernotify.model.Target.__add__)" href=#custom_components.supernotify.model.Target.__add__>__add__</a></code></td> <td class=doc-function-details> <div class=doc-md-description> <p>Create a new target by adding another to this one</p> </div> </td> </tr> <tr class=doc-section-item> <td><code><a class="autorefs autorefs-internal" title="__eq__(other) (custom_components.supernotify.model.Target.__eq__)" href=#custom_components.supernotify.model.Target.__eq__>__eq__</a></code></td> <td class=doc-function-details> <div class=doc-md-description> <p>Compare two targets</p> </div> </td> </tr> <tr class=doc-section-item> <td><code><a class="autorefs autorefs-internal" title="__len__() (custom_components.supernotify.model.Target.__len__)" href=#custom_components.supernotify.model.Target.__len__>__len__</a></code></td> <td class=doc-function-details> <div class=doc-md-description> <p>How many targets, whether direct or indirect</p> </div> </td> </tr> <tr class=doc-section-item> <td><code><a class="autorefs autorefs-internal" title="__sub__(other) (custom_components.supernotify.model.Target.__sub__)" href=#custom_components.supernotify.model.Target.__sub__>__sub__</a></code></td> <td class=doc-function-details> <div class=doc-md-description> <p>Create a new target by removing another from this one, ignoring target_data</p> </div> </td> </tr> </tbody> </table> <div class="doc doc-children"> <div class="doc doc-object doc-function"> <h3 id=custom_components.supernotify.model.Target.__add__ class="doc doc-heading"> <code class="highlight language-python"><span class=fm>__add__</span><span class=p>(</span><span class=n>other</span><span class=p>)</span></code> <a href=#custom_components.supernotify.model.Target.__add__ class=headerlink title="Permanent link">¶</a></h3> <div class="doc doc-contents "> <p>Create a new target by adding another to this one</p> </div> </div> <div class="doc doc-object doc-function"> <h3 id=custom_components.supernotify.model.Target.__eq__ class="doc doc-heading"> <code class="highlight language-python"><span class=fm>__eq__</span><span class=p>(</span><span class=n>other</span><span class=p>)</span></code> <a href=#custom_components.supernotify.model.Target.__eq__ class=headerlink title="Permanent link">¶</a></h3> <div class="doc doc-contents "> <p>Compare two targets</p> </div> </div> <div class="doc doc-object doc-function"> <h3 id=custom_components.supernotify.model.Target.__len__ class="doc doc-heading"> <code class="highlight language-python"><span class=fm>__len__</span><span class=p>()</span></code> <a href=#custom_components.supernotify.model.Target.__len__ class=headerlink title="Permanent link">¶</a></h3> <div class="doc doc-contents "> <p>How many targets, whether direct or indirect</p> </div> </div> <div class="doc doc-object doc-function"> <h3 id=custom_components.supernotify.model.Target.__sub__ class="doc doc-heading"> <code class="highlight language-python"><span class=fm>__sub__</span><span class=p>(</span><span class=n>other</span><span class=p>)</span></code> <a href=#custom_components.supernotify.model.Target.__sub__ class=headerlink title="Permanent link">¶</a></h3> <div class="doc doc-contents "> <p>Create a new target by removing another from this one, ignoring target_data</p> </div> </div> </div> </div> </div> <div class="doc doc-object doc-class"> <h2 id=custom_components.supernotify.model.DeliveryConfig class="doc doc-heading"> <code>custom_components.supernotify.model.DeliveryConfig</code> <a href=#custom_components.supernotify.model.DeliveryConfig class=headerlink title="Permanent link">¶</a></h2> <div class="doc doc-contents first"> <p>Shared config for transport defaults and Delivery definitions</p> <table> <thead> <tr> <th><span class=doc-section-title>METHOD</span></th> <th><span>DESCRIPTION</span></th> </tr> </thead> <tbody> <tr class=doc-section-item> <td><code><a class="autorefs autorefs-internal" title="__repr__() (custom_components.supernotify.model.DeliveryConfig.__repr__)" href=#custom_components.supernotify.model.DeliveryConfig.__repr__>__repr__</a></code></td> <td class=doc-function-details> <div class=doc-md-description> <p>Log friendly representation</p> </div> </td> </tr> </tbody> </table> <div class="doc doc-children"> <div class="doc doc-object doc-function"> <h3 id=custom_components.supernotify.model.DeliveryConfig.__repr__ class="doc doc-heading"> <code class="highlight language-python"><span class=fm>__repr__</span><span class=p>()</span></code> <a href=#custom_components.supernotify.model.DeliveryConfig.__repr__ class=headerlink title="Permanent link">¶</a></h3> <div class="doc doc-contents "> <p>Log friendly representation</p> </div> </div> </div> </div> </div> <div class="doc doc-object doc-class"> <h2 id=custom_components.supernotify.model.TransportConfig class="doc doc-heading"> <code>custom_components.supernotify.model.TransportConfig</code> <a href=#custom_components.supernotify.model.TransportConfig class=headerlink title="Permanent link">¶</a></h2> <div class="doc doc-contents first"> <div class="doc doc-children"> </div> </div> </div> <div class="doc doc-object doc-class"> <h2 id=custom_components.supernotify.snoozer.Snooze class="doc doc-heading"> <code>custom_components.supernotify.snoozer.Snooze</code> <a href=#custom_components.supernotify.snoozer.Snooze class=headerlink title="Permanent link">¶</a></h2> <div class="doc doc-contents first"> <table> <thead> <tr> <th><span class=doc-section-title>METHOD</span></th> <th><span>DESCRIPTION</span></th> </tr> </thead> <tbody> <tr class=doc-section-item> <td><code><a class="autorefs autorefs-internal" title="__eq__(other) (custom_components.supernotify.snoozer.Snooze.__eq__)" href=#custom_components.supernotify.snoozer.Snooze.__eq__>__eq__</a></code></td> <td class=doc-function-details> <div class=doc-md-description> <p>Check if two snoozes for the same thing</p> </div> </td> </tr> <tr class=doc-section-item> <td><code><a class="autorefs autorefs-internal" title="__repr__() (custom_components.supernotify.snoozer.Snooze.__repr__)" href=#custom_components.supernotify.snoozer.Snooze.__repr__>__repr__</a></code></td> <td class=doc-function-details> <div class=doc-md-description> <p>Return a string representation of the object.</p> </div> </td> </tr> </tbody> </table> <div class="doc doc-children"> <div class="doc doc-object doc-function"> <h3 id=custom_components.supernotify.snoozer.Snooze.__eq__ class="doc doc-heading"> <code class="highlight language-python"><span class=fm>__eq__</span><span class=p>(</span><span class=n>other</span><span class=p>)</span></code> <a href=#custom_components.supernotify.snoozer.Snooze.__eq__ class=headerlink title="Permanent link">¶</a></h3> <div class="doc doc-contents "> <p>Check if two snoozes for the same thing</p> </div> </div> <div class="doc doc-object doc-function"> <h3 id=custom_components.supernotify.snoozer.Snooze.__repr__ class="doc doc-heading"> <code class="highlight language-python"><span class=fm>__repr__</span><span class=p>()</span></code> <a href=#custom_components.supernotify.snoozer.Snooze.__repr__ class=headerlink title="Permanent link">¶</a></h3> <div class="doc doc-contents "> <p>Return a string representation of the object.</p> </div> </div> </div> </div> </div> <div class="doc doc-object doc-class"> <h2 id=custom_components.supernotify.model.ConditionVariables class="doc doc-heading"> <code>custom_components.supernotify.model.ConditionVariables</code> <span class="doc doc-labels"> <small class="doc doc-label doc-label-dataclass"><code>dataclass</code></small> </span> <a href=#custom_components.supernotify.model.ConditionVariables class=headerlink title="Permanent link">¶</a></h2> <div class="doc doc-contents first"> <p>Variables presented to all condition evaluations</p> <h4 id=custom_components.supernotify.model.ConditionVariables--attributes>Attributes<a class=headerlink href=#custom_components.supernotify.model.ConditionVariables--attributes title="Permanent link">¶</a></h4> <div class="language-text highlight"><pre><span></span><code>applied_scenarios (list[str]): Scenarios that have been applied required_scenarios (list[str]): Scenarios that must be applied constrain_scenarios (list[str]): Only scenarios in this list, or in explicit apply_scenarios, can be applied notification_priority (str): Priority of the notification notification_message (str): Message of the notification notification_title (str): Title of the notification occupancy (list[str]): List of occupancy scenarios </code></pre></div> <div class="doc doc-children"> </div> </div> </div> <div class="doc doc-object doc-class"> <h2 id=custom_components.supernotify.people.PeopleRegistry class="doc doc-heading"> <code>custom_components.supernotify.people.PeopleRegistry</code> <a href=#custom_components.supernotify.people.PeopleRegistry class=headerlink title="Permanent link">¶</a></h2> <div class="doc doc-contents first"> <table> <thead> <tr> <th><span class=doc-section-title>METHOD</span></th> <th><span>DESCRIPTION</span></th> </tr> </thead> <tbody> <tr class=doc-section-item> <td><code><a class="autorefs autorefs-internal" title="mobile_devices_for_person(person_entity_id) (custom_components.supernotify.people.PeopleRegistry.mobile_devices_for_person)" href=#custom_components.supernotify.people.PeopleRegistry.mobile_devices_for_person>mobile_devices_for_person</a></code></td> <td class=doc-function-details> <div class=doc-md-description> <p>Auto detect mobile_app targets for a person.</p> </div> </td> </tr> </tbody> </table> <div class="doc doc-children"> <div class="doc doc-object doc-function"> <h3 id=custom_components.supernotify.people.PeopleRegistry.mobile_devices_for_person class="doc doc-heading"> <code class="highlight language-python"><span class=n>mobile_devices_for_person</span><span class=p>(</span><span class=n>person_entity_id</span><span class=p>)</span></code> <a href=#custom_components.supernotify.people.PeopleRegistry.mobile_devices_for_person class=headerlink title="Permanent link">¶</a></h3> <div class="doc doc-contents "> <p>Auto detect mobile_app targets for a person.</p> <p>Targets not currently validated as async registration may not be complete at this stage</p> <hr> <div class="language-text highlight"><pre><span></span><code>person_entity_id (str): _description_ </code></pre></div> <hr> <div class="language-text highlight"><pre><span></span><code>list: mobile target actions for this person </code></pre></div> </div> </div> </div> </div> </div> <aside class=md-source-file> <span class=md-source-file__fact> <span class=md-icon title="Last update"> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M21 13.1c-.1 0-.3.1-.4.2l-1 1 2.1 2.1 1-1c.2-.2.2-.6 0-.8l-1.3-1.3c-.1-.1-.2-.2-.4-.2m-1.9 1.8-6.1 6V23h2.1l6.1-6.1zM12.5 7v5.2l4 2.4-1 1L11 13V7zM11 21.9c-5.1-.5-9-4.8-9-9.9C2 6.5 6.5 2 12 2c5.3 0 9.6 4.1 10 9.3-.3-.1-.6-.2-1-.2s-.7.1-1 .2C19.6 7.2 16.2 4 12 4c-4.4 0-8 3.6-8 8 0 4.1 3.1 7.5 7.1 7.9l-.1.2z"/></svg> </span> <span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-timeago" title="December 13, 2025 22:11:05 UTC"><span class=timeago datetime=2025-12-13T22:11:05+00:00 locale=en></span></span><span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date" title="December 13, 2025 22:11:05 UTC">2025-12-13</span> </span> <span class=md-source-file__fact> <span class=md-icon title=Created> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M14.47 15.08 11 13V7h1.5v5.25l3.08 1.83c-.41.28-.79.62-1.11 1m-1.39 4.84c-.36.05-.71.08-1.08.08-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8c0 .37-.03.72-.08 1.08.69.1 1.33.32 1.92.64.1-.56.16-1.13.16-1.72 0-5.5-4.5-10-10-10S2 6.5 2 12s4.47 10 10 10c.59 0 1.16-.06 1.72-.16-.32-.59-.54-1.23-.64-1.92M18 15v3h-3v2h3v3h2v-3h3v-2h-3v-3z"/></svg> </span> <span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-timeago" title="October 25, 2025 13:35:43 UTC"><span class=timeago datetime=2025-10-25T13:35:43+00:00 locale=en></span></span><span class="git-revision-date-localized-plugin git-revision-date-localized-plugin-iso_date" title="October 25, 2025 13:35:43 UTC">2025-10-25</span> </span> </aside> </article> </div> <script>var target=document.getElementById(location.hash.slice(1));target&&target.name&&(target.checked=target.name.startsWith("__tabbed_"))</script> </div> <button type=button class="md-top md-icon" data-md-component=top hidden> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 24 24"><path d="M13 20h-2V8l-5.5 5.5-1.42-1.42L12 4.16l7.92 7.92-1.42 1.42L13 8z"/></svg> Back to top </button> </main> <footer class=md-footer> <div class="md-footer-meta md-typeset"> <div class="md-footer-meta__inner md-grid"> <div class=md-copyright> Made with <a href=https://squidfunk.github.io/mkdocs-material/ target=_blank rel=noopener> Material for MkDocs </a> </div> <div class=md-social> <a href=https://github.com/rhizomatics target=_blank rel=noopener title=github.com class=md-social__link> <svg xmlns=http://www.w3.org/2000/svg viewbox="0 0 512 512"><!-- Font Awesome Free 7.1.0 by @fontawesome - https://fontawesome.com License - https://fontawesome.com/license/free (Icons: CC BY 4.0, Fonts: SIL OFL 1.1, Code: MIT License) Copyright 2025 Fonticons, Inc.--><path d="M173.9 397.4c0 2-2.3 3.6-5.2 3.6-3.3.3-5.6-1.3-5.6-3.6 0-2 2.3-3.6 5.2-3.6 3-.3 5.6 1.3 5.6 3.6m-31.1-4.5c-.7 2 1.3 4.3 4.3 4.9 2.6 1 5.6 0 6.2-2s-1.3-4.3-4.3-5.2c-2.6-.7-5.5.3-6.2 2.3m44.2-1.7c-2.9.7-4.9 2.6-4.6 4.9.3 2 2.9 3.3 5.9 2.6 2.9-.7 4.9-2.6 4.6-4.6-.3-1.9-3-3.2-5.9-2.9M252.8 8C114.1 8 8 113.3 8 252c0 110.9 69.8 205.8 169.5 239.2 12.8 2.3 17.3-5.6 17.3-12.1 0-6.2-.3-40.4-.3-61.4 0 0-70 15-84.7-29.8 0 0-11.4-29.1-27.8-36.6 0 0-22.9-15.7 1.6-15.4 0 0 24.9 2 38.6 25.8 21.9 38.6 58.6 27.5 72.9 20.9 2.3-16 8.8-27.1 16-33.7-55.9-6.2-112.3-14.3-112.3-110.5 0-27.5 7.6-41.3 23.6-58.9-2.6-6.5-11.1-33.3 2.6-67.9 20.9-6.5 69 27 69 27 20-5.6 41.5-8.5 62.8-8.5s42.8 2.9 62.8 8.5c0 0 48.1-33.6 69-27 13.7 34.7 5.2 61.4 2.6 67.9 16 17.7 25.8 31.5 25.8 58.9 0 96.5-58.9 104.2-114.8 110.5 9.2 7.9 17 22.9 17 46.4 0 33.7-.3 75.4-.3 83.6 0 6.5 4.6 14.4 17.3 12.1C436.2 457.8 504 362.9 504 252 504 113.3 391.5 8 252.8 8M105.2 352.9c-1.3 1-1 3.3.7 5.2 1.6 1.6 3.9 2.3 5.2 1 1.3-1 1-3.3-.7-5.2-1.6-1.6-3.9-2.3-5.2-1m-10.8-8.1c-.7 1.3.3 2.9 2.3 3.9 1.6 1 3.6.7 4.3-.7.7-1.3-.3-2.9-2.3-3.9-2-.6-3.6-.3-4.3.7m32.4 35.6c-1.6 1.3-1 4.3 1.3 6.2 2.3 2.3 5.2 2.6 6.5 1 1.3-1.3.7-4.3-1.3-6.2-2.2-2.3-5.2-2.6-6.5-1m-11.4-14.7c-1.6 1-1.6 3.6 0 5.9s4.3 3.3 5.6 2.3c1.6-1.3 1.6-3.9 0-6.2-1.4-2.3-4-3.3-5.6-2"/></svg> </a> </div> </div> </div> </footer> </div> <div class=md-dialog data-md-component=dialog> <div class="md-dialog__inner md-typeset"></div> </div> <script id=__config type=application/json>{"annotate": null, "base": "../..", "features": ["content.action.edit", "content.action.view", "content.code.copy", "content.code.select", "content.code.annotate", "navigation.instant", "navigation.tracking", "navigation.tabs", "navigation.tabs.sticky", "navigation.sections", "navigation.expand", "navigation.path", "navigation.indexes", "navigation.top", "search.suggest", "search", "search.share", "toc.follow", "toc.integrate"], "search": "../../assets/javascripts/workers/search.2c215733.min.js", "tags": null, "translations": {"clipboard.copied": "Copied to clipboard", "clipboard.copy": "Copy to clipboard", "search.result.more.one": "1 more on this page", "search.result.more.other": "# more on this page", "search.result.none": "No matching documents", "search.result.one": "1 matching document", "search.result.other": "# matching documents", "search.result.placeholder": "Type to start searching", "search.result.term.missing": "Missing", "select.version": "Select version"}, "version": {"provider": "mike"}}</script> <script src=../../assets/javascripts/bundle.79ae519e.min.js></script> <script src=../../js/timeago.min.js></script> <script src=../../js/timeago_mkdocs_material.js></script> <script src=../../assets/mkdocs_pagetree_plugin.js></script> </body> </html>