From 0cc9897848adb2752722e44fec66ebc5ec4698ef Mon Sep 17 00:00:00 2001 From: Cail Daley Date: Sat, 11 Jul 2026 11:58:36 +0200 Subject: [PATCH 1/5] =?UTF-8?q?felt:=20fork-implementation=20=E2=80=94=20#?= =?UTF-8?q?243=20green,=20#253=20rework=20under=20fix;=20fork=20PRs=20revi?= =?UTF-8?q?ewed?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01KpaRHk3QwN13myduQ3hJyf --- .felt/lint-gate-autofix/lint-gate-autofix.md | 11 ++ .felt/sp-validation-restructuring.md | 4 +- .../blinding-design/blinding-design.md | 33 ++++ .../data-product-map/data-product-map.md | 45 +++++ .../pr7-sacc-like-design.md | 55 ++++++ .../sacc-layout-contract.md | 56 ++++++ .../smokescreen-api-facts.md | 68 +++++++ .../drafts/issue-tree.md | 63 +++++++ .../drafts/prd-camb-ccl-crosscheck.md | 140 ++++++++++++++ .../drafts/prd-converters.md | 84 +++++++++ .../drafts/prd-cosmo-val-migration.md | 82 ++++++++ .../drafts/prd-dependencies.md | 100 ++++++++++ .../drafts/prd-fork-draw.md | 94 ++++++++++ .../drafts/prd-fork-packaging-ci.md | 100 ++++++++++ .../drafts/prd-fork-protocol.md | 148 +++++++++++++++ .../drafts/prd-native-sacc-likelihood.md | 76 ++++++++ .../drafts/prd-sacc-io-writers.md | 133 +++++++++++++ .../drafts/prd-smokescreen-blinding.md | 177 ++++++++++++++++++ .../drafts/ripple-analysis.md | 105 +++++++++++ .../fork-implementation.md | 63 +++++++ .../smokescreen-fork-replan/grounding.md | 54 ++++++ .../prd241-comments.md | 22 +++ .../smokescreen-fork-replan/prd241.md | 136 ++++++++++++++ .../smokescreen-fork-replan.md | 11 ++ .../smokescreen-sacc-prs.md | 63 +++++++ .../uv-lock-cosmo-numba.md | 37 ++++ .../uv-lock-cosmo-numba.md.lock | 0 27 files changed, 1959 insertions(+), 1 deletion(-) create mode 100644 .felt/lint-gate-autofix/lint-gate-autofix.md create mode 100644 .felt/sp_validation/smokescreen-sacc-prs/blinding-design/blinding-design.md create mode 100644 .felt/sp_validation/smokescreen-sacc-prs/data-product-map/data-product-map.md create mode 100644 .felt/sp_validation/smokescreen-sacc-prs/pr7-sacc-like-design/pr7-sacc-like-design.md create mode 100644 .felt/sp_validation/smokescreen-sacc-prs/sacc-layout-contract/sacc-layout-contract.md create mode 100644 .felt/sp_validation/smokescreen-sacc-prs/smokescreen-api-facts/smokescreen-api-facts.md create mode 100644 .felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/issue-tree.md create mode 100644 .felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-camb-ccl-crosscheck.md create mode 100644 .felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-converters.md create mode 100644 .felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-cosmo-val-migration.md create mode 100644 .felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-dependencies.md create mode 100644 .felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-fork-draw.md create mode 100644 .felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-fork-packaging-ci.md create mode 100644 .felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-fork-protocol.md create mode 100644 .felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-native-sacc-likelihood.md create mode 100644 .felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-sacc-io-writers.md create mode 100644 .felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-smokescreen-blinding.md create mode 100644 .felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/ripple-analysis.md create mode 100644 .felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/fork-implementation/fork-implementation.md create mode 100644 .felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/grounding.md create mode 100644 .felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/prd241-comments.md create mode 100644 .felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/prd241.md create mode 100644 .felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/smokescreen-fork-replan.md create mode 100644 .felt/sp_validation/smokescreen-sacc-prs/smokescreen-sacc-prs.md create mode 100644 .felt/sp_validation/uv-lock-cosmo-numba/uv-lock-cosmo-numba.md create mode 100644 .felt/sp_validation/uv-lock-cosmo-numba/uv-lock-cosmo-numba.md.lock diff --git a/.felt/lint-gate-autofix/lint-gate-autofix.md b/.felt/lint-gate-autofix/lint-gate-autofix.md new file mode 100644 index 00000000..25f883f4 --- /dev/null +++ b/.felt/lint-gate-autofix/lint-gate-autofix.md @@ -0,0 +1,11 @@ +--- +id: 01KX710NNPDHJ0YYXZB4TTN45R +name: 'Server-side ruff autofix bot (PR #264)' +tags: + - sp-validation + - ruff + - ci +created-at: 2026-07-11T00:05:21.462237313+02:00 +updated-at: 2026-07-11T00:05:21.462237313+02:00 +outcome: 'PR #264 (draft): lint gate now autofixes same-repo PRs — ruff --fix-only + format, bot commit pushed to the branch, re-lint in same run (GITHUB_TOKEN push doesn''t retrigger; no recursion). Fork PRs/develop pushes unchanged. Motivated by PR #236''s Copilot whack-a-mole; kills the failure class without anyone running pre-commit install. Awaiting Cail review+merge, then live test via scratch PR (gate runs base-branch workflow, can''t self-test).' +--- diff --git a/.felt/sp-validation-restructuring.md b/.felt/sp-validation-restructuring.md index 186f4138..7dc65bc1 100644 --- a/.felt/sp-validation-restructuring.md +++ b/.felt/sp-validation-restructuring.md @@ -1,13 +1,14 @@ --- id: 01KTCHX03Y3PVZYS5QHFWZRF5N name: SP Validation Restructuring -status: open +status: closed tags: - constitution - sp-validation - reorg - shuttle created-at: 0001-01-01T00:00:00Z +closed-at: 2026-07-10T22:04:28.430224171Z outcome: 'Phase 2 — the top-level moves — complete on cleanup/restructuring (PR #197), guard net green throughout (full suite 86 passed, 0 skipped; move-map guard active with 5 registered moves). The tree has the target shape: workflow/ + papers/{bmodes,catalog,harmonic} (bmodes split), cosmo_val/ promoted from notebooks/ with all tracked references swept and on-disk outputs moved along (candide-absolute paths through the pure_eb symlink stay live), tracked scratch/ with conventions README, one top-level results/ (contents gitignored), root output/ ignored, dead hand-listed notebook block dropped from .gitignore. CI hermeticity restored: the guard suite now passes inside the Docker image (no .git directory, no cluster mounts) — git-querying guards fall back to a tree walk of the image''s tracked-only content, and the workflow dry-run guard skips off-cluster like its data-bound siblings. Cleanup begun: defunct/ deleted; nbstripout + 2 MB large-file pre-commit hooks added (CONTRIBUTING documents activation). Remaining: fold glass_mock core into src/ (own pass), curate notebooks/ to official demos (reduction-notebook triage with Martin), branch/milestone tidy (#188/#189) with Cail.' horizon: now shuttle: @@ -16,6 +17,7 @@ shuttle: host: candide project_dir: /automnt/n17data/cdaley/unions/pure_eb/code/sp_validation agent: claude-opus +tempered: true --- ## Driver session - interactive; first action: land Sacha's #192 diff --git a/.felt/sp_validation/smokescreen-sacc-prs/blinding-design/blinding-design.md b/.felt/sp_validation/smokescreen-sacc-prs/blinding-design/blinding-design.md new file mode 100644 index 00000000..f218456e --- /dev/null +++ b/.felt/sp_validation/smokescreen-sacc-prs/blinding-design/blinding-design.md @@ -0,0 +1,33 @@ +--- +id: 01KX5T7GDXVHPTK7HEB920T15D +name: PR 6 blinding architecture (rulings) +tags: + - decision + - blinding +created-at: 2026-07-10T12:47:31.005842093+02:00 +updated-at: 2026-07-10T12:47:31.005842093+02:00 +outcome: Own seeded RNG draws (dS8,dOm); Smokescreen gets deterministic absolute {sigma8, Omega_c} (coarse xi only); pseudo-Cl + fine grid via direct CCL theory difference; COSEBIs/pure-EB re-derived through pipeline estimators guarded by a round-trip identity test; 4(b) custody = commit sha256(seed), encrypt seed+truth, strip seed_smokescreen. +--- + +The architecture for [[sp_validation/smokescreen-sacc-prs]] PR 6 (issue #252, PRD #241 §3/§4), fixed before the build from the verified facts in [[sp_validation/smokescreen-sacc-prs/smokescreen-api-facts]] and the [[sp_validation/smokescreen-sacc-prs/sacc-layout-contract]]. Four rulings: + +**Randomness is ours, Smokescreen executes.** The PRD's uniform (S8, Ωm) box is inexpressible in Smokescreen's shift dict (keys must be CCL params; tuple = absolute-bounds draw via *global* `np.random.seed`). So `draw_hidden_cosmology(seed, config)` is a pure function — sha256(seed) → `default_rng` → (ΔS8, ΔΩm) in the ±0.075/±0.1 box → hidden `TheoryConfig` via `from_overrides` — and Smokescreen receives deterministic absolute `{sigma8, Omega_c}` (its replace-not-add semantics never bite on single values). Reproducibility contract for §4(b): seed → shift is exact, forever. + +**Two shift paths, one hidden cosmology, pinned together by test.** Coarse ξ± goes through `ConcealDataVector` proper (extract coarse sub-SACC → conceal → verify → apply → merge back; `_verify_sacc_consistency` passes by construction because the likelihood reads its data vector from the same sub-SACC). Pseudo-Cℓ (W @ ΔCℓ_EE on the stored BandpowerWindows; ΔBB=ΔEB≡0, shift is pure E) and fine-grid ξ± (Δξ± at the fine θ) are direct CCL theory differences at the same two cosmologies — the fine grid cannot pass through firecrown (ConstGaussian densifies even a diagonal cov; contract ruling), and the PR-5 likelihood models ξ± only. A cross-path consistency test (Smokescreen factor vs direct-CCL diff at coarse θ) pins the paths; the P(k) recipe (CAMB HMCode2020, halofit_version string) must match — load-bearing, proven in PR 5. + +**Derived statistics are re-derived, never shifted.** COSEBIs and pure-E/B values in the analysis file are replaced by re-running the *same pipeline estimators* (`b_modes.calculate_cosebis`, `calculate_pure_eb_correlation`) on blinded ξ± — no re-implemented kernels. The seam is guarded by a round-trip identity test: unshifted re-derivation must reproduce the analysis-file values exactly. Covariances never change (blinding hides the vector, not the uncertainty). + +**Custody = §4(b) hash commitment.** Blind CLI: OS-entropy seed → blind immediately → publish sha256(seed) (commitment JSON, repo-committed) → encrypt seed + true vectors (`smokescreen.encryption`), delete plaintexts → strip `seed_smokescreen`, stamp `concealed=True`, `blind` label, `blind_commitment` (public hash ties file→commitment). Unblind verifies the hash before subtracting. PR-4's `blind=A` provenance naming reconciles here: the label in blinded metadata is the same axis. + +Snakemake wiring is deliberately out of scope (PR 6 stacks on PR 5, not PR 4); it follows once both land. + +## As landed (PR #253, review-hardened) + +Four amendments earned during build + adversarial review (16 findings → 10 confirmed → all fixed pre-draft): + +- **The Smokescreen path needs `systm_dict`, not just cosmo.** Its theory overlay keeps any firecrown default absent from `cosmo.to_dict()` — IA amplitude rode along at 0.5 vs our fiducial 0.0, polluting the coarse factor ~7% at low θ (invisible to round-trips; caught by demanding the realized-factor-vs-direct test). All non-cosmological fiducial params now pinned via `systm_dict=theory.ia_params()`; regression test guards it. +- **Direct paths are two-tracer.** Cross-pairs get `angular_cl(tracer_i, tracer_j)` with each bin's own n(z) — the auto-n(z) approximation was killed by review (2-bin Smokescreen-vs-direct observed 2.5e-10). +- **Commitment binds (seed, config).** Blinded metadata + commitment JSON carry a config digest (envelope + fiducial); unblind verifies both, so a wrong envelope can't silently subtract a wrong shift. +- **Pure-EB seam follows the pipeline's edge-based integration bounds** (identity vs `calculate_pure_eb_correlation`: rel diff 0.0); boundary-degenerate reporting points are NaN exactly as the pipeline's own estimator — production reporting grids are strict sub-ranges so it never fires on real files. + +Acceptance (observed, container): ΔBₙ/Bₙ = 6.5e-6; Δξ⁺_B = 0.7%, Δξ⁻_B = 2.3% of an injected 2e-5 B-mode; the ΔB is fixed-absolute (E-shift leakage through the estimator), independent of B amplitude. diff --git a/.felt/sp_validation/smokescreen-sacc-prs/data-product-map/data-product-map.md b/.felt/sp_validation/smokescreen-sacc-prs/data-product-map/data-product-map.md new file mode 100644 index 00000000..181124ef --- /dev/null +++ b/.felt/sp_validation/smokescreen-sacc-prs/data-product-map/data-product-map.md @@ -0,0 +1,45 @@ +--- +id: 01KX4MBNPK94DX92BZGCEJR5R3 +name: Current data-product map (origin/develop, pre-SACC) +tags: + - finding + - sacc +created-at: 2026-07-10T01:45:41.587031688+02:00 +updated-at: 2026-07-10T01:45:41.587031688+02:00 +outcome: Where every statistic is computed/written today; feeds PR 2-4 design. SACC surface is greenfield. +--- + +Distilled from an Explore-agent survey of origin/develop (2026-07-10), for the [[sp_validation/smokescreen-sacc-prs]] PRs. File:line anchors are the agent's; re-verify when implementing. + +## Writers today (what sacc_io replaces) + +| Product | Entry | Format today | +|---|---|---| +| ξ± | `cosmo_val/real_space.py` `RealSpaceMixin.calculate_2pcf` | TreeCorr .txt + optional FITS (BIN1/BIN2/ANGBIN/VALUE/ANG) | +| pure E/B | `cosmo_val/pure_eb.py` → `b_modes.calculate_pure_eb_correlation` + `save_pure_eb_results` | .npz (theta, xip_E/B, xim_E/B, amb, cov) | +| COSEBIs | `cosmo_val/cosebis.py` → `b_modes.calculate_cosebis` + `save_cosebis_results` | .npz (En, Bn, cov, chi2/PTE; multi-scale-cut dict) | +| pseudo-Cℓ | `cosmo_val/pseudo_cl.py` mixin over `pseudo_cl.py` primitives (NaMaster) | FITS `pseudo_cl_{ver}_blind={A,B,C}_{binning}_nbins={n}.fits`; separate `pseudo_cl_cov_…` rule (iNKA + optional OneCovariance) | +| ρ/τ | `cosmo_val/psf_systematics.py` → `rho_tau.py` (shear_psf_leakage) | `rho_stats_{base}.fits`, `tau_stats_{base}.fits` + `.npy` covs (th/jk/sim) | +| n(z) | read-only via `core.py get_redshift` from cat-config `nz.path` | FITS or ASCII; no writer in-package | + +## 2pt-FITS assembly (what PR 3 must reproduce byte-for-byte) + +`cosmo_inference/scripts/cosmosis_fitting.py`: `nz_to_fits` (NZDATA HDU), `_create_2pt_hdu` (XI_PLUS/XI_MINUS, QUANT=G+R), `covdat_to_fits` (blocked cov with STRT_i offset headers; xi+ | xi− | optionally TAU_0_PLUS/TAU_2_PLUS blocks). Output `cosmosis_{root}[_cell].fits`. **`tests/test_cosmosis_fitting.py` already exercises this assembly with synthetic deterministic inputs** — the natural scaffold for the PR-3 byte-compare; a *real* current output for the compare must be located on candide (papers/ or cosmo_inference data/ trees) at PR-3 time. + +## Orchestration & tests + +- Snakemake: `workflow/rules/twopoint.smk` — rules `xi`, `xi_highres` (10000-bin fine grid for COSEBIs), `rho_tau_stats`, `pseudo_cl`, `pseudo_cl_cov`; scripts in `workflow/scripts/` wrap the mixins (PR-4 touch points). +- `CosmologyValidation` (`cosmo_val/core.py`): versions + cat-config YAML; `_output_path`; **a `blind` A/B/C label already threads through pseudo-Cℓ naming — vestigial catalogue-level blinding, superseded by data-vector blinding; PR 6 should reconcile.** +- Tests import the full stack (container/venv); fast/slow markers; `test_glass_mock.py` + `glass_mock.py` generate synthetic catalogues → basis for PR-6 mocks. + +## Facts that shape the design + +- **SACC is greenfield** — one stray `.sacc` string in `test_config_paths_exist.py`, nothing else. +- Everything is single-bin (non-tomographic) today; tomography is the round's target → sacc_io is tomography-native from day one (`source_i` tracers), single-bin as the n=1 case. +- OneCovariance glue half-exists: `statistics.py cov_from_one_covariance` reshapes its flat output (col 9/10 gauss+ng/gauss). PR 3 adds the n(z)→OneCovariance input side. Sacha's `scratch/guerrini/one_covariance.py` overlaps — reserved, don't touch, don't import. +- Fine vs coarse ξ± in ONE sacc file needs a mechanism (likely sacc data-point tags); the PR-2 round-trip tests must verify whatever is chosen survives write→read. + +## Real 2pt-FITS references for the PR-3 byte-compare (located 2026-07-10) + +- Real data: `cosmo_inference/data/SP_v1.4.6_leak_corr_A_minsep=1.0_maxsep=250.0_nbins=20_npatch=1/cosmosis_SP_v1.4.6_leak_corr_A_….fits` (+ non-leak-corr sibling; also SP_v1.4.5 variants). +- Mocks: hundreds of `cosmo_inference/data/glass_mock_NNNNN/cosmosis_glass_mock_NNNNN.fits`. diff --git a/.felt/sp_validation/smokescreen-sacc-prs/pr7-sacc-like-design/pr7-sacc-like-design.md b/.felt/sp_validation/smokescreen-sacc-prs/pr7-sacc-like-design/pr7-sacc-like-design.md new file mode 100644 index 00000000..658a67dc --- /dev/null +++ b/.felt/sp_validation/smokescreen-sacc-prs/pr7-sacc-like-design/pr7-sacc-like-design.md @@ -0,0 +1,55 @@ +--- +id: 01KX65DDG2WNEW8HEYJ2HZZQ5K +name: PR 7 native sacc_like adoption (design rulings) +tags: + - decision + - sacc +created-at: 2026-07-10T16:02:58.946571302+02:00 +updated-at: 2026-07-10T17:11:27.695848437+02:00 +outcome: 'Landed as PR #255 (closes #254): shim over CSL SaccClLikelihood (arcmin/rad copy-swap + ordering guard), inference_prep revived onto {version}.sacc, chi2 equality with 2pt_like observed to machine zero (synthetic + real data); 2 MEDIUM review findings fixed pre-draft.' +--- + +Design rulings for PR 7 of [[sp_validation/smokescreen-sacc-prs]] (PRD #241 row 7: "adopt CosmoSIS's native SACC likelihood, validated against the PR-3 converter path"), grounded in a source read of CSL `likelihood/sacc/` at commit 4fd2f1c (2026-06-12, shallow clone at `sp_validation-worktrees/csl/`). + +## The prototype-grade verdict, now with mechanisms + +Three concrete defects/hazards found in upstream `sacc_like.py` + `sacc_likelihoods/twopoint.py`: + +1. **No angular-unit conversion (the killer).** `twopoint.py` L74–90 builds `SpectrumInterp(block[section,"theta"], theory)` — theory θ in **radians** (CosmoSIS convention) — and evaluates it at raw SACC `theta` tags (**arcmin**, our contract + firecrown convention). `2pt_like.py` L179–183 by contrast explicitly converts data to radians ("The units in cosmosis are all in radians"). With arcmin tags the spline is evaluated ~3437× outside its grid → SpectrumInterp returns 0 outside range → theory ≈ 0, χ² = dᵀC⁻¹d, **silently**. The HSC Y3 use was the Cℓ path (ℓ unit-free), which is why this never bit upstream. +2. **`keep_tracers` removal path references undefined `t1, t2`** (`sacc_like.py` L106: `s.remove_selection(tracers=(t1,t2))` — those names are stale loop variables; NameError or wrong-pair removal if the filter ever matches). We don't use `keep_tracers`; do not touch. +3. **Theory↔data ordering is assumed, not enforced.** Data vector = `s.get_mean()` (insertion order); theory = loop over `get_data_types()` × `get_tracer_combinations()` × points. A comment (L35) claims `to_canonical_order` was called on load — **it never is**. Aligned only when the file is grouped type-major-then-tracer in exactly that loop order. Our single-pair files ([ξ+ block; ξ− block]) align; tomographic pair-major files would silently misalign — same bug class the PR-2/PR-3 adversarial reviews caught. + +## Rulings + +- **Adopt by subclass, not fork or reimplementation**: `SaccLikeUnions(SaccClLikelihood)` — an sp_validation-owned CosmoSIS module file. Overrides `build_data()`: call super (cuts happen in arcmin, matching ini ergonomics and 2pt_like's angle_range convention), then (a) convert `theta` tags arcmin→rad on the in-memory `sacc_data` for real-category types, (b) run a loud ordering guard (reconstruct the theory-loop index order; require it equals arange — ValueError otherwise). Everything else (scale-cut grammar, Sellentin/Hartlap, save_theory, windows for Cℓ) rides upstream unmodified. Shim dies when upstream fixes units. +- **`like_name = 2pt_like`** in the ini (base class honors the option) so chain post-processing and `extra_output` see identical block keys across engines. +- **n(z) natively**: CSL ships `number_density/load_nz_sacc` (verified: reads NZ tracers `source_i`, zero-based contiguous, → `nz_source` section) — the native path needs no 2pt-FITS anywhere. +- **inference_prep rewiring honors PR 4's dormant-note contract**: consume assembled `{version}.sacc`, emit (a) converter 2pt-FITS + 2pt_like ini [the validating/legacy path, retiring cosmosis_fitting.py assembly] and (b) sacc_like ini pointing at the SACC [the native path]. Scope = the A_ia (IA-only, ξ±) fiducial pipeline; the PSF/xi_sys variant and glass-mock rules stay dormant/cosmosis_fitting-based (flagged in PR body, not silently). +- **Validation = in-process module equality**, not full-pipeline: both modules loaded standalone (`build_module()` setup/execute on a hand-built DataBlock carrying identical synthetic theory in `shear_xi_plus/minus`), same data through SACC vs converter-FITS → assert χ²/like equal (tight rtol), theory vectors equal, post-cut point counts equal; teeth = data perturbation moves both identically, unit regression (upstream class without shim → wildly different χ², documenting the bug), ordering guard raises on a pair-major 2-bin file. Real-data equality test candide-gated like PR 3's. No CAMB, no compiled CSL modules needed — pure-python likelihood files + pip `cosmosis` (3.25.2 verified importable py3.12; installed into shared venv). +- **Branch**: `feat/sacc-7-sacc-like` from `feat/sacc-4-migration` + merge `feat/sacc-3-converter` (needs PR 4's workflow surface AND PR 3's converter; they share the sacc-2 base and are disjoint). PR base = feat/sacc-4-migration; body flags the merged-in #249 content until the stack collapses. +- **Upstream CSL issues (units, L106) are out of scope** for a CosmoStat/sp_validation draft-PR fiber — recommended as follow-up in the PR body; Cail/team decide about posting to joezuntz/cosmosis-standard-library. + +## Open (settle during build) + +- Edge semantics of scale cuts at exact boundary values (sacc `remove_selection` lt/gt is inclusive-keep; 2pt_like's spectrum cut may differ) — test with off-point cut values, verify same post-cut N on both paths. +- `get_data_types()` order determinism (insertion-unique vs sorted) — probe empirically; the ordering guard makes either safe but the guard's construction needs the truth. +- Whether CI can run any of the cosmosis tests (image lacks cosmosis) — gate with `pytest.importorskip("cosmosis")` + CSL-dir env (`CSL_DIR`), cosmo_numba precedent. + +## As landed (PR #255, sub-issue #254) + +The open questions above all settled during the build: + +- **Scale-cut edge semantics**: no divergence observed — both engines produced identical post-cut N and χ² on the tested ranges; cut values in the templates don't land on data points. +- **`get_data_types()` order**: the ordering guard reconstructs the upstream theory loop faithfully regardless (tested against a pair-major 2-bin file — raises loudly); the single-pair files align. +- **CI**: `test_sacc_like.py` gates on `importorskip("cosmosis")` + `CSL_DIR`, skips cleanly in the image; the `[cosmosis]` extra is inert there (Dockerfile installs explicit extras). + +Two builder deviations accepted as improvements: a `_realistic_sacc` fixture (cov ~ (0.1|ξ|)²) because PR-3's byte-compare fixtures have χ²~1e-9 — no teeth for χ² dynamics; real-data equality scoped ξ-only (the full 2pt-FITS's COVMAT_CELL/τ blocks trip `twopoint.from_fits`, and ξ± is the A_ia scope). + +Adversarial review (5 opus lenses, 3 sonnet refuters/finding, 17 agents) confirmed 2 of 4 findings, both MEDIUM, both empirically reproduced and fixed pre-draft: + +1. **save_theory/save_realization wrote radian θ tags** — the shim's in-place tag mutation leaked into upstream's save-by-copy paths (a consumer reading arcmin is 3437× off; re-ingestion double-converts to ~8.5e-8). Fix: `self.sacc_data` stays arcmin; theory extraction swaps in a radian-θ copy (`_sacc_data_rad`) around `super().extract_theory_points` in try/finally. Regression test pins arcmin tags in saved output + re-execution χ² stability. +2. **Ini templates were rule `params`, not `input`s** — no DAG edge, so template edits never regenerated configs. Fix: templates bound as inputs, anchored on the running checkout (`INFERENCE_TEMPLATE_DIR`) with generated configs still landing in `COSMO_INFERENCE`; dry-run guard asserts the edge. + +Killed by refuters (correctly): boundary-semantics test-coverage nit; N=5-vs-20 fixture-size nit. + +Final observed numbers: shim ≡ 2pt_like at machine zero — synthetic χ² = 1.18829133107 (Δχ²=0, Δtheory=0), real SP_v1.4.6_leak_corr ξ-only χ² = 420310.753739 (N=40, Δχ²=0); tripwire: raw upstream ~631× off. Test surfaces: 8 sacc_like + 5 generator + 3 dry-run guards = 16 passed (independently re-run by the orchestrator); fast suite 202 passed / 1 pre-existing unrelated failure (config-paths-on-candide); ruff clean. diff --git a/.felt/sp_validation/smokescreen-sacc-prs/sacc-layout-contract/sacc-layout-contract.md b/.felt/sp_validation/smokescreen-sacc-prs/sacc-layout-contract/sacc-layout-contract.md new file mode 100644 index 00000000..20475444 --- /dev/null +++ b/.felt/sp_validation/smokescreen-sacc-prs/sacc-layout-contract/sacc-layout-contract.md @@ -0,0 +1,56 @@ +--- +id: 01KX4PKRY0KX848SNW2WZ5TZB0 +name: SACC layout contract (PR 2, grounds PRs 3/4/6) +tags: + - decision + - sacc +created-at: 2026-07-10T02:25:04.192529552+02:00 +updated-at: 2026-07-11T00:05:05.61612283+02:00 +outcome: ONE SACC file per catalogue version (re-ruled 2026-07-11 — the 10k-bin premise was a one-time convergence check; production fine grid is 1000 bins, and Paper II's dense CosmoCov fine covariance exists and is load-bearing). Fine ξ± rides as grid='fine' points with a dense per-pair block. Tags carry grid/scale-cut/mode; custom types for rho/tau/pure-EB; insertion-order covariance assembly. +--- + +The file-layout contract for [[sp_validation/smokescreen-sacc-prs]] PR 2 (`sacc_io`), fixed 2026-07-10 from empirical probes of sacc 2.4 (probe scripts: `sp_validation-worktrees/env-probe/sacc-probe/`) and the write-site inventory. PRs 3 (converter), 4 (migration), and 6 (blinding) consume this contract; change it only with a reason strong enough to re-open all three. + +## One file per catalogue version — the two-file split is retired (re-ruled 2026-07-11) + +The 2026-07-10 ruling split `{version}_xi_fine.sacc` out because a 10000-bin fine grid couldn't coexist with the analysis covariance (`covariance.size == len(mean)`; dense fine block = 3.2 GB single-bin). Cail: **10k was a one-time convergence check, never a production point.** Paper II production fine grid is **1000 bins, 0.5–300′** (`analyses/shear_2d/bmodes_2d/config/config.yaml` L34–36; the paper's "0.5–500" is a typo), where a dense per-pair fine block is 2000² ≈ 32 MB — unremarkable. + +Moreover the fine-grid covariance is not a placeholder: **Paper II's dense Gaussian CosmoCov covariance is computed *at* the 1000-bin integration binning and is the input to the derived-statistic covariances** — pure-E/B errors via 2000 MC draws through the Schneider transform, COSEBIs via matrix transform (`b_modes.py` L171–235 / L258–327; jackknife on the fine grid explicitly rejected as too noisy, `bmodes_2d/config/covariance.md`). Storing it is load-bearing for downstream error propagation. + +- **`{version}.sacc`** — everything. NZ tracers `source_i`; coarse ξ±, pseudo-Cℓ (EE/BB/EB) with `BandpowerWindow`s, COSEBIs at the fiducial scale cut, pure-E/B, ρ/τ; **and fine ξ± as `grid='fine'` tagged points**. Covariance is `BlockDiagonal`: the analysis block(s) as before (zero cross-blocks — the same independence assumption today's `cosmosis_fitting.py` `np.block` assembly makes), plus a dense per-pair fine block from the CosmoCov integration covariance when it exists, `varxip`/`varxim` diagonal as the explicit degraded fallback. Insertion order: analysis points contiguous first, then fine points, so blocks tile the mean. +- Extreme grids (a future 10k-style check) degrade to a diagonal fine block; they don't fork the file format. +- PR 6 unaffected in design: Smokescreen's `_verify_sacc_consistency` already forces per-block extract→blind→merge passes, so blinding the fine block is its own pass inside the same file; the fine-grid shift stays a direct CCL theory difference, not a likelihood pass. + +This restores the PRD §1 letter (one self-describing file per catalogue version); note the reversal on #241 and in the PR #245 body. Run-time access to "just the usual data vectors" is a Snakemake-parts concern, not a file-layout one: the terminal file is a pure gather; anyone wanting only coarse ξ targets the coarse part rule. (COSEBIs/pure-E/B depend on fine ξ in *any* layout, so a split never shortened the critical path.) + +**Naming stability is scoped to the terminal file above.** The per-statistic *parts* (`{version}_xi_coarse_…​.sacc`, tagged `pseudo_cl_…​.sacc`, `{version}_cosebis.sacc`, …) are internal DAG intermediates; their filenames carry the producing rule's binning/tag wildcards where Snakemake's one-wildcard-set-per-rule constraint demands it (PR-4 design ruling, adversarially reviewed). Consumers bind parts through the workflow's path helpers, never by hardcoding part names. + +## Data types and tracers + +| Product | Type string | Tracers | Point tags | +|---|---|---|---| +| ξ± coarse/fine | `galaxy_shear_xi_plus/minus` (standard) | (`source_i`,`source_j`) | `theta` (=TreeCorr `meanr`, **arcmin**), `theta_nom` (=`rnom`), `npairs`, `weight`, `grid`=`coarse`\|`fine` | +| pseudo-Cℓ | `galaxy_shear_cl_ee/bb/eb` (standard) | (`source_i`,`source_j`) | `ell` (effective), `window`/`window_ind` (one shared `BandpowerWindow(ells, W(nell,nbp))` per `add_ell_cl` call) | +| COSEBIs | `galaxy_shear_cosebi_ee/bb` (standard; ee=Eₙ, bb=Bₙ) | (`source_i`,`source_j`) | `n` (mode, 1-based), `theta_min`, `theta_max` (arcmin scale cut) | +| pure E/B | `galaxy_shear_xiPureE_plus/minus`, `…xiPureB_…`, `…xiPureAmb_…` (custom, grammar-valid) | (`source_i`,`source_j`) | `theta`, `theta_min`, `theta_max` if cut | +| ρₖ (PSF autos) | `psf_rho{k}_xi_plus/minus`, k=0…5 (custom) | (`psf_stars`,`psf_stars`) Misc | `theta` | +| τₖ (gal×PSF) | `galaxyPsf_tau{k}_xi_plus/minus`, k∈{0,2,5} (custom) | (`source_i`,`psf_stars`) | `theta` | +| n(z) | — | NZ tracer `source_i` (z, nz round-trip bitwise) | — | + +Pure-E/B writers are a deliberate addition beyond the PRD row-2 list: §3 derives them from blinded ξ± and the PR-6 acceptance test measures them; they need a home. Custom type strings all parse under `sacc.parse_data_type_name` (3–4 underscore parts) even though sacc doesn't enforce it. + +## Ordering and covariance assembly + +Insertion order is preserved bitwise through save/load (probed; `save_fits` never reorders) and covariance rows align to it. **Alignment holds by construction** (hardened by adversarial review before PR #245 opened): writers *enforce* strictly ascending θ/ℓ grids (loud ValueError), readers return `s.indices` insertion order (never re-sort — reader-side sorting is exactly what lets data, covariance sub-blocks, and window columns silently diverge), and bin pairs normalize to i≤j. Canonical order is **pair-major**: per `add_xi` call `[ξ+; ξ−]` (θ ascending, matching TreeCorr's cov layout), then Cℓ EE/BB/EB, COSEBIs (Eₙ then Bₙ), pure-E/B in `b_modes._EB_KEYS` order (verified: b_modes.py L19, sliced L392), ρ, τ. A tomographic ξ covariance with cross-pair correlations is supplied to `assemble_covariance` as ONE contiguous block spanning consecutive `add_xi` calls; type-major consumers (DES 2pt-FITS, PR 3) permute via `s.indices`. The assembler validates blocks contiguous-ascending, tiling `0..len(s.mean)` exactly, square and size-matched — loud ValueError otherwise. + +## API surface (module `src/sp_validation/sacc_io.py`) + +Builders `new_sacc(nz, metadata)` / `add_xi` / `add_pseudo_cl` / `add_cosebis` / `add_pure_eb` / `add_rho` / `add_tau` / `assemble_covariance(s, blocks)`; readers `get_xi(s, bins, grid=…)` etc. mirroring each writer (+ `get_nz`); `extract(s, …)` = `copy()`+`keep_selection` wrapper (probed: sub-covariance comes out exactly right, tag filters compose); thin `save`/`load`. Tomography-native `bins=(i,j)`; single-bin = `(0,0)`. Metadata: `catalogue_version`, `sp_validation_version`, `created`, `npatch`. + +## sacc 2.4 gotchas (probed) + +- Tag filters are **plain kwargs**: `s.indices(dt, tracers, grid='fine')`. The tempting `tags={'grid':'fine'}` silently returns `[]` with only a UserWarning. +- `get_theta_xi` accepts **no** tag filters — readers go through `indices`/`get_mean`/`get_tag`. +- `get_ell_cl(..., return_windows=True)` doesn't exist in 2.4; use `s.get_bandpower_windows(indices)`. +- Tracers must be added before any data point referencing them (`tracers_later=True` escape exists; don't use it). +- `add_covariance` with a 1-D array → `DiagonalCovariance`; with `np.diag(...)` → `FullCovariance` (wasteful for a diagonal fine fallback — pass the 1-D). diff --git a/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-api-facts/smokescreen-api-facts.md b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-api-facts/smokescreen-api-facts.md new file mode 100644 index 00000000..31f8a1eb --- /dev/null +++ b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-api-facts/smokescreen-api-facts.md @@ -0,0 +1,68 @@ +--- +id: 01KX4M42SJY25YJ6JM2H0DPR3Z +name: 'Smokescreen 1.5.6 + firecrown: verified API facts' +tags: + - finding + - sacc + - blinding +created-at: 2026-07-10T01:41:32.850257146+02:00 +updated-at: 2026-07-10T01:41:32.850257146+02:00 +outcome: Smokescreen requires py3.12 + extract-blind-merge architecture; firecrown not pip-resolvable (numcosmo_py) → --no-deps + explicit closure; PRD's (S8,Ωm) box needs our own seed→shift translation layer +--- + +Verified facts about Smokescreen 1.5.6 (PyPI) and firecrown v1.15.1, read from source and PyPI metadata on 2026-07-10. These ground PRs 1, 5, and 6 of [[sp_validation/smokescreen-sacc-prs]]. + +## Packaging (PR 1) + +- **Smokescreen 1.5.6** is on PyPI (name `Smokescreen`), `requires-python >=3.12` — this is where the PRD's py3.12 floor comes from. Deps: astropy≥5.2, cryptography, jsonargparse[signatures]≥4, numpy≥2.2, sacc≥0.12, scipy≥1.9, pytest (sloppy upstream runtime dep, harmless). It imports firecrown at module level (`smokescreen/datavector.py:31`) but does **not declare it** — DESC assumes conda-forge. +- **firecrown is not on PyPI**; conda-forge only. Git tag v1.15.1 pip-installs from source (setuptools-scm), but its declared deps include `numcosmo_py`, which doesn't exist on PyPI → **uv/pip resolution is impossible with deps**. Since ≤v1.12 this has been so. Consequence: firecrown installs `--no-deps` from the git tag, with its actually-needed runtime closure declared explicitly by us (pyccl, sacc, pydantic, …— empirically determined; see env recipe in the PR-1 body). Smokescreen 1.5.6 supports firecrown ≥1.15 via explicit version-gated imports (`datavector.py:34`). +- The container base (shapepipe:develop) is already `python:3.12-slim-bookworm`, so `requires-python = ">=3.12"` aligns pyproject with the actual runtime; no base-image change needed. + +## ConcealDataVector mechanics (PR 6) + +`ConcealDataVector(cosmo, likelihood, shifts_dict, sacc_data, systm_dict=None, seed="2112", shift_distr="flat")`: + +- `likelihood` is a **path to a module file** (or module) exposing firecrown's `build_likelihood(build_parameters)` convention; it receives `NamedParameters({'sacc_data': sacc_data})`. The sampling likelihood stays CosmoSIS; only `compute_theory_vector` is used. +- **`_verify_sacc_consistency` requires `sacc_data.mean` to equal `likelihood.get_data_vector()` element-for-element** (`datavector.py:209-266`) — the SACC file handed to Smokescreen must contain *exactly* the rows the likelihood models, nothing else. A master file carrying COSEBIs + ρ/τ cannot be passed directly. → **extract → blind → merge**: extract the to-be-blinded block (ξ± / pseudo-Cℓ) with its covariance sub-block into a temporary SACC, blind it, merge values back into the master, then re-derive COSEBIs/pure-E/B from blinded ξ±. Same seed ⇒ same hidden cosmology across per-block passes, so fine-grid ξ±, coarse-grid ξ±, and Cℓ blind consistently in separate passes. +- **Seed leak**: `save_concealed_datavector` stamps `metadata['seed_smokescreen'] = seed` (`datavector.py:580`), plus `concealed=True`, creator, timestamp. We strip the seed key (the PRD's "strip it"). +- Blinding factor: `calculate_concealing_factor(factor_type="add")` → f = t(hidden) − t(fid); `apply_concealing_to_likelihood_datavec()` adds it to `likelihood.get_data_vector()`. + +## Shift semantics — the (S8, Ωm) box needs our own translation layer (PR 6) + +`draw_flat_or_deterministic_param_shifts(cosmo, shifts_dict, seed)` (`param_shifts.py:56`): + +- Keys are validated against **CCL parameter names** (`cosmo._params`) — `S8` and `Omega_m` are not CCL params, so the PRD's "uniform in (S8, Ωm)" **cannot be expressed directly**. +- Tuple values are **absolute (lo, hi) bounds** (uniform draw of the new value, not a delta); single values are **absolute replacements** despite the docstring claiming FIDUCIAL+SHIFT (`_create_concealed_cosmo` does `dict[k] = shifts[k]`). +- Draw uses global `np.random.seed(string_to_seed(seed))` in `cosmo.to_dict()` key order — deterministic given seed. + +Design: our blinding step draws (ΔS8, ΔΩm) itself from a seeded RNG, converts to absolute `{sigma8: S8/√(Ωm/0.3), Omega_c: Ωm − Ωb − Ων}`, and passes those as **deterministic** values to Smokescreen. Seed→shift stays a pure function (reproducible, hash-commitment-friendly); the box is exactly the PRD's. + +## Encryption / plaintext deletion (PR 6) + +`smokescreen.encryption.encrypt_file(path, save_file=True, keep_original=False)` — Fernet key, writes `.encrpt` + `.key` side by side, deletes plaintext when `keep_original=False`. Key lives on the same disk (PRD: "protection is social discipline either way"). `decrypt_file` restores. + +## pip-installability: the full story (empirical, 2026-07-10) + +Resolution alone wasn't enough — two import-time walls surfaced only when actually running: + +- **numpy < 2.5 is required**: firecrown 1.15.1's `DataVector` subclasses `npt.NDArray`, which numpy 2.5 turned into a non-subclassable typing alias → TypeError at import. Bisected to exactly 2.5.0. `[blinding]` carries `numpy>=2.2,<2.5`; 2.4.x verified ABI-clean against the whole compiled stack + fast suite (111 passed; 2 failures are env-shaped: hardcoded `python3.12 -m snakemake`, and candide-path expectations in a fresh worktree). +- **Unpatched firecrown imports NumCosmo** through two non-cosmic-shear paths (eager LSST-bin re-export in `generators/__init__`; cluster likelihoods → lsstdesc-crow → `Ncm.IntegralND` subclass at module load). `scripts/patch_firecrown.py` (in PR #243) fixes both + ships a loud `numcosmo_py` shim; exact-string surgery, version-checked against the v1.15.1 pin, idempotent, self-verifying. Deceptive-green guard: CI's image build now smoke-tests `import sacc; import firecrown.likelihood; import smokescreen`. +- firecrown's real pip closure beyond the base scientific stack is just `lsstdesc-crow` (pydantic/pyyaml/rich/typer arrive with the base stack); the uv-overrides route installs it automatically as a firecrown dep. + +**Correction to a subagent claim**: Smokescreen 1.5.6 DOES ship `smokescreen.encryption` (`encrypt_file`/`decrypt_file`, verified in installed site-packages) — an env-report claimed otherwise; the source read above stands. + +**Watch item for PR 5** (RESOLVED — see PR 5 landed facts below): firecrown's environment.yml pins `sacc>=2.1,<2.2`; we run sacc 2.4 (PRD + Smokescreen require it). Toy pipeline fine; validate firecrown's SACC internals on real tomographic data in PR 5. + +**Shared venv state**: `/automnt/n17data/cdaley/unions/code/sp_validation-worktrees/venv` = `[test,glass,blinding]` pins + numpy 2.4.3 + `patch_firecrown.py` applied. Toy probes in `sp_validation-worktrees/env-probe/` all pass on it (finite 60-elt theory vector; blinded ≠ original; cov untouched; seed visible in metadata pre-strip). + +## PR 5 landed facts (2026-07-10, empirical — likelihood + review probes) + +- **`ConcealDataVector` consumes `sp_validation.blinding_likelihood` as-is** — driven end-to-end in review: `_load_likelihood` (ModuleType path) → `_verify_sacc_consistency` passes → `calculate_concealing_factor(factor_type="add")` → `apply_concealing_to_likelihood_datavec()`; the applied shift equals the theory difference exactly. +- **Smokescreen never passes `theory_config` through `build_parameters`** — `_load_likelihood` sends only `{'sacc_data': ...}`. The module's `TheoryConfig()` *defaults are the blinding fiducial*; overrides are reachable only from direct callers (tests, CLI). PR 6 sets the fiducial by changing the defaults (one config surface), not by threading overrides through Smokescreen. +- **Watch item resolved**: sacc 2.4 works through firecrown 1.15.1's full `read` + `compute_theory_vector` on tomographic-shaped `sacc_io` files despite firecrown's `sacc<2.2` environment.yml pin — no issue surfaced anywhere in PR 5's 19 tests or the review probes. +- **CAMB↔CCL floor** (single-bin synthetic fixture, 12 θ ∈ [5,250]′, HMCode2020+feedback, σ8-matched): ξ+ 0.21% / ξ− 0.10%; tolerances 0.5%/1.0%. σ8-matching is load-bearing — nominal A_s leaves σ8 3% off and blows the comparison to ~9–10%. The `halofit_version` string must match on both stacks (mead2020 vs mead2020_feedback differ by several % at k≳1). +- **CCLFactory routing**: `camb_extra_params` requires `creation_mode=PURE_CCL_MODE` (+ default `BOLTZMANN_CAMB` transfer); in DEFAULT mode firecrown/CCL already default to halofit-nonlinear. `firecrown.modeling_tools` is the non-deprecated import path for `CCLFactory`/`PoweSpecAmplitudeParameter` (member `.AS` — misspelling "Powe" is upstream's). + +## PR 6 landed fact: Smokescreen's systematics overlay (found as a real bug, 2026-07-10) + +`calculate_concealing_factor` builds BOTH theory vectors via `modify_default_params(firecrown_defaults, cosmo.to_dict(), systm_dict)` — and `ccl.Cosmology.to_dict()` carries no systematics, so **any firecrown default not overridden via `systm_dict` silently rides along** (observed: `ia_bias=0.5` while our fiducial sets 0.0 — the coarse Smokescreen factor diverged ~7% at low θ from the direct-CCL fine/Cℓ paths of the same blind; round-trip tests cannot see it because the same factor cancels). Consequence: **every non-cosmological parameter of the blinding fiducial must be pinned through `ConcealDataVector(systm_dict=…)`** — PR 6 passes `theory.ia_params()` and regression-guards Smokescreen's realized factor against the direct path (<1e-8; fails ~7% if the pin drops). diff --git a/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/issue-tree.md b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/issue-tree.md new file mode 100644 index 00000000..66de0ea0 --- /dev/null +++ b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/issue-tree.md @@ -0,0 +1,63 @@ +# Proposed issue tree: SACC + Smokescreen-fork blinding stream + +Board model (UNIONS-WL/projects/1): work areas slice; **everything is an issue**; **PRs are never cards — they ride Development links** via same-repo `Closes #N`; issues nest as sub-issues (cross-repo nesting allowed and survives transfer); **file each issue in the repo where the code changes**; the umbrella carries `Kind = Epic` and **no Status**; every item carries a `Work area`. + +**Numbering convention in this doc.** Nothing is posted to GitHub yet, so board issue numbers are *not yet assigned* — issues are named with symbolic placeholders (`ISSUE-DEPS`, `ISSUE-FORK`, …). The `#NNN` integers below are the *existing draft PRs* against the old PRD (#243/#245/#249/#251/#253/#255) and refer to PRs only, never issues. #232/#234/#241 are the real, already-existing umbrella/design/PRD numbers. + +Two repos are in play: +- **`CosmoStat/sp_validation`** — all format/migration/blinding-wiring/inference work. +- **`UNIONS-WL/Smokescreen`** (the new fork) — the fork + backend-independence work. + +## Tree + +``` +EPIC sp_validation #232 "SACC data format + Smokescreen blinding" [Kind=Epic, no Status] + (existing umbrella; design lives in PRD #241 / issue #234) +│ +├─ #234 PRD/design issue (sp_validation) ← PRD #241 text +│ +├─ ISSUE-BOARDCFG Add UNIONS-WL/Smokescreen to the effort +│ repo: UNIONS-WL/unions-wl.github.io (board-config home; precedes ISSUE-FORK) +│ +├─ ISSUE-FORK Fork Smokescreen + backend independence +│ repo: UNIONS-WL/Smokescreen (cross-repo sub-issue under #232) +│ ├─ ISSUE-FORK-PROTO theory_fn protocol + default CCL backend + fixed draw + firecrown lazy-sidelining + fork-test migration → sub-PR +│ └─ ISSUE-FORK-PKG packaging/install-identity + fork CI + pip-only docs → sub-PR (unblocks ISSUE-DEPS) +│ +├─ ISSUE-DEPS Dependencies (sp_validation) ← draft PR #243 +├─ ISSUE-SACCIO sacc_io writers (sp_validation) ← draft PR #245 +├─ ISSUE-CONV Converters (sp_validation) ← draft PR #249 +├─ ISSUE-MIGRATE cosmo_val migration (sp_validation) ← draft PR #251 +├─ ISSUE-BLIND Smokescreen blinding wiring (sp_validation) ← draft PR #253 (reworked onto fork; CAMB↔CCL cross-check folded in) +└─ ISSUE-SACCLIKE Native SACC likelihood (sp_validation) ← draft PR #255 +``` + +Each `ISSUE-*` gets a fresh board number when filed; each draft PR attaches to its issue via same-repo `Closes #`. Do not reuse the draft-PR integers as issue numbers — they are already spent as PRs, and typing them as issue IDs would collide. + +## The one new issue + +**`ISSUE-FORK` — "Fork Smokescreen to UNIONS-WL and make it theory-backend independent."** +- **Repo:** `UNIONS-WL/Smokescreen`. This is where the code changes, so the issue lives there even though its parent epic is in sp_validation. Cross-repo nesting is the board's designed behavior. +- **Parent:** sp_validation #232 (the existing SACC/blinding epic). +- **Body:** fork DESC Smokescreen to the UNIONS-WL org (community-facing blinding object); add a `theory_fn(cosmo_params) -> np.ndarray` backend protocol plus a built-in default CCL backend (so a standard cosmic-shear SACC file blinds out of the box; power users override with their own callable); make the inherited firecrown path lazy and optional (no module-level import) — it stays but is not installed, tested, supported, or maintained here; replace the global-seed/order-dependent draw with a fixed pure draw speaking CCL-native parameter names (no injectable-`draw_fn` abstraction — deferred); declare `pyccl` explicitly in the fork's `pyproject` (the default backend uses it; stock Smokescreen imports it at module level without declaring it) and settle the fork's install identity as a pinned `git+https` tag/SHA (no rename, no PyPI publish); migrate the fork's own test suite off module-level firecrown; add a backend smoke-test as the required CI gate; write pip-only install docs (`pip install git+https://github.com/UNIONS-WL/Smokescreen@` — no conda, no PyPI) noting the firecrown path is inherited-and-unsupported. No PR against DESC upstream; keep the fork diff small and clean for eventual upstream-PR-ability. **Acceptance:** a synthetic callable blinds a SACC vector end-to-end; the default CCL backend blinds a standard cosmic-shear SACC file; the amplitude envelope is expressed through CCL-native parameters; the fork blinds a real sp_validation `sacc_io` file end-to-end. +- **Decomposed now, not conditionally** — PR 0.1 is the highest-risk PR and one of its parts (packaging/CI) is the board's critical-path unblock. Two sub-issues, each with its own sub-PR: + - **`ISSUE-FORK-PROTO`** — `theory_fn` protocol + default CCL backend (`datavector.py` + a new backend module) + fixed pure draw (`param_shifts.py`) + firecrown lazy-sidelining + fork-test migration. The draw fix folds in here: with the injectable abstraction dropped it is a small change coupled to the same `datavector` rewrite. + - **`ISSUE-FORK-PKG`** — install identity (pinned `git+https` tag/SHA) + `pyccl` declaration + fork CI + pip-only docs. **This one unblocks `ISSUE-DEPS` and should not wait on review of the large protocol refactor.** + Each sub-PR carries `Closes #` in `UNIONS-WL/Smokescreen`. +- **Fields:** `Work area` = same blinding/SACC area as the rest of the stream (read the live option off the board; do not hardcode). `Kind = Task`. + +**`ISSUE-BOARDCFG` — "Add UNIONS-WL/Smokescreen to the effort."** Per the board model ("everything is an issue"), the board-config work is itself a card, not a floating prerequisite. `UNIONS-WL/Smokescreen` is **not** currently among the repos listed in the board README; adding it to the README and enabling `project item-add` of a `UNIONS-WL/Smokescreen` issue onto `UNIONS-WL/projects/1` is a discrete step that **precedes filing `ISSUE-FORK`**. Home repo: `UNIONS-WL/unions-wl.github.io` (the board README's "general-purpose home for issues that fit no code repo"). `Kind = Task`; same `Work area` as the stream. It has no PR — it is board/README config, closed by hand. + +## Existing issues — placement unchanged, content adjusted + +The six sp_validation sub-issues live in `CosmoStat/sp_validation` under epic #232, each carrying its implementing draft PR via same-repo `Closes #N`. The standalone CAMB↔CCL cross-check issue is retired — its test folds into `ISSUE-BLIND`. The content edits the ruling forces: +- **`ISSUE-DEPS`** (draft PR #243): body drops firecrown/`patch_firecrown.py`/numpy-ceiling and the `[blinding]` extra; blinding deps go core — the pinned `git+https` fork URL + `pyccl` (already core) + `cryptography` + `sacc>=0.12` (promoted to top-level); Python floor raised `>=3.11` → `>=3.12`. `cryptography` and `sacc>=0.12` come from the fork's `Requires-Dist` and `pyccl` comes from the fork declaring it — but *only after `ISSUE-FORK-PKG` rewrites the fork packaging*; "do not re-pin" is sound solely once that is verified (stock Smokescreen declares neither pyccl nor firecrown despite importing both). Body notes the container/`uv.lock` install-source move to the fork. **Blocked on `ISSUE-FORK-PKG`:** this PR cannot pin a fork SHA earlier than PR 0.1's firecrown-lazy-import + packaging commits, or it drags firecrown back in. +- **`ISSUE-BLIND`** (draft PR #253): body reworks onto the fork protocol (three sp_validation `theory_fn` backends overriding the fork's default CCL backend); the `systm_dict` IA-pin note is removed (firecrown is off our path — lazy and unsupported — and our backends are plain CCL callables that compute the fiducial exactly); the CAMB↔CCL cross-check is folded in as a test in this issue's suite. + +## Why the fork issue is a sub-issue, not its own epic + +The fork exists **to serve the blinding deliverable** — one enabling step in the SACC/Smokescreen stream, not a parallel work stream. It nests under #232 like the other implementation issues. It is cross-repo (the only one), which the board explicitly supports. If the fork later grows its own community-maintenance life (external users, releases, its own roadmap), promote it to a `Kind = Epic` in `UNIONS-WL/Smokescreen` then — not now. + +## Ordering / dependency note (for reviewers, not a board field) + +`ISSUE-BOARDCFG` precedes `ISSUE-FORK` (the fork repo must be on the board before its issue can be filed). Within `ISSUE-FORK`, `ISSUE-FORK-PKG` is the earliest sp_validation-facing unblock: `ISSUE-DEPS` is blocked on it (fork install identity + pyccl declaration). `ISSUE-FORK-PROTO` is independent of `ISSUE-DEPS`. The reworked `ISSUE-BLIND` depends on all of `ISSUE-FORK` (protocol + draw) plus the SACC writers (`ISSUE-SACCIO`). The pure-format PRs (`ISSUE-SACCIO`/`ISSUE-CONV`/`ISSUE-MIGRATE`) are independent of the fork and can proceed in parallel. diff --git a/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-camb-ccl-crosscheck.md b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-camb-ccl-crosscheck.md new file mode 100644 index 00000000..cb1f4f69 --- /dev/null +++ b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-camb-ccl-crosscheck.md @@ -0,0 +1,140 @@ +> **RETIRED (pass 2): folded into prd-smokescreen-blinding.md** — the cross-check is no longer its own PR; its verified technical content lives in the blinding PRD's test section. Kept for reference only. + +# PRD — CAMB↔CCL theory-consistency cross-check + +Repo: `CosmoStat/sp_validation`. + +## Purpose + +Data-vector blinding shifts the measured ξ± by a difference of theory vectors, `t(hidden) − t(fiducial)`, computed with CCL; cosmological inference downstream runs CAMB. That shift only means what we intend if CCL and CAMB predict the same ξ± at a fixed cosmology on our θ grid. This test asserts that agreement to a stated tolerance, and settles the one convention subtlety that would otherwise make the two stacks silently disagree: our fiducial fixes σ8 for CCL but A_s for CAMB, and a nominal `A_s = 2.1e-9` leaves CAMB's σ8 ≈3% off the target — enough to blow a ξ± comparison to ~9–10%. + +## Desired end state + +A standalone theory-consistency test compares ξ± computed two independent ways at one cosmology and n(z): + +- **Path A — CCL native.** CCL builds the nonlinear matter power spectrum through its Boltzmann-CAMB HMCode2020 route and projects to ξ± via its own Limber (`angular_cl`) + FFTLog (`correlation`). +- **Path B — independent CAMB P(k) → CCL projection.** A direct `pycamb` run produces the HMCode2020 `P(k, z)`, wrapped in a `ccl.Pk2D` and projected to ξ± through the same CCL Limber + FFTLog machinery. + +The two paths must agree to sub-percent on our θ grid. The fiducial cosmology and model configuration live in a small, dependency-light config object (`TheoryConfig`) that names one choice — HMCode2020 nonlinear via CAMB, NLA intrinsic alignments, normal-hierarchy neutrinos — shared by both paths and, crucially, by the blinding backend (see *Shared config* below). + +Because both paths route their nonlinear P(k) through CAMB's HMCode2020 and both project through CCL, a common bug in CCL's Limber+FFTLog cancels between them: this test validates the **P(k) recipe** and the **σ8/A_s amplitude convention**, not the projection. This scoping is stated once in the module docstring. + +## Interfaces and contracts + +### Shared config — this is a cross-PR interface, not a free choice + +`TheoryConfig` is imported by the blinding backend (`sp_validation.blinding_likelihood`), whose `TheoryConfig()` defaults *are* the blinding fiducial. Two consequences bind this PRD: + +- **Module home is fixed: `sp_validation.cosmology`.** The blinding work imports `TheoryConfig` from there; a different home breaks that import. (`sp_validation.cosmology` is already the CAMB/CCL theory module.) +- **The config carries the full fiducial**, including IA (`ia_*`) and neutrino fields the blinding backend pins into Smokescreen's `systm_dict` — so those fields are load-bearing for the *shared* fiducial even though this cross-check's two ξ± paths run IA-free (they build bare `WeakLensingTracer(dndz=(z,nz))`; see *The two ξ± paths*). This test does not exercise IA; it does not own the IA fields either. + +### `TheoryConfig` (no firecrown, no CCL/CAMB construction at import) + +A frozen dataclass carries the fiducial cosmology and model choices, parametrised by the blind axes `S8` and `Omega_m`. It imports only `numpy` at module load — CCL/CAMB are imported inside the functions that need them — so importing it never drags in a theory backend. + +```python +@dataclasses.dataclass(frozen=True) +class TheoryConfig: + # Blind axes + the rest of the cosmology. + S8: float = 0.80 + Omega_m: float = 0.30 + Omega_b: float = 0.0469 + h: float = 0.70 + n_s: float = 0.96 + m_nu: float = 0.06 # SUM of neutrino masses, eV (Σm_ν) + w0: float = -1.0 + wa: float = 0.0 + mass_split: str = "normal" # hierarchy for distributing Σm_ν; CCL token + # Nonlinear model — the SAME recipe, named per stack (see below). + ccl_halofit_version: str = "mead2020_feedback" # CCL extra_parameters token + camb_halofit_version: str = "mead2020" # camb.set_halofit_version token + hmcode_logT_AGN: float = 7.5 + # Intrinsic alignments — NLA; off in this cross-check, pinned by blinding. + ia_bias: float = 0.0 + ia_z_piv: float = 0.62 + ia_alphaz: float = 0.0 + Neff: float = 3.046 + T_CMB: float = 2.7255 + + def sigma8(self) -> float: # S8 / sqrt(Omega_m / 0.3) + def omega_c(self) -> float: # Omega_m - Omega_b - Omega_nu(Sigma m_nu, h) + def ccl_params(self) -> dict: + # EXACTLY: Omega_c, Omega_b, h, n_s, sigma8, m_nu, mass_split, + # w0, wa, Neff, T_CMB. No other keys; nothing rides CCL defaults. + + @classmethod + def from_overrides(cls, overrides: dict) -> "TheoryConfig": + # Applies overrides onto the fiducial. Unknown keys RAISE (fail-fast). +``` + +Contracts: +- `sigma8()` returns `S8 / sqrt(Omega_m / 0.3)` — the standard weak-lensing definition. At the fiducial (`S8=0.80`, `Omega_m=0.30`) this is `σ8 = 0.80`. +- `omega_c()` returns `Omega_m − Omega_b − Ω_ν`, with `Ω_ν h² = Σm_ν / 93.14 eV` (`m_nu` is the **sum**, distributed under `mass_split`), so the *total* matter density is exactly `Omega_m`. +- `ccl_params()` returns exactly the keys listed above and no others: every CCL cosmology parameter is set explicitly, so no CCL default silently rides along. +- `from_overrides` applies the given fields onto the fiducial and **raises on any unknown key** — a mistyped override is a bug, surfaced loudly. + +**Nonlinear-model token mapping (the load-bearing subtlety).** CCL and CAMB name the same HMCode2020+feedback recipe with *different* strings: CCL takes `mead2020_feedback` in `extra_parameters['camb']['halofit_version']`; `camb.set_halofit_version` takes `mead2020`. `TheoryConfig` therefore carries **two** tokens (`ccl_halofit_version`, `camb_halofit_version`) that denote one recipe, and each stack is fed its own. Passing a single string to both APIs is exactly the silent stack-disagreement this test exists to catch (`mead2020` vs `mead2020_feedback` differ by several % at k≳1). + +The defaults mirror the CosmoSIS v1.4.6.3 IA-fiducial (`logT_AGN=7.5`; `S8=0.80`, `Omega_m=0.30`, `h=0.70`, `n_s=0.96`, `m_nu=0.06`). + +### Amplitude reconciliation + +```python +def _camb_As_for_sigma8(config, sigma8_target, ...) -> tuple[float, callable]: + """CAMB A_s reproducing sigma8_target, plus a CAMBparams builder. + + Single closed-form rescale: A_s = A_s_seed * (sigma8_target / sigma8_seed)**2, + exact because LINEAR sigma8^2 is proportional to A_s. One CAMB linear-sigma8 + evaluation, one rescale — no iteration loop. So the CAMB stack shares sigma8 + with CCL before any projection. Returns (A_s, make_params), where + make_params(A_s, nonlinear) builds a CAMBparams at the fiducial background. + """ +``` + +`make_params` pins CAMB's power-spectrum output convention explicitly — `set_matter_power(hubble_units=False, k_hunit=False)` — so `P(k,z)` comes out in CCL's native `1/Mpc` / `Mpc³` and Path B's unit handling is unambiguous (see *The two ξ± paths*). The nonlinear model uses `config.camb_halofit_version` and `config.hmcode_logT_AGN`; `mnu`/`neutrino_hierarchy` come from `config.m_nu` / `config.mass_split`. + +### The two ξ± paths + +```python +def _ccl_native_xi(z, nz, theta_arcmin, config) -> tuple[np.ndarray, np.ndarray]: + """Path A: CCL Cosmology with matter_power_spectrum='camb' + HMCode2020 + extra_parameters, WeakLensingTracer(dndz=(z,nz)), angular_cl + correlation.""" + +def _independent_camb_xi(z, nz, theta_arcmin, config, ...) -> tuple[np.ndarray, np.ndarray, float]: + """Path B: direct pycamb HMCode2020 P(k,z) -> ccl.Pk2D -> angular_cl + + correlation. Returns (xi_plus, xi_minus, A_s).""" +``` + +Both paths build a CCL `Cosmology` from `config.ccl_params()` (`sigma8 = config.sigma8()`) with the HMCode2020 `extra_parameters` (`ccl_halofit_version`, `HMCode_logT_AGN`); both use a bare `WeakLensingTracer(dndz=(z,nz))` — IA is off in this cross-check. Path B additionally supplies its independent CAMB P(k) as `p_of_k_a`. + +Path B unit / ordering handling: because `make_params` pins `hubble_units=False, k_hunit=False`, CAMB already returns `k` in `1/Mpc` and `P` in `Mpc³` — **no `·h` / `/h³` conversion is applied** (applying one here would double-count and inject a silent `h³` amplitude error). Before constructing `ccl.Pk2D`, arrange the arrays so both axes ascend: `lk = log(k)` ascending, and scale factor `a` ascending (CAMB returns `z` ascending → reverse to make `a` ascend). + +θ is passed to `ccl.correlation` in degrees (`theta_arcmin / 60`), `type="GG+"` / `"GG-"`. + +### Fixture + +A single Gaussian source bin, `n(z) ∝ exp(−½((z−0.7)/0.2)²)` on `z ∈ [0.01, 3.0]`, trapezoid-normalised. θ grid: `np.geomspace(5.0, 250.0, 12)` arcmin. Deterministic and self-contained — no catalogue, no on-disk data. + +### File layout + +- `TheoryConfig` and the two ξ± path functions live in **`sp_validation.cosmology`** (numpy-only module-level imports; CCL/CAMB function-local; no firecrown). The blinding backend imports `TheoryConfig` from here. +- The test lives at `src/sp_validation/tests/test_camb_ccl_crosscheck.py`. + +## Acceptance criteria + +- **No firecrown.** `grep -r firecrown` over the test file and `sp_validation.cosmology` returns nothing. Importing `sp_validation.cosmology` does not import firecrown, pyccl, or camb (all function-local). +- **σ8/A_s reconciliation asserted.** A test proves, against the named fiducial (`σ8_target = 0.80`): (a) a nominal `A_s = 2.1e-9` leaves CAMB's σ8 offset by `abs(σ8_nominal/σ8_target − 1) > 0.02` (observed ≈0.03 — the convention offset is real, not negligible); and (b) the closed-form rescale lands CAMB's σ8 on the target to `< 1e-4` (this checks CAMB's linear-σ8 reproducibility, since the rescale is exact). +- **ξ± agreement at the fiducial.** Path A and Path B agree within `XIP_RTOL = 0.005` (ξ+) and `XIM_RTOL = 0.010` (ξ−) over the 12-point θ grid. **ξ− caveat:** ξ− crosses zero on this grid, where relative tolerance is ill-defined; the ξ− assertion applies only where `|ξ−| > XIM_FLOOR` (an absolute floor set from the fixture's peak |ξ−|), and asserts an absolute agreement elsewhere. ξ+ is finite and positive (physical); ξ− is not sign-definite and is not asserted positive. +- **ξ± agreement off the fiducial.** The same tolerances hold at a blind-sized offset (`from_overrides({"S8": 0.80 + 0.075, "Omega_m": 0.30 − 0.05})`), so the *shift* — a difference of two theory vectors — does not inherit a stack-disagreement bias. +- **Fast smoke variant.** A non-`slow` test runs both paths at coarse resolution (few θ, reduced ℓ grid) and asserts finite, positive, few-percent-agreeing ξ+ plus a σ8-matched `A_s` in `(1e-9, 3e-9)` — so broken wiring is caught in the fast suite. The precision assertions carry `@pytest.mark.slow`. +- The suite passes inside the container (`pytest src/sp_validation/tests/test_camb_ccl_crosscheck.py`), and CI runs it in the freshly built image before publish. + +*Context (informational, not a tolerance): on the shared-venv build the observed agreement floor is ξ+ ≈ 0.21% / ξ− ≈ 0.10% — headroom against the tolerances above, measured once; version bumps move it and that is not a regression.* + +## Non-goals + +- **No firecrown, no likelihood.** Nothing in the required path imports firecrown or builds a likelihood object; the blinding theory engine is CCL called directly, delivered by the blinding-wiring work. +- **No independent Limber/FFTLog validation.** Both paths project through CCL; a common projection bug cancels and is out of scope. +- **No blinding, seed, or Smokescreen wiring** — this is purely a theory-stack consistency check. +- **No tomographic multi-bin fixture** — one source bin exercises the amplitude and P(k) consistency. The path functions are written generically over `(z, nz)`; cross-tracer pairs and the two-tracer amplitude convention are validated by the blinding backend's own tests, not here. +- **No change to the fiducial-cosmology group decision.** The defaults are reasonable stand-ins mirroring the CosmoSIS v1.4.6.3 fiducial; a later named group choice changes config values, not code. diff --git a/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-converters.md b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-converters.md new file mode 100644 index 00000000..d382265c --- /dev/null +++ b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-converters.md @@ -0,0 +1,84 @@ +# PRD — Converters + +Repo: `CosmoStat/sp_validation`. Format work; theory-agnostic. + +## Purpose + +The SACC file is the standard container for every sp_validation data product, but two consumers do not read SACC: the CosmoSIS inference chain reads a DES-style "2pt-FITS" file, and OneCovariance neither emits nor ingests SACC. This PR supplies the two glue layers those consumers need — a SACC→2pt-FITS converter, and n(z)→OneCovariance-input plus OneCovariance-output→SACC-covariance glue. Nothing here computes theory or blinds anything. + +## Desired end state + +- A converter turns a `{version}.sacc` analysis file into a 2pt-FITS file with the exact HDU layout the CosmoSIS chain (including the PSF ρ/τ likelihood modules in the cosmosis-standard-library fork) consumes. The chain runs against the converter's output and produces results identical to running against a directly-assembled file, with no pipeline change. +- Two glue functions bridge OneCovariance: sp_validation n(z) tracers → OneCovariance's per-bin two-column text input (plus its config), and OneCovariance's flat output covariance → a SACC covariance block aligned to the analysis file's insertion order. +- Both directions are tested: the 2pt-FITS converter against a real reference file and a synthetic fixture; the OneCovariance glue round-trips through a fixture. + +## Target file: the 2pt-FITS layout + +The output is a multi-extension FITS file with **11 HDUs**, in this order: + +| # | EXTNAME | Type | Contents | +|---|---------|------|----------| +| 0 | `PRIMARY` | Primary | empty | +| 1 | `COVMAT` | Image | real-space covariance, blocked `XI_PLUS \| XI_MINUS` and (when present) `TAU_0_PLUS \| TAU_2_PLUS \| CELL_EE`, with `NAME_i`/`STRT_i` offset headers | +| 2 | `COVMAT_CELL` | Image | pseudo-Cℓ covariance, single `CELL_EE` block (`NAME_0=CELL_EE`, `STRT_0=0`) | +| 3 | `NZ_SOURCE` | BinTable | one n(z) per tomographic bin | +| 4 | `XI_PLUS` | BinTable | coarse-grid ξ₊ | +| 5 | `XI_MINUS` | BinTable | coarse-grid ξ₋ | +| 6 | `CELL_EE` | BinTable | pseudo-Cℓ EE | +| 7 | `CELL_BB` | BinTable | pseudo-Cℓ BB | +| 8 | `TAU_0_PLUS` | BinTable | τ₀₊ PSF statistic | +| 9 | `TAU_2_PLUS` | BinTable | τ₂₊ PSF statistic | +| 10 | `RHO_STATS` | BinTable | ρ statistics table (copied through) | + +The executable definition of every HDU's columns and header cards is `cosmo_inference/scripts/cosmosis_fitting.py` — its `nz_to_fits`, `_create_2pt_hdu`, `covdat_to_fits`, `cov_cl_to_fits`, `tau_to_fits`, `rho_to_fits`. Read those for the exact column formats and header keys; the load-bearing details: + +- **BinTable 2-point HDUs** (`_create_2pt_hdu`): columns `BIN1, BIN2, ANGBIN, VALUE, ANG`; header carries `2PTDATA=T`, `QUANT1`, `QUANT2`, `KERNEL_1=NZ_SOURCE`, `KERNEL_2=NZ_SOURCE`, `WINDOWS=SAMPLE`. The `(QUANT1, QUANT2)` pair labels the statistic: `XI_PLUS`/`XI_MINUS` use `(G+R, G+R)`; `TAU_0_PLUS` uses `(G+R, P+R)`; `TAU_2_PLUS` uses `(G+R, SR+R)`. There is no single `QUANT` key. +- **`NZ_SOURCE`** is the n(z) extname (not `NZDATA`; `NZDATA=T` is a header card *inside* the `NZ_SOURCE` HDU). The 2-point HDUs reference it via `KERNEL_1/2="NZ_SOURCE"`. +- **`COVMAT`** block order and offsets follow `covdat_to_fits`: `NAME_0=XI_PLUS, STRT_0=0`; `NAME_1=XI_MINUS, STRT_1=nbins`; then, when tau is present, `TAU_0_PLUS`/`TAU_2_PLUS`; then, when pseudo-Cℓ is present, `CELL_EE`. The τ covariance is truncated from 3·nbins to 2·nbins (drops the τ₅ block). `COVMAT_CELL` is a separate image HDU. +- **`RHO_STATS`** is copied through from the input ρ-statistics table (`rho_to_fits`). + +## Interfaces and contracts + +New module `src/sp_validation/converters.py`. + +### SACC → 2pt-FITS + +```python +def sacc_to_2pt_fits(sacc_path: str, out_path: str) -> None: + """Write a DES-style 2pt-FITS file (11-HDU layout above) from a + {version}.sacc analysis file, structurally matching cosmosis_fitting.py's + assembly of the same measurements.""" +``` + +The converter reads SACC points in the file's insertion order and permutes to the 2pt-FITS type-major layout via `sacc.Sacc.indices`; it never re-sorts by value. The real-space blocks of the SACC covariance are extracted as slices — the SACC file's `FullCovariance` is assembled with zero cross-statistic blocks (the zero-cross-block guarantee is the `sacc_io` PR's `assemble_covariance` contract for `{version}.sacc`; this converter depends on it), matching the block-diagonal `np.block` structure of `covdat_to_fits`. The pseudo-Cℓ covariance populates `COVMAT_CELL`. + +Load the SACC file with `sp_validation.sacc_io` readers; do not hand-parse FITS. + +### OneCovariance glue + +```python +def nz_to_onecovariance(sacc_path: str, out_dir: str) -> dict: + """Write per-bin two-column (z, nz) text files for OneCovariance and return + the config dict it needs.""" + +def onecovariance_to_sacc_cov(oc_output_path: str, s: "sacc.Sacc") -> np.ndarray: + """Read OneCovariance's flat output and return the covariance matrix aligned + to s's insertion order, ready for sacc_io.assemble_covariance.""" +``` + +- `nz_to_onecovariance` writes one whitespace-delimited two-column file per tomographic bin, no header line, column order `(z, nz)`, ascending z. The returned dict must enumerate exactly the fields OneCovariance's config consumes: at minimum the per-bin file paths (in bin order), the number of tomographic bins, and the z-column/nz-column conventions. Pin the exact key names in the docstring against OneCovariance's config parser — an unspecified key set lets two implementations diverge. +- `onecovariance_to_sacc_cov` reuses `sp_validation.statistics.cov_from_one_covariance` for parsing the flat table. Note the column convention there: `index_value = 10 if gaussian else 9`, i.e. **column 10 is the Gaussian-only covariance and column 9 is Gaussian+non-Gaussian** (source: `statistics.py`). This PR adds only the SACC-alignment wrapper around that reshape, plus the n(z)→text input side. It must not touch or import `scratch/guerrini/one_covariance.py` (reserved). + +## Acceptance criteria + +Primary contract is **semantic equality**, not byte-identity: the converter output and a directly-assembled reference must agree HDU-for-HDU on extension-name set and order, per-HDU data arrays, and every load-bearing header card (`QUANT1/2`, `KERNEL_*`, `2PTDATA`, `COVDATA`, `NAME_i`/`STRT_i` offsets). Byte-identity across two independent FITS assembly paths depends on astropy version, column/card insertion order, and padding, and is not required. (The reference file carries no `DATE`/`CHECKSUM`, so a byte-compare is not defeated by timestamps and may be run as an opportunistic extra check, but it is not the gate.) + +- **Real reference:** semantic-equality check against `cosmo_inference/data/SP_v1.4.6_leak_corr_A_minsep=1.0_maxsep=250.0_nbins=20_npatch=1/cosmosis_SP_v1.4.6_leak_corr_A_….fits` (11 HDUs). Convert the corresponding `{version}.sacc` and compare. +- **Synthetic:** `src/sp_validation/tests/test_cosmosis_fitting.py` provides deterministic synthetic inputs and per-HDU structural/value assertions (extension-name sets, data-vector shapes, `STRT_i` offsets, `np.array_equal` on data). Build a SACC file from those same inputs, convert, and assert the same structural/value equalities against the direct assembly. (This is net-new harness code; the existing test does not perform a byte-compare and none is required.) +- **CosmoSIS run** (manual gate, run inside the container; not CI): the chain runs to completion on a converter-produced file with the PSF ρ/τ modules loaded and produces a data vector / χ² matching a run on the directly-assembled file, with no pipeline change. +- **OneCovariance round-trip:** n(z) tracers → text input (correct per-bin files and config dict), and a sample OneCovariance flat output → a SACC covariance block whose ordering matches `assemble_covariance`'s contiguous-ascending tiling of `0..len(s.mean)`. +- No import of a theory backend (pyccl, CAMB, firecrown, Smokescreen) anywhere in the module. + +## Non-goals + +CosmoSIS keeps reading 2pt-FITS; adopting its native SACC likelihood is separate later work. The converter reproduces the current 2pt-FITS layout exactly and adds no statistics, binning, or covariance assumptions of its own; anything beyond the 11-HDU layout is out of scope. Converters operate on whatever vector is in the SACC file (blinded or not) and compute no theory or blinding. This PR supplies the glue at OneCovariance's two edges, not a runner that invokes it. diff --git a/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-cosmo-val-migration.md b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-cosmo-val-migration.md new file mode 100644 index 00000000..b1fcd195 --- /dev/null +++ b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-cosmo-val-migration.md @@ -0,0 +1,82 @@ +# PRD: cosmo_val migration to SACC + +## Purpose + +The cosmology-validation code computes every two-point data product — ξ± on coarse and fine θ grids, pseudo-Cℓ, COSEBIs, pure-E/B, ρ/τ PSF diagnostics, n(z) — but each mixin writes its own bespoke format (TreeCorr `.txt`, custom FITS, `.npz`), and a separate assembly step stitches them into an inference file. In the end state SACC is the sole native output format of the validation pipeline: every product is written through the `sacc_io` builders into SACC parts, and the Snakemake workflow assembles those parts into two terminal SACC files per catalogue version. No bespoke writer remains on the data-vector path. + +## Desired end state + +For each catalogue version the workflow produces exactly two terminal files: + +- **`{version}.sacc`** — the analysis vector: n(z) tracers, coarse ξ±, pseudo-Cℓ (EE/BB/EB) with bandpower windows, COSEBIs, pure-E/B, ρ/τ, and a `FullCovariance` assembled from per-statistic blocks with zero cross-blocks. +- **`{version}_xi_fine.sacc`** — the fine ξ± grid (10000 bins, npatch=1) with a `DiagonalCovariance` from TreeCorr variances, the integration input for COSEBIs and pure-E/B. + +Every per-statistic computation writes its result through a `sacc_io` builder into a single-statistic SACC **part** file. A dedicated assembly rule reads the parts, concatenates them in canonical order, attaches the assembled covariance, and writes the terminal file. The bespoke `.txt`/custom-FITS/`.npz` writers on the data-vector path are deleted; nothing downstream reads them. + +## Interfaces and contracts + +### `sacc_io` is a fixed dependency + +The `sacc_io` module (`src/sp_validation/sacc_io.py`) supplies the builders, readers, covariance assembler, and save/load helpers, in one fixed on-disk layout. Its API is a landed contract and is **the single source of truth for every builder signature** — this document does not restate those signatures, because a paraphrased API surface is a second source of truth that drifts. Implementers call the builders as `sacc_io` defines them (`new_sacc`, `add_xi(..., grid=…)`, `add_pseudo_cl`, `add_cosebis`, `add_pure_eb`, `add_rho`, `add_tau`, `assemble_covariance`, `save`, `load`, `extract`); consult `sacc_io` for exact arguments, including the tomographic `bins=(i,j)` addressing and the keyed pure-E/B series. + +Metadata keys required on every file: `catalogue_version`, `sp_validation_version`, `created`, `npatch`. + +### Compute-path contract — statistics write SACC parts + +Each `cosmo_val` statistic's write step is replaced by a call to the matching `sacc_io` builder, producing a **part** file that holds exactly one statistic (plus the self-describing n(z) tracers it references): + +| Producer | Statistic | Builder | Part | +|---|---|---|---| +| `RealSpaceMixin.calculate_2pcf` (rule `xi`, script `run_2pcf.py`) | coarse ξ± | `add_xi(..., grid="coarse")` | `{version}_xi_coarse_….sacc` | +| `RealSpaceMixin.calculate_2pcf` (rule `xi_highres`, script `run_2pcf_highres.py`) | fine ξ± | `add_xi(..., grid="fine")` | `{version}_xi_fine_….sacc` | +| `pseudo_cl.py` | pseudo-Cℓ | `add_pseudo_cl` | `pseudo_cl_….sacc` | +| `cosebis.py` | COSEBIs | `add_cosebis` | `{version}_cosebis_….sacc` | +| `pure_eb.py` | pure-E/B | `add_pure_eb` | `{version}_pure_eb_….sacc` | +| `psf_systematics.py` | ρ/τ | `add_rho` / `add_tau` | `{version}_rho_tau_….sacc` | + +A producer writes a part with a single `save(s, path)` call; it never assembles a terminal file and never emits a bespoke format alongside. TreeCorr variances (`varxip`/`varxim`) flow into the fine part as a 1-D array (yielding `DiagonalCovariance`); pseudo-Cℓ, COSEBIs, and ρ/τ covariances flow in as dense blocks for the analysis assembly step. + +### Point-tag and ordering contract (from the SACC layout contract, not re-decided here) + +- θ is stored in arcmin; grids are distinguished by the `grid` point tag (`coarse`|`fine`). +- Writers enforce strictly ascending θ/ℓ grids (loud `ValueError`); bin pairs normalize to `i ≤ j`. +- Canonical insertion order is pair-major: per `add_xi` call `[ξ+; ξ−]`, then Cℓ (EE/BB/EB), COSEBIs (Eₙ then Bₙ), pure-E/B, ρ, τ. Covariance rows align to insertion order by construction; readers never re-sort. + +### Snakemake contract — parts, then assembly + +Two rule tiers replace the current per-statistic FITS/txt rules: + +1. **Part rules** — one per statistic, each wrapping a producer and emitting a `.sacc` part. Each rule carries a single wildcard set: the producing statistic's own binning/scale-cut wildcards, plus the `blind` wildcard that already threads the current data-vector rules (e.g. `pseudo_cl`). The `blind` wildcard flows through part filenames and is preserved onto the terminal files unchanged; this migration does not draw, encrypt, or otherwise interpret blinding — it only carries the existing wildcard through. Snakemake's one-wildcard-set-per-rule constraint is what forces part filenames to carry these wildcards. Part filenames are DAG-internal intermediates and are **not** a stability surface. +2. **Assembly rules** — one per terminal file: + - `assemble_analysis`: inputs are the coarse-ξ±, pseudo-Cℓ, COSEBIs, pure-E/B, and ρ/τ parts for a version/blind; output is `{version}.sacc` (blind-tagged as the parts are). It loads each part, appends its data points in canonical order into one `Sacc`, calls `assemble_covariance` with the per-statistic dense blocks (zero cross-blocks), and saves. + - `assemble_xi_fine`: input is the fine-ξ± part; output is `{version}_xi_fine.sacc`. + +Consumers and downstream rules bind parts through the workflow's existing path helpers, never by hardcoding part filenames. The terminal filenames `{version}.sacc` and `{version}_xi_fine.sacc` (blind-tagged) are the only stable names. + +## Scope of deletion + +These are the data-vector writers this migration removes; each is superseded by a `sacc_io` part builder, and after the migration no code path reads the removed output: + +- `RealSpaceMixin.calculate_2pcf`'s `save_fits` TreeCorr-FITS / `.txt` ξ± writer (both grids). +- The pseudo-Cℓ FITS writer behind rule `pseudo_cl` (`pseudo_cl_{version}_….fits`). +- The COSEBIs and pure-E/B bespoke writers (`cosebis.py`, `pure_eb.py`). +- The ρ/τ writers behind `rho_tau_stats` / `cv_rho_tau_fits`. + +Explicitly **out of scope** (retained, not data-vector writers): the CosmoCov covariance products under `data/covariance/…` (rule family `covariance_*`), `pseudo_cl_cov_*.fits`, jackknife-sample `.npz` intermediates, and the `cosmo_val.smk` plot rules (`cv_plot_*`) that consume `.txt`/`.fits`/`.npz`. Plot rules that currently read a bespoke data-vector file are repointed to read the SACC part/terminal file instead; their own outputs (PDFs) are unaffected. + +## Acceptance criteria + +- Running the two-point workflow for a catalogue version produces `{version}.sacc` and `{version}_xi_fine.sacc`, and none of the writers named in *Scope of deletion* produce output. +- `{version}.sacc` loads via `sacc_io.load` and contains: n(z) tracers `source_i`; coarse ξ± (`grid="coarse"`); pseudo-Cℓ EE/BB/EB with bandpower windows; COSEBIs Eₙ/Bₙ; pure-E/B; ρ (k=0..5) and τ (k∈{0,2,5}); a `FullCovariance` with `covariance.size == len(mean)`. +- `{version}_xi_fine.sacc` contains fine ξ± (10000 bins, `grid="fine"`, npatch=1) with a `DiagonalCovariance` matching TreeCorr `varxip`/`varxim`. +- Every terminal file carries the four metadata keys with correct values and the `blind` label of its parts. +- Each part rule declares a single wildcard set; the DAG resolves from raw catalogues to both terminal files with no dangling targets pointing at a deleted writer. +- The writers named in *Scope of deletion* are removed from the codebase, and no remaining code path reads their outputs. +- Load-then-reload of each terminal file is bitwise-stable, and a covariance recovered by `s.indices` aligns element-for-element with the data vector — confirming the assembly step preserves insertion order and covariance alignment. (The write→read bitwise identity of each individual product is covered by `sacc_io`'s own round-trip tests and is not re-tested here.) + +## Non-goals + +- **No changes to `sacc_io`.** Builder, reader, and assembler signatures and the two-file layout are fixed inputs; if a builder proves insufficient, that is a defect in `sacc_io`, out of scope here. +- **No converters.** Producing DES 2pt-FITS from SACC, and the OneCovariance glue, are separate work. +- **No blinding logic.** The `blind` wildcard is carried through unchanged; drawing shifts, encrypting truths, and stamping concealed-file metadata belong to the blinding wiring, not here. +- **No science change.** Every product written is one the pipeline already computes at its existing binning; no new statistic, binning scheme, theory, or covariance is produced. Covariance blocks are the same arrays the pipeline computes today, re-homed into SACC, with the zero-cross-block independence assumption inherited unchanged. Existing bespoke-format outputs are left in place — new products are born in SACC. diff --git a/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-dependencies.md b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-dependencies.md new file mode 100644 index 00000000..3e145bfd --- /dev/null +++ b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-dependencies.md @@ -0,0 +1,100 @@ +# PRD — Dependencies + +Repo: `CosmoStat/sp_validation`. + +## Purpose + +Blinding the tomographic data vector requires Smokescreen and its CCL theory backend. This PR makes those dependencies installable and reproducible as **core** dependencies: it pins the `UNIONS-WL/Smokescreen` fork by git tag or SHA, promotes `sacc` to a top-level dependency, adds `cryptography`, raises the package's Python floor from `>=3.11` to `>=3.12`, and installs the closure in the container. There is no optional blinding extra — with firecrown out of the install closure the blinding closure is small enough (fork + `pyccl` + `cryptography`, with `sacc`) to live in the core install. + +## Prerequisite (blocking) + +This PR consumes a **single fork install identity** — one `git+https` reference into `UNIONS-WL/Smokescreen`, pinned by tag or SHA, produced by the fork's packaging PR and pinned here verbatim: + +``` +smokescreen @ git+https://github.com/UNIONS-WL/Smokescreen@ +``` + +`` is a tag or commit SHA that (a) declares `pyccl` in the fork's `Requires-Dist` and (b) has made the firecrown import lazy (no module-level firecrown import) so a clean install does not require firecrown. Pinning any earlier fork commit fails: stock Smokescreen imports `firecrown` and `pyccl` at module level (`datavector.py`) yet declares neither, so any install lacking firecrown `ImportError`s at `import smokescreen`. Nothing is published to PyPI — the fork ships as a git pin only. + +**Cold-implementability hole:** `` is the one load-bearing string this PR pins, and it does not exist until the fork's packaging PR lands. Until it is supplied, this PR cannot be implemented and the acceptance criteria below cannot be run — a reviewer must substitute the real tag/SHA before any install-resolution check is executable. This is a genuine cross-PR dependency, not an unfilled value: **this PR is blocked on the fork's packaging PR.** + +## Support-matrix change + +The current package declares `requires-python = ">=3.11"` (ruff `target-version = "py311"`). Smokescreen requires `>=3.12`, so this PR raises sp_validation's floor to `>=3.12`. This **drops Python 3.11 support** for sp_validation as a whole — a genuine support-matrix decision, not bookkeeping. It is safe against the container base (`python:3.12-slim-bookworm`, via `shapepipe:develop`) and against CI (which runs only inside that image); no external sp_validation consumer or CI matrix is known to run 3.11. + +## Desired end state + +- The blinding dependencies are **core** runtime dependencies in `[project].dependencies`: the fork (via the prerequisite ref), `cryptography`, and `sacc>=0.12`. `pyccl` is already core. +- There is **no `[blinding]` optional-dependency extra.** It is deleted; blinding installs with the base package. +- `requires-python` is `>=3.12`; ruff `target-version` is `py312`. +- **No `firecrown` anywhere** — no dependency, no `--no-deps` install step, no `scripts/patch_firecrown.py`, no firecrown import smoke-check, no guarded firecrown CI job. **No `numpy` upper bound anywhere** in the packaging. +- The container installs the full core closure, captured in `uv.lock` and the `Dockerfile`. +- The CI deploy image builds cleanly and runs the full fast test suite. `deploy-image.yml` already runs an `import sp_validation` smoke test and the fast suite in-image; this PR adds one new step to that job — an `import smokescreen` check that resolves the fork install. + +## Interfaces and contracts + +### `pyproject.toml` + +Raise the floor: + +```toml +[project] +requires-python = ">=3.12" +``` + +Add the blinding closure to core `dependencies` (`pyccl` is already declared there): + +```toml +dependencies = [ + ... + "smokescreen @ git+https://github.com/UNIONS-WL/Smokescreen@", + "sacc>=0.12", + "cryptography", + ... +] +``` + +- `` is the value fixed by the prerequisite above, copied byte-for-byte from the fork's packaging PR. +- `sacc>=0.12` and `cryptography` are declared explicitly here so the core runtime closure is self-documenting and independent of fork-metadata drift. Do not pin either more tightly than the fork does. + +There is no `[project.optional-dependencies].blinding` table. + +### Ruff target + +```toml +[tool.ruff] +target-version = "py312" +``` + +### `Dockerfile` + +The editable install line currently reads: + +```dockerfile +RUN uv pip install --no-cache-dir -e '.[test,glass]' +``` + +No extra is added — the blinding closure is core, so the existing line installs it unchanged. Only the resolved `uv.lock` (below) changes to point Smokescreen at the fork ref. The base image already resolves to Python 3.12, so the raised floor needs no base-image change. + +### `uv.lock` + +Regenerate so the resolved Smokescreen entry points at the fork ref and the lockfile carries the closure (`pyccl`, `cryptography`, `sacc`). No `firecrown` or `numpy<2.x` marker may appear in the resolved graph. + +## Acceptance criteria + +These criteria are runnable only once the prerequisite `` is supplied and substituted for the placeholder (see Prerequisite); an earlier fork pin fails by dragging firecrown in. + +- `uv pip install -e .` on Python 3.12 resolves and installs the blinding closure with no firecrown and no numpy ceiling in the resolved set. +- `python -c "import smokescreen"` succeeds in the installed environment without firecrown present. +- `grep -n 'requires-python' pyproject.toml` shows `>=3.12`; ruff `target-version` is `py312`. +- Core `dependencies` contains the fork git ref pin, `sacc>=0.12`, and `cryptography` (plus the pre-existing `pyccl`); there is **no `[blinding]` extra** in `pyproject.toml`. +- `grep -rn firecrown pyproject.toml Dockerfile uv.lock scripts/` returns nothing; `scripts/patch_firecrown.py` does not exist. +- `grep -rn 'numpy<' pyproject.toml uv.lock` returns nothing (no ceiling). +- The deploy-image CI job (`.github/workflows/deploy-image.yml`) builds the image and passes the pre-existing `import sp_validation` smoke test, the new `import smokescreen` check this PR adds, and the fast test suite (`pytest -m "not slow"`) against the freshly built image before publishing. + +## Non-goals + +- Wiring Smokescreen into the blinding pipeline, drawing shifts, or computing theory — this PR only makes the dependencies installable. +- Any fork-side change. This PR produces nothing in `UNIONS-WL/Smokescreen` and consumes its settled install identity as a blocking prerequisite. +- Supporting a firecrown theory backend. sp_validation never installs firecrown; the only theory path here is CCL, and no numpy ceiling is imposed. (The fork retains an inherited, lazy, unsupported firecrown path that this install never pulls in — firecrown stays undeclared and uninstalled.) +- Adopting Smokescreen against DESC upstream, or publishing to PyPI. The pin targets the `UNIONS-WL/Smokescreen` fork by git tag. diff --git a/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-fork-draw.md b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-fork-draw.md new file mode 100644 index 00000000..188e36de --- /dev/null +++ b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-fork-draw.md @@ -0,0 +1,94 @@ +> **RETIRED (pass 2, unrevived by pass 3): superseded by prd-fork-protocol.md** — the injectable `draw_fn` abstraction over an arbitrary parameter space is explicitly deferred (protocol PRD Non-goals; blinding PRD: "no injectable draw callable"); the pure order-independent local-RNG draw itself lives in the protocol PRD as the built-in `draw_param_shifts`. Kept for reference only. **Note (pass 3):** this doc's "no `pyccl` object in scope" / "validates keys against `pyccl.Cosmology`" framing is stale — pass 3 rules that the fork ships a default CCL backend that *uses* pyccl at construction; the draw itself remains RNG-only, but pyccl is a used runtime dependency of the fork, not something being removed. + +# PRD — PR-0.1a: Injectable pure `draw_fn` (fork) + +Repo: `UNIONS-WL/Smokescreen`. Sub-PR under the "fork Smokescreen and make it theory-backend independent" issue. + +This PR and the theory-protocol sub-PR both edit `ConcealDataVector.__init__`. They are **sequenced, not order-free**: this draw PR lands first against the stock signature (adding `draw_fn` + a pinned pure draw); the theory-protocol PR then rewrites the constructor wholesale (dropping `cosmo`/`likelihood`/`systm_dict`, adding `theory_fn`/`fiducial_params`) and carries `draw_fn` forward. The interfaces below are stated as they stand after both land, with the constructor shown in its final `theory_fn` form so the two PRDs agree on one target. + +## Purpose + +Smokescreen draws a hidden cosmology from a seed and shifts the data vector by the theory difference between that cosmology and the fiducial. The draw must be a **pure, reproducible function of `(seed, shift spec)` alone** — this is the load-bearing property of the blinding custody scheme: at unblind time the published seed is fed back through the same draw and must reproduce the identical shift to verify the hash commitment, possibly on a different checkout, machine, or process. A draw that depends on global RNG state, on dict iteration order, or on the fiducial cosmology's parameter ordering cannot serve as that verifiable function. This PR establishes the pure draw and makes it injectable, so a caller can supply its own draw over an arbitrary parameter space without subclassing. + +## Desired end state + +- A single pure function `draw_flat_param_shifts(shift_dict, seed)` backs flat shifts: it uses a local `numpy.random.Generator` (`default_rng`), touches no global RNG state, validates no keys against any cosmology, and draws in a canonical key order. +- The draw is **order-independent**: returned values depend only on `(seed, per-key spec)`, never on dict insertion order or on any cosmology's parameter ordering. Two shift dicts with the same keys and bounds in different order produce identical draws for a given seed. +- The draw operates over an **arbitrary parameter space**: keys are free-form strings. A box such as `{"S8": (-0.075, 0.075), "Omega_m": (-0.1, 0.1)}` is drawn natively. The draw makes no claim that its keys are cosmology parameters. +- The flat path calls this pure function. The stock flat path routes through `draw_flat_or_deterministic_param_shifts` (which seeds the global RNG, validates keys against `pyccl.Cosmology`, and iterates in `to_dict()` order); that function is **deleted** and `_load_shifts`'s flat branch is repointed to `draw_flat_param_shifts`. This repoint is the central change — the flat path does not currently call the pure function. +- `ConcealDataVector` accepts an **injectable** `draw_fn`. When supplied it is the sole source of shifts; the built-in flat/gaussian dispatch is bypassed. When omitted, behavior defaults to the built-in pure flat draw. +- The gaussian draw migrates to the same local-RNG, order-independent, arbitrary-key contract, keeping its `(mean, std)` tuple semantics. + +## Interfaces / contracts + +### `smokescreen/param_shifts.py` + +```python +def draw_flat_param_shifts( + shift_dict: dict[str, float | tuple[float, float]], + seed: int | str, +) -> dict[str, float]: + ... +``` + +- `seed`: an `int` used directly, or a `str` hashed to an `int` via the existing `smokescreen.utils.string_to_seed` (guarded by `type(seed) is str`, so an `int` seed is passed to `default_rng` raw, never re-hashed). `np.random.default_rng` accepts the resulting int. +- RNG: `rng = np.random.default_rng(seed)`. No call to `np.random.seed`. +- Per key: a 2-tuple `(lo, hi)` → `rng.uniform(lo, hi)` (absolute bounds); a scalar `w` → `rng.uniform(-w, w)` (symmetric half-width about zero). Tuple-vs-scalar is decided per key, not once for the whole dict. +- **Pinned order-independence mechanism** (not implementer's choice — it is the custody-verification contract and must be stable across versions and checkouts): iterate keys in `sorted(shift_dict)` and issue **one scalar `rng.uniform` call per key in that order**. Do not vectorize: a vectorized `rng.uniform(lo_arr, hi_arr)` consumes the bit stream differently and would yield different values for the same seed, silently breaking hash reproduction against any file blinded under the scalar-loop version. The scalar per-sorted-key loop is the frozen definition. +- Returns `{key: drawn_value}` for every key in `shift_dict`. +- No dependence on any `pyccl` object; no key validation against a cosmology. + +```python +def draw_gaussian_param_shifts( + shift_dict: dict[str, tuple[float, float]], + seed: int | str, +) -> dict[str, float]: + ... +``` + +- Same local-RNG, sorted-key, one-scalar-call-per-key, arbitrary-key contract. +- Every value must be a 2-tuple `(mean, std)`; a non-tuple raises `ValueError`. Draw is `rng.normal(mean, std)` per key in sorted order. +- The `cosmo` parameter and the `cosmo._params` / `cosmo.to_dict()` validation are removed. Key legality is enforced downstream at cosmology construction, not here. + +`draw_flat_or_deterministic_param_shifts` is **deleted**. Its flat (tuple) behavior is subsumed by `draw_flat_param_shifts`; its deterministic (scalar-as-absolute-replacement) behavior is not on the blinding path and is dropped. A caller needing deterministic shifts supplies them through `draw_fn`. + +### `smokescreen/datavector.py` — injectable draw + +`ConcealDataVector.__init__` (final form after the theory-protocol PR; this PR adds the `draw_fn` parameter and the `_load_shifts` dispatch, the protocol PR supplies `theory_fn`/`fiducial_params`): + +```python +def __init__(self, theory_fn, fiducial_params, shifts_dict, sacc_data, *, + seed="2112", draw_fn=None, shift_distr="flat"): + ... +``` + +- `draw_fn: Callable[[int | str], dict[str, float]] | None`. +- `shift_distr` becomes a **named parameter** with default `"flat"`, replacing the stock `**kwargs`-gated read (`if 'shift_distr' in kwargs: ...`). `_load_shifts`'s signature is `_load_shifts(self, seed, draw_fn=None, shift_distr="flat")` and dispatches: + - `draw_fn is not None` → returns `draw_fn(seed)`; neither `shifts_dict` nor `shift_distr` is consulted. + - `draw_fn is None`, `shift_distr == "flat"` → `draw_flat_param_shifts(shifts_dict, seed)`. + - `draw_fn is None`, `shift_distr == "gaussian"` → `draw_gaussian_param_shifts(shifts_dict, seed)`. +- **Output contract for the shift dict.** The dict `_load_shifts` returns is applied by overlaying its keys onto `fiducial_params` to form the concealed parameter set, which is then handed to `theory_fn`. So the shift keys must be keys the chosen `theory_fn` understands. Two obligations follow, and they are **caller obligations, not guarantees this PR can enforce**: + - The built-in flat/gaussian draws return their input keys verbatim. Using them means `shifts_dict` keys must already be keys the fiducial+theory path accepts (e.g. CCL primitives for a CCL `theory_fn`). The built-in draws do **not** translate parameter spaces. + - An injected `draw_fn` may draw in an arbitrary space (`S8`, `Omega_m`, …) **and must itself map to the theory backend's key space before returning**, since its output is overlaid onto `fiducial_params` directly. The `S8`/`Omega_m` → CCL-primitive translation is the caller's `draw_fn` composition (draw-in-derived-space, then map), living in the consuming blinding step — not in this module. This is how the "arbitrary parameter space" capability reaches the default path: through an injected `draw_fn`, not through the built-in draw. + +### Purity as a caller obligation + +For the built-in draws this PR **guarantees**: for a fixed `seed`, the pinned scalar-per-sorted-key mechanism returns identical values across processes, machines, and reordered `shifts_dict` inputs. For an injected `draw_fn`, Smokescreen cannot enforce purity or order-independence; it **requires** them as a precondition the caller must meet (`draw_fn` must be a pure, order-independent function of `seed`). The custody scheme's reproducibility rests on this precondition holding for whatever draw is in use. + +## Acceptance criteria + +- `draw_flat_param_shifts(sd, seed)` returns identical output for two dicts differing only in key insertion order (assert equality against a shuffled-key copy). +- Draws correctly for non-CCL keys (`{"S8": (-0.075, 0.075), "Omega_m": (-0.1, 0.1)}`) with no `pyccl` object in scope. +- Calling the flat or gaussian draw leaves `np.random.get_state()` unchanged (guards against *legacy global* mutation; does not by itself prove a `default_rng` isn't reseeded from a global — covered by the cross-process equality check below). +- Same seed → equal dicts; different seeds → unequal dicts (checkable on a fixed pair). +- A value drawn under the pinned scalar-per-sorted-key mechanism is asserted against a hardcoded expected number for a fixed `(seed, key, bounds)`, freezing the mechanism against silent drift (e.g. a future vectorization). +- `ConcealDataVector(..., draw_fn=f)` uses `f(seed)` and ignores `shifts_dict`/`shift_distr`; without `draw_fn` it reproduces the built-in flat draw. +- A synthetic `draw_fn` returning fixed backend-key shifts drives a full blind end-to-end (concealed params formed, concealing factor computed) without a firecrown import. +- The fork's `param_shifts` test suite is updated to the new signatures and passes. + +## Non-goals + +- The theory-backend protocol (`theory_fn`), firecrown-adapter extraction, and the wholesale `__init__` rewrite — the sequenced theory-protocol sub-PR (this PR only adds `draw_fn` + the pinned pure draw). +- Packaging, install identity, `pyccl` declaration, fork CI — a separate sub-PR. +- The `S8`/`Omega_m` → backend-key translation and the custody/encryption flow — they live in the consuming sp_validation blinding step, which supplies a `draw_fn`; this PR guarantees only the injection point and the pinned pure-draw contract. +- The concealing-factor computation and any systematics handling. diff --git a/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-fork-packaging-ci.md b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-fork-packaging-ci.md new file mode 100644 index 00000000..f7abd1fe --- /dev/null +++ b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-fork-packaging-ci.md @@ -0,0 +1,100 @@ +# PRD — Fork packaging, install identity, CI, and pip-only docs + +Repo: `UNIONS-WL/Smokescreen`. + +## Purpose + +The forked Smokescreen package must be installable by downstream projects as a first-class core dependency with correct dependency metadata, its CI must gate on a theory backend that requires no heavyweight optional stack, and its install path must be documented for pip-only consumers. This PR settles the fork's install identity, rewrites its dependency declarations so a clean install pulls exactly the blinding closure — and nothing test-only into runtime — re-points CI onto a backend smoke-test, and updates the README/docs to the pip-only install form. It is the packaging-and-docs slice of the fork work and the piece other repositories depend on to declare the fork. + +## Prerequisite + +This PR presupposes the theory-backend refactor already in the fork: the `theory_fn(cosmo_params) -> np.ndarray` protocol is the theory entry point, the fork ships a default CCL backend (`pyccl` imported inside the backend module, not at top level), `import smokescreen` succeeds without importing any theory backend, and both a synthetic-callable and a default-CCL blind path exist. Firecrown is retained only as an inherited, lazy-imported, unsupported path — never imported at module level. Without that refactor, `smokescreen/datavector.py` imports firecrown at module load and a clean install `ImportError`s at `import smokescreen`, so the CI gate below cannot pass. This PR is separable in *review* (packaging, CI, and docs are self-contained) but its CI gate goes green only once the protocol refactor is merged; that ordering is a hard dependency, not a choice. + +## Desired end state + +- The fork has a single, documented install identity that a downstream `pyproject`/lockfile pins without ambiguity: a git+https URL at a pinned tag. +- A clean install of the fork (into an empty venv — no packages preinstalled) succeeds and exposes `import smokescreen`. The install pulls `pyccl` as a declared runtime dependency that the fork **uses**: the default CCL backend module imports it (at backend construction, not at `import smokescreen`). "Clean" here means the consumer preinstalls nothing; pyccl arrives as part of the fork's own runtime closure. The load-bearing property is that `import smokescreen` imports no theory backend — pyccl is imported only when the default backend is built, and firecrown only along its lazy, unsupported path — so top-level import is self-contained. +- The fork's runtime dependency set is exactly the blinding closure: no test tooling (`pytest`, `pytest-cov`) appears as a runtime `Requires-Dist`; such tooling lives in a `[test]` extra. +- `cryptography` and `sacc>=0.12` are declared runtime dependencies, and the pyproject rewrite preserves them (asserted by the acceptance criteria below, not merely assumed). +- The pyproject carries `requires-python = ">=3.12"`, no `numpy` upper bound, and retains the stock `numpy>=2.2.0` floor. +- CI's required gate builds the fork on a clean environment, asserts `import smokescreen`, and blinds a synthetic data vector through a non-CCL callable backend end-to-end. +- The fork README/docs document the pip-only install path — `pip install git+https://github.com/UNIONS-WL/Smokescreen@` — with no conda and no PyPI publish. + +## Interfaces and contracts + +### Install identity: pinned git+https at a tag + +Downstreams depend on the fork via + +``` +smokescreen @ git+https://github.com/UNIONS-WL/Smokescreen@ +``` + +`[project].name` stays `"Smokescreen"` (the import package `smokescreen` is unchanged); nothing is published to PyPI and there is no rename. + +**Tag-cutting order.** The tag is the last step, not part of this PR's merge commit. It is cut only once *both* prerequisites are on the fork's default branch: the theory-backend protocol refactor (so `import smokescreen` succeeds on a clean install) and this packaging PR (so `Requires-Dist` declares `pyccl` and the pip-only docs are in place). Whichever of the two merges second, the tag is placed on the resulting default-branch commit. Concretely: do not cut the tag in this PR — merge this PR, ensure the protocol PR is also merged, then tag the merged tip. That tag is the value the downstream deps PR pins verbatim, so the two documents agree by construction. Keeping the fork diff small and clean preserves the option of PRing changes back upstream later. + +### Dependency metadata (`pyproject.toml`) + +The fork's `[project].dependencies` is **exactly** this set — no more, no fewer: + +``` +astropy>=5.2.0 +cryptography +jsonargparse[signatures]>=4.0 +numpy>=2.2.0 +pyccl +sacc>=0.12 +scipy>=1.9.0 +``` + +Provenance (so the set is checkable, not asserted): stock Smokescreen's built metadata declares `Requires-Dist` = `astropy`, `cryptography`, `jsonargparse` (with the `[signatures]` extra), `numpy>=2.2`, `sacc>=0.12`, `scipy`. The fork keeps that set verbatim — floors and all — and adds exactly one entry, `pyccl`, which stock leaves undeclared. Nothing is dropped. Verify against the stock metadata (Smokescreen 1.5.6, read from the installed package or PyPI) before landing the rewrite; the "exactly this set" contract is stock-`Requires-Dist` **+ `pyccl`**. + +Rules: +- `pyccl` is the one addition over stock: the fork's default CCL backend imports and uses it, and stock relied on it being present in a conda theory stack without declaring it. Declaring it makes a clean pip install of the fork's default blinding path self-contained. (The required CI gate blinds through a synthetic callable so it stays fast and stack-light; a separate non-required job may exercise the default CCL backend where pyccl is available.) +- `astropy`, `jsonargparse[signatures]`, `scipy` are inherited from stock `Requires-Dist` unchanged — retained, not curated. Do not promote any of them to a CLI-only or theory-only extra in this PR; that is out of scope, and the fork's own modules import them at runtime. +- `pytest`, `pytest-cov`, and any other test tooling are **not** runtime `Requires-Dist`. They move to a `[project.optional-dependencies].test` extra. A clean `pip install` of the fork must not drag pytest into a downstream runtime. +- `cryptography` and `sacc>=0.12` are declared runtime dependencies; the rewrite preserves them. +- No `numpy` **upper** bound anywhere. The `numpy>=2.2.0` **floor** is inherited from stock Smokescreen's metadata and retained unchanged; it is a floor, not the banned ceiling. +- `requires-python = ">=3.12"`. + +### Fork CI (`.github/workflows/`) + +One required job (`backend-smoke`): +- Fresh runner, no conda; install the fork from its own `pyproject` (the same identity path chosen above). +- Assert `python -c "import smokescreen"` succeeds. +- Run a smoke test with a concrete, observable assertion (a fresh engineer must not have to invent the fixture or tolerance): + - **Fixture:** a small in-memory SACC vector — a single tracer pair, ~10 data points is sufficient (no real survey data, no files on disk). + - **Backend:** a synthetic theory callable `theory_fn(cosmo_params) -> np.ndarray` returning an array aligned to the SACC rows (e.g. a smooth analytic function of the fixture's angular bins) — no CCL. + - **Changed:** the blinded vector differs from the input — `not np.allclose(blinded, original)`. + - **Reproducible from seed:** two blind calls with the *same* seed produce the identical shifted array — `np.array_equal(blind(seed), blind(seed))`; a *different* seed produces a different array — `not np.array_equal(blind(seed_a), blind(seed_b))`. +- Runs with `numpy` unconstrained above the `2.2` floor (no upper bound in the CI environment either). + +### Fork docs (README) + +The README documents the pip-only install path as the single supported form: + +``` +pip install git+https://github.com/UNIONS-WL/Smokescreen@ +``` + +- No conda-forge install instructions; no PyPI `pip install smokescreen`. +- The `` in the docs is byte-identical to the tag this PR cuts and to the pin the downstream deps PR consumes. +- Any stock install instructions that assumed a conda-forge theory stack are removed or replaced by the pip-only form. +- The docs state plainly, in neutral tone, that the firecrown integration path is inherited from upstream and **unsupported** in this fork: not installed, not tested, not maintained. The default and supported theory path is the built-in CCL backend. + +## Acceptance criteria + +- [ ] `pip install`ing the fork into an empty venv (nothing preinstalled) succeeds and `import smokescreen` works. The install resolves its full declared closure — including `pyccl` — and the default CCL backend constructs successfully; `import smokescreen` itself imports neither pyccl nor firecrown at module load. +- [ ] The fork's built metadata (`Requires-Dist`) is **exactly** `astropy>=5.2.0`, `cryptography`, `jsonargparse[signatures]>=4.0`, `numpy>=2.2.0`, `pyccl`, `sacc>=0.12`, `scipy>=1.9.0` — and no others: no `pytest`/`pytest-cov` in runtime position. +- [ ] Fork `pyproject` carries `requires-python = ">=3.12"`, retains the `numpy>=2.2.0` floor, and carries no numpy upper bound. +- [ ] A `[project.optional-dependencies].test` extra **exists** and carries the test tooling (`pytest`, `pytest-cov`), so `pip install [test]` provisions the fork's own test run; the tooling is present there and absent from the runtime `Requires-Dist`. +- [ ] The fork README documents the pip-only install form `pip install git+https://github.com/UNIONS-WL/Smokescreen@`, with no conda or PyPI path, and the `` string is byte-identical to the pin the downstream deps PR consumes. +- [ ] Required CI job `backend-smoke` passes: `import smokescreen` plus a synthetic-callable end-to-end blind on an in-memory SACC fixture, asserting `not np.allclose(blinded, original)` (the vector changed), `np.array_equal(blind(seed), blind(seed))` (same seed reproduces), and `not np.array_equal(blind(seed_a), blind(seed_b))` (different seeds diverge). + +## Non-goals + +- The theory-backend protocol refactor (`theory_fn`) and the fixed pure draw — landed separately; this PR is a hard consumer of the protocol (see Prerequisite) and defines only packaging, CI, and docs. +- Any change to `UNIONS-WL/Smokescreen` blinding semantics, encryption, or the shift math. +- Downstream (sp_validation) dependency declaration, container, or lockfile changes — those live in the sp_validation deps PR, which this PR unblocks but does not touch. +- Publishing to PyPI or conda, renaming the distribution, or opening any PR against DESC upstream `LSSTDESC/Smokescreen`. diff --git a/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-fork-protocol.md b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-fork-protocol.md new file mode 100644 index 00000000..c2051bed --- /dev/null +++ b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-fork-protocol.md @@ -0,0 +1,148 @@ +# PRD: theory_fn protocol + default CCL backend + fixed draw + fork-test migration + +Repo: `UNIONS-WL/Smokescreen`. + +## Purpose + +Smokescreen blinds a data vector by adding a theory difference, `d → d + t(hidden) − t(fiducial)`. The theory source is a single `theory_fn(cosmo_params) -> np.ndarray` protocol, so any callable — the built-in CCL backend, a ΔΣ emulator, a synthetic fixture — can drive blinding. This PR establishes that protocol as the theory contract, ships a built-in default CCL backend so a casual user can blind a standard cosmic-shear SACC file without writing a callable, and draws the hidden shift with a local, order-independent RNG over CCL-native parameter names. + +The theory backend is either the shipped CCL default or one the caller supplies. `pyccl` is a declared runtime dependency, imported by the default-backend module (not at top-level `import smokescreen`). Firecrown is a different case: it survives as an **optional, lazy-imported** path inherited from upstream — never imported at module level, never declared as a dependency, not installed, tested, supported, or maintained in this fork. "CCL-native parameter names" (`sigma8`, `Omega_c`, …) are the parameter keys the default backend and draw speak. The package's own test suite runs on a synthetic backend with firecrown absent. + +Packaging, install identity, `pyccl` declaration, fork CI wiring, and install docs are a **separate sub-PR** and are out of scope here (see Non-goals). + +## Desired end state + +- `import smokescreen` imports no theory backend at module load: `pyccl` is imported only inside the default-backend module when that backend is constructed, and `firecrown` is never imported at module level (lazy only, inside the inherited optional path). +- Firecrown is **not deleted** but is fully sidelined: no `import firecrown` / `from firecrown …` at module scope, no `ParamsMap` on the default path, no `patch_firecrown` / NumCosmo import surgery, no `numpy<2.5` ceiling anywhere in the fork. The firecrown path remains as inherited-upstream code behind a lazy import, unsupported and untested here. +- The fork ships a **default CCL `theory_fn`**: a built-in backend that computes a cosmic-shear theory vector from CCL for a standard SACC file. Power users override it with their own callable. +- `ConcealDataVector` obtains both theory vectors (fiducial, hidden) by calling a `theory_fn` — the default CCL backend when none is supplied, else the caller's. There is no `likelihood` path, no `_create_concealed_cosmo` step, no `systm_dict` inside the concealing computation. +- The hidden shift is drawn by a pure, local-RNG function over a free-form, order-independent parameter mapping keyed by CCL-native names (e.g. `sigma8`, `Omega_c`); no process-global `np.random.seed`. +- The package's own test suite exercises the full blinding machinery through a synthetic `theory_fn`, with firecrown absent. + +## Interfaces and contracts + +### Theory-function protocol + +The single theory entry point. Any callable satisfying this signature is a valid backend; the fork ships a default CCL implementation and accepts a caller-supplied override. + +```python +def theory_fn(cosmo_params: Mapping[str, float]) -> np.ndarray: + """Return the theory data vector aligned element-for-element to the + SACC rows being concealed, evaluated at `cosmo_params`.""" +``` + +- `cosmo_params` is a plain mapping of cosmological-parameter name → value. The protocol places no constraint on the parameter names; interpreting them is the backend's job. +- The return is a 1-D `np.ndarray` whose length and row order match `sacc_data.mean` for the rows to be concealed. Alignment is the backend's contract, not Smokescreen's. +- The callable is pure with respect to its argument: two calls with equal `cosmo_params` return equal vectors. + +### Default CCL backend + +The fork ships a built-in `theory_fn` so a standard cosmic-shear SACC file blinds out of the box: + +- It lives in its own module (e.g. `smokescreen.backends.ccl`) that imports `pyccl`. That import happens when the backend is constructed, **not** at `import smokescreen` / `import smokescreen.datavector` — top-level import stays backend-free. +- Given a `sacc_data` carrying weak-lensing tracers with n(z), it builds a CCL cosmic-shear `theory_fn`: for each `cosmo_params` mapping (CCL-native names), construct the `pyccl.Cosmology`, `WeakLensingTracer` per bin, and return the ξ± / Cℓ vector aligned to `sacc_data`'s rows. +- The parameter names it accepts are CCL-native (`sigma8`, `Omega_c`, `Omega_b`, `h`, `n_s`, …). Interpreting them is this backend's job; the protocol itself is name-agnostic. +- It is the value `ConcealDataVector` uses when `theory_fn=None`. It is exercised by the fork test suite only where pyccl is available; the core blinding-mechanics tests use a synthetic backend and do not require it. + +### `ConcealDataVector` + +```python +ConcealDataVector( + fiducial_params, # Mapping[str, float] + shifts_dict, # Mapping[str, float | tuple[float, float]] + sacc_data, # sacc.sacc.Sacc + *, + seed, # int | str; no default — see note + theory_fn=None, # Callable[[Mapping[str, float]], np.ndarray]; None → default CCL backend + shift_distr="flat", +) +``` + +- `theory_fn` defaults to the shipped CCL backend (below) when `None`; supplying a callable overrides it. The default backend is constructed from `sacc_data` (it reads the tracers' n(z) and the row layout to build a cosmic-shear vector) — passing `theory_fn=None` with a SACC the default backend cannot interpret raises a clear error at construction. +- `fiducial_params` replaces stock Smokescreen's `cosmo` + `likelihood` constructor pair as the description of the fiducial point. It is a plain mapping of cosmological-parameter name → value over a free-form parameter space (CCL-native names, e.g. `sigma8`, `Omega_c`); it is not a `pyccl.Cosmology` and is not constrained to CCL constructor names. Interpreting the names is the `theory_fn`'s job. The hidden point is `fiducial_params` with the drawn shifts overlaid, a mapping of the same shape — there is no `pyccl.Cosmology` object and no `_create_concealed_cosmo` step. +- `sacc_data` is retained for output assembly and for the row layout; it must contain exactly the rows the `theory_fn` returns (the length/order the concealing factor is added onto). The user owns this alignment. +- No `systm_dict` parameter. Systematics, if a backend needs them, are closed over inside that backend's `theory_fn`; they never transit `ConcealDataVector`. +- No `draw_fn` parameter. The shift draw is the built-in pure function below; `shifts_dict` and `shift_distr` are its specification. +- `seed` has **no default** and must be supplied explicitly. Blinding custody depends on the seed being a deliberate, secret choice; a defaulted blinding seed would silently blind against a public constant. `seed` accepts an `int` or a `str` (see Shift draw for the string→int normalization). +- `shifts_dict` maps a parameter name (a key of `fiducial_params`) to its shift envelope. **The envelope is a delta about zero, not an absolute value or absolute bound**: the drawn number is added to `fiducial_params[k]` (see Shift draw). A `float` `h` is a symmetric delta envelope `(-h, +h)`; a `(lo, hi)` tuple is a delta box, the drawn delta lies in `[lo, hi]` (typically straddling zero). `shift_distr` selects `"flat"` (uniform over the delta envelope) or `"gaussian"` (delta drawn from a zero-mean Gaussian with σ = the `float` half-width). `"gaussian"` accepts only the symmetric `float` form; a `(lo, hi)` tuple with `shift_distr="gaussian"` raises. + +### Shift draw + +A pure, module-level function is the sole shift source: + +```python +def draw_param_shifts( + shifts_dict: Mapping[str, float | tuple[float, float]], + seed, # int | str + shift_distr: str = "flat", +) -> dict[str, float]: + """Draw a delta for each named parameter from a local RNG seeded by + `seed`. Each returned value is a shift to be *added* to the fiducial + value, not an absolute parameter value. Order-independent: the delta + for a given key depends only on (key, seed, shift_distr), not on dict + iteration order.""" +``` + +- **Deltas, not absolute values.** Every returned number is a shift to overlay on `fiducial_params` (below), never a replacement value and never an absolute bound. This is the sole draw semantics; there is no absolute-replacement path. +- **Seed normalization.** `seed` may be an `int` or a `str`. A string is reduced to an integer seed deterministically (stable hash → int, e.g. SHA-256 of the UTF-8 bytes reduced to a 64-bit int) before constructing the RNG; an int is used as-is. The mapping from a given string to its integer seed is fixed and reproducible across runs and machines. +- Uses a **local** `numpy.random.default_rng(normalized_seed)`; it never calls `np.random.seed` and never perturbs process-global RNG state. +- **Order-independent.** The delta drawn for a parameter must not depend on the iteration order of `shifts_dict`. Concretely: iterate keys in a canonical order (sorted) and/or derive each key's draw from an RNG spawned deterministically per key, so that permuting `shifts_dict` yields identical per-key deltas. +- `"flat"` draws uniformly over the delta envelope (`(-h, +h)` for a `float` `h`, `[lo, hi]` for a tuple). `"gaussian"` draws from a zero-mean Gaussian with σ = the `float` half-width and accepts only the `float` form. +- Returns a mapping in `fiducial_params` space: `{param_name: drawn_delta}`, keys a subset of `fiducial_params` keys, values plain floats. No `pyccl` validation, no CCL-primitive dict, no `pyccl.Cosmology` construction, no import of pyccl. + +The concealed parameter set is `fiducial_params` overlaid with these deltas: `concealed_params[k] = fiducial_params[k] + shift[k]` for `k` in the drawn shift, `fiducial_params[k]` otherwise. + +### Concealing computation + +`calculate_concealing_factor(factor_type="add")` computes: + +``` +t_fid = theory_fn(fiducial_params) +t_conceal = theory_fn(concealed_params) # concealed_params = fiducial + drawn shift +factor = t_conceal - t_fid # "add"; t_conceal / t_fid for "mult" +``` + +Both branches are element-wise over the aligned theory vectors: `factor` is a 1-D array the length of `sacc_data.mean`, and for `"mult"` `factor = t_conceal / t_fid` is a per-row ratio. + +`apply_concealing_to_likelihood_datavec()` returns `sacc_data.mean + factor` (`"add"`) or `sacc_data.mean * factor` (`"mult"`, element-wise). The additive amplitude-shift envelope is the path sp_validation blinding uses; the multiplicative branch is preserved stock Smokescreen behavior, offered for callers that want it and not exercised by any sp_validation path. The default concealing path invokes the `theory_fn` directly: no firecrown `get_default_params_map`, `modify_default_params`, `tools.update/prepare`, or `likelihood.update/compute_theory_vector` calls are on it. The inherited firecrown likelihood path is not deleted, but it is off the default flow, lazily imported, and unsupported. + +### Save path + +`save_concealed_datavector` writes the blinded vector back to a SACC file through SACC's own API, with no firecrown import and no `likelihood`: + +- The rows to conceal are exactly the rows the caller placed in `sacc_data`, in `sacc_data.mean` order — the same rows `theory_fn` returns (extract-then-blind: the caller hands in a SACC containing only the to-be-blinded block). The concealing factor is added over the full mean. There is no wider-SACC / explicit-index path; scoping to a sub-block is the caller's job before construction. +- Writing: deep-copy `sacc_data`, overwrite its mean with the concealed vector (`concealed_sacc.mean = concealed_data_vector`), copy metadata, then `save_fits`/`save_hdf5`. **The copied SACC's covariance is carried over unchanged** — blinding shifts the mean and never touches the covariance. No `get_sacc_indices`, no `save_to_sacc`, no firecrown import. +- The metadata stamping/stripping (concealed flag, creator, timestamp, seed strip) is custody-owned and unchanged; this PRD does not alter it. + +### Consistency check + +There is **no value/covariance consistency check**. Row-to-theory alignment is the backend's contract (stated in the protocol), not Smokescreen's to verify; with no likelihood there is no second internal vector to compare a SACC mean against. Any `_verify_sacc_consistency`-style comparison of `sacc_data.mean` against a likelihood-derived vector (and its `allclose` covariance check) is absent from the fork — dropped, not re-expressed. This is a deliberate, non-behavior-preserving change. + +The sole guard is a **length check**: on construction, verify `len(theory_fn(fiducial_params)) == len(sacc_data.mean)` and surface a clear error on mismatch. This catches gross shape errors; it does **not** catch a `theory_fn` that returns a correctly-sized but wrong-cosmology or wrong-row-order vector. That is an accepted consequence of moving alignment into the backend contract, recorded here so the guard is not mistaken for behavior-preserving. + +### Test-suite migration + +- The blinding-mechanics tests (`ConcealDataVector` construction, shift draw, concealing factor, apply, save/metadata) run against a **synthetic `theory_fn`** — a closure returning a fixed-length vector as a deterministic function of `cosmo_params` — without importing firecrown, and without requiring the default CCL backend (they inject the synthetic callable). +- Every test, fixture, and helper that required a firecrown likelihood or asserted firecrown-specific behavior is removed from the fork's exercised suite: firecrown is not installed, tested, or maintained here, so no test depends on it. The inherited firecrown source stays in the tree behind its lazy import; the fork simply does not test it. +- The draw is tested directly: (i) a fixed `(shifts_dict, seed)` reproduces a fixed shift; (ii) permuting the key order of `shifts_dict` yields identical per-key shifts (order-independence); (iii) the draw does not perturb `np.random`'s global state (draw, then assert a subsequent `np.random.random()` matches a run with no draw); (iv) the returned value is a **delta** — with a fiducial value `v` and envelope `h`, the concealed parameter is `v + drawn_delta` with `|drawn_delta| ≤ h`, never an absolute value in the envelope's range; (v) a string `seed` and its normalized integer produce the same draw, confirming string→int normalization. + +## Acceptance criteria + +1. In an environment with `pyccl` present but `firecrown` and `numcosmo_py` absent: `import smokescreen` succeeds, a `ConcealDataVector` built from a synthetic `theory_fn` blinds a SACC vector end-to-end (`calculate_concealing_factor` → `apply_concealing_to_likelihood_datavec` → `save_concealed_datavector`) with the default backend never constructed, and a `ConcealDataVector` on `theory_fn=None` blinds a standard cosmic-shear SACC fixture through the default CCL backend — both producing a blinded vector that differs from the input and leaves the covariance untouched. +2. Import discipline, verified by test and grep: + - `import smokescreen` and `import smokescreen.datavector` import neither `pyccl` nor `firecrown` at module load (assert absence from `sys.modules` after a fresh import in a subprocess). `pyccl` enters `sys.modules` only once the default backend is constructed. + - No `import firecrown` / `from firecrown` at module scope **anywhere** in the package; the inherited firecrown path imports firecrown lazily, inside the function that uses it. `import numcosmo_py` appears nowhere at module scope. + - No `numpy<2.5` constraint and no `patch_firecrown` module anywhere. None of the removed default-path symbols `_verify_sacc_consistency`, `get_data_vector`, `get_sacc_indices`, `save_to_sacc`, `_create_concealed_cosmo`, `systm_dict` appear on the default concealing flow. +3. The concealing factor equals `theory_fn(concealed_params) - theory_fn(fiducial_params)` exactly (bit-for-bit) for the synthetic backend, and `apply_…` returns `sacc_data.mean + factor`. The `factor_type="mult"` branch (`t_conceal / t_fid`, applied multiplicatively) is exercised by the same synthetic backend and returns `sacc_data.mean * factor`. +4. `ConcealDataVector` construction raises a clear error when `len(theory_fn(fiducial_params)) != len(sacc_data.mean)`. +5. The shift draw uses a local RNG: after `draw_param_shifts(...)`, `np.random.random()` returns the same value it would with no prior draw (global state untouched). Permuting the key order of `shifts_dict` produces an identical per-key shift mapping. A fixed `(shifts_dict, seed, shift_distr)` reproduces a fixed shift across runs. The drawn value is a **delta** overlaid on the fiducial (`concealed_params[k] == fiducial_params[k] + drawn_delta[k]`, `|drawn_delta[k]|` within the envelope), not an absolute replacement. A string `seed` and its normalized integer yield the same draw. +6. The full exercised test suite passes in the supported firecrown-free environment (pyccl present — pyccl is the shipped default backend); no test is skipped for a missing firecrown. Only the synthetic-backend mechanics subset is additionally required to pass with pyccl absent; the suite as a whole is not required to run pyccl-absent. + +## Non-goals + +- **Packaging, install identity, dependency declaration, CI wiring, and install docs** — declaring `pyccl` in the fork `pyproject`, settling the fork's pinned `git+https` install identity, re-pointing fork CI gates, writing pip-only install docs. Owned by the packaging sub-PR. +- **A production, survey-specific theory backend.** This PR ships a general default CCL `theory_fn` for standard cosmic-shear SACC files; the sp_validation-specific backends (coarse/fine ξ± and pseudo-Cℓ against the master layout, IA-configured) are downstream blinding-wiring work, not part of this PR. +- **Firecrown support.** The inherited firecrown path is retained lazily but is not installed, tested, maintained, or documented as supported here. +- **Arbitrary-parameter-space draw indirection.** The draw is a fixed pure function over CCL-native parameter names; an injectable `draw_fn` abstraction over arbitrary parameter spaces is explicitly deferred. +- **Any change to the custody/encryption scheme** (seed handling, hash commitment, plaintext deletion, metadata stamping/stripping). Untouched here. +- **Any PR against DESC upstream.** All changes target the `UNIONS-WL/Smokescreen` fork. diff --git a/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-native-sacc-likelihood.md b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-native-sacc-likelihood.md new file mode 100644 index 00000000..15a1678c --- /dev/null +++ b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-native-sacc-likelihood.md @@ -0,0 +1,76 @@ +# PRD — Native SACC likelihood (PR-7) + +## Purpose + +sp_validation's data vectors live in SACC files, but the CosmoSIS inference chain reads a DES-style "2pt FITS" file produced by a converter. This PR lets CosmoSIS consume the SACC file **natively**, so the inference chain no longer depends on the FITS converter for the fiducial (IA-only, ξ±) pipeline. CosmoSIS ships a native SACC likelihood (`likelihood/sacc/sacc_like.py`, `SaccClLikelihood`), but its ξ± path evaluates a radian-θ theory spline at arcmin data tags (theory ≈ 0, χ² silently wrong) and assumes a theory↔data ordering it never enforces — so it cannot be used as-is. This PR adopts it through a thin sp_validation-owned subclass that fixes those two defects (a third — an undefined-name bug in the unused `keep_tracers` path — is deliberately left untouched), and proves χ² equality against the converter path to machine precision. + +## Desired end state + +- An sp_validation-owned CosmoSIS module, `SaccLikeUnions(SaccClLikelihood)`, that reads a `{version}.sacc` file and produces a ξ± likelihood **numerically identical** to the existing 2pt-FITS + `2pt_like` path. +- The inference-prep step emits, from one assembled `{version}.sacc`, two CosmoSIS ini files: the legacy 2pt-FITS + `2pt_like` path (validating/legacy) and a `sacc_like_unions` path pointing directly at the SACC file (native). +- n(z) is read directly from the SACC NZ tracers — no 2pt-FITS is required anywhere on the native path. +- A test suite asserts χ² / theory-vector / post-cut-count equality between the two paths, and asserts that the ordering guard raises on a misordered file. The suite is skipped cleanly where CosmoSIS is unavailable. +- The shim is self-retiring: a tripwire test fails the day upstream fixes the unit bug, signaling the subclass can be deleted. + +## Scope + +**In scope:** the fiducial A_ia (IA-only, ξ±) inference pipeline. The subclass, the inference-prep rewiring, the n(z)-from-SACC path, and the equality validation. + +**Out of scope (dormant, unchanged):** the PSF / xi_sys pipeline variant and the glass-mock rules stay on the existing FITS-assembly path (`cosmosis_fitting.py`); the PR body must state this explicitly rather than leave it silent. + +## Interfaces / contracts + +### The CosmoSIS module + +An sp_validation-owned Python module file usable as a CosmoSIS likelihood, subclassing the upstream `SaccClLikelihood` and overriding only what the two hazards require: + +```python +class SaccLikeUnions(SaccClLikelihood): + def build_data(self): + # 1. super().build_data() — scale cuts applied in arcmin + # (matches ini ergonomics and 2pt_like's angle_range convention) + # 2. loud ordering guard: replay SaccClLikelihood's own theory loop + # verbatim and require the resulting row order equals the + # get_mean() insertion order, or raise ValueError. (See below.) + ... +``` + +Contract points: + +- **Angular units (the contract).** CosmoSIS theory θ is in radians; the SACC contract stores θ in arcmin. The subclass must guarantee three things: (a) theory extraction sees **radian** θ, so the upstream spline is evaluated on its own grid; (b) `self.sacc_data` and every save-by-copy path (`save_theory`, `save_realization`) emit **arcmin** θ, so a consumer re-ingesting saved output sees arcmin and does not double-convert; (c) scale cuts are applied in arcmin (matching ini ergonomics and `2pt_like`'s `angle_range` convention). The reference implementation achieves (a)+(b) by confining a radian-θ copy of the SACC data to the theory-extraction call and leaving `self.sacc_data` in arcmin — the how is the implementer's, but all three guarantees are contractual. +- **Ordering guard.** The upstream data vector is `get_mean()` (SACC insertion order); the upstream theory vector is built by replaying its own loop over data types × tracer combinations × points, which is aligned to the data *only when the file is grouped type-major-then-tracer in exactly that loop order*. The guard reconstructs the row provenance by replaying that same loop **verbatim** — do not sort, dedup-reorder, or otherwise reinterpret it; reproduce `SaccClLikelihood`'s literal iteration (`for dt in sacc_data.get_data_types(): for tc in sacc_data.get_tracer_combinations(dt): for each point ...`), whatever iteration order those upstream methods yield — and require the reconstructed order to equal the `get_mean()` insertion order, raising `ValueError` otherwise. Because both the guard and the theory extraction derive from the identical replayed loop, the guard is correct regardless of whether `get_data_types()` iterates sorted or insertion-order. A file grouped pair-major (e.g. a tomographic 2-bin file laid out tracer-major) breaks the alignment and must raise. +- **`like_name = 2pt_like`.** Set in the ini so chain post-processing and `extra_output` see identical DataBlock keys regardless of which likelihood engine ran. +- **Everything else rides upstream unmodified:** scale-cut grammar, Sellentin/Hartlap corrections, `save_theory`, Cℓ bandpower windows. Do not touch the `keep_tracers` removal path (it references undefined names upstream; the fiducial pipeline never exercises it). + +### n(z) loading + +The native path reads n(z) through CosmoSIS's `number_density/load_nz_sacc`, which reads NZ tracers named `source_i` (zero-based, contiguous) into the `nz_source` section. No 2pt-FITS n(z) file is produced or consumed on the native path. + +### Inference-prep output + +The inference-prep step consumes the assembled `{version}.sacc` and emits both: + +1. **Legacy/validating path** — 2pt-FITS (via the SACC→2pt-FITS converter) + a `2pt_like` ini. On the fiducial native pipeline, inference-prep no longer *calls* `cosmosis_fitting.py`'s hand-rolled FITS assembly for its fiducial output; it routes through the converter instead. `cosmosis_fitting.py` itself is retained, not removed — it remains the byte-compare oracle for the converter PR and the assembly path for the dormant PSF/glass-mock variants. +2. **Native path** — a `sacc_like_unions` ini pointing at the `{version}.sacc` file. + +Inference-prep is the (revived) `inference_prep` Snakemake rule, which consumes the assembled `{version}.sacc` and writes both inis into the inference output directory (`COSMO_INFERENCE`). Its ini **templates must be bound as DAG `input:`s, not rule `params`**, anchored on the running checkout via `INFERENCE_TEMPLATE_DIR`, so that editing a template forces a regeneration; a dry-run guard asserts that DAG edge exists. + +## Acceptance criteria + +Validation is **in-process module equality**, not full-pipeline: load both likelihood modules standalone (`build_module()` setup/execute) on a hand-built DataBlock carrying identical synthetic theory in `shear_xi_plus`/`shear_xi_minus`, feed the same underlying data through SACC (native) vs converter-FITS (legacy), and check: + +1. **χ² / log-likelihood equal** across the two paths to machine zero (Δχ² = 0 at tight rtol), on both a synthetic realistic-covariance fixture (covariance ~ (0.1|ξ|)², to give χ² dynamics real teeth) and on real ξ-only data (N = 40). The claim is path-equality; the absolute χ² is not a target (it depends on the fixture seed and catalogue version). For reference, the implementation that produced this spec observed synthetic χ² = 1.18829133107 and real χ² = 420310.753739 — informative, not normative. +2. **Theory vectors equal** element-by-element (Δtheory = 0). +3. **Post-cut point counts equal** across both paths for the same scale cuts, including cut values placed off data points (edge semantics verified: no divergence between the two engines' cut behavior on tested ranges). +4. **Ordering guard raises** `ValueError` on a concretely-misaligned fixture: a 2-bin file whose rows are laid out **tracer-major** (all data types for pair 0, then all for pair 1) rather than the type-major-then-tracer order the upstream loop reconstructs. This layout is guaranteed to break alignment under the replayed loop (see the ordering-guard contract), so the fixture reliably triggers the guard. +5. **Unit-regression tripwire:** the raw upstream class (no shim), run on the same input, produces a χ² **~631× off** — the observed likelihood ratio from evaluating a radian-θ spline at arcmin tags (theory collapses to ≈ 0, so χ² → dᵀC⁻¹d). This test documents the upstream bug and fails the day upstream converts units correctly, signaling the shim can be retired. (The separate ~3437× figure is the radian↔arcmin θ ratio — the *cause* of the collapse, not a χ² factor; it belongs to the units contract above, not to this assertion.) +6. **Save-path regression:** saved theory/realization output carries **arcmin** θ tags, and re-executing on the saved output leaves χ² stable (no double-conversion). +7. **Skips cleanly without CosmoSIS:** the test module gates on `pytest.importorskip("cosmosis")` plus a CosmoSIS-standard-library directory env var (`CSL_DIR`); it skips in an image lacking CosmoSIS rather than failing. Real-data equality is additionally gated to the machine holding the catalogue. + +## Non-goals + +- **No upstream fix.** The upstream CosmoSIS unit bug and the undefined-name hazard in `keep_tracers` are not fixed here; they may be recommended as follow-ups in the PR body. This PR is a downstream shim, and it is designed to be deleted once upstream converts units correctly. +- **No reimplementation or fork of the likelihood.** Adoption is by subclass only; scale cuts, covariance corrections, and Cℓ windows ride the upstream implementation. +- **No tomographic support.** The fiducial pipeline is single-pair ξ±; the ordering guard exists precisely to fail loudly rather than silently mis-handle a pair-major tomographic file. Tomographic support is separate future work. +- **No change to the PSF / xi_sys or glass-mock pipelines,** which remain on the existing FITS-assembly path. +- **No CAMB or compiled CosmoSIS modules** in validation — the equality test uses pure-Python likelihood files plus a pip-installed `cosmosis`. diff --git a/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-sacc-io-writers.md b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-sacc-io-writers.md new file mode 100644 index 00000000..6b3a6716 --- /dev/null +++ b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-sacc-io-writers.md @@ -0,0 +1,133 @@ +# PRD — `sacc_io` writers + +## Purpose + +sp_validation produces weak-lensing data products (ξ±, pseudo-Cℓ, COSEBIs, pure-E/B, ρ/τ PSF diagnostics, n(z), covariance) scattered across TreeCorr `.txt`, custom FITS, `.npz`, and ASCII files. This PR introduces `src/sp_validation/sacc_io.py`: a single module that writes every product into self-describing [SACC](https://sacc.readthedocs.io) files in one fixed, self-consistent layout. It is pure format work — it defines the on-disk contract that the converter, migration, and blinding stages all consume, and nothing about it depends on where theory comes from. + +## Desired end state + +A new module `src/sp_validation/sacc_io.py` exposes per-statistic builder functions, mirror reader functions, a covariance assembler, and thin save/load helpers. Round-trip tests prove that every product's numeric payload survives write→read bit-exact and that insertion order, covariance alignment, and n(z) all reconstruct exactly. + +Each catalogue version is serialized as **two SACC files**, not one: + +- **`{version}.sacc`** — the analysis vector: NZ tracers, coarse ξ±, pseudo-Cℓ (EE/BB/EB) with bandpower windows, COSEBIs at the fiducial scale cut, pure-E/B, ρ/τ, and a `FullCovariance` assembled from per-statistic blocks with zero cross-blocks. +- **`{version}_xi_fine.sacc`** — the COSEBIs/pure-EB integration input: the same NZ tracers (self-describing), fine ξ± (10000 bins), and a `DiagonalCovariance` built from TreeCorr `varxip`/`varxim`. + +The two-file split is mandatory, not stylistic: sacc 2.4 requires `covariance.size == len(mean)` and serializes a `BlockDiagonalCovariance` as one FITS table per block (`storage_type = ONE_OBJECT_MULTIPLE_TABLES`). A 10000-bin fine grid cannot coexist with a full analysis covariance in one file — the dense fine block alone is 3.2 GB single-bin and grows to a ~720 GB dense-equivalent tomographically (300k points at 5 bins, 300000² × 8 bytes). Measured reference: 4070 points with a dense-block covariance = 129–133 MB. + +The API is tomography-native throughout: bin pairs are addressed as `bins=(i,j)`; the single-bin case is `(0,0)`. NZ tracers are named `source_i` (the suffix CosmoSIS's SACC reader expects). + +## Interfaces and contracts + +### Module surface (`src/sp_validation/sacc_io.py`) + +All builders **mutate `s` in place and return `None`** (the converters stage relies on this convention when it chains readers into `assemble_covariance`). All arrays are `np.ndarray`; `bins` is a `tuple[int, int]` normalized to `i ≤ j`. + +Builders: + +```python +new_sacc(nz: dict[int, tuple[np.ndarray, np.ndarray]], + metadata: dict) -> sacc.Sacc + # nz maps bin index -> (z, nz); iteration order fixes tracer order (source_0, source_1, …). + # Adds every NZ tracer first, stamps metadata, returns the fresh Sacc. + +add_xi(s, bins, theta, xip, xim, *, grid, npairs, weight, theta_nom) -> None + # Emits [ξ+ ; ξ−], θ ascending. One data point per (θ, sign). + +add_pseudo_cl(s, bins, ell, cl_ee, cl_bb, cl_eb, window) -> None + # Wraps THREE sacc.Sacc.add_ell_cl calls — one each for + # galaxy_shear_cl_ee, _bb, _eb — all sharing the single + # BandpowerWindow(window) passed in. "One shared window per call" + # means the same window object indexes all three sub-statistics. + +add_cosebis(s, bins, n, En, Bn, *, theta_min, theta_max) -> None +add_pure_eb(s, bins, theta, values_by_key, *, theta_min=None, theta_max=None) -> None + # values_by_key: dict keyed by the pure-E/B keys; see "pure-E/B ordering" below. +add_rho(s, k, theta, xip, xim) -> None # k = 0..5 +add_tau(s, bins, k, theta, xip, xim) -> None # k in {0, 2, 5} + +assemble_covariance(s, blocks: list[np.ndarray]) -> None + # blocks is an ORDERED list; block order = insertion order of the data + # vector it tiles. Calls s.add_covariance(scipy.linalg.block_diag(*blocks)). +``` + +Readers mirror each builder (`get_xi(s, bins, grid=…)`, `get_pseudo_cl`, `get_cosebis`, `get_pure_eb`, `get_rho`, `get_tau`, `get_nz`); each returns the arrays its builder consumed, in insertion order. + +Helpers: + +```python +extract(s, *, bins=None, data_type=None, grid=None, **tag_filters) -> sacc.Sacc + # s.copy() then s.keep_selection(...) on the given selectors; the retained + # sub-covariance and the tag-filtered points compose (intersection). +save(s, path) -> None +load(path) -> sacc.Sacc +``` + +**pure-E/B ordering.** The pure-E/B key set and their canonical order are defined by, and imported from, `b_modes._EB_KEYS` as the single source of truth — `add_pure_eb` writes and `get_pure_eb` reads in exactly that sequence. Do not hardcode a parallel list here or in the converters. + +### Data types, tracers, point tags + +| Product | Type string | Tracers | Point tags | +|---|---|---|---| +| ξ± coarse/fine | `galaxy_shear_xi_plus` / `…_minus` (standard) | (`source_i`, `source_j`) | `theta` (=TreeCorr `meanr`, **arcmin**), `theta_nom` (=`rnom`), `npairs`, `weight`, `grid` = `coarse`\|`fine` | +| pseudo-Cℓ | `galaxy_shear_cl_ee` / `…_bb` / `…_eb` (standard) | (`source_i`, `source_j`) | `ell` (effective), `window`/`window_ind` — one shared `BandpowerWindow(ells, W(nell, nbp))` per `add_pseudo_cl` call, indexing all three `add_ell_cl` (ee/bb/eb) sub-calls | +| COSEBIs | `galaxy_shear_cosebi_ee` / `…_bb` (standard; ee=Eₙ, bb=Bₙ) | (`source_i`, `source_j`) | `n` (mode, 1-based), `theta_min`, `theta_max` (arcmin scale cut) | +| pure E/B | `galaxy_shear_xiPureE_plus`/`…_minus`, `…xiPureB_…`, `…xiPureAmb_…` (custom) | (`source_i`, `source_j`) | `theta`, plus `theta_min`/`theta_max` if cut | +| ρₖ (PSF autos) | `psf_rho{k}_xi_plus` / `…_minus`, k=0…5 (custom) | (`psf_stars`, `psf_stars`) Misc tracer | `theta` | +| τₖ (gal×PSF) | `galaxyPsf_tau{k}_xi_plus` / `…_minus`, k∈{0,2,5} (custom) | (`source_i`, `psf_stars`) | `theta` | +| n(z) | — | NZ tracer `source_i` (`z`, `nz` round-trip bit-exact) | — | + +Custom type strings (pure-E/B, ρ, τ) are all 3–4 underscore-separated parts so they parse under `sacc.parse_data_type_name`, even though sacc does not enforce the grammar. Pure-E/B writers are part of this module's surface (not merely a downstream convenience): the pure-E/B products are derived from ξ± and consumed by the blinding acceptance test, so they need a canonical home here. + +### File layout + +- `{version}.sacc` — analysis file (contents above), `FullCovariance`. +- `{version}_xi_fine.sacc` — fine ξ± + NZ tracers, `DiagonalCovariance`. + +Naming stability is scoped to exactly these two terminal files. Any per-statistic intermediate files are DAG internals owned by the migration stage, not part of this contract; consumers bind them through workflow path helpers, never by hardcoding names. + +Metadata keys on every file: `catalogue_version`, `sp_validation_version`, `created`, `npatch`. + +Two fixed conventions: **θ is stored in arcminutes** (SACC stores θ unitless; downstream theory hard-codes arcmin). **n(z) carries no normalization convention** — every consumer normalizes internally. + +### Ordering and covariance assembly + +Insertion order is preserved exactly through save/load (as an index sequence — `s.indices` after reload equals `s.indices` before save) and covariance rows align to it by construction. Three rules make alignment hold and must all be enforced: + +1. **Writers enforce strictly ascending θ/ℓ grids** — a non-ascending grid raises a loud `ValueError`. +2. **Readers return `s.indices` insertion order and never re-sort.** Reader-side sorting is exactly what lets data, covariance sub-blocks, and window columns silently diverge. +3. **Bin pairs normalize to i ≤ j.** + +Canonical order is **pair-major**: within each `add_xi` call `[ξ+; ξ−]` with θ ascending (matching TreeCorr's covariance layout), then pseudo-Cℓ (EE, BB, EB), COSEBIs (all Eₙ then all Bₙ), pure-E/B in `b_modes._EB_KEYS` order (that constant is the single source of truth — see "pure-E/B ordering"), then ρ, then τ (ρ before τ; τ for k∈{0,2,5}). + +This is the block order the covariance byte-compare in the converters stage depends on: within ξ the sub-order is `[ξ+ | ξ−]`, and τ (when present) follows ρ as `TAU_0 | TAU_2 | TAU_5`. The converters stage consumes only τ0/τ2 and treats this PRD as the authority for that order; any change here is a contract change there. + +`assemble_covariance(s, blocks)` builds the analysis-file `FullCovariance` from per-statistic dense blocks with zero cross-blocks — the same independence assumption the current `np.block` assembly makes, which the converter's byte-compare needs preserved. A tomographic ξ covariance with cross-pair correlations is supplied as ONE contiguous block spanning consecutive `add_xi` calls; type-major consumers permute via `s.indices`. The assembler validates that the supplied blocks are contiguous-ascending, tile `0..len(s.mean)` exactly, and are each square and size-matched — loud `ValueError` otherwise. + +### sacc 2.4 constraints the implementation must respect + +- Tag filters are plain kwargs: `s.indices(dt, tracers, grid='fine')`. The `tags={'grid':'fine'}` form silently returns `[]` with only a `UserWarning` — never use it. +- `get_theta_xi` accepts no tag filters; readers go through `indices` / `get_mean` / `get_tag`. +- `get_ell_cl(..., return_windows=True)` does not exist in 2.4; use `s.get_bandpower_windows(indices)`. +- Tracers must be added before any data point that references them (`new_sacc` adds NZ tracers first; do not use the `tracers_later=True` escape). +- `add_covariance` with a 1-D array yields `DiagonalCovariance`; with `np.diag(...)` it yields `FullCovariance`. Pass the fine file its variances as a 1-D array (dense is wasteful). + +## Acceptance criteria + +- `src/sp_validation/sacc_io.py` exists and exposes every builder, reader, and helper above. +- Every product round-trips write→read: ξ± (coarse and fine), pseudo-Cℓ with windows, COSEBIs, pure-E/B, ρ (k=0…5), τ (k∈{0,2,5}), and n(z). The round-trip test asserts **bit-exact** equality (`np.array_equal`) on the numeric payload fields — `z`, `nz`, and every `mean` value — proving no float32 downcast, unit round-trip, or dtype coercion occurred; the test's job is to prove this, not assume it. +- A catalogue version serializes to exactly two files, `{version}.sacc` and `{version}_xi_fine.sacc`, each self-describing (NZ tracers present in both). +- After save→load, `s.indices` returns points in the canonical pair-major order, and a covariance recovered by index aligns element-for-element with the data vector. +- `assemble_covariance` raises `ValueError` on blocks that are non-contiguous, non-tiling, non-square, or size-mismatched; on valid input the resulting `FullCovariance` has `size == len(s.mean)`. +- Writers raise `ValueError` on a non-ascending θ/ℓ grid. +- `extract(s, *, bins=…, data_type=…, grid=…, **tags)` returns a sub-SACC whose covariance and tag-filtered points are exactly the selected subset (the retained covariance is the corresponding sub-matrix). +- Custom type strings parse under `sacc.parse_data_type_name` **into their intended `(sacc_quantity, …)` decomposition** — the test asserts the parsed tuple, not merely that parsing succeeds (any underscore string parses; the decomposition is what matters). +- Round-trip tests pass inside the container. + +## Non-goals + +- **No conversion to other formats.** SACC→2pt-FITS and SACC↔OneCovariance glue are a separate stage. +- **No migration of existing write sites.** `cosmo_val` mixins and the Snakemake workflow keep their current writers; re-pointing them is a separate stage. This module only defines the format and its I/O. +- **No blinding, theory, or cosmology.** No theory backend, no shift, no encryption — this module is theory-agnostic on-disk format only. +- **No regeneration of old products.** New products are born in this format; nothing existing is rewritten. +- **No fine-grid analysis covariance.** The fine file carries only a diagonal (TreeCorr variance) covariance; no full fine-grid covariance estimate exists or is produced here. diff --git a/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-smokescreen-blinding.md b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-smokescreen-blinding.md new file mode 100644 index 00000000..4375596f --- /dev/null +++ b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-smokescreen-blinding.md @@ -0,0 +1,177 @@ +# PRD — Smokescreen blinding wiring + +Repo: `CosmoStat/sp_validation`. Depends on the `UNIONS-WL/Smokescreen` fork exposing the theory-backend concealment entry point and the CCL-native draw described under *External contract*. + +## Purpose + +The tomographic data vector must be blinded before analysis so that no one can read S8 off the measured statistics until the collaboration agrees to unblind. This PR wires the measured SACC data vector through Smokescreen: it shifts ξ± and pseudo-Cℓ by a difference of theory vectors between the fiducial cosmology and a hidden cosmology drawn inside a fixed amplitude envelope, re-derives the dependent statistics from the blinded ξ±, and manages the seed under a public hash-commitment scheme so both the blind and the unblind are verifiable without a trusted keyholder. + +## Desired end state + +- A **blind** CLI takes a master SACC file (the full `sacc_io` product) and produces a blinded master SACC file plus an encrypted seed bundle and a repo-committable commitment JSON. The plaintext true vector is deleted at blinding time. +- The blinded file carries shifted ξ± (coarse and fine θ grids) and shifted pseudo-Cℓ; its COSEBIs and pure-E/B blocks are re-derived by the pipeline's own estimators from the blinded ξ±; its covariance and its ρ/τ PSF diagnostics are byte-identical to the input. +- An **unblind** CLI takes a blinded file and the encrypted bundle, verifies the commitment, recomputes the shift, and subtracts it to restore the true vector. +- The shift is a deterministic, reproducible function of `(seed, blinding config)`: re-blinding an updated catalogue needs no human round-trip, and unblinding is mechanical. +- B-mode null-test estimators return the same answer on a blinded file as on the true file, to the estimator's numerical floor. +- The CCL theory backend that computes the shift is cross-validated against an independent CAMB stack, so the shift means what it is intended to mean (see *Tests*). + +## External contract (provided by the fork, consumed here) + +This PR calls the fork through its concealment entry point and does not reach around it. The signatures below are the fork's authoritative contract; this PR does not restate their internals, only the two sp_validation-specific pieces it supplies: the three theory callables and the SACC assembly. The hidden cosmology is drawn by the fork's own CCL-native draw — there is no injectable draw callable. + +**Conceal.** The one entry point: + +```python +ConcealDataVector( + fiducial_params, # Mapping[str, float] — the fiducial CCL cosmology dict (== TheoryConfig.ccl_params()) + shifts_dict, # Mapping[str, float] — per-parameter uniform half-width (CCL-native); keys ⊆ fiducial_params + sacc_data, # sacc.Sacc — exactly the rows theory_fn spans + *, + seed, + theory_fn, # Callable[[Mapping[str, float]], np.ndarray] +) +``` + +This PR always supplies its own `theory_fn` explicitly (the three master-layout backends below), overriding the fork's built-in default CCL backend — the default is a general cosmic-shear convenience, whereas blinding needs the exact master ξ± / pseudo-Cℓ row layout with sp_validation's IA configuration. `fiducial_params` is the fiducial cosmology this PR passes explicitly (there is no `cosmo`/`likelihood` pair and no `systm_dict`); it **is** `TheoryConfig.ccl_params()`. The concealing factor the fork computes is `theory_fn(concealed_params) − theory_fn(fiducial_params)`, where `concealed_params = fiducial_params` overlaid with the fork's internal draw of `shifts_dict` under `seed`. Every `shifts_dict` key must name a key present in `fiducial_params` (the overlaid keys — `sigma8`, `Omega_c` — are a subset of the `ccl_params()` keys); an unknown key is a config bug. + +**Draw (in the fork, not here).** The fork draws the hidden cosmology internally from `shifts_dict` and `seed` using a local `numpy.random.default_rng`: order-independent, no global seed. `shifts_dict` keys are **CCL-native primitives** (e.g. `sigma8`, `Omega_c`); each value is a per-parameter uniform half-width `h`, and the fork draws that key **independently** as `U(fiducial_params[key] − h, fiducial_params[key] + h)`. Independent per-key uniform draws are the fork's draw law; the (S8, Ωm) → (sigma8, Omega_c) calibration below relies on it. There is no injectable draw callable and no (S8, Ωm) parameter space inside the fork — the fork speaks CCL. This PR's responsibility is to supply a `shifts_dict` in CCL-native primitives whose envelope is **calibrated to an equivalent S8 amplitude** (see *Envelope calibration* below). + +**Theory backend.** A callable aligned element-for-element to the SACC rows of the block being blinded: + +``` +theory_fn(cosmo_params: Mapping[str, float]) -> np.ndarray +``` + +Any callable satisfies the protocol; the fork imports no theory backend at module load (its default CCL backend imports pyccl only when constructed). This PR does not use that default — it supplies three of its own callables (coarse ξ±, fine ξ±, pseudo-Cℓ), each a direct CCL computation from `sp_validation.cosmology`, matching the master SACC layout. The theory this PR computes is exactly its fiducial: the fiducial cosmology and its non-cosmological parameters are the ones this PR passes, nothing rides along uninvited. + +**SACC assembly and encryption.** The concealment call returns a shifted `.mean` array; this PR assembles the blinded SACC itself from that array via `sp_validation`'s own SACC writers (`sacc_io`), which own the master layout and row order. Encryption helpers (`smokescreen.encryption.encrypt_file` / `decrypt_file`, Fernet) are used as-is for the seed bundle. + +## Interfaces and contracts + +### Theory config and backends + +The fiducial cosmology and the two ξ± theory paths (CCL-native and independent-CAMB) live in `sp_validation.cosmology`. The blinding backend imports the frozen `TheoryConfig` from there; its defaults **are** the blinding fiducial. `TheoryConfig` imports only `numpy` at module load — CCL and CAMB are imported inside the functions that need them — so importing it never drags in a theory backend. + +`TheoryConfig` carries the full fiducial cosmology parametrised by the blind axes `S8` and `Omega_m`, plus the rest (`Omega_b`, `h`, `n_s`, `m_nu` as Σm_ν, `w0`, `wa`, `mass_split`), the nonlinear-model tokens, and NLA intrinsic-alignment fields. It exposes: + +- `sigma8() = S8 / sqrt(Omega_m / 0.3)` — the standard weak-lensing definition; at the fiducial (`S8=0.80`, `Omega_m=0.30`), `σ8 = 0.80`. +- `omega_c() = Omega_m − Omega_b − Ω_ν`, with `Ω_ν h² = Σm_ν / 93.14 eV` (`m_nu` is the sum, distributed under `mass_split`), so the total matter density is exactly `Omega_m`. +- `ccl_params()` → exactly `Omega_c, Omega_b, h, n_s, sigma8, m_nu, mass_split, w0, wa, Neff, T_CMB` and no other keys — no CCL default rides along. `Neff` and `T_CMB` are fixed constants of the fiducial (`Neff = 3.046`, `T_CMB = 2.7255 K`), not user-facing `TheoryConfig` fields; they are load-bearing for the CAMB↔CCL amplitude match and are emitted explicitly rather than left to either stack's default. +- `from_overrides(overrides)` → applies overrides onto the fiducial; **raises on any unknown key** (fail-fast). + +**Nonlinear-model token mapping (load-bearing).** CCL and CAMB name the same HMCode2020+feedback recipe with *different* strings: CCL takes `mead2020_feedback` in `extra_parameters['camb']['halofit_version']`; `camb.set_halofit_version` takes `mead2020`. `TheoryConfig` carries **two** tokens (`ccl_halofit_version`, `camb_halofit_version`) denoting one recipe; each stack is fed its own. Passing a single string to both APIs is a silent stack disagreement (`mead2020` vs `mead2020_feedback` differ several % at k≳1). The defaults mirror the CosmoSIS v1.4.6.3 IA-fiducial (`logT_AGN=7.5`; `S8=0.80`, `Omega_m=0.30`, `h=0.70`, `n_s=0.96`, `m_nu=0.06`). + +### Envelope calibration: from S8 amplitude to CCL-native `shifts_dict` + +The blinding intent is an amplitude smear of a chosen S8 half-width (`ΔS8` config; nominal `|ΔS8| ≤ 0.075`, `|ΔΩm| ≤ 0.1`). The fork draws in CCL-native primitives, so this PR maps the intended (S8, Ωm) box to a `shifts_dict` in `{sigma8, Omega_c}` half-widths at the fiducial: + +``` +sigma8 = S8 / sqrt(Omega_m / 0.3) Omega_c = Omega_m − Omega_b − Ω_ν +``` + +The mapping is evaluated at the fiducial to set the half-widths handed to the fork; the calibration is exact enough for a blinding smear because the target is a *characteristic amplitude*, not a precise (S8, Ωm) posterior. The half-widths are **config, not code** (the group may resize the envelope). The same `seed` yields the same hidden cosmology across all three block passes, so the three shifted blocks are mutually consistent by construction. + +### Theory backends: three callables, one hidden cosmology + +All three are direct CCL theory differences at the same two cosmologies (fiducial and hidden), sharing one P(k) recipe (CAMB HMCode2020; `ccl_halofit_version` from `TheoryConfig`, matched to the inference stack). They are two-tracer: cross-pairs use `angular_cl(tracer_i, tracer_j)` with each bin's own n(z) — no auto-n(z) approximation. + +**n(z) and row alignment.** Each backend reads the per-bin n(z) directly from the tracers of the sub-SACC block it is handed (the same block extracted for concealment) — `WeakLensingTracer(cosmo, dndz=(z, nz))` per bin, IA from `TheoryConfig`'s NLA fields. The output vector is laid out to match that block's SACC rows element-for-element: iterate the block's data points in stored order, and for each `(bin_i, bin_j, θ or ℓ)` emit the corresponding theory value. The alignment is the block's own row order, not an assumed pairing; the fork's length guard (below) enforces length agreement, and AC #4's order-preservation assertion guards the merge back into the master. + +| Backend | Rows | Computation | +|---|---|---| +| coarse ξ± | analysis θ grid | ξ± at coarse θ | +| fine ξ± | fine θ grid | ξ± at fine θ | +| pseudo-Cℓ | bandpower rows | `W @ ΔCℓ_EE` on the stored `BandpowerWindows`; `ΔBB = ΔEB ≡ 0` (shift is pure E-mode) | + +Each is passed to `ConcealDataVector` as its `theory_fn` for the matching sub-SACC block. + +### Blinding: extract → conceal → merge, per block + +The master SACC file carries more rows than any single blindable block (COSEBIs, ρ/τ). The fork's extract-then-blind contract (with its length guard — there is no value/covariance consistency check) requires the SACC handed to it to contain exactly the rows the theory callable spans. Therefore, per block: + +1. Extract the block (ξ± coarse / ξ± fine / pseudo-Cℓ) with its covariance sub-block into a temporary SACC, recording each extracted row's index in the master. +2. `ConcealDataVector(fiducial_params, shifts_dict, sub_sacc, seed=seed, theory_fn=theory_fn)` → concealed `.mean` for the block. +3. Write the shifted values back into the master at their recorded indices, preserving row order exactly. Row-order preservation is asserted in tests (AC #4), not assumed — a mis-merge that scrambles ξ± ordering would silently corrupt the COSEBIs re-derivation. + +COSEBIs and pure-E/B are then re-derived by re-running the pipeline estimators (`b_modes.calculate_cosebis`, `b_modes.calculate_pure_eb_correlation`) on the blinded ξ± — never re-implemented, never shifted independently. Covariance and ρ/τ blocks are untouched. + +### Custody: hash commitment (no keyholder) + +Blind CLI: + +1. Draw an OS-entropy seed. +2. Blind immediately (all three blocks). +3. Write `commitment.json` (repo-committable): `sha256(seed)` + a **config digest** binding the blinding config (envelope half-widths + fiducial cosmology + the two fixed `halofit_version` tokens). The digest is `sha256` of a canonical serialization: JSON with sorted keys, floats formatted via `repr()` (round-trip-exact), the full ordered field set fixed by this PR — so two runs of the same config produce byte-identical digests. Both `sha256(seed)` and the config digest are checked at unblind, so a wrong envelope or a mismatched P(k) recipe cannot silently subtract a wrong shift. +4. Encrypt `seed` + the true vectors into a bundle (`smokescreen.encryption`, Fernet); delete plaintexts. +5. Stamp blinded-file metadata: `concealed = True`; `blind_commitment = sha256(seed)` (public hash ties file → commitment). Unblind clears `concealed` back to `False` and removes `blind_commitment`. **Strip `seed_smokescreen`** — Smokescreen writes the raw seed into metadata; it must not survive into the blinded file. + +Unblind CLI: decrypt the bundle → recompute `sha256(seed)` and the config digest, verify both against `commitment.json` → recompute the three shifts from `seed` → subtract → restore the true vector. Verification precedes subtraction. + +### Metadata keys (blinded file) + +| Key | Value | +|---|---| +| `concealed` | `True` (reset to `False` at unblind) | +| `blind_commitment` | `sha256(seed)` hex string (public; removed at unblind) | +| `seed_smokescreen` | **absent** (stripped) | + +### Module layout + +- `sp_validation/cosmology.py` — `TheoryConfig`, the CCL-native ξ± path, and the independent-CAMB ξ± path (numpy-only module-level imports; CCL/CAMB function-local). +- `sp_validation/blinding.py` — envelope calibration, the three theory backends, extract/conceal/merge orchestration, re-derivation, custody. Imports `TheoryConfig` from `sp_validation.cosmology`. +- Blind / unblind CLIs (entry points). +- Tests under `src/sp_validation/tests/`. + +## Tests + +### Acceptance criteria — blinding + +Checkable, run inside the container: + +1. **Idempotence / plumbing (zero-shift).** Blinding with a zero shift (hidden cosmology equal to fiducial) reproduces the input file's ξ±, COSEBIs, and pure-E/B values exactly. This exercises the extract/merge/re-derivation plumbing only — a broken `theory_fn` also passes, since `theory_fn(fiducial) − theory_fn(fiducial) = 0` for any callable. The backend itself is tested by AC #2. +2. **On-file shift equals the intended theory difference (central correctness).** For a fixed non-zero seed on a two-bin fixture, the per-row shift actually present in the blinded file (`blinded.mean − true.mean` at each shifted block's rows) equals `theory_fn(hidden_params) − theory_fn(fiducial_params)` — where `hidden_params` is recovered by re-running the fork's draw on that seed — to ~1e-10. This closes the loop AC #1 leaves open (a wrong theory backend fails here) and asserts the merge places the shift at the right rows. Run for all three blocks. +3. **Cross-backend consistency (reference-independent).** For the same hidden cosmology, the concealment-path shift for a block is compared against an **independently written** direct-CCL reference — a self-contained `angular_cl`+`correlation` call in the test file that does not import `sp_validation.blinding`'s backend, reading the same n(z) and θ/ℓ from the fixture — and they agree to ~1e-10 on a two-bin fixture. The reference is independent code, so agreement is not tautological; this pins the backend's projection against a from-scratch CCL computation. +4. **B-mode invariance.** On mocks, the ΔBₙ induced by blinding is bounded by the fixed E→B leakage floor of the estimator and is **independent of the injected B amplitude** (the shift is pure E-mode, so its leakage into B is a fixed absolute offset, not a fractional one). The test injects two different B amplitudes at fixed shift and asserts the absolute ΔBₙ is identical between them (to ~1e-10). The comparand — the shift-induced leakage — is defined concretely as `blind(true_file) B-block − true_file B-block` re-derived through the pipeline estimator on the blinded ξ±; the test asserts this vector is the same for both injected B amplitudes. The magnitude of the leakage floor is not asserted against a fixed number; it is measured by the run and reported (see note below). The criterion this AC enforces — B-amplitude independence — is exact by construction. +5. **Covariance, ρ/τ, and row order untouched.** The blinded file's covariance block and ρ/τ diagnostic rows are byte-identical to the input, and every shifted block's rows land back at their original master indices (order-preservation assertion, guarding COSEBIs re-derivation against a mis-merge). +6. **Custody verifiability.** Blind → commit → encrypt → strip leaves no plaintext seed and no `seed_smokescreen` key on disk in the blinded file; unblind fails closed if either `sha256(seed)` or the config digest mismatches the commitment. +7. **Reproducibility.** Two blind runs with the same seed and config produce identical shifts; unblinding after a re-blind of an updated catalogue needs no external state beyond the encrypted bundle. +8. **End-to-end integration.** The blind CLI blinds a real sp_validation `sacc_io` master file end-to-end and the unblind CLI restores it bit-for-bit; run on a fixture master file in the container. +9. **Pure-EB boundary behavior.** Re-derived pure-E/B follows the pipeline's edge-based integration bounds. The test runs re-derivation on a fixture whose θ grid deliberately includes a boundary-degenerate reporting point (the first point of the integration range, where the edge-based estimator has no interior support) and asserts that point is NaN in both the true-file and blinded-file re-derivations — i.e. NaN-parity with the pipeline's own estimator, never a spurious finite value. Production reporting grids are strict sub-ranges of the integration range, so this degeneracy never fires on real files; the fixture forces it to exercise the parity. + +*Note on the ΔBₙ leakage floor.* The absolute size of the shift-induced E→B leakage is a measured output, not a target: it is reported from the run that produces it (the mock B-mode invariance test), not carried as an unsourced constant in this PRD. The acceptance criterion enforces that this leakage is independent of the injected B amplitude and reproducible — both exact by construction — with the observed magnitude recorded alongside the test. + +### Acceptance criteria — CAMB↔CCL theory cross-check + +The shift is a difference of CCL theory vectors; downstream inference runs CAMB. The shift only means what it is intended to mean if CCL and CAMB predict the same ξ± at a fixed cosmology on our θ grid. This test asserts that agreement and settles the one convention subtlety that would otherwise make the two stacks silently disagree: the fiducial fixes σ8 for CCL but A_s for CAMB, and a nominal `A_s = 2.1e-9` leaves CAMB's σ8 ≈3% off target — enough to blow a ξ± comparison to ~9–10%. + +Two independent ξ± paths, both in `sp_validation.cosmology`, at one cosmology and n(z): + +- **Path A — CCL native.** CCL builds the nonlinear P(k) through its Boltzmann-CAMB HMCode2020 route (`matter_power_spectrum='camb'` + HMCode2020 `extra_parameters`, `ccl_halofit_version`, `HMCode_logT_AGN`) and projects to ξ± via its own Limber (`angular_cl`) + FFTLog (`correlation`). Bare `WeakLensingTracer(dndz=(z,nz))` — IA off in this cross-check. +- **Path B — independent CAMB P(k) → CCL projection.** A direct `pycamb` run produces the HMCode2020 `P(k, z)` (using `camb_halofit_version` and `hmcode_logT_AGN`), wrapped in `ccl.Pk2D` and projected through the same CCL Limber + FFTLog machinery, same bare tracer. + +Because both route their nonlinear P(k) through CAMB's HMCode2020 and both project through CCL, a common Limber+FFTLog bug cancels: this test validates the **P(k) recipe** and the **σ8/A_s amplitude convention**, not the projection. Stated once in the module docstring. + +**Amplitude reconciliation.** A single closed-form rescale sets CAMB's `A_s` to reproduce the CCL σ8 target: `A_s = A_s_seed * (sigma8_target / sigma8_seed)**2`, exact because linear σ8² ∝ A_s — one CAMB linear-σ8 evaluation, one rescale, no iteration. Path B's CAMB params are set from the **same `TheoryConfig` fields** CCL sees — `w0`, `wa` (via `set_dark_energy`), `Neff`, `T_CMB`, `m_nu`/`mass_split` — not just `A_s` plus the HMCode P(k) tokens; otherwise an unmatched dark-energy or `Neff`/`T_CMB` value reintroduces exactly the stack-disagreement bias AC #12 is designed to exclude. The CAMB `make_params` builder pins `set_matter_power(hubble_units=False, k_hunit=False)` so `P(k,z)` comes out in CCL's native `1/Mpc` / `Mpc³`; Path B applies **no `·h` / `/h³` conversion** (applying one double-counts an `h³` amplitude error). Before constructing `ccl.Pk2D`, arrange both axes ascending: `lk = log(k)` ascending, scale factor `a` ascending (CAMB returns `z` ascending → reverse). θ passed to `ccl.correlation` in degrees (`theta_arcmin / 60`), `type="GG+"` / `"GG-"`. + +**Fixture.** A single Gaussian source bin, `n(z) ∝ exp(−½((z−0.7)/0.2)²)` on `z ∈ [0.01, 3.0]`, trapezoid-normalised; θ grid `np.geomspace(5.0, 250.0, 12)` arcmin. Deterministic, self-contained — no catalogue. + +Criteria (test at `src/sp_validation/tests/test_camb_ccl_crosscheck.py`): + +10. **σ8/A_s reconciliation.** Against `σ8_target = 0.80`: (a) a nominal `A_s = 2.1e-9` leaves CAMB's σ8 offset by `abs(σ8_nominal/σ8_target − 1) > 0.02` (observed ≈0.03 — the convention offset is real); (b) the closed-form rescale lands CAMB's σ8 on target to `< 1e-4` (checks CAMB linear-σ8 reproducibility; the rescale is exact). +11. **ξ± agreement at the fiducial.** Path A and Path B agree within `XIP_RTOL = 0.005` (ξ+) and `XIM_RTOL = 0.010` (ξ−) over the 12-point θ grid. **ξ− caveat:** ξ− crosses zero on this grid; the relative assertion applies only where `|ξ−| > XIM_FLOOR` (absolute floor from the fixture's peak |ξ−|), with an absolute-agreement assertion elsewhere. ξ+ is finite and positive; ξ− is not sign-definite. +12. **ξ± agreement off the fiducial.** The same tolerances hold at a representative in-envelope offset — `from_overrides({"S8": 0.80 + 0.075, "Omega_m": 0.30 − 0.05})`, a point inside the (`|ΔS8| ≤ 0.075`, `|ΔΩm| ≤ 0.1`) envelope, not its edge — so the *shift* — a difference of two theory vectors — does not inherit a stack-disagreement bias. +13. **halofit token match.** The blinding backend's `ccl_halofit_version` equals the inference config's; a test asserts it directly against the inference config value. All three blinding backends share one recipe by construction and would agree with each other while jointly diverging from the inference stack (mead2020 vs mead2020_feedback is a several-percent trap), so this cannot be caught by AC #3 and is asserted independently here. +14. **Fast smoke variant.** A non-`slow` test runs both paths at coarse resolution (few θ, reduced ℓ grid) and asserts finite, positive, few-percent-agreeing ξ+ plus a σ8-matched `A_s` in `(1e-9, 3e-9)` — broken wiring caught in the fast suite. The precision assertions (AC #11, #12) carry `@pytest.mark.slow`. + +*Context (informational, not a tolerance): on the shared-venv build the observed agreement floor is ξ+ ≈ 0.21% / ξ− ≈ 0.10% — headroom against the 0.5%/1.0% tolerances above, measured once; version bumps move it and that is not a regression.* + +The full suite passes inside the container (`pytest src/sp_validation/tests/`), and CI runs it in the freshly built image before publish. + +## Non-goals + +- **No theory-backend refactor of Smokescreen.** The `theory_fn` protocol and the CCL-native draw live in the fork and are a precondition, not part of this PR. +- **No independent Limber/FFTLog validation.** Both cross-check paths project through CCL; a common projection bug cancels and is out of scope. The cross-check validates the P(k) recipe and amplitude convention only. +- **No Snakemake wiring.** Integrating the blind step into the pipeline DAG is deferred; this PR delivers the step and its CLIs. +- **No covariance blinding.** Blinding hides the vector, not the uncertainty; covariances never change. +- **No unblinding-criteria policy.** Which tests must pass at what thresholds before unblinding is a team-process decision, not code. +- **No change to the fiducial-cosmology group decision.** The `TheoryConfig` defaults mirror the CosmoSIS v1.4.6.3 fiducial; a later named group choice changes config values, not code. diff --git a/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/ripple-analysis.md b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/ripple-analysis.md new file mode 100644 index 00000000..0aa6700e --- /dev/null +++ b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/ripple-analysis.md @@ -0,0 +1,105 @@ +# Ripple analysis: how the fork ruling changes PRD #241 + +The ruling forks Smokescreen to `UNIONS-WL/Smokescreen`, gives it a `theory_fn` protocol with a shipped default CCL backend, and sidelines firecrown to an inherited, lazy-imported, unsupported path (never installed by us). This document states, per PRD §7 row and per existing draft PR, what survives, what changes, what is deleted, and what is new. Fork changes are prefixed **PR 0.1**; sp_validation-side rows keep the PRD's numbering. + +Draft-PR numbers below (#243, #245, #249, #250, #251, #253, #255) refer to the *existing draft PRs* against the old PRD; they are PR references, not the issue numbers the board will assign. New board issues are unnumbered here (nothing is posted yet) — see the issue-tree draft. **Draft-PR numbers are not sequential with PRD rows:** row 4 (migration) = #251, row 5 (cross-check) = #250 — the two are inverted. This matters for `Closes #N` wiring; read the number, not the position. + +**This document is retrospective — it is allowed to describe the delta.** But it directly seeds the per-PR PRDs, which must assume *nothing* about the journey. So each PR section below separates the **end-state spec** (what the PRD author lifts) from the **delta rationale** (why it changed — context only, never transcribed into a PRD). Delta language ("becomes", "dissolves", "no longer a workaround") lives only in the rationale blocks. + +## Top line + +- **New work, first in the stack:** PR 0.1 — fork Smokescreen to UNIONS-WL, give it a theory-callable protocol plus a shipped default CCL backend, and a fixed pure draw. Firecrown is not deleted: it stays as an inherited, lazy-imported, unsupported path — never imported at module level, never declared, not installed, tested, or maintained by us (no CI job, no patch script, no numpy ceiling). sp_validation never installs it. +- **The blinding dependency simplifies, but not by "transitive inheritance."** Stock Smokescreen `import`s both `pyccl` (`datavector.py:29`) and `firecrown` (`datavector.py:31`) at module level yet declares *neither* in `Requires-Dist` (verified: `smokescreen-1.5.6` METADATA declares astropy, cryptography, jsonargparse, numpy≥2.2, sacc≥0.12, scipy — no pyccl, no firecrown; DESC assumes conda-forge). So neither dep "arrives transitively" today. **PR 0.1's packaging job is to fix this**: the fork *declares and uses* `pyccl` (its default CCL backend imports it) and makes the firecrown import lazy so a clean install never needs firecrown. After PR 0.1, `cryptography` and `sacc>=0.12` arrive from the fork's `Requires-Dist` (both already declared) and `pyccl` arrives because the fork now declares it — but only because PR 0.1 rewrites the packaging. This is a **precondition, not an inheritance**: the "do not re-pin" instruction in the sp_validation deps PR is only sound *after* PR 0.1 has been verified to preserve cryptography/sacc and add pyccl in the fork's `pyproject`. +- **Everything the SACC layout contract touches is untouched by the ruling** — PRs 2, 3, 4, 7 do not care where theory comes from. +- **The firecrown likelihood (row 5) is deleted;** its CAMB↔CCL cross-check is demoted to a test inside the blinding PR (row 6), not a standalone PR. +- **The blinding PR (row 6) is reworked** onto the fork's protocol: our draw becomes a fixed CCL-native draw in the fork, the direct-CCL fine/Cℓ paths become theory backends, and the `systm_dict` IA-pin bug vanishes with firecrown. + +## Ordering constraint (load-bearing) + +Stock Smokescreen — even freshly forked, before PR 0.1's backend refactor — still `import pyccl` (`datavector.py:29`) and `import firecrown` (`datavector.py:31`) at module level and `ImportError`s on any clean install lacking them. A fork install is therefore **unusable until PR 0.1 makes the firecrown import lazy and declares pyccl.** Consequence for the board: the sp_validation deps PR (row 1) cannot pin a fork SHA prior to PR 0.1's firecrown-lazy-import + packaging commits, or it transitively drags firecrown back in. "sp_validation never installs firecrown" is the *end state after PR 0.1*, not a property of the mere fork. + +## Row-by-row + +| PRD §7 | Old draft PR | Under the fork | Change class | +|---|---|---|---| +| — | — | **PR 0.1** fork + `theory_fn` protocol + default CCL backend + lazy firecrown (`UNIONS-WL/Smokescreen`) | **NEW** | +| 1 — dependencies | #243 | Drop firecrown, `--no-deps` closure, `patch_firecrown.py`, numpy<2.5 ceiling entirely. Raise Python floor `>=3.11` → `>=3.12` (from Smokescreen itself). Blinding deps go CORE: pinned `git+https` fork URL + `pyccl` (already core) + `cryptography`; sacc is core. No `[blinding]` extra. | **SIMPLIFIED** | +| 2 — `sacc_io` writers | #245 | Untouched. SACC layout contract is theory-agnostic. | **AS-IS** | +| 3 — converters | #249 | Untouched. | **AS-IS** | +| 4 — cosmo_val migration | #251 | Untouched. | **AS-IS** | +| 5 — firecrown likelihood + CAMB↔CCL | #250 | Firecrown likelihood **deleted**. CAMB↔CCL cross-check demoted to a test folded into the blinding PR (row 6) — no standalone PR. | **RETIRED (deliverable struck; cross-check folded into row 6)** | +| 6 — Smokescreen blinding | #253 | Reworked onto the fork protocol: our draw → fork's fixed CCL-native draw; three shift paths → three sp_validation `theory_fn` backends (overriding the fork's default CCL backend); `systm_dict` IA-pin bug gone (our path is a plain CCL callable, never firecrown's defaults overlay); CAMB↔CCL cross-check folded in as a test. Custody scheme unchanged. | **REWORKED** | +| 7 — native SACC likelihood | #255 | Untouched (CosmoSIS-side, never involved firecrown). | **AS-IS** | + +## What each PR becomes + +### PR 0.1 — Fork and adapt Smokescreen (NEW, first) +Repo: `UNIONS-WL/Smokescreen`. This is the highest-risk PR in the stack and is **decomposed now**, not conditionally: it bundles a protocol-plus-default-backend-plus-draw refactor, firecrown lazy-import sidelining with fork-test migration, and packaging/CI/docs — the packaging part is the board's critical-path unblock for sp_validation. The decomposition below is the plan, filed as sub-issues under `ISSUE-FORK`. + +**End-state spec (what the fork exposes):** +- **Theory-backend protocol + default CCL backend.** `theory_fn(cosmo_params) -> np.ndarray` aligned to the SACC rows is the theory entry point; any callable satisfies it (e.g. a ΔΣ emulator). The fork ships a **built-in default CCL backend** so a standard cosmic-shear SACC file blinds out of the box, and power users override with their own callable. `import smokescreen` imports no theory backend — pyccl is imported inside the default-backend module at construction, firecrown only along its lazy path. +- **Firecrown lazy, not deleted.** The firecrown integration is retained from upstream but made optional and lazy: no module-level firecrown import, and it is not installed, tested, supported, or maintained by us — no firecrown-defaults overlay on the default path, no patch script, no numpy ceiling. Docs mark it inherited-and-unsupported. +- **Fixed pure draw.** The shift draw uses a local `default_rng` (order-independent, no global seed) and speaks CCL-native parameter names (e.g. `sigma8`, `Omega_c`). No injectable `draw_fn` abstraction — arbitrary-parameter-space indirection is deferred. The uniform amplitude envelope is calibrated to an equivalent S8 amplitude on the sp_validation side. +- **Declared packaging.** The fork's `pyproject` declares `pyccl` (used by the default CCL backend) alongside the inherited `cryptography`/`sacc>=0.12`. Install identity is a pinned git tag/SHA — no rename, no PyPI publish (see below). +- **Fork CI** runs a backend smoke-test (`import smokescreen` + a synthetic-callable blind) as the required gate. +- **Fork docs** document the pip-only install path: `pip install git+https://github.com/UNIONS-WL/Smokescreen@` — no conda, no PyPI — and note the firecrown path is inherited-and-unsupported. README/docs updated to match. + +**Decomposition (two sub-PRs under ISSUE-FORK):** +1. **Protocol + default CCL backend + draw refactor + firecrown sidelining + fork-test migration** — `datavector.py` / `param_shifts.py` / a new backend module: introduce the `theory_fn` protocol and the default CCL backend replacing the module-level firecrown import (`:31`) and the `ParamsMap`-through-likelihood path in `calculate_concealing_factor`; make the firecrown import lazy (retain the path, sideline it); fix the draw (local `default_rng`, order-independent, CCL-native names); migrate DESC's test suite (which assumes module-level firecrown) onto the synthetic/CCL backends. The draw fix folds in here — with the injectable abstraction dropped it is a small change coupled to the same `datavector` rewrite, not a standalone concern. +2. **Packaging + install identity + CI + docs** — settle install identity as a pinned `git+https` tag/SHA (no rename, no PyPI); declare `pyccl`; re-point fork CI; write the pip-only install docs (firecrown noted inherited-and-unsupported). **This sub-PR unblocks sp_validation's deps PR and should not wait on review of the large protocol refactor** — it is why the decomposition exists. + +*Delta rationale (context only, not for the PRD):* today `datavector.py:31` imports firecrown at module level and `calculate_concealing_factor` pushes a firecrown `ParamsMap` through the likelihood; the protocol makes the paper's "only needs a module conforming to the firecrown interface" claim true in its general reading. The global-seed/`cosmo.to_dict()`-order draw is why PR #253 drew its own hidden cosmology as a workaround — that workaround dissolves into the fork. The drafts previously coined "unions-smokescreen"; that name presumed a PyPI publish the ruling did not mandate — the ruling settles identity as a pinned git tag/SHA. Long-term, Cail will talk to Arthur (upstream maintainer) about PRing changes back, so the fork diff is kept small and clean to preserve upstream-PR-ability — which is why firecrown is sidelined lazily rather than amputated: a smaller diff that does not antagonize the maintainer by ripping out his integration. + +### PR 1 (#243) — Dependencies (SIMPLIFIED) +**End-state spec:** +- Blinding deps are **core**, not an extra: the pinned `git+https://github.com/UNIONS-WL/Smokescreen@` fork URL, `pyccl` (already core), and `cryptography`. `sacc>=0.12` is promoted to a top-level dep (it is not one today). There is no `[blinding]` extra. Do not re-pin `cryptography`/`sacc` in sp_validation *provided PR 0.1's fork `pyproject` is verified to keep them in `Requires-Dist`* — they then arrive from the fork. +- Python floor raised `>=3.11` → `>=3.12` (Smokescreen's own `requires-python`). **Verify against the actual Dockerfile `FROM` line** — the api-facts fiber records the base as `python:3.12-slim-bookworm` (shapepipe:develop), so the floor aligns with the existing base and no base-image change is needed; confirm the tag before asserting it in the PR. +- No numpy ceiling anywhere; the compiled stack is unconstrained. + +*Delta rationale (context only):* deleted from the old PR — firecrown git-tag pin, `--no-deps` install + explicit runtime closure, `scripts/patch_firecrown.py` (deleted outright, not migrated — sp_validation never installs firecrown, and the fork's inherited firecrown path is lazy and needs no patching), the `numpy<2.5` ceiling and its CI guard, the firecrown/numcosmo import smoke-test, and the `[blinding]` extra itself (blinding deps promoted to core). + +**Container ripple.** The install source moves from `smokescreen 1.5.6` (PyPI) to the pinned fork URL — a Dockerfile + `uv.lock` change. The deploy workflow (`.github/workflows/deploy-image.yml`) builds and runs the test suite inside the freshly built image before publish, so the fork install is exercised there — the container/`uv.lock` change lands *with* this PR. **This PR cannot pin a fork SHA earlier than PR 0.1's firecrown-lazy-import + packaging commits** (see ordering constraint above). + +### PR 2 (#245) — `sacc_io` writers (AS-IS) +No change. The two-file layout amendment (`{version}.sacc` + `{version}_xi_fine.sacc`), custom ρ/τ/pure-EB types, insertion-order covariance assembly all stand. + +### PR 3 (#249) — Converters (AS-IS) +No change. SACC→2pt-FITS byte-compare and SACC↔OneCovariance glue are unaffected by the theory backend. + +### PR 4 (#251) — cosmo_val migration (AS-IS) +No change. Writers-to-SACC and Snakemake part-assembly are format work. + +### PR 5 (#250) — firecrown likelihood + CAMB↔CCL (RETIRED as a PR) +This row is retired as a standalone PR. The minimal firecrown likelihood is deleted outright — nothing in the required path builds one. The CAMB↔CCL cross-check it carried never needed firecrown and moves into the blinding PR (row 6) as a test — see that section for its spec. There is no PR #250 successor in the plan. + +*Delta rationale (context only):* the cross-check was demoted from its own PRD to a test folded into blinding because it is a theory-consistency guard on the same CCL backend the blinding PR introduces, not an independent deliverable. `prd-camb-ccl-crosscheck.md` is retired. + +### PR 6 (#253) — Smokescreen blinding (REWORKED) +**End-state spec (kept from the landed design):** +- Custody = §4(b): OS-entropy seed → blind → publish sha256(seed) + config digest → encrypt seed+truths (`smokescreen.encryption`, no firecrown dep) → strip `seed_smokescreen`, stamp `concealed=True` + blind label. Unblind verifies hash before subtracting. +- Derived stats re-derived, never shifted (COSEBIs, pure-E/B re-run through pipeline estimators on blinded ξ±); covariances never change. +- Two-tracer direct paths; commitment binds (seed, config); pure-EB seam follows the pipeline's edge-based bounds. + +**End-state spec (on the fork protocol):** +- The amplitude-shift envelope is expressed through the fork's fixed CCL-native draw (order-independent, local `default_rng`), calibrated on the sp_validation side to an equivalent S8 amplitude. +- Three theory backends through one `ConcealDataVector` call: coarse ξ±, fine-grid ξ±, pseudo-Cℓ (W @ ΔCℓ_EE), each a `theory_fn` callable supplied by this PR (overriding the fork's built-in default CCL backend, which does not know the master layout or IA config). +- Cross-backend consistency: the same hidden cosmology through two theory callables agrees to machine precision (~1e-10). +- **CAMB↔CCL cross-check (folded-in test):** a theory-consistency test — same cosmology, same n(z), ξ± on our θ grid within tolerance. It must settle the σ8-for-CCL vs A_s-for-CAMB amplitude convention (σ8-matching is load-bearing: nominal A_s leaves σ8 ~3% off and blows the comparison to ~9–10% — verified, api-facts PR-5 facts), and `halofit_version` strings must match on both stacks (mead2020 vs mead2020_feedback differ several % at k≳1). Observed floor on the single-bin synthetic fixture: ξ+ 0.21% / ξ− 0.10% against 0.5%/1.0% tolerances. +- Acceptance: B-mode estimators unchanged under blinding on mocks — unchanged to the estimator's numerical floor. **TODO for the blinding-PRD author (do not lift this line verbatim):** the ΔBₙ/Bₙ figure is a hole the PRD must fill — cite it from the run that produces it, or state the criterion qualitatively; never carry an unsourced number. The acceptance criterion is not "implementable cold" until this is resolved. +- Acceptance: the fork blinds a real sp_validation `sacc_io` file end-to-end (integration line). + +*Delta rationale (context only):* our `draw_hidden_cosmology(seed, config)` is no longer a private sp_validation workaround around Smokescreen's replace-not-add global-seed semantics. The direct-CCL fine/Cℓ code stops being a *bypass* of the likelihood and becomes a first-class backend — the "fine grid can't pass through firecrown's ConstGaussian densification" constraint dissolves. The `systm_dict` IA-pin bug (firecrown's `modify_default_params` overlaying un-overridden defaults — IA amplitude riding at 0.5 vs our 0.0, a ~7% low-θ divergence per api-facts) is gone from our path: firecrown is off the default flow (lazy, unsupported, never on our blinding path), and our `theory_fn` backends are plain CCL callables that compute exactly our fiducial; the regression guard is unneeded. The CAMB↔CCL cross-check folds in here because it guards the same CCL backend this PR introduces. + +### PR 7 (#255) — Native SACC likelihood (AS-IS) +No change. CosmoSIS-side `SaccLikeUnions(SaccClLikelihood)` shim, χ² equality with the PR-3 converter path. Never involved firecrown. + +## Net delta + +- **+1 repo** in the effort: `UNIONS-WL/Smokescreen`. Adding it to the board README and getting a `UNIONS-WL/Smokescreen` issue onto `UNIONS-WL/projects/1` is itself work — filed as an explicit precursor (see issue-tree). +- **+1 PR** (0.1) on the fork, **decomposed into two sub-PRs** (protocol+draw+firecrown-sidelining+fork-tests / packaging+CI+docs). +- **-1 deliverable:** the firecrown likelihood. +- **-1 PR:** the standalone CAMB↔CCL cross-check PR (#250) is retired; the cross-check survives as a test folded into the blinding PR. +- **1 PR reworked** (6), **1 PR simplified** (1); **4 PRs unchanged** (2, 3, 4, 7). +- **Deleted from sp_validation:** the firecrown likelihood module, the numpy ceiling, the firecrown `--no-deps` closure, `patch_firecrown.py`, the `systm_dict` IA-pin and its regression guard, the `[blinding]` extra (blinding deps promoted to core). +- **Sidelined in the fork (not deleted):** firecrown becomes lazy-imported, inherited, and unsupported — no module-level import, no CI job, no numpy ceiling, no patch script. **Added to the fork:** a built-in default CCL backend (pyccl declared and used). +- **New in sp_validation deps (core):** the pinned `git+https` fork URL, `cryptography`, and `sacc>=0.12` (promoted to top-level), alongside the pre-existing `pyccl`. diff --git a/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/fork-implementation/fork-implementation.md b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/fork-implementation/fork-implementation.md new file mode 100644 index 00000000..b7462235 --- /dev/null +++ b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/fork-implementation/fork-implementation.md @@ -0,0 +1,63 @@ +--- +id: 01KX6YH5ZYRQRN1Y7CZA7VR9DE +name: Execute the Smokescreen-fork replan (fork, 2 fork PRs, sp_validation PR rework, board wiring) +status: active +tags: + - constitution + - sp-validation + - sacc + - blinding +created-at: 2026-07-10T23:21:56.734989469+02:00 +updated-at: 2026-07-11T11:58:35.83088803+02:00 +outcome: 'In progress: fork PRs #4 (protocol, reviewed+fixed, 64/64) & #5 (packaging, stacked) open; #241 rewritten state-shaped; #243 reworked and CI-green (0 confirmed review findings); #253 reworked (7 confirmed findings being fixed; CI red pending stack onto #243''s branch for the fork pin).' +shuttle: + kind: oneshot + host: candide + project_dir: /automnt/n17data/cdaley/unions/code/sp_validation + agent: claude-fable + runtime: + dispatched_at: "2026-07-10T21:24:03.631335Z" + session_uuid: 27f88a84-70fa-4418-8d60-074954811780 + effort: low +--- + +Executes the Smokescreen-fork replan ruled with Cail on 2026-07-10 (parent fiber [[sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan]]). The plan is fully drafted and human-approved: the parent's `grounding.md` carries the rulings (pass-2 and pass-3 amendment sections override where they conflict with earlier text), and `drafts/` carries the reviewed specs — `ripple-analysis.md` + `issue-tree.md` (the plan) and eight live PRDs (the per-PR contracts; two more carry RETIRED banners and are historical). Those documents are the contract for this work — cite them, don't re-derive them. The upstream context: sp_validation's blinding stack (PRD sp_validation#241, seven existing draft PRs) currently depends on firecrown, which is uninstallable-by-pip pain; the replan forks DESC's Smokescreen to `UNIONS-WL/Smokescreen`, makes theory pluggable (shipped CCL default backend + bring-your-own `theory_fn`; firecrown retained lazy/undeclared/unsupported), and strips firecrown from sp_validation entirely. + +## Desired State + +**GitHub structure (per `drafts/issue-tree.md`):** +- `LSSTDESC/Smokescreen` is forked to `UNIONS-WL/Smokescreen` (org fork, `gh repo fork --org UNIONS-WL`). If org-level fork creation is denied by permissions, that is a genuine block: stop and lead the outcome with "Blocked:". +- The issue tree from `drafts/issue-tree.md` exists on GitHub: umbrella + sub-issues in their stated repos, nested as sub-issues, on board `UNIONS-WL/projects/1` with Status + Work area set per the board model in `/automnt/n17data/cdaley/unions/CLAUDE.md`. A comment on sp_validation#241 states the plan amendment concisely (top-down, neutral tone — see tone rule below), citing the new issues. +- Every PR is **draft**, carries `Closes #N` to its same-repo issue, and nothing is merged — merging is Cail's gesture. + +**Fork PRs (against `UNIONS-WL/Smokescreen`, contracts in `drafts/prd-fork-protocol.md` and `drafts/prd-fork-packaging-ci.md`):** +- PROTO: theory-callable protocol (`theory_fn`), shipped default CCL backend (pyccl imported by the backend module), firecrown moved behind a lazy import (retained, undeclared, unsupported — never imported at module level), draw fixed (local `default_rng`, order-independent, CCL-native parameter names), DESC test suite migrated to the non-firecrown default. `import smokescreen` succeeds in a clean env with no firecrown. +- PKG: packaging (pyccl declared; cryptography/sacc retained; no firecrown in `Requires-Dist`), pip-only install docs (`pip install git+https://github.com/UNIONS-WL/Smokescreen@` — no conda, no PyPI), CI green on the non-firecrown path. +- Keep the diff small and upstream-PR-able: Cail may later PR this against DESC upstream. GitHub-facing text stays **neutral about firecrown** — no editorializing (collaboration relations). + +**sp_validation PRs (contracts in `drafts/prd-dependencies.md`, `drafts/prd-smokescreen-blinding.md`, plus `ripple-analysis.md` rows):** +- The deps PR (#243) is reworked per prd-dependencies: firecrown/`--no-deps` closure/`patch_firecrown.py`/numpy<2.5 ceiling all gone; blinding deps CORE (no `[blinding]` extra) — fork pinned by git tag/SHA (only after the fork's lazy-import + packaging commits exist), pyccl, cryptography, sacc promoted to top-level; py3.12 floor (a raise from 3.11); container/`uv.lock` ripple included. +- The blinding PR (#253) is reworked per prd-smokescreen-blinding: all three shift paths (coarse ξ±, fine ξ±, pseudo-Cℓ) through the fork protocol; the CAMB↔CCL cross-check folded in as tests (σ8-matched, halofit strings matched); `_verify_sacc_consistency` semantics per the protocol PRD (length guard); custody scheme unchanged from the landed design. +- #250's firecrown likelihood deliverable is struck per the ripple analysis (the PR is retitled/reworked or closed-with-comment, whichever the issue tree specifies). +- PRs #245, #249, #251, #255 are NOT touched — Cail is reviewing them as-is. + +**Quality bar:** each PR's test suite passes in CI; scientific-stack tests run in the container per repo conventions; a fresh-eyes adversarial review of each substantive diff against its PRD before the session that produced it closes. Never run heavy compute on the candide login node — allocate SLURM first and pass the `srun --jobid` prefix to any delegated runner (see `/automnt/n17data/cdaley/unions/CLAUDE.md`). + +**Not doing:** merging anything; posting opinions about firecrown/DESC; touching PRs #245/#249/#251/#255; PyPI publishing; upstream (LSSTDESC) PRs. + +## Status + +Not started. First moves: fork the repo, post the issue tree, then PROTO — the deps PR rework is gated on the fork's packaging commits existing. + +## PROTO implementation (Smokescreen#2, branch feat/theory-backend-protocol) + +**Done — draft PR https://github.com/UNIONS-WL/Smokescreen/pull/4 (Closes #2), branch feat/theory-backend-protocol, full suite 57 passed / 0 failed / 0 skipped.** Commits: 9d02f52 (protocol refactor), 76ded3f (inherited firecrown module), d00c7a7 (test migration), 8b80bf2 (backend-convention docstrings). + +Implemented per `drafts/prd-fork-protocol.md`. Landed shape: `ConcealDataVector(fiducial_params, shifts_dict, sacc_data, *, seed, theory_fn=None, shift_distr)`; both theory vectors from `theory_fn`; default backend `smokescreen/backends/ccl.py::build_ccl_theory_fn` (the sole `import pyccl` in src, so `import smokescreen` imports no backend); pure `param_shifts.draw_param_shifts` (sorted keys, one `default_rng` scalar draw per key, deltas, SHA-256 string→seed); length guard only, no `_verify_sacc_consistency`. Inherited firecrown path kept as `firecrown_datavector.FirecrownConcealDataVector` (lazy, unsupported, not wired in). + +**Ambiguity resolutions (for the PR reviewer to check):** +- *"firecrown retained lazily in-tree"*: **team-lead ruled my first take (delete the path, keep only examples/) NOT accepted** — the retention requirement is for upstream relations (a later DESC PR must not read as amputating firecrown). Resolved per ruling: the pre-refactor firecrown-likelihood class is preserved as `FirecrownConcealDataVector` in a new `src/smokescreen/firecrown_datavector.py`, all firecrown/pyccl imports function-local (via `_import_firecrown()` + local imports), module docstring marks it inherited-upstream/unsupported, not wired into the default flow (no main module imports it), no fork test exercises it. `examples/` also untouched. Grep confirms zero module-scope `firecrown`/`numcosmo` in `src/`; `import smokescreen` does not import the module; importing the module with no firecrown installed succeeds and imports no firecrown. Commit 76ded3f. +- *Default backend transfer function*: used pyccl-native `eisenstein_hu` + `halofit` (set inside the backend, overridable by cosmo_params) so the shipped backend runs against a bare pyccl install — the venv has no CAMB/CLASS. A caller's own `theory_fn` may route through a Boltzmann code. +- *Seed normalization*: added `param_shifts._normalize_seed` (SHA-256 → 64-bit int) per the PRD's explicit spec rather than reusing `utils.string_to_seed` (MD5 % 1e8) — they differ, and the PRD names SHA-256. `string_to_seed` left in utils untouched (used nowhere on the new path; kept for any inherited caller). +- *ξ± angle units*: the SACC `theta` tag is assumed to be **arcmin** and converted to degrees for `ccl.correlation`. Standard-cosmic-shear SACCs carry arcmin; a backend fed degrees would be off. Recorded because the default backend's row→theory alignment is its own contract, unchecked by Smokescreen. +- *No `_verify_sacc_consistency`*: dropped, not re-expressed (deliberate, non-behavior-preserving per PRD §Consistency check). Sole guard is the construction-time length check. diff --git a/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/grounding.md b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/grounding.md new file mode 100644 index 00000000..5ca3a7fb --- /dev/null +++ b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/grounding.md @@ -0,0 +1,54 @@ +# Grounding for the Smokescreen-fork PRD replan (2026-07-10) + +Audience: workflow agents drafting the replan documents. Everything here is settled with Cail today; do not relitigate it. Verify code claims against source where paths are given. + +## The ruling + +1. **Fork Smokescreen to the `UNIONS-WL` GitHub org** (community-facing, not personal). No PR against DESC upstream; PRs go against our fork. Rationale: keep Smokescreen as the community-trusted, community-maintained blinding object (grad students, CosmoStat group, cosmo pipe users — not just sp_validation), while removing what we can't live with. +2. **Drop firecrown entirely** from the required path — it is deleted from the PRD, not demoted. No `--no-deps` install, no `patch_firecrown.py`, no numpy<2.5 ceiling. Firecrown may remain as an optional lazy-import adapter in the fork, but we never install it. +3. **PR 0.1 (new, first): make Smokescreen backend-independent** in the fork: + - Theory backend protocol: `theory_fn(cosmo_params) -> np.ndarray` aligned to the SACC rows. Firecrown becomes one optional adapter behind lazy imports. This makes the Smokescreen paper's "only needs a module conforming to the firecrown interface" claim actually true in its general reading (today `datavector.py:31` imports firecrown at module level and `calculate_concealing_factor` pushes firecrown `ParamsMap` through the likelihood). + - Injectable, pure shift draw: replace the global `np.random.seed` + `cosmo.to_dict()`-order-dependent draw in `param_shifts.py` with a local `default_rng`, order-independent, injectable `draw_fn(seed) -> cosmology params` that supports arbitrary parameter spaces — so the PRD's uniform (S8, Ωm) box is expressible natively (S8/Ωm are not CCL params; that inexpressibility is why PR #253 drew its own hidden cosmology as a workaround — that workaround dissolves into the fork). + - Motivating probe requirement: blinding must work for ANY data vector, e.g. a ΔΣ vector whose theory comes from an emulator — any callable satisfies the protocol. +4. **Blinding stays an optional extra dependency-wise** but the extra shrinks to roughly `smokescreen-fork + pyccl + cryptography` (sacc is core). + +## What the fork inherits from the PR #253 design (keep) + +- Custody scheme unchanged: OS-entropy seed → blind → publish sha256 commitment (+ config digest) → encrypt seed + truths (`smokescreen.encryption`, no firecrown dep) → strip `seed_smokescreen`, stamp `concealed=True` + blind label. Unblind verifies hash before subtracting. +- Derived statistics re-derived, never shifted (COSEBIs, pure-E/B re-run through pipeline estimators on blinded ξ±); covariances never change. +- Cross-path/backend consistency tests (previously Smokescreen-vs-direct at 1e-10) become backend-vs-backend tests. +- The three shift paths (coarse ξ± / fine ξ± / pseudo-Cℓ = W @ ΔCℓ_EE) unify: all through `ConcealDataVector`, three theory callables. The fine-grid and pseudo-Cℓ direct-CCL code from PR #253 becomes backends instead of bypasses. + +## State of the world + +- PRD #241 text: `prd241.md` (this directory); comments: `prd241-comments.md`. +- Seven draft PRs exist implementing the OLD PRD: #243 deps, #245 sacc_io, #249 converters, #250 firecrown likelihood + CAMB↔CCL cross-check, #251 cosmo_val migration, #253 blinding, #255 (see repo). PRs 2/3/4 (#245/#249/#251) are expected untouched by the replan — the SACC layout contract doesn't care where theory comes from. #243 simplifies (drop firecrown/patch/numpy ceiling; keep py3.12 floor — that comes from Smokescreen itself). #250's firecrown likelihood is deleted; its CAMB↔CCL cross-check survives (never needed firecrown). #253 restructures around backends and loses `draw_hidden_cosmology` as a private function (moves into the fork). The `systm_dict` IA-pin (firecrown defaults overlay bug) vanishes with firecrown. +- Verified Smokescreen/firecrown facts (source-read + empirical): fiber `sp_validation/smokescreen-sacc-prs/smokescreen-api-facts` — file `.felt/sp_validation/smokescreen-sacc-prs/smokescreen-api-facts/smokescreen-api-facts.md`. +- PR-6 blinding architecture as landed: `.felt/sp_validation/smokescreen-sacc-prs/blinding-design/blinding-design.md`. +- SACC layout contract: `.felt/sp_validation/smokescreen-sacc-prs/sacc-layout-contract/sacc-layout-contract.md`. +- Smokescreen 1.5.6 source: installed in `/automnt/n17data/cdaley/unions/code/sp_validation-worktrees/venv` site-packages (read it there), and on PyPI/GitHub (DESC `LSSTDESC/Smokescreen`). + +## Pass-2 amendments (Cail, 2026-07-10 evening — these OVERRIDE anything above or in the pass-1 drafts that conflicts) + +1. **Firecrown has ZERO presence — not even an optional adapter.** The fork deletes the firecrown path outright: no lazy adapter, no `patch_firecrown.py` anywhere (fork or sp_validation), no guarded firecrown CI job, no numpy<2.5 ceiling anywhere. Any pass-1 text about a "retained-but-guarded adapter" is void. Tone rule for anything that will ever be GitHub-facing: neutral about firecrown, no editorializing. +2. **Fork docs are a first-class deliverable:** document the pip-only install path — `pip install git+https://github.com/UNIONS-WL/Smokescreen@` — no conda, no PyPI publish (for now). README/docs updated accordingly. +3. **Draw: native pyccl parameters, no injectable-draw_fn abstraction.** Fix the real bugs (local `default_rng`, order-independent draw, no global `np.random.seed`) but the shift specification speaks CCL-native parameter names (e.g. sigma8, Omega_c) with an envelope we calibrate to equivalent S8 amplitude on the sp_validation side. Arbitrary-parameter-space indirection is explicitly deferred ("maybe later something more fancy"). This shrinks fork sub-PR (a); the drafting agents may re-decide the sub-PR decomposition (e.g. fold the draw bugfix into the protocol PR) if that is now cleaner. +4. **No blinding extra — blinding deps go CORE.** With firecrown gone the extra is just the fork + cryptography (pyccl is already core; sacc becomes core in PR 2). Delete the `[blinding]` extra; core deps include the pinned `git+https` fork URL. Keep the py3.12 floor. +5. **Install identity: pinned git tag/SHA, settled — no rename, no PyPI.** Long-term Cail will talk to Arthur (upstream maintainer) about migrating changes back / PRing upstream; keep the fork diff small and clean to preserve upstream-PR-ability. +6. **CAMB↔CCL cross-check is demoted from its own PR to a test**: fold it into the blinding PR's test suite (or an issue), not a standalone PRD. `prd-camb-ccl-crosscheck.md` is retired as a PRD; its verified technical content (σ8-matching load-bearing, halofit_version string match, observed 0.21%/0.10% floor, 0.5%/1.0% tolerances) moves into the blinding PRD's test section. +7. **Delete the cross-repo sacc-pin compatibility section** — it was a firecrown-only concern; Smokescreen itself requires sacc>=0.12 and we run 2.4. (An end-to-end "fork blinds a real sp_validation SACC file" integration test is still welcome as a blinding-PR acceptance line.) +8. PRs 2/3/4/7 confirmed untouched — do not edit their PRDs except where they reference the deleted extra or firecrown. + +## Pass-3 amendments (Cail, 2026-07-10 late — these OVERRIDE pass-2 items 1 and the "fork imports no theory backend" ruling where they conflict) + +1. **Firecrown code is NOT deleted from the fork.** It stays as an *optional, lazy-imported* path — never imported at module level, never declared as a dependency, **not installed, not tested, not supported, not maintained by us** (no CI job, no patch script, no numpy ceiling in our packaging — those were only ever consequences of installing it). Docs say plainly: the firecrown path is inherited from upstream and unsupported in this fork. Rationale: smaller, merge-able-upstream diff; don't antagonize the upstream maintainer by amputating his integration. sp_validation still never installs firecrown (unchanged). +2. **The fork SHIPS a default CCL theory backend.** pyccl is a declared dependency *and used*: a built-in backend so a casual user can blind a standard cosmic-shear SACC file out of the box without writing a theory callable; power users override with their own `theory_fn` (e.g. ΔΣ emulator). Pass-2's "fork imports no theory backend at all" is void; lazy-import discipline applies to firecrown only. The "maximally minimal import" acceptance criteria (greps asserting no pyccl import) must be replaced accordingly. +3. Everything else from pass 2 stands (native-CCL draw semantics, no extra / deps core, pinned git identity, pip-only docs, crosscheck folded into blinding, PRs 2/3/4/7 untouched). + +## Deliverables Cail wants (markdown drafts only — NOTHING is posted to GitHub) + +1. **Ripple analysis**: how the ruling changes PRD #241 — row by row, PR by PR (which PRs survive as-is, which change how, what's deleted, what's new). +2. **Issue-tree proposal**: a new umbrella issue for the Smokescreen/blinding stream; sub-issue "fork and adapt Smokescreen"; PRs attached per issue (board model: issues nest, PRs ride Development links, same-repo `Closes #N`). Name each issue, its repo (sp_validation vs the UNIONS-WL/Smokescreen fork — note cross-repo nesting is allowed), and which PRs attach. +3. **One PRD per planned PR**, including PR 0.1 (fork + backend independence). Style contract: concise, top-down, high quality, assumes NOTHING about the journey (no references to old PR numbers as context, no "previously we…"; a fresh senior engineer must be able to implement from it alone). State the desired end state, the interfaces, the acceptance criteria. + +Quality bar: several adversarial review rounds; final gate per document is a low-effort fable review for concision/top-down-ness. diff --git a/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/prd241-comments.md b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/prd241-comments.md new file mode 100644 index 00000000..d8ba5c2b --- /dev/null +++ b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/prd241-comments.md @@ -0,0 +1,22 @@ +--- +## comment by cailmdaley +All seven draft PRs are now open — the PRD's implementation series is complete and ready for team review. The map: + +| PRD §7 row | PR | Sub-issue | Content | +|---|---|---|---| +| 1 — dependencies | #243 | — | py3.12 floor; `sacc` core dep; `[blinding]` extra (firecrown 1.15.1 + smokescreen 1.5.6 + pyccl 3.3.4, exact pins for seed-reproducibility) | +| 2 — `sacc_io` writers | #245 | — | writers/readers for ξ±, pseudo-Cℓ, COSEBIs, pure-E/B, ρ/τ, n(z), covariance assembly; round-trip + ordering-contract tests | +| 3 — converters | #249 | #246 | SACC→2pt-FITS byte-compared against the current `cosmosis_fitting.py` output (synthetic + real SP_v1.4.6_leak_corr / glass_mock); SACC↔OneCovariance glue | +| 4 — cosmo_val migration | #251 | #247 | cosmo_val + Snakemake produce per-statistic SACC parts, assembled into the terminal `{version}.sacc` (+ `{version}_xi_fine.sacc`) | +| 5 — firecrown likelihood | #250 | #248 | firecrown likelihood over the analysis SACC + CAMB↔CCL cross-check test | +| 6 — Smokescreen blinding | #253 | #252 | blinding step with §4(b) hash-commitment custody; acceptance observed: B-mode estimators unchanged on mocks (ΔBₙ/Bₙ ~ 6.5e-6 under a ~20% E-shift) | +| 7 — native SACC likelihood | #255 | #254 | CosmoSIS `sacc_like` adopted via a unit-fixing shim, χ² equality with the PR-3 converter path observed to machine zero (synthetic + real data) | + +Notes for reviewers: + +- **The PRs stack** (each based on the branch it builds on: 2←1, 3/4/5←2, 6←5, 7←4+3). GitHub retargets automatically as the stack merges from the bottom; until then a PR's diff can include its parents' files — each body says which files are its own. +- **One PRD amendment**, flagged on the layout: two SACC files per catalogue version (`{version}.sacc` analysis vector + `{version}_xi_fine.sacc` COSEBIs/pure-EB integration input) — sacc 2.4's covariance model makes a 10000-bin fine grid + full analysis covariance in one file physically impractical (details in #245). +- **Open questions from the PRD** (custody model, shift envelope, fiducial config) are implemented on the stated defaults, clearly marked configurable — they gate discussion, not code. +- Every PR was adversarially reviewed before opening (fresh-context multi-lens review, findings verified by independent refuters); confirmed findings are documented in each PR body. + +— Claude (Fable) on behalf of Cail. diff --git a/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/prd241.md b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/prd241.md new file mode 100644 index 00000000..dbf4f8dc --- /dev/null +++ b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/prd241.md @@ -0,0 +1,136 @@ +# PRD: SACC data format + Smokescreen blinding + +*Design document for issue #234 (SACC + blinding design), under epic #232 (SACC data format + Smokescreen blinding). The work is organized as a series of PR-sized rows, tabulated in §8; each sp_validation row already carries an open draft PR — discussion first, code second — while the two fork PRs are not yet open.* + +## Summary + +For the tomographic round — the UNIONS tomographic cosmic-shear analysis, the successor to the 2D shear paper — sp_validation adopts [SACC](https://sacc.readthedocs.io) (LSST DESC's data-vector container) as the standard format for all data products, and blinds the data vector with a UNIONS fork of [Smokescreen](https://github.com/UNIONS-WL/Smokescreen) (DESC's implementation of Muir et al. 2020 data-vector blinding), adapted so that theory comes from a pluggable backend with CCL as the shipped default. + +**Decisions — treated as settled unless someone objects:** + +- Two SACC files per catalogue version hold everything: an analysis file (ξ± on the coarse grid, pseudo-Cℓ with bandpower windows, COSEBIs, n(z) tracers, covariance, ρ/τ PSF diagnostics as custom data types) and a fine-grid ξ± file for COSEBIs integration (§1). +- Smokescreen is forked to `UNIONS-WL/Smokescreen` and given a `theory_fn` protocol: any callable that maps cosmological parameters to a theory vector can drive blinding, with a built-in CCL backend as the default. The firecrown integration is inherited from upstream and unsupported in the fork, and sp_validation never installs it (§3). +- The blind shifts the measured ξ± and pseudo-Cℓ by a theory difference — hidden cosmology minus fiducial — with the hidden cosmology drawn uniformly within **±0.075 in S8 and ±0.1 in Ωm** (§4). +- COSEBIs and pure-E/B are re-derived from the blinded ξ±, never shifted directly; the covariance is never touched; only blinded files are analyzed — Smokescreen encrypts the true vector and we delete the plaintext (§4). +- Custody is a hash commitment: a script draws the seed, blinds immediately, publishes `hash(seed)`; unblinding reveals the seed and anyone can verify it against the commitment (§5). +- CosmoSIS keeps running unchanged behind a SACC→2pt-FITS converter; adopting CosmoSIS's native SACC likelihood is its own row (§8), validated against the converter (§2). +- Issue #228 (which n(z) normalization convention to adopt) closes: every consumer normalizes n(z) internally, so no convention is needed (§1). + +**Open questions for the group:** + +- The shift envelope: is ±0.075 in S8 the right size? (§4) +- The fiducial cosmology and model configuration (halofit version, IA model, neutrino treatment) — one named choice that both theory stacks implement. Implementation proceeds on reasonable defaults meanwhile; the choice changes config values, not code (§6). + +**Deferred:** unblinding criteria (drawn from #233 — the enumeration of validation tests for the tomographic round — once it stabilizes) and procedural conventions like hidden contour axes — team process, not code (§7). + +## 1. SACC as the standard format + +Today we scatter data products across TreeCorr .txt, custom FITS, .npz, and ASCII files, and hand-assemble them into a "2pt FITS" file — the format DES built for its `twopoint` library, which CosmoSIS's `2pt_like` module reads. +SACC replaces all of it: self-describing files that carry every statistic, its binning, its tracers, and its covariance, in a format the wider community (DESC, HSC) reads natively. + +Per catalogue version, two files: + +- **`{version}.sacc`** — the analysis file: ξ± on the coarse analysis grid, **pseudo-Cℓ** with their bandpower windows, **COSEBIs** E/B modes (SACC defines `galaxy_shear_cosebi_ee/bb` officially), **n(z)** as one tracer per tomographic bin named `source_0, source_1, …` (the suffix CosmoSIS's SACC reader expects), the **covariance**, and the **ρ/τ PSF diagnostics** and **pure-E/B modes** as custom data types — SACC accepts custom types, and one unified file beats a sidecar. The PSF diagnostics stay out of the blind (§4). +- **`{version}_xi_fine.sacc`** — ξ± on the fine θ grid (the binning COSEBIs integration needs). In principle coarse is a weighted rebin of fine, but the exact rebin needs per-bin pair weights, so both are measured and stored. + +Two conventions, fixed here: + +- **θ in arcminutes.** SACC stores θ unitless; we already write arcminutes everywhere. +- **n(z) needs no normalization convention.** CosmoSIS, OneCovariance, and CCL each normalize n(z) internally (verified in source) — closing #228. + +The writers live in a new `sp_validation.sacc_io` module, and the `cosmo_val` mixins call it in place of their per-statistic writers. +New products — including new mocks — are born in this format; we regenerate nothing old. + +## 2. Interfaces to other codes + +**CosmoSIS.** A SACC→2pt-FITS converter reproduces today's assembled file exactly, so the whole inference chain — including the PSF ρ/τ likelihood modules in the cosmosis-standard-library fork of Sacha Guerrini (CosmoStat, UNIONS inference) — runs untouched, and we can byte-compare the converter's output against a current file to validate it. +CosmoSIS also ships a native SACC likelihood (`likelihood/sacc/sacc_like.py`, feature-equivalent to `2pt_like`: scale cuts, data-set selection, Hartlap/Sellentin); its Cℓ path carried the HSC Y3 analysis, but its ξ± path has not carried a published analysis and is far less exercised. +So: converter first, native adoption as its own row, each path validating the other. + +**OneCovariance.** It computes covariances rather than consuming data vectors, and it knows nothing of SACC. +The interface is two small pieces of glue: our n(z) tracers → its per-bin two-column text input plus config, and its output covariance list → the SACC covariance block. + +## 3. The Smokescreen fork + +Blinding runs through **`UNIONS-WL/Smokescreen`**, a fork of DESC's Smokescreen adapted to be theory-backend independent. What the fork exposes: + +- **A theory-function protocol.** `theory_fn(cosmo_params) -> np.ndarray`, aligned element-by-element to the SACC rows being concealed, is the single theory entry point. Any callable satisfies it; alignment to the data vector is the backend's contract. +- **A built-in default CCL backend**, so a standard cosmic-shear SACC file blinds out of the box; power users override with their own callable. `import smokescreen` imports no theory backend — `pyccl` loads only when the default backend is constructed. +- **A fixed pure draw.** The hidden cosmology is drawn by a local, order-independent RNG seeded from the blinding seed, over CCL-native parameter names (`sigma8`, `Omega_c`, …); the draw is exactly reproducible from the seed and never touches global RNG state. +- **Declared packaging.** The fork's `pyproject` declares `pyccl` alongside the inherited `cryptography` and `sacc>=0.12`; Python ≥3.12; no numpy upper bound. Install identity is a pinned `git+https` tag; the fork keeps the Smokescreen name and is never published to PyPI. +- **Firecrown status.** The firecrown integration is inherited from upstream and unsupported in the fork: lazily imported, never a declared dependency, not installed, tested, or maintained. sp_validation never installs firecrown; its only theory path is CCL. + +The fork work is two PRs on `UNIONS-WL/Smokescreen`: the protocol + default CCL backend + draw refactor + test-suite migration ([#2](https://github.com/UNIONS-WL/Smokescreen/issues/2)), and packaging + install identity + CI + pip-only docs ([#3](https://github.com/UNIONS-WL/Smokescreen/issues/3)). sp_validation's dependency PR pins a fork tag that is cut only after **both** fork PRs have merged — the lazy firecrown import lands in the protocol PR, and a tag without it would still pull firecrown transitively on a clean install — so the dependencies row (§8) is blocked on the tag, and the tag on both fork PRs. The fork diff is kept small and clean to preserve the option of contributing changes back upstream. + +## 4. Blinding + +**How it works.** +You hand `ConcealDataVector` the true data vector (a SACC file), a fiducial parameter mapping, a shift range per cosmological parameter, a seed, and (optionally) a `theory_fn`. +It seeds the fork's local RNG (§3) to draw a hidden cosmology within the shift range, computes theory at both cosmologies through the `theory_fn`, and writes a new SACC file with the difference added on: `d → d + t(hidden) − t(fiducial)`. +Noise and covariance stay untouched. +The measured vector then points at a cosmology offset by an unknown amount, and nobody can read off S8. +Goodness of fit survives to first order: if the fiducial equals the truth, the shifted data is *exactly* a realization of the hidden cosmology; otherwise a second-order χ² residual appears, proportional to (truth − fiducial) × (shift size), which Muir et al. show stays negligible for realistic shifts — one more reason not to make the shift range arbitrarily wide. +Unblinding means revealing the seed — anyone can recompute the shift and subtract it — and because the shift is exactly reproducible from the seed, re-blinding an updated catalogue takes seconds and needs no human in the loop. + +**Three sp_validation theory backends.** +The fork's default CCL backend does not know the layout of our analysis SACC file (§1) or our IA configuration, so the blinding step supplies its own `theory_fn` callables — plain CCL functions that compute exactly our fiducial model — one each for the coarse ξ±, the fine-grid ξ±, and the pseudo-Cℓ (bandpower window applied to ΔCℓ_EE). All three run through one `ConcealDataVector` draw, so a single hidden cosmology shifts every statistic consistently; a cross-backend test checks that the same hidden cosmology through two callables agrees to machine precision. + +**Extract → conceal → merge.** +The to-be-blinded block (ξ±, pseudo-Cℓ) is extracted from the analysis file, concealed, and merged back; derived statistics — COSEBIs, pure-E/B — are then **re-derived** from the blinded ξ± through the pipeline's own estimators, never shifted directly. Catalogue-level work — PSF diagnostics, ρ/τ, null tests, calibration, most of #233 — sits upstream of the data vector and never sees the blind. + +**We only analyze blinded files.** +Smokescreen encrypts the true vector at blinding time; we delete the plaintext. +No convention has to remind anyone not to plot the true vector, because the true vector isn't there. + +**The shift envelope.** +Uniform draws in (Ωm, S8) with half-widths ±0.075 in S8 and ±0.1 in Ωm. The fork's draw speaks CCL-native parameters (σ8, Ωc), so the blinding step translates this (S8, Ωm) envelope into the equivalent ranges on those parameters. +The envelope must be at least as wide as the effect we most need to stay agnostic about — the ~0.05–0.075 S8 tension between weak-lensing surveys and Planck — or a tension-sized pull could be reasoned away as "too big to be the blind." +S8 carries the amplitude blinding; the Ωm width just keeps the implied σ8 physical. +**Whether to resize is an open question for the group.** + +**Acceptance.** +The shift is a theory difference and therefore pure E-mode, so B-mode null tests must give the same answer blinded or not; the acceptance test (agreed with Sacha Guerrini) verifies exactly this on mocks — B-mode estimators unchanged under blinding to the estimator's numerical floor. A second acceptance line: the fork blinds a real `sacc_io` file end-to-end. + +## 5. Secret custody + +The shift is a deterministic function of (seed, config) — feed the same seed back through Smokescreen and the identical shift comes out — so re-blinding an updated catalogue needs no human in the loop, and unblinding is mechanical. + +Custody is a **hash commitment**, with no keyholder: + +1. A script draws the seed from OS entropy and applies the blind immediately; no one ever sees the seed. +2. It publishes `sha256(seed)` plus a digest of the blinding config to the repo — the commitment binds both. +3. It encrypts seed and true vector (via `smokescreen.encryption`) and deletes the plaintext; the seed is stripped from the blinded file's metadata, which is stamped `concealed=True` plus a label naming the blinding campaign, so blinded files from different blinds are distinguishable. +4. At the unblinding event the script reveals the seed; anyone recomputes the shift and checks the hash matches what we published — proof the revealed seed is the one fixed at blinding time, not a substitute. The unblind step verifies the hash before subtracting. + +Both the blind and the unblind are publicly verifiable, with no trusted party. + +## 6. Theory consistency + +The blinding shift is computed through CCL while inference runs CosmoSIS + CAMB, so the shift only means what we intend if the two stacks agree on our binning. Two work items: + +- **Pick the fiducial cosmology and model configuration** — halofit version, IA model, neutrino treatment — as one named choice for the tomographic round, which the CCL blinding backends and the CosmoSIS pipeline both then implement. Needed with or without blinding. We implement and test on reasonable defaults now; the eventual group choice changes config values, not code. +- **A CAMB↔CCL cross-check test**, part of the blinding row's test suite: same cosmology, same n(z), compare ξ± on our θ grid against a stated tolerance. Two subtleties it settles: CCL takes σ8 as its amplitude input while the CAMB pipeline is parameterized in A_s, and the test must match on σ8 (a nominal A_s leaves σ8 ~3% off and blows the comparison to ~10%); and the `halofit_version` strings must match on both stacks (mead2020 vs mead2020_feedback differ by several % at k≳1). + +## 7. Deferred + +- **Unblinding criteria** — which tests must pass, at what thresholds, before we unblind — wait for the validation-test enumeration in #233 to stabilize, then get drawn from it. +- **Procedural conventions** (hidden contour axes, no-external-comparison rules, post-unblinding change logs) are a team-process discussion that touches no code, and it's not obvious we need them at all once the data-vector blind hides the answer. + +## 8. Implementation series + +Two repos: `UNIONS-WL/Smokescreen` (the fork, umbrella issue [UNIONS-WL/Smokescreen#1](https://github.com/UNIONS-WL/Smokescreen/issues/1)) and `CosmoStat/sp_validation` (everything else, under epic #232). + +| Row | Content | Issue | Draft PR | +|-----|---------|-------|----------| +| Fork: protocol | `theory_fn` protocol + default CCL backend + fixed pure draw + fork-test migration | [UNIONS-WL/Smokescreen#2](https://github.com/UNIONS-WL/Smokescreen/issues/2) | PR pending | +| Fork: packaging | Install identity (pinned git tag), `pyccl` declared, fork CI smoke-test, pip-only docs | [UNIONS-WL/Smokescreen#3](https://github.com/UNIONS-WL/Smokescreen/issues/3) | PR pending | +| Dependencies | Python ≥3.12; blinding deps core (pinned fork tag, `pyccl`, `cryptography`, `sacc>=0.12`) — no extra; container/`uv.lock` move to the fork | #242 | #243 | +| `sacc_io` writers | ξ±, pseudo-Cℓ, COSEBIs, n(z), covariance, ρ/τ + pure-E/B custom types; two-file layout; round-trip tests | #244 | #245 | +| Converters | SACC→2pt-FITS (byte-compared against current output); SACC↔OneCovariance glue | #246 | #249 | +| Migration | `cosmo_val` + Snakemake migration to the SACC writers | #247 | #251 | +| Blinding | Fork wiring: three `theory_fn` backends, hash-commitment custody per §5, blinded-COSEBIs derivation, CAMB↔CCL cross-check test. Acceptance: B-mode estimators unchanged on mocks | #252 | #253 | +| SACC likelihood | Adopt CosmoSIS's native SACC likelihood, validated against the converter path | #254 | #255 | + +**Ordering:** the dependencies row is blocked on both fork rows — sp_validation pins a fork tag that is cut only from the merged tip of the protocol *and* packaging PRs (the lazy firecrown import lands in the protocol PR; a pin predating it would pull firecrown transitively on a clean install). The pure-format rows (`sacc_io`, converters, migration) are independent of the fork and proceed in parallel; the blinding row depends on both fork rows plus the writers. + +— Fable on behalf of Cail. diff --git a/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/smokescreen-fork-replan.md b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/smokescreen-fork-replan.md new file mode 100644 index 00000000..b874f78a --- /dev/null +++ b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/smokescreen-fork-replan.md @@ -0,0 +1,11 @@ +--- +id: 01KX6MNPVA6VD0Q6DWTNRJMQ22 +name: Smokescreen fork + PRD replan (fork to UNIONS-WL, drop firecrown) +tags: + - decision + - sacc + - blinding +created-at: 2026-07-10T20:29:39.306062131+02:00 +updated-at: 2026-07-10T22:54:15.942396501+02:00 +outcome: 'Drafts stable after 3 passes (drafts/: ripple-analysis, issue-tree, 8 live PRDs, 2 retired). Final shape: fork ships CCL default backend + theory_fn override; firecrown lazy/undeclared/unsupported (not deleted); deps core (no extra); native-CCL draw w/ RNG bugfix; pinned git identity; crosscheck folded into blinding tests. Awaiting Cail''s read-through; then constitutions + GitHub issue tree.' +--- diff --git a/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-sacc-prs.md b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-sacc-prs.md new file mode 100644 index 00000000..011a55ab --- /dev/null +++ b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-sacc-prs.md @@ -0,0 +1,63 @@ +--- +id: 01KX4JPKG1K7EAKFTATKBNKJ5R +name: 'Implement PRD #241: SACC + Smokescreen draft PRs' +status: active +tags: + - constitution + - sp-validation + - sacc + - blinding +created-at: 2026-07-10T01:16:42.625888497+02:00 +updated-at: 2026-07-10T17:33:51.121781533+02:00 +outcome: 'Done: all seven PRD-#241 draft PRs open, tested, adversarially reviewed, CI green (#243 #245 #249 #250 #251 #253 #255), sub-issues board-wired, summary comment maps PR↔row. Team review is the next act; follow-ups (upstream CSL bugs, PSF variant, tomographic) flagged in #255 and Status.' +shuttle: + kind: oneshot + host: candide + project_dir: /automnt/n17data/cdaley/unions/code/sp_validation + agent: claude-fable + effort: low + runtime: + dispatched_at: "2026-07-10T21:55:49.888417Z" + session_uuid: c3320e08-977e-4fdd-b31a-0bc6d7f10388 + handed_off_at: "2026-07-10T13:45:40.670475074Z" +--- + +[PRD #241](https://github.com/CosmoStat/sp_validation/issues/241) (sub-issue of umbrella #232) specifies sp_validation's adoption of SACC as the standard data-product format and Smokescreen for data-vector blinding, decomposed into seven PRs. The PRD is agreed in principle and its open questions (secret custody model, shift-envelope size, fiducial model config) change config values, not code — so implementation proceeds now, on the PRD's stated defaults, as **draft PRs** the team reviews against the PRD. Cail has abundant compute this week; the intent is fully tested, robust implementations, not sketches. The PRD text is the contract for *what*; this constitution carries the *how*. + +## Desired State + +Seven **draft** PRs open on CosmoStat/sp_validation, one per row of the PRD's §7 table, each: + +- based on the repo's integration branch (fetch and confirm the branch-vs-origin state before building; never build on a stale base), +- attached to the board correctly: one sub-issue per PR under #241 (same repo, Work area = Inference Pipeline, Kind = Task, Status = In Progress), PR body carrying `Closes #`, +- **fully tested**: unit tests for every writer/converter, the PR-3 converter byte-compared against a real current 2pt-FITS output, the PR-6 acceptance test proving B-mode estimators (COSEBIs Bₙ, pure-mode ξ_B) unchanged under blinding on mocks, and the suite green in CI, +- marked draft, no review requests, no @-mentions; PR bodies written in the worker's voice, signed "— Claude () on behalf of Cail.", +- **adversarially reviewed before opening**: a fresh-context reviewer attacks the diff (ordering/permutation, silent-empty selections, fitness-for-purpose driven end-to-end); this gate has caught a HIGH silent-misalignment bug in two of the first three reviewed PRs (PR 2: reader-side sorting; PR 3: tomographic truncation) — findings fixed and noted in the PR body before the draft opens. + +Specifically NOT doing: merging anything; resolving the PRD's open questions (implement §4(b) hash-commitment custody and the ±0.075 S8 / ±0.1 Ωm envelope as defaults, clearly marked configurable); touching Sacha's reserved zones ([[sp_validation/reserved-sacha]]: `scratch/guerrini/` and the namaster_utils→source migration — mechanical import fixes at the boundary are fine, flagged in the PR body). + +Done when all seven draft PRs are open, tested, and cross-linked from #241 with a summary comment mapping PR ↔ PRD row. + +## Sequencing & environment + +PR 1 is **done** ([#243](https://github.com/CosmoStat/sp_validation/pull/243), branch `feat/sacc-1-deps`): py3.12 floor; `sacc>=2.4,<3` core; `[blinding]` extra (firecrown git v1.15.1 + smokescreen==1.5.6 + pyccl==3.3.4, exact pins for seed-reproducibility); `uv-overrides.txt` drops firecrown's pip-unresolvable/unused connector deps (numcosmo-py, cosmosis, cobaya) — firecrown is NOT on PyPI, this override mechanism is the only clean pip path (see [[sp_validation/smokescreen-sacc-prs/smokescreen-api-facts]]). + +**Branch convention: the PRs stack** (branch `feat/sacc-N-`, PR base = the branch it builds on): 2 ← `feat/sacc-1-deps`; 3, 4, 5 ← `feat/sacc-2-sacc-io` (all three import `sacc_io` or build files with it); 6 ← the PR-5 branch (needs the firecrown likelihood); 7 last. GitHub retargets stacked PRs automatically when a base merges — CI builds the Docker image and runs the fast suite in it on every push, so a PR whose tests import sacc/firecrown must carry PR 1's deps in its image. GitHub retargets stacked PRs automatically when the base merges. 5 needs the firecrown likelihood before 6; 7 comes last. + +**Test environment**: shared uv py3.12 venv at `/automnt/n17data/cdaley/unions/code/sp_validation-worktrees/venv` (full `[test,glass,blinding]` stack, exact PR-1 pins), editable-installed against whichever worktree is under test (re-point with `uv pip install --python /bin/python --no-deps -e `). Worktrees live under `sp_validation-worktrees/`, one per PR branch; the main checkout sits on an unrelated image-sims branch — never build there. Working toy scripts for the firecrown likelihood and a full Smokescreen blind round-trip live in `sp_validation-worktrees/env-probe/` — they seed PR 5/6 implementations. + +**Heavy runs go through SLURM — never bare on the login node.** Anything that JIT-compiles numba, runs CCL/CAMB theory, or drives the slow suite (including the container launcher below, and including *subagents and review workflows told to run code*) gets an allocation first (`salloc -p comp -c N --no-shell` → `srun --jobid= …`, or `sbatch`). This was violated on 2026-07-10 (multi-core pytest at 1300% on the login node, caught by Cail); the on-run model in the global CLAUDE.md applies to test runs too. When dispatching agents that may execute code, put the srun prefix INTO their instructions. + +**cosmo_numba tests (COSEBIs/pure-EB re-derivation, PR-6 acceptance) need a hybrid launcher**: cosmo_numba + NumbaQuadpack live only in the apptainer container (compiled against glibc ≥2.29 — a copied `.so` cannot load on the host), while the blinding stack lives only in the venv. The verified union: run the venv's python *inside* the container with the two container-installed packages copied to `sp_validation-worktrees/extra-site/` — `apptainer exec --bind /home,/automnt,/n17data /n17data/cdaley/containers/containers/ env PYTHONPATH=/src:…/extra-site …/venv/bin/python -m pytest …`. Such tests gate on `pytest.importorskip("cosmo_numba")` + `slow`, so they skip in CI (image lacks cosmo_numba) and in the plain venv, and run under the launcher. + +Facts already verified (don't re-derive): θ convention is arcminutes (firecrown hard-codes `/60`); n(z) normalization is irrelevant to all consumers (CosmoSIS, OneCovariance, CCL all normalize internally); SACC officially defines `galaxy_shear_cosebi_ee/bb`; OneCovariance has no SACC I/O; Smokescreen writes the seed into blinded-file metadata (strip it); CosmoSIS's `sacc_like` ξ± path is prototype-grade — validate, don't trust. + +## Status + +**The desired state is realized — all seven draft PRs are open, tested, adversarially reviewed, and CI-green**: [#243](https://github.com/CosmoStat/sp_validation/pull/243) (PR 1, deps), [#245](https://github.com/CosmoStat/sp_validation/pull/245) (PR 2, `sacc_io`), [#249](https://github.com/CosmoStat/sp_validation/pull/249) (PR 3, converter, closes #246), [#251](https://github.com/CosmoStat/sp_validation/pull/251) (PR 4, migration, closes #247), [#250](https://github.com/CosmoStat/sp_validation/pull/250) (PR 5, likelihood, closes #248), [#253](https://github.com/CosmoStat/sp_validation/pull/253) (PR 6, blinding, closes #252), [#255](https://github.com/CosmoStat/sp_validation/pull/255) (PR 7, native sacc_like, closes #254). The [#241 summary comment](https://github.com/CosmoStat/sp_validation/issues/241#issuecomment-4936723538) maps PR ↔ PRD row with reviewer notes (stacking, the two-file layout amendment, defaults-not-decisions). CI observed green on every tip (#255: run 29103598394 `completed success`, observed 2026-07-10). + +PR 7 landed this session (rulings + as-landed record in [[sp_validation/smokescreen-sacc-prs/pr7-sacc-like-design]]): CSL's `sacc_like` ξ± path was confirmed prototype-grade with concrete mechanisms — no arcmin→rad conversion (2pt_like converts explicitly; sacc_like evaluates the radians theory spline at arcmin tags → theory silently ~0), ordering assumed never enforced, latent `keep_tracers` NameError. Adoption is a subclass shim (`sacc_like_unions.py`, radian-θ copy swapped in around theory extraction only + loud ordering guard), `inference_prep` revived onto the assembled `{version}.sacc` per PR 4's dormant-note contract, and equality with the PR-3 converter path observed to machine zero (synthetic χ²=1.18829133107 and real SP_v1.4.6_leak_corr ξ-only χ²=420310.753739, Δχ²=0 both; tripwire test fails the day upstream fixes units → retire the shim). Adversarial review (5 lenses, 3 refuters/finding) confirmed 2 MEDIUMs, fixed pre-draft; an independent fix-review cleared them on all attack vectors. + +**Where this picks up next** (human's desk, not a worker's): the team reviews the seven drafts against the PRD; the PRD's open questions (custody, envelope, fiducial config) are config-value discussions on top of implemented defaults. Follow-ups flagged but out of scope: upstream CSL issues (unit gap, `sacc_like.py` L106 NameError) — recommended in #255's body, Cail's call whether/how to file at joezuntz/cosmosis-standard-library; PSF/xi_sys pipeline variant + glass-mock prep still on `cosmosis_fitting.py`; tomographic support (converter fail-fast + shim guard) when the tomographic round needs it; PR 4's `dd474b3` "UNVERIFIED WIP" message still wants a squash-merge or reword. + +Durable environment lessons (beyond the env section above): the venv-vs-CI import matrix bites — the venv carries optional deps (cosmosis) the CI image lacks, and `test_imports.py` sweeps every package module, so optional-dep imports must be lazy (caught as a red CI run on #255, fixed in `151d997`); the sandbox container at `/n17data/cdaley/containers/containers/` is a stale shapepipe base (numpy yes, sacc/current cs_util no) — fine for bare-import checks, useless for the suite until rebuilt; CSL shallow clone lives at `sp_validation-worktrees/csl` (pin 4fd2f1c), cosmosis 3.25.2 is installed in the shared venv, and the new tests want `CSL_DIR` in the environment. diff --git a/.felt/sp_validation/uv-lock-cosmo-numba/uv-lock-cosmo-numba.md b/.felt/sp_validation/uv-lock-cosmo-numba/uv-lock-cosmo-numba.md new file mode 100644 index 00000000..175f4c3d --- /dev/null +++ b/.felt/sp_validation/uv-lock-cosmo-numba/uv-lock-cosmo-numba.md @@ -0,0 +1,37 @@ +--- +id: 01KX8781PRX0720TKFAEXY7RMY +name: 'sp_validation: declare cosmo_numba + migrate to uv/uv.lock' +status: active +tags: + - sp_validation + - deps + - future + - constitution +created-at: 2026-07-11T11:13:29.048895365+02:00 +updated-at: 2026-07-11T11:35:39.19956558+02:00 +outcome: 'Spun off 2026-07-11 from the image-sims gate failure: sp_validation''s published image drifted numpy to 2.5, breaking numba, because cosmo_numba (its numba-bearing dep, imported in b_modes.py and importorskip''d in tests) is undeclared and there is no lockfile — the resolver can''t see numba''s numpy window. Fix: declare cosmo_numba as a dependency, adopt uv with a committed uv.lock (mirroring shapepipe), and drop unscoped ''--upgrade'' install layers from the Dockerfile (use --upgrade-package). Unblocks collapsing the image-sims chain back to one container.' +shuttle: + kind: oneshot + host: candide + agent: claude-opus + effort: medium + runtime: + dispatched_at: "2026-07-11T09:41:21.794114Z" + session_uuid: 56c5f57c-71f7-43e0-8f81-08490705c2e6 +--- + +sp_validation's dependency environment is un-locked and incomplete, and it just cost a day: the published image (built `FROM` the ShapePipe image, which carries a numba-compatible numpy via its `uv.lock`) drifted numpy to 2.5 during its own unpinned install layers, killing numba — and with it the ShapePipe ngmix stage the image is supposed to be able to run. Root cause is structural, not a version accident: `cosmo_numba` (the numba-bearing dependency, imported in `b_modes.py`, `importorskip`'d in tests) is not declared in `pyproject.toml`, so the resolver never sees numba's numpy window; and with no lockfile, every image build re-resolves from scratch. This fiber makes sp_validation's environment reproducible the way [[science/unions/shapepipe|shapepipe]]'s already is, and thereby restores the one-container premise of the image-sims chain ([[science/unions/shapepipe-program/image-sims-workflow]] — its `.smk` currently carries a two-image workaround, `sif_pipeline`, to be collapsed once this lands). + +## Desired State + +1. **`cosmo_numba` is a declared dependency** of sp_validation (git ref or PyPI, whichever CosmoStat/cosmo-numba supports), so numba's constraints reach the resolver. Any other imported-but-undeclared deps found during the audit get declared too (sweep `src/` and `scripts/` imports against `pyproject.toml`). +2. **sp_validation is uv-managed with a committed `uv.lock`**, mirroring shapepipe's setup: `pyproject.toml` holds abstract minimums, `uv.lock` the exact pins, never hand-edited. CI and the Dockerfile install from the lock. +3. **The Dockerfile has no unscoped `--upgrade`** — the cs_util layer uses `--upgrade-package cs_util` (or the lock makes the layer unnecessary). No install layer can silently move a base-image pin. +4. **The rebuilt image runs the full ShapePipe chain**: `python -c "import numba, cosmo_numba"` passes and numpy inside the image satisfies numba's window; verified by running the image-sims `im_pipeline` stage (or at minimum a `shapepipe_run` ngmix smoke) in the new image. This is the checkable condition that lets the image-sims `.smk` drop `sif_pipeline`. +5. **The work lands as a PR** against sp_validation's integration branch, on its own feature branch. Pushing that feature branch (needed for CI image builds) is in scope; pushing/merging any shared branch is not — merge timing is Cail's. + +## Boundaries + +- Don't hand-pin numpy ceilings to track numba's compatibility — that's exactly the vigilance-based fix this task replaces with resolver-visible constraints. +- Don't touch the image-sims workflow rules in this fiber; the `sif_pipeline` collapse happens in the image-sims fiber once the healthy image is published and verified. +- Coordinate-lightly rule: Martin builds from the same Dockerfile lineage — keep the diff minimal and legible, no drive-by refactors of his layers. diff --git a/.felt/sp_validation/uv-lock-cosmo-numba/uv-lock-cosmo-numba.md.lock b/.felt/sp_validation/uv-lock-cosmo-numba/uv-lock-cosmo-numba.md.lock new file mode 100644 index 00000000..e69de29b From 4f6e325b829ec36377dd8d2d8150554048ba712a Mon Sep 17 00:00:00 2001 From: Cail Daley Date: Sat, 11 Jul 2026 12:37:25 +0200 Subject: [PATCH 2/5] =?UTF-8?q?felt:=20fork-implementation=20=E2=80=94=20c?= =?UTF-8?q?onstitution=20absorbs=20#241=20re-rulings=20(one-file=20layout,?= =?UTF-8?q?=20per-part=20blinding=20at=20birth)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Fable 5 Claude-Session: https://claude.ai/code/session_01KpaRHk3QwN13myduQ3hJyf --- .../drafts/prd-smokescreen-blinding.md | 6 +++--- .../fork-implementation/fork-implementation.md | 2 ++ 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-smokescreen-blinding.md b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-smokescreen-blinding.md index 4375596f..376bd000 100644 --- a/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-smokescreen-blinding.md +++ b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/drafts/prd-smokescreen-blinding.md @@ -128,15 +128,15 @@ Unblind CLI: decrypt the bundle → recompute `sha256(seed)` and the config dige Checkable, run inside the container: -1. **Idempotence / plumbing (zero-shift).** Blinding with a zero shift (hidden cosmology equal to fiducial) reproduces the input file's ξ±, COSEBIs, and pure-E/B values exactly. This exercises the extract/merge/re-derivation plumbing only — a broken `theory_fn` also passes, since `theory_fn(fiducial) − theory_fn(fiducial) = 0` for any callable. The backend itself is tested by AC #2. -2. **On-file shift equals the intended theory difference (central correctness).** For a fixed non-zero seed on a two-bin fixture, the per-row shift actually present in the blinded file (`blinded.mean − true.mean` at each shifted block's rows) equals `theory_fn(hidden_params) − theory_fn(fiducial_params)` — where `hidden_params` is recovered by re-running the fork's draw on that seed — to ~1e-10. This closes the loop AC #1 leaves open (a wrong theory backend fails here) and asserts the merge places the shift at the right rows. Run for all three blocks. +1. **Idempotence / plumbing (zero-shift).** Blinding with a zero shift (hidden cosmology equal to fiducial) reproduces the input file's ξ±, COSEBIs, and pure-E/B values exactly. This exercises the extract/merge/re-derivation plumbing only — a broken `theory_fn` also passes, since `theory_fn(fiducial) − theory_fn(fiducial) = 0` for any callable. The backend itself is tested by AC #3 (an independently written direct-CCL reference; AC #2 shares the backend and so cannot catch a wrong one). +2. **On-file shift equals the recovered theory difference (fork-draw recovery + merge placement).** For a fixed non-zero seed on a two-bin fixture, the per-row shift actually present in the blinded file (`blinded.mean − true.mean` at each shifted block's rows) equals `theory_fn(hidden_params) − theory_fn(fiducial_params)` — where `hidden_params` is recovered by re-running the fork's draw on that seed — to ~1e-10. This confirms the fork's draw is reproducible from `(seed, config)` and the merge places the shift at the right rows. It is **not** a backend-correctness test: both sides run the same `theory_fn`, so a wrong cosmology dependence cancels and a wrong backend still passes here — backend correctness is carried by AC #3, which compares the realized shift against an independently written direct-CCL reference. Run for all three blocks. 3. **Cross-backend consistency (reference-independent).** For the same hidden cosmology, the concealment-path shift for a block is compared against an **independently written** direct-CCL reference — a self-contained `angular_cl`+`correlation` call in the test file that does not import `sp_validation.blinding`'s backend, reading the same n(z) and θ/ℓ from the fixture — and they agree to ~1e-10 on a two-bin fixture. The reference is independent code, so agreement is not tautological; this pins the backend's projection against a from-scratch CCL computation. 4. **B-mode invariance.** On mocks, the ΔBₙ induced by blinding is bounded by the fixed E→B leakage floor of the estimator and is **independent of the injected B amplitude** (the shift is pure E-mode, so its leakage into B is a fixed absolute offset, not a fractional one). The test injects two different B amplitudes at fixed shift and asserts the absolute ΔBₙ is identical between them (to ~1e-10). The comparand — the shift-induced leakage — is defined concretely as `blind(true_file) B-block − true_file B-block` re-derived through the pipeline estimator on the blinded ξ±; the test asserts this vector is the same for both injected B amplitudes. The magnitude of the leakage floor is not asserted against a fixed number; it is measured by the run and reported (see note below). The criterion this AC enforces — B-amplitude independence — is exact by construction. 5. **Covariance, ρ/τ, and row order untouched.** The blinded file's covariance block and ρ/τ diagnostic rows are byte-identical to the input, and every shifted block's rows land back at their original master indices (order-preservation assertion, guarding COSEBIs re-derivation against a mis-merge). 6. **Custody verifiability.** Blind → commit → encrypt → strip leaves no plaintext seed and no `seed_smokescreen` key on disk in the blinded file; unblind fails closed if either `sha256(seed)` or the config digest mismatches the commitment. 7. **Reproducibility.** Two blind runs with the same seed and config produce identical shifts; unblinding after a re-blind of an updated catalogue needs no external state beyond the encrypted bundle. 8. **End-to-end integration.** The blind CLI blinds a real sp_validation `sacc_io` master file end-to-end and the unblind CLI restores it bit-for-bit; run on a fixture master file in the container. -9. **Pure-EB boundary behavior.** Re-derived pure-E/B follows the pipeline's edge-based integration bounds. The test runs re-derivation on a fixture whose θ grid deliberately includes a boundary-degenerate reporting point (the first point of the integration range, where the edge-based estimator has no interior support) and asserts that point is NaN in both the true-file and blinded-file re-derivations — i.e. NaN-parity with the pipeline's own estimator, never a spurious finite value. Production reporting grids are strict sub-ranges of the integration range, so this degeneracy never fires on real files; the fixture forces it to exercise the parity. +9. **Pure-EB NaN-parity under the blind.** Re-derived pure-E/B follows the pipeline's edge-based integration bounds; the Schneider estimator returns NaN wherever a reporting point lacks interior support against those bounds. The test asserts the re-derived NaN pattern is **identical on the true and blinded files** — blinding is a pure shift of the estimator's inputs, so it moves the finite values but never moves a NaN. On production files (and on the fixture, which now seeds pure-E/B through the exact pipeline convention — measured coarse reporting ξ± + fine integration grid + edge-based bounds) the reporting grid is a strict sub-range of the integration range, so the degeneracy does not fire and the pattern is empty; the invariant the AC enforces is the parity, which holds whether or not any point is degenerate. *Note on the ΔBₙ leakage floor.* The absolute size of the shift-induced E→B leakage is a measured output, not a target: it is reported from the run that produces it (the mock B-mode invariance test), not carried as an unsourced constant in this PRD. The acceptance criterion enforces that this leakage is independent of the injected B amplitude and reproducible — both exact by construction — with the observed magnitude recorded alongside the test. diff --git a/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/fork-implementation/fork-implementation.md b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/fork-implementation/fork-implementation.md index b7462235..25ec3891 100644 --- a/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/fork-implementation/fork-implementation.md +++ b/.felt/sp_validation/smokescreen-sacc-prs/smokescreen-fork-replan/fork-implementation/fork-implementation.md @@ -25,6 +25,8 @@ Executes the Smokescreen-fork replan ruled with Cail on 2026-07-10 (parent fiber ## Desired State +**Source of truth: the live body of sp_validation#241** (rewritten in place 2026-07-11; Cail edits it directly — re-read it each session and reconcile before building). Two later rulings supersede the drafts where they conflict: (a) **one SACC file per catalogue version** — fine ξ± rides in `{version}.sacc` as `grid='fine'` tagged points with a dense per-pair covariance block (see the re-ruled [[sp_validation/smokescreen-sacc-prs/sacc-layout-contract]]); PR #245 already implements this. (b) **Blinding is per intermediate product, at birth** — a `blind-init` step draws the seed once per catalogue version and publishes `hash(seed)`; each blindable part (coarse ξ±, fine ξ±, pseudo-Cℓ) is blinded the moment it is computed; only blinded intermediates persist on disk; COSEBIs/pure-E/B are derived from the already-blinded fine ξ± (born blinded); terminal assembly asserts the commitment hash is identical across parts. `prd-smokescreen-blinding.md`'s terminal-master-blind framing is superseded accordingly; its backends, custody primitives, and CAMB↔CCL cross-check stand. + **GitHub structure (per `drafts/issue-tree.md`):** - `LSSTDESC/Smokescreen` is forked to `UNIONS-WL/Smokescreen` (org fork, `gh repo fork --org UNIONS-WL`). If org-level fork creation is denied by permissions, that is a genuine block: stop and lead the outcome with "Blocked:". - The issue tree from `drafts/issue-tree.md` exists on GitHub: umbrella + sub-issues in their stated repos, nested as sub-issues, on board `UNIONS-WL/projects/1` with Status + Work area set per the board model in `/automnt/n17data/cdaley/unions/CLAUDE.md`. A comment on sp_validation#241 states the plan amendment concisely (top-down, neutral tone — see tone rule below), citing the new issues. From 95843df27e5989f7571d1c9d4866faea6b8f71b0 Mon Sep 17 00:00:00 2001 From: Cail Daley Date: Sat, 11 Jul 2026 12:51:55 +0200 Subject: [PATCH 3/5] deps: declare cosmo_numba + numba, adopt committed uv.lock, install image from lock MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Make sp_validation's environment reproducible so an image build can never re-resolve numpy past numba's ceiling — the drift that silently upgraded numpy to 2.5 and broke numba/ngmix. - Declare cosmo-numba (aguinot/cosmo-numba@main; not on PyPI) — the numba B-mode kernels b_modes.py imports. main carries numpy-2 FFT support via its rocket-fft dep and declares its own deps, so numba's numpy window reaches the resolver. Also pin numba directly: the one load-bearing constraint, made visible and resilient to cosmo-numba's dep metadata (which has emptied out between refs). - Declare the other imported-but-undeclared deps the audit found: matplotlib, pandas, pyyaml (core, src/); fitsio (glass extra); a new `workflow` extra for snakemake + mpi4py. cv_runner and unions_wl left undeclared (no resolvable source) with a NOTE. - requires-python and ruff target -> 3.12 (the container's Python; cosmo-numba's floor). - Commit uv.lock (un-ignored) as the SSOT; scope it to Linux via [tool.uv]. numpy resolves to 2.4.6, inside numba 0.66's <2.5 window. - Dockerfile installs from the lock: `uv sync --frozen --inexact` into the base image's /app/.venv (--inexact keeps the ShapePipe stack). Drops the ad-hoc snakemake layer and the cs_util `--upgrade` workaround — the lock pins cs_util 0.2.2 (with cs_util.size), decoupling us from the base image's cs_util. Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Vtw1qcgTrQ6YuMvxwYzNup --- .gitignore | 2 +- Dockerfile | 40 +- pyproject.toml | 48 +- uv.lock | 4370 ++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 4439 insertions(+), 21 deletions(-) create mode 100644 uv.lock diff --git a/.gitignore b/.gitignore index f8eec899..12fab2f1 100644 --- a/.gitignore +++ b/.gitignore @@ -122,7 +122,7 @@ venv.bak/ # and the lockfile has never been tracked. Ignore it rather than commit a # pinned-dep reproducibility promise the project hasn't made. Flip to tracked # if we decide to pin deps via uv. -uv.lock +# uv.lock is committed — it is the reproducible pin the container installs from. # Spyder project settings .spyderproject diff --git a/Dockerfile b/Dockerfile index c791877c..7df622a0 100644 --- a/Dockerfile +++ b/Dockerfile @@ -12,24 +12,28 @@ RUN apt-get update -y --quiet --fix-missing && \ npm \ tmux -# The base image installs into the system interpreter (/usr/local); use `uv pip` -# so the heavy scientific stack and our deps land where `python` resolves. -RUN uv pip install --no-cache-dir \ - snakemake - -# The base shapepipe image ships cs_util 0.1.9, and `uv pip install -e` does NOT -# upgrade an already-satisfied dependency to meet a *new* lower bound (astral-sh/uv -# #8410). sp_validation now needs `cs_util.size` (cs_util>=0.2.1), so upgrade it -# explicitly here — otherwise the editable install silently keeps 0.1.9 and the -# galaxy import smoke test fails. shear_psf_leakage@develop allows cs-util<0.3, -# so 0.2.x satisfies the whole graph. -RUN uv pip install --no-cache-dir --upgrade 'cs_util>=0.2.1' +# The base shapepipe image provides a uv-managed venv at /app/.venv (exported as +# VIRTUAL_ENV); install sp_validation's deps into that same venv rather than +# spawning a second one under /sp_validation. +ENV UV_PROJECT_ENVIRONMENT=/app/.venv WORKDIR /sp_validation -COPY . /sp_validation -# Install with the test + glass extras so the image can run the unit suite in CI -# *and* the GLASS map-level mock test. `glass` (Generator for Large Scale -# Structure) ships `glass.ext.camb`; `cosmology` provides the `Cosmology` wrapper -# (`Cosmology.from_camb`) GLASS consumes. Both come in via the `[glass]` extra. -RUN uv pip install --no-cache-dir -e '.[test,glass]' +# uv.lock is the SSOT: `uv sync --frozen` installs exactly what it pins, so an +# image build can never silently re-resolve and drift a base-image version (the +# numpy-past-numba drift this lockfile exists to prevent). `--inexact` keeps the +# base image's ShapePipe stack (shapepipe, ngmix, galsim, …) — packages not in +# our lock — instead of pruning them. Copy the lock + manifest first so this +# layer caches independently of source edits. Extras: test (CI unit suite), +# glass (GLASS map-level mock — pulls glass.ext.camb + the cosmology wrapper), +# workflow (Snakemake + mpi4py runners). cs_util 0.2.2 (with cs_util.size) and a +# numba-safe numpy 2.4.6 come straight from the lock, so the old ad-hoc snakemake +# and cs_util `--upgrade` layers are gone. +COPY pyproject.toml uv.lock /sp_validation/ +RUN uv sync --frozen --inexact --no-install-project \ + --extra test --extra glass --extra workflow + +# Install sp_validation itself (editable) into the same venv; deps are already +# satisfied by the sync above. +COPY . /sp_validation +RUN uv pip install --no-deps -e . diff --git a/pyproject.toml b/pyproject.toml index bb1fe413..43393f1d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -9,7 +9,10 @@ authors = [ ] license = {text = "MIT"} readme = "README.md" -requires-python = ">=3.11" +# 3.12 floor: cosmo-numba (a hard dependency below) requires >=3.12, and the +# production container is Python 3.12 (shapepipe base image). Keeping the floor +# in sync with the container is what makes `uv lock` resolvable. +requires-python = ">=3.12" classifiers = [ "License :: OSI Approved :: MIT License", "Programming Language :: Python :: 3", @@ -31,7 +34,27 @@ dependencies = [ # get_theo_c_ell / get_theo_xi / PLANCK18 in cs_util.cosmo, which land via # CosmoStat/cs_util#76 — so this goes green once #76 merges into develop. "cs_util @ git+https://github.com/CosmoStat/cs_util.git@develop", + # Fast numba B-mode kernels (Schneider et al. 2022): the Schneider E/B split + # and COSEBIS live here, imported in b_modes.py. Tracks aguinot/cosmo-numba + # main (not published on PyPI). main carries the numpy-2 FFT fix via its + # rocket-fft dependency (which teaches numba's nopython mode to handle + # np.fft), and declares numba/numpy/rocket-fft from its requirements.txt so + # those constraints reach the resolver. + "cosmo-numba @ git+https://github.com/aguinot/cosmo-numba.git@main", "emcee", + # numba is the load-bearing pin of this whole environment: its numpy ceiling + # (numba 0.66 -> numpy<2.5) is what keeps the resolver from drifting numpy + # forward and breaking numba/ngmix — the failure this lockfile exists to + # prevent. cosmo-numba above also carries this constraint, but we pin numba + # ourselves too: it makes the one critical constraint visible and resilient + # to cosmo-numba's dependency metadata (which has silently emptied out + # between refs before). We pin numba, never numpy directly. + "numba", + # Imported directly across src/ (calibration, plots) alongside seaborn — + # declared explicitly rather than leaned on as a seaborn transitive. + "matplotlib", + "pandas", + "pyyaml", # SHA-pinned snapshot of getdist branch `upper_triangle_whisker`. "getdist @ git+https://github.com/benabed/getdist.git@113cd22a9a0d013b6f72fe734be81f260f3d3be5", "h5py", @@ -78,6 +101,13 @@ dependencies = [ [project.urls] Homepage = "https://github.com/CosmoStat/sp_validation" +[tool.uv] +# The reproducibility target is the Linux container; scope the lock to Linux +# (mirrors shapepipe) so `uv lock` resolves the linux-centric stack (pymaster, +# mpi4py) without hunting for macOS/Windows wheels. macOS dev installs still +# work via `uv pip install -e .` (unlocked), just not `uv sync` from the lock. +environments = ["sys_platform == 'linux'"] + [project.optional-dependencies] test = [ "pytest", @@ -105,6 +135,20 @@ glass = [ "glass==2025.1", "glass.ext.camb==2023.6", "cosmology==2022.10.9", + # fitsio: make_unions_glass_sim.py writes the mock catalogue as FITS. + "fitsio", +] +# Cosmo-inference workflow runners (workflow/scripts/*). Kept optional: the core +# library resolves without them, but the container installs this extra so the +# Snakemake workflow and cross-validation runners are available. +workflow = [ + "snakemake", + # run_2pcf_highres.py drives the MPI convergence run; the container ships + # OpenMPI (/opt/ompi) so mpi4py builds against it. + "mpi4py", + # NOTE: workflow/scripts/cv_*.py also import `cv_runner`, which is not + # published or resolvable (no public repo found) — left undeclared pending + # its source. Same for `unions_wl` (scripts/check_footprint.py). ] develop = ["sp_validation[test,docs]"] @@ -124,7 +168,7 @@ markers = [ [tool.ruff] line-length = 88 -target-version = "py311" +target-version = "py312" # Snakemake injects a `snakemake` object into rule scripts at runtime, so ruff # can't see where it's defined. Declaring it a builtin silences the false diff --git a/uv.lock b/uv.lock new file mode 100644 index 00000000..e0330596 --- /dev/null +++ b/uv.lock @@ -0,0 +1,4370 @@ +version = 1 +revision = 3 +requires-python = ">=3.12" +resolution-markers = [ + "python_full_version >= '3.14' and sys_platform == 'linux'", + "python_full_version < '3.14' and sys_platform == 'linux'", +] +supported-markers = [ + "sys_platform == 'linux'", +] + +[[package]] +name = "adjusttext" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "matplotlib", marker = "sys_platform == 'linux'" }, + { name = "numpy", marker = "sys_platform == 'linux'" }, + { name = "scipy", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b5/5c/496e506ad3313664df24a79f801719cadcd62af5999fcb299c9b08ff0d4b/adjusttext-1.4.0.tar.gz", hash = "sha256:1f73860ced8cccce3f85ee6989ca133c2579b67a7453f63dbeb38f39bf123154", size = 15852, upload-time = "2026-06-08T16:48:32.726Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b8/2c/897bdd17b05724c894a5b831c6b2e9853adcc2d07a70d6246c0cd5cd3912/adjusttext-1.4.0-py3-none-any.whl", hash = "sha256:6febd6484c0d45c39a22f44b2c1f4a8cd01ef58fada565cab4b629c771df79b5", size = 13262, upload-time = "2026-06-08T16:48:31.765Z" }, +] + +[[package]] +name = "aenum" +version = "3.1.17" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/07/e9/8b283567c1fef7c24d1f390b37daede8b61593d8cdaffb8e95d571699e83/aenum-3.1.17.tar.gz", hash = "sha256:a969a4516b194895de72c875ece355f17c0d272146f7fda346ef74f93cf4d5ba", size = 137648, upload-time = "2026-03-20T20:43:29.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/8d/1fe30c6fd8999b9d462547c4a1bb6690bda24af38f2913c4bec7decb81f2/aenum-3.1.17-py3-none-any.whl", hash = "sha256:8b883a37a04e74cc838ac442bdd28c266eae5bbf13e1342c7ef123ed25230139", size = 165560, upload-time = "2026-03-20T20:43:27.681Z" }, +] + +[[package]] +name = "alabaster" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a6/f8/d9c74d0daf3f742840fd818d69cfae176fa332022fd44e3469487d5a9420/alabaster-1.0.0.tar.gz", hash = "sha256:c00dca57bca26fa62a6d7d0a9fcce65f3e026e9bfe33e9c538fd3fbb2144fd9e", size = 24210, upload-time = "2024-07-26T18:15:03.762Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/b3/6b4067be973ae96ba0d615946e314c5ae35f9f993eca561b356540bb0c2b/alabaster-1.0.0-py3-none-any.whl", hash = "sha256:fc6786402dc3fcb2de3cabd5fe455a2db534b371124f1f21de8731783dec828b", size = 13929, upload-time = "2024-07-26T18:15:02.05Z" }, +] + +[[package]] +name = "annotated-types" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081, upload-time = "2024-05-20T21:33:25.928Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643, upload-time = "2024-05-20T21:33:24.1Z" }, +] + +[[package]] +name = "anyio" +version = "4.14.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "idna", marker = "sys_platform == 'linux'" }, + { name = "typing-extensions", marker = "python_full_version < '3.13' and sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3b/72/5562aabb8dd7181e8e860622a38bea08d17842b99ecd4c91f84ac95251b0/anyio-4.14.1.tar.gz", hash = "sha256:8d648a3544c1a700e3ff78615cd679e4c5c3f149904287e73687b2596963629e", size = 254831, upload-time = "2026-06-24T20:56:06.017Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b0/7b/90df4a0a816d98d6ea26f559d87836d494a2cf1fcf063be67df50a7bcc30/anyio-4.14.1-py3-none-any.whl", hash = "sha256:4e5533c5b8ff0a24f5d7a176cbe6877129cd183893f66b537f8f227d10527d72", size = 124875, upload-time = "2026-06-24T20:56:04.413Z" }, +] + +[[package]] +name = "argon2-cffi" +version = "25.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "argon2-cffi-bindings", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0e/89/ce5af8a7d472a67cc819d5d998aa8c82c5d860608c4db9f46f1162d7dab9/argon2_cffi-25.1.0.tar.gz", hash = "sha256:694ae5cc8a42f4c4e2bf2ca0e64e51e23a040c6a517a85074683d3959e1346c1", size = 45706, upload-time = "2025-06-03T06:55:32.073Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4f/d3/a8b22fa575b297cd6e3e3b0155c7e25db170edf1c74783d6a31a2490b8d9/argon2_cffi-25.1.0-py3-none-any.whl", hash = "sha256:fdc8b074db390fccb6eb4a3604ae7231f219aa669a2652e0f20e16ba513d5741", size = 14657, upload-time = "2025-06-03T06:55:30.804Z" }, +] + +[[package]] +name = "argon2-cffi-bindings" +version = "25.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5c/2d/db8af0df73c1cf454f71b2bbe5e356b8c1f8041c979f505b3d3186e520a9/argon2_cffi_bindings-25.1.0.tar.gz", hash = "sha256:b957f3e6ea4d55d820e40ff76f450952807013d361a65d7f28acc0acbf29229d", size = 1783441, upload-time = "2025-07-30T10:02:05.147Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d4/d3/942aa10782b2697eee7af5e12eeff5ebb325ccfb86dd8abda54174e377e4/argon2_cffi_bindings-25.1.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a1c70058c6ab1e352304ac7e3b52554daadacd8d453c1752e547c76e9c99ac44", size = 86558, upload-time = "2025-07-30T10:01:43.943Z" }, + { url = "https://files.pythonhosted.org/packages/0d/82/b484f702fec5536e71836fc2dbc8c5267b3f6e78d2d539b4eaa6f0db8bf8/argon2_cffi_bindings-25.1.0-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e2fd3bfbff3c5d74fef31a722f729bf93500910db650c925c2d6ef879a7e51cb", size = 92364, upload-time = "2025-07-30T10:01:44.887Z" }, + { url = "https://files.pythonhosted.org/packages/c9/c1/a606ff83b3f1735f3759ad0f2cd9e038a0ad11a3de3b6c673aa41c24bb7b/argon2_cffi_bindings-25.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c4f9665de60b1b0e99bcd6be4f17d90339698ce954cfd8d9cf4f91c995165a92", size = 85637, upload-time = "2025-07-30T10:01:46.225Z" }, + { url = "https://files.pythonhosted.org/packages/44/b4/678503f12aceb0262f84fa201f6027ed77d71c5019ae03b399b97caa2f19/argon2_cffi_bindings-25.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ba92837e4a9aa6a508c8d2d7883ed5a8f6c308c89a4790e1e447a220deb79a85", size = 91934, upload-time = "2025-07-30T10:01:47.203Z" }, + { url = "https://files.pythonhosted.org/packages/c1/93/44365f3d75053e53893ec6d733e4a5e3147502663554b4d864587c7828a7/argon2_cffi_bindings-25.1.0-cp39-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e021e87faa76ae0d413b619fe2b65ab9a037f24c60a1e6cc43457ae20de6dc6", size = 81246, upload-time = "2025-07-30T10:01:54.145Z" }, + { url = "https://files.pythonhosted.org/packages/09/52/94108adfdd6e2ddf58be64f959a0b9c7d4ef2fa71086c38356d22dc501ea/argon2_cffi_bindings-25.1.0-cp39-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d3e924cfc503018a714f94a49a149fdc0b644eaead5d1f089330399134fa028a", size = 87126, upload-time = "2025-07-30T10:01:55.074Z" }, + { url = "https://files.pythonhosted.org/packages/72/70/7a2993a12b0ffa2a9271259b79cc616e2389ed1a4d93842fac5a1f923ffd/argon2_cffi_bindings-25.1.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:c87b72589133f0346a1cb8d5ecca4b933e3c9b64656c9d175270a000e73b288d", size = 80343, upload-time = "2025-07-30T10:01:56.007Z" }, + { url = "https://files.pythonhosted.org/packages/78/9a/4e5157d893ffc712b74dbd868c7f62365618266982b64accab26bab01edc/argon2_cffi_bindings-25.1.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:1db89609c06afa1a214a69a462ea741cf735b29a57530478c06eb81dd403de99", size = 86777, upload-time = "2025-07-30T10:01:56.943Z" }, +] + +[[package]] +name = "argparse-dataclass" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1a/ff/a2e4e328075ddef2ac3c9431eb12247e4ba707a70324894f1e6b4f43c286/argparse_dataclass-2.0.0.tar.gz", hash = "sha256:09ab641c914a2f12882337b9c3e5086196dbf2ee6bf0ef67895c74002cc9297f", size = 6395, upload-time = "2023-06-11T20:32:54.465Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/66/e6c0a808950ba5a4042e2fcedd577fc7401536c7db063de4d7c36be06f84/argparse_dataclass-2.0.0-py3-none-any.whl", hash = "sha256:3ffc8852a88d9d98d1364b4441a712491320afb91fb56049afd8a51d74bb52d2", size = 8762, upload-time = "2023-06-11T20:32:52.724Z" }, +] + +[[package]] +name = "array-api-compat" +version = "1.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/86/12/65d297d3e425cb7fe5247b7ec14b4ed83539e9b5e89b65c15ea7ee274182/array_api_compat-1.15.0.tar.gz", hash = "sha256:53c5f922491bf15f62847afafc4e39eedfae57d218988fefb8cce39c2a9b3dea", size = 129305, upload-time = "2026-06-07T20:53:24.964Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/86/16/1a8fd2b19544b84575cf84ef7aa3ad4c173b756d5f087c91f85d1b295777/array_api_compat-1.15.0-py3-none-any.whl", hash = "sha256:7b1b9c53269061403fd5f45a8de349f16e7887653328bfa0c5f2d45299ff0a8e", size = 79113, upload-time = "2026-06-07T20:53:23.621Z" }, +] + +[[package]] +name = "arrow" +version = "1.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "python-dateutil", marker = "sys_platform == 'linux'" }, + { name = "tzdata", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b9/33/032cdc44182491aa708d06a68b62434140d8c50820a087fac7af37703357/arrow-1.4.0.tar.gz", hash = "sha256:ed0cc050e98001b8779e84d461b0098c4ac597e88704a655582b21d116e526d7", size = 152931, upload-time = "2025-10-18T17:46:46.761Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ed/c9/d7977eaacb9df673210491da99e6a247e93df98c715fc43fd136ce1d3d33/arrow-1.4.0-py3-none-any.whl", hash = "sha256:749f0769958ebdc79c173ff0b0670d59051a535fa26e8eba02953dc19eb43205", size = 68797, upload-time = "2025-10-18T17:46:45.663Z" }, +] + +[[package]] +name = "asteval" +version = "1.0.9" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b1/71/bec6758ab41ada3b6870cb194ea16d2e76bb530562c8a8cd7d2167012bea/asteval-1.0.9.tar.gz", hash = "sha256:4f7323d63d9fbf89d7e1d5f8bb59b6c093970c15bb5926e6e67d0195858aa230", size = 55237, upload-time = "2026-06-11T18:40:36.086Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fe/d7/a71b12b625c44cfcb95d41397752edccc0a731903081609cffd6720f671d/asteval-1.0.9-py3-none-any.whl", hash = "sha256:60513ea5d608d27bdb0cf3785dc993a6c3adeaee45f1bded0953a09e904e461f", size = 23320, upload-time = "2026-06-11T18:40:35.068Z" }, +] + +[[package]] +name = "astropy" +version = "8.0.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "astropy-iers-data", marker = "sys_platform == 'linux'" }, + { name = "numpy", marker = "sys_platform == 'linux'" }, + { name = "packaging", marker = "sys_platform == 'linux'" }, + { name = "pyerfa", marker = "sys_platform == 'linux'" }, + { name = "pyyaml", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0e/c4/21be4313ddfde5f60e0607fd307f367b9e0f0bf153a89b10cbd036dd8cfd/astropy-8.0.1.tar.gz", hash = "sha256:45ca31d5b91fa294cd590a4791a32db94de7f9c8a343155f4d5877baa82351da", size = 7152500, upload-time = "2026-07-05T07:24:48.482Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/56/3b/d29035da0a08e3b0b03d63abe9ce69b900d8ef7863dc557a2e34ebf56a4e/astropy-8.0.1-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9a4044396c15969bb029b648521f7c25d294e982dbd23e7c2c7dd328178b8b98", size = 10414634, upload-time = "2026-07-05T07:24:36.129Z" }, + { url = "https://files.pythonhosted.org/packages/fa/14/6f4427419f8a02e1d0a885fb64d8d4454c5d443627aa7cb1a3a36e16abb7/astropy-8.0.1-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fa11d56855e10107ea2231a6b6a33dbf1edbea6890adf34634c1f1d8f25c5a5a", size = 10452095, upload-time = "2026-07-05T07:24:38.424Z" }, + { url = "https://files.pythonhosted.org/packages/b2/ef/a5cf36a402c4511a776405f12d0b35196f55f4312ce407012a2fbcf1e4e0/astropy-8.0.1-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:5b482bc6c57c966e6c6234410a1d9afbcf92bcac858cf287812f8c99ddc3fafc", size = 10407732, upload-time = "2026-07-05T07:24:40.774Z" }, +] + +[[package]] +name = "astropy-healpix" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "astropy", marker = "sys_platform == 'linux'" }, + { name = "numpy", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/bb/fb3dcca212b1d57ed26b33eabb9e1cc18fcadbfc2f2976b20530b7d80b90/astropy_healpix-2.0.0.tar.gz", hash = "sha256:6ce7646dc5b1c09a7ed24b1f23d3e2fce8e3570387220d26a24487ab001b3b0b", size = 112064, upload-time = "2026-06-29T20:02:46.407Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b8/d3/6055bf7486e0fc980a2c842fc757918f79b012c3181d6f03b3fe230a2f65/astropy_healpix-2.0.0-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6bf86b2cdd9615de0031bc13b33fb72bcf085c5a2c78a6cf27c7a02b9ec05be7", size = 191108, upload-time = "2026-06-29T20:02:34.106Z" }, + { url = "https://files.pythonhosted.org/packages/d0/9e/0bf5fdb204527abb6ee1ae8f77ce867b1150203864a47c19d0e5bd3ae63a/astropy_healpix-2.0.0-cp310-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bd3614d685ec2cd629f4e2bbb0e1db625fe878dde778b335ec07ab4754809d78", size = 193204, upload-time = "2026-06-29T20:02:35.261Z" }, + { url = "https://files.pythonhosted.org/packages/4a/1a/5b8680a2a68df29a38baebd9659c4c4b42f5885c7fcfeb03dc336afb0053/astropy_healpix-2.0.0-cp310-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:8ffc56532822414fc6ba9b5e80b7897f98c96762d4ae69f14f5797e18946c26e", size = 188492, upload-time = "2026-06-29T20:02:36.721Z" }, + { url = "https://files.pythonhosted.org/packages/7e/43/174bf249286926518e77e29a52179a5c971544fa29affe8dee6ab33bcd5b/astropy_healpix-2.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:727588aebabb0bdf7f27aeb793a721090e9c62ab44c5dfe083c5a5ec4ad91df8", size = 198639, upload-time = "2026-06-29T20:02:41.547Z" }, + { url = "https://files.pythonhosted.org/packages/95/e1/2e57926e5c1e6a7b648b980656a3efd94ee58909fda577f7bf4fd701dca5/astropy_healpix-2.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:31c4f998f83e7be4245fa75a48767d7749b2f233ee61e134573106dfbe53c73c", size = 201015, upload-time = "2026-06-29T20:02:42.721Z" }, + { url = "https://files.pythonhosted.org/packages/93/96/ce466e4f53b59b8e0a89fd09824cce2532c5b9146279b7397d844f78cadf/astropy_healpix-2.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3eca64fb1640dcb6b5633db73a33b2d208f64c5339a454ca38f538be3cdc0a4b", size = 195935, upload-time = "2026-06-29T20:02:43.868Z" }, +] + +[[package]] +name = "astropy-iers-data" +version = "0.2026.7.6.1.1.20" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7f/e3/d32d2401c53fa1aaf118c963c51c4eb9cd10d074a72a52430904dc8ef46e/astropy_iers_data-0.2026.7.6.1.1.20.tar.gz", hash = "sha256:bc38de235802c9f006c8a04693706e2adcc9e7ac1cbf415dc042b5f0ac14f1f3", size = 1939850, upload-time = "2026-07-06T01:02:02.379Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8c/a3/1d816863674c610234afef9a444d4eb562689a3fa1a872ac5687b4e0eac4/astropy_iers_data-0.2026.7.6.1.1.20-py3-none-any.whl", hash = "sha256:7aa50fa7f6d13258357d1e17fa97f3a8c2f04b9a7429d056e986a91cc46576a0", size = 1994649, upload-time = "2026-07-06T01:02:00.977Z" }, +] + +[[package]] +name = "asttokens" +version = "3.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/be/a5/8e3f9b6771b0b408517c82d97aed8f2036509bc247d46114925e32fe33f0/asttokens-3.0.1.tar.gz", hash = "sha256:71a4ee5de0bde6a31d64f6b13f2293ac190344478f081c3d1bccfcf5eacb0cb7", size = 62308, upload-time = "2025-11-15T16:43:48.578Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/39/e7eaf1799466a4aef85b6a4fe7bd175ad2b1c6345066aa33f1f58d4b18d0/asttokens-3.0.1-py3-none-any.whl", hash = "sha256:15a3ebc0f43c2d0a50eeafea25e19046c68398e487b9f1f5b517f7c0f40f976a", size = 27047, upload-time = "2025-11-15T16:43:16.109Z" }, +] + +[[package]] +name = "async-lru" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e8/1f/989ecfef8e64109a489fff357450cb73fa73a865a92bd8c272170a6922c2/async_lru-2.3.0.tar.gz", hash = "sha256:89bdb258a0140d7313cf8f4031d816a042202faa61d0ab310a0a538baa1c24b6", size = 16332, upload-time = "2026-03-19T01:04:32.413Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/e2/c2e3abf398f80732e58b03be77bde9022550d221dd8781bf586bd4d97cc1/async_lru-2.3.0-py3-none-any.whl", hash = "sha256:eea27b01841909316f2cc739807acea1c623df2be8c5cfad7583286397bb8315", size = 8403, upload-time = "2026-03-19T01:04:30.883Z" }, +] + +[[package]] +name = "attrs" +version = "26.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9a/8e/82a0fe20a541c03148528be8cac2408564a6c9a0cc7e9171802bc1d26985/attrs-26.1.0.tar.gz", hash = "sha256:d03ceb89cb322a8fd706d4fb91940737b6642aa36998fe130a9bc96c985eff32", size = 952055, upload-time = "2026-03-19T14:22:25.026Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/64/b4/17d4b0b2a2dc85a6df63d1157e028ed19f90d4cd97c36717afef2bc2f395/attrs-26.1.0-py3-none-any.whl", hash = "sha256:c647aa4a12dfbad9333ca4e71fe62ddc36f4e63b2d260a37a8b83d2f043ac309", size = 67548, upload-time = "2026-03-19T14:22:23.645Z" }, +] + +[[package]] +name = "babel" +version = "2.18.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7d/b2/51899539b6ceeeb420d40ed3cd4b7a40519404f9baf3d4ac99dc413a834b/babel-2.18.0.tar.gz", hash = "sha256:b80b99a14bd085fcacfa15c9165f651fbb3406e66cc603abf11c5750937c992d", size = 9959554, upload-time = "2026-02-01T12:30:56.078Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/77/f5/21d2de20e8b8b0408f0681956ca2c69f1320a3848ac50e6e7f39c6159675/babel-2.18.0-py3-none-any.whl", hash = "sha256:e2b422b277c2b9a9630c1d7903c2a00d0830c409c59ac8cae9081c92f1aeba35", size = 10196845, upload-time = "2026-02-01T12:30:53.445Z" }, +] + +[[package]] +name = "beautifulsoup4" +version = "4.15.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "soupsieve", marker = "sys_platform == 'linux'" }, + { name = "typing-extensions", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/43/65/318323f98dbee45d42dff61d8f047181bc6f2268a9068cfad035a46be5af/beautifulsoup4-4.15.0.tar.gz", hash = "sha256:288e3ca7d54b06f2ac191970bc275c1939cb46d450b255bf6718b04aa37ab4f7", size = 632571, upload-time = "2026-06-07T16:44:20.453Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/c6/92fcd42f1ba33e1184263f25bfabf3d27c383410470f169e4b8163bf9c17/beautifulsoup4-4.15.0-py3-none-any.whl", hash = "sha256:d6f88de62e1d4e38ecb1077eb9724cd0eff29d2a08ca16a401e9b9e93f117cf9", size = 109924, upload-time = "2026-06-07T16:44:21.566Z" }, +] + +[[package]] +name = "bleach" +version = "6.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "webencodings", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/48/3c/e12ac860709702bd5ebeb9b56a4fe334f1001246ee1b8f2b7ee28912df7d/bleach-6.4.0.tar.gz", hash = "sha256:4202482733d85cedd04e59fcb2f89f4e4c7c385a78d3c3c23c30446843a37452", size = 204857, upload-time = "2026-06-05T13:01:13.734Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/58/9d/40b6267367182187139a4000b82a3b287d84d745bccd808e75d916920e9d/bleach-6.4.0-py3-none-any.whl", hash = "sha256:4b6b6a54fff2e69a3dde9d21cc6301220bee3c3cb792187d11403fd795031081", size = 165109, upload-time = "2026-06-05T13:01:12.504Z" }, +] + +[package.optional-dependencies] +css = [ + { name = "tinycss2", marker = "sys_platform == 'linux'" }, +] + +[[package]] +name = "blosc2" +version = "4.8.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "httpx", extra = ["http2"], marker = "sys_platform == 'linux'" }, + { name = "msgpack", marker = "sys_platform == 'linux'" }, + { name = "ndindex", marker = "sys_platform == 'linux'" }, + { name = "numexpr", marker = "platform_machine != 'wasm32' and sys_platform == 'linux'" }, + { name = "numpy", marker = "sys_platform == 'linux'" }, + { name = "pydantic", marker = "sys_platform == 'linux'" }, + { name = "rich", marker = "sys_platform == 'linux'" }, + { name = "threadpoolctl", marker = "platform_machine != 'wasm32' and sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c1/26/c5b32a553f002e91886213ec91ff56a2dd8555e5e78eb4c289addb208642/blosc2-4.8.0.tar.gz", hash = "sha256:9789c3248052be59e63d6debafec4cd59d0eb4a6fd1cbaced36865d5d40ffa63", size = 5681856, upload-time = "2026-07-10T09:38:33.592Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/79/54ea19add4199547d684f3a90c3cc0568b6d915403b15c3e4bc73d4bbf3b/blosc2-4.8.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:95b04eb8a769e98de9640915f9c5c0a3074714762958896440e5a479a96bf83e", size = 6704345, upload-time = "2026-07-10T09:37:56.942Z" }, + { url = "https://files.pythonhosted.org/packages/e3/b0/aa277d5952ac4c673924454277de0800c780bcdb15917e303dac8ea3840f/blosc2-4.8.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:12668fe516f18f783877457ddcc5072d80edf4939914e27acf900ef65e970e69", size = 7208868, upload-time = "2026-07-10T09:37:58.649Z" }, + { url = "https://files.pythonhosted.org/packages/ab/1b/765d2d38609d11e727f63c44f30abacccd59132e74f6e082b3741656f108/blosc2-4.8.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:90b1a86b9044b3b242d78d5ac1d62abb8af7b1da355eb8eb45978539f9df2eac", size = 6708353, upload-time = "2026-07-10T09:38:05.91Z" }, + { url = "https://files.pythonhosted.org/packages/ee/aa/c72f0ff0c1cfa7e3a06530453f9b5388e4bb6266b73608f58232f181d68c/blosc2-4.8.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c17ec006d2770a4710552b0f4f8ceb40654fda08fe5047b27ccb7b0f396c3c6e", size = 7214012, upload-time = "2026-07-10T09:38:07.685Z" }, + { url = "https://files.pythonhosted.org/packages/6e/54/d7b8a01b43751840d75908d57601f03711a7cf260d46140f4c09dff5f9d6/blosc2-4.8.0-cp313-cp313-pyemscripten_2025_0_wasm32.whl", hash = "sha256:2af9162e7712323b21ad4d6502326c21459b6851b758b0421aa0be2e8b9dc0c1", size = 2300187, upload-time = "2026-07-10T09:38:09.407Z" }, + { url = "https://files.pythonhosted.org/packages/2a/2d/0c9961009c422f366555574af4653f3c13ba73fe075efb31e7af42151af5/blosc2-4.8.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0bb7d94bffdef8304454bbb373b8e9bf41966f8ddb58c449782c649d4d6a395c", size = 6724604, upload-time = "2026-07-10T09:38:16.688Z" }, + { url = "https://files.pythonhosted.org/packages/6d/8e/cb14d6e21fa44255739e2dac8d66ec7fb3d7aee348f198cc943e45d84d76/blosc2-4.8.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ec3fc9ad1b2528b471670233e9cf631be104b8526cf4b958a74099f6756c98f6", size = 7217824, upload-time = "2026-07-10T09:38:18.951Z" }, + { url = "https://files.pythonhosted.org/packages/e0/1f/ea276e70d09ed406aba4012a47c7595ed772b25fc096fba8b9eac3494db9/blosc2-4.8.0-cp314-cp314-pyemscripten_2026_0_wasm32.whl", hash = "sha256:da018d11be4ac995aeb7b1a406c5cafce8c9f8a3ca8a540fe872a482de198b0d", size = 2297787, upload-time = "2026-07-10T09:38:20.871Z" }, + { url = "https://files.pythonhosted.org/packages/2f/b7/cba879eed1f510b3f034fbeea7db81cb535c822fe96ac62b5e47012c0b9b/blosc2-4.8.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8574afd38d20f953e9114d7362535ef0019a4c85f2a672e6f3b36dcd00a77f32", size = 6669949, upload-time = "2026-07-10T09:38:27.542Z" }, + { url = "https://files.pythonhosted.org/packages/07/5a/012f58a518bebf0d11931a5a12ba08955aa959cca59764ad38a8d82c9a1b/blosc2-4.8.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9f8b459e22059a3a794480df2c72ff008ab6c95b9799fa2979c1dd7830cf44e2", size = 7186485, upload-time = "2026-07-10T09:38:29.411Z" }, +] + +[[package]] +name = "cadcutils" +version = "1.6.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "distro", marker = "sys_platform == 'linux'" }, + { name = "lxml", marker = "sys_platform == 'linux'" }, + { name = "packaging", marker = "sys_platform == 'linux'" }, + { name = "pyopenssl", marker = "sys_platform == 'linux'" }, + { name = "requests", marker = "sys_platform == 'linux'" }, + { name = "setuptools", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fe/44/4964823c72c9e6a93e26de0118cead37fa3c3600b4677f0c06788c903c80/cadcutils-1.6.2.tar.gz", hash = "sha256:6e2d7822756d48a363bc5f857cd717f80aab760554df86518b957f8826a7a906", size = 94673, upload-time = "2026-06-22T17:35:47.303Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/a4/963d9e7f8a2c385a42b77b2791a67f1bff32aa9c48299af2e6cafb8f3a5a/cadcutils-1.6.2-py3-none-any.whl", hash = "sha256:a95323d422731b41f9d24c2f06785ea2231cf69d1cc6ccacc4175df72b988877", size = 164697, upload-time = "2026-06-22T17:35:45.6Z" }, +] + +[[package]] +name = "camb" +version = "1.6.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", marker = "sys_platform == 'linux'" }, + { name = "packaging", marker = "sys_platform == 'linux'" }, + { name = "scipy", marker = "sys_platform == 'linux'" }, + { name = "sympy", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6d/ad/f2e6446fbd94f7adc1474e1f4e40d2e7fa7e5e7143640cb8557d492f0a73/camb-1.6.6.tar.gz", hash = "sha256:9856202a5c05570256e52377b20431891c7b08b2e9c334e141fd08d2a085516f", size = 799344, upload-time = "2026-03-11T16:46:55.819Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c9/f6/9131f388386c50982b1b2992424deca857e7c019f4014dab0770de690a84/camb-1.6.6-py3-none-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:eded2dd7f19226ed4717535c07a029fc958b7c581549250da33a768e12c87b13", size = 1592029, upload-time = "2026-03-11T16:46:44.925Z" }, + { url = "https://files.pythonhosted.org/packages/41/53/9d0b3cf1a2a07a882adac9565074ac6974fb8b031c31da438d407db22c89/camb-1.6.6-py3-none-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bb8e0c85b3e33d78ca0676c84b0b60b54dfa72d4e520a805166cab0458e81094", size = 2258716, upload-time = "2026-03-11T16:46:46.458Z" }, +] + +[[package]] +name = "certifi" +version = "2026.6.17" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c9/c7/424b75da314c1045981bd9777432fad05a9e0c69daa4ed7e308bbaffe405/certifi-2026.6.17.tar.gz", hash = "sha256:024c88eeec92ca068db80f02b8b07c9cef7b9fe261d1d535abfd5abd6f6af432", size = 134594, upload-time = "2026-06-17T10:31:07.894Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/2f/c5464532e965badff2f4c4c1a3a83f5697f0d7c407ed0cda44aaa99bb451/certifi-2026.6.17-py3-none-any.whl", hash = "sha256:2227dcbaafe0d2f59279d1762ddddc37783ed4354594f194ffc31d20f41fc3db", size = 133289, upload-time = "2026-06-17T10:31:06.348Z" }, +] + +[[package]] +name = "cffi" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pycparser", marker = "implementation_name != 'PyPy' and sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/57/5f/ff100cae70ebe9d8df1c01a00e510e45d9adb5c1fdda84791b199141de97/cffi-2.1.0.tar.gz", hash = "sha256:efc1cdd798b1aaf39b4610bba7aad28c9bea9b910f25c784ccf9ec1fa719d1f9", size = 531036, upload-time = "2026-07-06T21:34:30.382Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c3/c0/d1ec30ffb370f748f2fb54425972bfef9871e0132e82fb589c46b6676049/cffi-2.1.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:5972433ad71a9e46516584ef60a0fda12d9dc459938d1539c3ddecf9bdc1368d", size = 214815, upload-time = "2026-07-06T21:32:48.557Z" }, + { url = "https://files.pythonhosted.org/packages/1b/dc/5620cf930688be01f2d673804291de757a934c90b946dbdc3d84130c2ea4/cffi-2.1.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b6422532152adf4e59b110cb2808cee7a033800952f5c036b4af047ee43199e7", size = 222429, upload-time = "2026-07-06T21:32:49.848Z" }, + { url = "https://files.pythonhosted.org/packages/4b/a4/77b53abbf7a1e0beb9637edbef2a94d15f9c822f591e85d439ffd91519a6/cffi-2.1.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:46b1c8db8f6122420f32d02fffb924c2fe9bc772d228c7c711748fff56aabb2b", size = 210315, upload-time = "2026-07-06T21:32:51.221Z" }, + { url = "https://files.pythonhosted.org/packages/58/0c/f528df19cc94b675087324d4760d9e6d5bfae97d6217aa4fac43de4f5fcc/cffi-2.1.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:d9fafc5aa2e2a39aaf7f8cc0c1f044a9b07fca12e558dca53a3cc5c654ad67a7", size = 208859, upload-time = "2026-07-06T21:32:52.512Z" }, + { url = "https://files.pythonhosted.org/packages/62/f2/c9522a81c32132799a1972c39f5c5f8b4c8b9f00488a23feaa6c06f07741/cffi-2.1.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1e9f50d192a3e525b15a75ab5114e442d83d657b7ec29182a991bc9a88fd3a66", size = 221844, upload-time = "2026-07-06T21:32:53.704Z" }, + { url = "https://files.pythonhosted.org/packages/6e/28/bd53988b9833e8f8ad539d26f4c07a6b3f6bcb1e9e02e7ca038250b3428d/cffi-2.1.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98fff996e983a36d3aa2eca83af40c5821202e7e6f32d13ae94e3d2286f10cfe", size = 225287, upload-time = "2026-07-06T21:32:54.907Z" }, + { url = "https://files.pythonhosted.org/packages/79/99/0d0fd37f055224085f42bbb2c022d002e17dde4a97972822327b07d84101/cffi-2.1.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:379de10ce1ba048b1448599d1b37b24caee16309d1ac98d3982fc997f768700b", size = 223681, upload-time = "2026-07-06T21:32:56.329Z" }, + { url = "https://files.pythonhosted.org/packages/96/88/a996879e2eeccb815f6e3a5967b12a308257412acec882039d386bd2aa7b/cffi-2.1.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:10537b1df4967ca26d21e5072d7d54188354483b91dc75058968d3f0cf13fbda", size = 194331, upload-time = "2026-07-06T21:33:03.697Z" }, + { url = "https://files.pythonhosted.org/packages/58/85/7ae00d5c8dd6266f4e944c3db630f3c5c9a98b61d469c714d848b1d8138a/cffi-2.1.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:a95b05f9baf29b91171b3a8bd2020b028835243e7b0ff6bb23e2a3c228518b1b", size = 196966, upload-time = "2026-07-06T21:33:05.353Z" }, + { url = "https://files.pythonhosted.org/packages/a0/1c/4ed5a0e5bdca6cbc275556de3328dd1b76fd0c11cc13c88fe66d1d8715f2/cffi-2.1.0-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:63960549e4f8dc41e31accb97b975abaecfc44c03e396c093a6436763c2ea7db", size = 214747, upload-time = "2026-07-06T21:33:09.671Z" }, + { url = "https://files.pythonhosted.org/packages/3a/a6/e879bb68cc23a2bc9ba8f4b7d8019f0c2694bad2ab6c4a3701d429439f58/cffi-2.1.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ff067a8d8d880e7809e4ac88eb009bb848870115317b306666502ccad30b147f", size = 222392, upload-time = "2026-07-06T21:33:10.896Z" }, + { url = "https://files.pythonhosted.org/packages/88/f6/01890cfd63c08f8eb96a8319b0443690197d240a8bd6346048cf7bde9190/cffi-2.1.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:3b926723c13eba9f81d2ef3820d63aeceec3b2d4639906047bf675cb8a7a500d", size = 210285, upload-time = "2026-07-06T21:33:12.251Z" }, + { url = "https://files.pythonhosted.org/packages/a6/cf/2b684132056f438567b61e19d690dd31cd0921ace051e0a458be6074369e/cffi-2.1.0-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:47ff3a8bfd8cb9da1af7524b965127095055654c177fcfc7578debcb015eecd0", size = 208801, upload-time = "2026-07-06T21:33:13.617Z" }, + { url = "https://files.pythonhosted.org/packages/6f/08/f2e7d62c460faae0926f2d6e423694aa409ced3bc1fe2927a0a6e5f05416/cffi-2.1.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:799416bae98336e400981ff6e532d67d5c709cfb30afb79865a1315f94b0e224", size = 221808, upload-time = "2026-07-06T21:33:15.466Z" }, + { url = "https://files.pythonhosted.org/packages/38/37/04f54b8e63a02f3d908332c9effbf8c366167c6f733ed8a3d4f79b7e2a1e/cffi-2.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:961be50688f7fba2fa65f63712d3b9b341a22311f5253460ce933f52f0de1c8c", size = 225241, upload-time = "2026-07-06T21:33:16.869Z" }, + { url = "https://files.pythonhosted.org/packages/a9/d6/c72eecca433cd3e681c65ed313ab4835d9d4a379704d0f628a6a05f51c2e/cffi-2.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bf5c6cf48238b0eb4c086978c492ad1cbc22373fc5b2d7353b3a598ce6db887a", size = 223588, upload-time = "2026-07-06T21:33:18.239Z" }, + { url = "https://files.pythonhosted.org/packages/d8/f0/81478e482afa03f6d18dc8f2afb5edc45b3080853b634b5ed91961be0998/cffi-2.1.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:d2117334c3af3bdcb9a88522b844a2bdb5efdc4f71c6c822df55486ae1c3347a", size = 194142, upload-time = "2026-07-06T21:33:23.657Z" }, + { url = "https://files.pythonhosted.org/packages/7d/95/8de304305cd9204974b0ca051b86d307cafca13aa575a0ef1b44d92c0d8c/cffi-2.1.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:702c436735fbe99d59ada02a1f65cfc0d31c0ee8b7290912f8fbc5cd1e4b16c3", size = 196819, upload-time = "2026-07-06T21:33:25.007Z" }, + { url = "https://files.pythonhosted.org/packages/2e/d2/065fcae1c73979fac8e054462478d0ff8a29c40cdc2ed7ea5676a061df53/cffi-2.1.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:276f20fffd7b396e12516ba8edf9509210ac248cbbc5acbc39cd512f9f59ebe6", size = 222353, upload-time = "2026-07-06T21:33:29.178Z" }, + { url = "https://files.pythonhosted.org/packages/ed/a5/e8bbb1ce5b3ac2f53ad6a10bde44318a5a8d99d4f4a000d44a6e39aeb3e4/cffi-2.1.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:7d5980a3433d4b71a5e120f9dd551403d7824e31e2e67124fe2769c404c06913", size = 210051, upload-time = "2026-07-06T21:33:30.534Z" }, + { url = "https://files.pythonhosted.org/packages/28/ed/c127d3ac36e899c965e3361357c3befacd6578c03f40125183e41c3b219e/cffi-2.1.0-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:6ca4919c6e4f89aa99c42510b42cf54596892c00b3f9077f6bdd1505e24b9c8d", size = 208630, upload-time = "2026-07-06T21:33:31.753Z" }, + { url = "https://files.pythonhosted.org/packages/cc/d7/97d3136f81db489ec8d1d67748c110d6c994268fd7528014aa9f2b085e4e/cffi-2.1.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:d53d10f7da99ae46f7373b9150393e9c5eab9b224909982b43832668de4779f5", size = 221593, upload-time = "2026-07-06T21:33:33.044Z" }, + { url = "https://files.pythonhosted.org/packages/d3/27/93195977168ee63aed233a1a0993a2178798654d1f4bddcdd321d6fd3b21/cffi-2.1.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c351efb95e832a853a29361675f33a7ce53de1a109cd73fd47af0712213aa4ce", size = 225146, upload-time = "2026-07-06T21:33:34.224Z" }, + { url = "https://files.pythonhosted.org/packages/b3/c1/6dbd291ee2ae5a50a034aa057207081f545923bbf15dad4511e985aafff5/cffi-2.1.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:dbf7c7a88e2bac086f06d14577332760bdeecc42bdec8ac4077f6260557d9326", size = 223240, upload-time = "2026-07-06T21:33:35.57Z" }, + { url = "https://files.pythonhosted.org/packages/14/d0/117dcd9209255ad8571fbc8c92ef32593a1d294dcec91ddc4e4db50606f2/cffi-2.1.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:eb4e8997a49aa2c08a3e43c9045d224448b8941d88e7ac163c7d383e560cbf98", size = 223899, upload-time = "2026-07-06T21:33:39.514Z" }, + { url = "https://files.pythonhosted.org/packages/b6/3d/f20f8b886b254e3ad10e15cd4186d3aed49f3e6a35ab37aab9f8f25f7c03/cffi-2.1.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:bf01d8c84cbea96b944c73b22182e6c7c432b3475632b8111dbfdc95ddad6e13", size = 211652, upload-time = "2026-07-06T21:33:40.851Z" }, + { url = "https://files.pythonhosted.org/packages/28/3b/fad54de07260b93ddeef4b96d0131d57ea900675df1d410ae1deee52d7a6/cffi-2.1.0-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:33eb1ad83ebe8f313e0df035c406227d55a79456704a863fad9842136af5ad7d", size = 210755, upload-time = "2026-07-06T21:33:42.183Z" }, + { url = "https://files.pythonhosted.org/packages/cc/82/3d5c705acb7abbba9bbd7d79b8e62e0f25b6120eb7ae6ac49f1b721722fe/cffi-2.1.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:ac0f1a2d0cfa7eea3f2aaf006ab6e70e8feeb16b75d65b7e5939982ca2f11056", size = 223933, upload-time = "2026-07-06T21:33:43.603Z" }, + { url = "https://files.pythonhosted.org/packages/6c/d0/47e338384ab6b1004241002fa616301020cea4fc95f283506565d252f276/cffi-2.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:c16914df9fb7f500e440e6875fa23ff5e0b31db01fa9c06af98d59a91f0dc2e4", size = 226749, upload-time = "2026-07-06T21:33:45.046Z" }, + { url = "https://files.pythonhosted.org/packages/70/25/65bd5b58ea4bfdfc15cde02cb5365f89ef8ab8b2adfb8fe5c4bd4233382f/cffi-2.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:5ecbd0499275d57506d397eebe1981cee87b47fcd9ef5c22cab7ed7644a39a94", size = 225703, upload-time = "2026-07-06T21:33:46.374Z" }, + { url = "https://files.pythonhosted.org/packages/55/c7/8c8c50cb11c6750051daf12164098a9a6f027ac4356967fd4d800a07f242/cffi-2.1.0-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:2e9dabb9abcb7ad15938c7196ad5c1718a4e6d33cc79b4c0209bdb64c4a54a5c", size = 194121, upload-time = "2026-07-06T21:33:56.109Z" }, + { url = "https://files.pythonhosted.org/packages/99/e2/67680bf19a6b60d2bb7ff83baefa2a4c3d2d7dc0f3277034b802e1fc504c/cffi-2.1.0-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:37f525a7e7e50c017fdebe58b787be310ad59357ae43a053943a6e1a6c526001", size = 196820, upload-time = "2026-07-06T21:33:57.288Z" }, + { url = "https://files.pythonhosted.org/packages/ef/c3/ad299dc38f3583f8d916b299f028af418a9ec98bc695fcbebeae7420691c/cffi-2.1.0-cp315-cp315-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:90bec57cf82089383bd06a605b3eb8daebf7e5a668520beaf6e327a83a947699", size = 222342, upload-time = "2026-07-06T21:34:01.814Z" }, + { url = "https://files.pythonhosted.org/packages/eb/d8/df4543cc087245044ed02ef3ad8e0a26619d0075ac7a77a12dc81177851b/cffi-2.1.0-cp315-cp315-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6274dcb2d15cef48daa73ed1be5a40d501d74dccd0cd6db364776d12cb6ba022", size = 210073, upload-time = "2026-07-06T21:34:03.255Z" }, + { url = "https://files.pythonhosted.org/packages/2c/0e/fac738d73728c6cea2a88a2883dca54892496cbba88a1dc1f2909cb8a6f5/cffi-2.1.0-cp315-cp315-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:2b71d409cccee78310ab5dec549aed052aaea483346e282c7b02362596e01bb0", size = 208551, upload-time = "2026-07-06T21:34:04.433Z" }, + { url = "https://files.pythonhosted.org/packages/e6/3f/0b04a700dd64f465c93020253a793a82c9b4dff9961f48facd0df945d9b8/cffi-2.1.0-cp315-cp315-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7d3538f9c0e50670f4deb93dbb696576e60590369cae2faf7de681e597a8a1f1", size = 221649, upload-time = "2026-07-06T21:34:06.157Z" }, + { url = "https://files.pythonhosted.org/packages/5d/7c/b7379a5704c79eda57ce075869ba70a0368d1c850f803b3c0d078d39dcaf/cffi-2.1.0-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:8f9ec95b8a043d3dfbc74d9abc6f7baf524dd27a8dc160b0a32ff9cdab650c28", size = 225203, upload-time = "2026-07-06T21:34:07.489Z" }, + { url = "https://files.pythonhosted.org/packages/5a/02/d5e6c43ea85c41bda2a184a3418f195fe7cf602967a8d2b94e085b83deef/cffi-2.1.0-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:af5e2915d41fe6c961694d7bfdc8562942638200f3ce2765dfb8b745cf997629", size = 223263, upload-time = "2026-07-06T21:34:08.712Z" }, + { url = "https://files.pythonhosted.org/packages/e0/27/1d0b408497e41a74795af122d7b603c418c5fed0171450f899afd04e594f/cffi-2.1.0-cp315-cp315t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0520e1f4c35f44e209cbbb421b67eec42e6a157f59444dfb6058874ff3610e5d", size = 223904, upload-time = "2026-07-06T21:34:12.606Z" }, + { url = "https://files.pythonhosted.org/packages/8b/31/e115c985105dd7ffb32444505f18ceb874bb42d992af05d5dced7ecf1980/cffi-2.1.0-cp315-cp315t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:3681e031db29958a7502f5c0c9d6bbc4c36cb20f7b104086fa642d1799631ff8", size = 211554, upload-time = "2026-07-06T21:34:13.987Z" }, + { url = "https://files.pythonhosted.org/packages/5a/67/9e6e09409336d9e515c58367e7cfcf4f89df06ad25252675595a58eb59d5/cffi-2.1.0-cp315-cp315t-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:762f99479dcb369f60ab9017ad4ab97a36a1dd7c1ee5a3b15db0f4b8659120cd", size = 210795, upload-time = "2026-07-06T21:34:15.972Z" }, + { url = "https://files.pythonhosted.org/packages/19/e5/d3cc82a4a0be7902af279c04181ad038449c096734464a5ae1de3e1401bd/cffi-2.1.0-cp315-cp315t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0611e7ebf90573a535ebdc33ae9da222d037853983e13359f580fab781ca017f", size = 223843, upload-time = "2026-07-06T21:34:17.509Z" }, + { url = "https://files.pythonhosted.org/packages/b9/65/b434abc97ce7cecc2c640fde160507c0ecc7e21544b483ba3325d2e2ea17/cffi-2.1.0-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:86cf8755a791f72c85dc287128cc62d4f24d392e3f1e15837245623f4a33cccc", size = 226773, upload-time = "2026-07-06T21:34:19.05Z" }, + { url = "https://files.pythonhosted.org/packages/b5/9f/d4dc66ca651eb1145a133314cda721abf13cfac3d28c4a0402263ae6ad75/cffi-2.1.0-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:ba00f661f8ba35d075c937174e27c2c421cec3942fd2e0ea3e66996757c0fdd9", size = 225719, upload-time = "2026-07-06T21:34:20.576Z" }, +] + +[[package]] +name = "charset-normalizer" +version = "3.4.9" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bd/2a/23f34ec9d04624958e137efdc394888716353190e75f25dd22c7a2c7a8aa/charset_normalizer-3.4.9.tar.gz", hash = "sha256:673611bbd43f0810bec0b0f028ddeaaa501190339cac411f347ac76917c3ae7b", size = 152439, upload-time = "2026-07-07T14:34:58.454Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/96/5d9364e3342d69f3a045e1777bc47c85c383e6e9466d561b33fdb419d1f9/charset_normalizer-3.4.9-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9b2aff1c7b3884512b9512c3eaadd9bab39fb45042ffaaa1dd08ff2b9f8109d9", size = 215802, upload-time = "2026-07-07T14:33:17.031Z" }, + { url = "https://files.pythonhosted.org/packages/4b/4c/5361f9aa7f2cb58d94f2ab831b3d493f69efb1d239654b4744e3c09527cb/charset_normalizer-3.4.9-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9104ed0bd76a429d46f9ec0dbc9b08ad1d2dcdf2b00a5a0daa1c145329b35b44", size = 237171, upload-time = "2026-07-07T14:33:18.576Z" }, + { url = "https://files.pythonhosted.org/packages/50/78/ce342ca4ff30b2eb49fe6d9578df85974f90c67d294113e94efdd9664cbd/charset_normalizer-3.4.9-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7b86a2b16095d250c6f58b3d9b2eee6f4147754344f3dab0922f7c9bf7d226c9", size = 233075, upload-time = "2026-07-07T14:33:20.084Z" }, + { url = "https://files.pythonhosted.org/packages/01/c4/4fa4c8b3097a11f3c5f09a35b72ed6855fb1d332469504962ab7bafcc702/charset_normalizer-3.4.9-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e226f6218febc71f6c1fc2fafb91c226f75bdc1d8fb12d66823716e891608fd", size = 224256, upload-time = "2026-07-07T14:33:21.747Z" }, + { url = "https://files.pythonhosted.org/packages/87/3a/ad914516df7e358a81aae018caa5e0470ba827fa6d763b1d2e87d920a5f6/charset_normalizer-3.4.9-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:90c44bc373b7687f6948b693cceaea1348ae0975d7474746559494468e3c1d84", size = 208784, upload-time = "2026-07-07T14:33:23.313Z" }, + { url = "https://files.pythonhosted.org/packages/d7/74/3c12f9755717dfe5c5c87da63f35d765fa0c00382ec26bf23f7fae34f2ba/charset_normalizer-3.4.9-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9cdef90ae47919cae358d8ab15797a800ed41da7aba5d72419fb510729e2ed4b", size = 219928, upload-time = "2026-07-07T14:33:24.814Z" }, + { url = "https://files.pythonhosted.org/packages/33/9a/895095b83e7907abd6d3d99aad3a38ad0d9686cc186cb0c94c24320fe63e/charset_normalizer-3.4.9-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:60f44ade2cf573dad7a277e6f8ca9a51a21dda572b13bd7d8539bb3cd5dbedde", size = 218489, upload-time = "2026-07-07T14:33:26.42Z" }, + { url = "https://files.pythonhosted.org/packages/a1/34/ef5c05f412f42520d7709b7d3784d19640839eb7366ded1755511585429f/charset_normalizer-3.4.9-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:a1786910334ed46ab1dd73222f2cd1e05c2c3bb39f6dddb4f8b36fc382058a39", size = 210267, upload-time = "2026-07-07T14:33:27.952Z" }, + { url = "https://files.pythonhosted.org/packages/83/dc/9b29fa4412b318bf3bfea985c35d67eb55e04b59a7c3f2237168b0e0be6f/charset_normalizer-3.4.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:03d07803992c6c7bbc976327f34b18b6160327fc81cb82c9d504720ac0be3b62", size = 226030, upload-time = "2026-07-07T14:33:29.397Z" }, + { url = "https://files.pythonhosted.org/packages/d0/39/8ff066c672434225f8d25f8b739f992af250944392173dcc88362681c9bf/charset_normalizer-3.4.9-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:21e764fd1e70b6a3e205a0e46f3051701f98a8cb3fad66eeb80e48bb502f8698", size = 214982, upload-time = "2026-07-07T14:33:36.996Z" }, + { url = "https://files.pythonhosted.org/packages/92/8f/3a47a3667c83c2df9483d91644c6c107de3bf8874aa1793da9d3012eb986/charset_normalizer-3.4.9-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e4fd89cc178bced6ad29cb3e6dd4aa63fa5017c3524dbd0b25998fb64a87cc8b", size = 236460, upload-time = "2026-07-07T14:33:38.536Z" }, + { url = "https://files.pythonhosted.org/packages/f1/60/b22cdbee7e4013dab8b0d7647fc6181120fbbbc8f7025c226d15bd5a47fc/charset_normalizer-3.4.9-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:bd47ba7fc3ca94896759ea0109775132d3e7ab921fbf54038e1bab2e46c313c9", size = 232003, upload-time = "2026-07-07T14:33:40.059Z" }, + { url = "https://files.pythonhosted.org/packages/ea/f8/72eb13dcabe7257035cea8aefd922caad2f110d252bf9f67c4c2ca763aee/charset_normalizer-3.4.9-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:84fd18bcc17526fc2b3c1af7d2b9217d32c9c04448c16ec693b9b4f1985c3d33", size = 223149, upload-time = "2026-07-07T14:33:41.631Z" }, + { url = "https://files.pythonhosted.org/packages/b0/3e/faee8f9de92b14ee1198e9163252bb15efee7301b31256a3b6d9ebfdd0dd/charset_normalizer-3.4.9-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:5b10cd92fc5c498b35a8635df6d5a100207f88b63a4dc1de7ef9a548e1e2cd63", size = 207901, upload-time = "2026-07-07T14:33:43.209Z" }, + { url = "https://files.pythonhosted.org/packages/3a/25/45f30093ae27dd7b92a793b61882a38685f993700113ca36e0c9c14965e1/charset_normalizer-3.4.9-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:a4fbdde9dd4a9ce5fd52c2b3a347bb50cc89483ef783f1cb00d408c13f7a96c0", size = 219176, upload-time = "2026-07-07T14:33:44.725Z" }, + { url = "https://files.pythonhosted.org/packages/48/18/c8f397329c35e32f6a837e488986f4ae03bd2abebc453b48714991630c2f/charset_normalizer-3.4.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:416c229f77e5ea25b3dfd4b582f8d73d7e43c22320302b9ab128a2d3a0b38efe", size = 217356, upload-time = "2026-07-07T14:33:46.192Z" }, + { url = "https://files.pythonhosted.org/packages/86/7e/5ce0bba863470fd1902d5e5843968951bddf38abe4742fc97116ef4598b3/charset_normalizer-3.4.9-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:75286256590a6320cf106a0d28970d3560aad9ee09aa7b34fb40524792436d35", size = 209614, upload-time = "2026-07-07T14:33:47.705Z" }, + { url = "https://files.pythonhosted.org/packages/6c/ef/2473d3c4d869155be4af1191111d59c4d5c4e0173026f7e85b176e23bf65/charset_normalizer-3.4.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:69b157c5d3292bcd443faca052f3096f637f1e074b98212a933c074ae23dc3b8", size = 224991, upload-time = "2026-07-07T14:33:49.238Z" }, + { url = "https://files.pythonhosted.org/packages/2b/f9/ef4a69ea338ad3c0deceea0f5f7d2380ae8b52132b06d652cb0d2cd86706/charset_normalizer-3.4.9-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a79d9f4d8001473a30c163556b3c3bfebec837495a412dde78b51672f6134f9", size = 215898, upload-time = "2026-07-07T14:33:56.334Z" }, + { url = "https://files.pythonhosted.org/packages/8c/e7/5ddfd76fc061eb52de219658a4aa431cbacadf0a0219c8854f00da50d289/charset_normalizer-3.4.9-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:33bdcc2a32c0a0e861f60841a512c8acc658c87c2ac59d89e3a46dacf7d866e4", size = 236718, upload-time = "2026-07-07T14:33:57.9Z" }, + { url = "https://files.pythonhosted.org/packages/49/ba/768fa3f36048d81c477a0ce61f813bc1454d80917ccfe550abd9f44f5e24/charset_normalizer-3.4.9-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f840ed6d8ecba8255df8c42b87fadeda98ddfc6eeec05e2dc66e26d46dd6f58a", size = 232519, upload-time = "2026-07-07T14:33:59.811Z" }, + { url = "https://files.pythonhosted.org/packages/f4/c4/b3e049d2aa3766180c78507110543d9d50894cc97f57de543f1be521dcdc/charset_normalizer-3.4.9-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c25fe15c70c59eb7c5ce8c06a1f3fa1da0ecc5ea1e7a5922c40fd2fa9b0d5046", size = 223143, upload-time = "2026-07-07T14:34:01.517Z" }, + { url = "https://files.pythonhosted.org/packages/19/79/55c32d06d76ae4feafe053f061f3e3ab70bcf19f4007797ce8c3efda7830/charset_normalizer-3.4.9-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:f7fb7d750cfa0a070d2c24e831fd3481019a60dd317ea2b39acbcebc08b6ed81", size = 206742, upload-time = "2026-07-07T14:34:03.04Z" }, + { url = "https://files.pythonhosted.org/packages/10/e0/47c079dd82d217c807479cd59ffd30af56307ea31c108b75758970459ad3/charset_normalizer-3.4.9-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4d1c96a7a18b9690a4d46df09e3e3382406ae3213727cd1019ebade1c4a81917", size = 219191, upload-time = "2026-07-07T14:34:04.657Z" }, + { url = "https://files.pythonhosted.org/packages/42/ab/b9bc2e77d6b44a7e46ef62ec5cac1c9a6ba7b9135a5d560f002696ec9995/charset_normalizer-3.4.9-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a4cfde78a9f2880208d16a93b795726a3017d5977e08d1e162a7a31322479c41", size = 218328, upload-time = "2026-07-07T14:34:06.115Z" }, + { url = "https://files.pythonhosted.org/packages/f1/78/c9c71d599f5aa2d42bcdd35cbbd46d7f535351a57e40ff7d8e5a7e219401/charset_normalizer-3.4.9-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:d4d6fcde76f94f5cb9e43e9e9a61f16dacefd228cbbf6f1a09bd9b219a92f1a1", size = 207406, upload-time = "2026-07-07T14:34:07.554Z" }, + { url = "https://files.pythonhosted.org/packages/f6/39/c914445c321a845097ce4f6ac7de9a18228a77b766272125a1ce00d851eb/charset_normalizer-3.4.9-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:898f0e9068ca27d37f8e83a5b962821df851532e6c4a7d615c1c033f9da6eedf", size = 225157, upload-time = "2026-07-07T14:34:09.061Z" }, + { url = "https://files.pythonhosted.org/packages/cd/91/7253a32e86b7e1d1239b1b36ba6dd0f021a21107ab33054b53119cc083b9/charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:51447e9aa2684679af07ca5021c3db526e0284347ebf4ffcec1154c3350cfe32", size = 223022, upload-time = "2026-07-07T14:34:17.248Z" }, + { url = "https://files.pythonhosted.org/packages/cb/32/2e64bd2be10e89c61e57ebe6a93fd98ae88eb7ebe414b5121f22c96c69eb/charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:cc1b0fff8ead343dae06305f954eb8468ba0ec1a97881f42489d198e4ce3c632", size = 241590, upload-time = "2026-07-07T14:34:18.813Z" }, + { url = "https://files.pythonhosted.org/packages/3d/ef/d96ec496cfea0c21db43b0ad03891308b02388d054cc902cf0e5a1ad6a88/charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:fa36ec09ef71d158186bc79e359ff5fdd6e7996fe8ab638f00d6b93139ba4fcf", size = 239584, upload-time = "2026-07-07T14:34:20.52Z" }, + { url = "https://files.pythonhosted.org/packages/d4/ce/9af95f7876194bd7a14e3dfe4a4de2e0bff02666a3910d72beafd06cc297/charset_normalizer-3.4.9-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:df115d4d83168fdf2cae48ef1ff6d1cb4c466364e30861b37121de0f3bf1b990", size = 230224, upload-time = "2026-07-07T14:34:22.189Z" }, + { url = "https://files.pythonhosted.org/packages/52/94/af74dde74a3996bd959c350709bfe50e297823d70a8c1cbd54b838880863/charset_normalizer-3.4.9-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:f86c6358749bd4fda175388691e3ba8c46e24c5347d0afd20f9b7edfc9faf07d", size = 212667, upload-time = "2026-07-07T14:34:23.857Z" }, + { url = "https://files.pythonhosted.org/packages/ee/f0/f1c4fe746c395922961b5916ed1d7d6e7d4c84851d19ed43cc89980ec953/charset_normalizer-3.4.9-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:32286a2c8d167e897177b673176c1e3e00d4057caf5d2b64eef9a3666b03018e", size = 227179, upload-time = "2026-07-07T14:34:25.586Z" }, + { url = "https://files.pythonhosted.org/packages/e4/56/6c745619ac397e8871e2bcd3cea1eec86b877488f33888b3aef5c3ed506e/charset_normalizer-3.4.9-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:83aed2c10721ddd90f68140685391b50811a880af20654c59af6b6c66c40513c", size = 225372, upload-time = "2026-07-07T14:34:27.212Z" }, + { url = "https://files.pythonhosted.org/packages/78/ad/98aae8630ac71f16711968e38a5acfecce41b778bf2f0312851020f565a8/charset_normalizer-3.4.9-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:cd6c3d4b783c556fa00bf540854e42f135e2f256abd29669fcd0da0f2dec79c2", size = 215222, upload-time = "2026-07-07T14:34:28.774Z" }, + { url = "https://files.pythonhosted.org/packages/f7/40/9593d54209765207a7f11073c06494c1721e4ca4a0a426c597679bf7f91e/charset_normalizer-3.4.9-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ee2f2a527e3c1a6e6411eb4209642e138b544a2d72fe5d0d76daf77b24063534", size = 231958, upload-time = "2026-07-07T14:34:30.345Z" }, + { url = "https://files.pythonhosted.org/packages/98/2b/f97f1c193fb855c345d678f5077d6926034db0722df74c8f057020e05a25/charset_normalizer-3.4.9-py3-none-any.whl", hash = "sha256:68e5f26a1ad57ded6d1cfb85331d1c1a195314756471d97758c48498bb4dcdf5", size = 64538, upload-time = "2026-07-07T14:34:56.993Z" }, +] + +[[package]] +name = "click" +version = "8.4.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/76/d4/81420972a676e8ffea40450d8c8c92943e7218a78fe9b64359836cc9876b/click-8.4.2.tar.gz", hash = "sha256:9a6cea6e60b17ebe0a44c5cc636d94f09bd66142c1cd7d8b4cd731c4917a15f6", size = 338000, upload-time = "2026-06-24T17:45:15.148Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/e2/79c688af8b210d232694e31e59da9f6ec747bae31c3f5946e4e9b98860d5/click-8.4.2-py3-none-any.whl", hash = "sha256:e6f9f66136c816745b9d65817da91d61d957fb16e02e4dcd0552553c5a197b76", size = 119243, upload-time = "2026-06-24T17:45:13.73Z" }, +] + +[[package]] +name = "clmm" +version = "1.16.10" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "astropy", marker = "sys_platform == 'linux'" }, + { name = "healpy", marker = "sys_platform == 'linux'" }, + { name = "matplotlib", marker = "sys_platform == 'linux'" }, + { name = "numpy", marker = "sys_platform == 'linux'" }, + { name = "qp-prob", marker = "sys_platform == 'linux'" }, + { name = "scipy", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/db/73/7ff76d487cdbcddb9c80ec03313db1b11f48fe4fcb5e1609b6eca5a73159/clmm-1.16.10.tar.gz", hash = "sha256:48273784419c038a89619b798a140153ad1e451390ff56074f3b6825c91ebe32", size = 72475, upload-time = "2025-12-04T17:30:11.47Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b0/a6/2a730fd1b23bb67c31c83449b12e74d6a3369681e63a098f02e353bdb77f/clmm-1.16.10-py3-none-any.whl", hash = "sha256:97e70d1bb7f45f994ab19c07b405688d984bd28399d6e31187012e8a0bf2feb6", size = 89434, upload-time = "2025-12-04T17:30:10.009Z" }, +] + +[[package]] +name = "cloudpickle" +version = "3.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/27/fb/576f067976d320f5f0114a8d9fa1215425441bb35627b1993e5afd8111e5/cloudpickle-3.1.2.tar.gz", hash = "sha256:7fda9eb655c9c230dab534f1983763de5835249750e85fbcef43aaa30a9a2414", size = 22330, upload-time = "2025-11-03T09:25:26.604Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/39/799be3f2f0f38cc727ee3b4f1445fe6d5e4133064ec2e4115069418a5bb6/cloudpickle-3.1.2-py3-none-any.whl", hash = "sha256:9acb47f6afd73f60dc1df93bb801b472f05ff42fa6c84167d25cb206be1fbf4a", size = 22228, upload-time = "2025-11-03T09:25:25.534Z" }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, +] + +[[package]] +name = "comm" +version = "0.2.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4c/13/7d740c5849255756bc17888787313b61fd38a0a8304fc4f073dfc46122aa/comm-0.2.3.tar.gz", hash = "sha256:2dc8048c10962d55d7ad693be1e7045d891b7ce8d999c97963a5e3e99c055971", size = 6319, upload-time = "2025-07-25T14:02:04.452Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/97/891a0971e1e4a8c5d2b20bbe0e524dc04548d2307fee33cdeba148fd4fc7/comm-0.2.3-py3-none-any.whl", hash = "sha256:c615d91d75f7f04f095b30d1c1711babd43bdc6419c1be9886a85f2f4e489417", size = 7294, upload-time = "2025-07-25T14:02:02.896Z" }, +] + +[[package]] +name = "conda-inject" +version = "1.3.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyyaml", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/a8/8dc86113c65c949cc72d651461d6e4c544b3302a85ed14a5298829e6a419/conda_inject-1.3.2.tar.gz", hash = "sha256:0b8cde8c47998c118d8ff285a04977a3abcf734caf579c520fca469df1cd0aac", size = 3635, upload-time = "2024-05-27T12:20:58.873Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/87/4c/fc30b69fb4062aee57e3ab7ff493647c4220144908f0839c619f912045bf/conda_inject-1.3.2-py3-none-any.whl", hash = "sha256:6e641b408980c2814e3e527008c30749117909a21ff47392f07ef807da93a564", size = 4133, upload-time = "2024-05-27T12:20:57.332Z" }, +] + +[[package]] +name = "configargparse" +version = "1.7.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3f/0b/30328302903c55218ffc5199646d0e9d28348ff26c02ba77b2ffc58d294a/configargparse-1.7.5.tar.gz", hash = "sha256:e3f9a7bb6be34d66b2e3c4a2f58e3045f8dfae47b0dc039f87bcfaa0f193fb0f", size = 53548, upload-time = "2026-03-11T02:19:38.144Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fe/19/3ba5e1b0bcc7b91aeab6c258afd70e4907d220fed3972febe38feb40db30/configargparse-1.7.5-py3-none-any.whl", hash = "sha256:1e63fdffedf94da9cd435fc13a1cd24777e76879dd2343912c1f871d4ac8c592", size = 27692, upload-time = "2026-03-11T02:19:36.442Z" }, +] + +[[package]] +name = "connection-pool" +version = "0.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bd/df/c9b4e25dce00f6349fd28aadba7b6c3f7431cc8bd4308a158fbe57b6a22e/connection_pool-0.0.3.tar.gz", hash = "sha256:bf429e7aef65921c69b4ed48f3d48d3eac1383b05d2df91884705842d974d0dc", size = 3795, upload-time = "2020-09-17T02:48:28.824Z" } + +[[package]] +name = "contourpy" +version = "1.3.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/58/01/1253e6698a07380cd31a736d248a3f2a50a7c88779a1813da27503cadc2a/contourpy-1.3.3.tar.gz", hash = "sha256:083e12155b210502d0bca491432bb04d56dc3432f95a979b429f2848c3dbe880", size = 13466174, upload-time = "2025-07-26T12:03:12.549Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d4/1c/a12359b9b2ca3a845e8f7f9ac08bdf776114eb931392fcad91743e2ea17b/contourpy-1.3.3-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:92d9abc807cf7d0e047b95ca5d957cf4792fcd04e920ca70d48add15c1a90ea7", size = 332653, upload-time = "2025-07-26T12:01:24.155Z" }, + { url = "https://files.pythonhosted.org/packages/63/12/897aeebfb475b7748ea67b61e045accdfcf0d971f8a588b67108ed7f5512/contourpy-1.3.3-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b2e8faa0ed68cb29af51edd8e24798bb661eac3bd9f65420c1887b6ca89987c8", size = 379536, upload-time = "2025-07-26T12:01:25.91Z" }, + { url = "https://files.pythonhosted.org/packages/43/8a/a8c584b82deb248930ce069e71576fc09bd7174bbd35183b7943fb1064fd/contourpy-1.3.3-cp312-cp312-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:626d60935cf668e70a5ce6ff184fd713e9683fb458898e4249b63be9e28286ea", size = 384397, upload-time = "2025-07-26T12:01:27.152Z" }, + { url = "https://files.pythonhosted.org/packages/cc/8f/ec6289987824b29529d0dfda0d74a07cec60e54b9c92f3c9da4c0ac732de/contourpy-1.3.3-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4d00e655fcef08aba35ec9610536bfe90267d7ab5ba944f7032549c55a146da1", size = 362601, upload-time = "2025-07-26T12:01:28.808Z" }, + { url = "https://files.pythonhosted.org/packages/05/0a/a3fe3be3ee2dceb3e615ebb4df97ae6f3828aa915d3e10549ce016302bd1/contourpy-1.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:451e71b5a7d597379ef572de31eeb909a87246974d960049a9848c3bc6c41bf7", size = 1331288, upload-time = "2025-07-26T12:01:31.198Z" }, + { url = "https://files.pythonhosted.org/packages/33/1d/acad9bd4e97f13f3e2b18a3977fe1b4a37ecf3d38d815333980c6c72e963/contourpy-1.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:459c1f020cd59fcfe6650180678a9993932d80d44ccde1fa1868977438f0b411", size = 1403386, upload-time = "2025-07-26T12:01:33.947Z" }, + { url = "https://files.pythonhosted.org/packages/73/23/90e31ceeed1de63058a02cb04b12f2de4b40e3bef5e082a7c18d9c8ae281/contourpy-1.3.3-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:348ac1f5d4f1d66d3322420f01d42e43122f43616e0f194fc1c9f5d830c5b286", size = 334672, upload-time = "2025-07-26T12:01:41.942Z" }, + { url = "https://files.pythonhosted.org/packages/ed/93/b43d8acbe67392e659e1d984700e79eb67e2acb2bd7f62012b583a7f1b55/contourpy-1.3.3-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:655456777ff65c2c548b7c454af9c6f33f16c8884f11083244b5819cc214f1b5", size = 381234, upload-time = "2025-07-26T12:01:43.499Z" }, + { url = "https://files.pythonhosted.org/packages/46/3b/bec82a3ea06f66711520f75a40c8fc0b113b2a75edb36aa633eb11c4f50f/contourpy-1.3.3-cp313-cp313-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:644a6853d15b2512d67881586bd03f462c7ab755db95f16f14d7e238f2852c67", size = 385169, upload-time = "2025-07-26T12:01:45.219Z" }, + { url = "https://files.pythonhosted.org/packages/4b/32/e0f13a1c5b0f8572d0ec6ae2f6c677b7991fafd95da523159c19eff0696a/contourpy-1.3.3-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4debd64f124ca62069f313a9cb86656ff087786016d76927ae2cf37846b006c9", size = 362859, upload-time = "2025-07-26T12:01:46.519Z" }, + { url = "https://files.pythonhosted.org/packages/33/71/e2a7945b7de4e58af42d708a219f3b2f4cff7386e6b6ab0a0fa0033c49a9/contourpy-1.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a15459b0f4615b00bbd1e91f1b9e19b7e63aea7483d03d804186f278c0af2659", size = 1332062, upload-time = "2025-07-26T12:01:48.964Z" }, + { url = "https://files.pythonhosted.org/packages/12/fc/4e87ac754220ccc0e807284f88e943d6d43b43843614f0a8afa469801db0/contourpy-1.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ca0fdcd73925568ca027e0b17ab07aad764be4706d0a925b89227e447d9737b7", size = 1403932, upload-time = "2025-07-26T12:01:51.979Z" }, + { url = "https://files.pythonhosted.org/packages/ae/15/e59f5f3ffdd6f3d4daa3e47114c53daabcb18574a26c21f03dc9e4e42ff0/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e4e6b05a45525357e382909a4c1600444e2a45b4795163d3b22669285591c1ae", size = 326751, upload-time = "2025-07-26T12:02:00.343Z" }, + { url = "https://files.pythonhosted.org/packages/0f/81/03b45cfad088e4770b1dcf72ea78d3802d04200009fb364d18a493857210/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ab3074b48c4e2cf1a960e6bbeb7f04566bf36b1861d5c9d4d8ac04b82e38ba20", size = 375486, upload-time = "2025-07-26T12:02:02.128Z" }, + { url = "https://files.pythonhosted.org/packages/0c/ba/49923366492ffbdd4486e970d421b289a670ae8cf539c1ea9a09822b371a/contourpy-1.3.3-cp313-cp313t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c3d53c796f8647d6deb1abe867daeb66dcc8a97e8455efa729516b997b8ed99", size = 388106, upload-time = "2025-07-26T12:02:03.615Z" }, + { url = "https://files.pythonhosted.org/packages/9f/52/5b00ea89525f8f143651f9f03a0df371d3cbd2fccd21ca9b768c7a6500c2/contourpy-1.3.3-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50ed930df7289ff2a8d7afeb9603f8289e5704755c7e5c3bbd929c90c817164b", size = 352548, upload-time = "2025-07-26T12:02:05.165Z" }, + { url = "https://files.pythonhosted.org/packages/32/1d/a209ec1a3a3452d490f6b14dd92e72280c99ae3d1e73da74f8277d4ee08f/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:4feffb6537d64b84877da813a5c30f1422ea5739566abf0bd18065ac040e120a", size = 1322297, upload-time = "2025-07-26T12:02:07.379Z" }, + { url = "https://files.pythonhosted.org/packages/bc/9e/46f0e8ebdd884ca0e8877e46a3f4e633f6c9c8c4f3f6e72be3fe075994aa/contourpy-1.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2b7e9480ffe2b0cd2e787e4df64270e3a0440d9db8dc823312e2c940c167df7e", size = 1391023, upload-time = "2025-07-26T12:02:10.171Z" }, + { url = "https://files.pythonhosted.org/packages/b1/71/f93e1e9471d189f79d0ce2497007731c1e6bf9ef6d1d61b911430c3db4e5/contourpy-1.3.3-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:22e9b1bd7a9b1d652cd77388465dc358dafcd2e217d35552424aa4f996f524f5", size = 335810, upload-time = "2025-07-26T12:02:18.9Z" }, + { url = "https://files.pythonhosted.org/packages/91/f9/e35f4c1c93f9275d4e38681a80506b5510e9327350c51f8d4a5a724d178c/contourpy-1.3.3-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a22738912262aa3e254e4f3cb079a95a67132fc5a063890e224393596902f5a4", size = 382871, upload-time = "2025-07-26T12:02:20.418Z" }, + { url = "https://files.pythonhosted.org/packages/b5/71/47b512f936f66a0a900d81c396a7e60d73419868fba959c61efed7a8ab46/contourpy-1.3.3-cp314-cp314-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:afe5a512f31ee6bd7d0dda52ec9864c984ca3d66664444f2d72e0dc4eb832e36", size = 386264, upload-time = "2025-07-26T12:02:21.916Z" }, + { url = "https://files.pythonhosted.org/packages/04/5f/9ff93450ba96b09c7c2b3f81c94de31c89f92292f1380261bd7195bea4ea/contourpy-1.3.3-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f64836de09927cba6f79dcd00fdd7d5329f3fccc633468507079c829ca4db4e3", size = 363819, upload-time = "2025-07-26T12:02:23.759Z" }, + { url = "https://files.pythonhosted.org/packages/3e/a6/0b185d4cc480ee494945cde102cb0149ae830b5fa17bf855b95f2e70ad13/contourpy-1.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1fd43c3be4c8e5fd6e4f2baeae35ae18176cf2e5cced681cca908addf1cdd53b", size = 1333650, upload-time = "2025-07-26T12:02:26.181Z" }, + { url = "https://files.pythonhosted.org/packages/43/d7/afdc95580ca56f30fbcd3060250f66cedbde69b4547028863abd8aa3b47e/contourpy-1.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6afc576f7b33cf00996e5c1102dc2a8f7cc89e39c0b55df93a0b78c1bd992b36", size = 1404833, upload-time = "2025-07-26T12:02:28.782Z" }, + { url = "https://files.pythonhosted.org/packages/66/06/8a475c8ab718ebfd7925661747dbb3c3ee9c82ac834ccb3570be49d129f4/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d304906ecc71672e9c89e87c4675dc5c2645e1f4269a5063b99b0bb29f232d13", size = 326748, upload-time = "2025-07-26T12:02:37.193Z" }, + { url = "https://files.pythonhosted.org/packages/b4/a3/c5ca9f010a44c223f098fccd8b158bb1cb287378a31ac141f04730dc49be/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca658cd1a680a5c9ea96dc61cdbae1e85c8f25849843aa799dfd3cb370ad4fbe", size = 375554, upload-time = "2025-07-26T12:02:38.894Z" }, + { url = "https://files.pythonhosted.org/packages/80/5b/68bd33ae63fac658a4145088c1e894405e07584a316738710b636c6d0333/contourpy-1.3.3-cp314-cp314t-manylinux_2_26_s390x.manylinux_2_28_s390x.whl", hash = "sha256:ab2fd90904c503739a75b7c8c5c01160130ba67944a7b77bbf36ef8054576e7f", size = 388118, upload-time = "2025-07-26T12:02:40.642Z" }, + { url = "https://files.pythonhosted.org/packages/40/52/4c285a6435940ae25d7410a6c36bda5145839bc3f0beb20c707cda18b9d2/contourpy-1.3.3-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b7301b89040075c30e5768810bc96a8e8d78085b47d8be6e4c3f5a0b4ed478a0", size = 352555, upload-time = "2025-07-26T12:02:42.25Z" }, + { url = "https://files.pythonhosted.org/packages/24/ee/3e81e1dd174f5c7fefe50e85d0892de05ca4e26ef1c9a59c2a57e43b865a/contourpy-1.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2a2a8b627d5cc6b7c41a4beff6c5ad5eb848c88255fda4a8745f7e901b32d8e4", size = 1322295, upload-time = "2025-07-26T12:02:44.668Z" }, + { url = "https://files.pythonhosted.org/packages/3c/b2/6d913d4d04e14379de429057cd169e5e00f6c2af3bb13e1710bcbdb5da12/contourpy-1.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:fd6ec6be509c787f1caf6b247f0b1ca598bef13f4ddeaa126b7658215529ba0f", size = 1391027, upload-time = "2025-07-26T12:02:47.09Z" }, +] + +[[package]] +name = "cosmo-numba" +version = "1.0.1.dev6+g188d272c6" +source = { git = "https://github.com/aguinot/cosmo-numba.git?rev=main#188d272c67d6d699d7cff7a7a53ded8dec759bb0" } +dependencies = [ + { name = "mpmath", marker = "sys_platform == 'linux'" }, + { name = "numba", marker = "sys_platform == 'linux'" }, + { name = "numbaquadpack", marker = "sys_platform == 'linux'" }, + { name = "numpy", marker = "sys_platform == 'linux'" }, + { name = "rocket-fft", marker = "sys_platform == 'linux'" }, + { name = "sympy", marker = "sys_platform == 'linux'" }, +] + +[[package]] +name = "cosmology" +version = "2022.10.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c9/38/04099bb2b6a626bd69a3f117afc60f2c47c08899e0730e0e48c898bf4745/cosmology-2022.10.9.tar.gz", hash = "sha256:0c2857c9bf1fdd09f1f11ab5765df0389a4101f3a900fa11251c3f37696f02d4", size = 8488, upload-time = "2022-10-10T10:18:16.229Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2e/2c/c80db37593ad593e3f6c60705fbdf690b33f22c89edd5507d2731346cd87/cosmology-2022.10.9-py3-none-any.whl", hash = "sha256:3903658c2474177a1a1c75771ae14458d93200c516f8fc6c3f4d776f3287b288", size = 9341, upload-time = "2022-10-10T10:18:14.928Z" }, +] + +[[package]] +name = "coverage" +version = "7.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cc/8b/adeb62ea8951f13c4c7fef2e7a85e1a06b499c8d8237ea589d496029e53f/coverage-7.15.0.tar.gz", hash = "sha256:9ac3fe7a1435986463eaa8ee253ae2f2a268709ba4ae5c7dd1f52a05391ad78f", size = 925362, upload-time = "2026-07-02T13:10:50.535Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f0/17/99fa688541ae1d6e84543a0e544f83de0c944815b63e9e7b1ed411d15036/coverage-7.15.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:e4d0bb73455bf97ab243a8f12c37c686ccf1c13bb614b7b85f1d062f06f42b2c", size = 252705, upload-time = "2026-07-02T13:09:05.059Z" }, + { url = "https://files.pythonhosted.org/packages/fb/02/6a95a5cd83b74839017ef9cf48d2d8c9ae60af919e17a3f336e6f9f1b7bd/coverage-7.15.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:20d9ccc4ebd0edc434d86dfd2a1dd2a8efa6b6b3073d0485a394fee86459ebb4", size = 255441, upload-time = "2026-07-02T13:09:06.559Z" }, + { url = "https://files.pythonhosted.org/packages/67/f2/406f6c57d600f68185942422c4c00f1a3255d60aee6e5fd961425cd9987e/coverage-7.15.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:20c8a976c365c8cb12f0cbd099508772ea41fb5fa80657a8506df0e11bd278c5", size = 256556, upload-time = "2026-07-02T13:09:08.197Z" }, + { url = "https://files.pythonhosted.org/packages/74/8e/d3fa48489c15ecdec1ba48fd61f68798555dddd2f6716f9ad42adeb1a2a9/coverage-7.15.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f948fd5ba1b9cbca91f0ae08b4c1ce2b139509149a435e2585d056d57d70bf01", size = 258815, upload-time = "2026-07-02T13:09:09.691Z" }, + { url = "https://files.pythonhosted.org/packages/47/2e/2d40ddd110462c6a2769677cf7f1c119a52b45f568978fc6c98e4cc0dd0f/coverage-7.15.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:f58185f06edf6ad68ec9fb155d63ef650c82f3fbd7e1770e2867751fb13158f4", size = 253117, upload-time = "2026-07-02T13:09:11.212Z" }, + { url = "https://files.pythonhosted.org/packages/51/c0/310782f0d7c3cb2b5ac05ba8d205fe91f24a36f6bf3256098f1782181c38/coverage-7.15.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:02adc79a920c73c647c5d117f55747df7f2de94571884758ce8bc58e04f0a796", size = 254475, upload-time = "2026-07-02T13:09:13.029Z" }, + { url = "https://files.pythonhosted.org/packages/86/f7/702da6c275f8ae6ade423d2877243122932c9b27f5403003b9ef8c927d12/coverage-7.15.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:6eb7c300fbed667fd6e3588eba71c1904cdb06110ca6fdf908c26bdd88b8e382", size = 252619, upload-time = "2026-07-02T13:09:14.699Z" }, + { url = "https://files.pythonhosted.org/packages/fb/84/c5b15a7e5ecba4e56218d772d99fe80a63e63f8d11f12783723a6005ab45/coverage-7.15.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:b5fb23fa2de9dce1f5c36c09066d8fcda16cd96e8e26686caa2d7cb9b567d65c", size = 256689, upload-time = "2026-07-02T13:09:16.103Z" }, + { url = "https://files.pythonhosted.org/packages/95/2f/c8b07559b57701230c61b23a953858c052890c12ef568d81780c6c46e92e/coverage-7.15.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:cec79341dbe6281484024979976d0c7f22beae08b4a254655decd25d42cbe766", size = 252189, upload-time = "2026-07-02T13:09:17.828Z" }, + { url = "https://files.pythonhosted.org/packages/6b/80/6d2f049dd3fd3dbfd60b62ba6b2162a04009e2c002ce70b24cf3878dec7a/coverage-7.15.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6c664c5444b1d970b1b2a450e21fb19ee5c9cfdf151ded2dda37260031cca0da", size = 254059, upload-time = "2026-07-02T13:09:19.304Z" }, + { url = "https://files.pythonhosted.org/packages/7b/19/3a80b97d3b2a5c77a01ae359c6bed20c13738fe3d9380f08616d4fec0281/coverage-7.15.0-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:bbcbb317c2e5ded5b21104af81c29f391be2af98d065693ffbe8d23949b948e5", size = 252227, upload-time = "2026-07-02T13:09:28.543Z" }, + { url = "https://files.pythonhosted.org/packages/a1/fa/b70062750686bd7da454da27927622f48bbac6990ac7a4c4a4653e7b0036/coverage-7.15.0-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:27f31ecb458da3f859aab3f15ada871eb7a7768807d88df4a9f186bb17737970", size = 254823, upload-time = "2026-07-02T13:09:30.177Z" }, + { url = "https://files.pythonhosted.org/packages/a9/09/dad6a75a2e561b9dc5086a8c5257a7591d584246f67e23e70d2995b89ab6/coverage-7.15.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:13fb759be317fdc62e0f56bffdf61cfcb45c7761ad6b71e3e583e71a67ae753c", size = 256059, upload-time = "2026-07-02T13:09:31.979Z" }, + { url = "https://files.pythonhosted.org/packages/e6/e7/b5d2941fa9564573d44b693a871ff3156f0c42cbefe977a09fa7fdc59971/coverage-7.15.0-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:d5cf007add5ab4bb8fa9f4c77e3732127c9e6cad501d7db43355fbfafca0be84", size = 258190, upload-time = "2026-07-02T13:09:34.035Z" }, + { url = "https://files.pythonhosted.org/packages/7c/1d/8e895bcde3c57ccd46d896dda5f2b3d5df761a1b0c6c9d450d175dedc632/coverage-7.15.0-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:cc78d9843bd576fbe2118248258d485e968dc535f95ed504a7b0867ba9b51389", size = 252456, upload-time = "2026-07-02T13:09:35.765Z" }, + { url = "https://files.pythonhosted.org/packages/14/4c/f6997da343ddeb959be82c3b05322793f92c071ad45f7cb8a96336e2dd5f/coverage-7.15.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a263060f1de0b4b74b4e089c2a70b8003b3781c733329a9c8fd54995328f9950", size = 254192, upload-time = "2026-07-02T13:09:37.445Z" }, + { url = "https://files.pythonhosted.org/packages/17/27/a0bc09d032267b9da89d95a2d874cfbef2a5aebbf0e87cf7aba221d79a99/coverage-7.15.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c48decf16e0dfd5b049c7d5e82200c23c08126719142998d4f172444e3d0529e", size = 252153, upload-time = "2026-07-02T13:09:39.422Z" }, + { url = "https://files.pythonhosted.org/packages/54/c0/77fc233d9fba07b244c40948c53fe27308b8f21732fb3417f87fbd6fd992/coverage-7.15.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:08fb028000ed0aaa0a4cbdfbb98be7cb42f370db973fbbb469733505ab20e13e", size = 256310, upload-time = "2026-07-02T13:09:41.006Z" }, + { url = "https://files.pythonhosted.org/packages/d5/24/601cecfb5825becacb8d45219a018a3b55b9dbaec624efdb0ea249d08be2/coverage-7.15.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:fb7dc0c3b7d8a1077abea0b8546ebc5e26d6ef6ecefc2f0f5ad2b8a53bdad837", size = 251974, upload-time = "2026-07-02T13:09:42.733Z" }, + { url = "https://files.pythonhosted.org/packages/47/1e/6f45e5a5b3d5484318d368702af6716b5ab8913b0428bec981a562fcf296/coverage-7.15.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6cb3602054ccbe9f0d8c2dc04bbeba90d5719236e2cd06e042ddd6d3fc7b6e37", size = 253745, upload-time = "2026-07-02T13:09:44.376Z" }, + { url = "https://files.pythonhosted.org/packages/a7/ce/22bae91e0b75445f68d365c7643ed0aa4880bbf77450ee74ca65bdae53a7/coverage-7.15.0-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:769e8ece11a596315ebf5aa7ec383aeeed016c091d2bf6363ffb996d41529092", size = 252286, upload-time = "2026-07-02T13:09:54.996Z" }, + { url = "https://files.pythonhosted.org/packages/dd/1e/bec5e32aa508615d9d7a2790effb25fb4dc28606e995816afe400b25ece3/coverage-7.15.0-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:65a6b6164ee5c39e2f3803f314292d6c61a607ba7fee253d1e03c42dc3903502", size = 254789, upload-time = "2026-07-02T13:09:56.678Z" }, + { url = "https://files.pythonhosted.org/packages/17/29/0e865435b4354e4a7c03b1b7920046d31d0a273d55decefea27e011cb9bf/coverage-7.15.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:75128817f95a5c45bb01d65fd2d8b9cb54bbe03d81608fb70e3e14b437ad56c2", size = 256135, upload-time = "2026-07-02T13:09:58.343Z" }, + { url = "https://files.pythonhosted.org/packages/84/ff/33a870b58a13325d62fc0a6c8f01fa0ff667cef60c7498e2382a147dfa18/coverage-7.15.0-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:9887bb428fe2d4cd4bee89bac1a6c9932f484afd5b36fbd4ff6ea5f825bb1f5e", size = 258449, upload-time = "2026-07-02T13:10:00.057Z" }, + { url = "https://files.pythonhosted.org/packages/18/7b/6fffe596bf3ddba8462758d02c5dad730fd91055a6634aa2e4226229181a/coverage-7.15.0-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:0bfc0be1f702042207a93a00523b1065ee1fe951e96edf311581c0bbc2e34888", size = 252313, upload-time = "2026-07-02T13:10:01.946Z" }, + { url = "https://files.pythonhosted.org/packages/58/1b/11468dd6c1676ab831a70cb9a8d4e198e8607fa0b7220ab918b73fe9bfbd/coverage-7.15.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:f64627d55def5a43282d70e08396672692f77e4da610a5bb8bb4060b432b6859", size = 254142, upload-time = "2026-07-02T13:10:04.065Z" }, + { url = "https://files.pythonhosted.org/packages/79/41/29328e21d16b1b95092c30dd700e08cf915bd3734f836df8f3bdb0e8fa9f/coverage-7.15.0-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:2c6f0fa473003905c6d5bac328ee4eba9fbea654f15bc24b8a3274b23363fa99", size = 252108, upload-time = "2026-07-02T13:10:06.11Z" }, + { url = "https://files.pythonhosted.org/packages/9b/de/05ccfb990439655b35afbfd8e0d13fe66677565a7d4eb38c3f5ef2635e1c/coverage-7.15.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:2bcf9afaf064172c6ec3c58a325a9957ad1178c05dd934e25f253321776e0676", size = 256385, upload-time = "2026-07-02T13:10:08.141Z" }, + { url = "https://files.pythonhosted.org/packages/51/0e/486828a3d2695ea7a2609f17ff572f6b01905e608379440a11da4b8dffbe/coverage-7.15.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:baf06bc987115d6fb938d403f7eab684a057766c490367999a2b71a6883110c6", size = 251923, upload-time = "2026-07-02T13:10:10.179Z" }, + { url = "https://files.pythonhosted.org/packages/18/c7/03582b6715f078e5e558354c87616d945b9894cda2dace8e4009b17035e4/coverage-7.15.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f0405f2ff97b1c4c0e782cb32e02f32369bcf2e6b618b591d67e1ea754575dfe", size = 253580, upload-time = "2026-07-02T13:10:12.052Z" }, + { url = "https://files.pythonhosted.org/packages/6d/b4/c0ca3028f42c9a08e51feb4561ef1192e5de99797cd1db5b04590c215bda/coverage-7.15.0-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:94c9686bfe8a9a6810297aecbd99beaa3445f9e8dc2f80b1382cca0d86b64461", size = 263267, upload-time = "2026-07-02T13:10:23.261Z" }, + { url = "https://files.pythonhosted.org/packages/5f/aa/a375e3846e5d3c013dc600b2a3231089055c73d77f5393dd2192a8d64da6/coverage-7.15.0-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9bd671c25f9d85f09d7ec481d0e43d5139f486c06a37139847a7ce569788af72", size = 265390, upload-time = "2026-07-02T13:10:25.152Z" }, + { url = "https://files.pythonhosted.org/packages/92/e1/5783cdabb797305e1c9e4809fea496d31834c51fa772514f73dc148bcfc9/coverage-7.15.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:110cbdf8d2e216577312cf06ccf85539c0e5a5420ef747e4a4719b5e483c88cd", size = 267811, upload-time = "2026-07-02T13:10:27.249Z" }, + { url = "https://files.pythonhosted.org/packages/85/31/96d8bbf58b8e9193bc8389574a91a0db48355ee98feb66aa6bf8d1b32eea/coverage-7.15.0-cp314-cp314t-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2c5d4619214f1d9993e7b00a8600d14614b7e9d84e89507460b126aa5e6559e5", size = 268928, upload-time = "2026-07-02T13:10:29.242Z" }, + { url = "https://files.pythonhosted.org/packages/5e/7a/5294567e811a1cb7eda93140c628fa050d66189da28da320f93d1d815c73/coverage-7.15.0-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:781a704516e2d8346fbbd5be6c6f3412dd824785146528b3a01816f26c081007", size = 262378, upload-time = "2026-07-02T13:10:31.107Z" }, + { url = "https://files.pythonhosted.org/packages/69/3f/3f48538421f899f28946f90a3d272136a4686e1abf461cc9249a783ee0f3/coverage-7.15.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:bd4a1b44bcb65ee29e947ac92bbee04956df3a6bfc6143641bb6cae7ede00fc9", size = 265263, upload-time = "2026-07-02T13:10:32.942Z" }, + { url = "https://files.pythonhosted.org/packages/ce/d3/092df15efcab8a9c1467ee960eb8019bbad3f9300d115d89ea6195f369ff/coverage-7.15.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:0e4950c9d6d3e39c64c991814ff315e2d0b9cb8152363594212c9e55208c0a8f", size = 262866, upload-time = "2026-07-02T13:10:35.104Z" }, + { url = "https://files.pythonhosted.org/packages/e5/ab/0254d2b88665efb2c57ad368cc77ab5de3435bd8d5add4729c1b0e79431e/coverage-7.15.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:fe9c87ff42e5472d80d21704972e1f96e104a0a599d77c5e35db5a3c562e2571", size = 266599, upload-time = "2026-07-02T13:10:37.05Z" }, + { url = "https://files.pythonhosted.org/packages/a8/79/1cfa4023e489ce6fbc7be4a5d442dbc375edb4f4fda39a352cedb53263c2/coverage-7.15.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:f00d5ae1dd2fe13fb8186e3e7d37bcbd8b25c0d764ff7d1b32cef9be058510a8", size = 261714, upload-time = "2026-07-02T13:10:38.966Z" }, + { url = "https://files.pythonhosted.org/packages/b7/eb/fee5c8665656be63f497418d410484637c438172568688e8ac92e06574e7/coverage-7.15.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:363ab38cc78b615f11c9cac3cf1d7eef950c18b9fdedfb9066f59461dcf84d68", size = 264025, upload-time = "2026-07-02T13:10:40.789Z" }, + { url = "https://files.pythonhosted.org/packages/52/30/21b2ad45959cd50e909e02ebac1e30b4ceb7162e91c11d4c570223a458b7/coverage-7.15.0-py3-none-any.whl", hash = "sha256:56da6a4cbe8f7e9e80bd072ca9cefe67d7106a440a7ec06519ec6507ac94ad19", size = 212632, upload-time = "2026-07-02T13:10:48.641Z" }, +] + +[[package]] +name = "cryptography" +version = "49.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi", marker = "platform_python_implementation != 'PyPy' and sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1f/99/d1c90d6041656cc6ee229dc99cd67fd0cd5aec3c5f7d72fffc27cc750054/cryptography-49.0.0.tar.gz", hash = "sha256:f89660a348f4f78a92366240a61404e337586ef7f5909a2fef59ca88ef505493", size = 854345, upload-time = "2026-06-12T20:02:30.512Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/09/41/3797cfaf69cae04a13ee78ebd83f0678d9c02b4779d21ce24445326f1a69/cryptography-49.0.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:36d1709f992593689b45bda411498d62c6e365f2ca00b84657d4dadd24de16db", size = 4692978, upload-time = "2026-06-12T20:01:21.305Z" }, + { url = "https://files.pythonhosted.org/packages/e6/8b/43011f7ebe515a8aa20d61f290a326cd890c2e738e16e59eaff8d9c3a412/cryptography-49.0.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0e959b578856a3924bc0cbb710fc12c387b9412a951389f3ca61704a9e25f325", size = 4716422, upload-time = "2026-06-12T20:01:48.566Z" }, + { url = "https://files.pythonhosted.org/packages/4a/91/01ce7303a4579e6d3a6abef01bd322848e9ea7a219adcabc5048b9033571/cryptography-49.0.0-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:53ecee2e23f7169b6117e99fc8a944e5e50f79e69758a83b52a00cb98ab2b2d2", size = 4700503, upload-time = "2026-06-12T20:02:47.091Z" }, + { url = "https://files.pythonhosted.org/packages/62/99/a2c95cf8293f07491e9e27c20cc4dcd18176d944e674679adeb1d0173fd6/cryptography-49.0.0-cp311-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:2eda353d8a27bcbcaa4cbed18994a74ab4d19a2ca897db188ea269ab9b71419b", size = 5309779, upload-time = "2026-06-12T20:02:08.987Z" }, + { url = "https://files.pythonhosted.org/packages/20/2c/0622f20ff02b2ef32558733443805dc82fd4c275be01b2d19d14676f3a1b/cryptography-49.0.0-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:2afe9051da7ae7bd5905da5a949280c7d2bb75682e188f650a9d0f2756b834c6", size = 4749683, upload-time = "2026-06-12T20:02:03.335Z" }, + { url = "https://files.pythonhosted.org/packages/a3/5b/c5246635d5fd3b64e0d45ae10e99fd32fe9676a79915ccfe5a61ba9af1a5/cryptography-49.0.0-cp311-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:0b82e28ee398a386f0807bba7884d30f25218855690f45115831bcce5d90822c", size = 4337874, upload-time = "2026-06-12T20:02:54.323Z" }, + { url = "https://files.pythonhosted.org/packages/6d/88/05563c7fe2e914e87d1a536d06fe83e66b4e1d95cb593e05aea375531da8/cryptography-49.0.0-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:ccac2bfebc306b862133e3bb71f3f6ee8bb525240089b2d952e4144b3a6d5da7", size = 4700283, upload-time = "2026-06-12T20:01:34.822Z" }, + { url = "https://files.pythonhosted.org/packages/c4/b6/d7696e4e890d6ae1469935164c9e5215c557671cb78d6e3f458ccceaa632/cryptography-49.0.0-cp311-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:d0527ce944105f257f605a827d6ebead966c752038b6e8656abb9c5edee6fc68", size = 5265844, upload-time = "2026-06-12T20:01:24.09Z" }, + { url = "https://files.pythonhosted.org/packages/a9/3c/f3ad17eecc1a57b0ba236dc01f90e783c51f4a2f35f64777cc4f47a184b2/cryptography-49.0.0-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:cbc77da8c523d5abd028635ba850a6966fcee2c82e2bf65a41d1d8afe0f98be9", size = 4749290, upload-time = "2026-06-12T20:01:30.848Z" }, + { url = "https://files.pythonhosted.org/packages/4f/01/339573cf1023163a400b0b5d16f6d507de413b9f60be6fd1b77feeaf6737/cryptography-49.0.0-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:b87e65d263b3e5d3bb92a57e2a6638e2f31110fa7aa890c7b2dbba42248d0a3f", size = 4834612, upload-time = "2026-06-12T20:01:29.246Z" }, + { url = "https://files.pythonhosted.org/packages/71/fd/577302e213a1be9468f92d1afef66fcf1ef83d516819d9992ca547f592bd/cryptography-49.0.0-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:66ec79c3904820572d7e987abdf304281f141d37ad9a489b8e97066e7b9b6459", size = 4980804, upload-time = "2026-06-12T20:01:42.853Z" }, + { url = "https://files.pythonhosted.org/packages/86/12/c48a424f38db03027be9f7ed5c7dc5de9933dbee992865f98b13727a009d/cryptography-49.0.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:196ecd6a36e4e9aa10270393bb98d8df88fccee0bf1e5128b91ae4eb4375896d", size = 4678835, upload-time = "2026-06-12T20:02:48.743Z" }, + { url = "https://files.pythonhosted.org/packages/68/28/8a3ad4653662c93fc44dc4e5d8fd374c25c42e07b34bbfbadf49cf57a5a8/cryptography-49.0.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:7abcee80084cda3f7691f3eb1ce480d8df49cec637b429aa35986c1de71738aa", size = 4697239, upload-time = "2026-06-12T20:02:56.03Z" }, + { url = "https://files.pythonhosted.org/packages/a8/b2/2193fc74f81aee4f9b62733133b73b5176718932ed8f2e4b03fa040480a6/cryptography-49.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:4ae387c9cb68ea569ca17e490d66d8142b81c3cc814bf179974b7d146e490bbb", size = 4685593, upload-time = "2026-06-12T20:02:50.666Z" }, + { url = "https://files.pythonhosted.org/packages/47/f1/1d3eaa243bfc5de4a187b22aa8c048b3e4980bfbe830ac46e6bac2e66947/cryptography-49.0.0-cp314-cp314t-manylinux_2_28_ppc64le.whl", hash = "sha256:f37d847238971164fdbc68ade6f6574aecc9c0af714190e2083429ff68f4ce9d", size = 5289961, upload-time = "2026-06-12T20:01:46.468Z" }, + { url = "https://files.pythonhosted.org/packages/58/39/2d51306721330c486495853eda1c567880ff036de15a14c4b74f399934af/cryptography-49.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:c2bc30226390d60ea19d9f82b19db005fe0452154a23c1c410c12ea801e43561", size = 4731145, upload-time = "2026-06-12T20:02:16.832Z" }, + { url = "https://files.pythonhosted.org/packages/17/50/983e838c7fd0d87fd8c969bcdd328edaf5f756e38df5281637424c155873/cryptography-49.0.0-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:07cab27cc7b7e0fd28e5e26bb9eeedde5c135c868b46de4a27845abe94af6122", size = 4321719, upload-time = "2026-06-12T20:02:52.611Z" }, + { url = "https://files.pythonhosted.org/packages/a7/f5/8f571d7e27c55bce9f76f026143bcb1e040a4233149ecca0bea5fa5dd5f7/cryptography-49.0.0-cp314-cp314t-manylinux_2_34_aarch64.whl", hash = "sha256:b20133d204d2bb56ba047642199603876c872026ca53e79c35b83772ab2cc505", size = 4685209, upload-time = "2026-06-12T20:02:07.282Z" }, + { url = "https://files.pythonhosted.org/packages/e7/84/0e27016a6fc5a0886f797018b26aa42f40c09a82332bff77822a451deaaa/cryptography-49.0.0-cp314-cp314t-manylinux_2_34_ppc64le.whl", hash = "sha256:b970c6da94d5bb18629db453d14f2a1300f6bf59b61e9b82377931ef95504866", size = 5246285, upload-time = "2026-06-12T20:01:32.439Z" }, + { url = "https://files.pythonhosted.org/packages/11/2d/5e1fb307cb5931881516b464c98774b3f2c36b5d4bb9a2830253cf553cad/cryptography-49.0.0-cp314-cp314t-manylinux_2_34_x86_64.whl", hash = "sha256:d8ecde755e2e91bf773fc94e8c9d730cd7f2007004cb492263a794ec3899a1c8", size = 4730441, upload-time = "2026-06-12T20:02:01.469Z" }, + { url = "https://files.pythonhosted.org/packages/e4/c0/bff5a02ee731d207d6a1ed51732549d8c53d2bc8da1d10ec6f2844201d68/cryptography-49.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e3fb64c420688e5319ae25113a354015abbd8dffbfbc41781a1ea66fc7622ac3", size = 4815869, upload-time = "2026-06-12T20:01:36.574Z" }, + { url = "https://files.pythonhosted.org/packages/b9/26/814681d14248d95d73d5c3eea0c39a94eb8302df966f670a2c60de90974b/cryptography-49.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:32703d93296f5c1f4b53349ad3a250c2cae0fdecd3a3dd5d47e616d8d616af27", size = 4960948, upload-time = "2026-06-12T20:02:18.688Z" }, + { url = "https://files.pythonhosted.org/packages/3d/df/40577043ca124e17012f408ddddaeb213b856336ac82ddb3bc915f39e29f/cryptography-49.0.0-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f78ff2c9ed8dc2d036b0f4d640e22522213d047c1b14e61205a7e55c80a494d4", size = 4692429, upload-time = "2026-06-12T20:01:53.628Z" }, + { url = "https://files.pythonhosted.org/packages/2c/99/2d13299eb3dd27b02dcfaafcc91d6b5cb3329f7cbd6d8f51921acd566c1a/cryptography-49.0.0-cp39-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:35b151772baff2c74cba7fa290ceaff4c3b11c0c881eb93eb5dbc05a7cfbba18", size = 4700968, upload-time = "2026-06-12T20:02:45.383Z" }, + { url = "https://files.pythonhosted.org/packages/a5/4d/9c0cd02f95e2602dd5e563da149ee0830abef3537be8b34dc56281ebe27a/cryptography-49.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:0f21641cf4b30fca7aee061ced0ec7ad7b073518088b7c9969a297c0ae796c69", size = 4697758, upload-time = "2026-06-12T20:01:41.13Z" }, + { url = "https://files.pythonhosted.org/packages/24/01/186c825898477d77e2324d5360fefe622ff1d8d1963ec0554e2cada8ec77/cryptography-49.0.0-cp39-abi3-manylinux_2_28_ppc64le.whl", hash = "sha256:9e82dcc8e56052715fb18b2429e3bca4823b1629136a2084fc45a9a5cecb9b64", size = 5298863, upload-time = "2026-06-12T20:02:24.579Z" }, + { url = "https://files.pythonhosted.org/packages/b8/7b/62cbbab75d0659865bf0273790031544a0b16c8072d258f9428dcd8190dc/cryptography-49.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:6f2debedf9ca60cf1d5bd466475638af5130f89965605cd818484d19987d3a21", size = 4735983, upload-time = "2026-06-12T20:01:50.14Z" }, + { url = "https://files.pythonhosted.org/packages/6c/72/3e798c064bc39e471008075d0f9bc9daf77a80879c092e4a8e170c585ed4/cryptography-49.0.0-cp39-abi3-manylinux_2_31_armv7l.whl", hash = "sha256:8c25ceb16df5b9435f3f6a9829204985b0e0cbee3b48aacd432c7d2c850b44d9", size = 4334173, upload-time = "2026-06-12T20:01:44.743Z" }, + { url = "https://files.pythonhosted.org/packages/f0/ee/6fca21d1ac73e06f8bef71940abfd4d2f6472b4bca284d770f32bd4086f6/cryptography-49.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:28d8b15e6275f12c8a207dc309dfa957903c927d08d0cc937ee3f63f200693cc", size = 4697298, upload-time = "2026-06-12T20:02:20.918Z" }, + { url = "https://files.pythonhosted.org/packages/67/d0/a5fcd3515f0bae49a7b6d0413cc1bdccdcc1fc0047037a0d480642cdc5d6/cryptography-49.0.0-cp39-abi3-manylinux_2_34_ppc64le.whl", hash = "sha256:6fc361c34fb6aac015ce19435876635e5c6d21db31998b0920f675f131e043b8", size = 5254338, upload-time = "2026-06-12T20:02:22.737Z" }, + { url = "https://files.pythonhosted.org/packages/a0/84/84fe36f19caf857d61cb7fc9c63035a47ffabd84ea12d1d393148efa3615/cryptography-49.0.0-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:2400ef9c9e2299a25614eb1dea3db54a69b1349efd043bfac9c67630d136df36", size = 4735650, upload-time = "2026-06-12T20:02:41.389Z" }, + { url = "https://files.pythonhosted.org/packages/6c/a0/db537264e234f7273a73ec020873d6d6b39dfd8a53db78b550ca8320440e/cryptography-49.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:67e1d20ad9ef3a563c59ef22e7a8a0b8210bd26604369ea4a30a7c66aefe504e", size = 4834820, upload-time = "2026-06-12T20:01:51.847Z" }, + { url = "https://files.pythonhosted.org/packages/93/77/8df9eb486495979bccecd1062e2eaf435250e84437040295b57d09048b0b/cryptography-49.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:42b0684e0e40cf26122427802486f6d93aea593612603a94fbf260c7eb1e9c1b", size = 4967968, upload-time = "2026-06-12T20:02:12.524Z" }, +] + +[[package]] +name = "cs-util" +version = "0.2.2" +source = { git = "https://github.com/CosmoStat/cs_util.git?rev=develop#bedcdbf50ac57fc4d0b72a62b251373cd1807824" } +dependencies = [ + { name = "astropy", marker = "sys_platform == 'linux'" }, + { name = "camb", marker = "sys_platform == 'linux'" }, + { name = "datetime", marker = "sys_platform == 'linux'" }, + { name = "healpy", marker = "sys_platform == 'linux'" }, + { name = "healsparse", marker = "sys_platform == 'linux'" }, + { name = "keyring", marker = "sys_platform == 'linux'" }, + { name = "matplotlib", marker = "sys_platform == 'linux'" }, + { name = "numpy", marker = "sys_platform == 'linux'" }, + { name = "pyccl", marker = "sys_platform == 'linux'" }, + { name = "scipy", marker = "sys_platform == 'linux'" }, + { name = "swig", marker = "sys_platform == 'linux'" }, + { name = "vos", marker = "sys_platform == 'linux'" }, +] + +[[package]] +name = "cycler" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a9/95/a3dbbb5028f35eafb79008e7522a75244477d2838f38cbb722248dabc2a8/cycler-0.12.1.tar.gz", hash = "sha256:88bb128f02ba341da8ef447245a9e138fae777f6a23943da4540077d3601eb1c", size = 7615, upload-time = "2023-10-07T05:32:18.335Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/05/c19819d5e3d95294a6f5947fb9b9629efb316b96de511b418c53d245aae6/cycler-0.12.1-py3-none-any.whl", hash = "sha256:85cef7cff222d8644161529808465972e51340599459b8ac3ccbac5a854e0d30", size = 8321, upload-time = "2023-10-07T05:32:16.783Z" }, +] + +[[package]] +name = "dask" +version = "2026.7.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click", marker = "sys_platform == 'linux'" }, + { name = "cloudpickle", marker = "sys_platform == 'linux'" }, + { name = "fsspec", marker = "sys_platform == 'linux'" }, + { name = "packaging", marker = "sys_platform == 'linux'" }, + { name = "partd", marker = "sys_platform == 'linux'" }, + { name = "pyyaml", marker = "sys_platform == 'linux'" }, + { name = "toolz", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4d/b5/aa50877159f1efd65a744107e0662a15d2b80fa0c427d980313367f49493/dask-2026.7.0.tar.gz", hash = "sha256:b039970642ce97a063070bae2763dada8aae27e3cbd8ff6d894072f920a1e252", size = 11548914, upload-time = "2026-07-06T16:58:36.496Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/90/aa/ceeb81d9dc886d445416310f0eff5c3978f20224b4143e96e36b7e85b011/dask-2026.7.0-py3-none-any.whl", hash = "sha256:68def8b467529ab8425ef9fcc6735dcaefaaf715d5e19ae219485f99a394dbef", size = 1496878, upload-time = "2026-07-06T16:58:34.597Z" }, +] + +[package.optional-dependencies] +array = [ + { name = "numpy", marker = "sys_platform == 'linux'" }, +] + +[[package]] +name = "dask-image" +version = "2026.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "dask", extra = ["array"], marker = "sys_platform == 'linux'" }, + { name = "numpy", marker = "sys_platform == 'linux'" }, + { name = "pims", marker = "sys_platform == 'linux'" }, + { name = "scipy", marker = "sys_platform == 'linux'" }, + { name = "tifffile", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cc/49/e592a13a5e1efdcdb8f1faab7c4e309c61648792e276f9ced5fb79381b33/dask_image-2026.5.0.tar.gz", hash = "sha256:ed6b462277e691b2c12b0890ba801a0f9a00cc1894b0aa71b195a7a1419b2b00", size = 80457, upload-time = "2026-05-27T14:05:57.383Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/5b/15d6d6ff8697b188787609be059fe4f07f99fc00f43f68e9e1540fa8733e/dask_image-2026.5.0-py3-none-any.whl", hash = "sha256:acf86cd7f0f1e97804198d30b7cc931efd29f9dec86c65ec004b50405c3f5227", size = 43814, upload-time = "2026-05-27T14:05:56.237Z" }, +] + +[[package]] +name = "datetime" +version = "6.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pytz", marker = "sys_platform == 'linux'" }, + { name = "zope-interface", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/77/32/decbfd165e9985ba9d8c2d34a39afe5aeba2fc3fe390eb6e9ef1aab98fa8/datetime-6.0.tar.gz", hash = "sha256:c1514936d2f901e10c8e08d83bf04e6c9dbd7ca4f244da94fec980980a3bc4d5", size = 64167, upload-time = "2025-11-25T08:00:34.586Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cf/7a/ea0f3e3ea74be36fc7cf54f966cde732a3de72697983cdb5646b0a4dacde/datetime-6.0-py3-none-any.whl", hash = "sha256:d19988f0657a4e72c9438344157254a8dcad6aea8cd5ae70a5d1b5a75e5dc930", size = 52637, upload-time = "2025-11-25T08:00:33.077Z" }, +] + +[[package]] +name = "debugpy" +version = "1.8.21" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f2/aa/12037145b7a56eaa5b29b41872f7a21b538e807e13f32c4d3c46e59be084/debugpy-1.8.21.tar.gz", hash = "sha256:a3c53278e84c94e11bd87c53970ec391d1a67396c8b22609fcac576520e611a6", size = 1697577, upload-time = "2026-06-01T19:30:35.156Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/bf/09/59324b903599031ff9faaec1758292409f6561a0ec2492fe4b703327705a/debugpy-1.8.21-cp312-cp312-manylinux_2_34_x86_64.whl", hash = "sha256:c193d474f0a211191f2b4449d2d06157c689013035bd952f3b617e0ef422b176", size = 3968900, upload-time = "2026-06-01T19:30:52.341Z" }, + { url = "https://files.pythonhosted.org/packages/48/57/412421516afc3055fa577516f00beec3d663f9b0ab330639547ae6c57720/debugpy-1.8.21-cp313-cp313-manylinux_2_34_x86_64.whl", hash = "sha256:ecbd158386c31ffe71d46f72d44d56e66331ab9b16cad649156d514368f23ab2", size = 3962096, upload-time = "2026-06-01T19:30:59.235Z" }, + { url = "https://files.pythonhosted.org/packages/8c/2d/6e7ec524984a1702777868de49a4c53202bddac2a432a76a093469587750/debugpy-1.8.21-cp314-cp314-manylinux_2_34_x86_64.whl", hash = "sha256:3d6922439bf33fd38a3e2c447869ebc7b97da5cd3d329ff1ef9bc06c4903437e", size = 3927115, upload-time = "2026-06-01T19:31:05.863Z" }, + { 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 = "decorator" +version = "5.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/60/8b/32f9823da46cde7df2087faa08cd98d01b908f8dcab982cdba9c84e85355/decorator-5.3.1.tar.gz", hash = "sha256:4cbcdd55a6efadb9dbea26b858f4fb3264567b52d69ca0d25b721b553f60ea82", size = 58084, upload-time = "2026-05-18T06:03:28.057Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/05/7f/798705f5296a58ca505d600456748d1be48078eac8a7050d8a98bc9edb89/decorator-5.3.1-py3-none-any.whl", hash = "sha256:f47fe6fdbd2edd623ecfe36875d37aba411624e2670dd395dddae1358689bb3c", size = 10365, upload-time = "2026-05-18T06:03:26.517Z" }, +] + +[[package]] +name = "defusedxml" +version = "0.7.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/d5/c66da9b79e5bdb124974bfe172b4daf3c984ebd9c2a06e2b8a4dc7331c72/defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69", size = 75520, upload-time = "2021-03-08T10:59:26.269Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/6c/aa3f2f849e01cb6a001cd8554a88d4c77c5c1a31c95bdf1cf9301e6d9ef4/defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61", size = 25604, upload-time = "2021-03-08T10:59:24.45Z" }, +] + +[[package]] +name = "deprecated" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "wrapt", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/49/85/12f0a49a7c4ffb70572b6c2ef13c90c88fd190debda93b23f026b25f9634/deprecated-1.3.1.tar.gz", hash = "sha256:b1b50e0ff0c1fddaa5708a2c6b0a6588bb09b892825ab2b214ac9ea9d92a5223", size = 2932523, upload-time = "2025-10-30T08:19:02.757Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/84/d0/205d54408c08b13550c733c4b85429e7ead111c7f0014309637425520a9a/deprecated-1.3.1-py2.py3-none-any.whl", hash = "sha256:597bfef186b6f60181535a29fbe44865ce137a5079f295b479886c82729d5f3f", size = 11298, upload-time = "2025-10-30T08:19:00.758Z" }, +] + +[[package]] +name = "dill" +version = "0.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/81/e1/56027a71e31b02ddc53c7d65b01e68edf64dea2932122fe7746a516f75d5/dill-0.4.1.tar.gz", hash = "sha256:423092df4182177d4d8ba8290c8a5b640c66ab35ec7da59ccfa00f6fa3eea5fa", size = 187315, upload-time = "2026-01-19T02:36:56.85Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/77/dc8c558f7593132cf8fefec57c4f60c83b16941c574ac5f619abb3ae7933/dill-0.4.1-py3-none-any.whl", hash = "sha256:1e1ce33e978ae97fcfcff5638477032b801c46c7c65cf717f95fbc2248f79a9d", size = 120019, upload-time = "2026-01-19T02:36:55.663Z" }, +] + +[[package]] +name = "distro" +version = "1.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fc/f8/98eea607f65de6527f8a2e8885fc8015d3e6f5775df186e443e0964a11c3/distro-1.9.0.tar.gz", hash = "sha256:2fa77c6fd8940f116ee1d6b94a2f90b13b5ea8d019b98bc8bafdcabcdd9bdbed", size = 60722, upload-time = "2023-12-24T09:54:32.31Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/12/b3/231ffd4ab1fc9d679809f356cebee130ac7daa00d6d6f3206dd4fd137e9e/distro-1.9.0-py3-none-any.whl", hash = "sha256:7bffd925d65168f85027d8da9af6bddab658135b840670a223589bc0c8ef02b2", size = 20277, upload-time = "2023-12-24T09:54:30.421Z" }, +] + +[[package]] +name = "docutils" +version = "0.22.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ae/b6/03bb70946330e88ffec97aefd3ea75ba575cb2e762061e0e62a213befee8/docutils-0.22.4.tar.gz", hash = "sha256:4db53b1fde9abecbb74d91230d32ab626d94f6badfc575d6db9194a49df29968", size = 2291750, upload-time = "2025-12-18T19:00:26.443Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/10/5da547df7a391dcde17f59520a231527b8571e6f46fc8efb02ccb370ab12/docutils-0.22.4-py3-none-any.whl", hash = "sha256:d0013f540772d1420576855455d050a2180186c91c15779301ac2ccb3eeb68de", size = 633196, upload-time = "2025-12-18T19:00:18.077Z" }, +] + +[[package]] +name = "donfig" +version = "0.8.1.post1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pyyaml", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/25/71/80cc718ff6d7abfbabacb1f57aaa42e9c1552bfdd01e64ddd704e4a03638/donfig-0.8.1.post1.tar.gz", hash = "sha256:3bef3413a4c1c601b585e8d297256d0c1470ea012afa6e8461dc28bfb7c23f52", size = 19506, upload-time = "2024-05-23T14:14:31.513Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/d5/c5db1ea3394c6e1732fb3286b3bd878b59507a8f77d32a2cebda7d7b7cd4/donfig-0.8.1.post1-py3-none-any.whl", hash = "sha256:2a3175ce74a06109ff9307d90a230f81215cbac9a751f4d1c6194644b8204f9d", size = 21592, upload-time = "2024-05-23T14:13:55.283Z" }, +] + +[[package]] +name = "dpath" +version = "2.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b5/ce/e1fd64d36e4a5717bd5e6b2ad188f5eaa2e902fde871ea73a79875793fc9/dpath-2.2.0.tar.gz", hash = "sha256:34f7e630dc55ea3f219e555726f5da4b4b25f2200319c8e6902c394258dd6a3e", size = 28266, upload-time = "2024-06-12T22:08:03.686Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/05/d1/8952806fbf9583004ab479d8f58a9496c3d35f6b6009ddd458bdd9978eaf/dpath-2.2.0-py3-none-any.whl", hash = "sha256:b330a375ded0a0d2ed404440f6c6a715deae5313af40bbb01c8a41d891900576", size = 17618, upload-time = "2024-06-12T22:08:01.881Z" }, +] + +[[package]] +name = "ducc0" +version = "0.41.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cf/e7/849dd1a079b994184fa53905d47278f86d0dd3dcfb6ff2b0e3eb7d6a1c1b/ducc0-0.41.0.tar.gz", hash = "sha256:bac084745bbdb243482a4aec3ecc857bdd46faec298c67e48bc0bb90350dbabd", size = 353129, upload-time = "2026-03-26T18:56:04.669Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/8e/3a28ebdef748b9b59c22d9a801116a9ea073d0ce66d9a738bf5db6c29e0c/ducc0-0.41.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:94718e321194313232ae6ba73c528a3847d5eae212a9fc1ef67471e7113e6492", size = 4563683, upload-time = "2026-03-26T18:54:28.643Z" }, + { url = "https://files.pythonhosted.org/packages/11/72/5132178a63fbbbc8868c10b07cbacee138f248ac6f319040537e5a45b3a9/ducc0-0.41.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c17565f332745f08dd012334e07a4dcbb591c9591c2b14f51a1d57ad40018f53", size = 5601347, upload-time = "2026-03-26T18:54:34.054Z" }, + { url = "https://files.pythonhosted.org/packages/17/97/191420d245383304f20f96254774f14b96239e52a0eac44cab93c870941e/ducc0-0.41.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ca66a1806983545460c5447f053f15f6d9f8037b16b128b2a925f0410bcee06d", size = 4563741, upload-time = "2026-03-26T18:54:47.684Z" }, + { url = "https://files.pythonhosted.org/packages/1f/e3/a8783330d7225def7cafe33ed9a2fd7e29eff8f91e7312306037048199a2/ducc0-0.41.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d058b71274f9d60d6edae70cc31d6f5a72e29b0ecc7229725905682566d1e605", size = 5602698, upload-time = "2026-03-26T18:54:53.816Z" }, + { url = "https://files.pythonhosted.org/packages/67/ca/fce0c5395faca711cd4b7203bc001e820288608e6957f81ee183218509ed/ducc0-0.41.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5e8c2c49fbfae0c6f7f4ec759a46b936e00c0d4398eeba8f6cfafd562b7dbe55", size = 4563768, upload-time = "2026-03-26T18:55:05.598Z" }, + { url = "https://files.pythonhosted.org/packages/47/a4/70b5a521697c7482ceca8b00f4406bef5a111d37142a719b2fa4942252f6/ducc0-0.41.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:13f98aefcce65b3416e86fa998a0a81ee0ebd9f0feef2588f44c6694b2a50bf0", size = 5604100, upload-time = "2026-03-26T18:55:11.133Z" }, + { url = "https://files.pythonhosted.org/packages/0d/88/022d053b65c9acd69b2de2a9400afd3916ec3a409f7c5776dc906f86b228/ducc0-0.41.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:583d59d5eb4f23c3eb7c6f8a2b6f32da72e3868e9aa711598978a76a25425f96", size = 4579841, upload-time = "2026-03-26T18:55:19.689Z" }, + { url = "https://files.pythonhosted.org/packages/9a/91/428eca0cc8a1142b9952bef02c06bfe54526d730dd070de873424ab8c0bf/ducc0-0.41.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a3a71fd23661ddd6a7f6b44433e778d35a25b3f1492c9239217cdfedbe8178b1", size = 5613706, upload-time = "2026-03-26T18:55:24.971Z" }, +] + +[[package]] +name = "emcee" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cb/53/1045ee878cb24281387079f8ee4f0ade1622c6aae1ed1fd91a53e4fa5b19/emcee-3.1.6.tar.gz", hash = "sha256:11af4daf6ab8f9ca69681e3c29054665db7bbd87fd4eb8e437d2c3a1248c637d", size = 2871117, upload-time = "2024-04-19T10:03:19.555Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/ef/2196b9bf88ffa1bde45853c72df021fbd07a8fa91a0f59a22d14a050dc04/emcee-3.1.6-py2.py3-none-any.whl", hash = "sha256:f2d63752023bdccf744461450e512a5b417ae7d28f18e12acd76a33de87580cb", size = 47351, upload-time = "2024-04-19T10:03:17.522Z" }, +] + +[[package]] +name = "executing" +version = "2.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cc/28/c14e053b6762b1044f34a13aab6859bbf40456d37d23aa286ac24cfd9a5d/executing-2.2.1.tar.gz", hash = "sha256:3632cc370565f6648cc328b32435bd120a1e4ebb20c77e3fdde9a13cd1e533c4", size = 1129488, upload-time = "2025-09-01T09:48:10.866Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/ea/53f2148663b321f21b5a606bd5f191517cf40b7072c0497d3c92c4a13b1e/executing-2.2.1-py2.py3-none-any.whl", hash = "sha256:760643d3452b4d777d295bb167ccc74c64a81df23fb5e08eff250c425a4b2017", size = 28317, upload-time = "2025-09-01T09:48:08.5Z" }, +] + +[[package]] +name = "fastjsonschema" +version = "2.21.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/20/b5/23b216d9d985a956623b6bd12d4086b60f0059b27799f23016af04a74ea1/fastjsonschema-2.21.2.tar.gz", hash = "sha256:b1eb43748041c880796cd077f1a07c3d94e93ae84bba5ed36800a33554ae05de", size = 374130, upload-time = "2025-08-14T18:49:36.666Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/a8/20d0723294217e47de6d9e2e40fd4a9d2f7c4b6ef974babd482a59743694/fastjsonschema-2.21.2-py3-none-any.whl", hash = "sha256:1c797122d0a86c5cace2e54bf4e819c36223b552017172f32c5c024a6b77e463", size = 24024, upload-time = "2025-08-14T18:49:34.776Z" }, +] + +[[package]] +name = "fitsio" +version = "1.4.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/34/6b/5658778e070faaa194f1a1133527cedfa948d173daed29d61f25c5487ab6/fitsio-1.4.1.tar.gz", hash = "sha256:2b2bf0bfd37790114b44283931c59a14b1fec25a653bf65c4fc555b8d3b24de9", size = 4148217, upload-time = "2026-07-10T21:21:31.585Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/a0/86e2bde46aa5559b7b9544208def3045675d055f0d132b235ff325279a9b/fitsio-1.4.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:de7ac1df97ce68626dac1da5014e6b396cff2789d1c617c36df03d6bc6d98a2d", size = 881494, upload-time = "2026-07-10T21:21:09.496Z" }, + { url = "https://files.pythonhosted.org/packages/a5/53/f7f644b812e572c57015ef5215f982922d9cdac8d239549c136ba48f2850/fitsio-1.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:34df9129decab3ae85377601668b82442159ed704800bd1ed047428bc532c96d", size = 810043, upload-time = "2026-07-10T21:21:11.254Z" }, + { url = "https://files.pythonhosted.org/packages/83/5d/d71993140df9f939e81d2a5531f26d15cbd700855348a756921b0ad24235/fitsio-1.4.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:161806de2bb9971e271379558616d2cef795ce9590923270ec3bbdadea0d0b2f", size = 913505, upload-time = "2026-07-10T21:21:16.695Z" }, + { url = "https://files.pythonhosted.org/packages/ef/ae/e89778256e0aee3e5b51a620cdf9d91ac89f348504045461bee28006275d/fitsio-1.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:5ed27e5b8aaf1ae51718c6624d00fec1d6054fddde8d602eaea3bb6686bcfb0a", size = 815241, upload-time = "2026-07-10T21:21:18.018Z" }, + { url = "https://files.pythonhosted.org/packages/7c/47/7f64a60d883a4b69a0a15c1ec60ba9313d8e774af83ac2b00f57d511b76d/fitsio-1.4.1-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:1ab4eadb13caf362630d45bce7cf7e57e407d3c971f361f639ca9c316f460bb2", size = 913536, upload-time = "2026-07-10T21:21:22.556Z" }, + { url = "https://files.pythonhosted.org/packages/de/46/9f45b3c8bd371057f1333aec8f92879cb786fe9ed05b6b0c2643fd228558/fitsio-1.4.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2627eeec3dff4b692402babb88aec3cccbf73a3ee22d19b4accfe76491bd67a8", size = 815239, upload-time = "2026-07-10T21:21:23.61Z" }, + { url = "https://files.pythonhosted.org/packages/8b/3b/9a6d92637db9a603a18681f60689c30208f2485016ed91280e42b927df57/fitsio-1.4.1-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:5f499149738fdce6afa3324a76fd65a762082647d8b1d30a356dc002dd4a9178", size = 928341, upload-time = "2026-07-10T21:21:28.075Z" }, + { url = "https://files.pythonhosted.org/packages/0a/fa/eeb997744bb1c2c9308dab9b492bcdb1843e4eb3dc5d1697d2f0a312c8b7/fitsio-1.4.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:c2a0dba7a868b4b1716d7468431fda51bc89ee8d8f2a643ac28f9200d99d2e2b", size = 815548, upload-time = "2026-07-10T21:21:29.202Z" }, +] + +[[package]] +name = "flt" +version = "2026.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/80/66/538256582e373d81a944c0ee3a12fd0e4dd0f39d10136353c4ce914d7061/flt-2026.1.tar.gz", hash = "sha256:4bf2818d4a9137f5f715fd2ff13acfbf0175639373155cd89ea2b788edf00093", size = 12817, upload-time = "2026-03-20T22:47:29.754Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/0f/9911ee41dbb2eb043d6252aa8f9bade8995f7b7ee01406e049088c96acf1/flt-2026.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2962fd252df62d77bb2861859173ffc7cc436921a234a52c17eab7839bcce588", size = 479324, upload-time = "2026-03-20T22:46:55.38Z" }, + { url = "https://files.pythonhosted.org/packages/7c/86/c525fef761b2bf9cd961fa6e06a4e255ea9eca529d37e22098d8baa900f0/flt-2026.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8b73c4aac4874808dc66e2f7a3cbcdd20a65d0ef14d6f2d378a79930ff3d0bad", size = 478225, upload-time = "2026-03-20T22:46:56.902Z" }, + { url = "https://files.pythonhosted.org/packages/1e/14/9beb3e8a64536741b6f06f62324305171391f9b6d84b804c42e0519f472e/flt-2026.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e02e75d2c8d6441cd7de2d7a13e62bb8feb687cee2d70c4bd57c43c5c78dc630", size = 483678, upload-time = "2026-03-20T22:47:02.783Z" }, + { url = "https://files.pythonhosted.org/packages/95/05/086fd21633043fe19dbe972cab79a680199286c57ba66a88f899c1f51dc7/flt-2026.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ef91c6dd6e453062b5f5d3cbb0c489bd8b3ee1440ad9e5c940d22921664bb69a", size = 483418, upload-time = "2026-03-20T22:47:04.284Z" }, + { url = "https://files.pythonhosted.org/packages/f1/93/a24b0937fa882fc513d399713d6780262ac5beacdef16a3638370669c960/flt-2026.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:28c43c464fffa6edbee4bcaaf07565fdd8046ef649764d5647b0de9b2faa19a7", size = 479350, upload-time = "2026-03-20T22:47:10.738Z" }, + { url = "https://files.pythonhosted.org/packages/1a/d9/54d75cabcacbbfa79b3c54515167f5a3b2dcfcb7af1ec23e8df46bc59e52/flt-2026.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f011917cb43d3590c5fdb8e622a9641b5a42e5519d6fea27b4553aa8fc6c8f32", size = 480496, upload-time = "2026-03-20T22:47:11.894Z" }, + { url = "https://files.pythonhosted.org/packages/60/94/a12bc6dd3136b187dacbd5b820537c0e5507e8f63f5c7db10019eeb54394/flt-2026.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:999f1ffbea353fd77b1797ecd8b69a7bae7bb098723ae0dca51a05fc6e4df6dc", size = 480306, upload-time = "2026-03-20T22:47:17.933Z" }, + { url = "https://files.pythonhosted.org/packages/c0/7b/700fc7cfc5033090b27e14e69d9678b1973642f684cdfeffdcf08e561a98/flt-2026.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:10575dc192697bd024ab22f7948fa7f850c40ca6a036e80fe2e96afec6e5c703", size = 473443, upload-time = "2026-03-20T22:47:19.19Z" }, +] + +[[package]] +name = "fonttools" +version = "4.63.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/84/69/c97f2c18e0db87d2c7b15da1974dace76ae938f1cfa22e2727a648b7ed43/fonttools-4.63.0.tar.gz", hash = "sha256:caeb583deeb5168e694b65cda8b4ee62abedfa66cf88488734466f2366b9c4e0", size = 3597189, upload-time = "2026-05-14T12:04:30.958Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/44/04/0b91d8e916e92ad1fac9e4624760baf0fd5ff2ead614c2f68fb21373f03f/fonttools-4.63.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ef3048ef05dbb552b89817713d9cac912e00d0fde4a3105c00d29e52e10c89af", size = 5044298, upload-time = "2026-05-14T12:03:18.085Z" }, + { url = "https://files.pythonhosted.org/packages/77/c7/2342da9830e3e9d4870305ca5d2091d2a83284f2953079b7bdd3b5e029d8/fonttools-4.63.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:58dc6bb86a78d782f00f9190ca02c119cf5bbe2807536e361e18d42019f877d8", size = 4999800, upload-time = "2026-05-14T12:03:20.161Z" }, + { url = "https://files.pythonhosted.org/packages/e6/6d/67fe16c48d7ce050979b33f47e0d28a318f02da030602e944c34f7a16ef3/fonttools-4.63.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:ee08ebfa58f6e1aeff5697ab9582105bb620008c1caafb681e4c557e7483027b", size = 4982666, upload-time = "2026-05-14T12:03:22.87Z" }, + { url = "https://files.pythonhosted.org/packages/f2/00/3bbab338c07c71fa56269953845e92c951a61457bbbb0f1022551ea266d9/fonttools-4.63.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:27fdc65af8da6f88b9c6121c47a464cbe359fcfff7ff6fc2d37a1f395d755b78", size = 5133598, upload-time = "2026-05-14T12:03:25.168Z" }, + { url = "https://files.pythonhosted.org/packages/8e/40/e76320afa1df918e146155ef239b1719ee266092e96f5423bfd075affba1/fonttools-4.63.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1e874792a8212b44583ea02189d9e693906b2f78b261f372f95d6c563210ac1d", size = 5024840, upload-time = "2026-05-14T12:03:36.745Z" }, + { url = "https://files.pythonhosted.org/packages/ce/36/0b805d8c485f872f65a509cbe3b58a5d0d17bee855333b54a150c79d3061/fonttools-4.63.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:22135da48a348785c5e2d5d2d9d6bec5ed44adacbaeb9db12d9493bf6c6bfa68", size = 4975801, upload-time = "2026-05-14T12:03:38.833Z" }, + { url = "https://files.pythonhosted.org/packages/c8/26/2cee03d0aa083ab022da5c07aff9ed3f689da1defb81ad6917c9627896da/fonttools-4.63.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ccf41f2efdf56994d22d73bef4ced1052161958169428d06ba9724ea9e9a64be", size = 4965009, upload-time = "2026-05-14T12:03:41.494Z" }, + { url = "https://files.pythonhosted.org/packages/7e/48/cc4b66d9058c0d0982c833fad10127c4b0e9324606aafa41382295ca4102/fonttools-4.63.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9ced0bd02ac751dd6319b0da88aaef24414e3b0dbc32bb4f24944821a3741a27", size = 5105892, upload-time = "2026-05-14T12:03:43.525Z" }, + { url = "https://files.pythonhosted.org/packages/dd/87/64cfa18a7a1621d17b7f4502b2b0ed8a135a90c3db51ea590ee99043e76b/fonttools-4.63.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6b2248c5decb223562f7902ff6325077a073f608ee8e33e88ad88db734eb9f49", size = 5010526, upload-time = "2026-05-14T12:03:54.647Z" }, + { url = "https://files.pythonhosted.org/packages/36/e1/a8933a72c45a87177fbde2696e0d0755c8c9062f8c077a961c6215fa27b1/fonttools-4.63.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:308f957cdeaf8abe4e5f2f124902ef405448af92c90f80e302a3b771c2e6116b", size = 4923946, upload-time = "2026-05-14T12:03:56.984Z" }, + { url = "https://files.pythonhosted.org/packages/27/60/872e6e233b8c5e8b41413796ff18b7fe479661bd40147e071b450dfad7a1/fonttools-4.63.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:bf00f21eb5fb721dbaf73d1e9da6d02a1af7768f2ebcf9798be98beab8ba90f6", size = 4962489, upload-time = "2026-05-14T12:03:59.443Z" }, + { url = "https://files.pythonhosted.org/packages/30/c4/83c24f2ec38b90cfda84bf4b1a1f49df80e84a1db4e7ac6e0d41bf23bc39/fonttools-4.63.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c1aaa4b9c75798400ac043ce04d74e7830376c85095a5a6ed7cba2f17a266bf4", size = 5071870, upload-time = "2026-05-14T12:04:02.122Z" }, + { url = "https://files.pythonhosted.org/packages/ea/2b/0aa8db70f18cf52e49b4ed5ecec68547f981160bf5ded3b5aed6faa0a6f9/fonttools-4.63.0-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0eac00b9118c3c2f87d272e45341871c5b3066baa3c86897fa634a7c3fb59096", size = 5148649, upload-time = "2026-05-14T12:04:12.747Z" }, + { url = "https://files.pythonhosted.org/packages/7f/63/18e4369c25043096f1048e0c9915951adc4f842bd81c6b18155824d6fa99/fonttools-4.63.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:51394295f1a51de8b5f30bdb1e1b9a4231536c7064ef5c6e211eec19fa36036f", size = 4932147, upload-time = "2026-05-14T12:04:14.806Z" }, + { url = "https://files.pythonhosted.org/packages/a1/3f/67f3eac2ffd8a98446c5022f8ed3864eac878a5ff7af8df4c8286dba16cc/fonttools-4.63.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:9e12f105d2b6342c559c298afb674006bb2893afc7102dcf8a1b55b0486b4e40", size = 5027237, upload-time = "2026-05-14T12:04:17.675Z" }, + { url = "https://files.pythonhosted.org/packages/1a/ba/4e6214cb38a7b04779e97bb7636de9a5c7f20af7018d03dee0b64c08510a/fonttools-4.63.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:796f27556dbe094c4824f75ca85267e4df776c79036c8441469a4df37038c196", size = 5053933, upload-time = "2026-05-14T12:04:20.818Z" }, + { url = "https://files.pythonhosted.org/packages/2c/47/c99d5268f354002ce80f8d029cd9d7d872969da1de8b93d32de4dc56d6f4/fonttools-4.63.0-py3-none-any.whl", hash = "sha256:445af2eab030a16b9171ea8bdda7ebf7d96bda2df88ee182a464252f6e05e20d", size = 1164562, upload-time = "2026-05-14T12:04:29.092Z" }, +] + +[[package]] +name = "fqdn" +version = "1.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/30/3e/a80a8c077fd798951169626cde3e239adeba7dab75deb3555716415bd9b0/fqdn-1.5.1.tar.gz", hash = "sha256:105ed3677e767fb5ca086a0c1f4bb66ebc3c100be518f0e0d755d9eae164d89f", size = 6015, upload-time = "2021-03-11T07:16:29.08Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cf/58/8acf1b3e91c58313ce5cb67df61001fc9dcd21be4fadb76c1a2d540e09ed/fqdn-1.5.1-py3-none-any.whl", hash = "sha256:3a179af3761e4df6eb2e026ff9e1a3033d3587bf980a0b1b2e1e5d08d7358014", size = 9121, upload-time = "2021-03-11T07:16:28.351Z" }, +] + +[[package]] +name = "fsspec" +version = "2026.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/10/a1/ae4e3e5003468d6391d2c77b6fa1cd73bd5d13511d81c642d7b28ac90ed4/fsspec-2026.6.0.tar.gz", hash = "sha256:f5bac145310fe30e16e1471bd6840b2d990d609e872251d7e674241822abf01a", size = 313646, upload-time = "2026-06-16T01:57:28.105Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/22/4222d7ddf3da30f363edaa98e329c2bce6c65497c9cb2810931c8b2c0fbc/fsspec-2026.6.0-py3-none-any.whl", hash = "sha256:02e0b71817df9b2169dc30a16832045764def1191b43dcff5bb85bdee212d2a1", size = 203949, upload-time = "2026-06-16T01:57:26.358Z" }, +] + +[[package]] +name = "future" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a7/b2/4140c69c6a66432916b26158687e821ba631a4c9273c474343badf84d3ba/future-1.0.0.tar.gz", hash = "sha256:bd2968309307861edae1458a4f8a4f3598c03be43b97521076aebf5d94c07b05", size = 1228490, upload-time = "2024-02-21T11:52:38.461Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/da/71/ae30dadffc90b9006d77af76b393cb9dfbfc9629f339fc1574a1c52e6806/future-1.0.0-py3-none-any.whl", hash = "sha256:929292d34f5872e70396626ef385ec22355a1fae8ad29e1a734c3e43f9fbc216", size = 491326, upload-time = "2024-02-21T11:52:35.956Z" }, +] + +[[package]] +name = "getdist" +version = "1.6.1" +source = { git = "https://github.com/benabed/getdist.git?rev=113cd22a9a0d013b6f72fe734be81f260f3d3be5#113cd22a9a0d013b6f72fe734be81f260f3d3be5" } +dependencies = [ + { name = "matplotlib", marker = "sys_platform == 'linux'" }, + { name = "numpy", marker = "sys_platform == 'linux'" }, + { name = "packaging", marker = "sys_platform == 'linux'" }, + { name = "pyyaml", marker = "sys_platform == 'linux'" }, + { name = "scipy", marker = "sys_platform == 'linux'" }, +] + +[[package]] +name = "gitdb" +version = "4.0.12" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "smmap", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/72/94/63b0fc47eb32792c7ba1fe1b694daec9a63620db1e313033d18140c2320a/gitdb-4.0.12.tar.gz", hash = "sha256:5ef71f855d191a3326fcfbc0d5da835f26b13fbcba60c32c21091c349ffdb571", size = 394684, upload-time = "2025-01-02T07:20:46.413Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/61/5c78b91c3143ed5c14207f463aecfc8f9dbb5092fb2869baf37c273b2705/gitdb-4.0.12-py3-none-any.whl", hash = "sha256:67073e15955400952c6565cc3e707c554a4eea2e428946f7a4c162fab9bd9bcf", size = 62794, upload-time = "2025-01-02T07:20:43.624Z" }, +] + +[[package]] +name = "gitpython" +version = "3.1.50" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "gitdb", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/33/f6/354ae6491228b5eb40e10d89c4d13c651fe1cf7556e35ebdded50cff57ce/gitpython-3.1.50.tar.gz", hash = "sha256:80da2d12504d52e1f998772dc5baf6e553f8d2fcfe1fcc226c9d9a2ee3372dcc", size = 219798, upload-time = "2026-05-06T04:01:26.571Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/7a/1c6e3562dfd8950adbb11ffbc65d21e7c89d01a6e4f137fa981056de25c5/gitpython-3.1.50-py3-none-any.whl", hash = "sha256:d352abe2908d07355014abdd21ddf798c2a961469239afec4962e9da884858f9", size = 212507, upload-time = "2026-05-06T04:01:23.799Z" }, +] + +[[package]] +name = "glass" +version = "2025.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cosmology", marker = "sys_platform == 'linux'" }, + { name = "healpix", marker = "sys_platform == 'linux'" }, + { name = "healpy", marker = "sys_platform == 'linux'" }, + { name = "numpy", marker = "sys_platform == 'linux'" }, + { name = "transformcl", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a5/d6/26cd58e75834671259f26b9287a584d726e6023da35ddf7ca3b7f2c393fb/glass-2025.1.tar.gz", hash = "sha256:7b1aa2394e16010f7f1b4243f49e7e12d7a4dd28fcbf3e3f7cf25ce4905a8615", size = 48533, upload-time = "2025-02-21T18:43:48.046Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e4/e7/3e89bc5147a3e84245c783098afffbbacbcdf5678ba1aacc2c9c035434da/glass-2025.1-py3-none-any.whl", hash = "sha256:d7919a7d19e05ab8da4e52dbfbcfb5bd1ed2b72e0cc3afde39ec94ced22883c5", size = 47185, upload-time = "2025-02-21T18:43:46.649Z" }, +] + +[[package]] +name = "glass-ext-camb" +version = "2023.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "camb", marker = "sys_platform == 'linux'" }, + { name = "glass", marker = "sys_platform == 'linux'" }, + { name = "numpy", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b7/1a/18bb47c0f7cc267c2f8c95273055b82b1975e4dccbfea6051e82a4d1f513/glass.ext.camb-2023.6.tar.gz", hash = "sha256:f7b6e521b2d45d3b68400353ce6ab1747c772631832a257567de028aa2060509", size = 2989, upload-time = "2023-06-30T22:27:31.511Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/50/e92d9db0d26966bad6c4c441822c345784af592767747ee563a65ee24450/glass.ext.camb-2023.6-py3-none-any.whl", hash = "sha256:f46015ecedf87cffabf008d21ac06be5d7a55557027f12c54e258ee11b85c44a", size = 3634, upload-time = "2023-06-30T22:27:30.171Z" }, +] + +[[package]] +name = "google-crc32c" +version = "1.8.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/03/41/4b9c02f99e4c5fb477122cd5437403b552873f014616ac1d19ac8221a58d/google_crc32c-1.8.0.tar.gz", hash = "sha256:a428e25fb7691024de47fecfbff7ff957214da51eddded0da0ae0e0f03a2cf79", size = 14192, upload-time = "2025-12-16T00:35:25.142Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ce/a9/a780cc66f86335a6019f557a8aaca8fbb970728f0efd2430d15ff1beae0e/google_crc32c-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:14f87e04d613dfa218d6135e81b78272c3b904e2a7053b841481b38a7d901411", size = 33364, upload-time = "2025-12-16T00:40:22.96Z" }, + { url = "https://files.pythonhosted.org/packages/21/3f/3457ea803db0198c9aaca2dd373750972ce28a26f00544b6b85088811939/google_crc32c-1.8.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:cb5c869c2923d56cb0c8e6bcdd73c009c36ae39b652dbe46a05eb4ef0ad01454", size = 33740, upload-time = "2025-12-16T00:40:23.96Z" }, + { url = "https://files.pythonhosted.org/packages/ce/42/b468aec74a0354b34c8cbf748db20d6e350a68a2b0912e128cabee49806c/google_crc32c-1.8.0-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:3b9776774b24ba76831609ffbabce8cdf6fa2bd5e9df37b594221c7e333a81fa", size = 33344, upload-time = "2025-12-16T00:40:24.742Z" }, + { url = "https://files.pythonhosted.org/packages/1c/e8/b33784d6fc77fb5062a8a7854e43e1e618b87d5ddf610a88025e4de6226e/google_crc32c-1.8.0-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:89c17d53d75562edfff86679244830599ee0a48efc216200691de8b02ab6b2b8", size = 33694, upload-time = "2025-12-16T00:40:25.505Z" }, + { url = "https://files.pythonhosted.org/packages/56/15/c25671c7aad70f8179d858c55a6ae8404902abe0cdcf32a29d581792b491/google_crc32c-1.8.0-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b0d1a7afc6e8e4635564ba8aa5c0548e3173e41b6384d7711a9123165f582de2", size = 33381, upload-time = "2025-12-16T00:40:26.268Z" }, + { url = "https://files.pythonhosted.org/packages/42/fa/f50f51260d7b0ef5d4898af122d8a7ec5a84e2984f676f746445f783705f/google_crc32c-1.8.0-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8b3f68782f3cbd1bce027e48768293072813469af6a61a86f6bb4977a4380f21", size = 33734, upload-time = "2025-12-16T00:40:27.028Z" }, +] + +[[package]] +name = "greenlet" +version = "3.5.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e2/f1/fbbfef6af0bad0548f09bc28948ea3c275b4edb19e17fc5ca9900a6a634d/greenlet-3.5.3.tar.gz", hash = "sha256:a61efc018fd3eb317eeca31aba90ee9e7f26f22884a79b6c6ec715bf71bb62f1", size = 200270, upload-time = "2026-06-26T19:28:24.832Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7a/73/815dd90131c1b71ebdf53dbc7c276cafec2a1173b97559f97aba72724a87/greenlet-3.5.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:efa9f765dd09f9d0cdac651ffdf631ee59ec5dc6ee7a73e0c012ba9c52fbdf5b", size = 604761, upload-time = "2026-06-26T19:07:10.114Z" }, + { url = "https://files.pythonhosted.org/packages/9f/57/079cfe76bcef36b153b25607ee91c6fcb58f17f8b23c86bbbeabe0c88d72/greenlet-3.5.3-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:7faba15ac005376e02a0384504e0243be3370ce010296a44a820feb342b505ab", size = 617044, upload-time = "2026-06-26T19:10:07.25Z" }, + { url = "https://files.pythonhosted.org/packages/37/87/b4d095775a3fb1bcafbb483fc206b27ebb785724c83051447737085dc54e/greenlet-3.5.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:87142215824be6ac05e2e8e2786eec307ccbc27c36723c3881959df654af6861", size = 614244, upload-time = "2026-06-26T18:32:17.594Z" }, + { url = "https://files.pythonhosted.org/packages/8a/70/7559b609683650fa2b95b8ab84b4ab0b26556a635d19675e12aa832d826d/greenlet-3.5.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:215275b1b49320987352e6c1b054acca0064f965a2c66992bed9a6f7d913f149", size = 1574210, upload-time = "2026-06-26T19:09:03.077Z" }, + { url = "https://files.pythonhosted.org/packages/ae/73/be55392074c60fc37655ca40fa6022457bfbf6718e9e342a7b0b41f96dd2/greenlet-3.5.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:6b1b0eed82364b0e32c4ea0f221452d33e6bb17ae094d9f72aed9851812747ea", size = 1638627, upload-time = "2026-06-26T18:31:44.748Z" }, + { url = "https://files.pythonhosted.org/packages/d6/fa/5401ac78021c826a25b6dde0c705e0a8f29b617509f9185a31dac15fbe1b/greenlet-3.5.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a2d185dd1621757e70c3861cceffd5317ab4e7ed7eb09c82994828468527ade5", size = 607435, upload-time = "2026-06-26T19:07:11.412Z" }, + { url = "https://files.pythonhosted.org/packages/e9/76/1dc144a2e56e65d36405078ed774224375ea520a1870a6e46e08bb4ac7bf/greenlet-3.5.3-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1c514a468149bf8fbbab874188a3535cd8a48a3e353eb53a3d424296f8dbacd3", size = 619787, upload-time = "2026-06-26T19:10:08.396Z" }, + { url = "https://files.pythonhosted.org/packages/bf/87/c298cee62df1de4ad7fec32abda73526cff347fd143a6ed4ac369246668a/greenlet-3.5.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:915f887cf2682b66419b879423a2e072634aa7b7dce6f3ada4957cfced3f1e9a", size = 616786, upload-time = "2026-06-26T18:32:19.128Z" }, + { url = "https://files.pythonhosted.org/packages/9e/2e/e6f009885ed0705ccf33fe0583c117cfd03cde77e31a596dd5785a30762b/greenlet-3.5.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:766cfd421c13e450feb340cd472a3ed9957d438727b7b4593ad7c76c5d2b0deb", size = 1574316, upload-time = "2026-06-26T19:09:04.273Z" }, + { url = "https://files.pythonhosted.org/packages/ef/fe/43fd110b01e40da0adb7c90ac7ea744bef2d43dca00de5095fd2351c2a68/greenlet-3.5.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:2ecda9ec22edf38fa389369eaed8c3d37c05f3c54e69f69438dbb2cc1de1458b", size = 1638614, upload-time = "2026-06-26T18:31:46.297Z" }, + { url = "https://files.pythonhosted.org/packages/82/2f/146d218299046a43d1f029fd544b3d110d0f175a09c715c7e8da4a4a345d/greenlet-3.5.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:df0a0628d1597eb0897b62f55d1343f772405fd25f3b2a796c76874b0c2e22e8", size = 654096, upload-time = "2026-06-26T19:07:12.71Z" }, + { url = "https://files.pythonhosted.org/packages/a0/cc/04738cafb3f45fa991ea44f9de94c47dcec964f5a972300988a6751f49d9/greenlet-3.5.3-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ebd933a6adabc298bab47731a130fe6bfb888bd934eee37810f151159544540d", size = 666304, upload-time = "2026-06-26T19:10:09.503Z" }, + { url = "https://files.pythonhosted.org/packages/ce/aa/4e0dad5e605c270c784ab911c43da6adb136ccd4d81180f763ca429a723d/greenlet-3.5.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4b9d501b40e80b70e32323c799dd9b420a5577a9601469d362ae1ffb690f3a7c", size = 663635, upload-time = "2026-06-26T18:32:20.802Z" }, + { url = "https://files.pythonhosted.org/packages/d1/50/13efdbea246fe3d3b735e191fec08fb50809f53cd2383ebe123d0809e44b/greenlet-3.5.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:a1fad1d11e7d6aab184107baa8e4ece11ccba3ec9599cd7efa5ff4d70d43256a", size = 1621252, upload-time = "2026-06-26T19:09:05.647Z" }, + { url = "https://files.pythonhosted.org/packages/f7/22/c0a336ae4a1410fd5f5121098e5bfbf1865f64c5ef80b4b5412886c4a332/greenlet-3.5.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:fad5aec764399f1b5cc347ad250a59660f20c8f8888ea6bae1f93b769cce1154", size = 1684824, upload-time = "2026-06-26T18:31:47.738Z" }, + { url = "https://files.pythonhosted.org/packages/00/92/715c44721abe2b4d1ae9abde4179411868a5bff312479f54e105d372f131/greenlet-3.5.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:19131729ae0ddc3c2e1ef85e650169b5e37ee32e400f215f78b94d7b0d567310", size = 653382, upload-time = "2026-06-26T19:07:14.209Z" }, + { url = "https://files.pythonhosted.org/packages/a0/83/37a10372a1090a6624cca8e74c12df1a36c2dc36429ed0255b7fb1aeee23/greenlet-3.5.3-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1540dd8e5fc2a5aec40fbb98ef8e149fa47c89a4b4a1cf2575a14d3d1869d7a8", size = 659401, upload-time = "2026-06-26T19:10:10.876Z" }, + { url = "https://files.pythonhosted.org/packages/db/e2/d1509cad4207da559cc42986ecdd8fc67ad0d1bba2bf03023c467fd5e0f3/greenlet-3.5.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e81fa194a1d20967877bdf9c7794db2bc99063e5be36aee710c08f04c5bb087f", size = 656969, upload-time = "2026-06-26T18:32:22.272Z" }, + { url = "https://files.pythonhosted.org/packages/86/7d/eaf70de20aadca3a5884aec58362861c64ce45e7b277f47ed026926a3b89/greenlet-3.5.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:55cf4d777485d43110e47133cbba6d74a8885a87ec1227ef0267f9ee80c5aa21", size = 1617822, upload-time = "2026-06-26T19:09:06.893Z" }, + { url = "https://files.pythonhosted.org/packages/8a/f9/414d38fc400ae4350d4185eaad1827676f7cf5287b9136e0ed1cbbe20a7f/greenlet-3.5.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:12a248ba75f6a9a236375f52296c498c89ff1d8badf32deb9eca7abd5853f7da", size = 1677983, upload-time = "2026-06-26T18:31:49.396Z" }, + { url = "https://files.pythonhosted.org/packages/4f/ca/69db42d447a1378043e2c8f19c09cbbd1263371505053c496b49066d3d16/greenlet-3.5.3-cp315-cp315-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:78dbef602fda6d97d957eb7937f70c9ce9e9527330347f8f6b6f9e554a9e7a47", size = 659747, upload-time = "2026-06-26T19:07:15.565Z" }, + { url = "https://files.pythonhosted.org/packages/a8/0b/af7ac2ef8dd41e3da1a40dda6305c23b9a03e13ba975ec916357b50f8575/greenlet-3.5.3-cp315-cp315-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:6f73857adb8fee13fa56c172bd11262f888c0c648f9fea113e777bb2c7904a81", size = 670419, upload-time = "2026-06-26T19:10:12.293Z" }, + { url = "https://files.pythonhosted.org/packages/51/1e/1d51640cacbfc455dbe9f9a9f594c49e4e244f63b9971a2f4764e46cc53d/greenlet-3.5.3-cp315-cp315-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:232fec92e823addaf02d9472cf7381e24a1d046a6ced1103c5caa4c21b9dfc1d", size = 668787, upload-time = "2026-06-26T18:32:24.298Z" }, + { url = "https://files.pythonhosted.org/packages/21/66/4030d5b0b5894500023f003bb054d9bb354dfbd1e186c3a296759172f5f5/greenlet-3.5.3-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:2421c3564da9429d5586d46ca31ebb26516b5498a802cf65c041a8e8a8980d34", size = 1626305, upload-time = "2026-06-26T19:09:08.281Z" }, + { url = "https://files.pythonhosted.org/packages/0e/50/5221371c7550108dfa3c378debc41d032aa9c78e89abb01d8011cfc93289/greenlet-3.5.3-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:e0f0d160f0b2e558e6c75f7930967183255dc9735e5f5b8cae58ee09c9576d8b", size = 1688631, upload-time = "2026-06-26T18:31:51.278Z" }, + { url = "https://files.pythonhosted.org/packages/57/66/b3bfae3e220a9b63ea539a0eea681800c69ab1aada757eae8789f183e7ce/greenlet-3.5.3-cp315-cp315t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:629b614d2b786e89c50440e246f33eea78f58a962d0bdbbcc809e6d13605903f", size = 657221, upload-time = "2026-06-26T19:07:16.973Z" }, + { url = "https://files.pythonhosted.org/packages/7b/81/b6d4d73a709684fc77e7fa034d7c2fe82cffa9fc920fadcaa659c2626213/greenlet-3.5.3-cp315-cp315t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2b2e857ae16f5f72142edf75f9f176fe7526ba19a2841df1420516f83831c9f2", size = 663226, upload-time = "2026-06-26T19:10:13.723Z" }, + { url = "https://files.pythonhosted.org/packages/f5/07/e210b02b589f16e74ff48b730690e4a34ffe984219fce4f3c1a0e7ec8545/greenlet-3.5.3-cp315-cp315t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e515757e2e36bcbf1fad09a46e1557e8b1ae1797d4b44d09da7deed88ad28608", size = 660802, upload-time = "2026-06-26T18:32:26.081Z" }, + { url = "https://files.pythonhosted.org/packages/eb/2e/5303eb3fa06bca089060f479707182a93e360683bc252acf846c3090d34e/greenlet-3.5.3-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:b363d46ed1ea431825fdb01471bb024fc08399bad1572a616e853c7684415adb", size = 1622157, upload-time = "2026-06-26T19:09:09.527Z" }, + { url = "https://files.pythonhosted.org/packages/54/70/50de47a488f14df260b50ae34fb5d56016e308b098eab02c878b5223c26a/greenlet-3.5.3-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:e44da2f5bbdaabaf7d80b73dbb430c7035771e9f244e3c8b769715c9d8fa0a16", size = 1681159, upload-time = "2026-06-26T18:31:52.986Z" }, +] + +[[package]] +name = "gsl" +version = "0.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/01/36/a8a99ab67918beb6ee8722fb6c27512796a5ff8ed4c10036f787eef51569/gsl-0.0.3.tar.gz", hash = "sha256:85a6071e00a284510c963b97ab74ef8a3e7d1786c5f52dc2ff444cbb7d94ee3c", size = 44404, upload-time = "2018-05-30T09:02:51.203Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ee/1e/14d4c4657bc7130b900c65033861ee0db508d2d9206f4223f5da7c855acc/gsl-0.0.3-py3-none-any.whl", hash = "sha256:081c77375bf65cb759a3e5129275b8806be18648452f50f7c420f40dac60529a", size = 39432, upload-time = "2018-05-30T09:02:49.93Z" }, +] + +[[package]] +name = "h11" +version = "0.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/01/ee/02a2c011bdab74c6fb3c75474d40b3052059d95df7e73351460c8588d963/h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1", size = 101250, upload-time = "2025-04-24T03:35:25.427Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/4b/29cac41a4d98d144bf5f6d33995617b185d14b22401f75ca86f384e87ff1/h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86", size = 37515, upload-time = "2025-04-24T03:35:24.344Z" }, +] + +[[package]] +name = "h2" +version = "4.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "hpack", marker = "sys_platform == 'linux'" }, + { name = "hyperframe", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1d/17/afa56379f94ad0fe8defd37d6eb3f89a25404ffc71d4d848893d270325fc/h2-4.3.0.tar.gz", hash = "sha256:6c59efe4323fa18b47a632221a1888bd7fde6249819beda254aeca909f221bf1", size = 2152026, upload-time = "2025-08-23T18:12:19.778Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/b2/119f6e6dcbd96f9069ce9a2665e0146588dc9f88f29549711853645e736a/h2-4.3.0-py3-none-any.whl", hash = "sha256:c438f029a25f7945c69e0ccf0fb951dc3f73a5f6412981daee861431b70e2bdd", size = 61779, upload-time = "2025-08-23T18:12:17.779Z" }, +] + +[[package]] +name = "h5py" +version = "3.16.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/db/33/acd0ce6863b6c0d7735007df01815403f5589a21ff8c2e1ee2587a38f548/h5py-3.16.0.tar.gz", hash = "sha256:a0dbaad796840ccaa67a4c144a0d0c8080073c34c76d5a6941d6818678ef2738", size = 446526, upload-time = "2026-03-06T13:49:08.07Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/84/06281c82d4d1686fde1ac6b0f307c50918f1c0151062445ab3b6fa5a921d/h5py-3.16.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:ff24039e2573297787c3063df64b60aab0591980ac898329a08b0320e0cf2527", size = 5198852, upload-time = "2026-03-06T13:48:07.482Z" }, + { url = "https://files.pythonhosted.org/packages/9e/e9/1a19e42cd43cc1365e127db6aae85e1c671da1d9a5d746f4d34a50edb577/h5py-3.16.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:dfc21898ff025f1e8e67e194965a95a8d4754f452f83454538f98f8a3fcb207e", size = 5405250, upload-time = "2026-03-06T13:48:09.628Z" }, + { url = "https://files.pythonhosted.org/packages/b7/8e/9790c1655eabeb85b92b1ecab7d7e62a2069e53baefd58c98f0909c7a948/h5py-3.16.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:698dd69291272642ffda44a0ecd6cd3bda5faf9621452d255f57ce91487b9794", size = 5190108, upload-time = "2026-03-06T13:48:11.26Z" }, + { url = "https://files.pythonhosted.org/packages/51/d7/ab693274f1bd7e8c5f9fdd6c7003a88d59bedeaf8752716a55f532924fbb/h5py-3.16.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2b2c02b0a160faed5fb33f1ba8a264a37ee240b22e049ecc827345d0d9043074", size = 5419216, upload-time = "2026-03-06T13:48:13.322Z" }, + { url = "https://files.pythonhosted.org/packages/da/1e/6172269e18cc5a484e2913ced33339aad588e02ba407fafd00d369e22ef3/h5py-3.16.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:099f2525c9dcf28de366970a5fb34879aab20491589fa89ce2863a84218bb524", size = 5193860, upload-time = "2026-03-06T13:48:24.071Z" }, + { url = "https://files.pythonhosted.org/packages/bd/98/ef2b6fe2903e377cbe870c3b2800d62552f1e3dbe81ce49e1923c53d1c5c/h5py-3.16.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:9300ad32dea9dfc5171f94d5f6948e159ed93e4701280b0f508773b3f582f402", size = 5400417, upload-time = "2026-03-06T13:48:25.728Z" }, + { url = "https://files.pythonhosted.org/packages/bc/81/5b62d760039eed64348c98129d17061fdfc7839fc9c04eaaad6dee1004e4/h5py-3.16.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:171038f23bccddfc23f344cadabdfc9917ff554db6a0d417180d2747fe4c75a7", size = 5185214, upload-time = "2026-03-06T13:48:27.436Z" }, + { url = "https://files.pythonhosted.org/packages/28/c4/532123bcd9080e250696779c927f2cb906c8bf3447df98f5ceb8dcded539/h5py-3.16.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7e420b539fb6023a259a1b14d4c9f6df8cf50d7268f48e161169987a57b737ff", size = 5414598, upload-time = "2026-03-06T13:48:29.49Z" }, + { url = "https://files.pythonhosted.org/packages/58/a5/4964bc0e91e86340c2bbda83420225b2f770dcf1eb8a39464871ad769436/h5py-3.16.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:e2c04d129f180019e216ee5f9c40b78a418634091c8782e1f723a6ca3658b965", size = 5198886, upload-time = "2026-03-06T13:48:38.879Z" }, + { url = "https://files.pythonhosted.org/packages/f1/16/d905e7f53e661ce2c24686c38048d8e2b750ffc4350009d41c4e6c6c9826/h5py-3.16.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:e4360f15875a532bc7b98196c7592ed4fc92672a57c0a621355961cafb17a6dd", size = 5404883, upload-time = "2026-03-06T13:48:41.324Z" }, + { url = "https://files.pythonhosted.org/packages/4b/f2/58f34cb74af46d39f4cd18ea20909a8514960c5a3e5b92fd06a28161e0a8/h5py-3.16.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:3fae9197390c325e62e0a1aa977f2f62d994aa87aab182abbea85479b791197c", size = 5192039, upload-time = "2026-03-06T13:48:43.117Z" }, + { url = "https://files.pythonhosted.org/packages/ce/ca/934a39c24ce2e2db017268c08da0537c20fa0be7e1549be3e977313fc8f5/h5py-3.16.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:43259303989ac8adacc9986695b31e35dba6fd1e297ff9c6a04b7da5542139cc", size = 5421526, upload-time = "2026-03-06T13:48:44.838Z" }, + { url = "https://files.pythonhosted.org/packages/f5/a1/af87f64b9f986889884243643621ebbd4ac72472ba8ec8cec891ac8e2ca1/h5py-3.16.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:0f456f556e4e2cebeebd9d66adf8dc321770a42593494a0b6f0af54a7567b242", size = 5074061, upload-time = "2026-03-06T13:48:54.089Z" }, + { url = "https://files.pythonhosted.org/packages/cc/d0/146f5eaff3dc246a9c7f6e5e4f42bd45cc613bce16693bcd4d1f7c958bf5/h5py-3.16.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:3e6cb3387c756de6a9492d601553dffea3fe11b5f22b443aac708c69f3f55e16", size = 5279216, upload-time = "2026-03-06T13:48:56.75Z" }, + { url = "https://files.pythonhosted.org/packages/a1/9d/12a13424f1e604fc7df9497b73c0356fb78c2fb206abd7465ce47226e8fd/h5py-3.16.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8389e13a1fd745ad2856873e8187fd10268b2d9677877bb667b41aebd771d8b7", size = 5070068, upload-time = "2026-03-06T13:48:59.169Z" }, + { url = "https://files.pythonhosted.org/packages/41/8c/bbe98f813722b4873818a8db3e15aa3e625b59278566905ac439725e8070/h5py-3.16.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:346df559a0f7dcb31cf8e44805319e2ab24b8957c45e7708ce503b2ec79ba725", size = 5300253, upload-time = "2026-03-06T13:49:02.033Z" }, +] + +[[package]] +name = "healpix" +version = "2025.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/43/1a/c1af658a2d06cdd2734b085b0eee34d51646f091ed13b1669d3a596de57c/healpix-2025.1.tar.gz", hash = "sha256:733f16f30c15d911c8209f4045f0b0934e5fcafa63b8b39d62e425a036adccea", size = 22744, upload-time = "2025-07-07T16:38:42.402Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6b/9e/a14baf09831eef05592a91b8c0c29918025b5069511c9300c4ce64ef5f25/healpix-2025.1-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1a1d41e0c2a98ef3d3cf48e18ca7edadb599641f1754e28e8df0a0a96471fdd4", size = 70836, upload-time = "2025-07-07T16:38:22.512Z" }, + { url = "https://files.pythonhosted.org/packages/0b/06/7946ec2c0fd5a4fb2b077c9c49358fb32577b21c4e27c7457464716780d3/healpix-2025.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2e347f3c76407d7c8018cd8da7eccb4aebd715e46b8f60111dcf161e969bd25f", size = 69891, upload-time = "2025-07-07T16:38:23.692Z" }, + { url = "https://files.pythonhosted.org/packages/81/cb/82b05f0779924b73c2522f440a65bd4d27af2099aec876c44168bea01136/healpix-2025.1-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:e8cacfd6359564c12c7bc81633e92fa7d6e74fffb834a1e08a38e88cb9ac3c50", size = 70865, upload-time = "2025-07-07T16:38:29.898Z" }, + { url = "https://files.pythonhosted.org/packages/fa/0c/fc40bad841a2c6d45b8e59973135be667c8f4b2000c870b374a3a746a66a/healpix-2025.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa546ca045be0661dfc42f7a4e7996f2134dd07d0d5639ae8d7d1a6b293470a2", size = 69939, upload-time = "2025-07-07T16:38:31.257Z" }, +] + +[[package]] +name = "healpy" +version = "1.19.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "astropy", marker = "sys_platform == 'linux'" }, + { name = "numpy", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e3/4e/6f5328f375f88c8c38314f24f82b7e1486ec0358c557779500382db1503c/healpy-1.19.0.tar.gz", hash = "sha256:28e839cb885a23d36c77fc3423a3cb9271a07fda94085bd12fc329f941130ec5", size = 4075006, upload-time = "2025-12-02T08:27:19.766Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/17/51/c07439b92bc05966006897762b7291d7d2c83fde8807b8d53a48e140a8b4/healpy-1.19.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:730095eef4bbe3c94039edb330d1800285cf43c7e16a81ce5b87edb31a8ffa42", size = 8239086, upload-time = "2025-12-02T08:26:53.076Z" }, + { url = "https://files.pythonhosted.org/packages/61/c6/42745aeff172755e55af2487491c7a7475fe1068f152850cc14d64e04f30/healpy-1.19.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:89dbe14b270b5479a9652d1ab9f28fc7fce34253549db665f2e91e6cea588883", size = 8255685, upload-time = "2025-12-02T08:26:54.361Z" }, + { url = "https://files.pythonhosted.org/packages/9d/86/2a223bd92dde578de34f07095c71152c84b158644782c4057ca9b25e53b5/healpy-1.19.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:29bb5f7acde68ca5850c3a59ba33cacf4c3768c9e85f7013a99aa5fbd127ce84", size = 9042629, upload-time = "2025-12-02T08:26:55.773Z" }, + { url = "https://files.pythonhosted.org/packages/18/6d/037a7bb889c92b3e3f792de6a692e636de0577ea62bdd0038b1eb68270af/healpy-1.19.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:126bef3ae6594f461435ac85c6bcb32e427eca43f743881d00186bc3a55da1d8", size = 9376051, upload-time = "2025-12-02T08:26:57.516Z" }, + { url = "https://files.pythonhosted.org/packages/de/bb/314bf8c493701b5842cdd74a1b5b34cea1522444042efad5b7cb17b8d159/healpy-1.19.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:086bae2510ac60f7cf9bbb520e1d1b8864cc8fca74b46b16e24857e74d08f896", size = 8198878, upload-time = "2025-12-02T08:27:03.119Z" }, + { url = "https://files.pythonhosted.org/packages/f6/d4/a60ed9a50768ff5e896dd94d878496ae16767925ea32c49d5a4189ab818a/healpy-1.19.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:920c0a1c6749c05c8ad9522a5a2630f7bc83124c5742ef50f91b9f5e6a1bdcc7", size = 8205835, upload-time = "2025-12-02T08:27:04.416Z" }, + { url = "https://files.pythonhosted.org/packages/6c/fd/5f4c989b53423bbad07c91a4b9d52de5cde9f1154e3d2b145b397e1b8cd8/healpy-1.19.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:26e3e6c50f2d256c9218f0fb0624406a93c4f22bc66deebf51a0f31fd5594b89", size = 8991846, upload-time = "2025-12-02T08:27:06.123Z" }, + { url = "https://files.pythonhosted.org/packages/d5/df/00636a5d2f1141b1fa9646069436c4fc68b35ac2c53ef520f8812b900f05/healpy-1.19.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bc3c243985abf1f1b5d91da12a23ceed49181dd9d0e46ed362babdc92c814aa8", size = 9325719, upload-time = "2025-12-02T08:27:08.138Z" }, + { url = "https://files.pythonhosted.org/packages/c5/ca/f583967e1395e41608225d0a6d29e582236f615d83023d730e63bac89baa/healpy-1.19.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:b3cf9c627af77a3fc670d6240d8a83485f373c274945ca8ad156fc2a25d6eb61", size = 8172544, upload-time = "2025-12-02T08:27:13.684Z" }, + { url = "https://files.pythonhosted.org/packages/85/ae/80a5e0d36ee51e72b27fb8e11d0d43dfb3f8e2ccc315a38865a2ccd5ed73/healpy-1.19.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:c22360ad7ec6f16bdbb650dececf52d21f7f0e03a943eb1a1046fdb9c51a3c5e", size = 8198134, upload-time = "2025-12-02T08:27:15.156Z" }, + { url = "https://files.pythonhosted.org/packages/36/7b/34b9954fdf76b1f5ab0a76228650c2575b189fb6f9f7865c98477a46086d/healpy-1.19.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:1a479826c1d6ae8312476e079a3f5c7aa3e40911d74f2d7069adcd62e98604ad", size = 8986426, upload-time = "2025-12-02T08:27:16.417Z" }, + { url = "https://files.pythonhosted.org/packages/94/df/bb3ef51f423c62576fb0775fe72f0d2028a10e3ffb20b4fc76146ea8757b/healpy-1.19.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:a103e327102e124785c1b5bdd379c6e5469137633212b56a6196bf04ddd100ff", size = 9307512, upload-time = "2025-12-02T08:27:18.03Z" }, +] + +[[package]] +name = "healsparse" +version = "1.13.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "hpgeom", marker = "sys_platform == 'linux'" }, + { name = "numpy", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e3/33/36520faabae128fe9a4a5cbeb0916be864d2eb34cf7410d52dc532af044e/healsparse-1.13.0.tar.gz", hash = "sha256:c21e4eb075c686bd306bdc1b40e039134c4ca60ccfa4e7e73845c107a5b16544", size = 133589, upload-time = "2026-07-07T18:33:05.481Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b4/2f/7674b91031a12a9b3cd69f3bb675d3b1eac59657139e23bc528ed6d33d0a/healsparse-1.13.0-py3-none-any.whl", hash = "sha256:3b475a61d7701526246a592ed980758f94764caba4355429bf470a2f9b812964", size = 70673, upload-time = "2026-07-07T18:33:04.514Z" }, +] + +[[package]] +name = "hpack" +version = "4.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/26/5b/fcabf6028144a8723726318b07a32c2f3314acdff6265743cf08a344b18e/hpack-4.2.0.tar.gz", hash = "sha256:0895cfa3b5531fc65fe439c05eb65144f123bf7a394fcaa56aa423548d8e45c0", size = 51300, upload-time = "2026-06-23T18:34:46.667Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/b4/4a9fcfb2aef6ba44d9073ecd301443aa00b3dac95de5619f2a7de7ec8a91/hpack-4.2.0-py3-none-any.whl", hash = "sha256:858ac0b02280fa582b5080d68db0899c62a80375e0e5413a74970c5e518b6986", size = 34246, upload-time = "2026-06-23T18:34:45.472Z" }, +] + +[[package]] +name = "hpgeom" +version = "1.5.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/07/72/27640de7d85a566b8ecd27e7894f371a19669c56c268756e18111a137df8/hpgeom-1.5.4.tar.gz", hash = "sha256:85ac73e267c11f3f248920d3541a0e6ffab821cae54f0d44414d1939dfb91200", size = 153906, upload-time = "2026-02-24T19:03:01.954Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/7f/bae5e1a44d76fa7396c4a004e2e86acb5fe70d8aaaa7f91190c65eb09e97/hpgeom-1.5.4-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d544a9834477b0aedf61ee934ce4598170cf14f16742200cd1729103edb5f506", size = 192550, upload-time = "2026-02-24T19:02:49.454Z" }, + { url = "https://files.pythonhosted.org/packages/68/4d/8b83dcbbd08bd7e713583490c14db848515a909515644037c80d20e2b80c/hpgeom-1.5.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7af0216ff1db0a49a771356562088c49185104a10502b68ab26c8ca2816d17b0", size = 197180, upload-time = "2026-02-24T19:02:50.453Z" }, + { url = "https://files.pythonhosted.org/packages/75/dc/4c0c6d7eba1d42be23794b03e6048af4de0d92c5805f4f2ed29bc1ca0f16/hpgeom-1.5.4-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d7058b3396fb7deb8b8637ac7f2861bfaa213574c50b9e771bf80f4d1e9064f3", size = 192643, upload-time = "2026-02-24T19:02:54.045Z" }, + { url = "https://files.pythonhosted.org/packages/8d/9a/41ba036857a5489d2c1e6f742903aae452d874a48c5b24889de79e02e668/hpgeom-1.5.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e160d40a18b8e80b7e233b4459adcbd4aea5d1fb48cefe7f07e8fc7dfbdcd9f3", size = 197257, upload-time = "2026-02-24T19:02:55.356Z" }, + { url = "https://files.pythonhosted.org/packages/a7/83/45d4208eb33432195df1998d5b5d75afc52d52cdec5ccdec80fa9d3fb2cc/hpgeom-1.5.4-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:47fe1c0c334d9722110a0d6346d2e4222aaed4454138996f9b2638a78ec98b60", size = 192606, upload-time = "2026-02-24T19:02:58.915Z" }, + { url = "https://files.pythonhosted.org/packages/1d/67/ab80b95519d453e72cd65ccc6cd411f23a4d997f492ed9ad0dbc51bce0fa/hpgeom-1.5.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fce969f1311a2f44c4f1c58fca1302b472ef798e702725a75bc16a342f924a66", size = 197071, upload-time = "2026-02-24T19:03:00.063Z" }, +] + +[[package]] +name = "html2text" +version = "2025.4.15" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f8/27/e158d86ba1e82967cc2f790b0cb02030d4a8bef58e0c79a8590e9678107f/html2text-2025.4.15.tar.gz", hash = "sha256:948a645f8f0bc3abe7fd587019a2197a12436cd73d0d4908af95bfc8da337588", size = 64316, upload-time = "2025-04-15T04:02:30.045Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1d/84/1a0f9555fd5f2b1c924ff932d99b40a0f8a6b12f6dd625e2a47f415b00ea/html2text-2025.4.15-py3-none-any.whl", hash = "sha256:00569167ffdab3d7767a4cdf589b7f57e777a5ed28d12907d8c58769ec734acc", size = 34656, upload-time = "2025-04-15T04:02:28.44Z" }, +] + +[[package]] +name = "httpcore" +version = "1.0.9" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi", marker = "sys_platform == 'linux'" }, + { name = "h11", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/94/82699a10bca87a5556c9c59b5963f2d039dbd239f25bc2a63907a05a14cb/httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8", size = 85484, upload-time = "2025-04-24T22:06:22.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/f5/f66802a942d491edb555dd61e3a9961140fd64c90bce1eafd741609d334d/httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55", size = 78784, upload-time = "2025-04-24T22:06:20.566Z" }, +] + +[[package]] +name = "httpx" +version = "0.28.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio", marker = "sys_platform == 'linux'" }, + { name = "certifi", marker = "sys_platform == 'linux'" }, + { name = "httpcore", marker = "sys_platform == 'linux'" }, + { name = "idna", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406, upload-time = "2024-12-06T15:37:23.222Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517, upload-time = "2024-12-06T15:37:21.509Z" }, +] + +[package.optional-dependencies] +http2 = [ + { name = "h2", marker = "sys_platform == 'linux'" }, +] + +[[package]] +name = "humanfriendly" +version = "10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cc/3f/2c29224acb2e2df4d2046e4c73ee2662023c58ff5b113c4c1adac0886c43/humanfriendly-10.0.tar.gz", hash = "sha256:6b0b831ce8f15f7300721aa49829fc4e83921a9a301cc7f606be6686a2288ddc", size = 360702, upload-time = "2021-09-17T21:40:43.31Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f0/0f/310fb31e39e2d734ccaa2c0fb981ee41f7bd5056ce9bc29b2248bd569169/humanfriendly-10.0-py2.py3-none-any.whl", hash = "sha256:1697e1a8a8f550fd43c2865cd84542fc175a61dcb779b6fee18cf6b6ccba1477", size = 86794, upload-time = "2021-09-17T21:40:39.897Z" }, +] + +[[package]] +name = "hyperframe" +version = "6.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/02/e7/94f8232d4a74cc99514c13a9f995811485a6903d48e5d952771ef6322e30/hyperframe-6.1.0.tar.gz", hash = "sha256:f630908a00854a7adeabd6382b43923a4c4cd4b821fcb527e6ab9e15382a3b08", size = 26566, upload-time = "2025-01-22T21:41:49.302Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/30/47d0bf6072f7252e6521f3447ccfa40b421b6824517f82854703d0f5a98b/hyperframe-6.1.0-py3-none-any.whl", hash = "sha256:b03380493a519fce58ea5af42e4a42317bf9bd425596f7a0835ffce80f1a42e5", size = 13007, upload-time = "2025-01-22T21:41:47.295Z" }, +] + +[[package]] +name = "idna" +version = "3.18" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cd/63/9496c57188a2ee585e0f1db071d75089a11e98aa86eb99d9d7618fc1edce/idna-3.18.tar.gz", hash = "sha256:ffb385a7e039654cef1ab9ef32c6fafe283c0c0467bba1d9029738ce4a14a848", size = 196711, upload-time = "2026-06-02T14:34:07.794Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1e/5e/d4e9f1a599fb8e573b7b87160658329fbf28d19eac2718f51fc3def3aa5a/idna-3.18-py3-none-any.whl", hash = "sha256:7f952cbe720b688055e3f87de14f5c3e5fdaa8bc3928985c4077ca689de849a2", size = 65455, upload-time = "2026-06-02T14:34:06.319Z" }, +] + +[[package]] +name = "imageio" +version = "2.37.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", marker = "sys_platform == 'linux'" }, + { name = "pillow", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/84/93bcd1300216ea50811cee96873b84a1bebf8d0489ffaf7f2a3756bab866/imageio-2.37.3.tar.gz", hash = "sha256:bbb37efbfc4c400fcd534b367b91fcd66d5da639aaa138034431a1c5e0a41451", size = 389673, upload-time = "2026-03-09T11:31:12.573Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/fa/391e437a34e55095173dca5f24070d89cbc233ff85bf1c29c93248c6588d/imageio-2.37.3-py3-none-any.whl", hash = "sha256:46f5bb8522cd421c0f5ae104d8268f569d856b29eb1a13b92829d1970f32c9f0", size = 317646, upload-time = "2026-03-09T11:31:10.771Z" }, +] + +[[package]] +name = "imagesize" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/6c/e6/7bf14eeb8f8b7251141944835abd42eb20a658d89084b7e1f3e5fe394090/imagesize-2.0.0.tar.gz", hash = "sha256:8e8358c4a05c304f1fccf7ff96f036e7243a189e9e42e90851993c558cfe9ee3", size = 1773045, upload-time = "2026-03-03T14:18:29.941Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5f/53/fb7122b71361a0d121b669dcf3d31244ef75badbbb724af388948de543e2/imagesize-2.0.0-py2.py3-none-any.whl", hash = "sha256:5667c5bbb57ab3f1fa4bc366f4fbc971db3d5ed011fd2715fd8001f782718d96", size = 9441, upload-time = "2026-03-03T14:18:27.892Z" }, +] + +[[package]] +name = "immutables" +version = "0.21" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/69/41/0ccaa6ef9943c0609ec5aa663a3b3e681c1712c1007147b84590cec706a0/immutables-0.21.tar.gz", hash = "sha256:b55ffaf0449790242feb4c56ab799ea7af92801a0a43f9e2f4f8af2ab24dfc4a", size = 89008, upload-time = "2024-10-10T00:55:01.434Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f7/52/cb9e2bb7a69338155ffabbd2f993c968c750dd2d5c6c6eaa6ebb7bfcbdfa/immutables-0.21-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b48b116aaca4500398058b5a87814857a60c4cb09417fecc12d7da0f5639b73d", size = 104270, upload-time = "2024-10-10T00:54:21.912Z" }, + { url = "https://files.pythonhosted.org/packages/0f/a4/25df835a9b9b372a4a869a8a1ac30a32199f2b3f581ad0e249f7e3d19eed/immutables-0.21-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dad7c0c74b285cc0e555ec0e97acbdc6f1862fcd16b99abd612df3243732e741", size = 104864, upload-time = "2024-10-10T00:54:22.956Z" }, + { url = "https://files.pythonhosted.org/packages/4a/51/b548fbc657134d658e179ee8d201ae82d9049aba5c3cb2d858ed2ecb7e3f/immutables-0.21-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e44346e2221a5a676c880ca8e0e6429fa24d1a4ae562573f5c04d7f2e759b030", size = 99733, upload-time = "2024-10-10T00:54:23.99Z" }, + { url = "https://files.pythonhosted.org/packages/47/db/d7b1e0e88faf07fe9a88579a86f58078a9a37fff871f4b3dbcf28cad9a12/immutables-0.21-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:8b10139b529a460e53fe8be699ebd848c54c8a33ebe67763bcfcc809a475a26f", size = 101698, upload-time = "2024-10-10T00:54:25.734Z" }, + { url = "https://files.pythonhosted.org/packages/d2/d0/a5fb7c164ddb298ec37537e618b70dfa30c7cae9fac01de374c36489cbc9/immutables-0.21-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:583d2a63e444ce1538cc2bda56ae1f4a1a11473dbc0377c82b516bc7eec3b81e", size = 104334, upload-time = "2024-10-10T00:54:31.284Z" }, + { url = "https://files.pythonhosted.org/packages/f3/a5/5fda0ee4a261a85124011ac0750fec678f00e1b2d4a5502b149a3b4d86d9/immutables-0.21-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b274a52da9b106db55eceb93fc1aea858c4e6f4740189e3548e38613eafc2021", size = 104898, upload-time = "2024-10-10T00:54:32.295Z" }, + { url = "https://files.pythonhosted.org/packages/93/fa/d46bfe92f2c66d35916344176ff87fa839aac9c16849652947e722b7a15f/immutables-0.21-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:338bede057250b33716a3e4892e15df0bf5a5ddbf1d67ead996b3e680b49ef9e", size = 99966, upload-time = "2024-10-10T00:54:34.046Z" }, + { url = "https://files.pythonhosted.org/packages/d7/f5/2a19e2e095f7a39d8d77dcc10669734d2d99773ce00c99bdcfeeb7d714e6/immutables-0.21-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8781c89583b68f604cf30f0978b722165824c3075888639fde771bf1a3e12dc0", size = 101773, upload-time = "2024-10-10T00:54:35.851Z" }, +] + +[[package]] +name = "importlib-metadata" +version = "9.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "zipp", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a9/01/15bb152d77b21318514a96f43af312635eb2500c96b55398d020c93d86ea/importlib_metadata-9.0.0.tar.gz", hash = "sha256:a4f57ab599e6a2e3016d7595cfd72eb4661a5106e787a95bcc90c7105b831efc", size = 56405, upload-time = "2026-03-20T06:42:56.999Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/3d/2d244233ac4f76e38533cfcb2991c9eb4c7bf688ae0a036d30725b8faafe/importlib_metadata-9.0.0-py3-none-any.whl", hash = "sha256:2d21d1cc5a017bd0559e36150c21c830ab1dc304dedd1b7ea85d20f45ef3edd7", size = 27789, upload-time = "2026-03-20T06:42:55.665Z" }, +] + +[[package]] +name = "iniconfig" +version = "2.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/72/34/14ca021ce8e5dfedc35312d08ba8bf51fdd999c576889fc2c24cb97f4f10/iniconfig-2.3.0.tar.gz", hash = "sha256:c76315c77db068650d49c5b56314774a7804df16fee4402c1f19d6d15d8c4730", size = 20503, upload-time = "2025-10-18T21:55:43.219Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/b1/3846dd7f199d53cb17f49cba7e651e9ce294d8497c8c150530ed11865bb8/iniconfig-2.3.0-py3-none-any.whl", hash = "sha256:f631c04d2c48c52b84d0d0549c99ff3859c98df65b3101406327ecc7d53fbf12", size = 7484, upload-time = "2025-10-18T21:55:41.639Z" }, +] + +[[package]] +name = "ipykernel" +version = "7.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "comm", marker = "sys_platform == 'linux'" }, + { name = "debugpy", marker = "sys_platform == 'linux'" }, + { name = "ipython", marker = "sys_platform == 'linux'" }, + { name = "jupyter-client", marker = "sys_platform == 'linux'" }, + { name = "jupyter-core", marker = "sys_platform == 'linux'" }, + { name = "matplotlib-inline", marker = "sys_platform == 'linux'" }, + { name = "nest-asyncio2", marker = "sys_platform == 'linux'" }, + { name = "packaging", marker = "sys_platform == 'linux'" }, + { name = "psutil", marker = "sys_platform == 'linux'" }, + { name = "pyzmq", marker = "sys_platform == 'linux'" }, + { name = "tornado", marker = "sys_platform == 'linux'" }, + { name = "traitlets", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3d/c4/e4a38f579de4225a561305666f7541cdabb30075def2aa1ac17bd73c1fb5/ipykernel-7.3.0.tar.gz", hash = "sha256:9acaaaf97d16355166e4085afe9d225bfbdf2b7ef520f9df3be8f2b248275e09", size = 184899, upload-time = "2026-06-10T08:41:25.481Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3d/02/77b271f5dc58bfbc0b577c877b2365d1ffea2afe66a80c13f2312820348c/ipykernel-7.3.0-py3-none-any.whl", hash = "sha256:897eb64da762549ef610698fca5e9675195ec6ac8ec7f19d81ce1ca20c876057", size = 120583, upload-time = "2026-06-10T08:41:23.648Z" }, +] + +[[package]] +name = "ipython" +version = "9.15.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "decorator", marker = "sys_platform == 'linux'" }, + { name = "ipython-pygments-lexers", marker = "sys_platform == 'linux'" }, + { name = "jedi", marker = "sys_platform == 'linux'" }, + { name = "matplotlib-inline", marker = "sys_platform == 'linux'" }, + { name = "pexpect", marker = "sys_platform == 'linux'" }, + { name = "prompt-toolkit", marker = "sys_platform == 'linux'" }, + { name = "psutil", marker = "sys_platform == 'linux'" }, + { name = "pygments", marker = "sys_platform == 'linux'" }, + { name = "stack-data", marker = "sys_platform == 'linux'" }, + { name = "traitlets", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/53/59/165d3b4d75cc34add3122c4417ecb229085140ac573103c223cd01dde96f/ipython-9.15.0.tar.gz", hash = "sha256:da2819ce2aa83135257df830660b1176d986c3d2876db24df01974fa955b2756", size = 4442580, upload-time = "2026-06-26T11:03:35.913Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/40/3a/948263ca3b9d65bb2b1b0c521b3a49fad5d59ada58724bd87d2bd5ff3f36/ipython-9.15.0-py3-none-any.whl", hash = "sha256:515ad9c3cdf0c932a5a9f6245419e8aba706b7bd03c3e1d3a1c83d9351d6aa6e", size = 630895, upload-time = "2026-06-26T11:03:33.809Z" }, +] + +[[package]] +name = "ipython-genutils" +version = "0.2.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e8/69/fbeffffc05236398ebfcfb512b6d2511c622871dca1746361006da310399/ipython_genutils-0.2.0.tar.gz", hash = "sha256:eb2e116e75ecef9d4d228fdc66af54269afa26ab4463042e33785b887c628ba8", size = 22208, upload-time = "2017-03-13T22:12:26.393Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fa/bc/9bd3b5c2b4774d5f33b2d544f1460be9df7df2fe42f352135381c347c69a/ipython_genutils-0.2.0-py2.py3-none-any.whl", hash = "sha256:72dd37233799e619666c9f639a9da83c34013a73e8bbc79a7a6348d93c61fab8", size = 26343, upload-time = "2017-03-13T22:12:25.412Z" }, +] + +[[package]] +name = "ipython-pygments-lexers" +version = "1.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pygments", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ef/4c/5dd1d8af08107f88c7f741ead7a40854b8ac24ddf9ae850afbcf698aa552/ipython_pygments_lexers-1.1.1.tar.gz", hash = "sha256:09c0138009e56b6854f9535736f4171d855c8c08a563a0dcd8022f78355c7e81", size = 8393, upload-time = "2025-01-17T11:24:34.505Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d9/33/1f075bf72b0b747cb3288d011319aaf64083cf2efef8354174e3ed4540e2/ipython_pygments_lexers-1.1.1-py3-none-any.whl", hash = "sha256:a9462224a505ade19a605f71f8fa63c2048833ce50abc86768a0d81d876dc81c", size = 8074, upload-time = "2025-01-17T11:24:33.271Z" }, +] + +[[package]] +name = "ipywidgets" +version = "8.1.8" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "comm", marker = "sys_platform == 'linux'" }, + { name = "ipython", marker = "sys_platform == 'linux'" }, + { name = "jupyterlab-widgets", marker = "sys_platform == 'linux'" }, + { name = "traitlets", marker = "sys_platform == 'linux'" }, + { name = "widgetsnbextension", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4c/ae/c5ce1edc1afe042eadb445e95b0671b03cee61895264357956e61c0d2ac0/ipywidgets-8.1.8.tar.gz", hash = "sha256:61f969306b95f85fba6b6986b7fe45d73124d1d9e3023a8068710d47a22ea668", size = 116739, upload-time = "2025-11-01T21:18:12.393Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/56/6d/0d9848617b9f753b87f214f1c682592f7ca42de085f564352f10f0843026/ipywidgets-8.1.8-py3-none-any.whl", hash = "sha256:ecaca67aed704a338f88f67b1181b58f821ab5dc89c1f0f5ef99db43c1c2921e", size = 139808, upload-time = "2025-11-01T21:18:10.956Z" }, +] + +[[package]] +name = "isoduration" +version = "20.11.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "arrow", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7c/1a/3c8edc664e06e6bd06cce40c6b22da5f1429aa4224d0c590f3be21c91ead/isoduration-20.11.0.tar.gz", hash = "sha256:ac2f9015137935279eac671f94f89eb00584f940f5dc49462a0c4ee692ba1bd9", size = 11649, upload-time = "2020-11-01T11:00:00.312Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/55/e5326141505c5d5e34c5e0935d2908a74e4561eca44108fbfb9c13d2911a/isoduration-20.11.0-py3-none-any.whl", hash = "sha256:b2904c2a4228c3d44f409c8ae8e2370eb21a26f7ac2ec5446df141dde3452042", size = 11321, upload-time = "2020-11-01T10:59:58.02Z" }, +] + +[[package]] +name = "jaraco-classes" +version = "3.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "more-itertools", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/c0/ed4a27bc5571b99e3cff68f8a9fa5b56ff7df1c2251cc715a652ddd26402/jaraco.classes-3.4.0.tar.gz", hash = "sha256:47a024b51d0239c0dd8c8540c6c7f484be3b8fcf0b2d85c13825780d3b3f3acd", size = 11780, upload-time = "2024-03-31T07:27:36.643Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7f/66/b15ce62552d84bbfcec9a4873ab79d993a1dd4edb922cbfccae192bd5b5f/jaraco.classes-3.4.0-py3-none-any.whl", hash = "sha256:f662826b6bed8cace05e7ff873ce0f9283b5c924470fe664fff1c2f00f581790", size = 6777, upload-time = "2024-03-31T07:27:34.792Z" }, +] + +[[package]] +name = "jaraco-context" +version = "6.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/af/50/4763cd07e722bb6285316d390a164bc7e479db9d90daa769f22578f698b4/jaraco_context-6.1.2.tar.gz", hash = "sha256:f1a6c9d391e661cc5b8d39861ff077a7dc24dc23833ccee564b234b81c82dfe3", size = 16801, upload-time = "2026-03-20T22:13:33.922Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f2/58/bc8954bda5fcda97bd7c19be11b85f91973d67a706ed4a3aec33e7de22db/jaraco_context-6.1.2-py3-none-any.whl", hash = "sha256:bf8150b79a2d5d91ae48629d8b427a8f7ba0e1097dd6202a9059f29a36379535", size = 7871, upload-time = "2026-03-20T22:13:32.808Z" }, +] + +[[package]] +name = "jaraco-functools" +version = "4.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "more-itertools", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/36/cf/ea4ef2920830dea3f5ab2ea4da6fb67724e6dca80ee2553788c3607243d0/jaraco_functools-4.5.0.tar.gz", hash = "sha256:3bb5665ea4a020cf78a7040e89154c77edadb3ca74f366479669c5999aa70b03", size = 20272, upload-time = "2026-05-15T21:34:10.025Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/96/9a/982e48afcffcd727a9144506720ffd4224b6b7e355c98641866f38b7c043/jaraco_functools-4.5.0-py3-none-any.whl", hash = "sha256:79ce39246eddbde4b3a03b77ea5f0f7878dc669b166a66cf3fa8e266aa3fa2f4", size = 10594, upload-time = "2026-05-15T21:34:08.595Z" }, +] + +[[package]] +name = "jedi" +version = "0.20.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "parso", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/46/b7/a3635f6a2d7cf5b5dd98064fc1d5fbbafcb25477bcea204a3a92145d158b/jedi-0.20.0.tar.gz", hash = "sha256:c3f4ccbd276696f4b19c54618d4fb18f9fc24b0aef02acf704b23f487daa1011", size = 3119416, upload-time = "2026-05-01T23:38:47.814Z" } +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 = "jeepney" +version = "0.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7b/6f/357efd7602486741aa73ffc0617fb310a29b588ed0fd69c2399acbb85b0c/jeepney-0.9.0.tar.gz", hash = "sha256:cf0e9e845622b81e4a28df94c40345400256ec608d0e55bb8a3feaa9163f5732", size = 106758, upload-time = "2025-02-27T18:51:01.684Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b2/a3/e137168c9c44d18eff0376253da9f1e9234d0239e0ee230d2fee6cea8e55/jeepney-0.9.0-py3-none-any.whl", hash = "sha256:97e5714520c16fc0a45695e5365a2e11b81ea79bba796e26f9f1d178cb182683", size = 49010, upload-time = "2025-02-27T18:51:00.104Z" }, +] + +[[package]] +name = "jinja2" +version = "3.1.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markupsafe", marker = "sys_platform == 'linux'" }, +] +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.5.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/41/f2/d34e8b3a08a9cc79a50b2208a93dce981fe615b64d5a4d4abee421d898df/joblib-1.5.3.tar.gz", hash = "sha256:8561a3269e6801106863fd0d6d84bb737be9e7631e33aaed3fb9ce5953688da3", size = 331603, upload-time = "2025-12-15T08:41:46.427Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/91/984aca2ec129e2757d1e4e3c81c3fcda9d0f85b74670a094cc443d9ee949/joblib-1.5.3-py3-none-any.whl", hash = "sha256:5fc3c5039fc5ca8c0276333a188bbd59d6b7ab37fe6632daa76bc7f9ec18e713", size = 309071, upload-time = "2025-12-15T08:41:44.973Z" }, +] + +[[package]] +name = "json5" +version = "0.15.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e4/7d/05c46a96a78147ae3bf99c2f4169ce144a70220b8d6fcd56f6ec368b8ce9/json5-0.15.0.tar.gz", hash = "sha256:7424d1f1eb1d56da6e3d70643f53619862b4ce81440bdb8ecfd6f875e5ba4a71", size = 53278, upload-time = "2026-06-19T20:08:27.716Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/be/59527c99478aade6bb33a68d72e6e18dd4e6ff6eacfc7d01bdb15bc76912/json5-0.15.0-py3-none-any.whl", hash = "sha256:56636a30c0e8a4665fe2179c0212f32eae3796dea89ea6f649b9436ecdb39618", size = 36570, upload-time = "2026-06-19T20:08:26.748Z" }, +] + +[[package]] +name = "jsonpointer" +version = "3.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/c7/af399a2e7a67fd18d63c40c5e62d3af4e67b836a2107468b6a5ea24c4304/jsonpointer-3.1.1.tar.gz", hash = "sha256:0b801c7db33a904024f6004d526dcc53bbb8a4a0f4e32bfd10beadf60adf1900", size = 9068, upload-time = "2026-03-23T22:32:32.458Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/6a/a83720e953b1682d2d109d3c2dbb0bc9bf28cc1cbc205be4ef4be5da709d/jsonpointer-3.1.1-py3-none-any.whl", hash = "sha256:8ff8b95779d071ba472cf5bc913028df06031797532f08a7d5b602d8b2a488ca", size = 7659, upload-time = "2026-03-23T22:32:31.568Z" }, +] + +[[package]] +name = "jsonschema" +version = "4.26.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs", marker = "sys_platform == 'linux'" }, + { name = "jsonschema-specifications", marker = "sys_platform == 'linux'" }, + { name = "referencing", marker = "sys_platform == 'linux'" }, + { name = "rpds-py", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b3/fc/e067678238fa451312d4c62bf6e6cf5ec56375422aee02f9cb5f909b3047/jsonschema-4.26.0.tar.gz", hash = "sha256:0c26707e2efad8aa1bfc5b7ce170f3fccc2e4918ff85989ba9ffa9facb2be326", size = 366583, upload-time = "2026-01-07T13:41:07.246Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/69/90/f63fb5873511e014207a475e2bb4e8b2e570d655b00ac19a9a0ca0a385ee/jsonschema-4.26.0-py3-none-any.whl", hash = "sha256:d489f15263b8d200f8387e64b4c3a75f06629559fb73deb8fdfb525f2dab50ce", size = 90630, upload-time = "2026-01-07T13:41:05.306Z" }, +] + +[package.optional-dependencies] +format-nongpl = [ + { name = "fqdn", marker = "sys_platform == 'linux'" }, + { name = "idna", marker = "sys_platform == 'linux'" }, + { name = "isoduration", marker = "sys_platform == 'linux'" }, + { name = "jsonpointer", marker = "sys_platform == 'linux'" }, + { name = "rfc3339-validator", marker = "sys_platform == 'linux'" }, + { name = "rfc3986-validator", marker = "sys_platform == 'linux'" }, + { name = "rfc3987-syntax", marker = "sys_platform == 'linux'" }, + { name = "uri-template", marker = "sys_platform == 'linux'" }, + { name = "webcolors", marker = "sys_platform == 'linux'" }, +] + +[[package]] +name = "jsonschema-specifications" +version = "2025.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "referencing", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/19/74/a633ee74eb36c44aa6d1095e7cc5569bebf04342ee146178e2d36600708b/jsonschema_specifications-2025.9.1.tar.gz", hash = "sha256:b540987f239e745613c7a9176f3edb72b832a4ac465cf02712288397832b5e8d", size = 32855, upload-time = "2025-09-08T01:34:59.186Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/41/45/1a4ed80516f02155c51f51e8cedb3c1902296743db0bbc66608a0db2814f/jsonschema_specifications-2025.9.1-py3-none-any.whl", hash = "sha256:98802fee3a11ee76ecaca44429fda8a41bff98b00a0f2838151b113f210cc6fe", size = 18437, upload-time = "2025-09-08T01:34:57.871Z" }, +] + +[[package]] +name = "jupyter" +version = "1.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ipykernel", marker = "sys_platform == 'linux'" }, + { name = "ipywidgets", marker = "sys_platform == 'linux'" }, + { name = "jupyter-console", marker = "sys_platform == 'linux'" }, + { name = "jupyterlab", marker = "sys_platform == 'linux'" }, + { name = "nbconvert", marker = "sys_platform == 'linux'" }, + { name = "notebook", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/58/f3/af28ea964ab8bc1e472dba2e82627d36d470c51f5cd38c37502eeffaa25e/jupyter-1.1.1.tar.gz", hash = "sha256:d55467bceabdea49d7e3624af7e33d59c37fff53ed3a350e1ac957bed731de7a", size = 5714959, upload-time = "2024-08-30T07:15:48.299Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/64/285f20a31679bf547b75602702f7800e74dbabae36ef324f716c02804753/jupyter-1.1.1-py2.py3-none-any.whl", hash = "sha256:7a59533c22af65439b24bbe60373a4e95af8f16ac65a6c00820ad378e3f7cc83", size = 2657, upload-time = "2024-08-30T07:15:47.045Z" }, +] + +[[package]] +name = "jupyter-builder" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-core", marker = "sys_platform == 'linux'" }, + { name = "traitlets", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0d/df/db5efc4e28803a1421350445e53d85ec571a4e6928e3524ccc39f4e16584/jupyter_builder-1.1.0.tar.gz", hash = "sha256:b996e8af616900f18724fa34883169d869be2205497940bec78a3a1031eb897d", size = 971142, upload-time = "2026-07-11T07:24:02.4Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7c/fb/53adbc72931b4429275b160044c3e1bcbc8fbb5ea6b8f318a357834842fb/jupyter_builder-1.1.0-py3-none-any.whl", hash = "sha256:d9d5280e8845f726663545c3a6db55bd205127616eeb8958481091d6cba71b6a", size = 912964, upload-time = "2026-07-11T07:24:00.279Z" }, +] + +[[package]] +name = "jupyter-client" +version = "8.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-core", marker = "sys_platform == 'linux'" }, + { name = "python-dateutil", marker = "sys_platform == 'linux'" }, + { name = "pyzmq", marker = "sys_platform == 'linux'" }, + { name = "tornado", marker = "sys_platform == 'linux'" }, + { name = "traitlets", marker = "sys_platform == 'linux'" }, + { name = "typing-extensions", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7d/dc/5512503b088997c2250b8bf18258fba9d9ce5ead641183700960d3c9d342/jupyter_client-8.9.1.tar.gz", hash = "sha256:a58f730dd9e728ba16ba1d62ebccf7ffe1ebbdbce4e95cfae941b7321ae1f4fa", size = 359256, upload-time = "2026-06-09T13:15:01.033Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/6f/56d39bf385c5c27988aebaf0c18a2a17e960575740100973511018bd904e/jupyter_client-8.9.1-py3-none-any.whl", hash = "sha256:0b7a295bc46e8751e9adae84781f726c851c1d911bd793edc4a3bde942e3da81", size = 109828, upload-time = "2026-06-09T13:14:58.835Z" }, +] + +[[package]] +name = "jupyter-console" +version = "6.6.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ipykernel", marker = "sys_platform == 'linux'" }, + { name = "ipython", marker = "sys_platform == 'linux'" }, + { name = "jupyter-client", marker = "sys_platform == 'linux'" }, + { name = "jupyter-core", marker = "sys_platform == 'linux'" }, + { name = "prompt-toolkit", marker = "sys_platform == 'linux'" }, + { name = "pygments", marker = "sys_platform == 'linux'" }, + { name = "pyzmq", marker = "sys_platform == 'linux'" }, + { name = "traitlets", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bd/2d/e2fd31e2fc41c14e2bcb6c976ab732597e907523f6b2420305f9fc7fdbdb/jupyter_console-6.6.3.tar.gz", hash = "sha256:566a4bf31c87adbfadf22cdf846e3069b59a71ed5da71d6ba4d8aaad14a53539", size = 34363, upload-time = "2023-03-06T14:13:31.02Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ca/77/71d78d58f15c22db16328a476426f7ac4a60d3a5a7ba3b9627ee2f7903d4/jupyter_console-6.6.3-py3-none-any.whl", hash = "sha256:309d33409fcc92ffdad25f0bcdf9a4a9daa61b6f341177570fdac03de5352485", size = 24510, upload-time = "2023-03-06T14:13:28.229Z" }, +] + +[[package]] +name = "jupyter-core" +version = "5.9.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "platformdirs", marker = "sys_platform == 'linux'" }, + { name = "traitlets", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/02/49/9d1284d0dc65e2c757b74c6687b6d319b02f822ad039e5c512df9194d9dd/jupyter_core-5.9.1.tar.gz", hash = "sha256:4d09aaff303b9566c3ce657f580bd089ff5c91f5f89cf7d8846c3cdf465b5508", size = 89814, upload-time = "2025-10-16T19:19:18.444Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/e7/80988e32bf6f73919a113473a604f5a8f09094de312b9d52b79c2df7612b/jupyter_core-5.9.1-py3-none-any.whl", hash = "sha256:ebf87fdc6073d142e114c72c9e29a9d7ca03fad818c5d300ce2adc1fb0743407", size = 29032, upload-time = "2025-10-16T19:19:16.783Z" }, +] + +[[package]] +name = "jupyter-events" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jsonschema", extra = ["format-nongpl"], marker = "sys_platform == 'linux'" }, + { name = "packaging", marker = "sys_platform == 'linux'" }, + { name = "python-json-logger", marker = "sys_platform == 'linux'" }, + { name = "pyyaml", marker = "sys_platform == 'linux'" }, + { name = "referencing", marker = "sys_platform == 'linux'" }, + { name = "rfc3339-validator", marker = "sys_platform == 'linux'" }, + { name = "rfc3986-validator", marker = "sys_platform == 'linux'" }, + { name = "traitlets", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/18/f8/475c4241b2b75af0deaae453ed003c6c851766dbc44d332d8baf245dc931/jupyter_events-0.12.1.tar.gz", hash = "sha256:faff25f77218335752f35f23c5fe6e4a392a7bd99a5939ccb9b8fbf594636cf3", size = 62854, upload-time = "2026-04-20T23:17:50.66Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/eb/6c/6fcde0c8f616ed360ffd3587f7db9e225a7e62b583a04494d2f069cf64ea/jupyter_events-0.12.1-py3-none-any.whl", hash = "sha256:c366585253f537a627da52fa7ca7410c5b5301fe893f511e7b077c2d93ec8bcf", size = 19512, upload-time = "2026-04-20T23:17:48.927Z" }, +] + +[[package]] +name = "jupyter-lsp" +version = "2.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-server", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/36/ff/1e4a61f5170a9a1d978f3ac3872449de6c01fc71eaf89657824c878b1549/jupyter_lsp-2.3.1.tar.gz", hash = "sha256:fdf8a4aa7d85813976d6e29e95e6a2c8f752701f926f2715305249a3829805a6", size = 55677, upload-time = "2026-04-02T08:10:06.749Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/23/e8/9d61dcbd1dce8ef418f06befd4ac084b4720429c26b0b1222bc218685eff/jupyter_lsp-2.3.1-py3-none-any.whl", hash = "sha256:71b954d834e85ff3096400554f2eefaf7fe37053036f9a782b0f7c5e42dadb81", size = 77513, upload-time = "2026-04-02T08:10:01.753Z" }, +] + +[[package]] +name = "jupyter-server" +version = "2.20.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "anyio", marker = "sys_platform == 'linux'" }, + { name = "argon2-cffi", marker = "sys_platform == 'linux'" }, + { name = "jinja2", marker = "sys_platform == 'linux'" }, + { name = "jupyter-client", marker = "sys_platform == 'linux'" }, + { name = "jupyter-core", marker = "sys_platform == 'linux'" }, + { name = "jupyter-events", marker = "sys_platform == 'linux'" }, + { name = "jupyter-server-terminals", marker = "sys_platform == 'linux'" }, + { name = "nbconvert", marker = "sys_platform == 'linux'" }, + { name = "nbformat", marker = "sys_platform == 'linux'" }, + { name = "packaging", marker = "sys_platform == 'linux'" }, + { name = "prometheus-client", marker = "sys_platform == 'linux'" }, + { name = "pyzmq", marker = "sys_platform == 'linux'" }, + { name = "send2trash", marker = "sys_platform == 'linux'" }, + { name = "terminado", marker = "sys_platform == 'linux'" }, + { name = "tornado", marker = "sys_platform == 'linux'" }, + { name = "traitlets", marker = "sys_platform == 'linux'" }, + { name = "websocket-client", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6b/dc/db3a582633170186f8c8b31298d7eb26ad0eb031a1f53476c258b64eed05/jupyter_server-2.20.0.tar.gz", hash = "sha256:b5778ba337d8015a3dc2b80803ecdd5ac18d3797fddf61a50ea5fb472b4ebe14", size = 756523, upload-time = "2026-06-17T12:09:09.435Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f3/71/8c002223e873a870f5c41dc69b0a7c922301123e4a31d5d01ecb700aef77/jupyter_server-2.20.0-py3-none-any.whl", hash = "sha256:c3b67c93c471e947c18b5026f04f21614218adb706df8f48227d3ee8e0a7cdcc", size = 393143, upload-time = "2026-06-17T12:09:07.234Z" }, +] + +[[package]] +name = "jupyter-server-terminals" +version = "0.5.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "terminado", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/f4/a7/bcd0a9b0cbba88986fe944aaaf91bfda603e5a50bda8ed15123f381a3b2f/jupyter_server_terminals-0.5.4.tar.gz", hash = "sha256:bbda128ed41d0be9020349f9f1f2a4ab9952a73ed5f5ac9f1419794761fb87f5", size = 31770, upload-time = "2026-01-14T16:53:20.213Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/2d/6674563f71c6320841fc300911a55143925112a72a883e2ca71fba4c618d/jupyter_server_terminals-0.5.4-py3-none-any.whl", hash = "sha256:55be353fc74a80bc7f3b20e6be50a55a61cd525626f578dcb66a5708e2007d14", size = 13704, upload-time = "2026-01-14T16:53:18.738Z" }, +] + +[[package]] +name = "jupyterlab" +version = "4.6.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "async-lru", marker = "sys_platform == 'linux'" }, + { name = "httpx", marker = "sys_platform == 'linux'" }, + { name = "ipykernel", marker = "sys_platform == 'linux'" }, + { name = "jinja2", marker = "sys_platform == 'linux'" }, + { name = "jupyter-builder", marker = "sys_platform == 'linux'" }, + { name = "jupyter-core", marker = "sys_platform == 'linux'" }, + { name = "jupyter-lsp", marker = "sys_platform == 'linux'" }, + { name = "jupyter-server", marker = "sys_platform == 'linux'" }, + { name = "jupyterlab-server", marker = "sys_platform == 'linux'" }, + { name = "notebook-shim", marker = "sys_platform == 'linux'" }, + { name = "packaging", marker = "sys_platform == 'linux'" }, + { name = "tornado", marker = "sys_platform == 'linux'" }, + { name = "traitlets", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bc/2a/d6af53bfd45a43a5bfe7e40ba47ee7a8921a807daf4bb708e3a295bbb54d/jupyterlab-4.6.1.tar.gz", hash = "sha256:75315982ed28427edaa62bb85eadb5105e4043a757643c910efd787fe6ed0837", size = 28179125, upload-time = "2026-06-29T12:48:45.402Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5a/81/90ac6cc31d248e83a0d1eab343a5e6e68bc783d3f74fbe61640f42a61da4/jupyterlab-4.6.1-py3-none-any.whl", hash = "sha256:85a58546c831f3dce6cf919468c26874c9065e99c42279fb4abb8e1b552a98bb", size = 17164660, upload-time = "2026-06-29T12:48:41.21Z" }, +] + +[[package]] +name = "jupyterlab-pygments" +version = "0.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/90/51/9187be60d989df97f5f0aba133fa54e7300f17616e065d1ada7d7646b6d6/jupyterlab_pygments-0.3.0.tar.gz", hash = "sha256:721aca4d9029252b11cfa9d185e5b5af4d54772bb8072f9b7036f4170054d35d", size = 512900, upload-time = "2023-11-23T09:26:37.44Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b1/dd/ead9d8ea85bf202d90cc513b533f9c363121c7792674f78e0d8a854b63b4/jupyterlab_pygments-0.3.0-py3-none-any.whl", hash = "sha256:841a89020971da1d8693f1a99997aefc5dc424bb1b251fd6322462a1b8842780", size = 15884, upload-time = "2023-11-23T09:26:34.325Z" }, +] + +[[package]] +name = "jupyterlab-server" +version = "2.28.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "babel", marker = "sys_platform == 'linux'" }, + { name = "jinja2", marker = "sys_platform == 'linux'" }, + { name = "json5", marker = "sys_platform == 'linux'" }, + { name = "jsonschema", marker = "sys_platform == 'linux'" }, + { name = "jupyter-server", marker = "sys_platform == 'linux'" }, + { name = "packaging", marker = "sys_platform == 'linux'" }, + { name = "requests", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d6/2c/90153f189e421e93c4bb4f9e3f59802a1f01abd2ac5cf40b152d7f735232/jupyterlab_server-2.28.0.tar.gz", hash = "sha256:35baa81898b15f93573e2deca50d11ac0ae407ebb688299d3a5213265033712c", size = 76996, upload-time = "2025-10-22T13:59:18.37Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/07/a000fe835f76b7e1143242ab1122e6362ef1c03f23f83a045c38859c2ae0/jupyterlab_server-2.28.0-py3-none-any.whl", hash = "sha256:e4355b148fdcf34d312bbbc80f22467d6d20460e8b8736bf235577dd18506968", size = 59830, upload-time = "2025-10-22T13:59:16.767Z" }, +] + +[[package]] +name = "jupyterlab-widgets" +version = "3.0.16" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/26/2d/ef58fed122b268c69c0aa099da20bc67657cdfb2e222688d5731bd5b971d/jupyterlab_widgets-3.0.16.tar.gz", hash = "sha256:423da05071d55cf27a9e602216d35a3a65a3e41cdf9c5d3b643b814ce38c19e0", size = 897423, upload-time = "2025-11-01T21:11:29.724Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ab/b5/36c712098e6191d1b4e349304ef73a8d06aed77e56ceaac8c0a306c7bda1/jupyterlab_widgets-3.0.16-py3-none-any.whl", hash = "sha256:45fa36d9c6422cf2559198e4db481aa243c7a32d9926b500781c830c80f7ecf8", size = 914926, upload-time = "2025-11-01T21:11:28.008Z" }, +] + +[[package]] +name = "jupytext" +version = "1.19.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py", marker = "sys_platform == 'linux'" }, + { name = "mdit-py-plugins", marker = "sys_platform == 'linux'" }, + { name = "nbformat", marker = "sys_platform == 'linux'" }, + { name = "packaging", marker = "sys_platform == 'linux'" }, + { name = "pyyaml", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3b/52/e014296ac8f40ca783aeb73dae52e65edbb0eaae0dcdc1ea41bfaa8aebf7/jupytext-1.19.4.tar.gz", hash = "sha256:739bcd4bc12aa4fe298a38017cdb5ae27b08a6ba3a5470728d2fe9e04b155db1", size = 4581977, upload-time = "2026-06-21T21:48:58.32Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6e/e9/e2ae007456069dbe01865c69a4203a7ada6f7e337b78fc2f12e51bd3fae7/jupytext-1.19.4-py3-none-any.whl", hash = "sha256:032d4ef4bd2e96addcac780b9b1d6b5a266ca39beceaaca95bfb4f06e0b77029", size = 170889, upload-time = "2026-06-21T21:48:56.352Z" }, +] + +[[package]] +name = "keyring" +version = "25.7.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jaraco-classes", marker = "sys_platform == 'linux'" }, + { name = "jaraco-context", marker = "sys_platform == 'linux'" }, + { name = "jaraco-functools", marker = "sys_platform == 'linux'" }, + { name = "jeepney", marker = "sys_platform == 'linux'" }, + { name = "secretstorage", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/43/4b/674af6ef2f97d56f0ab5153bf0bfa28ccb6c3ed4d1babf4305449668807b/keyring-25.7.0.tar.gz", hash = "sha256:fe01bd85eb3f8fb3dd0405defdeac9a5b4f6f0439edbb3149577f244a2e8245b", size = 63516, upload-time = "2025-11-16T16:26:09.482Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/db/e655086b7f3a705df045bf0933bdd9c2f79bb3c97bfef1384598bb79a217/keyring-25.7.0-py3-none-any.whl", hash = "sha256:be4a0b195f149690c166e850609a477c532ddbfbaed96a404d4e43f8d5e2689f", size = 39160, upload-time = "2025-11-16T16:26:08.402Z" }, +] + +[[package]] +name = "kiwisolver" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/67/9c61eccb13f0bdca9307614e782fec49ffdde0f7a2314935d489fa93cd9c/kiwisolver-1.5.0.tar.gz", hash = "sha256:d4193f3d9dc3f6f79aaed0e5637f45d98850ebf01f7ca20e69457f3e8946b66a", size = 103482, upload-time = "2026-03-09T13:15:53.382Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c4/13/680c54afe3e65767bed7ec1a15571e1a2f1257128733851ade24abcefbcc/kiwisolver-1.5.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:bb5136fb5352d3f422df33f0c879a1b0c204004324150cc3b5e3c4f310c9049f", size = 1477934, upload-time = "2026-03-09T13:13:27.166Z" }, + { url = "https://files.pythonhosted.org/packages/c8/2f/cebfcdb60fd6a9b0f6b47a9337198bcbad6fbe15e68189b7011fd914911f/kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b2af221f268f5af85e776a73d62b0845fc8baf8ef0abfae79d29c77d0e776aaf", size = 1278537, upload-time = "2026-03-09T13:13:28.707Z" }, + { url = "https://files.pythonhosted.org/packages/f2/0d/9b782923aada3fafb1d6b84e13121954515c669b18af0c26e7d21f579855/kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:b0f172dc8ffaccb8522d7c5d899de00133f2f1ca7b0a49b7da98e901de87bf2d", size = 1296685, upload-time = "2026-03-09T13:13:30.528Z" }, + { url = "https://files.pythonhosted.org/packages/27/70/83241b6634b04fe44e892688d5208332bde130f38e610c0418f9ede47ded/kiwisolver-1.5.0-cp312-cp312-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6ab8ba9152203feec73758dad83af9a0bbe05001eb4639e547207c40cfb52083", size = 1346024, upload-time = "2026-03-09T13:13:32.818Z" }, + { url = "https://files.pythonhosted.org/packages/e4/db/30ed226fb271ae1a6431fc0fe0edffb2efe23cadb01e798caeb9f2ceae8f/kiwisolver-1.5.0-cp312-cp312-manylinux_2_39_riscv64.whl", hash = "sha256:cdee07c4d7f6d72008d3f73b9bf027f4e11550224c7c50d8df1ae4a37c1402a6", size = 987241, upload-time = "2026-03-09T13:13:34.435Z" }, + { url = "https://files.pythonhosted.org/packages/ec/bd/c314595208e4c9587652d50959ead9e461995389664e490f4dce7ff0f782/kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7c60d3c9b06fb23bd9c6139281ccbdc384297579ae037f08ae90c69f6845c0b1", size = 2227742, upload-time = "2026-03-09T13:13:36.4Z" }, + { url = "https://files.pythonhosted.org/packages/c1/43/0499cec932d935229b5543d073c2b87c9c22846aab48881e9d8d6e742a2d/kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:e315e5ec90d88e140f57696ff85b484ff68bb311e36f2c414aa4286293e6dee0", size = 2323966, upload-time = "2026-03-09T13:13:38.204Z" }, + { url = "https://files.pythonhosted.org/packages/3d/6f/79b0d760907965acfd9d61826a3d41f8f093c538f55cd2633d3f0db269f6/kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:1465387ac63576c3e125e5337a6892b9e99e0627d52317f3ca79e6930d889d15", size = 1977417, upload-time = "2026-03-09T13:13:39.966Z" }, + { url = "https://files.pythonhosted.org/packages/ab/31/01d0537c41cb75a551a438c3c7a80d0c60d60b81f694dac83dd436aec0d0/kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:530a3fd64c87cffa844d4b6b9768774763d9caa299e9b75d8eca6a4423b31314", size = 2491238, upload-time = "2026-03-09T13:13:41.698Z" }, + { url = "https://files.pythonhosted.org/packages/e4/34/8aefdd0be9cfd00a44509251ba864f5caf2991e36772e61c408007e7f417/kiwisolver-1.5.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1d9daea4ea6b9be74fe2f01f7fbade8d6ffab263e781274cffca0dba9be9eec9", size = 2294947, upload-time = "2026-03-09T13:13:43.343Z" }, + { url = "https://files.pythonhosted.org/packages/2b/0a/7b98e1e119878a27ba8618ca1e18b14f992ff1eda40f47bccccf4de44121/kiwisolver-1.5.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:332b4f0145c30b5f5ad9374881133e5aa64320428a57c2c2b61e9d891a51c2f3", size = 1477903, upload-time = "2026-03-09T13:13:52.084Z" }, + { url = "https://files.pythonhosted.org/packages/18/d8/55638d89ffd27799d5cc3d8aa28e12f4ce7a64d67b285114dbedc8ea4136/kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0c50b89ffd3e1a911c69a1dd3de7173c0cd10b130f56222e57898683841e4f96", size = 1278751, upload-time = "2026-03-09T13:13:54.673Z" }, + { url = "https://files.pythonhosted.org/packages/b8/97/b4c8d0d18421ecceba20ad8701358453b88e32414e6f6950b5a4bad54e65/kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:4db576bb8c3ef9365f8b40fe0f671644de6736ae2c27a2c62d7d8a1b4329f099", size = 1296793, upload-time = "2026-03-09T13:13:56.287Z" }, + { url = "https://files.pythonhosted.org/packages/c4/10/f862f94b6389d8957448ec9df59450b81bec4abb318805375c401a1e6892/kiwisolver-1.5.0-cp313-cp313-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0b85aad90cea8ac6797a53b5d5f2e967334fa4d1149f031c4537569972596cb8", size = 1346041, upload-time = "2026-03-09T13:13:58.269Z" }, + { url = "https://files.pythonhosted.org/packages/a3/6a/f1650af35821eaf09de398ec0bc2aefc8f211f0cda50204c9f1673741ba9/kiwisolver-1.5.0-cp313-cp313-manylinux_2_39_riscv64.whl", hash = "sha256:d36ca54cb4c6c4686f7cbb7b817f66f5911c12ddb519450bbe86707155028f87", size = 987292, upload-time = "2026-03-09T13:13:59.871Z" }, + { url = "https://files.pythonhosted.org/packages/de/19/d7fb82984b9238115fe629c915007be608ebd23dc8629703d917dbfaffd4/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:38f4a703656f493b0ad185211ccfca7f0386120f022066b018eb5296d8613e23", size = 2227865, upload-time = "2026-03-09T13:14:01.401Z" }, + { url = "https://files.pythonhosted.org/packages/7f/b9/46b7f386589fd222dac9e9de9c956ce5bcefe2ee73b4e79891381dda8654/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3ac2360e93cb41be81121755c6462cff3beaa9967188c866e5fce5cf13170859", size = 2324369, upload-time = "2026-03-09T13:14:02.972Z" }, + { url = "https://files.pythonhosted.org/packages/92/8b/95e237cf3d9c642960153c769ddcbe278f182c8affb20cecc1cc983e7cc5/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:c95cab08d1965db3d84a121f1c7ce7479bdd4072c9b3dafd8fecce48a2e6b902", size = 1977989, upload-time = "2026-03-09T13:14:04.503Z" }, + { url = "https://files.pythonhosted.org/packages/1b/95/980c9df53501892784997820136c01f62bc1865e31b82b9560f980c0e649/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:fc20894c3d21194d8041a28b65622d5b86db786da6e3cfe73f0c762951a61167", size = 2491645, upload-time = "2026-03-09T13:14:06.106Z" }, + { url = "https://files.pythonhosted.org/packages/cb/32/900647fd0840abebe1561792c6b31e6a7c0e278fc3973d30572a965ca14c/kiwisolver-1.5.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7a32f72973f0f950c1920475d5c5ea3d971b81b6f0ec53b8d0a956cc965f22e0", size = 2295237, upload-time = "2026-03-09T13:14:08.891Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7f/f943879cda9007c45e1f7dba216d705c3a18d6b35830e488b6c6a4e7cdf0/kiwisolver-1.5.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4432b835675f0ea7414aab3d37d119f7226d24869b7a829caeab49ebda407b0c", size = 1584848, upload-time = "2026-03-09T13:14:19.745Z" }, + { url = "https://files.pythonhosted.org/packages/37/f8/4d4f85cc1870c127c88d950913370dd76138482161cd07eabbc450deff01/kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:1b0feb50971481a2cc44d94e88bdb02cdd497618252ae226b8eb1201b957e368", size = 1391542, upload-time = "2026-03-09T13:14:21.54Z" }, + { url = "https://files.pythonhosted.org/packages/04/0b/65dd2916c84d252b244bd405303220f729e7c17c9d7d33dca6feeff9ffc4/kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:56fa888f10d0f367155e76ce849fa1166fc9730d13bd2d65a2aa13b6f5424489", size = 1404447, upload-time = "2026-03-09T13:14:23.205Z" }, + { url = "https://files.pythonhosted.org/packages/39/5c/2606a373247babce9b1d056c03a04b65f3cf5290a8eac5d7bdead0a17e21/kiwisolver-1.5.0-cp313-cp313t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:940dda65d5e764406b9fb92761cbf462e4e63f712ab60ed98f70552e496f3bf1", size = 1455918, upload-time = "2026-03-09T13:14:24.74Z" }, + { url = "https://files.pythonhosted.org/packages/d5/d1/c6078b5756670658e9192a2ef11e939c92918833d2745f85cd14a6004bdf/kiwisolver-1.5.0-cp313-cp313t-manylinux_2_39_riscv64.whl", hash = "sha256:89fc958c702ee9a745e4700378f5d23fddbc46ff89e8fdbf5395c24d5c1452a3", size = 1072856, upload-time = "2026-03-09T13:14:26.597Z" }, + { url = "https://files.pythonhosted.org/packages/cb/c8/7def6ddf16eb2b3741d8b172bdaa9af882b03c78e9b0772975408801fa63/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9027d773c4ff81487181a925945743413f6069634d0b122d0b37684ccf4f1e18", size = 2333580, upload-time = "2026-03-09T13:14:28.237Z" }, + { url = "https://files.pythonhosted.org/packages/9e/87/2ac1fce0eb1e616fcd3c35caa23e665e9b1948bb984f4764790924594128/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_ppc64le.whl", hash = "sha256:5b233ea3e165e43e35dba1d2b8ecc21cf070b45b65ae17dd2747d2713d942021", size = 2423018, upload-time = "2026-03-09T13:14:30.018Z" }, + { url = "https://files.pythonhosted.org/packages/67/13/c6700ccc6cc218716bfcda4935e4b2997039869b4ad8a94f364c5a3b8e63/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:ce9bf03dad3b46408c08649c6fbd6ca28a9fce0eb32fdfffa6775a13103b5310", size = 2062804, upload-time = "2026-03-09T13:14:32.888Z" }, + { url = "https://files.pythonhosted.org/packages/1b/bd/877056304626943ff0f1f44c08f584300c199b887cb3176cd7e34f1515f1/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_s390x.whl", hash = "sha256:fc4d3f1fb9ca0ae9f97b095963bc6326f1dbfd3779d6679a1e016b9baaa153d3", size = 2597482, upload-time = "2026-03-09T13:14:34.971Z" }, + { url = "https://files.pythonhosted.org/packages/75/19/c60626c47bf0f8ac5dcf72c6c98e266d714f2fbbfd50cf6dab5ede3aaa50/kiwisolver-1.5.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:f443b4825c50a51ee68585522ab4a1d1257fac65896f282b4c6763337ac9f5d2", size = 2394328, upload-time = "2026-03-09T13:14:36.816Z" }, + { url = "https://files.pythonhosted.org/packages/e7/f9/b06c934a6aa8bc91f566bd2a214fd04c30506c2d9e2b6b171953216a65b6/kiwisolver-1.5.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:80aa065ffd378ff784822a6d7c3212f2d5f5e9c3589614b5c228b311fd3063ac", size = 1475913, upload-time = "2026-03-09T13:14:46.247Z" }, + { url = "https://files.pythonhosted.org/packages/6b/f0/f768ae564a710135630672981231320bc403cf9152b5596ec5289de0f106/kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:4e7f886f47ab881692f278ae901039a234e4025a68e6dfab514263a0b1c4ae05", size = 1282782, upload-time = "2026-03-09T13:14:48.458Z" }, + { url = "https://files.pythonhosted.org/packages/e2/9f/1de7aad00697325f05238a5f2eafbd487fb637cc27a558b5367a5f37fb7f/kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:5060731cc3ed12ca3a8b57acd4aeca5bbc2f49216dd0bec1650a1acd89486bcd", size = 1300815, upload-time = "2026-03-09T13:14:50.721Z" }, + { url = "https://files.pythonhosted.org/packages/5a/c2/297f25141d2e468e0ce7f7a7b92e0cf8918143a0cbd3422c1ad627e85a06/kiwisolver-1.5.0-cp314-cp314-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:7a4aa69609f40fce3cbc3f87b2061f042eee32f94b8f11db707b66a26461591a", size = 1347925, upload-time = "2026-03-09T13:14:52.304Z" }, + { url = "https://files.pythonhosted.org/packages/b9/d3/f4c73a02eb41520c47610207b21afa8cdd18fdbf64ffd94674ae21c4812d/kiwisolver-1.5.0-cp314-cp314-manylinux_2_39_riscv64.whl", hash = "sha256:d168fda2dbff7b9b5f38e693182d792a938c31db4dac3a80a4888de603c99554", size = 991322, upload-time = "2026-03-09T13:14:54.637Z" }, + { url = "https://files.pythonhosted.org/packages/7b/46/d3f2efef7732fcda98d22bf4ad5d3d71d545167a852ca710a494f4c15343/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:413b820229730d358efd838ecbab79902fe97094565fdc80ddb6b0a18c18a581", size = 2232857, upload-time = "2026-03-09T13:14:56.471Z" }, + { url = "https://files.pythonhosted.org/packages/3f/ec/2d9756bf2b6d26ae4349b8d3662fb3993f16d80c1f971c179ce862b9dbae/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:5124d1ea754509b09e53738ec185584cc609aae4a3b510aaf4ed6aa047ef9303", size = 2329376, upload-time = "2026-03-09T13:14:58.072Z" }, + { url = "https://files.pythonhosted.org/packages/8f/9f/876a0a0f2260f1bde92e002b3019a5fabc35e0939c7d945e0fa66185eb20/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:e4415a8db000bf49a6dd1c478bf70062eaacff0f462b92b0ba68791a905861f9", size = 1982549, upload-time = "2026-03-09T13:14:59.668Z" }, + { url = "https://files.pythonhosted.org/packages/6c/4f/ba3624dfac23a64d54ac4179832860cb537c1b0af06024936e82ca4154a0/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:d618fd27420381a4f6044faa71f46d8bfd911bd077c555f7138ed88729bfbe79", size = 2494680, upload-time = "2026-03-09T13:15:01.364Z" }, + { url = "https://files.pythonhosted.org/packages/39/b7/97716b190ab98911b20d10bf92eca469121ec483b8ce0edd314f51bc85af/kiwisolver-1.5.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5092eb5b1172947f57d6ea7d89b2f29650414e4293c47707eb499ec07a0ac796", size = 2297905, upload-time = "2026-03-09T13:15:03.925Z" }, + { url = "https://files.pythonhosted.org/packages/f8/8a/685b297052dd041dcebce8e8787b58923b6e78acc6115a0dc9189011c44b/kiwisolver-1.5.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e7c4c09a490dc4d4a7f8cbee56c606a320f9dc28cf92a7157a39d1ce7676a657", size = 1584858, upload-time = "2026-03-09T13:15:15.103Z" }, + { url = "https://files.pythonhosted.org/packages/9e/80/04865e3d4638ac5bddec28908916df4a3075b8c6cc101786a96803188b96/kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2a075bd7bd19c70cf67c8badfa36cf7c5d8de3c9ddb8420c51e10d9c50e94920", size = 1392539, upload-time = "2026-03-09T13:15:16.661Z" }, + { url = "https://files.pythonhosted.org/packages/ba/01/77a19cacc0893fa13fafa46d1bba06fb4dc2360b3292baf4b56d8e067b24/kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:bdd3e53429ff02aa319ba59dfe4ceeec345bf46cf180ec2cf6fd5b942e7975e9", size = 1405310, upload-time = "2026-03-09T13:15:18.229Z" }, + { url = "https://files.pythonhosted.org/packages/53/39/bcaf5d0cca50e604cfa9b4e3ae1d64b50ca1ae5b754122396084599ef903/kiwisolver-1.5.0-cp314-cp314t-manylinux_2_24_s390x.manylinux_2_28_s390x.whl", hash = "sha256:3cdcb35dc9d807259c981a85531048ede628eabcffb3239adf3d17463518992d", size = 1456244, upload-time = "2026-03-09T13:15:20.444Z" }, + { url = "https://files.pythonhosted.org/packages/d0/7a/72c187abc6975f6978c3e39b7cf67aeb8b3c0a8f9790aa7fd412855e9e1f/kiwisolver-1.5.0-cp314-cp314t-manylinux_2_39_riscv64.whl", hash = "sha256:70d593af6a6ca332d1df73d519fddb5148edb15cd90d5f0155e3746a6d4fcc65", size = 1073154, upload-time = "2026-03-09T13:15:22.039Z" }, + { url = "https://files.pythonhosted.org/packages/c7/ca/cf5b25783ebbd59143b4371ed0c8428a278abe68d6d0104b01865b1bbd0f/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:377815a8616074cabbf3f53354e1d040c35815a134e01d7614b7692e4bf8acfa", size = 2334377, upload-time = "2026-03-09T13:15:23.741Z" }, + { url = "https://files.pythonhosted.org/packages/4a/e5/b1f492adc516796e88751282276745340e2a72dcd0d36cf7173e0daf3210/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:0255a027391d52944eae1dbb5d4cc5903f57092f3674e8e544cdd2622826b3f0", size = 2425288, upload-time = "2026-03-09T13:15:25.789Z" }, + { url = "https://files.pythonhosted.org/packages/e6/e5/9b21fbe91a61b8f409d74a26498706e97a48008bfcd1864373d32a6ba31c/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:012b1eb16e28718fa782b5e61dc6f2da1f0792ca73bd05d54de6cb9561665fc9", size = 2063158, upload-time = "2026-03-09T13:15:27.63Z" }, + { url = "https://files.pythonhosted.org/packages/b1/02/83f47986138310f95ea95531f851b2a62227c11cbc3e690ae1374fe49f0f/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_s390x.whl", hash = "sha256:0e3aafb33aed7479377e5e9a82e9d4bf87063741fc99fc7ae48b0f16e32bdd6f", size = 2597260, upload-time = "2026-03-09T13:15:29.421Z" }, + { url = "https://files.pythonhosted.org/packages/07/18/43a5f24608d8c313dd189cf838c8e68d75b115567c6279de7796197cfb6a/kiwisolver-1.5.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e7a116ae737f0000343218c4edf5bd45893bfeaff0993c0b215d7124c9f77646", size = 2394403, upload-time = "2026-03-09T13:15:31.517Z" }, + { url = "https://files.pythonhosted.org/packages/fa/06/7399a607f434119c6e1fdc8ec89a8d51ccccadf3341dee4ead6bd14caaf5/kiwisolver-1.5.0-graalpy312-graalpy250_312_native-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c31c13da98624f957b0fb1b5bae5383b2333c2c3f6793d9825dd5ce79b525cb7", size = 194295, upload-time = "2026-03-09T13:15:38.22Z" }, +] + +[[package]] +name = "lark" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/da/34/28fff3ab31ccff1fd4f6c7c7b0ceb2b6968d8ea4950663eadcb5720591a0/lark-1.3.1.tar.gz", hash = "sha256:b426a7a6d6d53189d318f2b6236ab5d6429eaf09259f1ca33eb716eed10d2905", size = 382732, upload-time = "2025-10-27T18:25:56.653Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/3d/14ce75ef66813643812f3093ab17e46d3a206942ce7376d31ec2d36229e7/lark-1.3.1-py3-none-any.whl", hash = "sha256:c629b661023a014c37da873b4ff58a817398d12635d3bbb2c5a03be7fe5d1e12", size = 113151, upload-time = "2025-10-27T18:25:54.882Z" }, +] + +[[package]] +name = "latexcodec" +version = "3.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/27/dd/4270b2c5e2ee49316c3859e62293bd2ea8e382339d63ab7bbe9f39c0ec3b/latexcodec-3.0.1.tar.gz", hash = "sha256:e78a6911cd72f9dec35031c6ec23584de6842bfbc4610a9678868d14cdfb0357", size = 31222, upload-time = "2025-06-17T18:47:34.051Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b5/40/23569737873cc9637fd488606347e9dd92b9fa37ba4fcda1f98ee5219a97/latexcodec-3.0.1-py3-none-any.whl", hash = "sha256:a9eb8200bff693f0437a69581f7579eb6bca25c4193515c09900ce76451e452e", size = 18532, upload-time = "2025-06-17T18:47:30.726Z" }, +] + +[[package]] +name = "lenspack" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "astropy", marker = "sys_platform == 'linux'" }, + { name = "numpy", marker = "sys_platform == 'linux'" }, + { name = "scipy", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/73/de/18cfc64028334a1907d44ba2b40e233a2c7a06d7c1e827acfd1785c0b293/lenspack-1.0.0.tar.gz", hash = "sha256:e528a5409473eb996b39695cccb744db067341eb5fac6f240cd8d0aa669c85ec", size = 32632, upload-time = "2020-09-04T08:33:53.267Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1b/3d/a93a1332b1412301ddb454f206507b5e0b3679e012471fbbb075ca3b0845/lenspack-1.0.0-py3-none-any.whl", hash = "sha256:f9c632697516bb681e16b3eff66a7210d6355926179b95aa7060c8936c2259cc", size = 37746, upload-time = "2020-09-04T08:33:50.114Z" }, +] + +[[package]] +name = "llvmlite" +version = "0.48.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/dc/a0/acc8ffcd5bdc63df0097e22c719bfcd61b604358343089313a8aebbb24ab/llvmlite-0.48.0.tar.gz", hash = "sha256:543b19f9ef8f3c7c60d1468191e4ee1b1537bf9f8a3d56f64c0ddd98de92edd2", size = 184016, upload-time = "2026-07-02T20:20:05.308Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/80/f2/72409351db66d0a317ec5087e076f31fb7b773a640db8a90ce6b5cac9edd/llvmlite-0.48.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:416fa4c2c66c2c6dc6d0a402648c19206e548efa0aa1eff01ad5cdad0af8217d", size = 59890118, upload-time = "2026-07-01T18:41:44.886Z" }, + { url = "https://files.pythonhosted.org/packages/3a/27/5ae2f3722606360480707adb47f001ad89df8251d06b14ee80336e660b66/llvmlite-0.48.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f5e5a5131045b72345c71062ea1a91910dde913792b6c9b28ebb2c1c0a712e98", size = 58343459, upload-time = "2026-07-01T18:41:40.306Z" }, + { url = "https://files.pythonhosted.org/packages/1b/4a/90715fa12006d681270b08d881195b6fab3ec39572e048764a1f7f59fed7/llvmlite-0.48.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8761b9e522f55207e24424fcd98370289eec2710bf8e915c82d1053f642450dc", size = 59890120, upload-time = "2026-07-01T18:42:00.748Z" }, + { url = "https://files.pythonhosted.org/packages/70/5e/7b3e20d64650ca3c80af0cdb664ec4b575ec83d9d4dd05bea8bd31f9bbb6/llvmlite-0.48.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2fe5cb59b2063bfa039dcb8ca6481c0181bf552f340d10dcf61d7996a665556e", size = 58343457, upload-time = "2026-07-01T18:41:56.41Z" }, + { url = "https://files.pythonhosted.org/packages/d6/e1/05b50692b647cac3c18200ac485b04f342f00ed173c9cc46767274469a15/llvmlite-0.48.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:05f0103c8f2f96a37441337e3643863c01b8e83e530aff38960dcb383c54a065", size = 59890115, upload-time = "2026-07-01T18:42:17.805Z" }, + { url = "https://files.pythonhosted.org/packages/f7/c3/470b8c4ff9ae2db2f9cf5c3e73de76ed908a32788ae9eb5602d43e6a476b/llvmlite-0.48.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:37d66fae72802175b0bfe1ea06e624b51e2d7aee6c3c34bbd09739b8f88e8e0b", size = 58343457, upload-time = "2026-07-01T18:42:13.217Z" }, + { url = "https://files.pythonhosted.org/packages/27/98/a29133b4728671a175f7d616fab8b1c6e1d8c269d1523581d3160697bfb1/llvmlite-0.48.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:1d9f952dff6c350c529997423d4fa43abae9722a884ac7ffafc37a3af676e7db", size = 59890119, upload-time = "2026-07-01T18:42:33.88Z" }, + { url = "https://files.pythonhosted.org/packages/1a/cf/7aac11a1f1c7ec54b60c7f6814e87561fb6b55b2f290455d7941eb113420/llvmlite-0.48.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:054aa7d46595935565f276cf0c1659b4f10929c996dd4a606875fae26fba2a23", size = 58343460, upload-time = "2026-07-01T18:42:29.545Z" }, +] + +[[package]] +name = "lmfit" +version = "1.3.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "asteval", marker = "sys_platform == 'linux'" }, + { name = "dill", marker = "sys_platform == 'linux'" }, + { name = "numpy", marker = "sys_platform == 'linux'" }, + { name = "scipy", marker = "sys_platform == 'linux'" }, + { name = "uncertainties", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5a/e5/a35942aed2de95e228728c34609b51fe3ec9182398eac50d288eef313aa2/lmfit-1.3.4.tar.gz", hash = "sha256:3c22c28c43f717f6c5b4a3bd81e893a2149739c26a592c046f2e33c23cfbe497", size = 630720, upload-time = "2025-07-19T20:09:01.876Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/38/7e/7b91c89a4cf0f543a83be978657afb20c86af6d725253e319589dcc4ce52/lmfit-1.3.4-py3-none-any.whl", hash = "sha256:afce1593b42324d37ae2908249b0c55445e2f4c1a0474ff706a8e2f7b5d949fa", size = 97662, upload-time = "2025-07-19T20:09:00.32Z" }, +] + +[[package]] +name = "locket" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2f/83/97b29fe05cb6ae28d2dbd30b81e2e402a3eed5f460c26e9eaa5895ceacf5/locket-1.0.0.tar.gz", hash = "sha256:5c0d4c052a8bbbf750e056a8e65ccd309086f4f0f18a2eac306a8dfa4112a632", size = 4350, upload-time = "2022-04-20T22:04:44.312Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/db/bc/83e112abc66cd466c6b83f99118035867cecd41802f8d044638aa78a106e/locket-1.0.0-py2.py3-none-any.whl", hash = "sha256:b6c819a722f7b6bd955b80781788e4a66a55628b858d347536b7e81325a3a5e3", size = 4398, upload-time = "2022-04-20T22:04:42.23Z" }, +] + +[[package]] +name = "lsstdesc-coord" +version = "1.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "future", marker = "sys_platform == 'linux'" }, + { name = "numpy", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b8/e0/6806df4cfa54927a2d8e425407611b4fc031dd125bc952b4a31deb743305/lsstdesc_coord-1.3.1.tar.gz", hash = "sha256:60f878c29e1f30a9b50bf60dca3c466dc9cfb2cbc71f0a27c575ced969de57ab", size = 41647, upload-time = "2026-02-13T18:37:32.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a1/f8/63121ece13d3dc7521e8989b4224389868f092ce13d3aae4c410b0f5de12/lsstdesc_coord-1.3.1-py3-none-any.whl", hash = "sha256:06afe1621ef5da89f51e1225b1016f9ab640f6eb955bbab1231d60342e536336", size = 27105, upload-time = "2026-02-13T18:37:31.214Z" }, +] + +[[package]] +name = "lxml" +version = "6.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/3b/aab6728cae887456f409b4d75e8a01856e4f04bd510de38052a47768b680/lxml-6.1.1.tar.gz", hash = "sha256:ba96ae44888e0185281e937633a743ea90d5a196c6000f82565ebb0580012d40", size = 4197430, upload-time = "2026-05-18T19:19:06.424Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/42/95/bb63f0fd62e554fe078e1fb3c8fe9083c14ddc7ad7fa178d10e57e071ac7/lxml-6.1.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:c921ba5c51e4e9f63b8b00267d06566e1f63407408a0496da2d1d0bfc819c7fc", size = 4930746, upload-time = "2026-05-18T19:18:29.637Z" }, + { url = "https://files.pythonhosted.org/packages/eb/99/0013e8d9b5960f4f041cf0b73e2f80c23eb5205b1f7bfb20203243651359/lxml-6.1.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:54a7f95e4de5fb94e2f9f4b9055c6ba33bf3d628fd77a1d647c5923caa2cdcdc", size = 5093723, upload-time = "2026-05-18T19:18:34.168Z" }, + { url = "https://files.pythonhosted.org/packages/29/91/317b332636bfc7bddcff828d41b3307f50043f4b237e40849c333d80fa1a/lxml-6.1.1-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96f2ec43df44b1f76249ee0a615334f9b5b060e1c8bd90e706dad2d14d02f383", size = 5005557, upload-time = "2026-05-18T19:18:39.798Z" }, + { url = "https://files.pythonhosted.org/packages/42/2f/cc9bf06afe70f9c9093ae60855d9759da9db601ec4080f7473319666ffd7/lxml-6.1.1-cp312-cp312-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:70ef8a7e102a1508f8121aae5b0867abd663f72c14f0a9c937e6554cb4587b7b", size = 5631036, upload-time = "2026-05-18T19:18:44.858Z" }, + { url = "https://files.pythonhosted.org/packages/08/f6/af32e23e563971ffb0fb86be52bc5be5c2c118858ffc119bf6a9039b173d/lxml-6.1.1-cp312-cp312-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ebe6af670449830d6d9b752c256a983291c766a1365ba5d5460048f9e33a7818", size = 5240367, upload-time = "2026-05-18T19:18:49.217Z" }, + { url = "https://files.pythonhosted.org/packages/78/83/8555d40948b09ce86f1bd0c68a7ac31d07b1929f92cc1b074006c97ef2d2/lxml-6.1.1-cp312-cp312-manylinux_2_28_i686.whl", hash = "sha256:27acc820660aaffa4f7c087f29120e12980f7779d56d8492d263170111284740", size = 5350171, upload-time = "2026-05-18T19:18:52.779Z" }, + { url = "https://files.pythonhosted.org/packages/63/75/5d92da93729b7bad783689e6496049fa40927b45bec7bf183c981de3ca70/lxml-6.1.1-cp312-cp312-manylinux_2_31_armv7l.whl", hash = "sha256:1db753c9115ec7100d073b744d17e25e88a8f90f5c39b2f5dd878149af59671f", size = 4694874, upload-time = "2026-05-18T19:18:55.139Z" }, + { url = "https://files.pythonhosted.org/packages/c5/b5/3aad415a9a25b822e783f15deeb4dffccf5113030f1afa2222dd929313d9/lxml-6.1.1-cp312-cp312-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c4f469aebd783bb741c2ecb2a681008fd26bfe5c16a9a72ed5467f834e810df2", size = 5244492, upload-time = "2026-05-18T19:19:01.28Z" }, + { url = "https://files.pythonhosted.org/packages/f1/a1/5fcf7eb9904b80086aa47dcf0027de07b1bb990afad2e6823144c368ae04/lxml-6.1.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:766b010012d59470072c1816b5b6c69f1d243e5db36ea5968e94accf430a4635", size = 5048232, upload-time = "2026-05-18T19:18:12.67Z" }, + { url = "https://files.pythonhosted.org/packages/77/74/1f601b63c7a69fcdf10fa9b148c81da8442204194f6c55509cc485c786b9/lxml-6.1.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:b8d812c6011c08b8111a15e54dd990b8923692d80adf35488bee34026c35accf", size = 4777023, upload-time = "2026-05-18T19:18:15.928Z" }, + { url = "https://files.pythonhosted.org/packages/a2/b9/7a78f51aec95b1bf780d78e12705a9f6533284f8693dc5c0e6724fa53d3f/lxml-6.1.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:fe0306bd29505a9177aac19f1877174b0e7422c222a59f70b2cd41633448c3dc", size = 5645773, upload-time = "2026-05-18T19:18:23.223Z" }, + { url = "https://files.pythonhosted.org/packages/a5/6e/98a7b7ad54e4e74fa1f20fff776913980619d0ebe5558232d7da6580bdd8/lxml-6.1.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:5ba186ad207446c65d3bb3d3e0412b032b1d9f595e59861e2354798c5703d955", size = 5233088, upload-time = "2026-05-18T19:18:31.433Z" }, + { url = "https://files.pythonhosted.org/packages/65/d1/bc0ed2427bf609f2ee10da303a6a226f9c8bce94f945dc29a32ce55de6e4/lxml-6.1.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:aa366a1e55b8ebfe8ca8ddc3cfe75c8ebade181aeb0f661d0cb05986b647f72a", size = 5260995, upload-time = "2026-05-18T19:18:37.091Z" }, + { url = "https://files.pythonhosted.org/packages/6e/ca/ab7bfe2bf4c972af5e7878262845ead3a24a929a9b04bc11c7c1ece6c82a/lxml-6.1.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:eb7c9811bfaa8b1ed5ed319f5d370dfbcaa59d52ea64be2a5a85e18195930354", size = 4924139, upload-time = "2026-05-18T19:19:04.873Z" }, + { url = "https://files.pythonhosted.org/packages/6b/55/a0c72851dfee5ecc689f949723a73dea457758912542cb955b108eaf0d8f/lxml-6.1.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:762ff394d5bd56da0cf034a23dcce4e13923f15321a2adfa2ac00201dc6d3fca", size = 5082329, upload-time = "2026-05-18T19:19:09.728Z" }, + { url = "https://files.pythonhosted.org/packages/f0/b6/0608f7d61a3b96cc67e5648a3d906e31a5082093e10e7be65b3886289938/lxml-6.1.1-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a088f287f7d8275a33c07f2cac6c50b9319309a0200a39e7e75d80c707723099", size = 4993564, upload-time = "2026-05-18T19:19:13.608Z" }, + { url = "https://files.pythonhosted.org/packages/4c/66/ae227524b066d29d55bf0b453d93d2d793c40218657d643dcbbca13b8faf/lxml-6.1.1-cp313-cp313-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e902da4b04e6b52e5893900d4b8ab46068f75f3561f01bf1080957f9fd932ed6", size = 5613467, upload-time = "2026-05-18T19:19:16.228Z" }, + { url = "https://files.pythonhosted.org/packages/a6/76/dbe4a00b50385e40194231dcfe5a12c059de7cf90e89c83407d2b085b719/lxml-6.1.1-cp313-cp313-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1d4962d4c66bf830a7e59ed6cfc17d148149898a3aefa8ec6e59763e6e3ed085", size = 5228304, upload-time = "2026-05-18T19:19:19.354Z" }, + { url = "https://files.pythonhosted.org/packages/1c/01/00b1b8442ed2041793336868ba0b9ea4b13d7da7c085c6404c207a63bf79/lxml-6.1.1-cp313-cp313-manylinux_2_28_i686.whl", hash = "sha256:581d4c8ae690a6609e64862dd6b7c2489635c2d13907fc2b20f2bc200ff1d21e", size = 5341607, upload-time = "2026-05-18T19:19:22.297Z" }, + { url = "https://files.pythonhosted.org/packages/63/36/1ad29931e9a4638bb707869f01d423a6c815f82152138d1a40dfcfde2b95/lxml-6.1.1-cp313-cp313-manylinux_2_31_armv7l.whl", hash = "sha256:876e1ff5930ed8bf295ec5ef9a8155e9b6b1876bbf1deed8b3a8069311875a8f", size = 4700168, upload-time = "2026-05-18T19:19:25.133Z" }, + { url = "https://files.pythonhosted.org/packages/3c/d1/a9536cecf9be18a0dc72d32bead283a2332d1ffebd2dd3ac70ce444686e5/lxml-6.1.1-cp313-cp313-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:9eb9b5a968f6e0f6d640092a567e14529ff8cea2e29d00da6f78a79fa49f013c", size = 5232487, upload-time = "2026-05-18T19:19:28.603Z" }, + { url = "https://files.pythonhosted.org/packages/0e/77/b4fb1e03bf5d130e879214d3100092e386418807fb74dd0adc4b0a48f351/lxml-6.1.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:aa49e06d94aba782c6a02eecb7e507969e7e7a41b267f1b359bb35585f295d5b", size = 5044231, upload-time = "2026-05-18T19:18:42.246Z" }, + { url = "https://files.pythonhosted.org/packages/26/4c/d00daeeb0a5530c4028a9232aa1b93db3ef4ed2158c116ea73c79a9765b3/lxml-6.1.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:70cdfd80589d59e43e18005dd7244e8895e93db8ab6a620b7e23df5445a4e3d2", size = 4769450, upload-time = "2026-05-18T19:18:48.013Z" }, + { url = "https://files.pythonhosted.org/packages/ed/6a/715a3a8d156ce42f29cf014706f5410c2ff3b02267774110fc23266409fe/lxml-6.1.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:aad9aa39483ed8ec44d6d2e59e5b98a0d80676ef0d92f44bfc374836111f62f5", size = 5635874, upload-time = "2026-05-18T19:18:51.914Z" }, + { url = "https://files.pythonhosted.org/packages/45/37/0544bc21dde2a88f3a17b504e6fc79c0e01d25a33c2f6079724e9e72b9c7/lxml-6.1.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:d49514be2f28d895c38cf9d2b72d7b9a07d00314519f456c0b50b53cfcf4c785", size = 5223987, upload-time = "2026-05-18T19:18:59.715Z" }, + { url = "https://files.pythonhosted.org/packages/4d/f8/f6a5e8185bcb28c2befae3d31f8e3df3b811cb0f47746517a81279fcafe1/lxml-6.1.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:47402e62c52ff5988c1e8c6c63177f5708bccf48e366dea4e3dcf1e645e04947", size = 5250276, upload-time = "2026-05-18T19:19:03.834Z" }, + { url = "https://files.pythonhosted.org/packages/d2/51/3904907c063451cf8d4a5c9fe0cad95fa1f4ec57f4e3884fa0731bd7a305/lxml-6.1.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:74a9717fd0d82effef5c2854f0d917231d5324b5a3eb7275c43ac9fa32f97a14", size = 4950022, upload-time = "2026-05-18T19:19:31.958Z" }, + { url = "https://files.pythonhosted.org/packages/94/cd/9c7611a51c37a2830928405817cc5d56a97f64fab83cc3f628748b135749/lxml-6.1.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:efe0374196335f93b53269acd811b944f2e6bdc88e8894f214bd636455484909", size = 5086695, upload-time = "2026-05-18T19:19:34.764Z" }, + { url = "https://files.pythonhosted.org/packages/da/d6/24e3b5906abb0b674ff2ae195bc3ce59708df2bcd17cf17703b2d7dd643a/lxml-6.1.1-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ac931cdc9442c1763b8a8f6cd62c0c938737eafc5be75eff88df55fc73bc0d00", size = 5031642, upload-time = "2026-05-18T19:19:37.771Z" }, + { url = "https://files.pythonhosted.org/packages/2d/db/6ec54f99019838bff54785c51da07f189eb4676861c5f2730962b0d8d665/lxml-6.1.1-cp314-cp314-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:aee395f5d0927f947758b4ec119fd5fc8ec71f07a1c5c52077b30b04c0fa6955", size = 5647338, upload-time = "2026-05-18T19:19:40.553Z" }, + { url = "https://files.pythonhosted.org/packages/42/3d/ef4dcfffd22d27a61805d8ed9f7fb888495bc6aa88648fa07c1eaa5586b6/lxml-6.1.1-cp314-cp314-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9395002973c827b3ed67db77e6ec09f092919a587022174554096a269378fb13", size = 5239528, upload-time = "2026-05-18T19:19:43.657Z" }, + { url = "https://files.pythonhosted.org/packages/62/bb/37fb3f0dff146bdcfa78eec47879273820b2a0bf350ec236ce14bd0b1c26/lxml-6.1.1-cp314-cp314-manylinux_2_28_i686.whl", hash = "sha256:73bc2086f141224ebddb7fc5c6a36ca58b31b94b561e1dfe8e073e3270fad1e7", size = 5350730, upload-time = "2026-05-18T19:19:46.307Z" }, + { url = "https://files.pythonhosted.org/packages/90/42/43253f168388df4fae1f38c01df36ddb9bee39e2048167b54cdcbae85ea3/lxml-6.1.1-cp314-cp314-manylinux_2_31_armv7l.whl", hash = "sha256:3779def59032b81e44a5f70096ef6bf2082f8d901937dca354474ba09782e245", size = 4697530, upload-time = "2026-05-18T19:19:49.889Z" }, + { url = "https://files.pythonhosted.org/packages/eb/a8/c5a8504f81bbdfc8e7094c2c850cdb4ed6777fc4d5ddd9e5ab819f3b0d54/lxml-6.1.1-cp314-cp314-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:86c89b9d55ebf820ad7c90bc533410f0d098054f293351f10603c0c46ff598f5", size = 5250670, upload-time = "2026-05-18T19:19:53.199Z" }, + { url = "https://files.pythonhosted.org/packages/77/b7/c7e76ab18744d75e21f320ebf9ff9d1ceae2b54dd431ea5a64caf26c9672/lxml-6.1.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:19607c6bbff2a44cf3fe8250abccd20942d3462473e0a721d01d379ed017e462", size = 5084485, upload-time = "2026-05-18T19:19:08.422Z" }, + { url = "https://files.pythonhosted.org/packages/31/31/b35c53f8ef7b7c31cacd23d3638652fff7bcd1deb6eedb709ab43b685908/lxml-6.1.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:c6ed5141a5c7507cf3ee76bd363b0d6f801e3321adc35b5d825a23115faa5465", size = 4737635, upload-time = "2026-05-18T19:19:12.321Z" }, + { url = "https://files.pythonhosted.org/packages/d9/06/31f23c813a7fe8e0cb1b175e915b08c9bf4e86d225b210feadbdbe519667/lxml-6.1.1-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:62aeb7e85b5d60320b9d77eef2e773994e2c0ce10121b277e0a19804e1654a5a", size = 5670681, upload-time = "2026-05-18T19:19:15.001Z" }, + { url = "https://files.pythonhosted.org/packages/1a/bc/ce619bccc89b1fd9ad8a8e1330ee3f3beff9f2ff95b712d7bbcdd6e22fc3/lxml-6.1.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:b1b963fd8f5caa68e99dfae060d54de1fe9cba899b8718b44a00cdca53c3e590", size = 5238229, upload-time = "2026-05-18T19:19:18.131Z" }, + { url = "https://files.pythonhosted.org/packages/2f/5d/b329acbbedc0b619ebc2be6cf7ee9ed07e80892c88d4dfd612c33805789a/lxml-6.1.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:63876be28efefa04a1df615b46770e82042cce445cfdce55160522f57b231ccb", size = 5264191, upload-time = "2026-05-18T19:19:21.118Z" }, + { url = "https://files.pythonhosted.org/packages/16/02/6f7061f4f95f51e545d48e87647c54791d204a4e881be4156e7a26ba5338/lxml-6.1.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:acd7d70b64c0aae0c7922cca83d288a16f5f6da523637697872253415269baef", size = 4970291, upload-time = "2026-05-18T19:19:56.215Z" }, + { url = "https://files.pythonhosted.org/packages/b0/02/55fc057d8283427dea7d6edb102e7a840239c77a64a983d92f62a304c0e9/lxml-6.1.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:4f0dd2f01f9f8a89f565d000e03abcf0a13d692a346c8d22f628d49af098777a", size = 5102822, upload-time = "2026-05-18T19:19:59.223Z" }, + { url = "https://files.pythonhosted.org/packages/e4/48/8e1cf78d89d66850121d9255a2a24414c98f775da93b90cf976956c24b14/lxml-6.1.1-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:0b7e8a14c8634bf6f7a568634cb395305a6d964aeb5b7ee32248094bed3a7e2c", size = 5027923, upload-time = "2026-05-18T19:20:01.549Z" }, + { url = "https://files.pythonhosted.org/packages/ed/00/0632a0647612c8af24d26997b3b961397daa9d5b2581444805933629a4cb/lxml-6.1.1-cp314-cp314t-manylinux_2_26_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:86281fbdd6a8162756f8d603f37e3435bfa38043adb79c6dc6a2dfee065e7525", size = 5595843, upload-time = "2026-05-18T19:20:03.93Z" }, + { url = "https://files.pythonhosted.org/packages/bc/86/ab008a7dc360711b66858d61c80a5979a70a09f2aa2b05d9698df80b803d/lxml-6.1.1-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c5d7152ec39ca7c402d8fb9bad86140a15b9503bd0c54484e3f1bbe3dd37ceca", size = 5224515, upload-time = "2026-05-18T19:20:06.381Z" }, + { url = "https://files.pythonhosted.org/packages/75/c6/2702ff375e728e34f56d9a45339a9cf7e4427e917f542225242d63a05afa/lxml-6.1.1-cp314-cp314t-manylinux_2_28_i686.whl", hash = "sha256:88d8cb75b9d82858497a5393e3c63cfbf03035225e4b35a49ed7ccb151e4dc0e", size = 5312511, upload-time = "2026-05-18T19:20:09.308Z" }, + { url = "https://files.pythonhosted.org/packages/b7/57/a5807c98f87a86f10ef9ffab35516df7c0f0c4b6d5d33e9f608ab9c04a31/lxml-6.1.1-cp314-cp314t-manylinux_2_31_armv7l.whl", hash = "sha256:f64ec5397ea6a41fc1b4af0380d79b44a755b5531dcaccd9940fb260dca93038", size = 4639206, upload-time = "2026-05-18T19:20:11.704Z" }, + { url = "https://files.pythonhosted.org/packages/1f/e1/8a0a2c35734812395f4da4eaf33748a7e5705bfb2a58b128da764339d5ec/lxml-6.1.1-cp314-cp314t-manylinux_2_38_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:d34bbf07dbc7ca5970671b1512e928991fb5e9d95365636c9b2d8b4f53af405e", size = 5232404, upload-time = "2026-05-18T19:20:14.064Z" }, + { url = "https://files.pythonhosted.org/packages/c2/e2/0e6a4dd5ad84d01d99aa7bae7cfefd4a760a0e0f8176818241de17d9b6c0/lxml-6.1.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:17e0e18d4ad8adbd0399291bc44845b69d9dd68439a3cdebdf35ff902ec05072", size = 5083769, upload-time = "2026-05-18T19:19:23.758Z" }, + { url = "https://files.pythonhosted.org/packages/a0/7e/161f33d463f6ffc1c7679104b65086dea120080d49dde4d238f015aaee2f/lxml-6.1.1-cp314-cp314t-musllinux_1_2_armv7l.whl", hash = "sha256:3ab541146f1f6968c462d6c2ac495148e8cdba2f8347700b2141b6ec5a75bf52", size = 4758936, upload-time = "2026-05-18T19:19:27.256Z" }, + { url = "https://files.pythonhosted.org/packages/f1/fb/2369825e3f6ca99305bf9f7b7085fda91c8b0922a89e54d900974aa3ef85/lxml-6.1.1-cp314-cp314t-musllinux_1_2_ppc64le.whl", hash = "sha256:2a0217714657e023ef4293500f65aa20fce6164c8fd6b08fa5bd4a859fb14b9b", size = 5620296, upload-time = "2026-05-18T19:19:29.993Z" }, + { url = "https://files.pythonhosted.org/packages/30/90/d61e383146f74c5ab683947ea14dc7b82778838ab9b95ea73a23b60d0191/lxml-6.1.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:05a82eb6e1530a64f26225b55cbd178113bd0b5af1c2b625f25e5296742c26d2", size = 5228598, upload-time = "2026-05-18T19:19:33.523Z" }, + { url = "https://files.pythonhosted.org/packages/76/2d/2dafd8149e94b05bb070690efd5bb2680720681e03ff03fc57d2b70a1105/lxml-6.1.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:9e36f163528fc50cbef305f02a5fd66d404edf7049cdaff211dbc2cba5a7013e", size = 5247845, upload-time = "2026-05-18T19:19:36.649Z" }, +] + +[[package]] +name = "markdown-it-py" +version = "4.2.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mdurl", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/06/ff/7841249c247aa650a76b9ee4bbaeae59370dc8bfd2f6c01f3630c35eb134/markdown_it_py-4.2.0.tar.gz", hash = "sha256:04a21681d6fbb623de53f6f364d352309d4094dd4194040a10fd51833e418d49", size = 82454, upload-time = "2026-05-07T12:08:28.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/81/4da04ced5a082363ecfa159c010d200ecbd959ae410c10c0264a38cac0f5/markdown_it_py-4.2.0-py3-none-any.whl", hash = "sha256:9f7ebbcd14fe59494226453aed97c1070d83f8d24b6fc3a3bcf9a38092641c4a", size = 91687, upload-time = "2026-05-07T12:08:27.182Z" }, +] + +[[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/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/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/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/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/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" }, +] + +[[package]] +name = "matplotlib" +version = "3.11.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "contourpy", marker = "sys_platform == 'linux'" }, + { name = "cycler", marker = "sys_platform == 'linux'" }, + { name = "fonttools", marker = "sys_platform == 'linux'" }, + { name = "kiwisolver", marker = "sys_platform == 'linux'" }, + { name = "numpy", marker = "sys_platform == 'linux'" }, + { name = "packaging", marker = "sys_platform == 'linux'" }, + { name = "pillow", marker = "sys_platform == 'linux'" }, + { name = "pyparsing", marker = "sys_platform == 'linux'" }, + { name = "python-dateutil", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1f/24/080c99d223d158d3a8902769269ab6da5b50f7a0e6e072513907e02b7a6c/matplotlib-3.11.0.tar.gz", hash = "sha256:68c0c7be01b30dcca3638934f7f591df73401235cbdbf0d1ab1c71e7db7f8b57", size = 33251176, upload-time = "2026-06-12T02:29:15.508Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/94/95/7f522393c88313336b20d70fc849555757b2e5febc22b83b3a3f0fd4bce9/matplotlib-3.11.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:be5f93a1d21981bfb802ded0d77a0caa92d4342a47d45754fac77e314a506344", size = 10031353, upload-time = "2026-06-12T02:27:55.215Z" }, + { url = "https://files.pythonhosted.org/packages/87/ce/8f25a0e3186aefd61913e7467d1b999465bcd0d0c03ac695c1b26ca559b7/matplotlib-3.11.0-cp312-cp312-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41635d7909d19e52e924a521dde6d8f670b0f53ab1d0e8c331fa831554f681d1", size = 10839232, upload-time = "2026-06-12T02:27:57.746Z" }, + { url = "https://files.pythonhosted.org/packages/85/c2/db15da2bbdf9e3ca66df7db8e2c33a1dfed67be24a24d2c878efaaff01d6/matplotlib-3.11.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:94f5000f67ca9faa300863ea17f8bce9175cb67b88bec4bc7780502d53dd7c9e", size = 10923899, upload-time = "2026-06-12T02:28:00.223Z" }, + { url = "https://files.pythonhosted.org/packages/a4/c0/1117d53077e3ac3152503a84e9cf7a5c239576805ee71276e80c2aaa7471/matplotlib-3.11.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:be152b7570324dc8d01574cc9474dd2d803237acf528bcbb5b211fa347461a09", size = 10031623, upload-time = "2026-06-12T02:28:11.26Z" }, + { url = "https://files.pythonhosted.org/packages/92/7e/e937138daffad65b71bf831a377809dcbc830fb4f31a31e067dc1faa2575/matplotlib-3.11.0-cp313-cp313-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:126f256df600652d7e4b394cf3164ff75210a00038f287c95a012a6f58d0e83f", size = 10839372, upload-time = "2026-06-12T02:28:14.102Z" }, + { url = "https://files.pythonhosted.org/packages/1d/c2/438ecc197ffb8023b6b9922915542f2172f5fd45b76703b0b4fc47322243/matplotlib-3.11.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:03acfeddf87b0dddb11b081ef7740ad445a3ca8bcb6b8e3011b08f2cf802b75c", size = 10924099, upload-time = "2026-06-12T02:28:16.383Z" }, + { url = "https://files.pythonhosted.org/packages/95/e4/b4b7c33151e74e5c802f3cde1ba807ebfc38401e329b44e215a5888dd76d/matplotlib-3.11.0-cp313-cp313t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:565af866fd63e4bd3f987d580afe27c44c2552a3b3305f4ecbb85133601ea6f3", size = 10045491, upload-time = "2026-06-12T02:28:27.141Z" }, + { url = "https://files.pythonhosted.org/packages/71/28/394548efd68354110c1a1be11fe6b6e559e06d1a23da35908a0e316c55a9/matplotlib-3.11.0-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e6b3e64dea5062c570f04358e2711859f3531b459f29516274fbad889079e4f3", size = 10857059, upload-time = "2026-06-12T02:28:29.222Z" }, + { url = "https://files.pythonhosted.org/packages/c8/44/e7922e6e2a4d63bdfbc9dc4a53e3850ab438d46cf42e6779bb15ec92c948/matplotlib-3.11.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:942b37c5db1899610bd1543ce8e13e4ecff9a4633e7f63bb6aa9205d2644ebd1", size = 10939576, upload-time = "2026-06-12T02:28:31.66Z" }, + { url = "https://files.pythonhosted.org/packages/b7/2d/4e1240ea82ee197dfb3851e71f71c87eeeb975f1753b56a0588e4e80739a/matplotlib-3.11.0-cp314-cp314-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d9695457a467ff86d23f35037a43deb6f1134dd6d3e2ac8ce1e2087cff09ffb9", size = 10843005, upload-time = "2026-06-12T02:28:42.39Z" }, + { url = "https://files.pythonhosted.org/packages/29/dc/6377ecfaa5fef79430f74a1a16638b4e2aa30d4692bae2c19f9d76fe3b01/matplotlib-3.11.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:19c16c61dea63b3582918503e6b294193961261d9daa806d4ae2151f1ad05430", size = 11127459, upload-time = "2026-06-12T02:28:44.483Z" }, + { url = "https://files.pythonhosted.org/packages/6f/41/795c405aa7560443a3b01309424cde4a1113b85c90b8a63417444a749617/matplotlib-3.11.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2d72ea8b7924f3cb955e61518d21e43b3df1e6c8a793b480a0c1214f185d30ba", size = 10925160, upload-time = "2026-06-12T02:28:46.564Z" }, + { url = "https://files.pythonhosted.org/packages/4b/cb/22f6bc35711a0b5639a784e74e653e77c86210bd4304449dd399a482f74e/matplotlib-3.11.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dfabef0230d0697aa0d717385194dd41162e00207a68bf4abf94c2bf4c27dca0", size = 10854181, upload-time = "2026-06-12T02:28:57.856Z" }, + { url = "https://files.pythonhosted.org/packages/3f/7e/9a9eaca731a2939589da520f0ebe8fd8753d0f51fca98c7d20af6dbe261a/matplotlib-3.11.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1644db30e759199443493ac5e5caec24fdb775a8f6123021f85ba47c4133c3cb", size = 11137715, upload-time = "2026-06-12T02:29:00.555Z" }, + { url = "https://files.pythonhosted.org/packages/ef/f9/9b030b6088354acb0296871bb624b25befc1c42509d3c6cd17420c83a5b8/matplotlib-3.11.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:15b0d160079cb10699a0e98b5989c70677b2df7cacdc62af67c30f2facec46d9", size = 10939427, upload-time = "2026-06-12T02:29:02.527Z" }, +] + +[[package]] +name = "matplotlib-inline" +version = "0.2.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "traitlets", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/bd/c0/9f7c9a46090390368a4d7bcb76bb87a4a36c421e4c0792cdb53486ffac7a/matplotlib_inline-0.2.2.tar.gz", hash = "sha256:72f3fe8fce36b70d4a5b612f899090cd0401deddc4ea90e1572b9f4bfb058c79", size = 8150, upload-time = "2026-05-08T17:33:33.49Z" } +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 = "mdit-py-plugins" +version = "0.6.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/59/fc/f8d0863f8862f25602c0404d75568e89fb6b4109804645e5cdfb1be5cf56/mdit_py_plugins-0.6.1.tar.gz", hash = "sha256:a2bca0f039f39dbd35fb74ae1b5f998608c437463371f0ff7f49a19a17a114d0", size = 56114, upload-time = "2026-05-13T09:03:38.91Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a5/69/6da5581c6a7fede7dc261bf4e67d6adca4196f176b43288b55b3db395b6e/mdit_py_plugins-0.6.1-py3-none-any.whl", hash = "sha256:214c82fb2ac524472ab6a5bcab1de80f73b50443e187f401bfd77efbc7c6481d", size = 66663, upload-time = "2026-05-13T09:03:37.76Z" }, +] + +[[package]] +name = "mdurl" +version = "0.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d6/54/cfe61301667036ec958cb99bd3efefba235e65cdeb9c84d24a8293ba1d90/mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba", size = 8729, upload-time = "2022-08-14T12:40:10.846Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/38/89ba8ad64ae25be8de66a6d463314cf1eb366222074cfda9ee839c56a4b4/mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8", size = 9979, upload-time = "2022-08-14T12:40:09.779Z" }, +] + +[[package]] +name = "mistune" +version = "3.3.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/7b/a5/2dab368d6950e6808904dec98f54c7e726ee7be4a0c6afe00e6e011bd52d/mistune-3.3.3.tar.gz", hash = "sha256:c4c6c0c840b8637a2e9b8b6d607eb7c8f00888bf14c754409bcd339e848c2477", size = 115363, upload-time = "2026-07-09T06:18:05.268Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/89/70/b1e4737b84163db5bb1dfde6f216dbfbf32783330a9989c965e121172830/mistune-3.3.3-py3-none-any.whl", hash = "sha256:99de1585e42dcbd826faa9e11a202727a5e202e4e4722a4c69ac1ff615793dd7", size = 63569, upload-time = "2026-07-09T06:18:03.839Z" }, +] + +[[package]] +name = "more-itertools" +version = "11.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/de/1d/f4da6f02cdffe04d6362210b807146a26044c88d839208aec273bb0d9184/more_itertools-11.1.0.tar.gz", hash = "sha256:48e8f4d9e7e5878571ecf6f2b4e57634f93cd474cc8cfbd2376f2d11b396e30d", size = 145772, upload-time = "2026-05-22T14:14:29.909Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e8/3d/1087453384dbde46a8c7f9356eead2c58be8a7bf156bca40243377c85715/more_itertools-11.1.0-py3-none-any.whl", hash = "sha256:4b65538ae22f6fed0ce4874efd317463a7489796a0939fa66824dd542125a192", size = 72226, upload-time = "2026-05-22T14:14:28.824Z" }, +] + +[[package]] +name = "mpi4py" +version = "4.1.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/75/83/231445bbcf7ef10864746c244ff2d82000011449b79275642c5d4ed8c8f4/mpi4py-4.1.2.tar.gz", hash = "sha256:56860286dc45f20e8821e93cb06669e30462348bf866f685553fa4b712d58d02", size = 501709, upload-time = "2026-05-16T10:35:23.618Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a3/0a/1da7f403e0d8ce0e26d541f7538302cec00cf5b0a98a7a52b929f938a25c/mpi4py-4.1.2-cp310-abi3-manylinux1_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2ef63b2e3083e6062fd90e4de8c4e3acbf81e0772406e0226eb8dde6a48cab8e", size = 1327130, upload-time = "2026-05-16T10:34:00.269Z" }, + { url = "https://files.pythonhosted.org/packages/e6/f9/65999152ae82bad914c6a083821ee774afefd6d0544e633b940c9a9ebf3f/mpi4py-4.1.2-cp310-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6508e654b9c8ff9f611b19548b2a17d1e323b520a15168189f92221e6757b8ff", size = 1182268, upload-time = "2026-05-16T10:34:02.206Z" }, + { url = "https://files.pythonhosted.org/packages/9f/2b/1e48c4c5f9acbdca8dd28beeba9123dde140cd2ca520f8e3a3cf22faeeaa/mpi4py-4.1.2-cp312-cp312-manylinux1_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:00f4cce8999d19f35243c3442ea22debbe3336f69c309cd5d3176df4e51c717a", size = 1358844, upload-time = "2026-05-16T10:34:28.247Z" }, + { url = "https://files.pythonhosted.org/packages/94/46/a37225d47997fcf30adca25d3849d035bbb61d972118b024db900306e528/mpi4py-4.1.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:0a58e164776acb7b52414548b1bf0e5caafce0ee90345deff147873a64b6b2cc", size = 1227206, upload-time = "2026-05-16T10:34:29.866Z" }, + { url = "https://files.pythonhosted.org/packages/0d/5e/493415cdb0da0c1c0b6ec9a1fb65ab57a174e8111b25c87f7507f663d0b4/mpi4py-4.1.2-cp313-cp313-manylinux1_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:085e0cb05427398fe2281856f27a87984b9f234cd6d98a2a384a6fbfe679a56f", size = 1358571, upload-time = "2026-05-16T10:34:37.478Z" }, + { url = "https://files.pythonhosted.org/packages/6f/51/3822e834fc9cafd96811501b85232e02bd9b31596d42965536a269a6c112/mpi4py-4.1.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:429437883b4511583d56a57bc58ad0d02965fb6c19f84f39e30c0646e6c0cab9", size = 1226562, upload-time = "2026-05-16T10:34:39.652Z" }, + { url = "https://files.pythonhosted.org/packages/ec/5e/d358fadb8672d58abd6dce16c95eda56f497b378dec5642a31cd6ededfc4/mpi4py-4.1.2-cp313-cp313t-manylinux1_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:85e332feaac3323d8ed1c71f17478fe3f529468f28f6f9bb4c9133ad2d3a3a6d", size = 1419007, upload-time = "2026-05-16T10:34:45.47Z" }, + { url = "https://files.pythonhosted.org/packages/27/eb/5cd53880337009cab9a9d17a007ad5aec731f3a55e211bdcc99dbb98a0e3/mpi4py-4.1.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:3e05dba75f6ad17ae761bdc01ee5c5271d15cd296e8a508e22c99c91b540dc99", size = 1298482, upload-time = "2026-05-16T10:34:46.858Z" }, + { url = "https://files.pythonhosted.org/packages/26/e4/32575e9b0d5380b08ffa04958c7a13b1bab86e3674f33b6de3827fbbe14c/mpi4py-4.1.2-cp314-cp314-manylinux1_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d53e8f7182bf125b37155f679b301a21cd64e5ae6861ca0ab989c9d2b2073bbd", size = 1368388, upload-time = "2026-05-16T10:34:53.665Z" }, + { url = "https://files.pythonhosted.org/packages/87/a8/ad5e925da9de402704ecfe8715348b068fb0b65059109c65dafb111f95e4/mpi4py-4.1.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:7cbf982d3425fd06890fbcff79ba19a7435e93bc74e5711ca8ac0b64d0c3ece9", size = 1238211, upload-time = "2026-05-16T10:34:55.094Z" }, + { url = "https://files.pythonhosted.org/packages/39/29/45a41d081342896af52d38a848017728bf6834c4c92814c50aa791dc750b/mpi4py-4.1.2-cp314-cp314t-manylinux1_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:db189238c37be98933eeb078a3e2b827eef969837e8fe0f3a2e6cdb7f4b1b05f", size = 1423092, upload-time = "2026-05-16T10:35:01.672Z" }, + { url = "https://files.pythonhosted.org/packages/0f/6f/c2127d426d87f2f7cdb4beacbb4febe7b0c93047a3c615d0e56cecb42563/mpi4py-4.1.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:d0fbf0bc100ed966c3d7f44231a19aef0025d523d1b813de468a1b114d0d9436", size = 1303134, upload-time = "2026-05-16T10:35:03.122Z" }, +] + +[[package]] +name = "mpmath" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e0/47/dd32fa426cc72114383ac549964eecb20ecfd886d1e5ccf5340b55b02f57/mpmath-1.3.0.tar.gz", hash = "sha256:7a28eb2a9774d00c7bc92411c19a89209d5da7c4c9a9e227be8330a23a25b91f", size = 508106, upload-time = "2023-03-07T16:47:11.061Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/e3/7d92a15f894aa0c9c4b49b8ee9ac9850d6e63b03c9c32c0367a13ae62209/mpmath-1.3.0-py3-none-any.whl", hash = "sha256:a0b2b9fe80bbcd81a6647ff13108738cfb482d481d826cc0e02f5b35e5c88d2c", size = 536198, upload-time = "2023-03-07T16:47:09.197Z" }, +] + +[[package]] +name = "msgpack" +version = "1.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/31/f9/c0a1c127f9049db9155afc316952ea571720dd01833ff5e4d7e8e6352dbb/msgpack-1.2.1.tar.gz", hash = "sha256:04c721c2c7448767e9e3f2520a475663d8ee0f09c31890f6d2bd70fd636a9647", size = 183960, upload-time = "2026-06-18T16:13:52.594Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/26/aa/753ad8b007b464e1d8aa0c8e650b9c5f4f725e658fc5ac8a7635c55b7f6e/msgpack-1.2.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:60926b75d00c8e816ef98f3034f484a8bc64242d66839cef4cf7e503142316a0", size = 410634, upload-time = "2026-06-18T16:13:00.383Z" }, + { url = "https://files.pythonhosted.org/packages/6a/fd/6adabd4f6d5e686f97dd02ce7fce3fe4cf672cbac36b8f67ff4040e8ad8b/msgpack-1.2.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:020e881a764b20d8d7ca1a54fc01b8175519d108e3c3f194fddc200bda95951a", size = 419989, upload-time = "2026-06-18T16:13:01.776Z" }, + { url = "https://files.pythonhosted.org/packages/5a/cc/85039b7b0eb168aaad7383a23c97e291a11f08351cb45a606ce865e4e3f1/msgpack-1.2.1-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:4202c74688ca06591f78cb18988228bd4cca2cc75d57b60008372892d2f1e6e6", size = 377544, upload-time = "2026-06-18T16:13:03.637Z" }, + { url = "https://files.pythonhosted.org/packages/ed/bf/35963899493b32030c85fc513b723ae66144ac70c11ebc52e889e16e3d99/msgpack-1.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8b267ce94efb76fbd1b3373511420074ee3187f0f7811bf394531de13294735a", size = 400842, upload-time = "2026-06-18T16:13:05.012Z" }, + { url = "https://files.pythonhosted.org/packages/a6/df/8e2ac970c8f99264cd9997d1c73df5466bc19da3301d7dc5500862a9b089/msgpack-1.2.1-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:e4f1d0f8f98ade9634e01fb704a408f9336c0a8f1117b369f5db83dc7551d8b1", size = 374108, upload-time = "2026-06-18T16:13:06.232Z" }, + { url = "https://files.pythonhosted.org/packages/17/dd/fa8bd265110dfa51c20cb529f9e6d240a16fafe7e645004c6af2d01353ba/msgpack-1.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f02cf17a6ca1abe29b5f980644f7551f94d71f2011509b26d8625ce038f0df64", size = 414939, upload-time = "2026-06-18T16:13:07.478Z" }, + { url = "https://files.pythonhosted.org/packages/e3/10/ddf7b06db879e8792d13934ddda09ff20bd2a583fd84c9b59aae9b0e650b/msgpack-1.2.1-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f310233ef7fb9c14e201c93639fe5f5260b005f56f0b29048e999c30935596cc", size = 407518, upload-time = "2026-06-18T16:13:14.233Z" }, + { url = "https://files.pythonhosted.org/packages/79/d3/36a46a8ed992b781acbc05928bd5bee3c810cb0c3563bf81a7b0c04a1a76/msgpack-1.2.1-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:787c9bebb5833e8f6fc8abca3c0597683d8d87f56a8842b6b89c75a5f3176e2d", size = 416405, upload-time = "2026-06-18T16:13:15.435Z" }, + { url = "https://files.pythonhosted.org/packages/f9/84/e8e9598b557c0ba6ddae901a73780a4c75ac667dddf59414b1e56a42fb34/msgpack-1.2.1-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:dc871b997a9370d855b7394465f2f350e847a5b806dd38dcc9c989e7d87da155", size = 376257, upload-time = "2026-06-18T16:13:17.022Z" }, + { url = "https://files.pythonhosted.org/packages/40/16/738fe6d875ad7e2a9429c165322a4ec088f4f273cdfae63d96a89c467961/msgpack-1.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:85f57e960d877f2977f6430896191b04a21f8901b3b4baf2e4604329f4db5402", size = 397469, upload-time = "2026-06-18T16:13:18.287Z" }, + { url = "https://files.pythonhosted.org/packages/ca/be/6d5952df75a7f24f35833af764c3a6860780364cb3a0030beb8099e1b2b4/msgpack-1.2.1-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:1233ee2dd0cefba127583de50ea654677277047d238303521db35def3d7b2e7c", size = 372802, upload-time = "2026-06-18T16:13:19.685Z" }, + { url = "https://files.pythonhosted.org/packages/e1/39/e2ef7dbf0473bcb8dc7c50bf782a892d67414877b63e47fc88eb189ef5e6/msgpack-1.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e3dc2feb0876209d9c38aa56cb1de169bd6c4348f1aa48271f241226590993e6", size = 411273, upload-time = "2026-06-18T16:13:21.028Z" }, + { url = "https://files.pythonhosted.org/packages/b8/a6/99e58722feaffc5f2fbcc0c8c0d1451ab9f84097f7af87291b46af2390f4/msgpack-1.2.1-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ca0dacff965c47afdc3749a8469d7302a8f801d6a28758d55120d75e66ce6889", size = 406090, upload-time = "2026-06-18T16:13:28.072Z" }, + { url = "https://files.pythonhosted.org/packages/19/03/8c63e8cf52958534ef688625965ab04c269a6cadd8caef16758b380a821a/msgpack-1.2.1-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0e2bf9280bceb5efca998435904b5d3e9fdbcc11d90dc9df30aec7973252b720", size = 412106, upload-time = "2026-06-18T16:13:29.427Z" }, + { url = "https://files.pythonhosted.org/packages/63/d2/155d9e71b40e41fd934bc0c48b9b2770f22263e1ac20aad8e29fdca7be3f/msgpack-1.2.1-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:aa6c4be5d1c02a42b066ca6ddb71adf36432868fdcdb6ee87e634e86e0674190", size = 374851, upload-time = "2026-06-18T16:13:30.631Z" }, + { url = "https://files.pythonhosted.org/packages/98/48/deaf2326262a8d5ea3295ce9649912ecd3f551ba7ec8e33c665d2ba583f3/msgpack-1.2.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ec0e675d59150a6269ddc9139087c722292664a37d071a849c05c473350f1f2d", size = 396168, upload-time = "2026-06-18T16:13:31.977Z" }, + { url = "https://files.pythonhosted.org/packages/10/2a/b4410f906c2ec0008f1608d3ab5143afc3ad3f4e6da0fed3ea2231d0bef4/msgpack-1.2.1-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:dd3bfe82d53edfe4b7fc9a7ec9761e23a7a5b1dac22264505af428253c29ed24", size = 371959, upload-time = "2026-06-18T16:13:33.282Z" }, + { url = "https://files.pythonhosted.org/packages/59/86/1edc67270099a528fa2093ea60fe191233cd238e4bd30cfacf7db79fc959/msgpack-1.2.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5ad5467fc3f68b5468e06c5f788d712e9f8ffc8b0cd1bcb160c105c1ee92dae7", size = 408457, upload-time = "2026-06-18T16:13:34.567Z" }, + { url = "https://files.pythonhosted.org/packages/a9/b4/b774d7eb95561739907fec675582f83203cf41c597a418c2589b4bfb8e9d/msgpack-1.2.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:20466cca18c49c7292a8984bc15d65857b171e7264bdcb5f96baf8be238791fc", size = 427661, upload-time = "2026-06-18T16:13:41.574Z" }, + { url = "https://files.pythonhosted.org/packages/b2/f9/3243191dc9937e00756c8bc1b0272fed8f23758e43df2a3b46f533e5090f/msgpack-1.2.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:196300e7e5d6e74d50f1607ab9c06c4a1484c383cd22defd727902591f7e8dde", size = 426375, upload-time = "2026-06-18T16:13:42.936Z" }, + { url = "https://files.pythonhosted.org/packages/23/c7/1693111db9944ba4ad4b67a1e788400d78a0b6af7a6523dc7e4e58f8274b/msgpack-1.2.1-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:575957e79cd51903a4e8495a242442949641e08f1efd5197b43bebd3ea7682b4", size = 380495, upload-time = "2026-06-18T16:13:44.306Z" }, + { url = "https://files.pythonhosted.org/packages/3e/2b/92f86956a0c13e8662f7e2ad630c4eb4db07497b967589bd5245e018b2c1/msgpack-1.2.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:8c2ed1e48cc0f460bf3c7780e7137ff21a4e18433451916f2442c1b21036cd7d", size = 410897, upload-time = "2026-06-18T16:13:45.629Z" }, + { url = "https://files.pythonhosted.org/packages/da/ea/1479f72d200313a76fc2f823a79d1e07ed052ab7b8a0280640aa7b95de42/msgpack-1.2.1-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:5f6277e5f783c36786a145e0247fc189a03f35f84b251646e53592d2bc12b355", size = 378519, upload-time = "2026-06-18T16:13:46.998Z" }, + { url = "https://files.pythonhosted.org/packages/f5/4d/fa006060ffa1011d32bfae826fe766fe73e02982183601633b7121058ab3/msgpack-1.2.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:f9389552ecf4784886345ead0647e4edc96bee37cbab05b75540f542f766c48c", size = 419815, upload-time = "2026-06-18T16:13:48.205Z" }, +] + +[[package]] +name = "myst-parser" +version = "5.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "docutils", marker = "sys_platform == 'linux'" }, + { name = "jinja2", marker = "sys_platform == 'linux'" }, + { name = "markdown-it-py", marker = "sys_platform == 'linux'" }, + { name = "mdit-py-plugins", marker = "sys_platform == 'linux'" }, + { name = "pyyaml", marker = "sys_platform == 'linux'" }, + { name = "sphinx", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/21/dc/603751677fff302f34396e206b610f556a59d7fe58b9a2145f54e96b48e8/myst_parser-5.1.0.tar.gz", hash = "sha256:ab69322dc6719dcc7f296479dbb70181b66df6ed315064f92dbc85c0e1bf2f02", size = 101182, upload-time = "2026-05-13T09:38:19.361Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/09/dc/f3dfb7488b770f3f67e6545085bf2abea5172e88f57b8ad25ef860ca704c/myst_parser-5.1.0-py3-none-any.whl", hash = "sha256:9c91c52b3cdb4d94a6506e4fab4e2f296c7623a0da0dcbe6de1565c3dad67a8a", size = 85817, upload-time = "2026-05-13T09:38:17.904Z" }, +] + +[[package]] +name = "nbclient" +version = "0.11.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-client", marker = "sys_platform == 'linux'" }, + { name = "jupyter-core", marker = "sys_platform == 'linux'" }, + { name = "nbformat", marker = "sys_platform == 'linux'" }, + { name = "traitlets", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/28/a5/b3bae4b590c0cbcada2c63a34f7580024e834a8ba213e949a2f906705787/nbclient-0.11.0.tar.gz", hash = "sha256:04a134a5b087f2c5887f228aca155db50169b8cd9334dee6942c8e927e56081a", size = 62535, upload-time = "2026-06-05T07:52:41.746Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/36/c9/94d73e5a01c5b926c3fa2496e97d7a8dc28ed5a77c0b2ed712f1a62e6694/nbclient-0.11.0-py3-none-any.whl", hash = "sha256:ef7fa0d59d6e1d41103933d8a445a18d5de860ca6b613b87b8574accdb3c2895", size = 25288, upload-time = "2026-06-05T07:52:40.115Z" }, +] + +[[package]] +name = "nbconvert" +version = "7.17.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "beautifulsoup4", marker = "sys_platform == 'linux'" }, + { name = "bleach", extra = ["css"], marker = "sys_platform == 'linux'" }, + { name = "defusedxml", marker = "sys_platform == 'linux'" }, + { name = "jinja2", marker = "sys_platform == 'linux'" }, + { name = "jupyter-core", marker = "sys_platform == 'linux'" }, + { name = "jupyterlab-pygments", marker = "sys_platform == 'linux'" }, + { name = "markupsafe", marker = "sys_platform == 'linux'" }, + { name = "mistune", marker = "sys_platform == 'linux'" }, + { name = "nbclient", marker = "sys_platform == 'linux'" }, + { name = "nbformat", marker = "sys_platform == 'linux'" }, + { name = "packaging", marker = "sys_platform == 'linux'" }, + { name = "pandocfilters", marker = "sys_platform == 'linux'" }, + { name = "pygments", marker = "sys_platform == 'linux'" }, + { name = "traitlets", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/01/b1/708e53fe2e429c103c6e6e159106bcf0357ac41aa4c28772bd8402339051/nbconvert-7.17.1.tar.gz", hash = "sha256:34d0d0a7e73ce3cbab6c5aae8f4f468797280b01fd8bd2ca746da8569eddd7d2", size = 865311, upload-time = "2026-04-08T00:44:14.914Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/67/f8/bb0a9d5f46819c821dc1f004aa2cc29b1d91453297dbf5ff20470f00f193/nbconvert-7.17.1-py3-none-any.whl", hash = "sha256:aa85c087b435e7bf1ffd03319f658e285f2b89eccab33bc1ba7025495ab3e7c8", size = 261927, upload-time = "2026-04-08T00:44:12.845Z" }, +] + +[[package]] +name = "nbformat" +version = "5.10.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "fastjsonschema", marker = "sys_platform == 'linux'" }, + { name = "jsonschema", marker = "sys_platform == 'linux'" }, + { name = "jupyter-core", marker = "sys_platform == 'linux'" }, + { name = "traitlets", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6d/fd/91545e604bc3dad7dca9ed03284086039b294c6b3d75c0d2fa45f9e9caf3/nbformat-5.10.4.tar.gz", hash = "sha256:322168b14f937a5d11362988ecac2a4952d3d8e3a2cbeb2319584631226d5b3a", size = 142749, upload-time = "2024-04-04T11:20:37.371Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a9/82/0340caa499416c78e5d8f5f05947ae4bc3cba53c9f038ab6e9ed964e22f1/nbformat-5.10.4-py3-none-any.whl", hash = "sha256:3b48d6c8fbca4b299bf3982ea7db1af21580e4fec269ad087b9e81588891200b", size = 78454, upload-time = "2024-04-04T11:20:34.895Z" }, +] + +[[package]] +name = "ndindex" +version = "1.10.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f5/92/4b9d2f4e0f3eabcfc7b02b48261f6e5ad36a3e2c1bbdcc4e3b7b6c768fa6/ndindex-1.10.1.tar.gz", hash = "sha256:0f6113c1f031248f8818cbee1aa92aa3c9472b7701debcce9fddebcd2f610f11", size = 271395, upload-time = "2025-11-19T20:40:08.899Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1f/40/139b6b050ba2b2a0bb40e0381a352b1eb6551302dcb8f86fb4c97dd34e92/ndindex-1.10.1-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:046c1e88d46b2bd2fd3483e06d27b4e85132b55bc693f2fca2db0bb56eea1e78", size = 542901, upload-time = "2025-11-19T20:38:44.43Z" }, + { url = "https://files.pythonhosted.org/packages/27/ae/defd665dbbeb2fffa077491365ed160acaec49274ce8d4b979f55db71f18/ndindex-1.10.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:03cf1e6cdac876bd8fc92d3b65bb223496b1581d10eab3ba113f7c195121a959", size = 546875, upload-time = "2025-11-19T20:38:45.938Z" }, + { url = "https://files.pythonhosted.org/packages/59/43/6d54d48e8eaee25cdab70d3e4c4f579ddb0255e4f1660040d5ad55e029c6/ndindex-1.10.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:752e78a5e87911ded117c57a7246596f26c9c6da066de3c2b533b3db694949bb", size = 1510036, upload-time = "2025-11-19T20:38:47.444Z" }, + { url = "https://files.pythonhosted.org/packages/09/61/e28ba3b98eacd18193176526526b34d7d70d2a6f9fd2b4d8309ab5692678/ndindex-1.10.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:c9dd58d91220b1c1fe516324bfcf4114566c98e84b1cbbe416abe345c75bd557", size = 1571849, upload-time = "2025-11-19T20:38:48.951Z" }, + { url = "https://files.pythonhosted.org/packages/77/34/a51b7c6f7159718a6a0a694fc1058b94d793c416d9a4fd649f1924cce5f8/ndindex-1.10.1-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6928e47fb008903f2e41309b7ff1e59b16abbcd59e2e945454571c28b2433c9e", size = 524127, upload-time = "2025-11-19T20:38:59.412Z" }, + { url = "https://files.pythonhosted.org/packages/21/91/d8f19f0b8fc9c5585b50fda44c05415da0bdc5fa9c9c69011015dac27880/ndindex-1.10.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e69a2cb1ac7be955c3c77f1def83f410775a81525c9ce2d4c0a3f2a61589ed47", size = 528213, upload-time = "2025-11-19T20:39:00.882Z" }, + { url = "https://files.pythonhosted.org/packages/2c/a9/77d9d037e871a3faa8579b354ca2dd09cc5bbf3e085d9e3c67f786d55ee3/ndindex-1.10.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cb76e0f3f235d8b1c768b17e771de48775d281713795c3aa045e8114ad61bdda", size = 1492172, upload-time = "2025-11-19T20:39:02.387Z" }, + { url = "https://files.pythonhosted.org/packages/ac/29/ad13676fc9312e0aa1a80a7c04bcb0b502b877ed4956136117ad663eced0/ndindex-1.10.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:7da34a78410c14341d5fff73be5ce924bd36500bf7f640fc59b8607d3a0df95e", size = 1552614, upload-time = "2025-11-19T20:39:04.232Z" }, + { url = "https://files.pythonhosted.org/packages/e2/d7/1df02df24880ce3f3c8137b6f3ca5a901a58d9079dcfd8c818419277ff87/ndindex-1.10.1-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d0ebdba2fade3f6916fe21fd49e2a0935af4f58c56100a60f3f2eb26e20baee7", size = 632517, upload-time = "2025-11-19T20:39:13.259Z" }, + { url = "https://files.pythonhosted.org/packages/34/96/b509c2b14e9b10710fe6ab6ba8bda1ee6ce36ab16397ff2f5bbb33bbbba3/ndindex-1.10.1-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:346a4bf09f5771548665c8206e81daadb6b9925d409746e709894bdd98adc701", size = 616179, upload-time = "2025-11-19T20:39:14.757Z" }, + { url = "https://files.pythonhosted.org/packages/38/e3/f89d60cf351c33a484bf1a4546a5dee6f4e7a6a973613ffa12bd316b14ad/ndindex-1.10.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:23d35696f802548143b5cc199bf2f171efb0061aa7934959251dd3bae56d038c", size = 1588373, upload-time = "2025-11-19T20:39:16.62Z" }, + { url = "https://files.pythonhosted.org/packages/ee/19/002fc1e6a4abeef8d92e9aa2e43aea4d462f6b170090f7752ea8887f4897/ndindex-1.10.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:a91e1a0398120233d5c3b23ccb2d4b78e970d66136f1a7221fa9a53873c3d5c5", size = 1636436, upload-time = "2025-11-19T20:39:18.266Z" }, + { url = "https://files.pythonhosted.org/packages/09/4a/028ab78a9f29fd2a7e86a90337cde4658eaa77b425c63045d83a1d2e4f26/ndindex-1.10.1-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cf80241b40adffdc3276b2c9fb63a96c6c98b4a9d941892738de8add65083962", size = 528125, upload-time = "2025-11-19T20:39:26.798Z" }, + { url = "https://files.pythonhosted.org/packages/00/a9/bd823b345fb06c83ade6ef1c1933521d4357cd04490e684d4fa30126926c/ndindex-1.10.1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cf5855881884b8467dfcf45764ccf2e4279075be14b155b89c96994bb08d2e6f", size = 527328, upload-time = "2025-11-19T20:39:28.292Z" }, + { url = "https://files.pythonhosted.org/packages/91/4f/40b9c15588cbf9dde43c4fb88a31dd1f636a913fa29649f18f8e3ebca36a/ndindex-1.10.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e81a9bd36fe054b6c9fcc53d26bc9a28cf15d1ab52a0f5b854f894116f3a54e1", size = 1497508, upload-time = "2025-11-19T20:39:30.735Z" }, + { url = "https://files.pythonhosted.org/packages/24/8f/b8048f7837d2e9dff0af507b398307fa84a2aa9ea3db71b4aa800b21da4a/ndindex-1.10.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:588e8875d836a93b3cd9af482c8074bb02288ae1aff92cf277e1f02d9ae0f992", size = 1552625, upload-time = "2025-11-19T20:39:32.404Z" }, + { url = "https://files.pythonhosted.org/packages/4d/05/a6fda696a2f02a3f8dd2ee9d816cb2edff6423bf0110a4876cc3b1259732/ndindex-1.10.1-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c65ca639a7abf72d79f22424f4abd18dece1f289a2b7b028a0ca455edd2168d4", size = 630898, upload-time = "2025-11-19T20:39:41.495Z" }, + { url = "https://files.pythonhosted.org/packages/73/78/eb2e5d067d4c054451e33eaece74cbdcb58236dc60516e73d783dae34c7e/ndindex-1.10.1-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:5c3634a8df43e7928122225a3d64d850c8957bd1edf2e403907deacb478af27b", size = 614419, upload-time = "2025-11-19T20:39:43.254Z" }, + { url = "https://files.pythonhosted.org/packages/78/51/261bfb49eb7920c2a7314cacba5821930a529911dce48c7c6cd786096a5a/ndindex-1.10.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:9d581f931e61f182478f18bdf5edd3955899df5da4892ed0d5de547a4cfd5b6f", size = 1587517, upload-time = "2025-11-19T20:39:44.809Z" }, + { url = "https://files.pythonhosted.org/packages/ec/37/084a332ecdf8b0049151bd78001a7baf2daf7f500d043beb8a1f95d0f4e3/ndindex-1.10.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:78ce45106ebf67aeba99714818c721d8fd5fb9534daebd2565665a2d64b50fc9", size = 1635372, upload-time = "2025-11-19T20:39:47.231Z" }, +] + +[[package]] +name = "nest-asyncio2" +version = "1.7.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b4/73/731debf26e27e0a0323d7bda270dc2f634b398e38f040a09da1f4351d0aa/nest_asyncio2-1.7.2.tar.gz", hash = "sha256:1921d70b92cc4612c374928d081552efb59b83d91b2b789d935c665fa01729a8", size = 14743, upload-time = "2026-02-13T00:34:04.386Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/3c/3179b85b0e1c3659f0369940200cd6d0fa900e6cefcc7ea0bc6dd0e29ffb/nest_asyncio2-1.7.2-py3-none-any.whl", hash = "sha256:f5dfa702f3f81f6a03857e9a19e2ba578c0946a4ad417b4c50a24d7ba641fe01", size = 7843, upload-time = "2026-02-13T00:34:02.691Z" }, +] + +[[package]] +name = "notebook" +version = "5.7.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ipykernel", marker = "sys_platform == 'linux'" }, + { name = "ipython-genutils", marker = "sys_platform == 'linux'" }, + { name = "jinja2", marker = "sys_platform == 'linux'" }, + { name = "jupyter-client", marker = "sys_platform == 'linux'" }, + { name = "jupyter-core", marker = "sys_platform == 'linux'" }, + { name = "nbconvert", marker = "sys_platform == 'linux'" }, + { name = "nbformat", marker = "sys_platform == 'linux'" }, + { name = "prometheus-client", marker = "sys_platform == 'linux'" }, + { name = "pyzmq", marker = "sys_platform == 'linux'" }, + { name = "send2trash", marker = "sys_platform == 'linux'" }, + { name = "terminado", marker = "sys_platform == 'linux'" }, + { name = "tornado", marker = "sys_platform == 'linux'" }, + { name = "traitlets", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/6e/22/b5dcce67559d63d0f22e46d806305710808c698a1b91c07eb09e389785e0/notebook-5.7.4.tar.gz", hash = "sha256:d908673a4010787625c8952e91a22adf737db031f2aa0793ad92f6558918a74a", size = 13389469, upload-time = "2018-12-17T10:06:00.805Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f8/a6/dbdf0954d073ab2cf5421cad20334d1e4c780da37205c04522c045298f67/notebook-5.7.4-py2.py3-none-any.whl", hash = "sha256:3ab2db8bc10e6edbd264c3c4b800bee276c99818386ee0c146d98d7e6bcf0a67", size = 8980706, upload-time = "2018-12-17T10:05:52.01Z" }, +] + +[[package]] +name = "notebook-shim" +version = "0.2.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "jupyter-server", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/54/d2/92fa3243712b9a3e8bafaf60aac366da1cada3639ca767ff4b5b3654ec28/notebook_shim-0.2.4.tar.gz", hash = "sha256:b4b2cfa1b65d98307ca24361f5b30fe785b53c3fd07b7a47e89acb5e6ac638cb", size = 13167, upload-time = "2024-02-14T23:35:18.353Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/33/bd5b9137445ea4b680023eb0469b2bb969d61303dedb2aac6560ff3d14a1/notebook_shim-0.2.4-py3-none-any.whl", hash = "sha256:411a5be4e9dc882a074ccbcae671eda64cceb068767e9a3419096986560e1cef", size = 13307, upload-time = "2024-02-14T23:35:16.286Z" }, +] + +[[package]] +name = "numba" +version = "0.66.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "llvmlite", marker = "sys_platform == 'linux'" }, + { name = "numpy", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ae/a0/570e3dc53e5602b49108f62a13e529f1eec8bfc7ef37d49c825924dcf546/numba-0.66.0.tar.gz", hash = "sha256:b900e63a0e26c05ea9a6d5a3a5a0a177cb64c5011887bf43edb8c3ed2c38d363", size = 2806181, upload-time = "2026-07-01T23:12:46.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2d/55/25c319845e9a4e08f16611ddbda56a192eb7b6ed13e1a2bff2da272ffb97/numba-0.66.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:0999e3ee1b18c48e1fb51d11af35ef59852c7f4f50569c9550c25faef0616ad1", size = 3866252, upload-time = "2026-07-01T23:12:20.429Z" }, + { url = "https://files.pythonhosted.org/packages/71/ef/a82d6fd6bf1b0fe461651e924d3647eeec9ac17f8eee4896264bf7480930/numba-0.66.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:efe0d2d5099790df945e0cb6e1b3104bd965d7bbfac50d62f1d5d1d6ade0825d", size = 3566974, upload-time = "2026-07-01T23:12:22.116Z" }, + { url = "https://files.pythonhosted.org/packages/44/b5/e930010965568fe7f2c6c962fd2849d458cb9f62c3ab7584af8a19a2b40a/numba-0.66.0-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:939316d5d8619751207b8972a67852b5a7646665298cb4de693cd6bf135152f4", size = 3873663, upload-time = "2026-07-01T23:12:27.308Z" }, + { url = "https://files.pythonhosted.org/packages/d0/ec/5b51457cbe96e4831141d83e892e65191b23a1b78728456c62909d231ace/numba-0.66.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cdf506775d9f02eb92a87bf5c5b1e0d25506fd18cafd769f4ed914a8feac73e7", size = 3573529, upload-time = "2026-07-01T23:12:28.944Z" }, + { url = "https://files.pythonhosted.org/packages/0f/26/885774c006de6620ed3d10f45d8e20fe0b8e6aad6d573211a2cbc8b3e528/numba-0.66.0-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:e2b101f23b8b63978d334574d2039f27f0dccfe1d891756f33a2e2f3e4c88cf4", size = 3842720, upload-time = "2026-07-01T23:12:33.938Z" }, + { url = "https://files.pythonhosted.org/packages/93/99/edebf7de890b73973d839dd971cf73734adfb81ffa1b4504f84b9059c3e5/numba-0.66.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:63b943eb2c9ba371908ce2cd6dfc643db51fc40f7966993376a1701bc922f537", size = 3543537, upload-time = "2026-07-01T23:12:35.566Z" }, + { url = "https://files.pythonhosted.org/packages/39/fd/e9c9680a3813f3d781c20e5d53c1074801b787d4feecca0472fdd7c05ce1/numba-0.66.0-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:651a2b53298340956db26ecbe7ab043106b50a40c2807e66d617a4917245a4ab", size = 3878695, upload-time = "2026-07-01T23:12:40.302Z" }, + { url = "https://files.pythonhosted.org/packages/61/3a/9b363287b85fcd4537ea3878793822878b2ac1008a78159d2096fea628de/numba-0.66.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8c1144ba1720ea59ad79f4f488ed54d149b2613b357f7e445678b7d0739c70e9", size = 3596323, upload-time = "2026-07-01T23:12:42.805Z" }, +] + +[[package]] +name = "numbaquadpack" +version = "0.1" +source = { git = "https://github.com/Nicholaswogan/NumbaQuadpack.git#9fa67a4a952860042177a3dba61e7102799671b3" } + +[[package]] +name = "numcodecs" +version = "0.16.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", marker = "sys_platform == 'linux'" }, + { name = "typing-extensions", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/44/bd/8a391e7c356366224734efd24da929cc4796fff468bfb179fe1af6548535/numcodecs-0.16.5.tar.gz", hash = "sha256:0d0fb60852f84c0bd9543cc4d2ab9eefd37fc8efcc410acd4777e62a1d300318", size = 6276387, upload-time = "2025-11-21T02:49:48.986Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/97/1e/98aaddf272552d9fef1f0296a9939d1487914a239e98678f6b20f8b0a5c8/numcodecs-0.16.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b554ab9ecf69de7ca2b6b5e8bc696bd9747559cb4dd5127bd08d7a28bec59c3a", size = 8534814, upload-time = "2025-11-21T02:49:28.547Z" }, + { url = "https://files.pythonhosted.org/packages/fb/53/78c98ef5c8b2b784453487f3e4d6c017b20747c58b470393e230c78d18e8/numcodecs-0.16.5-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ad1a379a45bd3491deab8ae6548313946744f868c21d5340116977ea3be5b1d6", size = 9173471, upload-time = "2025-11-21T02:49:30.444Z" }, + { url = "https://files.pythonhosted.org/packages/0b/00/787ea5f237b8ea7bc67140c99155f9c00b5baf11c49afc5f3bfefa298f95/numcodecs-0.16.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:015a7c859ecc2a06e2a548f64008c0ec3aaecabc26456c2c62f4278d8fc20597", size = 8483064, upload-time = "2025-11-21T02:49:36.454Z" }, + { url = "https://files.pythonhosted.org/packages/c4/e6/d359fdd37498e74d26a167f7a51e54542e642ea47181eb4e643a69a066c3/numcodecs-0.16.5-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:84230b4b9dad2392f2a84242bd6e3e659ac137b5a1ce3571d6965fca673e0903", size = 9126063, upload-time = "2025-11-21T02:49:38.018Z" }, + { url = "https://files.pythonhosted.org/packages/4e/15/e2e1151b5a8b14a15dfd4bb4abccce7fff7580f39bc34092780088835f3a/numcodecs-0.16.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:49f7b7d24f103187f53135bed28bb9f0ed6b2e14c604664726487bb6d7c882e1", size = 8476987, upload-time = "2025-11-21T02:49:43.363Z" }, + { url = "https://files.pythonhosted.org/packages/6d/30/16a57fc4d9fb0ba06c600408bd6634f2f1753c54a7a351c99c5e09b51ee2/numcodecs-0.16.5-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:aec9736d81b70f337d89c4070ee3ffeff113f386fd789492fa152d26a15043e4", size = 9102377, upload-time = "2025-11-21T02:49:45.508Z" }, +] + +[[package]] +name = "numexpr" +version = "2.14.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cb/2f/fdba158c9dbe5caca9c3eca3eaffffb251f2fb8674bf8e2d0aed5f38d319/numexpr-2.14.1.tar.gz", hash = "sha256:4be00b1086c7b7a5c32e31558122b7b80243fe098579b170967da83f3152b48b", size = 119400, upload-time = "2025-10-13T16:17:27.351Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/72/94/cc921e35593b820521e464cbbeaf8212bbdb07f16dc79fe283168df38195/numexpr-2.14.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d686dfb2c1382d9e6e0ee0b7647f943c1886dba3adbf606c625479f35f1956c1", size = 452468, upload-time = "2025-10-13T16:13:29.531Z" }, + { url = "https://files.pythonhosted.org/packages/d9/43/560e9ba23c02c904b5934496486d061bcb14cd3ebba2e3cf0e2dccb6c22b/numexpr-2.14.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eee6d4fbbbc368e6cdd0772734d6249128d957b3b8ad47a100789009f4de7083", size = 443631, upload-time = "2025-10-13T16:15:02.473Z" }, + { url = "https://files.pythonhosted.org/packages/7b/6c/78f83b6219f61c2c22d71ab6e6c2d4e5d7381334c6c29b77204e59edb039/numexpr-2.14.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3a2839efa25f3c8d4133252ea7342d8f81226c7c4dda81f97a57e090b9d87a48", size = 1417670, upload-time = "2025-10-13T16:13:33.464Z" }, + { url = "https://files.pythonhosted.org/packages/0e/bb/1ccc9dcaf46281568ce769888bf16294c40e98a5158e4b16c241de31d0d3/numexpr-2.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9f9137f1351b310436662b5dc6f4082a245efa8950c3b0d9008028df92fefb9b", size = 1466212, upload-time = "2025-10-13T16:15:12.828Z" }, + { url = "https://files.pythonhosted.org/packages/13/65/72b065f9c75baf8f474fd5d2b768350935989d4917db1c6c75b866d4067c/numexpr-2.14.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:06855053de7a3a8425429bd996e8ae3c50b57637ad3e757e0fa0602a7874be30", size = 455860, upload-time = "2025-10-13T16:13:35.811Z" }, + { url = "https://files.pythonhosted.org/packages/fc/f9/c9457652dfe28e2eb898372da2fe786c6db81af9540c0f853ee04a0699cc/numexpr-2.14.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:05f9366d23a2e991fd5a8b5e61a17558f028ba86158a4552f8f239b005cdf83c", size = 446574, upload-time = "2025-10-13T16:15:17.367Z" }, + { url = "https://files.pythonhosted.org/packages/b6/99/8d3879c4d67d3db5560cf2de65ce1778b80b75f6fa415eb5c3e7bd37ba27/numexpr-2.14.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c5f1b1605695778896534dfc6e130d54a65cd52be7ed2cd0cfee3981fd676bf5", size = 1417306, upload-time = "2025-10-13T16:13:42.813Z" }, + { url = "https://files.pythonhosted.org/packages/ea/05/6bddac9f18598ba94281e27a6943093f7d0976544b0cb5d92272c64719bd/numexpr-2.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a4ba71db47ea99c659d88ee6233fa77b6dc83392f1d324e0c90ddf617ae3f421", size = 1466145, upload-time = "2025-10-13T16:15:27.464Z" }, + { url = "https://files.pythonhosted.org/packages/84/78/3c8335f713d4aeb99fa758d7c62f0be1482d4947ce5b508e2052bb7aeee9/numexpr-2.14.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:33265294376e7e2ae4d264d75b798a915d2acf37b9dd2b9405e8b04f84d05cfc", size = 465972, upload-time = "2025-10-13T16:13:45.061Z" }, + { url = "https://files.pythonhosted.org/packages/35/81/9ee5f69b811e8f18746c12d6f71848617684edd3161927f95eee7a305631/numexpr-2.14.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:83647d846d3eeeb9a9255311236135286728b398d0d41d35dedb532dca807fe9", size = 456953, upload-time = "2025-10-13T16:15:31.186Z" }, + { url = "https://files.pythonhosted.org/packages/6d/39/9b8bc6e294d85cbb54a634e47b833e9f3276a8bdf7ce92aa808718a0212d/numexpr-2.14.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6e575fd3ad41ddf3355d0c7ef6bd0168619dc1779a98fe46693cad5e95d25e6e", size = 1426199, upload-time = "2025-10-13T16:13:48.231Z" }, + { url = "https://files.pythonhosted.org/packages/1e/ce/0d4fcd31ab49319740d934fba1734d7dad13aa485532ca754e555ca16c8b/numexpr-2.14.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:67ea4771029ce818573b1998f5ca416bd255156feea017841b86176a938f7d19", size = 1474214, upload-time = "2025-10-13T16:15:38.893Z" }, + { url = "https://files.pythonhosted.org/packages/9a/ed/aabd8678077848dd9a751c5558c2057839f5a09e2a176d8dfcd0850ee00e/numexpr-2.14.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5aedf38d4c0c19d3cecfe0334c3f4099fb496f54c146223d30fa930084bc8574", size = 455918, upload-time = "2025-10-13T16:13:50.338Z" }, + { url = "https://files.pythonhosted.org/packages/88/e1/3db65117f02cdefb0e5e4c440daf1c30beb45051b7f47aded25b7f4f2f34/numexpr-2.14.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:439ec4d57b853792ebe5456e3160312281c3a7071ecac5532ded3278ede614de", size = 446512, upload-time = "2025-10-13T16:15:42.313Z" }, + { url = "https://files.pythonhosted.org/packages/9a/fb/7ceb9ee55b5f67e4a3e4d73d5af4c7e37e3c9f37f54bee90361b64b17e3f/numexpr-2.14.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:e23b87f744e04e302d82ac5e2189ae20a533566aec76a46885376e20b0645bf8", size = 1417845, upload-time = "2025-10-13T16:13:53.836Z" }, + { url = "https://files.pythonhosted.org/packages/45/2d/9b5764d0eafbbb2889288f80de773791358acf6fad1a55767538d8b79599/numexpr-2.14.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:44f84e0e5af219dbb62a081606156420815890e041b87252fbcea5df55214c4c", size = 1466211, upload-time = "2025-10-13T16:15:48.985Z" }, + { url = "https://files.pythonhosted.org/packages/9e/d3/956a13e628d722d649fbf2fded615134a308c082e122a48bad0e90a99ce9/numexpr-2.14.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:dd72d8c2a165fe45ea7650b16eb8cc1792a94a722022006bb97c86fe51fd2091", size = 466242, upload-time = "2025-10-13T16:13:55.795Z" }, + { url = "https://files.pythonhosted.org/packages/d6/dd/abe848678d82486940892f2cacf39e82eec790e8930d4d713d3f9191063b/numexpr-2.14.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:70d80fcb418a54ca208e9a38e58ddc425c07f66485176b261d9a67c7f2864f73", size = 457149, upload-time = "2025-10-13T16:15:52.036Z" }, + { url = "https://files.pythonhosted.org/packages/fd/bb/797b583b5fb9da5700a5708ca6eb4f889c94d81abb28de4d642c0f4b3258/numexpr-2.14.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:edea2f20c2040df8b54ee8ca8ebda63de9545b2112872466118e9df4d0ae99f3", size = 1426493, upload-time = "2025-10-13T16:13:59.244Z" }, + { url = "https://files.pythonhosted.org/packages/77/c4/0519ab028fdc35e3e7ee700def7f2b4631b175cd9e1202bd7966c1695c33/numexpr-2.14.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:790447be6879a6c51b9545f79612d24c9ea0a41d537a84e15e6a8ddef0b6268e", size = 1474413, upload-time = "2025-10-13T16:15:59.211Z" }, +] + +[[package]] +name = "numpy" +version = "2.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/ad/fed0499ce6a338d2a03ebae59cd15093910c8875328855781952abf6c2fe/numpy-2.4.6.tar.gz", hash = "sha256:f3a3570c4a2a16746ac2c31a7c7c7b0c186b95ce902e33db6f28094ed7387dda", size = 20735807, upload-time = "2026-05-18T23:37:14.07Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c9/c6/50a46a6205feba2343f1d6d17438107c5dc491ed1c736e6ea68689fd906b/numpy-2.4.6-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5f9fb9157b4ce2971008323afe46053787b526ef624fea915b261468a8421a0f", size = 15671012, upload-time = "2026-05-18T23:34:05.485Z" }, + { url = "https://files.pythonhosted.org/packages/99/60/14115e6364fa676c5397c2ad3004e527e9aa487abf5d0706ec81bbd08529/numpy-2.4.6-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:90f9849678c75fe7afa2d348ac842c168b0a4d3d61919687216dfc547976d853", size = 16645538, upload-time = "2026-05-18T23:34:09.265Z" }, + { url = "https://files.pythonhosted.org/packages/ae/c5/693cbe59e57db94d2231fa519ca3978dc9e19da5a8f088588f5c6e947ff2/numpy-2.4.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c1a2af6c6ef86344a6b0db6b97834208bf598db514f2b155042439b62605601a", size = 17020706, upload-time = "2026-05-18T23:34:13.053Z" }, + { url = "https://files.pythonhosted.org/packages/ef/fc/85b7c4eff9b4966ade25c2273cf7e7012e92366c032058653934b37de044/numpy-2.4.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e5805d5a22fd19c8ccff10a9561f9df94436b0545619ea579db2d3c35294bce2", size = 18368541, upload-time = "2026-05-18T23:34:17.024Z" }, + { url = "https://files.pythonhosted.org/packages/bb/c5/7b863a97a91671a0338f4253bd3b5a3d3852f0692dae91711c9f4a10e787/numpy-2.4.6-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:72fbe16c6fac95aedf5937fa873445cec2110be35d8a4e9433d7501fd98dae6b", size = 15669392, upload-time = "2026-05-18T23:34:41.257Z" }, + { url = "https://files.pythonhosted.org/packages/a5/9d/3584b9984ca4c047aea75214ce1a4c4c73d849bd71b604264b7f5653f8a8/numpy-2.4.6-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a7830bab239b79cda9c08c2da014761cafb48da6150e1da17ac06283f43b6089", size = 16633220, upload-time = "2026-05-18T23:34:45.075Z" }, + { url = "https://files.pythonhosted.org/packages/05/ae/7c67fba23bd98caec7c99261f3a16072ade14813486b0282cb29846de832/numpy-2.4.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ef4aea96ce4d3b074422cb4f2f64e216bf9e213004bb58ecfdf50ea02ea8eb9a", size = 17020800, upload-time = "2026-05-18T23:34:49.065Z" }, + { url = "https://files.pythonhosted.org/packages/d9/5d/3b6725cb31d983c5e66916f5d36f6d7e5521129e4c4404d64f918292a5b6/numpy-2.4.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:dfa20cc6ca228e6b155b11da03825975ce66aea520985dbbddf0f2a5a495c605", size = 18357600, upload-time = "2026-05-18T23:34:52.709Z" }, + { url = "https://files.pythonhosted.org/packages/eb/0f/037e64c494b67581ae18193d770adef354c41f3f2c8ebf865602d949bf8f/numpy-2.4.6-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f74a575920ab21fe304421a3fc28793d82e299cae9eccb37084e9fc7f3617c20", size = 15728070, upload-time = "2026-05-18T23:35:14.79Z" }, + { url = "https://files.pythonhosted.org/packages/21/a6/5d2bae9c9542eb4df16dc9c46dc79c186e9bad53805dfa5399a6023c6db0/numpy-2.4.6-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ede83e07a75dd06bc501566c1eca2afc0d61677c1472ac9ad93fdee6e638a48d", size = 16681752, upload-time = "2026-05-18T23:35:18.836Z" }, + { url = "https://files.pythonhosted.org/packages/92/14/23d1dfb410ae362cd59ce53e936b1513d545eb40db3949ced632e19a459e/numpy-2.4.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:68bb27509ac1b9a3443094260f6326150663b06abe40b73a2f81160623da5b67", size = 17086024, upload-time = "2026-05-18T23:35:22.52Z" }, + { url = "https://files.pythonhosted.org/packages/4b/6e/23595a2c642cdf3bc567877064bdd7f91c8b0038a4453cf2daf7248eafe9/numpy-2.4.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:a0df0043bdb289bde1f62da130d20df23d58b45429f752bc7a8fc5325a225ecd", size = 18403398, upload-time = "2026-05-18T23:35:26.398Z" }, + { url = "https://files.pythonhosted.org/packages/d5/91/64288395ee1799bd2e0b04a305dce9666da90c961e1f3fe982a05ee1c036/numpy-2.4.6-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:40fdc1ae7125e518ea98e53e69a4ebc27e1fd50510c47b7ea130cf21e5e1d42b", size = 15685197, upload-time = "2026-05-18T23:35:50.863Z" }, + { url = "https://files.pythonhosted.org/packages/f3/eb/ebffaa97dc55502df69584a8f0dcf07f69a3e0b3e2323670a2722db9aa39/numpy-2.4.6-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a2c306dea656c12c68f51f4cea133cbe78ca7435eb28c735eac1d3ebe73be6e8", size = 16638245, upload-time = "2026-05-18T23:35:54.752Z" }, + { url = "https://files.pythonhosted.org/packages/b8/0b/54f9da33128d7e350fab89c7455902eeae70349ee52bddb448dc4a576f45/numpy-2.4.6-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:33111801a01c12a8a1e3721f0a9232f8cfc8ae2c6b7098167e6f623c6073f402", size = 17036587, upload-time = "2026-05-18T23:35:58.355Z" }, + { url = "https://files.pythonhosted.org/packages/b6/f0/fdebc1052db1cc37c64beb22072d67cd6d1c71adca1299f53dec2b5e20d3/numpy-2.4.6-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:ae506e6902902557576a26ff33eda8695e7ecb3cb36c3b573a0765dee114ebdb", size = 18363226, upload-time = "2026-05-18T23:36:02.845Z" }, + { url = "https://files.pythonhosted.org/packages/82/dd/1206a7ca6ab15e3f02069707ca96222e202af681bb73756da7527f3cb837/numpy-2.4.6-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:9cd5ffd25db4e7ba6a375693b3fc0fc1791ec636c17db3720da19bde7180ec43", size = 15730496, upload-time = "2026-05-18T23:36:25.713Z" }, + { url = "https://files.pythonhosted.org/packages/51/e7/38d3ea825dcab85a591734decb2f6c67caa7c8367d374df1a1c3842f9b07/numpy-2.4.6-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7d92c3819208a60205a12a245c91ad70cb0a85336659b19b834205573ac8456e", size = 16679616, upload-time = "2026-05-18T23:36:29.652Z" }, + { url = "https://files.pythonhosted.org/packages/93/b7/caabfdf53edf663e0b4eb74d7d405d83baef09eb5e83bcd32d601d72b93e/numpy-2.4.6-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:e85b752a1e912b70eaad4fafbd4d1238007ab221de2009b9a2f5ae7461239895", size = 17085145, upload-time = "2026-05-18T23:36:33.449Z" }, + { url = "https://files.pythonhosted.org/packages/f9/45/68d7c33a6bcf3e5aa3bdbd57a367e6f615286dfd6482f97e8ffeb734306e/numpy-2.4.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:29cb7f67d10b479ff07c17d33e39f78c07f71c40ef30d63c153d340e96cd3fb4", size = 18403813, upload-time = "2026-05-18T23:36:37.369Z" }, +] + +[[package]] +name = "numpydoc" +version = "1.10.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "sphinx", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e9/3c/dfccc9e7dee357fb2aa13c3890d952a370dd0ed071e0f7ed62ed0df567c1/numpydoc-1.10.0.tar.gz", hash = "sha256:3f7970f6eee30912260a6b31ac72bba2432830cd6722569ec17ee8d3ef5ffa01", size = 94027, upload-time = "2025-12-02T16:39:12.937Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/5e/3a6a3e90f35cea3853c45e5d5fb9b7192ce4384616f932cf7591298ab6e1/numpydoc-1.10.0-py3-none-any.whl", hash = "sha256:3149da9874af890bcc2a82ef7aae5484e5aa81cb2778f08e3c307ba6d963721b", size = 69255, upload-time = "2025-12-02T16:39:11.561Z" }, +] + +[[package]] +name = "opencv-python-headless" +version = "5.0.0.93" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1d/99/76b7c80252aa83c1af16393454aafd125a0287101afe8deb0a6821af0e30/opencv_python_headless-5.0.0.93.tar.gz", hash = "sha256:b82f9831daab90b725c7c1ee1b36cb5732c367096ac76d119e64e14eb70d5f3c", size = 81817738, upload-time = "2026-07-02T07:01:06.039Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/78/afca939f40ffe2b2380bfa86f812b2f7d4acc5a27b27dc41b49cad7ce7b4/opencv_python_headless-5.0.0.93-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:10818d91510e05c04568ae12b5cd120779c70c01bf897b001a6221fe430df80f", size = 36521085, upload-time = "2026-07-02T06:55:24.429Z" }, + { url = "https://files.pythonhosted.org/packages/2b/97/8170e9819764c47e436c130d3ff6cfb73b58f923eae9d3a03d8982b04aec/opencv_python_headless-5.0.0.93-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:09a872a157c1376ab922a69bbf22f9a95bcc7b658a9d8b436a60212b02b2eeb4", size = 56563598, upload-time = "2026-07-02T06:55:47.355Z" }, + { url = "https://files.pythonhosted.org/packages/3a/98/1a28a7101e31801042b3098871a74b76c61581d328ef40774ff4edb53a56/opencv_python_headless-5.0.0.93-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:840bd717c21e5c11cadadc022a823315ea417f961213d06b4df010e019eb16f4", size = 39648433, upload-time = "2026-07-02T06:56:04.255Z" }, + { url = "https://files.pythonhosted.org/packages/9b/21/f6ef335f6e65724aa78b8d792b48d40a48c381715f1e62f5a5049e09d07e/opencv_python_headless-5.0.0.93-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:ed709fdf9aa0bd1f2ed8549e71d19449b03a675bb581eb292285f6861953be37", size = 61204038, upload-time = "2026-07-02T06:56:41.823Z" }, +] + +[[package]] +name = "packaging" +version = "25.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, +] + +[[package]] +name = "pandas" +version = "2.3.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", marker = "sys_platform == 'linux'" }, + { name = "python-dateutil", marker = "sys_platform == 'linux'" }, + { name = "pytz", marker = "sys_platform == 'linux'" }, + { name = "tzdata", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/33/01/d40b85317f86cf08d853a4f495195c73815fdf205eef3993821720274518/pandas-2.3.3.tar.gz", hash = "sha256:e05e1af93b977f7eafa636d043f9f94c7ee3ac81af99c13508215942e64c993b", size = 4495223, upload-time = "2025-09-29T23:34:51.853Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/57/56/cf2dbe1a3f5271370669475ead12ce77c61726ffd19a35546e31aa8edf4e/pandas-2.3.3-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ecaf1e12bdc03c86ad4a7ea848d66c685cb6851d807a26aa245ca3d2017a1908", size = 11737212, upload-time = "2025-09-29T23:19:59.765Z" }, + { url = "https://files.pythonhosted.org/packages/e5/63/cd7d615331b328e287d8233ba9fdf191a9c2d11b6af0c7a59cfcec23de68/pandas-2.3.3-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b3d11d2fda7eb164ef27ffc14b4fcab16a80e1ce67e9f57e19ec0afaf715ba89", size = 12362693, upload-time = "2025-09-29T23:20:14.098Z" }, + { url = "https://files.pythonhosted.org/packages/a6/de/8b1895b107277d52f2b42d3a6806e69cfef0d5cf1d0ba343470b9d8e0a04/pandas-2.3.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a68e15f780eddf2b07d242e17a04aa187a7ee12b40b930bfdd78070556550e98", size = 12771002, upload-time = "2025-09-29T23:20:26.76Z" }, + { url = "https://files.pythonhosted.org/packages/87/21/84072af3187a677c5893b170ba2c8fbe450a6ff911234916da889b698220/pandas-2.3.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:371a4ab48e950033bcf52b6527eccb564f52dc826c02afd9a1bc0ab731bba084", size = 13450971, upload-time = "2025-09-29T23:20:41.344Z" }, + { url = "https://files.pythonhosted.org/packages/16/87/9472cf4a487d848476865321de18cc8c920b8cab98453ab79dbbc98db63a/pandas-2.3.3-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e32e7cc9af0f1cc15548288a51a3b681cc2a219faa838e995f7dc53dbab1062d", size = 11709872, upload-time = "2025-09-29T23:21:27.165Z" }, + { url = "https://files.pythonhosted.org/packages/15/07/284f757f63f8a8d69ed4472bfd85122bd086e637bf4ed09de572d575a693/pandas-2.3.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:318d77e0e42a628c04dc56bcef4b40de67918f7041c2b061af1da41dcff670ac", size = 12306371, upload-time = "2025-09-29T23:21:40.532Z" }, + { url = "https://files.pythonhosted.org/packages/33/81/a3afc88fca4aa925804a27d2676d22dcd2031c2ebe08aabd0ae55b9ff282/pandas-2.3.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e0a175408804d566144e170d0476b15d78458795bb18f1304fb94160cabf40c", size = 12765333, upload-time = "2025-09-29T23:21:55.77Z" }, + { url = "https://files.pythonhosted.org/packages/8d/0f/b4d4ae743a83742f1153464cf1a8ecfafc3ac59722a0b5c8602310cb7158/pandas-2.3.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:93c2d9ab0fc11822b5eece72ec9587e172f63cff87c00b062f6e37448ced4493", size = 13418120, upload-time = "2025-09-29T23:22:10.109Z" }, + { url = "https://files.pythonhosted.org/packages/46/b1/85331edfc591208c9d1a63a06baa67b21d332e63b7a591a5ba42a10bb507/pandas-2.3.3-cp313-cp313t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6435cb949cb34ec11cc9860246ccb2fdc9ecd742c12d3304989017d53f039a78", size = 11645189, upload-time = "2025-09-29T23:22:51.688Z" }, + { url = "https://files.pythonhosted.org/packages/44/23/78d645adc35d94d1ac4f2a3c4112ab6f5b8999f4898b8cdf01252f8df4a9/pandas-2.3.3-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:900f47d8f20860de523a1ac881c4c36d65efcb2eb850e6948140fa781736e110", size = 12121912, upload-time = "2025-09-29T23:23:05.042Z" }, + { url = "https://files.pythonhosted.org/packages/53/da/d10013df5e6aaef6b425aa0c32e1fc1f3e431e4bcabd420517dceadce354/pandas-2.3.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:a45c765238e2ed7d7c608fc5bc4a6f88b642f2f01e70c0c23d2224dd21829d86", size = 12712160, upload-time = "2025-09-29T23:23:28.57Z" }, + { url = "https://files.pythonhosted.org/packages/bd/17/e756653095a083d8a37cbd816cb87148debcfcd920129b25f99dd8d04271/pandas-2.3.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c4fc4c21971a1a9f4bdb4c73978c7f7256caa3e62b323f70d6cb80db583350bc", size = 13199233, upload-time = "2025-09-29T23:24:24.876Z" }, + { url = "https://files.pythonhosted.org/packages/ca/05/d01ef80a7a3a12b2f8bbf16daba1e17c98a2f039cbc8e2f77a2c5a63d382/pandas-2.3.3-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d2cefc361461662ac48810cb14365a365ce864afe85ef1f447ff5a1e99ea81c", size = 11814049, upload-time = "2025-09-29T23:27:15.384Z" }, + { url = "https://files.pythonhosted.org/packages/15/b2/0e62f78c0c5ba7e3d2c5945a82456f4fac76c480940f805e0b97fcbc2f65/pandas-2.3.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ee67acbbf05014ea6c763beb097e03cd629961c8a632075eeb34247120abcb4b", size = 12332638, upload-time = "2025-09-29T23:27:51.625Z" }, + { url = "https://files.pythonhosted.org/packages/c5/33/dd70400631b62b9b29c3c93d2feee1d0964dc2bae2e5ad7a6c73a7f25325/pandas-2.3.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:c46467899aaa4da076d5abc11084634e2d197e9460643dd455ac3db5856b24d6", size = 12886834, upload-time = "2025-09-29T23:28:21.289Z" }, + { url = "https://files.pythonhosted.org/packages/d3/18/b5d48f55821228d0d2692b34fd5034bb185e854bdb592e9c640f6290e012/pandas-2.3.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:6253c72c6a1d990a410bc7de641d34053364ef8bcd3126f7e7450125887dffe3", size = 13409925, upload-time = "2025-09-29T23:28:58.261Z" }, + { url = "https://files.pythonhosted.org/packages/f9/88/702bde3ba0a94b8c73a0181e05144b10f13f29ebfc2150c3a79062a8195d/pandas-2.3.3-cp314-cp314t-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:a21d830e78df0a515db2b3d2f5570610f5e6bd2e27749770e8bb7b524b89b450", size = 11634535, upload-time = "2025-09-29T23:30:21.003Z" }, + { url = "https://files.pythonhosted.org/packages/a4/1e/1bac1a839d12e6a82ec6cb40cda2edde64a2013a66963293696bbf31fbbb/pandas-2.3.3-cp314-cp314t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e3ebdb170b5ef78f19bfb71b0dc5dc58775032361fa188e814959b74d726dd5", size = 12121582, upload-time = "2025-09-29T23:30:43.391Z" }, + { url = "https://files.pythonhosted.org/packages/44/91/483de934193e12a3b1d6ae7c8645d083ff88dec75f46e827562f1e4b4da6/pandas-2.3.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:d051c0e065b94b7a3cea50eb1ec32e912cd96dba41647eb24104b6c6c14c5788", size = 12699963, upload-time = "2025-09-29T23:31:10.009Z" }, + { url = "https://files.pythonhosted.org/packages/70/44/5191d2e4026f86a2a109053e194d3ba7a31a2d10a9c2348368c63ed4e85a/pandas-2.3.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:3869faf4bd07b3b66a9f462417d0ca3a9df29a9f6abd5d0d0dbab15dac7abe87", size = 13202175, upload-time = "2025-09-29T23:31:59.173Z" }, +] + +[[package]] +name = "pandocfilters" +version = "1.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/70/6f/3dd4940bbe001c06a65f88e36bad298bc7a0de5036115639926b0c5c0458/pandocfilters-1.5.1.tar.gz", hash = "sha256:002b4a555ee4ebc03f8b66307e287fa492e4a77b4ea14d3f934328297bb4939e", size = 8454, upload-time = "2024-01-18T20:08:13.726Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/af/4fbc8cab944db5d21b7e2a5b8e9211a03a79852b1157e2c102fcc61ac440/pandocfilters-1.5.1-py2.py3-none-any.whl", hash = "sha256:93be382804a9cdb0a7267585f157e5d1731bbe5545a85b268d6f5fe6232de2bc", size = 8663, upload-time = "2024-01-18T20:08:11.28Z" }, +] + +[[package]] +name = "parso" +version = "0.8.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/30/4b/90c937815137d43ce71ba043cd3566221e9df6b9c805f24b5d138c9d40a7/parso-0.8.7.tar.gz", hash = "sha256:eaaac4c9fdd5e9e8852dc778d2d7405897ec510f2a298071453e5e3a07914bb1", size = 401824, upload-time = "2026-05-01T23:13:02.138Z" } +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 = "partd" +version = "1.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "locket", marker = "sys_platform == 'linux'" }, + { name = "toolz", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b2/3a/3f06f34820a31257ddcabdfafc2672c5816be79c7e353b02c1f318daa7d4/partd-1.4.2.tar.gz", hash = "sha256:d022c33afbdc8405c226621b015e8067888173d85f7f5ecebb3cafed9a20f02c", size = 21029, upload-time = "2024-05-06T19:51:41.945Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/71/e7/40fb618334dcdf7c5a316c0e7343c5cd82d3d866edc100d98e29bc945ecd/partd-1.4.2-py3-none-any.whl", hash = "sha256:978e4ac767ec4ba5b86c6eaa52e5a2a3bc748a2ca839e8cc798f1cc6ce6efb0f", size = 18905, upload-time = "2024-05-06T19:51:39.271Z" }, +] + +[[package]] +name = "patsy" +version = "1.0.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/be/44/ed13eccdd0519eff265f44b670d46fbb0ec813e2274932dc1c0e48520f7d/patsy-1.0.2.tar.gz", hash = "sha256:cdc995455f6233e90e22de72c37fcadb344e7586fb83f06696f54d92f8ce74c0", size = 399942, upload-time = "2025-10-20T16:17:37.535Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f1/70/ba4b949bdc0490ab78d545459acd7702b211dfccf7eb89bbc1060f52818d/patsy-1.0.2-py2.py3-none-any.whl", hash = "sha256:37bfddbc58fcf0362febb5f54f10743f8b21dd2aa73dec7e7ef59d1b02ae668a", size = 233301, upload-time = "2025-10-20T16:17:36.563Z" }, +] + +[[package]] +name = "pexpect" +version = "4.9.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ptyprocess", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/42/92/cc564bf6381ff43ce1f4d06852fc19a2f11d180f23dc32d9588bee2f149d/pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f", size = 166450, upload-time = "2023-11-25T09:07:26.339Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/c3/059298687310d527a58bb01f3b1965787ee3b40dce76752eda8b44e9a2c5/pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523", size = 63772, upload-time = "2023-11-25T06:56:14.81Z" }, +] + +[[package]] +name = "pillow" +version = "12.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1c/3d/bb7fca845737cf9d7dbde16ed1843984665ff2e0a518f5db43e77ec540b9/pillow-12.3.0.tar.gz", hash = "sha256:3b8182a766685eaa002637e28b4ec8d6b18819a0c71f579bf0dbaa5830297cce", size = 47025035, upload-time = "2026-07-01T11:56:38.965Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/25/27/ac8f99618ffd3dde21db0f4d4b1d2ab00c0880595bfd17df103f7f39fd0c/pillow-12.3.0-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d9c7f76c0673154f044e9d78c8655fb4213f6ca31a836df48b40fe5d187717b9", size = 6266838, upload-time = "2026-07-01T11:54:11.71Z" }, + { url = "https://files.pythonhosted.org/packages/84/21/a35af28dcc61f37ed850a2d64c65c701321dfbf25085e469d5559360cbbf/pillow-12.3.0-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:78cb2c6865a35ab8ff8b75fd122f6033b92a62c82801110e48ddd6c936a45d91", size = 6940830, upload-time = "2026-07-01T11:54:13.732Z" }, + { url = "https://files.pythonhosted.org/packages/eb/51/8b08617af3ad95e33ce6d7dd2c99ed6c8298f7fb131636303956be022e25/pillow-12.3.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e491916b378fba47242221bb9ead245211b70d504f495d105d17b14a24b4907c", size = 6344383, upload-time = "2026-07-01T11:54:15.756Z" }, + { url = "https://files.pythonhosted.org/packages/1d/72/cf78ac9780bb93c28328f408973845a309d4d145041665f734572ced1b52/pillow-12.3.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0dd2064cbc55aaec028ef5fbb60fa47bb6c3e7918e07ff17935284b227a9d2df", size = 7052934, upload-time = "2026-07-01T11:54:17.721Z" }, + { url = "https://files.pythonhosted.org/packages/9d/ac/31fb64e1e7efb5a4b50cd3d92049ba89ac6e4d8d3bb6a74e15048ca3353e/pillow-12.3.0-cp313-cp313-ios_13_0_arm64_iphoneos.whl", hash = "sha256:21900ce7ba264168cd50defae43cd75d25c833ad4ad6e73ffc5596d12e25ac89", size = 4161684, upload-time = "2026-07-01T11:54:25.934Z" }, + { url = "https://files.pythonhosted.org/packages/87/b4/9805e23d2b4d77842b468513841fda254ee42f0289d25088340e4ff46e2d/pillow-12.3.0-cp313-cp313-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:4e8c2a84d977f50b9daed6eeaf3baef67d00d5d74d932288f02cb94518ee3ace", size = 4255487, upload-time = "2026-07-01T11:54:27.935Z" }, + { url = "https://files.pythonhosted.org/packages/df/39/ecf519435a200c693fe053a6ee4d835b41cf963a4dfc2551c4e637cb2a71/pillow-12.3.0-cp313-cp313-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:ae26d61dfa7a47befdc7572b521024e8745f3d809bd95ca9505a7bba9ef849ec", size = 3696433, upload-time = "2026-07-01T11:54:29.813Z" }, + { url = "https://files.pythonhosted.org/packages/1f/01/e18aff37cb0b4aac47ac90f016d347a49aca667ef97f190b06ac2aabc928/pillow-12.3.0-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f7401aebd7f581d7f83a439d87d474999317ee099218e5ad25d125290990ba65", size = 6263736, upload-time = "2026-07-01T11:54:36.131Z" }, + { url = "https://files.pythonhosted.org/packages/f7/62/de5bdd77d935331f4f802edc11e4d82950f642caad6cb2f949837b8560e2/pillow-12.3.0-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0847a763afefb695bc912d7c131e7e0632d4edc1d8698f58ddabec8e46b8b6d3", size = 6937129, upload-time = "2026-07-01T11:54:38.216Z" }, + { url = "https://files.pythonhosted.org/packages/70/4d/105627a13300c5e0df1d174230b32fd1273062c96f7745fd552b945d1e1d/pillow-12.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:571b9fcb07b97ef3a492028fb3d2dc0993ca23a06138b0315286566d29ef718a", size = 6339562, upload-time = "2026-07-01T11:54:40.354Z" }, + { url = "https://files.pythonhosted.org/packages/6b/1d/f13de01a553988ab895ba1c722e06cf3144d4f57656fd5b81b6d881f1179/pillow-12.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:756c768d0c9c2955feb7a56c37ea24aea2e369f8d36a88da270b6a9f19e62b5e", size = 7049439, upload-time = "2026-07-01T11:54:42.489Z" }, + { url = "https://files.pythonhosted.org/packages/dc/01/001f65b68192f0228cc1dbbc8d2530ab5d58b61037ba0587f946fea607cd/pillow-12.3.0-cp314-cp314-ios_13_0_arm64_iphoneos.whl", hash = "sha256:9cf95fe4d0f84c82d282745d9bb08ad9f926efa00be4697e767b814ce40d4330", size = 4161736, upload-time = "2026-07-01T11:54:51.156Z" }, + { url = "https://files.pythonhosted.org/packages/1a/d2/0219746d0fd16fc8a84498e79452375be3797d3ce4044596ce565164b84f/pillow-12.3.0-cp314-cp314-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:8728f216dcdb6e6d555cf971cb34076139ad74b31fc2c14da4fafc741c5f6217", size = 4255435, upload-time = "2026-07-01T11:54:53.414Z" }, + { url = "https://files.pythonhosted.org/packages/c8/02/8d0bc62ef0302318c46ff2a512822d2610e81c7aa46c9b3abe6cbaca5ad0/pillow-12.3.0-cp314-cp314-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:a45650e8ce7fafffd731db8550230db6b0d306d181a90b67d3e6bca2f1990930", size = 3696262, upload-time = "2026-07-01T11:54:55.739Z" }, + { url = "https://files.pythonhosted.org/packages/b1/9d/8b2c807dbef61a5197c047afe99823787eb66f63daf9fb2432f91d6f0462/pillow-12.3.0-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e9aeb04d6aef139de265b29683e119b638208f88cf73cdd1658aa07221165321", size = 6263757, upload-time = "2026-07-01T11:55:01.778Z" }, + { url = "https://files.pythonhosted.org/packages/5c/44/c85361f65dbe00eea8576ee467c768d25129989efb76e94f205e9ca9bb46/pillow-12.3.0-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:251bf95b67017e27b13d82f5b326234ca62d70f9cf4c2b9032de2358a3b12c7b", size = 6936962, upload-time = "2026-07-01T11:55:03.93Z" }, + { url = "https://files.pythonhosted.org/packages/18/7e/e483414b35800b86b6f08dbbc7803fb5cd52c4d6f897f47d53ea2c7e6f65/pillow-12.3.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:fe3cca2e4e8a592be0f269a1ca4835c25199d9f3ce815c8491048f785b0a0198", size = 6339171, upload-time = "2026-07-01T11:55:05.989Z" }, + { url = "https://files.pythonhosted.org/packages/f0/f4/68c491844841ede6bed70189546b3ee9731cf9f2cbad396faff5e1ccba45/pillow-12.3.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:23aceaa007d6172b02c277f0cd359c79492bbb14f7072b4ede9fbcaf20648130", size = 7048116, upload-time = "2026-07-01T11:55:08.131Z" }, + { url = "https://files.pythonhosted.org/packages/d5/37/25c6692f06927ee973ff18c8d9ee98ad0b4d84ee67a09610c2dd1447958e/pillow-12.3.0-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3edce1d53195db527e0191f84b71d02022de0540bf43a16ed734ed7537b07385", size = 6322855, upload-time = "2026-07-01T11:55:21.613Z" }, + { url = "https://files.pythonhosted.org/packages/cc/91/420637fcb8f1bc11029e403b4538e6694744428d8246118e45719f944556/pillow-12.3.0-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bf16ba1b4d0b6b7c8e534936632270cf70eb00dbe09005bc345b2677b726855c", size = 6989642, upload-time = "2026-07-01T11:55:24.006Z" }, + { url = "https://files.pythonhosted.org/packages/10/08/b94d7811281ccf0d143a1cf768d1c49e1e54af63e7b708ab2ee3eb87face/pillow-12.3.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:24870b09b224f7ae3c39ed07d10e819d06f8720bc551847b1d623832b5b0e28d", size = 6391281, upload-time = "2026-07-01T11:55:26.252Z" }, + { url = "https://files.pythonhosted.org/packages/d2/87/24233f785f55474dc02ce3e739c5528a77e3a862e9333d1dd7a25cc31f70/pillow-12.3.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:30f2aa603c41533cc25c05acd0da21636e84a315768feb631c937177db558931", size = 7096716, upload-time = "2026-07-01T11:55:28.318Z" }, + { url = "https://files.pythonhosted.org/packages/5d/dc/8fdce34ec725a33c81c6ba122b904d6b9024e50ea9ac7bede62fab54506c/pillow-12.3.0-cp315-cp315-ios_13_0_arm64_iphoneos.whl", hash = "sha256:0feb2e9d6ad6c9e3c06effe9d00f3f1e618a6643273576b016f591e9315a7139", size = 4162063, upload-time = "2026-07-01T11:55:37.941Z" }, + { url = "https://files.pythonhosted.org/packages/76/66/2044b9a63d3b84ff048228dfcb7cd9bf0df983e8470971bf7d4c57b693de/pillow-12.3.0-cp315-cp315-ios_13_0_arm64_iphonesimulator.whl", hash = "sha256:9e881fca225083806662a5c43d627d215f258ff43c890f831966c7d7ba9c7402", size = 4255549, upload-time = "2026-07-01T11:55:40.022Z" }, + { url = "https://files.pythonhosted.org/packages/52/7e/1f67e6f4ece6b582ee4b539decbcc9f848dc245a93ed8cd7338bafef72f1/pillow-12.3.0-cp315-cp315-ios_13_0_x86_64_iphonesimulator.whl", hash = "sha256:4998562bf62a445225f22e07c896bb04b35b1b1f2eb6d760584c9c51d7a5f78c", size = 3696331, upload-time = "2026-07-01T11:55:41.98Z" }, + { url = "https://files.pythonhosted.org/packages/0c/08/93fa2e70e30a2d81547e481b6ee2bb9522117221fb1e0ce4b5df70967677/pillow-12.3.0-cp315-cp315-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:28ce87c5ab450a9dd970b52e5aca5fe63ed432d18a2eaddd1979a00a1ba24ace", size = 6273659, upload-time = "2026-07-01T11:55:48.264Z" }, + { url = "https://files.pythonhosted.org/packages/f8/6d/043e96ff814fc31a33077e4cba86082167db520c93632afdf2042febbb0c/pillow-12.3.0-cp315-cp315-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6b02afb9b97f65fbca5f31db6a2a3ba21aa93030225f150fa3f249717e938fb4", size = 6947439, upload-time = "2026-07-01T11:55:50.503Z" }, + { url = "https://files.pythonhosted.org/packages/af/92/ba71d2ee2ac0edf3fa33bd9d5ee9ee080da70b1766f3ca3934f9938ddac9/pillow-12.3.0-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:1182d52bc2d5e5d7d0949503aa7e36d12f42205dc287e4883f407b1988820d39", size = 6353577, upload-time = "2026-07-01T11:55:52.697Z" }, + { url = "https://files.pythonhosted.org/packages/0f/ce/e63064e2122923ff687c8ad792d0d736a7b3920a56a46982e81a7fdd25d6/pillow-12.3.0-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:e795b7eb908249c4e43c7c99fac7c2c75dab0c43566e37db472a355f63693d71", size = 7060394, upload-time = "2026-07-01T11:55:55.149Z" }, + { url = "https://files.pythonhosted.org/packages/13/4f/9e049dfa21af7c22427275720e2490267ba8138120add5c4c574deb69782/pillow-12.3.0-cp315-cp315t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:446c34dcc4324b084a53b705127dc15717b22c5e140ae0a3c38349d4efec071e", size = 6329237, upload-time = "2026-07-01T11:56:08.868Z" }, + { url = "https://files.pythonhosted.org/packages/36/16/cf6eeaae8d0fce8dd390a33437cf68c5d5bd73834a2bc6e2f14efda0ab45/pillow-12.3.0-cp315-cp315t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cf1845d02ad822a369a49f2bb9345b1614744267682e7a03527dc3bf6eea1777", size = 6997047, upload-time = "2026-07-01T11:56:11.379Z" }, + { url = "https://files.pythonhosted.org/packages/1e/69/dbf769bdd55f48bf5733cac28edc6364ffaa072ec9ba336266e4fe66be55/pillow-12.3.0-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:186941b6aef820ad110fb01fb06eb925374dc3a21b17e37ec9a53b250c6fe2d1", size = 6400440, upload-time = "2026-07-01T11:56:13.908Z" }, + { url = "https://files.pythonhosted.org/packages/a0/e1/ffc9cfc2eea0d178da8018e18e959301ad9d6bc9f3edb7181e748a474b97/pillow-12.3.0-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:f13c32a3abd6079a66d9526e18dad9b6d280384d49d7c54040cd57b6424041d9", size = 7105895, upload-time = "2026-07-01T11:56:16.575Z" }, +] + +[[package]] +name = "pims" +version = "0.7" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "imageio", marker = "sys_platform == 'linux'" }, + { name = "numpy", marker = "sys_platform == 'linux'" }, + { name = "packaging", marker = "sys_platform == 'linux'" }, + { name = "slicerator", marker = "sys_platform == 'linux'" }, + { name = "tifffile", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b8/02/5bf3639f5b77e9b183011c08541c5039ba3d04f5316c70312b48a8e003a9/pims-0.7.tar.gz", hash = "sha256:55907a4c301256086d2aa4e34a5361b9109f24e375c2071e1117b9491e82946b", size = 87779, upload-time = "2024-06-10T19:20:42.842Z" } + +[[package]] +name = "platformdirs" +version = "4.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/47/e4501f49c178ae1d9f4a75073fda4204f52647993f075a9db4d14930e0c5/platformdirs-4.10.0.tar.gz", hash = "sha256:31e761a6a0ca04faf7353ea759bdba55652be214725111e5aac52dfa29d4bef7", size = 31224, upload-time = "2026-05-28T03:32:53.587Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/e6/cd9575ac904136b3cbf7aa7ee819ef86eedb7274e46f230e94ea4342e729/platformdirs-4.10.0-py3-none-any.whl", hash = "sha256:fb516cdb12eb0d857d0cd85a7c57cea4d060bee4578d6cf5a14dfdf8cbf8784a", size = 22743, upload-time = "2026-05-28T03:32:52.175Z" }, +] + +[[package]] +name = "pluggy" +version = "1.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f9/e2/3e91f31a7d2b083fe6ef3fa267035b518369d9511ffab804f839851d2779/pluggy-1.6.0.tar.gz", hash = "sha256:7dcc130b76258d33b90f61b658791dede3486c3e6bfb003ee5c9bfb396dd22f3", size = 69412, upload-time = "2025-05-15T12:30:07.975Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/20/4d324d65cc6d9205fabedc306948156824eb9f0ee1633355a8f7ec5c66bf/pluggy-1.6.0-py3-none-any.whl", hash = "sha256:e920276dd6813095e9377c0bc5566d94c932c33b27a3e3945d8389c374dd4746", size = 20538, upload-time = "2025-05-15T12:30:06.134Z" }, +] + +[[package]] +name = "prometheus-client" +version = "0.25.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1b/fb/d9aa83ffe43ce1f19e557c0971d04b90561b0cfd50762aafb01968285553/prometheus_client-0.25.0.tar.gz", hash = "sha256:5e373b75c31afb3c86f1a52fa1ad470c9aace18082d39ec0d2f918d11cc9ba28", size = 86035, upload-time = "2026-04-09T19:53:42.359Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8d/9b/d4b1e644385499c8346fa9b622a3f030dce14cd6ef8a1871c221a17a67e7/prometheus_client-0.25.0-py3-none-any.whl", hash = "sha256:d5aec89e349a6ec230805d0df882f3807f74fd6c1a2fa86864e3c2279059fed1", size = 64154, upload-time = "2026-04-09T19:53:41.324Z" }, +] + +[[package]] +name = "prompt-toolkit" +version = "3.0.52" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "wcwidth", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a1/96/06e01a7b38dce6fe1db213e061a4602dd6032a8a97ef6c1a862537732421/prompt_toolkit-3.0.52.tar.gz", hash = "sha256:28cde192929c8e7321de85de1ddbe736f1375148b02f2e17edd840042b1be855", size = 434198, upload-time = "2025-08-27T15:24:02.057Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/84/03/0d3ce49e2505ae70cf43bc5bb3033955d2fc9f932163e84dc0779cc47f48/prompt_toolkit-3.0.52-py3-none-any.whl", hash = "sha256:9aac639a3bbd33284347de5ad8d68ecc044b91a762dc39b7c21095fcd6a19955", size = 391431, upload-time = "2025-08-27T15:23:59.498Z" }, +] + +[[package]] +name = "psutil" +version = "7.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/aa/c6/d1ddf4abb55e93cebc4f2ed8b5d6dbad109ecb8d63748dd2b20ab5e57ebe/psutil-7.2.2.tar.gz", hash = "sha256:0746f5f8d406af344fd547f1c8daa5f5c33dbc293bb8d6a16d80b4bb88f59372", size = 493740, upload-time = "2026-01-28T18:14:54.428Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/37/d6/246513fbf9fa174af531f28412297dd05241d97a75911ac8febefa1a53c6/psutil-7.2.2-cp313-cp313t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1a571f2330c966c62aeda00dd24620425d4b0cc86881c89861fbc04549e5dc63", size = 181476, upload-time = "2026-01-28T18:15:01.884Z" }, + { url = "https://files.pythonhosted.org/packages/b8/b5/9182c9af3836cca61696dabe4fd1304e17bc56cb62f17439e1154f225dd3/psutil-7.2.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:917e891983ca3c1887b4ef36447b1e0873e70c933afc831c6b6da078ba474312", size = 184062, upload-time = "2026-01-28T18:15:04.436Z" }, + { url = "https://files.pythonhosted.org/packages/d5/2e/e6782744700d6759ebce3043dcfa661fb61e2fb752b91cdeae9af12c2178/psutil-7.2.2-cp314-cp314t-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1fa4ecf83bcdf6e6c8f4449aff98eefb5d0604bf88cb883d7da3d8d2d909546a", size = 182383, upload-time = "2026-01-28T18:15:13.445Z" }, + { url = "https://files.pythonhosted.org/packages/57/49/0a41cefd10cb7505cdc04dab3eacf24c0c2cb158a998b8c7b1d27ee2c1f5/psutil-7.2.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e452c464a02e7dc7822a05d25db4cde564444a67e58539a00f929c51eddda0cf", size = 185210, upload-time = "2026-01-28T18:15:16.002Z" }, + { url = "https://files.pythonhosted.org/packages/b5/70/5d8df3b09e25bce090399cf48e452d25c935ab72dad19406c77f4e828045/psutil-7.2.2-cp36-abi3-manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:076a2d2f923fd4821644f5ba89f059523da90dc9014e85f8e45a5774ca5bc6f9", size = 155560, upload-time = "2026-01-28T18:15:25.976Z" }, + { url = "https://files.pythonhosted.org/packages/63/65/37648c0c158dc222aba51c089eb3bdfa238e621674dc42d48706e639204f/psutil-7.2.2-cp36-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b0726cecd84f9474419d67252add4ac0cd9811b04d61123054b9fb6f57df6e9e", size = 156997, upload-time = "2026-01-28T18:15:27.794Z" }, + { url = "https://files.pythonhosted.org/packages/8e/13/125093eadae863ce03c6ffdbae9929430d116a246ef69866dad94da3bfbc/psutil-7.2.2-cp36-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:fd04ef36b4a6d599bbdb225dd1d3f51e00105f6d48a28f006da7f9822f2606d8", size = 148972, upload-time = "2026-01-28T18:15:29.342Z" }, + { url = "https://files.pythonhosted.org/packages/04/78/0acd37ca84ce3ddffaa92ef0f571e073faa6d8ff1f0559ab1272188ea2be/psutil-7.2.2-cp36-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:b58fabe35e80b264a4e3bb23e6b96f9e45a3df7fb7eed419ac0e5947c61e47cc", size = 148266, upload-time = "2026-01-28T18:15:31.597Z" }, +] + +[[package]] +name = "ptyprocess" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/20/e5/16ff212c1e452235a90aeb09066144d0c5a6a8c0834397e03f5224495c4e/ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220", size = 70762, upload-time = "2020-12-28T15:15:30.155Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/a6/858897256d0deac81a172289110f31629fc4cee19b6f01283303e18c8db3/ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35", size = 13993, upload-time = "2020-12-28T15:15:28.35Z" }, +] + +[[package]] +name = "pulp" +version = "3.3.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/4e/70/69be07a67621ad804d6cf347965eb4e0d7786a97330d99c31d735aaa6c5a/pulp-3.3.2.tar.gz", hash = "sha256:d0904700c207ac11e25e3b1213b70eae1d6fb25faa719d75f3f15054901258c0", size = 16305346, upload-time = "2026-05-25T09:41:26.207Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dd/6e/d674f1dde91c71e2ac19e5e5cf1ee6d5845e3aefecd9c39ed9c4b0c9a696/pulp-3.3.2-py3-none-any.whl", hash = "sha256:631b166f72086971a9597f7a0233ababa99bb8d50a01cd543f7758be5a9f86c0", size = 16391742, upload-time = "2026-05-25T09:41:22.2Z" }, +] + +[[package]] +name = "pure-eval" +version = "0.2.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cd/05/0a34433a064256a578f1783a10da6df098ceaa4a57bbeaa96a6c0352786b/pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42", size = 19752, upload-time = "2024-07-21T12:58:21.801Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8e/37/efad0257dc6e593a18957422533ff0f87ede7c9c6ea010a2177d738fb82f/pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0", size = 11842, upload-time = "2024-07-21T12:58:20.04Z" }, +] + +[[package]] +name = "py-cpuinfo" +version = "9.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/37/a8/d832f7293ebb21690860d2e01d8115e5ff6f2ae8bbdc953f0eb0fa4bd2c7/py-cpuinfo-9.0.0.tar.gz", hash = "sha256:3cdbbf3fac90dc6f118bfd64384f309edeadd902d7c8fb17f02ffa1fc3f49690", size = 104716, upload-time = "2022-10-25T20:38:06.303Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e0/a9/023730ba63db1e494a271cb018dcd361bd2c917ba7004c3e49d5daf795a2/py_cpuinfo-9.0.0-py3-none-any.whl", hash = "sha256:859625bc251f64e21f077d099d4162689c762b5d6a4c3c97553d56241c9674d5", size = 22335, upload-time = "2022-10-25T20:38:27.636Z" }, +] + +[[package]] +name = "pyarrow" +version = "25.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/27/f3/95428098d1fa7d04432fb750eed06b41304c2f6a5d3319985e64db2d9d41/pyarrow-25.0.0.tar.gz", hash = "sha256:d2d697008b5ec06d75952ef260c2e9a8a0f6ccfce24266c04c9c8ade927cb3b4", size = 1199181, upload-time = "2026-07-10T08:29:50.116Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/95/1a/22bfb6597dcdc861fa83c39c06e1457cb56f698940eff42fbb25de30e8e5/pyarrow-25.0.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:fa1482b3da10cac2d4db6e26b81da543e237616af2ef6d466018b31ca586496f", size = 46841966, upload-time = "2026-07-10T08:27:07.685Z" }, + { url = "https://files.pythonhosted.org/packages/55/0e/cd705c042bc4fe7022478db577fcab4abdcfabb9bc37ab7a75556b3fcb2b/pyarrow-25.0.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:5d1dbf24e151042f2fa3c129563f65d66674128868496fb008c4272b16bdf778", size = 50088993, upload-time = "2026-07-10T08:27:14.268Z" }, + { url = "https://files.pythonhosted.org/packages/98/ee/d822e1ee31fe31ec5d057210e0605c950b975dcd8d9a332976cc859a9df8/pyarrow-25.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:20887a762dd61dcc530f93a140840ab1f6aa7836b33270e42d627ab3cf11e537", size = 49941005, upload-time = "2026-07-10T08:27:21.274Z" }, + { url = "https://files.pythonhosted.org/packages/33/1b/207a90cc64619a095eb75a263ae069735f2810056d43c667befd573ec083/pyarrow-25.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:58d1ab556b0cea1c93fdb799b24ad58adb2f2a2788dbce782a94f64ae1a5cc9b", size = 53112355, upload-time = "2026-07-10T08:27:27.911Z" }, + { url = "https://files.pythonhosted.org/packages/53/55/6d1d5f5aff317ec5de9421594679ed51ed828fe7e2ce209327f819d801e4/pyarrow-25.0.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:59516c822d5fd8e544aaa0dfe72f36fed5d4c24ea8390aab1bcd31d7e959c6be", size = 46841701, upload-time = "2026-07-10T08:27:49.741Z" }, + { url = "https://files.pythonhosted.org/packages/b5/5d/f790fb6965ab54c9da0dda7856abc75fd0d7648d865f8d603c111d203a64/pyarrow-25.0.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:6f9dbd83e91c239a1f5ee7ce13f108b5f6c0efbe40a4375260d8f08b43ad05e9", size = 50090118, upload-time = "2026-07-10T08:27:56.051Z" }, + { url = "https://files.pythonhosted.org/packages/0c/8c/faf025357ebf31bc96777f234277aa31e2aeca6dd4ecaa391f29085473c2/pyarrow-25.0.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:18dcc8cc50b5e72eae6fcbfc6c8776c21a007176b27a3cdec5c2f5bcf126708d", size = 49945559, upload-time = "2026-07-10T08:28:01.927Z" }, + { url = "https://files.pythonhosted.org/packages/07/a1/bd051871708ea99a5e0fc711926c26c6f2c6d0130c7aaac8093e34998af6/pyarrow-25.0.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4ec1895a87aa834c3b99b7a1e758747eb8bb57f922b32c0e0fa04afb8d6998b1", size = 53114238, upload-time = "2026-07-10T08:28:08.594Z" }, + { url = "https://files.pythonhosted.org/packages/af/9f/2d81ba89d1e4198d0cb25fe7529de936830fdaec0db926bb52a1ef7080d4/pyarrow-25.0.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:f57a39dbcb416345401c2e77a4373669b45fd111a1768e6cf267a7a0607ff0ec", size = 46905617, upload-time = "2026-07-10T08:28:29.376Z" }, + { url = "https://files.pythonhosted.org/packages/6a/29/0ed312ec800fb536f93783215126cee4b8977dcfeccba6f0f44df0cc87d7/pyarrow-25.0.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:447df764beb07c544f0178a5f6b70ef44b9ecf382b3cdfad4c2d7867353c3887", size = 50119765, upload-time = "2026-07-10T08:28:35.826Z" }, + { url = "https://files.pythonhosted.org/packages/ca/88/cab5063ba0c4d46a9f6b4b7eb1c9029dc0302d65cd5ab3510c949a386568/pyarrow-25.0.0-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ac5dfeee59f9ceb4d45ba76e83b026c38c24334135bb329d8274baa49cec3c62", size = 50027563, upload-time = "2026-07-10T08:28:43.848Z" }, + { url = "https://files.pythonhosted.org/packages/7b/fb/4d24f1b7fe2e042dc4ef315ef75e4e702d8e46fe10c37e63caff00502b03/pyarrow-25.0.0-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:f0f100dacf2c0f400601664a79d1a907ced4740514bb2b00917341038e2ce76f", size = 53162437, upload-time = "2026-07-10T08:28:52.819Z" }, + { url = "https://files.pythonhosted.org/packages/8a/18/b37fc31a69cff4bdfb8842683def5612f551b93fff6f44375e4a4a6a5535/pyarrow-25.0.0-cp314-cp314t-manylinux_2_28_aarch64.whl", hash = "sha256:b8af8ceedf0c9c160fd2b63440f2d205b9404db85866c1217bfea601de7cfb50", size = 46912304, upload-time = "2026-07-10T08:29:14.656Z" }, + { url = "https://files.pythonhosted.org/packages/32/35/5cae19ba72493e5598022468b56f6a5571f399f485bf412f157356476caa/pyarrow-25.0.0-cp314-cp314t-manylinux_2_28_x86_64.whl", hash = "sha256:c70a5fd9a82bd1a702fd482bdc62d38dcb672fb2b449b1d7c0d7d1f4be7b7bfe", size = 50073652, upload-time = "2026-07-10T08:29:22.467Z" }, + { url = "https://files.pythonhosted.org/packages/2e/a5/ddd508424bdfd5e6945765e9e2ffc687e2f6115972badc8ecf423076c407/pyarrow-25.0.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0490a7f8b38ffe11cc26526b50c65d111cb54ddac3717cec781806793f1244dc", size = 50058654, upload-time = "2026-07-10T08:29:29.689Z" }, + { url = "https://files.pythonhosted.org/packages/5f/a4/324d0db203ff5eebe8694ec2d6ec5a23f9aaa5d02e5b8c692914c518c33c/pyarrow-25.0.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:e83916bbcf380866b4e14255850b33323ff678dc9758411d0409cdd2523880b0", size = 53140153, upload-time = "2026-07-10T08:29:36.041Z" }, +] + +[[package]] +name = "pyavm" +version = "0.9.9" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/87/ac/a925d36dd37fc37f89afccc1f62ffa03b7344c8e4ff7850be7879b4497e6/pyavm-0.9.9.tar.gz", hash = "sha256:bc0f605d957c1fd6d7765523fcba8b9a72377ac6c51461c2a838fe44600bcd9a", size = 220572, upload-time = "2026-03-12T09:54:50.969Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/62/ab/ba8d2b40aee05cd986807d58ee324369eb16248b717a08b51eee977f8d33/pyavm-0.9.9-py3-none-any.whl", hash = "sha256:8bba0ee9645a8a9f215af9ceea67b494a6ee1fe380cebdc00ba99d781539ad76", size = 379786, upload-time = "2026-03-12T09:54:49.455Z" }, +] + +[[package]] +name = "pybind11" +version = "3.0.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/cc/f0/35145a3c3baffeef55d4b8324caa33abaa8fa56ab345ecd4b2211d09163e/pybind11-3.0.4.tar.gz", hash = "sha256:3286b59c8a774b9ee650169302dd5a4eedc30a8617905a0560dd8ee44775130c", size = 589533, upload-time = "2026-04-19T03:08:15.925Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b3/06/c3a23c9a0263b136c519f033a58d4641e73065fefc7754e9667ec206d992/pybind11-3.0.4-py3-none-any.whl", hash = "sha256:961720ee652da51d531b7b2451a6bd2bc042b0106e6d9baa48ecb7d58034ce63", size = 314166, upload-time = "2026-04-19T03:08:14.091Z" }, +] + +[[package]] +name = "pybtex" +version = "0.26.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "latexcodec", marker = "sys_platform == 'linux'" }, + { name = "pyyaml", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/4d/f5/f30da9c93f0fa6d619332b2f69597219b625f35780473a05164a9981fd9a/pybtex-0.26.1.tar.gz", hash = "sha256:2e5543bea424e60e9e42eef70bff597be48649d8f68ba061a7a092b2477d5464", size = 692991, upload-time = "2026-04-03T13:05:39.014Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/44/f6/775eb92e865b28cdb4ad1f2bed7a5446197516f76b58a950faa3be3fd08d/pybtex-0.26.1-py3-none-any.whl", hash = "sha256:e26c0412cc54f5f21b2a6d9d175762a2d2af9ccf3a8f651cdb89ec035db77aa1", size = 126134, upload-time = "2026-04-03T13:05:40.623Z" }, +] + +[[package]] +name = "pybtex-docutils" +version = "1.0.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "docutils", marker = "sys_platform == 'linux'" }, + { name = "pybtex", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7e/84/796ea94d26188a853660f81bded39f8de4cfe595130aef0dea1088705a11/pybtex-docutils-1.0.3.tar.gz", hash = "sha256:3a7ebdf92b593e00e8c1c538aa9a20bca5d92d84231124715acc964d51d93c6b", size = 18348, upload-time = "2023-08-22T18:47:54.833Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/11/b1/ce1f4596211efb5410e178a803f08e59b20bedb66837dcf41e21c54f9ec1/pybtex_docutils-1.0.3-py3-none-any.whl", hash = "sha256:8fd290d2ae48e32fcb54d86b0efb8d573198653c7e2447d5bec5847095f430b9", size = 6385, upload-time = "2023-08-22T06:43:20.513Z" }, +] + +[[package]] +name = "pyccl" +version = "3.3.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", marker = "sys_platform == 'linux'" }, + { name = "packaging", marker = "sys_platform == 'linux'" }, + { name = "pyyaml", marker = "sys_platform == 'linux'" }, + { name = "scipy", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/57/40/ff357d61a20c21420f1fe7417ca6d889be2e07a67b3564775aeaf6c3f366/pyccl-3.3.4.tar.gz", hash = "sha256:a9d22557354fd161df909e8f4f199e4f1c434c080fd6cddb2246609ddbd70e7c", size = 16783719, upload-time = "2026-05-14T16:26:27.327Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/80/1db2504f21eec9b481e1fe298b05deb96e108d06ddb1828494d16d32bf1c/pyccl-3.3.4-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0229c863acea5c3fc6748dc7c40611dd529709c9d26e3679ebdbc467511ef993", size = 3707759, upload-time = "2026-05-14T16:26:16.779Z" }, + { url = "https://files.pythonhosted.org/packages/1a/91/3000c5fc1ee8379636dc894946a3633baae74a3f1cce3c2d402e8991a0b5/pyccl-3.3.4-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:685d528a096251a2eb5d569e611b5a2e68cc3a4a0134734b16ac4e73a07e7f27", size = 3706950, upload-time = "2026-05-14T16:26:20.394Z" }, + { url = "https://files.pythonhosted.org/packages/e5/66/803e8196149d8d8a75319b4f20268210b1e1b31b3158a1143ce99cacf953/pyccl-3.3.4-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:601b687b50b506f7f5775475d79fa55d221616a827a96ad5d6d68bf7a15de9b9", size = 3706955, upload-time = "2026-05-14T16:26:25.302Z" }, +] + +[[package]] +name = "pycparser" +version = "3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1b/7d/92392ff7815c21062bea51aa7b87d45576f649f16458d78b7cf94b9ab2e6/pycparser-3.0.tar.gz", hash = "sha256:600f49d217304a5902ac3c37e1281c9fe94e4d0489de643a9504c5cdfdfc6b29", size = 103492, upload-time = "2026-01-21T14:26:51.89Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/c3/44f3fbbfa403ea2a7c779186dc20772604442dde72947e7d01069cbe98e3/pycparser-3.0-py3-none-any.whl", hash = "sha256:b727414169a36b7d524c1c3e31839a521725078d7b2ff038656844266160a992", size = 48172, upload-time = "2026-01-21T14:26:50.693Z" }, +] + +[[package]] +name = "pydantic" +version = "2.13.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "annotated-types", marker = "sys_platform == 'linux'" }, + { name = "pydantic-core", marker = "sys_platform == 'linux'" }, + { name = "typing-extensions", marker = "sys_platform == 'linux'" }, + { name = "typing-inspection", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/18/a5/b60d21ac674192f8ab0ba4e9fd860690f9b4a6e51ca5df118733b487d8d6/pydantic-2.13.4.tar.gz", hash = "sha256:c40756b57adaa8b1efeeced5c196f3f3b7c435f90e84ea7f443901bec8099ef6", size = 844775, upload-time = "2026-05-06T13:43:05.343Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fd/7b/122376b1fd3c62c1ed9dc80c931ace4844b3c55407b6fb2d199377c9736f/pydantic-2.13.4-py3-none-any.whl", hash = "sha256:45a282cde31d808236fd7ea9d919b128653c8b38b393d1c4ab335c62924d9aba", size = 472262, upload-time = "2026-05-06T13:43:02.641Z" }, +] + +[[package]] +name = "pydantic-core" +version = "2.46.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9d/56/921726b776ace8d8f5db44c4ef961006580d91dc52b803c489fafd1aa249/pydantic_core-2.46.4.tar.gz", hash = "sha256:62f875393d7f270851f20523dd2e29f082bcc82292d66db2b64ea71f64b6e1c1", size = 471464, upload-time = "2026-05-06T13:37:06.98Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8e/bc/f47d1ff9cbb1620e1b5b697eef06010035735f07820180e74178226b27b3/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8233f2947cf85404441fd7e0085f53b10c93e0ee78611099b5c7237e36aacbf7", size = 1975742, upload-time = "2026-05-06T13:37:09.448Z" }, + { url = "https://files.pythonhosted.org/packages/5b/11/9b9a5b0306345664a2da6410877af6e8082481b5884b3ddd78d47c6013ce/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3a233125ac121aa3ffba9a2b59edfc4a985a76092dc8279586ab4b71390875e7", size = 2052418, upload-time = "2026-05-06T13:37:38.234Z" }, + { url = "https://files.pythonhosted.org/packages/f1/b7/a65fec226f5d78fc39f4a13c4cc0c768c22b113438f60c14adc9d2865038/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5b712b53160b79a5850310b912a5ef8e57e56947c8ad690c227f5c9d7e561712", size = 2232274, upload-time = "2026-05-06T13:38:27.753Z" }, + { url = "https://files.pythonhosted.org/packages/68/f0/92039db98b907ef49269a8271f67db9cb78ae2fc68062ef7e4e77adb5f61/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9401557acd873c3a7f3eb9383edef8ac4968f9510e340f4808d427e75667e7b4", size = 2309940, upload-time = "2026-05-06T13:38:05.353Z" }, + { url = "https://files.pythonhosted.org/packages/5f/97/2aab507d3d00ca626e8e57c1eac6a79e4e5fbcc63eb99733ff55d1717f65/pydantic_core-2.46.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:926c9541b14b12b1681dca8a0b75feb510b06c6341b70a8e500c2fdcff837cce", size = 2094516, upload-time = "2026-05-06T13:39:10.577Z" }, + { url = "https://files.pythonhosted.org/packages/22/37/a8aca44d40d737dde2bc05b3c6c07dff0de07ce6f82e9f3167aeaf4d5dea/pydantic_core-2.46.4-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:56cb4851bcaf3d117eddcef4fe66afd750a50274b0da8e22be256d10e5611987", size = 2136854, upload-time = "2026-05-06T13:40:22.59Z" }, + { url = "https://files.pythonhosted.org/packages/24/99/fcef1b79238c06a8cbec70819ac722ba76e02bc8ada9b0fd66eba40da01b/pydantic_core-2.46.4-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:c68fcd102d71ea85c5b2dfac3f4f8476eff42a9e078fd5faefff6d145063536b", size = 2180306, upload-time = "2026-05-06T13:40:10.666Z" }, + { url = "https://files.pythonhosted.org/packages/ae/6c/fc44000918855b42779d007ae63b0532794739027b2f417321cddbc44f6a/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:b2f69dec1725e79a012d920df1707de5caf7ed5e08f3be4435e25803efc47458", size = 2190044, upload-time = "2026-05-06T13:40:43.231Z" }, + { url = "https://files.pythonhosted.org/packages/6b/65/d9cadc9f1920d7a127ad2edba16c1db7916e59719285cd6c94600b0080ba/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:8d0820e8192167f80d88d64038e609c31452eeca865b4e1d9950a27a4609b00b", size = 2329133, upload-time = "2026-05-06T13:39:57.365Z" }, + { url = "https://files.pythonhosted.org/packages/d0/cf/c873d91679f3a30bcf5e7ac280ce5573483e72295307685120d0d5ad3416/pydantic_core-2.46.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fbdb89b3e1c94a30cc5edfce477c6e6a5dc4d8f84665b455c27582f211a1c72c", size = 2374464, upload-time = "2026-05-06T13:38:06.976Z" }, + { url = "https://files.pythonhosted.org/packages/03/d5/fd02da45b659668b05923b17ba3a0100a0a3d5541e3bd8fcc4ecb711309e/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f027324c56cd5406ca49c124b0db10e56c69064fec039acc571c29020cc87c76", size = 1976802, upload-time = "2026-05-06T13:37:35.113Z" }, + { url = "https://files.pythonhosted.org/packages/21/f2/95727e1368be3d3ed485eaab7adbd7dda408f33f7a36e8b48e0144002b91/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e739fee756ba1010f8bcccb534252e85a35fe45ae92c295a06059ce58b74ccd3", size = 2052446, upload-time = "2026-05-06T13:37:12.313Z" }, + { url = "https://files.pythonhosted.org/packages/9c/86/5d99feea3f77c7234b8718075b23db11532773c1a0dbd9b9490215dc2eeb/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9d56801be94b86a9da183e5f3766e6310752b99ff647e38b09a9500d88e46e76", size = 2232757, upload-time = "2026-05-06T13:39:01.149Z" }, + { url = "https://files.pythonhosted.org/packages/d2/3a/508ac615935ef7588cf6d9e9b91309fdc2da751af865e02a9098de88258c/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2412e734dcb48da14d4e4006b82b46b74f2518b8a26ee7e58c6844a6cd6d03c4", size = 2309275, upload-time = "2026-05-06T13:37:41.406Z" }, + { url = "https://files.pythonhosted.org/packages/07/f8/41db9de19d7987d6b04715a02b3b40aea467000275d9d758ffaa31af7d50/pydantic_core-2.46.4-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9551187363ffc0de2a00b2e47c25aeaeb1020b69b668762966df15fc5659dd5a", size = 2094467, upload-time = "2026-05-06T13:39:18.847Z" }, + { url = "https://files.pythonhosted.org/packages/2c/e2/f35033184cb11d0052daf4416e8e10a502ea2ac006fc4f459aee872727d1/pydantic_core-2.46.4-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:0186750b482eefa11d7f435892b09c5c606193ef3375bcf94aa00ae6bfb66262", size = 2134417, upload-time = "2026-05-06T13:40:17.944Z" }, + { url = "https://files.pythonhosted.org/packages/7e/7b/6ceeb1cc90e193862f444ebe373d8fdf613f0a82572dde03fb10734c6c71/pydantic_core-2.46.4-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:5855698a4856556d86e8e6cd8434bc3ac0314ee8e12089ae0e143f64c6256e4e", size = 2179782, upload-time = "2026-05-06T13:40:32.618Z" }, + { url = "https://files.pythonhosted.org/packages/5a/f2/c8d7773ede6af08036423a00ae0ceffce266c3c52a096c435d68c896083f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:cbaf13819775b7f769bf4a1f066cb6df7a28d4480081a589828ef190226881cd", size = 2188782, upload-time = "2026-05-06T13:36:51.018Z" }, + { url = "https://files.pythonhosted.org/packages/59/31/0c864784e31f09f05cdd87606f08923b9c9e7f6e51dd27f20f62f975ce9f/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:633147d34cf4550417f12e2b1a0383973bdf5cdfde212cb09e9a581cf10820be", size = 2328334, upload-time = "2026-05-06T13:40:37.764Z" }, + { url = "https://files.pythonhosted.org/packages/c2/eb/4f6c8a41efa30baa755590f4141abf3a8c370fab610915733e74134a7270/pydantic_core-2.46.4-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:82cf5301172168103724d49a1444d3378cb20cdee30b116a1bd6031236298a5d", size = 2372986, upload-time = "2026-05-06T13:39:34.152Z" }, + { url = "https://files.pythonhosted.org/packages/95/30/5211a831ae054928054b2f79731661087a2bc5c01e825c672b3a4a8f1b3e/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ce5c1d2a8b27468f433ca974829c44060b8097eedc39933e3c206a90ee49c4a9", size = 1978926, upload-time = "2026-05-06T13:37:39.933Z" }, + { url = "https://files.pythonhosted.org/packages/57/e9/689668733b1eb67adeef047db3c2e8788fcf65a7fd9c9e2b46b7744fe245/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:7283d57845ecf5a163403eb0702dfc220cc4fbdd18919cb5ccea4f95ee1cdab4", size = 2046785, upload-time = "2026-05-06T13:38:01.995Z" }, + { url = "https://files.pythonhosted.org/packages/60/d9/6715260422ff50a2109878fd24d948a6c3446bb2664f34ee78cd972b3acd/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8daafc69c93ee8a0204506a3b6b30f586ef54028f52aeeeb5c4cfc5184fd5914", size = 2228733, upload-time = "2026-05-06T13:40:50.371Z" }, + { url = "https://files.pythonhosted.org/packages/18/ae/fdb2f64316afca925640f8e70bb1a564b0ec2721c1389e25b8eb4bf9a299/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cd2213145bcc2ba85884d0ac63d222fece9209678f77b9b4d76f054c561adb28", size = 2307534, upload-time = "2026-05-06T13:37:21.531Z" }, + { url = "https://files.pythonhosted.org/packages/89/1d/8eff589b45bb8190a9d12c49cfad0f176a5cbd1534908a6b5125e2886239/pydantic_core-2.46.4-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7a5f930472650a82629163023e630d160863fce524c616f4e5186e5de9d9a49b", size = 2099732, upload-time = "2026-05-06T13:39:31.942Z" }, + { url = "https://files.pythonhosted.org/packages/06/d5/ee5a3366637fee41dee51a1fc91562dcf12ddbc68fda34e6b253da2324bb/pydantic_core-2.46.4-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:c1b3f518abeca3aa13c712fd202306e145abf59a18b094a6bafb2d2bbf59192c", size = 2129627, upload-time = "2026-05-06T13:37:25.033Z" }, + { url = "https://files.pythonhosted.org/packages/94/33/2414be571d2c6a6c4d08be21f9292b6d3fdb08949a97b6dfe985017821db/pydantic_core-2.46.4-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1a7dd0b3ee80d90150e3495a3a13ac34dbcbfd4f012996a6a1d8900e91b5c0fb", size = 2179141, upload-time = "2026-05-06T13:37:14.046Z" }, + { url = "https://files.pythonhosted.org/packages/7b/79/7daa95be995be0eecc4cf75064cb33f9bbbfe3fe0158caf2f0d4a996a5c7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_aarch64.whl", hash = "sha256:3fb702cd90b0446a3a1c5e470bfa0dd23c0233b676a9099ddcc964fa6ca13898", size = 2184325, upload-time = "2026-05-06T13:36:53.615Z" }, + { url = "https://files.pythonhosted.org/packages/9f/cb/d0a382f5c0de8a222dc61c65348e0ce831b1f68e0a018450d31c2cace3a5/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_armv7l.whl", hash = "sha256:b8458003118a712e66286df6a707db01c52c0f52f7db8e4a38f0da1d3b94fc4e", size = 2323990, upload-time = "2026-05-06T13:40:29.971Z" }, + { url = "https://files.pythonhosted.org/packages/05/db/d9ba624cc4a5aced1598e88c04fdbd8310c8a69b9d38b9a3d39ce3a61ed7/pydantic_core-2.46.4-cp314-cp314-musllinux_1_1_x86_64.whl", hash = "sha256:372429a130e469c9cd698925ce5fc50940b7a1336b0d82038e63d5bbc4edc519", size = 2369978, upload-time = "2026-05-06T13:37:23.027Z" }, + { url = "https://files.pythonhosted.org/packages/e8/e7/1955d28d1afc56dd4b3ad7cc0cf39df1b9852964cf16e5d13912756d6d6b/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29c61fc04a3d840155ff08e475a04809278972fe6aef51e2720554e96367e34b", size = 1974605, upload-time = "2026-05-06T13:37:32.029Z" }, + { url = "https://files.pythonhosted.org/packages/93/e2/3fedbf0ba7a22850e6e9fd78117f1c0f10f950182344d8a6c535d468fdd8/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c50f2528cf200c5eed56faf3f4e22fcd5f38c157a8b78576e6ba3168ec35f000", size = 2030777, upload-time = "2026-05-06T13:38:55.239Z" }, + { url = "https://files.pythonhosted.org/packages/f8/61/46be275fcaaba0b4f5b9669dd852267ce1ff616592dccf7a7845588df091/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0cbe8b01f948de4286c74cdd6c667aceb38f5c1e26f0693b3983d9d74887c65e", size = 2236641, upload-time = "2026-05-06T13:37:08.096Z" }, + { url = "https://files.pythonhosted.org/packages/60/db/12e93e46a8bac9988be3c016860f83293daea8c716c029c9ace279036f2f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:617d7e2ca7dcb8c5cf6bcb8c59b8832c94b36196bbf1cbd1bfb56ed341905edd", size = 2286404, upload-time = "2026-05-06T13:40:20.221Z" }, + { url = "https://files.pythonhosted.org/packages/e2/4a/4d8b19008f38d31c53b8219cfedc2e3d5de5fe99d90076b7e767de29274f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7027560ee92211647d0d34e3f7cd6f50da56399d26a9c8ad0da286d3869a53f3", size = 2109219, upload-time = "2026-05-06T13:38:12.153Z" }, + { url = "https://files.pythonhosted.org/packages/88/70/3cbc40978fefb7bb09c6708d40d4ad1a5d70fd7213c3d17f971de868ec1f/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:f99626688942fb746e545232e7726926f3be91b5975f8b55327665fafda991c7", size = 2110594, upload-time = "2026-05-06T13:40:02.971Z" }, + { url = "https://files.pythonhosted.org/packages/9d/20/b8d36736216e29491125531685b2f9e61aa5b4b2599893f8268551da3338/pydantic_core-2.46.4-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:fc3e9034a63de20e15e8ade85358bc6efc614008cab72898b4b4952bea0509ff", size = 2159542, upload-time = "2026-05-06T13:39:27.506Z" }, + { url = "https://files.pythonhosted.org/packages/1d/a2/367df868eb584dacf6bf82a389272406d7178e301c4ac82545ab98bc2dd9/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_aarch64.whl", hash = "sha256:97e7cf2be5c77b7d1a9713a05605d49460d02c6078d38d8bef3cbe323c548424", size = 2168146, upload-time = "2026-05-06T13:38:31.93Z" }, + { url = "https://files.pythonhosted.org/packages/c1/b8/4460f77f7e201893f649a29ab355dddd3beee8a97bcb1a320db414f9a06e/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_armv7l.whl", hash = "sha256:3bf92c5d0e00fefaab325a4d27828fe6b6e2a21848686b5b60d2d9eeb09d76c6", size = 2306309, upload-time = "2026-05-06T13:37:44.717Z" }, + { url = "https://files.pythonhosted.org/packages/64/c4/be2639293acd87dc8ddbcec41a73cee9b2ebf996fe6d892a1a74e88ad3f7/pydantic_core-2.46.4-cp314-cp314t-musllinux_1_1_x86_64.whl", hash = "sha256:3ecbc122d18468d06ca279dc26a8c2e2d5acb10943bb35e36ae92096dc3b5565", size = 2369736, upload-time = "2026-05-06T13:37:05.645Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ca/eac61596cdeb4d7e174d3dc0bd8a6238f14f75f97a24e7b7db4c7e7340a0/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ad785e92e6dc634c21555edc8bd6b64957ab844541bcb96a1366c202951ae526", size = 1990696, upload-time = "2026-05-06T13:38:34.717Z" }, + { url = "https://files.pythonhosted.org/packages/fa/c3/7c8b240552251faf6b3a957db200fcfbbcec36763c050428b601e0c9b83b/pydantic_core-2.46.4-graalpy312-graalpy250_312_native-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00c603d540afdd6b80eb39f078f33ebd46211f02f33e34a32d9f053bba711de0", size = 2147590, upload-time = "2026-05-06T13:39:29.883Z" }, +] + +[[package]] +name = "pyerfa" +version = "2.0.1.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/71/39/63cc8291b0cf324ae710df41527faf7d331bce573899199d926b3e492260/pyerfa-2.0.1.5.tar.gz", hash = "sha256:17d6b24fe4846c65d5e7d8c362dcb08199dc63b30a236aedd73875cc83e1f6c0", size = 818430, upload-time = "2024-11-11T15:22:30.852Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cb/96/b6210fc624123c8ae13e1eecb68fb75e3f3adff216d95eee1c7b05843e3e/pyerfa-2.0.1.5-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b0603e8e1b839327d586c8a627cdc634b795e18b007d84f0cda5500a0908254e", size = 692794, upload-time = "2024-11-11T15:22:19.429Z" }, + { url = "https://files.pythonhosted.org/packages/e5/e0/050018d855d26d3c0b4a7d1b2ed692be758ce276d8289e2a2b44ba1014a5/pyerfa-2.0.1.5-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e43c7194e3242083f2350b46c09fd4bf8ba1bcc0ebd1460b98fc47fe2389906", size = 738711, upload-time = "2024-11-11T15:22:20.661Z" }, + { url = "https://files.pythonhosted.org/packages/b9/f5/ff91ee77308793ae32fa1e1de95e9edd4551456dd888b4e87c5938657ca5/pyerfa-2.0.1.5-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:07b80cd70701f5d066b1ac8cce406682cfcd667a1186ec7d7ade597239a6021d", size = 722966, upload-time = "2024-11-11T15:22:21.905Z" }, +] + +[[package]] +name = "pygments" +version = "2.20.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, +] + +[[package]] +name = "pymaster" +version = "2.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ducc0", marker = "sys_platform == 'linux'" }, + { name = "healpy", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/95/45/470858f2a6a3f5133955bb87aed978a5e921d4052aea1c19718e6b72f0ae/pymaster-2.6.tar.gz", hash = "sha256:056a09bc8631cf338e93ef14d8c70272ad9554ef10498d919e920994531c57a2", size = 33707181, upload-time = "2025-12-16T09:18:28.905Z" } + +[[package]] +name = "pyopenssl" +version = "26.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cryptography", marker = "sys_platform == 'linux'" }, + { name = "typing-extensions", marker = "python_full_version < '3.13' and sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/74/b7/da07bae88f5a9506b4def6f2f4903cf4c3b8831e560dba8fa18ca08f758f/pyopenssl-26.3.0.tar.gz", hash = "sha256:589de7fae1c9ea670d18422ed00fc04da787bbde8e1454aea872aa57b49ad341", size = 182024, upload-time = "2026-06-12T20:28:07.458Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/54/18/1dd71c9b43192ab83f1d531ad6002dc81108ac36c475f79fb7a295abe2f4/pyopenssl-26.3.0-py3-none-any.whl", hash = "sha256:46367f8f66b92271e6d218da9c87607e1ef5a0bc5c8dea5bb3db82f395c385a3", size = 56008, upload-time = "2026-06-12T20:28:05.999Z" }, +] + +[[package]] +name = "pyparsing" +version = "3.3.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f3/91/9c6ee907786a473bf81c5f53cf703ba0957b23ab84c264080fb5a450416f/pyparsing-3.3.2.tar.gz", hash = "sha256:c777f4d763f140633dcb6d8a3eda953bf7a214dc4eff598413c070bcdc117cbc", size = 6851574, upload-time = "2026-01-21T03:57:59.36Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/10/bd/c038d7cc38edc1aa5bf91ab8068b63d4308c66c4c8bb3cbba7dfbc049f9c/pyparsing-3.3.2-py3-none-any.whl", hash = "sha256:850ba148bd908d7e2411587e247a1e4f0327839c40e2e5e6d05a007ecc69911d", size = 122781, upload-time = "2026-01-21T03:57:55.912Z" }, +] + +[[package]] +name = "pytest" +version = "9.1.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "iniconfig", marker = "sys_platform == 'linux'" }, + { name = "packaging", marker = "sys_platform == 'linux'" }, + { name = "pluggy", marker = "sys_platform == 'linux'" }, + { name = "pygments", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/e4/47/b9efed96c114afcfa3c9d3fe98a76a1d14c74a9e266d397cf6eb64be5e01/pytest-9.1.1.tar.gz", hash = "sha256:1088fbde8f2b49d95a549a195707afa7a76a3ce9bcadc26b6d71f0ffda5fe313", size = 1636369, upload-time = "2026-06-19T10:58:32.857Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/24/25/1de2678b631f5a49215c6c96fff41ba892b0a34df68d6d80292b1b48aa7f/pytest-9.1.1-py3-none-any.whl", hash = "sha256:37a86b45efb9a47a61a36449063e8e18d0cab3161329fc099eb21783169c4f0c", size = 386536, upload-time = "2026-06-19T10:58:31.347Z" }, +] + +[[package]] +name = "pytest-cov" +version = "7.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "coverage", marker = "sys_platform == 'linux'" }, + { name = "pluggy", marker = "sys_platform == 'linux'" }, + { name = "pytest", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b1/51/a849f96e117386044471c8ec2bd6cfebacda285da9525c9106aeb28da671/pytest_cov-7.1.0.tar.gz", hash = "sha256:30674f2b5f6351aa09702a9c8c364f6a01c27aae0c1366ae8016160d1efc56b2", size = 55592, upload-time = "2026-03-21T20:11:16.284Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9d/7a/d968e294073affff457b041c2be9868a40c1c71f4a35fcc1e45e5493067b/pytest_cov-7.1.0-py3-none-any.whl", hash = "sha256:a0461110b7865f9a271aa1b51e516c9a95de9d696734a2f71e3e78f46e1d4678", size = 22876, upload-time = "2026-03-21T20:11:14.438Z" }, +] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } +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 = "python-json-logger" +version = "4.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f7/ff/3cc9165fd44106973cd7ac9facb674a65ed853494592541d339bdc9a30eb/python_json_logger-4.1.0.tar.gz", hash = "sha256:b396b9e3ed782b09ff9d6e4f1683d46c83ad0d35d2e407c09a9ebbf038f88195", size = 17573, upload-time = "2026-03-29T04:39:56.805Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/be/0631a861af4d1c875f096c07d34e9a63639560a717130e7a87cbc82b7e3f/python_json_logger-4.1.0-py3-none-any.whl", hash = "sha256:132994765cf75bf44554be9aa49b06ef2345d23661a96720262716438141b6b2", size = 15021, upload-time = "2026-03-29T04:39:55.266Z" }, +] + +[[package]] +name = "pytz" +version = "2026.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ff/46/dd499ec9038423421951e4fad73051febaa13d2df82b4064f87af8b8c0c3/pytz-2026.2.tar.gz", hash = "sha256:0e60b47b29f21574376f218fe21abc009894a2321ea16c6754f3cad6eb7cdd6a", size = 320861, upload-time = "2026-05-04T01:35:29.667Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ec/dd/96da98f892250475bdf2328112d7468abdd4acc7b902b6af23f4ed958ea0/pytz-2026.2-py2.py3-none-any.whl", hash = "sha256:04156e608bee23d3792fd45c94ae47fae1036688e75032eea2e3bf0323d1f126", size = 510141, upload-time = "2026-05-04T01:35:27.408Z" }, +] + +[[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/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/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/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/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" }, +] + +[[package]] +name = "pyzmq" +version = "27.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cffi", marker = "implementation_name == 'pypy' and sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/04/0b/3c9baedbdf613ecaa7aa07027780b8867f57b6293b6ee50de316c9f3222b/pyzmq-27.1.0.tar.gz", hash = "sha256:ac0765e3d44455adb6ddbf4417dcce460fc40a05978c08efdf2948072f6db540", size = 281750, upload-time = "2025-09-08T23:10:18.157Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e8/5e/c3c49fdd0f535ef45eefcc16934648e9e59dace4a37ee88fc53f6cd8e641/pyzmq-27.1.0-cp312-abi3-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1c179799b118e554b66da67d88ed66cd37a169f1f23b5d9f0a231b4e8d44a113", size = 895645, upload-time = "2025-09-08T23:08:05.301Z" }, + { url = "https://files.pythonhosted.org/packages/f8/e5/b0b2504cb4e903a74dcf1ebae157f9e20ebb6ea76095f6cfffea28c42ecd/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3837439b7f99e60312f0c926a6ad437b067356dc2bc2ec96eb395fd0fe804233", size = 652574, upload-time = "2025-09-08T23:08:06.828Z" }, + { url = "https://files.pythonhosted.org/packages/f8/9b/c108cdb55560eaf253f0cbdb61b29971e9fb34d9c3499b0e96e4e60ed8a5/pyzmq-27.1.0-cp312-abi3-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:43ad9a73e3da1fab5b0e7e13402f0b2fb934ae1c876c51d0afff0e7c052eca31", size = 840995, upload-time = "2025-09-08T23:08:08.396Z" }, + { url = "https://files.pythonhosted.org/packages/c2/bb/b79798ca177b9eb0825b4c9998c6af8cd2a7f15a6a1a4272c1d1a21d382f/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:0de3028d69d4cdc475bfe47a6128eb38d8bc0e8f4d69646adfbcd840facbac28", size = 1642070, upload-time = "2025-09-08T23:08:09.989Z" }, + { url = "https://files.pythonhosted.org/packages/9c/80/2df2e7977c4ede24c79ae39dcef3899bfc5f34d1ca7a5b24f182c9b7a9ca/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_i686.whl", hash = "sha256:cf44a7763aea9298c0aa7dbf859f87ed7012de8bda0f3977b6fb1d96745df856", size = 2021121, upload-time = "2025-09-08T23:08:11.907Z" }, + { url = "https://files.pythonhosted.org/packages/46/bd/2d45ad24f5f5ae7e8d01525eb76786fa7557136555cac7d929880519e33a/pyzmq-27.1.0-cp312-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f30f395a9e6fbca195400ce833c731e7b64c3919aa481af4d88c3759e0cb7496", size = 1878550, upload-time = "2025-09-08T23:08:13.513Z" }, + { url = "https://files.pythonhosted.org/packages/14/1d/d343f3ce13db53a54cb8946594e567410b2125394dafcc0268d8dda027e0/pyzmq-27.1.0-cp313-cp313t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:08363b2011dec81c354d694bdecaef4770e0ae96b9afea70b3f47b973655cc05", size = 897275, upload-time = "2025-09-08T23:08:26.063Z" }, + { url = "https://files.pythonhosted.org/packages/69/2d/d83dd6d7ca929a2fc67d2c3005415cdf322af7751d773524809f9e585129/pyzmq-27.1.0-cp313-cp313t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d54530c8c8b5b8ddb3318f481297441af102517602b569146185fa10b63f4fa9", size = 660469, upload-time = "2025-09-08T23:08:27.623Z" }, + { url = "https://files.pythonhosted.org/packages/3e/cd/9822a7af117f4bc0f1952dbe9ef8358eb50a24928efd5edf54210b850259/pyzmq-27.1.0-cp313-cp313t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:6f3afa12c392f0a44a2414056d730eebc33ec0926aae92b5ad5cf26ebb6cc128", size = 847961, upload-time = "2025-09-08T23:08:29.672Z" }, + { url = "https://files.pythonhosted.org/packages/9a/12/f003e824a19ed73be15542f172fd0ec4ad0b60cf37436652c93b9df7c585/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:c65047adafe573ff023b3187bb93faa583151627bc9c51fc4fb2c561ed689d39", size = 1650282, upload-time = "2025-09-08T23:08:31.349Z" }, + { url = "https://files.pythonhosted.org/packages/d5/4a/e82d788ed58e9a23995cee70dbc20c9aded3d13a92d30d57ec2291f1e8a3/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:90e6e9441c946a8b0a667356f7078d96411391a3b8f80980315455574177ec97", size = 2024468, upload-time = "2025-09-08T23:08:33.543Z" }, + { url = "https://files.pythonhosted.org/packages/d9/94/2da0a60841f757481e402b34bf4c8bf57fa54a5466b965de791b1e6f747d/pyzmq-27.1.0-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:add071b2d25f84e8189aaf0882d39a285b42fa3853016ebab234a5e78c7a43db", size = 1885394, upload-time = "2025-09-08T23:08:35.51Z" }, + { url = "https://files.pythonhosted.org/packages/48/43/d72ccdbf0d73d1343936296665826350cb1e825f92f2db9db3e61c2162a2/pyzmq-27.1.0-cp314-cp314t-manylinux2014_i686.manylinux_2_17_i686.whl", hash = "sha256:1779be8c549e54a1c38f805e56d2a2e5c009d26de10921d7d51cfd1c8d4632ea", size = 897175, upload-time = "2025-09-08T23:08:46.601Z" }, + { url = "https://files.pythonhosted.org/packages/2f/2e/a483f73a10b65a9ef0161e817321d39a770b2acf8bcf3004a28d90d14a94/pyzmq-27.1.0-cp314-cp314t-manylinux_2_26_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7200bb0f03345515df50d99d3db206a0a6bee1955fbb8c453c76f5bf0e08fb96", size = 660427, upload-time = "2025-09-08T23:08:48.187Z" }, + { url = "https://files.pythonhosted.org/packages/f5/d2/5f36552c2d3e5685abe60dfa56f91169f7a2d99bbaf67c5271022ab40863/pyzmq-27.1.0-cp314-cp314t-manylinux_2_26_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:01c0e07d558b06a60773744ea6251f769cd79a41a97d11b8bf4ab8f034b0424d", size = 847929, upload-time = "2025-09-08T23:08:49.76Z" }, + { url = "https://files.pythonhosted.org/packages/c4/2a/404b331f2b7bf3198e9945f75c4c521f0c6a3a23b51f7a4a401b94a13833/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:80d834abee71f65253c91540445d37c4c561e293ba6e741b992f20a105d69146", size = 1650193, upload-time = "2025-09-08T23:08:51.7Z" }, + { url = "https://files.pythonhosted.org/packages/1c/0b/f4107e33f62a5acf60e3ded67ed33d79b4ce18de432625ce2fc5093d6388/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:544b4e3b7198dde4a62b8ff6685e9802a9a1ebf47e77478a5eb88eca2a82f2fd", size = 2024388, upload-time = "2025-09-08T23:08:53.393Z" }, + { url = "https://files.pythonhosted.org/packages/0d/01/add31fe76512642fd6e40e3a3bd21f4b47e242c8ba33efb6809e37076d9b/pyzmq-27.1.0-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:cedc4c68178e59a4046f97eca31b148ddcf51e88677de1ef4e78cf06c5376c9a", size = 1885316, upload-time = "2025-09-08T23:08:55.702Z" }, +] + +[[package]] +name = "qp-prob" +version = "1.1.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "deprecated", marker = "sys_platform == 'linux'" }, + { name = "numpy", marker = "sys_platform == 'linux'" }, + { name = "scipy", marker = "sys_platform == 'linux'" }, + { name = "tables-io", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b0/65/c54639ac63667800ee00d74c8851bd104ccaefcae95138073d6e77832d17/qp_prob-1.1.4.tar.gz", hash = "sha256:a68a3a3785d3ca57a2246c0524398338b7b7dffef0aef0722c231c64dde30107", size = 2460490, upload-time = "2026-06-25T20:08:34.63Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1c/9f/6df94f6a8fc6af157b2479c7ea0f1ef86d06e8ce7f6cba09bfbb004d5de7/qp_prob-1.1.4-py3-none-any.whl", hash = "sha256:e68d193ba0a4eb0a92f9b4861b9defc59194712865fa90e06db57196f8227e30", size = 112941, upload-time = "2026-06-25T20:08:32.68Z" }, +] + +[[package]] +name = "referencing" +version = "0.37.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "attrs", marker = "sys_platform == 'linux'" }, + { name = "rpds-py", marker = "sys_platform == 'linux'" }, + { name = "typing-extensions", marker = "python_full_version < '3.13' and sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/22/f5/df4e9027acead3ecc63e50fe1e36aca1523e1719559c499951bb4b53188f/referencing-0.37.0.tar.gz", hash = "sha256:44aefc3142c5b842538163acb373e24cce6632bd54bdb01b21ad5863489f50d8", size = 78036, upload-time = "2025-10-13T15:30:48.871Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2c/58/ca301544e1fa93ed4f80d724bf5b194f6e4b945841c5bfd555878eea9fcb/referencing-0.37.0-py3-none-any.whl", hash = "sha256:381329a9f99628c9069361716891d34ad94af76e461dcb0335825aecc7692231", size = 26766, upload-time = "2025-10-13T15:30:47.625Z" }, +] + +[[package]] +name = "regions" +version = "0.12" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "astropy", marker = "sys_platform == 'linux'" }, + { name = "numpy", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d3/86/44ff464efa2777247d6addc74416059f1872ab05c88588bbe1aadca27a7c/regions-0.12.tar.gz", hash = "sha256:1c9460770f250ef299e90a9d5c0b35941f7d05bbf879f6ffaa0538250c018ef9", size = 273609, upload-time = "2026-06-24T20:10:17.78Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/a2/fe550b219404e98f2afc742ebb1d1bcd27888a6ad48ce60baf5fa96bde97/regions-0.12-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bf5a6d8f1060607eab07f131cf12709ef7c4e9b1918d4aa269572e6c49e68b12", size = 2410524, upload-time = "2026-06-24T20:10:11.56Z" }, + { url = "https://files.pythonhosted.org/packages/92/4c/21bed50e1f86aa9fc5148318057f23d68d81f9ce0c1b31038e6c5c0e9547/regions-0.12-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e3b74d83fc4042430e8f11a0f1a3939ec6f95a7244a7103caeb6ad115d845acf", size = 2426898, upload-time = "2026-06-24T20:10:13.042Z" }, +] + +[[package]] +name = "reproject" +version = "0.21.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "astropy", marker = "sys_platform == 'linux'" }, + { name = "astropy-healpix", marker = "sys_platform == 'linux'" }, + { name = "dask", extra = ["array"], marker = "sys_platform == 'linux'" }, + { name = "dask-image", marker = "sys_platform == 'linux'" }, + { name = "fsspec", marker = "sys_platform == 'linux'" }, + { name = "numpy", marker = "sys_platform == 'linux'" }, + { name = "pillow", marker = "sys_platform == 'linux'" }, + { name = "pyavm", marker = "sys_platform == 'linux'" }, + { name = "scipy", marker = "sys_platform == 'linux'" }, + { name = "zarr", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cc/44/6fd820ba336484277a91a2f4808b60d6ec0b9f033f588c237e778f20fe89/reproject-0.21.0.tar.gz", hash = "sha256:01ede715a1993c29431f52ff74189ef30f5e7b2e8b4dc88c1b002145a971dc1c", size = 1622661, upload-time = "2026-06-25T15:11:34.886Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f3/5b/8d9b51c754ab014194d374cb4873d0729b397f67997e67721538b643e682/reproject-0.21.0-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2132fc5d2fa3fbbd57337099f9d47582136e653ac82402783c7ceffa26804816", size = 1776590, upload-time = "2026-06-25T15:11:30.358Z" }, + { url = "https://files.pythonhosted.org/packages/da/2d/f9d76e8e308813978227e1e43a1f25f64cd0f4b030cecaeff8baeec9eeac/reproject-0.21.0-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8525baaca84e949a69532c02ff491c23993e3bc22a59f694af576e473f2a9d2f", size = 1791889, upload-time = "2026-06-25T15:11:31.741Z" }, +] + +[[package]] +name = "requests" +version = "2.34.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "certifi", marker = "sys_platform == 'linux'" }, + { name = "charset-normalizer", marker = "sys_platform == 'linux'" }, + { name = "idna", marker = "sys_platform == 'linux'" }, + { name = "urllib3", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/ac/c3/e2a2b89f2d3e2179abd6d00ebd70bff6273f37fb3e0cc209f48b39d00cbf/requests-2.34.2.tar.gz", hash = "sha256:f288924cae4e29463698d6d60bc6a4da69c89185ad1e0bcc4104f584e960b9ed", size = 142856, upload-time = "2026-05-14T19:25:27.735Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a0/f4/c67b0b3f1b9245e8d266f0f112c500d50e5b4e83cb6f3b71b6528104182a/requests-2.34.2-py3-none-any.whl", hash = "sha256:2a0d60c172f83ac6ab31e4554906c0f3b3588d37b5cb939b1c061f4907e278e0", size = 73075, upload-time = "2026-05-14T19:25:26.443Z" }, +] + +[[package]] +name = "rfc3339-validator" +version = "0.1.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "six", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/28/ea/a9387748e2d111c3c2b275ba970b735e04e15cdb1eb30693b6b5708c4dbd/rfc3339_validator-0.1.4.tar.gz", hash = "sha256:138a2abdf93304ad60530167e51d2dfb9549521a836871b88d7f4695d0022f6b", size = 5513, upload-time = "2021-05-12T16:37:54.178Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7b/44/4e421b96b67b2daff264473f7465db72fbdf36a07e05494f50300cc7b0c6/rfc3339_validator-0.1.4-py2.py3-none-any.whl", hash = "sha256:24f6ec1eda14ef823da9e36ec7113124b39c04d50a4d3d3a3c2859577e7791fa", size = 3490, upload-time = "2021-05-12T16:37:52.536Z" }, +] + +[[package]] +name = "rfc3986-validator" +version = "0.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/da/88/f270de456dd7d11dcc808abfa291ecdd3f45ff44e3b549ffa01b126464d0/rfc3986_validator-0.1.1.tar.gz", hash = "sha256:3d44bde7921b3b9ec3ae4e3adca370438eccebc676456449b145d533b240d055", size = 6760, upload-time = "2019-10-28T16:00:19.144Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9e/51/17023c0f8f1869d8806b979a2bffa3f861f26a3f1a66b094288323fba52f/rfc3986_validator-0.1.1-py2.py3-none-any.whl", hash = "sha256:2f235c432ef459970b4306369336b9d5dbdda31b510ca1e327636e01f528bfa9", size = 4242, upload-time = "2019-10-28T16:00:13.976Z" }, +] + +[[package]] +name = "rfc3987-syntax" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "lark", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/2c/06/37c1a5557acf449e8e406a830a05bf885ac47d33270aec454ef78675008d/rfc3987_syntax-1.1.0.tar.gz", hash = "sha256:717a62cbf33cffdd16dfa3a497d81ce48a660ea691b1ddd7be710c22f00b4a0d", size = 14239, upload-time = "2025-07-18T01:05:05.015Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/71/44ce230e1b7fadd372515a97e32a83011f906ddded8d03e3c6aafbdedbb7/rfc3987_syntax-1.1.0-py3-none-any.whl", hash = "sha256:6c3d97604e4c5ce9f714898e05401a0445a641cfa276432b0a648c80856f6a3f", size = 8046, upload-time = "2025-07-18T01:05:03.843Z" }, +] + +[[package]] +name = "rich" +version = "15.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "markdown-it-py", marker = "sys_platform == 'linux'" }, + { name = "pygments", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/c0/8f/0722ca900cc807c13a6a0c696dacf35430f72e0ec571c4275d2371fca3e9/rich-15.0.0.tar.gz", hash = "sha256:edd07a4824c6b40189fb7ac9bc4c52536e9780fbbfbddf6f1e2502c31b068c36", size = 230680, upload-time = "2026-04-12T08:24:00.75Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/82/3b/64d4899d73f91ba49a8c18a8ff3f0ea8f1c1d75481760df8c68ef5235bf5/rich-15.0.0-py3-none-any.whl", hash = "sha256:33bd4ef74232fb73fe9279a257718407f169c09b78a87ad3d296f548e27de0bb", size = 310654, upload-time = "2026-04-12T08:24:02.83Z" }, +] + +[[package]] +name = "rocket-fft" +version = "0.3.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numba", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/44/b0/09cbec3177ecf56e5ceb789a69fbcdcbabe758cbb682e5d36b14aa8c05fb/rocket_fft-0.3.1.tar.gz", hash = "sha256:ddc902a361099aff9fc02fe9ea3b0d036c2f67f93df356c2b754f7627d7fa4f4", size = 74276, upload-time = "2025-12-26T00:30:54.083Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/08/18/12d001c33cd7c4e012da59d25086879aec303e0e157d9ec737ecab8e8f58/rocket_fft-0.3.1-cp312-cp312-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:46970c0dcc70bd9c365d6a9f4a235edec2e8eaad628097c0e21d920669e25abe", size = 2151682, upload-time = "2025-12-26T00:30:30.315Z" }, + { url = "https://files.pythonhosted.org/packages/c8/92/98bd01cad9e5ceeb383722d744597d066e37cdd0e54742906341aa369c28/rocket_fft-0.3.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:7d64c9fc81206f2c77f74f68761f54ac6f1ebe4c8840f0ef9795c28ab229463f", size = 2160197, upload-time = "2025-12-26T00:30:31.945Z" }, + { url = "https://files.pythonhosted.org/packages/48/2c/5bbe8d6b0c4e009f7bc6f9f4eee802a9b556ec2c3b02b9d5e5ccfa8edff1/rocket_fft-0.3.1-cp313-cp313-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:5906c6517fc87295a1d142c7e6ebd1c55e057f6ee4c605549bbcecacab83774f", size = 2151627, upload-time = "2025-12-26T00:30:37.177Z" }, + { url = "https://files.pythonhosted.org/packages/55/0d/ac67fb0b2fac382ab5585719bbd1f4927c19ba0ee3bbc28dc8a1ef83e81d/rocket_fft-0.3.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9d830aacc34d65b28daab715aa4a90d98489e89a48c2836039982f18ba1e2db3", size = 2160355, upload-time = "2025-12-26T00:30:38.81Z" }, + { url = "https://files.pythonhosted.org/packages/d5/c6/3ff33ec86e61867c0e36436eb2c9ba258eceba94419594d73ff473460e27/rocket_fft-0.3.1-cp314-cp314-manylinux_2_24_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:65a7577d7f3b4e3672de179f91fee8339211b3f5ae13eef1b30cb6a318f0308c", size = 2151746, upload-time = "2025-12-26T00:30:43.66Z" }, + { url = "https://files.pythonhosted.org/packages/bf/d9/def65716cd225954d0cd5f1f6326c72c20601db5dc65557ef4b66157ccea/rocket_fft-0.3.1-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:97614dbebb2686a644bbf6c6f8a6198f063052f4c88901d0ca2808536c2e83cc", size = 2160407, upload-time = "2025-12-26T00:30:44.959Z" }, +] + +[[package]] +name = "roman-numerals" +version = "4.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ae/f9/41dc953bbeb056c17d5f7a519f50fdf010bd0553be2d630bc69d1e022703/roman_numerals-4.1.0.tar.gz", hash = "sha256:1af8b147eb1405d5839e78aeb93131690495fe9da5c91856cb33ad55a7f1e5b2", size = 9077, upload-time = "2025-12-17T18:25:34.381Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/04/54/6f679c435d28e0a568d8e8a7c0a93a09010818634c3c3907fc98d8983770/roman_numerals-4.1.0-py3-none-any.whl", hash = "sha256:647ba99caddc2cc1e55a51e4360689115551bf4476d90e8162cf8c345fe233c7", size = 7676, upload-time = "2025-12-17T18:25:33.098Z" }, +] + +[[package]] +name = "rpds-py" +version = "2026.6.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/aa/2a/9618a122aeb2a169a28b03889a2995fe297588964333d4a7d67bdf46e147/rpds_py-2026.6.3.tar.gz", hash = "sha256:1cebd1337c242e4ec2293e541f712b2da849b29f48f0c293684b71c0632625d4", size = 64051, upload-time = "2026-06-30T07:17:53.009Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/21/63/4239893be1c4d09b709b1a8f6be4188f0870084ff547f46606b8a75f1b03/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55927d532399c2c646100ff7feb48eaa940ad70f42cd68e1328f3ded9f81ca24", size = 368180, upload-time = "2026-06-30T07:15:17.62Z" }, + { url = "https://files.pythonhosted.org/packages/1c/ca/9c5de382225234ceb37b1844ebdb140db12b2a278bb9efe2fcd19f6c82ce/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f56f1695bc5c0871cbc33dc0130fcf503aab0c57dcc5a6700a4f49eba4f2652e", size = 375067, upload-time = "2026-06-30T07:15:18.952Z" }, + { url = "https://files.pythonhosted.org/packages/87/dc/863f69d1bf04ade34b7fe0d59b9fdf6f0135fe2d7cbca74f1d665589559d/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:270b293dae9058fc9fcedab50f13cebf46fb8ed1d1d54e0521a9da5d6b211975", size = 490509, upload-time = "2026-06-30T07:15:20.434Z" }, + { url = "https://files.pythonhosted.org/packages/ce/ef/eac16a12048b45ec7c7fa94f2be3438a5f26bf9cc8580b18a1cfd609b7f6/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:127565fead0a10943b282957bd5447804ff3160ad79f2ad2635e6d249e380680", size = 382754, upload-time = "2026-06-30T07:15:21.831Z" }, + { url = "https://files.pythonhosted.org/packages/04/8f/d2f3f532616be4d06c316ef119683e832bd3d41e112bf3a88f4151c95b17/rpds_py-2026.6.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ecabd69db66de867690f9797f2f8fa27ba501bbc24540cbdbdc649cd15888ba6", size = 366189, upload-time = "2026-06-30T07:15:23.371Z" }, + { url = "https://files.pythonhosted.org/packages/e3/29/41a7b0e98a4b44cd676ab7598419623373eb43b20be68c084935c1a8cf88/rpds_py-2026.6.3-cp312-cp312-manylinux_2_31_riscv64.whl", hash = "sha256:58eadac9cd119677b60e1cf8ac4052f35949d71b8a9e5556efccbe82533cf22a", size = 377750, upload-time = "2026-06-30T07:15:24.659Z" }, + { url = "https://files.pythonhosted.org/packages/2e/05/ecda0bec46f9a1565090bcdc941d023f6a25aff85fda28f89f8d19878152/rpds_py-2026.6.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7491ee23305ac3eb59e492b6945881f5cd77a6f731061a3f25b77fd40f9e99a4", size = 395576, upload-time = "2026-06-30T07:15:25.987Z" }, + { url = "https://files.pythonhosted.org/packages/68/a8/6ed52f03ee6cb854ce78785cc9a9a672eb880e83fd7224d471f667d151f1/rpds_py-2026.6.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2c99f7e8ccb3dd6e3e4bfeac657a7b208c9bac8075f4b078c02d7404c34107fa", size = 543807, upload-time = "2026-06-30T07:15:27.356Z" }, + { url = "https://files.pythonhosted.org/packages/8f/d6/156c0d3eea27ba09b92562ba2364ba124c0a061b199e17eac637cd25a5e2/rpds_py-2026.6.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:62698275682bf121181861295c9181e789030a2d516071f5b8f3c23c170cd0fc", size = 611187, upload-time = "2026-06-30T07:15:28.931Z" }, + { url = "https://files.pythonhosted.org/packages/f1/31/774212ed989c62f7f310220089f9b0a3fb8f40f5443d1727abd5d9f52bc9/rpds_py-2026.6.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a214c993455f99a89aaeadc9b21241900037adc9d97203e374d75513c5911822", size = 573030, upload-time = "2026-06-30T07:15:30.553Z" }, + { url = "https://files.pythonhosted.org/packages/9e/9b/069aa329940f8207615e091f5eedbbd40e1e15eac68a0790fd05ccdf796c/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54f45a148e28767bf343d33a684693c70e451c6f4c0e9904709a723fafbdfc1f", size = 367984, upload-time = "2026-06-30T07:15:39.008Z" }, + { url = "https://files.pythonhosted.org/packages/14/db/34c203e4becff3703e4d3bc121842c00b8689197f398161203a880052f4e/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:842e7b070435622248c7a2c44ae53fa1440e073cc3023bc919fed570884097a7", size = 374815, upload-time = "2026-06-30T07:15:40.253Z" }, + { url = "https://files.pythonhosted.org/packages/ee/7d/8071067d2cc453d916ad836e828c943f575e8a44612537759002a1e07381/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8020133a74bd81b4572dd8e4be028a6b1ebcd70e6726edc3918008c08bee6ee6", size = 490545, upload-time = "2026-06-30T07:15:41.729Z" }, + { url = "https://files.pythonhosted.org/packages/a3/42/da06c5aa8f0484ff07f270787434204d9f4535e2f8c3b51ed402267e63c3/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cdc7e35386f3847df728fbcb5e887e2d79c19e2fa1eba9e51b6621d23e3243af", size = 382828, upload-time = "2026-06-30T07:15:43.327Z" }, + { url = "https://files.pythonhosted.org/packages/57/d7/fe978efc2ae50abe48eb7464668ea99f53c010c60aeebb7b35ad27f23661/rpds_py-2026.6.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:acac386b453c2516111b50985d60ce46e7fadb5ea71ae7b25f4c946935bf27cf", size = 365678, upload-time = "2026-06-30T07:15:44.992Z" }, + { url = "https://files.pythonhosted.org/packages/69/9d/1d8922e1990b2a6eb532b6ff53d3e73d2b3bbffc84116c75826bee73dfc6/rpds_py-2026.6.3-cp313-cp313-manylinux_2_31_riscv64.whl", hash = "sha256:425560c6fa0415f27261727bb20bd097568485e5eb0c121f1949417d1c516885", size = 377811, upload-time = "2026-06-30T07:15:46.523Z" }, + { url = "https://files.pythonhosted.org/packages/b1/3d/198dceafb4fb034a6a47347e1b0735d34e0bd4a50be4e898d408ee66cb14/rpds_py-2026.6.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:a550fb4950a06dde3beb4721f5ad4b25bf4513784665b0a8522c792e2bd822a4", size = 395382, upload-time = "2026-06-30T07:15:47.955Z" }, + { url = "https://files.pythonhosted.org/packages/1f/f1/13968e49655d40b6b19d8b9140296bbc6f1d86b3f0f6c346cf9f1adddf4b/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4f4bca01b63096f606e095734dd56e74e175f94cfbf24ff3d63281cec61f7bb7", size = 543832, upload-time = "2026-06-30T07:15:49.33Z" }, + { url = "https://files.pythonhosted.org/packages/ac/ab/289bcb1b90bd3e40a2900c561fa0e2087345ecbb094f0b870f2345142b7c/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ccffae9a092a00deb7efd545fe5e2c33c33b88e7c054337e9a74c179347d0b7d", size = 611011, upload-time = "2026-06-30T07:15:50.847Z" }, + { url = "https://files.pythonhosted.org/packages/1e/16/5043105e679436ccfbc8e5e0dd2d663ed18a8b8113515fd06a5e5d77c83e/rpds_py-2026.6.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1cf01971c4f2c5553b772a542e4aaf191789cd331bc2cd4ff0e6e65ba49e1e97", size = 572431, upload-time = "2026-06-30T07:15:52.394Z" }, + { url = "https://files.pythonhosted.org/packages/63/ef/d4cdaf309e6b095b43597103cf8c0b951d6cca2acce68c474f75ec12e0c7/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bcfbcf66006befb9fd2aeaa9e01feaf881b4dc330a02ba07d2322b1c11be7b5d", size = 369454, upload-time = "2026-06-30T07:16:01.021Z" }, + { url = "https://files.pythonhosted.org/packages/96/4a/9559a68b7ee15db09d7981212e8c2e219d2a1d6d4faa0391d813c3496a36/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:847927daf4cffbd4e90e42bc890069897101edd015f956cb8721b3473372edda", size = 374583, upload-time = "2026-06-30T07:16:02.287Z" }, + { url = "https://files.pythonhosted.org/packages/ef/75/8964aa7d2c6e8ac43eba8eb6e6b0fdda1f46d39f2fc3e6aa9f2cb17f485d/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aca6c1ef08a82bfe327cc156da694660f599923e2e6665b6d81c9c2d0ac9ffc8", size = 492919, upload-time = "2026-06-30T07:16:03.723Z" }, + { url = "https://files.pythonhosted.org/packages/8f/97/6908094ac804115e65aedfd90f1b5fee4eebebd3f6c4cfc5419939267565/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ae50181a047c871561212bb97f7932a2d45fb53e947bd9b57ebad85b529cbc53", size = 383725, upload-time = "2026-06-30T07:16:05.305Z" }, + { url = "https://files.pythonhosted.org/packages/d1/9c/0d1fdc2e7aba23e290d603bc494e97bd205bae262ce33c6b32a69768ed5e/rpds_py-2026.6.3-cp314-cp314-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc319e5a1de4b6913aac94bf6a2f9e847371e0a140a43dd4991db1a09bc2d504", size = 367255, upload-time = "2026-06-30T07:16:07.086Z" }, + { url = "https://files.pythonhosted.org/packages/c4/fe/f0209ca4a9ed074bc8acb44dfd0e81c3122e94c9689f5645b7973a866719/rpds_py-2026.6.3-cp314-cp314-manylinux_2_31_riscv64.whl", hash = "sha256:e4316bf32babbed84e691e352faf967ce2f0f024174a8643c37c94a1080374fc", size = 379060, upload-time = "2026-06-30T07:16:08.525Z" }, + { url = "https://files.pythonhosted.org/packages/c6/8d/f1cc54c616b9d8897de8738aac148d20afca93f68187475fe194d09a71b9/rpds_py-2026.6.3-cp314-cp314-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:8c6e5a2f750cc71c3e3b11d71661f21d6f9bc6cebc6564b1466417a1ec03ec77", size = 395960, upload-time = "2026-06-30T07:16:09.989Z" }, + { url = "https://files.pythonhosted.org/packages/fb/04/aafff00f73aeca2945f734f1d483c64ab8f472d0864ab02377fd8e89c3b2/rpds_py-2026.6.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4470ce197d4090875cf6affbf1f853338387428df97c4fb7b7106317b8214698", size = 545356, upload-time = "2026-06-30T07:16:11.816Z" }, + { url = "https://files.pythonhosted.org/packages/fd/cc/e229663b9e4ddac5a4acbe9085dd80a71af2a5d356b8b39d6bff233f24b0/rpds_py-2026.6.3-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:ea964164cc9afa72d4d9b23cc28dafae93693c0a53e0b42acbff15b22c3f9ddd", size = 612319, upload-time = "2026-06-30T07:16:13.586Z" }, + { url = "https://files.pythonhosted.org/packages/e3/7a/8a0e6d3e6cd066af108b71b43122c3fe158dd9eb86acac626593a2582eb1/rpds_py-2026.6.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:639c8929aa0afe81be836b04de888460d6bed38b9c54cfc18da8f6bfabf5af5d", size = 573508, upload-time = "2026-06-30T07:16:15.23Z" }, + { url = "https://files.pythonhosted.org/packages/87/3c/7a9081c7c9e645b39efe19e4ffbeccd80add246327cd9b888aecffd72317/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:afd70d95892096cdb26f15a00c45907b17817577aa8d1c76b2dcc2788391f9e9", size = 370403, upload-time = "2026-06-30T07:16:24.415Z" }, + { url = "https://files.pythonhosted.org/packages/f7/69/af47021eb7dad6ff3396cb001c08f0f3c4d06c20253f75be6421a59fe6b7/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:29dfa0533a5d4c94d4dfa1b694fcb56c9c63aad8330ffdd816fd225d0a7a162f", size = 376055, upload-time = "2026-06-30T07:16:26.111Z" }, + { url = "https://files.pythonhosted.org/packages/81/fc/a3bcf517084396a6dd258c592567a3c011ba4557f2fde23dceaf26e74f2e/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:af05d726809bff6b141be124d4c7ce998f9c9c7f30edb1f46c07aa103d540b41", size = 494419, upload-time = "2026-06-30T07:16:27.596Z" }, + { url = "https://files.pythonhosted.org/packages/c9/eb/13d529d1788135425c7bf207f8463458ca5d92e43f3f701365b83e9dffc1/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9826217f048f620d9a712672818bf231442c1b35d96b227a07eabd11b4bb6945", size = 384848, upload-time = "2026-06-30T07:16:29.183Z" }, + { url = "https://files.pythonhosted.org/packages/8e/f4/b7ac49f30013aba8f7b9566b1dd07e81de95e708c1374b7bacc5b9bc5c9c/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:536bceea4fa4acf7e1c61da2b5786304367c816c8895be71b8f537c480b0ea1f", size = 371369, upload-time = "2026-06-30T07:16:30.912Z" }, + { url = "https://files.pythonhosted.org/packages/31/86/6260bafa622f788b07ddec0e52d810305c8b9b0b8c27f58a2ab04bf62b4f/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_31_riscv64.whl", hash = "sha256:bc0011654b91cc4fb2ae701bec0a0ba1e552c0714247fa7af6c59e0ccfa3a4e1", size = 379673, upload-time = "2026-06-30T07:16:32.486Z" }, + { url = "https://files.pythonhosted.org/packages/19/c3/03f1ee79a047b48daeca157c89a18509cde22b6b951d642b9b0af1be660a/rpds_py-2026.6.3-cp314-cp314t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:539d75de9e0d536c84ff18dfeb805398e58227001ce09231a26a08b9aed1ee0e", size = 397500, upload-time = "2026-06-30T07:16:34.471Z" }, + { url = "https://files.pythonhosted.org/packages/f0/95/8ed0cd8c377dca12aea498f119fe639fc474d1461545c39d2b5872eb1c0f/rpds_py-2026.6.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:166cf54d9f44fc6ceb53c7860258dde44a81406646de79f8ed3234fca3b6e538", size = 545978, upload-time = "2026-06-30T07:16:36.45Z" }, + { url = "https://files.pythonhosted.org/packages/d3/f2/0eb57f0eaa83f8fc152a7e03de968ab77e1f00732bebc892b190c6eebde7/rpds_py-2026.6.3-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:d34c20167764fbcf927194d532dd7e0c56772f0a5f943fa5ef9e9afbba8fb9db", size = 613350, upload-time = "2026-06-30T07:16:38.213Z" }, + { url = "https://files.pythonhosted.org/packages/5b/de/e0674bdbc3ef7634989b3f854c3f34bc1f587d36e5bfdc5c378d57034619/rpds_py-2026.6.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ea7bb13b7c9a29791f87a0387ba7d3ad3a6d783d827e4d3f27b40a0ff44495e2", size = 576486, upload-time = "2026-06-30T07:16:39.797Z" }, + { url = "https://files.pythonhosted.org/packages/ec/64/10a85681916ca55fffb91b0a211f84e34297c109243484dd6394660a8a7c/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3086b538543802f84c843911242db20447de00d8752dd0efc936dbcf02218ba", size = 369585, upload-time = "2026-06-30T07:16:48.101Z" }, + { url = "https://files.pythonhosted.org/packages/76/c2/baf95c7c38823e12ba34407c5f5767a89e5cf2233895e56f608167ae9493/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8f2e5c5ee828d42cb11760761c0af6507927bec42d0ad5458f97c9203b054617", size = 375479, upload-time = "2026-06-30T07:16:49.93Z" }, + { url = "https://files.pythonhosted.org/packages/6a/94/0aad06c72d65101e11d33528d438cda99a39ce0da99466e156158f2541d3/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ed0c1e5d10cdc7135537988c74a0188da68e2f3c30813ba3744ab1e42e0480f9", size = 492418, upload-time = "2026-06-30T07:16:51.641Z" }, + { url = "https://files.pythonhosted.org/packages/b5/17/de3f5a479a1f056535d7489819639d8cd591ea6281d700390b43b1abd745/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8c2642a7603ec0b16ed77da4555db3b4b472341904873788327c0b0d7b95f1bb", size = 384123, upload-time = "2026-06-30T07:16:53.622Z" }, + { url = "https://files.pythonhosted.org/packages/46/7d/bf09bd1b145bb2671c03e1e6d1ab8651858d90d8c7dfeadd85a37a934fd8/rpds_py-2026.6.3-cp315-cp315-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e4320744c1ffdd95a603def63344bfab2d33edeab301c5007e7de9f9f5b3885", size = 367351, upload-time = "2026-06-30T07:16:55.241Z" }, + { url = "https://files.pythonhosted.org/packages/a3/ea/1bb734f314b8be319149ddee80b18bd41372bdcfbdf88d28131c0cd37719/rpds_py-2026.6.3-cp315-cp315-manylinux_2_31_riscv64.whl", hash = "sha256:a9f4645593036b81bbdb36b9c8e0ea0d1c3fee968c4d59db0344c14087ef143a", size = 378827, upload-time = "2026-06-30T07:16:56.841Z" }, + { url = "https://files.pythonhosted.org/packages/4b/93/d9611e5b25e26df9a3649813ed66193ace9347a7c7fc4ab7cf70e94851c0/rpds_py-2026.6.3-cp315-cp315-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e55d236be29255554da47abe5c577637db7c24a02b8b46f0ca9524c855801868", size = 395966, upload-time = "2026-06-30T07:16:58.557Z" }, + { url = "https://files.pythonhosted.org/packages/c3/cb/99d77e16e5534ae1d90629bbe419ba6ee170833a6a85e3aa1cc41726fbbc/rpds_py-2026.6.3-cp315-cp315-musllinux_1_2_aarch64.whl", hash = "sha256:24e9c5386e16669b674a69c156c8eeefcb578f3b3397b713b08e6d60f3c7b187", size = 545680, upload-time = "2026-06-30T07:17:00.164Z" }, + { url = "https://files.pythonhosted.org/packages/59/15/11a29755f790cef7a2f755e8e14f4f0c33f39489e1893a632a2eee59672b/rpds_py-2026.6.3-cp315-cp315-musllinux_1_2_i686.whl", hash = "sha256:c60924535c75f1566b6eb75b5c31a48a43fef04fa2d0d201acbad8a9969c6107", size = 611853, upload-time = "2026-06-30T07:17:01.962Z" }, + { url = "https://files.pythonhosted.org/packages/68/86/0c27547e21644da938fb530f7e1a8148dd24d02db07e7a5f2567a17ce710/rpds_py-2026.6.3-cp315-cp315-musllinux_1_2_x86_64.whl", hash = "sha256:38a2fea2787428f811719ceb9114cb78964a3138838320c29ac39526c79c16ba", size = 573715, upload-time = "2026-06-30T07:17:03.693Z" }, + { url = "https://files.pythonhosted.org/packages/6f/2c/8e03767b5778ef25cebf74a7a91a2c3806f8eced4c92cb7406bbe060756d/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b95977e7211527ab0ba576e286d023389fbeeb32a6b7b771665d333c60e5342", size = 370763, upload-time = "2026-06-30T07:17:14.107Z" }, + { url = "https://files.pythonhosted.org/packages/2e/e1/df2a7e1ba2efd796af26194250b8d42c821b46592311595162af9ef0528d/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d15fde0e6fb0d88a60d221204873743e5d9f0b7d29165e62cd86d0413ad74ba6", size = 376467, upload-time = "2026-06-30T07:17:15.76Z" }, + { url = "https://files.pythonhosted.org/packages/6b/de/8a0814d1946af29cb068fb259aa8622f856df1d0bab58429448726b537f5/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a136d453475ac0fcbda502ef1e6504bd28d6d904700915d278deeab0d00fe140", size = 496689, upload-time = "2026-06-30T07:17:17.308Z" }, + { url = "https://files.pythonhosted.org/packages/df/f3/f19e0c852ba13694f5a79f3b719331051573cb5693feacf8a88ffffc3a71/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f826877d462181e5eb1c26a0026b8d0cab05d99844ecb6d8bf3627a2ca0c0442", size = 385340, upload-time = "2026-06-30T07:17:18.928Z" }, + { url = "https://files.pythonhosted.org/packages/e2/ae/7ec3a9d2d4351f99e37bcb06b6b6f954512646bfdbf9742e1de727865daf/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:79486287de1730dbaff3dbd124d0ca4d2ef7f9d29bf2544f1f93c09b5bcbbd12", size = 372179, upload-time = "2026-06-30T07:17:20.539Z" }, + { url = "https://files.pythonhosted.org/packages/d3/ac/9cee911dff2aaa9a5a8354f6610bf2e6a616de9197c5fff4f54f82585f1e/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_31_riscv64.whl", hash = "sha256:808345f53cb952433ca2816f1604ff3515608a81784954f38d4452acfe8e61d5", size = 379993, upload-time = "2026-06-30T07:17:22.212Z" }, + { url = "https://files.pythonhosted.org/packages/83/6b/7c2a07ba88d1e9a936612f7a5d067467ed03d971d5a06f7d309dff044a7e/rpds_py-2026.6.3-cp315-cp315t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1967debc37f64f2c4dc90a7f563aec558b471966e12adcac4e1c4240496b6ebf", size = 398909, upload-time = "2026-06-30T07:17:23.66Z" }, + { url = "https://files.pythonhosted.org/packages/97/0b/776ffcb66783637b0031f6d58d6fb55913c8b5abf00aeecd46bf933fb477/rpds_py-2026.6.3-cp315-cp315t-musllinux_1_2_aarch64.whl", hash = "sha256:f0840b5b17057f7fd918b76183a4b5a0635f43e14eb2ce60dce1d4ee4707ea00", size = 546584, upload-time = "2026-06-30T07:17:25.264Z" }, + { url = "https://files.pythonhosted.org/packages/55/33/ba3bc04d7092bd553c9b2b195624992d2cc4f3de1f380b7b93cbee67bd79/rpds_py-2026.6.3-cp315-cp315t-musllinux_1_2_i686.whl", hash = "sha256:faa679d19a6696fd54259ad321251ad77a13e70e03dd834daa762a44fb6196ef", size = 614357, upload-time = "2026-06-30T07:17:26.888Z" }, + { url = "https://files.pythonhosted.org/packages/8b/71/14edf065f04630b1a8472f7653cad03f6c478bcf95ea0e6aed55451e33ea/rpds_py-2026.6.3-cp315-cp315t-musllinux_1_2_x86_64.whl", hash = "sha256:23a439f31ccbeff1574e24889128821d1f7917470e830cf6544dced1c662262a", size = 576533, upload-time = "2026-06-30T07:17:28.546Z" }, +] + +[[package]] +name = "ruff" +version = "0.15.21" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0f/36/6f65aa9989acdec45d417192d8f4e7921931d8a6cf87ac74bce3eed98a8e/ruff-0.15.21.tar.gz", hash = "sha256:d0cfc841c572283c36548f82664a54ce6565567f1b0d5b4cf2caac693d8b7500", size = 4769401, upload-time = "2026-07-09T20:01:34.005Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d0/c6/ede15cac6839f3dbce52565c8f5164a8210e669c7bc4decb03e5bdf47d0d/ruff-0.15.21-py3-none-linux_armv6l.whl", hash = "sha256:63ea0e965e5d73c90e95b2434beeafc70820536717f561b32ab6e777cb9bdf5d", size = 10854342, upload-time = "2026-07-09T20:00:53.998Z" }, + { url = "https://files.pythonhosted.org/packages/9a/6f/b4523cc90ba239ede441447a19d0c968846a3012e5a0b0c5b62831a3d5e3/ruff-0.15.21-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:01d65b4831c6b2a4ba8ee6faa84049d44d982b7a706e622c4094c509e51673be", size = 10990053, upload-time = "2026-07-09T20:01:02.187Z" }, + { url = "https://files.pythonhosted.org/packages/92/cc/c6a9872a5375f0628875481cf2f66b13d7d865bf3ca2e57f91c7e762d976/ruff-0.15.21-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2c5a913a589120ce67933d5d05fd6ddbcc2481c6a054980ee767f7414c72b4fd", size = 10666096, upload-time = "2026-07-09T20:01:04.299Z" }, + { url = "https://files.pythonhosted.org/packages/ab/97/c621f7a17e097f1790fa3af6374138823b330b2d03fc38337945daca212c/ruff-0.15.21-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5ef04b681d02ad4dc9620f00f83ac5c22f652d0e9a9cfe431d219b16ad5ccc41", size = 11537011, upload-time = "2026-07-09T20:01:06.771Z" }, + { url = "https://files.pythonhosted.org/packages/ea/51/d928727e476e25ccc57c6f449ffd80241a651a973ad949d39cfb2a771d28/ruff-0.15.21-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:16d090c0740916594157e75b80d666eab8e78083b39b3b0e1d698f4670a17b86", size = 12347101, upload-time = "2026-07-09T20:01:08.859Z" }, + { url = "https://files.pythonhosted.org/packages/1e/88/8cd62026802b16018ad06931d87997cf795ba2a6239ab659606c87d96bf0/ruff-0.15.21-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3a10e74757dd65004d779b73e2f3c5210156d9980b41224d50d2ebcf1db51e67", size = 11572001, upload-time = "2026-07-09T20:01:11.092Z" }, + { url = "https://files.pythonhosted.org/packages/b2/97/f63084cf55444fc110e8cb985ebfcc592af47f597d44453d778cb81bc156/ruff-0.15.21-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bab0905d2f29e0d9fbc3c373ed23db0095edaa3f71f1f4f519ec15134d9e85c8", size = 11549239, upload-time = "2026-07-09T20:01:13.27Z" }, + { url = "https://files.pythonhosted.org/packages/9d/77/f107da4a2874b7715914b03f09ba9c54424de3ff8a1cc5d015d3ee2ce0ac/ruff-0.15.21-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:00eca240af5789fec6fe7df74c088cc1f9644ed83027113468efba7c92b94075", size = 11535340, upload-time = "2026-07-09T20:01:15.206Z" }, + { url = "https://files.pythonhosted.org/packages/d5/e9/601deb322d3303a7bf212b0100ead6f2ee3f6a044d89c30f2f92bf83c731/ruff-0.15.21-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:262ab31557a75141325e32d3357f3597645a7f084e732b6b054dde428ecd9341", size = 10964048, upload-time = "2026-07-09T20:01:17.723Z" }, + { url = "https://files.pythonhosted.org/packages/ea/2e/0f2176d1e99c15192caea19c8c3a0a955246b4cb4de795042eeb616345cd/ruff-0.15.21-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:659c4e7a4212f83306045ec7c5e5a356d16d9a6ef4ae0c7a4d872914fc655d9d", size = 10667055, upload-time = "2026-07-09T20:01:19.73Z" }, + { url = "https://files.pythonhosted.org/packages/48/60/abd74a02e0c4214f12a68becfd30af7165cfdcb0e661ecdc60bbb949c09a/ruff-0.15.21-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9e866eab611a5f959d36df2d10e446973a3610bc42b0c15b31dc27977d59c233", size = 11242043, upload-time = "2026-07-09T20:01:21.947Z" }, + { url = "https://files.pythonhosted.org/packages/b2/c6/583075d8ccabb4b229345edcaf1545eb3d8d6be90f686a479d7e94088bbf/ruff-0.15.21-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e89bc93c0d3803ba870b55c29671bad9dc6d94bb1eb181b056b52eb05b52854f", size = 11648064, upload-time = "2026-07-09T20:01:24.023Z" }, +] + +[[package]] +name = "scipy" +version = "1.17.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/7a/97/5a3609c4f8d58b039179648e62dd220f89864f56f7357f5d4f45c29eb2cc/scipy-1.17.1.tar.gz", hash = "sha256:95d8e012d8cb8816c226aef832200b1d45109ed4464303e997c5b13122b297c0", size = 30573822, upload-time = "2026-02-23T00:26:24.851Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/da/34/16f10e3042d2f1d6b66e0428308ab52224b6a23049cb2f5c1756f713815f/scipy-1.17.1-cp312-cp312-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e19ebea31758fac5893a2ac360fedd00116cbb7628e650842a6691ba7ca28a21", size = 32927842, upload-time = "2026-02-23T00:18:35.367Z" }, + { url = "https://files.pythonhosted.org/packages/01/8e/1e35281b8ab6d5d72ebe9911edcdffa3f36b04ed9d51dec6dd140396e220/scipy-1.17.1-cp312-cp312-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:02ae3b274fde71c5e92ac4d54bc06c42d80e399fec704383dcd99b301df37458", size = 35235890, upload-time = "2026-02-23T00:18:49.188Z" }, + { url = "https://files.pythonhosted.org/packages/c5/5c/9d7f4c88bea6e0d5a4f1bc0506a53a00e9fcb198de372bfe4d3652cef482/scipy-1.17.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8a604bae87c6195d8b1045eddece0514d041604b14f2727bbc2b3020172045eb", size = 35003557, upload-time = "2026-02-23T00:18:54.74Z" }, + { url = "https://files.pythonhosted.org/packages/65/94/7698add8f276dbab7a9de9fb6b0e02fc13ee61d51c7c3f85ac28b65e1239/scipy-1.17.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f590cd684941912d10becc07325a3eeb77886fe981415660d9265c4c418d0bea", size = 37625856, upload-time = "2026-02-23T00:19:00.307Z" }, + { url = "https://files.pythonhosted.org/packages/b4/e0/e58fbde4a1a594c8be8114eb4aac1a55bcd6587047efc18a61eb1f5c0d30/scipy-1.17.1-cp313-cp313-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2b64ca7d4aee0102a97f3ba22124052b4bd2152522355073580bf4845e2550b6", size = 32896429, upload-time = "2026-02-23T00:19:35.536Z" }, + { url = "https://files.pythonhosted.org/packages/f5/5f/f17563f28ff03c7b6799c50d01d5d856a1d55f2676f537ca8d28c7f627cd/scipy-1.17.1-cp313-cp313-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:581b2264fc0aa555f3f435a5944da7504ea3a065d7029ad60e7c3d1ae09c5464", size = 35203952, upload-time = "2026-02-23T00:19:42.259Z" }, + { url = "https://files.pythonhosted.org/packages/8d/a5/9afd17de24f657fdfe4df9a3f1ea049b39aef7c06000c13db1530d81ccca/scipy-1.17.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:beeda3d4ae615106d7094f7e7cef6218392e4465cc95d25f900bebabfded0950", size = 34979063, upload-time = "2026-02-23T00:19:47.547Z" }, + { url = "https://files.pythonhosted.org/packages/8b/13/88b1d2384b424bf7c924f2038c1c409f8d88bb2a8d49d097861dd64a57b2/scipy-1.17.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6609bc224e9568f65064cfa72edc0f24ee6655b47575954ec6339534b2798369", size = 37598449, upload-time = "2026-02-23T00:19:53.238Z" }, + { url = "https://files.pythonhosted.org/packages/6d/a0/3cb6f4d2fb3e17428ad2880333cac878909ad1a89f678527b5328b93c1d4/scipy-1.17.1-cp313-cp313t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:158dd96d2207e21c966063e1635b1063cd7787b627b6f07305315dd73d9c679e", size = 33019667, upload-time = "2026-02-23T00:20:17.208Z" }, + { url = "https://files.pythonhosted.org/packages/f3/c3/2d834a5ac7bf3a0c806ad1508efc02dda3c8c61472a56132d7894c312dea/scipy-1.17.1-cp313-cp313t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:74cbb80d93260fe2ffa334efa24cb8f2f0f622a9b9febf8b483c0b865bfb3475", size = 35264159, upload-time = "2026-02-23T00:20:23.087Z" }, + { url = "https://files.pythonhosted.org/packages/4d/77/d3ed4becfdbd217c52062fafe35a72388d1bd82c2d0ba5ca19d6fcc93e11/scipy-1.17.1-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:dbc12c9f3d185f5c737d801da555fb74b3dcfa1a50b66a1a93e09190f41fab50", size = 35102771, upload-time = "2026-02-23T00:20:28.636Z" }, + { url = "https://files.pythonhosted.org/packages/bd/12/d19da97efde68ca1ee5538bb261d5d2c062f0c055575128f11a2730e3ac1/scipy-1.17.1-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:94055a11dfebe37c656e70317e1996dc197e1a15bbcc351bcdd4610e128fe1ca", size = 37665910, upload-time = "2026-02-23T00:20:34.743Z" }, + { url = "https://files.pythonhosted.org/packages/ef/f2/7cdb8eb308a1a6ae1e19f945913c82c23c0c442a462a46480ce487fdc0ac/scipy-1.17.1-cp314-cp314-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:adb2642e060a6549c343603a3851ba76ef0b74cc8c079a9a58121c7ec9fe2350", size = 32957007, upload-time = "2026-02-23T00:21:19.663Z" }, + { url = "https://files.pythonhosted.org/packages/0b/2e/7eea398450457ecb54e18e9d10110993fa65561c4f3add5e8eccd2b9cd41/scipy-1.17.1-cp314-cp314-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:eee2cfda04c00a857206a4330f0c5e3e56535494e30ca445eb19ec624ae75118", size = 35221333, upload-time = "2026-02-23T00:21:25.278Z" }, + { url = "https://files.pythonhosted.org/packages/d9/77/5b8509d03b77f093a0d52e606d3c4f79e8b06d1d38c441dacb1e26cacf46/scipy-1.17.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:d2650c1fb97e184d12d8ba010493ee7b322864f7d3d00d3f9bb97d9c21de4068", size = 35042066, upload-time = "2026-02-23T00:21:31.358Z" }, + { url = "https://files.pythonhosted.org/packages/f9/df/18f80fb99df40b4070328d5ae5c596f2f00fffb50167e31439e932f29e7d/scipy-1.17.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:08b900519463543aa604a06bec02461558a6e1cef8fdbb8098f77a48a83c8118", size = 37612763, upload-time = "2026-02-23T00:21:37.247Z" }, + { url = "https://files.pythonhosted.org/packages/86/f1/3383beb9b5d0dbddd030335bf8a8b32d4317185efe495374f134d8be6cce/scipy-1.17.1-cp314-cp314t-manylinux_2_27_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e3dcd57ab780c741fde8dc68619de988b966db759a3c3152e8e9142c26295ad", size = 33030397, upload-time = "2026-02-23T00:22:01.404Z" }, + { url = "https://files.pythonhosted.org/packages/41/68/8f21e8a65a5a03f25a79165ec9d2b28c00e66dc80546cf5eb803aeeff35b/scipy-1.17.1-cp314-cp314t-manylinux_2_27_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:a9956e4d4f4a301ebf6cde39850333a6b6110799d470dbbb1e25326ac447f52a", size = 35281163, upload-time = "2026-02-23T00:22:07.024Z" }, + { url = "https://files.pythonhosted.org/packages/84/8d/c8a5e19479554007a5632ed7529e665c315ae7492b4f946b0deb39870e39/scipy-1.17.1-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:a4328d245944d09fd639771de275701ccadf5f781ba0ff092ad141e017eccda4", size = 35116291, upload-time = "2026-02-23T00:22:12.585Z" }, + { url = "https://files.pythonhosted.org/packages/52/52/e57eceff0e342a1f50e274264ed47497b59e6a4e3118808ee58ddda7b74a/scipy-1.17.1-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a77cbd07b940d326d39a1d1b37817e2ee4d79cb30e7338f3d0cddffae70fcaa2", size = 37682317, upload-time = "2026-02-23T00:22:18.513Z" }, +] + +[[package]] +name = "seaborn" +version = "0.13.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "matplotlib", marker = "sys_platform == 'linux'" }, + { name = "numpy", marker = "sys_platform == 'linux'" }, + { name = "pandas", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/86/59/a451d7420a77ab0b98f7affa3a1d78a313d2f7281a57afb1a34bae8ab412/seaborn-0.13.2.tar.gz", hash = "sha256:93e60a40988f4d65e9f4885df477e2fdaff6b73a9ded434c1ab356dd57eefff7", size = 1457696, upload-time = "2024-01-25T13:21:52.551Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/83/11/00d3c3dfc25ad54e731d91449895a79e4bf2384dc3ac01809010ba88f6d5/seaborn-0.13.2-py3-none-any.whl", hash = "sha256:636f8336facf092165e27924f223d3c62ca560b1f2bb5dff7ab7fad265361987", size = 294914, upload-time = "2024-01-25T13:21:49.598Z" }, +] + +[[package]] +name = "secretstorage" +version = "3.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "cryptography", marker = "sys_platform == 'linux'" }, + { name = "jeepney", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/1c/03/e834bcd866f2f8a49a85eaff47340affa3bfa391ee9912a952a1faa68c7b/secretstorage-3.5.0.tar.gz", hash = "sha256:f04b8e4689cbce351744d5537bf6b1329c6fc68f91fa666f60a380edddcd11be", size = 19884, upload-time = "2025-11-23T19:02:53.191Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/46/f5af3402b579fd5e11573ce652019a67074317e18c1935cc0b4ba9b35552/secretstorage-3.5.0-py3-none-any.whl", hash = "sha256:0ce65888c0725fcb2c5bc0fdb8e5438eece02c523557ea40ce0703c266248137", size = 15554, upload-time = "2025-11-23T19:02:51.545Z" }, +] + +[[package]] +name = "send2trash" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c5/f0/184b4b5f8d00f2a92cf96eec8967a3d550b52cf94362dad1100df9e48d57/send2trash-2.1.0.tar.gz", hash = "sha256:1c72b39f09457db3c05ce1d19158c2cbef4c32b8bedd02c155e49282b7ea7459", size = 17255, upload-time = "2026-01-14T06:27:36.056Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/1c/78/504fdd027da3b84ff1aecd9f6957e65f35134534ccc6da8628eb71e76d3f/send2trash-2.1.0-py3-none-any.whl", hash = "sha256:0da2f112e6d6bb22de6aa6daa7e144831a4febf2a87261451c4ad849fe9a873c", size = 17610, upload-time = "2026-01-14T06:27:35.218Z" }, +] + +[[package]] +name = "setuptools" +version = "83.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/34/26/f5d29e25ffdb535afef2d35cdb55b325298f96debd670da4c325e08d70f4/setuptools-83.0.0.tar.gz", hash = "sha256:025bccbbf0fa05b6192bc64ae1e7b16e001fd6d6d4d5de03c97b1c1ade523bef", size = 1154254, upload-time = "2026-07-04T15:31:22.699Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/40/e1e72872c6354b306daef1703549e8e83b4d43cfea356311bf722a043752/setuptools-83.0.0-py3-none-any.whl", hash = "sha256:29b23c360f22f414dc7336bb39178cc7bcbf6021ed2733cde173f09dba19abb3", size = 1008090, upload-time = "2026-07-04T15:31:20.885Z" }, +] + +[[package]] +name = "shear-psf-leakage" +version = "0.2.1" +source = { git = "https://github.com/CosmoStat/shear_psf_leakage.git?rev=develop#0b3c17523b77760c9259be15ba5bbba99d575d0a" } +dependencies = [ + { name = "camb", marker = "sys_platform == 'linux'" }, + { name = "cs-util", marker = "sys_platform == 'linux'" }, + { name = "emcee", marker = "sys_platform == 'linux'" }, + { name = "getdist", marker = "sys_platform == 'linux'" }, + { name = "gsl", marker = "sys_platform == 'linux'" }, + { name = "jupyter", marker = "sys_platform == 'linux'" }, + { name = "jupyter-server", marker = "sys_platform == 'linux'" }, + { name = "jupyterlab", marker = "sys_platform == 'linux'" }, + { name = "jupytext", marker = "sys_platform == 'linux'" }, + { name = "lenspack", marker = "sys_platform == 'linux'" }, + { name = "lmfit", marker = "sys_platform == 'linux'" }, + { name = "matplotlib", marker = "sys_platform == 'linux'" }, + { name = "notebook", marker = "sys_platform == 'linux'" }, + { name = "pandas", marker = "sys_platform == 'linux'" }, + { name = "pyccl", marker = "sys_platform == 'linux'" }, + { name = "pyyaml", marker = "sys_platform == 'linux'" }, + { name = "scipy", marker = "sys_platform == 'linux'" }, + { name = "stats", marker = "sys_platform == 'linux'" }, + { name = "swig", marker = "sys_platform == 'linux'" }, + { name = "tornado", marker = "sys_platform == 'linux'" }, + { name = "tqdm", marker = "sys_platform == 'linux'" }, + { name = "treecorr", marker = "sys_platform == 'linux'" }, + { name = "uncertainties", marker = "sys_platform == 'linux'" }, +] + +[[package]] +name = "six" +version = "1.17.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, +] + +[[package]] +name = "skyproj" +version = "2.5.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "astropy", marker = "sys_platform == 'linux'" }, + { name = "healsparse", marker = "sys_platform == 'linux'" }, + { name = "hpgeom", marker = "sys_platform == 'linux'" }, + { name = "matplotlib", marker = "sys_platform == 'linux'" }, + { name = "numpy", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/90/cf/5158151ae6fc60459f430451b612a4bf2da07ebff2a9f52a37e73715a5ee/skyproj-2.5.0.tar.gz", hash = "sha256:cb8d5115927ca43cacdb6d92f00bb4fcc8563ee71028f755203ce1752e67c140", size = 8521587, upload-time = "2026-06-26T19:51:15.378Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a8/b1/1d86ee4ae4ae7a47e31cc770dc83057388ef16311498283ca90046b3bd04/skyproj-2.5.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4cbfcbd4d3d600557ab19bb5cf79b750ec552da054e3be781bce88e996b9955d", size = 4146686, upload-time = "2026-06-26T19:51:04.011Z" }, + { url = "https://files.pythonhosted.org/packages/6e/e9/f2dd235dcb9f6c3b2fec36ef04d7dd36aef4daf9afc4ab4390d6230c96dc/skyproj-2.5.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:78618084c9362b62ddbfd336ca1864c94d99e2a1f26d2fbf3466fd19dc702c58", size = 4146630, upload-time = "2026-06-26T19:51:10.552Z" }, +] + +[[package]] +name = "slicerator" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0c/52/f38586b82b2935f8b59a09b0a79c545a22ed062e728c9418bafeb51f61e0/slicerator-1.1.0.tar.gz", hash = "sha256:44010a7f5cd87680c07213b5cabe81d1fb71252962943e5373ee7d14605d6046", size = 38283, upload-time = "2022-04-07T18:54:08.17Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e8/ae/fa6cd331b364ad2bbc31652d025f5747d89cbb75576733dfdf8efe3e4d62/slicerator-1.1.0-py3-none-any.whl", hash = "sha256:167668d48c6d3a5ba0bd3d54b2688e81ee267dc20aef299e547d711e6f3c441a", size = 10274, upload-time = "2022-04-07T18:54:07.029Z" }, +] + +[[package]] +name = "smart-open" +version = "7.7.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "wrapt", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/db/c6/22e7a2acd5d27941e85e0d7ede398da5abe2e4677d2265c924157247c32e/smart_open-7.7.1.tar.gz", hash = "sha256:9414ba5733e28309f29b28a303b0f1054ad23fe0275f1a1b600c80a724f4bd1a", size = 54952, upload-time = "2026-06-26T07:56:35.309Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8a/c5/14732c140fa0af0e59345949eaf9016c75ad3f076586f2413e3d3566a8da/smart_open-7.7.1-py3-none-any.whl", hash = "sha256:cb62dc45f519bf39b612564d326d2a17556f3a6056e3c3a86a07215d670d45bc", size = 65061, upload-time = "2026-06-26T07:56:33.685Z" }, +] + +[[package]] +name = "smmap" +version = "5.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1f/ea/49c993d6dfdd7338c9b1000a0f36817ed7ec84577ae2e52f890d1a4ff909/smmap-5.0.3.tar.gz", hash = "sha256:4d9debb8b99007ae47165abc08670bd74cb74b5227dda7f643eccc4e9eb5642c", size = 22506, upload-time = "2026-03-09T03:43:26.1Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c1/d4/59e74daffcb57a07668852eeeb6035af9f32cbfd7a1d2511f17d2fe6a738/smmap-5.0.3-py3-none-any.whl", hash = "sha256:c106e05d5a61449cf6ba9a1e650227ecfb141590d2a98412103ff35d89fc7b2f", size = 24390, upload-time = "2026-03-09T03:43:24.361Z" }, +] + +[[package]] +name = "snakemake" +version = "9.23.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "conda-inject", marker = "sys_platform == 'linux'" }, + { name = "configargparse", marker = "sys_platform == 'linux'" }, + { name = "connection-pool", marker = "sys_platform == 'linux'" }, + { name = "docutils", marker = "sys_platform == 'linux'" }, + { name = "dpath", marker = "sys_platform == 'linux'" }, + { name = "gitpython", marker = "sys_platform == 'linux'" }, + { name = "humanfriendly", marker = "sys_platform == 'linux'" }, + { name = "immutables", marker = "sys_platform == 'linux'" }, + { name = "jinja2", marker = "sys_platform == 'linux'" }, + { name = "jsonschema", marker = "sys_platform == 'linux'" }, + { name = "nbformat", marker = "sys_platform == 'linux'" }, + { name = "packaging", marker = "sys_platform == 'linux'" }, + { name = "platformdirs", marker = "sys_platform == 'linux'" }, + { name = "psutil", marker = "sys_platform == 'linux'" }, + { name = "pulp", marker = "sys_platform == 'linux'" }, + { name = "pyyaml", marker = "sys_platform == 'linux'" }, + { name = "referencing", marker = "sys_platform == 'linux'" }, + { name = "requests", marker = "sys_platform == 'linux'" }, + { name = "smart-open", marker = "sys_platform == 'linux'" }, + { name = "snakemake-interface-common", marker = "sys_platform == 'linux'" }, + { name = "snakemake-interface-executor-plugins", marker = "sys_platform == 'linux'" }, + { name = "snakemake-interface-logger-plugins", marker = "sys_platform == 'linux'" }, + { name = "snakemake-interface-report-plugins", marker = "sys_platform == 'linux'" }, + { name = "snakemake-interface-scheduler-plugins", marker = "sys_platform == 'linux'" }, + { name = "snakemake-interface-storage-plugins", marker = "sys_platform == 'linux'" }, + { name = "sqlmodel", marker = "sys_platform == 'linux'" }, + { name = "tabulate", marker = "sys_platform == 'linux'" }, + { name = "tenacity", marker = "sys_platform == 'linux'" }, + { name = "throttler", marker = "sys_platform == 'linux'" }, + { name = "wrapt", marker = "sys_platform == 'linux'" }, + { name = "yte", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9e/c2/45aa858e55edbb7dbc243ed60859f4f3d92d63ecdd67a80632aa3659fe6b/snakemake-9.23.1.tar.gz", hash = "sha256:ef8d698bfce66a6669cc29df7e344b0b367fd90956c725e5ae0a79a556e8e93f", size = 6802587, upload-time = "2026-06-18T09:42:57.653Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/65/2cb1c99117746bea8aff34dc434703f8f23d3876860e2ff3ebeccb754b0f/snakemake-9.23.1-py3-none-any.whl", hash = "sha256:9fdbfff25f1b442cdf7906ca06b465fc24b9bf72e2d51514fb93d83e3f8aeb35", size = 1162133, upload-time = "2026-06-18T09:42:55.541Z" }, +] + +[[package]] +name = "snakemake-interface-common" +version = "1.23.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "argparse-dataclass", marker = "sys_platform == 'linux'" }, + { name = "configargparse", marker = "sys_platform == 'linux'" }, + { name = "packaging", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/89/c3/592f832f6e5d2d31f749392e48e8401b7625dec668d3d365d8d28f2b6c30/snakemake_interface_common-1.23.0.tar.gz", hash = "sha256:6ed14531a461417659364a0dd0acc51b786af4e26fc15cc5e00ff3d9fcaffacc", size = 13960, upload-time = "2026-03-08T21:54:29.251Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/28/90/a4a3652e832667917383f8d34112bdb37b78a6d14efc049e22a2c8192524/snakemake_interface_common-1.23.0-py3-none-any.whl", hash = "sha256:43bb10102d07149f27787dfc65a7342b86ff772973e7f9ca4940c89cb412a11e", size = 17162, upload-time = "2026-03-08T21:54:28.074Z" }, +] + +[[package]] +name = "snakemake-interface-executor-plugins" +version = "9.4.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "argparse-dataclass", marker = "sys_platform == 'linux'" }, + { name = "snakemake-interface-common", marker = "sys_platform == 'linux'" }, + { name = "throttler", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/54/50/de06b284c45a8e94fb8e4a12d5235065e78b49b8f84329dc10fe39f4b7dd/snakemake_interface_executor_plugins-9.4.0.tar.gz", hash = "sha256:9d4138897beacbaadaedad94b63f948eaeb604b7fc78f9cf65ac57f090f2c066", size = 16549, upload-time = "2026-03-08T17:04:02.644Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5c/2c/4422eb14884bb4955ce65819799ff6452dcd3aa5f8e158540a287877bbcf/snakemake_interface_executor_plugins-9.4.0-py3-none-any.whl", hash = "sha256:d335c093185897e4e3654a39bab3a6f1c57dc1a54f998c92bd2d88640ab4a05e", size = 22567, upload-time = "2026-03-08T17:04:01.296Z" }, +] + +[[package]] +name = "snakemake-interface-logger-plugins" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "snakemake-interface-common", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a7/0c/3fa5d592663c65669a867526604aadc6fbc235fb9284e94b49c0ef59aa41/snakemake_interface_logger_plugins-2.1.0.tar.gz", hash = "sha256:c89a00d2a398490cecd91b6dc6db8049cba93712d82e1d8f3000f3040bf3791c", size = 15917, upload-time = "2026-05-20T15:12:35.259Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/aa/43/cfdaf562303012024c8f48efebdfe258eef3d895665bd7e0000fdeb2411d/snakemake_interface_logger_plugins-2.1.0-py3-none-any.whl", hash = "sha256:601e3e0770dd1b460c1dcb7bd33f4fc2eb8af5016634b80d985cb993f674ef46", size = 14313, upload-time = "2026-05-20T15:12:34.186Z" }, +] + +[[package]] +name = "snakemake-interface-report-plugins" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "snakemake-interface-common", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/18/d6/6160ed98de665d6871dd356597dbf726688cc786e88668359ca37b7d9f54/snakemake_interface_report_plugins-1.3.0.tar.gz", hash = "sha256:fc9495298bec4e69721ab8afe6d6d88a86966fda2eeb003db56b9a88b86d5934", size = 4283, upload-time = "2025-10-31T10:52:36.55Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f0/f0/df73f6abc9b5910e43612ae28c7b6f666af80c4edd46a216ef47599ab6cb/snakemake_interface_report_plugins-1.3.0-py3-none-any.whl", hash = "sha256:78da3931f70e79eef51e5645a40b172929e555fe4d86ff45d6b856e521a379db", size = 7251, upload-time = "2025-10-31T10:52:35.474Z" }, +] + +[[package]] +name = "snakemake-interface-scheduler-plugins" +version = "2.0.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "snakemake-interface-common", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/88/d9/d480807d2cfc2d132bc760d877d45ec8fbe620a24200ec4d2697c4a26031/snakemake_interface_scheduler_plugins-2.0.2.tar.gz", hash = "sha256:2797e8fa9019d983132c2b403f14d6fcd3c5ad4c8d8a66b984b4740a71cacc46", size = 8642, upload-time = "2025-10-20T13:58:12.988Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0e/d0/f4e9894c8aaf37efe3bf1afe15ee3cf0546d82b2713a589e266ee47bf2ef/snakemake_interface_scheduler_plugins-2.0.2-py3-none-any.whl", hash = "sha256:b9ddfa508bd480711de1770dfb24f3b813cfa3cd0f862f0127ef721ae5346915", size = 10766, upload-time = "2025-10-20T13:58:11.898Z" }, +] + +[[package]] +name = "snakemake-interface-storage-plugins" +version = "4.4.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "humanfriendly", marker = "sys_platform == 'linux'" }, + { name = "snakemake-interface-common", marker = "sys_platform == 'linux'" }, + { name = "tenacity", marker = "sys_platform == 'linux'" }, + { name = "throttler", marker = "sys_platform == 'linux'" }, + { name = "wrapt", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/93/6e/f3c5b2d621fd6a6b78d8cfc01fef6b926fe2c277f5ed77c5e4deeacb94eb/snakemake_interface_storage_plugins-4.4.1.tar.gz", hash = "sha256:b2b5bf05318af36955ebf2ce76c921c0fb06904ca98fb30e1657d88b7b7b6945", size = 14924, upload-time = "2026-03-16T11:16:01.075Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b6/49/1f72d8c05d8588f06a61f1af3deb125a4ff8169d2a41f1b839d62c824d1c/snakemake_interface_storage_plugins-4.4.1-py3-none-any.whl", hash = "sha256:6e075f448543cc3d0cb1ee5e6e5a83af9761e7085f3ce0922011685d098f231e", size = 18256, upload-time = "2026-03-16T11:15:59.582Z" }, +] + +[[package]] +name = "snowballstemmer" +version = "3.1.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/f8/0a71edf031f03c40db17503cb8ca78a69a171254e568e7db241b0ab57ea1/snowballstemmer-3.1.1.tar.gz", hash = "sha256:e07bbc54a0d798fe6010a12398422e62a8bfbba95c394fd0956ef58cb4d3e260", size = 123314, upload-time = "2026-06-03T00:56:40.194Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4c/07/2ebca9b11fb9be7340a818d8d6f63feaebb146be2c4afbd6061701d6df6e/snowballstemmer-3.1.1-py3-none-any.whl", hash = "sha256:7e207fa178741da09cdee59d3ecec3827ad5f92b1fc5c9ff3755b639f71f5752", size = 104164, upload-time = "2026-06-03T00:56:38.614Z" }, +] + +[[package]] +name = "soupsieve" +version = "2.8.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/47/2c/0a5f6f8ee0d5589e48c7640213ed5175d52cf540a06725b628cc1a45d6ce/soupsieve-2.8.4.tar.gz", hash = "sha256:e121fd02e975c695e4e9e8774a5ee35d74714b59307868dcc5319ad2d9e3328e", size = 121110, upload-time = "2026-05-24T13:55:57.154Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5e/f5/0c41cb68dcae6b7de4fac4188a3a9589e21fb31df21ea3a2e888db95e6c9/soupsieve-2.8.4-py3-none-any.whl", hash = "sha256:e7e6b0769c8f51ed59acab6e994b00621096cfb1c640a7509295987388fbaf65", size = 37304, upload-time = "2026-05-24T13:55:55.406Z" }, +] + +[[package]] +name = "sp-validation" +version = "0.6.0" +source = { virtual = "." } +dependencies = [ + { name = "adjusttext", marker = "sys_platform == 'linux'" }, + { name = "astropy", marker = "sys_platform == 'linux'" }, + { name = "camb", marker = "sys_platform == 'linux'" }, + { name = "clmm", marker = "sys_platform == 'linux'" }, + { name = "colorama", marker = "sys_platform == 'linux'" }, + { name = "cosmo-numba", marker = "sys_platform == 'linux'" }, + { name = "cs-util", marker = "sys_platform == 'linux'" }, + { name = "emcee", marker = "sys_platform == 'linux'" }, + { name = "getdist", marker = "sys_platform == 'linux'" }, + { name = "h5py", marker = "sys_platform == 'linux'" }, + { name = "healpy", marker = "sys_platform == 'linux'" }, + { name = "healsparse", marker = "sys_platform == 'linux'" }, + { name = "importlib-metadata", marker = "sys_platform == 'linux'" }, + { name = "joblib", marker = "sys_platform == 'linux'" }, + { name = "jupyter", marker = "sys_platform == 'linux'" }, + { name = "jupyterlab", marker = "sys_platform == 'linux'" }, + { name = "jupytext", marker = "sys_platform == 'linux'" }, + { name = "lenspack", marker = "sys_platform == 'linux'" }, + { name = "lmfit", marker = "sys_platform == 'linux'" }, + { name = "matplotlib", marker = "sys_platform == 'linux'" }, + { name = "numba", marker = "sys_platform == 'linux'" }, + { name = "numexpr", marker = "sys_platform == 'linux'" }, + { name = "numpy", marker = "sys_platform == 'linux'" }, + { name = "opencv-python-headless", marker = "sys_platform == 'linux'" }, + { name = "pandas", marker = "sys_platform == 'linux'" }, + { name = "pyarrow", marker = "sys_platform == 'linux'" }, + { name = "pyccl", marker = "sys_platform == 'linux'" }, + { name = "pymaster", marker = "sys_platform == 'linux'" }, + { name = "pyyaml", marker = "sys_platform == 'linux'" }, + { name = "regions", marker = "sys_platform == 'linux'" }, + { name = "reproject", marker = "sys_platform == 'linux'" }, + { name = "scipy", marker = "sys_platform == 'linux'" }, + { name = "seaborn", marker = "sys_platform == 'linux'" }, + { name = "shear-psf-leakage", marker = "sys_platform == 'linux'" }, + { name = "skyproj", marker = "sys_platform == 'linux'" }, + { name = "statsmodels", marker = "sys_platform == 'linux'" }, + { name = "tqdm", marker = "sys_platform == 'linux'" }, + { name = "treecorr", marker = "sys_platform == 'linux'" }, + { name = "uncertainties", marker = "sys_platform == 'linux'" }, +] + +[package.optional-dependencies] +develop = [ + { name = "myst-parser", marker = "sys_platform == 'linux'" }, + { name = "numpydoc", marker = "sys_platform == 'linux'" }, + { name = "pytest", marker = "sys_platform == 'linux'" }, + { name = "pytest-cov", marker = "sys_platform == 'linux'" }, + { name = "ruff", marker = "sys_platform == 'linux'" }, + { name = "sphinx", marker = "sys_platform == 'linux'" }, + { name = "sphinxawesome-theme", marker = "sys_platform == 'linux'" }, + { name = "sphinxcontrib-bibtex", marker = "sys_platform == 'linux'" }, +] +docs = [ + { name = "myst-parser", marker = "sys_platform == 'linux'" }, + { name = "numpydoc", marker = "sys_platform == 'linux'" }, + { name = "sphinx", marker = "sys_platform == 'linux'" }, + { name = "sphinxawesome-theme", marker = "sys_platform == 'linux'" }, + { name = "sphinxcontrib-bibtex", marker = "sys_platform == 'linux'" }, +] +glass = [ + { name = "cosmology", marker = "sys_platform == 'linux'" }, + { name = "fitsio", marker = "sys_platform == 'linux'" }, + { name = "glass", marker = "sys_platform == 'linux'" }, + { name = "glass-ext-camb", marker = "sys_platform == 'linux'" }, +] +test = [ + { name = "pytest", marker = "sys_platform == 'linux'" }, + { name = "pytest-cov", marker = "sys_platform == 'linux'" }, + { name = "ruff", marker = "sys_platform == 'linux'" }, +] +workflow = [ + { name = "mpi4py", marker = "sys_platform == 'linux'" }, + { name = "snakemake", marker = "sys_platform == 'linux'" }, +] + +[package.metadata] +requires-dist = [ + { name = "adjusttext" }, + { name = "astropy", specifier = ">=5.0" }, + { name = "camb", specifier = ">=1.6" }, + { name = "clmm" }, + { name = "colorama" }, + { name = "cosmo-numba", git = "https://github.com/aguinot/cosmo-numba.git?rev=main" }, + { name = "cosmology", marker = "extra == 'glass'", specifier = "==2022.10.9" }, + { name = "cs-util", git = "https://github.com/CosmoStat/cs_util.git?rev=develop" }, + { name = "emcee" }, + { name = "fitsio", marker = "extra == 'glass'" }, + { name = "getdist", git = "https://github.com/benabed/getdist.git?rev=113cd22a9a0d013b6f72fe734be81f260f3d3be5" }, + { name = "glass", marker = "extra == 'glass'", specifier = "==2025.1" }, + { name = "glass-ext-camb", marker = "extra == 'glass'", specifier = "==2023.6" }, + { name = "h5py" }, + { name = "healpy" }, + { name = "healsparse" }, + { name = "importlib-metadata" }, + { name = "joblib", specifier = ">=0.13" }, + { name = "jupyter" }, + { name = "jupyterlab" }, + { name = "jupytext", specifier = ">=1.15" }, + { name = "lenspack" }, + { name = "lmfit" }, + { name = "matplotlib" }, + { name = "mpi4py", marker = "extra == 'workflow'" }, + { name = "myst-parser", marker = "extra == 'docs'", specifier = ">=4.0" }, + { name = "numba" }, + { name = "numexpr" }, + { name = "numpy", specifier = ">=2.0" }, + { name = "numpydoc", marker = "extra == 'docs'", specifier = ">=1.8" }, + { name = "opencv-python-headless" }, + { name = "pandas" }, + { name = "pyarrow" }, + { name = "pyccl" }, + { name = "pymaster" }, + { name = "pytest", marker = "extra == 'test'" }, + { name = "pytest-cov", marker = "extra == 'test'" }, + { name = "pyyaml" }, + { name = "regions" }, + { name = "reproject" }, + { name = "ruff", marker = "extra == 'test'" }, + { name = "scipy", specifier = "<1.18" }, + { name = "seaborn" }, + { name = "shear-psf-leakage", git = "https://github.com/CosmoStat/shear_psf_leakage.git?rev=develop" }, + { name = "skyproj" }, + { name = "snakemake", marker = "extra == 'workflow'" }, + { name = "sp-validation", extras = ["test", "docs"], marker = "extra == 'develop'" }, + { name = "sphinx", marker = "extra == 'docs'", specifier = ">=8.0" }, + { name = "sphinxawesome-theme", marker = "extra == 'docs'", specifier = ">=5.3,!=6.0.3" }, + { name = "sphinxcontrib-bibtex", marker = "extra == 'docs'", specifier = ">=2.6" }, + { name = "statsmodels" }, + { name = "tqdm" }, + { name = "treecorr", specifier = ">=5.0" }, + { name = "uncertainties" }, +] +provides-extras = ["test", "docs", "glass", "workflow", "develop"] + +[[package]] +name = "sphinx" +version = "9.1.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "alabaster", marker = "sys_platform == 'linux'" }, + { name = "babel", marker = "sys_platform == 'linux'" }, + { name = "docutils", marker = "sys_platform == 'linux'" }, + { name = "imagesize", marker = "sys_platform == 'linux'" }, + { name = "jinja2", marker = "sys_platform == 'linux'" }, + { name = "packaging", marker = "sys_platform == 'linux'" }, + { name = "pygments", marker = "sys_platform == 'linux'" }, + { name = "requests", marker = "sys_platform == 'linux'" }, + { name = "roman-numerals", marker = "sys_platform == 'linux'" }, + { name = "snowballstemmer", marker = "sys_platform == 'linux'" }, + { name = "sphinxcontrib-applehelp", marker = "sys_platform == 'linux'" }, + { name = "sphinxcontrib-devhelp", marker = "sys_platform == 'linux'" }, + { name = "sphinxcontrib-htmlhelp", marker = "sys_platform == 'linux'" }, + { name = "sphinxcontrib-jsmath", marker = "sys_platform == 'linux'" }, + { name = "sphinxcontrib-qthelp", marker = "sys_platform == 'linux'" }, + { name = "sphinxcontrib-serializinghtml", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cd/bd/f08eb0f4eed5c83f1ba2a3bd18f7745a2b1525fad70660a1c00224ec468a/sphinx-9.1.0.tar.gz", hash = "sha256:7741722357dd75f8190766926071fed3bdc211c74dd2d7d4df5404da95930ddb", size = 8718324, upload-time = "2025-12-31T15:09:27.646Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/73/f7/b1884cb3188ab181fc81fa00c266699dab600f927a964df02ec3d5d1916a/sphinx-9.1.0-py3-none-any.whl", hash = "sha256:c84fdd4e782504495fe4f2c0b3413d6c2bf388589bb352d439b2a3bb99991978", size = 3921742, upload-time = "2025-12-31T15:09:25.561Z" }, +] + +[[package]] +name = "sphinxawesome-theme" +version = "6.0.5" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "beautifulsoup4", marker = "sys_platform == 'linux'" }, + { name = "sphinx", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9a/3f/ba7f8dc2837c0ac362127c6cd491578c23ac4d4e8cc6a37726531be29256/sphinxawesome_theme-6.0.5.tar.gz", hash = "sha256:ed3d82b7f0e30e3d6f38f5245d89775e9472a80a45ffd73d6a0a4b9d05ac5736", size = 343775, upload-time = "2026-06-15T15:09:36.094Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2d/5c/31521b6a35410cdced12af394b715387537a262bdd1bcf08b2a34a9a4df9/sphinxawesome_theme-6.0.5-py3-none-any.whl", hash = "sha256:c18e60b06f164f181e3ef7540a4a237f1cf4e82d8909a964e5c65e6e8293f51c", size = 376755, upload-time = "2026-06-15T15:09:34.523Z" }, +] + +[[package]] +name = "sphinxcontrib-applehelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ba/6e/b837e84a1a704953c62ef8776d45c3e8d759876b4a84fe14eba2859106fe/sphinxcontrib_applehelp-2.0.0.tar.gz", hash = "sha256:2f29ef331735ce958efa4734873f084941970894c6090408b079c61b2e1c06d1", size = 20053, upload-time = "2024-07-29T01:09:00.465Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5d/85/9ebeae2f76e9e77b952f4b274c27238156eae7979c5421fba91a28f4970d/sphinxcontrib_applehelp-2.0.0-py3-none-any.whl", hash = "sha256:4cd3f0ec4ac5dd9c17ec65e9ab272c9b867ea77425228e68ecf08d6b28ddbdb5", size = 119300, upload-time = "2024-07-29T01:08:58.99Z" }, +] + +[[package]] +name = "sphinxcontrib-bibtex" +version = "2.7.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "docutils", marker = "sys_platform == 'linux'" }, + { name = "pybtex", marker = "sys_platform == 'linux'" }, + { name = "pybtex-docutils", marker = "sys_platform == 'linux'" }, + { name = "sphinx", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/15/6a/8e0b2c2420286389e7fed78ff361ec30e2f1d58c8560af8d64df5e7b61e0/sphinxcontrib_bibtex-2.7.0.tar.gz", hash = "sha256:fee700f7aae29bb8f654c62913f00d34ac44fc0b8ca0fa67ac922ff4453addee", size = 120669, upload-time = "2026-05-06T09:29:24.935Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/52/c0/d28e62407f4733bbe0169287bc012f0ac3b4a2021066b285570654119c8b/sphinxcontrib_bibtex-2.7.0-py3-none-any.whl", hash = "sha256:28cf0ec7a957d1c7548d5749317ed472ce877e1b629f430f88e3789aa51f87b1", size = 40287, upload-time = "2026-05-06T09:29:23.253Z" }, +] + +[[package]] +name = "sphinxcontrib-devhelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/d2/5beee64d3e4e747f316bae86b55943f51e82bb86ecd325883ef65741e7da/sphinxcontrib_devhelp-2.0.0.tar.gz", hash = "sha256:411f5d96d445d1d73bb5d52133377b4248ec79db5c793ce7dbe59e074b4dd1ad", size = 12967, upload-time = "2024-07-29T01:09:23.417Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/35/7a/987e583882f985fe4d7323774889ec58049171828b58c2217e7f79cdf44e/sphinxcontrib_devhelp-2.0.0-py3-none-any.whl", hash = "sha256:aefb8b83854e4b0998877524d1029fd3e6879210422ee3780459e28a1f03a8a2", size = 82530, upload-time = "2024-07-29T01:09:21.945Z" }, +] + +[[package]] +name = "sphinxcontrib-htmlhelp" +version = "2.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/43/93/983afd9aa001e5201eab16b5a444ed5b9b0a7a010541e0ddfbbfd0b2470c/sphinxcontrib_htmlhelp-2.1.0.tar.gz", hash = "sha256:c9e2916ace8aad64cc13a0d233ee22317f2b9025b9cf3295249fa985cc7082e9", size = 22617, upload-time = "2024-07-29T01:09:37.889Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0a/7b/18a8c0bcec9182c05a0b3ec2a776bba4ead82750a55ff798e8d406dae604/sphinxcontrib_htmlhelp-2.1.0-py3-none-any.whl", hash = "sha256:166759820b47002d22914d64a075ce08f4c46818e17cfc9470a9786b759b19f8", size = 98705, upload-time = "2024-07-29T01:09:36.407Z" }, +] + +[[package]] +name = "sphinxcontrib-jsmath" +version = "1.0.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b2/e8/9ed3830aeed71f17c026a07a5097edcf44b692850ef215b161b8ad875729/sphinxcontrib-jsmath-1.0.1.tar.gz", hash = "sha256:a9925e4a4587247ed2191a22df5f6970656cb8ca2bd6284309578f2153e0c4b8", size = 5787, upload-time = "2019-01-21T16:10:16.347Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c2/42/4c8646762ee83602e3fb3fbe774c2fac12f317deb0b5dbeeedd2d3ba4b77/sphinxcontrib_jsmath-1.0.1-py2.py3-none-any.whl", hash = "sha256:2ec2eaebfb78f3f2078e73666b1415417a116cc848b72e5172e596c871103178", size = 5071, upload-time = "2019-01-21T16:10:14.333Z" }, +] + +[[package]] +name = "sphinxcontrib-qthelp" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/68/bc/9104308fc285eb3e0b31b67688235db556cd5b0ef31d96f30e45f2e51cae/sphinxcontrib_qthelp-2.0.0.tar.gz", hash = "sha256:4fe7d0ac8fc171045be623aba3e2a8f613f8682731f9153bb2e40ece16b9bbab", size = 17165, upload-time = "2024-07-29T01:09:56.435Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/83/859ecdd180cacc13b1f7e857abf8582a64552ea7a061057a6c716e790fce/sphinxcontrib_qthelp-2.0.0-py3-none-any.whl", hash = "sha256:b18a828cdba941ccd6ee8445dbe72ffa3ef8cbe7505d8cd1fa0d42d3f2d5f3eb", size = 88743, upload-time = "2024-07-29T01:09:54.885Z" }, +] + +[[package]] +name = "sphinxcontrib-serializinghtml" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/3b/44/6716b257b0aa6bfd51a1b31665d1c205fb12cb5ad56de752dfa15657de2f/sphinxcontrib_serializinghtml-2.0.0.tar.gz", hash = "sha256:e9d912827f872c029017a53f0ef2180b327c3f7fd23c87229f7a8e8b70031d4d", size = 16080, upload-time = "2024-07-29T01:10:09.332Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/52/a7/d2782e4e3f77c8450f727ba74a8f12756d5ba823d81b941f1b04da9d033a/sphinxcontrib_serializinghtml-2.0.0-py3-none-any.whl", hash = "sha256:6e2cb0eef194e10c27ec0023bfeb25badbbb5868244cf5bc5bdc04e4464bf331", size = 92072, upload-time = "2024-07-29T01:10:08.203Z" }, +] + +[[package]] +name = "sqlalchemy" +version = "2.0.51" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "greenlet", marker = "(platform_machine == 'AMD64' and sys_platform == 'linux') or (platform_machine == 'WIN32' and sys_platform == 'linux') or (platform_machine == 'aarch64' and sys_platform == 'linux') or (platform_machine == 'amd64' and sys_platform == 'linux') or (platform_machine == 'ppc64le' and sys_platform == 'linux') or (platform_machine == 'win32' and sys_platform == 'linux') or (platform_machine == 'x86_64' and sys_platform == 'linux')" }, + { name = "typing-extensions", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/02/f1/a7a892f18d4d224e6b26f706531eafccc41e37594d37d304786969ee13cb/sqlalchemy-2.0.51.tar.gz", hash = "sha256:804dccd8a4a6242c4e30ad961e540e18a588f6527202f2d6791b01845d59fdc9", size = 9912201, upload-time = "2026-06-15T15:41:20.012Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/1c/71ee0f8a6b9d7316a1ccd30430b4c62b6c2e36adc96017a4e3a72dce49d6/sqlalchemy-2.0.51-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:581921d849d6e6f994d560389192955e80e2950e18fcdfe2ccea863e01158e6e", size = 3343835, upload-time = "2026-06-15T16:19:42.613Z" }, + { url = "https://files.pythonhosted.org/packages/2b/7c/7ab9f9aadc5944fdd06612484ed7918fe376ad871a5f50404dc1536e0194/sqlalchemy-2.0.51-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1d21ce524ab86c23046e992a5b81cb54c21079c6df6e78b8fc77d77cac70a6b9", size = 3358470, upload-time = "2026-06-15T16:26:38.011Z" }, + { url = "https://files.pythonhosted.org/packages/d0/7d/ff77169fee6186de145a7f2b87006c39638391130abbab2b1f63ac6ea583/sqlalchemy-2.0.51-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c5d98a2709840027f5a347c3af0a7c3d5f6c1ff93af2ca1c54494e23cba8f389", size = 3289874, upload-time = "2026-06-15T16:19:45.212Z" }, + { url = "https://files.pythonhosted.org/packages/6f/3b/6c505903710d781b55bc3141ee34a062bf9745a6b5bc7333305b9ed63b33/sqlalchemy-2.0.51-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:1181256e0f16479691b5616d36375dc2620ad8332b25978763c3d206ad3f3f1d", size = 3321692, upload-time = "2026-06-15T16:26:39.747Z" }, + { url = "https://files.pythonhosted.org/packages/17/6b/2dce8369b199cb855110e056032f94a9f66dacc2237d3d39c115a86eac56/sqlalchemy-2.0.51-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:483b11bd46bf35fc14c52faf338b04300c9e6ce554bce9b11be85bfec3bc3195", size = 3284735, upload-time = "2026-06-15T16:19:46.934Z" }, + { url = "https://files.pythonhosted.org/packages/53/ff/dbc495b8a14da840faffb353857a72d4190113cac33727906fb997047f0f/sqlalchemy-2.0.51-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1bed1ee8b01da6088210aa9412023326fb98a599ba502e6118308601dcbef77f", size = 3302756, upload-time = "2026-06-15T16:26:41.336Z" }, + { url = "https://files.pythonhosted.org/packages/cf/d5/fde8f4dddcf518ee15ab35a7c6a28acc32c8ba548d1d2aa451f96e6dbb0b/sqlalchemy-2.0.51-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:72ca54c952107ba5cd58854b67a5a6268631289d21651a1235396f3b98b47400", size = 3232055, upload-time = "2026-06-15T16:19:49.286Z" }, + { url = "https://files.pythonhosted.org/packages/67/d1/43d3a0ac955a58601c24fa23038b1c55ee3a1ec02c0f96ebb1eae2bcf614/sqlalchemy-2.0.51-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b3e693d15533a45cd5906f0589f9c35090bef6ef45bf1e8195c424aa0ae06a8d", size = 3269850, upload-time = "2026-06-15T16:26:43.017Z" }, + { url = "https://files.pythonhosted.org/packages/23/6b/2e0e38cf75c8780eca78d9b2e78164f8bcfd70125e5caa588ff5cbb9c9f4/sqlalchemy-2.0.51-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c45a496d6bc05dec41dcd4c3a2b183723f47473255c159cd80b503c8f246424d", size = 3282539, upload-time = "2026-06-15T16:19:51.065Z" }, + { url = "https://files.pythonhosted.org/packages/dd/a1/e77854cb5336fd37dc3c6ae3b71de242c98caac5725120be0b526b31cbd0/sqlalchemy-2.0.51-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4004ada0aafe8ae1991b2cd1d99c6d9146126e123bd6f883c260d974aa012e54", size = 3287545, upload-time = "2026-06-15T16:26:44.735Z" }, + { url = "https://files.pythonhosted.org/packages/f6/ab/9e17272fd4dac8df3b83c4fbe52b998a1c9d89a843c8c35ff29b74ff7364/sqlalchemy-2.0.51-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:0f6bcad487aee1c638d707235682fc96f741de00663619881ab235400d03289e", size = 3230929, upload-time = "2026-06-15T16:19:52.625Z" }, + { url = "https://files.pythonhosted.org/packages/02/3c/52f408ea701781caee975606beccc48845f2aee8711ac29843d612c0306c/sqlalchemy-2.0.51-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:39a76529db6305693d8d4affa58ad5b5e2e18edd62daea628b29b97930b3513d", size = 3252888, upload-time = "2026-06-15T16:26:46.454Z" }, + { url = "https://files.pythonhosted.org/packages/bf/90/a1bb5c7cbba76b7bc1fbd586d0a5479a7bc9c27b4a8298f22ec9423b2bb3/sqlalchemy-2.0.51-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:7c6b36ed71f41942bdcd2ad2522be46bfce09d5705be5640ecf19bbc7660e4b7", size = 3566534, upload-time = "2026-06-15T15:58:35.024Z" }, + { url = "https://files.pythonhosted.org/packages/15/4b/481f1fed30e0e9e8dd24aecbb49f29eb57fe7657ece5cf06ee9b84bb97d8/sqlalchemy-2.0.51-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0c2c62877097e1a0db401fba5cb4debee33265e5b2a55c4ccb489c02c53b4f72", size = 3535844, upload-time = "2026-06-15T16:02:43.973Z" }, + { url = "https://files.pythonhosted.org/packages/02/71/0aa64aeda645510af0a43f7d9ee70932f0d1dc4263aed34c50ee891d9df3/sqlalchemy-2.0.51-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0378d055e9e8cd6ce4d8dff683bdd3d7d413533c4ee51d67a2b1e0f9eacc0f23", size = 3475355, upload-time = "2026-06-15T15:58:36.592Z" }, + { url = "https://files.pythonhosted.org/packages/05/db/6061db32316446135a3abae5f308d144ab988a34234726042da3e58b1c63/sqlalchemy-2.0.51-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:6e46fc36029eff666391e0531e5387b62ce6c4f1d8e50b3fb3099eaca1b42522", size = 3486591, upload-time = "2026-06-15T16:02:45.346Z" }, + { url = "https://files.pythonhosted.org/packages/e2/22/dbf013a12ec759e54a34a119e9e217435b3f71b2dd5c61a7ade0a25dae87/sqlalchemy-2.0.51-py3-none-any.whl", hash = "sha256:bb024d8b621d0be75f4f44ecc7c950450026e76d66dc8f791bb5331d7fed59d5", size = 1944334, upload-time = "2026-06-15T16:09:22.418Z" }, +] + +[[package]] +name = "sqlmodel" +version = "0.0.37" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "pydantic", marker = "sys_platform == 'linux'" }, + { name = "sqlalchemy", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/fb/26/1d2faa0fd5a765267f49751de533adac6b9ff9366c7c6e7692df4f32230f/sqlmodel-0.0.37.tar.gz", hash = "sha256:d2c19327175794faf50b1ee31cc966764f55b1dedefc046450bc5741a3d68352", size = 85527, upload-time = "2026-02-21T16:39:47.038Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/b1/e1/7c8d18e737433f3b5bbe27b56a9072a9fcb36342b48f1bef34b6da1d61f2/sqlmodel-0.0.37-py3-none-any.whl", hash = "sha256:2137a4045ef3fd66a917a7717ada959a1ceb3630d95e1f6aaab39dd2c0aef278", size = 27224, upload-time = "2026-02-21T16:39:47.781Z" }, +] + +[[package]] +name = "stack-data" +version = "0.6.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "asttokens", marker = "sys_platform == 'linux'" }, + { name = "executing", marker = "sys_platform == 'linux'" }, + { name = "pure-eval", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/28/e3/55dcc2cfbc3ca9c29519eb6884dd1415ecb53b0e934862d3559ddcb7e20b/stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9", size = 44707, upload-time = "2023-09-30T13:58:05.479Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f1/7b/ce1eafaf1a76852e2ec9b22edecf1daa58175c090266e9f6c64afcd81d91/stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695", size = 24521, upload-time = "2023-09-30T13:58:03.53Z" }, +] + +[[package]] +name = "stats" +version = "0.1.2a0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/87/43/f2d8d8e2660740ecca9c0fab85a07bc02da27d1fcc5071ee481082888720/stats-0.1.2a.tar.gz", hash = "sha256:854e59fa99f92ce8319c16149ef8e9939dba3e2237bbb0fb6a6094c60155bd4c", size = 127625, upload-time = "2010-12-31T09:02:15.131Z" } + +[[package]] +name = "statsmodels" +version = "0.14.6" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", marker = "sys_platform == 'linux'" }, + { name = "packaging", marker = "sys_platform == 'linux'" }, + { name = "pandas", marker = "sys_platform == 'linux'" }, + { name = "patsy", marker = "sys_platform == 'linux'" }, + { name = "scipy", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/0d/81/e8d74b34f85285f7335d30c5e3c2d7c0346997af9f3debf9a0a9a63de184/statsmodels-0.14.6.tar.gz", hash = "sha256:4d17873d3e607d398b85126cd4ed7aad89e4e9d89fc744cdab1af3189a996c2a", size = 20689085, upload-time = "2025-12-05T23:08:39.522Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/48/f5/3a73b51e6450c31652c53a8e12e24eac64e3824be816c0c2316e7dbdcb7d/statsmodels-0.14.6-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:d8c00a42863e4f4733ac9d078bbfad816249c01451740e6f5053ecc7db6d6368", size = 10058649, upload-time = "2025-12-05T23:10:12.775Z" }, + { url = "https://files.pythonhosted.org/packages/81/68/dddd76117df2ef14c943c6bbb6618be5c9401280046f4ddfc9fb4596a1b8/statsmodels-0.14.6-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:19b58cf7474aa9e7e3b0771a66537148b2df9b5884fbf156096c0e6c1ff0469d", size = 10339446, upload-time = "2025-12-05T23:10:28.503Z" }, + { url = "https://files.pythonhosted.org/packages/56/4a/dce451c74c4050535fac1ec0c14b80706d8fc134c9da22db3c8a0ec62c33/statsmodels-0.14.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:81e7dcc5e9587f2567e52deaff5220b175bf2f648951549eae5fc9383b62bc37", size = 10368705, upload-time = "2025-12-05T23:10:44.339Z" }, + { url = "https://files.pythonhosted.org/packages/ee/77/0ec96803eba444efd75dba32f2ef88765ae3e8f567d276805391ec2c98c6/statsmodels-0.14.6-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:89ee7d595f5939cc20bf946faedcb5137d975f03ae080f300ebb4398f16a5bd4", size = 10060269, upload-time = "2025-12-05T23:11:46.338Z" }, + { url = "https://files.pythonhosted.org/packages/10/b9/fd41f1f6af13a1a1212a06bb377b17762feaa6d656947bf666f76300fc05/statsmodels-0.14.6-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:730f3297b26749b216a06e4327fe0be59b8d05f7d594fb6caff4287b69654589", size = 10324155, upload-time = "2025-12-05T23:12:01.805Z" }, + { url = "https://files.pythonhosted.org/packages/ee/0f/a6900e220abd2c69cd0a07e3ad26c71984be6061415a60e0f17b152ecf08/statsmodels-0.14.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:f1c08befa85e93acc992b72a390ddb7bd876190f1360e61d10cf43833463bc9c", size = 10349765, upload-time = "2025-12-05T23:12:18.018Z" }, + { url = "https://files.pythonhosted.org/packages/c1/98/b0dfb4f542b2033a3341aa5f1bdd97024230a4ad3670c5b0839d54e3dcab/statsmodels-0.14.6-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e443e7077a6e2d3faeea72f5a92c9f12c63722686eb80bb40a0f04e4a7e267ad", size = 10090802, upload-time = "2025-12-05T23:13:20.653Z" }, + { url = "https://files.pythonhosted.org/packages/34/0e/2408735aca9e764643196212f9069912100151414dd617d39ffc72d77eee/statsmodels-0.14.6-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3414e40c073d725007a6603a18247ab7af3467e1af4a5e5a24e4c27bc26673b4", size = 10337587, upload-time = "2025-12-05T23:13:37.597Z" }, + { url = "https://files.pythonhosted.org/packages/0f/36/4d44f7035ab3c0b2b6a4c4ebb98dedf36246ccbc1b3e2f51ebcd7ac83abb/statsmodels-0.14.6-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:a518d3f9889ef920116f9fa56d0338069e110f823926356946dae83bc9e33e19", size = 10363350, upload-time = "2025-12-05T23:13:53.08Z" }, +] + +[[package]] +name = "swig" +version = "4.4.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/9c/99/0556919f96b1c291a7ff83793adb328e2a1a5e6cfb379d5acc637cdec959/swig-4.4.1.tar.gz", hash = "sha256:db9a625653f6454530a6c6553d17cf576d7aa2d253c76dc8cdd5979f0cb15012", size = 25956, upload-time = "2025-12-27T03:25:49.609Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c0/4d/860e5475fe38b9c7dc36f61d0c370a62b6cc725d2bd11ada1d22a60ff5f7/swig-4.4.1-py3-none-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:520fde8805b4775ef3814576929b8c44d666220b06d8da625f292192f9e74fe8", size = 1917511, upload-time = "2025-12-27T03:25:18.064Z" }, + { url = "https://files.pythonhosted.org/packages/84/e1/5cd4de23ff2b1d225279f7c7826191b1dbdb77fc858fe12ee7be2562ddb7/swig-4.4.1-py3-none-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:d8cca45a0e8d1e045a1490ea2d05bc1c49e2c266dbbe5954048e2a93d125ee07", size = 2066284, upload-time = "2025-12-27T03:25:19.624Z" }, + { url = "https://files.pythonhosted.org/packages/96/42/d49992f3c39c90d3d46c431a4afea60fc16bae542cf07f394b298a1b21b5/swig-4.4.1-py3-none-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:bfe6ce6189fc8b983f65f5ed3db8e1d8be03accb0ec3869f986a8343f014e4d9", size = 1912492, upload-time = "2025-12-27T03:25:21.843Z" }, + { url = "https://files.pythonhosted.org/packages/10/2e/4baa50fcf932f9d58bc8394b211c7daf3b7ec1e53c08d560142f1bc99cb9/swig-4.4.1-py3-none-manylinux_2_12_i686.manylinux2010_i686.whl", hash = "sha256:9c98d7b882b6debe3cbb87e6503858e104162d7ce5ab4cfc23425da2e26e51b5", size = 1979872, upload-time = "2025-12-27T03:25:23.48Z" }, + { url = "https://files.pythonhosted.org/packages/fa/7b/e3a14d053fa18b0d2e14efcc21883816964ddbe52a0c43018e195a99aba2/swig-4.4.1-py3-none-manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:ae3da2bf679a4c942a2c100789395d4d167e7da8286018124e4665f5eff43e31", size = 1895896, upload-time = "2025-12-27T03:25:24.98Z" }, + { url = "https://files.pythonhosted.org/packages/f0/a6/c961a911385a4cc4ae10b4dcbcf5dede0407530e59870ce6e4f7bacce47d/swig-4.4.1-py3-none-manylinux_2_24_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7945f153f7fc93f1ab280f44a3740d6bbfeec3829f954784ba83990fc61a11a8", size = 1912119, upload-time = "2025-12-27T03:25:27.661Z" }, + { url = "https://files.pythonhosted.org/packages/86/4b/a08a2673a2fd3185932db110de67a9f6fdfcece6bf9220e18502bf745f7e/swig-4.4.1-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:5a9c74b87151d8247d802bda33f78cab9f27c759f0605b760a8f9c9893b5606b", size = 1885810, upload-time = "2025-12-27T03:25:29.562Z" }, + { url = "https://files.pythonhosted.org/packages/7e/38/efa343b506221a9d43bb1132f08b29fcb07d4113165f598d8a1ea733a1e4/swig-4.4.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:a95ae66aebb8ccce4c50febd496e6927b888d98aba272dd5642fe9312bf61a3b", size = 2950985, upload-time = "2025-12-27T03:25:31.586Z" }, + { url = "https://files.pythonhosted.org/packages/de/0b/5b46e61798982f3cb0ed54fc30a30bad5fa6e3bdd1d9177e439976f7a7e5/swig-4.4.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a8f06227e6472832dad3ae34d5bd88710b7bbb109f2927e14a21e6725146e944", size = 2781782, upload-time = "2025-12-27T03:25:33.534Z" }, + { url = "https://files.pythonhosted.org/packages/17/e6/a15efd9cbf39b1289ee7c1acb8d18824a0c2532b85cdbd93acfdf15ee000/swig-4.4.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:98d61b45215982dd3a71745dfc31599176ed79d286b58bc712c10ed031432fdf", size = 3272993, upload-time = "2025-12-27T03:25:35.862Z" }, + { url = "https://files.pythonhosted.org/packages/d6/fa/516b95f9966c57acf1da9f2eb22e4e63104452d6e28686d57b216171ee7c/swig-4.4.1-py3-none-musllinux_1_2_ppc64le.whl", hash = "sha256:b6909a8bd68037ea0df061a52c664431b062dbdfb1eb90768719518c120139d1", size = 3189093, upload-time = "2025-12-27T03:25:38.158Z" }, + { url = "https://files.pythonhosted.org/packages/0c/03/88ca92d3d8e9dd765a66985202db23745bd26a368570a8d8db9a218bfe90/swig-4.4.1-py3-none-musllinux_1_2_riscv64.whl", hash = "sha256:6a6a6331a5c7759ba5a910aa83aa5d33022b8e691b6cb466635c7fc2238facd2", size = 2967789, upload-time = "2025-12-27T03:25:40.24Z" }, + { url = "https://files.pythonhosted.org/packages/bf/97/5ca3d750f294048c983edfad1f2ad093a83480494fccb2f2e2496304f965/swig-4.4.1-py3-none-musllinux_1_2_s390x.whl", hash = "sha256:2d076358cded172d2f44b3c617923c593dbae664b3fa45051641f028f7f74010", size = 3203253, upload-time = "2025-12-27T03:25:41.953Z" }, + { url = "https://files.pythonhosted.org/packages/97/44/96586955c0f08b0b9b6c8b2b68ecb43a815da94d5362cfb6691ede3b9fdf/swig-4.4.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:43a0a876b4660f6addb6ae72d14a72324dc1388e1c168ed38bb00fd123048749", size = 3060721, upload-time = "2025-12-27T03:25:44.322Z" }, +] + +[[package]] +name = "sympy" +version = "1.14.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mpmath", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/83/d3/803453b36afefb7c2bb238361cd4ae6125a569b4db67cd9e79846ba2d68c/sympy-1.14.0.tar.gz", hash = "sha256:d3d3fe8df1e5a0b42f0e7bdf50541697dbe7d23746e894990c030e2b05e72517", size = 7793921, upload-time = "2025-04-27T18:05:01.611Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a2/09/77d55d46fd61b4a135c444fc97158ef34a095e5681d0a6c10b75bf356191/sympy-1.14.0-py3-none-any.whl", hash = "sha256:e091cc3e99d2141a0ba2847328f5479b05d94a6635cb96148ccb3f34671bd8f5", size = 6299353, upload-time = "2025-04-27T18:04:59.103Z" }, +] + +[[package]] +name = "tables" +version = "3.11.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "blosc2", marker = "sys_platform == 'linux'" }, + { name = "numexpr", marker = "sys_platform == 'linux'" }, + { name = "numpy", marker = "sys_platform == 'linux'" }, + { name = "packaging", marker = "sys_platform == 'linux'" }, + { name = "py-cpuinfo", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/cc/a3/d213ebe7376d48055bd55a29cd9f99061afa0dcece608f94a5025d797b0a/tables-3.11.1.tar.gz", hash = "sha256:78abcf413091bc7c1e4e8c10fbbb438d1ac0b5a87436c5b972c3e8253871b6fb", size = 4790533, upload-time = "2026-03-01T11:43:36.036Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/a3/ec228901fca4c996306b17f5c60a4105144df0bbd07b3a4a816f91f37b4a/tables-3.11.1-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:56bf6fb9132ead989b7e76695d7613d6d08f071a8019038d6565ba90c66b9f3e", size = 6903733, upload-time = "2026-03-01T11:42:58.349Z" }, + { url = "https://files.pythonhosted.org/packages/99/29/c2dc674ea70fa9a4819417289a9c0d3e4780835beeed573eb66964cfb763/tables-3.11.1-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1e78fe190fdeb4afe430b79651bae2a4f341904eb85aa8dbafe5f1caee1c7f67", size = 7241357, upload-time = "2026-03-01T11:43:03.938Z" }, + { url = "https://files.pythonhosted.org/packages/59/3c/f4a694aa744d2b14d536e172c28dd70c84445f4787083a82d6d44a39e39f/tables-3.11.1-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3a9c35f87fcb6a48c79fbc4e3ab15ca8f6053c4ce13063d6ca2ec36cbb58f40f", size = 7014135, upload-time = "2026-03-01T11:43:22.359Z" }, + { url = "https://files.pythonhosted.org/packages/45/82/94d4320d6c0fe5bd55230eec90cd142d58cda37b7cce00a318ac2a6abd93/tables-3.11.1-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4cf3218b76ba78d156d6ee75c19fb757d50682f6c7b4905370441afbfc9d77f3", size = 7349293, upload-time = "2026-03-01T11:43:27.569Z" }, +] + +[[package]] +name = "tables-io" +version = "1.1.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click", marker = "sys_platform == 'linux'" }, + { name = "deprecated", marker = "sys_platform == 'linux'" }, + { name = "h5py", marker = "sys_platform == 'linux'" }, + { name = "numpy", marker = "sys_platform == 'linux'" }, + { name = "pandas", marker = "sys_platform == 'linux'" }, + { name = "tables", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/12/1b/61bed3c55ce4602be5379362ce939b71a2e707e856ee497c1d1e72f8ff3d/tables_io-1.1.2.tar.gz", hash = "sha256:ea27eac8b22ff4e3500afd92140794bd41161f768a2c84520b91b3b58e945182", size = 91394, upload-time = "2026-06-18T16:21:20.896Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/68/025307ebd3c54c65e540d2a4ced11d0e5aa370c8ddb6d0e83066e5a39054/tables_io-1.1.2-py3-none-any.whl", hash = "sha256:4361e04dfcc10471bf9a3940d9ee6a1f903ac76ece51d32ef7fec7ea572b20c0", size = 39206, upload-time = "2026-06-18T16:21:19.577Z" }, +] + +[[package]] +name = "tabulate" +version = "0.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/46/58/8c37dea7bbf769b20d58e7ace7e5edfe65b849442b00ffcdd56be88697c6/tabulate-0.10.0.tar.gz", hash = "sha256:e2cfde8f79420f6deeffdeda9aaec3b6bc5abce947655d17ac662b126e48a60d", size = 91754, upload-time = "2026-03-04T18:55:34.402Z" } +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 = "tenacity" +version = "9.1.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/47/c6/ee486fd809e357697ee8a44d3d69222b344920433d3b6666ccd9b374630c/tenacity-9.1.4.tar.gz", hash = "sha256:adb31d4c263f2bd041081ab33b498309a57c77f9acf2db65aadf0898179cf93a", size = 49413, upload-time = "2026-02-07T10:45:33.841Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d7/c1/eb8f9debc45d3b7918a32ab756658a0904732f75e555402972246b0b8e71/tenacity-9.1.4-py3-none-any.whl", hash = "sha256:6095a360c919085f28c6527de529e76a06ad89b23659fa881ae0649b867a9d55", size = 28926, upload-time = "2026-02-07T10:45:32.24Z" }, +] + +[[package]] +name = "terminado" +version = "0.18.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "ptyprocess", marker = "os_name != 'nt' and sys_platform == 'linux'" }, + { name = "tornado", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/8a/11/965c6fd8e5cc254f1fe142d547387da17a8ebfd75a3455f637c663fb38a0/terminado-0.18.1.tar.gz", hash = "sha256:de09f2c4b85de4765f7714688fff57d3e75bad1f909b589fde880460c753fd2e", size = 32701, upload-time = "2024-03-12T14:34:39.026Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/6a/9e/2064975477fdc887e47ad42157e214526dcad8f317a948dee17e1659a62f/terminado-0.18.1-py3-none-any.whl", hash = "sha256:a4468e1b37bb318f8a86514f65814e1afc977cf29b3992a4500d9dd305dcceb0", size = 14154, upload-time = "2024-03-12T14:34:36.569Z" }, +] + +[[package]] +name = "threadpoolctl" +version = "3.6.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b7/4d/08c89e34946fce2aec4fbb45c9016efd5f4d7f24af8e5d93296e935631d8/threadpoolctl-3.6.0.tar.gz", hash = "sha256:8ab8b4aa3491d812b623328249fab5302a68d2d71745c8a4c719a2fcaba9f44e", size = 21274, upload-time = "2025-03-13T13:49:23.031Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/32/d5/f9a850d79b0851d1d4ef6456097579a9005b31fea68726a4ae5f2d82ddd9/threadpoolctl-3.6.0-py3-none-any.whl", hash = "sha256:43a0b8fd5a2928500110039e43a5eed8480b918967083ea48dc3ab9f13c4a7fb", size = 18638, upload-time = "2025-03-13T13:49:21.846Z" }, +] + +[[package]] +name = "throttler" +version = "1.2.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ce/3f/47baf510c31e0e52ac0d80d9071e5e166ca069167fee4a6c13841f9d5f5f/throttler-1.2.3.tar.gz", hash = "sha256:d2f5b0b499d62f1fc984dcac8043450b606549b0097753a9c8a707f7427c27e1", size = 11792, upload-time = "2026-01-27T00:48:11.552Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/66/70/42d8796acc57c8bcd9ae395b1a6a0bbc833f738492a8ed192a44ccd58035/throttler-1.2.3-py3-none-any.whl", hash = "sha256:241ea3e97438dec4dc2f31ddc56dbd96262787a9b1d0598adfcc0bada1134b66", size = 9704, upload-time = "2026-01-27T00:48:09.544Z" }, +] + +[[package]] +name = "tifffile" +version = "2026.6.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "numpy", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b7/38/5e2ecef5af2f4fd4a89bb8d6240de9458bab4d51a4cbd97aeb3a0cd618e2/tifffile-2026.6.1.tar.gz", hash = "sha256:626c892c0e899d959b9438e7c0e1491dc154a7fead1f1f37a991724a50eceba9", size = 429694, upload-time = "2026-05-31T23:57:12.165Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/81/59/208f71d70ddc6184f79b8c6d87d46eb7d7b12c19186a817dec9c9c3f3693/tifffile-2026.6.1-py3-none-any.whl", hash = "sha256:0d7382d2769b855b81ce358528e2b40c16d48aa39031746efa81215205332a8d", size = 267108, upload-time = "2026-05-31T23:57:10.597Z" }, +] + +[[package]] +name = "tinycss2" +version = "1.5.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "webencodings", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/a3/ae/2ca4913e5c0f09781d75482874c3a95db9105462a92ddd303c7d285d3df2/tinycss2-1.5.1.tar.gz", hash = "sha256:d339d2b616ba90ccce58da8495a78f46e55d4d25f9fd71dfd526f07e7d53f957", size = 88195, upload-time = "2025-11-23T10:29:10.082Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/60/45/c7b5c3168458db837e8ceab06dc77824e18202679d0463f0e8f002143a97/tinycss2-1.5.1-py3-none-any.whl", hash = "sha256:3415ba0f5839c062696996998176c4a3751d18b7edaaeeb658c9ce21ec150661", size = 28404, upload-time = "2025-11-23T10:29:08.676Z" }, +] + +[[package]] +name = "toolz" +version = "1.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/11/d6/114b492226588d6ff54579d95847662fc69196bdeec318eb45393b24c192/toolz-1.1.0.tar.gz", hash = "sha256:27a5c770d068c110d9ed9323f24f1543e83b2f300a687b7891c1a6d56b697b5b", size = 52613, upload-time = "2025-10-17T04:03:21.661Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fb/12/5911ae3eeec47800503a238d971e51722ccea5feb8569b735184d5fcdbc0/toolz-1.1.0-py3-none-any.whl", hash = "sha256:15ccc861ac51c53696de0a5d6d4607f99c210739caf987b5d2054f3efed429d8", size = 58093, upload-time = "2025-10-17T04:03:20.435Z" }, +] + +[[package]] +name = "tornado" +version = "6.5.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/64/24/95ec527ad67b76d59299e5465b3935d05e4294b7e0290a3924b7487df30b/tornado-6.5.7.tar.gz", hash = "sha256:66c513a76cda70d53907bc27cf1447557699c2e95aa48ba27a442ff61c3ddfc2", size = 519252, upload-time = "2026-06-08T17:34:51.232Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/37/d8/ef374952fd5da67d4463122c2b8e5a96536ec10b4b339254c6dcde81d01c/tornado-6.5.7-cp39-abi3-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:8d759e71906ee783f8867b93bf26a265743da4c1e2f4a018464c1ba019862972", size = 449774, upload-time = "2026-06-08T17:34:41.204Z" }, + { url = "https://files.pythonhosted.org/packages/35/37/d434c73f4c6e014b745b9b37085f34f40c022f007efff3d7fe65991899f3/tornado-6.5.7-cp39-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8a46347a18f23fb92b396beebe0fb78f61dda0cc302445202c16203d8a18848b", size = 450745, upload-time = "2026-06-08T17:34:42.531Z" }, + { url = "https://files.pythonhosted.org/packages/b6/2b/56b9aff361d7f1ab728a805ec7d7ea835f8807afa9f5cc690ea0e630efb9/tornado-6.5.7-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:7778b30bef919231265e91c69963ce0f49a1e9c07ac900bbe75b19ce2575ba92", size = 450578, upload-time = "2026-06-08T17:34:43.787Z" }, + { url = "https://files.pythonhosted.org/packages/02/30/a7444fb23aa76860a14198fab96ac79f1866b0a6e19e26c4381b0938e50f/tornado-6.5.7-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:e726f0c75da7726eec023aa62751ff8878bd2737e34fbdd33b1ae5897d2200f5", size = 449985, upload-time = "2026-06-08T17:34:45.326Z" }, +] + +[[package]] +name = "tqdm" +version = "4.68.4" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ae/5f/57ff8b434839e70dab45601284ea413e947a63799891b7553e5960a793a8/tqdm-4.68.4.tar.gz", hash = "sha256:19829c9673638f2a0b8617da4cdcb927e831cd88bcfcb6e78d42a4d1af131520", size = 792418, upload-time = "2026-07-07T09:58:18.369Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/22/2a/5e5e750890ada51017d18d0d4c30da696e5b5bd3180947729927628fc3cb/tqdm-4.68.4-py3-none-any.whl", hash = "sha256:5168118b2368f48c561afda8020fd79195b1bdb0bdf8086b88442c267a315dc2", size = 676612, upload-time = "2026-07-07T09:58:16.256Z" }, +] + +[[package]] +name = "traitlets" +version = "5.15.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/57/a9/a2584b8313b89f94869ddb3c4074617a691de1812a614d2d50e32ca5a7a6/traitlets-5.15.1.tar.gz", hash = "sha256:7b1c07854fe25acb39e009bae49f11b79ff6cbb2f27999104e9110e7a6b53722", size = 163344, upload-time = "2026-06-03T12:26:06.181Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/96/8d/1080ee4c231f361b6ce4470d556c8c435b67c7e0753aaa641497ee92f88b/traitlets-5.15.1-py3-none-any.whl", hash = "sha256:770a53705f84b81ac107e83a1b3328ff2dae16094d8fc3cfc004e4b22dfd8e92", size = 85858, upload-time = "2026-06-03T12:26:04.395Z" }, +] + +[[package]] +name = "transformcl" +version = "2026.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "array-api-compat", marker = "sys_platform == 'linux'" }, + { name = "flt", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9d/ce/ae8373b67259c3ea6033425161f7d195387b1e68b17d4d00eee1b68e5edd/transformcl-2026.1.tar.gz", hash = "sha256:14551c33d164f3db24b9141f1f77553182a4b9c789f883476eb33d87ea4d8f13", size = 4850, upload-time = "2026-03-02T19:18:21.221Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/fc/98/de7a05005238e03bdc57cd2885c27ad9140539bbaddf2b6ad2b2a0aa9863/transformcl-2026.1-py3-none-any.whl", hash = "sha256:fe9c380074ef783a4f854e0d326eadac677d6a35bc683e3b429d5b49a8e57223", size = 3597, upload-time = "2026-03-02T19:18:19.832Z" }, +] + +[[package]] +name = "treecorr" +version = "5.1.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "lsstdesc-coord", marker = "sys_platform == 'linux'" }, + { name = "numpy", marker = "sys_platform == 'linux'" }, + { name = "pybind11", marker = "sys_platform == 'linux'" }, + { name = "pyyaml", marker = "sys_platform == 'linux'" }, + { name = "setuptools", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/5d/95/ff399cb37b9e3d7c758f8cf0d5757f06a38093f223f2a65d7cc5b50313d5/treecorr-5.1.3.tar.gz", hash = "sha256:d921ccace064325a8ebb93f371c624f13fcc9559373e3b37cc216cb94ae81ed2", size = 1146147, upload-time = "2026-03-18T18:38:03.626Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/97/74/1cc590e4fe1afb69ec2f10a67ee8e0a92ecafd36512052755362ff302d9c/treecorr-5.1.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:596b6f5eea3115a9e211dc83ec6465887983f41b24e484e08fc47170c6cf4e26", size = 20941767, upload-time = "2026-03-18T18:37:37.874Z" }, + { url = "https://files.pythonhosted.org/packages/6f/bb/5ba5aa1021fce0cf459fa264cb0d298dfd095ddb48d63fb6589b90fdefac/treecorr-5.1.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:660dacd47a9af18790de279bcb6e7f375369096ad77e7cc64bf21a9b78f6c430", size = 19785388, upload-time = "2026-03-18T18:37:40.573Z" }, + { url = "https://files.pythonhosted.org/packages/be/92/be01211263a4fa488e768c9288c6f9b0f4402870423a88de4d60031b3384/treecorr-5.1.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:73c938c6c31e1bad4d5338ad4519d1d78eedf3b7ef579b1e3a19d983e220ed93", size = 20940568, upload-time = "2026-03-18T18:37:44.966Z" }, + { url = "https://files.pythonhosted.org/packages/dc/a3/69e5a16aa33600ba22d28a47c6d8de3b3118292e79f9ae77dc69a3df7c77/treecorr-5.1.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:dc17b1f623bae6769148f57cac8c3a295e26e5d6215698117bd97e14c8bb0d6b", size = 19781991, upload-time = "2026-03-18T18:37:47.468Z" }, +] + +[[package]] +name = "typing-extensions" +version = "4.16.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/f6/cc/6253133b5bb138fc3306cebfbda2c520f545d36b5be2c7255cc528bb45d6/typing_extensions-4.16.0.tar.gz", hash = "sha256:dc983d19a509c94dba722ee6abd33940f7c05a89e243c47e907eb4db6f1a43e5", size = 113555, upload-time = "2026-07-02T08:40:05.92Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/49/d3/b8441a820a491ddfc024b0b0cf0393375b75ea13866d9c66727e54c2fc80/typing_extensions-4.16.0-py3-none-any.whl", hash = "sha256:481caa481374e813c1b176ada14e97f1f67a4539ce9cfeb3f350d78d6370c2e8", size = 45571, upload-time = "2026-07-02T08:40:04.659Z" }, +] + +[[package]] +name = "typing-inspection" +version = "0.4.2" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, +] + +[[package]] +name = "tzdata" +version = "2026.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/92/ff/5a28bdfd8c3ebec42564ac7d0e54ca3db65044a9314a97f9564fa7a1e926/tzdata-2026.3.tar.gz", hash = "sha256:4a1518b8993086a7982523e071643f3c0e5f213e75b21318e78bcabfff9d1415", size = 198674, upload-time = "2026-07-10T08:50:37.887Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e5/6d/b53b99a9f2766d095985947a5782f1702cabb129a34f7a802d7197af832f/tzdata-2026.3-py2.py3-none-any.whl", hash = "sha256:dc096730c87af6cab1b171c9d532be840741ff5d459015e7f6947bd7d7e54931", size = 348168, upload-time = "2026-07-10T08:50:36.46Z" }, +] + +[[package]] +name = "uncertainties" +version = "3.2.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fe/0c/cb09f33b26955399c675ab378e4063ed7e48422d3d49f96219ab0be5eba9/uncertainties-3.2.3.tar.gz", hash = "sha256:76a5653e686f617a42922d546a239e9efce72e6b35411b7750a1d12dcba03031", size = 160492, upload-time = "2025-04-21T19:58:28.63Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/8f/5e/f1e1dd319e35e962a4e00b33150a8868b6329cc1d19fd533436ba5488f09/uncertainties-3.2.3-py3-none-any.whl", hash = "sha256:313353900d8f88b283c9bad81e7d2b2d3d4bcc330cbace35403faaed7e78890a", size = 60118, upload-time = "2025-04-21T19:58:26.864Z" }, +] + +[[package]] +name = "uri-template" +version = "1.3.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/31/c7/0336f2bd0bcbada6ccef7aaa25e443c118a704f828a0620c6fa0207c1b64/uri-template-1.3.0.tar.gz", hash = "sha256:0e00f8eb65e18c7de20d595a14336e9f337ead580c70934141624b6d1ffdacc7", size = 21678, upload-time = "2023-06-21T01:49:05.374Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e7/00/3fca040d7cf8a32776d3d81a00c8ee7457e00f80c649f1e4a863c8321ae9/uri_template-1.3.0-py3-none-any.whl", hash = "sha256:a44a133ea12d44a0c0f06d7d42a52d71282e77e2f937d8abd5655b8d56fc1363", size = 11140, upload-time = "2023-06-21T01:49:03.467Z" }, +] + +[[package]] +name = "urllib3" +version = "2.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/53/0c/06f8b233b8fd13b9e5ee11424ef85419ba0d8ba0b3138bf360be2ff56953/urllib3-2.7.0.tar.gz", hash = "sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c", size = 433602, upload-time = "2026-05-07T16:13:18.596Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897", size = 131087, upload-time = "2026-05-07T16:13:17.151Z" }, +] + +[[package]] +name = "vos" +version = "3.6.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "aenum", marker = "sys_platform == 'linux'" }, + { name = "cadcutils", marker = "sys_platform == 'linux'" }, + { name = "html2text", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/3e/6c/445bbedf2f90e71c09ff890aa8b409af5d074b1578eef383117cbcdfd09a/vos-3.6.4.tar.gz", hash = "sha256:67e4e24689ee881124b6670d7d2fc6527cc404687fc527fffc20cf5b1bd4c0bd", size = 103445, upload-time = "2025-12-12T00:20:56.398Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/0c/21/e2d351883aa11b9175223a78d3a77b0fedf86461596cdbfb019893ca9260/vos-3.6.4-py3-none-any.whl", hash = "sha256:4a7b2248bad0f50da465a47ab1c819dff8378c189c184c2d8e2c17a714c62f17", size = 153404, upload-time = "2025-12-12T00:20:53.232Z" }, +] + +[[package]] +name = "wcwidth" +version = "0.8.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/34/74/c6428f875774288bec1396f5bfcbc2d925700a4dad61727fd5f2b12f249d/wcwidth-0.8.2.tar.gz", hash = "sha256:91fbef97204b96a3d4d421609b80340b760cf33e26da123ff243d76b1fda8dda", size = 1466253, upload-time = "2026-06-29T18:11:11.601Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/96/42/3e5985a0a7e57de470b320c6d6a1a67c844f6737a587f3d44dd13d1819e7/wcwidth-0.8.2-py3-none-any.whl", hash = "sha256:d63947694a0539a1d51e01eda7caf800c291020e6cdd7e28ad7b14dd33ad4f85", size = 323166, upload-time = "2026-06-29T18:11:09.888Z" }, +] + +[[package]] +name = "webcolors" +version = "25.10.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/1d/7a/eb316761ec35664ea5174709a68bbd3389de60d4a1ebab8808bfc264ed67/webcolors-25.10.0.tar.gz", hash = "sha256:62abae86504f66d0f6364c2a8520de4a0c47b80c03fc3a5f1815fedbef7c19bf", size = 53491, upload-time = "2025-10-31T07:51:03.977Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e2/cc/e097523dd85c9cf5d354f78310927f1656c422bd7b2613b2db3e3f9a0f2c/webcolors-25.10.0-py3-none-any.whl", hash = "sha256:032c727334856fc0b968f63daa252a1ac93d33db2f5267756623c210e57a4f1d", size = 14905, upload-time = "2025-10-31T07:51:01.778Z" }, +] + +[[package]] +name = "webencodings" +version = "0.5.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/0b/02/ae6ceac1baeda530866a85075641cec12989bd8d31af6d5ab4a3e8c92f47/webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923", size = 9721, upload-time = "2017-04-05T20:21:34.189Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f4/24/2a3e3df732393fed8b3ebf2ec078f05546de641fe1b667ee316ec1dcf3b7/webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78", size = 11774, upload-time = "2017-04-05T20:21:32.581Z" }, +] + +[[package]] +name = "websocket-client" +version = "1.9.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/2c/41/aa4bf9664e4cda14c3b39865b12251e8e7d239f4cd0e3cc1b6c2ccde25c1/websocket_client-1.9.0.tar.gz", hash = "sha256:9e813624b6eb619999a97dc7958469217c3176312b3a16a4bd1bc7e08a46ec98", size = 70576, upload-time = "2025-10-07T21:16:36.495Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/34/db/b10e48aa8fff7407e67470363eac595018441cf32d5e1001567a7aeba5d2/websocket_client-1.9.0-py3-none-any.whl", hash = "sha256:af248a825037ef591efbf6ed20cc5faa03d3b47b9e5a2230a529eeee1c1fc3ef", size = 82616, upload-time = "2025-10-07T21:16:34.951Z" }, +] + +[[package]] +name = "widgetsnbextension" +version = "4.0.15" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/bd/f4/c67440c7fb409a71b7404b7aefcd7569a9c0d6bd071299bf4198ae7a5d95/widgetsnbextension-4.0.15.tar.gz", hash = "sha256:de8610639996f1567952d763a5a41af8af37f2575a41f9852a38f947eb82a3b9", size = 1097402, upload-time = "2025-11-01T21:15:55.178Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3f/0e/fa3b193432cfc60c93b42f3be03365f5f909d2b3ea410295cf36df739e31/widgetsnbextension-4.0.15-py3-none-any.whl", hash = "sha256:8156704e4346a571d9ce73b84bee86a29906c9abfd7223b7228a28899ccf3366", size = 2196503, upload-time = "2025-11-01T21:15:53.565Z" }, +] + +[[package]] +name = "wrapt" +version = "2.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/fe/a4/282c8e64300a59fc834518a54bf0afabb4ff9218b5fa76958b450459a844/wrapt-2.2.2.tar.gz", hash = "sha256:0788e321027c999bf221b667bd4a54aaefd1a36283749a860ac3eb77daed0302", size = 129068, upload-time = "2026-06-20T23:49:44.49Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/5f/b3/7e6e9fcf4fe7e1b69a49fe6cc5a44e8224bab6283c5233c97e132f14908e/wrapt-2.2.2-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2e096c9d39a59b35b63c9aacfbbbec2088ff51ff1fc31051acc60a07f42f273a", size = 169828, upload-time = "2026-06-20T23:48:02.719Z" }, + { url = "https://files.pythonhosted.org/packages/0b/43/894f132d857ed5a9904d937baf368badcbe5ea9e436e2f1930fe21c9f1f0/wrapt-2.2.2-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6d1a6050405bf334be33bf66296f113563622972a34900ae6fa60fd283a1a900", size = 171544, upload-time = "2026-06-20T23:48:04.266Z" }, + { url = "https://files.pythonhosted.org/packages/29/de/3c833e03725b477e9ea34028224dd21a48781830101e4e036f77e8b6b102/wrapt-2.2.2-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:10adb01371408c6de504a6658b9886480f1a4919a83752748a387a504a21df79", size = 160663, upload-time = "2026-06-20T23:48:05.708Z" }, + { url = "https://files.pythonhosted.org/packages/33/be/27edce350b24e3054d9d047f65f16d4c4d4c1f3f31c4278a1f8a95c723c8/wrapt-2.2.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3442eee2a5798f9b451f1b2cd7518ce8b7e28a2a364696c414460a0e295c012a", size = 169387, upload-time = "2026-06-20T23:48:07.243Z" }, + { url = "https://files.pythonhosted.org/packages/e2/c4/9fd9679af8bf38e146652c7f47b6b352c3e5795b4ad1c0b7f94e15ac2aa7/wrapt-2.2.2-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:6c99012a22f735a85eed7c4b86a3e99c30fdd57d9e115b2b45f796264b58d0bf", size = 158849, upload-time = "2026-06-20T23:48:08.91Z" }, + { url = "https://files.pythonhosted.org/packages/bc/c2/aa6c0c2206803068c6859dabe01f8c84c43744da93d4c67b8946d21655ee/wrapt-2.2.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3b686cfc008776a3952d6213cb296ed7f45d782a8453936406faa89eac0835ab", size = 168147, upload-time = "2026-06-20T23:48:10.374Z" }, + { url = "https://files.pythonhosted.org/packages/15/ff/63ad96f98eb58a742b1a20d80f21da88924405910149950b912368150468/wrapt-2.2.2-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:fb18fc51e813df0d9c98049e3bf2298a5495a648602040e21fa3c7329371159e", size = 167882, upload-time = "2026-06-20T23:48:18.764Z" }, + { url = "https://files.pythonhosted.org/packages/20/1f/8bb62d8933df7acf3247194e6e9fc68edf9d2fa203252c89c94b319dd472/wrapt-2.2.2-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:94b00b00f806eb3ef2abe9049ed45994a81ee9284884d96e6b8314927c6cea3d", size = 167411, upload-time = "2026-06-20T23:48:20.315Z" }, + { url = "https://files.pythonhosted.org/packages/17/09/8789dcb09ee1de715727db7521aabbb68ffa68dfade3a49468440cfced49/wrapt-2.2.2-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:62415fd095bc590b842b6d092f2b5d9ccbaeb7e0b28535c03dcea2718b48636b", size = 158607, upload-time = "2026-06-20T23:48:21.728Z" }, + { url = "https://files.pythonhosted.org/packages/9c/20/66e02562d53ee67d841f175e38e3c993c2d78a3e104c576cad61c028b43c/wrapt-2.2.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a41e758d80dc0ab8c210f641ac892009d356cf1f955d97db544c8dd317b4d14c", size = 166367, upload-time = "2026-06-20T23:48:23.177Z" }, + { url = "https://files.pythonhosted.org/packages/bd/a3/832ac4e41222fb263b3042d42c2f08d305db7d0f0c9b1d3a271a9eede8f6/wrapt-2.2.2-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:b84cd4058001c9727b0e9980b7a9e66325b5ca748b1b578e822cade1bc6b304f", size = 157176, upload-time = "2026-06-20T23:48:24.711Z" }, + { url = "https://files.pythonhosted.org/packages/b7/01/1bd5e4d2df9c0178989ac8da9186543465388588ee2ef153e2591accebef/wrapt-2.2.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:26fc73a1b15e0946d2942b9a4426d162b51676338327dc067ccd8d2d76385f94", size = 167025, upload-time = "2026-06-20T23:48:26.118Z" }, + { url = "https://files.pythonhosted.org/packages/18/1e/f060df47755e87b57684cee7bfc1362b204df55fac96ffebc0631b697b79/wrapt-2.2.2-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0065a3b657cec06813b4241d2462ccec287f6863103d7445b725fb3a889736f9", size = 203399, upload-time = "2026-06-20T23:48:34.97Z" }, + { url = "https://files.pythonhosted.org/packages/c4/de/2316a757a1abb6453700b79d83e532146dcef2611348282d4d8889792161/wrapt-2.2.2-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:30f7424af5c5c345b7f26490e097f74a2ef45b3d08b664dc33571aee3bd3b56c", size = 210461, upload-time = "2026-06-20T23:48:36.569Z" }, + { url = "https://files.pythonhosted.org/packages/ed/29/d1160785ae18ca2495a6d82a21154103d74f656c9fd457fb35f6b11b965a/wrapt-2.2.2-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:07fdcb012821859168641acf68afad61ef9783cf37100af85f152550e9677194", size = 195313, upload-time = "2026-06-20T23:48:38.175Z" }, + { url = "https://files.pythonhosted.org/packages/f5/2d/7caa9598ae61a9cf0989cc501739cbeeb7d650ab3193cca1407b9af0c6ab/wrapt-2.2.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:f90038ab58fafb584801ca62d72384d7d5225d93c76f7b773c22fae545bd8066", size = 206116, upload-time = "2026-06-20T23:48:39.804Z" }, + { url = "https://files.pythonhosted.org/packages/ac/02/281ea1088b8650d865f311b35cf86fd21df89128e2909714f1161e01c9d0/wrapt-2.2.2-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:c5d7825491bfa2d08b97e9557768987952c7b9ae687d06c3320b40a37ccb7f20", size = 192668, upload-time = "2026-06-20T23:48:41.346Z" }, + { url = "https://files.pythonhosted.org/packages/be/7d/976e2d5b4b5c5babda40974edd54d0a5585cb60132ed86b46f4b80239b16/wrapt-2.2.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:0ad520e6daa9bbf136f14de735474dbec7dcc0891f718e1d274ce8dc92e645af", size = 198891, upload-time = "2026-06-20T23:48:43.056Z" }, + { url = "https://files.pythonhosted.org/packages/74/eb/df7b7f0b631dbbc750f39be27d8b55f65777d8ac86da80e12be41a644c4b/wrapt-2.2.2-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0abfd648dac9ac9c5b3aa9b523d27f1789046640b58dcd5652a720ddb325e1fc", size = 167713, upload-time = "2026-06-20T23:48:52.598Z" }, + { url = "https://files.pythonhosted.org/packages/4d/9a/d1bd36f6d088c8e652a9383cabbd49af30b8c576302a7eccddbab6963e3f/wrapt-2.2.2-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:f4bfd8d1eb438153eff8b8cfe87f032ba65731e1ce06138b5090f745a33f6f95", size = 166779, upload-time = "2026-06-20T23:48:54.33Z" }, + { url = "https://files.pythonhosted.org/packages/4c/ae/24ffacd4187fac2740a1972093929e836dea092d42c87d728cd98fee11a6/wrapt-2.2.2-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:c427c9d06d859848a69f0d928fe28b5c33a941b2265d10a0e1f15cd244f1ee33", size = 158407, upload-time = "2026-06-20T23:48:55.944Z" }, + { url = "https://files.pythonhosted.org/packages/a3/ed/974427668249a356051e8d67d47fa54ef6c777f0fcf3bae9d292c047d4b6/wrapt-2.2.2-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4250b43d1a129d947e083c4dc6baf333c9bb34edd26f912d5b0457841fc858ab", size = 166594, upload-time = "2026-06-20T23:48:57.617Z" }, + { url = "https://files.pythonhosted.org/packages/fb/5f/e1d7c6e4523f78db2fbd7826babd0348da1d5e0834c4f918b9ab5757dfae/wrapt-2.2.2-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:173e5bb5ca350a6e0abab60b7ec7cdd7992a814cb14b4de670a28f067f105663", size = 157068, upload-time = "2026-06-20T23:48:59.171Z" }, + { url = "https://files.pythonhosted.org/packages/1e/c1/7ebd1027f00700c0b0233b20aceef2b4784294ed64971424c4a78e069e34/wrapt-2.2.2-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:aa14b01804bce36c6d63d7b6a4f55df390f29f8648cc13a1f40b166f4d54680d", size = 166470, upload-time = "2026-06-20T23:49:00.737Z" }, + { url = "https://files.pythonhosted.org/packages/4e/ea/1a89e6d3b7a83c3affe5c09cde77792c947e63e4bc85ad84cd5bb9abb0d8/wrapt-2.2.2-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:45c2f2768e790c9f8db90f239ef23a2af8e7570f25a35619ef902df4a738447f", size = 203362, upload-time = "2026-06-20T23:49:09.811Z" }, + { url = "https://files.pythonhosted.org/packages/19/d8/3b58763d9863b5a73771c0d97110f9595d248db454009e07e1535ee905a4/wrapt-2.2.2-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:bbf00ee0cb55ec24e2b0995a71942b85b21a066db8f3f46e1dbfdb9433ffba81", size = 210449, upload-time = "2026-06-20T23:49:11.521Z" }, + { url = "https://files.pythonhosted.org/packages/2d/6f/17fd9e053103d8be148d20d5d7505facc72d5fe1f9127973904ceaed79cf/wrapt-2.2.2-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:2252f77663651b89255895f58cc6ac08fcb206d4371813e5af61bb62d4f7689c", size = 195349, upload-time = "2026-06-20T23:49:13.346Z" }, + { url = "https://files.pythonhosted.org/packages/ef/04/d0d1ccaaa12cb7dccf28a23f0279a608ba498f71e81d949d5ed54bcfd5c1/wrapt-2.2.2-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:2cd7181ab1c31192ff5219269830744b5a62020b3a6d433588c4f1c95b8f8bff", size = 206099, upload-time = "2026-06-20T23:49:15.051Z" }, + { url = "https://files.pythonhosted.org/packages/44/b3/e8aa07b619890a2aa6cde1931b1887abb08820721b564a5f80b7ca3f3aa0/wrapt-2.2.2-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:6fe35fd51b74867d8b80174c277bd6bbf6a73e443f908129dc531c4b688a20d5", size = 192728, upload-time = "2026-06-20T23:49:16.854Z" }, + { url = "https://files.pythonhosted.org/packages/b7/f0/1819fb50f0d3c9bd758d8a83b56f1b470dee8b5b8eac8702b7c137cea9d4/wrapt-2.2.2-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:11d95fc2fbad3163596c39d440e6f21ca9fccece74b56e30a37ac2fca786a07c", size = 198842, upload-time = "2026-06-20T23:49:18.504Z" }, + { url = "https://files.pythonhosted.org/packages/6e/d2/6317eb6d4554855bbf12d61857774af34747bf88a42c19bf306de67e2fa3/wrapt-2.2.2-py3-none-any.whl", hash = "sha256:5bad217350f19ce99ca5b5e71d406765ea86fe541628426772b657375ee1c048", size = 61460, upload-time = "2026-06-20T23:49:42.966Z" }, +] + +[[package]] +name = "yte" +version = "1.9.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "argparse-dataclass", marker = "sys_platform == 'linux'" }, + { name = "dpath", marker = "sys_platform == 'linux'" }, + { name = "pyyaml", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/44/f5/7e44620e6e077bfe624b9a17c329b8e0d0159e176e1f1a93c2790428ab2c/yte-1.9.4.tar.gz", hash = "sha256:86a47e6d722cec9419a7ac88be57d0d6c4ce28f02860393b71a66f2c674069f6", size = 8101, upload-time = "2025-11-27T12:55:00.85Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4d/63/6a44729fdc60eb255a7b156a84e7552290174a9bf151e3b6c18e83d6fbfa/yte-1.9.4-py3-none-any.whl", hash = "sha256:5dac63303d3e6bc2ebadc36ece3c3fb09343772fe6e25e9356d9baf8f9dfaf6d", size = 10618, upload-time = "2025-11-27T12:55:01.685Z" }, +] + +[[package]] +name = "zarr" +version = "3.2.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "donfig", marker = "sys_platform == 'linux'" }, + { name = "google-crc32c", marker = "sys_platform == 'linux'" }, + { name = "numcodecs", marker = "sys_platform == 'linux'" }, + { name = "numpy", marker = "sys_platform == 'linux'" }, + { name = "packaging", marker = "sys_platform == 'linux'" }, + { name = "typing-extensions", marker = "sys_platform == 'linux'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/93/8d/aeb164004f87543b06ef54f885d02c342c31ceb274e2bbec470a98927621/zarr-3.2.1.tar.gz", hash = "sha256:71565b738a0e7e8ed226f0516eba8c6bb53440ad7669a8c48ebb3534a161d035", size = 675161, upload-time = "2026-05-05T12:37:22.383Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/0a/469e2bd01be1490336e6c8707386845655d59261543315778a3ccc7e8019/zarr-3.2.1-py3-none-any.whl", hash = "sha256:f78cdd3d9687ad0e9f9cba2c5683b64f0c52589c19f685eeabe872e93cc0d2c7", size = 319617, upload-time = "2026-05-05T12:37:20.66Z" }, +] + +[[package]] +name = "zipp" +version = "4.1.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b9/d8/eab98a517c14134c0b2eb4e2387bc5f457334293ec5d2dd3857ec2966802/zipp-4.1.0.tar.gz", hash = "sha256:4cb57381f544315db7688e976e922a2b18cdb513d21cc194eb42232ba2a3e602", size = 26214, upload-time = "2026-05-18T20:08:57.967Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3a/13/547360d81e6d88d58492968ffda9f9542854f11310ee556fef14260cc886/zipp-4.1.0-py3-none-any.whl", hash = "sha256:25ad4e16390cd314347dd8f1de67a2ac538ae658ed4ab9db16029c07c188e97f", size = 10238, upload-time = "2026-05-18T20:08:57.045Z" }, +] + +[[package]] +name = "zope-interface" +version = "8.5" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/08/dc/50550cfcbb2ea3cbca5f1d7ed05c8aa840f831a0f2d63aec0a953f7c590e/zope_interface-8.5.tar.gz", hash = "sha256:7a3ba1c5877f0f3e3906b02ddf793abed2becc2948116414ce0e1dd820b68d6d", size = 257957, upload-time = "2026-05-26T06:50:14.574Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/e1/c3/005032195ff3b210c139b7c560ed5c534e844b0907d8e44d2b3d8919305e/zope_interface-8.5-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:e6347b8d8d12c5eca6502450a92be30079b7acfade2c4f693efa0deb8871b06e", size = 265296, upload-time = "2026-05-26T06:49:29.741Z" }, + { url = "https://files.pythonhosted.org/packages/c5/66/1036543d6a66bc04c19df3cf650f3ad938a002ab0a443c24e23e8de5e8b9/zope_interface-8.5-cp312-cp312-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:5e970dabea777a24b0b0bbf9dae3ab75ce8b2d8e948edf4875627034b21f3560", size = 270689, upload-time = "2026-05-26T06:49:31.767Z" }, + { url = "https://files.pythonhosted.org/packages/30/4c/8b56259558cace4414e753ca6740396a1f59d4a95ddb55b4658600408670/zope_interface-8.5-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:f0b48ccadaa9839e09ff81e969703cecb3f402c813bfe8b958652e699bea69f5", size = 270280, upload-time = "2026-05-26T06:49:33.489Z" }, + { url = "https://files.pythonhosted.org/packages/aa/a5/692a2b8d70f78e848793231d5fae5fecbf8d0cccd73430fdc34802a6d3c1/zope_interface-8.5-cp313-cp313-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:7849ad8fa90763cc1087f4dda78ca3a233e950b3e08fac7079297c9cafbbd7bb", size = 265191, upload-time = "2026-05-26T06:49:43.449Z" }, + { url = "https://files.pythonhosted.org/packages/70/8d/454a9cfc7a050c394ab4f11b3371f7897828b7415e096afff724637e65e0/zope_interface-8.5-cp313-cp313-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:5578c9421ca409a1f39f153d6f7803e4cde01da592ec75a9ac5e1b777d18d33b", size = 270626, upload-time = "2026-05-26T06:49:45.425Z" }, + { url = "https://files.pythonhosted.org/packages/51/8c/db8409cfa3575b8e9b4800babd7d49f8228433cd1f0c56814bd0ada49c33/zope_interface-8.5-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:e1bd7d96b4ca5fa311f54c9eac16dce4886b428c1531dbe06067763ccdf123b4", size = 270444, upload-time = "2026-05-26T06:49:47.025Z" }, + { url = "https://files.pythonhosted.org/packages/32/67/bc8b4f465d388039255003e230c284a175cedf1203c692f23cb7bff64efe/zope_interface-8.5-cp314-cp314-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:3090e3a663d20194756a59a272e0c8508b889341e31d5894223331fe6b4f9b21", size = 266827, upload-time = "2026-05-26T06:49:54.873Z" }, + { url = "https://files.pythonhosted.org/packages/a7/eb/37d05b935ede53d79690fecc8d201440084418e590bcfc05f384451c7593/zope_interface-8.5-cp314-cp314-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:9342fb74e2afefdb081bf1df727d209ea56995c6e13f5a0540e6d7aff4beafb8", size = 270139, upload-time = "2026-05-26T06:49:57.116Z" }, + { url = "https://files.pythonhosted.org/packages/8b/0b/fd0c54579e2ce8dc6cf1a757903f3374bc6fbda929a46af9e0f53cb0e5f0/zope_interface-8.5-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:6c54725d818f1b57a7efb8b16528326e1f3c257b602b32393fd255c45af8799d", size = 270338, upload-time = "2026-05-26T06:49:58.698Z" }, + { url = "https://files.pythonhosted.org/packages/c2/95/d97430abd5ae9677e8b9295b58720c0064a5b557dbb6b8bf5928484cf0d8/zope_interface-8.5-cp314-cp314t-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:14b0e9799351d4c34fe99afd67f0cdd76e55ba15c66a98699d5fc22ea8241e08", size = 294905, upload-time = "2026-05-26T06:50:07.384Z" }, + { url = "https://files.pythonhosted.org/packages/41/ec/a0f8f3dad6e74992f4654bdd94802be0929eabca7b871cac3b6fbb5e961b/zope_interface-8.5-cp314-cp314t-manylinux1_x86_64.manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0cd6a732ac84b94eb1ef9222a117347a27efd294ee16810ffdf7ecd307677ed5", size = 300885, upload-time = "2026-05-26T06:50:08.997Z" }, + { url = "https://files.pythonhosted.org/packages/0f/da/6881b48803a0ee8d23eb5efa30fce3ed218a2bd9de5758ce489d224fee81/zope_interface-8.5-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:798b7c87d0e59a7d5d086d642208d0d8700ff0d55c4029134b3c479c3bfb110f", size = 304672, upload-time = "2026-05-26T06:50:10.563Z" }, +] From 1a5db3a1dd00bedd498aec9c75753689b8726123 Mon Sep 17 00:00:00 2001 From: Cail Daley Date: Sat, 11 Jul 2026 12:57:14 +0200 Subject: [PATCH 4/5] =?UTF-8?q?felt:=20uv-lock-cosmo-numba=20=E2=80=94=20@?= =?UTF-8?q?main=20resolution,=20install=20model,=20cosmo-numba=20gotcha=20?= =?UTF-8?q?finding?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Vtw1qcgTrQ6YuMvxwYzNup --- .../cosmo-numba-refs-uv-empty-deps.md | 20 +++++++++++++++++++ .../uv-lock-cosmo-numba.md | 16 +++++++++++++-- 2 files changed, 34 insertions(+), 2 deletions(-) create mode 100644 .felt/sp_validation/uv-lock-cosmo-numba/cosmo-numba-refs-uv-empty-deps/cosmo-numba-refs-uv-empty-deps.md diff --git a/.felt/sp_validation/uv-lock-cosmo-numba/cosmo-numba-refs-uv-empty-deps/cosmo-numba-refs-uv-empty-deps.md b/.felt/sp_validation/uv-lock-cosmo-numba/cosmo-numba-refs-uv-empty-deps/cosmo-numba-refs-uv-empty-deps.md new file mode 100644 index 00000000..6bf3f771 --- /dev/null +++ b/.felt/sp_validation/uv-lock-cosmo-numba/cosmo-numba-refs-uv-empty-deps/cosmo-numba-refs-uv-empty-deps.md @@ -0,0 +1,20 @@ +--- +id: 01KX8D3CDT73EYYTXCF72XH9CV +name: 'cosmo-numba: use @main; a git dep with dependencies=[] resolves to zero deps in uv' +tags: + - finding + - gotcha + - deps +created-at: 2026-07-11T12:55:47.643001731+02:00 +updated-at: 2026-07-11T12:56:25.583499035+02:00 +--- + +Two durable facts about depending on `cosmo-numba` (`aguinot/cosmo-numba`), learned the slow way while locking sp_validation. + +**Depend on `@main`, not the fork.** cosmo-numba is **not on PyPI**. Its refs diverge in a way that matters: +- `aguinot/cosmo-numba@main` — declares its deps dynamically from `requirements.txt` (uv reads this correctly) and gets numpy-2 FFT support from its **`rocket-fft`** dependency (rocket-fft teaches numba's nopython mode to compile `np.fft`). This is the ref you want. +- `cailmdaley/cosmo-numba@fix/numpy2-fft-compat` (tip `db452c48`) — a dead end. It carries an earlier `nb.objmode()` FFT workaround but its `pyproject.toml` declares `dependencies = []` (empty). Cail's PR of that workaround (aguinot#17) was **closed** in favor of the rocket-fft approach (aguinot#18, merged) — his own closing comment: *"real solution is rocket-fft dependency."* + +**The uv gotcha that cost the time:** when a git/source dependency's `pyproject.toml` declares `dependencies = []` (or otherwise advertises no requirements), **uv silently resolves it to itself with zero transitive deps — no error, no warning** ("Resolved 1 package"). The lock entry simply has no `dependencies` block. So if a package you depend on isn't pulling in what you expect, check the *ref you're actually resolving* declares them — don't assume a uv or `requirements.txt` bug (uv reads `[tool.setuptools.dynamic] dependencies = {file = "requirements.txt"}` fine, verified against a minimal repro four ways). Corollary defensive move: pin the load-bearing transitive (here `numba`, for its `numpy<2.5` ceiling) directly in your own `pyproject.toml`, so the constraint survives the dependency's metadata going empty between refs. + +**Process lesson:** the fast path was one command — `uv pip compile 'cosmo-numba @ git+…@main'` — which would have shown deps propagating and rocket-fft appearing immediately. Try the cheap alternative ref *before* dissecting why the first ref failed, especially when the premise that a ref is special came from an unverified source (a subagent audit that also hallucinated a PyPI release). diff --git a/.felt/sp_validation/uv-lock-cosmo-numba/uv-lock-cosmo-numba.md b/.felt/sp_validation/uv-lock-cosmo-numba/uv-lock-cosmo-numba.md index 175f4c3d..c54752d1 100644 --- a/.felt/sp_validation/uv-lock-cosmo-numba/uv-lock-cosmo-numba.md +++ b/.felt/sp_validation/uv-lock-cosmo-numba/uv-lock-cosmo-numba.md @@ -8,8 +8,8 @@ tags: - future - constitution created-at: 2026-07-11T11:13:29.048895365+02:00 -updated-at: 2026-07-11T11:35:39.19956558+02:00 -outcome: 'Spun off 2026-07-11 from the image-sims gate failure: sp_validation''s published image drifted numpy to 2.5, breaking numba, because cosmo_numba (its numba-bearing dep, imported in b_modes.py and importorskip''d in tests) is undeclared and there is no lockfile — the resolver can''t see numba''s numpy window. Fix: declare cosmo_numba as a dependency, adopt uv with a committed uv.lock (mirroring shapepipe), and drop unscoped ''--upgrade'' install layers from the Dockerfile (use --upgrade-package). Unblocks collapsing the image-sims chain back to one container.' +updated-at: 2026-07-11T12:55:32.54099491+02:00 +outcome: 'PR #266 open (Closes #265), CI image build running — the validator of desired-state #4. Change: declare cosmo-numba @ aguinot/cosmo-numba@main (main carries the numpy-2 FFT fix via rocket-fft AND declares its deps, so numba''s window reaches the resolver) + pin numba directly as insurance; commit uv.lock (numpy 2.4.6, cs_util 0.2.2); Dockerfile installs from the lock via `uv sync --frozen --inexact` into the base /app/.venv, dropping the ad-hoc snakemake and cs_util `--upgrade` layers. Next: confirm the image build goes green (then it''s ready for Cail to merge — merge timing his). Open: cv_runner + unions_wl left undeclared (no resolvable source); numba insurance pin is droppable; shapepipe cs_util refresh now optional (we''re decoupled from the base''s cs_util).' shuttle: kind: oneshot host: candide @@ -35,3 +35,15 @@ sp_validation's dependency environment is un-locked and incomplete, and it just - Don't hand-pin numpy ceilings to track numba's compatibility — that's exactly the vigilance-based fix this task replaces with resolver-visible constraints. - Don't touch the image-sims workflow rules in this fiber; the `sif_pipeline` collapse happens in the image-sims fiber once the healthy image is published and verified. - Coordinate-lightly rule: Martin builds from the same Dockerfile lineage — keep the diff minimal and legible, no drive-by refactors of his layers. + +## Status + +Landed as **PR #266** (Closes #265, base `develop`, branch `uv-lock-cosmo-numba`), committed at `95843df`. All of desired-state #1–#3 and #5 are done; #4 is being validated by the CI image build triggered on push. + +**The resolution of the cosmo_numba question** (the session's main find): the constitution's premise — "declare cosmo_numba → numba's numpy window reaches the resolver" — was only half right. cosmo-numba is **not on PyPI**. Its refs diverge: the `fix/numpy2-fft-compat` fork tip (`db452c48`) declares `dependencies = []` (empty), so it contributes *nothing* to the resolver; `aguinot/cosmo-numba@main` declares its deps from `requirements.txt` (which uv reads fine) **and** carries the real numpy-2 FFT fix as a `rocket-fft` dependency (Cail's own PR-#17 objmode workaround was closed in favor of this — see his comment there). So we point at **@main**. Belt-and-suspenders: `numba` is *also* pinned directly in sp_validation, because cosmo-numba's dep metadata proved it can silently empty out between refs. Result: numpy locks to 2.4.6 (inside numba 0.66's <2.5 window). + +**Install model:** sp_validation builds `FROM` shapepipe's image, which provides a uv venv at `/app/.venv` (VIRTUAL_ENV). The Dockerfile does `uv sync --frozen --inexact` with `UV_PROJECT_ENVIRONMENT=/app/.venv` — `--inexact` keeps the inherited ShapePipe stack (not in our lock) rather than pruning it. Because our lock pins cs_util 0.2.2, we're **decoupled from the base image's cs_util** — the old `--upgrade` layer is gone and the shapepipe-side cs_util refresh Cail floated is now optional housekeeping, not a blocker here. + +**Next session picks up at:** watch PR #266's image build. Green → desired-state #4 met (import smoke + fast unit suite pass in the rebuilt image), ready for Cail to merge (his call). Red → read the failing step: likely candidates are NumbaQuadpack's git build (needs the apt build tools, present) or a base-vs-lock version clash surfaced by `uv sync --inexact` moving numpy/scipy under the inherited ngmix. Do **not** close this fiber until the build is green and merged; merge timing is Cail's. + +**Open threads:** `cv_runner` (imported in `workflow/scripts/cv_*.py`) and `unions_wl` (one footprint script) are left undeclared — no resolvable source found; Cail flagged cv_runner as not his. The `numba` insurance pin is deliberate but droppable once trust in cosmo-numba@main's metadata is established. From e572c62165b90bb7188fdb3d3f06903362e1e1bf Mon Sep 17 00:00:00 2001 From: Cail Daley Date: Sat, 11 Jul 2026 13:01:36 +0200 Subject: [PATCH 5/5] test: don't load base image's stale pytest-pydocstyle/pycodestyle plugins uv sync installs a newer pytest than the base ShapePipe image's pytest-pydocstyle/pytest-pycodestyle (>=2.4) expect; their pytest_collect_file hooks use the removed `path` arg and crash collection. sp_validation lints with ruff, so disable both via addopts (`-p no:`). Co-Authored-By: Claude Opus 4.8 Claude-Session: https://claude.ai/code/session_01Vtw1qcgTrQ6YuMvxwYzNup --- pyproject.toml | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index 43393f1d..150aba11 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -159,7 +159,14 @@ addopts = [ "--cov=sp_validation", "--cov-report=term", "--cov-report=xml", - "--junitxml=pytest.xml" + "--junitxml=pytest.xml", + # The base ShapePipe image's test extra ships old pytest-pydocstyle / + # pytest-pycodestyle, whose pytest_collect_file hooks use the `path` arg the + # newer pytest our lock installs has removed — they crash collection. + # sp_validation lints with ruff, not these, so don't load them. Harmless if + # absent (`-p no:` just skips an unregistered plugin). + "-p", "no:pydocstyle", + "-p", "no:pycodestyle" ] markers = [ "fast: marks tests as fast (deselect with '-m \"not fast\"')",