diff --git a/.buildinfo b/.buildinfo new file mode 100644 index 000000000..994a46357 --- /dev/null +++ b/.buildinfo @@ -0,0 +1,4 @@ +# Sphinx build info version 1 +# This file records the configuration used when building these files. When it is not found, a full rebuild will be done. +config: c9c19100d8ab1d5c1cd514173feef339 +tags: 645f666f9bcd5a90fca523b33c5a78b7 diff --git a/.nojekyll b/.nojekyll new file mode 100644 index 000000000..e69de29bb diff --git a/_images/2021-05-09_10-32.jpg b/_images/2021-05-09_10-32.jpg new file mode 100644 index 000000000..d16a02951 Binary files /dev/null and b/_images/2021-05-09_10-32.jpg differ diff --git a/_images/2021-05-09_10-36.jpg b/_images/2021-05-09_10-36.jpg new file mode 100644 index 000000000..db2876cb3 Binary files /dev/null and b/_images/2021-05-09_10-36.jpg differ diff --git a/_images/2021-05-09_10-50.jpg b/_images/2021-05-09_10-50.jpg new file mode 100644 index 000000000..cd12ca5d9 Binary files /dev/null and b/_images/2021-05-09_10-50.jpg differ diff --git a/_images/2021-05-09_17-36.jpg b/_images/2021-05-09_17-36.jpg new file mode 100644 index 000000000..b5581088b Binary files /dev/null and b/_images/2021-05-09_17-36.jpg differ diff --git a/_images/2021-05-09_17-38.jpg b/_images/2021-05-09_17-38.jpg new file mode 100644 index 000000000..60c056e85 Binary files /dev/null and b/_images/2021-05-09_17-38.jpg differ diff --git a/_images/2021-05-09_17-44.jpg b/_images/2021-05-09_17-44.jpg new file mode 100644 index 000000000..83b414d0f Binary files /dev/null and b/_images/2021-05-09_17-44.jpg differ diff --git a/_images/2021-05-09_17-57.jpg b/_images/2021-05-09_17-57.jpg new file mode 100644 index 000000000..b9dd0947e Binary files /dev/null and b/_images/2021-05-09_17-57.jpg differ diff --git a/_images/2021-05-09_21-21.jpg b/_images/2021-05-09_21-21.jpg new file mode 100644 index 000000000..1b27de5f0 Binary files /dev/null and b/_images/2021-05-09_21-21.jpg differ diff --git a/_images/2021-05-09_21-46.jpg b/_images/2021-05-09_21-46.jpg new file mode 100644 index 000000000..903bd8e92 Binary files /dev/null and b/_images/2021-05-09_21-46.jpg differ diff --git a/_images/2021-05-09_22-09.jpg b/_images/2021-05-09_22-09.jpg new file mode 100644 index 000000000..5b3a1fcd2 Binary files /dev/null and b/_images/2021-05-09_22-09.jpg differ diff --git a/_images/2021-05-09_22-39.jpg b/_images/2021-05-09_22-39.jpg new file mode 100644 index 000000000..d02b6668f Binary files /dev/null and b/_images/2021-05-09_22-39.jpg differ diff --git a/_images/2021-05-10_22-35.jpg b/_images/2021-05-10_22-35.jpg new file mode 100644 index 000000000..9c3650585 Binary files /dev/null and b/_images/2021-05-10_22-35.jpg differ diff --git a/_images/2021-05-10_22-59.jpg b/_images/2021-05-10_22-59.jpg new file mode 100644 index 000000000..ca184bc6c Binary files /dev/null and b/_images/2021-05-10_22-59.jpg differ diff --git a/_images/2021-05-12_18-18.jpg b/_images/2021-05-12_18-18.jpg new file mode 100644 index 000000000..5ee9dac5a Binary files /dev/null and b/_images/2021-05-12_18-18.jpg differ diff --git a/_images/2021-05-12_18-51.jpg b/_images/2021-05-12_18-51.jpg new file mode 100644 index 000000000..afb248858 Binary files /dev/null and b/_images/2021-05-12_18-51.jpg differ diff --git a/_images/2021-05-12_19-12.jpg b/_images/2021-05-12_19-12.jpg new file mode 100644 index 000000000..cda80cf9d Binary files /dev/null and b/_images/2021-05-12_19-12.jpg differ diff --git a/_images/2021-05-12_20-06.jpg b/_images/2021-05-12_20-06.jpg new file mode 100644 index 000000000..b34855edf Binary files /dev/null and b/_images/2021-05-12_20-06.jpg differ diff --git a/_images/2021-05-12_20-10.jpg b/_images/2021-05-12_20-10.jpg new file mode 100644 index 000000000..04d6402f1 Binary files /dev/null and b/_images/2021-05-12_20-10.jpg differ diff --git a/_images/2021-05-12_21-03.jpg b/_images/2021-05-12_21-03.jpg new file mode 100644 index 000000000..384e2ba0d Binary files /dev/null and b/_images/2021-05-12_21-03.jpg differ diff --git a/_images/2021-05-13_20-46.jpg b/_images/2021-05-13_20-46.jpg new file mode 100644 index 000000000..d3448b877 Binary files /dev/null and b/_images/2021-05-13_20-46.jpg differ diff --git a/_images/2021-05-17_11-50.jpg b/_images/2021-05-17_11-50.jpg new file mode 100644 index 000000000..3fb35b9c0 Binary files /dev/null and b/_images/2021-05-17_11-50.jpg differ diff --git a/_images/crosslayer_intro.jpg b/_images/crosslayer_intro.jpg new file mode 100644 index 000000000..41349a91a Binary files /dev/null and b/_images/crosslayer_intro.jpg differ diff --git a/_images/examples_11_Complexity_Assessment_2_1.svg b/_images/examples_11_Complexity_Assessment_2_1.svg new file mode 100644 index 000000000..27079911d --- /dev/null +++ b/_images/examples_11_Complexity_Assessment_2_1.svg @@ -0,0 +1,39 @@ + + + +180 +objects + + +31% + +16% + +27% + +27% + +18 +diagrams + + +39% + +22% + +28% + +11% + + + +Operational Analysis + +System Analysis + +Logical Architecture + +Physical Architecture + + + \ No newline at end of file diff --git a/_images/harrys_wand.png b/_images/harrys_wand.png new file mode 100644 index 000000000..effece64b Binary files /dev/null and b/_images/harrys_wand.png differ diff --git a/_images/waypoints.png b/_images/waypoints.png new file mode 100644 index 000000000..fd021c986 Binary files /dev/null and b/_images/waypoints.png differ diff --git a/_sources/code/capellambse.aird.rst.txt b/_sources/code/capellambse.aird.rst.txt new file mode 100644 index 000000000..1f1585a4a --- /dev/null +++ b/_sources/code/capellambse.aird.rst.txt @@ -0,0 +1,7 @@ +capellambse.aird package +======================== + +.. automodule:: capellambse.aird + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/code/capellambse.diagram.rst.txt b/_sources/code/capellambse.diagram.rst.txt new file mode 100644 index 000000000..bf6ec497b --- /dev/null +++ b/_sources/code/capellambse.diagram.rst.txt @@ -0,0 +1,18 @@ +capellambse.diagram package +=========================== + +.. automodule:: capellambse.diagram + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +capellambse.diagram.capstyle module +----------------------------------- + +.. automodule:: capellambse.diagram.capstyle + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/code/capellambse.extensions.metrics.rst.txt b/_sources/code/capellambse.extensions.metrics.rst.txt new file mode 100644 index 000000000..a81d6a574 --- /dev/null +++ b/_sources/code/capellambse.extensions.metrics.rst.txt @@ -0,0 +1,26 @@ +capellambse.extensions.metrics package +====================================== + +.. automodule:: capellambse.extensions.metrics + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +capellambse.extensions.metrics.collector module +----------------------------------------------- + +.. automodule:: capellambse.extensions.metrics.collector + :members: + :undoc-members: + :show-inheritance: + +capellambse.extensions.metrics.composer module +---------------------------------------------- + +.. automodule:: capellambse.extensions.metrics.composer + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/code/capellambse.extensions.pvmt.rst.txt b/_sources/code/capellambse.extensions.pvmt.rst.txt new file mode 100644 index 000000000..a5b88bc87 --- /dev/null +++ b/_sources/code/capellambse.extensions.pvmt.rst.txt @@ -0,0 +1,7 @@ +capellambse.extensions.pvmt package +=================================== + +.. automodule:: capellambse.extensions.pvmt + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/code/capellambse.extensions.reqif.rst.txt b/_sources/code/capellambse.extensions.reqif.rst.txt new file mode 100644 index 000000000..f9b4452e8 --- /dev/null +++ b/_sources/code/capellambse.extensions.reqif.rst.txt @@ -0,0 +1,18 @@ +capellambse.extensions.reqif package +==================================== + +.. automodule:: capellambse.extensions.reqif + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +capellambse.extensions.reqif.exporter module +-------------------------------------------- + +.. automodule:: capellambse.extensions.reqif.exporter + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/code/capellambse.extensions.rst.txt b/_sources/code/capellambse.extensions.rst.txt new file mode 100644 index 000000000..3e97e40c8 --- /dev/null +++ b/_sources/code/capellambse.extensions.rst.txt @@ -0,0 +1,29 @@ +capellambse.extensions package +============================== + +.. automodule:: capellambse.extensions + :members: + :undoc-members: + :show-inheritance: + +Subpackages +----------- + +.. toctree:: + :maxdepth: 4 + + capellambse.extensions.metrics + capellambse.extensions.pvmt + capellambse.extensions.reqif + capellambse.extensions.validation + +Submodules +---------- + +capellambse.extensions.filtering module +--------------------------------------- + +.. automodule:: capellambse.extensions.filtering + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/code/capellambse.extensions.validation.rst.txt b/_sources/code/capellambse.extensions.validation.rst.txt new file mode 100644 index 000000000..31adde34e --- /dev/null +++ b/_sources/code/capellambse.extensions.validation.rst.txt @@ -0,0 +1,18 @@ +capellambse.extensions.validation package +========================================= + +.. automodule:: capellambse.extensions.validation + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +capellambse.extensions.validation.rules module +---------------------------------------------- + +.. automodule:: capellambse.extensions.validation.rules + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/code/capellambse.filehandler.rst.txt b/_sources/code/capellambse.filehandler.rst.txt new file mode 100644 index 000000000..695066a24 --- /dev/null +++ b/_sources/code/capellambse.filehandler.rst.txt @@ -0,0 +1,74 @@ +capellambse.filehandler package +=============================== + +.. automodule:: capellambse.filehandler + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +capellambse.filehandler.abc module +---------------------------------- + +.. automodule:: capellambse.filehandler.abc + :members: + :undoc-members: + :show-inheritance: + +capellambse.filehandler.git module +---------------------------------- + +.. automodule:: capellambse.filehandler.git + :members: + :undoc-members: + :show-inheritance: + +capellambse.filehandler.git\_askpass module +------------------------------------------- + +.. automodule:: capellambse.filehandler.git_askpass + :members: + :undoc-members: + :show-inheritance: + +capellambse.filehandler.gitlab\_artifacts module +------------------------------------------------ + +.. automodule:: capellambse.filehandler.gitlab_artifacts + :members: + :undoc-members: + :show-inheritance: + +capellambse.filehandler.http module +----------------------------------- + +.. automodule:: capellambse.filehandler.http + :members: + :undoc-members: + :show-inheritance: + +capellambse.filehandler.local module +------------------------------------ + +.. automodule:: capellambse.filehandler.local + :members: + :undoc-members: + :show-inheritance: + +capellambse.filehandler.memory module +------------------------------------- + +.. automodule:: capellambse.filehandler.memory + :members: + :undoc-members: + :show-inheritance: + +capellambse.filehandler.zip module +---------------------------------- + +.. automodule:: capellambse.filehandler.zip + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/code/capellambse.loader.rst.txt b/_sources/code/capellambse.loader.rst.txt new file mode 100644 index 000000000..fee2c29ab --- /dev/null +++ b/_sources/code/capellambse.loader.rst.txt @@ -0,0 +1,34 @@ +capellambse.loader package +========================== + +.. automodule:: capellambse.loader + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +capellambse.loader.core module +------------------------------ + +.. automodule:: capellambse.loader.core + :members: + :undoc-members: + :show-inheritance: + +capellambse.loader.exs module +----------------------------- + +.. automodule:: capellambse.loader.exs + :members: + :undoc-members: + :show-inheritance: + +capellambse.loader.modelinfo module +----------------------------------- + +.. automodule:: capellambse.loader.modelinfo + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/code/capellambse.metamodel.information.rst.txt b/_sources/code/capellambse.metamodel.information.rst.txt new file mode 100644 index 000000000..1875b6af0 --- /dev/null +++ b/_sources/code/capellambse.metamodel.information.rst.txt @@ -0,0 +1,26 @@ +capellambse.metamodel.information package +========================================= + +.. automodule:: capellambse.metamodel.information + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +capellambse.metamodel.information.datatype module +------------------------------------------------- + +.. automodule:: capellambse.metamodel.information.datatype + :members: + :undoc-members: + :show-inheritance: + +capellambse.metamodel.information.datavalue module +-------------------------------------------------- + +.. automodule:: capellambse.metamodel.information.datavalue + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/code/capellambse.metamodel.rst.txt b/_sources/code/capellambse.metamodel.rst.txt new file mode 100644 index 000000000..3fe94be1e --- /dev/null +++ b/_sources/code/capellambse.metamodel.rst.txt @@ -0,0 +1,114 @@ +capellambse.metamodel package +============================= + +.. automodule:: capellambse.metamodel + :members: + :undoc-members: + :show-inheritance: + +Subpackages +----------- + +.. toctree:: + :maxdepth: 4 + + capellambse.metamodel.information + +Submodules +---------- + +capellambse.metamodel.capellacommon module +------------------------------------------ + +.. automodule:: capellambse.metamodel.capellacommon + :members: + :undoc-members: + :show-inheritance: + +capellambse.metamodel.capellacore module +---------------------------------------- + +.. automodule:: capellambse.metamodel.capellacore + :members: + :undoc-members: + :show-inheritance: + +capellambse.metamodel.capellamodeller module +-------------------------------------------- + +.. automodule:: capellambse.metamodel.capellamodeller + :members: + :undoc-members: + :show-inheritance: + +capellambse.metamodel.cs module +------------------------------- + +.. automodule:: capellambse.metamodel.cs + :members: + :undoc-members: + :show-inheritance: + +capellambse.metamodel.fa module +------------------------------- + +.. automodule:: capellambse.metamodel.fa + :members: + :undoc-members: + :show-inheritance: + +capellambse.metamodel.interaction module +---------------------------------------- + +.. automodule:: capellambse.metamodel.interaction + :members: + :undoc-members: + :show-inheritance: + +capellambse.metamodel.la module +------------------------------- + +.. automodule:: capellambse.metamodel.la + :members: + :undoc-members: + :show-inheritance: + +capellambse.metamodel.modellingcore module +------------------------------------------ + +.. automodule:: capellambse.metamodel.modellingcore + :members: + :undoc-members: + :show-inheritance: + +capellambse.metamodel.modeltypes module +--------------------------------------- + +.. automodule:: capellambse.metamodel.modeltypes + :members: + :undoc-members: + :show-inheritance: + +capellambse.metamodel.oa module +------------------------------- + +.. automodule:: capellambse.metamodel.oa + :members: + :undoc-members: + :show-inheritance: + +capellambse.metamodel.pa module +------------------------------- + +.. automodule:: capellambse.metamodel.pa + :members: + :undoc-members: + :show-inheritance: + +capellambse.metamodel.sa module +------------------------------- + +.. automodule:: capellambse.metamodel.sa + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/code/capellambse.model.rst.txt b/_sources/code/capellambse.model.rst.txt new file mode 100644 index 000000000..bfaf4cd63 --- /dev/null +++ b/_sources/code/capellambse.model.rst.txt @@ -0,0 +1,18 @@ +capellambse.model package +========================= + +.. automodule:: capellambse.model + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +capellambse.model.diagram module +-------------------------------- + +.. automodule:: capellambse.model.diagram + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/code/capellambse.rst.txt b/_sources/code/capellambse.rst.txt new file mode 100644 index 000000000..620699648 --- /dev/null +++ b/_sources/code/capellambse.rst.txt @@ -0,0 +1,58 @@ +capellambse package +=================== + +.. automodule:: capellambse + :no-index: + :members: + :undoc-members: + :show-inheritance: + +Subpackages +----------- + +.. toctree:: + :maxdepth: 4 + + capellambse.aird + capellambse.diagram + capellambse.extensions + capellambse.filehandler + capellambse.loader + capellambse.metamodel + capellambse.model + capellambse.svg + +Submodules +---------- + +capellambse.cli\_helpers module +------------------------------- + +.. automodule:: capellambse.cli_helpers + :members: + :undoc-members: + :show-inheritance: + +capellambse.decl module +----------------------- + +.. automodule:: capellambse.decl + :members: + :undoc-members: + :show-inheritance: + +capellambse.diagram\_cache module +--------------------------------- + +.. automodule:: capellambse.diagram_cache + :members: + :undoc-members: + :show-inheritance: + +capellambse.helpers module +-------------------------- + +.. automodule:: capellambse.helpers + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/code/capellambse.svg.rst.txt b/_sources/code/capellambse.svg.rst.txt new file mode 100644 index 000000000..e8e2069f9 --- /dev/null +++ b/_sources/code/capellambse.svg.rst.txt @@ -0,0 +1,58 @@ +capellambse.svg package +======================= + +.. automodule:: capellambse.svg + :members: + :undoc-members: + :show-inheritance: + +Submodules +---------- + +capellambse.svg.decorations module +---------------------------------- + +.. automodule:: capellambse.svg.decorations + :members: + :undoc-members: + :show-inheritance: + +capellambse.svg.drawing module +------------------------------ + +.. automodule:: capellambse.svg.drawing + :members: + :undoc-members: + :show-inheritance: + +capellambse.svg.generate module +------------------------------- + +.. automodule:: capellambse.svg.generate + :members: + :undoc-members: + :show-inheritance: + +capellambse.svg.helpers module +------------------------------ + +.. automodule:: capellambse.svg.helpers + :members: + :undoc-members: + :show-inheritance: + +capellambse.svg.style module +---------------------------- + +.. automodule:: capellambse.svg.style + :members: + :undoc-members: + :show-inheritance: + +capellambse.svg.symbols module +------------------------------ + +.. automodule:: capellambse.svg.symbols + :members: + :undoc-members: + :show-inheritance: diff --git a/_sources/code/modules.rst.txt b/_sources/code/modules.rst.txt new file mode 100644 index 000000000..34442a353 --- /dev/null +++ b/_sources/code/modules.rst.txt @@ -0,0 +1,7 @@ +py-capellambse +============== + +.. toctree:: + :maxdepth: 4 + + capellambse diff --git a/_sources/development/developing-docs.rst.txt b/_sources/development/developing-docs.rst.txt new file mode 100644 index 000000000..1da7cba73 --- /dev/null +++ b/_sources/development/developing-docs.rst.txt @@ -0,0 +1,31 @@ +.. + SPDX-FileCopyrightText: Copyright DB InfraGO AG + SPDX-License-Identifier: Apache-2.0 + +************************* +Documentation development +************************* + +First, make sure that the necessary dependencies for building documentation are +installed: + +.. code:: bash + + pip install '.[docs]' + +The following command builds the documentation: + +.. code:: bash + + make -C docs html + +The resulting documentation build will be available in ``docs/build/html``. + +Instead, you can also use ``make -C docs serve`` to (re-)build the docs and start a +local server, which can be accessed on http://localhost:8000. + +The following command deletes previously built documentation: + +.. code:: bash + + make -C docs clean diff --git a/_sources/development/how-to-explore-capella-mm.rst.txt b/_sources/development/how-to-explore-capella-mm.rst.txt new file mode 100644 index 000000000..963cba880 --- /dev/null +++ b/_sources/development/how-to-explore-capella-mm.rst.txt @@ -0,0 +1,225 @@ +.. + SPDX-FileCopyrightText: Copyright DB InfraGO AG + SPDX-License-Identifier: Apache-2.0 + +********************************* +How to explore Capella meta-model +********************************* + +Initially the API design was mostly based on our understanding of XML files, +however we soon moved on into exploring the Capella meta-model. Here is a short +summary of how we do it. + +Getting the meta-model sources +############################## + +First of all we need to get the data - the most straight-forward way is to +clone the Capella source code: + +.. code-block:: bash + + mkdir capella-mm && cd capella-mm + git clone https://github.com/eclipse/capella.git + +As there are quite a few files we may want to discover the packages of interest +using ``find``: + +- ``find -name '*.ecore' -o -name '*.genmodel'`` lists all the ECore models and + Generation files and adds Generation viewpoint for related ecore +- ``find -name '*.odesign'`` lists all the Sirius definitions (if you like to + see how the diagram look-and-feel is defined) + +You could open all the related projects right where they are but I'd prefer to +have a clean sandbox. + +.. code-block:: bash + + mkdir capella-metamodel + cp -r capella/common/plugins/org.polarsys.capella.common.data.activity.gen capella-metamodel + cp -r capella/common/plugins/org.polarsys.capella.common.data.behavior.gen capella-metamodel + cp -r capella/common/plugins/org.polarsys.capella.common.data.core.gen capella-metamodel + cp -r capella/common/plugins/org.polarsys.capella.common.libraries.gen capella-metamodel + cp -r capella/common/plugins/org.polarsys.capella.common.re.gen capella-metamodel + cp -r capella/core/plugins/org.polarsys.capella.core.data.gen capella-metamodel + cp -r capella/releng/cdo/plugins/org.polarsys.kitalpha.emde.model.cdo capella-metamodel + cp -r capella/tests/plugins/org.polarsys.capella.test.diagram.layout.ju capella-metamodel + +Now we have all of the meta-model dependencies in one place and can open it as +a single Eclipse project. You could open those with any Eclipse that has EMF +(like the Modeling bundle) but I'd advise using `Capella Studio`__ (open the +link and search for "Studio") for the best experience - it is provisioned with +all the extras that help you visualize / review the meta-model. + +__ https://www.eclipse.org/capella/download.html + +.. image:: ../_static/img/2021-05-09_10-32.jpg +.. image:: ../_static/img/2021-05-09_10-36.jpg + +After import Eclipse may highlight some projects with error or warning sign - +that's fine, we'll let it go for now. + +Before we dive into visualizations, let's have a quick look around. The core of +Capella metamodel is provided by ``org.polarsys.capella.common.data.core.gen`` +project. There you'll find the definitions of the "Capella Layers" and the +enabling "EnginereengConcerns" components. For example, the ``SystemAnalysis`` +is provided by ``ContextArchitecture.ecore``. + +.. image:: ../_static/img/2021-05-09_10-50.jpg + +Even though the default tree-view (triggered by double-click on a ``.core``) is +already giving us something there are much better ways to review the models. +We'll talk about that in the `Visualizing ECores`_ chapter. But first we +should have a look into the package structure and interdependencies. + +Quick intro to package structure +################################ + +If you are unfamiliar with ECore you might be wondering what are those ECore +files anyways. We could say that they act as UML Packages. Every package +contains ontology elements (or UML Classes) and "local" element relationships +(Associations). The packages depend on each-other as elements frequently build +on top of each-other via Generalization relationship. Thats one of the best +things about Capella metamodel - it is defined by UML (or well, structural +subset, but still pretty cool)! + +So, from using Capella we know our model layers - Operational Analysis, System +Analysis, Logical Architecture, Physical Architecture and EPBS. We can locate +the corresponding ECores pretty quick, but what are all the other packages +about? To answer that question we should visualize the package dependency - the +quickest way to do so is to `create a new representation file`__. And after +that follow the steps in `create package dependency overview`__. The result may +look like what we have below: + +__ #create-new-representations-file +__ #package-dependency-overview + +.. image:: ../_static/img/2021-05-09_17-38.jpg + +And even though there are not too many packages in the meta-model, when we +visualize the inter-package dependency it may be a bit difficult to understand. +By the way, the figure above `is also available in SVG`__ - you can open it in +a new tab and zoom-in if you like or scroll down for a simplified one (but +opinionated). + +__ core-pkg-deps-raw.svg + +It almost feels like everything depends on everything but that isn't true +really. We could change perspective and look for the dependencies of an +end-user exposed package, such as Operational Analysis (oa). I'll use Papyrus +to visualize that: + +.. image:: ../_static/img/2021-05-09_17-44.jpg + +When we add all the Capella layers to that picture things get a bit more +interesting. I added some artificial grouping on top of the existing packages +that will help us later on - the artificial groups are: ``CapellaLayers`` - +packages that cover the layers we used to see in the tool; ``CrossLayer`` - +packages that define ontology and patterns that we see in almost every layer; +``Enablers`` - the low level ontology that enables every element. + +.. image:: ../_static/img/2021-05-09_21-21.jpg + +To make a further point on ``CrossLayer``, lets have a closer look at a +Function. We know that Functions are quite similar in how they look and feel +across Capella layers and have a lot in common with OperationalActivity. When +we open ``LogicalArchitecture.ecore`` we see it defines a ``LogicalFunction`` +as a specialization of ``AbstractFunction`` that comes from +``FunctionalAnalysis.ecore``. There is a very nice feature provided by the +`Ecore Tools`__ (that is also included in Capella Studio) - Class Inheritance +view (there is also a tiny `how-to use it below`__). We'll use that to +visualize the way the functions are made. + +__ https://www.eclipse.org/ecoretools/overview.html +__ # + +.. image:: ../_static/img/2021-05-09_22-09.jpg + +Just to be on a safe side I've done the above exercise for +``OperationalActivity``, ``SystemFunction``, ``LogicalFunction`` and +``PhysicalFunction`` - the inheritance tree is exactly the same. I've done this +check for a few other familiar ontology elements and got same result. I think +this gives a feeling for what the ``CrossLayer`` is about - to me that's the +place where most of the magic happens. And this is how the relationship between +the ``CapellaLayers`` and ``CrossLayer`` looks like when we de-noise it a bit: + +.. image:: ../_static/img/2021-05-09_22-39.jpg + +It's been a lengthy chain of thought and to finish on a hopefully useful +visualization - lets have a look at the Class contexts of some things that we +use most frequently + +Visualizations of some frequently used ontology elements +######################################################## + +Below you'll find some quick visualizations for frequently used ontology +elements, grouped by CrossLayer package + +Functional Analysis +******************* + +.. image:: ../_static/img/2021-05-10_22-35.jpg + +.. image:: ../_static/img/2021-05-17_11-50.jpg + +.. image:: ../_static/img/2021-05-10_22-59.jpg + +.. image:: ../_static/img/2021-05-12_21-03.jpg + +State Machines +************** + +.. image:: ../_static/img/2021-05-12_18-18.jpg + +.. image:: ../_static/img/2021-05-13_20-46.jpg + +The figure above is somewhat a "treasure map" to everything related to state +machines. It is made in a semi-automatic way with the help of ECore Tools and +ELK + +Composite Structure +******************* + +.. image:: ../_static/img/2021-05-12_20-10.jpg + +.. image:: ../_static/img/2021-05-12_18-51.jpg + +You may also want to have a look at the Block context below as it defines some +other useful things that a Component (or LogicalComponent) can do. + +.. image:: ../_static/img/2021-05-12_20-06.jpg + +.. image:: ../_static/img/2021-05-12_19-12.jpg + +.. _Visualizing ECores: + +Appendix: Visualizing ECores +############################ + +If you are new to CapellaStudio and Ecore, here are some practical hints for +how to get stuff done, ignore the below otherwise: + +Create new representations file +******************************* + +To start playing with visualizations we need a new representations file +(.aird). It is pretty easy to get there but just in case, there is figure below +to guide you through that. + +.. image:: ../_static/img/2021-05-09_17-36.jpg + +Package dependency overview +*************************** + +To create a package dependency overview for all packages you may follow the +guidance in the figure below: + +.. image:: ../_static/img/2021-05-09_17-57.jpg + +Visualizing class inheritance +***************************** + +There is a very nice feature that allows given a class to show all of its +super-classes (generalizations) and specializations. The figure below gives you +some hints for how to use it: + +.. image:: ../_static/img/2021-05-09_21-46.jpg diff --git a/_sources/development/low-level-api.rst.txt b/_sources/development/low-level-api.rst.txt new file mode 100644 index 000000000..0b01fc56d --- /dev/null +++ b/_sources/development/low-level-api.rst.txt @@ -0,0 +1,307 @@ +.. + SPDX-FileCopyrightText: Copyright DB InfraGO AG + SPDX-License-Identifier: Apache-2.0 + +************* +Low-level API +************* + +.. py:currentmodule:: capellambse.loader.core + +The high level :py:class:`~capellambse.model.MelodyModel`-based API is largely +manually designed, and therefore sometimes does not cover all interesting +objects to a usable level. While we are constantly working on improving the +situation, it's also possible to use the low-level API based directly on the +XML files in order to temporarily work around these shortcomings. This +documentation sheds some light on the inner workings of this low-level API. + +In order to effectively work with it, you need to understand the basics of XML. +It also helps to be familiar with LXML_, which is used to parse and manipulate +the XML trees in memory. + +Unfortunately it's not possible to use LXML's built-in XML serializer. It +produces different whitespace in the XML tree, which confuses Capella's XML +diff-merge algorithm. This is why |project| ships with a custom serializer that +produces the same output format as Capella. It resides in the +:py:mod:`capellambse.loader.exs` module. + +.. _LXML: https://lxml.de/ + +The MelodyLoader object +======================= + +While the main object of interest for the high-level API is the +:py:class:`capellambse.model.MelodyModel` class, for the low-level API it is +the :py:class:`capellambse.loader.core.MelodyLoader`. It offers numerous +methods to search elements, resolve references, ensure model integrity during +certain modifications, and many more. + +The following sections categorize and document the various methods. + +The ``MelodyLoader`` closely works together with its auxiliary class +:py:class:`~capellambse.loader.core.ModelFile`. However, the ``ModelFile`` +mainly plays a role while loading or saving a model from/to disk (or other data +stores), and isn't used much when interacting with an already loaded model. + +.. _api-level-shift: + +Shifting between API levels +=========================== + +High to low-level shift +----------------------- + +Every model object (i.e. instance of ``ModelElement`` or one of its subclasses) +has an attribute ``_element``, which holds a reference to the corresponding +:py:class:`lxml.etree._Element` instance. The low-level API works directly with +these ``_Element`` instances. + +The ``MelodyModel`` object stores a reference to the +:py:class:`~capellambse.loader.core.MelodyLoader` instance. + +Low to high-level shift +----------------------- + +The ModelElement class offers the +:py:meth:`~capellambse.model.ModelElement.from_model` class method, which takes +a ``MelodyModel`` instance and a low-level LXML ``_Element`` as arguments and +constructs a high-level API proxy object from them. This is the way "back up" +to the high-level API. + +.. note:: + + Always call ``from_model`` on the base ``ModelElement`` class, not on its + subclasses. The base class automatically searches for the correct subclass + to instantiate, based on the ``xsi:type`` of the passed XML element. Calling + the method on a subclass directly may inadvertently cause the wrong class to + be picked. + +.. code-block:: python + + >>> myfunc = model.search("LogicalFunction")[0] + >>> el = myfunc._element + >>> el + + >>> from capellambse.model import ModelElement + >>> high_el = ModelElement.from_model(model, el) + >>> high_el == myfunc + True + +When working with multiple objects, it can be desirable to directly construct a +high-level :py:class:`~capellambse.model.ElementList` with them. The +ElementList constructor works similar to ``ModelElement.from_model``, but it +takes a list of elements instead of only a single one. + +.. code-block:: python + + >>> mycomp = model.search("LogicalComponent")[0] + >>> children = mycomp._element.getchildren() + >>> len(children) + 7 + >>> mylist = ElementList(model, children) + >>> mylist + [0] + [1] + [2] + [3] + [4] + [5] + [6] + +Moving along the XML tree +========================= + +In most simple cases, you can use the standard LXML methods in order to select +parent, child and sibling elements. + +.. code-block:: python + + >>> myfunc = model.search("LogicalFunction")[3] + >>> myfunc._element.getparent() + + >>> myfunc._element.getchildren() + [] + >>> myfunc._element.getprevious() + + >>> myfunc._element.getnext() + + +These elements and lists of elements can then be fed into +``ModelElement.from_model`` or the ``ElementList`` constructor respectively in +order to :ref:`return to the high-level API `. + +Capella models support fragmentation into multiple files, which results in +multiple XML trees being loaded into memory. This makes it difficult to +traverse up and down the hierarchy, because in theory every element can be a +fragment boundary – in this case, it does not have a physical parent element, +and ``getparent()`` will return ``None``. A call to ``getchildren()`` or +similar on the (logical) parent element will yield a placeholder which only +contains a reference to the real element, but does not hold any other +information. + +``MelodyLoader`` provides methods to traverse upwards or downwards in the +model's XML tree, while also taking into account fragment boundaries and the +aforementioned placeholder elements. + +.. class:: MelodyLoader + :noindex: + + .. automethod:: iterancestors + :noindex: + .. automethod:: iterchildren_xt + :noindex: + .. automethod:: iterdescendants + :noindex: + .. automethod:: iterdescendants_xt + :noindex: + +Resolving references +==================== + +You will often encounter attributes that contain references to other elements. + +The ``MelodyLoader`` provides the following methods to work with references: + +.. class:: MelodyLoader + :noindex: + + .. automethod:: follow_link + :noindex: + .. automethod:: follow_links + :noindex: + .. automethod:: create_link + :noindex: + +Finding elements elsewhere +========================== + +The low-level API implements the fundamentals for looking up model objects or +finding them by their type. The following methods are involved in these +operations: + +.. class:: MelodyLoader + :noindex: + + .. automethod:: iterall + :noindex: + .. automethod:: iterall_xt + :noindex: + .. automethod:: xpath + :noindex: + .. automethod:: xpath2 + :noindex: + +Manipulating objects +==================== + +.. warning:: + + The low-level API by itself does not do any consistency or validity checks + when modifying a model. Therefore it is very easy to break a model using it, + which can be very hard to recover from. Proceed with caution. + +As ``ModelElement`` instances are simply wrappers around the raw XML elements, +any changes to their attributes are directly reflected by changes to the +attributes or children of the underlying XML element and vice versa. This means +that no special care needs to be taken to keep the high-level and low-level +parts of the API synchronized. + +In many cases, the attribute names of the high-level API match those in the +XML, with the difference that the former uses ``snake_case`` naming (as is +conventional in the Python world), while the latter uses ``camelCase`` naming. +This example shows how the name of a function is accessed and modified using +the low-level API: + +.. code-block:: python + + >>> myfunc = model.search("LogicalFunction")[3] + >>> myfunc.name + 'defend the surrounding area against Intruders' + >>> myfunc._element.attrib["name"] + 'defend the surrounding area against Intruders' + >>> myfunc._element.attrib["name"] = "My Function" + >>> myfunc.name + 'My Function' + +Be aware that the XML usually does not explicitly store attributes that are set +to their default value (as defined by the meta model). In addition to that, the +high-level API often offers convenience shortcuts and reverse lookups that are +not directly reflected by XML attributes. Without at the detailed definitions, +it can therefore be difficult to infer the correct attributes for the low-level +API objects. + +Creating and deleting objects +============================= + +.. warning:: + + Creating or deleting objects through the low-level API is highly + discouraged, as it bears a very high risk of breaking the model. It's + unlikely that we can support you with any breakage that you encounter as a + result of using the low-level API. + + If you need access to model elements and relations that are not yet covered + by our high-level API, please consider contributing and extending it instead + – it's probably easier anyway. ;) + +The ID cache +------------ + +In order to provide instantaneous access to any model element via its UUID, the +MelodyLoader maintains a hashmap containing all UUIDs. This hashmap needs to be +updated when inserting or removing elements in the tree. The following methods +take care of that: + +.. class:: MelodyLoader + :noindex: + + .. automethod:: idcache_index + :noindex: + .. automethod:: idcache_remove + :noindex: + .. automethod:: idcache_rebuild + :noindex: + +Creating objects +---------------- + +Creating a new object with the low-level API is a rather complex process. The +``MelodyLoader`` does provide some basic integrity checks, but most of the +meta-model-aware logic is implemented within the high-level API. + +Before creating a new object, you need to generate and reserve a UUID for it. +This is done using the ``generate_uuid`` method. ``new_uuid`` provides a +context manager around it, which automatically cleans up the model in case +anything went wrong. It also checks that the UUID was properly registered with +the ID cache (see below). It is therefore highly recommended to use +``new_uuid`` over directly calling ``generate_uuid``. Note that even when using +``new_uuid``, you still need to manually call ``idcache_index`` on the newly +inserted element. + +.. class:: MelodyLoader + :noindex: + + .. automethod:: generate_uuid + :noindex: + .. automethod:: new_uuid + :noindex: + +Deleting objects +---------------- + +Inversely to creating new ones, when deleting an object from the XML tree it +also needs to be removed from the ID cache. This is done by calling +``idcache_remove`` (see above) on the element to be removed. Afterwards, delete +the element from its parent using the standard LXML API. + +Saving modifications +==================== + +The ``MelodyLoader`` provides the same ``save()`` method as the high-level +``MelodyModel``. + +.. class:: MelodyLoader + :noindex: + + .. automethod:: save + :noindex: diff --git a/_sources/development/repl.rst.txt b/_sources/development/repl.rst.txt new file mode 100644 index 000000000..e9ad7c89a --- /dev/null +++ b/_sources/development/repl.rst.txt @@ -0,0 +1,16 @@ +.. + SPDX-FileCopyrightText: Copyright DB InfraGO AG + SPDX-License-Identifier: Apache-2.0 + +The |project| REPL +================== + +.. automodule:: capellambse.repl + +.. sphinx_argparse_cli:: + :module: capellambse.repl + :func: main + :hook: + :prog: capellambse/repl.py + :title: Capellambse Repl + :group_title_prefix: diff --git a/_sources/examples/01 Introduction.ipynb.txt b/_sources/examples/01 Introduction.ipynb.txt new file mode 100644 index 000000000..edbbd9edf --- /dev/null +++ b/_sources/examples/01 Introduction.ipynb.txt @@ -0,0 +1,665 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "1a1fe414", + "metadata": {}, + "source": [ + "# Introduction\n", + "\n", + "Welcome to the py-capella-mbse Showcase notebook. This notebook will show you some basic (and not so basic) things that you can get done using this library. For more advanced features have a look around the nearby notebooks.\n", + "\n", + "The below code loads the library and one of the test models:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "3e28d1c9", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import capellambse\n", + "\n", + "path_to_model = \"../../../tests/data/melodymodel/5_0/Melody Model Test.aird\"\n", + "model = capellambse.MelodyModel(path_to_model)\n", + "model" + ] + }, + { + "cell_type": "markdown", + "id": "48ce0c1e", + "metadata": {}, + "source": [ + "Let's go to the first practical example of working with the library!" + ] + }, + { + "cell_type": "markdown", + "id": "7e68b88c-b4bc-4c20-a39f-48094c0eabdd", + "metadata": { + "tags": [] + }, + "source": [ + "## Example 1: Actor functions\n", + "\n", + "The below code will print every Actor available in the Logical Architecture layer" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "abcd8693", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Multiport\n", + "Prof. S. Snape\n", + "Voldemort\n", + "R. Weasley\n", + "Prof. A. P. W. B. Dumbledore\n", + "Harry J. Potter\n" + ] + } + ], + "source": [ + "for actor in model.la.all_actors:\n", + " print(actor.name)" + ] + }, + { + "cell_type": "markdown", + "id": "4ddbf9be", + "metadata": {}, + "source": [ + "but we could also \"zoom-in\" to an actor of interest:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "56bb4b44", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/html": [ + "

Prof. S. Snape (org.polarsys.capella.core.data.la:LogicalComponent)

allocated_functions
  1. LogicalFunction "Teaching" (a7acb298-d14b-4707-a419-fea272434541)
  2. LogicalFunction "maintain a layer of defense for the Sorcerer's Stone" (4a2a7f3c-d223-4d44-94a7-50dd2906a70c)
applied_property_value_groups
  1. PropertyValueGroup "DarkMagic.Power" (2a480409-57d1-46f8-a0ce-e574706a9a7c)
  2. PropertyValueGroup "DarkMagic.Power Level" (b1d7453b-69ab-4d81-ab8b-1e48b5870340)
applied_property_values

(Empty list)

components

(Empty list)

constraints

(Empty list)

context_diagramContext of Prof. S. Snape (uuid: 6f463eed-c77b-4568-8078-beec0536f243_context)
description

Good guy and teacher of brewing arts.

\n", + "
diagrams

(Empty list)

exchanges

(Empty list)

filtering_criteria

(Empty list)

functions
  1. LogicalFunction "Teaching" (a7acb298-d14b-4707-a419-fea272434541)
  2. LogicalFunction "maintain a layer of defense for the Sorcerer's Stone" (4a2a7f3c-d223-4d44-94a7-50dd2906a70c)
is_abstractFalse
is_actorTrue
is_humanTrue
nameProf. S. Snape
ownerLogicalComponentPkg "Structure" (84c0978d-9a32-4f5b-8013-5b0b6adbfd73)
parentLogicalComponentPkg "Structure" (84c0978d-9a32-4f5b-8013-5b0b6adbfd73)
partsBackreference to Part - omitted: can be slow to compute. Display this property directly to show.
physical_links

(Empty list)

physical_paths

(Empty list)

physical_ports

(Empty list)

ports
  1. ComponentPort "CP 1" (b4e39757-b0fd-41ff-a7b8-c9fc36de2ca9)
progress_statusNOT_SET
property_value_groups
  1. PropertyValueGroup "DarkMagic.Power" (2a480409-57d1-46f8-a0ce-e574706a9a7c)
  2. PropertyValueGroup "DarkMagic.Power Level" (b1d7453b-69ab-4d81-ab8b-1e48b5870340)
property_values

(Empty list)

pvmt<capellambse.extensions.pvmt.PropertyValueProxy object at 0x7f496cb3f010>
realized_components

(Empty list)

realized_system_components

(Empty list)

realizing_componentsBackreference to - omitted: can be slow to compute. Display this property directly to show.
realizing_physical_componentsBackreference to PhysicalComponent - omitted: can be slow to compute. Display this property directly to show.
related_exchangesBackreference to ComponentExchange - omitted: can be slow to compute. Display this property directly to show.
requirements

(Empty list)

state_machines

(Empty list)

summaryNone
traces

(Empty list)

uuid6f463eed-c77b-4568-8078-beec0536f243
xtypeorg.polarsys.capella.core.data.la:LogicalComponent
" + ], + "text/plain": [ + "\n", + ".allocated_functions = [0] \n", + " [1] \n", + ".applied_property_value_groups = [0] \n", + " [1] \n", + ".applied_property_values = []\n", + ".components = []\n", + ".constraints = []\n", + ".context_diagram = \n", + ".description = Markup('

Good guy and teacher of brewing arts.

\\n')\n", + ".diagrams = []\n", + ".exchanges = []\n", + ".filtering_criteria = []\n", + ".functions = [0] \n", + " [1] \n", + ".is_abstract = False\n", + ".is_actor = True\n", + ".is_human = True\n", + ".name = 'Prof. S. Snape'\n", + ".owner = \n", + ".parent = \n", + ".parts = ... # backreference to Part - omitted: can be slow to compute\n", + ".physical_links = []\n", + ".physical_paths = []\n", + ".physical_ports = []\n", + ".ports = [0] \n", + ".progress_status = 'NOT_SET'\n", + ".property_value_groups = [0] \n", + " [1] \n", + ".property_values = []\n", + ".pvmt = \n", + ".realized_components = []\n", + ".realized_system_components = []\n", + ".realizing_components = ... # backreference to - omitted: can be slow to compute\n", + ".realizing_physical_components = ... # backreference to PhysicalComponent - omitted: can be slow to compute\n", + ".related_exchanges = ... # backreference to ComponentExchange - omitted: can be slow to compute\n", + ".requirements = []\n", + ".state_machines = []\n", + ".summary = None\n", + ".traces = []\n", + ".uuid = '6f463eed-c77b-4568-8078-beec0536f243'\n", + ".xtype = 'org.polarsys.capella.core.data.la:LogicalComponent'" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.la.all_actors.by_name(\"Prof. S. Snape\")" + ] + }, + { + "cell_type": "markdown", + "id": "30e17ac3", + "metadata": {}, + "source": [ + "We can also turn the above data into a table, for example \"actor function allocation\", using `pandas`.\n", + "\n", + "For this, we first make sure pandas itself is installed, as well as an extension we'll use later." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "400e483d-eca7-4fdd-a9e0-71467e1af8d8", + "metadata": {}, + "outputs": [], + "source": [ + "%pip install -q pandas openpyxl" + ] + }, + { + "cell_type": "markdown", + "id": "acbe1247-e1a1-4da8-a95a-7b41f4836937", + "metadata": {}, + "source": [ + "Now we can use it together with `capellambse`:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "833220d0", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
actorfunctions
0MultiportLAF 1
1Prof. S. SnapeTeaching; maintain a layer of defense for the ...
2Voldemortno functions assigned
3R. Weasleyassist Harry; break school rules
4Prof. A. P. W. B. Dumbledoremanage the school; advise Harry
5Harry J. Potterkill He Who Must Not Be Named
\n", + "
" + ], + "text/plain": [ + " actor \\\n", + "0 Multiport \n", + "1 Prof. S. Snape \n", + "2 Voldemort \n", + "3 R. Weasley \n", + "4 Prof. A. P. W. B. Dumbledore \n", + "5 Harry J. Potter \n", + "\n", + " functions \n", + "0 LAF 1 \n", + "1 Teaching; maintain a layer of defense for the ... \n", + "2 no functions assigned \n", + "3 assist Harry; break school rules \n", + "4 manage the school; advise Harry \n", + "5 kill He Who Must Not Be Named " + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import pandas as pd\n", + "\n", + "data = []\n", + "for actor in model.la.all_actors:\n", + " actor_functions = (\n", + " \"; \".join(function.name for function in actor.functions)\n", + " or \"no functions assigned\"\n", + " )\n", + " data.append({\"actor\": actor.name, \"functions\": actor_functions})\n", + "df = pd.DataFrame(data)\n", + "df" + ] + }, + { + "cell_type": "markdown", + "id": "6e04c482", + "metadata": {}, + "source": [ + "and any `pandas.DataFrame` can always be turned into an Excel Spreadsheet, just like that:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "10af24a2", + "metadata": {}, + "outputs": [], + "source": [ + "df.to_excel(\"01_intro_actor_functions.xlsx\")" + ] + }, + { + "cell_type": "markdown", + "id": "5370bc56", + "metadata": { + "tags": [] + }, + "source": [ + "you can check the resulting file in the folder next to this notebook (right after you run the above cell)\n", + "\n", + "Now that we've seen the basics, lets do something visually cool." + ] + }, + { + "cell_type": "markdown", + "id": "5afcdfdd-79e0-4e07-b321-d92a11f1d082", + "metadata": { + "tags": [] + }, + "source": [ + "## Example 2: working with diagrams\n", + "\n", + "The below code will find some diagrams for us." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "eb5f8747", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "[LAB] Wizzard Education\n", + "[LAB] Test Component Port Filter\n", + "[LAB] Hidden Wizzard Education\n" + ] + } + ], + "source": [ + "for diagram in model.la.diagrams.by_type(\"LAB\"):\n", + " print(diagram.name)" + ] + }, + { + "cell_type": "markdown", + "id": "66609218", + "metadata": {}, + "source": [ + "We can analyze which model objects are shown in a particular diagram." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "71bf090e", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/html": [ + "
  1. Part "Hogwarts" (101ffa60-f8a2-4ea2-a0d8-d10910ceac06)
  2. LogicalFunction "produce Great Wizards" (0e71a0d3-0a18-4671-bba0-71b5f88f95dd)
  3. LogicalFunction "protect Students against the Death Eaters" (264fb47d-67b7-4bdc-8d06-8a0e5139edbf)
  4. Part "Campus" (a3194240-cd17-4998-8f8b-785233487ec3)
  5. Part "School" (018a8ae9-8e8e-4aea-8191-4abf844a79e3)
  6. LogicalFunction "educate Wizards" (957c5799-1d4a-4ac0-b5de-33a65bf1519c)
  7. Part "Whomping Willow" (1188fc31-789b-424f-a2d4-06791873a351)
  8. LogicalFunction "defend the surrounding area against Intruders" (7f2936ab-0b54-4e92-9f0c-85a9f0981959)
  9. Part "Prof. A. P. W. B. Dumbledore" (4c1f2b5d-0641-42c7-911f-7a42928580b8)
  10. LogicalFunction "manage the school" (f708bc29-d69f-42a0-90cc-11fc01054cd0)
  11. LogicalFunction "advise Harry" (beaf5ba4-8fa9-4342-911f-0266bb29be45)
  12. Part "Prof. S. Snape" (ccbad61a-39dc-4af8-8199-3fee30de2f1d)
  13. LogicalFunction "Teaching" (a7acb298-d14b-4707-a419-fea272434541)
  14. LogicalFunction "maintain a layer of defense for the Sorcerer's Stone" (4a2a7f3c-d223-4d44-94a7-50dd2906a70c)
  15. ComponentExchange "Headmaster Responsibilities" (c0bc49e1-8043-4418-8c0a-de6c6b749eab)
  16. ComponentExchange "Teacher Responsibilities" (9cbdd233-aff5-47dd-9bef-9be1277c77c3)
  17. Part "Harry J. Potter" (26543596-7646-4d81-8f15-c4e01ec930a7)
  18. LogicalFunction "kill He Who Must Not Be Named" (aa9931e3-116c-461e-8215-6b9fdbdd4a1b)
  19. Part "R. Weasley" (4d31caaf-210e-4bdf-982e-cdecbc80c947)
  20. LogicalFunction "assist Harry" (c1a42acc-1f53-42bb-8404-77a5c08c414b)
  21. LogicalFunction "break school rules" (edbd1ad4-31c0-4d53-b856-3ffa60e0e99b)
  22. ComponentExchange "Punishment" (85a1fb20-38ea-4d77-acd7-90a8c44dc695)
  23. FunctionalExchange "wizardry" (6545a77d-d224-4662-a5b2-3c016b78e33d)
  24. PortAllocation "" (a4e2bf11-0705-4f20-bf73-5fa5519954f7)
  25. PortAllocation "" (7d31ab50-63d6-46bb-bf53-1716175beae3)
  26. PortAllocation "" (317715cb-376c-4df6-a32c-433e3c081f8d)
  27. ComponentExchange "Learning" (3b3fc202-be5c-49ae-bf2f-1d61daf3bb50)
  28. PortAllocation "" (c1019d06-f376-48e3-832e-634a8ec59463)
  29. PortAllocation "" (4cbdf5fd-7268-470b-9811-b62ad67fded1)
  30. FunctionalExchange "assistance" (241f3901-11f0-4b00-a903-ed158cce73de)
  31. FunctionalExchange "friendship" (1bbb9b2d-517c-4f77-a35c-b3aa3f9422b8)
  32. PortAllocation "" (18fa81ee-8b16-4815-86ea-0c287ace43d8)
  33. ComponentExchange "Help for Harry" (d8655737-39ab-4482-a934-ee847c7ff6bd)
  34. FunctionalExchange "punish" (96a0cf4c-adfe-4490-92d1-bcf75ee77004)
  35. FunctionalExchange "educate & mature" (09efaeb7-2d50-40ed-a4da-46afcb9ca7a1)
  36. FunctionalExchange "Knowledge" (b1a817bc-40a9-4fc4-b62c-8dea4aa28915)
  37. PortAllocation "" (dda7a62a-f25f-46d8-8f05-867c616914c1)
  38. PortAllocation "" (fee1fff5-d751-401b-bb3c-2114a74f0c8a)
  39. PortAllocation "" (0f6e1aa0-942a-40a9-930f-c7df34b9d8eb)
  40. ComponentExchange "Care" (c31491db-817d-44b3-a27c-67e9cc1e06a2)
  41. PortAllocation "" (98760017-b3a3-46ca-b1ef-87eee9ea1600)
  42. PortAllocation "" (74bd0ab3-6a28-4025-822e-90201445a56e)
  43. PortAllocation "" (3ed5ae4f-8a4e-4690-9088-655990a1b77b)
  44. PortAllocation "" (299b98b8-8716-4dbc-bc7e-4b9349778c26)
  45. PortAllocation "" (14cabdd9-c36f-4e01-ad09-110f906ad725)
  46. PortAllocation "" (6d882e28-4208-41d0-b8a5-3a19e1805a34)
  47. FunctionalExchange "educate" (cdc69c5e-ddd8-4e59-8b99-f510400650aa)
  48. PortAllocation "" (c90bb30d-e36b-46a3-a3a1-e39fdcb519be)
" + ], + "text/plain": [ + "[0] \n", + "[1] \n", + "[2] \n", + "[3] \n", + "[4] \n", + "[5] \n", + "[6] \n", + "[7] \n", + "[8] \n", + "[9] \n", + "[10] \n", + "[11] \n", + "[12] \n", + "[13] \n", + "[14] \n", + "[15] \n", + "[16] \n", + "[17] \n", + "[18] \n", + "[19] \n", + "[20] \n", + "[21] \n", + "[22] \n", + "[23] \n", + "[24] \n", + "[25] \n", + "[26] \n", + "[27] \n", + "[28] \n", + "[29] \n", + "[30] \n", + "[31] \n", + "[32] \n", + "[33] \n", + "[34] \n", + "[35] \n", + "[36] \n", + "[37] \n", + "[38] \n", + "[39] \n", + "[40] \n", + "[41] \n", + "[42] \n", + "[43] \n", + "[44] \n", + "[45] \n", + "[46] \n", + "[47] " + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "diagram = model.diagrams.by_name(\"[LAB] Wizzard Education\")\n", + "diagram.nodes" + ] + }, + { + "cell_type": "markdown", + "id": "eaaffccd", + "metadata": {}, + "source": [ + "And again there are warnings - there are quite a few visual filters in Capella and we are not handling all of those yet but mostly those that are used in our projects. The filter coverage will eventally improve, stay tuned." + ] + }, + { + "cell_type": "markdown", + "id": "9ec8f512-6e78-46fe-9dce-ed6fbfc8ad7a", + "metadata": {}, + "source": [ + "And finally, you can display the diagram right in the notebook." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "cc09fd22", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "image/svg+xml": [ + "LFHogwartsproduce GreatWizardsprotectStudentsagainst theDeath EatersCampusSchooleducate WizardsWhomping Willowdefend thesurrounding areaagainst IntrudersProf. A. P. W. B.Dumbledoremanage theschooladviseHarryProf. S. SnapeTeachingmaintain alayer ofdefense fortheSorcerer'sStoneHarry J. Potterkill He WhoMust Not BeNamedR. Weasleyassist Harrybreak schoolruleswizardryHeadmasterResponsibilitiesTeacherResponsibilitiesHelp for HarryKnowledgePunishmentLearningeducate & maturefriendshipassistanceCarepunisheducate" + ], + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "diagram" + ] + }, + { + "cell_type": "markdown", + "id": "f678a3ee-ac7e-4ce4-a8e2-0d41c612800e", + "metadata": {}, + "source": [ + "We use SVG diagrams a lot since they look great in documentation, are zoomable and really light-weight. To make integrating them into a pipeline easier, we also support some derived formats, which you can access using `.as_` style attributes. With some additional dependencies set up (see the README), capellambse can also automatically convert these images to PNG format." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "b5699e75-2e4c-4b8e-81af-51be00ff6dc3", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "'` tag, using the above `data:` URI as `src`\n", + "print(repr( diagram.as_png )[:100], \"...\") # A raw PNG byte stream, which can be written to a `.png` file" + ] + }, + { + "cell_type": "markdown", + "id": "7917bb3a-d1b8-4ce4-9d60-5c0c50b5b1da", + "metadata": {}, + "source": [ + "It's also possible to directly save a diagram to a file by calling its `save` method:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "7798e7f0-61eb-4395-99f2-2cc6dbd46ff1", + "metadata": {}, + "outputs": [], + "source": [ + "diagram.save(\"[LAB] Wizzard Education.svg\", \"svg\", pretty_print=True)" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "93a2e9cf-e599-4c3d-96b7-d6c590e74b16", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "...\n" + ] + } + ], + "source": [ + "with open(\"[LAB] Wizzard Education.svg\") as f:\n", + " print(*f.readlines()[:10], \"...\", sep=\"\")" + ] + }, + { + "cell_type": "markdown", + "id": "21e0b9c2", + "metadata": {}, + "source": [ + "Lets now try something else - we check if function port has any protocols (state machines) underneath:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "cf91c71a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
  1. StateMachine "FaultStates" (06cefb2b-534e-4453-9aba-fe53329197ad)
" + ], + "text/plain": [ + "[0] " + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "fnc = model.la.all_functions.by_name(\n", + " \"defend the surrounding area against Intruders\"\n", + ")\n", + "stms = fnc.outputs[0].state_machines\n", + "stms" + ] + }, + { + "cell_type": "markdown", + "id": "dc8069df", + "metadata": {}, + "source": [ + "and we can also check what states it could have:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "b5751a0d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
  1. State "normal defence" (e494e247-efce-4258-9cc6-fd799dbb0adf)
  2. State "erroneous defence" (81f3de46-4596-41b0-8569-c3c21161a2f6)
  3. State "no defence" (5b6a03d8-0ef9-4b2b-9a50-a745f490d663)
" + ], + "text/plain": [ + "[0] \n", + "[1] \n", + "[2] " + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "stms[0].regions[0].states" + ] + }, + { + "cell_type": "markdown", + "id": "86e23011", + "metadata": {}, + "source": [ + "This concludes our introduction. There is a lot more you can do with the library - feel free to explore the examples collection or create an issue to ask for a specific use-case example and you may see it around pretty soon." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.5" + }, + "vscode": { + "interpreter": { + "hash": "c5ea7dc634d8047a259e5b898f154d237fbe6934b444b1a949475949608d751e" + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/_sources/examples/02 Intro to Physical Architecture API.ipynb.txt b/_sources/examples/02 Intro to Physical Architecture API.ipynb.txt new file mode 100644 index 000000000..c691c26bb --- /dev/null +++ b/_sources/examples/02 Intro to Physical Architecture API.ipynb.txt @@ -0,0 +1,762 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "b02a2030", + "metadata": {}, + "source": [ + "# Introduction to Physical Architecture API\n", + "\n", + "**Note**: In this notebook we will use `pandas` dataframes library to construct and visualize tables, **if you don't have pandas installed** in the current environment you may want to do so by running the cell below." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "4c181cfb", + "metadata": { + "editable": true, + "slideshow": { + "slide_type": "" + }, + "tags": [] + }, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Requirement already satisfied: pandas in /home/dahbar/projects/py-capellambse/.venv/lib/python3.11/site-packages (2.1.1)\n", + "Requirement already satisfied: numpy>=1.23.2 in /home/dahbar/projects/py-capellambse/.venv/lib/python3.11/site-packages (from pandas) (1.26.0)\n", + "Requirement already satisfied: python-dateutil>=2.8.2 in /home/dahbar/projects/py-capellambse/.venv/lib/python3.11/site-packages (from pandas) (2.8.2)\n", + "Requirement already satisfied: pytz>=2020.1 in /home/dahbar/projects/py-capellambse/.venv/lib/python3.11/site-packages (from pandas) (2023.3.post1)\n", + "Requirement already satisfied: tzdata>=2022.1 in /home/dahbar/projects/py-capellambse/.venv/lib/python3.11/site-packages (from pandas) (2023.3)\n", + "Requirement already satisfied: six>=1.5 in /home/dahbar/projects/py-capellambse/.venv/lib/python3.11/site-packages (from python-dateutil>=2.8.2->pandas) (1.16.0)\n", + "Note: you may need to restart the kernel to use updated packages.\n" + ] + } + ], + "source": [ + "%pip install pandas" + ] + }, + { + "cell_type": "markdown", + "id": "3d39f975", + "metadata": {}, + "source": [ + "The cell below loads our test model so we could play with it and silences warnings." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "1386d2f7", + "metadata": { + "scrolled": true + }, + "outputs": [], + "source": [ + "import logging\n", + "\n", + "import pandas as pd\n", + "\n", + "import capellambse\n", + "\n", + "logging.getLogger().setLevel(logging.CRITICAL)\n", + "path_to_model = \"../../../tests/data/melodymodel/5_0/Melody Model Test.aird\"\n", + "model = capellambse.MelodyModel(path_to_model)" + ] + }, + { + "cell_type": "markdown", + "id": "9f73eb7e", + "metadata": {}, + "source": [ + "but before we jump into code, lets have a look first at Capella metamodel concerning the Physical Architecture layer (PA).\n", + "\n", + "Things in PA are very similar to what we see in SysML when it comes to `ibd`s (Internal Block Diagrams) - the boxes we see on those are `Part`s that are instanciated from `Block` objects. Same happens in Capella - the boxes we see on `PAB` diagrams are `Parts` that were instanciated from `PhysicalComponent`s. Here also comes the very special difference of Capella - unless you explicitly enable **part re-use**, `PhysicalComponent` will always have only one `Part`. This is the default behavior of Capella. \n", + "\n", + "Our API should support both cases but at the moment we don't use models with **part re-use** enabled in production yet and so don't test the library against this case. Yet we do implement Parts and support many parts - one component relationship model.\n", + "\n", + "One more issue to mention - rendering PA diagrams outside of Capella was never a high priority so the resulting representations of PABs rendered without Capella are not very accurate at the moment. We hope to improve it soon though. If you still do want to see how it looks like when we render it right now - uncomment the `# diagram` in the cell below" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "8b555976", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "image/svg+xml": [ + "VehicleEquipment compartmentServerCompute Card 1Card 1 OSCamera Driver SWCApp 1 SWCCooling FanX2Compute Card 2Card 2 OSApp 2 SWCX2Network SwitchSwitch FirmwareSwitch ConfigurationP1P3P2Sensor compartmentCameraAssemblyCameraFirmwarecard...PL 1Eth Cable 2Eth Cable 3C 1C 2C 3C 4C 5C 6card1 - card2 connectionD 7D 8PL 1C 10" + ], + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "diagram = model.pa.diagrams.by_name(\"[PAB] A sample vehicle arch\")\n", + "diagram" + ] + }, + { + "cell_type": "markdown", + "id": "1c479ca3", + "metadata": {}, + "source": [ + "## Example 1: List components that are visible on a diagram\n", + "\n", + "To start, let's get all parts on that diagram and turn them into PhysicalComponents." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "711574aa", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/html": [ + "
  1. PhysicalComponent "Vehicle" (b327d900-abd2-4138-a111-9ff0684739d8)
  2. PhysicalComponent "Equipment compartment" (3d68852d-fcc0-452c-af12-a2fbe22f81fa)
  3. PhysicalComponent "Server" (9137f463-7497-40c2-b20a-897158fdba9a)
  4. PhysicalComponent "Compute Card 1" (63be604e-883e-41ea-9023-fc74f29906fe)
  5. PhysicalComponent "Card 1 OS" (7b188ad0-0d82-4b2c-9913-45292e537871)
  6. PhysicalComponent "Camera Driver SWC" (74067f56-33bf-47f5-bb8b-f3604097f653)
  7. PhysicalComponent "App 1 SWC" (b80a6fcc-8d35-4675-a2e6-60efcbd61e27)
  8. PhysicalComponent "Cooling Fan" (65e82f3f-c5b7-44c1-bfea-8e20bb0230be)
  9. PhysicalComponent "Compute Card 2" (3a982128-3281-4d37-8838-a6058b7a25d9)
  10. PhysicalComponent "Card 2 OS" (09e19313-c824-467f-9fb5-95ed8b4e2d51)
  11. PhysicalComponent "App 2 SWC" (ca5af12c-5259-4844-aaac-9ca9f84aa90b)
  12. PhysicalComponent "Network Switch" (b51ccc6f-5f96-4e28-b90e-72463a3b50cf)
  13. PhysicalComponent "Switch Firmware" (c78b5d7c-be0c-4ed4-9d12-d447cb39304e)
  14. PhysicalComponent "Switch Configuration" (23c47b69-7352-481d-be88-498fb351adbe)
  15. PhysicalComponent "Sensor compartment" (3f416925-9d8a-4e9c-99f3-e912efb23d2f)
  16. PhysicalComponent "Camera Assembly" (5bfc516b-c20d-4007-9a38-5ba0e889d0a4)
  17. PhysicalComponent "Camera Firmware" (db2d86d7-48ee-478b-a6fc-d6387ab0032e)
" + ], + "text/plain": [ + "[0] \n", + "[1] \n", + "[2] \n", + "[3] \n", + "[4] \n", + "[5] \n", + "[6] \n", + "[7] \n", + "[8] \n", + "[9] \n", + "[10] \n", + "[11] \n", + "[12] \n", + "[13] \n", + "[14] \n", + "[15] \n", + "[16] " + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "components_on_diagram = diagram.nodes.by_type(\"Part\").map(\"type\")\n", + "components_on_diagram" + ] + }, + { + "cell_type": "markdown", + "id": "aab38c3e", + "metadata": {}, + "source": [ + "We could also get all components across the entire PA layer by doing `model.pa.all_components`, but we will not go there in this example.\n", + "\n", + "We can review any single component from that list above:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "21ef5c4d", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/home/dahbar/projects/py-capellambse/capellambse/model/common/element.py:295: FutureWarning: PhysicalComponent.functions is deprecated, use allocated_functions instead\n", + " value = getattr(self, attr)\n", + "/home/dahbar/projects/py-capellambse/capellambse/model/common/element.py:363: FutureWarning: PhysicalComponent.functions is deprecated, use allocated_functions instead\n", + " value = getattr(self, attr)\n" + ] + }, + { + "data": { + "text/html": [ + "

Cooling Fan (org.polarsys.capella.core.data.pa:PhysicalComponent)

allocated_functions

(Empty list)

applied_property_value_groups

(Empty list)

applied_property_values

(Empty list)

components

(Empty list)

constraints

(Empty list)

context_diagramContext of Cooling Fan (uuid: 65e82f3f-c5b7-44c1-bfea-8e20bb0230be_context)
deployed_components

(Empty list)

deploying_componentsBackreference to PhysicalComponent - omitted: can be slow to compute. Display this property directly to show.
description
diagrams

(Empty list)

exchanges

(Empty list)

filtering_criteria

(Empty list)

functions

(Empty list)

is_abstractFalse
is_actorFalse
is_humanFalse
kind<Kind.HARDWARE: 2>
nameCooling Fan
nature<Nature.NODE: 1>
owned_components

(Empty list)

ownerPhysicalComponent "Compute Card 1" (63be604e-883e-41ea-9023-fc74f29906fe)
parentPhysicalComponent "Compute Card 1" (63be604e-883e-41ea-9023-fc74f29906fe)
partsBackreference to Part - omitted: can be slow to compute. Display this property directly to show.
physical_links

(Empty list)

physical_paths

(Empty list)

physical_ports

(Empty list)

ports

(Empty list)

progress_statusNOT_SET
property_value_groups

(Empty list)

property_values

(Empty list)

pvmt<capellambse.extensions.pvmt.PropertyValueProxy object at 0x7f4a9f006190>
realized_components

(Empty list)

realized_logical_components

(Empty list)

realizing_componentsBackreference to - omitted: can be slow to compute. Display this property directly to show.
related_exchangesBackreference to ComponentExchange - omitted: can be slow to compute. Display this property directly to show.
requirements

(Empty list)

state_machines

(Empty list)

summaryNone
traces

(Empty list)

uuid65e82f3f-c5b7-44c1-bfea-8e20bb0230be
xtypeorg.polarsys.capella.core.data.pa:PhysicalComponent
" + ], + "text/plain": [ + "\n", + ".allocated_functions = []\n", + ".applied_property_value_groups = []\n", + ".applied_property_values = []\n", + ".components = []\n", + ".constraints = []\n", + ".context_diagram = \n", + ".deployed_components = []\n", + ".deploying_components = ... # backreference to PhysicalComponent - omitted: can be slow to compute\n", + ".description = ''\n", + ".diagrams = []\n", + ".exchanges = []\n", + ".filtering_criteria = []\n", + ".functions = []\n", + ".is_abstract = False\n", + ".is_actor = False\n", + ".is_human = False\n", + ".kind = \n", + ".name = 'Cooling Fan'\n", + ".nature = \n", + ".owned_components = []\n", + ".owner = \n", + ".parent = \n", + ".parts = ... # backreference to Part - omitted: can be slow to compute\n", + ".physical_links = []\n", + ".physical_paths = []\n", + ".physical_ports = []\n", + ".ports = []\n", + ".progress_status = 'NOT_SET'\n", + ".property_value_groups = []\n", + ".property_values = []\n", + ".pvmt = \n", + ".realized_components = []\n", + ".realized_logical_components = []\n", + ".realizing_components = ... # backreference to - omitted: can be slow to compute\n", + ".related_exchanges = ... # backreference to ComponentExchange - omitted: can be slow to compute\n", + ".requirements = []\n", + ".state_machines = []\n", + ".summary = None\n", + ".traces = []\n", + ".uuid = '65e82f3f-c5b7-44c1-bfea-8e20bb0230be'\n", + ".xtype = 'org.polarsys.capella.core.data.pa:PhysicalComponent'" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "components_on_diagram[7]" + ] + }, + { + "cell_type": "markdown", + "id": "22343924", + "metadata": {}, + "source": [ + "However we may need just a few of those attributes in a view.\n", + "\n", + "Now that we have a list of components lets collect some of the attributes of interest in a table. To keep it simple we'll introduce an attribute extractor function that will turn fields of interest into a nice dictionary." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "63ff286c", + "metadata": {}, + "outputs": [], + "source": [ + "def extract_attrs_of_interest(component):\n", + " return {\n", + " \"name\": component.name,\n", + " \"nature\": component.nature,\n", + " \"kind\": component.kind,\n", + " \"components\": \"; \".join(cmp.name for cmp in component.components),\n", + " }" + ] + }, + { + "cell_type": "markdown", + "id": "55d509d0", + "metadata": {}, + "source": [ + "We can then apply that extractor function to our list of components and use `pandas` to display it for us in a tabular form:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "6d8ff25c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
namenaturekindcomponents
0VehicleNODESOFTWARE_DEPLOYMENT_UNITEquipment compartment; Sensor compartment
1Equipment compartmentNODEFACILITIESServer; Network Switch
2ServerNODEHARDWARECompute Card 1; Compute Card 2
3Compute Card 1NODEHARDWARECard 1 OS; Cooling Fan
4Card 1 OSBEHAVIORSERVICESCamera Driver SWC; App 1 SWC
5Camera Driver SWCBEHAVIORSOFTWARE
6App 1 SWCBEHAVIORSOFTWARE
7Cooling FanNODEHARDWARE
8Compute Card 2NODEHARDWARECard 2 OS
9Card 2 OSBEHAVIORSOFTWAREApp 2 SWC
10App 2 SWCBEHAVIORSOFTWARE
11Network SwitchNODEHARDWARESwitch Firmware; Switch Configuration
12Switch FirmwareBEHAVIORHARDWARE_COMPUTER
13Switch ConfigurationBEHAVIORDATA
14Sensor compartmentNODEFACILITIESCamera Assembly
15Camera AssemblyNODEHARDWARECamera Firmware
16Camera FirmwareBEHAVIORSOFTWARE_EXECUTION_UNIT
\n", + "
" + ], + "text/plain": [ + " name nature kind \\\n", + "0 Vehicle NODE SOFTWARE_DEPLOYMENT_UNIT \n", + "1 Equipment compartment NODE FACILITIES \n", + "2 Server NODE HARDWARE \n", + "3 Compute Card 1 NODE HARDWARE \n", + "4 Card 1 OS BEHAVIOR SERVICES \n", + "5 Camera Driver SWC BEHAVIOR SOFTWARE \n", + "6 App 1 SWC BEHAVIOR SOFTWARE \n", + "7 Cooling Fan NODE HARDWARE \n", + "8 Compute Card 2 NODE HARDWARE \n", + "9 Card 2 OS BEHAVIOR SOFTWARE \n", + "10 App 2 SWC BEHAVIOR SOFTWARE \n", + "11 Network Switch NODE HARDWARE \n", + "12 Switch Firmware BEHAVIOR HARDWARE_COMPUTER \n", + "13 Switch Configuration BEHAVIOR DATA \n", + "14 Sensor compartment NODE FACILITIES \n", + "15 Camera Assembly NODE HARDWARE \n", + "16 Camera Firmware BEHAVIOR SOFTWARE_EXECUTION_UNIT \n", + "\n", + " components \n", + "0 Equipment compartment; Sensor compartment \n", + "1 Server; Network Switch \n", + "2 Compute Card 1; Compute Card 2 \n", + "3 Card 1 OS; Cooling Fan \n", + "4 Camera Driver SWC; App 1 SWC \n", + "5 \n", + "6 \n", + "7 \n", + "8 Card 2 OS \n", + "9 App 2 SWC \n", + "10 \n", + "11 Switch Firmware; Switch Configuration \n", + "12 \n", + "13 \n", + "14 Camera Assembly \n", + "15 Camera Firmware \n", + "16 " + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "pd.DataFrame(list(map(extract_attrs_of_interest, components_on_diagram)))" + ] + }, + { + "cell_type": "markdown", + "id": "91a9ab15", + "metadata": {}, + "source": [ + "## Example 2: Create HW-SW allocation table\n", + "\n", + "Now let's assume that components of \"Node\" nature are hardware things and \"Behavior\" corresponds to software components. Assuming that, let's identify leaf hardware components (lowest replaceable units), and for each of those indicate which software components they have.\n", + "\n", + "To get there, let's first filter out the list of components of \"Node\" nature that have at least one subcomponent of \"Behavior\" nature. We'll use the `.filter` method of our object list. To use that method we'll need to provide a function or lambda that determines whether an object should be selected. We can also make use of the implicit \"truthiness\" of non-empty list attributes:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "01644c9d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
  1. PhysicalComponent "Sub PC" (793e6da2-d019-4716-a5c5-af8ad550ca5e)
  2. PhysicalComponent "Deploy Sub PC" (8a6c6ec9-095d-4d8b-9728-69bc79af5f27)
  3. PhysicalComponent "Compute Card 1" (63be604e-883e-41ea-9023-fc74f29906fe)
  4. PhysicalComponent "Compute Card 2" (3a982128-3281-4d37-8838-a6058b7a25d9)
  5. PhysicalComponent "Network Switch" (b51ccc6f-5f96-4e28-b90e-72463a3b50cf)
  6. PhysicalComponent "Camera Assembly" (5bfc516b-c20d-4007-9a38-5ba0e889d0a4)
  7. PhysicalComponent "Computer" (b14ff190-9198-4d05-95db-b121c11e9f17)
  8. PhysicalComponent "ISP Network" (221cef9f-0582-419c-b67e-96ddb678dd4c)
" + ], + "text/plain": [ + "[0] \n", + "[1] \n", + "[2] \n", + "[3] \n", + "[4] \n", + "[5] \n", + "[6] \n", + "[7] " + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cmps = model.pa.all_components[1:].by_nature(\"NODE\")\n", + "# Note: the above [1:] assumes that 0th component is the root component and is not of interest (+ see issue #41)\n", + "cmps_with_sw = cmps.filter(lambda i: i.components.by_nature(\"BEHAVIOR\"))\n", + "cmps_with_sw" + ] + }, + { + "cell_type": "markdown", + "id": "4286bd9d", + "metadata": {}, + "source": [ + "For sure we could come to the above list filtering by `kind` attribute, however in practice not all projects strictly use the `kind` attribute / it needs manual setting and maintenance and therefore is a bit less reliable.\n", + "\n", + "Our next stop is to list the SW components of those HW components. As SW components may be nested (i.e. apps on OS or partitions, etc.) we would simply \"flatten\" that hierarchy. We can create function `get_sw_components` that would recursively crawl down the SW components tree and give us back a flat list and test it on one component." + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "70abf6f9", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
  1. PhysicalComponent "Card 1 OS" (7b188ad0-0d82-4b2c-9913-45292e537871)
  2. PhysicalComponent "Camera Driver SWC" (74067f56-33bf-47f5-bb8b-f3604097f653)
  3. PhysicalComponent "App 1 SWC" (b80a6fcc-8d35-4675-a2e6-60efcbd61e27)
" + ], + "text/plain": [ + "[0] \n", + "[1] \n", + "[2] " + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def get_sw_components(sw_component):\n", + " subcmp = sw_component.components.by_nature(\"BEHAVIOR\")\n", + " for cmp in subcmp:\n", + " subcmp += get_sw_components(cmp)\n", + " return subcmp\n", + "\n", + "\n", + "get_sw_components(cmps_with_sw.by_name(\"Compute Card 1\"))" + ] + }, + { + "cell_type": "markdown", + "id": "8086d62c", + "metadata": {}, + "source": [ + "Let's apply the `get_sw_components` function to the complete list of components with SW, `cmps_with_sw`, and turn the results into a table. In this table we'll serialize SW components into a semicolon-separated string:" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "faa00eb0", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
hardware_componentdeployed_sw_components
0Sub PCPC 16
1Deploy Sub PCPC 17
2Compute Card 1Card 1 OS; Camera Driver SWC; App 1 SWC
3Compute Card 2Card 2 OS; App 2 SWC
4Network SwitchSwitch Firmware; Switch Configuration
5Camera AssemblyCamera Firmware
6ComputerMail client
7ISP NetworkMail server
\n", + "
" + ], + "text/plain": [ + " hardware_component deployed_sw_components\n", + "0 Sub PC PC 16\n", + "1 Deploy Sub PC PC 17\n", + "2 Compute Card 1 Card 1 OS; Camera Driver SWC; App 1 SWC\n", + "3 Compute Card 2 Card 2 OS; App 2 SWC\n", + "4 Network Switch Switch Firmware; Switch Configuration\n", + "5 Camera Assembly Camera Firmware\n", + "6 Computer Mail client\n", + "7 ISP Network Mail server" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "def describe_hw_component_sw_allocations(hw_component):\n", + " return {\n", + " \"hardware_component\": hw_component.name,\n", + " \"deployed_sw_components\": \"; \".join(\n", + " i.name for i in get_sw_components(hw_component)\n", + " ),\n", + " }\n", + "\n", + "\n", + "df = pd.DataFrame(\n", + " list(map(describe_hw_component_sw_allocations, cmps_with_sw))\n", + ")\n", + "df" + ] + }, + { + "cell_type": "markdown", + "id": "851b0540", + "metadata": {}, + "source": [ + "To complete the picture, we could also list all HW components that don't have software (so that a sanity check could be performed):" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "e48d4998", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
  1. PhysicalComponent "PC 1" (8a6d68c8-ac3d-4654-a07e-ada7adeed09f)
  2. PhysicalComponent "PC 3" (f5d7980d-e1e9-4515-8bb0-be7e80ac5839)
  3. PhysicalComponent "Vehicle" (a2c7f619-b38a-4b92-94a5-cbaa631badfc)
  4. PhysicalComponent "Vehicle" (b327d900-abd2-4138-a111-9ff0684739d8)
  5. PhysicalComponent "Equipment compartment" (3d68852d-fcc0-452c-af12-a2fbe22f81fa)
  6. PhysicalComponent "Server" (9137f463-7497-40c2-b20a-897158fdba9a)
  7. PhysicalComponent "Cooling Fan" (65e82f3f-c5b7-44c1-bfea-8e20bb0230be)
  8. PhysicalComponent "Sensor compartment" (3f416925-9d8a-4e9c-99f3-e912efb23d2f)
  9. PhysicalComponent "Router" (69bfe48d-78f0-4b1f-89c0-917dc2339ff9)
  10. PhysicalComponent "PA 1" (a0847e9c-8b82-407d-8143-e908e2db97a1)
" + ], + "text/plain": [ + "[0] \n", + "[1] \n", + "[2] \n", + "[3] \n", + "[4] \n", + "[5] \n", + "[6] \n", + "[7] \n", + "[8] \n", + "[9] " + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cmps_without_sw = cmps.filter(lambda i: not i.components.by_nature(\"BEHAVIOR\"))\n", + "cmps_without_sw" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/_sources/examples/03 Data Values.ipynb.txt b/_sources/examples/03 Data Values.ipynb.txt new file mode 100644 index 000000000..e4fee37a8 --- /dev/null +++ b/_sources/examples/03 Data Values.ipynb.txt @@ -0,0 +1,604 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "1a1fe414", + "metadata": {}, + "source": [ + "# Data Types and Data Values\n", + "\n", + "This Jupyter notebook demonstrates how Data Values in Capella can be handled.\n", + "First, let's load the model again..." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "3e28d1c9", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Cannot load PVMT extension: ValueError: Provided model does not have a PropertyValuePkg\n", + "Property values are not available in this model\n" + ] + }, + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import capellambse\n", + "\n", + "path_to_model = \"../../../tests/data/melodymodel/5_2/Melody Model Test.aird\"\n", + "model = capellambse.MelodyModel(path_to_model)\n", + "model" + ] + }, + { + "cell_type": "markdown", + "id": "48ce0c1e", + "metadata": {}, + "source": [ + "As explained in the notebook 01, please ignore the warning about PVMT missing above." + ] + }, + { + "cell_type": "markdown", + "id": "7e68b88c-b4bc-4c20-a39f-48094c0eabdd", + "metadata": { + "tags": [] + }, + "source": [ + "## Example 1: Look into the Data package of the Logical Architecture\n", + "\n", + "Let's have a look into the data package on the Logical Architecture. It works the same with the other architectures, just replace the `oa` accordingly. We can see the defined classes, collections, enuemrations, and so on." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "da8b86b7", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "

Data (org.polarsys.capella.core.data.information:DataPkg)

applied_property_value_groups

(Empty list)

applied_property_values

(Empty list)

classes
  1. Class "Wand" (c710f1c2-ede6-444e-9e2b-0ff30d7fd040)
  2. Class "Class 2" (1adf8097-18f9-474e-b136-6c845fc6d9e9)
  3. Class "Branch" (2b34c799-769c-42f2-8a1b-4533dba209a0)
collections

(Empty list)

complex_values

(Empty list)

constraints

(Empty list)

description
diagrams
  1. [CDB] Harry's Wand (uuid: _kqdwsF9REe2rko4oG1H6IQ)
enumerations
  1. Enumeration "Wand Core" (546cd75a-c7ac-4e07-9d2d-8a1f93d82419)
  2. Enumeration "Wand Wood" (60314ce6-bc96-4b57-8965-7187241148ae)
filtering_criteria

(Empty list)

nameData
packages
  1. DataPkg "Wand Objects" (880af86d-6fac-4fba-a559-2fffd036fa9a)
parentLogicalArchitecture "Logical Architecture" (853cb005-cba0-489b-8fe3-bb694ad4543b)
progress_statusNOT_SET
property_value_groups

(Empty list)

property_values

(Empty list)

requirements

(Empty list)

summaryNone
traces

(Empty list)

unions

(Empty list)

uuid39e99d4a-a32c-4b70-b4b6-d03fec612e17
xtypeorg.polarsys.capella.core.data.information:DataPkg
" + ], + "text/plain": [ + "\n", + ".applied_property_value_groups = []\n", + ".applied_property_values = []\n", + ".classes = [0] \n", + " [1] \n", + " [2] \n", + ".collections = []\n", + ".complex_values = []\n", + ".constraints = []\n", + ".description = ''\n", + ".diagrams = [0] \n", + ".enumerations = [0] \n", + " [1] \n", + ".filtering_criteria = []\n", + ".name = 'Data'\n", + ".packages = [0] \n", + ".parent = \n", + ".progress_status = 'NOT_SET'\n", + ".property_value_groups = []\n", + ".property_values = []\n", + ".requirements = []\n", + ".summary = None\n", + ".traces = []\n", + ".unions = []\n", + ".uuid = '39e99d4a-a32c-4b70-b4b6-d03fec612e17'\n", + ".xtype = 'org.polarsys.capella.core.data.information:DataPkg'" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.la.data_package" + ] + }, + { + "cell_type": "markdown", + "id": "e01263c2", + "metadata": {}, + "source": [ + "For Enumerations we can see the Literals assigned to it. We can see both the literals that have been inherited by the specialized super class, and the literals that are defined within this model element (own_literals)." + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "abcd8693", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "

Wand Core (org.polarsys.capella.core.data.information.datatype:Enumeration)

applied_property_value_groups

(Empty list)

applied_property_values

(Empty list)

constraints

(Empty list)

description
diagrams

(Empty list)

filtering_criteria

(Empty list)

literals
  1. EnumerationLiteral "Unicorn Hair" (79263437-b45d-410d-a264-8aa28d7574d1)
  2. EnumerationLiteral "Dragon Heartstring" (6bb9876c-f3a7-4d59-a6d1-819372368fa0)
  3. EnumerationLiteral "Pheonix Feather" (492fd9ca-88cb-4e9d-b92e-df14a1c1543b)
  4. EnumerationLiteral "Thestral Tail-Hair" (1e73d13b-1c26-4537-834d-e467f993befe)
nameWand Core
owned_literals
  1. EnumerationLiteral "Unicorn Hair" (79263437-b45d-410d-a264-8aa28d7574d1)
  2. EnumerationLiteral "Dragon Heartstring" (6bb9876c-f3a7-4d59-a6d1-819372368fa0)
  3. EnumerationLiteral "Pheonix Feather" (492fd9ca-88cb-4e9d-b92e-df14a1c1543b)
  4. EnumerationLiteral "Thestral Tail-Hair" (1e73d13b-1c26-4537-834d-e467f993befe)
parentDataPkg "Data" (39e99d4a-a32c-4b70-b4b6-d03fec612e17)
progress_statusNOT_SET
property_value_groups

(Empty list)

property_values

(Empty list)

requirements

(Empty list)

subBackreference to Enumeration - omitted: can be slow to compute. Display this property directly to show.
summaryNone
superNone
traces

(Empty list)

uuid546cd75a-c7ac-4e07-9d2d-8a1f93d82419
xtypeorg.polarsys.capella.core.data.information.datatype:Enumeration
" + ], + "text/plain": [ + "\n", + ".applied_property_value_groups = []\n", + ".applied_property_values = []\n", + ".constraints = []\n", + ".description = ''\n", + ".diagrams = []\n", + ".filtering_criteria = []\n", + ".literals = [0] \n", + " [1] \n", + " [2] \n", + " [3] \n", + ".name = 'Wand Core'\n", + ".owned_literals = [0] \n", + " [1] \n", + " [2] \n", + " [3] \n", + ".parent = \n", + ".progress_status = 'NOT_SET'\n", + ".property_value_groups = []\n", + ".property_values = []\n", + ".requirements = []\n", + ".sub = ... # backreference to Enumeration - omitted: can be slow to compute\n", + ".summary = None\n", + ".super = None\n", + ".traces = []\n", + ".uuid = '546cd75a-c7ac-4e07-9d2d-8a1f93d82419'\n", + ".xtype = 'org.polarsys.capella.core.data.information.datatype:Enumeration'" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.la.data_package.enumerations[0]" + ] + }, + { + "cell_type": "markdown", + "id": "dfcbe9cf", + "metadata": {}, + "source": [ + "Let's do the same for a class. Again, we can see the properties of the super class and the properties of the own model element.\n", + "\n", + "![Harry's Wand](../_static/img/harrys_wand.png)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "a968821f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "

Wand (org.polarsys.capella.core.data.information:Class)

applied_property_value_groups

(Empty list)

applied_property_values

(Empty list)

constraints

(Empty list)

description
diagrams

(Empty list)

filtering_criteria

(Empty list)

is_abstractFalse
is_finalFalse
is_primitiveFalse
nameWand
owned_properties
  1. Property "owner" (9b1f6d9c-58d6-4e5e-a0f1-822cb5440a51)
  2. Property "core" (32f70910-a1fd-4ec9-8d22-4c585ceaf7b9)
  3. Property "wood" (df884a71-e774-49e1-8aee-0a675179c647)
parentDataPkg "Data" (39e99d4a-a32c-4b70-b4b6-d03fec612e17)
progress_statusNOT_SET
properties
  1. Property "owner" (9b1f6d9c-58d6-4e5e-a0f1-822cb5440a51)
  2. Property "core" (32f70910-a1fd-4ec9-8d22-4c585ceaf7b9)
  3. Property "wood" (df884a71-e774-49e1-8aee-0a675179c647)
  4. Property "wood" (87f356eb-c79e-4155-b297-8d733685621c)
property_value_groups

(Empty list)

property_values

(Empty list)

realizations
  1. InformationRealization "" (793520e1-acbf-4f93-a219-587840aa5a3b)
realized_byBackreference to Class - omitted: can be slow to compute. Display this property directly to show.
realized_classes
  1. Class "SpecialTwist" (0fef2887-04ce-4406-b1a1-a1b35e1ce0f3)
requirements

(Empty list)

state_machines

(Empty list)

subBackreference to Class - omitted: can be slow to compute. Display this property directly to show.
summaryNone
superClass "Branch" (2b34c799-769c-42f2-8a1b-4533dba209a0)
traces

(Empty list)

uuidc710f1c2-ede6-444e-9e2b-0ff30d7fd040
visibility<VisibilityKind.UNSET: 1>
xtypeorg.polarsys.capella.core.data.information:Class
" + ], + "text/plain": [ + "\n", + ".applied_property_value_groups = []\n", + ".applied_property_values = []\n", + ".constraints = []\n", + ".description = ''\n", + ".diagrams = []\n", + ".filtering_criteria = []\n", + ".is_abstract = False\n", + ".is_final = False\n", + ".is_primitive = False\n", + ".name = 'Wand'\n", + ".owned_properties = [0] \n", + " [1] \n", + " [2] \n", + ".parent = \n", + ".progress_status = 'NOT_SET'\n", + ".properties = [0] \n", + " [1] \n", + " [2] \n", + " [3] \n", + ".property_value_groups = []\n", + ".property_values = []\n", + ".realizations = [0] \n", + ".realized_by = ... # backreference to Class - omitted: can be slow to compute\n", + ".realized_classes = [0] \n", + ".requirements = []\n", + ".state_machines = []\n", + ".sub = ... # backreference to Class - omitted: can be slow to compute\n", + ".summary = None\n", + ".super = \n", + ".traces = []\n", + ".uuid = 'c710f1c2-ede6-444e-9e2b-0ff30d7fd040'\n", + ".visibility = \n", + ".xtype = 'org.polarsys.capella.core.data.information:Class'" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.la.data_package.classes[0]" + ] + }, + { + "cell_type": "markdown", + "id": "b7bc5a40", + "metadata": {}, + "source": [ + "We can investigate the properties of a Class" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "56bb4b44", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "

owner (org.polarsys.capella.core.data.information:Property)

applied_property_value_groups

(Empty list)

applied_property_values

(Empty list)

associationBackreference to Association - omitted: can be slow to compute. Display this property directly to show.
constraints

(Empty list)

default_valueNone
description
diagrams

(Empty list)

filtering_criteria

(Empty list)

is_abstractFalse
is_derivedFalse
is_orderedFalse
is_part_of_keyFalse
is_read_onlyFalse
is_staticFalse
is_uniqueFalse
kind<AggregationKind.UNSET: 1>
maxNone
max_cardLiteralNumericValue "": 1 (43e39098-ace4-47c4-8f1c-1df1986063e2)
minNone
min_cardLiteralNumericValue "": 1 (95d6a6e5-6442-408d-afb2-d8f7a24c5f56)
nameowner
null_valueNone
parentClass "Wand" (c710f1c2-ede6-444e-9e2b-0ff30d7fd040)
progress_statusNOT_SET
property_value_groups

(Empty list)

property_values

(Empty list)

requirements

(Empty list)

summaryNone
traces

(Empty list)

typeModelElement "String" (b2f035e6-78c8-4dfd-99f0-bf4a40ea3e81)
uuid9b1f6d9c-58d6-4e5e-a0f1-822cb5440a51
visibility<VisibilityKind.UNSET: 1>
xtypeorg.polarsys.capella.core.data.information:Property
" + ], + "text/plain": [ + "\n", + ".applied_property_value_groups = []\n", + ".applied_property_values = []\n", + ".association = ... # backreference to Association - omitted: can be slow to compute\n", + ".constraints = []\n", + ".default_value = None\n", + ".description = ''\n", + ".diagrams = []\n", + ".filtering_criteria = []\n", + ".is_abstract = False\n", + ".is_derived = False\n", + ".is_ordered = False\n", + ".is_part_of_key = False\n", + ".is_read_only = False\n", + ".is_static = False\n", + ".is_unique = False\n", + ".kind = \n", + ".max = None\n", + ".max_card = \n", + ".min = None\n", + ".min_card = \n", + ".name = 'owner'\n", + ".null_value = None\n", + ".parent = \n", + ".progress_status = 'NOT_SET'\n", + ".property_value_groups = []\n", + ".property_values = []\n", + ".requirements = []\n", + ".summary = None\n", + ".traces = []\n", + ".type = \n", + ".uuid = '9b1f6d9c-58d6-4e5e-a0f1-822cb5440a51'\n", + ".visibility = \n", + ".xtype = 'org.polarsys.capella.core.data.information:Property'" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.la.data_package.classes[0].properties[0]" + ] + }, + { + "cell_type": "markdown", + "id": "36670ae2", + "metadata": {}, + "source": [ + "As you can see the `kind` attribute is `UNSET`. That means this property isn't modelled as an association. An example for a `COMPOSITION`:\n", + "\n", + "![Waypoint](../_static/img/waypoints.png)" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "7ca2429b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "

waypoints (org.polarsys.capella.core.data.information:Property)

applied_property_value_groups

(Empty list)

applied_property_values

(Empty list)

associationBackreference to Association - omitted: can be slow to compute. Display this property directly to show.
constraints

(Empty list)

default_valueNone
description
diagrams

(Empty list)

filtering_criteria

(Empty list)

is_abstractFalse
is_derivedFalse
is_orderedFalse
is_part_of_keyFalse
is_read_onlyFalse
is_staticFalse
is_uniqueFalse
kind<AggregationKind.COMPOSITION: 4>
maxNone
max_cardLiteralNumericValue "": inf (57d146cf-6e40-42f4-9413-1cd0240d1431)
minNone
min_cardLiteralNumericValue "": 1 (1df38231-5a0a-4c47-8c99-96119b8b8af8)
namewaypoints
null_valueNone
parentClass "Trajectory" (c3c96805-d6f6-4092-b9f4-df7970651cdc)
progress_statusNOT_SET
property_value_groups

(Empty list)

property_values

(Empty list)

requirements

(Empty list)

summaryNone
traces

(Empty list)

typeClass "Waypoint" (c89849fd-0643-4708-a4da-74c9ea9ca7b1)
uuid424efd65-eaa9-4220-b61b-fb3340dbc19a
visibility<VisibilityKind.UNSET: 1>
xtypeorg.polarsys.capella.core.data.information:Property
" + ], + "text/plain": [ + "\n", + ".applied_property_value_groups = []\n", + ".applied_property_values = []\n", + ".association = ... # backreference to Association - omitted: can be slow to compute\n", + ".constraints = []\n", + ".default_value = None\n", + ".description = ''\n", + ".diagrams = []\n", + ".filtering_criteria = []\n", + ".is_abstract = False\n", + ".is_derived = False\n", + ".is_ordered = False\n", + ".is_part_of_key = False\n", + ".is_read_only = False\n", + ".is_static = False\n", + ".is_unique = False\n", + ".kind = \n", + ".max = None\n", + ".max_card = \n", + ".min = None\n", + ".min_card = \n", + ".name = 'waypoints'\n", + ".null_value = None\n", + ".parent = \n", + ".progress_status = 'NOT_SET'\n", + ".property_value_groups = []\n", + ".property_values = []\n", + ".requirements = []\n", + ".summary = None\n", + ".traces = []\n", + ".type = \n", + ".uuid = '424efd65-eaa9-4220-b61b-fb3340dbc19a'\n", + ".visibility = \n", + ".xtype = 'org.polarsys.capella.core.data.information:Property'" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "prop = model.sa.all_classes.by_name(\"Trajectory\").properties[0]\n", + "prop" + ] + }, + { + "cell_type": "markdown", + "id": "7ab5f3a6", + "metadata": {}, + "source": [ + "The role name is exposed as the `name` attribute of the property. As you can see the only *navigable* role is `waypoints` and its min- and max-card are also accessible. The `Class` can be accessed via the `type` attribute and the `association` is there to receive information about the incoming role/property. Let's have a look at it:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "90c3cf8c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "

waypoint association (org.polarsys.capella.core.data.information:Association)

applied_property_value_groups

(Empty list)

applied_property_values

(Empty list)

constraints

(Empty list)

description
diagrams

(Empty list)

filtering_criteria

(Empty list)

members
  1. Property "trajectory" (c0e5b34c-297e-4b3c-8957-58bbe4d36199)
namewaypoint association
navigable_members
  1. Property "waypoints" (424efd65-eaa9-4220-b61b-fb3340dbc19a)
parentDataPkg "Data" (814464a3-3278-48eb-b66c-e255ed11afa8)
progress_statusNOT_SET
property_value_groups

(Empty list)

property_values

(Empty list)

requirements

(Empty list)

roles
  1. Property "trajectory" (c0e5b34c-297e-4b3c-8957-58bbe4d36199)
  2. Property "waypoints" (424efd65-eaa9-4220-b61b-fb3340dbc19a)
source_roleProperty "trajectory" (c0e5b34c-297e-4b3c-8957-58bbe4d36199)
summaryFind waypoints and you will finish consistently.
traces

(Empty list)

uuid3d738685-83e8-45f9-ade2-d5bcc6de1a0c
xtypeorg.polarsys.capella.core.data.information:Association
" + ], + "text/plain": [ + "\n", + ".applied_property_value_groups = []\n", + ".applied_property_values = []\n", + ".constraints = []\n", + ".description = ''\n", + ".diagrams = []\n", + ".filtering_criteria = []\n", + ".members = [0] \n", + ".name = 'waypoint association'\n", + ".navigable_members = [0] \n", + ".parent = \n", + ".progress_status = 'NOT_SET'\n", + ".property_value_groups = []\n", + ".property_values = []\n", + ".requirements = []\n", + ".roles = [0] \n", + " [1] \n", + ".source_role = \n", + ".summary = 'Find waypoints and you will finish consistently.'\n", + ".traces = []\n", + ".uuid = '3d738685-83e8-45f9-ade2-d5bcc6de1a0c'\n", + ".xtype = 'org.polarsys.capella.core.data.information:Association'" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "prop.association" + ] + }, + { + "cell_type": "markdown", + "id": "19c3fffc", + "metadata": {}, + "source": [ + "An `Association` has `navigable_members` which can be at most 2 (the source and target roles) and a `source_role`. Whenever the `is Navigable` option is ticked in Capella the property element will appear underneath the target `Class` of the `Association`." + ] + }, + { + "cell_type": "markdown", + "id": "eb05ea54", + "metadata": {}, + "source": [ + "## Example 2: Complex Values (instances of Classes)\n", + "\n", + "Capella allows to create Complex Values which have the type of a class model element. Complex Values can contain Value Parts that instantiate the properties of the class. Let's have a look at Harry's wand:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "77a5dc04", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "

Harry's Wand (org.polarsys.capella.core.data.information.datavalue:ComplexValue)

applied_property_value_groups

(Empty list)

applied_property_values

(Empty list)

constraints

(Empty list)

description
diagrams

(Empty list)

filtering_criteria

(Empty list)

nameHarry's Wand
parentDataPkg "Wand Objects" (880af86d-6fac-4fba-a559-2fffd036fa9a)
progress_statusNOT_SET
property_value_groups

(Empty list)

property_values

(Empty list)

requirements

(Empty list)

summaryNone
traces

(Empty list)

typeClass "Wand" (c710f1c2-ede6-444e-9e2b-0ff30d7fd040)
uuid3a467d68-f53c-4d66-9d32-fe032a8cb2c5
value_parts
  1. ValuePart "": \n", + ".applied_property_value_groups = []\n", + ".applied_property_values = []\n", + ".constraints = []\n", + ".description = ''\n", + ".diagrams = []\n", + ".filtering_criteria = []\n", + ".is_abstract = False\n", + ".name = 'LiteralStringValue'\n", + ".parent = \n", + ".progress_status = 'NOT_SET'\n", + ".property_value_groups = []\n", + ".property_values = []\n", + ".requirements = []\n", + ".summary = None\n", + ".traces = []\n", + ".type = \n", + ".uuid = 'f7b00d88-cf53-4ae0-a0e6-bb2049b4bdea'\n", + ".value = 'Harry Potter'\n", + ".xtype = 'org.polarsys.capella.core.data.information.datavalue:LiteralStringValue' (c996225b-5b1f-4d53-83cb-2bc72597e8ad)
  2. ValuePart "": \n", + ".applied_property_value_groups = []\n", + ".applied_property_values = []\n", + ".constraints = []\n", + ".description = ''\n", + ".diagrams = []\n", + ".filtering_criteria = []\n", + ".name = 'EnumerationReference'\n", + ".parent = \n", + ".progress_status = 'NOT_SET'\n", + ".property_value_groups = []\n", + ".property_values = []\n", + ".requirements = []\n", + ".summary = None\n", + ".traces = []\n", + ".type = \n", + ".uuid = '3406b669-4572-44e9-b703-1e319c350e9b'\n", + ".value = \n", + ".xtype = 'org.polarsys.capella.core.data.information.datavalue:EnumerationReference' (66da894f-6261-47ac-9ad7-217db04671d2)
  3. ValuePart "": \n", + ".applied_property_value_groups = []\n", + ".applied_property_values = []\n", + ".constraints = []\n", + ".description = ''\n", + ".diagrams = []\n", + ".filtering_criteria = []\n", + ".name = 'EnumerationReference'\n", + ".parent = \n", + ".progress_status = 'NOT_SET'\n", + ".property_value_groups = []\n", + ".property_values = []\n", + ".requirements = []\n", + ".summary = None\n", + ".traces = []\n", + ".type = \n", + ".uuid = '9645687f-9485-45f0-a10b-01f8b9d24914'\n", + ".value = \n", + ".xtype = 'org.polarsys.capella.core.data.information.datavalue:EnumerationReference' (a10de770-c6de-43fc-8d9f-868efe5cd29f)
xtypeorg.polarsys.capella.core.data.information.datavalue:ComplexValue
" + ], + "text/plain": [ + "\n", + ".applied_property_value_groups = []\n", + ".applied_property_values = []\n", + ".constraints = []\n", + ".description = ''\n", + ".diagrams = []\n", + ".filtering_criteria = []\n", + ".name = \"Harry's Wand\"\n", + ".parent = \n", + ".progress_status = 'NOT_SET'\n", + ".property_value_groups = []\n", + ".property_values = []\n", + ".requirements = []\n", + ".summary = None\n", + ".traces = []\n", + ".type = \n", + ".uuid = '3a467d68-f53c-4d66-9d32-fe032a8cb2c5'\n", + ".value_parts = [0] \n", + " [1] \n", + " [2] \n", + ".xtype = 'org.polarsys.capella.core.data.information.datavalue:ComplexValue'" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.la.data_package.packages[0].complex_values[0]" + ] + }, + { + "cell_type": "markdown", + "id": "8e7b17c0", + "metadata": {}, + "source": [ + "and let's see what wood Harry's wand is made of:" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "0557c2a5", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "The owner of Harry's Wand is Harry Potter.\n", + "The core of Harry's Wand is Pheonix Feather.\n", + "The wood of Harry's Wand is Holly.\n" + ] + } + ], + "source": [ + "from capellambse.model.crosslayer.information import datavalue\n", + "\n", + "instance = model.la.data_package.packages[0].complex_values[0]\n", + "for value_part in instance.value_parts:\n", + " value = value_part.value.value\n", + " if isinstance(value, datavalue.EnumerationLiteral):\n", + " value = value.name\n", + "\n", + " print(\n", + " f\"The {value_part.referenced_property.name} of {instance.name} is {value}.\"\n", + " )" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.5" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/_sources/examples/04 Intro to Jinja templating.ipynb.txt b/_sources/examples/04 Intro to Jinja templating.ipynb.txt new file mode 100644 index 000000000..74e8b51ca --- /dev/null +++ b/_sources/examples/04 Intro to Jinja templating.ipynb.txt @@ -0,0 +1,658 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Using capellambse with Jinja2\n", + "\n", + "Welcome to the py-capellambse jinja2 templating showcase. When using capella\n", + "for systems engineering you might want to generate documentation for your model\n", + "you can use M2DOC, one of capella's [addons] which we found too challenging or\n", + "you can use Jinja2 a richful templating language with high degree of freedom.\n", + "\n", + "This notebook will introduce you into writing jinja2 templates where you'll plant model\n", + "information and diagrams. Additonally we'll give a side-note on how to handle\n", + "unique identifiers professionally with PVMT and some hints onto how to use jinja\n", + "in a professional manner which could give you the option onto developping an\n", + "automated document generation system.\n", + "\n", + "With Jinja2 you are able to generate any text-based format(HTML, XML, CSV, LaTex,...)\n", + "but during this tutorial we will only generate .html files. The jinja2 syntax is\n", + "inspired by python. Check out their [docs]!\n", + "\n", + "[docs]: https://jinja2docs.readthedocs.io/en/stable/\n", + "[addons]: https://www.eclipse.org/capella/addons.html\n", + "\n", + "Below code loads the needed libraries and instantiates a test model:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Cannot load PVMT extension: ValueError: Provided model does not have a PropertyValuePkg\n", + "Property values are not available in this model\n" + ] + } + ], + "source": [ + "import jinja2\n", + "from IPython.core.display import HTML\n", + "\n", + "import capellambse\n", + "\n", + "path_to_model = \"../../../tests/data/melodymodel/5_0/Melody Model Test.aird\"\n", + "model = capellambse.MelodyModel(path_to_model)\n", + "env = jinja2.Environment()" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In the following we want to make a template to document all modelled actors from\n", + "the logical layer. Therefore we define a template string where we iterate over\n", + "all actors and plant the name, uuid and description into it.\n", + "\n", + "*Hint: Make sure that you know of capella's [metamodel] as we are implementing the\n", + "capellambse.layers as close as possible to it while being as efficient and pythonic\n", + "we can be currently. This knowledge can shorten used statements in the template immensely!*\n", + "\n", + "[metamodel]: https://dsd-dbs.github.io/py-capellambse/start/intro-to-api.html" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "

Actor definitions

\n", + "\n", + "

Prof. A. P. W. B. Dumbledore

\n", + "

Actor definition

\n", + "

UUID: 08e02248-504d-4ed8-a295-c7682a614f66

\n", + "

Principal of Hogwarts, wearer of the elder wand and greatest mage of all time.

\n", + "

\n", + "\n", + "

Prof. S. Snape

\n", + "

Actor definition

\n", + "

UUID: 6f463eed-c77b-4568-8078-beec0536f243

\n", + "

Good guy and teacher of brewing arts.

\n", + "

\n", + "\n", + "

Harry J. Potter

\n", + "

Actor definition

\n", + "

UUID: a8c46457-a702-41c4-a971-c815c4c5a674

\n", + "

\n", + "\n", + "

R. Weasley

\n", + "

Actor definition

\n", + "

UUID: ff7b8672-84db-4b93-9fea-22a410907fb1

\n", + "

\n", + "\n", + "

Voldemort

\n", + "

Actor definition

\n", + "

UUID: 3e0ee19f-0e3f-49d4-ae99-29bd4a3260c5

\n", + "

\n", + "\n", + "

Multiport

\n", + "

Actor definition

\n", + "

UUID: b3888dad-a870-4b8b-97d4-0ddb83ef9251

\n", + "

\n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "templ = \"\"\"\n", + "

Actor definitions

\n", + "{% for actor in model.la.all_components.by_is_actor(True) %}\n", + "

{{ actor.name }}

\n", + "

Actor definition

\n", + "

UUID: {{ actor.uuid }}

\n", + "

{{ actor.description }}

\n", + "{% endfor %}\n", + "\"\"\"\n", + "\n", + "HTML(env.from_string(templ).render(model=model))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "As an extra: We don't use the UUID from capella in our documents. If you still\n", + "need an identifier, in the following it's explained how we are doing it:\n", + "\n", + "With the capella PVMT, one of the various capella addons, you can make property\n", + "value groups and then set arbitrary values with these. Capellambse is able to recognize\n", + "the pvmt extension and gives read and write access. In our workflows we are maintaining\n", + "an ID database for all model elements. If that is done you can access pvmt attributes\n", + "like:\n", + "\n", + "```html\n", + "{{ ... }}\n", + "

ID: {{ actor.pvmt[\"Group.Identification.MY MODEL ID\"] }}

\n", + "{{ ... }}\n", + "```\n", + "\n", + "For a PVMT showcase look into [TODO: pvmt-showcase notebook]." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Filters and object manipulation\n", + "\n", + "Now to step up our templating-game, we'll bring in more complexity.\n", + "We want a template that documents functional context of all actors. For that\n", + "iff the actor has a non-empty functions attribute we make a table with columns\n", + "for function's uid, name, description and `FunctionalExchange`s.\n", + "\n", + "We can define variables in the template via the set statement. Furthermore\n", + "the builtin jinja [filters] already give much power for object manipulation during\n", + "rendering. Here we use map(.) to create `FunctionalExchange` iterators and sum these\n", + "up into one large list that stores all `FunctionalExchange`s that have an an actor\n", + "as either source or target. In the table for-loop we then filter on this lookup\n", + "container and set outgoing and incoming `FunctionalExchange`s that we need for\n", + "the last column.\n", + "\n", + "The jupyter environment is great for writing templates b/c you can investigate\n", + "possible attributes of objects right away in another cell.\n", + "\n", + "*Hint: You can define custom filter-functions and add them to the Environment.filters.*\n", + "\n", + "[filters]: https://jinja.palletsprojects.com/en/3.0.x/templates/#builtin-filters" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "

Actor definitions

\n", + "\n", + "\n", + "

Harry J. Potter

\n", + "

Actor definition

\n", + "

\n", + "

Actor functions

\n", + " \n", + "

The table below identifies functions of Harry J. Potter.

\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
IDFunctionDescriptionInvolved Subsystems
aa9931e3-116c-461e-8215-6b9fdbdd4a1bkill He Who Must Not Be NamedLearning
\n", + "

Functions of Harry J. Potter

\n", + " \n", + "\n", + "

Prof. A. P. W. B. Dumbledore

\n", + "

Actor definition

\n", + "

Principal of Hogwarts, wearer of the elder wand and greatest mage of all time.

\n", + "

\n", + "

Actor functions

\n", + " \n", + "

The table below identifies functions of Prof. A. P. W. B. Dumbledore.

\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
IDFunctionDescriptionInvolved Subsystems
f708bc29-d69f-42a0-90cc-11fc01054cd0manage the school
beaf5ba4-8fa9-4342-911f-0266bb29be45advise Harry
\n", + "

Functions of Prof. A. P. W. B. Dumbledore

\n", + " \n", + "\n", + "

Prof. S. Snape

\n", + "

Actor definition

\n", + "

Good guy and teacher of brewing arts.

\n", + "

\n", + "

Actor functions

\n", + " \n", + "

The table below identifies functions of Prof. S. Snape.

\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
IDFunctionDescriptionInvolved Subsystems
a7acb298-d14b-4707-a419-fea272434541TeachingTeacher Responsibilities
4a2a7f3c-d223-4d44-94a7-50dd2906a70cmaintain a layer of defense for the Sorcerer's Stone
\n", + "

Functions of Prof. S. Snape

\n", + " \n", + "\n", + "

Multiport

\n", + "

Actor definition

\n", + "

\n", + "

Actor functions

\n", + " \n", + "

The table below identifies functions of Multiport.

\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
IDFunctionDescriptionInvolved Subsystems
9c1885f5-fac7-48fd-9d54-a11092508867LAF 1C 5
\n", + "

Functions of Multiport

\n", + " \n", + "\n", + "

Voldemort

\n", + "

Actor definition

\n", + "

\n", + "

Actor functions

\n", + " \n", + "

No actor functions were identified.

\n", + " \n", + "\n", + "

R. Weasley

\n", + "

Actor definition

\n", + "

\n", + "

Actor functions

\n", + " \n", + "

The table below identifies functions of R. Weasley.

\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + "
IDFunctionDescriptionInvolved Subsystems
c1a42acc-1f53-42bb-8404-77a5c08c414bassist Harry
edbd1ad4-31c0-4d53-b856-3ffa60e0e99bbreak school rulesPunishment
\n", + "

Functions of R. Weasley

\n", + " \n" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "templ1 = \"\"\"\n", + "

Actor definitions

\n", + "{% set fexs = model.la.actor_exchanges.map(\"func_exchanges\") %}\n", + "{% for actor in model.la.all_actors %}\n", + "

{{ actor.name }}

\n", + "

Actor definition

\n", + "

{{ actor.description }}

\n", + "

Actor functions

\n", + " {% if actor.functions %}\n", + "

The table below identifies functions of {{ actor.name }}.

\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " {% for fnc in actor.functions %}\n", + " {% set outs = fexs.by_source.owner(fnc) %}\n", + " {% set ins = fexs.by_target.owner(fnc) %}\n", + " {% set subs = (ins + outs) | map(attribute=\"owner.name\") | unique | sort %}\n", + " \n", + " \n", + " \n", + " \n", + " \n", + " \n", + " {% endfor %}\n", + " \n", + "
IDFunctionDescriptionInvolved Subsystems
{{ fnc.uuid }}{{ fnc.name }}{{ fnc.description }}{{ subs | join(', ') }}
\n", + "

Functions of {{ actor.name }}

\n", + " {% else %}\n", + "

No actor functions were identified.

\n", + " {% endif %}\n", + "{% endfor %}\n", + "\"\"\"\n", + "HTML(env.from_string(templ1).render(model=model))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Beautiful SVG diagrams\n", + "\n", + "Finally we will render a template that displays a diagram. There are many ways\n", + "to do this and with jinja2 you have full control. We like our figures inside\n", + "tables such that a caption can be displayed" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Unknown global filter 'hide.sequencing.information.filter'\n", + "Unknown global filter 'ModelExtensionFilter'\n", + "Unknown global filter 'hide.simplified.diagram.based.component.exchanges.filter'\n", + "Unknown global filter 'hide.simplified.oriented.grouped.component.exchanges.filter'\n", + "Unknown global filter 'hide.simplified.group.of.component.exchanges.filter'\n" + ] + }, + { + "data": { + "text/html": [ + "

Hogwarts

\n", + "

This instance is the mighty Hogwarts. Do you really need a description? Then maybe read the books or watch atleast the epic movies.

\n", + "\n", + "\n", + " \n", + " \n", + "
Figure 1: [LAB] Wizzard Education
LFHogwartsproduce GreatWizardsprotectStudentsagainst theDeath EatersCampusSchooleducate WizardsWhomping Willowdefend thesurrounding areaagainst IntrudersProf. A. P. W. B.Dumbledoremanage theschooladviseHarryProf. S. SnapeTeachingmaintain alayer ofdefense fortheSorcerer'sStoneHarry J. Potterkill He WhoMust Not BeNamedR. Weasleyassist Harrybreak schoolruleswizardryHeadmasterResponsibilitiesTeacherResponsibilitiesHelp for HarryKnowledgePunishmentLearningeducate & maturefriendshipassistanceCarepunisheducate
" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "templ = \"\"\"\\\n", + "

{{ component.name }}

\n", + "{{ component.description }}\n", + "\n", + " \n", + " \n", + "
Figure {{ fig_id }}: {{ fig_caption | e }}
{{ figure.as_svg | safe }}
\n", + "\"\"\"\n", + "diagram = model.diagrams.by_name(\"[LAB] Wizzard Education\")\n", + "rendered = env.from_string(templ).render(\n", + " component=model.search(\"LogicalComponent\").by_name(\"Hogwarts\"),\n", + " fig_id=1,\n", + " fig_caption=diagram.name,\n", + " figure=diagram,\n", + ")\n", + "HTML(rendered)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "*Hint: Take notice of the [jinja.Environment]. Instead of handing the figure_table-markup\n", + "over in the rendering call you could also set an insert_figure_as_table function,\n", + "which you ideally defined before, in the environment globals or you can define\n", + "[macros] right in the template. These tools can automate repetitive content placement.*\n", + "\n", + "[jinja.Environment]: https://jinja.palletsprojects.com/en/3.0.x/api/#jinja2.Environment\n", + "[macros]: https://jinja.palletsprojects.com/en/3.0.x/templates/#macros" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Template inheritance\n", + "\n", + "The last cell will present a routine where a full .html document is generated.\n", + "Earlier rendered content were HTML-fragments to be precise. On top you can see\n", + "a showcase on jinja's [template-inheritance] functionality. The special DictLoader\n", + "gives support for finding the base template called \"template.html\". This was just\n", + "needed because we are dealing with content in memory and didn't create template.html\n", + "in our FileSystem before. Per default jinja is using the FileSystemLoader when\n", + "creating an Environment. It's not a bad idea to check the [Loaders] they have, if\n", + "you want to understand how template loading is working and/or plan on developing\n", + "a pipeline system for document distribution.\n", + "\n", + "[template-inheritance]: https://jinja.palletsprojects.com/en/3.0.x/templates/#template-inheritance\n", + "[Loaders]: https://jinja.palletsprojects.com/en/3.0.x/api/#loaders" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "\n", + "\n", + "\n", + "\n", + "\n", + " \n", + "\n", + "\n", + "\n", + "

Hogwarts

\n", + "

This instance is the mighty Hogwarts. Do you really need a description? Then maybe read the books or watch atleast the epic movies.

\n", + "\n", + "\n", + " \n", + " \n", + "
Figure 1: [LAB] Wizzard Education
LFHogwartsproduce GreatWizardsprotectStudentsagainst theDeath EatersCampusSchooleducate WizardsWhomping Willowdefend thesurrounding areaagainst IntrudersProf. A. P. W. B.Dumbledoremanage theschooladviseHarryProf. S. SnapeTeachingmaintain alayer ofdefense fortheSorcerer'sStoneHarry J. Potterkill He WhoMust Not BeNamedR. Weasleyassist Harrybreak schoolruleswizardryHeadmasterResponsibilitiesTeacherResponsibilitiesHelp for HarryKnowledgePunishmentLearningeducate & maturefriendshipassistanceCarepunisheducate
\n", + "\n", + "\n", + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "fig_templ = \"\".join(\n", + " (\n", + " '{% extends \"template.html\" %}',\n", + " \"{% block content %}\",\n", + " templ,\n", + " \"{% endblock %}\",\n", + " )\n", + ")\n", + "final_templ = \"\"\"\n", + "\n", + "\n", + "\n", + "\n", + " \n", + "\n", + "\n", + "\n", + " {% block content %}\n", + " {% endblock %}\n", + "\n", + "\n", + "\"\"\"\n", + "\n", + "env = jinja2.Environment(\n", + " loader=jinja2.DictLoader({\"template.html\": final_templ})\n", + ")\n", + "rendered = env.from_string(fig_templ).render(\n", + " component=model.search(\"LogicalComponent\").by_name(\"Hogwarts\"),\n", + " fig_id=1,\n", + " fig_caption=diagram.name,\n", + " figure=diagram,\n", + ")\n", + "HTML(rendered)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.5" + }, + "vscode": { + "interpreter": { + "hash": "e7370f93d1d0cde622a1f8e1c04877d8463912d04d973331ad4851f04de6915a" + } + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/_sources/examples/05 Introduction to Libraries.ipynb.txt b/_sources/examples/05 Introduction to Libraries.ipynb.txt new file mode 100644 index 000000000..ba5690eda --- /dev/null +++ b/_sources/examples/05 Introduction to Libraries.ipynb.txt @@ -0,0 +1,261 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Introduction to Libraries\n", + "\n", + "This notebook illustrates the use of Capella Libraries. When trying to load a\n", + "model that uses a library, you may encounter an error similar to this:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MissingResourceLocationError: 'Library Test'\n" + ] + } + ], + "source": [ + "import capellambse\n", + "\n", + "path_to_model = \"../../../tests/data/Library Project/Library Project.aird\"\n", + "\n", + "try:\n", + " capellambse.MelodyModel(path_to_model)\n", + "except Exception as err:\n", + " print(f\"{type(err).__name__}: {err}\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "This tells us the name that was given to the library: `Library Test`. So, we need to define a resource location with that name. As there can be arbitrarily many resource locations (i.e. linked libraries) with arbitrary names given to them, these locations are handed over in a Python `dict`.\n", + "\n", + "There are three ways of defining a resource location:\n", + "\n", + "1. A simple `str` containing only a path or URL, similar to the first positional argument of `MelodyModel`.\n", + "2. A nested dictionary with a `path` key, as well as other keys needed to find and access that resource. These may include `subdir` or `username` and `password`.\n", + "3. A constructed `FileHandler` object.\n", + "\n", + "The following cell shows a concrete example of each of them." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "# Simple `str`\n", + "resources = {\n", + " \"Library Test\": \"/data/models/Library Test\",\n", + "}\n", + "\n", + "# Nested `dict`\n", + "resources = {\n", + " \"Library Test\": {\n", + " \"path\": \"https://raw.githubusercontent.com/DSD-DBS/py-capellambse/master/tests/data/Library%20Test\",\n", + " # More options can be added here if necessary, e.g.:\n", + " # \"username\": \"demouser\",\n", + " # \"password\": \"super secret passphrase\",\n", + " }\n", + "}\n", + "\n", + "# `FileHandler` object\n", + "# (Be aware that constructing a `FileHandler` may already involve network access,\n", + "# for example cloning a remote git repository into a local cache.)\n", + "lib_handler = capellambse.get_filehandler(\n", + " \"git+https://github.com/DSD-DBS/py-capellambse.git\",\n", + " subdir=\"tests/data/Library Test\",\n", + " revision=\"master\",\n", + " # More options can be added here as well, e.g.:\n", + " # username=\"demouser\",\n", + " # password=\"super secret passphrase\",\n", + ")\n", + "resources = {\"Library Test\": lib_handler}" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Equipped with this `resources` dictionary, we can now try to load the model again:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Cannot load PVMT extension: ValueError: Provided model does not have a PropertyValuePkg\n", + "Property values are not available in this model\n" + ] + } + ], + "source": [ + "model = capellambse.MelodyModel(path_to_model, resources=resources)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "If you receive more `MissingResourceLocationError`s, add them to the same `resources` dictionary and pass them to the `MelodyModel` as well." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Once you no longer receive errors during loading, you can use the model as normal." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
  1. [CDB] Library Product (uuid: _q-c-0KN2EeyJNLcTD9ngpQ)
  2. [LAB] E-Commerce (uuid: _SMS4sKFFEeyn0YWM8vjd5w)
" + ], + "text/plain": [ + "[0] \n", + "[1] " + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.diagrams" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Unknown global filter 'hide.sequencing.information.filter'\n", + "Unknown global filter 'hide.simplified.diagram.based.component.exchanges.filter'\n", + "Unknown global filter 'hide.simplified.oriented.grouped.component.exchanges.filter'\n", + "Unknown global filter 'ModelExtensionFilter'\n", + "Unknown global filter 'hide.simplified.group.of.component.exchanges.filter'\n" + ] + }, + { + "data": { + "image/png": "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", + "image/svg+xml": [ + "LFE-Commerceoffer productsassign orderClientselect productget productTruck Companyreceive orderdeliver productproduct listsupply detailsorder details" + ], + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.diagrams.by_name(\"[LAB] E-Commerce\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Common pitfalls\n", + "\n", + "In order for `capellambse` to be able to find your elements, ensure that you:\n", + "\n", + "1. Created a replicable element collection (REC) in the Capella Library. To do that, right-click the element in the library, and choose \"REC / RPL\" > \"Create REC\".\n", + "2. Have instantiated the REC as a so-called Replica (RPL) in your primary project. For this, right-click any element in your project and choose \"REC / RPL\" > \"Instantiate RPL from REC\".\n", + "\n", + "For more information, watch this [short video about REC / RPL](https://youtu.be/h-ax61eVlxM)." + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Logical System\n", + "E-Commerce\n", + "Truck Company\n", + "Client\n" + ] + } + ], + "source": [ + "for component in model.la.all_components:\n", + " print(component.name)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Saving a model\n", + "\n", + "You can save the model as usual by calling `model.save()`. However, **this will only save the primary model**. Modifications to elements that are defined only in a library will be lost.\n", + "\n", + "This is normally not a problem when following the standard REC / RPL based workflow, as the definitions of those elements will be copied to and modified in the primary model.\n", + "\n", + "In order to modify elements in one of the used libraries, you can load the library itself as a model. This allows you to apply any needed modifications and then save the library. Afterwards, the updated library can be used in the `resources` of other models." + ] + } + ], + "metadata": { + "interpreter": { + "hash": "e5607734f15d1b90b8506e690cd35fc527f703262c75faee6ce3cf6c6d2ff5b2" + }, + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.5" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/_sources/examples/06 Introduction to Requirement access and management.ipynb.txt b/_sources/examples/06 Introduction to Requirement access and management.ipynb.txt new file mode 100644 index 000000000..daf6561d6 --- /dev/null +++ b/_sources/examples/06 Introduction to Requirement access and management.ipynb.txt @@ -0,0 +1,691 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "7bcee230", + "metadata": {}, + "source": [ + "# Introduction to Requirement access and management\n", + "\n", + "Welcome to the ReqIF extension Showcase notebook. This notebook will show you some basic (and not so basic) things that you can get done using this library.\n", + "\n", + "The below code loads the library and one of the test models:" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "a52777dd", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 1, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "import capellambse\n", + "\n", + "path_to_model = \"../../../tests/data/melodymodel/5_0/Melody Model Test.aird\"\n", + "model = capellambse.MelodyModel(path_to_model)\n", + "model" + ] + }, + { + "cell_type": "markdown", + "id": "d8442183", + "metadata": {}, + "source": [ + "You can access a lookup for all requirements defined in a specific layer." + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "42a46a49", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
  1. Requirement "TestReq1" (3c2d312c-37c9-41b5-8c32-67578fa52dc3)
  2. Requirement "TypedReq2" (0a9a68b1-ba9a-4793-b2cf-4448f0b4b8cc)
  3. Requirement "TestReq3" (79291c33-5147-4543-9398-9077d582576d)
  4. Requirement "TypedReq1" (85d41db2-9e17-438b-95cf-49342452ddf3)
  5. Requirement "TestReq" (1092f69a-5f3a-4fe6-a8fd-b2dffde90650)
" + ], + "text/plain": [ + "[0] \n", + "[1] \n", + "[2] \n", + "[3] \n", + "[4] " + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.oa.all_requirements" + ] + }, + { + "cell_type": "markdown", + "id": "904c842b", + "metadata": {}, + "source": [ + "Have a look at all of the available attributes for a Requirement ModelElement:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "cb0a5b75", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "

TestReq1 (Requirements:Requirement)

applied_property_value_groups

(Empty list)

applied_property_values

(Empty list)

attributes
  1. BooleanValueAttribute "AttrDef" (9c692405-b8aa-4caa-b988-51d27db5cd1b)
  2. DateValueAttribute "AttrDef" (b97c09b5-948a-46e8-a656-69d764ddce7d)
  3. IntegerValueAttribute "AttrDef" (85dfd42c-7f6e-4236-a181-bdd784040431)
  4. RealValueAttribute "AttrDef" (d2231d14-854d-4625-b48b-6cf1c2554367)
  5. StringValueAttribute "AttrDef" (ee8a69ef-61b9-4db9-9a0f-628e5d4704e1)
  6. BooleanValueAttribute "None" (dcb8614e-2d1c-4cb3-aa0c-667a297e7489)
chapter_name2
constraints

(Empty list)

descriptionThis is a test requirement of kind 1.
diagrams

(Empty list)

filtering_criteria

(Empty list)

foreign_id1
identifierREQTYPE-1
long_name1
nameTestReq1
ownerFolder "Folder" (e16f5cc1-3299-43d0-b1a0-82d31a137111)
parentFolder "Folder" (e16f5cc1-3299-43d0-b1a0-82d31a137111)
prefix3
progress_statusNOT_SET
property_value_groups

(Empty list)

property_values

(Empty list)

pvmt<capellambse.extensions.pvmt.PropertyValueProxy object at 0x7f3afe4e68d0>
related
  1. Entity "Weather" (4bf0356c-89dd-45e9-b8a6-e0332c026d33)
  2. SystemFunction "Sysexfunc" (00e7b925-cf4c-4cb0-929e-5409a1cd872b)
  3. Requirement "TypedReq1" (85d41db2-9e17-438b-95cf-49342452ddf3)
  4. LogicalComponent "Hogwarts" (0d2edb8f-fa34-4e73-89ec-fb9a63001440)
relations
  1. CapellaIncomingRelation "Controlling the weather" (078b2c69-4352-4cf9-9ea5-6573b75e5eec)
  2. CapellaIncomingRelation "Test req" (24c824ef-b187-4725-a051-a68707e82d70)
  3. InternalRelation "None" (7de4c1a5-e106-4171-902a-502b816b60b0)
  4. CapellaOutgoingRelation "None" (57033242-3766-4961-8091-ce3d9326ed67)
requirements
  1. Entity "Weather" (4bf0356c-89dd-45e9-b8a6-e0332c026d33)
  2. SystemFunction "Sysexfunc" (00e7b925-cf4c-4cb0-929e-5409a1cd872b)
  3. Requirement "TypedReq1" (85d41db2-9e17-438b-95cf-49342452ddf3)
  4. LogicalComponent "Hogwarts" (0d2edb8f-fa34-4e73-89ec-fb9a63001440)
summaryNone
text

Test requirement 1 really l o n g text that is way too long to display here as that

\n", + "\n", + "

< > " '

\n", + "\n", + "
    \n", + "\t
  • This is a list
  • \n", + "\t
  • an unordered one
  • \n", + "
\n", + "\n", + "
    \n", + "\t
  1. Ordered list
  2. \n", + "\t
  3. Ok
  4. \n", + "
\n", + "
traces

(Empty list)

typeRequirementType "ReqType" (db47fca9-ddb6-4397-8d4b-e397e53d277e)
uuid3c2d312c-37c9-41b5-8c32-67578fa52dc3
xtypeRequirements:Requirement
" + ], + "text/plain": [ + "\n", + ".applied_property_value_groups = []\n", + ".applied_property_values = []\n", + ".attributes = [0] \n", + " [1] \n", + " [2] \n", + " [3] \n", + " [4] \n", + " [5] \n", + ".chapter_name = '2'\n", + ".constraints = []\n", + ".description = 'This is a test requirement of kind 1.'\n", + ".diagrams = []\n", + ".filtering_criteria = []\n", + ".foreign_id = 1\n", + ".identifier = 'REQTYPE-1'\n", + ".long_name = '1'\n", + ".name = 'TestReq1'\n", + ".owner = \n", + ".parent = \n", + ".prefix = '3'\n", + ".progress_status = 'NOT_SET'\n", + ".property_value_groups = []\n", + ".property_values = []\n", + ".pvmt = \n", + ".related = [0] \n", + " [1] \n", + " [2] \n", + " [3] \n", + ".relations = [0] to (078b2c69-4352-4cf9-9ea5-6573b75e5eec)>\n", + " [1] to (24c824ef-b187-4725-a051-a68707e82d70)>\n", + " [2] to (7de4c1a5-e106-4171-902a-502b816b60b0)>\n", + " [3] to (57033242-3766-4961-8091-ce3d9326ed67)>\n", + ".requirements = [0] \n", + " [1] \n", + " [2] \n", + " [3] \n", + ".summary = None\n", + ".text = Markup('

Test requirement 1 really l o n g text that is way too long to display here as that

\\n\\n

< > " '

\\n\\n
    \\n\\t
  • This is a list
  • \\n\\t
  • an unordered one
  • \\n
\\n\\n
    \\n\\t
  1. Ordered [...]\n", + ".traces = []\n", + ".type = \n", + ".uuid = '3c2d312c-37c9-41b5-8c32-67578fa52dc3'\n", + ".xtype = 'Requirements:Requirement'" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.oa.all_requirements[0]" + ] + }, + { + "cell_type": "markdown", + "id": "896e3633", + "metadata": {}, + "source": [ + "## Filtering for requirements by type\n", + "\n", + "You probably know about typing of your Requirements. You can have a view of all requirement type folders directly on a specific layer and see the stored requirement_types:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "8dad0bed", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "

    CapellaTypesFolder (CapellaRequirements:CapellaTypesFolder)

    applied_property_value_groups

    (Empty list)

    applied_property_values

    (Empty list)

    constraints

    (Empty list)

    data_type_definitions
    1. DataTypeDefinition "DataTypeDef" (3b7ec38a-e26a-4c23-9fa3-275af3f629ee)
    2. EnumerationDataTypeDefinition "EnumDataTypeDef" (637caf95-3229-4607-99a0-7d7b990bc97f)
    descriptionNone
    diagrams

    (Empty list)

    filtering_criteria

    (Empty list)

    identifierNone
    long_nameTypes
    module_types
    1. ModuleType "ModuleType" (a67e7f43-4b49-425c-a6a7-d44e1054a488)
    nameNone
    parentOperationalAnalysis "Operational Analysis" (ddbef16d-ddb9-4162-934c-f1e40e6f8bed)
    prefixNone
    progress_statusNOT_SET
    property_value_groups

    (Empty list)

    property_values

    (Empty list)

    pvmt<capellambse.extensions.pvmt.PropertyValueProxy object at 0x7f3ad72c8f50>
    relation_types
    1. RelationType "RelationType" (f1aceb81-5f70-4469-a127-94830eb9be04)
    requirement_types
    1. RequirementType "ReqType" (db47fca9-ddb6-4397-8d4b-e397e53d277e)
    requirements

    (Empty list)

    summaryNone
    traces

    (Empty list)

    typeNone
    uuid67bba9cf-953c-4f0b-9986-41991c68d241
    xtypeCapellaRequirements:CapellaTypesFolder
    " + ], + "text/plain": [ + "\n", + ".applied_property_value_groups = []\n", + ".applied_property_values = []\n", + ".constraints = []\n", + ".data_type_definitions = [0] \n", + " [1] \n", + ".description = None\n", + ".diagrams = []\n", + ".filtering_criteria = []\n", + ".identifier = None\n", + ".long_name = 'Types'\n", + ".module_types = [0] \n", + ".name = None\n", + ".parent = \n", + ".prefix = None\n", + ".progress_status = 'NOT_SET'\n", + ".property_value_groups = []\n", + ".property_values = []\n", + ".pvmt = \n", + ".relation_types = [0] \n", + ".requirement_types = [0] \n", + ".requirements = []\n", + ".summary = None\n", + ".traces = []\n", + ".type = None\n", + ".uuid = '67bba9cf-953c-4f0b-9986-41991c68d241'\n", + ".xtype = 'CapellaRequirements:CapellaTypesFolder'" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.oa.requirement_types_folders[0]" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "28c463c1", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "

    RequirementType (Requirements:RequirementType)

    applied_property_value_groups

    (Empty list)

    applied_property_values

    (Empty list)

    attribute_definitions
    1. AttributeDefinition "AttrDef" (682bd51d-5451-4930-a97e-8bfca6c3a127)
    2. AttributeDefinitionEnumeration "AttrDefEnum" (c316ab07-c5c3-4866-a896-92e34733055c)
    3. AttributeDefinitionEnumeration "MultiEnum" (f31d4dd3-99f7-41d1-b1ce-f07b20d26eac)
    4. AttributeDefinition "version" (0bd40628-10a5-451e-86da-187c93bc3b10)
    constraints

    (Empty list)

    descriptionNone
    diagrams

    (Empty list)

    filtering_criteria

    (Empty list)

    identifierNone
    long_nameReqType
    nameNone
    ownerCapellaTypesFolder "Types" (67bba9cf-953c-4f0b-9986-41991c68d241)
    parentCapellaTypesFolder "Types" (67bba9cf-953c-4f0b-9986-41991c68d241)
    prefixNone
    progress_statusNOT_SET
    property_value_groups

    (Empty list)

    property_values

    (Empty list)

    pvmt<capellambse.extensions.pvmt.PropertyValueProxy object at 0x7f3ad72f7910>
    requirements

    (Empty list)

    summaryNone
    traces

    (Empty list)

    typeNone
    uuiddb47fca9-ddb6-4397-8d4b-e397e53d277e
    xtypeRequirements:RequirementType
    " + ], + "text/plain": [ + "\n", + ".applied_property_value_groups = []\n", + ".applied_property_values = []\n", + ".attribute_definitions = [0] \n", + " [1] \n", + " [2] \n", + " [3] \n", + ".constraints = []\n", + ".description = None\n", + ".diagrams = []\n", + ".filtering_criteria = []\n", + ".identifier = None\n", + ".long_name = 'ReqType'\n", + ".name = None\n", + ".owner = \n", + ".parent = \n", + ".prefix = None\n", + ".progress_status = 'NOT_SET'\n", + ".property_value_groups = []\n", + ".property_values = []\n", + ".pvmt = \n", + ".requirements = []\n", + ".summary = None\n", + ".traces = []\n", + ".type = None\n", + ".uuid = 'db47fca9-ddb6-4397-8d4b-e397e53d277e'\n", + ".xtype = 'Requirements:RequirementType'" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "reqtype = model.oa.requirement_types_folders[0].requirement_types[0]\n", + "reqtype" + ] + }, + { + "cell_type": "markdown", + "id": "62baecda", + "metadata": {}, + "source": [ + "Now we actually want to filter the requirements by this type with name 'ReqType'. Very original name, we know. You wouldn't really see the filtering effect since all requirements in the oa layer are of that type. So let us create one new requirement dynamically:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "2d985277", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "

    New showcase req1 (Requirements:Requirement)

    applied_property_value_groups

    (Empty list)

    applied_property_values

    (Empty list)

    attributes

    (Empty list)

    chapter_nameNone
    constraints

    (Empty list)

    descriptionNone
    diagrams

    (Empty list)

    filtering_criteria

    (Empty list)

    foreign_idNone
    identifierNone
    long_nameNone
    nameNew showcase req1
    ownerCapellaModule "Test Module" (f8e2195d-b5f5-4452-a12b-79233d943d5e)
    parentCapellaModule "Test Module" (f8e2195d-b5f5-4452-a12b-79233d943d5e)
    prefixNone
    progress_statusNOT_SET
    property_value_groups

    (Empty list)

    property_values

    (Empty list)

    pvmt<capellambse.extensions.pvmt.PropertyValueProxy object at 0x7f3afc3ddd50>
    related

    (Empty list)

    relations

    (Empty list)

    requirements

    (Empty list)

    summaryNone
    text
    traces

    (Empty list)

    typeNone
    uuid0ce7877e-68d6-4113-8aca-be69b2e25253
    xtypeRequirements:Requirement
    " + ], + "text/plain": [ + "\n", + ".applied_property_value_groups = []\n", + ".applied_property_values = []\n", + ".attributes = []\n", + ".chapter_name = None\n", + ".constraints = []\n", + ".description = None\n", + ".diagrams = []\n", + ".filtering_criteria = []\n", + ".foreign_id = None\n", + ".identifier = None\n", + ".long_name = None\n", + ".name = 'New showcase req1'\n", + ".owner = \n", + ".parent = \n", + ".prefix = None\n", + ".progress_status = 'NOT_SET'\n", + ".property_value_groups = []\n", + ".property_values = []\n", + ".pvmt = \n", + ".related = []\n", + ".relations = []\n", + ".requirements = []\n", + ".summary = None\n", + ".text = ''\n", + ".traces = []\n", + ".type = None\n", + ".uuid = '0ce7877e-68d6-4113-8aca-be69b2e25253'\n", + ".xtype = 'Requirements:Requirement'" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "
    1. Requirement "TestReq1" (3c2d312c-37c9-41b5-8c32-67578fa52dc3)
    2. Requirement "TypedReq2" (0a9a68b1-ba9a-4793-b2cf-4448f0b4b8cc)
    3. Requirement "TestReq3" (79291c33-5147-4543-9398-9077d582576d)
    4. Requirement "TypedReq1" (85d41db2-9e17-438b-95cf-49342452ddf3)
    5. Requirement "New showcase req1" (0ce7877e-68d6-4113-8aca-be69b2e25253)
    6. Requirement "TestReq" (1092f69a-5f3a-4fe6-a8fd-b2dffde90650)
    " + ], + "text/plain": [ + "[0] \n", + "[1] \n", + "[2] \n", + "[3] \n", + "[4] \n", + "[5] " + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "new_req = model.oa.requirement_modules[0].requirements.create(\n", + " name=\"New showcase req1\"\n", + ")\n", + "display(new_req)\n", + "model.oa.all_requirements" + ] + }, + { + "cell_type": "markdown", + "id": "58941b28", + "metadata": {}, + "source": [ + "Info about creation: Whenever you have an ElementList which deals with one\n", + "specified classtype, here it is Requirement, then the classtype name doesn't\n", + "need to be included." + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "9156aac3", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
    1. Requirement "TestReq1" (3c2d312c-37c9-41b5-8c32-67578fa52dc3)
    2. Requirement "TypedReq2" (0a9a68b1-ba9a-4793-b2cf-4448f0b4b8cc)
    3. Requirement "TestReq3" (79291c33-5147-4543-9398-9077d582576d)
    4. Requirement "TypedReq1" (85d41db2-9e17-438b-95cf-49342452ddf3)
    5. Requirement "TestReq" (1092f69a-5f3a-4fe6-a8fd-b2dffde90650)
    " + ], + "text/plain": [ + "[0] \n", + "[1] \n", + "[2] \n", + "[3] \n", + "[4] " + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.oa.all_requirements.by_type(\"ReqType\")" + ] + }, + { + "cell_type": "markdown", + "id": "f6687b07", + "metadata": {}, + "source": [ + "We see our Requirements with type `ReqType` are missing the new one.\n", + "Let's change that, without using capella." + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "19f5f917", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
    1. Requirement "TestReq1" (3c2d312c-37c9-41b5-8c32-67578fa52dc3)
    2. Requirement "TypedReq2" (0a9a68b1-ba9a-4793-b2cf-4448f0b4b8cc)
    3. Requirement "TestReq3" (79291c33-5147-4543-9398-9077d582576d)
    4. Requirement "TypedReq1" (85d41db2-9e17-438b-95cf-49342452ddf3)
    5. Requirement "New showcase req1" (0ce7877e-68d6-4113-8aca-be69b2e25253)
    6. Requirement "TestReq" (1092f69a-5f3a-4fe6-a8fd-b2dffde90650)
    " + ], + "text/plain": [ + "[0] \n", + "[1] \n", + "[2] \n", + "[3] \n", + "[4] \n", + "[5] " + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "new_req.type = reqtype\n", + "model.oa.all_requirements.by_type(\"ReqType\")" + ] + }, + { + "cell_type": "markdown", + "id": "3878d8d5", + "metadata": {}, + "source": [ + "If you are sure about attributes when creating a Requirement you can also include\n", + "it during creation. " + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "f46766d6", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
    1. Requirement "TestReq1" (3c2d312c-37c9-41b5-8c32-67578fa52dc3)
    2. Requirement "TypedReq2" (0a9a68b1-ba9a-4793-b2cf-4448f0b4b8cc)
    3. Requirement "TestReq3" (79291c33-5147-4543-9398-9077d582576d)
    4. Requirement "TypedReq1" (85d41db2-9e17-438b-95cf-49342452ddf3)
    5. Requirement "New showcase req1" (0ce7877e-68d6-4113-8aca-be69b2e25253)
    6. Requirement "ReqType during Creation" (ec5f6680-501c-4a6c-a2ce-3ae8fe93be00)
    7. Requirement "TestReq" (1092f69a-5f3a-4fe6-a8fd-b2dffde90650)
    " + ], + "text/plain": [ + "[0] \n", + "[1] \n", + "[2] \n", + "[3] \n", + "[4] \n", + "[5] \n", + "[6] " + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.oa.requirement_modules[0].requirements.create(\n", + " name=\"ReqType during Creation\",\n", + " type=reqtype,\n", + ")\n", + "model.oa.all_requirements.by_type(\"ReqType\")" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "2530e4a4", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "

    TestReq1 (Requirements:Requirement)

    applied_property_value_groups

    (Empty list)

    applied_property_values

    (Empty list)

    attributes
    1. BooleanValueAttribute "AttrDef" (9c692405-b8aa-4caa-b988-51d27db5cd1b)
    2. DateValueAttribute "AttrDef" (b97c09b5-948a-46e8-a656-69d764ddce7d)
    3. IntegerValueAttribute "AttrDef" (85dfd42c-7f6e-4236-a181-bdd784040431)
    4. RealValueAttribute "AttrDef" (d2231d14-854d-4625-b48b-6cf1c2554367)
    5. StringValueAttribute "AttrDef" (ee8a69ef-61b9-4db9-9a0f-628e5d4704e1)
    6. BooleanValueAttribute "None" (dcb8614e-2d1c-4cb3-aa0c-667a297e7489)
    chapter_name2
    constraints

    (Empty list)

    descriptionThis is a test requirement of kind 1.
    diagrams

    (Empty list)

    filtering_criteria

    (Empty list)

    foreign_id1
    identifierREQTYPE-1
    long_name1
    nameTestReq1
    ownerFolder "Folder" (e16f5cc1-3299-43d0-b1a0-82d31a137111)
    parentFolder "Folder" (e16f5cc1-3299-43d0-b1a0-82d31a137111)
    prefix3
    progress_statusNOT_SET
    property_value_groups

    (Empty list)

    property_values

    (Empty list)

    pvmt<capellambse.extensions.pvmt.PropertyValueProxy object at 0x7f3ad72dfd90>
    related
    1. Entity "Weather" (4bf0356c-89dd-45e9-b8a6-e0332c026d33)
    2. SystemFunction "Sysexfunc" (00e7b925-cf4c-4cb0-929e-5409a1cd872b)
    3. Requirement "TypedReq1" (85d41db2-9e17-438b-95cf-49342452ddf3)
    4. LogicalComponent "Hogwarts" (0d2edb8f-fa34-4e73-89ec-fb9a63001440)
    relations
    1. CapellaIncomingRelation "Controlling the weather" (078b2c69-4352-4cf9-9ea5-6573b75e5eec)
    2. CapellaIncomingRelation "Test req" (24c824ef-b187-4725-a051-a68707e82d70)
    3. InternalRelation "None" (7de4c1a5-e106-4171-902a-502b816b60b0)
    4. CapellaOutgoingRelation "None" (57033242-3766-4961-8091-ce3d9326ed67)
    requirements
    1. Entity "Weather" (4bf0356c-89dd-45e9-b8a6-e0332c026d33)
    2. SystemFunction "Sysexfunc" (00e7b925-cf4c-4cb0-929e-5409a1cd872b)
    3. Requirement "TypedReq1" (85d41db2-9e17-438b-95cf-49342452ddf3)
    4. LogicalComponent "Hogwarts" (0d2edb8f-fa34-4e73-89ec-fb9a63001440)
    summaryNone
    text

    Test requirement 1 really l o n g text that is way too long to display here as that

    \n", + "\n", + "

    < > " '

    \n", + "\n", + "
      \n", + "\t
    • This is a list
    • \n", + "\t
    • an unordered one
    • \n", + "
    \n", + "\n", + "
      \n", + "\t
    1. Ordered list
    2. \n", + "\t
    3. Ok
    4. \n", + "
    \n", + "
    traces

    (Empty list)

    typeRequirementType "ReqType" (db47fca9-ddb6-4397-8d4b-e397e53d277e)
    uuid3c2d312c-37c9-41b5-8c32-67578fa52dc3
    xtypeRequirements:Requirement
    " + ], + "text/plain": [ + "\n", + ".applied_property_value_groups = []\n", + ".applied_property_values = []\n", + ".attributes = [0] \n", + " [1] \n", + " [2] \n", + " [3] \n", + " [4] \n", + " [5] \n", + ".chapter_name = '2'\n", + ".constraints = []\n", + ".description = 'This is a test requirement of kind 1.'\n", + ".diagrams = []\n", + ".filtering_criteria = []\n", + ".foreign_id = 1\n", + ".identifier = 'REQTYPE-1'\n", + ".long_name = '1'\n", + ".name = 'TestReq1'\n", + ".owner = \n", + ".parent = \n", + ".prefix = '3'\n", + ".progress_status = 'NOT_SET'\n", + ".property_value_groups = []\n", + ".property_values = []\n", + ".pvmt = \n", + ".related = [0] \n", + " [1] \n", + " [2] \n", + " [3] \n", + ".relations = [0] to (078b2c69-4352-4cf9-9ea5-6573b75e5eec)>\n", + " [1] to (24c824ef-b187-4725-a051-a68707e82d70)>\n", + " [2] to (7de4c1a5-e106-4171-902a-502b816b60b0)>\n", + " [3] to (57033242-3766-4961-8091-ce3d9326ed67)>\n", + ".requirements = [0] \n", + " [1] \n", + " [2] \n", + " [3] \n", + ".summary = None\n", + ".text = Markup('

    Test requirement 1 really l o n g text that is way too long to display here as that

    \\n\\n

    < > " '

    \\n\\n
      \\n\\t
    • This is a list
    • \\n\\t
    • an unordered one
    • \\n
    \\n\\n
      \\n\\t
    1. Ordered [...]\n", + ".traces = []\n", + ".type = \n", + ".uuid = '3c2d312c-37c9-41b5-8c32-67578fa52dc3'\n", + ".xtype = 'Requirements:Requirement'" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.oa.all_requirements[0]" + ] + }, + { + "cell_type": "markdown", + "id": "ec7a07c8", + "metadata": {}, + "source": [ + "## Export all requirements to excel with pandas\n", + "\n", + "With `Pandas` you are able to generate data tables and export to many file-types\n", + "like .xlsx for excel. Note that this requires the `xlsxwriter` module in\n", + "addition to `pandas` itself." + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "acbe3e06", + "metadata": {}, + "outputs": [], + "source": [ + "import pandas as pd\n", + "\n", + "requirements = [\n", + " {\"id\": f\"Req_{i}\", \"uuid\": req.uuid, \"text\": req.text}\n", + " for i, req in enumerate(model.oa.all_requirements)\n", + "]\n", + "data = pd.DataFrame(requirements)\n", + "data.to_excel(excel_writer=\"Test_requirements.xlsx\")" + ] + }, + { + "cell_type": "markdown", + "id": "03bf76ca-0703-4ae7-9270-e743063d7372", + "metadata": {}, + "source": [ + "## Export a Requirements module as Requirements Interchange Format (`.reqif`) file\n", + "\n", + "`capellambse` features basic export functionality for requirements modules, which allows to write `.reqif` or compressed `.reqifz` files. These can then be imported into other ReqIF-compliant applications, like CodeBeamer or IBM DOORS.\n", + "\n", + "Let's first take a glance at the module we're going to export:" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "e3f44e4c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "

      Test Module (CapellaRequirements:CapellaModule)

      applied_property_value_groups

      (Empty list)

      applied_property_values

      (Empty list)

      attributes
      1. EnumerationValueAttribute "AttrDefEnum" (11a2e07a-41f7-4eee-a94e-f3e33738c487)
      constraints

      (Empty list)

      descriptionThis is a test requirement module.
      diagrams

      (Empty list)

      filtering_criteria

      (Empty list)

      folders
      1. Folder "Folder" (e16f5cc1-3299-43d0-b1a0-82d31a137111)
      identifier1
      long_nameModule
      nameTest Module
      parentOperationalAnalysis "Operational Analysis" (ddbef16d-ddb9-4162-934c-f1e40e6f8bed)
      prefixT
      progress_statusNOT_SET
      property_value_groups

      (Empty list)

      property_values

      (Empty list)

      pvmt<capellambse.extensions.pvmt.PropertyValueProxy object at 0x7f3ad4787a10>
      requirement_types_folders

      (Empty list)

      requirements
      1. Requirement "TypedReq1" (85d41db2-9e17-438b-95cf-49342452ddf3)
      2. Requirement "New showcase req1" (0ce7877e-68d6-4113-8aca-be69b2e25253)
      3. Requirement "ReqType during Creation" (ec5f6680-501c-4a6c-a2ce-3ae8fe93be00)
      summaryNone
      traces

      (Empty list)

      typeModuleType "ModuleType" (a67e7f43-4b49-425c-a6a7-d44e1054a488)
      uuidf8e2195d-b5f5-4452-a12b-79233d943d5e
      xtypeCapellaRequirements:CapellaModule
      " + ], + "text/plain": [ + "\n", + ".applied_property_value_groups = []\n", + ".applied_property_values = []\n", + ".attributes = [0] \n", + ".constraints = []\n", + ".description = 'This is a test requirement module.'\n", + ".diagrams = []\n", + ".filtering_criteria = []\n", + ".folders = [0] \n", + ".identifier = '1'\n", + ".long_name = 'Module'\n", + ".name = 'Test Module'\n", + ".parent = \n", + ".prefix = 'T'\n", + ".progress_status = 'NOT_SET'\n", + ".property_value_groups = []\n", + ".property_values = []\n", + ".pvmt = \n", + ".requirement_types_folders = []\n", + ".requirements = [0] \n", + " [1] \n", + " [2] \n", + ".summary = None\n", + ".traces = []\n", + ".type = \n", + ".uuid = 'f8e2195d-b5f5-4452-a12b-79233d943d5e'\n", + ".xtype = 'CapellaRequirements:CapellaModule'" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "req_module = model.by_uuid(\"f8e2195d-b5f5-4452-a12b-79233d943d5e\")\n", + "req_module" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "5c555118-246d-47be-b462-6ce01822e156", + "metadata": {}, + "outputs": [], + "source": [ + "req_module.to_reqif(req_module.name + \".reqif\")" + ] + }, + { + "cell_type": "markdown", + "id": "94297761-841e-4900-945c-b5f87825627f", + "metadata": {}, + "source": [ + "And that's it! This code has created the file \"Test Module.reqif\" next to this notebook, which contains all Requirements defined in that module." + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.5" + }, + "vscode": { + "interpreter": { + "hash": "e7370f93d1d0cde622a1f8e1c04877d8463912d04d973331ad4851f04de6915a" + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/_sources/examples/07 Code Generation.ipynb.txt b/_sources/examples/07 Code Generation.ipynb.txt new file mode 100644 index 000000000..f9117c3a9 --- /dev/null +++ b/_sources/examples/07 Code Generation.ipynb.txt @@ -0,0 +1,399 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Introduction to Code Generation\n", + "\n", + "This notebook exemplifies how to generate automatically code in terms of interfaces. For this three examples are provided. The first one creates a ROS message, the second a standard python class and the last a protobuf interface." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import capellambse" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "path_to_model = \"../../../tests/data/melodymodel/5_0/Melody Model Test.aird\"\n", + "model = capellambse.MelodyModel(path_to_model)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In particular, we want to create code from our class:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Unknown global filter 'hide.technical.interfaces.filter'\n", + "Unknown global filter 'ModelExtensionFilter'\n" + ] + }, + { + "data": { + "image/png": "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", + "image/svg+xml": [ + "Trajectorylat : floatlon : floatalt : floatWaypointtest : strExamplefloatstr" + ], + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.diagrams.by_name(\"[CDB] CodeGeneration\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In order to access the classes, we can simply access the `data_package` of the operational layer, and from there access the attribute `classes`." + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
      1. Class "Twist" (8164ae8b-36d5-4502-a184-5ec064db4ec3)
      2. Class "Trajectory" (c5ea0585-7657-4764-9eb2-3a6584980ce6)
      3. Class "Waypoint" (2a923851-a4ca-4fd2-a4b3-302edb8ac178)
      4. Class "Example" (a7ecc231-c55e-4ab9-ae14-9558e3ec2a34)
      " + ], + "text/plain": [ + "[0] \n", + "[1] \n", + "[2] \n", + "[3] " + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "data_pkg = model.oa.data_package\n", + "data_pkg.classes" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## ROS2 IDL Message\n", + "\n", + "Let's have a brief look into the structure of ROS2 Message descriptions. They are stored in `.msg` files and comprised of a type and name, separated by whitespace, i.e.:\n", + "\n", + "```\n", + "fieldtype1 fieldname1\n", + "fieldtype2[] fieldname2\n", + "```" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [], + "source": [ + "def class_to_ros2_idl(cls):\n", + " filename = f\"{cls.name}.msg\"\n", + " lines = []\n", + " for prop in cls.properties:\n", + " multiplicity = (\"\", \"[]\")[prop.max_card.value > 1]\n", + " lines.append(f\"{prop.type.name}{multiplicity} {prop.name}\")\n", + " text = \"\\n\".join(lines)\n", + " with open(filename, \"w\") as file:\n", + " file.write(text)\n", + " print(f\"# file: {filename} \\n{text}\\n\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "In our example, files would be generated with the following content:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "# file: Twist.msg \n", + "\n", + "\n", + "# file: Trajectory.msg \n", + "Waypoint[] waypoints\n", + "\n", + "# file: Waypoint.msg \n", + "float lat\n", + "float lon\n", + "float alt\n", + "Example[] examples\n", + "\n", + "# file: Example.msg \n", + "str test\n", + "\n" + ] + } + ], + "source": [ + "data_pkg = model.oa.data_package\n", + "for cls in data_pkg.classes:\n", + " class_to_ros2_idl(cls)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Interface for python classes\n", + "\n", + "A python class has the following structure:\n", + "\n", + "\n", + "```\n", + "class class_name:\n", + " name1: type \n", + " name2: [type]\n", + "```" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "A python interface can be generated as follows:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "def class_to_python(cls, current_classes=None):\n", + " lines = [f\"class {cls.name}:\"]\n", + " current_classes = [cls]\n", + " if not cls.properties:\n", + " lines.append(4 * \" \" + \"pass\")\n", + " for prop in cls.properties:\n", + " if (\n", + " isinstance(\n", + " prop.type, capellambse.model.crosslayer.information.Class\n", + " )\n", + " and prop.type not in current_classes\n", + " ):\n", + " nested_text = class_to_python(prop.type, current_classes)\n", + " lines = [nested_text] + [\"\\n\"] + lines\n", + " multiplicity = (f\"{prop.type.name}\", f\"list[{prop.type.name}]\")[\n", + " prop.max_card.value > 1\n", + " ]\n", + " lines.append(4 * \" \" + f\"{prop.name}: {multiplicity}\")\n", + " return \"\\n\".join(lines)" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "# file: trajectory.py \n", + "class Example:\n", + " test: str\n", + "\n", + "\n", + "class Waypoint:\n", + " lat: float\n", + " lon: float\n", + " alt: float\n", + " examples: list[Example]\n", + "\n", + "\n", + "class Trajectory:\n", + " waypoints: list[Waypoint]\n", + "\n" + ] + } + ], + "source": [ + "trajectory = data_pkg.classes.by_name(\"Trajectory\")\n", + "text = class_to_python(trajectory)\n", + "filename = f\"{trajectory.name.lower()}.py\"\n", + "with open(filename, \"w\") as file:\n", + " file.write(text)\n", + "print(f\"# file: {filename} \\n{text}\\n\")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## Interface for Protocol Buffers (Protobuf) \n", + "\n", + "Protobuf Message descriptions are stored in `.proto` files where a class definition starts with `message` and each property of the class is defined by at least three parts: the data type, name and its order number. Classes can also be nested in other classes. An example is shown in the following:\n", + "\n", + "\n", + "```\n", + "syntax = \"proto3\";\n", + "\n", + "message class1 {\n", + " datatype class1_name1 = 1;\n", + " datatype class1_name2 = 2;\n", + " message class2 {\n", + " datatype class2_name1 = 1;\n", + " }\n", + " repeated class2 class_name = 3;\n", + "}\n", + "\n", + "```\n" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "metadata": {}, + "outputs": [], + "source": [ + "def class_to_proto(cls, current_classes=None, indent=\"\"):\n", + " if current_classes is None:\n", + " current_classes = [cls]\n", + " lines = ['syntax = \"proto3\";\\n']\n", + " indent += \" \" * 4\n", + " lines.append(f\"{indent[:-4]}message {cls.name} {{\")\n", + " else:\n", + " lines = [f\"{indent[:-4]}message {cls.name} {{\"]\n", + "\n", + " for counter, prop in enumerate(cls.properties, start=1):\n", + " multiplicity = (\"\", \"[]\")[prop.max_card.value > 1]\n", + " if (\n", + " isinstance(\n", + " prop.type, capellambse.model.crosslayer.information.Class\n", + " )\n", + " and prop.type not in current_classes\n", + " ):\n", + " current_classes.append(prop.type)\n", + " nested_text = class_to_proto(\n", + " prop.type, current_classes, indent + \" \" * 4\n", + " )\n", + " lines.append(nested_text)\n", + " lines.append(\n", + " f\"{indent}repeated {prop.type.name}{multiplicity} {prop.name} = {counter};\"\n", + " )\n", + " else:\n", + " lines.append(\n", + " f\"{indent}{prop.type.name}{multiplicity} {prop.name} = {counter};\"\n", + " )\n", + " lines.append(f\"{indent[:-4]}}}\")\n", + " return \"\\n\".join(lines)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "The protobuf interface of class `Trajectory` would look as follows:\n" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "# file: Trajectory.proto \n", + "syntax = \"proto3\";\n", + "\n", + "message Trajectory {\n", + " message Waypoint {\n", + " float lat = 1;\n", + " float lon = 2;\n", + " float alt = 3;\n", + " message Example {\n", + " str test = 1;\n", + " }\n", + " repeated Example[] examples = 4;\n", + " }\n", + " repeated Waypoint[] waypoints = 1;\n", + "}\n", + "\n" + ] + } + ], + "source": [ + "trajectory = data_pkg.classes.by_name(\"Trajectory\")\n", + "text = class_to_proto(trajectory)\n", + "filename = f\"{trajectory.name}.proto\"\n", + "with open(filename, \"w\") as file:\n", + " file.write(text)\n", + "print(f\"# file: {filename} \\n{text}\\n\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.5" + }, + "vscode": { + "interpreter": { + "hash": "c5ea7dc634d8047a259e5b898f154d237fbe6934b444b1a949475949608d751e" + } + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/_sources/examples/08 Property Values.ipynb.txt b/_sources/examples/08 Property Values.ipynb.txt new file mode 100644 index 000000000..8b637c4a8 --- /dev/null +++ b/_sources/examples/08 Property Values.ipynb.txt @@ -0,0 +1,930 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "f4599550", + "metadata": {}, + "source": [ + "# Property Values and Property Value Management Tool (PVMT) support\n", + "\n", + "capellambse provides access to property values and property value groups, as well as the additional information maintained by the Property Value Management Tool (PVMT) extension.\n", + "\n", + "Let's first take a look at how to work with basic property values." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "fb62b658", + "metadata": {}, + "outputs": [], + "source": [ + "import capellambse\n", + "\n", + "model = capellambse.MelodyModel(\n", + " \"../../../tests/data/melodymodel/5_0/Melody Model Test.aird\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "id": "f4effeec", + "metadata": {}, + "source": [ + "Model objects can own property values and PV groups. To access those, use the `property_values` and `property_value_groups` attributes respectively:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "3491dc40", + "metadata": {}, + "outputs": [], + "source": [ + "obj = model.search(\"LogicalComponent\").by_name(\"Whomping Willow\")" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "6f1304b7", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
      1. IntegerPropertyValue "cars_defeated": 1 (a928fa22-cef7-4357-9b87-675a432f6591)
      " + ], + "text/plain": [ + "[0] " + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "obj.property_values" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "573ce32d", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "

      cars_defeated (org.polarsys.capella.core.data.capellacore:IntegerPropertyValue)

      applied_property_value_groups

      (Empty list)

      applied_property_values

      (Empty list)

      constraints

      (Empty list)

      description
      diagrams

      (Empty list)

      enumerations

      (Empty list)

      filtering_criteria

      (Empty list)

      layerLogicalArchitecture "Logical Architecture" (853cb005-cba0-489b-8fe3-bb694ad4543b)
      namecars_defeated
      parent\"LogicalComponent\" "Whomping Willow" (3bdd4fa2-5646-44a1-9fa6-80c68433ddb7)
      progress_statusNOT_SET
      property_value_groups

      (Empty list)

      property_values

      (Empty list)

      pvmtProperty Value Management for IntegerPropertyValue "cars_defeated": 1 (a928fa22-cef7-4357-9b87-675a432f6591)
      requirements

      (Empty list)

      summaryNone
      traces

      (Empty list)

      uuida928fa22-cef7-4357-9b87-675a432f6591
      validation<capellambse.extensions.validation._validate.ElementValidation object at 0x720dec0f03b0>
      value1
      xtypeorg.polarsys.capella.core.data.capellacore:IntegerPropertyValue
      " + ], + "text/plain": [ + "\n", + ".applied_property_value_groups = []\n", + ".applied_property_values = []\n", + ".constraints = []\n", + ".description = ''\n", + ".diagrams = []\n", + ".enumerations = []\n", + ".filtering_criteria = []\n", + ".layer = \n", + ".name = 'cars_defeated'\n", + ".parent = \n", + ".progress_status = 'NOT_SET'\n", + ".property_value_groups = []\n", + ".property_values = []\n", + ".pvmt = >\n", + ".requirements = []\n", + ".summary = None\n", + ".traces = []\n", + ".uuid = 'a928fa22-cef7-4357-9b87-675a432f6591'\n", + ".validation = \n", + ".value = 1\n", + ".xtype = 'org.polarsys.capella.core.data.capellacore:IntegerPropertyValue'" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "obj.property_values[0]" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "3c105268", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
      1. PropertyValueGroup "Stats" (81bcc3d3-24d2-411e-a296-9943029acfd9)
      " + ], + "text/plain": [ + "[0] " + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "obj.property_value_groups" + ] + }, + { + "cell_type": "markdown", + "id": "06426fae", + "metadata": {}, + "source": [ + "## dict-like access to property values\n", + "\n", + "In addition to standard attribute-based access, these property value-related attributes can also behave like dicts in some cases. Here the dict key equates to the `name` of a property value or group, and the dict value equates to either the `value` of a property value object, or a list of PV objects in the group (which again can behave dict-like)." + ] + }, + { + "cell_type": "markdown", + "id": "574022f7", + "metadata": {}, + "source": [ + "This significantly shortens the way to a specific value. For comparison, this would be the \"usual\" attribute-based way of accessing it:" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "a10cf035", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "150" + ] + }, + "execution_count": 6, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "obj.property_value_groups.by_name(\"Stats\").property_values.by_name(\"WIS\").value" + ] + }, + { + "cell_type": "markdown", + "id": "12800ba6", + "metadata": {}, + "source": [ + "And here is the same again, leveraging the dict-like behavior:" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "id": "0e03011b", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "150" + ] + }, + "execution_count": 7, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "obj.property_value_groups[\"Stats\"][\"WIS\"]" + ] + }, + { + "cell_type": "markdown", + "id": "3e8f3666", + "metadata": {}, + "source": [ + "This of course also works for ungrouped property values:" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "id": "c56a533f", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1" + ] + }, + "execution_count": 8, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "obj.property_values[\"cars_defeated\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 9, + "id": "2cc26810", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
      1. IntegerPropertyValue "HP": 8000 (0e95950d-272f-4b50-b68d-ee8fed002c94)
      2. IntegerPropertyValue "STR": 42 (32be6f26-4b33-4861-b501-3bfce3df94cb)
      3. IntegerPropertyValue "AGI": 0 (addb1e4a-9ecc-411c-b7ef-b76388e5840d)
      4. IntegerPropertyValue "WIS": 150 (7c8c9c21-86b9-4dba-9c7c-cd9db2f09c11)
      5. IntegerPropertyValue "INT": 12 (647a5565-a1de-4e15-ab21-eb628eea413c)
      " + ], + "text/plain": [ + "[0] \n", + "[1] \n", + "[2] \n", + "[3] \n", + "[4] " + ] + }, + "execution_count": 9, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "obj.property_value_groups[\"Stats\"]" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "id": "b7943324", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "150" + ] + }, + "execution_count": 10, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "obj.property_value_groups[\"Stats\"][\"WIS\"]" + ] + }, + { + "cell_type": "markdown", + "id": "65b98527", + "metadata": {}, + "source": [ + "These property values can also be written to:" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "id": "b34fdf10", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
      1. IntegerPropertyValue "HP": 8000 (0e95950d-272f-4b50-b68d-ee8fed002c94)
      2. IntegerPropertyValue "STR": 42 (32be6f26-4b33-4861-b501-3bfce3df94cb)
      3. IntegerPropertyValue "AGI": 0 (addb1e4a-9ecc-411c-b7ef-b76388e5840d)
      4. IntegerPropertyValue "WIS": 150 (7c8c9c21-86b9-4dba-9c7c-cd9db2f09c11)
      5. IntegerPropertyValue "INT": 18 (647a5565-a1de-4e15-ab21-eb628eea413c)
      " + ], + "text/plain": [ + "[0] \n", + "[1] \n", + "[2] \n", + "[3] \n", + "[4] " + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "obj.property_value_groups[\"Stats\"][\"INT\"] = 18\n", + "obj.property_value_groups[\"Stats\"]" + ] + }, + { + "cell_type": "markdown", + "id": "75aa67fd-ab50-4796-8290-1c8c675a599f", + "metadata": {}, + "source": [ + "# Property Value Management (PVMT)\n", + "\n", + "Property values become much more powerful when using the [Property Value Management Tool extension](https://github.com/eclipse-capella/capella/wiki/PVMT). This extension groups property values into domains and groups, and allows to automatically apply certain groups based on specific conditions. These conditions may include the object class, the architectural layer, and other already applied property values.\n", + "\n", + "Metadata about the defined domains and groups is stored in a package named \"EXTENSIONS\" at the root level of the model, which is conveniently accessible as `model.pvmt`. The package will automatically be created if it does not exist yet." + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "id": "eda8206e-0272-4629-b467-b0cd1d959113", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/html": [ + "

      EXTENSIONS (org.polarsys.capella.core.data.capellacore:PropertyValuePkg)

      applied_property_value_groups

      (Empty list)

      applied_property_values

      (Empty list)

      constraints

      (Empty list)

      description
      diagrams

      (Empty list)

      domains
      1. ManagedDomain "DarkMagic" (3763dd54-a878-446a-9330-b5d9c7121865)
      filtering_criteria

      (Empty list)

      nameEXTENSIONS
      parent<capellambse.model.MelodyModel object at 0x720df69da180>
      progress_statusNOT_SET
      property_value_groups

      (Empty list)

      property_values

      (Empty list)

      pvmtProperty Value Management for PropertyValuePkg "EXTENSIONS" (fdbeb3b8-e1e2-4c6d-aff4-bccb1b9f437f)
      requirements

      (Empty list)

      summaryNone
      traces

      (Empty list)

      uuidfdbeb3b8-e1e2-4c6d-aff4-bccb1b9f437f
      validation<capellambse.extensions.validation._validate.ElementValidation object at 0x720dec2e55b0>
      xtypeorg.polarsys.capella.core.data.capellacore:PropertyValuePkg
      " + ], + "text/plain": [ + "\n", + ".applied_property_value_groups = []\n", + ".applied_property_values = []\n", + ".constraints = []\n", + ".description = ''\n", + ".diagrams = []\n", + ".domains = [0] \n", + ".filtering_criteria = []\n", + ".name = 'EXTENSIONS'\n", + ".parent = \n", + ".progress_status = 'NOT_SET'\n", + ".property_value_groups = []\n", + ".property_values = []\n", + ".pvmt = >\n", + ".requirements = []\n", + ".summary = None\n", + ".traces = []\n", + ".uuid = 'fdbeb3b8-e1e2-4c6d-aff4-bccb1b9f437f'\n", + ".validation = \n", + ".xtype = 'org.polarsys.capella.core.data.capellacore:PropertyValuePkg'" + ] + }, + "execution_count": 12, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.pvmt" + ] + }, + { + "cell_type": "markdown", + "id": "d87329f6-506f-4c92-8724-36ac6eed8ef6", + "metadata": {}, + "source": [ + "From there, we can easily enumerate the defined domains:" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "id": "2752918c-940a-46c5-916d-5a5bf0adac43", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
      1. ManagedDomain "DarkMagic" (3763dd54-a878-446a-9330-b5d9c7121865)
      " + ], + "text/plain": [ + "[0] " + ] + }, + "execution_count": 13, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.pvmt.domains" + ] + }, + { + "cell_type": "markdown", + "id": "812d4830-212b-46f1-aead-984d5041152e", + "metadata": {}, + "source": [ + "And see which groups are defined in that domain:" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "id": "542d35f7-826c-4275-b166-d7ecbcbe9a8c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
      1. ManagedGroup "DarkMagic.Power" (1e241678-282c-46f3-abbd-e0cf34e743ee)
      2. ManagedGroup "DarkMagic.Power Level" (a0cb5a23-955e-43d6-a633-2c4e66991364)
      " + ], + "text/plain": [ + "[0] \n", + "[1] " + ] + }, + "execution_count": 14, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "domain = model.pvmt.domains[\"DarkMagic\"]\n", + "domain.groups" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "id": "255adbdc-119d-4b1d-9085-31f5b8c42c55", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/html": [ + "

      Power Level (org.polarsys.capella.core.data.capellacore:PropertyValueGroup)

      applied_property_value_groups

      (Empty list)

      applied_property_values

      (Empty list)

      constraints

      (Empty list)

      diagrams

      (Empty list)

      filtering_criteria

      (Empty list)

      fullnameDarkMagic.Power Level
      namePower Level
      parentPropertyValuePkg "DarkMagic" (3763dd54-a878-446a-9330-b5d9c7121865)
      progress_statusNOT_SET
      property_value_groups

      (Empty list)

      property_values
      1. EnumerationPropertyValue "Skill": EnumerationPropertyLiteral "TheOneWhoShallNotBeNamed" (4da42696-28e2-4f90-bfb6-90ba1fc52d01) (7367c731-aabb-4807-9d74-7ef2c6482ec9)
      pvmtProperty Value Management for PropertyValueGroup "Power Level" (a0cb5a23-955e-43d6-a633-2c4e66991364)
      requirements

      (Empty list)

      selectorSelectorRules(raw='[PROPERTY]DarkMagic.Power.Max<10000.0[/PROPERTY]\\n[ARCHITECTURE]LOGICAL[/ARCHITECTURE]')
      summaryNone
      traces

      (Empty list)

      uuida0cb5a23-955e-43d6-a633-2c4e66991364
      validation<capellambse.extensions.validation._validate.ElementValidation object at 0x720dec0f1850>
      xtypeorg.polarsys.capella.core.data.capellacore:PropertyValueGroup
      " + ], + "text/plain": [ + "\n", + ".applied_property_value_groups = []\n", + ".applied_property_values = []\n", + ".constraints = []\n", + ".diagrams = []\n", + ".filtering_criteria = []\n", + ".fullname = 'DarkMagic.Power Level'\n", + ".name = 'Power Level'\n", + ".parent = \n", + ".progress_status = 'NOT_SET'\n", + ".property_value_groups = []\n", + ".property_values = [0] \n", + ".pvmt = >\n", + ".requirements = []\n", + ".selector = SelectorRules(raw='[PROPERTY]DarkMagic.Power.Max<10000.0[/PROPERTY]\\n[ARCHITECTURE]LOGICAL[/ARCHITECTURE]')\n", + ".summary = None\n", + ".traces = []\n", + ".uuid = 'a0cb5a23-955e-43d6-a633-2c4e66991364'\n", + ".validation = \n", + ".xtype = 'org.polarsys.capella.core.data.capellacore:PropertyValueGroup'" + ] + }, + "execution_count": 15, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "group = domain.groups[\"Power Level\"]\n", + "group" + ] + }, + { + "cell_type": "markdown", + "id": "f6ac05bf-5146-432a-b0c9-70adfee5cc78", + "metadata": {}, + "source": [ + "Group definitions also have a `selector`, which contains rules that determine the applicable model elements.\n", + "\n", + "The current ruleset can be introspected by reading the attributes of the `selector`:" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "id": "4d5fb68e-117c-43fb-9ab0-abcfa83df53b", + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "()\n", + "(,)\n", + "(('DarkMagic.Power.Max', '<', '10000.0'),)\n" + ] + } + ], + "source": [ + "print(group.selector.classes)\n", + "print(group.selector.layers)\n", + "print(group.selector.properties)" + ] + }, + { + "cell_type": "markdown", + "id": "c94d0ad0-827e-4597-8ffc-9bb9b35f18f0", + "metadata": {}, + "source": [ + "The ManagedGroup object provides some helper methods that interpret this selector:" + ] + }, + { + "cell_type": "code", + "execution_count": 17, + "id": "c7e0e417-6356-4839-ac70-f6c03439045a", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\u001b[0;31mSignature:\u001b[0m \u001b[0mgroup\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mfind_applicable\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m->\u001b[0m \u001b[0;34m'c.ElementList'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mDocstring:\u001b[0m Find all elements in the model that this group applies to.\n", + "\u001b[0;31mFile:\u001b[0m ~/devspace/capellambse/capellambse/extensions/pvmt/_config.py\n", + "\u001b[0;31mType:\u001b[0m method" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "?group.find_applicable" + ] + }, + { + "cell_type": "code", + "execution_count": 18, + "id": "59f8b642-1da4-4637-81bb-a29b8ab56347", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
      1. \"LogicalComponent\" "Harry J. Potter" (a8c46457-a702-41c4-a971-c815c4c5a674)
      2. \"LogicalComponent\" "Prof. A. P. W. B. Dumbledore" (08e02248-504d-4ed8-a295-c7682a614f66)
      3. \"LogicalComponent\" "R. Weasley" (ff7b8672-84db-4b93-9fea-22a410907fb1)
      4. \"LogicalComponent\" "Prof. S. Snape" (6f463eed-c77b-4568-8078-beec0536f243)
      " + ], + "text/plain": [ + "[0] \n", + "[1] \n", + "[2] \n", + "[3] " + ] + }, + "execution_count": 18, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "group.find_applicable()" + ] + }, + { + "cell_type": "code", + "execution_count": 19, + "id": "a040ff51-8804-47e2-983b-28963aaff0eb", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "\u001b[0;31mSignature:\u001b[0m \u001b[0mgroup\u001b[0m\u001b[0;34m.\u001b[0m\u001b[0mapplies_to\u001b[0m\u001b[0;34m(\u001b[0m\u001b[0mobj\u001b[0m\u001b[0;34m:\u001b[0m \u001b[0;34m'c.ModelObject'\u001b[0m\u001b[0;34m)\u001b[0m \u001b[0;34m->\u001b[0m \u001b[0;34m'bool'\u001b[0m\u001b[0;34m\u001b[0m\u001b[0;34m\u001b[0m\u001b[0m\n", + "\u001b[0;31mDocstring:\u001b[0m Determine whether this group applies to a model element.\n", + "\u001b[0;31mFile:\u001b[0m ~/devspace/capellambse/capellambse/extensions/pvmt/_config.py\n", + "\u001b[0;31mType:\u001b[0m method" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "?group.applies_to" + ] + }, + { + "cell_type": "code", + "execution_count": 20, + "id": "ca3e54f1-89be-4f94-b945-ec243fe45bd2", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "True" + ] + }, + "execution_count": 20, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dumbledore = model.search(\"LogicalComponent\").by_name(\n", + " \"Prof. A. P. W. B. Dumbledore\"\n", + ")\n", + "group.applies_to(dumbledore)" + ] + }, + { + "cell_type": "markdown", + "id": "27d394e5-f288-4d10-bae6-b1e954b0c6e4", + "metadata": {}, + "source": [ + "And finally, a group can be applied to an element with the `apply` method. If the group was already applied earlier, the existing group instance will be returned:" + ] + }, + { + "cell_type": "code", + "execution_count": 21, + "id": "f009f925-4257-400d-813b-e9f1a905fd8e", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/html": [ + "

      DarkMagic.Power Level (org.polarsys.capella.core.data.capellacore:PropertyValueGroup)

      applied_property_value_groups
      1. PropertyValueGroup "Power Level" (a0cb5a23-955e-43d6-a633-2c4e66991364)
      applied_property_values

      (Empty list)

      constraints

      (Empty list)

      description
      diagrams

      (Empty list)

      filtering_criteria

      (Empty list)

      layerLogicalArchitecture "Logical Architecture" (853cb005-cba0-489b-8fe3-bb694ad4543b)
      nameDarkMagic.Power Level
      parent\"LogicalComponent\" "Prof. A. P. W. B. Dumbledore" (08e02248-504d-4ed8-a295-c7682a614f66)
      progress_statusNOT_SET
      property_value_groups

      (Empty list)

      property_values
      1. EnumerationPropertyValue "Skill": EnumerationPropertyLiteral "Mighty" (1e5efe87-d919-4bd0-af2b-7c976ef9da96) (ba86dc67-296c-472e-8057-b660d5491532)
      pvmtProperty Value Management for PropertyValueGroup "DarkMagic.Power Level" (6cf12387-7187-4b91-9efe-8fedb8a148cb)
      requirements

      (Empty list)

      summaryNone
      traces

      (Empty list)

      uuid6cf12387-7187-4b91-9efe-8fedb8a148cb
      validation<capellambse.extensions.validation._validate.ElementValidation object at 0x720dec24dcd0>
      values
      1. EnumerationPropertyValue "Skill": EnumerationPropertyLiteral "Mighty" (1e5efe87-d919-4bd0-af2b-7c976ef9da96) (ba86dc67-296c-472e-8057-b660d5491532)
      xtypeorg.polarsys.capella.core.data.capellacore:PropertyValueGroup
      " + ], + "text/plain": [ + "\n", + ".applied_property_value_groups = [0] \n", + ".applied_property_values = []\n", + ".constraints = []\n", + ".description = ''\n", + ".diagrams = []\n", + ".filtering_criteria = []\n", + ".layer = \n", + ".name = 'DarkMagic.Power Level'\n", + ".parent = \n", + ".progress_status = 'NOT_SET'\n", + ".property_value_groups = []\n", + ".property_values = [0] \n", + ".pvmt = >\n", + ".requirements = []\n", + ".summary = None\n", + ".traces = []\n", + ".uuid = '6cf12387-7187-4b91-9efe-8fedb8a148cb'\n", + ".validation = \n", + ".values = [0] \n", + ".xtype = 'org.polarsys.capella.core.data.capellacore:PropertyValueGroup'" + ] + }, + "execution_count": 21, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "group.apply(dumbledore)" + ] + }, + { + "cell_type": "markdown", + "id": "49268151-0e87-4219-99e6-6f441f1275d1", + "metadata": {}, + "source": [ + "Each model element can have several property value groups applied to it. PVMT-managed groups can be easily inspected by using the element's `pvmt` attribute:" + ] + }, + { + "cell_type": "code", + "execution_count": 22, + "id": "6eff1218-4902-4eb2-b7de-5592e71610e8", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "

      Property Value Management

      Owner: \"LogicalComponent\" "Prof. A. P. W. B. Dumbledore" (08e02248-504d-4ed8-a295-c7682a614f66)

      ManagedGroup "DarkMagic.Power" (1e241678-282c-46f3-abbd-e0cf34e743ee)
      Min800.00.0
      Max1600.010000.0
      ManagedGroup "DarkMagic.Power Level" (a0cb5a23-955e-43d6-a633-2c4e66991364)
      SkillEnumerationPropertyLiteral "Mighty" (1e5efe87-d919-4bd0-af2b-7c976ef9da96)EnumerationPropertyLiteral "TheOneWhoShallNotBeNamed" (4da42696-28e2-4f90-bfb6-90ba1fc52d01)
      PropertyValueDefault
      " + ], + "text/plain": [ + ">\n", + "Group \"DarkMagic.Power\"\n", + " - Min: 0.0\n", + " - Max: 10000.0\n", + "Group \"DarkMagic.Power Level\"\n", + " - Skill: " + ] + }, + "execution_count": 22, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dumbledore.pvmt" + ] + }, + { + "cell_type": "markdown", + "id": "e14a5463-5305-404a-823d-fd9c13d3c679", + "metadata": {}, + "source": [ + "The `groupdefs` attribute will give access to the definitions of all groups that apply to this element:" + ] + }, + { + "cell_type": "code", + "execution_count": 23, + "id": "6ba61f22-2794-4690-b364-35279ceea31e", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
      1. ManagedGroup "DarkMagic.Power" (1e241678-282c-46f3-abbd-e0cf34e743ee)
      2. ManagedGroup "DarkMagic.Power Level" (a0cb5a23-955e-43d6-a633-2c4e66991364)
      " + ], + "text/plain": [ + "[0] \n", + "[1] " + ] + }, + "execution_count": 23, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dumbledore.pvmt.groupdefs" + ] + }, + { + "cell_type": "markdown", + "id": "f43313d5-7447-49eb-a610-28e166d35876", + "metadata": {}, + "source": [ + "On the other hand, the `applied_groups` attribute will yield the group instances that are currently applied to the object.\n", + "\n", + "**Note:** This list may be missing some groups from `groupdefs`. These can be applied using the group definition's `apply` method (see above)." + ] + }, + { + "cell_type": "code", + "execution_count": 24, + "id": "254db373-7b62-4985-9a3f-b02f589eb0ff", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
      1. PropertyValueGroup "DarkMagic.Power" (42dc9aeb-a06d-4012-8bc6-02fb06f94cdc)
      2. PropertyValueGroup "DarkMagic.Power Level" (6cf12387-7187-4b91-9efe-8fedb8a148cb)
      " + ], + "text/plain": [ + "[0] \n", + "[1] " + ] + }, + "execution_count": 24, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dumbledore.pvmt.applied_groups" + ] + }, + { + "cell_type": "markdown", + "id": "f16e13e2-919b-464c-92f2-8f5350f232b9", + "metadata": {}, + "source": [ + "Property values can also be accessed using convenient dict-like semantics.\n", + "\n", + "With keys like \"Domain.Group\", an applied group instance will be returned, where the group is applied first if needed:" + ] + }, + { + "cell_type": "code", + "execution_count": 25, + "id": "c31b91a4-00d6-4086-a0f7-0d74360cd8b3", + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/html": [ + "

      DarkMagic.Power (org.polarsys.capella.core.data.capellacore:PropertyValueGroup)

      applied_property_value_groups
      1. PropertyValueGroup "Power" (1e241678-282c-46f3-abbd-e0cf34e743ee)
      applied_property_values

      (Empty list)

      constraints

      (Empty list)

      description
      diagrams

      (Empty list)

      filtering_criteria

      (Empty list)

      layerLogicalArchitecture "Logical Architecture" (853cb005-cba0-489b-8fe3-bb694ad4543b)
      nameDarkMagic.Power
      parent\"LogicalComponent\" "Prof. A. P. W. B. Dumbledore" (08e02248-504d-4ed8-a295-c7682a614f66)
      progress_statusNOT_SET
      property_value_groups

      (Empty list)

      property_values
      1. FloatPropertyValue "Min": 800.0 (68b3e1b8-2d5a-432a-bf56-a8d3ad6b1742)
      2. FloatPropertyValue "Max": 1600.0 (defd6bbb-0209-47a6-b195-0e86f6210417)
      pvmtProperty Value Management for PropertyValueGroup "DarkMagic.Power" (42dc9aeb-a06d-4012-8bc6-02fb06f94cdc)
      requirements

      (Empty list)

      summaryNone
      traces

      (Empty list)

      uuid42dc9aeb-a06d-4012-8bc6-02fb06f94cdc
      validation<capellambse.extensions.validation._validate.ElementValidation object at 0x720df5da19d0>
      values
      1. FloatPropertyValue "Min": 800.0 (68b3e1b8-2d5a-432a-bf56-a8d3ad6b1742)
      2. FloatPropertyValue "Max": 1600.0 (defd6bbb-0209-47a6-b195-0e86f6210417)
      xtypeorg.polarsys.capella.core.data.capellacore:PropertyValueGroup
      " + ], + "text/plain": [ + "\n", + ".applied_property_value_groups = [0] \n", + ".applied_property_values = []\n", + ".constraints = []\n", + ".description = ''\n", + ".diagrams = []\n", + ".filtering_criteria = []\n", + ".layer = \n", + ".name = 'DarkMagic.Power'\n", + ".parent = \n", + ".progress_status = 'NOT_SET'\n", + ".property_value_groups = []\n", + ".property_values = [0] \n", + " [1] \n", + ".pvmt = >\n", + ".requirements = []\n", + ".summary = None\n", + ".traces = []\n", + ".uuid = '42dc9aeb-a06d-4012-8bc6-02fb06f94cdc'\n", + ".validation = \n", + ".values = [0] \n", + " [1] \n", + ".xtype = 'org.polarsys.capella.core.data.capellacore:PropertyValueGroup'" + ] + }, + "execution_count": 25, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dumbledore.pvmt[\"DarkMagic.Power\"]" + ] + }, + { + "cell_type": "markdown", + "id": "c81d6198-1515-4b99-82ea-fce3460e257d", + "metadata": {}, + "source": [ + "Keys may also contain a Property, in which case the value of that property is returned directly.\n", + "This is similar to the basic property values shown in the first part of this notebook.\n", + "However, like in the case without a Property, the group will first be applied if needed.\n", + "Newly applied groups have all their properties set to the default values from the group definition." + ] + }, + { + "cell_type": "code", + "execution_count": 26, + "id": "86c135a0-b032-4512-af77-d03fbc3492d0", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "1600.0" + ] + }, + "execution_count": 26, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dumbledore.pvmt[\"DarkMagic.Power.Max\"]" + ] + }, + { + "cell_type": "markdown", + "id": "0c19e78c-0fc6-420d-9aae-61e54fe80977", + "metadata": {}, + "source": [ + "This latter style also supports directly setting individual properties." + ] + }, + { + "cell_type": "code", + "execution_count": 27, + "id": "582b7c4c-29b7-4d6d-a5e7-c86a7afa171c", + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "9000.0" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dumbledore.pvmt[\"DarkMagic.Power.Max\"] = 9000\n", + "dumbledore.pvmt[\"DarkMagic.Power.Max\"]" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.12.4" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/_sources/examples/09 Context Diagrams.ipynb.txt b/_sources/examples/09 Context Diagrams.ipynb.txt new file mode 100644 index 000000000..0ef85d664 --- /dev/null +++ b/_sources/examples/09 Context Diagrams.ipynb.txt @@ -0,0 +1,853 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "id": "2cdf5dd5", + "metadata": {}, + "source": [ + "# Context Diagrams Extension\n", + "\n", + "We have an extension that visualizes contexts of Capella objects. The viewpoint\n", + "definiton depends on the object type. The extension is external to\n", + "`capellambse` library and needs to be installed separately. You may use the\n", + "below command to install it or find more guidance in the [package\n", + "documentation](https://dsd-dbs.github.io/capellambse-context-diagrams/)." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "e49dac7a", + "metadata": {}, + "outputs": [], + "source": [ + "!pip install capellambse_context_diagrams" + ] + }, + { + "cell_type": "markdown", + "id": "c93ced3d", + "metadata": {}, + "source": [ + "Now that the lib is installed we can load a test model" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "id": "d64ff435", + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Cannot load PVMT extension: ValueError: Provided model does not have a PropertyValuePkg\n", + "Property values are not available in this model\n" + ] + } + ], + "source": [ + "from IPython.display import HTML, display # we'll need that later\n", + "\n", + "import capellambse\n", + "\n", + "path_to_model = \"../../../tests/data/melodymodel/5_2/Melody Model Test.aird\"\n", + "model = capellambse.MelodyModel(path_to_model)" + ] + }, + { + "cell_type": "markdown", + "id": "e88f088c", + "metadata": {}, + "source": [ + "## Logical Component Context" + ] + }, + { + "cell_type": "markdown", + "id": "71d8da10", + "metadata": {}, + "source": [ + "and now as the model is loaded lets have a look at a context diagram for the `School` component" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "09c4d2ee", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "image/svg+xml": [ + "LFWhomping WillowR. WeasleySchoolPunishmentCare" + ], + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cmp = model.la.all_components.by_name(\"Whomping Willow\")\n", + "cmp.context_diagram" + ] + }, + { + "cell_type": "markdown", + "id": "e721cfa4", + "metadata": {}, + "source": [ + "## Component Exchange Context\n", + "\n", + "We also found it useful to spell-out the `ComponentExchange`s - this gives us a nice overview of functional interactions between the components" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "id": "040bfc14", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "image/svg+xml": [ + "LFWhomping Willowdefend the surrounding area against IntrudersR. Weasleybreak school rulespunish" + ], + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 3, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "cmp.related_exchanges.by_name(\"Punishment\").context_diagram" + ] + }, + { + "cell_type": "markdown", + "id": "8cff65de", + "metadata": {}, + "source": [ + "it also works for more complex arrangements but we dont have one in the current test model ;-)" + ] + }, + { + "cell_type": "markdown", + "id": "e9ecb867", + "metadata": {}, + "source": [ + "## Functional (dataflow) Context\n", + "\n", + "same applies for functions - we saw it useful to see what functions are dependent on an output of a function of interest and what inputs it needs to do what it should. We frequently use that view in documentation" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "id": "ba760fda", + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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", + "image/svg+xml": [ + "LFeducate Wizardskill He Who Must Not Be NamedTeachingeducate & matureeducate" + ], + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "fnc = model.la.all_functions.by_name(\"educate Wizards\")\n", + "fnc.context_diagram" + ] + }, + { + "cell_type": "markdown", + "id": "b073bfc3", + "metadata": {}, + "source": [ + "## Layers, other than LA\n", + "\n", + "Other layers are supported too - for complete list see https://dsd-dbs.github.io/capellambse-context-diagrams/ (Features section)" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "id": "99743283", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "

      Context of Root Operational Activity

      " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "image/svg+xml": [ + "OARoot Operational Activity" + ], + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "

      Context of Sleep

      " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "image/svg+xml": [ + "OASleepEatRepeatRestStart again" + ], + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "

      Context of Eat

      " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "image/svg+xml": [ + "OAEatMake FoodSleepMunchPrepared foodRest" + ], + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "

      Context of Spawn wild animal

      " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "image/svg+xml": [ + "OASpawn wild animal" + ], + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "

      Context of Make Food

      " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "image/svg+xml": [ + "OAMake FoodHunt wild animalEatHunted animalPrepared food" + ], + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "

      Context of Hunt wild animal

      " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "image/svg+xml": [ + "OAHunt wild animalSearch for animalsMake FoodAnimal locationHunted animal" + ], + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "

      Context of Search for animals

      " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "image/svg+xml": [ + "OASearch for animalsHunt wild animalRun awayAnimal locationSpot it" + ], + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "

      Context of Play games

      " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "image/svg+xml": [ + "OAPlay games" + ], + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "

      Context of Spawn tree

      " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "image/svg+xml": [ + "OASpawn treeCreate landslideTree" + ], + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "

      Context of Create landslide

      " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAApkAAAB2CAIAAAAMQB97AAAABmJLR0QA/wD/AP+gvaeTAAAgAElEQVR4nO3dd1wT5xsA8OfussmADPaQoSgyVAQHbhGLWgfu0aqtra11tNW2+rO1am1rbdVaV6u2xdZaVx11DxQVFReC4gAB2ZswEhIgyd3vD5QiIGhAMfJ8P/kj3r335uE+Z568645gGAYQQgghZLLI5g4AIYQQQo2CuRwhhBAybZjLEUIIIdOGuRwhhBAybZjLEUIIIdOGuRwhhBAybZjLEUIIIdOGuRwhhBAybZjLEUIIIdPGasK6UhISrpw9E3v1UkFeQUmRiqbxjnJ1oyjS3EJsaWfj16t/t/6BIomkuSNCCCFkwogmuYdrdnr63xvXJsff6eIv8fYSKeRckYhNYpv/CQw0U1yky8jUXrmmio0tGTRm/KCx4yhWU/6uQggh1HI0QS6PjozctPyr14Lkffsq2CyiScJqOQoKKrbvyNZUSOYu/0EoFjd3OAghhExPY3N5dGTklhXLPnjP0dnZrKliamkYBvYdyI6+ZVi07mdM5wghhJ5Vo3J5dnr60pnTZ81wwkTeeP/sy0rLkX36/WoSBycQQgg9i0bl8tULP3O1yw4aYNmYCLLzSo+cSkhLV7M5XJ2BcXESDernJLPgN6ZOU0TTsGpNsl//cQNHjmzuWBBCCJkS4+dbpSQkJMffmTbJ3egayisMK9eeF+gMI3u0c+rpTwjkIJAl5Vb8/s95Ah58OLUdRbWg0XeShPFjrFatCe0VHMwXCJo7HIQQQibD+Fx+5eyZLv4Soye7MQwsXHx4doDU0d6J4Iuqtrs62S6Y80F8RtGStauXfti+nhr0xaU3b6pzNSC2E3m2E4gp4wJ5idjZ8Vu7mV0OD+8zaFBzx4JeHFzM2SxwaejzlpSUHxGRFBWdnp+nLi7S4oXdIIoizaUCW1tJQDfn3r3dxGLe0x9rfB/7l++9NXo4181VaNzhYecT6VsxgR0dwGD4YZ+6lMVvN2mIYMemIwErNo92JgXynQePO4svd/CQ13m4ISP7x1B16z4yBwFTlKW37mXZzshAnsyg2v6t0meBU/sX+Cvh+vXCC1HCT1f8+OI+EjUfXMzZjHBp6POTmVm85bfIhMT8jr3dPDo7yazEQnM+Sbagflbj0Aa6WKnJTlVGn0+4ey01JMQnZIQPi/VU3wjGX7j5ufmWchejD79zO2uSIwcAdIn52m49v7R58PXVO5RdH4d7N4sZZwuALl16hB04+aRcnnWjkAhwfT2AQwBARwAARlN6I5m0okvv5hIOPhbuMhL0upTY4vs5Bo6txK89KzOyUO+pcBeDIaf4TBq7Z2cBF+jUq4W6VrziHEJBa+JywdZH6qF4eOJybxbEZZWWHMrS+ln7mpdeTaScOJrb+ZzO3UUijfbmDVUeyffpLFJwAACY0ppbjNOqldnuvanGH49MR9VizmmT3HEx54tHkYRUypFKOV6ekoKCiu07DkZdOIdLQxvv6tWU1T+G9xnRYdS8QBbb9PtLXyCSIi0UQguFsJ2vY2Guau8vEZcik5cuDhaJGm6gG98EUBWrhSK20Ye7u1vfzKgAALazlLp0fcXxMkdd0vUsVfrt66fVAAA3oq62e3Kj39yGm38h+3KqzlC1Sa06/nPi0SxSytUc+Cn5SjEYckqup9FCOasoPHHzBYMhPTfsjoEBJvVC2u4dufEVAAb1hdMavUF1fEvyaSUlM9MeXJcarXlYn9CWL6FYjh5iB3MC1Oqw0MQ9MXquhMWuUO/dnJnK48pL8zaFFhQxALW3GMvcgl2oLDb+eGQiKhdzzprhFDTAsjGJnGGgqLhMb6CbMLYWSCbjzJzh2NpZu3Tme+qSkuYOx4RdvZry409npywM7j3ch2JRDAPGvQwGulhZqNcbjK7B1F/mCtHUhcFOXnZzPzmgUpU1eOaNb5fTNNOYzsDA3q7zjsW2daqwsrH9fLqcEMgJgXyqQEbw5YQAUtLSI87s+nae55MOF3Zyel+XdfDPu3sqeJ362w3raSYAYLW2HhMoFRMWCuW9f2J0fr1kIXYADKPlqpdf09r7C/Ouq/X+nHvZooHe2tvJjAdfnWEjDiG1LFfFiN4WYkICd+8lZDMdXAgAEMgF1pZlTi5mVhQwaqDsFeNHW0kJ0F5JilXI3nfmU63kbaPy48tlXjdza2zxf4ZhjsdQJGHA7+VXXXZ6+qblXzVmMae2TP/rX1F52RoOiycQiCoYVplez+Ebpo5ytVbgAlFjEASEDLdmmKx1S77ApaHGycwsXvVj+NT/BTu1tgSjmjTqkpJ/1n6jyYwXULSALyhj2BqGx5bahrw701wma+p4X3YEQPBEf9rAfPvdqWVLB9c/SNFsg0MkSXy1ePCK1WdtecljegtljyZu5+QX7Tj6b1FJypI57eo7nqAcutrP6GqvyVDuD036k9/2XSeAh5cPobDiqLJ1hhLtkZ252TyORK0qZEnYrhKHg+o0JTtFbD6xA2y8rckXl4o9rDigraqUzSb0hid8IIusPFkadYUyufDiRQ0JwPYyt6Hq2IJQPf7euPa1ILnRifz+A+XG9WfnBLk69WhDCOQEv/KnsKzEwFv5y9buHUr6d7dp2oBfFjRdrAKx5DmOu44YZrNqTfLJfftwaagRtvwW2Wd4B8c2lsZ1TcZFXTn6w0fzB5jb+NnBw6taTgjkBVrWN98u6j5ygk+3gMaGSGvURYSZlG9CY1qvTfLf/OWhg4dihw31qqdYc/72NOOzl/wvMGh0pz+jHiz++8zX2w5+ufH3HYf/GB7ILJzRnvN0Ay0CO2lQF05Bjp4BYCroCgAAKMjXWcg4BVeyEtwc33nDcVSQxBwY4Ag9LUqjL6q57YRCN4nigTLiPtGudb2fUtfMQJGCJ1RIBgyxHfq67dBBUgd2HVsQepLKxZx9+yqMO9xgYDasPb1imLWjnHM78s76kxm5NJMaceZQGi0RCb/64svr9y3SMlUN1KIru7E/afmyO0uX3f5i2f0Tyc/43UuX3zxfnFdv/xGTm/392rySZ6uYvrb5zr7UmsdUVWVIz163OTeLbvgQo1UuDf13W6hWo2m4NKomKSk/ITE/YJAnMGDEq0yjPbpi5qrBLGtz6r8L+/yZQ2m0XGq+evHcywf3Fhcon1hD6cndI8du/mh26OxpWz5bfy+brrMYnbhr1zcHCgzAZOz88/NDpXT1vRV3vnk3/L6h8p91FWieF0kQw6YF7NwZpdFU1HP+m3/SprODZPY7/s96VM7F1BP5vNYOHE5pacRFwu9tHgnFhqScncfZPeXas7cE/WazhLfZhRH5UQqB8mJRISECgtXWgwjdSU/6hiJ4Ii/hg18LbZeKAfKe8BkER8bTxESpxC5mDtU2czysehxLCj1GBrYmC4sob18zQe0tJvSrD71YjVzMGRmVHuwCFEnoE5O2qr0+sY5fe97CKjY2PrlTsLslG2DWzHm/rJ394RTRE6tgdNf+fHDZ0XHWQjMzAhi9oZx4xmCYitizRVR3iZG/R4xFOdounPfcPwWXhhonIiKpQ083ik0Z98PqwpF9k9ooCcKu8sKeZ/Xowk7xDW5jyQb44O03d/27b/iUt59UA2E5YPD302wovXLvpzt23XCb5Vu7oUa4TZn6PcCjLlzm0ZsqTLVddRZoFlaOUmcPm4iIpKCgtk8q0/y53DiWna173C15kF2mEpgNnWPbSkIwucBqLe8m0eeoBUNnWDjxAXyd3iEK7mbrHQa7TM2nKACRt/UoPeMlBADKo7/DcLVYTgAIhQFdSC4BAISlj9xT9uh7jeT2e8sh8nppehHf3qaqDADFD57jdu96UXIiYeFiziLq2oLQI6UqlZnov8wae/XS6OFPTrQN0Wh1AjYAAGOgGYrisllUxp3wTIE+4+o9g78XAJ/PK9fV9/1jyMg7qVV80N/MjAAAIFgUD4DJzVn9t9aa0Sbw5NPfkZafT9sfXVFeTji+5jTGh0Nn5G7+Mz+PBj0lCJ7qaHMz83pGWcLaiuTBboPd6NSzjxUman5c9WOdukDOig3FEgWpLqpg2thPHyURE3TaudSdl7TlBlKvZrwBmFL10W0Zt0uhXMvuM92lql+Vyc3+YSc1faai9iHAGOoP45n4+QovhJ/AXP5MoqLTgyZ3Nzr1lWtUZpVrggw0TVFcNkVl3gnPFOjTr1Re2EKhWblW+8T6/8u9LHNXZ1ZCGcMAHbcp9KDnm/O6s+j0yE838L742qd0118/m41YMkTwX8bW5h756eTJtAqaMhQb3Kolczr92JHF5yuU+YzXuyOmdTEjyvPDNoYdTy7T6ER9PxgU4sGJr1U/eeviT6EPVIYKjcL3fwt9rLTZh9efvZirK6Osx8zt31Vh9GXp3d3tfPi9VzCXExyOs4/c2efxrRTbrauiU9XZIihHX0vHyvd2AAAgFvXr83CnwFU+8OE7YfdH/QKW3orqN6Rly0Q9gyq/dv8rAwDA4bbtZvXYSa29BSEAmqa/eO89c6l01FtveXTsCI1ezBng5/DVwWsBnsBu4zrpRvI2pdub7fkFw7s4Z6ZnlQEI4Y8/fw/uWfdKzkraFA3taCGs+aXCVGQz7vPbTpAQhrTM1fGid+fIRNriP37Kjvd0dLeSvznXUsAGVWTiqvDSz0fa+kYqfWY5tafAkJazq0bhx1tD1GPHqjv3AeAIB0+3cyDLj618cCFXMpDO3XGNN2FuKzui7OgPiWUAmpjsaDvH+UP4lUOATG6ts5pV8xBDegNhPBNcGmqE3Fy1zEps9D3Bu7w2csfcnxe7ALuN26SoB9uUbm+2FxQM7+KckZ5VBiCC37btDBgx8Yn1M0CXpGfcu6svjb/51y3HN6eSzKOkXDkz/NEbePyNIXX/8XNOA7/7TEGkXvpsaQX8twv4HQIWTLOh0i/N/y4m3a8L8e+JMOsByz6UG+LPL/jhkueGXjXrZ7SXdt1vNeuNCc6Vl64hafepmA7Dlw0QaCKPfr4j1XeWo7Ep195NceSPS/UUMNVcjpBJuHX1am5mZm5m5jcff+zZuXPI5MmNXMwp4LMHDuu8/Pitj4ZIfXp4dBDICb7cVUASNh0t+czW7X/rVdHebev7rUDTjF5fxy24KFthazEBAMUJqqRk1e6tKhLorGI6vxzcBYQuWXn6rjYvUZPPNdDwX56sq/Dj9bJqHAukiCOhAAiOvTUdW8Kos1RMewcbFgBwFFIiDYBnZ8YcStkK8i7+Fu0s68jJ6vs1D2k4jGeBS0ONoCrWmon5RvdIm8vkjq9/tDps/ewgWYee7Tvw5YSg8sLupODSa3/7m2vTytapVT31EyJ7W/d21qSruaAsPDyyuENgZTusej95rcFoRhMbA74zZWxgwFqiIHOrtfAJmbWIDQxhbelQkVRk0KRdN3ScKWUDw27dvpfgyO08un2N+gmOcxtm+8ojMNijT+9WtnxVbHTG/Ziw1VEklBUoKwrLGIdaP6KfklhqVlhQWk+BVyiXC6t1g5u4vaGhzR0CajInbtzwatXKxsIi9tq12GvXACDpgdroGyYCQJ8eLo4O0m+2XWczGV6ujhYWhVpIjU3JKSwpHNTPMmBgA41+M1ue/qIqjzazfsLMVzabtOpsOyXErCqLam6mrLsgGDPaulsb5t5ppv7CNdRzLAABAARJ1Li7J+Vk88knopvXlUfX5t6d0jak1ohE7UMaDOOZ4NJQI9A0QxBEY4aX+4S8meje4dNfvjGHVG8ntYV5oYrJvJmmzi+n+o6Z6tGpc32V/9dnzjHzGOK0d/b1uD59SGAeNpkf7a31IkiS1htqZvvqhQGAIYEBxmAwPCpJkWwKSGBq1k+6vjlxhW/C+bDIRftSPvrJn8OT9pw8eGpbskacz44kyfqvyVcnlxOCx7vBTdnerVubOwTUZPKKi0/HxHg4OnZ0eZhll393b9RI+9cGWhtdp4uT+dKF/XV6Oi5JmVdQaCnivNfLWihwaPhIAMrZsh8v7vd9/OnDJVIKwEBXAFm9o0DoLjELy78dZOYtBIYBggB1TjnXzcZNTpUllOUzZgAERRvK9QBUHYUfIghgGBpqH1uTwEmg21aY1p/vxNIVVU7A19FgLuwcKHSEuG0pesbrYVX1HPLEMNAL1IiHbj7k4uE9Y82O8rKy5Ptxafl5Egvp0PFteQLBU1b+sPNcn1Ok5PEEJLAtOJkPlLoAhSGvqJC2qt7HDgTQBgNDmLm10a87nT10qjVHqS5koFqZRyWBAQCG4LfzNKwNyx76ljUrM/6a3vFtBcGpVX95OSNt7z7cw5L5+Pj9Eq6fH//A4aQQd1cxwTAM8Tyvy1cnl79KQiZPbu4QUJOpapdXbZn/WdvGtMursFmkZ5v6hsbrRnL7vONG7c/Y+G0GyWcJ+JxOw5x6VEvmhEI+KTjt7/VxZ4QkIZNNHiuVd1RIf0n49jbXnKsXswmgBH5++r/WJMT3dRzrV7OwpHJKncSsTXnqr//ypndXSDdVO7YWyt5qQqcH21bECWVsWgWtANR3Mn4+piF5hIEQBE3mkPyHVb3X9YmH1I5ZguncZHF5PHcvn4bLPY7OPXVs4W0uQQHDMg+c08+eJGBAV48lBz+JFsvNygCsqhUmpO0dyn88tM12xMRRAwJWnPj0Q56VnCkh6rkzA9lq1MBeK08tmEPxeBZ9Z/V3JAmmRv2M5saWA3vuEzwWTbbxn6MgpUMGjtlwcunH18U8wmpg8Lt9jO1ib5jxz1aZ1Lfvlk2dmzYaBADT3r227cyZ5o7i2ezfvz8uLq7yvbW19aRJkyjqsc7OU6dOXb58ufqWwMDALl26vLgQm0nM5cvfz59f+b5yvHzprFn4H+flZ4r/DV+wGgs0Bg/+efmu95oxnlfe/DE/Hz78xDOM7XLUBP78fVNpWpSrvZSkuPsTi8+eCfst9I/qBQ4fPnQr6kpnr9aMvozWl4VH3uLxeC0hl3v5+Vna2lafx47QK6D2Ag2Al2MtdkuFuRw1jRHdWw3t2Y7iiXWkoOcHoRERET169KheILhf15mTgvWaIoO2SKuu9vgK/Y1Vo2fuzqbLs+8mMs4eNjxSEbJm7yedX4lrkyTJr37+uXrzBaFXQO0FGoCpvFm9Et+XqPkRJItNsnkEm8fniWaP6zM4OKhEra1eQiLk9vV1bWMnZnRahtb/t4PV8eN9Fz4GOmVN0GT9L6fnur5iD7XARG6icDlJ/Wos0BCR0ow7PezaPfGBWOi5wlyOmgIBQHEINo9k80k2LzDAZ+Vv/6Yssa9eZFNE6bIffwv9ZjqtLwP6CU+weYROWPnazHttmOhLoql/73ijdPNHn+9L1WhYHT/d9MNQe5JR3fj58S3P849DLRMuJ6lfjQUaLFr512ezek+Z7h8yrrlDa4kwl6MmQABBUmySxSdZPILFs7eX5RbXfODuEC/e6nVxjK6M1pU91i6vG6OJK+9z6dI6a5Y+eklQeJ/txyZZlRx+N/j7c8FretxeNffxLX3weTaoqeFykvrVWKChJ6VvfLPErp1n41emISNgLkdNg6A4BJtHsHkkm6cqBx6n5qWlNzAsiqD1ZYyujGmoXQ4ArPY9e1qxAOisiPDL18599nYYCaX3ssqSVQbXmlsYkL68K5BqTPdFpiJkypQmrG3Hjh0pKSmV752cnMaOHVtjtfHBgwdv3rxZfcvrr7/u7e3dhDE0oZjLl4MeTXmrHC//6LMIu7aeOGbeXDCXoyZBEBSbZPMqX/GJWa1tat4VJOxeuZ+HE60ro/Xap2iX/1czl2fmNnrRr8v9H12sTG7NLS+vuqf7opbnl3Wrxbp0BytzguLsDFVev3r5+5WrqxfYs3u3MietfWsHRl9G68uPnrtha2v70ubyuhZoRGAeb0bGfxlSFGmgGYp8edtDpoimgTTFU0oAQXEqO9gJFn//ySs3U1UWcwurF7EQcvb/GMjonrZdXlW1vG+Q/KctJ+b5DZITDE0TJFl7S5P/QU2lzum+qCUiYEJft16dXCmeuNTA7T59y5tT3vLy8qpWghkR3HvCkO4GbZFBU5iZ/dgjZSrOzfFc7Hbq1CxHEkB/Zb7noPuL4vZMkBEA+msLe6z0Pv73WMlTx6KPWdz9a/fTu8YbfceiuhdoYDJvPsbncnMLcXGRTirlNGE0qKREJzE3xf5YgqDYlXPfspWlf/8bFhcX7+zsXLX7ow9nW9Lp7Z2kBm0hrSuDZ2iXA+n67ob5c2cP67dOZkY4T96yerRN7S0vTTa/Gx19Nzq6+pba92NPSGzU/diRaXq41oNk8yQiybujevp19i2v0FUvcfSQWXfPH+2lHFpfBvRjN9/mdA7qkRJ6sWSWozkY7p24yrHKOnxGNWGUGOjUc5HyvjPFL/aPgboWaOBIeTMyPpfbtnJMTtFgLm9aeXllcitFc0dhjN1hMTEPCkkW59Sl2x99NLd6Iq90/GJsbl4Ooyun9eVX4/Pa9K+xn3Sacyq86h9u88IPVe3iuU9Yf3xC9cK1t7ws7kZH15j//Dzux45MEUFxKjuuSBZvQDfvvYdPn59T/b6i8N0J1Q8bt636dDyjK2OYx/uu+N0HdPr47LXycYHslFOX7ed/47Hy33Olo4YIlOcjoPd3lpAbvmzWV6eyVCpO1wWbV45yZjO54V8/voXOPLrwvWXn8nW6gpTb7X98oX88es6Mz+X+vQOvntveqaN5E0aDbsaqPf36NncUz2zS5Leq7uG6IHDM2LFjaxQYPGSoXPHf19ZIP6hxJ5lXTDsfn3YdOlS+f373Y0emhCAIFqdy0SbJ5tnZ2eSW6GoUed2LN233bVpfRutqrdskzHsHuqw6d0ff3+b0ebPAXwZYnl12MLJ8SLdL5/K7f+BceuyDhQ8mHjgz1CJrx6QB83b23DM06ovHt+wecvnzxTnTDkcMleX/Oqj14ab/E7Fd3oyMz+Vd+vbb8+umzKwyWxteEwbUkul09OUrxfNWmF4uHz58eP0FAgMDAwMDX0wwL4N2HTpUzoKuPd336w/nODvX8bgw9PJ4TtNWCIpbeT8lgs0rrdAIuDUf0KozAIsiGV0Zo9c+/mQ4ACCs+vUTzIjIUMpP032+lwokgz0XHb2u4Z1N6DjEk4n+40rbkJ/kBIDtiDe7Ldl7Q+N4vMYWrUNYlOfIjXICwKJzlzbHm/ivoyiS1tMk9dIMd71aGJqp/5o0/rwLzMyGTnxz+44sGp/z20ROnc538/BydGng+dPIhFRO923j6fm/Vavmf/99G0/PyokmzR0Xqs/zmLZCAFHZx06yeCSLdz8l382SW6NMWFx5Z09nWldXuxyAcu7fSxVx8vApVY9AGxKEvQe5XTr4T9hN135+HEavr9DpKr+KCTaHx6JqbwGKIvT659Z0NrcQlBRp6npEOL6a4KUq1kjMBfWc/0Yt6hkQMvLGxfP7/s0eORxH/horMVF9Kqzgyw3LmzsQ1JRqT/fFiSYvv+c0bYVkcSo72Ak2f9+py6dvF1nMVVYvYGnOP7y2J6PX0rXHywGA5RnYNX76ctnEHc4kAIj7BVsv/N+fnss+EADbu5f39e17M16faKs6u/+mT9AygXdhjS38dkr3a9v3Zg6ZYKuOiYrXuzftX+fgaJGRlCeW4uDRc6HMLZEr6ju3jeoPIUly5uJlMbcMe/dn40hJYyQmqjduSpu+YJGlTT3Pz0UmqcZ0X//egVevqZsrGPQ0bsaqPf26NXGlBEGwKu+nxE/MKDgWfiU7O5up5o1JExZ/MMLZSkjrypi673PM8Qv0KTZ0HNCOAgAgpAMGuans+vaxIICQhyxfZrt1RI++gaM2SRd9O0xK1t4iG/ntYsWWwQEDhk07UKBo6r7wngEud64kNH8D9hV9xUen+nayr+f8N/ZmG0KxeNH6X1Z+Nnft+pQJ463lspq9Rqh+Oh196nTeqTDl9AWLvP39mzsc9NzhRJOX3PObtvLHoavh0ekki3soPGrZ118rFI83/Rnm3zMx8YnJjK6M1pXfTMofWKsGwZDQrCFV/yKs3j5S+PbDf7CcRvx4YkT1wnVscR697vTopvpzaujZ03XrH1dyMwoVdhYNl0bPQq8z3L58f9zi4HrKUIsXL27kx3C43J4Dg4tLDL/+fDY9o4LFZlgUyeWRJGGC9zx5IWgaikt0qWna8HMFf2zLZAlaz1y8zKVt2+aOCzWBu9HRd2Ni2nXoUDWPvQY2h8NisY8fjOzaxQL/i7yETpzKYwncgkJGNW21XL6ZmcxOKHc0k9qNnzBp4sSJNQqw2Byu2FJg2drMpp3Qzsvbt3ufPn2srKzqrO0lxOFQLBZ16vBNr65tCLyym1Tk8RgJhxg61KueMgTTdJ3j6pKSS6fDrp49lZuRVagsNhhwUlzdSJKQSIRya8v2ft38e/fFyW6vkr2hoXu3bg2ZPLmeu3nTNL1i3ocONoU40eRlk5io3vBL2pcbNuNolxFomln4+WGJvaLvqC7NHcurIz0xZ8/aY6tXjbC2ru+GQE15Q2uhWDxg+IgBw0c0XBShFqxyosnSme8RkD1imDW2YV4SOG2lkUiS+N+CwLnzDhAE0XuEP17YjZeemPPPhuPz5varP5FDI+e+IYSMUznR5P4D/tr1KfkF5c0dTkun09FHj+ds+CXt3fk4baVRRCLeyh+GZydk7vrpSGGeimEAX8a9dBWGi0dv7Fl3bO5HfX19HRo8800wXo4QqtLgeHkVnGjSvHDaynPC5bIC+7dRF2m2/3ImL11JsigWi+Rw2YQpPjXqxWJoprRYk51acP3MnaN/njXnEgvmD2jTxvJpjm3K8XKE0NOMl9eAE02aBU5bed5UqrKzZxMiLjzIzCopUpbihd0gkiTEEoFCIfT1te8R4OLsLHv6Y1/+B0Aj9IrDiSbolSQS8YYM8RwyxLO5A2kRcLwcIYQQMm2YyxFCCCHThrkcIYQQMm2YyxFCCCHThrkcIYQQMm2YyxFCCCHThrkcIYQQMm2YyxFCCCHThrkcIYQQMm2YyxFCCHK7cHoAABD3SURBVCHThrkcIYQQMm2YyxFCCCHThrkcIYQQMm2YyxFCCCHT9szPPE1JSLhy9kzs1UsFeQUlRSqaxsefPzOKIs0txJZ2Nn69+nfrHyiSSJo7IoQQQibsGXJ5dnr63xvXJsff6eIvGT1cpJA7i0RsEhv2z85AM8VFuoxM7ZVre/Zt/W3QmPGDxo6jWPgseYQQQsZ42vwRHRm5aflXrwXJp01yZ7OI5xrTK48iCamUI5VyvDwlBQUV23ccjLpwbu7yH4RicXOHhhBCyPQ8VbM6OjJyy4pls2Y4BQ2wxETetGQyzswZjq2dtUtnvqcuKWnucBBCCJmehnN5dnr6puVfffCeo7Oz2QsIqAUiCAgZbu3jSa5b8gVN080dDkIIIRPTcB/73xvXvhYkb2QiV2t0R08l3IlXsig2DaRUygvu6+DiiHO+/jNimM2qNckn9+0bOHJkc8eCEELIlDSQy1MSEpLj70yb5N6Yz/ht2/W0+LyQgNajRvekzOQEX56nZe8Pv7plV8yn77ibS3iNqfyVQZIwfozVqjWhvYKD+QJBc4eDEELIZDTQx37l7Jku/pLGjJGv2XDenVYuGu7q5SQliYf1WMok098Y9/n8b5esT9KW6euvQV9cGnU+59jxnIuxmhKD0YGYADs7fms3s8vh4c0dCEIIIVPSQC6PvXrJ20tkdO0FhVpddlY3VyEwmr3bLi3acnLZ+ZKMfRu7fBejBTCXiOfOW7r9UGo9NRgystesy0onOVaW7PJUdYbW6FgazaDavizl9nP+MeHnK7wSfuL5fgZCCKFXSwN97Pm5+ZZyF6Nrj3+g9JIDAIBGGcNzXzRBsHzn/cNc16ns25fL+/cVgKuLS3Z+fXebybpRSAS4vh7AIQCgIwAAoym9kUxa0aV3cwkHHwt3GQl6XUps8f0cA8dW4teelRlZqPdUuIvBkFN8Jo3ds7OAC3Tq1UJdK15xDqGgNXG5YOsj9VCQAACMPvFS3eX1bcTUg0fVevJUNwviskpLDmVp/aw72xJMqfbmDVUeyffpLFJwgNGoryZSThzN7XxO5+4isbEdGa1ame3eW9+PG4QQQqiGBtrlqmK1UMQ2unY3J4u7SgAA4Fu0Vcd/9/d9jq3qYlxhZsb9Yzd0AJCaliY3r68Gcxtu/oXsy6m6/9rDatXxnxOPZpFSrubAT8lXisGQU3I9jRbKWUXhiZsvGAzpuWF3DAwwqRfSdu/Ija8AMKgvnNboDarjW5JPKymZmfbgutRoDQAAEBT9hPIVxdWqjagQ2vIlFMvRQ+xgTkCFeu/mzFQeV16atym0oIgBUKvDQhP3xOi5Epbx5wvA3IJdqCxuRAUIIYRanAba5TTNNObObgqZoMJcEZ2q6eguHz+lKyGQEwIZMUpOCOSEgK0u1Xz33RdLZ9fX7hd2cnpfl3Xwz7t7Knid+tsN62kmAGC1th4TKBUTFgrlvX9idH69ZCF2AAyj5aqXX9Pa+wvzrqv1/px72aKB3trbyYwHX51hIw4htSxXxYjeFmJCAnfvJWQzHVwIAKKVZ93lRzpK2jpWVathdxdYW5Y5uZhZUaC9khurkL3vzKdaydtG5ceXy/wAKHvF+NFW0sYtv6dIwmDAZWkIIYSewXO/b+gnc/qu33Lp+KGk8b25zs6VHe6g1pTtP3ow6ta1Be+0FgrqbccSlENX+xld7TUZyv2hSX/y277rBACV3fKEwoqjytYZSrRHduZm8zgStaqQJWG7ShwOqtOU7BSx+cQOsPG2Jl9cKvaw4kDVYDvBZhP6Ry39J5Vnl5T8W63a6kFp1BXK5MKLFzUkANvL3IYCACBYJN6FFSGE0Iv33LMPQcDMd7opi7T7j8anX0ljsbkGmuCbsQb2sRs3yOfp6xHYSYO65P2So2ecgKmgKwAAoCBfZyHjFFxJS3Bz/qgvh05Mu32aAY7I0yI3+iKL204mdGMUJ5QRAqLdeArKn1A1R1hn+bwrWY9VCwAMU/kjQqTgCRXiAUOkZo9a4fiEGYQQQs3lBbUkpeb8t8Y/Q+auknMx9UQ+r7UDh1NaGnGR8HubR0KxISln53F2T7n27C1Bv9ks4W12YUR+lEKgvFhUSIiAYLX1IEJ30pO+oQieyEv44NdC26VigLwnfMYTygvMa1TLkfE0MVEqsYuZo4dVj2NJocfIwNZkYRHl7WvGb8zZQQghhBrhZe8Vtuxs3eNuyYPsMpXAbOgc21YSgskFVmt5N4k+Ry0YOsPCiQ/g6/QOUXA3W+8w2GVqPkUBiLytR+kZLyEAUB79HYarxXICQCgM6EJyCQAgLH3knrL/RrbrLE/UqJbk9nvLIfJ6aXoR30HGD57jdu96UXIiYeFiznqscoQQQuiFetlzOcHhOPvInWs06Sm2W1dFp6rESVCOvpaOle/tAABALOrX5+FOgat84MN3wu7+Dzdaeissq39KneVrVUvKRD2DHq2253DbdrNqW1VFtcoRQgihFwkfP44QQgiZtpe9XV6HFtCbvTc0tLlDQEa6Gx3d3CEghFoc08vlRAvozd67dWtzh4AQQshkmF4ubwlCJk9u7hBQo7Tr0KG5Q0AItSCYy19GIVOmNHcICCGETAbm8lefVqstKyurfM/lcgW1Ho6u0+mqClTicDhcLvcFxYcQQqhxcB77q++rpUttbaxcWjm4tHKwsbbcWmti3ebNm2Uyma2Nja2Nta2NtUIumzN7VnNEihBCyBiYy1sCZs5g19sbh937/c0TqyZ++snH9+7dq1Hi7YkjC2IP517dnnl2/bezhjPME5/TTqce/3l/3KPdTN7533bGlD2p8FMFp7y09e+o0nq3vFj6O/9sOp2FT7hBCJkM7GNvEQiKRbL5BJvn5iSeM773pPFjfH19q/beu3dPVVxQqCwQsnSMvoyhdfXcX96QcnTDvn5Th7tTAAB03rlfd9iPGOvDayCCitMzu+4aGvlzEKfmHkZ54fe/JK+N6/Tfze1rbXmx9Lf3/BLj/FY/G/ylixAyDZjLWwaKTbB5JJtHsnmjBnZZ8dvRCW7p5KNM2c4WIrQVcxev2vjlNFpXxhh0z/qwGEYZufcK11V/41wC0+718QNcBQAV2VcO7DuXpJV4DBwTzDu97ezdK3lffV087rPRbnnXjh2JiC8283ht7CAPIQBTnnHhrzXJJTY9RoT42zx2TTKFsYf/CUtieQ0Z28+l2l3vmaLbR/aciIO2Xey1ep/hvbiXd14y8+XfOJ7sMmpKTyvN/bB/jsWW2fceOayjnKQzwn69Zv/WMHeKUV7cepw/ZnyHstoBA1MUe3jPyXhw1qrwWTkIIVOCLY8WgSBZJItHsngEi2djZcXncQa3503palb1+iFEcuDUFUOFlnmYy58No4xYOf7tdSliJ4s7S4fOPFjElEf8b8SiWzIvb3uiVE2Tco/2NhzrDkFBHWxIffzJfTe0Cmd5xsYxE7ak0gC6Czv3FFjZG058MOD9Q8pqebT03IKxi6JEbRwLN02Y/GdGVbe3NvLLoe8f0jnal+/7cMKik1k0o7ywdur4Tw4XCm3MBRVR34ZM31dmZ6fdPy3ww5MlQGec3LwvTg8AdMGF37dfVzO1A4ayyC+Hzjisc7QvP7LvYkWTnHaEEHoxsF3eIhAki2DzCDaPZPNJNo/LYZXrH2t6mvNJDovIyy+Q8vRG5HIA4AS8//WMUVbEYPpUj4h7uh4PEosVo317vuYqIAAAzDq2cb3v28WvNQdA+ubXXgBMRZHZpZ67YnR9gdPvo9Wzx1kRI+xT/JbtyQnu97DOon/XHXWdvLerB4ue3nfPL+dL3xgnAgBQH1t/yHfZpfd7cWEQnO9xEwAAWD7vrf1+lgMJpQem7G2/+ML0XlwIViR2XrO/oE/bBgPW983acNh32cXH60QIIZPQQC6nKNJAMxT5St8x9WVC00A+h7NNUCySzascMtcT7Fylykby2Mq07BIDm8WSC1l6rar+8XIgCMZgqNrPMDTxWMCUQEBV6AiLkcsWXJ073GOxReC8Navf6VhtgRuTc3LJh+vjRE62+efSuAMqKwUAAE47L5eClLxHzW+6OC8n/ereraHRFABv0LB27IfblenZ0lZO7MpoHn04weVxCACg85PTzR/u5bl7OhVkF9B15fLHA6aV6VkWtepECCGT0EAuN7cQFxfppNJaE5bQ81FSopOYixou94wIkk2y+ASLR7J4l289sLQQfvqvpmqvwWC4l6Ub0sub1lf2sevrGS+nrO0s4m7G60d4swBAk5RYbhdgVkc5Qfs3fjr2xg+Zh2YPXPDXkKNvATAMAwBAJ/31zcWAP47NdDBcnHtsLQ0AwNAMAIAhLTnXtpX1o4EfUuHqKncJmrNonOyx5ErK7a2yTsSXgVPNlfIAAKSFtSzjTFwZOAlAn5ZcYNfRimJzQKvRATx5yTwpt7PKOvmkOhFC6KXWQC63beWYnKLBXP7C5OWVya0UTV4tQbGq5r5t3nWiz8Ch3boHVO0NDw83M8R888HrtK6E1pcxhgqgnlgV6TJxdvvgadMEH41orYv5a1PRu1t6siG5Rimm+NzPG+Kt/dw48Xl8ewcRQdm3El87sPesZbfOTvbWab/+utfNO/W3A+lUAABUnFn98RrpOOm1Dae6fnpEQapF/PSo8Lv5owbMeWvFpLe/5XzYyyw9SzJ4VFcLAgBAEPjWgKWfzFirDhFf2hBeEfDJY58tHvx+8Iq5M9ZqRorOrb3y2tJFEpa+e8fbX3+5TdSjeOfv13Uf1/V3CQbUVydCCL3MqMWLF9ezW1ehv3Hpemdf8YuKp6ULP6e0bd3To2OnJqwzLCxMV5Ll49FaB+wj52/+deDsocNHunXr5vtITk5OUWa8v7tCXVykLimOis/UcO1eHzq87uoIkcew8QG81Ni4HFb7N778fIgjCwAIUuDQwcuGA0AQpNS9c2srlirx5q34fPnQhXNfs+aQsk593fIir+dbeHYNGhIgSLyRRHtPnf6avYOHu6VF5wG++rj4Cu93ls7qZk4QonadbNKj0s29fDr0HzvQMiPq2j2ledvOnk6Sh73sXOcBIb6Ge7H5sgCn/LP6/m/3saaqAgBOqwGjuhBxN5LJLjOXTusoJIDr1j/IPvtGfIXbhHdHuNi39bBh1wjY183S5VGdA98e39HWxaOVCLvaEUKmgXjY8fkEmtLSTyaNm/tRK1ubhhYQo0bT6eiFi+LnrVjj6OLShNUuXbLkxx9XVY5JKxTyXbv/8fHxqV4gNDT000/mwsMrgQGGmTL17RU/rGzCGJ4XQ+yyfkuc9+2aKMW8ixBquRrI5QBwfM/uq6d3fjzHmcT1a8/Z0eO5abl2s5d+09yBvPSY3OOr1yc4dJbf/W2Tas6B7/sImzsihBBqRg3n5wEhI1k8233/Zr+AaFqyxET1qbCCce/jjdCfAiHx6d9dkpNU5P3lru8wkSOEWrqG2+UAoC4pWTrzvQ5e1Ihh1rhc53lITFRv3JT27vxF3v7+zR0LQgghE/NUuRwA1CrVys/m8tlFE8Zby2X4NMwmo9PRp07nnQpTTl+AiRwhhJAxnjaXA4BBrz+6e9fhHX+1by/x9xPa2fDNLdh4Gxkj0DSUqHS5ueW3YlWXrxS7eXiNe3+WpY1Nc8eFEELIJD1DLq+kLim5dDrs6tlTuRlZhcpigwEfDfnMSJKQSIRya8v2ft38e/dt2lnrCCGEWppnzuUIIYQQeqngOjOEEELItGEuRwghhEwb5nKEEELItGEuRwghhEwb5nKEEELItGEuRwghhEwb5nKEEELItGEuRwghhEzb/wE1ZzQbOg+lBgAAAABJRU5ErkJggg==", + "image/svg+xml": [ + "OACreate landslideSpawn waterSpawn treeBuild houseUnstable groundTreeWood" + ], + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "

      Context of Spawn water

      " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "image/svg+xml": [ + "OASpawn waterCreate landslideUnstable ground" + ], + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "

      Context of Build house

      " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "image/svg+xml": [ + "OABuild houseCreate landslideWood" + ], + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "

      Context of Run away

      " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "image/svg+xml": [ + "OARun awaySearch for animalsSpot it" + ], + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "

      Context of Repeat

      " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "image/svg+xml": [ + "OARepeatSleepKillStart againHunt" + ], + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "

      Context of Kill

      " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "image/svg+xml": [ + "OAKillRepeatHunt" + ], + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "for act in model.oa.all_activities:\n", + " display(HTML(f\"

      Context of {act.name}

      \"))\n", + " display(act.context_diagram)" + ] + }, + { + "cell_type": "markdown", + "id": "b9b28af3", + "metadata": {}, + "source": [ + "## Customizing context views\n", + "\n", + "For almost every context view you can do some tuning. Just like in Capella itself you can apply view filters, like hide or show exchange items instead or next to exchange names. You can see more of the tuning options here: https://dsd-dbs.github.io/capellambse-context-diagrams/extras/filters/#capella-filters" + ] + }, + { + "cell_type": "code", + "execution_count": 6, + "id": "2c88ed82", + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "

      Context of Stay alive

      " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "image/svg+xml": [ + "Stay aliveEscape predatorsEat foodFunctional Human Being" + ], + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "

      Context of Escape predators

      " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "image/svg+xml": [ + "Escape predatorsStay alivePreyPredatorFunctional Human BeingWeatherEntity 5" + ], + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "

      Context of Eat food

      " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "image/svg+xml": [ + "Eat foodStay alive" + ], + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "

      Context of Provide environment to live in

      " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "image/svg+xml": [ + "Provide environment to live inProvide food sourcesEnvironment" + ], + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "

      Context of Provide clean water

      " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "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", + "image/svg+xml": [ + "Provide clean waterProvide environment to live in" + ], + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/html": [ + "

      Context of Provide food sources

      " + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAaUAAAA4CAIAAADSP3DQAAAABmJLR0QA/wD/AP+gvaeTAAASkUlEQVR4nO2deVgURxbAX3X3zHDDwHB7IUY8oigYUVFRVBRBgwoqoAYFjSaeIVE/71s8FkXU1fWKUXHVJESMUUlUjOAV4xGNy4KGRIlCQJQZGJiZ7q79YziG4RwYCevUz/74/F53vXqvqnjdVa+pRhhjIBAIBAOA+rsNIBAIhGaCxDsCgWAokHhHIBAMBRLvCASCoUDiHYFAMBRIvCMQCIYCiXcEAsFQIPGOQCAYCiTeEQgEQ4Gp+3RqampaWhoAeHt79+/fn0gMRNJo/Pz8mlKcQGg6ycnJtZ1Cdf89WWpqahN/AQj/dzSl0/38/M4kJerXHgKh4YwaPaaOeFfP811aWhqJd4ZGEzsdY16PxhAIeqSeeEcg6A7ZgYLQQqkn3nl7ezePHYSWQxM7ney4Q2ix1BPvyGTWAGlip5N4R2ixkPksQc+Q9TtCi6We9+9SU1Obxw5Cy6HJnY7JQY6/76gLkp8laNPk/Gw9Y45A+Lsg81mCniHxjtBiab78LMexRdLXGPOm5lYCgVBfagl6p8n5Wf2s33GsqlgmBQBTcwuaEehFJ8HAebP5WY5j7137Pjf7N4x5WiCwsLBGFCqSvlYpFQCUhY1db59AocioKVUQ9E5T87P1raHUgUqlenAzRVqQhwCJhEZmlmIAKJK+VihKMGBLa7t3vXwEAhL7CI3kDc5nb1xOev74QdfuPV0H+NJCI1pgRNEChIDnWE6l4JSlr/JfnE+IM7dxHBgQRtNkZv220Kj5LMb4p5TvpHnPe3j2tXHvxQiNaYEI0QJAgMsGTEl+TvaVxM8tbBzeGxyAENK74YS3njeSn+VY1dcHYoyUhd4DBklsHRFCCFGIoiiKRhSDKBohCiFkYSnu02+go7XpyT1rSuRFjbK/gQZJX+QUkbckGkgT87NYd5SK0rNH4p2szAYMHGplLUGIAkQhiqZomqIYhCi1RGwtGTBwiJO1+dkj8UpFaSMq0pXS/JyXirekFr2jq9nN42bdg7OeeKfeNkNXTh+O7dKhnZ2DIwKEkPoHhRCNaLo82FGAEABCCFlaivt4enxzIAbztUck6dEgcavuffp69erhFbTywnPdYhd7P3bMxN3pnKas9FSo57I7bO2F5Hd2TvEfHhC87Gyubs8r9Wpu6TSw0xMSEu7evVtdjjGv63HhxN7eHh5iGwkg9T+EKASIKrs7UjSgsoEEgMTWtl6enhdO7G2AZuWdNT7veI4cNsx/oE/wnCO/FutkGP/q7KLg5ReLNIWqB1t9pyYW6e6jTrU0y8HJ7nz579uFfF2S6ofiwpzhS64pdTa7udyse9Dqf/+7B7cu21kITUxMAIH6KBvBiFKPXURRUBYEy4owDNOlY7uUb4/WoZZuN+Vg6vWbt69/Pvjm7OivXuoSgxiPVTdSFnahdXFDmbb/kMVnZ85+uS7AnsycqvHs2bNZs2Z5eHj4+/s/fPhQ8xQGrNNxJzW5s0trI5FR+XBRxzYKUVR5sKMQQppnRSKjzi6t76QmN0C/sO+i4xeSv7305UfCPdHxD1Q62IYsgvalxI8wrioH0NHBRtXSDAdfeOfr47cL+bok+jO7udyse9zqPz/7+H5aj87vZD17sS8hqZWzs62dHc0Ic/IKCmXFK1assLOze1UoXb9ug1BAOdlLMMcqSuRSaWHk+OGZvz1qgHrjTuODXA/fz8p4GjovvSO+d9186vETU/mET6MP/vpaqnAO27Z3QfuksSN+XXxzcx8Bfnl0/Lg/Vu4VzY62PHFmuj0qur93zoLDGXKWVuSrAgAAy+7uWbAs8alczvRc+K+to1tRAADS5DVLEx88uzHq975T4uPDHTKOaOj/pI8YlaRrS6ppBgAA/OrHmBmrk1+pigtbzTx5dJqLQqug+U+L++3ud/Xz0SIuc4vvJ+JTSdOksSNmV7gWSX25cP4/f5Fx0HHm4b1h4vtVrUXa+vVwA2tIp7du3To7Ozs+Pn7Dhg3du3cPCAjYunWrm5sbgM7rd/lPM9v37JH+5I/PT51r26a1jcSWZoTZOX8pVdzKlSusrMR5eXkbNm4yNzO2k4iBUylK5EVFsukT/B/fvQt4aJ26KwMUZdMvyLtoX4Ys+UDUKaF99q0/ey0/vqb7/djFcVdyimXCngu2LffP3+K3rcOpIyESxN5bP2Fvj/1jksOvhCat78PwOSnro3dcK2BVBdnpnVYCxtzzS+uXHvylsERpM2ptXIS7SVmV1eSq5Hl+W/M7WpfmP5faR2zfPrn0H7XUgpMXhNZm2+i2WEvPtK5ILbEpzfuzyHnshA6ZF39++jzfNGjd/rkexi/qMWOq3cW1O9LSlFGhGVGbNo1tRwPOO68pafvqRlUDmLImLWtYZfK896+EJq0SaDXa4Z09b9XUMir19ev7VHek+d7W0H9+FrNKAJg8Z+XiuZHBQYGMyIQRmTIik83bdk2JmHrh/LkZMz/u6OqyYtF8ViEvO5RyVlFMA6tSKet7VYUvuP1T3ruB7akn8v8qBl2/vtOB4TK2+R9pu/38ri7sz6uGTt8y8MaCMe32fPeQ7dOz+NK5Ar+lbvR36sLcf3bNP9V55+VDXVF6jO/EIgD2fmx0yqCE85PspWdn+G/50T9ukAAALPxWrA787vykb+N8BMBlbJtbRf/NtZZ7tCVm2prVjVFwOjape1zq8nfVD5dchnbBNTU1YYVrfNbu0QccNp6P62bEsSzF319T1drt3arq1wsN7HRzc/MlS5bMmTNHHfU6d+4cGBgol8vrXUPRhmM5jpswc8muTUuHDvahRSaMyIQRmSxevu6j2XOPHzsWNmXqiGG+s2dEcIriyjGjkAPH1lcXxlC2oAjKrDv/lXT/QASXsv5ss/6rix2NUdEP0Zv/GLfvmxGWuYnzx61M6rPXf1DOviuvx401y0z+qW3AHFO4AIAx5gsvrI/9a9KhsyPEBcci3vseMP8yafU+Zu7BUz2YJ7sjlp7wS4hwpAAAF1STS4Arsg7YmBBqJb3w2ch/XgmNraUWjEFVu20HA7X1xPsAV2QdGHNsomXBV7P6J1hdPHnYSXVrmd/upPBNxvWaEe+3bHa/HG5jwgxnCjDGABJNieyHDVoGjLFFUJZ+V1uLATBmulV1Z7YiaWFNLaNZUNuSoc32iob+s6LqIdi2lcPjrGeawozMTNf2rgDQ3sXl8ZMsjqtcTuM4HmOMANWxhMdm7JsyKNVexIic/WO3vm8ljWW6DhhgzwDgvJQfFMO2u4kARD0nh1hEXc1eOznIKeRcJvtOxrn8IZ+60aCOdzjvxyv88LhOIgBo59qavg/8i9SUm7d/XBR5kYLi9Belv8swWGtNX6vrf5prVk1iqqVZDbLo5sGvnRGFp4eHBQ/pYFZN1TO+pthS4drLS+deD97cxQgAaIbhn2lbC95V9JvrZea9atWq1atXN6LgmTNnAGDf/s+joj7QpRymacbZ0e5x1rOhg0HtAstyT37LcnfvAQDtXVwyMp9oLs2wHAcAqAHzFwyq1JjQgC9MhYxZl8kbl3WirlL27l4uRghj1a+X7rgGbBQDgH3A2F5bzv8CgQE+zw+mFY/qePlWq2EfmuMb6kdE9tGVX9wCt4oBwKJHD9dLGKsepd7Ifkwvm00Bzs193vUFCw4CAKhBboMp2/YuZgBg1qmT7eE8KeNTcy2AcR22qQK09WCMKdv27UwBwMLtHWdLSwsaY6pDpzavcnMfZtdrBsYac/Oy1qqU1GBAkK+w7JryySNgwFjQpYo7Ro/W1NgymgWrWSJqriWj+vdz1/URjxIKAeBQ7PLE5Gv/2HVQYmtHM4L8V9KR/sMnTAzFPB+zfm1i4tcbt+6wtbHiVAqlokReVBQ5fjiLqTrexWM6Tv8iZUOvcnt5acUZzLEsy5blB4QCIYNpJPF/33byuXT3jFyfuW40ZJVdStM0x2pmEpDIyLRDyIoDMb1rb4jq+qnqNVbTXIbAc0XKlWFnTibEjIz/4dDVOdUKAgBf+0MKy7IaJ2uy1lpTf1qMt3GtfjSYoUOHrlq1quHXy+Xy1atXx8bGmpmZOTk5RUSE1btsrAmmaQA4tTcmMflq7O5D1hIJIxDl5hVMnTJpzLhgjPk9u3acOHFiw5Y4ibUlr1IoFaXK0pJpIX48TddXEY+xwHvR0YPBpuWVqTBgBDzGPPAqVqVScTzGAJgWiGgKU+/6ez1NuJ759Lb9iDAzzGPAgHmMEY1ULM9jrL6dYwwCI1O30PWbQiwr3OAxANQgV5Ur4TECBDyutRZcp208q62Hr9QMCCGMMY8xRqiBZvC4IrlU0VwVkpoMwFh9TaW1gHmMmSruQHotLVO9YBVLmgf952edXd1fFuQLhcLwcSOjP54WOXl8VET4skXRIePGIADMcwjw6IARSxfOnzZ5/LTwcVHhYz+KCFYplWaSVo1zwd67n/J0wt1iANVv35xX+Q5pRSHJyNGWyasO/Nk/yK1ypofEvTwVp4/fLQbgcp7n8gBIMthP8t3+5HwMALU8XVbX38ZRW9LaRltzOaVycO47/pO4vTMtf75TYFvNVMbW3jzz4WMVgPLZ7y+4qlUjiXs32bnT6QoAAIxrsraK/ny9vHOjU6efOXPG1dV1+/bt8+bNe/r0qbOzM0VROr1AYG7rLJUVmpqIIia8v2DW1MhJEyKnhK1Y8tmowJGY5zDPIQQhY0cv/Wxe5KTxU8PGRYWNmTEpSCqTmkkcG/Z2grao7D+MW5/OD776NofF/OtryY+69u/OYKbbsN6/ndx8VTy8v2nlxbSrh+uDr77NZTEuevjwCYsx08m37+/HEx6XYowxx3HlymuUa1igtqbmWuqzrboeDQlgjZOYdmuAGSAUMsWyIl6jaSolNRpQVpZn2SoKq7hTW8vU6GbleoPeqHu46n8+23vw6JN7VoklDozIGCp6ATDGPOY5KL+BVJwCwJjn7/4nPWRmY+ZQAMB0n7974ofzB/uIzE1cw3Zs60oDgI3/KOP523utcaMBKqIA4z5/x7jIjwcOsmnrxL2k3gOgXGfsXhw9933fnTamyOWD/dtCHKvdAqrrZ3ANEi3NAACA879fOn7TXdpMwFKe0QechQ7aBSkcvqj/hLD+KW2cLQsp1LNq1QKvT7cPiYz0GWJhwreZdvhfk7SsDRZU1d+cn5t78uTJ9OnTU1JSgoOD4+LiHB0dy53W7W7da+CICwl7fLxtsbBylwuMMZQPmPLVojK1GIBjuXsPHw0Pn1lfXRqJu0pJuRysApYt+Cl61qijpibWHtHrh1gBBrrLSI+s8OwF280q0n0YwDJg6dwbCyIDjzs5mb+2oQCwycCFq+8tWhpy2dySFvX9bNtHPdS/StXlGjXi8uljjbXgum3jatCDNX3UnJs2xAwQDxrdacbiiY/8F+6Mek8EAFUkNTQOBgCqS78OMesWHdu2zq5CYRV3amuZmtysYnNz8Ea+16MolX99YJNHd3exrQMtMmaEJozQmBYaUYwQAHhWxalKWWUJp5CzSrlc9vr6tasjwueLbewb7wdBf9Tb6SUlJRs3bty8ebOXl9fOnTu7detWccrPz+/IkV261lhSLLuSeKy/t4+5WMIITWiRCSM0pgVGFCMAAJ5VcqpSVlGiHjOywvyrV1MGjZ1kbGreCO8IbzeTJ3/c+O+TNRqe5y6d/qJUlt/Ts6+ZpQ1dNnwZAMRzKvWfB5UWS+/9fE2F6WFjo0RGelh4Ivzt+Pn5ffFFfCMKcix744czIoQ8ew80sRDTQmNaIKJoAQDmWZZTlXLKErns9e1bPyp53mvYKIbsIECoiSlT5jT++2SNhqLooWOmFhdJb15OKpHdpRAlsXM0sxBTNC2TFrz86znH8bTQqLdfKHmse8to3B2Uoul+w4OKZYW3bqVyKlYoENk5tLawlgAGaUF+3l9PFUoFJRC823eQqbllo2shGDj6z89qYmpm4TtqEgBwHFuQl1MkfcVzXGv7Nj28Axiyy0VLpakfHW5CJDI1s+jtOxIAOI59/TJPKnsFACa2YvdOHSt3lCCRjtBYmml/Y5pmbB1a2To0LgNLaFaaur9xE/aDqoCiaWs7B2s7B/2qJRg4ZBcmgp7R6eU7AqE5Id+fJWhDvj9LeFsh358laEO+P0t4WyHzWYLeIfGO0EJ5s/lZwv8jTex0sn5HaLGQ788StCHfnyW8rZD5LEHPkHhHaLGQ/CxBmyZ3Ool3hBYKyc8StGlyfpas3xFaKPXPZ1NTU9Ubonl7e6t/E4jEECSN5sMPlzWlOIHw5nhT+6MQCARCS6M5N4gkEAiEvxMS7wgEgqFA4h2BQDAUSLwjEAiGAol3BALBUCDxjkAgGAok3hEIBEOBxDsCgWAo/A//3Rz+6FgxfQAAAABJRU5ErkJggg==", + "image/svg+xml": [ + "Provide food sourcesProvide environment to live in" + ], + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "for cap in model.oa.all_capabilities:\n", + " display(HTML(f\"

      Context of {cap.name}

      \"))\n", + " diag = cap.context_diagram\n", + " diag.display_symbols_as_boxes = True\n", + " diag.render(None, no_edgelabels=True)\n", + " display(diag)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.5" + }, + "vscode": { + "interpreter": { + "hash": "e7370f93d1d0cde622a1f8e1c04877d8463912d04d973331ad4851f04de6915a" + } + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/_sources/examples/10 Declarative Modeling.ipynb.txt b/_sources/examples/10 Declarative Modeling.ipynb.txt new file mode 100644 index 000000000..7138ccffa --- /dev/null +++ b/_sources/examples/10 Declarative Modeling.ipynb.txt @@ -0,0 +1,281 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Declarative Modeling Example\n", + "\n", + "Declarative approach to modeling means that one could define or update a model using a fragment of structured text. A number of fragments could be \"played\" against a model in a sequence to build it up.\n", + "\n", + "Enabling declarative modeling for Capella models enables a range of complex automations around modeling process that are explainable / transparent to human auditors.\n", + "\n", + "This notebook will demonstrate a basic application of this approach to modeling on a coffee machine example. Please note that we will not model any specific modeling process but rather a \"free-form\" demo." + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "## System Analysis of a Coffee Machine\n", + "\n", + "Lets do a quick system analysis of a coffee machine. Lets assume that our meta-solution is an automated coffee machine for a household use. We may look into variant management scenario in a separate example.\n", + "\n", + "### 0. Initialize\n", + "\n", + "But before we can model something lets first initialize the model. We will use an empty Capella 5.2 model as a starting point." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Cannot load PVMT extension: ValueError: Provided model does not have a PropertyValuePkg\n", + "Property values are not available in this model\n" + ] + } + ], + "source": [ + "import io\n", + "\n", + "import capellambse\n", + "from capellambse import decl\n", + "\n", + "model = capellambse.MelodyModel(\n", + " \"../../../tests/data/decl/empty_project_52/empty_project_52.aird\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "to visualize the modeling results we'll use context-diagrams extension, you may get one by uncommenting and running the command below" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "!pip install capellambse_context_diagrams" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "lets verify that the model is empty at SA layer:" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "At SA layer the model has 0, out of which 0 are allocated to Root Component\n" + ] + } + ], + "source": [ + "functions_allocated = model.sa.root_component.allocated_functions\n", + "functions_available = model.sa.root_function.functions\n", + "print(\n", + " f\"At SA layer the model has {len(functions_available)},\"\n", + " f\" out of which {len(functions_allocated)} are allocated to Root Component\"\n", + ")" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Also for this to work we'll need \"coordinates\" of some key elements in the model:" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "root_function = model.sa.root_function\n", + "root_component = model.sa.root_component\n", + "structure = model.sa.component_package" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "### 1. Context\n", + "\n", + "Lets start by renaming the root component from **System** to **Coffee Machine**, creating a human actor **User** and a component exchange between those two.\n", + "\n", + "We can achieve this by applying the following YAML patch to an empty Capella model:" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": { + "scrolled": true + }, + "outputs": [ + { + "data": { + "text/plain": [ + "{Promise(identifier='usr-port-promise'): \n", + " .applied_property_value_groups = []\n", + " .applied_property_values = []\n", + " .constraints = []\n", + " .description = ''\n", + " .direction = \n", + " .exchanges = ... # backreference to ComponentExchange - omitted: can be slow to compute\n", + " .filtering_criteria = []\n", + " .name = 'usr'\n", + " .owner = \n", + " .parent = \n", + " .progress_status = 'NOT_SET'\n", + " .property_value_groups = []\n", + " .property_values = []\n", + " .requirements = []\n", + " .summary = None\n", + " .traces = []\n", + " .uuid = '3a2ff9e0-adcc-4d2d-ae4f-7001a0c25475'\n", + " .xtype = 'org.polarsys.capella.core.data.fa:ComponentPort',\n", + " Promise(identifier='cm-port-promise'): \n", + " .applied_property_value_groups = []\n", + " .applied_property_values = []\n", + " .constraints = []\n", + " .description = ''\n", + " .direction = \n", + " .exchanges = ... # backreference to ComponentExchange - omitted: can be slow to compute\n", + " .filtering_criteria = []\n", + " .name = 'cm'\n", + " .owner = \n", + " .parent = \n", + " .progress_status = 'NOT_SET'\n", + " .property_value_groups = []\n", + " .property_values = []\n", + " .requirements = []\n", + " .summary = None\n", + " .traces = []\n", + " .uuid = '99f8db47-4771-4e4e-993a-b252398d8806'\n", + " .xtype = 'org.polarsys.capella.core.data.fa:ComponentPort'}" + ] + }, + "execution_count": 4, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model_update = f\"\"\"\n", + "- parent: !uuid {root_component.uuid}\n", + " modify:\n", + " name: Coffee Machine\n", + "- parent: !uuid {root_component.uuid}\n", + " extend:\n", + " ports:\n", + " - name: usr\n", + " direction: INOUT\n", + " promise_id: usr-port-promise\n", + " exchanges:\n", + " - name: user interactions\n", + " source: !promise usr-port-promise\n", + " target: !promise cm-port-promise\n", + "- parent: !uuid {structure.uuid}\n", + " extend:\n", + " components:\n", + " - name: User\n", + " is_actor: true\n", + " is_human: true\n", + " ports:\n", + " - name: cm\n", + " direction: INOUT\n", + " promise_id: cm-port-promise\n", + "\"\"\"\n", + "# the below line applies the model_update to the model\n", + "decl.apply(model, io.StringIO(model_update))" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "and now we can verify the changes by visualizing the context of our system under analysis:" + ] + }, + { + "cell_type": "code", + "execution_count": 5, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAXgAAAA7CAIAAAD+RAaHAAAABmJLR0QA/wD/AP+gvaeTAAAQD0lEQVR4nO3deVxN6f8A8M9Z7r0ldStUqGQZRMu4Iaa0IWLwbZAtSyGG+BKmmrEMGQbTYJoJZZgxUxjL2Pk2Y4mRmJRGJHuMsrTTcu89y++Pm7rd9nQSv8/7dV5ej7M8n+fo9LnP85x7DoLneUAIISGRb7sBCKH3HyYahJDgMNEghASHiQYhJDhMNAghwWGiQQgJDhMNQkhwmGgQQoLDRIMQEhxd8+bhw7c2TTtQwxw/PvttNwGh2tWSaABg4xG8lJuphSPxYwC9G3DohBASXO09GnzoEiH0hmpPNICJBiH0ZurQo2mCViCE3mvYo0EICQ57NAghwWGPBiEkOLzrhBASHA6dEEKCE2rolJqclJedXa9DzDt1bm/RsSHBEEJ1U1xcvHbd+ltpaRYdOiz9PFhPT69p4go1dIo7fmywy6B6HXLu6OGJ/gsaEgwhVDdBQUGUtG3fgSOfP83wneG3/7c9TRO3Dj2aBtHVk1rbyqrbeuHc6UtxF1TlMeMmder8AQDEXUsQqDFNTJGdUaTbTl/caBVa6xDVbSKITwEA/8+c/88IotrLQ0X98rjz4JHbyP4AYGTS7voVBcMwNC1UElDX+D2aPw/tV5bI76beOHRgj1Tf0HWgOwDcvZOmUMgBgCKpbpY94y7Gfr9pvWp/uz72qkQDfJWxuLzLW75b81NKFsfL5S2cVm345hOjSk9ocZlHNy0Mu8O3d10aMab1qbKyl7Wobq1mUlbYLs4JPRA2VOd1lY9/cJkQP+/0L2MlNR2oOD+nX7z35c8+eh2Izz0d4HpxbGLIcJ2ajqunGlJJrdcZeu/V/fKgSVKpkIvEEpZlDXW1mybLgBBzNI9Tbkyd5jfE0Q0AondFqhLNtIme6Q/vA4BEItkZ9fvjR+lVB6oUS5701eKlz8dvO7+8ozYAU/xKqUVU3o17dijsttvO8JntSeAyt5aV69N4nss+sPHYYvdx5iQAQNH5qMi/Ges61MBrtNxg6M60ofUKjVBT+Wb92kWfBckVShFNrQlZ2WRxa396m6/nQlKURCxRLQSpWT9JUgOc3czMO9QpEJ93LuyoZcg3Aztq8wA80FottQGAe3Fu29SBvkP6jhsxPyZdyaZFhnx75upGzznj1iTcKC8nKoF9cnyTt/usEY6+PmE3ioCHKtaUZglCx36E4YltcSUAPHDPD27NcB5vQQHPv7iwbNA4xz7j7WVz1l8o4IHLubhj+iDfYU5TR69OkgNwT86vHD93pOMYF6+9KXIeFOfnyNbHKXlQnJ/TfZLXaLVN1UaveUGosXTt2vXooYMWpm2PHzlka2vbZHEbv0dj1LHT/hOHUq5c6mPXp1v3HlXuM9prkqy3/fV/kqxtetn26l1tLOXNf250trWWVFxfcDHkiydeh7cPM8ja7+33+V7ZLzOD/Pes09kd5mtCAGdUVuazYpZ9Swcc29qLTg8btiHa8ztfrT811kw3fZ0LSan7AqvtG2KeOowwSPrtgOHoJW22RQJAa7vFB6NW6VHyhDD3FTFTepmFBj8YtT9yhBHJMhzFXQTKbMKWsKltXp30nRIWM2rrkNIT4QG4Av0REWHehqWbtvSPrTb6G4mKek+mt9D7qvG/R/MyP09RVEQAn5eXm52dNXjIcAAYOnxU1otnz55mmplbAIBUqm9qZp6Z+cTUzFxLS6v6WAyrkCuYiuuV1+Kudh+4vjUAtB4xxfbrg6nKieZqH/7lHQFl8pVLDx9Sc5ZRwD/NeGb1L6ss1FwDpkRZaLHN6Clk4I5r/SzDUp0CZ7Tcuw2AB0JCZF76NfKfO7f/yXkueZ70IK6j6yojAoCnaAIUPGli8YEBANHC0qbVjqcvebXOCGli3kmvfJOiUnteR39D0dGYaFAtFArF8uXLVeUrV64EBQWVlJQUFxcvXbrUzMxM6OiNPxnMFBUt9F+sKoeHbVAVln65FgBiz/7h7DoYAHZE/lA2GfxT9O8DB3tA6VipYl1Utw86/xN/ocDDQ+1uP8cwCqWSVe0soiU0+TrH8GWZprQskejYjFq/c7j09bHKvzTX8K/TEw88TxqOXNBzxOyAM90m7e5OZgLwAEzqrgl+z/zCfRZNbntn1DOOUSp5Tm3emofSaWyeIAhVPWVrNDZVbg9f7zxepYkTe9e+E3pPnThRp91EIlFgYKCqnJmZqSrr6uo2l7tO9f1VePE08+zp/7EsQ1P0o/QHZesZhkl/cP+6YSIAPH/+tOpAmrGMBs8d9uuiGfvbbR9to0cAW1KklGjbyHpePXnkibNXu8K/Dt2xcp9Lw0uNw1Vl2tbB4c7OX1IHz7UUA8dxJFl5jcbQRdJv/GST5IfzXA0JyFC1+8GDF5aD3axbi9Kyszigu1paJJz5M8tleGuC5/mymWm+DoVaozfUpEmNmWhiY2Pj4+NVZV1dXR8fH21tbfUdEhMTT548qb5GJpN5eHg0YhtQ3Xl712k3giAMDAxUZYlEUlZuGo0/dBo5/VN5SXHsvqgxnmOn+s4qj0TToz7xUpWlUv26xSJaOIWGfbVmc5DbgZIWUkOptLd/YOAQty9XJ8/3nLZLV7uVw8x1o/QIKFA7XO1P3b6fh99YNGvWaakerSULip4iq7xGBBWOIo0nH94BAACsao3IcaTnxjVDXKPNjLlCuhdhMuTLwMSAYdMj9UjaeW5UoMasbQ0TunwV7anj3fcmderUqQNHTnTpbkVR5POMx7v37I09d1Y9KcbHx+/Zu6+/kwvLcEqWTbuZ8jA9XcBEwyly8gkDA1ET3cZv4nBNLjc39/jx4/fv3+/UqVOTBSVq/q7X8OFbV0c15OXkv0d856eWZTQcO3Lgj1PHVOVZcxf26GkDAFt2RIzxm9eAWO89mUFNPyaCqOWHWF/BwcG3Hr/4z/hpErFILKJDlsyZN3e2r49P2Q7h4eEX468uWba6WKEokSsO7vm1JC8zMiKiEdugjr2XsCSSXrDmQ/PKHUDu5d8xOWbuHUzesG+oVk9N4Zqlmi+AylsDAgImTJgQGhoaHR3daJ3q2gj1CEJudvaF2DPVbZVKDcaMm6wqZ2dlqfZkGAa/4FqdJv5WHkmSNEXRFCWi6Qk+ny5esmS6r6/6DmKx5CPXQTYye4ZhWY4TtDFU597ffl3NNq4g4UQ6NejNE015PTWFa67qfnkkJSXp6en16dPH29s7PDzc399f0IaVEWoeaITPbHlxcb0O8ZD1E6gx77qrOVUn4GXeWwX6f50okqBpSrV82LuvvLh4+7FLEq3ymZrrCXEb14VERh9mWJbj2OoG2Ozty4uPGa8PsBBx+QeC41oGe7jTmfvCEhJfcfJCHY/gge5GzL0TF3+59KpETnYe4zzDXgcykpdtyWsPWana3QODerYngc9IDo4QB62wlGYmB65+ZGhC5ucU8db2gb6m2UevxqXnpa4sujNu8LieXA1VLR4PUT+kPuVASbUeG+Dk2o7POB8fcSK7mIP2Hi4eeeX1eBmmqMLpE8y/Zy5tj8l9VcS2cvlonqexjmYDzPULK56O8VsYb9W9P8vzfGho6LZt2wDg448/nj179t27d7t06SJk60oJ1aNpZdS2AUdhj6aZIAlK1aOhKUoiFuvpG7zMy5WYlCcaK7t+YauWvCwoIGia4+rxc3sVn3zZwmHDBENVF4S9n7z9ervPQrrqF6WHLb+WYudgBSB/wlqHen5qUFUvRWLiFdynE5m/P/js6SdmY0bYfXT2nv0KJxkN7P2kmqpSKuav7akjhryzMcuOPXMclRMR02LaKgcLMc+yBMWX18NnlIbintzcekbXL2SAOfsi6ovYA1afTGmp2YAhtyqcTjO3a9eu0aNH6+iUPhyzdu1af3//qKioJgiNb9hDVSDLejQURVNUcVGhpOKNJ47lAIDleGBYluPq/jmubdGG2x27GSxdnTvbtqNzbmSk3cncuekJAcy/OcyzYrACoMzbWulX/ZtLSlsa0gCEbkcz9mo+DyZlW/haqhLR8tv3ziZlZ97KfqpVkp/8qNCmn7kYAAiKAmCqiJV//V9lLwdTEYCotZujePONV7y9ZgMqnk5znz/29PRUfy+EgYHBli1bmiY0vvgKVaFsjoamqVcv8zmO05VWuBuadj2xnak5LRKVKBQcx1HVV6Uxf0N3sVu3zvTyhTv7VqQkLfyPp1jUztHuvz5GZTXwL+vUQgI0fqkJUY1VFV65EBJjOGOmrZs1l3yUZ9lau2E8x/IsW9p8miYpvkJEVQM0TsenRxM9o9gwld8+02Tvo6nDs048Ls10EQxBksTroRN97o9TEol48qAP1ZfQpfOnzprPsCzDsFz1k8GkVFv7SU4GA8C8eqaaaVIw0Mp4gKeD/zDx3XslejamegmpiQWqK60Bp0TRnLJYCQAgrakqvuDffC0rix7GEj4z9zkHeh1bFV99+Fip2rlCPWX/CPo9jJn4u/dKAJiC+KucrW3LKjosFU+nmXwqKy8ssJl6RF76N/bmVw6eP+e+1Rbh0AlVhSRJ1dCJYRS7f47Yv2+fs7Nz2dbw8PCYsxc/7NO/RKFgWJbleFE1Vwlh9MHYnn9sWJLRppW4kITOAAVJV9buzyK1SJZs88l/dUjDHnPGxm1bdeSYnogw7jrfr3P9vkZGtx4woGTripMpHzv6OdVQFWHsYNlm7cnFCbqttOX6YoLuZutne25z4NEWEr6Nu9t81/J6Zr6eG6UsbOY4x0YEHxZp021dHGd2eP0dTjUap9PMh05vUe3fo1nxkyD3NdCbWzlNkLtOwcGfn/jfn1a2vSiKup2aYtmty84dO9R3CA8P3xT2g23v/gzLsgz74G6avZ3N9sjIRm8JahjlhQV2293+/nmkBACAvfmV0xemxw6OvP6138qYXGVhvuns3371tShM2rpw6e+PioroXp9FfDPSFO6GDvW/1ZW/dknXZ/feOV1rGA/XH/ZokKahQ4fo65c+juXY98Pp06dr7NCvX7+pueVdcXvbbjJZtW9TRM0Dn3P42yM2m/9aZqVKIMy1bxedc4k+5W1ccNzPY8N5j81OwBelyV0uXfrepPFnmnAyGGlydnZWHyhVJpPJMLO8awg9axkX4jeDnzlp4piBXXQy/zp3OeF84PTTJBTeyix5+JJ3AqB7DhhgLMh8NvZoEHrfEGIJUZBXxIOEAAC+qFCupS0W2S0/Fzv46G/RXw8L+3PnXwFaOl3GLv/x675lKYDLEbBJeNfpHV4QqhLdw7nPrV0/phQCAJ8Xtye2nVt/bSgpgvb9vQI2b5stvZqYbejq3vrE9pgsHgB4gR8iAeEeQUAIvTW6Hut23F7g79KP09GStB305RZfMyLr6Bde65KoliKGtFv0Y3u6rV940KL5o9y+b6VDdJy6feNYYyFbVPtdJyGjozcl0LNOCDWuRn7DAEIIVfZOPAuGEHq3YaJBCAkOEw1CSHCYaBBCgsNEgxASHCYahJDgMNEghASHiQYhJDhMNAghwWGiQQgJDhMNQkhw/wfYV5WzD1zjoQAAAABJRU5ErkJggg==", + "image/svg+xml": [ + "SFCoffee Machineuser interactionsUser" + ], + "text/html": [ + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 5, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "root_component.context_diagram" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Please note: the changes we made are not yet stored - if you like those to be saved you may use `model.save()` method. This will save the model back to where it was loaded from, for example by writing back into local files, or by creating a Git commit and pushing it back to the remote.\n" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.5" + }, + "vscode": { + "interpreter": { + "hash": "c5ea7dc634d8047a259e5b898f154d237fbe6934b444b1a949475949608d751e" + } + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/_sources/examples/11 Complexity Assessment.ipynb.txt b/_sources/examples/11 Complexity Assessment.ipynb.txt new file mode 100644 index 000000000..d01035863 --- /dev/null +++ b/_sources/examples/11 Complexity Assessment.ipynb.txt @@ -0,0 +1,121 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Complexity Assessment\n", + "\n", + "This notebook demonstrates how to use / view the model complexity badge for a Capella model." + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "from IPython.display import SVG\n", + "\n", + "import capellambse" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Cannot load PVMT extension: ValueError: Provided model does not have a PropertyValuePkg\n", + "Property values are not available in this model\n" + ] + }, + { + "data": { + "image/svg+xml": [ + "\n", + "\n", + "\n", + "180\n", + "objects\n", + "\n", + "\n", + "31%\n", + "\n", + "16%\n", + "\n", + "27%\n", + "\n", + "27%\n", + "\n", + "18\n", + "diagrams\n", + "\n", + "\n", + "39%\n", + "\n", + "22%\n", + "\n", + "28%\n", + "\n", + "11%\n", + "\n", + "\n", + "\n", + "Operational Analysis\n", + "\n", + "System Analysis\n", + "\n", + "Logical Architecture\n", + "\n", + "Physical Architecture\n", + "\n", + "\n", + "" + ], + "text/plain": [ + "" + ] + }, + "execution_count": 2, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "path_to_model = \"../../../tests/data/melodymodel/5_2/Melody Model Test.aird\"\n", + "model = capellambse.MelodyModel(path_to_model)\n", + "SVG(model.description_badge)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.11.5" + }, + "vscode": { + "interpreter": { + "hash": "f5c9192943a88c565de58e6fd7c534c9de794a35889e45ad6809ab92c821a96c" + } + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/_sources/howtos/howtos.rst.txt b/_sources/howtos/howtos.rst.txt new file mode 100644 index 000000000..fdef7f6de --- /dev/null +++ b/_sources/howtos/howtos.rst.txt @@ -0,0 +1,21 @@ +.. + SPDX-FileCopyrightText: Copyright DB InfraGO AG + SPDX-License-Identifier: Apache-2.0 + +.. _howtos: + +******* +How Tos +******* + +In this section you can view dedicated tutorial-notebooks of key +features. + + +.. toctree:: + :maxdepth: 4 + :caption: How tos: + :numbered: + :glob: + + ../examples/* diff --git a/_sources/index.rst.txt b/_sources/index.rst.txt new file mode 100644 index 000000000..d0e840245 --- /dev/null +++ b/_sources/index.rst.txt @@ -0,0 +1,78 @@ +.. + SPDX-FileCopyrightText: Copyright DB InfraGO AG + SPDX-License-Identifier: Apache-2.0 + +***************************** +Welcome to the documentation! +***************************** + +Python Capella MBSE Tools +========================= + +.. image:: https://img.shields.io/badge/code%20style-black-000000.svg + :target: https://github.com/psf/black + :alt: Black + +**Date**: |today| **Version**: |Version| + +Description +----------- + +This library was designed to enable and support Model Based System Engineering +using Polarsys' Capella_ with Python. Common usage for this API: + +* parsing .aird files +* easy access to model elements and objects +* property-value access and manipulation +* diagram access and export as SVG + +Additionally and as a core idea it provides an interface for the underlying +database of the Capella model. + +Since v0.5, it also supports a simple, but powerful :ref:`declarative modelling +language `, which is based on the API for the semantic +model. + +If you want a quickstart at how to use this package, head right into the +:ref:`how-tos section `. + +.. toctree:: + :caption: Start + :maxdepth: 1 + :titlesonly: + + start/installation + start/specifying-models + start/envvars + start/intro-to-api + start/declarative + start/migrating-0.6 + +.. toctree:: + :caption: Tutorials + :titlesonly: + + howtos/howtos + +.. toctree:: + :caption: API reference + :maxdepth: 4 + + code/modules + +.. toctree:: + :caption: Integration with other tools + :maxdepth: 2 + + tools/sphinx-extension.rst + +.. toctree:: + :caption: Development + :maxdepth: 2 + + development/low-level-api + development/how-to-explore-capella-mm + development/developing-docs + development/repl + +.. _Capella: https://www.eclipse.org/capella/ diff --git a/_sources/start/declarative.rst.txt b/_sources/start/declarative.rst.txt new file mode 100644 index 000000000..1e8eb3737 --- /dev/null +++ b/_sources/start/declarative.rst.txt @@ -0,0 +1,381 @@ +.. + SPDX-FileCopyrightText: Copyright DB InfraGO AG + SPDX-License-Identifier: Apache-2.0 + +.. _declarative-modelling: + +********************* +Declarative modelling +********************* + +.. versionadded:: 0.5.0 + Introduced the declarative modelling module. + +|project| supports declarative modelling with the :py:mod:`capellambse.decl` +module. This requires the optional dependency ``capellambse[decl]`` to be +installed. + +The YAML-based declarative modelling engine combines a few simple concepts into +a powerful, but easy to use file format. These files can then be applied to any +model supported by |project|. + +Example +======= + +Here is an example YAML file that declares a simple coffee machine with a +couple of functions, and functional exchanges between them: + +.. literalinclude:: ../../../tests/data/decl/coffee-machine.yml + :language: yaml + :lines: 4- + :lineno-start: 1 + :linenos: + +CLI usage +--------- + +If the additional optional dependency ``capellambse[decl,cli]`` is installed, +this file can be applied from the command line. Assuming it is saved as +``coffee-machine.yml``, it can then be applied to a locally stored Capella +model like this: + +.. code-block:: sh + + python -m capellambse.decl --model path/to/model.aird coffee-machine.yml + +Refer to the :py:func:`capellambse.cli_helpers.loadcli` documentation to find +out the supported argument format for ``--model``. + +API usage +--------- + +Declarative YAML can also be applied programmatically, by calling the +:py:func:`capellambse.decl.apply` function. It takes a (loaded) |project| +model, and either a path to a file or a file-like object. To pass in a string +containing YAML, wrap it in :external:class:`io.StringIO`: + +.. code-block:: python + :emphasize-lines: 5 + + import io, capellambse.decl + my_model = capellambse.MelodyModel(...) + my_yaml = "..." + + capellambse.decl.apply(my_model, io.StringIO(my_yaml)) + + my_model.save() + +Format description +================== + +The YAML file may contain one or two YAML documents (separated by a line +containing only three minus signs ``---``). The first document contains +metadata, while the second document contains the instructions to perform +against the model. The metadata document may be omitted, in which case the file +only contains an instruction stream. + +Metadata +-------- + +.. versionadded:: 0.6.8 + Added metadata section to the declarative modelling YAML. + +The metadata section is optional and has the following format: + +.. code-block:: yaml + + model: + url: https://example.com/model.git + revision: 0123456789abcdefdeadbeef0123456789abcdef + entrypoint: path/to/model.aird + written_by: + capellambse_version: 1.0.0 + generator: Example Generator 1.0.0 + +It contains information about which model the declarative modelling YAML file +wants to change, and which capellambse version and generator it was written +with. A versioned model can be uniquely identified by its repository URL, the +revision, and the model entrypoint. ``decl.apply()`` with ``strict=True`` will +verify these values against the ``model.info`` of the passed model. + +Instructions +------------ + +The expected instruction document in the YAML follows a simple format, where a +parent object (i.e. an object that already exists in the model) is selected, +and one or more of three different operations is applied to it: + +- ``extend``-ing the object on list attributes, +- ``set``-ting properties on the object itself, +- ``sync``-ing objects into the model, or +- ``delete``-ing one or more children. + +Selecting a parent +------------------ + +There are a few ways to select a parent object from the model. + +The most straight-forward way is to use the universally unique ID (UUID), using +the ``!uuid`` YAML tag. The following query selects the root logical function +in our test model: + +.. code-block:: yaml + + - parent: !uuid f28ec0f8-f3b3-43a0-8af7-79f194b29a2d + +A more versatile way involves the ``!find`` YAML tag, which allows specifying a +set of attributes in order to filter down to a single model element. This tag +simply takes a mapping of all the attributes to select for. This usually also +involves the element's type (or class), which is selectable with the ``_type`` +attribute: + +.. code-block:: yaml + + - parent: !find + _type: LogicalFunction + # ^-- note the leading underscore, to disambiguate from the "type" + # property that exists on some model elements + name: Root Logical Function + set: [...] + +The ``!find`` tag also supports dot-notation for filtering on nested +attributes. + +.. code-block:: yaml + + - parent: !find + _type: FunctionOutputPort + name: FOP 1 + owner.name: manage the school + set: [...] + +Extending objects +----------------- + +The following subsections show how to create completely new objects, or +reference and move already existing ones, using examples of declarative YAML +files on :py:class:`~capellambse.model.ElementListCouplingMixin`-ish +attributes. The extension of one-to-one attributes works in the same way, +adhering to the YAML syntax. + +Creating new objects +^^^^^^^^^^^^^^^^^^^^ + +:py:class:`~capellambse.metamodel.la.LogicalFunction` objects have several +different attributes which can be modified from a declarative YAML file. For +example, it is possible to create new +sub-:py:attr:`~capellambse.metamodel.la.LogicalFunction.functions`. This +snippet creates a function with the name "brew coffee" directly below the root +function: + +.. code-block:: yaml + :emphasize-lines: 2 + + - parent: !uuid f28ec0f8-f3b3-43a0-8af7-79f194b29a2d + extend: + functions: + - name: brew coffee + +Functions can be nested arbitrarily deeply, and can also receive any other +supported attributes at the same time. The "brew coffee" function for example +could further receive nested child functions, each providing an output port: + +.. code-block:: yaml + :emphasize-lines: 4-5 + + - parent: !uuid f28ec0f8-f3b3-43a0-8af7-79f194b29a2d + extend: + functions: + - name: brew coffee + functions: + - name: grind beans + outputs: + - name: Ground Beans port + - name: heat water + outputs: + - name: Hot Water port + +While objects that already exist in the base model can be referenced with +``!uuid``, this is not possible for objects declared by the YAML file, as they +will have a random UUID assigned to ensure uniqueness. For this reason, a +promise mechanic exists, which allows to "tag" any declared object with a +``promise_id``, and later reference that object with the ``!promise`` YAML tag. +These promise IDs are user defined strings. The only requirement is that two +objects cannot receive the same ID, however they can be referenced any number +of times. This example snippet demonstrates how to declare two logical +functions, which communicate through a functional exchange: + +.. code-block:: yaml + :emphasize-lines: 7,11,14-15 + + - parent: !uuid f28ec0f8-f3b3-43a0-8af7-79f194b29a2d + extend: + functions: + - name: brew coffee + inputs: + - name: Steam port + promise_id: steam-input + - name: produce steam + outputs: + - name: Steam port + promise_id: steam-output + exchanges: + - name: Steam + source: !promise steam-output + target: !promise steam-input + +The ``!promise`` tag (and the ``!uuid`` tag as well) can be used anywhere where +a model object is expected. + +Creating new references +^^^^^^^^^^^^^^^^^^^^^^^ + +It is important to understand when new model objects are created and when only +references are added. The following example would create a reference in the +``.allocated_functions`` attribute of the +:py:class:`~capellambse.metamodel.la.LogicalComponent` which is also the +logical ``root_component`` (parent) to the logical ``root_function``: + +.. code-block:: yaml + :emphasize-lines: 2 + + - parent: !uuid 0d2edb8f-fa34-4e73-89ec-fb9a63001440 + extend: + allocated_functions: + - !uuid f28ec0f8-f3b3-43a0-8af7-79f194b29a2d + +This is caused by the type of relationship (non- +:py:class:`~capellambse.model.DirectProxyAccessor`) between the parent and its +``allocated_functions``. + +It is also possible to create references to promised objects, but extra caution +for declaring ``promise_id``\ s for resolving these promises successfully: + +.. code-block:: yaml + :emphasize-lines: 5,9 + + - parent: !uuid f28ec0f8-f3b3-43a0-8af7-79f194b29a2d + extend: + functions: + - name: The promised one + promise_id: promised-fnc + - parent: !uuid 0d2edb8f-fa34-4e73-89ec-fb9a63001440 + extend: + functions: + - !promise promised-fnc + +The ``promise_id`` declaration can also happen after referencing it. + +Moving objects +^^^^^^^^^^^^^^ + +The following example would move a logical function from underneath a +:py:class:`~capellambse.metamodel.la.LogicalFunctionPkg` (accessible via +``functions``) into ``functions`` of the logical ``root_function`` (parent) +since the ``functions`` attribute has a parent/children relationship (i.e. the +:py:class:`~capellambse.model.DirectProxyAccessor` is used). + +.. code-block:: yaml + + - parent: !uuid f28ec0f8-f3b3-43a0-8af7-79f194b29a2d + extend: + functions: + - !uuid 8833d2dc-b862-4a50-b26c-6f7e0f17faef + +Setting properties +------------------ + +After selecting a parent, it is also possible to directly change its properties +without introducing new objects into the model. This happens by specifying the +attributes in the ``set:`` key. + +The following example would change the ``name`` of the root +:py:class:`~capellambse.metamodel.la.LogicalComponent` to "Coffee Machine" +(notice how we use a different UUID than before): + +.. code-block:: yaml + :emphasize-lines: 2 + + - parent: !uuid 0d2edb8f-fa34-4e73-89ec-fb9a63001440 + set: + name: Coffee Machine + +This is not limited to string attributes; it is just as well possible to change +e.g. numeric properties. This example changes the ``min_card`` property of an +:py:class:`~capellambse.metamodel.information.ExchangeItemElement` to ``0`` and +the ``max_card`` to infinity, effectively removing both limitations: + +.. code-block:: yaml + :emphasize-lines: 3- + + - parent: !uuid 81b87fcc-03cf-434b-ad5b-ef18266c5a3e + set: + min_card: 0 + max_card: .inf + +Synchronizing objects +--------------------- + +The ``sync:`` key is a combination of the above ``extend:`` and ``set:`` keys. +Using it, it is possible to modify objects that already exist, or create new +objects if they don't exist yet. + +Unlike the other keys however, ``sync:`` takes two sets of attributs: one that +is used to find a matching object (using the ``find:`` key), and one that is +only used to set values once the object of interest was found (using the +``set:`` key). + +This operation also supports Promise IDs, which are resolved either using the +found existing object or the newly created one. + +The following snippet ensures that the root LogicalFunction contains a +subfunction "brew coffee" with the given description. A function named "brew +coffee" will be used if it already exists, but if not, a new one will be +created. In either case, the used function will resolve the "brew-coffee" +promise, which can be used to reference it elsewhere: + +.. code-block:: yaml + + - parent: !uuid f28ec0f8-f3b3-43a0-8af7-79f194b29a2d # the root function + sync: + functions: + - find: + name: brew coffee + set: + description: This function brews coffee. + promise_id: brew-coffee + - parent: !uuid 0d2edb8f-fa34-4e73-89ec-fb9a63001440 # the root component + extend: + allocated_functions: + - !promise brew-coffee + +Deleting objects +---------------- + +Finally, with declarative modelling files, it is possible to delete objects +from the model. Depending on where the delete operation occurs, either the +target object is deleted entirely, or only the link to it is destroyed. + +Currently, objects to be deleted can only be selected by their UUID. + +For example, this snippet deletes the logical function named "produce Great +Wizards" from the model: + +.. code-block:: yaml + :emphasize-lines: 3 + + - parent: !uuid f28ec0f8-f3b3-43a0-8af7-79f194b29a2d + delete: + functions: + - !uuid 0e71a0d3-0a18-4671-bba0-71b5f88f95dd + +In contrast, this snippet only removes its allocation to the "Hogwarts" root +component, but the function still exists afterwards: + +.. code-block:: yaml + :emphasize-lines: 3 + + - parent: !uuid 0d2edb8f-fa34-4e73-89ec-fb9a63001440 + delete: + allocated_functions: + - !uuid 0e71a0d3-0a18-4671-bba0-71b5f88f95dd diff --git a/_sources/start/envvars.rst.txt b/_sources/start/envvars.rst.txt new file mode 100644 index 000000000..cd3398013 --- /dev/null +++ b/_sources/start/envvars.rst.txt @@ -0,0 +1,66 @@ +.. + SPDX-FileCopyrightText: Copyright DB InfraGO AG + SPDX-License-Identifier: Apache-2.0 + +Environment variables affecting |project| +========================================= + +This page provides an overview over the environment variables that |project| +understands, and how they affect regular operation. + +- ``GIT_USERNAME`` and ``GIT_PASSWORD`` can be used to provide default + credentials to the Git file handler. If set, the file handler overrides + ``GIT_ASKPASS`` when interacting with git in order to forward these + credentials. + +- ``CAPELLAMBSE_GLART_MAX_JOBS`` determines the maximum number of CI jobs that + the Gitlab Artifacts file handler will search through when looking for the + last successful job with a given name. It can be used to limit the search + radius to reduce server load, or to extend it to find older jobs as well. + + It defaults to 1000, which results in up to 5 requests to the Gitlab server. + The limit can be disabled by setting the variable to 0. + +- ``CI_SERVER_URL``, ``CI_PROJECT_ID``, ``CI_DEFAULT_BRANCH`` and + ``CI_JOB_TOKEN`` are used by the Gitlab Artifacts file handler to fill in the + hostname, the "project" and "branch" parameters, and the access token, + respectively, if they were not passed explicitly. These variables are + automatically set by Gitlab CI/CD runners. + +- ``CREDENTIALS_DIRECTORY`` is used to find files containing tokens or other + types of credentials, if no absolute path is given. + +- ``CAPELLAMBSE_PNG_SCALE`` can be used to upscale diagrams before rendering + them as PNG. + +- ``TERM`` is used to determine whether the terminal supports PNG display, in + order to preview diagrams in the REPL. + +Debugging helpers +----------------- + +- ``AIRD_NOSNAP``, if defined, disables point snapping while parsing AIRD data. + This causes the positioning data from the AIRD file to be used as-is, which + leads to very broken layouts. + +- ``CAPELLAMBSE_SVG_DEBUG``, if defined, causes the built-in SVG renderer to + draw additional red markers to indicate various reference positions. + +Experimental features +--------------------- + +- ``CAPELLAMBSE_XHTML``: If set to "1", content from attributes that contain + HTML markup will be cleaned up and made XHTML compliant before it is returned + when using the high-level model API. This means that content read with + capellambse no longer fully matches what is stored in the model. + + Considered experimental, as it may be changed or removed without a preceding + deprecation period. + +- ``CAPELLAMBSE_EXPERIMENTAL_CROP_SVG_DIAGRAM_CACHE_VIEWPORT`` can be set to + "1" to recalculate the viewport of SVG files exported by Capella. This can be + used to reduce white borders in some cases. + + Experimental because not all possible elements are currently handled, and + because the bounding box calculations for text objects don't fully match what + Capella or some other SVG viewers use. diff --git a/_sources/start/installation.rst.txt b/_sources/start/installation.rst.txt new file mode 100644 index 000000000..b1da8a644 --- /dev/null +++ b/_sources/start/installation.rst.txt @@ -0,0 +1,65 @@ +.. + SPDX-FileCopyrightText: Copyright DB InfraGO AG + SPDX-License-Identifier: Apache-2.0 + +************ +Installation +************ + +.. image:: https://img.shields.io/pypi/pyversions/capellambse + :target: https://pypi.org/project/capellambse/ + :alt: PyPI - Python Version + +This guide helps you to get |project| installed. There are a few ways to get it +done: + +Install from PyPI +================= + +Installing |project| from Python Package Index via pip__ is the quickest way to +get started. + +__ http://www.pip-installer.org/ + +.. code:: bash + + pip install capellambse + +Windows +======= + +If you intend to use |project|'s PNG export functionality, you need a working +installation of cairosvg__. Unfortunately, the Windows wheels on PyPI do not +ship with all necessary libraries. However, they can be manually installed with +the `GTK for Windows Runtime Environment Installer`__. + +__ https://pypi.org/project/CairoSVG/ +__ https://github.com/tschoonj/GTK-for-Windows-Runtime-Environment-Installer/releases + +This should give you a fully functioning |project|. + +Install as a package from Github +================================ + +If you want to have a comfortable playground with examples / Jupyter notebooks +/ export to excel demo and test models you may clone the repository directly +from Github, create a virtual environment and install all the extras: + +.. code-block:: bash + + git clone https://github.com/DSD-DBS/py-capellambse.git + cd py-capellambse + python3 -m venv .venv + source .venv/bin/activate + pip install . + pip install jupyter + cd examples + jupyter-notebook + +Install for development +======================= + +In case you'd like to contribute to the development or improve documentation, +sample models or examples collection please follow the `contribution guide`__. + +__ https://github.com/DSD-DBS/py-capellambse/blob/master/CONTRIBUTING.md diff --git a/_sources/start/intro-to-api.rst.txt b/_sources/start/intro-to-api.rst.txt new file mode 100644 index 000000000..a7538f7a5 --- /dev/null +++ b/_sources/start/intro-to-api.rst.txt @@ -0,0 +1,63 @@ +.. + SPDX-FileCopyrightText: Copyright DB InfraGO AG + SPDX-License-Identifier: Apache-2.0 + +********************************** +Introduction to py-capellambse API +********************************** + +|project| provides access to model elements using a meta-model similar to the +one of Capella. However in this meta-model we make a few simplifications. A +collection of automated tests and design reviews help us to ensure that those +simplifications don't break compatibility with original Capella models (however +coverage isn't complete yet). + +As you may know the meta-model behind Capella is layered. There are many +packages involved and there is a long inheritance chain behind almost every +model element. We are simplifying that by "flattening" the lower layers. + +You may see an example of how that works in the figure below: + +.. image:: ../_static/img/crosslayer_intro.jpg + +In the example above we see that `LogicalFunction` is a subtype of +`AbstractFunction`, just like `SystemFunction` or `OperationalActivity`. +Because of that, all of those subtypes can be `.available_in_states` or have a +layer-specific structural `owner`, like `LogicalComponent` for +`LogicalFunction`. Any layer-specific class that inherits from `Component` may +also have `state_machines`. + +The API reference part of this documentation provides you with the complete (as +it is generated from the code base) list of available methods and attributes. + +Layer-specific packages +======================= + +The following packages enable working with model layers: + +* :mod:`capellambse.metamodel.oa` - covers Operational Analysis layer. +* :mod:`capellambse.metamodel.sa` - covers System Analysis layer. +* :mod:`capellambse.metamodel.la` - covers Logical Architecture layer. +* :mod:`capellambse.metamodel.pa` - covers Physical Architecture layer. + +Cross-layer packages +==================== + +The following packages enable all (almost) of the layer packages: + +* :mod:`capellambse.metamodel.fa` - covers Functional Analysis concerns, + defines things like AbstractFunction or FunctionalExchange +* :mod:`capellambse.metamodel.cs` - covers Composite Structure concerns, + defines things like Component +* :mod:`capellambse.metamodel.capellacommon` - covers common concerns, + defines things like StateMachine, State +* :mod:`capellambse.metamodel.information` - covers Information + concerns, defines things like Class, DataPkg, ExchangeItem + +Extension packages +================== + +* :mod:`capellambse.extensions.reqif` - provides means for working with ReqIF + Requirements within Capella model. +* :mod:`capellambse.extensions.pvmt` - provides means for working with object + attributes created with PVMT package. diff --git a/_sources/start/migrating-0.6.rst.txt b/_sources/start/migrating-0.6.rst.txt new file mode 100644 index 000000000..f0d5300b6 --- /dev/null +++ b/_sources/start/migrating-0.6.rst.txt @@ -0,0 +1,126 @@ +.. + SPDX-FileCopyrightText: Copyright DB InfraGO AG + SPDX-License-Identifier: Apache-2.0 + +Migrating from |project| v0.5.x to v0.6.x +========================================= + +This page lists the most important differences between the v0.5.x and v0.6.x +series of releases. It is aimed at helping to transition client code using the +public high-level model API, and therefore may omit internal details that +client code should not be aware of. + +- The metamodel definitions are now available in ``capellambse.metamodel.*``. + The previous definitions at ``capellambse.model.layers.*`` and + ``capellambse.model.crosslayer.*`` have been removed. + +- The model implementation (previously ``capellambse.model.common``) has been + reorganized under the ``capellambse.model`` package. All relevant classes are + now directly exported on ``capellambse.model`` instead of any submodules. + Submodules are now considered private. + +- The PVMT extension has been revamped to be more feature-rich and easier to + use. Please see the new `PVMT introduction notebook`__ for more details on + how to use it. + + __ ../examples/08 Property Values.html + +- Previously deprecated names have been removed from the metamodel. + +- The auditing feature has been removed. Some design flaws led to it being + unreliable and hard to work with, and it was causing relatively high + maintenance overhead when making changes to the model implementation. + +- The format of ``MelodyModel.info`` has changed. Detailed information about + the used resources is now provided in the ``resources`` attribute, keyed by + resource identifier. The ``url`` of the primary resource is still made + available on the top-level info object for convenience, but other file + handler specific attributes are now only available in its resource info + (``model.info.resources["\x00"]``). + +- The Git file handler no longer accepts the ``shallow`` keyword argument. + Partial clones are always used instead, which offer better performance. + +Changed Model attributes +------------------------ + +The metamodel +~~~~~~~~~~~~~ + +The metamodel is now located in the ``capellambse.metamodel`` package. This +affects the following modules: + +.. note:: + + Note especially that the ``ctx`` module has been renamed to ``sa`` for + consistency with other modelling layers. + +.. list-table:: + :header-rows: 1 + + * - Old module path + - New module path + * - capellambse.model.crosslayer.* + - capellambse.metamodel.* + * - capellambse.model.layers.* + - capellambse.metamodel.* + * - capellambse.model.layers.ctx + - capellambse.metamodel.sa + +Requirements extension (``capellambse.extensions.reqif``) +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +The following deprecated aliases have been removed: + +.. list-table:: + :header-rows: 1 + + * - Removed alias + - Correct name + * - EnumDataTypeDefinition + - EnumerationDataTypeDefinition + * - RequirementsFolder + - Folder + * - RequirementsIncRelation + - CapellaIncomingRelation + * - RequirementsIntRelation + - InternalRelation + * - RequirementsModule + - CapellaModule + * - RequirementsOutRelation + - CapellaOutgoingRelation + * - RequirementsTypesFolder + - CapellaTypesFolder + * - String constants starting with ``XT_`` + - Use :func:`~capellambse.model.build_xtype` instead + * - The ``reqif.elements`` submodule + - Removed, use the ``reqif`` package directly + +Model implementation +~~~~~~~~~~~~~~~~~~~~ + +The implementation of the high-level model is now available on +``capellambse.model.*``. The previous submodule structure below +``capellambse.model.common.*`` has been dissolved. + +The ``capellambse.model.diagram`` module is not affected by this change. + +In addition, some classes have been renamed: + +.. list-table:: + :header-rows: 1 + + * - Old name + - New name + * - AttributeProperty + - StringPOD + * - HTMLAttributeProperty + - HTMLStringPOD + * - NumericAttributeProperty + - IntPOD or FloatPOD + * - BooleanAttributeProperty + - BoolPOD + * - DatetimeAttributeProperty + - DatetimePOD + * - EnumAttributeProperty + - EnumPOD diff --git a/_sources/start/specifying-models.rst.txt b/_sources/start/specifying-models.rst.txt new file mode 100644 index 000000000..526f0d873 --- /dev/null +++ b/_sources/start/specifying-models.rst.txt @@ -0,0 +1,163 @@ +.. + SPDX-FileCopyrightText: Copyright DB InfraGO AG + SPDX-License-Identifier: Apache-2.0 + +.. _specifying-models: + +***************** +Specifying models +***************** + +.. currentmodule:: capellambse.cli_helpers + +|project| and tools using it generally support multiple ways of specifying a +model to load and use. Which way to use depends on the specific situation. This +page lists all the ways that are commonly supported. + +Simple paths +============ + +A model can be specified by the path to its main ``*.aird`` file. + +.. code:: text + + /home/username/models/coffee-machine/coffee-machine.aird + C:\Capella\workspace\coffee-machine\coffee-machine.aird + ./model/model.aird + model.aird + +This is equivalent to specifying the *path* and *entrypoint* arguments to the +:class:`~capellambse.model.MelodyModel` constructor, e.g.: + +.. code:: python + + model = capellambse.MelodyModel( + path="/home/username/models/coffee-machine", + entrypoint="coffee-machine.aird", + ) + +Just like how the *entrypoint* argument is optional if there is only one +``*.aird`` file in the given *path*, the file name here may be omitted in this +case as well: + +.. code:: text + + /home/username/models/coffee-machine/ + C:\Capella\workspace\coffee-machine + ./model + . + +Make sure to escape any special characters such as whitespace or backslashes +when specifying paths on the command line. + +Remote URLs +=========== + +Models can also be loaded from various remote locations by specifying a URL in +the form of ``protocol://host.name/path/to/model.aird``. Out of the box, +|project| supports the following protocols: + +- :class:`file:///local/folder + ` +- :class:`git://host.name/repo.git + ` and variants, like: + ``git+https://host.name/repo``, ``git@host.name:repo`` +- :class:`http:// and https:// `, + example: ``https://host.name/path/%s?param=arg`` +- :class:`zip://, zip+https:// etc. + `, examples: + ``zip:///local/file.zip``, ``zip+https://host.name/remote/file.zip``, + ``zip+https://host.name/remote/%s?param=arg!file.zip`` + +Click on a protocol to get to the detailed documentation including supported +additional arguments, which can be passed in using JSON (see below). + +JSON +==== + +For more complex cases, like remote models that require credentials, it is +possible to pass a JSON-encoded dictionary. This dictionary can contain any key +that the :class:`~capellambse.model.MelodyModel` constructor and the underlying +:class:`~capellambse.filehandler.FileHandler` understands. + +Note that, when passing such JSON as command line argument, it is necessary to +escape the whole JSON string to prevent the Shell from interpreting it, +removing quotes, replacing variables, etc. In bash-like shells, this is usually +accomplished by wrapping it in single quotes, like this: + +.. code:: bash + + python -m capellambse.repl '{"path": "git@example.com:demo-model.git", "revision": "dev", ...}' + +.. known-models: + +Known models +============ + +A model can be given a short name by placing a JSON file in the user's +'known_models' folder. This is the exact same JSON as described above, just put +into a file instead of passed as string. + +Run the following command to find out where to put the files: + +.. code:: bash + + python -m capellambse.cli_helpers + +This will show the folder for custom 'known_models' files, and list the names +of all files found in either the custom or built-in folder. These names can +then be passed to any CLI command in place of the full model definition. + +For example, to start a capellambse REPL using the built-in "coffee-machine" +model definition, you can run: + +.. code:: bash + + python -m capellambse.repl coffee-machine + +The most common keys to use include ``path`` and ``entrypoint``, as well as +credential-related keys like ``username``, ``password`` or ``identity_file``. +Refer to the documentation of :class:`~capellambse.model.MelodyModel`, as well +as the respective FileHandler class you want to use for more details: + +- For local file paths: + :class:`~capellambse.filehandler.local.LocalFileHandler` +- For Git repositories: :class:`~capellambse.filehandler.git.GitFileHandler` +- For simple HTTP/HTTPS servers, optionally using HTTP Basic Authentication: + :class:`~capellambse.filehandler.http.HTTPFileHandler` +- For the Gitlab Artifacts service: + :class:`~capellambse.filehandler.gitlab_artifacts.GitlabArtifactsFiles` + +CLI support +=========== + +In order to make it easy to support model loading from the CLI, |project| +exposes a few functions and classes in the :mod:`capellambse.cli_helpers` +module. + +Standalone functions +-------------------- + +These functions help with loading a model from arbitrary user-supplied strings, +such as command line arguments. + +.. autofunction:: loadinfo + :noindex: + +.. autofunction:: loadcli + :noindex: + +.. autofunction:: enumerate_known_models + :noindex: + +Click parameter types +--------------------- + +There are also Click parameter types available that encapsulate the +``loadinfo`` and ``loadcli`` functions, respectively: + +.. autoclass:: ModelInfoCLI + :noindex: + +.. autoclass:: ModelCLI + :noindex: diff --git a/_sources/tools/sphinx-extension.rst.txt b/_sources/tools/sphinx-extension.rst.txt new file mode 100644 index 000000000..46a68c875 --- /dev/null +++ b/_sources/tools/sphinx-extension.rst.txt @@ -0,0 +1,8 @@ +.. + SPDX-FileCopyrightText: Copyright DB InfraGO AG + SPDX-License-Identifier: Apache-2.0 + +The |project| Sphinx extension +============================== + +.. automodule:: capellambse.sphinx diff --git a/_static/basic.css b/_static/basic.css new file mode 100644 index 000000000..7ebbd6d07 --- /dev/null +++ b/_static/basic.css @@ -0,0 +1,914 @@ +/* + * Sphinx stylesheet -- basic theme. + */ + +/* -- main layout ----------------------------------------------------------- */ + +div.clearer { + clear: both; +} + +div.section::after { + display: block; + content: ''; + clear: left; +} + +/* -- relbar ---------------------------------------------------------------- */ + +div.related { + width: 100%; + font-size: 90%; +} + +div.related h3 { + display: none; +} + +div.related ul { + margin: 0; + padding: 0 0 0 10px; + list-style: none; +} + +div.related li { + display: inline; +} + +div.related li.right { + float: right; + margin-right: 5px; +} + +/* -- sidebar --------------------------------------------------------------- */ + +div.sphinxsidebarwrapper { + padding: 10px 5px 0 10px; +} + +div.sphinxsidebar { + float: left; + width: 230px; + margin-left: -100%; + font-size: 90%; + word-wrap: break-word; + overflow-wrap : break-word; +} + +div.sphinxsidebar ul { + list-style: none; +} + +div.sphinxsidebar ul ul, +div.sphinxsidebar ul.want-points { + margin-left: 20px; + list-style: square; +} + +div.sphinxsidebar ul ul { + margin-top: 0; + margin-bottom: 0; +} + +div.sphinxsidebar form { + margin-top: 10px; +} + +div.sphinxsidebar input { + border: 1px solid #98dbcc; + font-family: sans-serif; + font-size: 1em; +} + +div.sphinxsidebar #searchbox form.search { + overflow: hidden; +} + +div.sphinxsidebar #searchbox input[type="text"] { + float: left; + width: 80%; + padding: 0.25em; + box-sizing: border-box; +} + +div.sphinxsidebar #searchbox input[type="submit"] { + float: left; + width: 20%; + border-left: none; + padding: 0.25em; + box-sizing: border-box; +} + + +img { + border: 0; + max-width: 100%; +} + +/* -- search page ----------------------------------------------------------- */ + +ul.search { + margin-top: 10px; +} + +ul.search li { + padding: 5px 0; +} + +ul.search li a { + font-weight: bold; +} + +ul.search li p.context { + color: #888; + margin: 2px 0 0 30px; + text-align: left; +} + +ul.keywordmatches li.goodmatch a { + font-weight: bold; +} + +/* -- index page ------------------------------------------------------------ */ + +table.contentstable { + width: 90%; + margin-left: auto; + margin-right: auto; +} + +table.contentstable p.biglink { + line-height: 150%; +} + +a.biglink { + font-size: 1.3em; +} + +span.linkdescr { + font-style: italic; + padding-top: 5px; + font-size: 90%; +} + +/* -- general index --------------------------------------------------------- */ + +table.indextable { + width: 100%; +} + +table.indextable td { + text-align: left; + vertical-align: top; +} + +table.indextable ul { + margin-top: 0; + margin-bottom: 0; + list-style-type: none; +} + +table.indextable > tbody > tr > td > ul { + padding-left: 0em; +} + +table.indextable tr.pcap { + height: 10px; +} + +table.indextable tr.cap { + margin-top: 10px; + background-color: #f2f2f2; +} + +img.toggler { + margin-right: 3px; + margin-top: 3px; + cursor: pointer; +} + +div.modindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +div.genindex-jumpbox { + border-top: 1px solid #ddd; + border-bottom: 1px solid #ddd; + margin: 1em 0 1em 0; + padding: 0.4em; +} + +/* -- domain module index --------------------------------------------------- */ + +table.modindextable td { + padding: 2px; + border-collapse: collapse; +} + +/* -- general body styles --------------------------------------------------- */ + +div.body { + min-width: 360px; + max-width: 800px; +} + +div.body p, div.body dd, div.body li, div.body blockquote { + -moz-hyphens: auto; + -ms-hyphens: auto; + -webkit-hyphens: auto; + hyphens: auto; +} + +a.headerlink { + visibility: hidden; +} + +a:visited { + color: #551A8B; +} + +h1:hover > a.headerlink, +h2:hover > a.headerlink, +h3:hover > a.headerlink, +h4:hover > a.headerlink, +h5:hover > a.headerlink, +h6:hover > a.headerlink, +dt:hover > a.headerlink, +caption:hover > a.headerlink, +p.caption:hover > a.headerlink, +div.code-block-caption:hover > a.headerlink { + visibility: visible; +} + +div.body p.caption { + text-align: inherit; +} + +div.body td { + text-align: left; +} + +.first { + margin-top: 0 !important; +} + +p.rubric { + margin-top: 30px; + font-weight: bold; +} + +img.align-left, figure.align-left, .figure.align-left, object.align-left { + clear: left; + float: left; + margin-right: 1em; +} + +img.align-right, figure.align-right, .figure.align-right, object.align-right { + clear: right; + float: right; + margin-left: 1em; +} + +img.align-center, figure.align-center, .figure.align-center, object.align-center { + display: block; + margin-left: auto; + margin-right: auto; +} + +img.align-default, figure.align-default, .figure.align-default { + display: block; + margin-left: auto; + margin-right: auto; +} + +.align-left { + text-align: left; +} + +.align-center { + text-align: center; +} + +.align-default { + text-align: center; +} + +.align-right { + text-align: right; +} + +/* -- sidebars -------------------------------------------------------------- */ + +div.sidebar, +aside.sidebar { + margin: 0 0 0.5em 1em; + border: 1px solid #ddb; + padding: 7px; + background-color: #ffe; + width: 40%; + float: right; + clear: right; + overflow-x: auto; +} + +p.sidebar-title { + font-weight: bold; +} + +nav.contents, +aside.topic, +div.admonition, div.topic, blockquote { + clear: left; +} + +/* -- topics ---------------------------------------------------------------- */ + +nav.contents, +aside.topic, +div.topic { + border: 1px solid #ccc; + padding: 7px; + margin: 10px 0 10px 0; +} + +p.topic-title { + font-size: 1.1em; + font-weight: bold; + margin-top: 10px; +} + +/* -- admonitions ----------------------------------------------------------- */ + +div.admonition { + margin-top: 10px; + margin-bottom: 10px; + padding: 7px; +} + +div.admonition dt { + font-weight: bold; +} + +p.admonition-title { + margin: 0px 10px 5px 0px; + font-weight: bold; +} + +div.body p.centered { + text-align: center; + margin-top: 25px; +} + +/* -- content of sidebars/topics/admonitions -------------------------------- */ + +div.sidebar > :last-child, +aside.sidebar > :last-child, +nav.contents > :last-child, +aside.topic > :last-child, +div.topic > :last-child, +div.admonition > :last-child { + margin-bottom: 0; +} + +div.sidebar::after, +aside.sidebar::after, +nav.contents::after, +aside.topic::after, +div.topic::after, +div.admonition::after, +blockquote::after { + display: block; + content: ''; + clear: both; +} + +/* -- tables ---------------------------------------------------------------- */ + +table.docutils { + margin-top: 10px; + margin-bottom: 10px; + border: 0; + border-collapse: collapse; +} + +table.align-center { + margin-left: auto; + margin-right: auto; +} + +table.align-default { + margin-left: auto; + margin-right: auto; +} + +table caption span.caption-number { + font-style: italic; +} + +table caption span.caption-text { +} + +table.docutils td, table.docutils th { + padding: 1px 8px 1px 5px; + border-top: 0; + border-left: 0; + border-right: 0; + border-bottom: 1px solid #aaa; +} + +th { + text-align: left; + padding-right: 5px; +} + +table.citation { + border-left: solid 1px gray; + margin-left: 1px; +} + +table.citation td { + border-bottom: none; +} + +th > :first-child, +td > :first-child { + margin-top: 0px; +} + +th > :last-child, +td > :last-child { + margin-bottom: 0px; +} + +/* -- figures --------------------------------------------------------------- */ + +div.figure, figure { + margin: 0.5em; + padding: 0.5em; +} + +div.figure p.caption, figcaption { + padding: 0.3em; +} + +div.figure p.caption span.caption-number, +figcaption span.caption-number { + font-style: italic; +} + +div.figure p.caption span.caption-text, +figcaption span.caption-text { +} + +/* -- field list styles ----------------------------------------------------- */ + +table.field-list td, table.field-list th { + border: 0 !important; +} + +.field-list ul { + margin: 0; + padding-left: 1em; +} + +.field-list p { + margin: 0; +} + +.field-name { + -moz-hyphens: manual; + -ms-hyphens: manual; + -webkit-hyphens: manual; + hyphens: manual; +} + +/* -- hlist styles ---------------------------------------------------------- */ + +table.hlist { + margin: 1em 0; +} + +table.hlist td { + vertical-align: top; +} + +/* -- object description styles --------------------------------------------- */ + +.sig { + font-family: 'Consolas', 'Menlo', 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', monospace; +} + +.sig-name, code.descname { + background-color: transparent; + font-weight: bold; +} + +.sig-name { + font-size: 1.1em; +} + +code.descname { + font-size: 1.2em; +} + +.sig-prename, code.descclassname { + background-color: transparent; +} + +.optional { + font-size: 1.3em; +} + +.sig-paren { + font-size: larger; +} + +.sig-param.n { + font-style: italic; +} + +/* C++ specific styling */ + +.sig-inline.c-texpr, +.sig-inline.cpp-texpr { + font-family: unset; +} + +.sig.c .k, .sig.c .kt, +.sig.cpp .k, .sig.cpp .kt { + color: #0033B3; +} + +.sig.c .m, +.sig.cpp .m { + color: #1750EB; +} + +.sig.c .s, .sig.c .sc, +.sig.cpp .s, .sig.cpp .sc { + color: #067D17; +} + + +/* -- other body styles ----------------------------------------------------- */ + +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; +} + +:not(li) > ol > li:first-child > :first-child, +:not(li) > ul > li:first-child > :first-child { + margin-top: 0px; +} + +:not(li) > ol > li:last-child > :last-child, +:not(li) > ul > li:last-child > :last-child { + margin-bottom: 0px; +} + +ol.simple ol p, +ol.simple ul p, +ul.simple ol p, +ul.simple ul p { + margin-top: 0; +} + +ol.simple > li:not(:first-child) > p, +ul.simple > li:not(:first-child) > p { + margin-top: 0; +} + +ol.simple p, +ul.simple p { + margin-bottom: 0; +} + +aside.footnote > span, +div.citation > span { + float: left; +} +aside.footnote > span:last-of-type, +div.citation > span:last-of-type { + padding-right: 0.5em; +} +aside.footnote > p { + margin-left: 2em; +} +div.citation > p { + margin-left: 4em; +} +aside.footnote > p:last-of-type, +div.citation > p:last-of-type { + margin-bottom: 0em; +} +aside.footnote > p:last-of-type:after, +div.citation > p:last-of-type:after { + content: ""; + clear: both; +} + +dl.field-list { + display: grid; + grid-template-columns: fit-content(30%) auto; +} + +dl.field-list > dt { + font-weight: bold; + word-break: break-word; + padding-left: 0.5em; + padding-right: 5px; +} + +dl.field-list > dd { + padding-left: 0.5em; + margin-top: 0em; + margin-left: 0em; + margin-bottom: 0em; +} + +dl { + margin-bottom: 15px; +} + +dd > :first-child { + margin-top: 0px; +} + +dd ul, dd table { + margin-bottom: 10px; +} + +dd { + margin-top: 3px; + margin-bottom: 10px; + 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; +} + +dt:target, span.highlighted { + background-color: #fbe54e; +} + +rect.highlighted { + fill: #fbe54e; +} + +dl.glossary dt { + font-weight: bold; + font-size: 1.1em; +} + +.versionmodified { + font-style: italic; +} + +.system-message { + background-color: #fda; + padding: 5px; + border: 3px solid red; +} + +.footnote:target { + background-color: #ffa; +} + +.line-block { + display: block; + margin-top: 1em; + margin-bottom: 1em; +} + +.line-block .line-block { + margin-top: 0; + margin-bottom: 0; + margin-left: 1.5em; +} + +.guilabel, .menuselection { + font-family: sans-serif; +} + +.accelerator { + text-decoration: underline; +} + +.classifier { + font-style: oblique; +} + +.classifier:before { + font-style: normal; + margin: 0 0.5em; + content: ":"; + display: inline-block; +} + +abbr, acronym { + border-bottom: dotted 1px; + cursor: help; +} + +.translated { + background-color: rgba(207, 255, 207, 0.2) +} + +.untranslated { + background-color: rgba(255, 207, 207, 0.2) +} + +/* -- code displays --------------------------------------------------------- */ + +pre { + overflow: auto; + overflow-y: hidden; /* fixes display issues on Chrome browsers */ +} + +pre, div[class*="highlight-"] { + clear: both; +} + +span.pre { + -moz-hyphens: none; + -ms-hyphens: none; + -webkit-hyphens: none; + hyphens: none; + white-space: nowrap; +} + +div[class*="highlight-"] { + margin: 1em 0; +} + +td.linenos pre { + border: 0; + background-color: transparent; + color: #aaa; +} + +table.highlighttable { + display: block; +} + +table.highlighttable tbody { + display: block; +} + +table.highlighttable tr { + display: flex; +} + +table.highlighttable td { + margin: 0; + padding: 0; +} + +table.highlighttable td.linenos { + padding-right: 0.5em; +} + +table.highlighttable td.code { + flex: 1; + overflow: hidden; +} + +.highlight .hll { + display: block; +} + +div.highlight pre, +table.highlighttable pre { + margin: 0; +} + +div.code-block-caption + div { + margin-top: 0; +} + +div.code-block-caption { + margin-top: 1em; + padding: 2px 5px; + font-size: small; +} + +div.code-block-caption code { + background-color: transparent; +} + +table.highlighttable td.linenos, +span.linenos, +div.highlight span.gp { /* gp: Generic.Prompt */ + user-select: none; + -webkit-user-select: text; /* Safari fallback only */ + -webkit-user-select: none; /* Chrome/Safari */ + -moz-user-select: none; /* Firefox */ + -ms-user-select: none; /* IE10+ */ +} + +div.code-block-caption span.caption-number { + padding: 0.1em 0.3em; + font-style: italic; +} + +div.code-block-caption span.caption-text { +} + +div.literal-block-wrapper { + margin: 1em 0; +} + +code.xref, a code { + background-color: transparent; + font-weight: bold; +} + +h1 code, h2 code, h3 code, h4 code, h5 code, h6 code { + background-color: transparent; +} + +.viewcode-link { + float: right; +} + +.viewcode-back { + float: right; + font-family: sans-serif; +} + +div.viewcode-block:target { + margin: -1px -10px; + padding: 0 10px; +} + +/* -- math display ---------------------------------------------------------- */ + +img.math { + vertical-align: middle; +} + +div.body div.math p { + text-align: center; +} + +span.eqno { + float: right; +} + +span.eqno a.headerlink { + position: absolute; + z-index: 1; +} + +div.math:hover a.headerlink { + visibility: visible; +} + +/* -- printout stylesheet --------------------------------------------------- */ + +@media print { + div.document, + div.documentwrapper, + div.bodywrapper { + margin: 0 !important; + width: 100%; + } + + div.sphinxsidebar, + div.related, + div.footer, + #top-link { + display: none; + } +} \ No newline at end of file diff --git a/_static/debug.css b/_static/debug.css new file mode 100644 index 000000000..74d4aec33 --- /dev/null +++ b/_static/debug.css @@ -0,0 +1,69 @@ +/* + This CSS file should be overridden by the theme authors. It's + meant for debugging and developing the skeleton that this theme provides. +*/ +body { + font-family: -apple-system, "Segoe UI", Roboto, Helvetica, Arial, sans-serif, + "Apple Color Emoji", "Segoe UI Emoji"; + background: lavender; +} +.sb-announcement { + background: rgb(131, 131, 131); +} +.sb-announcement__inner { + background: black; + color: white; +} +.sb-header { + background: lightskyblue; +} +.sb-header__inner { + background: royalblue; + color: white; +} +.sb-header-secondary { + background: lightcyan; +} +.sb-header-secondary__inner { + background: cornflowerblue; + color: white; +} +.sb-sidebar-primary { + background: lightgreen; +} +.sb-main { + background: blanchedalmond; +} +.sb-main__inner { + background: antiquewhite; +} +.sb-header-article { + background: lightsteelblue; +} +.sb-article-container { + background: snow; +} +.sb-article-main { + background: white; +} +.sb-footer-article { + background: lightpink; +} +.sb-sidebar-secondary { + background: lightgoldenrodyellow; +} +.sb-footer-content { + background: plum; +} +.sb-footer-content__inner { + background: palevioletred; +} +.sb-footer { + background: pink; +} +.sb-footer__inner { + background: salmon; +} +.sb-article { + background: white; +} diff --git a/_static/doctools.js b/_static/doctools.js new file mode 100644 index 000000000..0398ebb9f --- /dev/null +++ b/_static/doctools.js @@ -0,0 +1,149 @@ +/* + * Base JavaScript utilities for all Sphinx HTML documentation. + */ +"use strict"; + +const BLACKLISTED_KEY_CONTROL_ELEMENTS = new Set([ + "TEXTAREA", + "INPUT", + "SELECT", + "BUTTON", +]); + +const _ready = (callback) => { + if (document.readyState !== "loading") { + callback(); + } else { + document.addEventListener("DOMContentLoaded", callback); + } +}; + +/** + * Small JavaScript module for the documentation. + */ +const Documentation = { + init: () => { + Documentation.initDomainIndexTable(); + Documentation.initOnKeyListeners(); + }, + + /** + * i18n support + */ + TRANSLATIONS: {}, + PLURAL_EXPR: (n) => (n === 1 ? 0 : 1), + LOCALE: "unknown", + + // gettext and ngettext don't access this so that the functions + // can safely bound to a different name (_ = Documentation.gettext) + gettext: (string) => { + const translated = Documentation.TRANSLATIONS[string]; + switch (typeof translated) { + case "undefined": + return string; // no translation + case "string": + return translated; // translation exists + default: + return translated[0]; // (singular, plural) translation tuple exists + } + }, + + ngettext: (singular, plural, n) => { + const translated = Documentation.TRANSLATIONS[singular]; + if (typeof translated !== "undefined") + return translated[Documentation.PLURAL_EXPR(n)]; + return n === 1 ? singular : plural; + }, + + addTranslations: (catalog) => { + Object.assign(Documentation.TRANSLATIONS, catalog.messages); + Documentation.PLURAL_EXPR = new Function( + "n", + `return (${catalog.plural_expr})` + ); + Documentation.LOCALE = catalog.locale; + }, + + /** + * helper function to focus on search bar + */ + focusSearchBar: () => { + document.querySelectorAll("input[name=q]")[0]?.focus(); + }, + + /** + * Initialise the domain index toggle buttons + */ + initDomainIndexTable: () => { + const toggler = (el) => { + const idNumber = el.id.substr(7); + const toggledRows = document.querySelectorAll(`tr.cg-${idNumber}`); + if (el.src.substr(-9) === "minus.png") { + el.src = `${el.src.substr(0, el.src.length - 9)}plus.png`; + toggledRows.forEach((el) => (el.style.display = "none")); + } else { + el.src = `${el.src.substr(0, el.src.length - 8)}minus.png`; + toggledRows.forEach((el) => (el.style.display = "")); + } + }; + + const togglerElements = document.querySelectorAll("img.toggler"); + togglerElements.forEach((el) => + el.addEventListener("click", (event) => toggler(event.currentTarget)) + ); + togglerElements.forEach((el) => (el.style.display = "")); + if (DOCUMENTATION_OPTIONS.COLLAPSE_INDEX) togglerElements.forEach(toggler); + }, + + initOnKeyListeners: () => { + // only install a listener if it is really needed + if ( + !DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS && + !DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS + ) + return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.altKey || event.ctrlKey || event.metaKey) return; + + if (!event.shiftKey) { + switch (event.key) { + case "ArrowLeft": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const prevLink = document.querySelector('link[rel="prev"]'); + if (prevLink && prevLink.href) { + window.location.href = prevLink.href; + event.preventDefault(); + } + break; + case "ArrowRight": + if (!DOCUMENTATION_OPTIONS.NAVIGATION_WITH_KEYS) break; + + const nextLink = document.querySelector('link[rel="next"]'); + if (nextLink && nextLink.href) { + window.location.href = nextLink.href; + event.preventDefault(); + } + break; + } + } + + // some keyboard layouts may need Shift to get / + switch (event.key) { + case "/": + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) break; + Documentation.focusSearchBar(); + event.preventDefault(); + } + }); + }, +}; + +// quick alias for translations +const _ = Documentation.gettext; + +_ready(Documentation.init); diff --git a/_static/documentation_options.js b/_static/documentation_options.js new file mode 100644 index 000000000..7e4c114f2 --- /dev/null +++ b/_static/documentation_options.js @@ -0,0 +1,13 @@ +const DOCUMENTATION_OPTIONS = { + VERSION: '', + LANGUAGE: 'en', + COLLAPSE_INDEX: false, + BUILDER: 'html', + FILE_SUFFIX: '.html', + LINK_SUFFIX: '.html', + HAS_SOURCE: true, + SOURCELINK_SUFFIX: '.txt', + NAVIGATION_WITH_KEYS: false, + SHOW_SEARCH_SUMMARY: true, + ENABLE_SEARCH_SHORTCUTS: true, +}; \ No newline at end of file diff --git a/_static/file.png b/_static/file.png new file mode 100644 index 000000000..a858a410e Binary files /dev/null and b/_static/file.png differ diff --git a/_static/img/2021-05-09_10-32.jpg b/_static/img/2021-05-09_10-32.jpg new file mode 100644 index 000000000..d16a02951 Binary files /dev/null and b/_static/img/2021-05-09_10-32.jpg differ diff --git a/_static/img/2021-05-09_10-32.jpg.license b/_static/img/2021-05-09_10-32.jpg.license new file mode 100644 index 000000000..62a1749a9 --- /dev/null +++ b/_static/img/2021-05-09_10-32.jpg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Copyright DB InfraGO AG +SPDX-License-Identifier: Apache-2.0 diff --git a/_static/img/2021-05-09_10-36.jpg b/_static/img/2021-05-09_10-36.jpg new file mode 100644 index 000000000..db2876cb3 Binary files /dev/null and b/_static/img/2021-05-09_10-36.jpg differ diff --git a/_static/img/2021-05-09_10-36.jpg.license b/_static/img/2021-05-09_10-36.jpg.license new file mode 100644 index 000000000..62a1749a9 --- /dev/null +++ b/_static/img/2021-05-09_10-36.jpg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Copyright DB InfraGO AG +SPDX-License-Identifier: Apache-2.0 diff --git a/_static/img/2021-05-09_10-50.jpg b/_static/img/2021-05-09_10-50.jpg new file mode 100644 index 000000000..cd12ca5d9 Binary files /dev/null and b/_static/img/2021-05-09_10-50.jpg differ diff --git a/_static/img/2021-05-09_10-50.jpg.license b/_static/img/2021-05-09_10-50.jpg.license new file mode 100644 index 000000000..62a1749a9 --- /dev/null +++ b/_static/img/2021-05-09_10-50.jpg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Copyright DB InfraGO AG +SPDX-License-Identifier: Apache-2.0 diff --git a/_static/img/2021-05-09_17-36.jpg b/_static/img/2021-05-09_17-36.jpg new file mode 100644 index 000000000..b5581088b Binary files /dev/null and b/_static/img/2021-05-09_17-36.jpg differ diff --git a/_static/img/2021-05-09_17-36.jpg.license b/_static/img/2021-05-09_17-36.jpg.license new file mode 100644 index 000000000..62a1749a9 --- /dev/null +++ b/_static/img/2021-05-09_17-36.jpg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Copyright DB InfraGO AG +SPDX-License-Identifier: Apache-2.0 diff --git a/_static/img/2021-05-09_17-38.jpg b/_static/img/2021-05-09_17-38.jpg new file mode 100644 index 000000000..60c056e85 Binary files /dev/null and b/_static/img/2021-05-09_17-38.jpg differ diff --git a/_static/img/2021-05-09_17-38.jpg.license b/_static/img/2021-05-09_17-38.jpg.license new file mode 100644 index 000000000..62a1749a9 --- /dev/null +++ b/_static/img/2021-05-09_17-38.jpg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Copyright DB InfraGO AG +SPDX-License-Identifier: Apache-2.0 diff --git a/_static/img/2021-05-09_17-44.jpg b/_static/img/2021-05-09_17-44.jpg new file mode 100644 index 000000000..83b414d0f Binary files /dev/null and b/_static/img/2021-05-09_17-44.jpg differ diff --git a/_static/img/2021-05-09_17-44.jpg.license b/_static/img/2021-05-09_17-44.jpg.license new file mode 100644 index 000000000..62a1749a9 --- /dev/null +++ b/_static/img/2021-05-09_17-44.jpg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Copyright DB InfraGO AG +SPDX-License-Identifier: Apache-2.0 diff --git a/_static/img/2021-05-09_17-57.jpg b/_static/img/2021-05-09_17-57.jpg new file mode 100644 index 000000000..b9dd0947e Binary files /dev/null and b/_static/img/2021-05-09_17-57.jpg differ diff --git a/_static/img/2021-05-09_17-57.jpg.license b/_static/img/2021-05-09_17-57.jpg.license new file mode 100644 index 000000000..62a1749a9 --- /dev/null +++ b/_static/img/2021-05-09_17-57.jpg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Copyright DB InfraGO AG +SPDX-License-Identifier: Apache-2.0 diff --git a/_static/img/2021-05-09_19-50.jpg b/_static/img/2021-05-09_19-50.jpg new file mode 100644 index 000000000..7decd28c0 Binary files /dev/null and b/_static/img/2021-05-09_19-50.jpg differ diff --git a/_static/img/2021-05-09_19-50.jpg.license b/_static/img/2021-05-09_19-50.jpg.license new file mode 100644 index 000000000..62a1749a9 --- /dev/null +++ b/_static/img/2021-05-09_19-50.jpg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Copyright DB InfraGO AG +SPDX-License-Identifier: Apache-2.0 diff --git a/_static/img/2021-05-09_21-16.jpg b/_static/img/2021-05-09_21-16.jpg new file mode 100644 index 000000000..165f0ba53 Binary files /dev/null and b/_static/img/2021-05-09_21-16.jpg differ diff --git a/_static/img/2021-05-09_21-16.jpg.license b/_static/img/2021-05-09_21-16.jpg.license new file mode 100644 index 000000000..62a1749a9 --- /dev/null +++ b/_static/img/2021-05-09_21-16.jpg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Copyright DB InfraGO AG +SPDX-License-Identifier: Apache-2.0 diff --git a/_static/img/2021-05-09_21-21.jpg b/_static/img/2021-05-09_21-21.jpg new file mode 100644 index 000000000..1b27de5f0 Binary files /dev/null and b/_static/img/2021-05-09_21-21.jpg differ diff --git a/_static/img/2021-05-09_21-21.jpg.license b/_static/img/2021-05-09_21-21.jpg.license new file mode 100644 index 000000000..62a1749a9 --- /dev/null +++ b/_static/img/2021-05-09_21-21.jpg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Copyright DB InfraGO AG +SPDX-License-Identifier: Apache-2.0 diff --git a/_static/img/2021-05-09_21-46.jpg b/_static/img/2021-05-09_21-46.jpg new file mode 100644 index 000000000..903bd8e92 Binary files /dev/null and b/_static/img/2021-05-09_21-46.jpg differ diff --git a/_static/img/2021-05-09_21-46.jpg.license b/_static/img/2021-05-09_21-46.jpg.license new file mode 100644 index 000000000..62a1749a9 --- /dev/null +++ b/_static/img/2021-05-09_21-46.jpg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Copyright DB InfraGO AG +SPDX-License-Identifier: Apache-2.0 diff --git a/_static/img/2021-05-09_22-09.jpg b/_static/img/2021-05-09_22-09.jpg new file mode 100644 index 000000000..5b3a1fcd2 Binary files /dev/null and b/_static/img/2021-05-09_22-09.jpg differ diff --git a/_static/img/2021-05-09_22-09.jpg.license b/_static/img/2021-05-09_22-09.jpg.license new file mode 100644 index 000000000..62a1749a9 --- /dev/null +++ b/_static/img/2021-05-09_22-09.jpg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Copyright DB InfraGO AG +SPDX-License-Identifier: Apache-2.0 diff --git a/_static/img/2021-05-09_22-39.jpg b/_static/img/2021-05-09_22-39.jpg new file mode 100644 index 000000000..d02b6668f Binary files /dev/null and b/_static/img/2021-05-09_22-39.jpg differ diff --git a/_static/img/2021-05-09_22-39.jpg.license b/_static/img/2021-05-09_22-39.jpg.license new file mode 100644 index 000000000..62a1749a9 --- /dev/null +++ b/_static/img/2021-05-09_22-39.jpg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Copyright DB InfraGO AG +SPDX-License-Identifier: Apache-2.0 diff --git a/_static/img/2021-05-10_22-35.jpg b/_static/img/2021-05-10_22-35.jpg new file mode 100644 index 000000000..9c3650585 Binary files /dev/null and b/_static/img/2021-05-10_22-35.jpg differ diff --git a/_static/img/2021-05-10_22-35.jpg.license b/_static/img/2021-05-10_22-35.jpg.license new file mode 100644 index 000000000..62a1749a9 --- /dev/null +++ b/_static/img/2021-05-10_22-35.jpg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Copyright DB InfraGO AG +SPDX-License-Identifier: Apache-2.0 diff --git a/_static/img/2021-05-10_22-59.jpg b/_static/img/2021-05-10_22-59.jpg new file mode 100644 index 000000000..ca184bc6c Binary files /dev/null and b/_static/img/2021-05-10_22-59.jpg differ diff --git a/_static/img/2021-05-10_22-59.jpg.license b/_static/img/2021-05-10_22-59.jpg.license new file mode 100644 index 000000000..62a1749a9 --- /dev/null +++ b/_static/img/2021-05-10_22-59.jpg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Copyright DB InfraGO AG +SPDX-License-Identifier: Apache-2.0 diff --git a/_static/img/2021-05-12_18-18.jpg b/_static/img/2021-05-12_18-18.jpg new file mode 100644 index 000000000..5ee9dac5a Binary files /dev/null and b/_static/img/2021-05-12_18-18.jpg differ diff --git a/_static/img/2021-05-12_18-18.jpg.license b/_static/img/2021-05-12_18-18.jpg.license new file mode 100644 index 000000000..62a1749a9 --- /dev/null +++ b/_static/img/2021-05-12_18-18.jpg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Copyright DB InfraGO AG +SPDX-License-Identifier: Apache-2.0 diff --git a/_static/img/2021-05-12_18-51.jpg b/_static/img/2021-05-12_18-51.jpg new file mode 100644 index 000000000..afb248858 Binary files /dev/null and b/_static/img/2021-05-12_18-51.jpg differ diff --git a/_static/img/2021-05-12_18-51.jpg.license b/_static/img/2021-05-12_18-51.jpg.license new file mode 100644 index 000000000..62a1749a9 --- /dev/null +++ b/_static/img/2021-05-12_18-51.jpg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Copyright DB InfraGO AG +SPDX-License-Identifier: Apache-2.0 diff --git a/_static/img/2021-05-12_19-12.jpg b/_static/img/2021-05-12_19-12.jpg new file mode 100644 index 000000000..cda80cf9d Binary files /dev/null and b/_static/img/2021-05-12_19-12.jpg differ diff --git a/_static/img/2021-05-12_19-12.jpg.license b/_static/img/2021-05-12_19-12.jpg.license new file mode 100644 index 000000000..62a1749a9 --- /dev/null +++ b/_static/img/2021-05-12_19-12.jpg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Copyright DB InfraGO AG +SPDX-License-Identifier: Apache-2.0 diff --git a/_static/img/2021-05-12_20-06.jpg b/_static/img/2021-05-12_20-06.jpg new file mode 100644 index 000000000..b34855edf Binary files /dev/null and b/_static/img/2021-05-12_20-06.jpg differ diff --git a/_static/img/2021-05-12_20-06.jpg.license b/_static/img/2021-05-12_20-06.jpg.license new file mode 100644 index 000000000..62a1749a9 --- /dev/null +++ b/_static/img/2021-05-12_20-06.jpg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Copyright DB InfraGO AG +SPDX-License-Identifier: Apache-2.0 diff --git a/_static/img/2021-05-12_20-10.jpg b/_static/img/2021-05-12_20-10.jpg new file mode 100644 index 000000000..04d6402f1 Binary files /dev/null and b/_static/img/2021-05-12_20-10.jpg differ diff --git a/_static/img/2021-05-12_20-10.jpg.license b/_static/img/2021-05-12_20-10.jpg.license new file mode 100644 index 000000000..62a1749a9 --- /dev/null +++ b/_static/img/2021-05-12_20-10.jpg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Copyright DB InfraGO AG +SPDX-License-Identifier: Apache-2.0 diff --git a/_static/img/2021-05-12_21-03.jpg b/_static/img/2021-05-12_21-03.jpg new file mode 100644 index 000000000..384e2ba0d Binary files /dev/null and b/_static/img/2021-05-12_21-03.jpg differ diff --git a/_static/img/2021-05-12_21-03.jpg.license b/_static/img/2021-05-12_21-03.jpg.license new file mode 100644 index 000000000..62a1749a9 --- /dev/null +++ b/_static/img/2021-05-12_21-03.jpg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Copyright DB InfraGO AG +SPDX-License-Identifier: Apache-2.0 diff --git a/_static/img/2021-05-13_20-46.jpg b/_static/img/2021-05-13_20-46.jpg new file mode 100644 index 000000000..d3448b877 Binary files /dev/null and b/_static/img/2021-05-13_20-46.jpg differ diff --git a/_static/img/2021-05-13_20-46.jpg.license b/_static/img/2021-05-13_20-46.jpg.license new file mode 100644 index 000000000..62a1749a9 --- /dev/null +++ b/_static/img/2021-05-13_20-46.jpg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Copyright DB InfraGO AG +SPDX-License-Identifier: Apache-2.0 diff --git a/_static/img/2021-05-17_11-50.jpg b/_static/img/2021-05-17_11-50.jpg new file mode 100644 index 000000000..3fb35b9c0 Binary files /dev/null and b/_static/img/2021-05-17_11-50.jpg differ diff --git a/_static/img/2021-05-17_11-50.jpg.license b/_static/img/2021-05-17_11-50.jpg.license new file mode 100644 index 000000000..62a1749a9 --- /dev/null +++ b/_static/img/2021-05-17_11-50.jpg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Copyright DB InfraGO AG +SPDX-License-Identifier: Apache-2.0 diff --git a/_static/img/core-pkg-deps-raw.svg b/_static/img/core-pkg-deps-raw.svg new file mode 100644 index 000000000..04321b962 --- /dev/null +++ b/_static/img/core-pkg-deps-raw.svg @@ -0,0 +1,1146 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + http://www.polarsys.org/capella/common/activity/5.0.0 + + + + + + + + + + + http://www.polarsys.org/capella/common/behavior/5.0.0 + + + + + + + + + + + http://www.polarsys.org/capella/core/common/5.0.0 + + + + + + + + + + + http://www.polarsys.org/capella/core/core/5.0.0 + + + + + + + + + + + http://www.polarsys.org/capella/core/cs/5.0.0 + + + + + + + + + + + http://www.polarsys.org/capella/core/ctx/5.0.0 + + + + + + + + + + + http://www.polarsys.org/kitalpha/emde/1.0.0 + + + + + + + + + + + http://www.polarsys.org/capella/core/epbs/5.0.0 + + + + + + + + + + + http://www.polarsys.org/capella/core/fa/5.0.0 + + + + + + + + + + + http://www.polarsys.org/capella/core/information/5.0.0 + + + + + + + + + + + http://www.polarsys.org/capella/core/interaction/5.0.0 + + + + + + + + + + + http://www.polarsys.org/capella/core/la/5.0.0 + + + + + + + + + + + http://www.polarsys.org/capella/common/core/5.0.0 + + + + + + + + + + + http://www.polarsys.org/capella/core/oa/5.0.0 + + + + + + + + + + + http://www.polarsys.org/capella/core/pa/5.0.0 + + + + + + + + + + + http://www.polarsys.org/capella/core/requirement/5.0.0 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/_static/img/core-pkg-deps-raw.svg.license b/_static/img/core-pkg-deps-raw.svg.license new file mode 100644 index 000000000..62a1749a9 --- /dev/null +++ b/_static/img/core-pkg-deps-raw.svg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Copyright DB InfraGO AG +SPDX-License-Identifier: Apache-2.0 diff --git a/_static/img/crosslayer_intro.jpg b/_static/img/crosslayer_intro.jpg new file mode 100644 index 000000000..41349a91a Binary files /dev/null and b/_static/img/crosslayer_intro.jpg differ diff --git a/_static/img/crosslayer_intro.jpg.license b/_static/img/crosslayer_intro.jpg.license new file mode 100644 index 000000000..62a1749a9 --- /dev/null +++ b/_static/img/crosslayer_intro.jpg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Copyright DB InfraGO AG +SPDX-License-Identifier: Apache-2.0 diff --git a/_static/img/dep-graph-oa.jpg b/_static/img/dep-graph-oa.jpg new file mode 100644 index 000000000..1e771de2f Binary files /dev/null and b/_static/img/dep-graph-oa.jpg differ diff --git a/_static/img/dep-graph-oa.jpg.license b/_static/img/dep-graph-oa.jpg.license new file mode 100644 index 000000000..62a1749a9 --- /dev/null +++ b/_static/img/dep-graph-oa.jpg.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Copyright DB InfraGO AG +SPDX-License-Identifier: Apache-2.0 diff --git a/_static/img/harrys_wand.png b/_static/img/harrys_wand.png new file mode 100644 index 000000000..effece64b Binary files /dev/null and b/_static/img/harrys_wand.png differ diff --git a/_static/img/harrys_wand.png.license b/_static/img/harrys_wand.png.license new file mode 100644 index 000000000..62a1749a9 --- /dev/null +++ b/_static/img/harrys_wand.png.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Copyright DB InfraGO AG +SPDX-License-Identifier: Apache-2.0 diff --git a/_static/img/waypoints.png b/_static/img/waypoints.png new file mode 100644 index 000000000..fd021c986 Binary files /dev/null and b/_static/img/waypoints.png differ diff --git a/_static/img/waypoints.png.license b/_static/img/waypoints.png.license new file mode 100644 index 000000000..62a1749a9 --- /dev/null +++ b/_static/img/waypoints.png.license @@ -0,0 +1,2 @@ +SPDX-FileCopyrightText: Copyright DB InfraGO AG +SPDX-License-Identifier: Apache-2.0 diff --git a/_static/language_data.js b/_static/language_data.js new file mode 100644 index 000000000..c7fe6c6fa --- /dev/null +++ b/_static/language_data.js @@ -0,0 +1,192 @@ +/* + * This script contains the language-specific data used by searchtools.js, + * namely the list of stopwords, stemmer, scorer and splitter. + */ + +var stopwords = ["a", "and", "are", "as", "at", "be", "but", "by", "for", "if", "in", "into", "is", "it", "near", "no", "not", "of", "on", "or", "such", "that", "the", "their", "then", "there", "these", "they", "this", "to", "was", "will", "with"]; + + +/* Non-minified version is copied as a separate JS file, if available */ + +/** + * Porter Stemmer + */ +var Stemmer = function() { + + var step2list = { + ational: 'ate', + tional: 'tion', + enci: 'ence', + anci: 'ance', + izer: 'ize', + bli: 'ble', + alli: 'al', + entli: 'ent', + eli: 'e', + ousli: 'ous', + ization: 'ize', + ation: 'ate', + ator: 'ate', + alism: 'al', + iveness: 'ive', + fulness: 'ful', + ousness: 'ous', + aliti: 'al', + iviti: 'ive', + biliti: 'ble', + logi: 'log' + }; + + var step3list = { + icate: 'ic', + ative: '', + alize: 'al', + iciti: 'ic', + ical: 'ic', + ful: '', + ness: '' + }; + + var c = "[^aeiou]"; // consonant + var v = "[aeiouy]"; // vowel + var C = c + "[^aeiouy]*"; // consonant sequence + var V = v + "[aeiou]*"; // vowel sequence + + var mgr0 = "^(" + C + ")?" + V + C; // [C]VC... is m>0 + var meq1 = "^(" + C + ")?" + V + C + "(" + V + ")?$"; // [C]VC[V] is m=1 + var mgr1 = "^(" + C + ")?" + V + C + V + C; // [C]VCVC... is m>1 + var s_v = "^(" + C + ")?" + v; // vowel in stem + + this.stemWord = function (w) { + var stem; + var suffix; + var firstch; + var origword = w; + + if (w.length < 3) + return w; + + var re; + var re2; + var re3; + var re4; + + firstch = w.substr(0,1); + if (firstch == "y") + w = firstch.toUpperCase() + w.substr(1); + + // Step 1a + re = /^(.+?)(ss|i)es$/; + re2 = /^(.+?)([^s])s$/; + + if (re.test(w)) + w = w.replace(re,"$1$2"); + else if (re2.test(w)) + w = w.replace(re2,"$1$2"); + + // Step 1b + re = /^(.+?)eed$/; + re2 = /^(.+?)(ed|ing)$/; + if (re.test(w)) { + var fp = re.exec(w); + re = new RegExp(mgr0); + if (re.test(fp[1])) { + re = /.$/; + w = w.replace(re,""); + } + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1]; + re2 = new RegExp(s_v); + if (re2.test(stem)) { + w = stem; + re2 = /(at|bl|iz)$/; + re3 = new RegExp("([^aeiouylsz])\\1$"); + re4 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re2.test(w)) + w = w + "e"; + else if (re3.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + else if (re4.test(w)) + w = w + "e"; + } + } + + // Step 1c + re = /^(.+?)y$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(s_v); + if (re.test(stem)) + w = stem + "i"; + } + + // Step 2 + re = /^(.+?)(ational|tional|enci|anci|izer|bli|alli|entli|eli|ousli|ization|ation|ator|alism|iveness|fulness|ousness|aliti|iviti|biliti|logi)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step2list[suffix]; + } + + // Step 3 + re = /^(.+?)(icate|ative|alize|iciti|ical|ful|ness)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + suffix = fp[2]; + re = new RegExp(mgr0); + if (re.test(stem)) + w = stem + step3list[suffix]; + } + + // Step 4 + re = /^(.+?)(al|ance|ence|er|ic|able|ible|ant|ement|ment|ent|ou|ism|ate|iti|ous|ive|ize)$/; + re2 = /^(.+?)(s|t)(ion)$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + if (re.test(stem)) + w = stem; + } + else if (re2.test(w)) { + var fp = re2.exec(w); + stem = fp[1] + fp[2]; + re2 = new RegExp(mgr1); + if (re2.test(stem)) + w = stem; + } + + // Step 5 + re = /^(.+?)e$/; + if (re.test(w)) { + var fp = re.exec(w); + stem = fp[1]; + re = new RegExp(mgr1); + re2 = new RegExp(meq1); + re3 = new RegExp("^" + C + v + "[^aeiouwxy]$"); + if (re.test(stem) || (re2.test(stem) && !(re3.test(stem)))) + w = stem; + } + re = /ll$/; + re2 = new RegExp(mgr1); + if (re.test(w) && re2.test(w)) { + re = /.$/; + w = w.replace(re,""); + } + + // and turn initial Y back to y + if (firstch == "y") + w = firstch.toLowerCase() + w.substr(1); + return w; + } +} + diff --git a/_static/minus.png b/_static/minus.png new file mode 100644 index 000000000..d96755fda Binary files /dev/null and b/_static/minus.png differ diff --git a/_static/nbsphinx-broken-thumbnail.svg b/_static/nbsphinx-broken-thumbnail.svg new file mode 100644 index 000000000..4919ca882 --- /dev/null +++ b/_static/nbsphinx-broken-thumbnail.svg @@ -0,0 +1,9 @@ + + + + diff --git a/_static/nbsphinx-code-cells.css b/_static/nbsphinx-code-cells.css new file mode 100644 index 000000000..a3fb27c30 --- /dev/null +++ b/_static/nbsphinx-code-cells.css @@ -0,0 +1,259 @@ +/* remove conflicting styling from Sphinx themes */ +div.nbinput.container div.prompt *, +div.nboutput.container div.prompt *, +div.nbinput.container div.input_area pre, +div.nboutput.container div.output_area pre, +div.nbinput.container div.input_area .highlight, +div.nboutput.container div.output_area .highlight { + border: none; + padding: 0; + margin: 0; + box-shadow: none; +} + +div.nbinput.container > div[class*=highlight], +div.nboutput.container > div[class*=highlight] { + margin: 0; +} + +div.nbinput.container div.prompt *, +div.nboutput.container div.prompt * { + background: none; +} + +div.nboutput.container div.output_area .highlight, +div.nboutput.container div.output_area pre { + background: unset; +} + +div.nboutput.container div.output_area div.highlight { + color: unset; /* override Pygments text color */ +} + +/* avoid gaps between output lines */ +div.nboutput.container div[class*=highlight] pre { + line-height: normal; +} + +/* input/output containers */ +div.nbinput.container, +div.nboutput.container { + display: -webkit-flex; + display: flex; + align-items: flex-start; + margin: 0; + width: 100%; +} +@media (max-width: 540px) { + div.nbinput.container, + div.nboutput.container { + flex-direction: column; + } +} + +/* input container */ +div.nbinput.container { + padding-top: 5px; +} + +/* last container */ +div.nblast.container { + padding-bottom: 5px; +} + +/* input prompt */ +div.nbinput.container div.prompt pre, +/* for sphinx_immaterial theme: */ +div.nbinput.container div.prompt pre > code { + color: #307FC1; +} + +/* output prompt */ +div.nboutput.container div.prompt pre, +/* for sphinx_immaterial theme: */ +div.nboutput.container div.prompt pre > code { + color: #BF5B3D; +} + +/* all prompts */ +div.nbinput.container div.prompt, +div.nboutput.container div.prompt { + width: 4.5ex; + padding-top: 5px; + position: relative; + user-select: none; +} + +div.nbinput.container div.prompt > div, +div.nboutput.container div.prompt > div { + position: absolute; + right: 0; + margin-right: 0.3ex; +} + +@media (max-width: 540px) { + div.nbinput.container div.prompt, + div.nboutput.container div.prompt { + width: unset; + text-align: left; + padding: 0.4em; + } + div.nboutput.container div.prompt.empty { + padding: 0; + } + + div.nbinput.container div.prompt > div, + div.nboutput.container div.prompt > div { + position: unset; + } +} + +/* disable scrollbars and line breaks on prompts */ +div.nbinput.container div.prompt pre, +div.nboutput.container div.prompt pre { + overflow: hidden; + white-space: pre; +} + +/* input/output area */ +div.nbinput.container div.input_area, +div.nboutput.container div.output_area { + -webkit-flex: 1; + flex: 1; + overflow: auto; +} +@media (max-width: 540px) { + div.nbinput.container div.input_area, + div.nboutput.container div.output_area { + width: 100%; + } +} + +/* input area */ +div.nbinput.container div.input_area { + border: 1px solid #e0e0e0; + border-radius: 2px; + /*background: #f5f5f5;*/ +} + +/* override MathJax center alignment in output cells */ +div.nboutput.container div[class*=MathJax] { + text-align: left !important; +} + +/* override sphinx.ext.imgmath center alignment in output cells */ +div.nboutput.container div.math p { + text-align: left; +} + +/* standard error */ +div.nboutput.container div.output_area.stderr { + background: #fdd; +} + +/* ANSI colors */ +.ansi-black-fg { color: #3E424D; } +.ansi-black-bg { background-color: #3E424D; } +.ansi-black-intense-fg { color: #282C36; } +.ansi-black-intense-bg { background-color: #282C36; } +.ansi-red-fg { color: #E75C58; } +.ansi-red-bg { background-color: #E75C58; } +.ansi-red-intense-fg { color: #B22B31; } +.ansi-red-intense-bg { background-color: #B22B31; } +.ansi-green-fg { color: #00A250; } +.ansi-green-bg { background-color: #00A250; } +.ansi-green-intense-fg { color: #007427; } +.ansi-green-intense-bg { background-color: #007427; } +.ansi-yellow-fg { color: #DDB62B; } +.ansi-yellow-bg { background-color: #DDB62B; } +.ansi-yellow-intense-fg { color: #B27D12; } +.ansi-yellow-intense-bg { background-color: #B27D12; } +.ansi-blue-fg { color: #208FFB; } +.ansi-blue-bg { background-color: #208FFB; } +.ansi-blue-intense-fg { color: #0065CA; } +.ansi-blue-intense-bg { background-color: #0065CA; } +.ansi-magenta-fg { color: #D160C4; } +.ansi-magenta-bg { background-color: #D160C4; } +.ansi-magenta-intense-fg { color: #A03196; } +.ansi-magenta-intense-bg { background-color: #A03196; } +.ansi-cyan-fg { color: #60C6C8; } +.ansi-cyan-bg { background-color: #60C6C8; } +.ansi-cyan-intense-fg { color: #258F8F; } +.ansi-cyan-intense-bg { background-color: #258F8F; } +.ansi-white-fg { color: #C5C1B4; } +.ansi-white-bg { background-color: #C5C1B4; } +.ansi-white-intense-fg { color: #A1A6B2; } +.ansi-white-intense-bg { background-color: #A1A6B2; } + +.ansi-default-inverse-fg { color: #FFFFFF; } +.ansi-default-inverse-bg { background-color: #000000; } + +.ansi-bold { font-weight: bold; } +.ansi-underline { text-decoration: underline; } + + +div.nbinput.container div.input_area div[class*=highlight] > pre, +div.nboutput.container div.output_area div[class*=highlight] > pre, +div.nboutput.container div.output_area div[class*=highlight].math, +div.nboutput.container div.output_area.rendered_html, +div.nboutput.container div.output_area > div.output_javascript, +div.nboutput.container div.output_area:not(.rendered_html) > img{ + padding: 5px; + margin: 0; +} + +/* fix copybtn overflow problem in chromium (needed for 'sphinx_copybutton') */ +div.nbinput.container div.input_area > div[class^='highlight'], +div.nboutput.container div.output_area > div[class^='highlight']{ + overflow-y: hidden; +} + +/* hide copy button on prompts for 'sphinx_copybutton' extension ... */ +.prompt .copybtn, +/* ... and 'sphinx_immaterial' theme */ +.prompt .md-clipboard.md-icon { + display: none; +} + +/* Some additional styling taken form the Jupyter notebook CSS */ +.jp-RenderedHTMLCommon table, +div.rendered_html table { + border: none; + border-collapse: collapse; + border-spacing: 0; + color: black; + font-size: 12px; + table-layout: fixed; +} +.jp-RenderedHTMLCommon thead, +div.rendered_html thead { + border-bottom: 1px solid black; + vertical-align: bottom; +} +.jp-RenderedHTMLCommon tr, +.jp-RenderedHTMLCommon th, +.jp-RenderedHTMLCommon td, +div.rendered_html tr, +div.rendered_html th, +div.rendered_html td { + text-align: right; + vertical-align: middle; + padding: 0.5em 0.5em; + line-height: normal; + white-space: normal; + max-width: none; + border: none; +} +.jp-RenderedHTMLCommon th, +div.rendered_html th { + font-weight: bold; +} +.jp-RenderedHTMLCommon tbody tr:nth-child(odd), +div.rendered_html tbody tr:nth-child(odd) { + background: #f5f5f5; +} +.jp-RenderedHTMLCommon tbody tr:hover, +div.rendered_html tbody tr:hover { + background: rgba(66, 165, 245, 0.2); +} + diff --git a/_static/nbsphinx-gallery.css b/_static/nbsphinx-gallery.css new file mode 100644 index 000000000..365c27a96 --- /dev/null +++ b/_static/nbsphinx-gallery.css @@ -0,0 +1,31 @@ +.nbsphinx-gallery { + display: grid; + grid-template-columns: repeat(auto-fill, minmax(160px, 1fr)); + gap: 5px; + margin-top: 1em; + margin-bottom: 1em; +} + +.nbsphinx-gallery > a { + padding: 5px; + border: 1px dotted currentColor; + border-radius: 2px; + text-align: center; +} + +.nbsphinx-gallery > a:hover { + border-style: solid; +} + +.nbsphinx-gallery img { + max-width: 100%; + max-height: 100%; +} + +.nbsphinx-gallery > a > div:first-child { + display: flex; + align-items: start; + justify-content: center; + height: 120px; + margin-bottom: 5px; +} diff --git a/_static/nbsphinx-no-thumbnail.svg b/_static/nbsphinx-no-thumbnail.svg new file mode 100644 index 000000000..9dca7588f --- /dev/null +++ b/_static/nbsphinx-no-thumbnail.svg @@ -0,0 +1,9 @@ + + + + diff --git a/_static/plus.png b/_static/plus.png new file mode 100644 index 000000000..7107cec93 Binary files /dev/null and b/_static/plus.png differ diff --git a/_static/pygments.css b/_static/pygments.css new file mode 100644 index 000000000..5c8cad8b4 --- /dev/null +++ b/_static/pygments.css @@ -0,0 +1,258 @@ +.highlight pre { line-height: 125%; } +.highlight td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +.highlight span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +.highlight td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +.highlight .hll { background-color: #ffffcc } +.highlight { background: #f8f8f8; } +.highlight .c { color: #8f5902; font-style: italic } /* Comment */ +.highlight .err { color: #a40000; border: 1px solid #ef2929 } /* Error */ +.highlight .g { color: #000000 } /* Generic */ +.highlight .k { color: #204a87; font-weight: bold } /* Keyword */ +.highlight .l { color: #000000 } /* Literal */ +.highlight .n { color: #000000 } /* Name */ +.highlight .o { color: #ce5c00; font-weight: bold } /* Operator */ +.highlight .x { color: #000000 } /* Other */ +.highlight .p { color: #000000; font-weight: bold } /* Punctuation */ +.highlight .ch { color: #8f5902; font-style: italic } /* Comment.Hashbang */ +.highlight .cm { color: #8f5902; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #8f5902; font-style: italic } /* Comment.Preproc */ +.highlight .cpf { color: #8f5902; font-style: italic } /* Comment.PreprocFile */ +.highlight .c1 { color: #8f5902; font-style: italic } /* Comment.Single */ +.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 */ +.highlight .go { color: #000000; font-style: italic } /* Generic.Output */ +.highlight .gp { color: #8f5902 } /* Generic.Prompt */ +.highlight .gs { color: #000000; font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold } /* Generic.Subheading */ +.highlight .gt { color: #a40000; font-weight: bold } /* Generic.Traceback */ +.highlight .kc { color: #204a87; font-weight: bold } /* Keyword.Constant */ +.highlight .kd { color: #204a87; font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { color: #204a87; font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { color: #204a87; font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { color: #204a87; font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #204a87; font-weight: bold } /* Keyword.Type */ +.highlight .ld { color: #000000 } /* Literal.Date */ +.highlight .m { color: #0000cf; font-weight: bold } /* Literal.Number */ +.highlight .s { color: #4e9a06 } /* Literal.String */ +.highlight .na { color: #c4a000 } /* Name.Attribute */ +.highlight .nb { color: #204a87 } /* Name.Builtin */ +.highlight .nc { color: #000000 } /* Name.Class */ +.highlight .no { color: #000000 } /* Name.Constant */ +.highlight .nd { color: #5c35cc; font-weight: bold } /* Name.Decorator */ +.highlight .ni { color: #ce5c00 } /* Name.Entity */ +.highlight .ne { color: #cc0000; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #000000 } /* Name.Function */ +.highlight .nl { color: #f57900 } /* Name.Label */ +.highlight .nn { color: #000000 } /* Name.Namespace */ +.highlight .nx { color: #000000 } /* Name.Other */ +.highlight .py { color: #000000 } /* Name.Property */ +.highlight .nt { color: #204a87; font-weight: bold } /* Name.Tag */ +.highlight .nv { color: #000000 } /* Name.Variable */ +.highlight .ow { color: #204a87; font-weight: bold } /* Operator.Word */ +.highlight .pm { color: #000000; font-weight: bold } /* Punctuation.Marker */ +.highlight .w { color: #f8f8f8 } /* Text.Whitespace */ +.highlight .mb { color: #0000cf; font-weight: bold } /* Literal.Number.Bin */ +.highlight .mf { color: #0000cf; font-weight: bold } /* Literal.Number.Float */ +.highlight .mh { color: #0000cf; font-weight: bold } /* Literal.Number.Hex */ +.highlight .mi { color: #0000cf; font-weight: bold } /* Literal.Number.Integer */ +.highlight .mo { color: #0000cf; font-weight: bold } /* Literal.Number.Oct */ +.highlight .sa { color: #4e9a06 } /* Literal.String.Affix */ +.highlight .sb { color: #4e9a06 } /* Literal.String.Backtick */ +.highlight .sc { color: #4e9a06 } /* Literal.String.Char */ +.highlight .dl { color: #4e9a06 } /* Literal.String.Delimiter */ +.highlight .sd { color: #8f5902; font-style: italic } /* Literal.String.Doc */ +.highlight .s2 { color: #4e9a06 } /* Literal.String.Double */ +.highlight .se { color: #4e9a06 } /* Literal.String.Escape */ +.highlight .sh { color: #4e9a06 } /* Literal.String.Heredoc */ +.highlight .si { color: #4e9a06 } /* Literal.String.Interpol */ +.highlight .sx { color: #4e9a06 } /* Literal.String.Other */ +.highlight .sr { color: #4e9a06 } /* Literal.String.Regex */ +.highlight .s1 { color: #4e9a06 } /* Literal.String.Single */ +.highlight .ss { color: #4e9a06 } /* Literal.String.Symbol */ +.highlight .bp { color: #3465a4 } /* Name.Builtin.Pseudo */ +.highlight .fm { color: #000000 } /* Name.Function.Magic */ +.highlight .vc { color: #000000 } /* Name.Variable.Class */ +.highlight .vg { color: #000000 } /* Name.Variable.Global */ +.highlight .vi { color: #000000 } /* Name.Variable.Instance */ +.highlight .vm { color: #000000 } /* Name.Variable.Magic */ +.highlight .il { color: #0000cf; font-weight: bold } /* Literal.Number.Integer.Long */ +@media not print { +body[data-theme="dark"] .highlight pre { line-height: 125%; } +body[data-theme="dark"] .highlight td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +body[data-theme="dark"] .highlight span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +body[data-theme="dark"] .highlight td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +body[data-theme="dark"] .highlight span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +body[data-theme="dark"] .highlight .hll { background-color: #49483e } +body[data-theme="dark"] .highlight { background: #272822; color: #f8f8f2 } +body[data-theme="dark"] .highlight .c { color: #959077 } /* Comment */ +body[data-theme="dark"] .highlight .err { color: #ed007e; background-color: #1e0010 } /* Error */ +body[data-theme="dark"] .highlight .esc { color: #f8f8f2 } /* Escape */ +body[data-theme="dark"] .highlight .g { color: #f8f8f2 } /* Generic */ +body[data-theme="dark"] .highlight .k { color: #66d9ef } /* Keyword */ +body[data-theme="dark"] .highlight .l { color: #ae81ff } /* Literal */ +body[data-theme="dark"] .highlight .n { color: #f8f8f2 } /* Name */ +body[data-theme="dark"] .highlight .o { color: #ff4689 } /* Operator */ +body[data-theme="dark"] .highlight .x { color: #f8f8f2 } /* Other */ +body[data-theme="dark"] .highlight .p { color: #f8f8f2 } /* Punctuation */ +body[data-theme="dark"] .highlight .ch { color: #959077 } /* Comment.Hashbang */ +body[data-theme="dark"] .highlight .cm { color: #959077 } /* Comment.Multiline */ +body[data-theme="dark"] .highlight .cp { color: #959077 } /* Comment.Preproc */ +body[data-theme="dark"] .highlight .cpf { color: #959077 } /* Comment.PreprocFile */ +body[data-theme="dark"] .highlight .c1 { color: #959077 } /* Comment.Single */ +body[data-theme="dark"] .highlight .cs { color: #959077 } /* Comment.Special */ +body[data-theme="dark"] .highlight .gd { color: #ff4689 } /* Generic.Deleted */ +body[data-theme="dark"] .highlight .ge { color: #f8f8f2; font-style: italic } /* Generic.Emph */ +body[data-theme="dark"] .highlight .ges { color: #f8f8f2; font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +body[data-theme="dark"] .highlight .gr { color: #f8f8f2 } /* Generic.Error */ +body[data-theme="dark"] .highlight .gh { color: #f8f8f2 } /* Generic.Heading */ +body[data-theme="dark"] .highlight .gi { color: #a6e22e } /* Generic.Inserted */ +body[data-theme="dark"] .highlight .go { color: #66d9ef } /* Generic.Output */ +body[data-theme="dark"] .highlight .gp { color: #ff4689; font-weight: bold } /* Generic.Prompt */ +body[data-theme="dark"] .highlight .gs { color: #f8f8f2; font-weight: bold } /* Generic.Strong */ +body[data-theme="dark"] .highlight .gu { color: #959077 } /* Generic.Subheading */ +body[data-theme="dark"] .highlight .gt { color: #f8f8f2 } /* Generic.Traceback */ +body[data-theme="dark"] .highlight .kc { color: #66d9ef } /* Keyword.Constant */ +body[data-theme="dark"] .highlight .kd { color: #66d9ef } /* Keyword.Declaration */ +body[data-theme="dark"] .highlight .kn { color: #ff4689 } /* Keyword.Namespace */ +body[data-theme="dark"] .highlight .kp { color: #66d9ef } /* Keyword.Pseudo */ +body[data-theme="dark"] .highlight .kr { color: #66d9ef } /* Keyword.Reserved */ +body[data-theme="dark"] .highlight .kt { color: #66d9ef } /* Keyword.Type */ +body[data-theme="dark"] .highlight .ld { color: #e6db74 } /* Literal.Date */ +body[data-theme="dark"] .highlight .m { color: #ae81ff } /* Literal.Number */ +body[data-theme="dark"] .highlight .s { color: #e6db74 } /* Literal.String */ +body[data-theme="dark"] .highlight .na { color: #a6e22e } /* Name.Attribute */ +body[data-theme="dark"] .highlight .nb { color: #f8f8f2 } /* Name.Builtin */ +body[data-theme="dark"] .highlight .nc { color: #a6e22e } /* Name.Class */ +body[data-theme="dark"] .highlight .no { color: #66d9ef } /* Name.Constant */ +body[data-theme="dark"] .highlight .nd { color: #a6e22e } /* Name.Decorator */ +body[data-theme="dark"] .highlight .ni { color: #f8f8f2 } /* Name.Entity */ +body[data-theme="dark"] .highlight .ne { color: #a6e22e } /* Name.Exception */ +body[data-theme="dark"] .highlight .nf { color: #a6e22e } /* Name.Function */ +body[data-theme="dark"] .highlight .nl { color: #f8f8f2 } /* Name.Label */ +body[data-theme="dark"] .highlight .nn { color: #f8f8f2 } /* Name.Namespace */ +body[data-theme="dark"] .highlight .nx { color: #a6e22e } /* Name.Other */ +body[data-theme="dark"] .highlight .py { color: #f8f8f2 } /* Name.Property */ +body[data-theme="dark"] .highlight .nt { color: #ff4689 } /* Name.Tag */ +body[data-theme="dark"] .highlight .nv { color: #f8f8f2 } /* Name.Variable */ +body[data-theme="dark"] .highlight .ow { color: #ff4689 } /* Operator.Word */ +body[data-theme="dark"] .highlight .pm { color: #f8f8f2 } /* Punctuation.Marker */ +body[data-theme="dark"] .highlight .w { color: #f8f8f2 } /* Text.Whitespace */ +body[data-theme="dark"] .highlight .mb { color: #ae81ff } /* Literal.Number.Bin */ +body[data-theme="dark"] .highlight .mf { color: #ae81ff } /* Literal.Number.Float */ +body[data-theme="dark"] .highlight .mh { color: #ae81ff } /* Literal.Number.Hex */ +body[data-theme="dark"] .highlight .mi { color: #ae81ff } /* Literal.Number.Integer */ +body[data-theme="dark"] .highlight .mo { color: #ae81ff } /* Literal.Number.Oct */ +body[data-theme="dark"] .highlight .sa { color: #e6db74 } /* Literal.String.Affix */ +body[data-theme="dark"] .highlight .sb { color: #e6db74 } /* Literal.String.Backtick */ +body[data-theme="dark"] .highlight .sc { color: #e6db74 } /* Literal.String.Char */ +body[data-theme="dark"] .highlight .dl { color: #e6db74 } /* Literal.String.Delimiter */ +body[data-theme="dark"] .highlight .sd { color: #e6db74 } /* Literal.String.Doc */ +body[data-theme="dark"] .highlight .s2 { color: #e6db74 } /* Literal.String.Double */ +body[data-theme="dark"] .highlight .se { color: #ae81ff } /* Literal.String.Escape */ +body[data-theme="dark"] .highlight .sh { color: #e6db74 } /* Literal.String.Heredoc */ +body[data-theme="dark"] .highlight .si { color: #e6db74 } /* Literal.String.Interpol */ +body[data-theme="dark"] .highlight .sx { color: #e6db74 } /* Literal.String.Other */ +body[data-theme="dark"] .highlight .sr { color: #e6db74 } /* Literal.String.Regex */ +body[data-theme="dark"] .highlight .s1 { color: #e6db74 } /* Literal.String.Single */ +body[data-theme="dark"] .highlight .ss { color: #e6db74 } /* Literal.String.Symbol */ +body[data-theme="dark"] .highlight .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */ +body[data-theme="dark"] .highlight .fm { color: #a6e22e } /* Name.Function.Magic */ +body[data-theme="dark"] .highlight .vc { color: #f8f8f2 } /* Name.Variable.Class */ +body[data-theme="dark"] .highlight .vg { color: #f8f8f2 } /* Name.Variable.Global */ +body[data-theme="dark"] .highlight .vi { color: #f8f8f2 } /* Name.Variable.Instance */ +body[data-theme="dark"] .highlight .vm { color: #f8f8f2 } /* Name.Variable.Magic */ +body[data-theme="dark"] .highlight .il { color: #ae81ff } /* Literal.Number.Integer.Long */ +@media (prefers-color-scheme: dark) { +body:not([data-theme="light"]) .highlight pre { line-height: 125%; } +body:not([data-theme="light"]) .highlight td.linenos .normal { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +body:not([data-theme="light"]) .highlight span.linenos { color: inherit; background-color: transparent; padding-left: 5px; padding-right: 5px; } +body:not([data-theme="light"]) .highlight td.linenos .special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +body:not([data-theme="light"]) .highlight span.linenos.special { color: #000000; background-color: #ffffc0; padding-left: 5px; padding-right: 5px; } +body:not([data-theme="light"]) .highlight .hll { background-color: #49483e } +body:not([data-theme="light"]) .highlight { background: #272822; color: #f8f8f2 } +body:not([data-theme="light"]) .highlight .c { color: #959077 } /* Comment */ +body:not([data-theme="light"]) .highlight .err { color: #ed007e; background-color: #1e0010 } /* Error */ +body:not([data-theme="light"]) .highlight .esc { color: #f8f8f2 } /* Escape */ +body:not([data-theme="light"]) .highlight .g { color: #f8f8f2 } /* Generic */ +body:not([data-theme="light"]) .highlight .k { color: #66d9ef } /* Keyword */ +body:not([data-theme="light"]) .highlight .l { color: #ae81ff } /* Literal */ +body:not([data-theme="light"]) .highlight .n { color: #f8f8f2 } /* Name */ +body:not([data-theme="light"]) .highlight .o { color: #ff4689 } /* Operator */ +body:not([data-theme="light"]) .highlight .x { color: #f8f8f2 } /* Other */ +body:not([data-theme="light"]) .highlight .p { color: #f8f8f2 } /* Punctuation */ +body:not([data-theme="light"]) .highlight .ch { color: #959077 } /* Comment.Hashbang */ +body:not([data-theme="light"]) .highlight .cm { color: #959077 } /* Comment.Multiline */ +body:not([data-theme="light"]) .highlight .cp { color: #959077 } /* Comment.Preproc */ +body:not([data-theme="light"]) .highlight .cpf { color: #959077 } /* Comment.PreprocFile */ +body:not([data-theme="light"]) .highlight .c1 { color: #959077 } /* Comment.Single */ +body:not([data-theme="light"]) .highlight .cs { color: #959077 } /* Comment.Special */ +body:not([data-theme="light"]) .highlight .gd { color: #ff4689 } /* Generic.Deleted */ +body:not([data-theme="light"]) .highlight .ge { color: #f8f8f2; font-style: italic } /* Generic.Emph */ +body:not([data-theme="light"]) .highlight .ges { color: #f8f8f2; font-weight: bold; font-style: italic } /* Generic.EmphStrong */ +body:not([data-theme="light"]) .highlight .gr { color: #f8f8f2 } /* Generic.Error */ +body:not([data-theme="light"]) .highlight .gh { color: #f8f8f2 } /* Generic.Heading */ +body:not([data-theme="light"]) .highlight .gi { color: #a6e22e } /* Generic.Inserted */ +body:not([data-theme="light"]) .highlight .go { color: #66d9ef } /* Generic.Output */ +body:not([data-theme="light"]) .highlight .gp { color: #ff4689; font-weight: bold } /* Generic.Prompt */ +body:not([data-theme="light"]) .highlight .gs { color: #f8f8f2; font-weight: bold } /* Generic.Strong */ +body:not([data-theme="light"]) .highlight .gu { color: #959077 } /* Generic.Subheading */ +body:not([data-theme="light"]) .highlight .gt { color: #f8f8f2 } /* Generic.Traceback */ +body:not([data-theme="light"]) .highlight .kc { color: #66d9ef } /* Keyword.Constant */ +body:not([data-theme="light"]) .highlight .kd { color: #66d9ef } /* Keyword.Declaration */ +body:not([data-theme="light"]) .highlight .kn { color: #ff4689 } /* Keyword.Namespace */ +body:not([data-theme="light"]) .highlight .kp { color: #66d9ef } /* Keyword.Pseudo */ +body:not([data-theme="light"]) .highlight .kr { color: #66d9ef } /* Keyword.Reserved */ +body:not([data-theme="light"]) .highlight .kt { color: #66d9ef } /* Keyword.Type */ +body:not([data-theme="light"]) .highlight .ld { color: #e6db74 } /* Literal.Date */ +body:not([data-theme="light"]) .highlight .m { color: #ae81ff } /* Literal.Number */ +body:not([data-theme="light"]) .highlight .s { color: #e6db74 } /* Literal.String */ +body:not([data-theme="light"]) .highlight .na { color: #a6e22e } /* Name.Attribute */ +body:not([data-theme="light"]) .highlight .nb { color: #f8f8f2 } /* Name.Builtin */ +body:not([data-theme="light"]) .highlight .nc { color: #a6e22e } /* Name.Class */ +body:not([data-theme="light"]) .highlight .no { color: #66d9ef } /* Name.Constant */ +body:not([data-theme="light"]) .highlight .nd { color: #a6e22e } /* Name.Decorator */ +body:not([data-theme="light"]) .highlight .ni { color: #f8f8f2 } /* Name.Entity */ +body:not([data-theme="light"]) .highlight .ne { color: #a6e22e } /* Name.Exception */ +body:not([data-theme="light"]) .highlight .nf { color: #a6e22e } /* Name.Function */ +body:not([data-theme="light"]) .highlight .nl { color: #f8f8f2 } /* Name.Label */ +body:not([data-theme="light"]) .highlight .nn { color: #f8f8f2 } /* Name.Namespace */ +body:not([data-theme="light"]) .highlight .nx { color: #a6e22e } /* Name.Other */ +body:not([data-theme="light"]) .highlight .py { color: #f8f8f2 } /* Name.Property */ +body:not([data-theme="light"]) .highlight .nt { color: #ff4689 } /* Name.Tag */ +body:not([data-theme="light"]) .highlight .nv { color: #f8f8f2 } /* Name.Variable */ +body:not([data-theme="light"]) .highlight .ow { color: #ff4689 } /* Operator.Word */ +body:not([data-theme="light"]) .highlight .pm { color: #f8f8f2 } /* Punctuation.Marker */ +body:not([data-theme="light"]) .highlight .w { color: #f8f8f2 } /* Text.Whitespace */ +body:not([data-theme="light"]) .highlight .mb { color: #ae81ff } /* Literal.Number.Bin */ +body:not([data-theme="light"]) .highlight .mf { color: #ae81ff } /* Literal.Number.Float */ +body:not([data-theme="light"]) .highlight .mh { color: #ae81ff } /* Literal.Number.Hex */ +body:not([data-theme="light"]) .highlight .mi { color: #ae81ff } /* Literal.Number.Integer */ +body:not([data-theme="light"]) .highlight .mo { color: #ae81ff } /* Literal.Number.Oct */ +body:not([data-theme="light"]) .highlight .sa { color: #e6db74 } /* Literal.String.Affix */ +body:not([data-theme="light"]) .highlight .sb { color: #e6db74 } /* Literal.String.Backtick */ +body:not([data-theme="light"]) .highlight .sc { color: #e6db74 } /* Literal.String.Char */ +body:not([data-theme="light"]) .highlight .dl { color: #e6db74 } /* Literal.String.Delimiter */ +body:not([data-theme="light"]) .highlight .sd { color: #e6db74 } /* Literal.String.Doc */ +body:not([data-theme="light"]) .highlight .s2 { color: #e6db74 } /* Literal.String.Double */ +body:not([data-theme="light"]) .highlight .se { color: #ae81ff } /* Literal.String.Escape */ +body:not([data-theme="light"]) .highlight .sh { color: #e6db74 } /* Literal.String.Heredoc */ +body:not([data-theme="light"]) .highlight .si { color: #e6db74 } /* Literal.String.Interpol */ +body:not([data-theme="light"]) .highlight .sx { color: #e6db74 } /* Literal.String.Other */ +body:not([data-theme="light"]) .highlight .sr { color: #e6db74 } /* Literal.String.Regex */ +body:not([data-theme="light"]) .highlight .s1 { color: #e6db74 } /* Literal.String.Single */ +body:not([data-theme="light"]) .highlight .ss { color: #e6db74 } /* Literal.String.Symbol */ +body:not([data-theme="light"]) .highlight .bp { color: #f8f8f2 } /* Name.Builtin.Pseudo */ +body:not([data-theme="light"]) .highlight .fm { color: #a6e22e } /* Name.Function.Magic */ +body:not([data-theme="light"]) .highlight .vc { color: #f8f8f2 } /* Name.Variable.Class */ +body:not([data-theme="light"]) .highlight .vg { color: #f8f8f2 } /* Name.Variable.Global */ +body:not([data-theme="light"]) .highlight .vi { color: #f8f8f2 } /* Name.Variable.Instance */ +body:not([data-theme="light"]) .highlight .vm { color: #f8f8f2 } /* Name.Variable.Magic */ +body:not([data-theme="light"]) .highlight .il { color: #ae81ff } /* Literal.Number.Integer.Long */ +} +} \ No newline at end of file diff --git a/_static/scripts/furo-extensions.js b/_static/scripts/furo-extensions.js new file mode 100644 index 000000000..e69de29bb diff --git a/_static/scripts/furo.js b/_static/scripts/furo.js new file mode 100644 index 000000000..0abb2afac --- /dev/null +++ b/_static/scripts/furo.js @@ -0,0 +1,3 @@ +/*! For license information please see furo.js.LICENSE.txt */ +(()=>{var t={856:function(t,e,n){var o,r;r=void 0!==n.g?n.g:"undefined"!=typeof window?window:this,o=function(){return function(t){"use strict";var e={navClass:"active",contentClass:"active",nested:!1,nestedClass:"active",offset:0,reflow:!1,events:!0},n=function(t,e,n){if(n.settings.events){var o=new CustomEvent(t,{bubbles:!0,cancelable:!0,detail:n});e.dispatchEvent(o)}},o=function(t){var e=0;if(t.offsetParent)for(;t;)e+=t.offsetTop,t=t.offsetParent;return e>=0?e:0},r=function(t){t&&t.sort((function(t,e){return o(t.content)=Math.max(document.body.scrollHeight,document.documentElement.scrollHeight,document.body.offsetHeight,document.documentElement.offsetHeight,document.body.clientHeight,document.documentElement.clientHeight)},l=function(t,e){var n=t[t.length-1];if(function(t,e){return!(!s()||!c(t.content,e,!0))}(n,e))return n;for(var o=t.length-1;o>=0;o--)if(c(t[o].content,e))return t[o]},a=function(t,e){if(e.nested&&t.parentNode){var n=t.parentNode.closest("li");n&&(n.classList.remove(e.nestedClass),a(n,e))}},i=function(t,e){if(t){var o=t.nav.closest("li");o&&(o.classList.remove(e.navClass),t.content.classList.remove(e.contentClass),a(o,e),n("gumshoeDeactivate",o,{link:t.nav,content:t.content,settings:e}))}},u=function(t,e){if(e.nested){var n=t.parentNode.closest("li");n&&(n.classList.add(e.nestedClass),u(n,e))}};return function(o,c){var s,a,d,f,m,v={setup:function(){s=document.querySelectorAll(o),a=[],Array.prototype.forEach.call(s,(function(t){var e=document.getElementById(decodeURIComponent(t.hash.substr(1)));e&&a.push({nav:t,content:e})})),r(a)},detect:function(){var t=l(a,m);t?d&&t.content===d.content||(i(d,m),function(t,e){if(t){var o=t.nav.closest("li");o&&(o.classList.add(e.navClass),t.content.classList.add(e.contentClass),u(o,e),n("gumshoeActivate",o,{link:t.nav,content:t.content,settings:e}))}}(t,m),d=t):d&&(i(d,m),d=null)}},h=function(e){f&&t.cancelAnimationFrame(f),f=t.requestAnimationFrame(v.detect)},g=function(e){f&&t.cancelAnimationFrame(f),f=t.requestAnimationFrame((function(){r(a),v.detect()}))};return v.destroy=function(){d&&i(d,m),t.removeEventListener("scroll",h,!1),m.reflow&&t.removeEventListener("resize",g,!1),a=null,s=null,d=null,f=null,m=null},m=function(){var t={};return Array.prototype.forEach.call(arguments,(function(e){for(var n in e){if(!e.hasOwnProperty(n))return;t[n]=e[n]}})),t}(e,c||{}),v.setup(),v.detect(),t.addEventListener("scroll",h,!1),m.reflow&&t.addEventListener("resize",g,!1),v}}(r)}.apply(e,[]),void 0===o||(t.exports=o)}},e={};function n(o){var r=e[o];if(void 0!==r)return r.exports;var c=e[o]={exports:{}};return t[o].call(c.exports,c,c.exports,n),c.exports}n.n=t=>{var e=t&&t.__esModule?()=>t.default:()=>t;return n.d(e,{a:e}),e},n.d=(t,e)=>{for(var o in e)n.o(e,o)&&!n.o(t,o)&&Object.defineProperty(t,o,{enumerable:!0,get:e[o]})},n.g=function(){if("object"==typeof globalThis)return globalThis;try{return this||new Function("return this")()}catch(t){if("object"==typeof window)return window}}(),n.o=(t,e)=>Object.prototype.hasOwnProperty.call(t,e),(()=>{"use strict";var t=n(856),e=n.n(t),o=null,r=null,c=document.documentElement.scrollTop;const s=64;function l(){const t=localStorage.getItem("theme")||"auto";var e;"light"!==(e=window.matchMedia("(prefers-color-scheme: dark)").matches?"auto"===t?"light":"light"==t?"dark":"auto":"auto"===t?"dark":"dark"==t?"light":"auto")&&"dark"!==e&&"auto"!==e&&(console.error(`Got invalid theme mode: ${e}. Resetting to auto.`),e="auto"),document.body.dataset.theme=e,localStorage.setItem("theme",e),console.log(`Changed to ${e} mode.`)}function a(){!function(){const t=document.getElementsByClassName("theme-toggle");Array.from(t).forEach((t=>{t.addEventListener("click",l)}))}(),function(){let t=0,e=!1;window.addEventListener("scroll",(function(n){t=window.scrollY,e||(window.requestAnimationFrame((function(){var n;(function(t){const e=Math.floor(r.getBoundingClientRect().top);console.log(`headerTop: ${e}`),0==e&&t!=e?r.classList.add("scrolled"):r.classList.remove("scrolled")})(n=t),function(t){tc&&document.documentElement.classList.remove("show-back-to-top"),c=t}(n),function(t){null!==o&&(0==t?o.scrollTo(0,0):Math.ceil(t)>=Math.floor(document.documentElement.scrollHeight-window.innerHeight)?o.scrollTo(0,o.scrollHeight):document.querySelector(".scroll-current"))}(n),e=!1})),e=!0)})),window.scroll()}(),null!==o&&new(e())(".toc-tree a",{reflow:!0,recursive:!0,navClass:"scroll-current",offset:()=>{let t=parseFloat(getComputedStyle(document.documentElement).fontSize);return r.getBoundingClientRect().height+2.5*t+1}})}document.addEventListener("DOMContentLoaded",(function(){document.body.parentNode.classList.remove("no-js"),r=document.querySelector("header"),o=document.querySelector(".toc-scroll"),a()}))})()})(); +//# sourceMappingURL=furo.js.map \ No newline at end of file diff --git a/_static/scripts/furo.js.LICENSE.txt b/_static/scripts/furo.js.LICENSE.txt new file mode 100644 index 000000000..1632189c7 --- /dev/null +++ b/_static/scripts/furo.js.LICENSE.txt @@ -0,0 +1,7 @@ +/*! + * gumshoejs v5.1.2 (patched by @pradyunsg) + * A simple, framework-agnostic scrollspy script. + * (c) 2019 Chris Ferdinandi + * MIT License + * http://github.com/cferdinandi/gumshoe + */ diff --git a/_static/scripts/furo.js.map b/_static/scripts/furo.js.map new file mode 100644 index 000000000..80ea12b85 --- /dev/null +++ b/_static/scripts/furo.js.map @@ -0,0 +1 @@ +{"version":3,"file":"scripts/furo.js","mappings":"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","sources":["webpack:///./src/furo/assets/scripts/gumshoe-patched.js","webpack:///webpack/bootstrap","webpack:///webpack/runtime/compat get default export","webpack:///webpack/runtime/define property getters","webpack:///webpack/runtime/global","webpack:///webpack/runtime/hasOwnProperty shorthand","webpack:///./src/furo/assets/scripts/furo.js"],"sourcesContent":["/*!\n * gumshoejs v5.1.2 (patched by @pradyunsg)\n * A simple, framework-agnostic scrollspy script.\n * (c) 2019 Chris Ferdinandi\n * MIT License\n * http://github.com/cferdinandi/gumshoe\n */\n\n(function (root, factory) {\n if (typeof define === \"function\" && define.amd) {\n define([], function () {\n return factory(root);\n });\n } else if (typeof exports === \"object\") {\n module.exports = factory(root);\n } else {\n root.Gumshoe = factory(root);\n }\n})(\n typeof global !== \"undefined\"\n ? global\n : typeof window !== \"undefined\"\n ? window\n : this,\n function (window) {\n \"use strict\";\n\n //\n // Defaults\n //\n\n var defaults = {\n // Active classes\n navClass: \"active\",\n contentClass: \"active\",\n\n // Nested navigation\n nested: false,\n nestedClass: \"active\",\n\n // Offset & reflow\n offset: 0,\n reflow: false,\n\n // Event support\n events: true,\n };\n\n //\n // Methods\n //\n\n /**\n * Merge two or more objects together.\n * @param {Object} objects The objects to merge together\n * @returns {Object} Merged values of defaults and options\n */\n var extend = function () {\n var merged = {};\n Array.prototype.forEach.call(arguments, function (obj) {\n for (var key in obj) {\n if (!obj.hasOwnProperty(key)) return;\n merged[key] = obj[key];\n }\n });\n return merged;\n };\n\n /**\n * Emit a custom event\n * @param {String} type The event type\n * @param {Node} elem The element to attach the event to\n * @param {Object} detail Any details to pass along with the event\n */\n var emitEvent = function (type, elem, detail) {\n // Make sure events are enabled\n if (!detail.settings.events) return;\n\n // Create a new event\n var event = new CustomEvent(type, {\n bubbles: true,\n cancelable: true,\n detail: detail,\n });\n\n // Dispatch the event\n elem.dispatchEvent(event);\n };\n\n /**\n * Get an element's distance from the top of the Document.\n * @param {Node} elem The element\n * @return {Number} Distance from the top in pixels\n */\n var getOffsetTop = function (elem) {\n var location = 0;\n if (elem.offsetParent) {\n while (elem) {\n location += elem.offsetTop;\n elem = elem.offsetParent;\n }\n }\n return location >= 0 ? location : 0;\n };\n\n /**\n * Sort content from first to last in the DOM\n * @param {Array} contents The content areas\n */\n var sortContents = function (contents) {\n if (contents) {\n contents.sort(function (item1, item2) {\n var offset1 = getOffsetTop(item1.content);\n var offset2 = getOffsetTop(item2.content);\n if (offset1 < offset2) return -1;\n return 1;\n });\n }\n };\n\n /**\n * Get the offset to use for calculating position\n * @param {Object} settings The settings for this instantiation\n * @return {Float} The number of pixels to offset the calculations\n */\n var getOffset = function (settings) {\n // if the offset is a function run it\n if (typeof settings.offset === \"function\") {\n return parseFloat(settings.offset());\n }\n\n // Otherwise, return it as-is\n return parseFloat(settings.offset);\n };\n\n /**\n * Get the document element's height\n * @private\n * @returns {Number}\n */\n var getDocumentHeight = function () {\n return Math.max(\n document.body.scrollHeight,\n document.documentElement.scrollHeight,\n document.body.offsetHeight,\n document.documentElement.offsetHeight,\n document.body.clientHeight,\n document.documentElement.clientHeight,\n );\n };\n\n /**\n * Determine if an element is in view\n * @param {Node} elem The element\n * @param {Object} settings The settings for this instantiation\n * @param {Boolean} bottom If true, check if element is above bottom of viewport instead\n * @return {Boolean} Returns true if element is in the viewport\n */\n var isInView = function (elem, settings, bottom) {\n var bounds = elem.getBoundingClientRect();\n var offset = getOffset(settings);\n if (bottom) {\n return (\n parseInt(bounds.bottom, 10) <\n (window.innerHeight || document.documentElement.clientHeight)\n );\n }\n return parseInt(bounds.top, 10) <= offset;\n };\n\n /**\n * Check if at the bottom of the viewport\n * @return {Boolean} If true, page is at the bottom of the viewport\n */\n var isAtBottom = function () {\n if (\n Math.ceil(window.innerHeight + window.pageYOffset) >=\n getDocumentHeight()\n )\n return true;\n return false;\n };\n\n /**\n * Check if the last item should be used (even if not at the top of the page)\n * @param {Object} item The last item\n * @param {Object} settings The settings for this instantiation\n * @return {Boolean} If true, use the last item\n */\n var useLastItem = function (item, settings) {\n if (isAtBottom() && isInView(item.content, settings, true)) return true;\n return false;\n };\n\n /**\n * Get the active content\n * @param {Array} contents The content areas\n * @param {Object} settings The settings for this instantiation\n * @return {Object} The content area and matching navigation link\n */\n var getActive = function (contents, settings) {\n var last = contents[contents.length - 1];\n if (useLastItem(last, settings)) return last;\n for (var i = contents.length - 1; i >= 0; i--) {\n if (isInView(contents[i].content, settings)) return contents[i];\n }\n };\n\n /**\n * Deactivate parent navs in a nested navigation\n * @param {Node} nav The starting navigation element\n * @param {Object} settings The settings for this instantiation\n */\n var deactivateNested = function (nav, settings) {\n // If nesting isn't activated, bail\n if (!settings.nested || !nav.parentNode) return;\n\n // Get the parent navigation\n var li = nav.parentNode.closest(\"li\");\n if (!li) return;\n\n // Remove the active class\n li.classList.remove(settings.nestedClass);\n\n // Apply recursively to any parent navigation elements\n deactivateNested(li, settings);\n };\n\n /**\n * Deactivate a nav and content area\n * @param {Object} items The nav item and content to deactivate\n * @param {Object} settings The settings for this instantiation\n */\n var deactivate = function (items, settings) {\n // Make sure there are items to deactivate\n if (!items) return;\n\n // Get the parent list item\n var li = items.nav.closest(\"li\");\n if (!li) return;\n\n // Remove the active class from the nav and content\n li.classList.remove(settings.navClass);\n items.content.classList.remove(settings.contentClass);\n\n // Deactivate any parent navs in a nested navigation\n deactivateNested(li, settings);\n\n // Emit a custom event\n emitEvent(\"gumshoeDeactivate\", li, {\n link: items.nav,\n content: items.content,\n settings: settings,\n });\n };\n\n /**\n * Activate parent navs in a nested navigation\n * @param {Node} nav The starting navigation element\n * @param {Object} settings The settings for this instantiation\n */\n var activateNested = function (nav, settings) {\n // If nesting isn't activated, bail\n if (!settings.nested) return;\n\n // Get the parent navigation\n var li = nav.parentNode.closest(\"li\");\n if (!li) return;\n\n // Add the active class\n li.classList.add(settings.nestedClass);\n\n // Apply recursively to any parent navigation elements\n activateNested(li, settings);\n };\n\n /**\n * Activate a nav and content area\n * @param {Object} items The nav item and content to activate\n * @param {Object} settings The settings for this instantiation\n */\n var activate = function (items, settings) {\n // Make sure there are items to activate\n if (!items) return;\n\n // Get the parent list item\n var li = items.nav.closest(\"li\");\n if (!li) return;\n\n // Add the active class to the nav and content\n li.classList.add(settings.navClass);\n items.content.classList.add(settings.contentClass);\n\n // Activate any parent navs in a nested navigation\n activateNested(li, settings);\n\n // Emit a custom event\n emitEvent(\"gumshoeActivate\", li, {\n link: items.nav,\n content: items.content,\n settings: settings,\n });\n };\n\n /**\n * Create the Constructor object\n * @param {String} selector The selector to use for navigation items\n * @param {Object} options User options and settings\n */\n var Constructor = function (selector, options) {\n //\n // Variables\n //\n\n var publicAPIs = {};\n var navItems, contents, current, timeout, settings;\n\n //\n // Methods\n //\n\n /**\n * Set variables from DOM elements\n */\n publicAPIs.setup = function () {\n // Get all nav items\n navItems = document.querySelectorAll(selector);\n\n // Create contents array\n contents = [];\n\n // Loop through each item, get it's matching content, and push to the array\n Array.prototype.forEach.call(navItems, function (item) {\n // Get the content for the nav item\n var content = document.getElementById(\n decodeURIComponent(item.hash.substr(1)),\n );\n if (!content) return;\n\n // Push to the contents array\n contents.push({\n nav: item,\n content: content,\n });\n });\n\n // Sort contents by the order they appear in the DOM\n sortContents(contents);\n };\n\n /**\n * Detect which content is currently active\n */\n publicAPIs.detect = function () {\n // Get the active content\n var active = getActive(contents, settings);\n\n // if there's no active content, deactivate and bail\n if (!active) {\n if (current) {\n deactivate(current, settings);\n current = null;\n }\n return;\n }\n\n // If the active content is the one currently active, do nothing\n if (current && active.content === current.content) return;\n\n // Deactivate the current content and activate the new content\n deactivate(current, settings);\n activate(active, settings);\n\n // Update the currently active content\n current = active;\n };\n\n /**\n * Detect the active content on scroll\n * Debounced for performance\n */\n var scrollHandler = function (event) {\n // If there's a timer, cancel it\n if (timeout) {\n window.cancelAnimationFrame(timeout);\n }\n\n // Setup debounce callback\n timeout = window.requestAnimationFrame(publicAPIs.detect);\n };\n\n /**\n * Update content sorting on resize\n * Debounced for performance\n */\n var resizeHandler = function (event) {\n // If there's a timer, cancel it\n if (timeout) {\n window.cancelAnimationFrame(timeout);\n }\n\n // Setup debounce callback\n timeout = window.requestAnimationFrame(function () {\n sortContents(contents);\n publicAPIs.detect();\n });\n };\n\n /**\n * Destroy the current instantiation\n */\n publicAPIs.destroy = function () {\n // Undo DOM changes\n if (current) {\n deactivate(current, settings);\n }\n\n // Remove event listeners\n window.removeEventListener(\"scroll\", scrollHandler, false);\n if (settings.reflow) {\n window.removeEventListener(\"resize\", resizeHandler, false);\n }\n\n // Reset variables\n contents = null;\n navItems = null;\n current = null;\n timeout = null;\n settings = null;\n };\n\n /**\n * Initialize the current instantiation\n */\n var init = function () {\n // Merge user options into defaults\n settings = extend(defaults, options || {});\n\n // Setup variables based on the current DOM\n publicAPIs.setup();\n\n // Find the currently active content\n publicAPIs.detect();\n\n // Setup event listeners\n window.addEventListener(\"scroll\", scrollHandler, false);\n if (settings.reflow) {\n window.addEventListener(\"resize\", resizeHandler, false);\n }\n };\n\n //\n // Initialize and return the public APIs\n //\n\n init();\n return publicAPIs;\n };\n\n //\n // Return the Constructor\n //\n\n return Constructor;\n },\n);\n","// The module cache\nvar __webpack_module_cache__ = {};\n\n// The require function\nfunction __webpack_require__(moduleId) {\n\t// Check if module is in cache\n\tvar cachedModule = __webpack_module_cache__[moduleId];\n\tif (cachedModule !== undefined) {\n\t\treturn cachedModule.exports;\n\t}\n\t// Create a new module (and put it into the cache)\n\tvar module = __webpack_module_cache__[moduleId] = {\n\t\t// no module.id needed\n\t\t// no module.loaded needed\n\t\texports: {}\n\t};\n\n\t// Execute the module function\n\t__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n\t// Return the exports of the module\n\treturn module.exports;\n}\n\n","// getDefaultExport function for compatibility with non-harmony modules\n__webpack_require__.n = (module) => {\n\tvar getter = module && module.__esModule ?\n\t\t() => (module['default']) :\n\t\t() => (module);\n\t__webpack_require__.d(getter, { a: getter });\n\treturn getter;\n};","// define getter functions for harmony exports\n__webpack_require__.d = (exports, definition) => {\n\tfor(var key in definition) {\n\t\tif(__webpack_require__.o(definition, key) && !__webpack_require__.o(exports, key)) {\n\t\t\tObject.defineProperty(exports, key, { enumerable: true, get: definition[key] });\n\t\t}\n\t}\n};","__webpack_require__.g = (function() {\n\tif (typeof globalThis === 'object') return globalThis;\n\ttry {\n\t\treturn this || new Function('return this')();\n\t} catch (e) {\n\t\tif (typeof window === 'object') return window;\n\t}\n})();","__webpack_require__.o = (obj, prop) => (Object.prototype.hasOwnProperty.call(obj, prop))","import Gumshoe from \"./gumshoe-patched.js\";\n\n////////////////////////////////////////////////////////////////////////////////\n// Scroll Handling\n////////////////////////////////////////////////////////////////////////////////\nvar tocScroll = null;\nvar header = null;\nvar lastScrollTop = document.documentElement.scrollTop;\nconst GO_TO_TOP_OFFSET = 64;\n\nfunction scrollHandlerForHeader(positionY) {\n const headerTop = Math.floor(header.getBoundingClientRect().top);\n\n console.log(`headerTop: ${headerTop}`);\n if (headerTop == 0 && positionY != headerTop) {\n header.classList.add(\"scrolled\");\n } else {\n header.classList.remove(\"scrolled\");\n }\n}\n\nfunction scrollHandlerForBackToTop(positionY) {\n if (positionY < GO_TO_TOP_OFFSET) {\n document.documentElement.classList.remove(\"show-back-to-top\");\n } else {\n if (positionY < lastScrollTop) {\n document.documentElement.classList.add(\"show-back-to-top\");\n } else if (positionY > lastScrollTop) {\n document.documentElement.classList.remove(\"show-back-to-top\");\n }\n }\n lastScrollTop = positionY;\n}\n\nfunction scrollHandlerForTOC(positionY) {\n if (tocScroll === null) {\n return;\n }\n\n // top of page.\n if (positionY == 0) {\n tocScroll.scrollTo(0, 0);\n } else if (\n // bottom of page.\n Math.ceil(positionY) >=\n Math.floor(document.documentElement.scrollHeight - window.innerHeight)\n ) {\n tocScroll.scrollTo(0, tocScroll.scrollHeight);\n } else {\n // somewhere in the middle.\n const current = document.querySelector(\".scroll-current\");\n if (current == null) {\n return;\n }\n\n // https://github.com/pypa/pip/issues/9159 This breaks scroll behaviours.\n // // scroll the currently \"active\" heading in toc, into view.\n // const rect = current.getBoundingClientRect();\n // if (0 > rect.top) {\n // current.scrollIntoView(true); // the argument is \"alignTop\"\n // } else if (rect.bottom > window.innerHeight) {\n // current.scrollIntoView(false);\n // }\n }\n}\n\nfunction scrollHandler(positionY) {\n scrollHandlerForHeader(positionY);\n scrollHandlerForBackToTop(positionY);\n scrollHandlerForTOC(positionY);\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Theme Toggle\n////////////////////////////////////////////////////////////////////////////////\nfunction setTheme(mode) {\n if (mode !== \"light\" && mode !== \"dark\" && mode !== \"auto\") {\n console.error(`Got invalid theme mode: ${mode}. Resetting to auto.`);\n mode = \"auto\";\n }\n\n document.body.dataset.theme = mode;\n localStorage.setItem(\"theme\", mode);\n console.log(`Changed to ${mode} mode.`);\n}\n\nfunction cycleThemeOnce() {\n const currentTheme = localStorage.getItem(\"theme\") || \"auto\";\n const prefersDark = window.matchMedia(\"(prefers-color-scheme: dark)\").matches;\n\n if (prefersDark) {\n // Auto (dark) -> Light -> Dark\n if (currentTheme === \"auto\") {\n setTheme(\"light\");\n } else if (currentTheme == \"light\") {\n setTheme(\"dark\");\n } else {\n setTheme(\"auto\");\n }\n } else {\n // Auto (light) -> Dark -> Light\n if (currentTheme === \"auto\") {\n setTheme(\"dark\");\n } else if (currentTheme == \"dark\") {\n setTheme(\"light\");\n } else {\n setTheme(\"auto\");\n }\n }\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Setup\n////////////////////////////////////////////////////////////////////////////////\nfunction setupScrollHandler() {\n // Taken from https://developer.mozilla.org/en-US/docs/Web/API/Document/scroll_event\n let last_known_scroll_position = 0;\n let ticking = false;\n\n window.addEventListener(\"scroll\", function (e) {\n last_known_scroll_position = window.scrollY;\n\n if (!ticking) {\n window.requestAnimationFrame(function () {\n scrollHandler(last_known_scroll_position);\n ticking = false;\n });\n\n ticking = true;\n }\n });\n window.scroll();\n}\n\nfunction setupScrollSpy() {\n if (tocScroll === null) {\n return;\n }\n\n // Scrollspy -- highlight table on contents, based on scroll\n new Gumshoe(\".toc-tree a\", {\n reflow: true,\n recursive: true,\n navClass: \"scroll-current\",\n offset: () => {\n let rem = parseFloat(getComputedStyle(document.documentElement).fontSize);\n return header.getBoundingClientRect().height + 2.5 * rem + 1;\n },\n });\n}\n\nfunction setupTheme() {\n // Attach event handlers for toggling themes\n const buttons = document.getElementsByClassName(\"theme-toggle\");\n Array.from(buttons).forEach((btn) => {\n btn.addEventListener(\"click\", cycleThemeOnce);\n });\n}\n\nfunction setup() {\n setupTheme();\n setupScrollHandler();\n setupScrollSpy();\n}\n\n////////////////////////////////////////////////////////////////////////////////\n// Main entrypoint\n////////////////////////////////////////////////////////////////////////////////\nfunction main() {\n document.body.parentNode.classList.remove(\"no-js\");\n\n header = document.querySelector(\"header\");\n tocScroll = document.querySelector(\".toc-scroll\");\n\n setup();\n}\n\ndocument.addEventListener(\"DOMContentLoaded\", main);\n"],"names":["root","g","window","this","defaults","navClass","contentClass","nested","nestedClass","offset","reflow","events","emitEvent","type","elem","detail","settings","event","CustomEvent","bubbles","cancelable","dispatchEvent","getOffsetTop","location","offsetParent","offsetTop","sortContents","contents","sort","item1","item2","content","isInView","bottom","bounds","getBoundingClientRect","parseFloat","getOffset","parseInt","innerHeight","document","documentElement","clientHeight","top","isAtBottom","Math","ceil","pageYOffset","max","body","scrollHeight","offsetHeight","getActive","last","length","item","useLastItem","i","deactivateNested","nav","parentNode","li","closest","classList","remove","deactivate","items","link","activateNested","add","selector","options","navItems","current","timeout","publicAPIs","querySelectorAll","Array","prototype","forEach","call","getElementById","decodeURIComponent","hash","substr","push","active","activate","scrollHandler","cancelAnimationFrame","requestAnimationFrame","detect","resizeHandler","destroy","removeEventListener","merged","arguments","obj","key","hasOwnProperty","extend","setup","addEventListener","factory","__webpack_module_cache__","__webpack_require__","moduleId","cachedModule","undefined","exports","module","__webpack_modules__","n","getter","__esModule","d","a","definition","o","Object","defineProperty","enumerable","get","globalThis","Function","e","prop","tocScroll","header","lastScrollTop","scrollTop","GO_TO_TOP_OFFSET","cycleThemeOnce","currentTheme","localStorage","getItem","mode","matchMedia","matches","console","error","dataset","theme","setItem","log","buttons","getElementsByClassName","from","btn","setupTheme","last_known_scroll_position","ticking","scrollY","positionY","headerTop","floor","scrollHandlerForHeader","scrollHandlerForBackToTop","scrollTo","querySelector","scrollHandlerForTOC","scroll","setupScrollHandler","recursive","rem","getComputedStyle","fontSize","height"],"sourceRoot":""} \ No newline at end of file diff --git a/_static/searchtools.js b/_static/searchtools.js new file mode 100644 index 000000000..2c774d17a --- /dev/null +++ b/_static/searchtools.js @@ -0,0 +1,632 @@ +/* + * Sphinx JavaScript utilities for the full-text search. + */ +"use strict"; + +/** + * Simple result scoring code. + */ +if (typeof Scorer === "undefined") { + var Scorer = { + // Implement the following function to further tweak the score for each result + // The function takes a result array [docname, title, anchor, descr, score, filename] + // and returns the new score. + /* + score: result => { + const [docname, title, anchor, descr, score, filename, kind] = result + return score + }, + */ + + // query matches the full name of an object + objNameMatch: 11, + // or matches in the last dotted part of the object name + objPartialMatch: 6, + // Additive scores depending on the priority of the object + objPrio: { + 0: 15, // used to be importantResults + 1: 5, // used to be objectResults + 2: -5, // used to be unimportantResults + }, + // Used when the priority is not in the mapping. + objPrioDefault: 0, + + // query found in title + title: 15, + partialTitle: 7, + // query found in terms + term: 5, + partialTerm: 2, + }; +} + +// Global search result kind enum, used by themes to style search results. +class SearchResultKind { + static get index() { return "index"; } + static get object() { return "object"; } + static get text() { return "text"; } + static get title() { return "title"; } +} + +const _removeChildren = (element) => { + while (element && element.lastChild) element.removeChild(element.lastChild); +}; + +/** + * See https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Regular_Expressions#escaping + */ +const _escapeRegExp = (string) => + string.replace(/[.*+\-?^${}()|[\]\\]/g, "\\$&"); // $& means the whole matched string + +const _displayItem = (item, searchTerms, highlightTerms) => { + const docBuilder = DOCUMENTATION_OPTIONS.BUILDER; + 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, kind] = item; + + let listItem = document.createElement("li"); + // Add a class representing the item's type: + // can be used by a theme's CSS selector for styling + // See SearchResultKind for the class names. + listItem.classList.add(`kind-${kind}`); + let requestUrl; + let linkUrl; + if (docBuilder === "dirhtml") { + // dirhtml builder + let dirname = docName + "/"; + if (dirname.match(/\/index\/$/)) + dirname = dirname.substring(0, dirname.length - 6); + else if (dirname === "index/") dirname = ""; + requestUrl = contentRoot + dirname; + linkUrl = requestUrl; + } else { + // normal html builders + 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) { + 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()) + .then((data) => { + if (data) + listItem.appendChild( + Search.makeSearchSummary(data, searchTerms, anchor) + ); + // 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); +}; +const _finishSearch = (resultCount) => { + Search.stopPulse(); + Search.title.innerText = _("Search Results"); + if (!resultCount) + Search.status.innerText = Documentation.gettext( + "Your search did not match any documents. Please make sure that all words are spelled correctly and that you've selected enough categories." + ); + else + Search.status.innerText = Documentation.ngettext( + "Search finished, found one page matching the search query.", + "Search finished, found ${resultCount} pages matching the search query.", + resultCount, + ).replace('${resultCount}', resultCount); +}; +const _displayNextItem = ( + results, + resultCount, + 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, highlightTerms); + setTimeout( + () => _displayNextItem(results, resultCount, searchTerms, highlightTerms), + 5 + ); + } + // search finished, update title and status message + else _finishSearch(resultCount); +}; +// Helper function used by query() to order search results. +// Each input is an array of [docname, title, anchor, descr, score, filename, kind]. +// Order the results by score (in opposite order of appearance, since the +// `_displayNextItem` function uses pop() to retrieve items) and then alphabetically. +const _orderResultsByScoreThenName = (a, b) => { + const leftScore = a[4]; + const rightScore = b[4]; + if (leftScore === rightScore) { + // same score: sort alphabetically + const leftTitle = a[1].toLowerCase(); + const rightTitle = b[1].toLowerCase(); + if (leftTitle === rightTitle) return 0; + return leftTitle > rightTitle ? -1 : 1; // inverted is intentional + } + return leftScore > rightScore ? 1 : -1; +}; + +/** + * Default splitQuery function. Can be overridden in ``sphinx.search`` with a + * custom function per language. + * + * The regular expression works by splitting the string on consecutive characters + * that are not Unicode letters, numbers, underscores, or emoji characters. + * This is the same as ``\W+`` in Python, preserving the surrogate pair area. + */ +if (typeof splitQuery === "undefined") { + var splitQuery = (query) => query + .split(/[^\p{Letter}\p{Number}_\p{Emoji_Presentation}]+/gu) + .filter(term => term) // remove remaining empty strings +} + +/** + * Search Module + */ +const Search = { + _index: null, + _queued_query: null, + _pulse_status: -1, + + htmlToText: (htmlString, anchor) => { + const htmlElement = new DOMParser().parseFromString(htmlString, 'text/html'); + for (const removalQuery of [".headerlink", "script", "style"]) { + htmlElement.querySelectorAll(removalQuery).forEach((el) => { el.remove() }); + } + if (anchor) { + const anchorContent = htmlElement.querySelector(`[role="main"] ${anchor}`); + if (anchorContent) return anchorContent.textContent; + + console.warn( + `Anchored content block not found. Sphinx search tries to obtain it via DOM query '[role=main] ${anchor}'. Check your theme or template.` + ); + } + + // if anchor not specified or not found, fall back to main content + const docContent = htmlElement.querySelector('[role="main"]'); + if (docContent) return docContent.textContent; + + console.warn( + "Content block not found. Sphinx search tries to obtain it via DOM query '[role=main]'. Check your theme or template." + ); + return ""; + }, + + init: () => { + const query = new URLSearchParams(window.location.search).get("q"); + document + .querySelectorAll('input[name="q"]') + .forEach((el) => (el.value = query)); + if (query) Search.performSearch(query); + }, + + loadIndex: (url) => + (document.body.appendChild(document.createElement("script")).src = url), + + setIndex: (index) => { + Search._index = index; + if (Search._queued_query !== null) { + const query = Search._queued_query; + Search._queued_query = null; + Search.query(query); + } + }, + + hasIndex: () => Search._index !== null, + + deferQuery: (query) => (Search._queued_query = query), + + stopPulse: () => (Search._pulse_status = -1), + + startPulse: () => { + if (Search._pulse_status >= 0) return; + + const pulse = () => { + Search._pulse_status = (Search._pulse_status + 1) % 4; + Search.dots.innerText = ".".repeat(Search._pulse_status); + if (Search._pulse_status >= 0) window.setTimeout(pulse, 500); + }; + pulse(); + }, + + /** + * perform a search for something (or wait until index is loaded) + */ + performSearch: (query) => { + // create the required interface elements + const searchText = document.createElement("h2"); + searchText.textContent = _("Searching"); + const searchSummary = document.createElement("p"); + searchSummary.classList.add("search-summary"); + searchSummary.innerText = ""; + const searchList = document.createElement("ul"); + searchList.setAttribute("role", "list"); + searchList.classList.add("search"); + + const out = document.getElementById("search-results"); + Search.title = out.appendChild(searchText); + Search.dots = Search.title.appendChild(document.createElement("span")); + Search.status = out.appendChild(searchSummary); + Search.output = out.appendChild(searchList); + + const searchProgress = document.getElementById("search-progress"); + // Some themes don't use the search progress node + if (searchProgress) { + searchProgress.innerText = _("Preparing search..."); + } + Search.startPulse(); + + // index already loaded, the browser was quick! + if (Search.hasIndex()) Search.query(query); + else Search.deferQuery(query); + }, + + _parseQuery: (query) => { + // stem the search terms and add them to the correct list + const stemmer = new Stemmer(); + const searchTerms = new Set(); + const excludedTerms = new Set(); + const highlightTerms = new Set(); + const objectTerms = new Set(splitQuery(query.toLowerCase().trim())); + splitQuery(query.trim()).forEach((queryTerm) => { + const queryTermLower = queryTerm.toLowerCase(); + + // maybe skip this "word" + // stopwords array is from language_data.js + if ( + stopwords.indexOf(queryTermLower) !== -1 || + queryTerm.match(/^\d+$/) + ) + return; + + // stem the word + let word = stemmer.stemWord(queryTermLower); + // select the correct list + if (word[0] === "-") excludedTerms.add(word.substr(1)); + else { + searchTerms.add(word); + highlightTerms.add(queryTermLower); + } + }); + + if (SPHINX_HIGHLIGHT_ENABLED) { // set in sphinx_highlight.js + localStorage.setItem("sphinx_highlight_terms", [...highlightTerms].join(" ")) + } + + // console.debug("SEARCH: searching for:"); + // console.info("required: ", [...searchTerms]); + // console.info("excluded: ", [...excludedTerms]); + + return [query, searchTerms, excludedTerms, highlightTerms, objectTerms]; + }, + + /** + * execute search (requires search index to be loaded) + */ + _performSearch: (query, searchTerms, excludedTerms, highlightTerms, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + const allTitles = Search._index.alltitles; + const indexEntries = Search._index.indexentries; + + // Collect multiple result groups to be sorted separately and then ordered. + // Each is an array of [docname, title, anchor, descr, score, filename, kind]. + const normalResults = []; + const nonMainIndexResults = []; + + _removeChildren(document.getElementById("search-progress")); + + const queryLower = query.toLowerCase().trim(); + for (const [title, foundTitles] of Object.entries(allTitles)) { + if (title.toLowerCase().trim().includes(queryLower) && (queryLower.length >= title.length/2)) { + for (const [file, id] of foundTitles) { + const score = Math.round(Scorer.title * queryLower.length / title.length); + const boost = titles[file] === title ? 1 : 0; // add a boost for document titles + normalResults.push([ + docNames[file], + titles[file] !== title ? `${titles[file]} > ${title}` : title, + id !== null ? "#" + id : "", + null, + score + boost, + filenames[file], + SearchResultKind.title, + ]); + } + } + } + + // search for explicit entries in index directives + for (const [entry, foundEntries] of Object.entries(indexEntries)) { + if (entry.includes(queryLower) && (queryLower.length >= entry.length/2)) { + for (const [file, id, isMain] of foundEntries) { + const score = Math.round(100 * queryLower.length / entry.length); + const result = [ + docNames[file], + titles[file], + id ? "#" + id : "", + null, + score, + filenames[file], + SearchResultKind.index, + ]; + if (isMain) { + normalResults.push(result); + } else { + nonMainIndexResults.push(result); + } + } + } + } + + // lookup as object + objectTerms.forEach((term) => + normalResults.push(...Search.performObjectSearch(term, objectTerms)) + ); + + // lookup as search terms in fulltext + normalResults.push(...Search.performTermsSearch(searchTerms, excludedTerms)); + + // let the scorer override scores with a custom scoring function + if (Scorer.score) { + normalResults.forEach((item) => (item[4] = Scorer.score(item))); + nonMainIndexResults.forEach((item) => (item[4] = Scorer.score(item))); + } + + // Sort each group of results by score and then alphabetically by name. + normalResults.sort(_orderResultsByScoreThenName); + nonMainIndexResults.sort(_orderResultsByScoreThenName); + + // Combine the result groups in (reverse) order. + // Non-main index entries are typically arbitrary cross-references, + // so display them after other results. + let results = [...nonMainIndexResults, ...normalResults]; + + // remove duplicate search results + // note the reversing of results, so that in the case of duplicates, the highest-scoring entry is kept + let seen = new Set(); + results = results.reverse().reduce((acc, result) => { + let resultStr = result.slice(0, 4).concat([result[5]]).map(v => String(v)).join(','); + if (!seen.has(resultStr)) { + acc.push(result); + seen.add(resultStr); + } + return acc; + }, []); + + return results.reverse(); + }, + + query: (query) => { + const [searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms] = Search._parseQuery(query); + const results = Search._performSearch(searchQuery, searchTerms, excludedTerms, highlightTerms, objectTerms); + + // for debugging + //Search.lastresults = results.slice(); // a copy + // console.info("search results:", Search.lastresults); + + // print the results + _displayNextItem(results, results.length, searchTerms, highlightTerms); + }, + + /** + * search for object names + */ + performObjectSearch: (object, objectTerms) => { + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const objects = Search._index.objects; + const objNames = Search._index.objnames; + const titles = Search._index.titles; + + const results = []; + + const objectSearchCallback = (prefix, match) => { + const name = match[4] + const fullname = (prefix ? prefix + "." : "") + name; + const fullnameLower = fullname.toLowerCase(); + if (fullnameLower.indexOf(object) < 0) return; + + let score = 0; + const parts = fullnameLower.split("."); + + // check for different match types: exact matches of full name or + // "last name" (i.e. last dotted part) + if (fullnameLower === object || parts.slice(-1)[0] === object) + score += Scorer.objNameMatch; + else if (parts.slice(-1)[0].indexOf(object) > -1) + score += Scorer.objPartialMatch; // matches in last name + + const objName = objNames[match[1]][2]; + const title = titles[match[0]]; + + // If more than one term searched for, we require other words to be + // found in the name/title/description + const otherTerms = new Set(objectTerms); + otherTerms.delete(object); + if (otherTerms.size > 0) { + const haystack = `${prefix} ${name} ${objName} ${title}`.toLowerCase(); + if ( + [...otherTerms].some((otherTerm) => haystack.indexOf(otherTerm) < 0) + ) + return; + } + + let anchor = match[3]; + if (anchor === "") anchor = fullname; + else if (anchor === "-") anchor = objNames[match[1]][1] + "-" + fullname; + + const descr = objName + _(", in ") + title; + + // add custom score for some objects according to scorer + if (Scorer.objPrio.hasOwnProperty(match[2])) + score += Scorer.objPrio[match[2]]; + else score += Scorer.objPrioDefault; + + results.push([ + docNames[match[0]], + fullname, + "#" + anchor, + descr, + score, + filenames[match[0]], + SearchResultKind.object, + ]); + }; + Object.keys(objects).forEach((prefix) => + objects[prefix].forEach((array) => + objectSearchCallback(prefix, array) + ) + ); + return results; + }, + + /** + * search for full-text terms in the index + */ + performTermsSearch: (searchTerms, excludedTerms) => { + // prepare search + const terms = Search._index.terms; + const titleTerms = Search._index.titleterms; + const filenames = Search._index.filenames; + const docNames = Search._index.docnames; + const titles = Search._index.titles; + + const scoreMap = new Map(); + const fileMap = new Map(); + + // perform the search on the required terms + searchTerms.forEach((word) => { + const files = []; + const arr = [ + { files: terms[word], score: Scorer.term }, + { files: titleTerms[word], score: Scorer.title }, + ]; + // add support for partial matches + if (word.length > 2) { + const escapedWord = _escapeRegExp(word); + if (!terms.hasOwnProperty(word)) { + Object.keys(terms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: terms[term], score: Scorer.partialTerm }); + }); + } + if (!titleTerms.hasOwnProperty(word)) { + Object.keys(titleTerms).forEach((term) => { + if (term.match(escapedWord)) + arr.push({ files: titleTerms[term], score: Scorer.partialTitle }); + }); + } + } + + // no match but word was a required one + if (arr.every((record) => record.files === undefined)) return; + + // found search word in contents + arr.forEach((record) => { + if (record.files === undefined) return; + + let recordFiles = record.files; + if (recordFiles.length === undefined) recordFiles = [recordFiles]; + files.push(...recordFiles); + + // set score for the word in each file + recordFiles.forEach((file) => { + if (!scoreMap.has(file)) scoreMap.set(file, {}); + scoreMap.get(file)[word] = record.score; + }); + }); + + // create the mapping + files.forEach((file) => { + if (!fileMap.has(file)) fileMap.set(file, [word]); + else if (fileMap.get(file).indexOf(word) === -1) fileMap.get(file).push(word); + }); + }); + + // now check if the files don't contain excluded terms + const results = []; + for (const [file, wordList] of fileMap) { + // check if all requirements are matched + + // as search terms with length < 3 are discarded + const filteredTermCount = [...searchTerms].filter( + (term) => term.length > 2 + ).length; + if ( + wordList.length !== searchTerms.size && + wordList.length !== filteredTermCount + ) + continue; + + // ensure that none of the excluded terms is in the search result + if ( + [...excludedTerms].some( + (term) => + terms[term] === file || + titleTerms[term] === file || + (terms[term] || []).includes(file) || + (titleTerms[term] || []).includes(file) + ) + ) + break; + + // select one (max) score for the file. + const score = Math.max(...wordList.map((w) => scoreMap.get(file)[w])); + // add result to the result list + results.push([ + docNames[file], + titles[file], + "", + null, + score, + filenames[file], + SearchResultKind.text, + ]); + } + return results; + }, + + /** + * helper function to return a node containing the + * search summary for a given text. keywords is a list + * of stemmed words. + */ + makeSearchSummary: (htmlText, keywords, anchor) => { + const text = Search.htmlToText(htmlText, anchor); + if (text === "") return null; + + const textLower = text.toLowerCase(); + const actualStartPosition = [...keywords] + .map((k) => textLower.indexOf(k.toLowerCase())) + .filter((i) => i > -1) + .slice(-1)[0]; + const startWithContext = Math.max(actualStartPosition - 120, 0); + + const top = startWithContext === 0 ? "" : "..."; + const tail = startWithContext + 240 < text.length ? "..." : ""; + + let summary = document.createElement("p"); + summary.classList.add("context"); + summary.textContent = top + text.substr(startWithContext, 240).trim() + tail; + + return summary; + }, +}; + +_ready(Search.init); diff --git a/_static/skeleton.css b/_static/skeleton.css new file mode 100644 index 000000000..467c878c6 --- /dev/null +++ b/_static/skeleton.css @@ -0,0 +1,296 @@ +/* Some sane resets. */ +html { + height: 100%; +} + +body { + margin: 0; + min-height: 100%; +} + +/* All the flexbox magic! */ +body, +.sb-announcement, +.sb-content, +.sb-main, +.sb-container, +.sb-container__inner, +.sb-article-container, +.sb-footer-content, +.sb-header, +.sb-header-secondary, +.sb-footer { + display: flex; +} + +/* These order things vertically */ +body, +.sb-main, +.sb-article-container { + flex-direction: column; +} + +/* Put elements in the center */ +.sb-header, +.sb-header-secondary, +.sb-container, +.sb-content, +.sb-footer, +.sb-footer-content { + justify-content: center; +} +/* Put elements at the ends */ +.sb-article-container { + justify-content: space-between; +} + +/* These elements grow. */ +.sb-main, +.sb-content, +.sb-container, +article { + flex-grow: 1; +} + +/* Because padding making this wider is not fun */ +article { + box-sizing: border-box; +} + +/* The announcements element should never be wider than the page. */ +.sb-announcement { + max-width: 100%; +} + +.sb-sidebar-primary, +.sb-sidebar-secondary { + flex-shrink: 0; + width: 17rem; +} + +.sb-announcement__inner { + justify-content: center; + + box-sizing: border-box; + height: 3rem; + + overflow-x: auto; + white-space: nowrap; +} + +/* Sidebars, with checkbox-based toggle */ +.sb-sidebar-primary, +.sb-sidebar-secondary { + position: fixed; + height: 100%; + top: 0; +} + +.sb-sidebar-primary { + left: -17rem; + transition: left 250ms ease-in-out; +} +.sb-sidebar-secondary { + right: -17rem; + transition: right 250ms ease-in-out; +} + +.sb-sidebar-toggle { + display: none; +} +.sb-sidebar-overlay { + position: fixed; + top: 0; + width: 0; + height: 0; + + transition: width 0ms ease 250ms, height 0ms ease 250ms, opacity 250ms ease; + + opacity: 0; + background-color: rgba(0, 0, 0, 0.54); +} + +#sb-sidebar-toggle--primary:checked + ~ .sb-sidebar-overlay[for="sb-sidebar-toggle--primary"], +#sb-sidebar-toggle--secondary:checked + ~ .sb-sidebar-overlay[for="sb-sidebar-toggle--secondary"] { + width: 100%; + height: 100%; + opacity: 1; + transition: width 0ms ease, height 0ms ease, opacity 250ms ease; +} + +#sb-sidebar-toggle--primary:checked ~ .sb-container .sb-sidebar-primary { + left: 0; +} +#sb-sidebar-toggle--secondary:checked ~ .sb-container .sb-sidebar-secondary { + right: 0; +} + +/* Full-width mode */ +.drop-secondary-sidebar-for-full-width-content + .hide-when-secondary-sidebar-shown { + display: none !important; +} +.drop-secondary-sidebar-for-full-width-content .sb-sidebar-secondary { + display: none !important; +} + +/* Mobile views */ +.sb-page-width { + width: 100%; +} + +.sb-article-container, +.sb-footer-content__inner, +.drop-secondary-sidebar-for-full-width-content .sb-article, +.drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 100vw; +} + +.sb-article, +.match-content-width { + padding: 0 1rem; + box-sizing: border-box; +} + +@media (min-width: 32rem) { + .sb-article, + .match-content-width { + padding: 0 2rem; + } +} + +/* Tablet views */ +@media (min-width: 42rem) { + .sb-article-container { + width: auto; + } + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 42rem; + } + .sb-article, + .match-content-width { + width: 42rem; + } +} +@media (min-width: 46rem) { + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 46rem; + } + .sb-article, + .match-content-width { + width: 46rem; + } +} +@media (min-width: 50rem) { + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 50rem; + } + .sb-article, + .match-content-width { + width: 50rem; + } +} + +/* Tablet views */ +@media (min-width: 59rem) { + .sb-sidebar-secondary { + position: static; + } + .hide-when-secondary-sidebar-shown { + display: none !important; + } + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 59rem; + } + .sb-article, + .match-content-width { + width: 42rem; + } +} +@media (min-width: 63rem) { + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 63rem; + } + .sb-article, + .match-content-width { + width: 46rem; + } +} +@media (min-width: 67rem) { + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 67rem; + } + .sb-article, + .match-content-width { + width: 50rem; + } +} + +/* Desktop views */ +@media (min-width: 76rem) { + .sb-sidebar-primary { + position: static; + } + .hide-when-primary-sidebar-shown { + display: none !important; + } + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 59rem; + } + .sb-article, + .match-content-width { + width: 42rem; + } +} + +/* Full desktop views */ +@media (min-width: 80rem) { + .sb-article, + .match-content-width { + width: 46rem; + } + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 63rem; + } +} + +@media (min-width: 84rem) { + .sb-article, + .match-content-width { + width: 50rem; + } + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 67rem; + } +} + +@media (min-width: 88rem) { + .sb-footer-content__inner, + .drop-secondary-sidebar-for-full-width-content .sb-article, + .drop-secondary-sidebar-for-full-width-content .match-content-width { + width: 67rem; + } + .sb-page-width { + width: 88rem; + } +} diff --git a/_static/sphinx_highlight.js b/_static/sphinx_highlight.js new file mode 100644 index 000000000..8a96c69a1 --- /dev/null +++ b/_static/sphinx_highlight.js @@ -0,0 +1,154 @@ +/* Highlighting utilities for Sphinx HTML documentation. */ +"use strict"; + +const SPHINX_HIGHLIGHT_ENABLED = true + +/** + * highlight a given string on a node by wrapping it in + * span elements with the given class name. + */ +const _highlight = (node, addItems, text, className) => { + if (node.nodeType === Node.TEXT_NODE) { + const val = node.nodeValue; + const parent = node.parentNode; + const pos = val.toLowerCase().indexOf(text); + if ( + pos >= 0 && + !parent.classList.contains(className) && + !parent.classList.contains("nohighlight") + ) { + let span; + + const closestNode = parent.closest("body, svg, foreignObject"); + const isInSVG = closestNode && closestNode.matches("svg"); + if (isInSVG) { + span = document.createElementNS("http://www.w3.org/2000/svg", "tspan"); + } else { + span = document.createElement("span"); + span.classList.add(className); + } + + span.appendChild(document.createTextNode(val.substr(pos, text.length))); + const rest = document.createTextNode(val.substr(pos + text.length)); + parent.insertBefore( + span, + parent.insertBefore( + 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( + "http://www.w3.org/2000/svg", + "rect" + ); + const bbox = parent.getBBox(); + rect.x.baseVal.value = bbox.x; + rect.y.baseVal.value = bbox.y; + rect.width.baseVal.value = bbox.width; + rect.height.baseVal.value = bbox.height; + rect.setAttribute("class", className); + addItems.push({ parent: parent, target: rect }); + } + } + } else if (node.matches && !node.matches("button, select, textarea")) { + node.childNodes.forEach((el) => _highlight(el, addItems, text, className)); + } +}; +const _highlightText = (thisNode, text, className) => { + let addItems = []; + _highlight(thisNode, addItems, text, className); + addItems.forEach((obj) => + obj.parent.insertAdjacentElement("beforebegin", obj.target) + ); +}; + +/** + * Small JavaScript module for the documentation. + */ +const SphinxHighlight = { + + /** + * highlight the search words provided in localstorage in the text + */ + highlightSearchWords: () => { + if (!SPHINX_HIGHLIGHT_ENABLED) return; // bail if no highlight + + // get and clear terms from localstorage + const url = new URL(window.location); + const highlight = + localStorage.getItem("sphinx_highlight_terms") + || url.searchParams.get("highlight") + || ""; + localStorage.removeItem("sphinx_highlight_terms") + url.searchParams.delete("highlight"); + window.history.replaceState({}, "", url); + + // get individual terms from highlight string + const terms = highlight.toLowerCase().split(/\s+/).filter(x => x); + if (terms.length === 0) return; // nothing to do + + // There should never be more than one element matching "div.body" + const divBody = document.querySelectorAll("div.body"); + const body = divBody.length ? divBody[0] : document.querySelector("body"); + window.setTimeout(() => { + terms.forEach((term) => _highlightText(body, term, "highlighted")); + }, 10); + + const searchBox = document.getElementById("searchbox"); + if (searchBox === null) return; + searchBox.appendChild( + document + .createRange() + .createContextualFragment( + '" + ) + ); + }, + + /** + * helper function to hide the search marks again + */ + hideSearchWords: () => { + document + .querySelectorAll("#searchbox .highlight-link") + .forEach((el) => el.remove()); + document + .querySelectorAll("span.highlighted") + .forEach((el) => el.classList.remove("highlighted")); + localStorage.removeItem("sphinx_highlight_terms") + }, + + initEscapeListener: () => { + // only install a listener if it is really needed + if (!DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS) return; + + document.addEventListener("keydown", (event) => { + // bail for input elements + if (BLACKLISTED_KEY_CONTROL_ELEMENTS.has(document.activeElement.tagName)) return; + // bail with special keys + if (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey) return; + if (DOCUMENTATION_OPTIONS.ENABLE_SEARCH_SHORTCUTS && (event.key === "Escape")) { + SphinxHighlight.hideSearchWords(); + event.preventDefault(); + } + }); + }, +}; + +_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-extensions.css b/_static/styles/furo-extensions.css new file mode 100644 index 000000000..822958761 --- /dev/null +++ b/_static/styles/furo-extensions.css @@ -0,0 +1,2 @@ +#furo-sidebar-ad-placement{padding:var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal)}#furo-sidebar-ad-placement .ethical-sidebar{background:var(--color-background-secondary);border:none;box-shadow:none}#furo-sidebar-ad-placement .ethical-sidebar:hover{background:var(--color-background-hover)}#furo-sidebar-ad-placement .ethical-sidebar a{color:var(--color-foreground-primary)}#furo-sidebar-ad-placement .ethical-callout a{color:var(--color-foreground-secondary)!important}#furo-readthedocs-versions{background:transparent;display:block;position:static;width:100%}#furo-readthedocs-versions .rst-versions{background:#1a1c1e}#furo-readthedocs-versions .rst-current-version{background:var(--color-sidebar-item-background);cursor:unset}#furo-readthedocs-versions .rst-current-version:hover{background:var(--color-sidebar-item-background)}#furo-readthedocs-versions .rst-current-version .fa-book{color:var(--color-foreground-primary)}#furo-readthedocs-versions>.rst-other-versions{padding:0}#furo-readthedocs-versions>.rst-other-versions small{opacity:1}#furo-readthedocs-versions .injected .rst-versions{position:unset}#furo-readthedocs-versions:focus-within,#furo-readthedocs-versions:hover{box-shadow:0 0 0 1px var(--color-sidebar-background-border)}#furo-readthedocs-versions:focus-within .rst-current-version,#furo-readthedocs-versions:hover .rst-current-version{background:#1a1c1e;font-size:inherit;height:auto;line-height:inherit;padding:12px;text-align:right}#furo-readthedocs-versions:focus-within .rst-current-version .fa-book,#furo-readthedocs-versions:hover .rst-current-version .fa-book{color:#fff;float:left}#furo-readthedocs-versions:focus-within .fa-caret-down,#furo-readthedocs-versions:hover .fa-caret-down{display:none}#furo-readthedocs-versions:focus-within .injected,#furo-readthedocs-versions:focus-within .rst-current-version,#furo-readthedocs-versions:focus-within .rst-other-versions,#furo-readthedocs-versions:hover .injected,#furo-readthedocs-versions:hover .rst-current-version,#furo-readthedocs-versions:hover .rst-other-versions{display:block}#furo-readthedocs-versions:focus-within>.rst-current-version,#furo-readthedocs-versions:hover>.rst-current-version{display:none}.highlight:hover button.copybtn{color:var(--color-code-foreground)}.highlight button.copybtn{align-items:center;background-color:var(--color-code-background);border:none;color:var(--color-background-item);cursor:pointer;height:1.25em;right:.5rem;top:.625rem;transition:color .3s,opacity .3s;width:1.25em}.highlight button.copybtn:hover{background-color:var(--color-code-background);color:var(--color-brand-content)}.highlight button.copybtn:after{background-color:transparent;color:var(--color-code-foreground);display:none}.highlight button.copybtn.success{color:#22863a;transition:color 0ms}.highlight button.copybtn.success:after{display:block}.highlight button.copybtn svg{padding:0}body{--sd-color-primary:var(--color-brand-primary);--sd-color-primary-highlight:var(--color-brand-content);--sd-color-primary-text:var(--color-background-primary);--sd-color-shadow:rgba(0,0,0,.05);--sd-color-card-border:var(--color-card-border);--sd-color-card-border-hover:var(--color-brand-content);--sd-color-card-background:var(--color-card-background);--sd-color-card-text:var(--color-foreground-primary);--sd-color-card-header:var(--color-card-marginals-background);--sd-color-card-footer:var(--color-card-marginals-background);--sd-color-tabs-label-active:var(--color-brand-content);--sd-color-tabs-label-hover:var(--color-foreground-muted);--sd-color-tabs-label-inactive:var(--color-foreground-muted);--sd-color-tabs-underline-active:var(--color-brand-content);--sd-color-tabs-underline-hover:var(--color-foreground-border);--sd-color-tabs-underline-inactive:var(--color-background-border);--sd-color-tabs-overline:var(--color-background-border);--sd-color-tabs-underline:var(--color-background-border)}.sd-tab-content{box-shadow:0 -2px var(--sd-color-tabs-overline),0 1px var(--sd-color-tabs-underline)}.sd-card{box-shadow:0 .1rem .25rem var(--sd-color-shadow),0 0 .0625rem rgba(0,0,0,.1)}.sd-shadow-sm{box-shadow:0 .1rem .25rem var(--sd-color-shadow),0 0 .0625rem rgba(0,0,0,.1)!important}.sd-shadow-md{box-shadow:0 .3rem .75rem var(--sd-color-shadow),0 0 .0625rem rgba(0,0,0,.1)!important}.sd-shadow-lg{box-shadow:0 .6rem 1.5rem var(--sd-color-shadow),0 0 .0625rem rgba(0,0,0,.1)!important}.sd-card-hover:hover{transform:none}.sd-cards-carousel{gap:.25rem;padding:.25rem}body{--tabs--label-text:var(--color-foreground-muted);--tabs--label-text--hover:var(--color-foreground-muted);--tabs--label-text--active:var(--color-brand-content);--tabs--label-text--active--hover:var(--color-brand-content);--tabs--label-background:transparent;--tabs--label-background--hover:transparent;--tabs--label-background--active:transparent;--tabs--label-background--active--hover:transparent;--tabs--padding-x:0.25em;--tabs--margin-x:1em;--tabs--border:var(--color-background-border);--tabs--label-border:transparent;--tabs--label-border--hover:var(--color-foreground-muted);--tabs--label-border--active:var(--color-brand-content);--tabs--label-border--active--hover:var(--color-brand-content)}[role=main] .container{max-width:none;padding-left:0;padding-right:0}.shadow.docutils{border:none;box-shadow:0 .2rem .5rem rgba(0,0,0,.05),0 0 .0625rem rgba(0,0,0,.1)!important}.sphinx-bs .card{background-color:var(--color-background-secondary);color:var(--color-foreground)} +/*# sourceMappingURL=furo-extensions.css.map*/ \ No newline at end of file diff --git a/_static/styles/furo-extensions.css.map b/_static/styles/furo-extensions.css.map new file mode 100644 index 000000000..c26eac7f5 --- /dev/null +++ b/_static/styles/furo-extensions.css.map @@ -0,0 +1 @@ +{"version":3,"file":"styles/furo-extensions.css","mappings":"AAGA,2BACE,oFACA,4CAKE,6CAHA,YACA,eAEA,CACA,kDACE,yCAEF,8CACE,sCAEJ,8CACE,kDAEJ,2BAGE,uBACA,cAHA,gBACA,UAEA,CAGA,yCACE,mBAEF,gDAEE,gDADA,YACA,CACA,sDACE,gDACF,yDACE,sCAEJ,+CACE,UACA,qDACE,UAGF,mDACE,eAEJ,yEAEE,4DAEA,mHASE,mBAPA,kBAEA,YADA,oBAGA,aADA,gBAIA,CAEA,qIAEE,WADA,UACA,CAEJ,uGACE,aAEF,iUAGE,cAEF,mHACE,aC1EJ,gCACE,mCAEF,0BAEE,mBAUA,8CACA,YAFA,mCAKA,eAZA,cAIA,YADA,YAYA,iCAdA,YAcA,CAEA,gCAEE,8CADA,gCACA,CAEF,gCAGE,6BADA,mCADA,YAEA,CAEF,kCAEE,cADA,oBACA,CACA,wCACE,cAEJ,8BACE,UCzCN,KAEE,6CAA8C,CAC9C,uDAAwD,CACxD,uDAAwD,CAGxD,iCAAsC,CAGtC,+CAAgD,CAChD,uDAAwD,CACxD,uDAAwD,CACxD,oDAAqD,CACrD,6DAA8D,CAC9D,6DAA8D,CAG9D,uDAAwD,CACxD,yDAA0D,CAC1D,4DAA6D,CAC7D,2DAA4D,CAC5D,8DAA+D,CAC/D,iEAAkE,CAClE,uDAAwD,CACxD,wDAAyD,CAG3D,gBACE,qFAGF,SACE,6EAEF,cACE,uFAEF,cACE,uFAEF,cACE,uFAGF,qBACE,eAEF,mBACE,WACA,eChDF,KACE,gDAAiD,CACjD,uDAAwD,CACxD,qDAAsD,CACtD,4DAA6D,CAC7D,oCAAqC,CACrC,2CAA4C,CAC5C,4CAA6C,CAC7C,mDAAoD,CACpD,wBAAyB,CACzB,oBAAqB,CACrB,6CAA8C,CAC9C,gCAAiC,CACjC,yDAA0D,CAC1D,uDAAwD,CACxD,8DAA+D,CCbjE,uBACE,eACA,eACA,gBAGF,iBACE,YACA,+EAGF,iBACE,mDACA","sources":["webpack:///./src/furo/assets/styles/extensions/_readthedocs.sass","webpack:///./src/furo/assets/styles/extensions/_copybutton.sass","webpack:///./src/furo/assets/styles/extensions/_sphinx-design.sass","webpack:///./src/furo/assets/styles/extensions/_sphinx-inline-tabs.sass","webpack:///./src/furo/assets/styles/extensions/_sphinx-panels.sass"],"sourcesContent":["// This file contains the styles used for tweaking how ReadTheDoc's embedded\n// contents would show up inside the theme.\n\n#furo-sidebar-ad-placement\n padding: var(--sidebar-item-spacing-vertical) var(--sidebar-item-spacing-horizontal)\n .ethical-sidebar\n // Remove the border and box-shadow.\n border: none\n box-shadow: none\n // Manage the background colors.\n background: var(--color-background-secondary)\n &:hover\n background: var(--color-background-hover)\n // Ensure the text is legible.\n a\n color: var(--color-foreground-primary)\n\n .ethical-callout a\n color: var(--color-foreground-secondary) !important\n\n#furo-readthedocs-versions\n position: static\n width: 100%\n background: transparent\n display: block\n\n // Make the background color fit with the theme's aesthetic.\n .rst-versions\n background: rgb(26, 28, 30)\n\n .rst-current-version\n cursor: unset\n background: var(--color-sidebar-item-background)\n &:hover\n background: var(--color-sidebar-item-background)\n .fa-book\n color: var(--color-foreground-primary)\n\n > .rst-other-versions\n padding: 0\n small\n opacity: 1\n\n .injected\n .rst-versions\n position: unset\n\n &:hover,\n &:focus-within\n box-shadow: 0 0 0 1px var(--color-sidebar-background-border)\n\n .rst-current-version\n // Undo the tweaks done in RTD's CSS\n font-size: inherit\n line-height: inherit\n height: auto\n text-align: right\n padding: 12px\n\n // Match the rest of the body\n background: #1a1c1e\n\n .fa-book\n float: left\n color: white\n\n .fa-caret-down\n display: none\n\n .rst-current-version,\n .rst-other-versions,\n .injected\n display: block\n\n > .rst-current-version\n display: none\n",".highlight\n &:hover button.copybtn\n color: var(--color-code-foreground)\n\n button.copybtn\n // Align things correctly\n align-items: center\n\n height: 1.25em\n width: 1.25em\n\n top: 0.625rem // $code-spacing-vertical\n right: 0.5rem\n\n // Make it look better\n color: var(--color-background-item)\n background-color: var(--color-code-background)\n border: none\n\n // Change to cursor to make it obvious that you can click on it\n cursor: pointer\n\n // Transition smoothly, for aesthetics\n transition: color 300ms, opacity 300ms\n\n &:hover\n color: var(--color-brand-content)\n background-color: var(--color-code-background)\n\n &::after\n display: none\n color: var(--color-code-foreground)\n background-color: transparent\n\n &.success\n transition: color 0ms\n color: #22863a\n &::after\n display: block\n\n svg\n padding: 0\n","body\n // Colors\n --sd-color-primary: var(--color-brand-primary)\n --sd-color-primary-highlight: var(--color-brand-content)\n --sd-color-primary-text: var(--color-background-primary)\n\n // Shadows\n --sd-color-shadow: rgba(0, 0, 0, 0.05)\n\n // Cards\n --sd-color-card-border: var(--color-card-border)\n --sd-color-card-border-hover: var(--color-brand-content)\n --sd-color-card-background: var(--color-card-background)\n --sd-color-card-text: var(--color-foreground-primary)\n --sd-color-card-header: var(--color-card-marginals-background)\n --sd-color-card-footer: var(--color-card-marginals-background)\n\n // Tabs\n --sd-color-tabs-label-active: var(--color-brand-content)\n --sd-color-tabs-label-hover: var(--color-foreground-muted)\n --sd-color-tabs-label-inactive: var(--color-foreground-muted)\n --sd-color-tabs-underline-active: var(--color-brand-content)\n --sd-color-tabs-underline-hover: var(--color-foreground-border)\n --sd-color-tabs-underline-inactive: var(--color-background-border)\n --sd-color-tabs-overline: var(--color-background-border)\n --sd-color-tabs-underline: var(--color-background-border)\n\n// Tabs\n.sd-tab-content\n box-shadow: 0 -2px var(--sd-color-tabs-overline), 0 1px var(--sd-color-tabs-underline)\n\n// Shadows\n.sd-card // Have a shadow by default\n box-shadow: 0 0.1rem 0.25rem var(--sd-color-shadow), 0 0 0.0625rem rgba(0, 0, 0, 0.1)\n\n.sd-shadow-sm\n box-shadow: 0 0.1rem 0.25rem var(--sd-color-shadow), 0 0 0.0625rem rgba(0, 0, 0, 0.1) !important\n\n.sd-shadow-md\n box-shadow: 0 0.3rem 0.75rem var(--sd-color-shadow), 0 0 0.0625rem rgba(0, 0, 0, 0.1) !important\n\n.sd-shadow-lg\n box-shadow: 0 0.6rem 1.5rem var(--sd-color-shadow), 0 0 0.0625rem rgba(0, 0, 0, 0.1) !important\n\n// Cards\n.sd-card-hover:hover // Don't change scale on hover\n transform: none\n\n.sd-cards-carousel // Have a bit of gap in the carousel by default\n gap: 0.25rem\n padding: 0.25rem\n","// This file contains styles to tweak sphinx-inline-tabs to work well with Furo.\n\nbody\n --tabs--label-text: var(--color-foreground-muted)\n --tabs--label-text--hover: var(--color-foreground-muted)\n --tabs--label-text--active: var(--color-brand-content)\n --tabs--label-text--active--hover: var(--color-brand-content)\n --tabs--label-background: transparent\n --tabs--label-background--hover: transparent\n --tabs--label-background--active: transparent\n --tabs--label-background--active--hover: transparent\n --tabs--padding-x: 0.25em\n --tabs--margin-x: 1em\n --tabs--border: var(--color-background-border)\n --tabs--label-border: transparent\n --tabs--label-border--hover: var(--color-foreground-muted)\n --tabs--label-border--active: var(--color-brand-content)\n --tabs--label-border--active--hover: var(--color-brand-content)\n","// This file contains styles to tweak sphinx-panels to work well with Furo.\n\n// sphinx-panels includes Bootstrap 4, which uses .container which can conflict\n// with docutils' `.. container::` directive.\n[role=\"main\"] .container\n max-width: initial\n padding-left: initial\n padding-right: initial\n\n// Make the panels look nicer!\n.shadow.docutils\n border: none\n box-shadow: 0 0.2rem 0.5rem rgba(0, 0, 0, 0.05), 0 0 0.0625rem rgba(0, 0, 0, 0.1) !important\n\n// Make panel colors respond to dark mode\n.sphinx-bs .card\n background-color: var(--color-background-secondary)\n color: var(--color-foreground)\n"],"names":[],"sourceRoot":""} \ No newline at end of file diff --git a/_static/styles/furo.css b/_static/styles/furo.css new file mode 100644 index 000000000..05a56b17f --- /dev/null +++ b/_static/styles/furo.css @@ -0,0 +1,2 @@ +/*! normalize.css v8.0.1 | MIT License | github.com/necolas/normalize.css */html{line-height:1.15;-webkit-text-size-adjust:100%}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,p,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{height:1px!important;margin:-1px!important;overflow:hidden!important;padding:0!important;position:absolute!important;width:1px!important;clip:rect(0,0,0,0)!important;background:var(--color-background-primary);border:0!important;color:var(--color-foreground-primary);white-space:nowrap!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-stack--headings:var(--font-stack);--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:#6b6f76;--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:#0a4bff;--color-brand-content:#2757dd;--color-brand-visited:#872ee0;--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-api-added:#21632c;--color-api-added-border:#38a84d;--color-api-changed:#046172;--color-api-changed-border:#06a1bc;--color-api-deprecated:#605706;--color-api-deprecated-border:#f0d90f;--color-api-removed:#b30000;--color-api-removed-border:#ff5c5c;--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-underline:var(--color-background-border);--color-link--hover:var(--color-brand-content);--color-link-underline--hover:var(--color-foreground-border);--color-link--visited:var(--color-brand-visited);--color-link-underline--visited:var(--color-background-border);--color-link--visited--hover:var(--color-brand-visited);--color-link-underline--visited--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:#cfd0d0;--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:#3d94ff;--color-brand-content:#5ca5ff;--color-brand-visited:#b27aeb;--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-api-added:#3db854;--color-api-added-border:#267334;--color-api-changed:#09b0ce;--color-api-changed-border:#056d80;--color-api-deprecated:#b1a10b;--color-api-deprecated-border:#6e6407;--color-api-removed:#ff7575;--color-api-removed-border:#b03b3b;--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:#cfd0d0;--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:#3d94ff;--color-brand-content:#5ca5ff;--color-brand-visited:#b27aeb;--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-api-added:#3db854;--color-api-added-border:#267334;--color-api-changed:#09b0ce;--color-api-changed-border:#056d80;--color-api-deprecated:#b1a10b;--color-api-deprecated-border:#6e6407;--color-api-removed:#ff7575;--color-api-removed-border:#b03b3b;--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-light{display:block}@media(prefers-color-scheme:dark){body[data-theme=auto] .theme-toggle svg.theme-icon-when-auto-dark{display:block}body[data-theme=auto] .theme-toggle svg.theme-icon-when-auto-light{display:none}}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-family:var(--font-stack--headings);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:visited{color:var(--color-link--visited);text-decoration-color:var(--color-link-underline--visited)}a:visited:hover{color:var(--color-link--visited--hover);text-decoration-color:var(--color-link-underline--visited--hover)}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--hover);text-decoration-color:var(--color-link-underline--hover)}a.muted-link:hover:visited{color:var(--color-link--visited--hover);text-decoration-color:var(--color-link-underline--visited--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{height:100%}.skip-to-content,body,html{background:var(--color-background-primary);color:var(--color-foreground-primary)}.skip-to-content{border-radius:1rem;left:.25rem;padding:1rem;position:fixed;top:.25rem;transform:translateY(-200%);transition:transform .3s ease-in-out;z-index:40}.skip-to-content:focus-within{transform:translateY(0)}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{display:flex}.theme-toggle{background:transparent;border:none;cursor:pointer;display:flex;padding:0}.theme-toggle svg{color:var(--color-foreground-primary);display:none;height:1.25rem;width:1.25rem}.theme-toggle-header{align-items:center;display:flex;justify-content:center}.nav-overlay-icon,.toc-overlay-icon{cursor:pointer;display:none}.nav-overlay-icon .icon,.toc-overlay-icon .icon{color:var(--color-foreground-secondary);height:1.5rem;width:1.5rem}.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,.content-icon-container .view-this-page svg{color:inherit;height:1.25rem;width:1.25rem}.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{height:1rem;width:1rem;fill:currentColor;display:inline-block}.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){.content{margin-left:auto;margin-right:auto;padding:0 1em}}@media(max-width:63em){.nav-overlay-icon{display:flex}.sidebar-drawer{height:100vh;left:-15em;position:fixed;top:0;width:15em}.theme-toggle-header,.toc-header-icon{display:flex}.theme-toggle-content,.toc-content-icon{display:none}.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.5rem;width:1.5rem}:target{scroll-margin-top:calc(var(--header-height) + 2.5rem)}.back-to-top{top:calc(var(--header-height) + .5rem)}.page{flex-direction:column;justify-content:center}}@media(max-width:48em){.content{overflow-x:auto;width:100%}}@media(max-width:46em){article[role=main] 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:4.25rem}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}div.deprecated,div.versionadded,div.versionchanged,div.versionremoved{border-left:.1875rem solid;border-radius:.125rem;padding-left:.75rem}div.deprecated p,div.versionadded p,div.versionchanged p,div.versionremoved p{margin-bottom:.125rem;margin-top:.125rem}div.versionadded{border-color:var(--color-api-added-border)}div.versionadded .versionmodified{color:var(--color-api-added)}div.versionchanged{border-color:var(--color-api-changed-border)}div.versionchanged .versionmodified{color:var(--color-api-changed)}div.deprecated{border-color:var(--color-api-deprecated-border)}div.deprecated .versionmodified{color:var(--color-api-deprecated)}div.versionremoved{border-color:var(--color-api-removed-border)}div.versionremoved .versionmodified{color:var(--color-api-removed)}.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>:not(span),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}[role=main] .table-wrapper.container{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:2.5rem}@media(max-width:67em){:target{scroll-margin-top:calc(2.5rem + var(--header-height))}section>span:target{scroll-margin-top:calc(2.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);color:var(--color-sidebar-link-text)}.sidebar-tree .reference.external:after{color:var(--color-sidebar-link-text);content:url("data:image/svg+xml;charset=utf-8,%3Csvg xmlns='http://www.w3.org/2000/svg' width='12' height='12' fill='none' stroke='%23607D8B' stroke-linecap='round' stroke-linejoin='round' stroke-width='1.5' viewBox='0 0 24 24'%3E%3Cpath stroke='none' d='M0 0h24v24H0z'/%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 a.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 new file mode 100644 index 000000000..3ecc37150 --- /dev/null +++ b/_static/styles/furo.css.map @@ -0,0 +1 @@ +{"version":3,"file":"styles/furo.css","mappings":"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sCAIA,aADF,WACE,CAKF,SACE,CAHJ,kBAEE,CAJE,gBAEJ,CAHI,iBAMA,yFAKA,aACA,eACA,cElbJ,iBAEE,aADA,iBACA,6BAEA,kCAEA,SACA,UAIA,gCACA,CALA,SAEA,SAEA,CAJA,0EAEA,CAFA,OAKA,CAGA,mDACE,iBAGF,gCACE,CADF,UACE,aAEJ,iCAEE,CAFF,UAEE,wCAEA,WACA,WADA,UACA,CACA,4CAGA,MACA,CADA,KACA,wCACA,UAGA,CAJA,UAIA,6DAUA,0CACE,CAFF,mBAEE,wEACA,CAVA,YACA,CAMF,mBAJE,OAOA,gBAJJ,gCACE,CANE,cACA,CAHA,oBACA,CAGA,QAGJ,CAII,0BACA,CADA,UACA,wCAEJ,kBACE,0DACA,gCACE,kBACA,CADA,YACA,oEACA,2CAMF,mDAII,CALN,YACE,CANE,cAKJ,CACE,iBAII,kEACA,yCACE,kDACA,yDACE,+CACA,uBANN,CAMM,+BANN,uCACE,qDACA,4BAEE,mBADA,0CACA,CADA,qBACA,0DACE,wCACA,sGALJ,oCACA,sBACE,kBAFF,UAEE,2CACA,wFACE,cACA,kEANN,uBACE,iDACA,CADA,UACA,0DACE,wDAEE,iEACA,qEANN,sCACE,CAGE,iBAHF,gBAGE,qBACE,CAJJ,uBACA,gDACE,wDACA,6DAHF,2CACA,CADA,gBACA,eACE,CAGE,sBANN,8BACE,CAII,iBAFF,4DACA,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,yDCrEA,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,wDAEE,uCAEF,kE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","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/variables/_layout.scss","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, p\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 color: var(--color-foreground-primary)\n background: var(--color-background-primary)\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-light\n display: block\n\n @media (prefers-color-scheme: dark)\n .theme-toggle svg.theme-icon-when-auto-dark\n display: block\n .theme-toggle svg.theme-icon-when-auto-light\n display: none\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 --font-stack--headings: var(--font-stack);\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: #6b6f76; // 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: #0a4bff;\n --color-brand-content: #2757dd;\n --color-brand-visited: #872ee0;\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\n --color-api-added: #21632c;\n --color-api-added-border: #38a84d;\n --color-api-changed: #046172;\n --color-api-changed-border: #06a1bc;\n --color-api-deprecated: #605706;\n --color-api-deprecated-border: #f0d90f;\n --color-api-removed: #b30000;\n --color-api-removed-border: #ff5c5c;\n\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-underline: var(--color-background-border);\n --color-link--hover: var(--color-brand-content);\n --color-link-underline--hover: var(--color-foreground-border);\n\n --color-link--visited: var(--color-brand-visited);\n --color-link-underline--visited: var(--color-background-border);\n --color-link--visited--hover: var(--color-brand-visited);\n --color-link-underline--visited--hover: var(--color-foreground-border);\n}\n\n@mixin colors-dark {\n --color-problematic: #ee5151;\n\n // Base Colors\n --color-foreground-primary: #cfd0d0; // 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: #3d94ff;\n --color-brand-content: #5ca5ff;\n --color-brand-visited: #b27aeb;\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 --color-api-added: #3db854;\n --color-api-added-border: #267334;\n --color-api-changed: #09b0ce;\n --color-api-changed-border: #056d80;\n --color-api-deprecated: #b1a10b;\n --color-api-deprecated-border: #6e6407;\n --color-api-removed: #ff7575;\n --color-api-removed-border: #b03b3b;\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-family: var(--font-stack--headings)\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 &:visited\n color: var(--color-link--visited)\n text-decoration-color: var(--color-link-underline--visited)\n &:hover\n color: var(--color-link--visited--hover)\n text-decoration-color: var(--color-link-underline--visited--hover)\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--hover)\n text-decoration-color: var(--color-link-underline--hover)\n &:visited\n color: var(--color-link--visited--hover)\n text-decoration-color: var(--color-link-underline--visited--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\n.skip-to-content\n position: fixed\n padding: 1rem\n border-radius: 1rem\n left: 0.25rem\n top: 0.25rem\n z-index: 40\n background: var(--color-background-primary)\n color: var(--color-foreground-primary)\n\n transform: translateY(-200%)\n transition: transform 300ms ease-in-out\n\n &:focus-within\n transform: translateY(0%)\n\narticle\n color: var(--color-content-foreground)\n background: var(--color-content-background)\n overflow-wrap: break-word\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 display: flex\n\n.theme-toggle\n display: flex\n cursor: pointer\n border: none\n padding: 0\n background: transparent\n\n.theme-toggle svg\n height: 1.25rem\n width: 1.25rem\n color: var(--color-foreground-primary)\n display: none\n\n.theme-toggle-header\n display: flex\n align-items: center\n justify-content: center\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: 1.5rem\n width: 1.5rem\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, .view-this-page\n svg\n color: inherit\n height: 1.25rem\n width: 1.25rem\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: $content-padded-width + $sidebar-width)\n // Center the page\n .content\n margin-left: auto\n margin-right: auto\n padding: 0 $content-padding--small\n\n@media (max-width: $content-padded-width--small + $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, .theme-toggle-header\n display: flex\n .toc-content-icon, .theme-toggle-content\n display: none\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.5rem\n width: 1.5rem\n\n // Add a scroll margin for the content\n :target\n scroll-margin-top: calc(var(--header-height) + 2.5rem)\n\n // Show back-to-top below the header\n .back-to-top\n top: calc(var(--header-height) + 0.5rem)\n\n // Accommodate for the header.\n .page\n flex-direction: column\n justify-content: center\n\n@media (max-width: $content-width + 2* $content-padding--small)\n // Content should respect window limits.\n .content\n width: 100%\n overflow-x: auto\n\n@media (max-width: $content-width)\n article[role=main] aside.sidebar\n float: none\n width: 100%\n margin: 1rem 0\n","// Overall Layout Variables\n//\n// Because CSS variables can't be used in media queries. The fact that this\n// makes the layout non-user-configurable is a good thing.\n$content-padding: 3em;\n$content-padding--small: 1em;\n$content-width: 46em;\n$sidebar-width: 15em;\n$content-padded-width: $content-width + 2 * $content-padding;\n$content-padded-width--small: $content-width + 2 * $content-padding--small;\n$full-width: $content-padded-width + 2 * $sidebar-width;\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\n.admonition p.admonition-title,\np.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: 4.25rem\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\ndiv.versionadded,\ndiv.versionchanged,\ndiv.deprecated,\ndiv.versionremoved\n border-left: 0.1875rem solid\n border-radius: 0.125rem\n\n padding-left: 0.75rem\n\n p\n margin-top: 0.125rem\n margin-bottom: 0.125rem\n\ndiv.versionadded\n border-color: var(--color-api-added-border)\n .versionmodified\n color: var(--color-api-added)\n\ndiv.versionchanged\n border-color: var(--color-api-changed-border)\n .versionmodified\n color: var(--color-api-changed)\n\ndiv.deprecated\n border-color: var(--color-api-deprecated-border)\n .versionmodified\n color: var(--color-api-deprecated)\n\ndiv.versionremoved\n border-color: var(--color-api-removed-border)\n .versionmodified\n color: var(--color-api-removed)\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 pre.literal-block &\n font-size: inherit\n padding: 0\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 > *:not(span),\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","[role=main] .table-wrapper.container\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: 2.5rem\n\n@media (max-width: $full-width - $sidebar-width)\n :target\n scroll-margin-top: calc(2.5rem + var(--header-height))\n\n // When a heading is selected\n section > span:target\n scroll-margin-top: calc(2.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 color: var(--color-sidebar-link-text)\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