diff --git a/.github/workflows/docs.yaml b/.github/workflows/docs.yaml new file mode 100644 index 0000000..8970645 --- /dev/null +++ b/.github/workflows/docs.yaml @@ -0,0 +1,77 @@ +name: documentation + +on: + push: + branches: [main] + pull_request: + workflow_dispatch: + +permissions: {} + +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + +jobs: + changes: + runs-on: ubuntu-latest + permissions: + contents: read + pull-requests: read + outputs: + docs: ${{ steps.filter.outputs.docs }} + steps: + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 + with: + persist-credentials: false + - uses: dorny/paths-filter@ceb8a2b8f2d89434be7ff52d3de7ec3738c5cc9d # v4.0.3 + id: filter + with: + filters: | + docs: + - '.github/workflows/docs.yaml' + - 'docs/**' + - 'src/**' + - 'pyproject.toml' + - 'uv.lock' + - 'zensical.toml' + + build: + needs: changes + if: ${{ needs.changes.outputs.docs == 'true' || github.event_name == 'workflow_dispatch' }} + runs-on: ubuntu-latest + permissions: + contents: read + steps: + - uses: actions/checkout@d23441a48e516b6c34aea4fa41551a30e30af803 # v6 + with: + fetch-depth: 0 + persist-credentials: false + - uses: astral-sh/setup-uv@37802adc94f370d6bfd71619e3f0bf239e1f3b78 # v7.6.0 + with: + python-version: "3.13" + - name: Build documentation + run: uv run --extra docs --no-dev zensical build --clean --strict + - name: Configure Pages + if: github.event_name != 'pull_request' + uses: actions/configure-pages@45bfe0192ca1faeb007ade9deae92b16b8254a0d # v6 + - name: Upload Pages artifact + if: github.event_name != 'pull_request' + uses: actions/upload-pages-artifact@fc324d3547104276b827a68afc52ff2a11cc49c9 # v5 + with: + path: site + + deploy: + if: github.event_name != 'pull_request' + needs: build + runs-on: ubuntu-latest + environment: + name: github-pages + url: ${{ steps.deployment.outputs.page_url }} + permissions: + pages: write + id-token: write + steps: + - name: Deploy to GitHub Pages + id: deployment + uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5 diff --git a/.gitignore b/.gitignore index 68d62bc..140a628 100644 --- a/.gitignore +++ b/.gitignore @@ -10,6 +10,7 @@ dist/ .pytest_cache/ .coverage htmlcov/ +site/ .ipynb_checkpoints/ .DS_Store diff --git a/README.md b/README.md index dedc9dd..29121fd 100644 --- a/README.md +++ b/README.md @@ -1,81 +1,19 @@
-# SpinForge +# SpinForge
SpinForge is a group-theoretic generator for spin-symmetry-adapted (SSA) and oriented magnetic crystal structures based on spin space groups. -## Installation +[Documentation](https://spglib.github.io/spinforge/) · +[PyPI](https://pypi.org/project/spinforge/) · +[Issue tracker](https://github.com/spglib/spinforge/issues) -SpinForge supports Python 3.11 and later. - -```shell -python -m pip install spinforge -``` - -For a source checkout and contributor setup, see -[CONTRIBUTING.md](./CONTRIBUTING.md). - -## Quickstart: oriented magnetic structures - -Given a primitive crystal structure in `MnTe.cif`, this example enumerates -collinear SSA candidates with propagation-vector index one and generates every -maximal oriented descendant: - -```python -from moyopy import Cell -from pymatgen.core import Structure -from spinspg.spin import SpinOnlyGroupType - -from spinforge.configuration import SSAGenerator - -structure = Structure.from_file("MnTe.cif") -prim_cell = Cell( - basis=structure.lattice.matrix.tolist(), - positions=structure.frac_coords.tolist(), - numbers=list(structure.atomic_numbers), -) -magnetic_site_indices = [ - index for index, atomic_number in enumerate(prim_cell.numbers) if atomic_number == 25 -] - -generator = SSAGenerator( - prim_cell=prim_cell, - magnetic_site_indices=magnetic_site_indices, -) - -for spin_only_group, spin_space_group, adapted_structure in generator.enumerate( - spin_only_group_type=SpinOnlyGroupType.COLLINEAR, - k_index=1, - max_depth=0, -): - oriented_structures = generator.generate_oriented( - adapted_structure, - spin_only_group=spin_only_group, - nontrivial_spin_space_group=spin_space_group, - ) - for magnetic_structure, magnetic_space_subgroup in oriented_structures: - print(magnetic_structure.formula, magnetic_space_subgroup.msg_type) -``` - -`SSAGenerator` requires a primitive input cell. The family-subgroup, -spin-space-group, and oriented spin-frame equivalence controls are separate. -See the [enumeration and equivalence guide](./docs/equivalence.md) for the -precise criteria and the options for larger searches. - -## Examples - -The paper examples are provided as notebooks in [`examples/paper`](./examples/paper): - -- [collinear MnTe](./examples/paper/collinear_MnTe) -- [coplanar Mn3Sn](./examples/paper/coplanar_Mn3Sn) -- [noncoplanar CoTa3S6](./examples/paper/noncoplanar_CoTa3S6) - -These examples are published as-is. The paper figures, MAGNDATA-derived -datasets, and the raw 283-material SDFT workflow are not part of this -repository. +Installation, tutorials, examples, citation guidance, and API references are +maintained in the [documentation](https://spglib.github.io/spinforge/). For a +source checkout and contributor setup, see [CONTRIBUTING.md](./CONTRIBUTING.md). ## Release flow @@ -129,30 +67,6 @@ Please use bugs and in-scope feature requests. Security reports follow [SECURITY.md](./SECURITY.md). -## Citation - -If SpinForge contributes to published work, cite the software metadata in -[`CITATION.cff`](./CITATION.cff) and the associated oriented-spin-space-group -paper: - -> T. Nomoto, K. Shinohara, H. Watanabe, and R. Arita, -> “Systematic magnetic structure generation based on oriented spin space -> groups: Formulation, applications, and high-throughput first-principles -> calculations,” *Physical Review X* (accepted 2026). -> [doi:10.1103/8n3w-h2t1](https://doi.org/10.1103/8n3w-h2t1) - -```bibtex -@article{SpinForgePRX2026, - author = {Nomoto, Takuya and Shinohara, Kohei and Watanabe, Hikaru and Arita, Ryotaro}, - title = {Systematic Magnetic Structure Generation Based on Oriented Spin Space Groups: - Formulation, Applications, and High-Throughput First-Principles Calculations}, - journal = {Physical Review X}, - year = {2026}, - doi = {10.1103/8n3w-h2t1}, - note = {Accepted} -} -``` - ## Data attribution and license Third-party and literature-derived fixture notices are collected in diff --git a/docs/THIRD_PARTY_DATA.md b/docs/THIRD_PARTY_DATA.md index 188841f..8aae547 100644 --- a/docs/THIRD_PARTY_DATA.md +++ b/docs/THIRD_PARTY_DATA.md @@ -36,8 +36,9 @@ Please cite: ## MnTe structural model `src/spinforge/testing/assets/MnTe.cif` and -`examples/paper/collinear_MnTe/MnTe.cif` are identical, locally serialized -pymatgen CIFs for the NiAs-type MnTe structure. The lattice constants +`examples/paper/collinear_MnTe/MnTe.cif` are identical to the documentation +copy at `docs/paper/MnTe.cif`. They are locally serialized pymatgen CIFs for +the NiAs-type MnTe structure. The lattice constants `a = b = 4.17349018 Å` and `c = 6.75345133 Å` follow the supplemental material to: @@ -74,3 +75,24 @@ The SpinForge fixture is not a byte-for-byte COD or MAGNDATA record. within the SpinForge project. Repository history records no external database file as its source, so no third-party dataset license is asserted for this file. + +## Article example figures + +The following PNG schematics under `docs/assets/paper/` illustrate examples +from the associated article: + +- `fig_example_collinear.png` +- `fig_example_coplanar.png` +- `fig_example_noncoplanar.png` + +The figures were created for: + +> T. Nomoto, K. Shinohara, H. Watanabe, and R. Arita, +> “Systematic magnetic structure generation based on oriented spin space +> groups: Formulation, applications, and high-throughput first-principles +> calculations,” *Physical Review X* (accepted 2026). +> [doi:10.1103/8n3w-h2t1](https://doi.org/10.1103/8n3w-h2t1) + +They are included with permission from their copyright holder, granted on +September 6, 2026. This notice records that permission without asserting a +Creative Commons license before the article's Version of Record is published. diff --git a/docs/api/configuration.md b/docs/api/configuration.md new file mode 100644 index 0000000..1e81d84 --- /dev/null +++ b/docs/api/configuration.md @@ -0,0 +1,5 @@ +# Configuration + +High-level structure generation and supercell objects. + +::: spinforge.configuration diff --git a/docs/api/irreps.md b/docs/api/irreps.md new file mode 100644 index 0000000..38a233a --- /dev/null +++ b/docs/api/irreps.md @@ -0,0 +1,6 @@ +# Irreducible representations + +Real irreducible-representation and intertwiner utilities used by the +spin-space-group enumerators. + +::: spinforge.irreps diff --git a/docs/api/magnetic-space-group.md b/docs/api/magnetic-space-group.md new file mode 100644 index 0000000..2eb7a4e --- /dev/null +++ b/docs/api/magnetic-space-group.md @@ -0,0 +1,5 @@ +# Magnetic space groups + +Oriented descendants and magnetic-space-subgroup objects. + +::: spinforge.msg diff --git a/docs/api/mcif.md b/docs/api/mcif.md new file mode 100644 index 0000000..d6d4b69 --- /dev/null +++ b/docs/api/mcif.md @@ -0,0 +1,6 @@ +# MCIF + +Write a pymatgen magnetic structure as a symmetrized magnetic CIF in the +BNS/MAGNDATA convention. + +::: spinforge.mcif diff --git a/docs/api/space-group.md b/docs/api/space-group.md new file mode 100644 index 0000000..b5bb18c --- /dev/null +++ b/docs/api/space-group.md @@ -0,0 +1,6 @@ +# Space groups + +Family and normal space-subgroup enumeration, parent-normalizer actions, and +translation sublattices. + +::: spinforge.space_group diff --git a/docs/api/spin-space-group.md b/docs/api/spin-space-group.md new file mode 100644 index 0000000..625c1ac --- /dev/null +++ b/docs/api/spin-space-group.md @@ -0,0 +1,5 @@ +# Spin space groups + +Nontrivial spin space groups, symmetry operations, and subgroup enumeration. + +::: spinforge.ssg diff --git a/docs/api/spincif.md b/docs/api/spincif.md new file mode 100644 index 0000000..7e37533 --- /dev/null +++ b/docs/api/spincif.md @@ -0,0 +1,5 @@ +# spinCIF + +Read and write SpinForge's supported subset of the draft spinCIF format. + +::: spinforge.scif diff --git a/docs/assets/logo-mark.svg b/docs/assets/logo-mark.svg new file mode 100644 index 0000000..e9d9bbf --- /dev/null +++ b/docs/assets/logo-mark.svg @@ -0,0 +1,310 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/logo.svg b/docs/assets/logo.svg similarity index 100% rename from logo.svg rename to docs/assets/logo.svg diff --git a/docs/assets/paper/fig_example_collinear.png b/docs/assets/paper/fig_example_collinear.png new file mode 100644 index 0000000..98361e2 Binary files /dev/null and b/docs/assets/paper/fig_example_collinear.png differ diff --git a/docs/assets/paper/fig_example_coplanar.png b/docs/assets/paper/fig_example_coplanar.png new file mode 100644 index 0000000..59ca34f Binary files /dev/null and b/docs/assets/paper/fig_example_coplanar.png differ diff --git a/docs/assets/paper/fig_example_noncoplanar.png b/docs/assets/paper/fig_example_noncoplanar.png new file mode 100644 index 0000000..ad04f6d Binary files /dev/null and b/docs/assets/paper/fig_example_noncoplanar.png differ diff --git a/docs/changelog.md b/docs/changelog.md new file mode 100644 index 0000000..786b75d --- /dev/null +++ b/docs/changelog.md @@ -0,0 +1 @@ +--8<-- "CHANGELOG.md" diff --git a/docs/citation.md b/docs/citation.md new file mode 100644 index 0000000..5d26bf7 --- /dev/null +++ b/docs/citation.md @@ -0,0 +1,26 @@ +# Citation + +If SpinForge contributes to published work, cite both the software metadata in +[`CITATION.cff`](https://github.com/spglib/spinforge/blob/main/CITATION.cff) and +the associated oriented-spin-space-group paper: + +> T. Nomoto, K. Shinohara, H. Watanabe, and R. Arita, +> “Systematic magnetic structure generation based on oriented spin space +> groups: Formulation, applications, and high-throughput first-principles +> calculations,” *Physical Review X* (accepted 2026). +> [doi:10.1103/8n3w-h2t1](https://doi.org/10.1103/8n3w-h2t1) + +```bibtex +@article{SpinForgePRX2026, + author = {Nomoto, Takuya and Shinohara, Kohei and Watanabe, Hikaru and Arita, Ryotaro}, + title = {Systematic Magnetic Structure Generation Based on Oriented Spin Space Groups: + Formulation, Applications, and High-Throughput First-Principles Calculations}, + journal = {Physical Review X}, + year = {2026}, + doi = {10.1103/8n3w-h2t1}, + note = {Accepted} +} +``` + +SpinForge is distributed under the BSD 3-Clause License. Third-party data +retain the terms listed in the [data notices](THIRD_PARTY_DATA.md). diff --git a/docs/classification-model.md b/docs/classification-model.md new file mode 100644 index 0000000..fe6e436 --- /dev/null +++ b/docs/classification-model.md @@ -0,0 +1,83 @@ +# Classification model + +!!! abstract "Page contract" + + - **Starting point:** You understand the objects in the + [domain model](domain-model.md) but not which distinctions SpinForge + preserves. + - **Destination:** You can identify which setting changes the search space, + an equivalence relation, or only the orientation of a result. + - **Next:** Apply those distinctions in + [Control an enumeration](control-enumeration.md). + - **Skip:** Use the [exact reference](equivalence.md) directly when the + conceptual distinctions are already familiar. + +The [SpinForge article](https://doi.org/10.1103/8n3w-h2t1) is the authoritative +source for the underlying theory and derivations. This page only maps those +concepts to package decisions. + +## The decisions are independent + +| Question | SpinForge decision | What changes | +|---|---|---| +| What kind of spin configuration is sought? | `SpinOnlyGroupType.COLLINEAR`, `.COPLANAR`, or `.NONCOPLANAR` | The compatible spin-only groups and spin-space-group assignments | +| Which translation lattices are admissible? | An index bound with `k_index`, or a lattice fixed by `with_propagation_vectors()` | The spatial families and supercells searched | +| How far below the parent spatial symmetry should the search go? | `max_depth` and `multiplicity_preserving` | The family space subgroups retained | +| Should parent-conjugate spatial families be listed separately? | `up_to_parent_conjugacy` | The number of family-subgroup representatives | +| Should a coplanar mirror partner remain distinct after orientation? | `preserve_spin_planochirality` | The oriented descendants returned | + +Changing one row does not silently change the others. In particular, retaining +more family-space-group conjugates is distinct from changing spin-frame +equivalence, and orientation is a later classification step rather than a new +family-subgroup search. + +## Spin class + +The requested spin-only-group type classifies the allowed geometry of the +candidate moments: + +- `COLLINEAR`: all moments lie on one spin axis; +- `COPLANAR`: moments lie in one spin plane but need not share an axis; +- `NONCOPLANAR`: moments are not restricted to one plane. + +This is an input classification, not a label inferred from experimental data. +If a propagation-vector constraint is incompatible with the selected class, +an empty enumeration can be the correct result. + +## Translation constraint + +`k_index` gives a finite index bound when the translation lattice is unknown. +`SSAGenerator.with_propagation_vectors()` instead fixes the commensurate +translation lattice from measured or calculated propagation vectors. + +These are alternative ways to supply the translation constraint. When +propagation vectors are present, their lattice supplies the index, and an +explicit `k_index` must equal that computed index. See +[use propagation vectors](propagation-vectors.md) for coordinate-frame handling +and [control enumeration](control-enumeration.md) for practical search choices. + +## Spatial-family breadth + +`max_depth` bounds the translationengleiche Hermann groups visited beneath the +parent. It is not a generic "subgroup depth" for every emitted family. +`multiplicity_preserving=True` additionally removes family subgroups that split +the selected magnetic-site orbits incompatibly with the package's multiplicity +criterion. + +By default, `up_to_parent_conjugacy=True` retains one representative of each +family-subgroup class under the crystallographic parent $G$. The `False` +setting retains the separate parent-conjugate embeddings. + +## Keep spin-frame and spatial equivalence separate + +For a fixed family group $G'$, compatible spin-space groups are identified up +to a global orthogonal change of spin frame. The high-level generator also +reduces them by the applicable parent normalizer $N_G(G')$. These relations do +not become weaker when parent-conjugate family groups are retained separately. + +Orientation then uses the axes of the fixed family subgroup. For coplanar results, +`preserve_spin_planochirality=True` keeps enantiomorphs related by an improper +spin transformation distinct; `False` identifies them. + +For the formal actions, defaults, and lower-level API behavior, consult the +[enumeration and equivalence reference](equivalence.md). diff --git a/docs/control-enumeration.md b/docs/control-enumeration.md new file mode 100644 index 0000000..98b8ce9 --- /dev/null +++ b/docs/control-enumeration.md @@ -0,0 +1,96 @@ +# Control an enumeration + +!!! abstract "Page contract" + + - **Starting point:** You can construct an `SSAGenerator` and run the + quickstart search. + - **Destination:** You can choose the five search controls deliberately. + - **Next:** Check the implemented relations in + [Enumeration and equivalence](equivalence.md) when candidate counts need + explanation. + - **Skip:** The quickstart settings already cover your calculation. + +## Start with the smallest relevant search + +Select the moment geometry required by the problem, then keep the default +equivalence reductions: + +```python +from spinspg.spin import SpinOnlyGroupType + +candidates = generator.enumerate( + spin_only_group_type=SpinOnlyGroupType.COLLINEAR, + k_index=1, + max_depth=0, + up_to_parent_conjugacy=True, +) +``` + +Use `COLLINEAR`, `COPLANAR`, or `NONCOPLANAR` according to the moment geometry +you intend to model. Moving to a less restrictive type changes the physical +search, not merely its cost. + +## Set the translation bound + +Without measured propagation vectors, `k_index` is required. It is the index +of the final invariant translation lattice that bounds enumeration: + +- `k_index=1` restricts the final lattice to the primitive translation lattice. +- A larger value admits compatible family translation lattices whose indices + divide that value. + +If commensurate propagation vectors are known, construct the generator with +`SSAGenerator.with_propagation_vectors()` instead. SpinForge then derives the +lattice and supplies its index automatically; follow [Constrain an enumeration +with propagation vectors](propagation-vectors.md). + +## Set the Hermann depth + +`max_depth` controls which translationengleiche Hermann groups are searched. +Their bounded klassengleiche descendants remain included. + +| Value | Hermann groups retained | +|---|---| +| `0` | Parent only | +| `1` | Parent and maximal proper subgroups (default) | +| `None` | All subgroup depths | + +Begin at `0` when validating a workflow. Increase the depth only when the +target family symmetry requires it. + +## Choose the spatial reduction + +Keep `up_to_parent_conjugacy=True` to return one representative for family +space subgroups related by the crystallographic parent. Set it to `False` only +when you need every conjugate family subgroup explicitly: + +```python +all_conjugates = generator.enumerate( + spin_only_group_type=SpinOnlyGroupType.COLLINEAR, + k_index=1, + max_depth=0, + up_to_parent_conjugacy=False, +) +``` + +This option changes family-subgroup reduction. It does not disable the +spin-frame equivalence applied within each retained family subgroup. + +## Choose the magnetic-site filter + +By default, the generator omits family subgroups that change the multiplicity +of the supplied magnetic sites. Disable this constructor-time filter only when +those splittings are part of the intended search: + +```python +generator = SSAGenerator( + prim_cell=primitive_cell, + magnetic_site_indices=magnetic_site_indices, + multiplicity_preserving=False, +) +``` + +Change one control at a time and record the number of returned candidates. For +the exact equivalence relations and subgroup construction, see +[Enumeration and equivalence](equivalence.md). For the underlying scientific +derivation, see the [SpinForge article](https://doi.org/10.1103/8n3w-h2t1). diff --git a/docs/domain-model.md b/docs/domain-model.md new file mode 100644 index 0000000..ec3697c --- /dev/null +++ b/docs/domain-model.md @@ -0,0 +1,88 @@ +# Domain model + +!!! abstract "Page contract" + + - **Starting point:** You can recognize a magnetic structure but are new to + SpinForge's vocabulary. + - **Destination:** You can follow an enumeration result from its + crystallographic input to an oriented magnetic structure. + - **Next:** Learn which distinctions affect a candidate set in the + [classification model](classification-model.md). + - **Skip:** This page when SpinForge's objects and workflow stages are + already familiar. + +For derivations and the full scientific treatment, see the +[SpinForge article](https://doi.org/10.1103/8n3w-h2t1). + +## One workflow, several distinct objects + +``` mermaid +flowchart TB + A[Primitive cell
and magnetic sites] + B[Family space subgroup] + C[Spin space group
and spin-only group] + D[SSA structure
supercell + moment basis] + E[Oriented magnetic structure
and magnetic space subgroup] + + A -->|enumerate spatial families| B + B -->|assign spin rotations| C + C -->|construct allowed moments| D + D -->|orient relative to lattice| E +``` + +SpinForge keeps these stages separate because they answer different +questions. A family space subgroup (shortened below to *family subgroup*) is a +spatial symmetry choice relative to the crystallographic parent. A spin space +group adds how spatial operations act on spins. A spin-symmetry-adapted (SSA) +structure represents the magnetic-moment subspace allowed by that symmetry. +An oriented result finally relates the spin frame to the crystal lattice. + +## Input state + +[`SSAGenerator`][spinforge.configuration.SSAGenerator] starts from: + +- a primitive [`moyopy.Cell`](https://spglib.github.io/moyo/python/api/#moyopy.Cell); +- indices identifying the magnetic sites in that exact cell; +- optionally, propagation vectors that fix a commensurate translation lattice. + +The cell defines the crystallographic parent space group $G$. The magnetic +site indices determine which parent-site orbits must support moments. Search +bounds and propagation vectors limit the translation lattices considered; they +do not become additional atoms or moments in the input object. + +## Enumeration state + +Calling `SSAGenerator.enumerate()` returns tuples of: + +1. a `SpinOnlyGroup`, which records the requested collinear, coplanar, or + noncoplanar spin-only symmetry; +2. a [`NontrivialSpinSpaceGroup`][spinforge.ssg.NontrivialSpinSpaceGroup], + which records the nontrivial coupling between spatial and spin operations; +3. a + [`SpinSymmetryAdaptedStructure`][spinforge.configuration.SpinSymmetryAdaptedStructure], + which contains a supercell and a basis for symmetry-allowed magnetic + moments. + +These are candidate symmetry classes, not predicted ground states. SpinForge +does not rank them by energy or fit them to measurements. + +## Generated and oriented state + +`SpinSymmetryAdaptedStructure.generate()` selects a moment configuration from +the adapted basis. If the basis has more than one dimension, its coefficients +are sampled; pass a NumPy random generator when the selected point must be +reproducible. + +`SSAGenerator.generate_oriented()` performs a different step: it enumerates +the allowed orientations of the spin frame relative to the family subgroup's +crystallographic axes. Each result pairs a pymatgen `Structure`, with Cartesian +moments in its `magmom` site property, with a +[`MagneticSpaceSubgroup`][spinforge.msg.MagneticSpaceSubgroup]. + +!!! tip "What to read next" + + - Read the [classification model](classification-model.md) to choose the + boundary and equivalence controls that change a candidate set. + - Follow [your first structure](quickstart.md) to run this workflow. + - Use the [configuration API](api/configuration.md) when you need exact + signatures and return types. diff --git a/docs/equivalence.md b/docs/equivalence.md index 0ce2af7..e1a3ebe 100644 --- a/docs/equivalence.md +++ b/docs/equivalence.md @@ -1,4 +1,23 @@ -# Enumeration and equivalence +# Enumeration and equivalence reference + +This is the exact technical reference for the enumeration bounds and +equivalence relations implemented by SpinForge. + +!!! abstract "Page contract" + + - **Starting point:** You understand the objects and stages in the + [domain model](domain-model.md) and need to interpret candidate counts or + implement against the enumeration APIs. + - **Destination:** You can state which group action identifies each class + and what each search control retains. + - **Next:** Check exact signatures in the + [configuration API](api/configuration.md). + - **Skip:** You only need to run the default workflow; use + [Your first structure](quickstart.md) instead. + +The [SpinForge article](https://doi.org/10.1103/8n3w-h2t1) remains the +authoritative source for derivations and the broader scientific treatment. +This page records the software contract rather than repeating that material. ## Equivalence criteria at a glance @@ -36,7 +55,9 @@ For the parent-normalizer action that classifies normal space subgroups, the act inverse conjugation. Thus a stored normalizer transformation $h_x$ maps a subgroup $H_x$ to the representative $H_r$ when -$$h_x^{-1}H_xh_x=H_r.$$ +$$ +h_x^{-1}H_xh_x=H_r. +$$ The corresponding stabilizer consists of the normalizer transformations $h$ satisfying $h^{-1}H_rh=H_r$. Code and API descriptions use the concrete phrases "equivalent objects," @@ -64,7 +85,9 @@ Let $G$ be the parent space group and $T$ its primitive translation subgroup. A SpinForge follows the Hermann theorem. For every $G'\leq G$, there is a unique intermediate group -$$G'\leq M\leq G$$ +$$ +G'\leq M\leq G +$$ such that $M$ is a t-subgroup of $G$ and $G'$ is a k-subgroup of $M$. Thus $M$ and $G'$ have the same point group, while $G$ and $M$ have the same translation group $T$. This separates the finite point-group choice from the bounded translation-lattice choice: @@ -75,7 +98,9 @@ such that $M$ is a t-subgroup of $G$ and $G'$ is a k-subgroup of $M$. Thus $M$ a `with_propagation_vectors()` fixes the final commensurate invariant lattice -$$L=\{t\in T\mid k_i\cdot t\in\mathbb{Z}\text{ for every supplied }k_i\}.$$ +$$ +L=\{t\in T\mid k_i\cdot t\in\mathbb{Z}\text{ for every supplied }k_i\}. +$$ In that case, only family lattices satisfying $L\leq T'\leq T$ are considered, and the relative lattice $L\leq T'$ replaces the unrestricted index-$n/d$ search. An explicitly supplied `k_index` must equal $[T:L]$. @@ -109,7 +134,9 @@ The lower-level `SpinSpaceGroupEnumerator` receives one fixed family space group `SpinSpaceSubgroupEnumerator` instead consumes an enumerated `FamilySpaceSubgroup`. The family object records the inclusion $G'\leq G$ and the induced action of $N_G(G')/G'$. By default the class returns representatives under -$$N_G(G') \times O(3).$$ +$$ +N_G(G') \times O(3). +$$ It first classifies invariant space subgroups $H'\trianglelefteq G'$ under $N_G(G')$. For each representative $H'$, it then classifies its spin-rotation assignments under the stabilizer of $H'$ in $N_G(G')$ together with the global $O(3)$ spin-frame action. Results are expressed in the translation-lattice basis of $G'$; `SSAGenerator` transforms them to the translation-lattice basis of the parent group $G$ for magnetic-structure generation. @@ -128,7 +155,9 @@ The criteria exposed by the enumeration APIs are therefore: There is no separate `up_to_family_space_group_conjugacy` option. For an invariant subgroup $H'\trianglelefteq G'$ and spin representation $U$, preconjugation by $g\in G'$ gives -$$U^g(x)=U(g^{-1}xg)=U(g)^{-1}U(x)U(g),$$ +$$ +U^g(x)=U(g^{-1}xg)=U(g)^{-1}U(x)U(g), +$$ which is already identified by the global $O(3)$ spin-frame equivalence. Such a boolean would therefore not change the abstract SSG classes. `SSAGenerator.up_to_parent_conjugacy` remains independent and controls only whether $G$-conjugate family space subgroups are retained separately. diff --git a/docs/examples.md b/docs/examples.md new file mode 100644 index 0000000..ba33cbf --- /dev/null +++ b/docs/examples.md @@ -0,0 +1,43 @@ +# Examples + +!!! abstract "Page contract" + + - **Starting point:** You have completed + [Your first structure](quickstart.md) and want to map that workflow to a + physical example. + - **Destination:** You can choose the notebook whose spin-only-group class + and translation bound match your task. + - **Next:** Open that notebook and use the article for its scientific + interpretation. + - **Skip:** This page if you only need an exact API signature. + +The repository contains the notebooks used for three representative examples +in the [SpinForge article](https://doi.org/10.1103/8n3w-h2t1). Each follows the +same software workflow: choose the magnetic sites, select a spin-only-group +class and `k_index`, enumerate SSA structures, generate oriented descendants, +and write spinCIF output. The article is the source for the formalism, +derivations, and physical interpretation. + +## Schematic overview + +The figures summarize the enumerated spin space groups and representative +oriented structures. Follow each figure to its corresponding notebook for the +software workflow, and use the article for interpretation. + +=== "Collinear MnTe" + + ![Collinear MnTe spin-space-group and oriented-structure schematic](assets/paper/fig_example_collinear.png){ .paper-figure } + + Continue with the [collinear MnTe notebook](https://github.com/spglib/spinforge/blob/main/docs/paper/collinear_MnTe.ipynb). + +=== "Coplanar Mn₃Sn" + + ![Coplanar Mn₃Sn spin-space-group and oriented-structure schematic](assets/paper/fig_example_coplanar.png){ .paper-figure } + + Continue with the [coplanar Mn₃Sn notebook](https://github.com/spglib/spinforge/blob/main/docs/paper/coplanar_Mn3Sn.ipynb). + +=== "Noncoplanar CoTa₃S₆" + + ![Noncoplanar CoTa₃S₆ spin-space-group and oriented-structure schematic](assets/paper/fig_example_noncoplanar.png){ .paper-figure } + + Continue with the [noncoplanar CoTa₃S₆ notebook](https://github.com/spglib/spinforge/blob/main/docs/paper/noncoplanar_CoTa3S6.ipynb). diff --git a/docs/export-files.md b/docs/export-files.md new file mode 100644 index 0000000..f15e9aa --- /dev/null +++ b/docs/export-files.md @@ -0,0 +1,72 @@ +# Export result files + +!!! abstract "Page contract" + + - **Starting point:** You have the five objects returned by enumeration and + orientation: `spin_only_group`, `spin_space_group`, `adapted`, + `magnetic_structure`, and `magnetic_space_subgroup`. + - **Destination:** You have a spinCIF, an MCIF, or both, plus a basic parse + check. + - **Next:** Apply your downstream calculation's checks to the parsed + structure. + - **Skip:** If the workflow remains entirely in Python. If the format is + undecided, read [Choose an output format](file-formats.md) first. + +## Write spinCIF + +Use the orientation-aware constructor for a structure returned by +`generate_oriented()`. It applies the same orientation to the stored spin +operations: + +```python +from spinforge.scif import SpinCifWriter + +spin_cif = SpinCifWriter.from_oriented( + adapted, + spin_space_group, + magnetic_structure, + magnetic_space_subgroup, + spin_only_group=spin_only_group, +) +spin_cif.write_file("candidate.scif") +``` + +Do not replace this with the plain `SpinCifWriter(...)` constructor for an +oriented result; that constructor expects magnetic moments in the original +enumeration frame. + +## Write MCIF + +The oriented `magnetic_structure` already contains Cartesian moments in its +`magmom` site property: + +```python +from spinforge.mcif import MCifWriter + +MCifWriter(magnetic_structure).write_file("candidate.mcif") +``` + +Pass `symprec` or `mag_symprec` to `MCifWriter` when the default symmetry-search +tolerances are unsuitable for the structure. + +## Check the files + +Parse the spinCIF with SpinForge and expand its asymmetric unit: + +```python +from spinforge.scif import SpinCifReader + +spin_structure = SpinCifReader.from_file("candidate.scif").get_structure() +``` + +Parse the MCIF with pymatgen: + +```python +from pymatgen.core import Structure + +magnetic_structure_from_file = Structure.from_file("candidate.mcif") +``` + +A successful parse catches syntax and expansion errors. Add application-level +checks for composition, lattice, positions, and moment vectors before using a +round-tripped structure in a calculation. diff --git a/docs/file-formats.md b/docs/file-formats.md new file mode 100644 index 0000000..5157888 --- /dev/null +++ b/docs/file-formats.md @@ -0,0 +1,40 @@ +# Choose an output format + +!!! abstract "Page contract" + + - **Starting point:** You have an oriented magnetic structure but have not + chosen a file representation. + - **Destination:** You know which format preserves the object needed by the + next tool. + - **Next:** Write and check it with + [Export result files](export-files.md). + - **Skip:** If the workflow remains entirely in Python. + +| Choose | When you need to preserve | SpinForge interface | +|---|---|---| +| spinCIF (`.scif`) | The spin space group, including independent spatial and spin operations | [`SpinCifWriter`][spinforge.scif.SpinCifWriter] and [`SpinCifReader`][spinforge.scif.SpinCifReader] | +| MCIF (`.mcif`) | The magnetic space group of one oriented magnetic structure in BNS/MAGNDATA convention | [`MCifWriter`][spinforge.mcif.MCifWriter] | + +The distinction is about symmetry, not only filename syntax. A spinCIF records +the spin-space description carried by a SpinForge result. An MCIF +records the magnetic space group that `MCifWriter` identifies from the +oriented structure and its Cartesian `magmom` site property. + +Choose spinCIF when another calculation or archive needs the spin-space-group +description. Choose MCIF when the consumer understands conventional magnetic +crystallographic symmetry but not spin-space symmetry. You can write both when +you need both representations. + +## Format limits + +- The spinCIF dictionary is preliminary. SpinForge stamps the supported draft + revision, [`SPINCIF_REVISION`][spinforge.scif.SPINCIF_REVISION], into each + file. The reader supports files written by SpinForge and the FINDSPINGROUP + reference files; it is not a general-purpose spinCIF parser. +- MCIF output supports partial occupancy of a single species at a site. It does + not support mixed solid-solution sites because those sites cannot pass + through the symmetry identification used by the writer. + +To write and check either format, continue to [Export result files](export-files.md). +For the scientific relation between spin and magnetic symmetry, see the +[SpinForge article](https://doi.org/10.1103/8n3w-h2t1). diff --git a/docs/index.md b/docs/index.md new file mode 100644 index 0000000..bd2f484 --- /dev/null +++ b/docs/index.md @@ -0,0 +1,97 @@ +--- +hide: + - toc +--- + +# Forge magnetic structures from symmetry + +SpinForge generates spin-symmetry-adapted and oriented magnetic crystal +structures from crystallographic symmetry. Use this page to choose a route +based on what you already know and what you need to do. + +[Choose a route](#choose-your-route){ .md-button .md-button--primary } +[Install SpinForge](installation.md){ .md-button } + +!!! note "Project scope" + + SpinForge generates symmetry-compatible candidates. It does not determine + or refine a magnetic structure from experimental or first-principles data. + +## Choose your route + +You do not need to read the documentation from beginning to end. Each route +below states its prerequisite, reading order, and destination. Follow one route +until it meets your goal, then stop or branch to another. + +
+ +- :material-compass-outline:{ .lg .middle } **Understand the model** + + --- + + **Start here if:** SpinForge's domain vocabulary or representation of a + magnetic structure is new to you. + + **Read:** [Domain model](domain-model.md) → + [Classification model](classification-model.md) + + **You will be able to:** explain what SpinForge represents, which stages it + distinguishes, and why different equivalence relations produce different + candidate sets. + + **You can skip:** installation, tutorials, and API details if you only need + the conceptual model. + +- :material-school-outline:{ .lg .middle } **Learn SpinForge** + + --- + + **Start here if:** you know the magnetic-crystallography concepts and are + new to the package. + + **Read:** [Installation](installation.md) → + [Your first structure](quickstart.md) → [Examples](examples.md) + + **You will be able to:** install SpinForge, enumerate a first set of + candidates, and inspect the result. + + **You can skip:** the conceptual route when its terminology is already + familiar. Return to the classification model if a result count or grouping + is unexpected. + +- :material-tools:{ .lg .middle } **Complete a task** + + --- + + **Start here if:** SpinForge is installed and you can already run a basic + enumeration. + + **Go directly to:** [Control enumeration](control-enumeration.md), + [Use propagation vectors](propagation-vectors.md), or + [Export files](export-files.md). + + **You will be able to:** change the search and equivalence settings or + write the selected candidates for downstream use. + + **You can skip:** the tutorial and unrelated task guides. + +- :material-code-braces:{ .lg .middle } **Check exact behavior** + + --- + + **Start here if:** you are implementing against SpinForge or verifying an + exact contract. + + **Go directly to:** [Enumeration and equivalence](equivalence.md), + [File formats](file-formats.md), or the relevant + [API reference](api/configuration.md). Consult the + [Classification model](classification-model.md) when the meaning of a + returned object or equivalence relation matters. + + **You will be able to:** confirm signatures, return types, object + relationships, and classification semantics. + + **You can skip:** tutorials and task guides when you already know which API + surface you need. + +
diff --git a/docs/installation.md b/docs/installation.md new file mode 100644 index 0000000..5b65277 --- /dev/null +++ b/docs/installation.md @@ -0,0 +1,70 @@ +# Installation + +SpinForge supports Python 3.11 and later. + +!!! abstract "Page contract" + + - **Starting point:** You have Python 3.11 or later and can run commands in a + terminal. + - **Destination:** SpinForge imports successfully and you are ready to run + an example. + - **Next:** Follow [Your first structure](quickstart.md). + - **Skip:** The source and documentation sections if you only need the + released Python package. + +## From PyPI + +Create an isolated environment, then install the package: + +=== "uv" + + ```shell + uv venv + uv pip install spinforge + ``` + +=== "pip" + + ```shell + python -m venv .venv + source .venv/bin/activate + python -m pip install spinforge + ``` + +Confirm that the installation is importable: + +```shell +python -c "import spinforge; print('SpinForge is ready')" +``` + +Continue with [Your first structure](quickstart.md). + +## From a source checkout + +Contributors need [uv](https://docs.astral.sh/uv/) and +[just](https://just.systems/): + +```shell +git clone https://github.com/spglib/spinforge.git +cd spinforge +uv sync --dev +uv run prek install +``` + +Run the tests and repository checks before opening a pull request: + +```shell +just test +just prek +``` + +## Build the documentation locally + +The development environment includes Zensical and mkdocstrings: + +```shell +just docs +``` + +This starts a local preview server with live reload. Use `just docs-build` to +run the same strict production build used by GitHub Pages. diff --git a/docs/javascripts/mathjax.js b/docs/javascripts/mathjax.js new file mode 100644 index 0000000..7946497 --- /dev/null +++ b/docs/javascripts/mathjax.js @@ -0,0 +1,23 @@ +window.MathJax = { + tex: { + inlineMath: [["\\(", "\\)"]], + displayMath: [["\\[", "\\]"]], + processEscapes: true, + processEnvironments: true, + }, + options: { + ignoreHtmlClass: ".*|", + processHtmlClass: "arithmatex", + }, +}; + +document$.subscribe(() => { + MathJax.startup.output.clearCache(); + MathJax.typesetClear(); + MathJax.texReset(); + MathJax.typesetPromise(); +}); + +component$.subscribe(({ ref }) => { + if (ref.classList.contains("md-annotation")) MathJax.typesetPromise([ref]); +}); diff --git a/docs/paper/MnTe.cif b/docs/paper/MnTe.cif new file mode 100644 index 0000000..9f56350 --- /dev/null +++ b/docs/paper/MnTe.cif @@ -0,0 +1,56 @@ +# generated using pymatgen +data_MnTe +_symmetry_space_group_name_H-M P6_3/mmc +_cell_length_a 4.17349018 +_cell_length_b 4.17349018 +_cell_length_c 6.75345133 +_cell_angle_alpha 90.00000000 +_cell_angle_beta 90.00000000 +_cell_angle_gamma 120.00000000 +_symmetry_Int_Tables_number 194 +_chemical_formula_structural MnTe +_chemical_formula_sum 'Mn2 Te2' +_cell_volume 101.87208560 +_cell_formula_units_Z 2 +loop_ + _symmetry_equiv_pos_site_id + _symmetry_equiv_pos_as_xyz + 1 'x, y, z' + 2 '-x, -y, -z' + 3 'x-y, x, z+1/2' + 4 '-x+y, -x, -z+1/2' + 5 '-y, x-y, z' + 6 'y, -x+y, -z' + 7 '-x, -y, z+1/2' + 8 'x, y, -z+1/2' + 9 '-x+y, -x, z' + 10 'x-y, x, -z' + 11 'y, -x+y, z+1/2' + 12 '-y, x-y, -z+1/2' + 13 '-y, -x, -z+1/2' + 14 'y, x, z+1/2' + 15 '-x, -x+y, -z' + 16 'x, x-y, z' + 17 '-x+y, y, -z+1/2' + 18 'x-y, -y, z+1/2' + 19 'y, x, -z' + 20 '-y, -x, z' + 21 'x, x-y, -z+1/2' + 22 '-x, -x+y, z+1/2' + 23 'x-y, -y, -z' + 24 '-x+y, y, z' +loop_ + _atom_type_symbol + _atom_type_oxidation_number + Mn2+ 2.0 + Te2- -2.0 +loop_ + _atom_site_type_symbol + _atom_site_label + _atom_site_symmetry_multiplicity + _atom_site_fract_x + _atom_site_fract_y + _atom_site_fract_z + _atom_site_occupancy + Mn2+ Mn0 2 0.00000000 0.00000000 0.00000000 1 + Te2- Te1 2 0.33333333 0.66666667 0.25000000 1 diff --git a/examples/paper/collinear_MnTe/collinear_MnTe.ipynb b/docs/paper/collinear_MnTe.ipynb similarity index 100% rename from examples/paper/collinear_MnTe/collinear_MnTe.ipynb rename to docs/paper/collinear_MnTe.ipynb diff --git a/examples/paper/coplanar_Mn3Sn/Mn3Sn.ipynb b/docs/paper/coplanar_Mn3Sn.ipynb similarity index 100% rename from examples/paper/coplanar_Mn3Sn/Mn3Sn.ipynb rename to docs/paper/coplanar_Mn3Sn.ipynb diff --git a/examples/paper/noncoplanar_CoTa3S6/CoTa3S6.ipynb b/docs/paper/noncoplanar_CoTa3S6.ipynb similarity index 100% rename from examples/paper/noncoplanar_CoTa3S6/CoTa3S6.ipynb rename to docs/paper/noncoplanar_CoTa3S6.ipynb diff --git a/docs/propagation-vectors.md b/docs/propagation-vectors.md new file mode 100644 index 0000000..a326f06 --- /dev/null +++ b/docs/propagation-vectors.md @@ -0,0 +1,80 @@ +# Constrain an enumeration with propagation vectors + +!!! abstract "Page contract" + + - **Starting point:** One or more commensurate propagation vectors and the + magnetic sites are known in the input structure's setting. + - **Destination:** Your `SSAGenerator` uses their common translation lattice + as its bound. + - **Next:** Enumerate and orient candidates as in + [Your first structure](quickstart.md). + - **Skip:** When no propagation vector is known, choose `k_index` in + [Control an enumeration](control-enumeration.md) instead. + +## Construct the generator in the input frame + +For vectors reported with an experimental CIF, keep the structure and vectors +in that CIF's setting and use `k_frame="input"`: + +```python +import numpy as np +from moyopy import Cell +from pymatgen.core import Structure +from spinforge.configuration import SSAGenerator +from spinspg.spin import SpinOnlyGroupType + +structure = Structure.from_file("input.cif") +cell = Cell( + basis=structure.lattice.matrix.tolist(), + positions=structure.frac_coords.tolist(), + numbers=list(structure.atomic_numbers), +) +magnetic_site_indices = [ + index + for index, atomic_number in enumerate(cell.numbers) + if atomic_number == 25 +] + +generator = SSAGenerator.with_propagation_vectors( + cell=cell, + propagation_vectors=[np.array([0.0, 0.0, 0.5])], + magnetic_site_indices=magnetic_site_indices, + k_frame="input", +) + +candidates = generator.enumerate( + spin_only_group_type=SpinOnlyGroupType.COLLINEAR, +) +``` + +Replace the atomic-number selection with the magnetic species or sites in your +system. Site indices must refer to the exact `cell` passed to +`with_propagation_vectors()`. + +SpinForge standardizes the cell, transforms the vectors to its primitive +standardized setting, and logs each vector in both frames. It derives the +translation index automatically. Do not pass a different `k_index` to +`enumerate()`; an explicit value must equal the derived index. + +## Use the standardized frame only when it is already known + +Set `k_frame="prim_std"` only when the supplied vectors are already expressed +in moyopy's primitive standardized setting. They are then used as-is. + +## Diagnose an empty result + +If enumeration returns no candidates: + +1. Compare the input and standardized vectors in the construction log. A + surprising permutation or value usually indicates that the vector and cell + came from different settings. +2. Confirm that the chosen spin-only-group type can realize the translation + quotient. For example, a collinear spin-only group can realize only the + identity and spin-flip quotient. +3. Try `COPLANAR` or `NONCOPLANAR` only if that moment geometry is physically + part of the intended search. + +The translation lattice is the common commensurate lattice of the supplied +vectors. For its derivation and the surrounding classification, see the +[SpinForge article](https://doi.org/10.1103/8n3w-h2t1); the operational API +details are in [`SSAGenerator.with_propagation_vectors()`][spinforge.configuration.SSAGenerator.with_propagation_vectors]. diff --git a/docs/quickstart.md b/docs/quickstart.md new file mode 100644 index 0000000..4baf56b --- /dev/null +++ b/docs/quickstart.md @@ -0,0 +1,105 @@ +# Your first structure + +This walkthrough enumerates collinear spin-symmetry-adapted structures for +MnTe and then generates their oriented descendants. + +!!! abstract "Page contract" + + - **Starting point:** SpinForge is [installed](installation.md), and you can + identify a primitive crystal cell and its magnetic sites. + - **Destination:** You can run one bounded enumeration and inspect its + oriented structures. + - **Skip:** The formal derivation and physical interpretation; those belong + to the [associated article](https://doi.org/10.1103/8n3w-h2t1). + +## 1. Prepare a primitive cell + +SpinForge accepts a +[`moyopy.Cell`](https://spglib.github.io/moyo/python/api/#moyopy.Cell). The direct constructor of +[`SSAGenerator`][spinforge.configuration.SSAGenerator] requires the cell to be +primitive. + +```python +from moyopy.interface import MoyoAdapter +from pymatgen.core import Structure + +structure = Structure.from_file("MnTe.cif") +primitive_cell = MoyoAdapter.from_structure(structure) +``` + +Select the magnetic sites by their indices in that cell. Here manganese has +atomic number 25: + +```python +magnetic_site_indices = [ + index + for index, atomic_number in enumerate(primitive_cell.numbers) + if atomic_number == 25 +] +``` + +!!! warning "Site indices follow the cell" + + If you transform, standardize, or reorder the cell, recompute the site + indices. They refer to the exact `Cell` passed to the generator. + +## 2. Enumerate SSA structures + +```python +from spinforge.configuration import SSAGenerator +from spinspg.spin import SpinOnlyGroupType + +generator = SSAGenerator( + prim_cell=primitive_cell, + magnetic_site_indices=magnetic_site_indices, +) + +candidates = generator.enumerate( + spin_only_group_type=SpinOnlyGroupType.COLLINEAR, + k_index=1, + max_depth=0, +) +``` + +`k_index=1` limits the invariant translation lattice to the primitive lattice. +`max_depth=0` retains the parent as the only Hermann group while still allowing +the bounded descendants described in the +[enumeration guide](equivalence.md#enumerate-parameters). + +Each result contains: + +1. the trivial spin-only group; +2. the nontrivial spin space group; +3. a [`SpinSymmetryAdaptedStructure`][spinforge.configuration.SpinSymmetryAdaptedStructure] + containing a supercell and a basis for allowed magnetic moments. + +## 3. Generate oriented structures + +```python +for spin_only_group, spin_space_group, adapted in candidates: + descendants = generator.generate_oriented( + adapted, + spin_only_group=spin_only_group, + nontrivial_spin_space_group=spin_space_group, + ) + + for magnetic_structure, magnetic_space_subgroup in descendants: + print( + magnetic_structure.formula, + magnetic_space_subgroup.msg_type, + ) +``` + +`magnetic_structure` is a pymatgen `Structure` whose `magmom` site property +contains Cartesian moment vectors. By default, coplanar enantiomorphs are kept +distinct. Pass `preserve_spin_planochirality=False` to identify structures +related by improper spin-frame transformations. + +## Next steps + +- Compare the three supported spin-only-group workflows in + [Examples](examples.md). +- Use measured or calculated propagation vectors to constrain the translation + lattice in the [propagation-vector guide](propagation-vectors.md). +- Read [Control enumeration](control-enumeration.md) before expanding a search. +- Export a result with [Export files](export-files.md). diff --git a/docs/stylesheets/extra.css b/docs/stylesheets/extra.css new file mode 100644 index 0000000..11f943f --- /dev/null +++ b/docs/stylesheets/extra.css @@ -0,0 +1,72 @@ +:root { + --md-primary-fg-color: #4f3f91; + --md-primary-fg-color--light: #7768b5; + --md-primary-fg-color--dark: #362a69; + --md-accent-fg-color: #df3c43; +} + +[data-md-color-scheme="slate"] { + --md-hue: 244; + --md-default-bg-color: hsla(var(--md-hue), 15%, 12%, 1); + --md-code-bg-color: hsla(var(--md-hue), 18%, 16%, 1); +} + +.md-typeset h1 { + font-weight: 700; + letter-spacing: -0.025em; +} + +.md-typeset .grid.cards > ul > li { + border-radius: 0.6rem; + transition: + border-color 180ms, + box-shadow 180ms, + transform 180ms; +} + +.md-typeset .grid.cards > ul > li:hover { + border-color: var(--md-accent-fg-color); + box-shadow: 0 0.35rem 1rem rgb(0 0 0 / 10%); + transform: translateY(-2px); +} + +.md-typeset .route-grid > ul { + grid-template-columns: repeat(2, minmax(0, 1fr)); + gap: 1rem; +} + +.md-typeset .route-grid > ul > li { + min-height: 17rem; + padding: 1.25rem 1.4rem; +} + +.md-typeset .route-grid > ul > li > p:first-child { + font-size: 1.05rem; +} + +@media screen and (max-width: 44.9844em) { + .md-typeset .route-grid > ul { + grid-template-columns: 1fr; + } + + .md-typeset .route-grid > ul > li { + min-height: auto; + } +} + +.md-typeset .md-button { + border-radius: 2rem; +} + +.md-typeset table:not([class]) th { + background: color-mix(in srgb, var(--md-primary-fg-color) 12%, transparent); +} + +.md-typeset .paper-figure { + display: block; + width: 100%; + height: auto; + margin: 1rem auto 1.25rem; + border: 1px solid var(--md-default-fg-color--lightest); + border-radius: 0.4rem; +} diff --git a/justfile b/justfile index e947af7..66bd217 100644 --- a/justfile +++ b/justfile @@ -11,6 +11,12 @@ install: uv sync --dev uv run prek install +docs: + uv run zensical serve + +docs-build: + uv run zensical build --clean --strict + test *args: OMP_NUM_THREADS=1 OPENBLAS_NUM_THREADS=1 MKL_NUM_THREADS=1 uv run pytest -v -n 4 --dist load --maxschedchunk=1 "$@" diff --git a/pyproject.toml b/pyproject.toml index f61473d..7dc7234 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -43,8 +43,13 @@ optional-dependencies.dev = [ "ipykernel", "prek", "setuptools-scm>=8.2", + "spinforge[docs]", "spinforge[testing]", ] +optional-dependencies.docs = [ + "mkdocstrings-python>=2", + "zensical>=0.0.46", +] optional-dependencies.testing = [ "pytest", "pytest-split", diff --git a/uv.lock b/uv.lock index c3074de..affa58e 100644 --- a/uv.lock +++ b/uv.lock @@ -310,6 +310,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/cc/61/d01fc49b8dea277640b55a9e15960dbca9fdc8c9fde18e572d39c59f4019/charset_normalizer-3.5.1-py3-none-any.whl", hash = "sha256:6df0ec430f9a831772c23ca5a224cba36517a58a84bb32c32bb59a9fa67c47f6", size = 68658, upload-time = "2026-08-15T08:20:43.306Z" }, ] +[[package]] +name = "click" +version = "8.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/0e/7fa0ef50764b67090eca4114772a2abf8b6148198475e54c660b97caeee6/click-8.5.0.tar.gz", hash = "sha256:ba0d2089de75ea0310e2dde03160e6ca10009947fb95a182f9b54021bb272e34", size = 382235, upload-time = "2026-08-26T13:33:14.56Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/58/50/6c0d534c5f134586a8e1ba4e330569e32f057e33372ae556463212fb4cd3/click-8.5.0-py3-none-any.whl", hash = "sha256:255bc9599cf7748b4b1a446ccc735421bd08a2ae529a8b88597d3de5664ee360", size = 125251, upload-time = "2026-08-26T13:33:12.928Z" }, +] + [[package]] name = "cloudpickle" version = "3.1.2" @@ -454,6 +463,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/95/51/67e7cf11a53e40694f720457d5b3a1cdaaa3d5a9a633e482f225456b93ff/debugpy-1.8.21-py2.py3-none-any.whl", hash = "sha256:b1e37d333663c8851516a47364ef473da127f9caebe4417e6df6f5825a7e9a92", size = 5352888, upload-time = "2026-06-01T19:31:25.186Z" }, ] +[[package]] +name = "deepmerge" +version = "3.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/38/6e/5cb3548b4d3112fea529375e55e6f3cdc52b8054e3a66f203b1f888ba885/deepmerge-3.0.1.tar.gz", hash = "sha256:35b39a4cb92cf328d6eca61cbbf65f68a37c2ceb3085f0f853cbb2e52a59fc23", size = 22328, upload-time = "2026-09-01T14:09:44.383Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/91/600003aaad107e27553fbc9cbfc57e96fa37e0223d2ef9d7d3a0e8d8d070/deepmerge-3.0.1-py3-none-any.whl", hash = "sha256:35c96f6a68fcf90719a5b31d9f8042ecef6c00fb56836660d33455d0f5cfda65", size = 14909, upload-time = "2026-09-01T14:09:43.364Z" }, +] + [[package]] name = "execnet" version = "2.1.2" @@ -537,6 +555,27 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/82/f8/7188153c4b265c899cd035de6a062677d51f67118a4ba640902bd9683e90/fonttools-4.64.0-py3-none-any.whl", hash = "sha256:4a05783ff54ce4c7a28f18e5772efdf63c219374bd9ffc55452182e1cef8be60", size = 1195327, upload-time = "2026-08-31T15:44:31.741Z" }, ] +[[package]] +name = "ghp-import" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "python-dateutil" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d9/29/d40217cbe2f6b1359e00c6c307bb3fc876ba74068cbab3dde77f03ca0dc4/ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343", size = 10943, upload-time = "2022-05-02T15:47:16.11Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619", size = 11034, upload-time = "2022-05-02T15:47:14.552Z" }, +] + +[[package]] +name = "griffelib" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/27/af/018c10bc9edd42b6ef6db2e96b09542050d5253f9b195e74bc910b2d13ab/griffelib-2.3.0.tar.gz", hash = "sha256:7b0952caf5bca6afa4bb5ee8c6a2d183fe3f21b62efc5f6c7243cb2b26d2d115", size = 234534, upload-time = "2026-09-04T15:08:17.472Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/41/63/e876e789525063c840ccfa8857febdabd6523bcef9ce7eb979b9305ea895/griffelib-2.3.0-py3-none-any.whl", hash = "sha256:1b8f9cd525681c26b1d6d574faa1371651e8459ca51d209684f50b8096ae06e0", size = 169423, upload-time = "2026-09-04T15:08:12.956Z" }, +] + [[package]] name = "hsnf" version = "0.4.0" @@ -643,6 +682,18 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/9a/93/242e2eab5fe682ffcb8b0084bde703a41d51e17ee0f3a31ff0d9d813620a/jedi-0.20.0-py2.py3-none-any.whl", hash = "sha256:7bdd9c2634f56713299976f4cbd59cb3fa92165cc5e05ea811fb253480728b67", size = 4884812, upload-time = "2026-05-01T23:38:43.919Z" }, ] +[[package]] +name = "jinja2" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, +] + [[package]] name = "joblib" version = "1.6.0" @@ -960,6 +1011,89 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/03/5c/91fe48856f9f8089be3096fa4dbe4b3fb5526f3bf3e852ea9497f399cb9f/lxml-6.1.3-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:bc8dd3d9c93e70c3df974a201ac2958b6d77b465d813c51d1f15fa8e645763ae", size = 3511258, upload-time = "2026-09-02T14:46:49.046Z" }, ] +[[package]] +name = "markdown" +version = "3.10.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/29/6f/da4c6aea59b3001f2e8c0ec7497475aadaf3b021c10cab5b2858f0f32b26/markdown-3.10.3.tar.gz", hash = "sha256:3589362618f743188b4d955b874402bc814f4f83f544dc207719f4baa7d9c45f", size = 372596, upload-time = "2026-07-30T19:05:29.005Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/69/4a5af2bc115a9a33fefe51709749de8262be3f9ba063d1753a837cdbc49c/markdown-3.10.3-py3-none-any.whl", hash = "sha256:fa6c92a00a4a3c98b22728c64a935ae1928250ae65058a6ded814d2cc29a4cea", size = 110757, upload-time = "2026-07-30T19:05:27.883Z" }, +] + +[[package]] +name = "markupsafe" +version = "3.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7e/99/7690b6d4034fffd95959cbe0c02de8deb3098cc577c67bb6a24fe5d7caa7/markupsafe-3.0.3.tar.gz", hash = "sha256:722695808f4b6457b320fdc131280796bdceb04ab50fe1795cd540799ebe1698", size = 80313, upload-time = "2025-09-27T18:37:40.426Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/08/db/fefacb2136439fc8dd20e797950e749aa1f4997ed584c62cfb8ef7c2be0e/markupsafe-3.0.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1cc7ea17a6824959616c525620e387f6dd30fec8cb44f649e31712db02123dad", size = 11631, upload-time = "2025-09-27T18:36:18.185Z" }, + { url = "https://files.pythonhosted.org/packages/e1/2e/5898933336b61975ce9dc04decbc0a7f2fee78c30353c5efba7f2d6ff27a/markupsafe-3.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bd4cd07944443f5a265608cc6aab442e4f74dff8088b0dfc8238647b8f6ae9a", size = 12058, upload-time = "2025-09-27T18:36:19.444Z" }, + { url = "https://files.pythonhosted.org/packages/1d/09/adf2df3699d87d1d8184038df46a9c80d78c0148492323f4693df54e17bb/markupsafe-3.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b5420a1d9450023228968e7e6a9ce57f65d148ab56d2313fcd589eee96a7a50", size = 24287, upload-time = "2025-09-27T18:36:20.768Z" }, + { url = "https://files.pythonhosted.org/packages/30/ac/0273f6fcb5f42e314c6d8cd99effae6a5354604d461b8d392b5ec9530a54/markupsafe-3.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0bf2a864d67e76e5c9a34dc26ec616a66b9888e25e7b9460e1c76d3293bd9dbf", size = 22940, upload-time = "2025-09-27T18:36:22.249Z" }, + { url = "https://files.pythonhosted.org/packages/19/ae/31c1be199ef767124c042c6c3e904da327a2f7f0cd63a0337e1eca2967a8/markupsafe-3.0.3-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:bc51efed119bc9cfdf792cdeaa4d67e8f6fcccab66ed4bfdd6bde3e59bfcbb2f", size = 21887, upload-time = "2025-09-27T18:36:23.535Z" }, + { url = "https://files.pythonhosted.org/packages/b2/76/7edcab99d5349a4532a459e1fe64f0b0467a3365056ae550d3bcf3f79e1e/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:068f375c472b3e7acbe2d5318dea141359e6900156b5b2ba06a30b169086b91a", size = 23692, upload-time = "2025-09-27T18:36:24.823Z" }, + { url = "https://files.pythonhosted.org/packages/a4/28/6e74cdd26d7514849143d69f0bf2399f929c37dc2b31e6829fd2045b2765/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:7be7b61bb172e1ed687f1754f8e7484f1c8019780f6f6b0786e76bb01c2ae115", size = 21471, upload-time = "2025-09-27T18:36:25.95Z" }, + { url = "https://files.pythonhosted.org/packages/62/7e/a145f36a5c2945673e590850a6f8014318d5577ed7e5920a4b3448e0865d/markupsafe-3.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f9e130248f4462aaa8e2552d547f36ddadbeaa573879158d721bbd33dfe4743a", size = 22923, upload-time = "2025-09-27T18:36:27.109Z" }, + { url = "https://files.pythonhosted.org/packages/0f/62/d9c46a7f5c9adbeeeda52f5b8d802e1094e9717705a645efc71b0913a0a8/markupsafe-3.0.3-cp311-cp311-win32.whl", hash = "sha256:0db14f5dafddbb6d9208827849fad01f1a2609380add406671a26386cdf15a19", size = 14572, upload-time = "2025-09-27T18:36:28.045Z" }, + { url = "https://files.pythonhosted.org/packages/83/8a/4414c03d3f891739326e1783338e48fb49781cc915b2e0ee052aa490d586/markupsafe-3.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:de8a88e63464af587c950061a5e6a67d3632e36df62b986892331d4620a35c01", size = 15077, upload-time = "2025-09-27T18:36:29.025Z" }, + { url = "https://files.pythonhosted.org/packages/35/73/893072b42e6862f319b5207adc9ae06070f095b358655f077f69a35601f0/markupsafe-3.0.3-cp311-cp311-win_arm64.whl", hash = "sha256:3b562dd9e9ea93f13d53989d23a7e775fdfd1066c33494ff43f5418bc8c58a5c", size = 13876, upload-time = "2025-09-27T18:36:29.954Z" }, + { url = "https://files.pythonhosted.org/packages/5a/72/147da192e38635ada20e0a2e1a51cf8823d2119ce8883f7053879c2199b5/markupsafe-3.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d53197da72cc091b024dd97249dfc7794d6a56530370992a5e1a08983ad9230e", size = 11615, upload-time = "2025-09-27T18:36:30.854Z" }, + { url = "https://files.pythonhosted.org/packages/9a/81/7e4e08678a1f98521201c3079f77db69fb552acd56067661f8c2f534a718/markupsafe-3.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1872df69a4de6aead3491198eaf13810b565bdbeec3ae2dc8780f14458ec73ce", size = 12020, upload-time = "2025-09-27T18:36:31.971Z" }, + { url = "https://files.pythonhosted.org/packages/1e/2c/799f4742efc39633a1b54a92eec4082e4f815314869865d876824c257c1e/markupsafe-3.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a7e8ae81ae39e62a41ec302f972ba6ae23a5c5396c8e60113e9066ef893da0d", size = 24332, upload-time = "2025-09-27T18:36:32.813Z" }, + { url = "https://files.pythonhosted.org/packages/3c/2e/8d0c2ab90a8c1d9a24f0399058ab8519a3279d1bd4289511d74e909f060e/markupsafe-3.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d6dd0be5b5b189d31db7cda48b91d7e0a9795f31430b7f271219ab30f1d3ac9d", size = 22947, upload-time = "2025-09-27T18:36:33.86Z" }, + { url = "https://files.pythonhosted.org/packages/2c/54/887f3092a85238093a0b2154bd629c89444f395618842e8b0c41783898ea/markupsafe-3.0.3-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:94c6f0bb423f739146aec64595853541634bde58b2135f27f61c1ffd1cd4d16a", size = 21962, upload-time = "2025-09-27T18:36:35.099Z" }, + { url = "https://files.pythonhosted.org/packages/c9/2f/336b8c7b6f4a4d95e91119dc8521402461b74a485558d8f238a68312f11c/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:be8813b57049a7dc738189df53d69395eba14fb99345e0a5994914a3864c8a4b", size = 23760, upload-time = "2025-09-27T18:36:36.001Z" }, + { url = "https://files.pythonhosted.org/packages/32/43/67935f2b7e4982ffb50a4d169b724d74b62a3964bc1a9a527f5ac4f1ee2b/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:83891d0e9fb81a825d9a6d61e3f07550ca70a076484292a70fde82c4b807286f", size = 21529, upload-time = "2025-09-27T18:36:36.906Z" }, + { url = "https://files.pythonhosted.org/packages/89/e0/4486f11e51bbba8b0c041098859e869e304d1c261e59244baa3d295d47b7/markupsafe-3.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:77f0643abe7495da77fb436f50f8dab76dbc6e5fd25d39589a0f1fe6548bfa2b", size = 23015, upload-time = "2025-09-27T18:36:37.868Z" }, + { url = "https://files.pythonhosted.org/packages/2f/e1/78ee7a023dac597a5825441ebd17170785a9dab23de95d2c7508ade94e0e/markupsafe-3.0.3-cp312-cp312-win32.whl", hash = "sha256:d88b440e37a16e651bda4c7c2b930eb586fd15ca7406cb39e211fcff3bf3017d", size = 14540, upload-time = "2025-09-27T18:36:38.761Z" }, + { url = "https://files.pythonhosted.org/packages/aa/5b/bec5aa9bbbb2c946ca2733ef9c4ca91c91b6a24580193e891b5f7dbe8e1e/markupsafe-3.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:26a5784ded40c9e318cfc2bdb30fe164bdb8665ded9cd64d500a34fb42067b1c", size = 15105, upload-time = "2025-09-27T18:36:39.701Z" }, + { url = "https://files.pythonhosted.org/packages/e5/f1/216fc1bbfd74011693a4fd837e7026152e89c4bcf3e77b6692fba9923123/markupsafe-3.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:35add3b638a5d900e807944a078b51922212fb3dedb01633a8defc4b01a3c85f", size = 13906, upload-time = "2025-09-27T18:36:40.689Z" }, + { url = "https://files.pythonhosted.org/packages/38/2f/907b9c7bbba283e68f20259574b13d005c121a0fa4c175f9bed27c4597ff/markupsafe-3.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e1cf1972137e83c5d4c136c43ced9ac51d0e124706ee1c8aa8532c1287fa8795", size = 11622, upload-time = "2025-09-27T18:36:41.777Z" }, + { url = "https://files.pythonhosted.org/packages/9c/d9/5f7756922cdd676869eca1c4e3c0cd0df60ed30199ffd775e319089cb3ed/markupsafe-3.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:116bb52f642a37c115f517494ea5feb03889e04df47eeff5b130b1808ce7c219", size = 12029, upload-time = "2025-09-27T18:36:43.257Z" }, + { url = "https://files.pythonhosted.org/packages/00/07/575a68c754943058c78f30db02ee03a64b3c638586fba6a6dd56830b30a3/markupsafe-3.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:133a43e73a802c5562be9bbcd03d090aa5a1fe899db609c29e8c8d815c5f6de6", size = 24374, upload-time = "2025-09-27T18:36:44.508Z" }, + { url = "https://files.pythonhosted.org/packages/a9/21/9b05698b46f218fc0e118e1f8168395c65c8a2c750ae2bab54fc4bd4e0e8/markupsafe-3.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ccfcd093f13f0f0b7fdd0f198b90053bf7b2f02a3927a30e63f3ccc9df56b676", size = 22980, upload-time = "2025-09-27T18:36:45.385Z" }, + { url = "https://files.pythonhosted.org/packages/7f/71/544260864f893f18b6827315b988c146b559391e6e7e8f7252839b1b846a/markupsafe-3.0.3-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:509fa21c6deb7a7a273d629cf5ec029bc209d1a51178615ddf718f5918992ab9", size = 21990, upload-time = "2025-09-27T18:36:46.916Z" }, + { url = "https://files.pythonhosted.org/packages/c2/28/b50fc2f74d1ad761af2f5dcce7492648b983d00a65b8c0e0cb457c82ebbe/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4afe79fb3de0b7097d81da19090f4df4f8d3a2b3adaa8764138aac2e44f3af1", size = 23784, upload-time = "2025-09-27T18:36:47.884Z" }, + { url = "https://files.pythonhosted.org/packages/ed/76/104b2aa106a208da8b17a2fb72e033a5a9d7073c68f7e508b94916ed47a9/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:795e7751525cae078558e679d646ae45574b47ed6e7771863fcc079a6171a0fc", size = 21588, upload-time = "2025-09-27T18:36:48.82Z" }, + { url = "https://files.pythonhosted.org/packages/b5/99/16a5eb2d140087ebd97180d95249b00a03aa87e29cc224056274f2e45fd6/markupsafe-3.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8485f406a96febb5140bfeca44a73e3ce5116b2501ac54fe953e488fb1d03b12", size = 23041, upload-time = "2025-09-27T18:36:49.797Z" }, + { url = "https://files.pythonhosted.org/packages/19/bc/e7140ed90c5d61d77cea142eed9f9c303f4c4806f60a1044c13e3f1471d0/markupsafe-3.0.3-cp313-cp313-win32.whl", hash = "sha256:bdd37121970bfd8be76c5fb069c7751683bdf373db1ed6c010162b2a130248ed", size = 14543, upload-time = "2025-09-27T18:36:51.584Z" }, + { url = "https://files.pythonhosted.org/packages/05/73/c4abe620b841b6b791f2edc248f556900667a5a1cf023a6646967ae98335/markupsafe-3.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:9a1abfdc021a164803f4d485104931fb8f8c1efd55bc6b748d2f5774e78b62c5", size = 15113, upload-time = "2025-09-27T18:36:52.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/3a/fa34a0f7cfef23cf9500d68cb7c32dd64ffd58a12b09225fb03dd37d5b80/markupsafe-3.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:7e68f88e5b8799aa49c85cd116c932a1ac15caaa3f5db09087854d218359e485", size = 13911, upload-time = "2025-09-27T18:36:53.513Z" }, + { url = "https://files.pythonhosted.org/packages/e4/d7/e05cd7efe43a88a17a37b3ae96e79a19e846f3f456fe79c57ca61356ef01/markupsafe-3.0.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:218551f6df4868a8d527e3062d0fb968682fe92054e89978594c28e642c43a73", size = 11658, upload-time = "2025-09-27T18:36:54.819Z" }, + { url = "https://files.pythonhosted.org/packages/99/9e/e412117548182ce2148bdeacdda3bb494260c0b0184360fe0d56389b523b/markupsafe-3.0.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:3524b778fe5cfb3452a09d31e7b5adefeea8c5be1d43c4f810ba09f2ceb29d37", size = 12066, upload-time = "2025-09-27T18:36:55.714Z" }, + { url = "https://files.pythonhosted.org/packages/bc/e6/fa0ffcda717ef64a5108eaa7b4f5ed28d56122c9a6d70ab8b72f9f715c80/markupsafe-3.0.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e885a3d1efa2eadc93c894a21770e4bc67899e3543680313b09f139e149ab19", size = 25639, upload-time = "2025-09-27T18:36:56.908Z" }, + { url = "https://files.pythonhosted.org/packages/96/ec/2102e881fe9d25fc16cb4b25d5f5cde50970967ffa5dddafdb771237062d/markupsafe-3.0.3-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8709b08f4a89aa7586de0aadc8da56180242ee0ada3999749b183aa23df95025", size = 23569, upload-time = "2025-09-27T18:36:57.913Z" }, + { url = "https://files.pythonhosted.org/packages/4b/30/6f2fce1f1f205fc9323255b216ca8a235b15860c34b6798f810f05828e32/markupsafe-3.0.3-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:b8512a91625c9b3da6f127803b166b629725e68af71f8184ae7e7d54686a56d6", size = 23284, upload-time = "2025-09-27T18:36:58.833Z" }, + { url = "https://files.pythonhosted.org/packages/58/47/4a0ccea4ab9f5dcb6f79c0236d954acb382202721e704223a8aafa38b5c8/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9b79b7a16f7fedff2495d684f2b59b0457c3b493778c9eed31111be64d58279f", size = 24801, upload-time = "2025-09-27T18:36:59.739Z" }, + { url = "https://files.pythonhosted.org/packages/6a/70/3780e9b72180b6fecb83a4814d84c3bf4b4ae4bf0b19c27196104149734c/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:12c63dfb4a98206f045aa9563db46507995f7ef6d83b2f68eda65c307c6829eb", size = 22769, upload-time = "2025-09-27T18:37:00.719Z" }, + { url = "https://files.pythonhosted.org/packages/98/c5/c03c7f4125180fc215220c035beac6b9cb684bc7a067c84fc69414d315f5/markupsafe-3.0.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8f71bc33915be5186016f675cd83a1e08523649b0e33efdb898db577ef5bb009", size = 23642, upload-time = "2025-09-27T18:37:01.673Z" }, + { url = "https://files.pythonhosted.org/packages/80/d6/2d1b89f6ca4bff1036499b1e29a1d02d282259f3681540e16563f27ebc23/markupsafe-3.0.3-cp313-cp313t-win32.whl", hash = "sha256:69c0b73548bc525c8cb9a251cddf1931d1db4d2258e9599c28c07ef3580ef354", size = 14612, upload-time = "2025-09-27T18:37:02.639Z" }, + { url = "https://files.pythonhosted.org/packages/2b/98/e48a4bfba0a0ffcf9925fe2d69240bfaa19c6f7507b8cd09c70684a53c1e/markupsafe-3.0.3-cp313-cp313t-win_amd64.whl", hash = "sha256:1b4b79e8ebf6b55351f0d91fe80f893b4743f104bff22e90697db1590e47a218", size = 15200, upload-time = "2025-09-27T18:37:03.582Z" }, + { url = "https://files.pythonhosted.org/packages/0e/72/e3cc540f351f316e9ed0f092757459afbc595824ca724cbc5a5d4263713f/markupsafe-3.0.3-cp313-cp313t-win_arm64.whl", hash = "sha256:ad2cf8aa28b8c020ab2fc8287b0f823d0a7d8630784c31e9ee5edea20f406287", size = 13973, upload-time = "2025-09-27T18:37:04.929Z" }, + { url = "https://files.pythonhosted.org/packages/33/8a/8e42d4838cd89b7dde187011e97fe6c3af66d8c044997d2183fbd6d31352/markupsafe-3.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:eaa9599de571d72e2daf60164784109f19978b327a3910d3e9de8c97b5b70cfe", size = 11619, upload-time = "2025-09-27T18:37:06.342Z" }, + { url = "https://files.pythonhosted.org/packages/b5/64/7660f8a4a8e53c924d0fa05dc3a55c9cee10bbd82b11c5afb27d44b096ce/markupsafe-3.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:c47a551199eb8eb2121d4f0f15ae0f923d31350ab9280078d1e5f12b249e0026", size = 12029, upload-time = "2025-09-27T18:37:07.213Z" }, + { url = "https://files.pythonhosted.org/packages/da/ef/e648bfd021127bef5fa12e1720ffed0c6cbb8310c8d9bea7266337ff06de/markupsafe-3.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f34c41761022dd093b4b6896d4810782ffbabe30f2d443ff5f083e0cbbb8c737", size = 24408, upload-time = "2025-09-27T18:37:09.572Z" }, + { url = "https://files.pythonhosted.org/packages/41/3c/a36c2450754618e62008bf7435ccb0f88053e07592e6028a34776213d877/markupsafe-3.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:457a69a9577064c05a97c41f4e65148652db078a3a509039e64d3467b9e7ef97", size = 23005, upload-time = "2025-09-27T18:37:10.58Z" }, + { url = "https://files.pythonhosted.org/packages/bc/20/b7fdf89a8456b099837cd1dc21974632a02a999ec9bf7ca3e490aacd98e7/markupsafe-3.0.3-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:e8afc3f2ccfa24215f8cb28dcf43f0113ac3c37c2f0f0806d8c70e4228c5cf4d", size = 22048, upload-time = "2025-09-27T18:37:11.547Z" }, + { url = "https://files.pythonhosted.org/packages/9a/a7/591f592afdc734f47db08a75793a55d7fbcc6902a723ae4cfbab61010cc5/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec15a59cf5af7be74194f7ab02d0f59a62bdcf1a537677ce67a2537c9b87fcda", size = 23821, upload-time = "2025-09-27T18:37:12.48Z" }, + { url = "https://files.pythonhosted.org/packages/7d/33/45b24e4f44195b26521bc6f1a82197118f74df348556594bd2262bda1038/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:0eb9ff8191e8498cca014656ae6b8d61f39da5f95b488805da4bb029cccbfbaf", size = 21606, upload-time = "2025-09-27T18:37:13.485Z" }, + { url = "https://files.pythonhosted.org/packages/ff/0e/53dfaca23a69fbfbbf17a4b64072090e70717344c52eaaaa9c5ddff1e5f0/markupsafe-3.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2713baf880df847f2bece4230d4d094280f4e67b1e813eec43b4c0e144a34ffe", size = 23043, upload-time = "2025-09-27T18:37:14.408Z" }, + { url = "https://files.pythonhosted.org/packages/46/11/f333a06fc16236d5238bfe74daccbca41459dcd8d1fa952e8fbd5dccfb70/markupsafe-3.0.3-cp314-cp314-win32.whl", hash = "sha256:729586769a26dbceff69f7a7dbbf59ab6572b99d94576a5592625d5b411576b9", size = 14747, upload-time = "2025-09-27T18:37:15.36Z" }, + { url = "https://files.pythonhosted.org/packages/28/52/182836104b33b444e400b14f797212f720cbc9ed6ba34c800639d154e821/markupsafe-3.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:bdc919ead48f234740ad807933cdf545180bfbe9342c2bb451556db2ed958581", size = 15341, upload-time = "2025-09-27T18:37:16.496Z" }, + { url = "https://files.pythonhosted.org/packages/6f/18/acf23e91bd94fd7b3031558b1f013adfa21a8e407a3fdb32745538730382/markupsafe-3.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:5a7d5dc5140555cf21a6fefbdbf8723f06fcd2f63ef108f2854de715e4422cb4", size = 14073, upload-time = "2025-09-27T18:37:17.476Z" }, + { url = "https://files.pythonhosted.org/packages/3c/f0/57689aa4076e1b43b15fdfa646b04653969d50cf30c32a102762be2485da/markupsafe-3.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:1353ef0c1b138e1907ae78e2f6c63ff67501122006b0f9abad68fda5f4ffc6ab", size = 11661, upload-time = "2025-09-27T18:37:18.453Z" }, + { url = "https://files.pythonhosted.org/packages/89/c3/2e67a7ca217c6912985ec766c6393b636fb0c2344443ff9d91404dc4c79f/markupsafe-3.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:1085e7fbddd3be5f89cc898938f42c0b3c711fdcb37d75221de2666af647c175", size = 12069, upload-time = "2025-09-27T18:37:19.332Z" }, + { url = "https://files.pythonhosted.org/packages/f0/00/be561dce4e6ca66b15276e184ce4b8aec61fe83662cce2f7d72bd3249d28/markupsafe-3.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b52b4fb9df4eb9ae465f8d0c228a00624de2334f216f178a995ccdcf82c4634", size = 25670, upload-time = "2025-09-27T18:37:20.245Z" }, + { url = "https://files.pythonhosted.org/packages/50/09/c419f6f5a92e5fadde27efd190eca90f05e1261b10dbd8cbcb39cd8ea1dc/markupsafe-3.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fed51ac40f757d41b7c48425901843666a6677e3e8eb0abcff09e4ba6e664f50", size = 23598, upload-time = "2025-09-27T18:37:21.177Z" }, + { url = "https://files.pythonhosted.org/packages/22/44/a0681611106e0b2921b3033fc19bc53323e0b50bc70cffdd19f7d679bb66/markupsafe-3.0.3-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f190daf01f13c72eac4efd5c430a8de82489d9cff23c364c3ea822545032993e", size = 23261, upload-time = "2025-09-27T18:37:22.167Z" }, + { url = "https://files.pythonhosted.org/packages/5f/57/1b0b3f100259dc9fffe780cfb60d4be71375510e435efec3d116b6436d43/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e56b7d45a839a697b5eb268c82a71bd8c7f6c94d6fd50c3d577fa39a9f1409f5", size = 24835, upload-time = "2025-09-27T18:37:23.296Z" }, + { url = "https://files.pythonhosted.org/packages/26/6a/4bf6d0c97c4920f1597cc14dd720705eca0bf7c787aebc6bb4d1bead5388/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f3e98bb3798ead92273dc0e5fd0f31ade220f59a266ffd8a4f6065e0a3ce0523", size = 22733, upload-time = "2025-09-27T18:37:24.237Z" }, + { url = "https://files.pythonhosted.org/packages/14/c7/ca723101509b518797fedc2fdf79ba57f886b4aca8a7d31857ba3ee8281f/markupsafe-3.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5678211cb9333a6468fb8d8be0305520aa073f50d17f089b5b4b477ea6e67fdc", size = 23672, upload-time = "2025-09-27T18:37:25.271Z" }, + { url = "https://files.pythonhosted.org/packages/fb/df/5bd7a48c256faecd1d36edc13133e51397e41b73bb77e1a69deab746ebac/markupsafe-3.0.3-cp314-cp314t-win32.whl", hash = "sha256:915c04ba3851909ce68ccc2b8e2cd691618c4dc4c4232fb7982bca3f41fd8c3d", size = 14819, upload-time = "2025-09-27T18:37:26.285Z" }, + { url = "https://files.pythonhosted.org/packages/1a/8a/0402ba61a2f16038b48b39bccca271134be00c5c9f0f623208399333c448/markupsafe-3.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4faffd047e07c38848ce017e8725090413cd80cbc23d86e55c587bf979e579c9", size = 15426, upload-time = "2025-09-27T18:37:27.316Z" }, + { url = "https://files.pythonhosted.org/packages/70/bc/6f1c2f612465f5fa89b95bead1f44dcb607670fd42891d8fdcd5d039f4f4/markupsafe-3.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:32001d6a8fc98c8cb5c947787c5d08b0a50663d139f1305bac5885d98d9b40fa", size = 14146, upload-time = "2025-09-27T18:37:28.327Z" }, +] + [[package]] name = "matplotlib" version = "3.11.1" @@ -1037,6 +1171,98 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/41/09/5b161152e2d90f7b87f781c2e1267494aef9c32498df793f73ad0a0a494a/matplotlib_inline-0.2.2-py3-none-any.whl", hash = "sha256:3c821cf1c209f59fb2d2d64abbf5b23b67bcb2210d663f9918dd851c6da1fcf6", size = 9534, upload-time = "2026-05-08T17:33:32.055Z" }, ] +[[package]] +name = "mergedeep" +version = "1.3.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3a/41/580bb4006e3ed0361b8151a01d324fb03f420815446c7def45d02f74c270/mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8", size = 4661, upload-time = "2021-02-05T18:55:30.623Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307", size = 6354, upload-time = "2021-02-05T18:55:29.583Z" }, +] + +[[package]] +name = "mkdocs" +version = "1.6.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "ghp-import" }, + { name = "jinja2" }, + { name = "markdown" }, + { name = "markupsafe" }, + { name = "mergedeep" }, + { name = "mkdocs-get-deps" }, + { name = "packaging" }, + { name = "pathspec" }, + { name = "pyyaml" }, + { name = "pyyaml-env-tag" }, + { name = "watchdog" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bc/c6/bbd4f061bd16b378247f12953ffcb04786a618ce5e904b8c5a01a0309061/mkdocs-1.6.1.tar.gz", hash = "sha256:7b432f01d928c084353ab39c57282f29f92136665bdd6abf7c1ec8d822ef86f2", size = 3889159, upload-time = "2024-08-30T12:24:06.899Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl", hash = "sha256:db91759624d1647f3f34aa0c3f327dd2601beae39a366d6e064c03468d35c20e", size = 3864451, upload-time = "2024-08-30T12:24:05.054Z" }, +] + +[[package]] +name = "mkdocs-autorefs" +version = "1.4.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown" }, + { name = "markupsafe" }, + { name = "mkdocs" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/52/c0/f641843de3f612a6b48253f39244165acff36657a91cc903633d456ae1ac/mkdocs_autorefs-1.4.4.tar.gz", hash = "sha256:d54a284f27a7346b9c38f1f852177940c222da508e66edc816a0fa55fc6da197", size = 56588, upload-time = "2026-02-10T15:23:55.105Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/28/de/a3e710469772c6a89595fc52816da05c1e164b4c866a89e3cb82fb1b67c5/mkdocs_autorefs-1.4.4-py3-none-any.whl", hash = "sha256:834ef5408d827071ad1bc69e0f39704fa34c7fc05bc8e1c72b227dfdc5c76089", size = 25530, upload-time = "2026-02-10T15:23:53.817Z" }, +] + +[[package]] +name = "mkdocs-get-deps" +version = "0.2.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mergedeep" }, + { name = "platformdirs" }, + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ce/25/b3cccb187655b9393572bde9b09261d267c3bf2f2cdabe347673be5976a6/mkdocs_get_deps-0.2.2.tar.gz", hash = "sha256:8ee8d5f316cdbbb2834bc1df6e69c08fe769a83e040060de26d3c19fad3599a1", size = 11047, upload-time = "2026-03-10T02:46:33.632Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/29/744136411e785c4b0b744d5413e56555265939ab3a104c6a4b719dad33fd/mkdocs_get_deps-0.2.2-py3-none-any.whl", hash = "sha256:e7878cbeac04860b8b5e0ca31d3abad3df9411a75a32cde82f8e44b6c16ff650", size = 9555, upload-time = "2026-03-10T02:46:32.256Z" }, +] + +[[package]] +name = "mkdocstrings" +version = "1.0.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jinja2" }, + { name = "markdown" }, + { name = "markupsafe" }, + { name = "mkdocs" }, + { name = "mkdocs-autorefs" }, + { name = "pymdown-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/53/71/f85bdf13355073ae15a7375f09879375a830553552e58c1c4b7e0bbc5c8b/mkdocstrings-1.0.6.tar.gz", hash = "sha256:a0b8c2bdd29a6416c80d717aa369bbf7831946bd9f23c2a66db1b1dbe7693dbd", size = 100649, upload-time = "2026-07-11T19:38:05.732Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/5b/4c1902e8bdd5c4db63284e9d101dece4038d4025d6d88850ffe0a1578980/mkdocstrings-1.0.6-py3-none-any.whl", hash = "sha256:2703708697487d1b6d6d7b412e176fa436edf120c1bf81dc9e126b12d00893c7", size = 35787, upload-time = "2026-07-11T19:38:04.417Z" }, +] + +[[package]] +name = "mkdocstrings-python" +version = "2.0.8" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "griffelib" }, + { name = "mkdocs-autorefs" }, + { name = "mkdocstrings" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c5/65/0db919b7c91bf033b42d04f15ff16a56f4edd6afb26e84d448359660ece3/mkdocstrings_python-2.0.8.tar.gz", hash = "sha256:34545b54681cf0b212aab95394d37b0f5326a93b102f6ad1df3d965c79384c9d", size = 201771, upload-time = "2026-08-31T20:16:06.698Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0b/b7/a5a854d4e44853f26decc0c5e0d68df052399f3da344a313da4178f00816/mkdocstrings_python-2.0.8-py3-none-any.whl", hash = "sha256:e555d9ef53b0febdeae4dd603144d4f86ec90fef672276645ea3bb61232c3d24", size = 105443, upload-time = "2026-08-31T20:16:05.25Z" }, +] + [[package]] name = "monty" version = "2026.7.16" @@ -1412,6 +1638,15 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/99/5d/8268b644392ee874ee82a635cd0df1773de230bde356c38de28e298392cc/parso-0.8.7-py2.py3-none-any.whl", hash = "sha256:a8926eb2a1b915486941fdbd31e86a4baf88fe8c210f25f2f35ecec5b574ca1c", size = 107025, upload-time = "2026-05-01T23:12:58.867Z" }, ] +[[package]] +name = "pathspec" +version = "1.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/5a/82/42f767fc1c1143d6fd36efb827202a2d997a375e160a71eb2888a925aac1/pathspec-1.1.1.tar.gz", hash = "sha256:17db5ecd524104a120e173814c90367a96a98d07c45b2e10c2f3919fff91bf5a", size = 135180, upload-time = "2026-04-27T01:46:08.907Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f1/d9/7fb5aa316bc299258e68c73ba3bddbc499654a07f151cba08f6153988714/pathspec-1.1.1-py3-none-any.whl", hash = "sha256:a00ce642f577bf7f473932318056212bc4f8bfdf53128c78bbd5af0b9b20b189", size = 57328, upload-time = "2026-04-27T01:46:07.06Z" }, +] + [[package]] name = "pexpect" version = "4.9.0" @@ -1682,6 +1917,19 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/af/6d/f4fc1db359ef452a652eeb2b9cae480565be7b665da42f20247355fe0344/pymatgen_core-2026.8.30-cp314-cp314-win_amd64.whl", hash = "sha256:01c136076b47f34f32c355339a0063a824fa20acc9ba0c671aa432b0202fe41f", size = 2923538, upload-time = "2026-08-30T03:02:52.231Z" }, ] +[[package]] +name = "pymdown-extensions" +version = "11.0.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown" }, + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ad/17/2db4b414de89659144488e0d9c6c0bf0c8395841dc12d81d0532cc6ef310/pymdown_extensions-11.0.2.tar.gz", hash = "sha256:9506fcbe66fa355a775b768084334238dd6805020ac4b92bea0c0dda6f8f223d", size = 855419, upload-time = "2026-08-22T19:28:47.236Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a6/43/9f45ec4d14e596efc32c925a78104934790438b0c0628b70d741016734ad/pymdown_extensions-11.0.2-py3-none-any.whl", hash = "sha256:259910762019732caa1dfd76f3faa62c59f191d46573e80bcb1d13c0f675bbe5", size = 269929, upload-time = "2026-08-22T19:28:45.389Z" }, +] + [[package]] name = "pyparsing" version = "3.3.2" @@ -1744,6 +1992,73 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, ] +[[package]] +name = "pyyaml" +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6d/16/a95b6757765b7b031c9374925bb718d55e0a9ba8a1b6a12d25962ea44347/pyyaml-6.0.3-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:44edc647873928551a01e7a563d7452ccdebee747728c1080d881d68af7b997e", size = 185826, upload-time = "2025-09-25T21:31:58.655Z" }, + { url = "https://files.pythonhosted.org/packages/16/19/13de8e4377ed53079ee996e1ab0a9c33ec2faf808a4647b7b4c0d46dd239/pyyaml-6.0.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:652cb6edd41e718550aad172851962662ff2681490a8a711af6a4d288dd96824", size = 175577, upload-time = "2025-09-25T21:32:00.088Z" }, + { url = "https://files.pythonhosted.org/packages/0c/62/d2eb46264d4b157dae1275b573017abec435397aa59cbcdab6fc978a8af4/pyyaml-6.0.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:10892704fc220243f5305762e276552a0395f7beb4dbf9b14ec8fd43b57f126c", size = 775556, upload-time = "2025-09-25T21:32:01.31Z" }, + { url = "https://files.pythonhosted.org/packages/10/cb/16c3f2cf3266edd25aaa00d6c4350381c8b012ed6f5276675b9eba8d9ff4/pyyaml-6.0.3-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:850774a7879607d3a6f50d36d04f00ee69e7fc816450e5f7e58d7f17f1ae5c00", size = 882114, upload-time = "2025-09-25T21:32:03.376Z" }, + { url = "https://files.pythonhosted.org/packages/71/60/917329f640924b18ff085ab889a11c763e0b573da888e8404ff486657602/pyyaml-6.0.3-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b8bb0864c5a28024fac8a632c443c87c5aa6f215c0b126c449ae1a150412f31d", size = 806638, upload-time = "2025-09-25T21:32:04.553Z" }, + { url = "https://files.pythonhosted.org/packages/dd/6f/529b0f316a9fd167281a6c3826b5583e6192dba792dd55e3203d3f8e655a/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:1d37d57ad971609cf3c53ba6a7e365e40660e3be0e5175fa9f2365a379d6095a", size = 767463, upload-time = "2025-09-25T21:32:06.152Z" }, + { url = "https://files.pythonhosted.org/packages/f2/6a/b627b4e0c1dd03718543519ffb2f1deea4a1e6d42fbab8021936a4d22589/pyyaml-6.0.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37503bfbfc9d2c40b344d06b2199cf0e96e97957ab1c1b546fd4f87e53e5d3e4", size = 794986, upload-time = "2025-09-25T21:32:07.367Z" }, + { url = "https://files.pythonhosted.org/packages/45/91/47a6e1c42d9ee337c4839208f30d9f09caa9f720ec7582917b264defc875/pyyaml-6.0.3-cp311-cp311-win32.whl", hash = "sha256:8098f252adfa6c80ab48096053f512f2321f0b998f98150cea9bd23d83e1467b", size = 142543, upload-time = "2025-09-25T21:32:08.95Z" }, + { url = "https://files.pythonhosted.org/packages/da/e3/ea007450a105ae919a72393cb06f122f288ef60bba2dc64b26e2646fa315/pyyaml-6.0.3-cp311-cp311-win_amd64.whl", hash = "sha256:9f3bfb4965eb874431221a3ff3fdcddc7e74e3b07799e0e84ca4a0f867d449bf", size = 158763, upload-time = "2025-09-25T21:32:09.96Z" }, + { url = "https://files.pythonhosted.org/packages/d1/33/422b98d2195232ca1826284a76852ad5a86fe23e31b009c9886b2d0fb8b2/pyyaml-6.0.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7f047e29dcae44602496db43be01ad42fc6f1cc0d8cd6c83d342306c32270196", size = 182063, upload-time = "2025-09-25T21:32:11.445Z" }, + { url = "https://files.pythonhosted.org/packages/89/a0/6cf41a19a1f2f3feab0e9c0b74134aa2ce6849093d5517a0c550fe37a648/pyyaml-6.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:fc09d0aa354569bc501d4e787133afc08552722d3ab34836a80547331bb5d4a0", size = 173973, upload-time = "2025-09-25T21:32:12.492Z" }, + { url = "https://files.pythonhosted.org/packages/ed/23/7a778b6bd0b9a8039df8b1b1d80e2e2ad78aa04171592c8a5c43a56a6af4/pyyaml-6.0.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9149cad251584d5fb4981be1ecde53a1ca46c891a79788c0df828d2f166bda28", size = 775116, upload-time = "2025-09-25T21:32:13.652Z" }, + { url = "https://files.pythonhosted.org/packages/65/30/d7353c338e12baef4ecc1b09e877c1970bd3382789c159b4f89d6a70dc09/pyyaml-6.0.3-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:5fdec68f91a0c6739b380c83b951e2c72ac0197ace422360e6d5a959d8d97b2c", size = 844011, upload-time = "2025-09-25T21:32:15.21Z" }, + { url = "https://files.pythonhosted.org/packages/8b/9d/b3589d3877982d4f2329302ef98a8026e7f4443c765c46cfecc8858c6b4b/pyyaml-6.0.3-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ba1cc08a7ccde2d2ec775841541641e4548226580ab850948cbfda66a1befcdc", size = 807870, upload-time = "2025-09-25T21:32:16.431Z" }, + { url = "https://files.pythonhosted.org/packages/05/c0/b3be26a015601b822b97d9149ff8cb5ead58c66f981e04fedf4e762f4bd4/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8dc52c23056b9ddd46818a57b78404882310fb473d63f17b07d5c40421e47f8e", size = 761089, upload-time = "2025-09-25T21:32:17.56Z" }, + { url = "https://files.pythonhosted.org/packages/be/8e/98435a21d1d4b46590d5459a22d88128103f8da4c2d4cb8f14f2a96504e1/pyyaml-6.0.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:41715c910c881bc081f1e8872880d3c650acf13dfa8214bad49ed4cede7c34ea", size = 790181, upload-time = "2025-09-25T21:32:18.834Z" }, + { url = "https://files.pythonhosted.org/packages/74/93/7baea19427dcfbe1e5a372d81473250b379f04b1bd3c4c5ff825e2327202/pyyaml-6.0.3-cp312-cp312-win32.whl", hash = "sha256:96b533f0e99f6579b3d4d4995707cf36df9100d67e0c8303a0c55b27b5f99bc5", size = 137658, upload-time = "2025-09-25T21:32:20.209Z" }, + { url = "https://files.pythonhosted.org/packages/86/bf/899e81e4cce32febab4fb42bb97dcdf66bc135272882d1987881a4b519e9/pyyaml-6.0.3-cp312-cp312-win_amd64.whl", hash = "sha256:5fcd34e47f6e0b794d17de1b4ff496c00986e1c83f7ab2fb8fcfe9616ff7477b", size = 154003, upload-time = "2025-09-25T21:32:21.167Z" }, + { url = "https://files.pythonhosted.org/packages/1a/08/67bd04656199bbb51dbed1439b7f27601dfb576fb864099c7ef0c3e55531/pyyaml-6.0.3-cp312-cp312-win_arm64.whl", hash = "sha256:64386e5e707d03a7e172c0701abfb7e10f0fb753ee1d773128192742712a98fd", size = 140344, upload-time = "2025-09-25T21:32:22.617Z" }, + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, +] + +[[package]] +name = "pyyaml-env-tag" +version = "1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyyaml" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/eb/2e/79c822141bfd05a853236b504869ebc6b70159afc570e1d5a20641782eaa/pyyaml_env_tag-1.1.tar.gz", hash = "sha256:2eb38b75a2d21ee0475d6d97ec19c63287a7e140231e4214969d0eac923cd7ff", size = 5737, upload-time = "2025-05-13T15:24:01.64Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl", hash = "sha256:17109e1a528561e32f026364712fee1264bc2ea6715120891174ed1b980d2e04", size = 4722, upload-time = "2025-05-13T15:23:59.629Z" }, +] + [[package]] name = "pyzmq" version = "27.2.0" @@ -2088,11 +2403,17 @@ dependencies = [ [package.optional-dependencies] dev = [ { name = "ipykernel" }, + { name = "mkdocstrings-python" }, { name = "prek" }, { name = "pytest" }, { name = "pytest-split" }, { name = "pytest-xdist" }, { name = "setuptools-scm" }, + { name = "zensical" }, +] +docs = [ + { name = "mkdocstrings-python" }, + { name = "zensical" }, ] testing = [ { name = "pytest" }, @@ -2111,6 +2432,7 @@ requires-dist = [ { name = "hsnf", specifier = ">=0.3.16" }, { name = "ipykernel", marker = "extra == 'dev'" }, { name = "loguru", specifier = ">=0.7.3" }, + { name = "mkdocstrings-python", marker = "extra == 'docs'", specifier = ">=2.0" }, { name = "moyopy", specifier = ">=0.16" }, { name = "prek", marker = "extra == 'dev'" }, { name = "pymatgen-core", specifier = ">=2026.7.16" }, @@ -2120,10 +2442,12 @@ requires-dist = [ { name = "scipy", specifier = ">=1.15.2" }, { name = "setuptools-scm", marker = "extra == 'dev'", specifier = ">=8.2" }, { name = "spgrep", specifier = ">=0.7" }, + { name = "spinforge", extras = ["docs"], marker = "extra == 'dev'" }, { name = "spinforge", extras = ["testing"], marker = "extra == 'dev'" }, { name = "spinspg", specifier = ">=0.3.2" }, + { name = "zensical", marker = "extra == 'docs'", specifier = ">=0.0.46" }, ] -provides-extras = ["dev", "testing"] +provides-extras = ["dev", "docs", "testing"] [package.metadata.requires-dev] dev = [{ name = "spinforge", extras = ["dev"] }] @@ -2183,6 +2507,60 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/99/55/db07de81b5c630da5cbf5c7df646580ca26dfaefa593667fc6f2fe016d2e/tabulate-0.10.0-py3-none-any.whl", hash = "sha256:f0b0622e567335c8fabaaa659f1b33bcb6ddfe2e496071b743aa113f8774f2d3", size = 39814, upload-time = "2026-03-04T18:55:31.284Z" }, ] +[[package]] +name = "tomli" +version = "2.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/22/de/48c59722572767841493b26183a0d1cc411d54fd759c5607c4590b6563a6/tomli-2.4.1.tar.gz", hash = "sha256:7c7e1a961a0b2f2472c1ac5b69affa0ae1132c39adcb67aba98568702b9cc23f", size = 17543, upload-time = "2026-03-25T20:22:03.828Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/11/db3d5885d8528263d8adc260bb2d28ebf1270b96e98f0e0268d32b8d9900/tomli-2.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f8f0fc26ec2cc2b965b7a3b87cd19c5c6b8c5e5f436b984e85f486d652285c30", size = 154704, upload-time = "2026-03-25T20:21:10.473Z" }, + { url = "https://files.pythonhosted.org/packages/6d/f7/675db52c7e46064a9aa928885a9b20f4124ecb9bc2e1ce74c9106648d202/tomli-2.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4ab97e64ccda8756376892c53a72bd1f964e519c77236368527f758fbc36a53a", size = 149454, upload-time = "2026-03-25T20:21:12.036Z" }, + { url = "https://files.pythonhosted.org/packages/61/71/81c50943cf953efa35bce7646caab3cf457a7d8c030b27cfb40d7235f9ee/tomli-2.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96481a5786729fd470164b47cdb3e0e58062a496f455ee41b4403be77cb5a076", size = 237561, upload-time = "2026-03-25T20:21:13.098Z" }, + { url = "https://files.pythonhosted.org/packages/48/c1/f41d9cb618acccca7df82aaf682f9b49013c9397212cb9f53219e3abac37/tomli-2.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5a881ab208c0baf688221f8cecc5401bd291d67e38a1ac884d6736cbcd8247e9", size = 243824, upload-time = "2026-03-25T20:21:14.569Z" }, + { url = "https://files.pythonhosted.org/packages/22/e4/5a816ecdd1f8ca51fb756ef684b90f2780afc52fc67f987e3c61d800a46d/tomli-2.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:47149d5bd38761ac8be13a84864bf0b7b70bc051806bc3669ab1cbc56216b23c", size = 242227, upload-time = "2026-03-25T20:21:15.712Z" }, + { url = "https://files.pythonhosted.org/packages/6b/49/2b2a0ef529aa6eec245d25f0c703e020a73955ad7edf73e7f54ddc608aa5/tomli-2.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ec9bfaf3ad2df51ace80688143a6a4ebc09a248f6ff781a9945e51937008fcbc", size = 247859, upload-time = "2026-03-25T20:21:17.001Z" }, + { url = "https://files.pythonhosted.org/packages/83/bd/6c1a630eaca337e1e78c5903104f831bda934c426f9231429396ce3c3467/tomli-2.4.1-cp311-cp311-win32.whl", hash = "sha256:ff2983983d34813c1aeb0fa89091e76c3a22889ee83ab27c5eeb45100560c049", size = 97204, upload-time = "2026-03-25T20:21:18.079Z" }, + { url = "https://files.pythonhosted.org/packages/42/59/71461df1a885647e10b6bb7802d0b8e66480c61f3f43079e0dcd315b3954/tomli-2.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:5ee18d9ebdb417e384b58fe414e8d6af9f4e7a0ae761519fb50f721de398dd4e", size = 108084, upload-time = "2026-03-25T20:21:18.978Z" }, + { url = "https://files.pythonhosted.org/packages/b8/83/dceca96142499c069475b790e7913b1044c1a4337e700751f48ed723f883/tomli-2.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:c2541745709bad0264b7d4705ad453b76ccd191e64aa6f0fc66b69a293a45ece", size = 95285, upload-time = "2026-03-25T20:21:20.309Z" }, + { url = "https://files.pythonhosted.org/packages/c1/ba/42f134a3fe2b370f555f44b1d72feebb94debcab01676bf918d0cb70e9aa/tomli-2.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c742f741d58a28940ce01d58f0ab2ea3ced8b12402f162f4d534dfe18ba1cd6a", size = 155924, upload-time = "2026-03-25T20:21:21.626Z" }, + { url = "https://files.pythonhosted.org/packages/dc/c7/62d7a17c26487ade21c5422b646110f2162f1fcc95980ef7f63e73c68f14/tomli-2.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7f86fd587c4ed9dd76f318225e7d9b29cfc5a9d43de44e5754db8d1128487085", size = 150018, upload-time = "2026-03-25T20:21:23.002Z" }, + { url = "https://files.pythonhosted.org/packages/5c/05/79d13d7c15f13bdef410bdd49a6485b1c37d28968314eabee452c22a7fda/tomli-2.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ff18e6a727ee0ab0388507b89d1bc6a22b138d1e2fa56d1ad494586d61d2eae9", size = 244948, upload-time = "2026-03-25T20:21:24.04Z" }, + { url = "https://files.pythonhosted.org/packages/10/90/d62ce007a1c80d0b2c93e02cab211224756240884751b94ca72df8a875ca/tomli-2.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:136443dbd7e1dee43c68ac2694fde36b2849865fa258d39bf822c10e8068eac5", size = 253341, upload-time = "2026-03-25T20:21:25.177Z" }, + { url = "https://files.pythonhosted.org/packages/1a/7e/caf6496d60152ad4ed09282c1885cca4eea150bfd007da84aea07bcc0a3e/tomli-2.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5e262d41726bc187e69af7825504c933b6794dc3fbd5945e41a79bb14c31f585", size = 248159, upload-time = "2026-03-25T20:21:26.364Z" }, + { url = "https://files.pythonhosted.org/packages/99/e7/c6f69c3120de34bbd882c6fba7975f3d7a746e9218e56ab46a1bc4b42552/tomli-2.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5cb41aa38891e073ee49d55fbc7839cfdb2bc0e600add13874d048c94aadddd1", size = 253290, upload-time = "2026-03-25T20:21:27.46Z" }, + { url = "https://files.pythonhosted.org/packages/d6/2f/4a3c322f22c5c66c4b836ec58211641a4067364f5dcdd7b974b4c5da300c/tomli-2.4.1-cp312-cp312-win32.whl", hash = "sha256:da25dc3563bff5965356133435b757a795a17b17d01dbc0f42fb32447ddfd917", size = 98141, upload-time = "2026-03-25T20:21:28.492Z" }, + { url = "https://files.pythonhosted.org/packages/24/22/4daacd05391b92c55759d55eaee21e1dfaea86ce5c571f10083360adf534/tomli-2.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:52c8ef851d9a240f11a88c003eacb03c31fc1c9c4ec64a99a0f922b93874fda9", size = 108847, upload-time = "2026-03-25T20:21:29.386Z" }, + { url = "https://files.pythonhosted.org/packages/68/fd/70e768887666ddd9e9f5d85129e84910f2db2796f9096aa02b721a53098d/tomli-2.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:f758f1b9299d059cc3f6546ae2af89670cb1c4d48ea29c3cacc4fe7de3058257", size = 95088, upload-time = "2026-03-25T20:21:30.677Z" }, + { url = "https://files.pythonhosted.org/packages/07/06/b823a7e818c756d9a7123ba2cda7d07bc2dd32835648d1a7b7b7a05d848d/tomli-2.4.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:36d2bd2ad5fb9eaddba5226aa02c8ec3fa4f192631e347b3ed28186d43be6b54", size = 155866, upload-time = "2026-03-25T20:21:31.65Z" }, + { url = "https://files.pythonhosted.org/packages/14/6f/12645cf7f08e1a20c7eb8c297c6f11d31c1b50f316a7e7e1e1de6e2e7b7e/tomli-2.4.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:eb0dc4e38e6a1fd579e5d50369aa2e10acfc9cace504579b2faabb478e76941a", size = 149887, upload-time = "2026-03-25T20:21:33.028Z" }, + { url = "https://files.pythonhosted.org/packages/5c/e0/90637574e5e7212c09099c67ad349b04ec4d6020324539297b634a0192b0/tomli-2.4.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c7f2c7f2b9ca6bdeef8f0fa897f8e05085923eb091721675170254cbc5b02897", size = 243704, upload-time = "2026-03-25T20:21:34.51Z" }, + { url = "https://files.pythonhosted.org/packages/10/8f/d3ddb16c5a4befdf31a23307f72828686ab2096f068eaf56631e136c1fdd/tomli-2.4.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3c6818a1a86dd6dca7ddcaaf76947d5ba31aecc28cb1b67009a5877c9a64f3f", size = 251628, upload-time = "2026-03-25T20:21:36.012Z" }, + { url = "https://files.pythonhosted.org/packages/e3/f1/dbeeb9116715abee2485bf0a12d07a8f31af94d71608c171c45f64c0469d/tomli-2.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d312ef37c91508b0ab2cee7da26ec0b3ed2f03ce12bd87a588d771ae15dcf82d", size = 247180, upload-time = "2026-03-25T20:21:37.136Z" }, + { url = "https://files.pythonhosted.org/packages/d3/74/16336ffd19ed4da28a70959f92f506233bd7cfc2332b20bdb01591e8b1d1/tomli-2.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:51529d40e3ca50046d7606fa99ce3956a617f9b36380da3b7f0dd3dd28e68cb5", size = 251674, upload-time = "2026-03-25T20:21:38.298Z" }, + { url = "https://files.pythonhosted.org/packages/16/f9/229fa3434c590ddf6c0aa9af64d3af4b752540686cace29e6281e3458469/tomli-2.4.1-cp313-cp313-win32.whl", hash = "sha256:2190f2e9dd7508d2a90ded5ed369255980a1bcdd58e52f7fe24b8162bf9fedbd", size = 97976, upload-time = "2026-03-25T20:21:39.316Z" }, + { url = "https://files.pythonhosted.org/packages/6a/1e/71dfd96bcc1c775420cb8befe7a9d35f2e5b1309798f009dca17b7708c1e/tomli-2.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:8d65a2fbf9d2f8352685bc1364177ee3923d6baf5e7f43ea4959d7d8bc326a36", size = 108755, upload-time = "2026-03-25T20:21:40.248Z" }, + { url = "https://files.pythonhosted.org/packages/83/7a/d34f422a021d62420b78f5c538e5b102f62bea616d1d75a13f0a88acb04a/tomli-2.4.1-cp313-cp313-win_arm64.whl", hash = "sha256:4b605484e43cdc43f0954ddae319fb75f04cc10dd80d830540060ee7cd0243cd", size = 95265, upload-time = "2026-03-25T20:21:41.219Z" }, + { url = "https://files.pythonhosted.org/packages/3c/fb/9a5c8d27dbab540869f7c1f8eb0abb3244189ce780ba9cd73f3770662072/tomli-2.4.1-cp314-cp314-macosx_10_15_x86_64.whl", hash = "sha256:fd0409a3653af6c147209d267a0e4243f0ae46b011aa978b1080359fddc9b6cf", size = 155726, upload-time = "2026-03-25T20:21:42.23Z" }, + { url = "https://files.pythonhosted.org/packages/62/05/d2f816630cc771ad836af54f5001f47a6f611d2d39535364f148b6a92d6b/tomli-2.4.1-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:a120733b01c45e9a0c34aeef92bf0cf1d56cfe81ed9d47d562f9ed591a9828ac", size = 149859, upload-time = "2026-03-25T20:21:43.386Z" }, + { url = "https://files.pythonhosted.org/packages/ce/48/66341bdb858ad9bd0ceab5a86f90eddab127cf8b046418009f2125630ecb/tomli-2.4.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:559db847dc486944896521f68d8190be1c9e719fced785720d2216fe7022b662", size = 244713, upload-time = "2026-03-25T20:21:44.474Z" }, + { url = "https://files.pythonhosted.org/packages/df/6d/c5fad00d82b3c7a3ab6189bd4b10e60466f22cfe8a08a9394185c8a8111c/tomli-2.4.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01f520d4f53ef97964a240a035ec2a869fe1a37dde002b57ebc4417a27ccd853", size = 252084, upload-time = "2026-03-25T20:21:45.62Z" }, + { url = "https://files.pythonhosted.org/packages/00/71/3a69e86f3eafe8c7a59d008d245888051005bd657760e96d5fbfb0b740c2/tomli-2.4.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7f94b27a62cfad8496c8d2513e1a222dd446f095fca8987fceef261225538a15", size = 247973, upload-time = "2026-03-25T20:21:46.937Z" }, + { url = "https://files.pythonhosted.org/packages/67/50/361e986652847fec4bd5e4a0208752fbe64689c603c7ae5ea7cb16b1c0ca/tomli-2.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ede3e6487c5ef5d28634ba3f31f989030ad6af71edfb0055cbbd14189ff240ba", size = 256223, upload-time = "2026-03-25T20:21:48.467Z" }, + { url = "https://files.pythonhosted.org/packages/8c/9a/b4173689a9203472e5467217e0154b00e260621caa227b6fa01feab16998/tomli-2.4.1-cp314-cp314-win32.whl", hash = "sha256:3d48a93ee1c9b79c04bb38772ee1b64dcf18ff43085896ea460ca8dec96f35f6", size = 98973, upload-time = "2026-03-25T20:21:49.526Z" }, + { url = "https://files.pythonhosted.org/packages/14/58/640ac93bf230cd27d002462c9af0d837779f8773bc03dee06b5835208214/tomli-2.4.1-cp314-cp314-win_amd64.whl", hash = "sha256:88dceee75c2c63af144e456745e10101eb67361050196b0b6af5d717254dddf7", size = 109082, upload-time = "2026-03-25T20:21:50.506Z" }, + { url = "https://files.pythonhosted.org/packages/d5/2f/702d5e05b227401c1068f0d386d79a589bb12bf64c3d2c72ce0631e3bc49/tomli-2.4.1-cp314-cp314-win_arm64.whl", hash = "sha256:b8c198f8c1805dc42708689ed6864951fd2494f924149d3e4bce7710f8eb5232", size = 96490, upload-time = "2026-03-25T20:21:51.474Z" }, + { url = "https://files.pythonhosted.org/packages/45/4b/b877b05c8ba62927d9865dd980e34a755de541eb65fffba52b4cc495d4d2/tomli-2.4.1-cp314-cp314t-macosx_10_15_x86_64.whl", hash = "sha256:d4d8fe59808a54658fcc0160ecfb1b30f9089906c50b23bcb4c69eddc19ec2b4", size = 164263, upload-time = "2026-03-25T20:21:52.543Z" }, + { url = "https://files.pythonhosted.org/packages/24/79/6ab420d37a270b89f7195dec5448f79400d9e9c1826df982f3f8e97b24fd/tomli-2.4.1-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:7008df2e7655c495dd12d2a4ad038ff878d4ca4b81fccaf82b714e07eae4402c", size = 160736, upload-time = "2026-03-25T20:21:53.674Z" }, + { url = "https://files.pythonhosted.org/packages/02/e0/3630057d8eb170310785723ed5adcdfb7d50cb7e6455f85ba8a3deed642b/tomli-2.4.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1d8591993e228b0c930c4bb0db464bdad97b3289fb981255d6c9a41aedc84b2d", size = 270717, upload-time = "2026-03-25T20:21:55.129Z" }, + { url = "https://files.pythonhosted.org/packages/7a/b4/1613716072e544d1a7891f548d8f9ec6ce2faf42ca65acae01d76ea06bb0/tomli-2.4.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:734e20b57ba95624ecf1841e72b53f6e186355e216e5412de414e3c51e5e3c41", size = 278461, upload-time = "2026-03-25T20:21:56.228Z" }, + { url = "https://files.pythonhosted.org/packages/05/38/30f541baf6a3f6df77b3df16b01ba319221389e2da59427e221ef417ac0c/tomli-2.4.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8a650c2dbafa08d42e51ba0b62740dae4ecb9338eefa093aa5c78ceb546fcd5c", size = 274855, upload-time = "2026-03-25T20:21:57.653Z" }, + { url = "https://files.pythonhosted.org/packages/77/a3/ec9dd4fd2c38e98de34223b995a3b34813e6bdadf86c75314c928350ed14/tomli-2.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:504aa796fe0569bb43171066009ead363de03675276d2d121ac1a4572397870f", size = 283144, upload-time = "2026-03-25T20:21:59.089Z" }, + { url = "https://files.pythonhosted.org/packages/ef/be/605a6261cac79fba2ec0c9827e986e00323a1945700969b8ee0b30d85453/tomli-2.4.1-cp314-cp314t-win32.whl", hash = "sha256:b1d22e6e9387bf4739fbe23bfa80e93f6b0373a7f1b96c6227c32bef95a4d7a8", size = 108683, upload-time = "2026-03-25T20:22:00.214Z" }, + { url = "https://files.pythonhosted.org/packages/12/64/da524626d3b9cc40c168a13da8335fe1c51be12c0a63685cc6db7308daae/tomli-2.4.1-cp314-cp314t-win_amd64.whl", hash = "sha256:2c1c351919aca02858f740c6d33adea0c5deea37f9ecca1cc1ef9e884a619d26", size = 121196, upload-time = "2026-03-25T20:22:01.169Z" }, + { url = "https://files.pythonhosted.org/packages/5a/cd/e80b62269fc78fc36c9af5a6b89c835baa8af28ff5ad28c7028d60860320/tomli-2.4.1-cp314-cp314t-win_arm64.whl", hash = "sha256:eab21f45c7f66c13f2a9e0e1535309cee140182a9cdae1e041d02e47291e8396", size = 100393, upload-time = "2026-03-25T20:22:02.137Z" }, + { url = "https://files.pythonhosted.org/packages/7b/61/cceae43728b7de99d9b847560c262873a1f6c98202171fd5ed62640b494b/tomli-2.4.1-py3-none-any.whl", hash = "sha256:0d85819802132122da43cb86656f8d1f8c6587d54ae7dcaf30e90533028b49fe", size = 14583, upload-time = "2026-03-25T20:22:03.012Z" }, +] + [[package]] name = "tornado" version = "6.5.8" @@ -2269,6 +2647,33 @@ wheels = [ { url = "https://files.pythonhosted.org/packages/a0/30/cbf2883ee604dc83ff510516ae05e93b17bfcb4d18279ae12905e13f49da/vcs_versioning-2.3.4-py3-none-any.whl", hash = "sha256:076afa0e12a42a23faba92bcb62cb016c1ce38051ceee1f302de1e2676a68bbc", size = 115414, upload-time = "2026-09-03T13:04:29.925Z" }, ] +[[package]] +name = "watchdog" +version = "6.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", size = 131220, upload-time = "2024-11-01T14:07:13.037Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/24/d9be5cd6642a6aa68352ded4b4b10fb0d7889cb7f45814fb92cecd35f101/watchdog-6.0.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:6eb11feb5a0d452ee41f824e271ca311a09e250441c262ca2fd7ebcf2461a06c", size = 96393, upload-time = "2024-11-01T14:06:31.756Z" }, + { url = "https://files.pythonhosted.org/packages/63/7a/6013b0d8dbc56adca7fdd4f0beed381c59f6752341b12fa0886fa7afc78b/watchdog-6.0.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ef810fbf7b781a5a593894e4f439773830bdecb885e6880d957d5b9382a960d2", size = 88392, upload-time = "2024-11-01T14:06:32.99Z" }, + { url = "https://files.pythonhosted.org/packages/d1/40/b75381494851556de56281e053700e46bff5b37bf4c7267e858640af5a7f/watchdog-6.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:afd0fe1b2270917c5e23c2a65ce50c2a4abb63daafb0d419fde368e272a76b7c", size = 89019, upload-time = "2024-11-01T14:06:34.963Z" }, + { url = "https://files.pythonhosted.org/packages/39/ea/3930d07dafc9e286ed356a679aa02d777c06e9bfd1164fa7c19c288a5483/watchdog-6.0.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:bdd4e6f14b8b18c334febb9c4425a878a2ac20efd1e0b231978e7b150f92a948", size = 96471, upload-time = "2024-11-01T14:06:37.745Z" }, + { url = "https://files.pythonhosted.org/packages/12/87/48361531f70b1f87928b045df868a9fd4e253d9ae087fa4cf3f7113be363/watchdog-6.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:c7c15dda13c4eb00d6fb6fc508b3c0ed88b9d5d374056b239c4ad1611125c860", size = 88449, upload-time = "2024-11-01T14:06:39.748Z" }, + { url = "https://files.pythonhosted.org/packages/5b/7e/8f322f5e600812e6f9a31b75d242631068ca8f4ef0582dd3ae6e72daecc8/watchdog-6.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6f10cb2d5902447c7d0da897e2c6768bca89174d0c6e1e30abec5421af97a5b0", size = 89054, upload-time = "2024-11-01T14:06:41.009Z" }, + { url = "https://files.pythonhosted.org/packages/68/98/b0345cabdce2041a01293ba483333582891a3bd5769b08eceb0d406056ef/watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c", size = 96480, upload-time = "2024-11-01T14:06:42.952Z" }, + { url = "https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134", size = 88451, upload-time = "2024-11-01T14:06:45.084Z" }, + { url = "https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b", size = 89057, upload-time = "2024-11-01T14:06:47.324Z" }, + { url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079, upload-time = "2024-11-01T14:06:59.472Z" }, + { url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078, upload-time = "2024-11-01T14:07:01.431Z" }, + { url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076, upload-time = "2024-11-01T14:07:02.568Z" }, + { url = "https://files.pythonhosted.org/packages/ab/cc/da8422b300e13cb187d2203f20b9253e91058aaf7db65b74142013478e66/watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f", size = 79077, upload-time = "2024-11-01T14:07:03.893Z" }, + { url = "https://files.pythonhosted.org/packages/2c/3b/b8964e04ae1a025c44ba8e4291f86e97fac443bca31de8bd98d3263d2fcf/watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26", size = 79078, upload-time = "2024-11-01T14:07:05.189Z" }, + { url = "https://files.pythonhosted.org/packages/62/ae/a696eb424bedff7407801c257d4b1afda455fe40821a2be430e173660e81/watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c", size = 79077, upload-time = "2024-11-01T14:07:06.376Z" }, + { url = "https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2", size = 79078, upload-time = "2024-11-01T14:07:07.547Z" }, + { url = "https://files.pythonhosted.org/packages/07/f6/d0e5b343768e8bcb4cda79f0f2f55051bf26177ecd5651f84c07567461cf/watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a", size = 79065, upload-time = "2024-11-01T14:07:09.525Z" }, + { url = "https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680", size = 79070, upload-time = "2024-11-01T14:07:10.686Z" }, + { url = "https://files.pythonhosted.org/packages/33/e8/e40370e6d74ddba47f002a32919d91310d6074130fe4e17dabcafc15cbf1/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", size = 79067, upload-time = "2024-11-01T14:07:11.845Z" }, +] + [[package]] name = "wcwidth" version = "0.8.3" @@ -2298,3 +2703,30 @@ sdist = { url = "https://files.pythonhosted.org/packages/b3/8f/705086c9d734d3b66 wheels = [ { url = "https://files.pythonhosted.org/packages/e1/07/c6fe3ad3e685340704d314d765b7912993bcb8dc198f0e7a89382d37974b/win32_setctime-1.2.0-py3-none-any.whl", hash = "sha256:95d644c4e708aba81dc3704a116d8cbc974d70b3bdb8be1d150e36be6e9d1390", size = 4083, upload-time = "2024-12-07T15:28:26.465Z" }, ] + +[[package]] +name = "zensical" +version = "0.0.59" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "deepmerge" }, + { name = "jinja2" }, + { name = "markdown" }, + { name = "pygments" }, + { name = "pymdown-extensions" }, + { name = "pyyaml" }, + { name = "tomli" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/34/6b/51a78b43239986744089dfa7da7930d808797eb844405f6ce740f5070a67/zensical-0.0.59.tar.gz", hash = "sha256:2b3c3ad561bbc781144b68c7a75246f1e859d3e80319221f59d927d229df21d5", size = 4110437, upload-time = "2026-09-03T18:41:13.942Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/66/09/b9ed4bec7dd871474b8b9c932828e9fa058f4d48e287fb8c773ccb1f638a/zensical-0.0.59-cp310-abi3-macosx_10_12_x86_64.whl", hash = "sha256:2a39a413fb38f3cc1572c49e8196e30537b75b53fe9d93180d419db5c8db0e68", size = 14169206, upload-time = "2026-09-03T18:40:51.289Z" }, + { url = "https://files.pythonhosted.org/packages/06/3b/a7ab8573d40e780dfbc316c24191170f898e4d7d158d06e19465260c044a/zensical-0.0.59-cp310-abi3-macosx_11_0_arm64.whl", hash = "sha256:b733edf61722a71d184c3899f035390b27915773fc77599987da934dd87fb76b", size = 13916290, upload-time = "2026-09-03T18:40:54.146Z" }, + { url = "https://files.pythonhosted.org/packages/e4/e8/92c5a80fd3701253660f5c2df8a938c6e6f1fef2218df9830b9d596ef237/zensical-0.0.59-cp310-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:973322d6cba380dae7acbefce84b74f67f8610435ba97c3557f5f25b6e49ed40", size = 14188906, upload-time = "2026-09-03T18:40:56.484Z" }, + { url = "https://files.pythonhosted.org/packages/5d/16/f898fa52c525f4241fd7709638b10e185b2bca2bc6e34f5dd5741cbe7b8e/zensical-0.0.59-cp310-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ef84401d8ad34835b5f7d31950f549758fa610d65f20a0cff8d5d71343112644", size = 14211088, upload-time = "2026-09-03T18:40:58.754Z" }, + { url = "https://files.pythonhosted.org/packages/09/50/084f74d4b98d553c566d484bb68e2bd472484027329e4f32e7334d0848ee/zensical-0.0.59-cp310-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0331651ffde09bb48904b428de3efa009290434760dbd5ec69b50c05a682a59c", size = 14466906, upload-time = "2026-09-03T18:41:01.305Z" }, + { url = "https://files.pythonhosted.org/packages/c2/bf/3472a57f8c816656fe5f8dde9fae1f5380e97ca5c2bda0b37614f61f5d62/zensical-0.0.59-cp310-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:f16ec02bb8582ccdf631db2bedb0a0d19901b6f3f22d9fc8aad97ea61d547746", size = 14363960, upload-time = "2026-09-03T18:41:03.961Z" }, + { url = "https://files.pythonhosted.org/packages/83/f2/7193e2ae24636d63cc4e9e261acabacbc56ea8e48201b90cb737d9c56147/zensical-0.0.59-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6d61b8db3e198f8b735186be029842ee829be66ca29b6797084948b0eec1c2cb", size = 14695910, upload-time = "2026-09-03T18:41:06.122Z" }, + { url = "https://files.pythonhosted.org/packages/84/89/ff115a9335f12b6f3cb4401ff8be133fa12689e38d3cedb8142cf47d6101/zensical-0.0.59-cp310-abi3-win_amd64.whl", hash = "sha256:308596a2ff58130b4491c417cafd249c33e709f13b425a4482a3c5deaf4f0cff", size = 14479792, upload-time = "2026-09-03T18:41:08.465Z" }, + { url = "https://files.pythonhosted.org/packages/f7/2e/0e3eccdac45739d9bbf35ac9ab801e07de13f7d9b7cff19a3a4331fd4025/zensical-0.0.59-cp310-abi3-win_arm64.whl", hash = "sha256:6c4e4d706396e63daac3faee4b7ac4bc57b4baded163b97a0375db11ec3fae3f", size = 14190921, upload-time = "2026-09-03T18:41:11.068Z" }, +] diff --git a/zensical.toml b/zensical.toml new file mode 100644 index 0000000..2fc063c --- /dev/null +++ b/zensical.toml @@ -0,0 +1,143 @@ +[project] +site_name = "SpinForge" +site_description = "Group-theoretic magnetic structure generation in Python." +site_author = "Kohei Shinohara" +site_url = "https://spglib.github.io/spinforge/" +copyright = "Copyright © 2026, Kohei Shinohara" + +docs_dir = "docs" + +repo_url = "https://github.com/spglib/spinforge" +repo_name = "spglib/spinforge" +edit_uri = "edit/main/docs/" + +nav = [ + { "Home" = "index.md" }, + { "Learn SpinForge" = [ + { "Installation" = "installation.md" }, + { "Your first structure" = "quickstart.md" }, + { "Examples" = "examples.md" }, + ] }, + { "Understand the model" = [ + { "Domain model" = "domain-model.md" }, + { "Classification model" = "classification-model.md" }, + ] }, + { "Complete a task" = [ + { "Control enumeration" = "control-enumeration.md" }, + { "Use propagation vectors" = "propagation-vectors.md" }, + { "Export files" = "export-files.md" }, + ] }, + { "Technical reference" = [ + { "Enumeration and equivalence" = "equivalence.md" }, + { "File formats" = "file-formats.md" }, + ] }, + { "API reference" = [ + { "Configuration" = "api/configuration.md" }, + { "Space groups" = "api/space-group.md" }, + { "Spin space groups" = "api/spin-space-group.md" }, + { "Magnetic space groups" = "api/magnetic-space-group.md" }, + { "spinCIF" = "api/spincif.md" }, + { "MCIF" = "api/mcif.md" }, + { "Irreducible representations" = "api/irreps.md" }, + ] }, + { "Project" = [ + { "Citation" = "citation.md" }, + { "Changelog" = "changelog.md" }, + { "Third-party data" = "THIRD_PARTY_DATA.md" }, + ] }, +] + +extra_javascript = [ + "javascripts/mathjax.js", + "https://unpkg.com/mathjax@3/es5/tex-mml-chtml.js", +] +extra_css = ["stylesheets/extra.css"] + +[project.theme] +name = "material" +language = "en" +logo = "assets/logo-mark.svg" +favicon = "assets/logo-mark.svg" +features = [ + "content.code.copy", + "content.code.annotate", + "navigation.footer", + "navigation.indexes", + "navigation.instant", + "navigation.sections", + "navigation.top", + "navigation.tracking", + "search.highlight", + "search.suggest", + "toc.follow", +] + +[[project.theme.palette]] +scheme = "default" +primary = "deep purple" +accent = "red" +toggle.icon = "lucide/sun" +toggle.name = "Switch to dark mode" + +[[project.theme.palette]] +scheme = "slate" +primary = "deep purple" +accent = "red" +toggle.icon = "lucide/moon" +toggle.name = "Switch to light mode" + +[project.markdown_extensions.admonition] +[project.markdown_extensions.attr_list] +[project.markdown_extensions.def_list] +[project.markdown_extensions.footnotes] +[project.markdown_extensions.md_in_html] +[project.markdown_extensions.toc] +permalink = true +[project.markdown_extensions.pymdownx.arithmatex] +generic = true +[project.markdown_extensions.pymdownx.details] +[project.markdown_extensions.pymdownx.emoji] +emoji_generator = "zensical.extensions.emoji.to_svg" +emoji_index = "zensical.extensions.emoji.twemoji" +[project.markdown_extensions.pymdownx.highlight] +anchor_linenums = true +line_spans = "__span" +pygments_lang_class = true +[project.markdown_extensions.pymdownx.inlinehilite] +[project.markdown_extensions.pymdownx.magiclink] +[project.markdown_extensions.pymdownx.smartsymbols] +[project.markdown_extensions.pymdownx.snippets] +base_path = ["."] +check_paths = true +[project.markdown_extensions.pymdownx.superfences] +custom_fences = [ + { name = "mermaid", class = "mermaid", format = "pymdownx.superfences.fence_code_format" }, +] +[project.markdown_extensions.pymdownx.tabbed] +alternate_style = true +[project.markdown_extensions.pymdownx.tasklist] +custom_checkbox = true + +[project.plugins.mkdocstrings.handlers.python] +paths = ["src"] +inventories = [ + "https://docs.python.org/3/objects.inv", + "https://numpy.org/doc/stable/objects.inv", + "https://pymatgen.org/objects.inv", +] + +[project.plugins.mkdocstrings.handlers.python.options] +docstring_style = "numpy" +docstring_section_style = "table" +filters = ["!^_"] +inherited_members = true +merge_init_into_class = true +separate_signature = true +show_if_no_docstring = true +show_root_full_path = false +show_root_heading = true +show_signature_annotations = true +show_source = false +show_symbol_type_heading = true +show_symbol_type_toc = true +signature_crossrefs = true