diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 85a1925..4277d2f 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,76 +1,173 @@ -# Zenzic โ€” Agent Guidelines +# Zenzic Agent Guidelines โ€” v0.6.1 "Obsidian Glass" Stable -Zenzic is an engine-agnostic linter and security shield for Markdown documentation (Docusaurus v3, MkDocs, Zensical, bare Markdown). It ships as a CLI (`zenzic`), a Python library, and a native MkDocs plugin. Python โ‰ฅ 3.11 required. +Zenzic is the high-performance, engine-agnostic Safe Harbor for Markdown documentation. +It is a STABLE product. Agents must prioritize precision, security, and "Value-First" communication. -## Build & Test +--- -```bash -uv sync --all-groups # install all dependency groups (once after clone) -just test # run tests โ€” Hypothesis dev profile (50 examples) -just test-full # CI-grade run (500 examples) -just preflight # full local CI: lint + format + typecheck + pytest + reuse -just verify # preflight + self-lint (zenzic check all --strict) -``` +## ๐ŸŽฏ Mission: The Safe Harbor -Common individual sessions: +- **Target:** Engineers, Technical Writers, and curious users. +- **Philosophy:** "If the engine builds the site, Zenzic guarantees the source." +- **Communication:** README is a Landing Page, not a manual. Move technical deep-dives to the documentation portal (zenzic.dev). -```bash -nox -s lint -- --fix # ruff autofix -nox -s fmt # ruff format in-place -nox -s typecheck # mypy --strict on src/ -nox -s reuse # SPDX/REUSE compliance check -``` +--- + +## ๐Ÿš€ Key Features (v0.6.1 โ€” Obsidian Glass Stable) + +- **Instant Entry:** `uvx zenzic check all ./path` is the primary curiosity path. +- **Zenzic Lab:** 9 interactive Acts for onboarding (zero-config showroom). Run `zenzic lab` to see the menu; `zenzic lab ` to run a specific act. +- **Standalone Mode:** Default engine for pure Markdown projects with no recognised build system. Replaces the old "Vanilla" identity entirely. +- **Zensical Bridge:** Transparent Proxy for `mkdocs.yml` compatibility under `engine = "zensical"`. +- **Enterprise Docusaurus:** Full versioning, `@site/` alias, and slug logic alignment. +- **Offline Mode:** `--offline` flag for flat `.html` URL structure. +- **SEO Guardrail:** `Z401 MISSING_DIRECTORY_INDEX` detection for directories without a landing page. +- **Finding Codes (Zxxx):** Every diagnostic carries a unique `Zxxx` identifier for enterprise-grade auditing and future filtering. + +--- + +## ๐Ÿงฑ The 3 Pillars (Non-Negotiable) + +1. **Lint the Source:** Never depend on HTML output. Analyze raw Markdown and configs. +2. **No Subprocesses:** 100% pure Python. No `subprocess.run`, no Node.js execution. +3. **Pure Functions First:** Deterministic logic. No I/O in hot-path loops. + +--- + +## ๐Ÿ›ก๏ธ Core Laws for Code -See [justfile](../justfile) for the full recipe list and [noxfile.py](../noxfile.py) for session definitions. +- **Zero I/O in hot paths:** No `Path.exists()` or `open()` inside link/file loops. +- **Mandatory ExclusionManager:** No discovery without an explicit exclusion manager. +- **Exit Codes:** 0 (Success), 1 (Quality), 2 (Shield/Secrets), 3 (Blood Sentinel/Fatal). +- **Finding Codes:** Every `Finding` object must carry a `Zxxx` code from `src/zenzic/core/codes.py`. Never hardcode a raw string code; always use `codes.normalize()`. -## Architecture +--- + +## ๐Ÿ“ Architecture Map ```text src/zenzic/ -โ”œโ”€โ”€ main.py / cli.py # Typer CLI (commands: check, score, diff) -โ”œโ”€โ”€ core/ # Hot-path analysis engine (zero I/O โ€” see Core Laws) -โ”‚ โ”œโ”€โ”€ adapter.py # BaseAdapter Protocol + RouteMetadata -โ”‚ โ”œโ”€โ”€ adapters/ # docusaurus_v3, mkdocs, zensical, vanilla -โ”‚ โ”œโ”€โ”€ discovery.py # Universal file discovery (os.walk + LayeredExclusionManager) -โ”‚ โ”œโ”€โ”€ exclusion.py # LayeredExclusionManager (4-level: System โ†’ VCS โ†’ Config โ†’ CLI) -โ”‚ โ”œโ”€โ”€ rules.py # AdaptiveRuleEngine + O(V+E) circular detection -โ”‚ โ”œโ”€โ”€ shield.py # Credential scanner (9 families, 8-step normalization, lookback buffer) -โ”‚ โ”œโ”€โ”€ resolver.py # InMemoryPathResolver (link resolution) -โ”‚ โ”œโ”€โ”€ scanner.py # Two-Pass Reference Pipeline (Harvest โ†’ Cross-Check โ†’ Report) -โ”‚ โ””โ”€โ”€ validator.py # validate_links_async orchestrator -โ”œโ”€โ”€ models/ # Pydantic models (config, references, vsm) -โ””โ”€โ”€ integrations/mkdocs.py # Native MkDocs plugin + cli.py โ€” Typer CLI entry-points; builds Finding objects via _to_findings() + lab.py โ€” Interactive showcase (9 Acts); menu-driven with positional arg + core/ + adapter.py โ€” Public re-exports (StandaloneAdapter, MkDocsAdapter, โ€ฆ) + adapters/ + _standalone.py โ€” StandaloneAdapter: no-op engine for pure Markdown projects + _mkdocs.py โ€” MkDocs engine adapter + _docusaurus.py โ€” Docusaurus v3 engine adapter + _zensical.py โ€” Zensical engine adapter (+ Transparent Proxy) + _factory.py โ€” get_adapter() factory; contains vanillaโ†’standalone migration guard + __init__.py โ€” Public adapter registry + codes.py โ€” Zxxx finding code registry (SINGLE SOURCE OF TRUTH) + reporter.py โ€” SentinelReporter; renders Finding objects to Rich output + scanner.py โ€” File discovery, orphan detection, shield bridge + validator.py โ€” Link / anchor / path-traversal validation + rules.py โ€” VSM-based rule engine (Z001, Z002) + shield.py โ€” Credential scanner (exits 2/3) + scorer.py โ€” Quality score engine + models/ + config.py โ€” ZenzicConfig / BuildContext (Pydantic) + vsm.py โ€” Virtual Site Map (Route, build_vsm, detect_collisions) + references.py โ€” Reference integrity (IntegrityReport, ReferenceFinding) + ui.py โ€” Shared Rich colour constants and emoji helpers +tests/ + test_standalone_mode.py โ€” StandaloneAdapter unit tests + factory routing + test_vsm.py โ€” Virtual Site Map tests + test_blue_vsm_edge.py โ€” VSM edge-case stress tests + test_protocol_evolution.py โ€” Adapter protocol compliance + Hypothesis stress tests + test_cli.py โ€” CLI integration tests (Typer runner) + test_scanner.py โ€” Scanner / orphan / i18n tests + test_rules.py โ€” Rule engine tests + test_shield.py โ€” Shield / credential detection tests ``` -Third-party adapters and rules are discoverable via `zenzic.adapters` / `zenzic.rules` entry-point groups. +--- + +## ๐Ÿ”Ž Finding Code Standard (Zxxx) + +All diagnostics emitted by Zenzic carry a `Zxxx` code. The registry is in +`src/zenzic/core/codes.py`. **Never add a new finding without registering its code there first.** + +| Range | Category | Examples | +|-------|----------|---------| +| Z1xx | Link Integrity | Z101 LINK_BROKEN, Z102 ANCHOR_MISSING, Z104 FILE_NOT_FOUND | +| Z2xx | Security | Z201 SHIELD_SECRET, Z202 PATH_TRAVERSAL | +| Z3xx | Reference Integrity | Z301 DANGLING_REF, Z302 DEAD_DEF | +| Z4xx | Structure | Z401 MISSING_DIRECTORY_INDEX, Z402 ORPHAN_PAGE | +| Z5xx | Content Quality | Z501 PLACEHOLDER, Z503 SNIPPET_ERROR | +| Z9xx | Engine / System | Z902 RULE_TIMEOUT | + +When creating a `Finding`, always call `codes.normalize(raw_code)` to map legacy strings to canonical `Zxxx` codes. The `_to_findings()` function in `cli.py` is the authorised conversion point. + +--- + +## ๐Ÿญ Adapter Identity Rules + +- **"standalone"** is the canonical engine name for projects with no build config. Use `StandaloneAdapter`. +- **"vanilla"** is a removed legacy name. Any usage raises `ConfigurationError` with code `Z000`. +- `pyproject.toml` entry-point: `standalone = "zenzic.core.adapters:StandaloneAdapter"`. +- In Standalone Mode, navigation-based checks (orphan detection) are disabled because there is no declared nav. +- When `zenzic init` finds no engine config, it writes `engine = "standalone"` in the `[build_context]` block. + +--- + +## ๐Ÿงช Quality Gate + +- **Coverage:** โ‰ฅ 80% mandatory. +- **Mutation:** Mutmut audit on `rules.py` and `shield.py`. +- **Property Testing:** Hypothesis for `resolver.py` and adapter stress-testing. +- **Test naming:** All test functions relating to the Standalone adapter use the prefix `test_standalone_*`. + +--- + +## ๐Ÿ“ README Restyling Rules + +When editing `README.md` or `README.it.md`: + +1. **Above the Fold:** Hook + uvx command + Quick Start + Sentinel Report must be visible within 2 scrolls. +2. **Problem/Solution:** Use tables to contrast "Without Zenzic" vs "With Zenzic". +3. **Deduplicate:** Technical implementation details belong in `/docs/internals` on zenzic.dev. +4. **Bilingual Parity:** EN and IT must be perfectly mirrored in structure and quality. +5. **Branding:** Keep "Shield", "Blood Sentinel", "VSM", "Ghost Routes" as-is (Proper Nouns). +6. **Standalone, not Vanilla:** Never write "Vanilla Mode" in user-facing copy. Use "Standalone Mode". + +--- + +## ๐Ÿงน Maintenance & Sunset Clauses (Technical Debt Tracking) + +### 1. Vanilla-to-Standalone Migration Guard + +- **Status:** Deprecated. +- **Location:** `src/zenzic/core/adapters/_factory.py` (check for `engine == "vanilla"`). +- **Behavior:** Raises a `ConfigurationError` with code `Z000` to guide users to `engine = "standalone"`. +- **Sunset Target:** **v0.7.0**. +- **Instruction:** Do NOT remove this guard in 0.6.x patches. MUST be deleted entirely in the 0.7.0 release to achieve zero-legacy codebase. + +### 2. Finding Codes (Zxxx) + +- **Standard:** All diagnostics must use the `Zxxx` format. +- **Rule:** Never introduce a new finding string without a corresponding code in `src/zenzic/core/codes.py`. + +--- + +## ๐Ÿ—บ๏ธ Sprint History (for institutional memory) + +### Direttiva 036 โ€” Finding Code Mapping -## Core Laws +Codified all diagnostic outputs into the `Zxxx` scheme. `codes.py` created as single source of truth. -1. **Zero I/O in the hot path**: nothing inside `src/zenzic/core/` may call `Path.exists()`, `open()`, or subprocesses inside per-link or per-file loops. Only two I/O phases are permitted: `discovery.py` file enumeration (via `os.walk` + `LayeredExclusionManager`) and `InMemoryPathResolver.__init__`. -2. **Subprocess-free linting**: `zenzic check` never calls `mkdocs build` or any external process. -3. **Mandatory ExclusionManager**: every file-discovery entry point requires a `LayeredExclusionManager` argument โ€” no `Optional`, no `None` default. Omitting it is a `TypeError` at call time, not a silent full-tree scan at runtime. +### Direttiva 037 โ€” Standalone Renaissance -Violating any of these laws is a blocking defect โ€” do not introduce exceptions. +Full rename: `VanillaAdapter` โ†’ `StandaloneAdapter`, `_vanilla.py` โ†’ `_standalone.py`, entry-point `vanilla` โ†’ `standalone`. Breaking change: `engine = "vanilla"` raises `ConfigurationError [Z000]`. Test suite fully migrated to `test_standalone_mode.py`. -## Code Conventions +### Direttiva 038 โ€” Final Audit Record -- **Type checking**: `mypy --strict` must pass on all of `src/`. Never suppress with `# type: ignore` without a comment explaining why. -- **Linting**: ruff rules `E, F, W, I, B, C4, UP, A`; line length 100; isort `known-first-party = ["zenzic"]`. -- **SPDX headers**: every source file must start with `# SPDX-FileCopyrightText: ...` and `# SPDX-License-Identifier: Apache-2.0`. Run `nox -s reuse` to verify. -- **No stubs**: no `TODO`, placeholder text, or stub implementations in committed code. -- **Coverage**: โ‰ฅ 80% branch coverage enforced by pytest. Mutation goal โ‰ฅ 90% on `rules.py`, `shield.py`, `reporter.py`. -- **Discovery**: never use `Path.rglob()` or `glob.glob()` directly. All file enumeration goes through `discovery.iter_markdown_sources()` or `discovery.walk_files()` with a `LayeredExclusionManager`. +CHANGELOG.md, CHANGELOG.it.md, and RELEASE.md updated to reflect the Breaking Change (Vanilla โ†’ Standalone), the Zxxx code introduction, and the interactive Lab menu. -## Tests +### Direttiva 039 โ€” The Guardrail Lifecycle -- Tests live in `tests/`; helpers in `tests/_helpers.py`; fixtures in `tests/conftest.py`. -- Hypothesis profiles: `dev` (50), `ci` (500), `purity` (1000) โ€” set via `HYPOTHESIS_PROFILE`. -- Markers: `slow`, `integration` โ€” run with `-m "not slow"` to skip heavy tests locally. -- The `_reset_zenzic_logger` autouse fixture resets the `RichHandler` after each test; do not remove it. +Migration guard in `_factory.py` annotated with `# TODO: Remove this migration guard in v0.7.0.` and error message prefixed with `[Z000]`. Docstring clarified. -## Key Docs +### Direttiva 040 โ€” Institutional Memory -- [CONTRIBUTING.md](../CONTRIBUTING.md) โ€” dev workflow, PR conventions, Core Laws reference -- [SECURITY.md](../SECURITY.md) โ€” vulnerability reporting and scope -- [CHANGELOG.md](../CHANGELOG.md) โ€” version history -- [RELEASE.md](../RELEASE.md) โ€” release checklist +This file (`.github/copilot-instructions.md`) created / restored as the canonical agent briefing document, embedding all sprint directives and sunset clauses for permanent institutional memory. diff --git a/.gitignore b/.gitignore index 5c8fb2b..d6f28bf 100644 --- a/.gitignore +++ b/.gitignore @@ -41,6 +41,7 @@ dist/ # Zenzic: Drafts drafts/ +Draft/ *.egg MANIFEST .installed.cfg diff --git a/CHANGELOG.it.md b/CHANGELOG.it.md index ac72242..285cd9f 100644 --- a/CHANGELOG.it.md +++ b/CHANGELOG.it.md @@ -11,6 +11,76 @@ Le versioni seguono il [Semantic Versioning](https://semver.org/). ## [Non rilasciato] +## [0.6.1] โ€” 2026-04-19 โ€” Obsidian Glass (Stable) + +### Modifiche che rompono la compatibilitร  + +- **Standalone Engine sostituisce Vanilla (Direttiva 037).** `VanillaAdapter` e la + keyword `engine = "vanilla"` sono stati rimossi. Tutti i progetti devono migrare a + `engine = "standalone"`. Qualsiasi `zenzic.toml` che usa ancora `engine = "vanilla"` + genera una `ConfigurationError [Z000]` all'avvio con un messaggio di migrazione chiaro. + *Migrazione:* sostituire `engine = "vanilla"` con `engine = "standalone"` nel proprio + `zenzic.toml` o nel blocco `[tool.zenzic]`. + +### Aggiunto + +- **Codici Finding (Zxxx) (Direttiva 036).** Ogni diagnostica emessa da Zenzic ora + porta un identificatore univoco leggibile dalla macchina (es. `Z101 LINK_BROKEN`, + `Z201 SHIELD_SECRET`, `Z401 MISSING_DIRECTORY_INDEX`). Il registro completo si trova + in `src/zenzic/core/codes.py` โ€” unica fonte di veritร  per tutti i codici. +- **Menu interattivo del Lab.** `zenzic lab` senza argomenti mostra ora l'indice degli + atti per scegliere quale scenario esplorare. Eseguire `zenzic lab ` per avviare + un atto specifico (0โ€“8). L'opzione `--act` รจ stata sostituita da un argomento + posizionale. +- **Identitร  Standalone Mode.** `StandaloneAdapter` รจ il motore no-op canonico per + progetti Markdown puri. `zenzic init` ora scrive `engine = "standalone"` quando non + viene rilevata nessuna configurazione di framework. + +- **Flag `--offline` per la risoluzione URL Flat.** Disponibile su `check all`, + `check links` e `check orphans`. Forza tutti gli adapter a produrre URL `.html` + (es. `guida/install.md` โ†’ `/guida/install.html`) invece di slug in stile directory. +- **Supporto multi-versione Docusaurus v3.** `DocusaurusAdapter` ora identifica + `versions.json`, `versioned_docs/` e le traduzioni versionate. +- **Proxy Trasparente Zensical.** Se viene dichiarato `engine = "zensical"` ma + `zensical.toml` รจ assente, l'adapter crea automaticamente un ponte con il tuo + `mkdocs.yml` esistente. +- **Ghost Routing consapevole delle versioni.** I percorsi della documentazione + versionata sono automaticamente classificati come `REACHABLE`. +- **Risoluzione Alias @site/.** Aggiunto il supporto per l'alias di percorso `@site/` + in `DocusaurusAdapter`, permettendo la corretta risoluzione dei link relativi al progetto. +- **Integritร  dell'Indice di Directory.** Nuovo metodo `provides_index(path)` nel protocollo + `BaseAdapter` per il rilevamento engine-aware delle directory prive di landing page. + Il finding `MISSING_DIRECTORY_INDEX` (severitร : `info`), emesso da `zenzic check all`, + avvisa di ogni sottodirectory che contiene sorgenti Markdown ma nessun indice fornito + dall'engine โ€” prevenendo i 404 gerarchici prima del deploy. +- **Notifiche nel Banner Sentinel.** Nuovi messaggi di stato per l'attivazione della + **Modalitร  Offline** e della **Modalitร  Proxy**. + +### Corretto + +- **Audit dei Guardiani: Allineamento Specifiche Ufficiali.** + - **Versioning Docusaurus:** Corretta la mappatura URL della versione "latest" (prima voce + in `versions.json`) per escludere il prefisso dell'etichetta di versione, allineandosi + al comportamento ufficiale di Docusaurus. In precedenza ogni file versionato riceveva + un prefisso `/versione/`, generando falsi positivi per tutte le pagine della versione latest. + - **Slug Docusaurus:** Gli slug frontmatter assoluti (es. `slug: /mio-percorso`) sono + ora correttamente preceduti dalla `routeBasePath` (es. `/docs/mio-percorso/`), + allineandosi alla specifica Docusaurus `normalizeUrl([versionMetadata.path, docSlug])`. + - **Collasso Intelligente dei File:** La logica `isCategoryIndex` ora rispecchia + esattamente Docusaurus: `README.md`, `INDEX.md` (case-insensitive) e + `{NomeCartella}/{NomeCartella}.md` collassano nell'URL della directory genitore, + prevenendo falsi positivi per le convenzioni valide di landing page di categoria. + - **Risoluzione Alias `@site/`:** `InMemoryPathResolver` ora risolve i link `@site/` + rispetto al corretto confine `repo_root` invece di sfuggire tramite `../`, + eliminando errori `PathTraversal` spuri per tutti i link relativi al progetto Docusaurus. +- **Integritร  dei Metadati.** Corretto l'allineamento delle stringhe di versione in + `CITATION.cff` e `pyproject.toml`. +- **Default routeBasePath Docusaurus.** Ripristinato `docs` come prefisso URL predefinito + per i progetti Docusaurus per corrispondere al comportamento ufficiale dell'engine. + +- **Paritร  Documentale Bilingue.** Copertura completa della documentazione EN/IT per + tutte le feature della v0.6.1 nelle guide Architettura, Motori e Comandi. + ## [0.6.1rc2] โ€” 2026-04-16 โ€” Obsidian Bastion (Hardened) ### SICUREZZA: Risultati Operation Obsidian Stress @@ -97,7 +167,7 @@ Le versioni seguono il [Semantic Versioning](https://semver.org/). `check_nav_contract`, e tutte le funzioni dello scanner. Nessun default `None` retrocompatibile. -## [0.6.0a2] โ€” 2026-04-13 โ€” Obsidian Glass +## [0.6.0a2] โ€” 2026-04-13 โ€” Obsidian Glass (Alpha 2) ### Aggiunto diff --git a/CHANGELOG.md b/CHANGELOG.md index 9ad9bda..5b97a35 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,73 @@ Versions follow [Semantic Versioning](https://semver.org/). ## [Unreleased] +## [0.6.1] โ€” 2026-04-19 โ€” Obsidian Glass (Stable) + +### Breaking Changes + +- **Standalone Engine replaces Vanilla (Direttiva 037).** The `VanillaAdapter` and the + `engine = "vanilla"` keyword have been removed. All projects must migrate to + `engine = "standalone"`. Any `zenzic.toml` still using `engine = "vanilla"` will + raise a `ConfigurationError [Z000]` at startup with a clear migration message. + *Migration:* replace `engine = "vanilla"` with `engine = "standalone"` in your + `zenzic.toml` or `[tool.zenzic]` block. + +### Added + +- **Finding Codes (Zxxx) (Direttiva 036).** Every diagnostic emitted by Zenzic now + carries a unique machine-readable identifier (e.g. `Z101 LINK_BROKEN`, + `Z201 SHIELD_SECRET`, `Z401 MISSING_DIRECTORY_INDEX`). The full registry lives in + `src/zenzic/core/codes.py` โ€” the single source of truth for all codes. +- **Interactive Lab menu.** `zenzic lab` without arguments now displays the act index + so you can choose which scenario to explore. Run `zenzic lab ` to execute a + specific act (0โ€“8). The `--act` option has been replaced by a positional argument. +- **Standalone Mode identity.** `StandaloneAdapter` is the canonical no-op engine for + pure Markdown projects. `zenzic init` now writes `engine = "standalone"` when no + framework config is detected. + +- **`--offline` flag for Flat URL resolution.** Available on `check all`, `check links`, + and `check orphans`. Forces all adapters to produce `.html` URLs (e.g. `guide/install.md` + โ†’ `/guide/install.html`) instead of directory-style slugs. +- **Docusaurus v3 Multi-version support.** The `DocusaurusAdapter` now identifies + `versions.json`, `versioned_docs/`, and versioned translations. +- **Zensical Transparent Proxy.** If `engine = "zensical"` is declared but `zensical.toml` + is missing, the adapter automatically bridges your existing `mkdocs.yml`. +- **Version-aware Ghost Routing.** Versioned documentation paths are automatically + classified as `REACHABLE`. +- **@site/ Alias Resolution.** Added support for the `@site/` path alias in + `DocusaurusAdapter`, enabling project-relative links to be resolved correctly. +- **Directory Index Integrity.** New `provides_index(path)` method on the `BaseAdapter` + protocol enables engine-aware detection of directories that lack a landing page. + The `MISSING_DIRECTORY_INDEX` finding (severity: `info`) is emitted by `zenzic check all` + for every subdirectory that contains Markdown sources but no engine-provided index entry + โ€” preventing hierarchical 404s before deployment. +- **Sentinel Banner Notifications.** New status messages for **Offline Mode** and + **Proxy Mode** activation. + +### Fixed + +- **Guardians Audit: Official Specs Alignment.** + - **Docusaurus Versioning:** Fixed "latest" version (first entry in `versions.json`) URL + mapping to exclude the version label prefix, matching official Docusaurus behavior. + Previously every versioned file received a `/version/` prefix, causing false positive + broken-link reports for all latest-version pages. + - **Docusaurus Slugs:** Absolute frontmatter slugs (e.g. `slug: /my-path`) are now + correctly prepended with `routeBasePath` (e.g. `/docs/my-path/`), aligning with + the Docusaurus `normalizeUrl([versionMetadata.path, docSlug])` specification. + - **Smart File Collapsing:** `isCategoryIndex` logic now mirrors Docusaurus exactly: + `README.md`, `INDEX.md` (case-insensitive), and `{FolderName}/{FolderName}.md` + collapse to the parent directory URL, preventing false positive broken-link reports + for valid category landing page conventions. + - **`@site/` Alias Resolution:** The `InMemoryPathResolver` now resolves `@site/` + links against the correct `repo_root` boundary instead of escaping via `../`, + eliminating spurious `PathTraversal` errors for all Docusaurus project-relative links. +- **Metadata Integrity.** Corrected version string alignment in `CITATION.cff` and `pyproject.toml`. +- **Docusaurus routeBasePath default.** Restored `docs` as the default URL prefix for + Docusaurus projects to match official engine behavior. + +- **Bilingual Documentation Parity.** Full EN/IT documentation coverage for all + v0.6.1 features across the Architecture, Engine, and Command guides. + ## [0.6.1rc2] โ€” 2026-04-16 โ€” Obsidian Bastion (Hardened) ### SECURITY: Operation Obsidian Stress Findings @@ -91,7 +158,7 @@ Versions follow [Semantic Versioning](https://semver.org/). `check_nav_contract`, and all scanner functions. No backward-compatible `None` default. -## [0.6.0a2] โ€” 2026-04-13 โ€” Obsidian Glass +## [0.6.0a2] โ€” 2026-04-13 โ€” Obsidian Glass (Alpha 2) ### Added diff --git a/CITATION.cff b/CITATION.cff index 880f693..2451651 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -14,8 +14,8 @@ abstract: >- Markdown-based documentation. Zenzic introduces Universal Discovery, VCS-aware exclusion mapping, and the Sentinel Shield middleware to provide a deterministic Safe Harbor for complex documentation lifecycles. -version: 0.6.1rc2 -date-released: 2026-04-16 +version: 0.6.1 +date-released: 2026-04-19 url: "https://zenzic.dev" repository-code: "https://github.com/PythonWoods/zenzic" repository-artifact: "https://pypi.org/project/zenzic/" diff --git a/CONTRIBUTING.it.md b/CONTRIBUTING.it.md index 833050e..3a052b6 100644 --- a/CONTRIBUTING.it.md +++ b/CONTRIBUTING.it.md @@ -223,7 +223,7 @@ repo_root = find_repo_root() Aggiungere `fallback_to_cwd=True` a qualsiasi comando diverso da `init` richiede un Architecture Decision Record che spieghi perchรฉ quel comando necessita di accesso senza perimetro. -Vedi [ADR 003](https://zenzic.dev/docs/internals/adr/003-discovery-logic) per la motivazione completa e la storia della modifica ZRT-005. +Vedi [ADR 003](https://zenzic.dev/docs/internals/adr/discovery-logic/) per la motivazione completa e la storia della modifica ZRT-005. ### Il Motore di Discovery diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b058f7a..3f67f16 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -282,7 +282,7 @@ Adding `fallback_to_cwd=True` to any command other than `init` requires a recorded Architecture Decision Record explaining why that command needs perimeter-free access. -See [ADR 003](https://zenzic.dev/docs/internals/adr/003-discovery-logic) for the full rationale and +See [ADR 003](https://zenzic.dev/docs/internals/adr/discovery-logic/) for the full rationale and the ZRT-005 amendment history. ### The Discovery Engine diff --git a/README.it.md b/README.it.md index 9727288..6b06a80 100644 --- a/README.it.md +++ b/README.it.md @@ -12,7 +12,7 @@ SPDX-License-Identifier: Apache-2.0

- PyPI Version + PyPI Version Python Versions @@ -35,690 +35,365 @@ SPDX-License-Identifier: Apache-2.0

- Zenzic Shield audita internamente questo repository per credenziali esposte ad ogni commit. + Zenzic Shield verifica internamente questo repository per credenziali esposte ad ogni commit.

- "Zenzic รจ il Safe Harbor (Porto Sicuro) per l'integritร  della tua documentazione. Non si limita a controllare i link; audita la resilienza tecnica del tuo progetto."
- Sentinella della documentazione โ€” autonoma, agnostica rispetto all'engine, e a prova di sicurezza. + Il Safe Harbor per la tua documentazione Markdown.
+ Analisi statica engine-agnostic โ€” standalone, con sicurezza rafforzata, zero configurazione richiesta.

-```bash -โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ ๐Ÿ›ก ZENZIC SENTINEL v0.6.1rc2 โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€-โ”€โ”€โ”€โ”€โ•ฎ -โ”‚ โ”‚ -โ”‚ docusaurus โ€ข 38 files (18 docs, 20 assets) โ€ข 0.9s โ”‚ -โ”‚ โ”‚ -โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ -โ”‚ โ”‚ -โ”‚ โœ” All checks passed. Your documentation is secure. โ”‚ -โ”‚ โ”‚ -โ”‚ ๐Ÿ’ก 4 info findings suppressed โ€” use --show-info for details. โ”‚ -โ”‚ โ”‚ -โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ -``` - --- -> La documentazione non fallisce rumorosamente. Degrada in silenzio. - -Link non raggiungibili, pagine orfane, snippet di codice non validi, contenuto placeholder mai -completato e chiavi API esposte si accumulano nel tempo โ€” finchรฉ gli utenti non li incontrano in -produzione. Zenzic rileva tutto questo nei progetti [Docusaurus][docusaurus], [MkDocs][mkdocs] e -[Zensical][zensical] come **CLI autonoma**, senza richiedere l'installazione di alcun framework -di build. +## โšก Provalo subito โ€” Zero Installazione -Zenzic รจ **agnostico** โ€” funziona con qualsiasi sistema di documentazione basato su Markdown -(Docusaurus, MkDocs, Zensical, o una semplice cartella di file `.md`) senza installare alcun -framework di build. Legge i file sorgente e le configurazioni di build come testo puro. Ed รจ -**opinionated**: i link assoluti sono un errore bloccante, l'identitร  dell'engine deve essere -dimostrabile, e la CLI รจ 100% subprocess-free. +Hai una cartella di file Markdown? Esegui un audit istantaneo dei link e della sicurezza usando [`uv`][uv]: ---- - -## Capacitร  Principali - -- **Sicurezza** โ€” Shield (9 famiglie di credenziali, Exit 2) con resistenza all'offuscamento Unicode, decodifica entitร  HTML, difesa da comment-interleaving e lookback per token spezzati tra righe. Sentinella di Sangue (path traversal verso directory di sistema, Exit 3). Regex ReDoS-safe (F2-1), protezione jailbreak (F4-1). Nessuno dei due รจ sopprimibile con `--exit-zero`. -- **Integritร ** โ€” Rilevamento link circolari O(V+E), Virtual Site Map con cache content-addressable, punteggio qualitร  deterministico 0โ€“100. -- **Intelligenza** โ€” Multi-engine: MkDocs, Docusaurus v3, Zensical e Vanilla. Cache adapter a livello di modulo. Gli adapter di terze parti si installano come pacchetti Python tramite entry point. -- **Discovery** โ€” Iterazione file universale VCS-aware (zero `rglob`), `ExclusionManager` obbligatorio su ogni entry point, gerarchia di Esclusione a 4 livelli, parser `.gitignore` pure-Python. +```bash +uvx zenzic check all ./tua-cartella +``` -> ๐Ÿš€ **Ultima Release: v0.6.1rc2 "Obsidian Bastion"** โ€” vedi [CHANGELOG.md](CHANGELOG.md) per i dettagli. +Zenzic identificherร  il tuo motore tramite i file di configurazione o passerร  alla **modalitร  Vanilla** +per cartelle indipendenti โ€” garantendo protezione immediata per link, credenziali e integritร  strutturale. --- -## ๐Ÿ“– Documentazione +## ๐Ÿš€ Quick Start -- ๐Ÿš€ **[Guida Utente][docs-it-home]**: Installazione, comandi CLI e tutti i controlli disponibili. -- โš™๏ธ **[Configurazione][docs-it-config]**: Riferimento completo di `zenzic.toml`, DSL - `[[custom_rules]]` e sistema di adapter. -- ๐Ÿ”„ **[Guida alla Migrazione][docs-it-migration]**: Come usare Zenzic per validare la migrazione - da MkDocs a Zensical. -- ๐Ÿ—๏ธ **[Architettura][docs-it-arch]**: Approfondimento sulla pipeline deterministica, il - Two-Pass Reference Scanner e il sistema di adapter. -- ๐Ÿ”Œ **[Scrivere un Adapter][docs-it-adapter]**: Estendi Zenzic con supporto per il tuo engine - di documentazione. +```bash +pip install zenzic +zenzic lab # Showroom interattivo โ€” 9 atti, ogni motore, zero configurazione +zenzic check all # Analizza la cartella corrente +``` -

- Esplora la documentazione completa โ†’ -

+๐Ÿ“– [Documentazione completa โ†’][docs-it-home] ยท ๐Ÿ… [Badge][docs-it-badges] ยท ๐Ÿ”„ [Guida CI/CD][docs-it-cicd] --- -## Cosa controlla Zenzic - -| Controllo | Comando CLI | Cosa rileva | -| --- | --- | --- | -| Links | `zenzic check links` | Link interni non raggiungibili, ancore morte, **path traversal** | -| Orfani | `zenzic check orphans` | File `.md` assenti dalla `nav` | -| Snippet | `zenzic check snippets` | Blocchi Python, YAML, JSON e TOML con errori di sintassi | -| Placeholder | `zenzic check placeholders` | Pagine stub e pattern di testo proibiti | -| Asset | `zenzic check assets` | Immagini e file non referenziati da nessuna pagina | -| **Riferimenti** | `zenzic check references` | Dangling References, Dead Definitions, **Zenzic Shield** | - -`zenzic score` aggrega tutti i controlli in un punteggio di qualitร  deterministico 0โ€“100. -`zenzic diff` confronta il punteggio attuale con un baseline salvato โ€” abilitando il rilevamento -delle regressioni su ogni pull request. +## ๐ŸŽฏ Perchรฉ Zenzic? -**Autofix:** Zenzic fornisce anche utility di pulizia attiva. Esegui `zenzic clean assets` per eliminare automaticamente le immagini non utilizzate identificate da `check assets` (in modo interattivo o tramite `-y`). +| Senza Zenzic | Con Zenzic | +| :--- | :--- | +| โŒ Ancore rotte passano silenziosamente in Docusaurus v3 | โœ… Validazione matematica delle ancore tramite VSM | +| โŒ Chiavi API esposte nei blocchi di codice committate su git | โœ… **The Shield** โ€” scanner 9 famiglie di credenziali, exit 2 | +| โŒ Path traversal `../../../../etc/passwd` nei link | โœ… **Blood Sentinel** โ€” exit 3 non sopprimibile | +| โŒ Pagine orfane irraggiungibili da qualsiasi link di navigazione | โœ… Rilevamento semantico degli orfani โ€” non solo file-exists | +| โŒ 404 silenziosi che si accumulano in Google Search Console | โœ… Controlli di integritร  Directory Index | +| โŒ Migrazione MkDocs โ†’ Zensical con errori sconosciuti | โœ… **Transparent Proxy** โ€” analizza entrambi con un comando | --- -## Standard di Portabilitร  - -Zenzic applica due regole che rendono la documentazione portabile su qualsiasi ambiente di hosting -e indipendente da qualsiasi motore di build specifico. - -### Applicazione dei Percorsi Relativi +## ๐Ÿงฉ Cosa NON รจ Zenzic -Zenzic **rifiuta i link interni che iniziano con `/`**. I percorsi assoluti dipendono dall'ambiente: -un link a `/assets/logo.png` funziona quando il sito รจ alla radice del dominio, ma restituisce 404 -quando รจ ospitato in una sottodirectory (es. `https://example.com/docs/assets/logo.png` โ‰  -`https://example.com/assets/logo.png`). - -```markdown - -[Scarica](/assets/guide.pdf) - - -[Scarica](../assets/guide.pdf) -``` +- **Non รจ un generatore di siti.** Analizza la sorgente; non costruisce mai HTML. +- **Non รจ un wrapper di build.** Zero-Trust Execution: nessun sottoprocesso, nessun binario `mkdocs` o `docusaurus` invocato. +- **Non รจ un correttore ortografico.** Struttura e sicurezza โ€” non prosa. +- **Non รจ un crawler HTTP.** Tutta la validazione รจ locale e basata su file. -Il messaggio di errore include un suggerimento di correzione esplicito. Gli URL esterni (`https://...`) non -sono interessati. - -### Supporto i18n: Risoluzione Locale Multi-Engine - -Zenzic supporta nativamente documentazione locale-aware su tutti gli engine: +--- -**MkDocs โ€” Suffix Mode** (`pagina.locale.md`) e **Folder Mode** (`docs/it/pagina.md`) tramite -`mkdocs-static-i18n`. I link da pagine tradotte a pagine non tradotte sono risolti attraverso -il fallback alla locale di default quando `fallback_to_default: true` รจ impostato. +## ๐Ÿ“‹ Matrice delle Funzionalitร  -**Docusaurus v3 โ€” directory i18n** (`i18n/it/docusaurus-plugin-content-docs/current/`). -Zenzic scopre gli alberi di locale da `docusaurus.config.ts` automaticamente. I link tra -pagine locale e asset della locale di default sono risolti senza configurazione. +| Funzionalitร  | Comando | Rileva | Exit | +| :--- | :--- | :--- | :---: | +| Integritร  dei link | `check links` | Link rotti, ancore morte | 1 | +| Rilevamento orfani | `check orphans` | File assenti dalla `nav` โ€” invisibili dopo la build | 1 | +| Snippet di codice | `check snippets` | Errori di sintassi in blocchi Python / YAML / JSON / TOML | 1 | +| Contenuto placeholder | `check placeholders` | Pagine stub e pattern di testo vietati | 1 | +| Asset inutilizzati | `check assets` | Immagini e file non referenziati | 1 | +| **Scansione credenziali** | `check references` | **9 famiglie di credenziali** โ€” testo, URL, blocchi di codice | **2** | +| **Path traversal** | `check links` | Tentativi di fuga verso path di sistema | **3** | +| Punteggio qualitร  | `score` | Metrica composita deterministica 0โ€“100 | โ€” | +| Rilevamento regressioni | `diff` | Calo del punteggio vs baseline salvata โ€” CI-friendly | 1 | -**Zensical** โ€” Solo Suffix Mode (`pagina.locale.md`), simile a MkDocs. +**Correzione automatica:** `zenzic clean assets [-y] [--dry-run]` elimina gli asset inutilizzati. -In Folder Mode (MkDocs) e Docusaurus i18n, Zenzic usa la sezione `[build_context]` in -`zenzic.toml` per identificare le directory di locale: +> ๐Ÿš€ **v0.6.1 "Obsidian Glass" (Stabile)** โ€” Versioning completo Docusaurus v3, risoluzione +> alias `@site/` e Transparent Proxy Zensical. Vedi [CHANGELOG.md](CHANGELOG.md). -```toml -# zenzic.toml -[build_context] -engine = "mkdocs" # "mkdocs", "docusaurus", "zensical" o "vanilla" -default_locale = "en" -locales = ["it", "fr"] # nomi delle directory locale non default -``` - -Quando `zenzic.toml` รจ assente, Zenzic legge la configurazione locale direttamente da `mkdocs.yml` -(rispettando `docs_structure`, `fallback_to_default` e `languages`). Non รจ richiesta alcuna -configurazione per i progetti che non usano i18n. +--- -## Integrazioni di Prima Classe +## ๐Ÿ›ก๏ธ Sicurezza: The Shield & Blood Sentinel -Zenzic รจ **agnostico rispetto al motore di build**. Funziona con qualsiasi sistema di documentazione -basato su Markdown โ€” MkDocs, Docusaurus, Zensical, o una semplice cartella di file `.md`. Non รจ necessario -installare alcun framework di build; Zenzic legge solo i file sorgente grezzi. +Due livelli di sicurezza sono permanentemente attivi โ€” nessuno รจ sopprimibile con `--exit-zero`: -Dove un ecosistema di documentazione definisce convenzioni consolidate per la struttura multi-locale -o la generazione di artefatti a build-time, Zenzic fornisce supporto avanzato, opt-in, leggendo il file -di configurazione del progetto (YAML, TOML, o testo piano JS/TS) โ€” senza mai importare o eseguire il -framework stesso. +**The Shield** scansiona ogni riga โ€” inclusi i blocchi di codice delimitati โ€” alla ricerca di +credenziali. La normalizzazione Unicode sconfigge l'offuscamento (entitร  HTML, interposizione +di commenti, lookback multi-riga). Famiglie rilevate: AWS, GitHub/GitLab, Stripe, Slack, OpenAI, +Google, intestazioni PEM, payload esadecimali. +**โ†’ Exit 2. Ruota e verifica immediatamente.** -### Adapter Engine +**Blood Sentinel** normalizza ogni link risolto con `os.path.normpath` e rifiuta qualsiasi +percorso che sfugge alla root `docs/`. Intercetta tentativi di tipo `../../../../etc/passwd` +prima di qualsiasi syscall OS. +**โ†’ Exit 3.** -Zenzic traduce la conoscenza engine-specifica in risposte engine-agnostiche attraverso un sottile -**adapter layer**: +| Exit | Significato | +| :---: | :--- | +| `0` | Tutti i controlli superati | +| `1` | Problemi di qualitร  rilevati | +| **`2`** | **SICUREZZA โ€” credenziale esposta rilevata** | +| **`3`** | **SICUREZZA โ€” path traversal di sistema rilevato** | -```text -zenzic.toml โ†’ get_adapter() โ†’ Adapter โ†’ Core (Scanner + Validator) -``` +> Aggiungi `zenzic check references` ai tuoi hook pre-commit per bloccare le fughe prima della history git. -L'adapter risponde alle domande che il Core necessita senza conoscere nulla degli interni di MkDocs o -Zensical: +--- -| Metodo | Domanda | -| :--- | :--- | -| `is_locale_dir(part)` | Questa componente del percorso รจ una directory locale non default? | -| `resolve_asset(path)` | Esiste un fallback nella locale di default per questo asset mancante? | -| `is_shadow_of_nav_page(rel, nav)` | Questo file di locale รจ un mirror di una pagina nella nav? | -| `get_nav_paths()` | Quali percorsi `.md` sono dichiarati nella nav? | -| `get_ignored_patterns()` | Quali pattern di filename sono file locale non default (suffix mode)? | -| `get_route_info(rel)` | Metadati di routing completi: URL canonico, stato, slug, route base path? | +## ๐Ÿ”Œ Supporto Multi-Motore -Quattro adapter sono disponibili, selezionati automaticamente da `get_adapter()`: +Zenzic legge i file di configurazione come testo semplice โ€” non importa nรฉ esegue mai il tuo framework di build: -| Adapter | Quando selezionato | Sorgente config | +| Motore | Adapter | Funzionalitร  chiave | | :--- | :--- | :--- | -| `MkDocsAdapter` | `engine = "mkdocs"` o engine sconosciuto | `mkdocs.yml` (YAML) | -| `DocusaurusAdapter` | `engine = "docusaurus"` | `docusaurus.config.ts` / `.js` (testo piano) | -| `ZensicalAdapter` | `engine = "zensical"` | `zensical.toml` (TOML, zero YAML) | -| `VanillaAdapter` | Nessun file config, nessuna locale dichiarata | โ€” (tutti no-op) | - -**Applicazione Nativa** โ€” `engine = "zensical"` richiede che `zensical.toml` sia presente. -Se รจ assente, Zenzic lancia `ConfigurationError` immediatamente. Non c'รจ nessun fallback a -`mkdocs.yml` e nessuna degradazione silenziosa. L'identitร  Zensical deve essere dimostrabile. +| [Docusaurus v3][docusaurus] | `DocusaurusAdapter` | Docs versionati, alias `@site/`, rilevamento Ghost Route | +| [MkDocs][mkdocs] | `MkDocsAdapter` | Modalitร  i18n suffix + folder, `fallback_to_default` | +| [Zensical][zensical] | `ZensicalAdapter` | Transparent Proxy ponte `mkdocs.yml` se `zensical.toml` assente | +| Qualsiasi cartella | `VanillaAdapter` | Zero-config, Directory Index Integrity โ€” nessun motore richiesto | -### Come funziona โ€” Virtual Site Map (VSM) +Adapter di terze parti si installano tramite il gruppo di entry-point `zenzic.adapters`. +Vedi la [Guida Developer][docs-it-arch] per le API degli adapter. -La maggior parte degli analizzatori di documentazione controlla se un file collegato esiste su disco. -Zenzic va oltre: costruisce un **Virtual Site Map** prima che qualsiasi regola venga eseguita. - -```text -File sorgente โ”€โ”€โ–บ Adapter โ”€โ”€โ–บ VSM โ”€โ”€โ–บ Rule Engine โ”€โ”€โ–บ Violazioni - .md + config (conoscenza (URL โ†’ stato) (funzioni pure) - engine- - specifica) -``` - -Il VSM mappa ogni file sorgente `.md` all'URL canonico che il motore di build servirร  โ€” -**senza eseguire il build**. Ogni route porta uno stato: - -| Stato | Significato | -| :--- | :--- | -| `REACHABLE` | La pagina รจ nella nav; gli utenti possono trovarla. | -| `ORPHAN_BUT_EXISTING` | Il file esiste su disco ma รจ assente dalla `nav:`. Gli utenti non possono trovarlo tramite navigazione. | -| `CONFLICT` | Due file mappano allo stesso URL (es. `index.md` + `README.md`). Il risultato del build รจ indefinito. | -| `IGNORED` | Il file non verrร  servito (`README.md` non elencato, directory `_private/` di Zensical). | - -Questo rende Zenzic unicamente preciso: un link a una pagina `ORPHAN_BUT_EXISTING` -viene intercettato come `UNREACHABLE_LINK` โ€” il file esiste, il link risolve, ma -l'utente otterrร  un 404 dopo il build perchรฉ la pagina non รจ navigabile. - -**Ghost Routes** (`reconfigure_material: true`) โ€” quando `mkdocs-material` -auto-genera entry point di locale (es. `/it/`) a build-time, queste pagine -non appaiono mai nella `nav:`. Zenzic rileva questo flag e le marca `REACHABLE` -automaticamente, evitando falsi warning di orfani. +--- -**Cache content-addressable** โ€” Zenzic evita di ri-lintare file invariati usando -come chiave `SHA256(content) + SHA256(config)`. Per le regole VSM-aware -la chiave include anche `SHA256(vsm_snapshot)`, garantendo l'invalidazione quando -lo stato di routing di qualsiasi file cambia. I timestamp non vengono mai consultati โ€” -la cache รจ corretta in ambienti CI dove `git clone` resetta `mtime`. +## โš™๏ธ Configurazione -### MkDocs โ€” fallback i18n +Zero-config di default. Prioritร : `zenzic.toml` > `[tool.zenzic]` in `pyproject.toml` > valori predefiniti. -Quando `mkdocs.yml` dichiara il plugin i18n con `fallback_to_default: true`, Zenzic rispecchia -la logica di risoluzione del plugin: un link da una pagina tradotta a una pagina non tradotta **non** -viene segnalato come rotto, perchรฉ il build servirร  la versione nella locale di default. Supportato sia per -`docs_structure: suffix` che per `docs_structure: folder`. +```toml +# zenzic.toml (tutti i campi sono opzionali) +docs_dir = "docs" +fail_under = 80 # exit 1 se punteggio < soglia; 0 = solo osservazione +excluded_dirs = ["includes", "assets", "overrides"] +excluded_build_artifacts = ["pdf/*.pdf", "dist/*.zip"] +placeholder_patterns = ["coming soon", "todo", "stub"] -```yaml -# mkdocs.yml -plugins: - - i18n: - docs_structure: folder - fallback_to_default: true - languages: - - locale: en - default: true - build: true - - locale: it - build: true +[build_context] +engine = "mkdocs" # mkdocs | docusaurus | zensical | vanilla +default_locale = "en" +locales = ["it"] ``` -Se `mkdocs.yml` รจ assente (o il plugin i18n non รจ configurato), Zenzic torna alla validazione -a locale singola โ€” nessun errore, nessun warning, nessun framework richiesto. - -### Artefatti di build (`excluded_build_artifacts`) +```bash +zenzic init # Genera zenzic.toml con valori auto-rilevati +zenzic init --pyproject # Incorpora [tool.zenzic] in pyproject.toml +``` -Si applica a qualsiasi sistema di documentazione. Se i link puntano a file generati a build-time -(PDF, ZIP), dichiara i loro pattern glob in `zenzic.toml`: +**Regole di lint personalizzate** โ€” dichiara pattern specifici del progetto in `zenzic.toml`, senza Python: ```toml -# zenzic.toml -excluded_build_artifacts = ["pdf/*.pdf", "dist/*.zip"] +[[custom_rules]] +id = "ZZ-NODRAFT" +pattern = "(?i)\\bDRAFT\\b" +message = "Rimuovere il marker DRAFT prima della pubblicazione." +severity = "warning" ``` -Zenzic sopprime gli errori per i percorsi corrispondenti al momento del lint. Il build resta -responsabile della generazione degli artefatti; Zenzic si fida del link senza richiedere il file su disco. - -### Link in stile referenza - -I link `[testo][id]` sono risolti attraverso la stessa pipeline dei link inline โ€” incluso il -fallback i18n โ€” per tutti i sistemi di documentazione. - -```markdown -[Riferimento API][api-ref] - -[api-ref]: api.md -``` +Le regole si attivano identicamente su tutti gli adapter. Nessuna modifica richiesta dopo la migrazione del motore. --- -## Adapter vs. Integrazioni: L'Ecosistema Zenzic - -Zenzic separa **comprendere** dal **agire** attraverso due punti di estensione distinti: - -| | Adapter | Integrazione (Plugin) | -| :--- | :--- | :--- | -| **Scopo** | Permettere a Zenzic di *capire* il tuo sito. | Permettere a Zenzic di *sorvegliare* la tua build. | -| **Direzione** | Engine โ†’ Zenzic | Zenzic โ†’ Engine | -| **Dipendenze** | Nessuna โ€” analisi testuale pura. | Richiesta (`mkdocs` lib per il plugin MkDocs). | -| **Attivazione** | Automatica su ogni `zenzic check`. | Opt-in via config engine (es. `mkdocs.yml`). | -| **Obiettivo** | Discovery e routing zero-config. | Blocco della build in caso di errori. | -| **Posizione** | `zenzic.core.adapters.*` | `zenzic.integrations.*` | - -**In pratica:** l'Adapter รจ la *mente* โ€” legge `mkdocs.yml` come testo puro e costruisce -la VSM. L'Integrazione (plugin) รจ il *braccio* โ€” si aggancia agli eventi di `mkdocs build` -e solleva un `PluginError` se i controlli di qualitร  falliscono. - -La maggior parte degli utenti ha bisogno solo degli adapter (automatici). Installa -un'integrazione solo quando vuoi che Zenzic diventi un guardiano nel pipeline di build. - -### Plugin MkDocs - -```bash -# Installa l'extra opzionale -pip install "zenzic[mkdocs]" -``` +## ๐Ÿ”„ Integrazione CI/CD ```yaml -# mkdocs.yml -plugins: - - zenzic: - strict: false - fail_on_error: true - checks: [orfani, snippet, segnaposto, assets] +- name: ๐Ÿ›ก๏ธ Zenzic Sentinel + run: uvx zenzic check all --strict + # Exit 1 = qualitร  ยท Exit 2 = credenziale esposta ยท Exit 3 = path traversal + # Exit 2 e 3 non sono mai sopprimibili. + +- name: Gate regressione + run: | + uvx zenzic score --save # sul branch main + uvx zenzic diff # sulla PR โ€” exit 1 se il punteggio cala ``` -La classe del plugin si trova in `zenzic.integrations.mkdocs:ZenzicPlugin` ed รจ -auto-scoperta da MkDocs tramite l'entry point `mkdocs.plugins` โ€” nessun percorso manuale -richiesto. +Per automazione badge e gate di regressione, vedi la [guida CI/CD][docs-it-cicd]. +Workflow completo: [`.github/workflows/ci.yml`][ci-workflow] --- -## Installazione - -### Con `uv` (consigliato) - -[`uv`][uv] รจ il modo piรน veloce per installare e eseguire Zenzic: +## ๐Ÿ“ฆ Installazione ```bash -# Esecuzione una-tantum senza installazione -uvx --pre zenzic check all - -# Strumento globale disponibile in qualsiasi progetto -uv tool install --pre zenzic +# Audit one-shot senza installazione (consigliato per CI ed esplorazione) +uvx zenzic check all ./docs -# Dipendenza dev del progetto โ€” versione fissata in uv.lock -uv add --dev --pre zenzic -``` +# Tool CLI globale +uv tool install zenzic -### Con `pip` - -```bash -# Installazione globale (considera un ambiente virtuale) -pip install --pre zenzic +# Dipendenza dev con versione fissata +uv add --dev zenzic -# Dentro un ambiente virtuale (consigliato) -python -m venv .venv -source .venv/bin/activate # Windows: .venv\Scripts\activate -pip install --pre zenzic +# pip +pip install zenzic +pip install "zenzic[mkdocs]" # + plugin build-time MkDocs ``` -### Lean e Agnostico per Design +> L'extra `[mkdocs]` aggiunge il plugin build-time (`zenzic.integrations.mkdocs`). +> Tutti gli adapter dei motori (Docusaurus, Zensical, Vanilla) sono inclusi nell'installazione base. -Zenzic esegue un'**analisi statica** dei tuoi file di configurazione (`mkdocs.yml`, `docusaurus.config.ts`, `zensical.toml`, `pyproject.toml`). **Non esegue** il motore di build nรฉ i suoi plugin โ€” รจ 100% subprocess-free. La configurazione di Docusaurus (`.ts`/`.js`) viene analizzata tramite parsing statico del testo, senza mai invocare Node.js. - -Questo significa che **non รจ necessario installare** MkDocs, Docusaurus, Material for MkDocs o altri -plugin di build nel tuo ambiente di linting. Zenzic rimane leggero e privo di dipendenze, rendendolo -ideale per pipeline CI/CD veloci e isolate. - -**Extra di installazione:** - -| Comando | Cosa ottieni | -| :--- | :--- | -| `pip install zenzic` | CLI core + adapter Docusaurus, Zensical e Vanilla. Nessuna libreria engine richiesta. | -| `pip install "zenzic[mkdocs]"` | Core + il **plugin MkDocs** (`zenzic.integrations.mkdocs`). Aggiunge `mkdocs` come dipendenza. | - -> L'extra MkDocs รจ necessario **solo** se vuoi l'integrazione plugin a build-time. -> Per l'uso standalone della CLI (`zenzic check all`), l'installazione base รจ sufficiente per ogni engine. -> -> **Artefatti di build:** Se la documentazione punta a file generati a build-time -> (PDF, ZIP), aggiungi i loro pattern glob a `excluded_build_artifacts` in `zenzic.toml` -> anzichรฉ pre-generarli. Vedi la sezione [Integrazioni di Prima Classe](#integrazioni-di-prima-classe). - -### Setup progetto - -```bash -zenzic init # crea zenzic.toml con engine rilevato automaticamente -zenzic init --pyproject # incorpora [tool.zenzic] in pyproject.toml -``` - -Quando `pyproject.toml` esiste, `zenzic init` chiede interattivamente se incorporare -la configurazione lรฌ. Usa `--pyproject` per saltare il prompt. +**Portabilitร :** Zenzic rifiuta i link interni assoluti (che iniziano con `/`). I link relativi +funzionano con qualsiasi percorso di hosting. Gli URL esterni `https://` non sono mai interessati. --- -## Utilizzo CLI +## ๐Ÿ–ฅ๏ธ Riferimento CLI ```bash -# Controlli individuali -zenzic check links --strict +# Controlli +zenzic check links [--strict] zenzic check orphans zenzic check snippets zenzic check placeholders zenzic check assets +zenzic check references [--strict] [--links] +zenzic check all [--strict] [--exit-zero] [--format json] [--engine ENGINE] +zenzic check all [--exclude-dir DIR] [--include-dir DIR] -# Autofix & Cleanup -zenzic clean assets # Elimina interattivamente gli asset non utilizzati -zenzic clean assets -y # Elimina gli asset non utilizzati immediatamente -zenzic clean assets --dry-run # Mostra cosa verrebbe eliminato senza farlo - -# Pipeline dei riferimenti -zenzic check references # Harvest โ†’ Cross-Check โ†’ Shield โ†’ Punteggio integritร  -zenzic check references --strict # Tratta le Dead Definitions come errori -zenzic check references --links # Valida anche gli URL dei riferimenti via HTTP asincrono - -# Tutti i controlli in un comando -zenzic check all --strict -zenzic check all --exit-zero # report senza bloccare la pipeline -zenzic check all --format json # output machine-readable -zenzic check all --engine docusaurus # override esplicito dell'engine - -# Controllo esclusioni -zenzic check all --exclude-dir drafts --exclude-dir temp -zenzic check all --include-dir guides # Scansiona solo directory specifiche - -# Punteggio qualitร  (0โ€“100) -zenzic score -zenzic score --save # persiste il baseline -zenzic score --fail-under 80 # exit 1 se sotto la soglia - -# Rilevamento regressioni contro snapshot salvato -zenzic diff # exit 1 su qualsiasi calo -zenzic diff --threshold 5 # exit 1 solo se il calo รจ > 5 punti -``` - -> **Nota (v0.6.1+):** `zenzic serve` รจ stato rimosso. A partire dalla v0.6.1, Zenzic si -> focalizza esclusivamente sull'analisi. Per visualizzare i documenti, usa il comando nativo -> del tuo engine: `mkdocs serve`, `docusaurus start`, o `zensical serve`. - -### Codici di uscita - -| Codice | Significato | -| :---: | :--- | -| `0` | Tutti i controlli selezionati sono passati | -| `1` | Uno o piรน controlli hanno segnalato problemi | -| **`2`** | **SECURITY CRITICAL โ€” Zenzic Shield ha rilevato una credenziale esposta** | -| **`3`** | **SECURITY CRITICAL โ€” Sentinella di Sangue ha rilevato un path traversal di sistema** | - -> **Attenzione:** -> Il **codice di uscita 2** รจ riservato agli eventi Shield (credenziali esposte). Il **codice -> di uscita 3** รจ riservato alla Sentinella di Sangue (path traversal verso directory di sistema -> come `/etc/`, `/root/`). Entrambi non vengono mai soppressi da `--exit-zero`. Ruotare e -> verificare immediatamente. +# Punteggio e diff +zenzic score [--save] [--fail-under N] +zenzic diff [--threshold N] ---- +# Correzione automatica +zenzic clean assets [-y] [--dry-run] -## ๐Ÿ›ก๏ธ Zenzic Shield +# Inizializzazione +zenzic init [--pyproject] -Lo **Zenzic Shield** รจ un sistema di sicurezza a due livelli integrato nel core engine: - -| Livello | Protegge contro | -| --- | --- | -| **Rilevamento credenziali** | Chiavi API / token esposti incorporati nelle URL dei riferimenti | -| **Path traversal** | Escape da `docs/` in stile `../../../../etc/passwd` | - -### Rilevamento credenziali - -Il livello credenziali viene eseguito durante il **Pass 1** (Harvesting) della pipeline dei riferimenti -e scansiona ogni URL di riferimento per pattern di credenziali noti prima che qualsiasi richiesta HTTP -venga emessa. - -```markdown - -[api-docs]: https://api.example.com/?key=sk-xxxx-xxxx-xxxx-xxxx-xxxx-xxxx +# Showroom interattivo +zenzic lab [--act N] [--list] ``` -```bash -โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•— -โ•‘ SECURITY CRITICAL โ•‘ -โ•‘ Secret(s) detected in documentation โ•‘ -โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• +--- - [SHIELD] docs/api.md:12 โ€” openai-api-key detected in URL - https://api.example.com/?key=sk-xxxx-xxxx-x... +## ๐Ÿ“Ÿ Tour Visivo -Build aborted. Rotate the exposed credential immediately. +```text +โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ ๐Ÿ›ก ZENZIC SENTINEL v0.6.1 โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ +โ”‚ โ”‚ +โ”‚ docusaurus โ€ข 38 file (18 docs, 20 asset) โ€ข 0.9s โ”‚ +โ”‚ โ”‚ +โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ docs/guides/setup.mdx โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ +โ”‚ โ”‚ +โ”‚ โœ— 12: [Z001] 'quickstart.mdx' non trovato in docs โ”‚ +โ”‚ โ”‚ โ”‚ +โ”‚ 12 โ”‚ Leggi la [guida quickstart](quickstart.mdx) prima. โ”‚ +โ”‚ โ”‚ โ”‚ +โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ +โ”‚ โ”‚ +โ”‚ โœ— 1 errore โ€ข 1 file con risultati โ€ข FALLITO โ”‚ +โ”‚ โ”‚ +โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ ``` -**Come funziona:** - -1. Lo Shield viene eseguito *dentro* il Pass 1 โ€” prima che il Pass 2 validi i link e prima che qualsiasi - ping HTTP venga emesso. Un documento contenente una credenziale esposta non viene mai usato per effettuare - richieste in uscita. -2. I pattern usano quantificatori a lunghezza esatta (`{48}`, `{36}`, `{16}`) โ€” nessun backtracking, O(1) per riga. -3. Otto famiglie di credenziali sono coperte out of the box: - -| Tipo | Pattern | -| --- | --- | -| Chiave API OpenAI | `sk-[a-zA-Z0-9]{48}` | -| Token GitHub | `gh[pousr]_[a-zA-Z0-9]{36}` | -| Access key AWS | `AKIA[0-9A-Z]{16}` | -| Chiave live Stripe | `sk_live_[0-9a-zA-Z]{24}` | -| Token Slack | `xox[baprs]-[0-9a-zA-Z]{10,48}` | -| Chiave API Google | `AIza[0-9A-Za-z\-_]{35}` | -| Chiave privata PEM | `-----BEGIN [A-Z ]+ PRIVATE KEY-----` | -| Payload hex-encoded | 3+ sequenze consecutive `\xNN` | - -1. **Nessun punto cieco** โ€” lo Shield scansiona ogni riga del file sorgente, incluse le righe dentro - blocchi di codice fenced (`bash`, `yaml`, senza etichetta, ecc.). Una credenziale inserita in un esempio - di codice รจ comunque una credenziale esposta. - -> **Suggerimento:** -> Aggiungi `zenzic check references` ai tuoi hook pre-commit per intercettare credenziali esposte prima che -> vengano mai committate nel version control. +Visita il [portale di documentazione][docs-it-home] per screenshot interattivi ed esempi ricchi. -### Path traversal +--- -Il livello di path traversal viene eseguito dentro `InMemoryPathResolver` durante `check links`. Normalizza -ogni href risolto con `os.path.normpath` (puro C, zero system call) e verifica che il risultato -sia contenuto dentro `docs/` usando un singolo confronto di prefisso stringa โ€” $O(1)$, zero allocazioni. +## ๐Ÿ—บ๏ธ Roadmap v0.7.0 -```bash -Attack href: ../../../../etc/passwd -After resolve: /etc/passwd -Shield check: /etc/passwd does not start with /docs/ โ†’ PathTraversal returned, link rejected -``` - -Qualsiasi href che esce dalla root docs viene evidenziato come un errore `PathTraversal` distinto โ€” mai -collassato silenziosamente in un generico "file non trovato". +- [ ] **Auto-fix Engine** โ€” Riparazione automatica di link rotti e ancore orfane. +- [ ] **Estensioni IDE** โ€” Lint in tempo reale per VS Code e Cursor tramite LSP. +- [ ] **AI Context Provider** โ€” Export VSM in formato LLM-friendly per agenti AI. +- [ ] **Adapter Astro & VitePress** โ€” Espandere il Safe Harbor ai framework JS. --- -## Integrazione CI/CD +## ๐Ÿ—๏ธ Filosofia di Design -### GitHub Actions +Zenzic รจ costruito su tre contratti operativi: -```yaml -- name: Lint documentazione - run: uvx --pre zenzic check all +**Analizza la Sorgente, non la Build.** La VSM (Virtual Site Map) mappa ogni file `.md` al suo +URL canonico senza eseguire la build โ€” gli errori vengono intercettati prima di raggiungere la produzione. -- name: Controlla riferimenti ed esegui Shield - run: uvx --pre zenzic check references -``` +**Zero-Trust Execution.** Nessun sottoprocesso, nessuna esecuzione di codice arbitrario, nessuna +importazione di motori di build. I config Docusaurus `.ts`/`.js` sono analizzati tramite analisi +testuale statica โ€” Node.js non viene mai invocato. -Workflow completo: [`.github/workflows/zenzic.yml`][ci-workflow] +**Esclusione Obbligatoria ad Ogni Entry Point.** Tutta la scoperta dei file passa attraverso +`LayeredExclusionManager` โ€” una gerarchia a 4 livelli (Sistema โ†’ VCS โ†’ Config โ†’ CLI). Nessuna +scansione globale senza un contesto di esclusione esplicito. -Per l'automazione dinamica dei badge e il rilevamento delle regressioni, consulta la [guida all'integrazione CI/CD][docs-it-cicd]. +Vedi la [Guida all'Architettura][docs-it-arch] per il Two-Pass Reference Pipeline e l'analisi approfondita della VSM. --- -## Configurazione +## ๐Ÿ™‹ FAQ -Tutti i campi sono opzionali. Zenzic funziona senza alcun file di configurazione. +**Perchรฉ non usare `grep`?** Grep รจ cieco alla struttura. Zenzic comprende il versioning di +Docusaurus, i fallback i18n di MkDocs e le Ghost Route โ€” pagine che non esistono come file ma +sono URL validi. -Zenzic segue una catena di prioritร  a tre livelli **Agnostic Citizen**: +**Esegue il mio motore di build?** No. 100% subprocess-free. Analisi statica solo su testo semplice. -1. `zenzic.toml` alla root del repository โ€” sovrano; ha sempre la precedenza. -2. `[tool.zenzic]` in `pyproject.toml` โ€” usato quando `zenzic.toml` รจ assente. -3. Default built-in. +**Regge migliaia di file?** Sรฌ. Parallelismo adattivo per la scoperta; lookup VSM O(1) per link; +cache content-addressable (`SHA256(content + config + vsm_snapshot)`) salta i file invariati. -```toml -# zenzic.toml (oppure [tool.zenzic] in pyproject.toml) -docs_dir = "docs" -excluded_dirs = ["includes", "assets", "stylesheets", "overrides", "hooks"] -snippet_min_lines = 1 -placeholder_max_words = 50 -placeholder_patterns = ["coming soon", "todo", "stub"] -fail_under = 80 # exit 1 se il punteggio scende sotto questa soglia; 0 = modalitร  osservativa - -# Contesto engine e i18n โ€” richiesto solo per progetti multi-locale in folder mode. -# Quando assente, Zenzic legge la configurazione locale direttamente da mkdocs.yml. -[build_context] -engine = "mkdocs" # "mkdocs", "docusaurus", "zensical" o "vanilla" -default_locale = "en" -locales = ["it"] # nomi delle directory locale non default -``` +**Shield vs Blood Sentinel?** Shield = segreti *nel* contenuto (exit 2). Blood Sentinel = +link che puntano a *path* di sistema OS (exit 3). Entrambi non sono sopprimibili. ---- +**Non serve `zenzic.toml`?** Corretto. Zenzic identifica il motore dai file di configurazione presenti e applica i default sicuri. +Esegui `zenzic init` in qualsiasi momento per generare un file di configurazione pre-compilato. -## DSL `[[custom_rules]]` - -Dichiara regole lint specifiche del progetto in `zenzic.toml` senza scrivere Python: - -```toml -[[custom_rules]] -id = "ZZ-NODRAFT" -pattern = "(?i)\\bDRAFT\\b" -message = "Rimuovere il marker DRAFT prima della pubblicazione." -severity = "warning" - -[[custom_rules]] -id = "ZZ-NOINTERNAL" -pattern = "internal\\.corp\\.example\\.com" -message = "L'hostname interno non deve apparire nella documentazione pubblica." -severity = "error" -``` - -Le regole si attivano identicamente con tutti gli adapter (MkDocs, Docusaurus, Zensical, Vanilla). Nessuna -modifica richiesta dopo la migrazione da un engine all'altro. +**Cos'รจ `zenzic lab`?** Uno showroom interattivo a 9 atti che copre ogni motore e ogni classe di +errore. Eseguilo una volta prima di integrare Zenzic in qualsiasi progetto. --- -## Sviluppo - -Per un workflow di sviluppo piรน veloce e interattivo usando **just**, o per istruzioni dettagliate su -come aggiungere nuovi controlli, consulta la [Guida ai Contributi][contributing]. +## ๐Ÿ› ๏ธ Sviluppo ```bash -uv sync --group dev -nox -s dev # Installa gli hook pre-commit (una volta) - -nox -s tests # pytest + coverage -nox -s lint # ruff check -nox -s format # ruff format +uv sync --all-groups +nox -s tests # pytest + copertura +nox -s lint # ruff nox -s typecheck # mypy --strict -nox -s preflight # pipeline CI completa (lint + test + self-check) -``` - ---- - -## Visual Tour - -L'audit completo della Sentinella โ€” banner, rilevamento engine e verdetto: - -```bash -โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ ๐Ÿ›ก ZENZIC SENTINEL v0.6.1rc2 โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ -โ”‚ โ”‚ -โ”‚ docusaurus โ€ข 38 files (18 docs, 20 assets) โ€ข 0.9s โ”‚ -โ”‚ โ”‚ -โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ docs/guides/setup.mdx โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ -โ”‚ โ”‚ -โ”‚ โœ— 12: [Z001] 'quickstart.mdx' not found in docs โ”‚ -โ”‚ โ”‚ โ”‚ -โ”‚ 12 โ”‚ Read the [quickstart guide](quickstart.mdx) first. โ”‚ -โ”‚ โ”‚ โ”‚ -โ”‚ โ”‚ -โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ -โ”‚ โ”‚ -โ”‚ โœ— 1 error โ€ข 1 file with findings โ”‚ -โ”‚ โ”‚ -โ”‚ FAILED: One or more checks failed. โ”‚ -โ”‚ โ”‚ -โ”‚ ๐Ÿ’ก 4 info findings suppressed โ€” use --show-info for details. โ”‚ -โ”‚ โ”‚ -โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ +nox -s preflight # lint + format + typecheck + pytest + reuse +just verify # preflight + zenzic check all --strict (self-dogfood) ``` -Lo **Shield** intercetta credenziali esposte prima che qualsiasi richiesta HTTP venga emessa. -La **Sentinella di Sangue** blocca tentativi di path traversal che escono dalla root `docs/`. -Entrambi attivano codici di uscita non sopprimibili (2 e 3). Il **VSM** (Virtual Site Map) -assicura che la validazione dei link operi su URL canonici โ€” non su percorsi filesystem โ€” -cosรฌ che pagine orfane e slug override vengano rilevati accuratamente su tutti gli engine. - -Per screenshot interattivi ed esempi visivi completi, visita il -[portale documentazione](https://zenzic.dev/docs/it/). +Vedi la [Guida alla Contribuzione][contributing] per la checklist del metodo Zenzic e le convenzioni PR. --- -## Contribuire - -Bug report, miglioramenti alla documentazione e pull request sono benvenuti. Prima di iniziare: +## ๐Ÿค Contribuire -1. Apri un'issue per discutere la modifica โ€” usa il [template appropriato][issues]. -2. Leggi la [Guida ai Contributi][contributing] โ€” in particolare il setup locale e la checklist **Zenzic Way** (funzioni pure, nessun sottoprocesso, source-first). -3. Ogni PR deve superare `nox -s preflight` (test + lint + typecheck + self-dogfood) e includere le intestazioni REUSE/SPDX sui nuovi file. +1. Apri una [issue][issues] per discutere la modifica. +2. Leggi la [Guida alla Contribuzione][contributing] โ€” checklist del metodo Zenzic, funzioni pure, + nessun sottoprocesso, source-first. +3. Ogni PR deve superare `nox -s preflight` e includere intestazioni REUSE/SPDX sui nuovi file. -Consulta anche il [Codice di Condotta][coc] e la [Policy di Sicurezza][security]. +Vedi anche: [Codice di Condotta][coc] ยท [Politica di Sicurezza][security] -## Citare Zenzic +## ๐Ÿ“Ž Citare Zenzic -Il file [`CITATION.cff`][citation-cff] รจ presente nella root del repository. GitHub lo -visualizza automaticamente โ€” clicca **"Cite this repository"** sulla pagina del repo per -ottenere il riferimento in formato APA o BibTeX. +Un file [`CITATION.cff`][citation-cff] รจ presente alla radice del repository. Clicca su +**"Cite this repository"** su GitHub per l'output APA o BibTeX. -## Licenza +## ๐Ÿ“„ Licenza Apache-2.0 โ€” vedi [LICENSE][license]. ---

- © 2026 PythonWoods. Progettato con precisione.
- Based in Italy ๐Ÿ‡ฎ๐Ÿ‡น  ยท  Committed to the craft of Python development.
+ © 2026 PythonWoods. Ingegnerizzato con precisione.
+ Con sede in Italia ๐Ÿ‡ฎ๐Ÿ‡น  ยท  Dediti all'arte dello sviluppo Python.
dev@pythonwoods.dev

- - -[mkdocs]: https://www.mkdocs.org/ -[docusaurus]: https://docusaurus.io/ -[zensical]: https://zensical.org/ -[uv]: https://docs.astral.sh/uv/ -[docs-it-home]: https://zenzic.dev/docs/it/usage/ -[docs-it-config]: https://zenzic.dev/docs/it/configuration/ -[docs-it-migration]: https://zenzic.dev/docs/it/guide/migration/ -[docs-it-arch]: https://zenzic.dev/docs/it/architecture/ -[docs-it-adapter]: https://zenzic.dev/docs/it/developers/writing-an-adapter/ -[docs-it-cicd]: https://zenzic.dev/docs/it/ci-cd/ -[ci-workflow]: .github/workflows/ci.yml -[contributing]: CONTRIBUTING.md -[license]: LICENSE -[citation-cff]: CITATION.cff -[coc]: CODE_OF_CONDUCT.md -[security]: SECURITY.md -[issues]: https://github.com/PythonWoods/zenzic/issues + + +[mkdocs]: https://www.mkdocs.org/ +[docusaurus]: https://docusaurus.io/ +[zensical]: https://zensical.org/ +[uv]: https://docs.astral.sh/uv/ +[docs-it-home]: https://zenzic.dev/it/docs/ +[docs-it-badges]: https://zenzic.dev/it/docs/usage/badges/ +[docs-it-cicd]: https://zenzic.dev/it/docs/guides/ci-cd/ +[docs-it-arch]: https://zenzic.dev/it/docs/internals/architecture-overview/ +[ci-workflow]: .github/workflows/ci.yml +[contributing]: CONTRIBUTING.it.md +[license]: LICENSE +[citation-cff]: CITATION.cff +[coc]: CODE_OF_CONDUCT.md +[security]: SECURITY.md +[issues]: https://github.com/PythonWoods/zenzic/issues diff --git a/README.md b/README.md index 1dab6e9..f4b7eae 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ SPDX-License-Identifier: Apache-2.0

- PyPI Version + PyPI Version Python Versions @@ -39,650 +39,332 @@ SPDX-License-Identifier: Apache-2.0

- "Zenzic is the Safe Harbor for your documentation integrity. It doesn't just check links; it audits your brand's technical resilience."
- Engineering-grade documentation linter โ€” standalone, engine-agnostic, and security-hardened. + The Safe Harbor for your Markdown documentation.
+ Engine-agnostic static analysis โ€” standalone, security-hardened, zero configuration needed.

-```bash -โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ ๐Ÿ›ก ZENZIC SENTINEL v0.6.1rc2 โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ -โ”‚ โ”‚ -โ”‚ docusaurus โ€ข 38 files (18 docs, 20 assets) โ€ข 0.9s โ”‚ -โ”‚ โ”‚ -โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ -โ”‚ โ”‚ -โ”‚ โœ” All checks passed. Your documentation is secure. โ”‚ -โ”‚ โ”‚ -โ”‚ ๐Ÿ’ก 4 info findings suppressed โ€” use --show-info for details. โ”‚ -โ”‚ โ”‚ -โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ -``` - --- -> Documentation doesn't fail loudly. It decays silently. - -Broken links, orphan pages, invalid code snippets, stale placeholder content, and leaked API keys -accumulate over time โ€” until users hit them in production. Zenzic catches all of these across -[Docusaurus][docusaurus], [MkDocs][mkdocs], and [Zensical][zensical] projects as a **standalone CLI** โ€” -no build framework required. +## โšก Try it now โ€” Zero Installation -Zenzic is **agnostic** โ€” it works with any Markdown-based documentation system (Docusaurus, MkDocs, -Zensical, or a bare folder of `.md` files) without installing any build framework. It reads raw source -files and build configurations as plain text. And it is **opinionated**: absolute links are a hard error, -engine identity must be provable, and the CLI is 100% subprocess-free. +Got a folder of Markdown files? Run an instant security and link audit using [`uv`][uv]: ---- - -## Core Capabilities - -- **Security** โ€” Shield (9 credential families, Exit 2) with Unicode obfuscation resistance, HTML entity decoding, comment-interleaving defense, and cross-line split-token lookback. Blood Sentinel (host-path traversal, Exit 3). ReDoS-safe regex (F2-1), jailbreak protection (F4-1). Neither is suppressed by `--exit-zero`. -- **Integrity** โ€” O(V+E) circular link detection, Virtual Site Map with content-addressable cache, deterministic 0โ€“100 quality score. -- **Intelligence** โ€” Multi-engine: MkDocs, Docusaurus v3, Zensical, and Vanilla. Module-level adapter cache. Third-party adapters install as Python packages via entry points. -- **Discovery** โ€” Universal VCS-aware file iteration (zero `rglob`), mandatory `ExclusionManager` on every entry point, 4-level Layered Exclusion hierarchy, pure-Python `.gitignore` parser. +```bash +uvx zenzic check all ./your-folder +``` -> ๐Ÿš€ **Latest Release: v0.6.1rc2 "Obsidian Bastion"** โ€” see [CHANGELOG.md](CHANGELOG.md) for details. +Zenzic will identify your engine via its configuration files or default to **Vanilla mode** for +standalone folders โ€” providing immediate protection for links, credentials, and structural integrity. --- -## ๐Ÿ“– Documentation - -Zenzic provides an extensive, engineering-grade documentation portal: +## ๐Ÿš€ Quick Start -- ๐Ÿš€ **[User Guide][docs-home]**: Installation, CLI usage, and all available checks. -- ๐Ÿ… **[Badges][docs-badges]**: Official Zenzic Shield and Score badge snippets for your README. -- ๐Ÿ”„ **[CI/CD Integration][docs-cicd]**: GitHub Actions workflows, dynamic badges, and regression detection. -- โš™๏ธ **[Developer Guide][docs-arch]**: Deep dive into the deterministic pure-core architecture, Two-Pass Pipeline, and state-machine parsing. -- ๐Ÿค **[Contributing][docs-contributing]**: Set up the local development environment (`uv`, `nox`), run the test suite, and submit PRs. +```bash +pip install zenzic +zenzic lab # Interactive showroom โ€” 9 acts, every engine, zero setup +zenzic check all # Audit the current directory +``` -

- Explore the full documentation โ†’ -

+๐Ÿ“– [Full docs โ†’][docs-home] ยท ๐Ÿ… [Badges][docs-badges] ยท ๐Ÿ”„ [CI/CD guide][docs-cicd] --- -## What Zenzic checks - -| Check | CLI command | What it detects | -| --- | --- | --- | -| Links | `zenzic check links` | Broken internal links, dead anchors, and **path traversal** attempts | -| Orphans | `zenzic check orphans` | `.md` files absent from `nav` | -| Snippets | `zenzic check snippets` | Python, YAML, JSON, and TOML blocks with syntax errors | -| Placeholders | `zenzic check placeholders` | Stub pages and forbidden text patterns | -| Assets | `zenzic check assets` | Images and files not referenced anywhere | -| **References** | `zenzic check references` | Dangling References, Dead Definitions, **Zenzic Shield** | +## ๐ŸŽฏ Why Zenzic? -Beyond pass/fail, `zenzic score` aggregates all checks into a deterministic 0โ€“100 quality score. -`zenzic diff` compares the current score against a saved baseline โ€” enabling regression detection -on every pull request. - -**Autofix:** Zenzic also provides active cleanup utilities. Run `zenzic clean assets` to automatically deleting the unused images identified by `check assets` (interactive or via `-y`). +| Without Zenzic | With Zenzic | +| :--- | :--- | +| โŒ Broken anchors silently 200 OK in Docusaurus v3 | โœ… Mathematical anchor validation via VSM | +| โŒ Leaked API keys in code blocks committed to git | โœ… **The Shield** โ€” 9-family credential scanner, exit 2 | +| โŒ Path traversal `../../../../etc/passwd` in links | โœ… **Blood Sentinel** โ€” non-suppressible exit 3 | +| โŒ Orphan pages unreachable from any nav link | โœ… Semantic orphan detection โ€” not just file-exists | +| โŒ Silent 404s accumulating in Google Search Console | โœ… Directory Index Integrity checks | +| โŒ MkDocs โ†’ Zensical migration with unknown breakage | โœ… **Transparent Proxy** โ€” lint both with one command | --- -## Portability Standards - -Zenzic enforces two rules that make documentation portable across any hosting environment -and independent of any specific build engine. +## ๐Ÿงฉ What Zenzic is NOT -### Relative Path Enforcement +- **Not a site generator.** It audits source; it never builds HTML. +- **Not a build wrapper.** Zero-Trust Execution: no subprocesses, no `mkdocs` or `docusaurus` binaries invoked. +- **Not a spell checker.** Structure and security โ€” not prose. +- **Not an HTTP crawler.** All validation is local and file-based. -Zenzic **rejects internal links that start with `/`**. Absolute paths are environment-dependent: -a link to `/assets/logo.png` works when the site is at the domain root, but returns 404 when -hosted in a subdirectory (e.g. `https://example.com/docs/assets/logo.png` โ‰  -`https://example.com/assets/logo.png`). - -```markdown - -[Download](/assets/guide.pdf) - - -[Download](../assets/guide.pdf) -``` - -The error message includes an explicit fix suggestion. External URLs (`https://...`) are not -affected. - -### i18n Support: Multi-Engine Locale Resolution - -Zenzic natively supports locale-aware documentation across all engines: - -**MkDocs โ€” Suffix Mode** (`page.locale.md`) and **Folder Mode** (`docs/it/page.md`) via -`mkdocs-static-i18n`. Links from translated pages to untranslated pages are resolved through -the default-locale fallback when `fallback_to_default: true` is set. +--- -**Docusaurus v3 โ€” i18n directory** (`i18n/it/docusaurus-plugin-content-docs/current/`). -Zenzic discovers locale trees from `docusaurus.config.ts` automatically. Links between -locale pages and default-locale assets are resolved without configuration. +## ๐Ÿ“‹ Capability Matrix -**Zensical** โ€” Suffix Mode only (`page.locale.md`), similar to MkDocs. +| Capability | Command | Detects | Exit | +| :--- | :--- | :--- | :---: | +| Link integrity | `check links` | Broken links, dead anchors | 1 | +| Orphan detection | `check orphans` | Files absent from `nav` โ€” invisible after build | 1 | +| Code snippets | `check snippets` | Syntax errors in Python / YAML / JSON / TOML blocks | 1 | +| Placeholder content | `check placeholders` | Stub pages and forbidden text patterns | 1 | +| Unused assets | `check assets` | Images and files not referenced anywhere | 1 | +| **Credential scanning** | `check references` | **9 credential families** โ€” text, URLs, code blocks | **2** | +| **Path traversal** | `check links` | System-path escape attempts | **3** | +| Quality score | `score` | Deterministic 0โ€“100 composite metric | โ€” | +| Regression detection | `diff` | Score drop vs saved baseline โ€” CI-friendly | 1 | -In Folder Mode (MkDocs) and Docusaurus i18n, Zenzic uses the `[build_context]` section in -`zenzic.toml` to identify locale directories: +**Autofix:** `zenzic clean assets [-y] [--dry-run]` deletes unused images. -```toml -# zenzic.toml -[build_context] -engine = "mkdocs" # "mkdocs", "docusaurus", "zensical", or "vanilla" -default_locale = "en" -locales = ["it", "fr"] # non-default locale directory names -``` +> ๐Ÿš€ **v0.6.1 "Obsidian Glass" (Stable)** โ€” Full Docusaurus v3 versioning, `@site/` alias +> resolution, and Zensical Transparent Proxy. See [CHANGELOG.md](CHANGELOG.md). -When `zenzic.toml` is absent, Zenzic reads locale configuration directly from `mkdocs.yml` -(respecting `docs_structure`, `fallback_to_default`, and `languages`). No configuration is -required for projects that do not use i18n. +--- -## First-Class Integrations +## ๐Ÿ›ก๏ธ Security: The Shield & Blood Sentinel -Zenzic is **build-engine agnostic**. It works with any Markdown-based documentation system โ€” -MkDocs, Docusaurus, Zensical, or a bare folder of `.md` files. No build framework needs to be installed; -Zenzic reads raw source files only. +Two security layers are permanently active โ€” neither is suppressible by `--exit-zero`: -Where a documentation ecosystem defines well-known conventions for multi-locale structure or -build-time artifact generation, Zenzic provides enhanced, opt-in support by reading the project's -configuration file (YAML, TOML, or plain-text JS/TS) โ€” never by importing or executing the -framework itself. +**The Shield** scans every line โ€” including fenced code blocks โ€” for credentials. Unicode +normalization defeats obfuscation (HTML entities, comment interleaving, cross-line lookback). +Detected families: AWS, GitHub/GitLab, Stripe, Slack, OpenAI, Google, PEM headers, hex payloads. +**โ†’ Exit 2. Rotate and audit immediately.** -### Engine Adapters +**Blood Sentinel** normalizes every resolved link with `os.path.normpath` and rejects any path +escaping the `docs/` root. Catches `../../../../etc/passwd`-style traversal before any OS syscall. +**โ†’ Exit 3.** -Zenzic translates engine-specific knowledge into engine-agnostic answers through a thin -**adapter layer**: +| Exit | Meaning | +| :---: | :--- | +| `0` | All checks passed | +| `1` | Quality issues found | +| **`2`** | **SECURITY โ€” leaked credential detected** | +| **`3`** | **SECURITY โ€” system-path traversal detected** | -```text -zenzic.toml โ†’ get_adapter() โ†’ Adapter โ†’ Core (Scanner + Validator) -``` +> Add `zenzic check references` to your pre-commit hooks to catch leaks before git history. -The adapter answers the questions the Core needs without knowing anything about MkDocs or -Zensical internals: +--- -| Method | Question | -| :--- | :--- | -| `is_locale_dir(part)` | Is this path component a non-default locale directory? | -| `resolve_asset(path)` | Does a default-locale fallback exist for this missing asset? | -| `is_shadow_of_nav_page(rel, nav)` | Is this locale file a mirror of a nav-listed page? | -| `get_nav_paths()` | Which `.md` paths are declared in the nav? | -| `get_ignored_patterns()` | Which filename patterns are non-default locale files (suffix mode)? | -| `get_route_info(rel)` | Full route metadata: canonical URL, status, slug, route base path? | +## ๐Ÿ”Œ Multi-Engine Support -Four adapters are available, selected automatically by `get_adapter()`: +Zenzic reads config files as plain text โ€” never imports or executes your build framework: -| Adapter | When selected | Config source | +| Engine | Adapter | Highlights | | :--- | :--- | :--- | -| `MkDocsAdapter` | `engine = "mkdocs"` or unknown engine | `mkdocs.yml` (YAML) | -| `DocusaurusAdapter` | `engine = "docusaurus"` | `docusaurus.config.ts` / `.js` (plain text) | -| `ZensicalAdapter` | `engine = "zensical"` | `zensical.toml` (TOML, zero YAML) | -| `VanillaAdapter` | No config file, no locales declared | โ€” (all no-ops) | - -**Native Enforcement** โ€” `engine = "zensical"` requires `zensical.toml` to be present. -If it is absent, Zenzic raises `ConfigurationError` immediately. There is no fallback to -`mkdocs.yml` and no silent degradation. Zensical identity must be provable. +| [Docusaurus v3][docusaurus] | `DocusaurusAdapter` | Versioned docs, `@site/` alias, Ghost Route detection | +| [MkDocs][mkdocs] | `MkDocsAdapter` | i18n suffix + folder modes, `fallback_to_default` | +| [Zensical][zensical] | `ZensicalAdapter` | Transparent Proxy bridges `mkdocs.yml` if `zensical.toml` absent | +| Any folder | `VanillaAdapter` | Zero-config, Directory Index Integrity โ€” no engine required | -### How it works โ€” Virtual Site Map (VSM) +Third-party adapters install via the `zenzic.adapters` entry-point group. +See the [Developer Guide][docs-arch] for the adapter API. -Most documentation linters check whether a linked file exists on disk. -Zenzic goes further: it builds a **Virtual Site Map** before any rule fires. - -```text -Source files โ”€โ”€โ–บ Adapter โ”€โ”€โ–บ VSM โ”€โ”€โ–บ Rule Engine โ”€โ”€โ–บ Violations - .md + config (engine- (URL โ†’ status) (pure functions) - specific - knowledge) -``` - -The VSM maps every `.md` source file to the canonical URL the build engine -will serve โ€” **without running the build**. Each route carries a status: - -| Status | Meaning | -| :--- | :--- | -| `REACHABLE` | Page is in the nav; users can find it. | -| `ORPHAN_BUT_EXISTING` | File exists on disk but is absent from `nav:`. Users cannot find it via navigation. | -| `CONFLICT` | Two files map to the same URL (e.g. `index.md` + `README.md`). Build result is undefined. | -| `IGNORED` | File will not be served (unlisted `README.md`, Zensical `_private/` dirs). | - -This makes Zenzic uniquely precise: a link to an `ORPHAN_BUT_EXISTING` page -is caught as `UNREACHABLE_LINK` โ€” the file exists, the link resolves, but -the user will hit a 404 after the build because the page is not navigable. - -**Ghost Routes** (`reconfigure_material: true`) โ€” when `mkdocs-material` -auto-generates locale entry points (e.g. `/it/`) at build time, those pages -never appear in `nav:`. Zenzic detects this flag and marks them `REACHABLE` -automatically, so no false orphan warnings are emitted. +--- -**Content-addressable cache** โ€” Zenzic avoids re-linting unchanged files by -keying results on `SHA256(content) + SHA256(config)`. For VSM-aware rules -the key also includes `SHA256(vsm_snapshot)`, ensuring invalidation when any -file's routing state changes. Timestamps are never consulted โ€” the cache is -correct in CI environments where `git clone` resets `mtime`. +## โš™๏ธ Configuration -### MkDocs โ€” i18n fallback +Zero-config by default. Priority: `zenzic.toml` > `[tool.zenzic]` in `pyproject.toml` > built-ins. -When `mkdocs.yml` declares the i18n plugin with `fallback_to_default: true`, Zenzic mirrors -the plugin's resolution logic: a link from a translated page to an untranslated page is **not** -reported as broken, because the build will serve the default-locale version. Supported for both -`docs_structure: suffix` and `docs_structure: folder`. +```toml +# zenzic.toml (all fields optional) +docs_dir = "docs" +fail_under = 80 # exit 1 if score < threshold; 0 = observe only +excluded_dirs = ["includes", "assets", "overrides"] +excluded_build_artifacts = ["pdf/*.pdf", "dist/*.zip"] +placeholder_patterns = ["coming soon", "todo", "stub"] -```yaml -# mkdocs.yml -plugins: - - i18n: - docs_structure: folder - fallback_to_default: true - languages: - - locale: en - default: true - build: true - - locale: it - build: true +[build_context] +engine = "mkdocs" # mkdocs | docusaurus | zensical | vanilla +default_locale = "en" +locales = ["it"] ``` -If `mkdocs.yml` is absent (or the i18n plugin is not configured), Zenzic falls back to standard -single-locale validation โ€” no errors, no warnings, no framework required. - -### Build-time artifacts (`excluded_build_artifacts`) +```bash +zenzic init # Generate zenzic.toml with auto-detected values +zenzic init --pyproject # Embed [tool.zenzic] in pyproject.toml +``` -Applies to any documentation system. If links point to files generated at build time (PDFs, -ZIPs), declare their glob patterns in `zenzic.toml`: +**Custom lint rules** โ€” declare project-specific patterns in `zenzic.toml`, no Python required: ```toml -# zenzic.toml -excluded_build_artifacts = ["pdf/*.pdf", "dist/*.zip"] +[[custom_rules]] +id = "ZZ-NODRAFT" +pattern = "(?i)\\bDRAFT\\b" +message = "Remove DRAFT marker before publishing." +severity = "warning" ``` -Zenzic suppresses errors for matching paths at lint time. The build remains responsible for -generating the artifacts; Zenzic trusts the link without requiring the file on disk. - -### Reference-style links - -`[text][id]` links are resolved through the same pipeline as inline links โ€” including i18n -fallback โ€” for all documentation systems. - -```markdown -[API Reference][api-ref] - -[api-ref]: api.md -``` +Rules fire identically across all adapters. No changes required after engine migration. --- -## Adapters vs. Integrations: The Zenzic Ecosystem - -Zenzic separates **understanding** from **acting** through two distinct extension points: - -| | Adapter | Integration (Plugin) | -| :--- | :--- | :--- | -| **Purpose** | Let Zenzic *understand* your site. | Let Zenzic *guard* your build. | -| **Direction** | Engine โ†’ Zenzic | Zenzic โ†’ Engine | -| **Dependency** | None โ€” pure text analysis. | Required (`mkdocs` lib for the MkDocs plugin). | -| **Trigger** | Automatic on every `zenzic check`. | Opt-in via engine config (e.g. `mkdocs.yml`). | -| **Goal** | Zero-config discovery & routing. | Build-blocking quality control. | -| **Location** | `zenzic.core.adapters.*` | `zenzic.integrations.*` | - -**In practice:** the Adapter is the *mind* โ€” it reads `mkdocs.yml` as plain text and builds -the VSM. The Integration (plugin) is the *arm* โ€” it hooks into `mkdocs build` events and -raises a `PluginError` if quality checks fail. - -Most users only need adapters (automatic). Install an integration only when you want -Zenzic to become a gate inside your engine's build pipeline. - -### MkDocs Plugin - -```bash -# Install the optional extra -pip install "zenzic[mkdocs]" -``` +## ๐Ÿ”„ CI/CD Integration ```yaml -# mkdocs.yml -plugins: - - zenzic: - strict: false - fail_on_error: true - checks: [orphans, snippets, placeholders, assets] +- name: ๐Ÿ›ก๏ธ Zenzic Sentinel + run: uvx zenzic check all --strict + # Exit 1 = quality ยท Exit 2 = leaked credential ยท Exit 3 = path traversal + # Exits 2 and 3 are never suppressible. + +- name: Regression gate + run: | + uvx zenzic score --save # on main branch + uvx zenzic diff # on PR โ€” exit 1 if score drops ``` -The plugin class lives at `zenzic.integrations.mkdocs:ZenzicPlugin` and is auto-discovered -by MkDocs via the `mkdocs.plugins` entry point โ€” no manual path required. +For badge automation and regression gates, see the [CI/CD guide][docs-cicd]. +Full workflow: [`.github/workflows/ci.yml`][ci-workflow] --- -## Installation - -### With `uv` (recommended) - -[`uv`][uv] is the fastest way to install and run Zenzic: +## ๐Ÿ“ฆ Installation ```bash -# Zero-install, one-shot audit -uvx --pre zenzic check all +# Zero-install, one-shot audit (recommended for CI and exploration) +uvx zenzic check all ./docs -# Global CLI tool โ€” available in any project -uv tool install --pre zenzic +# Global CLI tool +uv tool install zenzic -# Project dev dependency โ€” version-pinned in uv.lock -uv add --dev --pre zenzic -``` +# Pinned dev dependency +uv add --dev zenzic -### With `pip` - -```bash -# Global install (consider a virtual environment) -pip install --pre zenzic - -# Inside a virtual environment (recommended) -python -m venv .venv -source .venv/bin/activate # Windows: .venv\Scripts\activate -pip install --pre zenzic +# pip +pip install zenzic +pip install "zenzic[mkdocs]" # + MkDocs build-time plugin ``` -### Lean & Agnostic by Design - -Zenzic performs a **static analysis** of your configuration files (`mkdocs.yml`, `docusaurus.config.ts`, `zensical.toml`, `pyproject.toml`). It does **not** execute the build engine or its plugins โ€” it is 100% subprocess-free. Docusaurus configuration (`.ts`/`.js`) is analysed via static text parsing โ€” Node.js is never invoked. - -This means you **do not need to install** MkDocs, Docusaurus, Material for MkDocs, or any other -build-related plugins in your linting environment. Zenzic remains lightweight and dependency-free, -making it ideal for fast, isolated CI/CD pipelines. +> The `[mkdocs]` extra adds the build-time plugin (`zenzic.integrations.mkdocs`). +> All engine adapters (Docusaurus, Zensical, Vanilla) are included in the base install. -**Installation extras:** - -| Command | What you get | -| :--- | :--- | -| `pip install zenzic` | Core CLI + Docusaurus, Zensical, and Vanilla adapters. No engine library required. | -| `pip install "zenzic[mkdocs]"` | Core + the **MkDocs plugin** (`zenzic.integrations.mkdocs`). Adds `mkdocs` as a dependency. | - -> The MkDocs extra is needed **only** if you want the build-time plugin integration. -> For standalone CLI usage (`zenzic check all`), the base install is sufficient for every engine. -> -> **Build artifacts:** If your documentation links to files generated at build time -> (PDFs, ZIPs), add their glob patterns to `excluded_build_artifacts` in `zenzic.toml` -> rather than pre-generating them. See the [First-Class Integrations](#first-class-integrations) section above. - -### Project setup - -```bash -zenzic init # creates zenzic.toml with auto-detected engine -zenzic init --pyproject # embeds [tool.zenzic] in pyproject.toml instead -``` - -When `pyproject.toml` exists, `zenzic init` asks interactively whether to embed -configuration there. Pass `--pyproject` to skip the prompt. +**Portability:** Zenzic rejects absolute internal links (starting with `/`). Relative links +work at any hosting path. External `https://` URLs are never affected. --- -## CLI usage +## ๐Ÿ–ฅ๏ธ CLI Reference ```bash -# Individual checks -zenzic check links --strict +# Checks +zenzic check links [--strict] zenzic check orphans zenzic check snippets zenzic check placeholders zenzic check assets +zenzic check references [--strict] [--links] +zenzic check all [--strict] [--exit-zero] [--format json] [--engine ENGINE] +zenzic check all [--exclude-dir DIR] [--include-dir DIR] -# Autofix & Cleanup -zenzic clean assets # Interactively delete unused assets -zenzic clean assets -y # Delete unused assets immediately -zenzic clean assets --dry-run # Preview what would be deleted - -# Reference pipeline -zenzic check references # Harvest โ†’ Cross-Check โ†’ Shield โ†’ Integrity score -zenzic check references --strict # Treat Dead Definitions as errors -zenzic check references --links # Also validate reference URLs via async HTTP - -# All checks in one command -zenzic check all --strict -zenzic check all --exit-zero # Report without blocking the pipeline -zenzic check all --format json # Machine-readable output -zenzic check all --engine docusaurus # Explicit engine override - -# Exclusion control -zenzic check all --exclude-dir drafts --exclude-dir temp -zenzic check all --include-dir guides # Only scan specific directories - -# Quality score (0โ€“100) -zenzic score -zenzic score --save # Persist baseline snapshot -zenzic score --fail-under 80 # Exit 1 if below threshold - -# Regression detection against saved snapshot -zenzic diff # Exit 1 on any score drop -zenzic diff --threshold 5 # Exit 1 only if drop > 5 points -``` - -> **Note (v0.6.1+):** `zenzic serve` has been removed. Zenzic focuses exclusively on -> static analysis. To preview your docs, use your engine's native command: -> `mkdocs serve`, `docusaurus start`, or `zensical serve`. - -### Exit codes +# Score & diff +zenzic score [--save] [--fail-under N] +zenzic diff [--threshold N] -| Code | Meaning | -| :---: | :--- | -| `0` | All selected checks passed | -| `1` | One or more checks reported issues | -| **`2`** | **SECURITY CRITICAL โ€” Zenzic Shield detected a leaked credential** | -| **`3`** | **SECURITY CRITICAL โ€” Blood Sentinel detected a system-path traversal** | - -> **Warning:** -> **Exit code 2** is reserved for Shield events (leaked credentials). **Exit code 3** is -> reserved for Blood Sentinel events (path traversal to OS system directories such as -> `/etc/`, `/root/`). Both are never suppressed by `--exit-zero`. Rotate and audit immediately. - ---- - -## ๐Ÿ›ก๏ธ Zenzic Shield - -The **Zenzic Shield** is a two-layer security system built into the core engine: +# Autofix +zenzic clean assets [-y] [--dry-run] -| Layer | Protects against | -| --- | --- | -| **Credential detection** | Leaked API keys / tokens embedded in reference URLs | -| **Path traversal** | `../../../../etc/passwd`-style escape from `docs/` | +# Init +zenzic init [--pyproject] -### Credential detection - -The credential layer runs during **Pass 1** (Harvesting) of the reference pipeline and scans -every reference URL for known credential patterns before any HTTP request is issued. - -```markdown - -[api-docs]: https://api.example.com/?key=sk-xxxx-xxxx-xxxx-xxxx-xxxx-xxxx +# Interactive showroom +zenzic lab [--act N] [--list] ``` -```bash -โ•”โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•— -โ•‘ SECURITY CRITICAL โ•‘ -โ•‘ Secret(s) detected in documentation โ•‘ -โ•šโ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ•โ• +--- - [SHIELD] docs/api.md:12 โ€” openai-api-key detected in URL - https://api.example.com/?key=sk-xxxx-xxxx-x... +## ๐Ÿ“Ÿ Visual Tour -Build aborted. Rotate the exposed credential immediately. +```text +โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ ๐Ÿ›ก ZENZIC SENTINEL v0.6.1 โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ +โ”‚ โ”‚ +โ”‚ docusaurus โ€ข 38 files (18 docs, 20 assets) โ€ข 0.9s โ”‚ +โ”‚ โ”‚ +โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ docs/guides/setup.mdx โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ +โ”‚ โ”‚ +โ”‚ โœ— 12: [Z001] 'quickstart.mdx' not found in docs โ”‚ +โ”‚ โ”‚ โ”‚ +โ”‚ 12 โ”‚ Read the [quickstart guide](quickstart.mdx) first. โ”‚ +โ”‚ โ”‚ โ”‚ +โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ +โ”‚ โ”‚ +โ”‚ โœ— 1 error โ€ข 1 file with findings โ€ข FAILED โ”‚ +โ”‚ โ”‚ +โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ ``` -**How it works:** - -1. The Shield runs *inside* Pass 1 โ€” before Pass 2 validates links and before any HTTP ping is - issued. A document containing a leaked credential is never used to make outbound requests. -2. Patterns use exact-length quantifiers (`{48}`, `{36}`, `{16}`) โ€” no backtracking, O(1) per line. -3. Eight credential families are covered out of the box: - -| Type | Pattern | -| --- | --- | -| OpenAI API key | `sk-[a-zA-Z0-9]{48}` | -| GitHub token | `gh[pousr]_[a-zA-Z0-9]{36}` | -| AWS access key | `AKIA[0-9A-Z]{16}` | -| Stripe live key | `sk_live_[0-9a-zA-Z]{24}` | -| Slack token | `xox[baprs]-[0-9a-zA-Z]{10,48}` | -| Google API key | `AIza[0-9A-Za-z\-_]{35}` | -| PEM private key | `-----BEGIN [A-Z ]+ PRIVATE KEY-----` | -| Hex-encoded payload | 3+ consecutive `\xNN` escape sequences | - -1. **No blind spots** โ€” the Shield scans every line of the source file, including lines inside - fenced code blocks (`bash`, `yaml`, unlabelled, etc.). A credential committed inside a code - example is still a committed credential. - -> **Tip:** -> Add `zenzic check references` to your pre-commit hooks to catch leaked credentials before they -> are ever committed to version control. +Visit the [documentation portal][docs-home] for interactive screenshots and rich examples. -### Path traversal +--- -The path traversal layer runs inside `InMemoryPathResolver` during `check links`. It normalises -every resolved href with `os.path.normpath` (pure C, zero kernel calls) and verifies the result -is contained within `docs/` using a single string prefix check โ€” $O(1)$, allocation-free. +## ๐Ÿ—บ๏ธ Roadmap v0.7.0 -```bash -Attack href: ../../../../etc/passwd -After resolve: /etc/passwd -Shield check: /etc/passwd does not start with /docs/ โ†’ PathTraversal returned, link rejected -``` - -Any href that escapes the docs root is surfaced as a distinct `PathTraversal` error โ€” never -silently collapsed into a generic "file not found". +- [ ] **Auto-fix Engine** โ€” Automatic repair of broken links and orphaned anchors. +- [ ] **IDE Extensions** โ€” Real-time linting for VS Code and Cursor via LSP. +- [ ] **AI Context Provider** โ€” VSM export in LLM-friendly format for AI agents. +- [ ] **Astro & VitePress Adapters** โ€” Expanding the Safe Harbor to JS frameworks. --- -## CI/CD integration +## ๐Ÿ—๏ธ Design Philosophy -### GitHub Actions +Zenzic is built on three operational contracts: -```yaml -- name: Lint documentation - run: uvx --pre zenzic check all +**Lint the Source, Not the Build.** The VSM (Virtual Site Map) maps every `.md` file to its +canonical URL without running the build โ€” errors are caught before they reach production. -- name: Check references and run Shield - run: uvx --pre zenzic check references -``` +**Zero-Trust Execution.** No subprocesses, no arbitrary code execution, no build engine imports. +Docusaurus `.ts`/`.js` configs are parsed via static text analysis โ€” Node.js is never invoked. -Full workflow: [`.github/workflows/zenzic.yml`][ci-workflow] +**Mandatory Exclusion at Every Entry Point.** All file discovery goes through +`LayeredExclusionManager` โ€” a 4-level hierarchy (System โ†’ VCS โ†’ Config โ†’ CLI). No global scan +without an explicit exclusion context. -For dynamic badge automation and regression detection, see the [CI/CD Integration guide][docs-cicd]. +See the [Architecture Guide][docs-arch] for the Two-Pass Reference Pipeline and VSM deep-dive. --- -## Configuration - -All fields are optional. Zenzic works with no configuration file at all. +## ๐Ÿ™‹ FAQ -Zenzic follows a three-level **Agnostic Citizen** priority chain: +**Why not `grep`?** Grep is blind to structure. Zenzic understands Docusaurus versioning, +MkDocs i18n fallbacks, and Ghost Routes โ€” pages that don't exist as files but are valid URLs. -1. `zenzic.toml` at the repository root โ€” sovereign; always wins. -2. `[tool.zenzic]` in `pyproject.toml` โ€” used when `zenzic.toml` is absent. -3. Built-in defaults. +**Does it run my build engine?** No. 100% subprocess-free. Static analysis on plain text only. -```toml -# zenzic.toml (or [tool.zenzic] in pyproject.toml) -docs_dir = "docs" -excluded_dirs = ["includes", "assets", "stylesheets", "overrides", "hooks"] -snippet_min_lines = 1 -placeholder_max_words = 50 -placeholder_patterns = ["coming soon", "todo", "stub"] -fail_under = 80 # exit 1 if score drops below this; 0 = observational mode - -# Engine and i18n context โ€” required only for folder-mode multi-locale projects. -# When absent, Zenzic reads locale config directly from mkdocs.yml. -[build_context] -engine = "mkdocs" # "mkdocs", "docusaurus", "zensical", or "vanilla" -default_locale = "en" -locales = ["it"] # non-default locale directory names -``` +**Can it handle thousands of files?** Yes. Adaptive parallelism for discovery; O(1) VSM lookup +per link; content-addressable cache (`SHA256(content + config + vsm_snapshot)`) skips unchanged files. ---- - -## DSL `[[custom_rules]]` - -Declare project-specific lint rules in `zenzic.toml` without writing Python: - -```toml -[[custom_rules]] -id = "ZZ-NODRAFT" -pattern = "(?i)\\bDRAFT\\b" -message = "Remove the DRAFT marker before publishing." -severity = "warning" +**Shield vs Blood Sentinel?** Shield = secrets *inside* content (exit 2). Blood Sentinel = +links pointing to OS system *paths* (exit 3). Both are non-suppressible. -[[custom_rules]] -id = "ZZ-NOINTERNAL" -pattern = "internal\\.corp\\.example\\.com" -message = "Internal hostname must not appear in public documentation." -severity = "error" -``` +**No `zenzic.toml` needed?** Correct. Zenzic identifies the engine from config files present and applies safe defaults. Run +`zenzic init` at any time to generate a pre-populated config file. -Rules fire identically across all adapters (MkDocs, Docusaurus, Zensical, Vanilla). No changes -required after migrating from one engine to another. +**What is `zenzic lab`?** A 9-act interactive showroom covering every engine and error class. +Run it once before integrating Zenzic into any project. --- -## Development - -For a faster, interactive development workflow using **just**, or for detailed instructions on -adding new checks, see the [Contributing Guide][contributing]. +## ๐Ÿ› ๏ธ Development ```bash -uv sync --group dev -nox -s dev # Install pre-commit hooks (once) - +uv sync --all-groups nox -s tests # pytest + coverage -nox -s lint # ruff check -nox -s format # ruff format +nox -s lint # ruff nox -s typecheck # mypy --strict -nox -s preflight # full CI pipeline (lint + test + self-check) -``` - ---- - -## Visual Tour - -The full Sentinel audit โ€” banner, engine detection, and pass/fail verdict: - -```bash -โ•ญโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ ๐Ÿ›ก ZENZIC SENTINEL v0.6.1rc2 โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฎ -โ”‚ โ”‚ -โ”‚ docusaurus โ€ข 38 files (18 docs, 20 assets) โ€ข 0.9s โ”‚ -โ”‚ โ”‚ -โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ docs/guides/setup.mdx โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ -โ”‚ โ”‚ -โ”‚ โœ— 12: [Z001] 'quickstart.mdx' not found in docs โ”‚ -โ”‚ โ”‚ โ”‚ -โ”‚ 12 โ”‚ Read the [quickstart guide](quickstart.mdx) first. โ”‚ -โ”‚ โ”‚ โ”‚ -โ”‚ โ”‚ -โ”‚ โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ โ”‚ -โ”‚ โ”‚ -โ”‚ โœ— 1 error โ€ข 1 file with findings โ”‚ -โ”‚ โ”‚ -โ”‚ FAILED: One or more checks failed. โ”‚ -โ”‚ โ”‚ -โ”‚ ๐Ÿ’ก 4 info findings suppressed โ€” use --show-info for details. โ”‚ -โ”‚ โ”‚ -โ•ฐโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ•ฏ +nox -s preflight # lint + format + typecheck + pytest + reuse +just verify # preflight + zenzic check all --strict (self-dogfood) ``` -**Shield** catches leaked credentials before any HTTP request is issued. **Blood Sentinel** -blocks path traversal attempts that escape the `docs/` root. Both trigger non-suppressible -exit codes (2 and 3). The **VSM** (Virtual Site Map) ensures link validation operates on -canonical URLs โ€” not filesystem paths โ€” so orphan pages and slug overrides are detected -accurately across all engines. - -For interactive screenshots and rich visual examples, visit the -[documentation portal](https://zenzic.dev/docs/). +See the [Contributing Guide][contributing] for the Zenzic Way checklist and PR conventions. --- -## Contributing - -We welcome bug reports, documentation improvements, and pull requests. Before you start: +## ๐Ÿค Contributing -1. Open an issue to discuss the change โ€” use the [bug report][issues], [feature request][issues], or [docs issue][issues] template. -2. Read the [Contributing Guide][contributing] โ€” especially the **Local development setup** and the **Zenzic Way** checklist (pure functions, no subprocesses, source-first). -3. Every PR must pass `nox -s preflight` (tests + lint + typecheck + self-dogfood) and include REUSE/SPDX headers on new files. +1. Open an [issue][issues] to discuss the change. +2. Read the [Contributing Guide][contributing] โ€” Zenzic Way checklist, pure functions, no + subprocesses, source-first. +3. Every PR must pass `nox -s preflight` and include REUSE/SPDX headers on new files. -Please also review our [Code of Conduct][coc] and [Security Policy][security]. +See also: [Code of Conduct][coc] ยท [Security Policy][security] -## Citing Zenzic +## ๐Ÿ“Ž Citing -A [`CITATION.cff`][citation-cff] file is present at the root of the repository. GitHub renders -it automatically โ€” click **"Cite this repository"** on the repo page for APA or BibTeX output. +A [`CITATION.cff`][citation-cff] is present at the root. Click **"Cite this repository"** on +GitHub for APA or BibTeX output. -## License +## ๐Ÿ“„ License Apache-2.0 โ€” see [LICENSE][license]. @@ -702,9 +384,8 @@ Apache-2.0 โ€” see [LICENSE][license]. [uv]: https://docs.astral.sh/uv/ [docs-home]: https://zenzic.dev/docs/ [docs-badges]: https://zenzic.dev/docs/usage/badges/ -[docs-cicd]: https://zenzic.dev/docs/ci-cd/ -[docs-arch]: https://zenzic.dev/docs/architecture/ -[docs-contributing]: https://zenzic.dev/docs/community/contribute/ +[docs-cicd]: https://zenzic.dev/docs/guides/ci-cd/ +[docs-arch]: https://zenzic.dev/docs/internals/architecture-overview/ [ci-workflow]: .github/workflows/ci.yml [contributing]: CONTRIBUTING.md [license]: LICENSE diff --git a/RELEASE.md b/RELEASE.md index e0f8b69..b170542 100644 --- a/RELEASE.md +++ b/RELEASE.md @@ -1,174 +1,72 @@ +# ๐Ÿ›ก๏ธ Zenzic v0.6.1 โ€” Obsidian Glass -# Zenzic v0.6.1rc2 โ€” Obsidian Bastion (Hardened) Release Protocol +## "Precision, Security, and the new Standalone Standard." -**Prepared by:** S-1 (Auditor) -**Date:** 2026-04-16 -**Status:** RELEASE CANDIDATE 2 โ€” Security audit completed -**Branch:** `main` -**Codename:** Obsidian Bastion (Hardened) โ€” Post-Stress-Test Seal +We are proud to announce the stable release of **Zenzic v0.6.1 "Obsidian Glass"**. This version marks a major milestone in our mission to provide the most resilient, engine-agnostic documentation integrity suite for the modern engineering stack. -> **Tech Lead note:** RC2 follows Operation Obsidian Stress โ€” a controlled -> siege by Red/Blue/Purple teams. The Red Team found 4 Shield bypass vectors -> (Unicode Cf, HTML entities, comment-interleaving, cross-line split). All -> have been sealed. The Purple Team identified 6 documentation drift items -> including a phantom `serve` command. All corrected. 1046 tests pass. +Documentation should be portable, secure, and verifiable regardless of the build engine you choose. With *Obsidian Glass*, Zenzic breaks the final chains of engine dependency โ€” and speaks a professional language that enterprises can audit. ---- - -## 1. Version Anchors - -| Location | Expected | Status | -| :--- | :--- | :---: | -| `src/zenzic/__init__.py` | `0.6.1rc2` | โœ… | -| `pyproject.toml` `[project]` | `0.6.1rc2` | โœ… | -| `pyproject.toml` `[tool.bumpversion]` | `0.6.1rc2` | โœ… | -| `CITATION.cff` | `0.6.1rc2` | โœ… | -| `CHANGELOG.md` top entry | `[0.6.1rc2]` | โœ… | -| `CHANGELOG.it.md` top entry | `[0.6.1rc2]` | โœ… | - -**Not tracked** (Clean Harbor): - -- `mkdocs.yml` โ€” deleted (docs migrated to `zenzic-doc`) -- `uv.lock` โ€” updated by `uv lock`, not by bumpversion - ---- - -## 2. The Adapter Gate (Core Logic) - -### 2a. Docusaurus v3 Adapter (new in v0.6.0a1) - -- [x] `DocusaurusAdapter` satisfies the `@runtime_checkable` `BaseAdapter` protocol -- [x] `baseUrl` and `routeBasePath` extraction via static parsing (zero Node.js โ€” Pillar 2) -- [x] Ghost Route mapping for locale entry points (`/it/`, `/`) verified -- [x] `from_repo()` auto-discovers `docusaurus.config.ts` / `.js` -- [x] `classify_route()` marks `_`-prefixed files as `IGNORED` -- [x] Frontmatter `slug:` resolution (absolute and relative) -- [x] `.md` and `.mdx` source file handling -- [x] i18n locale tree discovery (`i18n/{locale}/docusaurus-plugin-content-docs/current/`) -- [x] Dynamic config detection (`async`, `import()`, `require()`) with graceful fallback -- [x] 65 dedicated tests across 12 test classes - -### 2b. Metadata-Driven Routing (new in v0.6.0a2) - -- [x] `RouteMetadata` dataclass and `get_route_info()` on `BaseAdapter` protocol -- [x] All 4 adapters implement the metadata API -- [x] `build_vsm()` prefers metadata path, falls back to legacy `map_url()` + `classify_route()` -- [x] Shield IO Middleware: `safe_read_line()` scans frontmatter through Shield before parsing - -### 2c. Adapter Inventory +### ๐Ÿš€ Key Highlights -| Adapter | LOC | Status | -| :--- | :---: | :---: | -| MkDocs | 698 | โœ… | -| Docusaurus v3 | 589 | โœ… | -| Zensical | 324 | โœ… | -| Vanilla | 92 | โœ… | -| Factory + cache | 164 | โœ… | +#### 1. Standalone Engine โ€” A New Identity ---- +We replaced the informal "Vanilla" mode with a robust **Standalone Engine**, ensuring Zenzic is the perfect companion even for pure Markdown folders that have no build framework at all. The `StandaloneAdapter` is now the canonical engine for framework-free projects, and `zenzic init` writes `engine = "standalone"` automatically when no framework configuration is detected. -## 3. The Obsidian Bastion Gate (Layered Exclusion) +> *"We replaced the 'Vanilla' mode with a robust Standalone Engine, ensuring Zenzic is the perfect companion even for pure Markdown folders."* -- [x] `ExclusionManager` โ€” 4-level hierarchy (L1 System โ†’ L2 VCS โ†’ L3 Config โ†’ L4 CLI) -- [x] L1 System Guardrails immutable (`.git/`, `node_modules/`, etc.) -- [x] L2 VCS Ignore Parser โ€” Pure Python `.gitignore` interpreter with pre-compiled regex -- [x] L3 Config โ€” `excluded_dirs` / `excluded_file_patterns` from `zenzic.toml` -- [x] L4 CLI โ€” `--exclude-dir` / `--include-dir` repeatable flags -- [x] `exclusion_manager` parameter **mandatory** on all scanner/validator entry points -- [x] 57 dedicated tests (677 lines in `test_exclusion.py`) +**Breaking change:** `engine = "vanilla"` in any `zenzic.toml` now raises `ConfigurationError [Z000]`. Update to `engine = "standalone"`. ---- +#### 2. Zenzic Finding Codes (Zxxx) -## 4. The Tabula Rasa Gate (Universal Discovery) +Introducing **Zenzic Finding Codes**: every diagnostic message now carries a unique `Zxxx` identifier, giving the Sentinel a professional language for enterprise-grade reporting and future tooling integrations. -- [x] **Every** `rglob()` call removed from the entire codebase -- [x] All file iteration via `walk_files()` / `iter_markdown_sources()` in `discovery.py` -- [x] 168 call sites updated across 13 test files -- [x] No `Optional[ExclusionManager]` โ€” `TypeError` at call time if missing +> *"Introducing Zenzic Finding Codes (Zxxx): giving our Sentinel a professional language for enterprise-grade reporting."* ---- +| Code | Meaning | +|------|---------| +| Z101 | LINK_BROKEN | +| Z201 | SHIELD_SECRET | +| Z401 | MISSING_DIRECTORY_INDEX | +| Z402 | ORPHAN_PAGE | -## 5. Security Hardening Gate +Full registry: `src/zenzic/core/codes.py`. -- [x] **F2-1:** Lines > 1 MiB truncated before Shield regex matching (ReDoS prevention) -- [x] **F4-1:** `_validate_docs_root()` rejects `docs_dir` escaping repo root (Exit Code 3) -- [x] **Adapter Cache:** Module-level dict keyed by `(engine, docs_root, repo_root)`, thread-safe -- [x] **Shield IO Middleware:** Frontmatter lines scanned before any parser processes them -- [x] **ZRT-006:** Unicode Cf character stripping in Shield normalizer (zero-width bypass) -- [x] **ZRT-006:** HTML entity decoding in Shield normalizer (`&#NNN;` bypass) -- [x] **ZRT-007:** HTML/MDX comment stripping in Shield normalizer (interleaving bypass) -- [x] **ZRT-007:** 1-line lookback buffer `scan_lines_with_lookback()` (split-token bypass) -- [x] **Red Team:** 11 Blood Sentinel jailbreak vectors tested โ€” all blocked -- [x] **Red Team:** DoS resilience verified (10MB lines, 5000 files, 50-level nesting) +#### 3. Interactive Lab (`zenzic lab`) ---- +The `zenzic lab` command is now **menu-driven**. Run it without arguments to see all nine acts and choose what to explore. Run `zenzic lab ` to dive straight into a specific scenario. -## 6. Clean Harbor Gate (Repo Hygiene) +#### 4. Zensical Transparent Proxy (Legacy Bridge) -- [x] `mkdocs.yml` โ€” physically deleted -- [x] `overrides/` โ€” physically deleted -- [x] `scripts/generate_docs_assets.py` โ€” physically deleted -- [x] `scripts/generate_hero_specimen.py` โ€” physically deleted -- [x] `scripts/generate_social.py` โ€” physically deleted -- [x] `.github/workflows/deploy-docs.yml` โ€” physically deleted -- [x] `.github/workflows/zenzic.yml` โ€” physically deleted -- [x] `docs/` fully migrated to `zenzic-doc` repository -- [x] `noxfile.py` โ€” doc sessions removed -- [x] MkDocs plugin relocated to `zenzic.integrations.mkdocs` +Migrating from MkDocs to Zensical? Do it one step at a time. Zenzic now includes a transparent bridge that allows the **Zensical engine** to understand your legacy `mkdocs.yml` structure. No configuration changes required โ€” Zenzic identifies your project and bridges the gap automatically. ---- +#### 2. Docusaurus v3 Multi-Versioning -## 7. Architectural Purity Gate (Pillar 2) +Zenzic is now a first-class citizen for large-scale Docusaurus projects. Weโ€™ve implemented native support for `versions.json` and the `versioned_docs/` directory. Your versioned routes are now automatically tracked in the **Virtual Site Map (VSM)**, ensuring that links to older documentation are validated with the same rigor as your latest release. -- [x] `zenzic serve` โ€” removed entirely -- [x] Zero `subprocess.run()`, `os.system()`, or shell calls in codebase -- [x] Docusaurus config parsed as text, not via Node.js -- [x] `.gitignore` interpreted in Pure Python, not via `git check-ignore` -- [x] Core free of engine-specific imports +#### 3. Global Offline Mode (`--offline`) ---- +Distributed documentation on USB drives? Local intranets without directory-index support? The new `--offline` flag forces all adapters to resolve Markdown sources to flat `.html` files (e.g., `intro.md` โ†’ `/intro.html`). Ensure your documentation remains navigable even in air-gapped environments. -## 8. Quality Gates +#### 4. @site/ Alias Resolution -- [x] `pytest` โ€” 1046 tests passing, 0 failed -- [x] `ruff check src/` โ†’ 0 violations -- [x] `reuse lint` โ†’ compliant -- [x] `pip install -e .` โ†’ `zenzic --help` outputs usage -- [x] `uv run zenzic --version` โ†’ `Zenzic v0.6.1rc2` +For Docusaurus users, weโ€™ve added support for the `@site/` path alias. Zenzic now correctly resolves project-relative links like `[logo](@site/static/img/logo.png)` without requiring complex exclusion rules. ---- +### ๐Ÿ› ๏ธ Migration & Call to Action -## 9. Docusaurus Validation (zenzic-doc) +If you are currently using MkDocs and considering a move to a more modern, TOML-based or MDX-powered architecture, **Zenzic v0.6.1 is your safety net**. -- [x] `zenzic check all --engine docusaurus` โ†’ exit code 0 -- [x] Zero CONFLICT routes -- [x] `zenzic-doc` has `release-docs.yml` workflow for Cloudflare Pages deploy -- [x] `release-docs.yml` has `deployments: write` permission (fixed in `fix/deploy-permissions`) +1. Install Zenzic: `uv tool install zenzic` +2. Run `zenzic check all` on your existing MkDocs project. +3. Switch your engine to `zensical` or `docusaurus` and watch Zenzic validate the migration in real-time. ---- - -## 10. Performance Benchmark - -| Scenario | Result | -| :--- | :--- | -| 5,000 files, 100 VCS patterns | 626 ms | -| RSS memory delta | 0 MB | +**If you used `engine = "vanilla"`:** update your `zenzic.toml` to `engine = "standalone"` before upgrading. --- -## 11. RC2 Gate Decision +### ๐Ÿ‡ฎ๐Ÿ‡น Engineered with Precision -- [x] All gates (ยงยง 2โ€“9) verified -- [x] Benchmark ยง 10 within acceptable thresholds -- [x] Operation Obsidian Stress completed โ€” 4 Shield bypasses sealed -- [x] Documentation Reality Sync โ€” 6 drift items corrected -- [x] CI pipeline green on `main` - -**Decision:** โœ… RC2 approved โ€” `v0.6.1rc2` tagged and published to PyPI - ---- +Zenzic is developed by **PythonWoods**, based in Italy, and committed to the craft of high-performance, deterministic Python engineering. -*"Il Bastione non si fida dell'assenza di attacchi โ€” si fida della resistenza verificata."* -โ€” Senior Tech Lead +[**Read the Full Documentation โ†’**](https://zenzic.dev) diff --git a/REUSE.toml b/REUSE.toml index a13de63..7271a07 100644 --- a/REUSE.toml +++ b/REUSE.toml @@ -19,6 +19,11 @@ path = ".zenzic-score.json" SPDX-FileCopyrightText = "2026 PythonWoods " SPDX-License-Identifier = "Apache-2.0" +[[annotations]] +path = "coverage.json" +SPDX-FileCopyrightText = "2026 PythonWoods " +SPDX-License-Identifier = "Apache-2.0" + # โ”€โ”€ Source โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ [[annotations]] diff --git a/coverage.json b/coverage.json new file mode 100644 index 0000000..1138a0d --- /dev/null +++ b/coverage.json @@ -0,0 +1 @@ +{"meta": {"format": 3, "version": "7.13.5", "timestamp": "2026-04-19T19:36:40.826624", "branch_coverage": true, "show_contexts": false}, "files": {"src/zenzic/__init__.py": {"executed_lines": [5], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"": {"executed_lines": [5], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "src/zenzic/cli.py": {"executed_lines": [5, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19, 21, 22, 23, 24, 33, 34, 42, 43, 44, 47, 54, 61, 68, 73, 83, 89, 96, 97, 114, 116, 136, 139, 161, 177, 178, 187, 194, 195, 196, 197, 207, 219, 220, 222, 223, 224, 225, 226, 227, 232, 235, 243, 244, 246, 247, 254, 257, 258, 269, 271, 272, 273, 275, 276, 278, 279, 280, 284, 285, 292, 294, 314, 315, 316, 317, 319, 320, 321, 322, 324, 325, 326, 336, 337, 338, 339, 340, 343, 344, 361, 363, 364, 365, 367, 368, 370, 371, 373, 374, 375, 377, 388, 389, 390, 391, 393, 395, 396, 397, 408, 409, 412, 413, 420, 422, 423, 424, 426, 427, 429, 430, 431, 432, 433, 435, 436, 437, 439, 440, 441, 442, 449, 460, 461, 462, 463, 465, 467, 468, 469, 479, 480, 483, 484, 516, 518, 519, 520, 522, 523, 525, 526, 527, 528, 529, 531, 532, 538, 541, 542, 543, 544, 545, 546, 547, 550, 564, 565, 577, 580, 591, 592, 593, 594, 596, 597, 598, 600, 602, 603, 604, 616, 617, 619, 620, 623, 624, 631, 633, 634, 635, 637, 638, 640, 641, 642, 644, 655, 656, 657, 658, 660, 662, 663, 664, 675, 676, 679, 680, 724, 725, 731, 733, 734, 735, 737, 738, 740, 741, 742, 744, 745, 746, 747, 748, 749, 756, 769, 770, 771, 782, 783, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 797, 798, 799, 800, 812, 820, 823, 824, 825, 829, 836, 837, 859, 861, 863, 864, 865, 866, 867, 869, 870, 889, 890, 900, 901, 902, 909, 920, 921, 922, 923, 924, 925, 926, 927, 928, 931, 944, 945, 955, 966, 967, 969, 970, 971, 972, 975, 976, 977, 979, 989, 1005, 1006, 1008, 1014, 1021, 1022, 1025, 1026, 1027, 1028, 1029, 1035, 1036, 1040, 1043, 1060, 1063, 1064, 1065, 1070, 1071, 1072, 1075, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1088, 1089, 1145, 1146, 1147, 1149, 1150, 1154, 1155, 1156, 1157, 1159, 1160, 1168, 1169, 1171, 1172, 1179, 1182, 1183, 1184, 1192, 1207, 1208, 1209, 1210, 1213, 1215, 1218, 1219, 1220, 1222, 1224, 1225, 1227, 1229, 1230, 1231, 1245, 1246, 1247, 1250, 1251, 1252, 1257, 1259, 1260, 1261, 1264, 1265, 1276, 1278, 1279, 1280, 1281, 1284, 1286, 1287, 1288, 1291, 1297, 1300, 1329, 1343, 1344, 1345, 1346, 1347, 1348, 1351, 1353, 1354, 1355, 1356, 1358, 1359, 1362, 1363, 1364, 1365, 1369, 1370, 1371, 1372, 1374, 1375, 1385, 1387, 1396, 1397, 1398, 1399, 1400, 1402, 1403, 1404, 1405, 1407, 1408, 1409, 1417, 1419, 1420, 1423, 1426, 1445, 1446, 1447, 1448, 1449, 1451, 1452, 1453, 1457, 1459, 1460, 1462, 1463, 1485, 1486, 1487, 1488, 1489, 1490, 1491, 1492, 1493, 1494, 1495, 1496, 1497, 1502, 1503, 1504, 1507, 1510, 1541, 1543, 1544, 1545, 1548, 1549, 1551, 1553, 1558, 1559, 1561, 1564, 1566, 1567, 1568, 1570, 1573, 1575, 1576, 1577, 1578, 1581, 1583, 1585, 1586, 1591, 1593, 1595, 1596, 1597, 1599, 1624, 1626, 1634, 1636, 1637, 1642, 1644, 1646, 1647, 1652, 1654, 1656, 1657, 1658, 1660, 1667, 1668, 1670, 1672, 1678, 1680, 1688, 1694, 1695, 1699, 1700, 1701, 1707, 1708, 1709, 1710, 1712, 1713, 1714, 1718, 1720, 1721, 1722, 1723, 1725, 1744, 1775, 1794, 1802, 1803, 1804, 1808, 1812, 1813, 1815], "summary": {"covered_lines": 544, "num_statements": 676, "percent_covered": 78.15217391304348, "percent_covered_display": "78", "missing_lines": 132, "excluded_lines": 0, "percent_statements_covered": 80.4733727810651, "percent_statements_covered_display": "80", "num_branches": 244, "num_partial_branches": 37, "covered_branches": 175, "missing_branches": 69, "percent_branches_covered": 71.72131147540983, "percent_branches_covered_display": "72"}, "missing_lines": [85, 86, 98, 99, 100, 101, 102, 103, 104, 105, 109, 110, 111, 141, 142, 143, 144, 145, 149, 150, 151, 153, 154, 155, 157, 158, 198, 199, 204, 248, 249, 274, 281, 282, 318, 366, 369, 392, 425, 443, 444, 445, 446, 447, 448, 464, 521, 548, 549, 551, 552, 553, 554, 578, 581, 595, 599, 618, 636, 659, 689, 690, 691, 692, 694, 695, 696, 697, 699, 700, 701, 703, 704, 705, 707, 708, 709, 713, 714, 717, 718, 719, 721, 736, 750, 751, 752, 753, 754, 755, 826, 827, 903, 904, 905, 906, 907, 908, 929, 930, 956, 973, 974, 978, 990, 1030, 1034, 1066, 1067, 1073, 1074, 1148, 1151, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1308, 1315, 1316, 1317, 1318, 1320, 1367, 1569, 1696, 1697, 1702, 1705], "excluded_lines": [], "executed_branches": [[96, 97], [225, 226], [225, 227], [243, 244], [243, 254], [247, 254], [273, 275], [314, 315], [314, 324], [317, 319], [320, 321], [320, 322], [337, 338], [337, 339], [339, -257], [339, 340], [365, 367], [368, 370], [388, 389], [388, 395], [391, 393], [408, -343], [408, 409], [424, 426], [440, 441], [440, 460], [442, 449], [460, 461], [460, 467], [463, 465], [479, -412], [479, 480], [520, 522], [542, 543], [542, 580], [545, 546], [545, 550], [550, 564], [564, 565], [564, 577], [577, 542], [580, 591], [591, 592], [591, 602], [594, 596], [598, 600], [617, 619], [619, -483], [619, 620], [635, 637], [655, 656], [655, 662], [658, 660], [675, -623], [675, 676], [735, 737], [745, 746], [745, 769], [747, 748], [749, 756], [782, -724], [782, 783], [825, 829], [869, 870], [869, 889], [889, 890], [889, 900], [900, 901], [900, 920], [902, 909], [920, 921], [920, 944], [922, 923], [924, 925], [924, 931], [927, 928], [944, 945], [944, 955], [955, 966], [966, 967], [966, 1008], [970, 971], [970, 975], [975, 976], [975, 989], [977, 979], [989, 1005], [1005, 966], [1005, 1006], [1025, 1026], [1025, 1036], [1026, 1027], [1026, 1028], [1028, 1025], [1028, 1029], [1029, 1035], [1070, 1071], [1070, 1078], [1147, 1149], [1150, 1154], [1156, 1157], [1156, 1159], [1182, 1183], [1182, 1213], [1184, 1192], [1208, 1209], [1208, 1210], [1218, 1219], [1218, 1222], [1224, 1225], [1224, 1227], [1229, 1230], [1229, 1231], [1246, 1247], [1246, 1250], [1251, 1252], [1251, 1257], [1259, -1088], [1259, 1260], [1260, -1088], [1260, 1261], [1279, 1280], [1279, 1286], [1287, 1288], [1287, 1297], [1353, 1354], [1353, 1358], [1358, 1359], [1358, 1362], [1362, 1363], [1362, 1364], [1364, 1365], [1402, 1403], [1402, 1417], [1403, 1404], [1403, 1407], [1419, -1329], [1419, 1420], [1452, 1453], [1452, 1459], [1462, 1463], [1462, 1485], [1491, 1492], [1491, 1502], [1503, -1426], [1503, 1504], [1543, 1544], [1543, 1548], [1551, 1553], [1551, 1558], [1558, 1559], [1558, 1561], [1566, 1567], [1566, 1568], [1568, 1570], [1575, 1576], [1575, 1578], [1585, 1586], [1585, 1593], [1596, 1597], [1596, 1599], [1636, 1637], [1636, 1644], [1646, 1647], [1646, 1654], [1657, 1658], [1657, 1660], [1667, 1668], [1667, 1670], [1670, 1672], [1670, 1678], [1695, 1699], [1701, 1707], [1713, 1714], [1713, 1720]], "missing_branches": [[96, 98], [99, 100], [99, 110], [103, 104], [103, 105], [157, -139], [157, 158], [247, 248], [248, 249], [248, 254], [273, 274], [317, 318], [365, 366], [368, 369], [391, 392], [424, 425], [442, 443], [445, 446], [445, 449], [463, 464], [520, 521], [550, 551], [552, 553], [552, 554], [577, 578], [580, 581], [594, 595], [598, 599], [617, 618], [635, 636], [658, 659], [695, 696], [695, 699], [700, 701], [700, 703], [703, 704], [703, 707], [707, 708], [707, 717], [709, 713], [709, 717], [717, 718], [717, 721], [735, 736], [747, 756], [749, 750], [752, 753], [752, 756], [825, 826], [902, 903], [905, 906], [905, 909], [922, 931], [927, 931], [955, 956], [977, 978], [989, 990], [1029, 1030], [1147, 1148], [1150, 1151], [1184, 1185], [1185, 1184], [1185, 1186], [1186, 1185], [1186, 1187], [1364, 1367], [1568, 1569], [1695, 1696], [1701, 1702]], "functions": {"_print_no_config_hint": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 2, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [85, 86], "excluded_lines": [], "start_line": 83, "executed_branches": [], "missing_branches": []}, "_apply_engine_override": {"executed_lines": [96, 97], "summary": {"covered_lines": 2, "num_statements": 13, "percent_covered": 15.789473684210526, "percent_covered_display": "16", "missing_lines": 11, "excluded_lines": 0, "percent_statements_covered": 15.384615384615385, "percent_statements_covered_display": "15", "num_branches": 6, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 5, "percent_branches_covered": 16.666666666666668, "percent_branches_covered_display": "17"}, "missing_lines": [98, 99, 100, 101, 102, 103, 104, 105, 109, 110, 111], "excluded_lines": [], "start_line": 89, "executed_branches": [[96, 97]], "missing_branches": [[96, 98], [99, 100], [99, 110], [103, 104], [103, 105]]}, "_output_json_findings": {"executed_lines": [116, 136], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 114, "executed_branches": [], "missing_branches": []}, "_render_link_error": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 13, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 13, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0"}, "missing_lines": [141, 142, 143, 144, 145, 149, 150, 151, 153, 154, 155, 157, 158], "excluded_lines": [], "start_line": 139, "executed_branches": [], "missing_branches": [[157, -139], [157, 158]]}, "_build_exclusion_manager": {"executed_lines": [177, 178], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 161, "executed_branches": [], "missing_branches": []}, "_validate_docs_root": {"executed_lines": [194, 195, 196, 197], "summary": {"covered_lines": 4, "num_statements": 7, "percent_covered": 57.142857142857146, "percent_covered_display": "57", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 57.142857142857146, "percent_statements_covered_display": "57", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [198, 199, 204], "excluded_lines": [], "start_line": 187, "executed_branches": [], "missing_branches": []}, "_count_docs_assets": {"executed_lines": [219, 220, 222, 223, 224, 225, 226, 227, 232, 235, 243, 244, 246, 247, 254], "summary": {"covered_lines": 15, "num_statements": 17, "percent_covered": 80.0, "percent_covered_display": "80", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 88.23529411764706, "percent_statements_covered_display": "88", "num_branches": 8, "num_partial_branches": 1, "covered_branches": 5, "missing_branches": 3, "percent_branches_covered": 62.5, "percent_branches_covered_display": "62"}, "missing_lines": [248, 249], "excluded_lines": [], "start_line": 207, "executed_branches": [[225, 226], [225, 227], [243, 244], [243, 254], [247, 254]], "missing_branches": [[247, 248], [248, 249], [248, 254]]}, "check_links": {"executed_lines": [269, 271, 272, 273, 275, 276, 278, 284, 285, 292, 294, 314, 315, 316, 317, 319, 320, 321, 322, 324, 325, 326, 336, 337, 338, 339, 340], "summary": {"covered_lines": 27, "num_statements": 29, "percent_covered": 90.2439024390244, "percent_covered_display": "90", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 93.10344827586206, "percent_statements_covered_display": "93", "num_branches": 12, "num_partial_branches": 2, "covered_branches": 10, "missing_branches": 2, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83"}, "missing_lines": [274, 318], "excluded_lines": [], "start_line": 258, "executed_branches": [[273, 275], [314, 315], [314, 324], [317, 319], [320, 321], [320, 322], [337, 338], [337, 339], [339, -257], [339, 340]], "missing_branches": [[273, 274], [317, 318]]}, "check_links._rel": {"executed_lines": [279, 280], "summary": {"covered_lines": 2, "num_statements": 4, "percent_covered": 50.0, "percent_covered_display": "50", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 50.0, "percent_statements_covered_display": "50", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [281, 282], "excluded_lines": [], "start_line": 278, "executed_branches": [], "missing_branches": []}, "check_orphans": {"executed_lines": [361, 363, 364, 365, 367, 368, 370, 371, 373, 374, 375, 377, 388, 389, 390, 391, 393, 395, 396, 397, 408, 409], "summary": {"covered_lines": 22, "num_statements": 25, "percent_covered": 82.85714285714286, "percent_covered_display": "83", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 88.0, "percent_statements_covered_display": "88", "num_branches": 10, "num_partial_branches": 3, "covered_branches": 7, "missing_branches": 3, "percent_branches_covered": 70.0, "percent_branches_covered_display": "70"}, "missing_lines": [366, 369, 392], "excluded_lines": [], "start_line": 344, "executed_branches": [[365, 367], [368, 370], [388, 389], [388, 395], [391, 393], [408, -343], [408, 409]], "missing_branches": [[365, 366], [368, 369], [391, 392]]}, "check_snippets": {"executed_lines": [420, 422, 423, 424, 426, 427, 429, 435, 436, 437, 439, 440, 441, 442, 449, 460, 461, 462, 463, 465, 467, 468, 469, 479, 480], "summary": {"covered_lines": 25, "num_statements": 33, "percent_covered": 72.34042553191489, "percent_covered_display": "72", "missing_lines": 8, "excluded_lines": 0, "percent_statements_covered": 75.75757575757575, "percent_statements_covered_display": "76", "num_branches": 14, "num_partial_branches": 3, "covered_branches": 9, "missing_branches": 5, "percent_branches_covered": 64.28571428571429, "percent_branches_covered_display": "64"}, "missing_lines": [425, 443, 444, 445, 446, 447, 448, 464], "excluded_lines": [], "start_line": 413, "executed_branches": [[424, 426], [440, 441], [440, 460], [442, 449], [460, 461], [460, 467], [463, 465], [479, -412], [479, 480]], "missing_branches": [[424, 425], [442, 443], [445, 446], [445, 449], [463, 464]]}, "check_snippets._rel": {"executed_lines": [430, 431, 432, 433], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 429, "executed_branches": [], "missing_branches": []}, "check_references": {"executed_lines": [516, 518, 519, 520, 522, 523, 525, 531, 532, 538, 541, 542, 543, 544, 545, 546, 547, 550, 564, 565, 577, 580, 591, 592, 593, 594, 596, 597, 598, 600, 602, 603, 604, 616, 617, 619, 620], "summary": {"covered_lines": 37, "num_statements": 49, "percent_covered": 72.0, "percent_covered_display": "72", "missing_lines": 12, "excluded_lines": 0, "percent_statements_covered": 75.51020408163265, "percent_statements_covered_display": "76", "num_branches": 26, "num_partial_branches": 7, "covered_branches": 17, "missing_branches": 9, "percent_branches_covered": 65.38461538461539, "percent_branches_covered_display": "65"}, "missing_lines": [521, 548, 549, 551, 552, 553, 554, 578, 581, 595, 599, 618], "excluded_lines": [], "start_line": 484, "executed_branches": [[520, 522], [542, 543], [542, 580], [545, 546], [545, 550], [550, 564], [564, 565], [564, 577], [577, 542], [580, 591], [591, 592], [591, 602], [594, 596], [598, 600], [617, 619], [619, -483], [619, 620]], "missing_branches": [[520, 521], [550, 551], [552, 553], [552, 554], [577, 578], [580, 581], [594, 595], [598, 599], [617, 618]]}, "check_references._rel": {"executed_lines": [526, 527, 528, 529], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 525, "executed_branches": [], "missing_branches": []}, "check_assets": {"executed_lines": [631, 633, 634, 635, 637, 638, 640, 641, 642, 644, 655, 656, 657, 658, 660, 662, 663, 664, 675, 676], "summary": {"covered_lines": 20, "num_statements": 22, "percent_covered": 86.66666666666667, "percent_covered_display": "87", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 90.9090909090909, "percent_statements_covered_display": "91", "num_branches": 8, "num_partial_branches": 2, "covered_branches": 6, "missing_branches": 2, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75"}, "missing_lines": [636, 659], "excluded_lines": [], "start_line": 624, "executed_branches": [[635, 637], [655, 656], [655, 662], [658, 660], [675, -623], [675, 676]], "missing_branches": [[635, 636], [658, 659]]}, "clean_assets": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 23, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 23, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 12, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 12, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0"}, "missing_lines": [689, 690, 691, 692, 694, 695, 696, 697, 699, 700, 701, 703, 704, 705, 707, 708, 709, 713, 714, 717, 718, 719, 721], "excluded_lines": [], "start_line": 680, "executed_branches": [], "missing_branches": [[695, 696], [695, 699], [700, 701], [700, 703], [703, 704], [703, 707], [707, 708], [707, 717], [709, 713], [709, 717], [717, 718], [717, 721]]}, "check_placeholders": {"executed_lines": [731, 733, 734, 735, 737, 738, 740, 741, 742, 744, 745, 746, 747, 748, 749, 756, 769, 770, 771, 782, 783], "summary": {"covered_lines": 21, "num_statements": 28, "percent_covered": 70.0, "percent_covered_display": "70", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 75.0, "percent_statements_covered_display": "75", "num_branches": 12, "num_partial_branches": 3, "covered_branches": 7, "missing_branches": 5, "percent_branches_covered": 58.333333333333336, "percent_branches_covered_display": "58"}, "missing_lines": [736, 750, 751, 752, 753, 754, 755], "excluded_lines": [], "start_line": 725, "executed_branches": [[735, 737], [745, 746], [745, 769], [747, 748], [749, 756], [782, -724], [782, 783]], "missing_branches": [[735, 736], [747, 756], [749, 750], [752, 753], [752, 756]]}, "_AllCheckResults.failed": {"executed_lines": [799, 800], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 798, "executed_branches": [], "missing_branches": []}, "_collect_all_results": {"executed_lines": [820, 823, 824, 825, 829, 836, 837], "summary": {"covered_lines": 7, "num_statements": 9, "percent_covered": 72.72727272727273, "percent_covered_display": "73", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 77.77777777777777, "percent_statements_covered_display": "78", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50"}, "missing_lines": [826, 827], "excluded_lines": [], "start_line": 812, "executed_branches": [[825, 829]], "missing_branches": [[825, 826]]}, "_to_findings": {"executed_lines": [861, 863, 869, 870, 889, 890, 900, 901, 902, 909, 920, 921, 922, 923, 924, 925, 926, 927, 928, 931, 944, 945, 955, 966, 967, 969, 970, 971, 972, 975, 976, 977, 979, 989, 1005, 1006, 1008], "summary": {"covered_lines": 37, "num_statements": 50, "percent_covered": 75.0, "percent_covered_display": "75", "missing_lines": 13, "excluded_lines": 0, "percent_statements_covered": 74.0, "percent_statements_covered_display": "74", "num_branches": 34, "num_partial_branches": 6, "covered_branches": 26, "missing_branches": 8, "percent_branches_covered": 76.47058823529412, "percent_branches_covered_display": "76"}, "missing_lines": [903, 904, 905, 906, 907, 908, 929, 930, 956, 973, 974, 978, 990], "excluded_lines": [], "start_line": 859, "executed_branches": [[869, 870], [869, 889], [889, 890], [889, 900], [900, 901], [900, 920], [902, 909], [920, 921], [920, 944], [922, 923], [924, 925], [924, 931], [927, 928], [944, 945], [944, 955], [955, 966], [966, 967], [966, 1008], [970, 971], [970, 975], [975, 976], [975, 989], [977, 979], [989, 1005], [1005, 966], [1005, 1006]], "missing_branches": [[902, 903], [905, 906], [905, 909], [922, 931], [927, 931], [955, 956], [977, 978], [989, 990]]}, "_to_findings._rel": {"executed_lines": [864, 865, 866, 867], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 863, "executed_branches": [], "missing_branches": []}, "_resolve_target": {"executed_lines": [1021, 1022, 1025, 1026, 1027, 1028, 1029, 1035, 1036, 1040], "summary": {"covered_lines": 10, "num_statements": 12, "percent_covered": 85.0, "percent_covered_display": "85", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 83.33333333333333, "percent_statements_covered_display": "83", "num_branches": 8, "num_partial_branches": 1, "covered_branches": 7, "missing_branches": 1, "percent_branches_covered": 87.5, "percent_branches_covered_display": "88"}, "missing_lines": [1030, 1034], "excluded_lines": [], "start_line": 1014, "executed_branches": [[1025, 1026], [1025, 1036], [1026, 1027], [1026, 1028], [1028, 1025], [1028, 1029], [1029, 1035]], "missing_branches": [[1029, 1030]]}, "_apply_target": {"executed_lines": [1060, 1063, 1064, 1065, 1070, 1071, 1072, 1075, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085], "summary": {"covered_lines": 16, "num_statements": 20, "percent_covered": 81.81818181818181, "percent_covered_display": "82", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 80.0, "percent_statements_covered_display": "80", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [1066, 1067, 1073, 1074], "excluded_lines": [], "start_line": 1043, "executed_branches": [[1070, 1071], [1070, 1078]], "missing_branches": []}, "check_all": {"executed_lines": [1145, 1146, 1147, 1149, 1150, 1154, 1155, 1156, 1157, 1159, 1160, 1168, 1169, 1171, 1172, 1179, 1182, 1183, 1184, 1192, 1207, 1208, 1209, 1210, 1213, 1215, 1218, 1219, 1220, 1222, 1224, 1225, 1227, 1229, 1230, 1231, 1245, 1246, 1247, 1250, 1251, 1252, 1257, 1259, 1260, 1261], "summary": {"covered_lines": 46, "num_statements": 55, "percent_covered": 81.17647058823529, "percent_covered_display": "81", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 83.63636363636364, "percent_statements_covered_display": "84", "num_branches": 30, "num_partial_branches": 3, "covered_branches": 23, "missing_branches": 7, "percent_branches_covered": 76.66666666666667, "percent_branches_covered_display": "77"}, "missing_lines": [1148, 1151, 1185, 1186, 1187, 1188, 1189, 1190, 1191], "excluded_lines": [], "start_line": 1089, "executed_branches": [[1147, 1149], [1150, 1154], [1156, 1157], [1156, 1159], [1182, 1183], [1182, 1213], [1184, 1192], [1208, 1209], [1208, 1210], [1218, 1219], [1218, 1222], [1224, 1225], [1224, 1227], [1229, 1230], [1229, 1231], [1246, 1247], [1246, 1250], [1251, 1252], [1251, 1257], [1259, -1088], [1259, 1260], [1260, -1088], [1260, 1261]], "missing_branches": [[1147, 1148], [1150, 1151], [1184, 1185], [1185, 1184], [1185, 1186], [1186, 1185], [1186, 1187]]}, "plugins_list": {"executed_lines": [1276, 1278, 1279, 1280, 1281, 1284, 1286, 1287, 1288, 1291, 1297], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1265, "executed_branches": [[1279, 1280], [1279, 1286], [1287, 1288], [1287, 1297]], "missing_branches": []}, "_run_all_checks": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 6, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [1308, 1315, 1316, 1317, 1318, 1320], "excluded_lines": [], "start_line": 1300, "executed_branches": [], "missing_branches": []}, "score": {"executed_lines": [1343, 1344, 1345, 1346, 1347, 1348, 1351, 1353, 1354, 1355, 1356, 1358, 1359, 1362, 1363, 1364, 1365, 1369, 1370, 1371, 1372, 1374, 1375, 1385, 1387, 1396, 1397, 1398, 1399, 1400, 1402, 1403, 1404, 1405, 1407, 1408, 1409, 1417, 1419, 1420, 1423], "summary": {"covered_lines": 41, "num_statements": 42, "percent_covered": 96.42857142857143, "percent_covered_display": "96", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 97.61904761904762, "percent_statements_covered_display": "98", "num_branches": 14, "num_partial_branches": 1, "covered_branches": 13, "missing_branches": 1, "percent_branches_covered": 92.85714285714286, "percent_branches_covered_display": "93"}, "missing_lines": [1367], "excluded_lines": [], "start_line": 1329, "executed_branches": [[1353, 1354], [1353, 1358], [1358, 1359], [1358, 1362], [1362, 1363], [1362, 1364], [1364, 1365], [1402, 1403], [1402, 1417], [1403, 1404], [1403, 1407], [1419, -1329], [1419, 1420]], "missing_branches": [[1364, 1367]]}, "diff": {"executed_lines": [1445, 1446, 1447, 1448, 1449, 1451, 1452, 1453, 1457, 1459, 1460, 1462, 1463, 1485, 1486, 1487, 1488, 1489, 1490, 1491, 1492, 1493, 1494, 1495, 1496, 1497, 1502, 1503, 1504, 1507], "summary": {"covered_lines": 30, "num_statements": 30, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 8, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1426, "executed_branches": [[1452, 1453], [1452, 1459], [1462, 1463], [1462, 1485], [1491, 1492], [1491, 1502], [1503, -1426], [1503, 1504]], "missing_branches": []}, "init": {"executed_lines": [1541, 1543, 1544, 1545, 1548, 1549, 1551, 1553, 1558, 1559, 1561], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 6, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1510, "executed_branches": [[1543, 1544], [1543, 1548], [1551, 1553], [1551, 1558], [1558, 1559], [1558, 1561]], "missing_branches": []}, "_detect_init_engine": {"executed_lines": [1566, 1567, 1568, 1570], "summary": {"covered_lines": 4, "num_statements": 5, "percent_covered": 77.77777777777777, "percent_covered_display": "78", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 80.0, "percent_statements_covered_display": "80", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 1, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75"}, "missing_lines": [1569], "excluded_lines": [], "start_line": 1564, "executed_branches": [[1566, 1567], [1566, 1568], [1568, 1570]], "missing_branches": [[1568, 1569]]}, "_engine_feedback": {"executed_lines": [1575, 1576, 1577, 1578], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1573, "executed_branches": [[1575, 1576], [1575, 1578]], "missing_branches": []}, "_init_standalone": {"executed_lines": [1583, 1585, 1586, 1591, 1593, 1595, 1596, 1597, 1599, 1624, 1626], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1581, "executed_branches": [[1585, 1586], [1585, 1593], [1596, 1597], [1596, 1599]], "missing_branches": []}, "_init_pyproject": {"executed_lines": [1636, 1637, 1642, 1644, 1646, 1647, 1652, 1654, 1656, 1657, 1658, 1660, 1667, 1668, 1670, 1672, 1678, 1680], "summary": {"covered_lines": 18, "num_statements": 18, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 10, "num_partial_branches": 0, "covered_branches": 10, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1634, "executed_branches": [[1636, 1637], [1636, 1644], [1646, 1647], [1646, 1654], [1657, 1658], [1657, 1660], [1667, 1668], [1667, 1670], [1670, 1672], [1670, 1678]], "missing_branches": []}, "_scaffold_plugin": {"executed_lines": [1694, 1695, 1699, 1700, 1701, 1707, 1708, 1709, 1710, 1712, 1713, 1714, 1718, 1720, 1721, 1722, 1723, 1725, 1744, 1775, 1794, 1802, 1803, 1804, 1808, 1812, 1813, 1815], "summary": {"covered_lines": 28, "num_statements": 32, "percent_covered": 84.21052631578948, "percent_covered_display": "84", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 87.5, "percent_statements_covered_display": "88", "num_branches": 6, "num_partial_branches": 2, "covered_branches": 4, "missing_branches": 2, "percent_branches_covered": 66.66666666666667, "percent_branches_covered_display": "67"}, "missing_lines": [1696, 1697, 1702, 1705], "excluded_lines": [], "start_line": 1688, "executed_branches": [[1695, 1699], [1701, 1707], [1713, 1714], [1713, 1720]], "missing_branches": [[1695, 1696], [1701, 1702]]}, "": {"executed_lines": [5, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19, 21, 22, 23, 24, 33, 34, 42, 43, 44, 47, 54, 61, 68, 73, 83, 89, 114, 139, 161, 187, 207, 257, 258, 343, 344, 412, 413, 483, 484, 623, 624, 679, 680, 724, 725, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 797, 798, 812, 859, 1014, 1043, 1088, 1089, 1264, 1265, 1300, 1329, 1426, 1510, 1564, 1573, 1581, 1634, 1688], "summary": {"covered_lines": 77, "num_statements": 77, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"_AllCheckResults": {"executed_lines": [799, 800], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 787, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [5, 7, 8, 9, 10, 11, 12, 14, 15, 16, 17, 18, 19, 21, 22, 23, 24, 33, 34, 42, 43, 44, 47, 54, 61, 68, 73, 83, 89, 96, 97, 114, 116, 136, 139, 161, 177, 178, 187, 194, 195, 196, 197, 207, 219, 220, 222, 223, 224, 225, 226, 227, 232, 235, 243, 244, 246, 247, 254, 257, 258, 269, 271, 272, 273, 275, 276, 278, 279, 280, 284, 285, 292, 294, 314, 315, 316, 317, 319, 320, 321, 322, 324, 325, 326, 336, 337, 338, 339, 340, 343, 344, 361, 363, 364, 365, 367, 368, 370, 371, 373, 374, 375, 377, 388, 389, 390, 391, 393, 395, 396, 397, 408, 409, 412, 413, 420, 422, 423, 424, 426, 427, 429, 430, 431, 432, 433, 435, 436, 437, 439, 440, 441, 442, 449, 460, 461, 462, 463, 465, 467, 468, 469, 479, 480, 483, 484, 516, 518, 519, 520, 522, 523, 525, 526, 527, 528, 529, 531, 532, 538, 541, 542, 543, 544, 545, 546, 547, 550, 564, 565, 577, 580, 591, 592, 593, 594, 596, 597, 598, 600, 602, 603, 604, 616, 617, 619, 620, 623, 624, 631, 633, 634, 635, 637, 638, 640, 641, 642, 644, 655, 656, 657, 658, 660, 662, 663, 664, 675, 676, 679, 680, 724, 725, 731, 733, 734, 735, 737, 738, 740, 741, 742, 744, 745, 746, 747, 748, 749, 756, 769, 770, 771, 782, 783, 786, 787, 788, 789, 790, 791, 792, 793, 794, 795, 797, 798, 812, 820, 823, 824, 825, 829, 836, 837, 859, 861, 863, 864, 865, 866, 867, 869, 870, 889, 890, 900, 901, 902, 909, 920, 921, 922, 923, 924, 925, 926, 927, 928, 931, 944, 945, 955, 966, 967, 969, 970, 971, 972, 975, 976, 977, 979, 989, 1005, 1006, 1008, 1014, 1021, 1022, 1025, 1026, 1027, 1028, 1029, 1035, 1036, 1040, 1043, 1060, 1063, 1064, 1065, 1070, 1071, 1072, 1075, 1078, 1079, 1080, 1081, 1082, 1083, 1084, 1085, 1088, 1089, 1145, 1146, 1147, 1149, 1150, 1154, 1155, 1156, 1157, 1159, 1160, 1168, 1169, 1171, 1172, 1179, 1182, 1183, 1184, 1192, 1207, 1208, 1209, 1210, 1213, 1215, 1218, 1219, 1220, 1222, 1224, 1225, 1227, 1229, 1230, 1231, 1245, 1246, 1247, 1250, 1251, 1252, 1257, 1259, 1260, 1261, 1264, 1265, 1276, 1278, 1279, 1280, 1281, 1284, 1286, 1287, 1288, 1291, 1297, 1300, 1329, 1343, 1344, 1345, 1346, 1347, 1348, 1351, 1353, 1354, 1355, 1356, 1358, 1359, 1362, 1363, 1364, 1365, 1369, 1370, 1371, 1372, 1374, 1375, 1385, 1387, 1396, 1397, 1398, 1399, 1400, 1402, 1403, 1404, 1405, 1407, 1408, 1409, 1417, 1419, 1420, 1423, 1426, 1445, 1446, 1447, 1448, 1449, 1451, 1452, 1453, 1457, 1459, 1460, 1462, 1463, 1485, 1486, 1487, 1488, 1489, 1490, 1491, 1492, 1493, 1494, 1495, 1496, 1497, 1502, 1503, 1504, 1507, 1510, 1541, 1543, 1544, 1545, 1548, 1549, 1551, 1553, 1558, 1559, 1561, 1564, 1566, 1567, 1568, 1570, 1573, 1575, 1576, 1577, 1578, 1581, 1583, 1585, 1586, 1591, 1593, 1595, 1596, 1597, 1599, 1624, 1626, 1634, 1636, 1637, 1642, 1644, 1646, 1647, 1652, 1654, 1656, 1657, 1658, 1660, 1667, 1668, 1670, 1672, 1678, 1680, 1688, 1694, 1695, 1699, 1700, 1701, 1707, 1708, 1709, 1710, 1712, 1713, 1714, 1718, 1720, 1721, 1722, 1723, 1725, 1744, 1775, 1794, 1802, 1803, 1804, 1808, 1812, 1813, 1815], "summary": {"covered_lines": 542, "num_statements": 674, "percent_covered": 78.10457516339869, "percent_covered_display": "78", "missing_lines": 132, "excluded_lines": 0, "percent_statements_covered": 80.41543026706232, "percent_statements_covered_display": "80", "num_branches": 244, "num_partial_branches": 37, "covered_branches": 175, "missing_branches": 69, "percent_branches_covered": 71.72131147540983, "percent_branches_covered_display": "72"}, "missing_lines": [85, 86, 98, 99, 100, 101, 102, 103, 104, 105, 109, 110, 111, 141, 142, 143, 144, 145, 149, 150, 151, 153, 154, 155, 157, 158, 198, 199, 204, 248, 249, 274, 281, 282, 318, 366, 369, 392, 425, 443, 444, 445, 446, 447, 448, 464, 521, 548, 549, 551, 552, 553, 554, 578, 581, 595, 599, 618, 636, 659, 689, 690, 691, 692, 694, 695, 696, 697, 699, 700, 701, 703, 704, 705, 707, 708, 709, 713, 714, 717, 718, 719, 721, 736, 750, 751, 752, 753, 754, 755, 826, 827, 903, 904, 905, 906, 907, 908, 929, 930, 956, 973, 974, 978, 990, 1030, 1034, 1066, 1067, 1073, 1074, 1148, 1151, 1185, 1186, 1187, 1188, 1189, 1190, 1191, 1308, 1315, 1316, 1317, 1318, 1320, 1367, 1569, 1696, 1697, 1702, 1705], "excluded_lines": [], "start_line": 1, "executed_branches": [[96, 97], [225, 226], [225, 227], [243, 244], [243, 254], [247, 254], [273, 275], [314, 315], [314, 324], [317, 319], [320, 321], [320, 322], [337, 338], [337, 339], [339, -257], [339, 340], [365, 367], [368, 370], [388, 389], [388, 395], [391, 393], [408, -343], [408, 409], [424, 426], [440, 441], [440, 460], [442, 449], [460, 461], [460, 467], [463, 465], [479, -412], [479, 480], [520, 522], [542, 543], [542, 580], [545, 546], [545, 550], [550, 564], [564, 565], [564, 577], [577, 542], [580, 591], [591, 592], [591, 602], [594, 596], [598, 600], [617, 619], [619, -483], [619, 620], [635, 637], [655, 656], [655, 662], [658, 660], [675, -623], [675, 676], [735, 737], [745, 746], [745, 769], [747, 748], [749, 756], [782, -724], [782, 783], [825, 829], [869, 870], [869, 889], [889, 890], [889, 900], [900, 901], [900, 920], [902, 909], [920, 921], [920, 944], [922, 923], [924, 925], [924, 931], [927, 928], [944, 945], [944, 955], [955, 966], [966, 967], [966, 1008], [970, 971], [970, 975], [975, 976], [975, 989], [977, 979], [989, 1005], [1005, 966], [1005, 1006], [1025, 1026], [1025, 1036], [1026, 1027], [1026, 1028], [1028, 1025], [1028, 1029], [1029, 1035], [1070, 1071], [1070, 1078], [1147, 1149], [1150, 1154], [1156, 1157], [1156, 1159], [1182, 1183], [1182, 1213], [1184, 1192], [1208, 1209], [1208, 1210], [1218, 1219], [1218, 1222], [1224, 1225], [1224, 1227], [1229, 1230], [1229, 1231], [1246, 1247], [1246, 1250], [1251, 1252], [1251, 1257], [1259, -1088], [1259, 1260], [1260, -1088], [1260, 1261], [1279, 1280], [1279, 1286], [1287, 1288], [1287, 1297], [1353, 1354], [1353, 1358], [1358, 1359], [1358, 1362], [1362, 1363], [1362, 1364], [1364, 1365], [1402, 1403], [1402, 1417], [1403, 1404], [1403, 1407], [1419, -1329], [1419, 1420], [1452, 1453], [1452, 1459], [1462, 1463], [1462, 1485], [1491, 1492], [1491, 1502], [1503, -1426], [1503, 1504], [1543, 1544], [1543, 1548], [1551, 1553], [1551, 1558], [1558, 1559], [1558, 1561], [1566, 1567], [1566, 1568], [1568, 1570], [1575, 1576], [1575, 1578], [1585, 1586], [1585, 1593], [1596, 1597], [1596, 1599], [1636, 1637], [1636, 1644], [1646, 1647], [1646, 1654], [1657, 1658], [1657, 1660], [1667, 1668], [1667, 1670], [1670, 1672], [1670, 1678], [1695, 1699], [1701, 1707], [1713, 1714], [1713, 1720]], "missing_branches": [[96, 98], [99, 100], [99, 110], [103, 104], [103, 105], [157, -139], [157, 158], [247, 248], [248, 249], [248, 254], [273, 274], [317, 318], [365, 366], [368, 369], [391, 392], [424, 425], [442, 443], [445, 446], [445, 449], [463, 464], [520, 521], [550, 551], [552, 553], [552, 554], [577, 578], [580, 581], [594, 595], [598, 599], [617, 618], [635, 636], [658, 659], [695, 696], [695, 699], [700, 701], [700, 703], [703, 704], [703, 707], [707, 708], [707, 717], [709, 713], [709, 717], [717, 718], [717, 721], [735, 736], [747, 756], [749, 750], [752, 753], [752, 756], [825, 826], [902, 903], [905, 906], [905, 909], [922, 931], [927, 931], [955, 956], [977, 978], [989, 990], [1029, 1030], [1147, 1148], [1150, 1151], [1184, 1185], [1185, 1184], [1185, 1186], [1186, 1185], [1186, 1187], [1364, 1367], [1568, 1569], [1695, 1696], [1701, 1702]]}}}, "src/zenzic/core/__init__.py": {"executed_lines": [10, 20], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"": {"executed_lines": [10, 20], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [10, 20], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "src/zenzic/core/adapter.py": {"executed_lines": [9, 10], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"": {"executed_lines": [9, 10], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [9, 10], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "src/zenzic/core/adapters/__init__.py": {"executed_lines": [29, 31, 32, 41, 42, 53, 54, 57], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"": {"executed_lines": [29, 31, 32, 41, 42, 53, 54, 57], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [29, 31, 32, 41, 42, 53, 54, 57], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "src/zenzic/core/adapters/_base.py": {"executed_lines": [18, 20, 21, 22, 32, 33, 58, 59, 60, 61, 62, 63, 69, 70, 77, 81, 85, 115, 119, 123, 127, 136, 152, 171], "summary": {"covered_lines": 24, "num_statements": 24, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 12, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [25, 26, 79, 83, 113, 117, 121, 125, 134, 150, 169, 195], "executed_branches": [], "missing_branches": [], "functions": {"BaseAdapter.is_locale_dir": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 1, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [79], "start_line": 77, "executed_branches": [], "missing_branches": []}, "BaseAdapter.resolve_asset": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 1, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [83], "start_line": 81, "executed_branches": [], "missing_branches": []}, "BaseAdapter.resolve_anchor": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 1, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [113], "start_line": 85, "executed_branches": [], "missing_branches": []}, "BaseAdapter.is_shadow_of_nav_page": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 1, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [117], "start_line": 115, "executed_branches": [], "missing_branches": []}, "BaseAdapter.get_ignored_patterns": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 1, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [121], "start_line": 119, "executed_branches": [], "missing_branches": []}, "BaseAdapter.get_nav_paths": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 1, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [125], "start_line": 123, "executed_branches": [], "missing_branches": []}, "BaseAdapter.has_engine_config": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 1, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [134], "start_line": 127, "executed_branches": [], "missing_branches": []}, "BaseAdapter.map_url": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 1, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [150], "start_line": 136, "executed_branches": [], "missing_branches": []}, "BaseAdapter.classify_route": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 1, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [169], "start_line": 152, "executed_branches": [], "missing_branches": []}, "BaseAdapter.get_route_info": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 1, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [195], "start_line": 171, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [18, 20, 21, 22, 32, 33, 58, 59, 60, 61, 62, 63, 69, 70, 77, 81, 85, 115, 119, 123, 127, 136, 152, 171], "summary": {"covered_lines": 24, "num_statements": 24, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 2, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [25, 26], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"RouteMetadata": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 33, "executed_branches": [], "missing_branches": []}, "BaseAdapter": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 10, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [79, 83, 113, 117, 121, 125, 134, 150, 169, 195], "start_line": 70, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [18, 20, 21, 22, 32, 33, 58, 59, 60, 61, 62, 63, 69, 70, 77, 81, 85, 115, 119, 123, 127, 136, 152, 171], "summary": {"covered_lines": 24, "num_statements": 24, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 2, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [25, 26], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "src/zenzic/core/adapters/_docusaurus.py": {"executed_lines": [32, 34, 35, 36, 37, 39, 40, 47, 53, 62, 65, 66, 67, 68, 69, 70, 71, 73, 80, 90, 92, 98, 104, 105, 106, 107, 108, 116, 118, 121, 140, 141, 142, 143, 145, 147, 148, 154, 156, 157, 160, 176, 177, 178, 179, 181, 183, 184, 186, 187, 188, 189, 194, 195, 198, 210, 211, 212, 213, 214, 215, 216, 222, 251, 259, 260, 261, 265, 269, 270, 275, 276, 279, 281, 290, 291, 292, 293, 296, 297, 298, 299, 303, 305, 307, 309, 310, 311, 312, 314, 327, 328, 329, 330, 332, 334, 340, 343, 344, 345, 347, 355, 363, 365, 371, 408, 411, 412, 413, 415, 416, 418, 419, 420, 421, 425, 426, 430, 432, 433, 434, 436, 437, 443, 444, 446, 447, 448, 450, 451, 453, 455, 458, 460, 461, 464, 467, 468, 471, 497, 498, 499, 505, 509, 510, 513, 514, 518, 522, 523, 524, 525, 528, 530, 543, 545, 546, 548, 549, 550, 553, 554, 555, 556, 557, 560, 561, 564, 575, 576, 598, 599, 601, 602, 604, 606, 608, 609, 610, 618, 619, 621], "summary": {"covered_lines": 182, "num_statements": 220, "percent_covered": 77.9874213836478, "percent_covered_display": "78", "missing_lines": 38, "excluded_lines": 7, "percent_statements_covered": 82.72727272727273, "percent_statements_covered_display": "83", "num_branches": 98, "num_partial_branches": 16, "covered_branches": 66, "missing_branches": 32, "percent_branches_covered": 67.34693877551021, "percent_branches_covered_display": "67"}, "missing_lines": [294, 295, 331, 353, 367, 428, 438, 439, 440, 456, 462, 465, 469, 506, 515, 519, 562, 600, 611, 612, 613, 614, 615, 616, 640, 641, 642, 643, 644, 646, 648, 649, 650, 653, 654, 661, 662, 664], "excluded_lines": [43, 44, 45, 122, 266, 504, 559], "executed_branches": [[67, 68], [67, 69], [69, 70], [69, 71], [104, 105], [104, 108], [106, 104], [106, 107], [147, 148], [147, 156], [183, 184], [183, 186], [187, 188], [187, 189], [211, 212], [211, 213], [214, 215], [214, 216], [291, 292], [291, 299], [297, 291], [297, 298], [309, 310], [309, 311], [327, 328], [327, 329], [330, 332], [343, 344], [343, 345], [412, 413], [412, 425], [413, 415], [413, 418], [419, 420], [419, 421], [426, 430], [433, 434], [433, 436], [437, 443], [443, 444], [443, 446], [447, 448], [447, 450], [451, 453], [455, 458], [461, 464], [464, 467], [467, 468], [498, 499], [498, 505], [505, 509], [509, 510], [509, 513], [514, 518], [518, 522], [522, 523], [522, 528], [524, 525], [554, 555], [554, 560], [556, 557], [561, 564], [599, 601], [601, 602], [601, 604], [610, 618]], "missing_branches": [[330, 331], [426, 428], [437, 438], [439, 440], [439, 443], [451, 455], [455, 456], [461, 462], [464, 465], [467, 469], [505, 506], [514, 515], [518, 519], [524, 528], [556, 560], [561, 562], [599, 600], [610, 611], [613, 614], [613, 618], [641, 642], [641, 646], [643, 641], [643, 644], [646, 648], [646, 664], [649, 650], [649, 653], [653, 646], [653, 654], [661, 653], [661, 662]], "functions": {"_strip_js_comments": {"executed_lines": [65, 73], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 62, "executed_branches": [], "missing_branches": []}, "_strip_js_comments._replacer": {"executed_lines": [66, 67, 68, 69, 70, 71], "summary": {"covered_lines": 6, "num_statements": 6, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 65, "executed_branches": [[67, 68], [67, 69], [69, 70], [69, 71]], "missing_branches": []}, "_is_dynamic_config": {"executed_lines": [92], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 90, "executed_branches": [], "missing_branches": []}, "find_docusaurus_config": {"executed_lines": [104, 105, 106, 107, 108], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 98, "executed_branches": [[104, 105], [104, 108], [106, 104], [106, 107]], "missing_branches": []}, "_extract_base_url": {"executed_lines": [140, 141, 142, 143, 145, 147, 148, 154, 156, 157], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 1, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [122], "start_line": 121, "executed_branches": [[147, 148], [147, 156]], "missing_branches": []}, "_extract_route_base_path": {"executed_lines": [176, 177, 178, 179, 181, 183, 184, 186, 187, 188, 189], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 160, "executed_branches": [[183, 184], [183, 186], [187, 188], [187, 189]], "missing_branches": []}, "_extract_frontmatter_slug": {"executed_lines": [210, 211, 212, 213, 214, 215, 216], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 198, "executed_branches": [[211, 212], [211, 213], [214, 215], [214, 216]], "missing_branches": []}, "DocusaurusAdapter.__init__": {"executed_lines": [259, 260, 261, 265, 269, 270, 275, 276, 279], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 1, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [266], "start_line": 251, "executed_branches": [], "missing_branches": []}, "DocusaurusAdapter.set_slug_map": {"executed_lines": [290, 291, 292, 293, 296, 297, 298, 299], "summary": {"covered_lines": 8, "num_statements": 10, "percent_covered": 85.71428571428571, "percent_covered_display": "86", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 80.0, "percent_statements_covered_display": "80", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [294, 295], "excluded_lines": [], "start_line": 281, "executed_branches": [[291, 292], [291, 299], [297, 291], [297, 298]], "missing_branches": []}, "DocusaurusAdapter.is_locale_dir": {"executed_lines": [305], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 303, "executed_branches": [], "missing_branches": []}, "DocusaurusAdapter.resolve_asset": {"executed_lines": [309, 310, 311, 312], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 307, "executed_branches": [[309, 310], [309, 311]], "missing_branches": []}, "DocusaurusAdapter.resolve_anchor": {"executed_lines": [327, 328, 329, 330, 332], "summary": {"covered_lines": 5, "num_statements": 6, "percent_covered": 80.0, "percent_covered_display": "80", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 83.33333333333333, "percent_statements_covered_display": "83", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 1, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75"}, "missing_lines": [331], "excluded_lines": [], "start_line": 314, "executed_branches": [[327, 328], [327, 329], [330, 332]], "missing_branches": [[330, 331]]}, "DocusaurusAdapter.is_shadow_of_nav_page": {"executed_lines": [340, 343, 344, 345], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 334, "executed_branches": [[343, 344], [343, 345]], "missing_branches": []}, "DocusaurusAdapter.get_ignored_patterns": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [353], "excluded_lines": [], "start_line": 347, "executed_branches": [], "missing_branches": []}, "DocusaurusAdapter.get_nav_paths": {"executed_lines": [363], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 355, "executed_branches": [], "missing_branches": []}, "DocusaurusAdapter.has_engine_config": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [367], "excluded_lines": [], "start_line": 365, "executed_branches": [], "missing_branches": []}, "DocusaurusAdapter.map_url": {"executed_lines": [408, 411, 412, 413, 415, 416, 418, 419, 420, 421, 425, 426, 430, 432, 433, 434, 436, 437, 443, 444, 446, 447, 448, 450, 451, 453, 455, 458, 460, 461, 464, 467, 468], "summary": {"covered_lines": 33, "num_statements": 41, "percent_covered": 75.3623188405797, "percent_covered_display": "75", "missing_lines": 8, "excluded_lines": 0, "percent_statements_covered": 80.48780487804878, "percent_statements_covered_display": "80", "num_branches": 28, "num_partial_branches": 7, "covered_branches": 19, "missing_branches": 9, "percent_branches_covered": 67.85714285714286, "percent_branches_covered_display": "68"}, "missing_lines": [428, 438, 439, 440, 456, 462, 465, 469], "excluded_lines": [], "start_line": 371, "executed_branches": [[412, 413], [412, 425], [413, 415], [413, 418], [419, 420], [419, 421], [426, 430], [433, 434], [433, 436], [437, 443], [443, 444], [443, 446], [447, 448], [447, 450], [451, 453], [455, 458], [461, 464], [464, 467], [467, 468]], "missing_branches": [[426, 428], [437, 438], [439, 440], [439, 443], [451, 455], [455, 456], [461, 462], [464, 465], [467, 469]]}, "DocusaurusAdapter.classify_route": {"executed_lines": [497, 498, 499, 505, 509, 510, 513, 514, 518, 522, 523, 524, 525, 528], "summary": {"covered_lines": 14, "num_statements": 17, "percent_covered": 77.41935483870968, "percent_covered_display": "77", "missing_lines": 3, "excluded_lines": 1, "percent_statements_covered": 82.3529411764706, "percent_statements_covered_display": "82", "num_branches": 14, "num_partial_branches": 4, "covered_branches": 10, "missing_branches": 4, "percent_branches_covered": 71.42857142857143, "percent_branches_covered_display": "71"}, "missing_lines": [506, 515, 519], "excluded_lines": [504], "start_line": 471, "executed_branches": [[498, 499], [498, 505], [505, 509], [509, 510], [509, 513], [514, 518], [518, 522], [522, 523], [522, 528], [524, 525]], "missing_branches": [[505, 506], [514, 515], [518, 519], [524, 528]]}, "DocusaurusAdapter.get_route_info": {"executed_lines": [543, 545, 546, 548, 549, 550, 553, 554, 555, 556, 557, 560, 561, 564], "summary": {"covered_lines": 14, "num_statements": 15, "percent_covered": 85.71428571428571, "percent_covered_display": "86", "missing_lines": 1, "excluded_lines": 1, "percent_statements_covered": 93.33333333333333, "percent_statements_covered_display": "93", "num_branches": 6, "num_partial_branches": 2, "covered_branches": 4, "missing_branches": 2, "percent_branches_covered": 66.66666666666667, "percent_branches_covered_display": "67"}, "missing_lines": [562], "excluded_lines": [559], "start_line": 530, "executed_branches": [[554, 555], [554, 560], [556, 557], [561, 564]], "missing_branches": [[556, 560], [561, 562]]}, "DocusaurusAdapter.from_repo": {"executed_lines": [598, 599, 601, 602, 604, 606, 608, 609, 610, 618, 619], "summary": {"covered_lines": 11, "num_statements": 18, "percent_covered": 57.69230769230769, "percent_covered_display": "58", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 61.111111111111114, "percent_statements_covered_display": "61", "num_branches": 8, "num_partial_branches": 2, "covered_branches": 4, "missing_branches": 4, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50"}, "missing_lines": [600, 611, 612, 613, 614, 615, 616], "excluded_lines": [], "start_line": 576, "executed_branches": [[599, 601], [601, 602], [601, 604], [610, 618]], "missing_branches": [[599, 600], [610, 611], [613, 614], [613, 618]]}, "DocusaurusAdapter.get_locale_source_roots": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 14, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 14, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 12, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 12, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0"}, "missing_lines": [640, 641, 642, 643, 644, 646, 648, 649, 650, 653, 654, 661, 662, 664], "excluded_lines": [], "start_line": 621, "executed_branches": [], "missing_branches": [[641, 642], [641, 646], [643, 641], [643, 644], [646, 648], [646, 664], [649, 650], [649, 653], [653, 646], [653, 654], [661, 653], [661, 662]]}, "": {"executed_lines": [32, 34, 35, 36, 37, 39, 40, 47, 53, 62, 80, 90, 98, 116, 118, 121, 160, 194, 195, 198, 222, 251, 281, 303, 307, 314, 334, 347, 355, 365, 371, 471, 530, 575, 576, 621], "summary": {"covered_lines": 36, "num_statements": 36, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 3, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [43, 44, 45], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"DocusaurusAdapter": {"executed_lines": [259, 260, 261, 265, 269, 270, 275, 276, 279, 290, 291, 292, 293, 296, 297, 298, 299, 305, 309, 310, 311, 312, 327, 328, 329, 330, 332, 340, 343, 344, 345, 363, 408, 411, 412, 413, 415, 416, 418, 419, 420, 421, 425, 426, 430, 432, 433, 434, 436, 437, 443, 444, 446, 447, 448, 450, 451, 453, 455, 458, 460, 461, 464, 467, 468, 497, 498, 499, 505, 509, 510, 513, 514, 518, 522, 523, 524, 525, 528, 543, 545, 546, 548, 549, 550, 553, 554, 555, 556, 557, 560, 561, 564, 598, 599, 601, 602, 604, 606, 608, 609, 610, 618, 619], "summary": {"covered_lines": 104, "num_statements": 142, "percent_covered": 68.46846846846847, "percent_covered_display": "68", "missing_lines": 38, "excluded_lines": 3, "percent_statements_covered": 73.2394366197183, "percent_statements_covered_display": "73", "num_branches": 80, "num_partial_branches": 16, "covered_branches": 48, "missing_branches": 32, "percent_branches_covered": 60.0, "percent_branches_covered_display": "60"}, "missing_lines": [294, 295, 331, 353, 367, 428, 438, 439, 440, 456, 462, 465, 469, 506, 515, 519, 562, 600, 611, 612, 613, 614, 615, 616, 640, 641, 642, 643, 644, 646, 648, 649, 650, 653, 654, 661, 662, 664], "excluded_lines": [266, 504, 559], "start_line": 222, "executed_branches": [[291, 292], [291, 299], [297, 291], [297, 298], [309, 310], [309, 311], [327, 328], [327, 329], [330, 332], [343, 344], [343, 345], [412, 413], [412, 425], [413, 415], [413, 418], [419, 420], [419, 421], [426, 430], [433, 434], [433, 436], [437, 443], [443, 444], [443, 446], [447, 448], [447, 450], [451, 453], [455, 458], [461, 464], [464, 467], [467, 468], [498, 499], [498, 505], [505, 509], [509, 510], [509, 513], [514, 518], [518, 522], [522, 523], [522, 528], [524, 525], [554, 555], [554, 560], [556, 557], [561, 564], [599, 601], [601, 602], [601, 604], [610, 618]], "missing_branches": [[330, 331], [426, 428], [437, 438], [439, 440], [439, 443], [451, 455], [455, 456], [461, 462], [464, 465], [467, 469], [505, 506], [514, 515], [518, 519], [524, 528], [556, 560], [561, 562], [599, 600], [610, 611], [613, 614], [613, 618], [641, 642], [641, 646], [643, 641], [643, 644], [646, 648], [646, 664], [649, 650], [649, 653], [653, 646], [653, 654], [661, 653], [661, 662]]}, "": {"executed_lines": [32, 34, 35, 36, 37, 39, 40, 47, 53, 62, 65, 66, 67, 68, 69, 70, 71, 73, 80, 90, 92, 98, 104, 105, 106, 107, 108, 116, 118, 121, 140, 141, 142, 143, 145, 147, 148, 154, 156, 157, 160, 176, 177, 178, 179, 181, 183, 184, 186, 187, 188, 189, 194, 195, 198, 210, 211, 212, 213, 214, 215, 216, 222, 251, 281, 303, 307, 314, 334, 347, 355, 365, 371, 471, 530, 575, 576, 621], "summary": {"covered_lines": 78, "num_statements": 78, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 4, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 18, "num_partial_branches": 0, "covered_branches": 18, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [43, 44, 45, 122], "start_line": 1, "executed_branches": [[67, 68], [67, 69], [69, 70], [69, 71], [104, 105], [104, 108], [106, 104], [106, 107], [147, 148], [147, 156], [183, 184], [183, 186], [187, 188], [187, 189], [211, 212], [211, 213], [214, 215], [214, 216]], "missing_branches": []}}}, "src/zenzic/core/adapters/_factory.py": {"executed_lines": [33, 35, 36, 37, 38, 40, 42, 43, 44, 45, 51, 59, 66, 67, 68, 69, 70, 73, 86, 87, 90, 100, 138, 140, 141, 143, 145, 146, 147, 149, 155, 156, 158, 159, 160, 163, 168, 169, 171, 175, 177, 178, 179], "summary": {"covered_lines": 43, "num_statements": 49, "percent_covered": 86.95652173913044, "percent_covered_display": "87", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 87.75510204081633, "percent_statements_covered_display": "88", "num_branches": 20, "num_partial_branches": 3, "covered_branches": 17, "missing_branches": 3, "percent_branches_covered": 85.0, "percent_branches_covered_display": "85"}, "missing_lines": [75, 76, 96, 97, 151, 164], "excluded_lines": [], "executed_branches": [[67, 68], [67, 70], [68, 67], [68, 69], [140, 141], [140, 143], [145, 146], [145, 147], [147, 149], [155, 156], [155, 158], [159, 160], [159, 163], [163, 168], [168, 169], [168, 175], [177, 178]], "missing_branches": [[147, 151], [163, 164], [177, 179]], "functions": {"_load_adapter_class": {"executed_lines": [66, 67, 68, 69, 70], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 59, "executed_branches": [[67, 68], [67, 70], [68, 67], [68, 69]], "missing_branches": []}, "list_adapter_engines": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 2, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [75, 76], "excluded_lines": [], "start_line": 73, "executed_branches": [], "missing_branches": []}, "clear_adapter_cache": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 2, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [96, 97], "excluded_lines": [], "start_line": 90, "executed_branches": [], "missing_branches": []}, "get_adapter": {"executed_lines": [138, 140, 141, 143, 145, 146, 147, 149, 155, 156, 158, 159, 160, 163, 168, 169, 171, 175, 177, 178, 179], "summary": {"covered_lines": 21, "num_statements": 23, "percent_covered": 87.17948717948718, "percent_covered_display": "87", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 91.30434782608695, "percent_statements_covered_display": "91", "num_branches": 16, "num_partial_branches": 3, "covered_branches": 13, "missing_branches": 3, "percent_branches_covered": 81.25, "percent_branches_covered_display": "81"}, "missing_lines": [151, 164], "excluded_lines": [], "start_line": 100, "executed_branches": [[140, 141], [140, 143], [145, 146], [145, 147], [147, 149], [155, 156], [155, 158], [159, 160], [159, 163], [163, 168], [168, 169], [168, 175], [177, 178]], "missing_branches": [[147, 151], [163, 164], [177, 179]]}, "": {"executed_lines": [33, 35, 36, 37, 38, 40, 42, 43, 44, 45, 51, 59, 73, 86, 87, 90, 100], "summary": {"covered_lines": 17, "num_statements": 17, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [33, 35, 36, 37, 38, 40, 42, 43, 44, 45, 51, 59, 66, 67, 68, 69, 70, 73, 86, 87, 90, 100, 138, 140, 141, 143, 145, 146, 147, 149, 155, 156, 158, 159, 160, 163, 168, 169, 171, 175, 177, 178, 179], "summary": {"covered_lines": 43, "num_statements": 49, "percent_covered": 86.95652173913044, "percent_covered_display": "87", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 87.75510204081633, "percent_statements_covered_display": "88", "num_branches": 20, "num_partial_branches": 3, "covered_branches": 17, "missing_branches": 3, "percent_branches_covered": 85.0, "percent_branches_covered_display": "85"}, "missing_lines": [75, 76, 96, 97, 151, 164], "excluded_lines": [], "start_line": 1, "executed_branches": [[67, 68], [67, 70], [68, 67], [68, 69], [140, 141], [140, 143], [145, 146], [145, 147], [147, 149], [155, 156], [155, 158], [159, 160], [159, 163], [163, 168], [168, 169], [168, 175], [177, 178]], "missing_branches": [[147, 151], [163, 164], [177, 179]]}}}, "src/zenzic/core/adapters/_mkdocs.py": {"executed_lines": [10, 12, 13, 14, 15, 16, 18, 19, 21, 22, 23, 26, 37, 41, 51, 52, 58, 69, 73, 74, 75, 77, 80, 81, 82, 84, 85, 87, 93, 98, 99, 105, 117, 118, 119, 125, 126, 127, 129, 135, 142, 143, 145, 146, 147, 148, 149, 150, 151, 152, 153, 155, 156, 157, 159, 165, 167, 168, 171, 173, 174, 175, 176, 177, 178, 179, 180, 186, 198, 199, 200, 201, 202, 203, 204, 205, 207, 208, 210, 211, 212, 213, 216, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 248, 268, 269, 270, 271, 272, 273, 274, 277, 296, 297, 298, 299, 301, 304, 310, 311, 313, 314, 317, 327, 328, 330, 331, 332, 333, 334, 335, 336, 337, 339, 340, 342, 343, 345, 346, 347, 348, 349, 354, 360, 362, 363, 364, 365, 366, 367, 368, 369, 370, 372, 373, 374, 375, 376, 382, 406, 414, 415, 416, 417, 421, 425, 426, 427, 429, 430, 436, 441, 452, 454, 456, 472, 473, 474, 475, 477, 507, 508, 509, 510, 511, 512, 514, 528, 531, 532, 533, 535, 537, 539, 541, 542, 543, 545, 552, 556, 577, 580, 581, 582, 583, 586, 587, 588, 589, 590, 591, 592, 594, 618, 623, 624, 625, 626, 629, 630, 632, 633, 636, 637, 644, 645, 646, 649, 651, 661, 663, 664, 665, 669, 670, 671, 672, 673, 675, 681, 682, 696, 697], "summary": {"covered_lines": 238, "num_statements": 264, "percent_covered": 87.44075829383887, "percent_covered_display": "87", "missing_lines": 26, "excluded_lines": 5, "percent_statements_covered": 90.15151515151516, "percent_statements_covered_display": "90", "num_branches": 158, "num_partial_branches": 21, "covered_branches": 131, "missing_branches": 27, "percent_branches_covered": 82.9113924050633, "percent_branches_covered_display": "83"}, "missing_lines": [53, 54, 55, 70, 71, 76, 78, 83, 86, 90, 100, 101, 102, 120, 121, 122, 206, 300, 312, 329, 338, 341, 442, 578, 584, 647], "excluded_lines": [29, 30, 31, 128, 136], "executed_branches": [[51, 52], [69, 73], [73, 74], [75, 77], [77, 80], [81, 82], [81, 87], [82, 84], [85, 81], [98, 99], [117, 118], [145, 146], [145, 155], [146, 147], [146, 153], [147, 148], [147, 150], [150, 151], [151, 146], [151, 152], [155, 156], [155, 159], [156, 157], [156, 159], [174, 175], [174, 176], [199, 200], [199, 213], [200, 201], [200, 202], [202, 203], [202, 204], [204, 205], [204, 212], [205, 207], [207, 204], [207, 208], [210, 204], [210, 211], [232, 233], [232, 245], [233, 234], [233, 235], [235, 236], [235, 237], [237, 238], [237, 244], [238, 239], [238, 240], [240, 237], [240, 241], [242, 237], [242, 243], [268, 269], [268, 274], [269, 270], [269, 271], [271, 272], [271, 273], [296, 297], [296, 298], [299, 301], [310, 311], [310, 314], [311, 313], [327, -317], [327, 328], [328, 330], [330, 331], [330, 332], [332, 333], [332, 334], [336, 337], [336, 346], [337, 339], [340, 342], [342, 343], [342, 345], [346, 347], [346, 348], [348, 349], [348, 354], [362, 363], [362, 364], [364, 365], [364, 367], [367, 368], [367, 374], [368, 369], [368, 373], [369, 370], [369, 372], [374, 375], [375, -360], [375, 376], [425, 426], [425, 429], [441, -406], [472, 473], [472, 474], [507, 508], [507, 509], [510, 511], [510, 512], [531, 532], [531, 533], [577, 580], [583, 586], [586, 587], [586, 588], [588, 589], [588, 590], [590, 591], [590, 592], [623, 624], [623, 629], [624, 625], [624, 626], [629, 630], [629, 632], [632, 633], [632, 636], [636, 637], [636, 644], [644, 645], [644, 649], [646, 649], [670, 671], [670, 675], [672, 673], [672, 675]], "missing_branches": [[51, 53], [53, 54], [53, 55], [69, 70], [73, 90], [75, 76], [77, 78], [82, 83], [85, 86], [98, 100], [100, 101], [100, 102], [117, 120], [120, 121], [120, 122], [150, 146], [205, 206], [299, 300], [311, 312], [328, 329], [337, 338], [340, 341], [374, -360], [441, 442], [577, 578], [583, 584], [646, 647]], "functions": {"_construct_unknown_tag": {"executed_lines": [51, 52], "summary": {"covered_lines": 2, "num_statements": 5, "percent_covered": 33.333333333333336, "percent_covered_display": "33", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 40.0, "percent_statements_covered_display": "40", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 3, "percent_branches_covered": 25.0, "percent_branches_covered_display": "25"}, "missing_lines": [53, 54, 55], "excluded_lines": [], "start_line": 41, "executed_branches": [[51, 52]], "missing_branches": [[51, 53], [53, 54], [53, 55]]}, "_construct_env_tag": {"executed_lines": [69, 73, 74, 75, 77, 80, 81, 82, 84, 85, 87], "summary": {"covered_lines": 11, "num_statements": 18, "percent_covered": 59.375, "percent_covered_display": "59", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 61.111111111111114, "percent_statements_covered_display": "61", "num_branches": 14, "num_partial_branches": 6, "covered_branches": 8, "missing_branches": 6, "percent_branches_covered": 57.142857142857146, "percent_branches_covered_display": "57"}, "missing_lines": [70, 71, 76, 78, 83, 86, 90], "excluded_lines": [], "start_line": 58, "executed_branches": [[69, 73], [73, 74], [75, 77], [77, 80], [81, 82], [81, 87], [82, 84], [85, 81]], "missing_branches": [[69, 70], [73, 90], [75, 76], [77, 78], [82, 83], [85, 86]]}, "_construct_relative_tag": {"executed_lines": [98, 99], "summary": {"covered_lines": 2, "num_statements": 5, "percent_covered": 33.333333333333336, "percent_covered_display": "33", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 40.0, "percent_statements_covered_display": "40", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 3, "percent_branches_covered": 25.0, "percent_branches_covered_display": "25"}, "missing_lines": [100, 101, 102], "excluded_lines": [], "start_line": 93, "executed_branches": [[98, 99]], "missing_branches": [[98, 100], [100, 101], [100, 102]]}, "_construct_python_tag": {"executed_lines": [117, 118, 119], "summary": {"covered_lines": 3, "num_statements": 6, "percent_covered": 40.0, "percent_covered_display": "40", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 50.0, "percent_statements_covered_display": "50", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 3, "percent_branches_covered": 25.0, "percent_branches_covered_display": "25"}, "missing_lines": [120, 121, 122], "excluded_lines": [], "start_line": 105, "executed_branches": [[117, 118]], "missing_branches": [[117, 120], [120, 121], [120, 122]]}, "_iter_plugins": {"executed_lines": [142, 143, 145, 146, 147, 148, 149, 150, 151, 152, 153, 155, 156, 157, 159], "summary": {"covered_lines": 15, "num_statements": 15, "percent_covered": 96.55172413793103, "percent_covered_display": "97", "missing_lines": 0, "excluded_lines": 1, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 14, "num_partial_branches": 1, "covered_branches": 13, "missing_branches": 1, "percent_branches_covered": 92.85714285714286, "percent_branches_covered_display": "93"}, "missing_lines": [], "excluded_lines": [136], "start_line": 135, "executed_branches": [[145, 146], [145, 155], [146, 147], [146, 153], [147, 148], [147, 150], [150, 151], [151, 146], [151, 152], [155, 156], [155, 159], [156, 157], [156, 159]], "missing_branches": [[150, 146]]}, "find_config_file": {"executed_lines": [167, 168], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 165, "executed_branches": [], "missing_branches": []}, "_load_doc_config": {"executed_lines": [173, 174, 175, 176, 177, 178, 179, 180], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 171, "executed_branches": [[174, 175], [174, 176]], "missing_branches": []}, "_extract_i18n_locale_patterns": {"executed_lines": [198, 199, 200, 201, 202, 203, 204, 205, 207, 208, 210, 211, 212, 213], "summary": {"covered_lines": 14, "num_statements": 15, "percent_covered": 93.10344827586206, "percent_covered_display": "93", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 93.33333333333333, "percent_statements_covered_display": "93", "num_branches": 14, "num_partial_branches": 1, "covered_branches": 13, "missing_branches": 1, "percent_branches_covered": 92.85714285714286, "percent_branches_covered_display": "93"}, "missing_lines": [206], "excluded_lines": [], "start_line": 186, "executed_branches": [[199, 200], [199, 213], [200, 201], [200, 202], [202, 203], [202, 204], [204, 205], [204, 212], [205, 207], [207, 204], [207, 208], [210, 204], [210, 211]], "missing_branches": [[205, 206]]}, "_extract_i18n_locale_dirs": {"executed_lines": [231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245], "summary": {"covered_lines": 15, "num_statements": 15, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 14, "num_partial_branches": 0, "covered_branches": 14, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 216, "executed_branches": [[232, 233], [232, 245], [233, 234], [233, 235], [235, 236], [235, 237], [237, 238], [237, 244], [238, 239], [238, 240], [240, 237], [240, 241], [242, 237], [242, 243]], "missing_branches": []}, "_extract_i18n_reconfigure_material": {"executed_lines": [268, 269, 270, 271, 272, 273, 274], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 6, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 248, "executed_branches": [[268, 269], [268, 274], [269, 270], [269, 271], [271, 272], [271, 273]], "missing_branches": []}, "_detect_redundant_alternate": {"executed_lines": [296, 297, 298, 299, 301], "summary": {"covered_lines": 5, "num_statements": 6, "percent_covered": 80.0, "percent_covered_display": "80", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 83.33333333333333, "percent_statements_covered_display": "83", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 1, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75"}, "missing_lines": [300], "excluded_lines": [], "start_line": 277, "executed_branches": [[296, 297], [296, 298], [299, 301]], "missing_branches": [[299, 300]]}, "_extract_i18n_fallback_to_default": {"executed_lines": [310, 311, 313, 314], "summary": {"covered_lines": 4, "num_statements": 5, "percent_covered": 77.77777777777777, "percent_covered_display": "78", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 80.0, "percent_statements_covered_display": "80", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 1, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75"}, "missing_lines": [312], "excluded_lines": [], "start_line": 304, "executed_branches": [[310, 311], [310, 314], [311, 313]], "missing_branches": [[311, 312]]}, "_validate_i18n_fallback_config": {"executed_lines": [327, 328, 330, 331, 332, 333, 334, 335, 336, 337, 339, 340, 342, 343, 345, 346, 347, 348, 349, 354], "summary": {"covered_lines": 20, "num_statements": 23, "percent_covered": 86.04651162790698, "percent_covered_display": "86", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 86.95652173913044, "percent_statements_covered_display": "87", "num_branches": 20, "num_partial_branches": 3, "covered_branches": 17, "missing_branches": 3, "percent_branches_covered": 85.0, "percent_branches_covered_display": "85"}, "missing_lines": [329, 338, 341], "excluded_lines": [], "start_line": 317, "executed_branches": [[327, -317], [327, 328], [328, 330], [330, 331], [330, 332], [332, 333], [332, 334], [336, 337], [336, 346], [337, 339], [340, 342], [342, 343], [342, 345], [346, 347], [346, 348], [348, 349], [348, 354]], "missing_branches": [[328, 329], [337, 338], [340, 341]]}, "_collect_nav_paths": {"executed_lines": [362, 363, 364, 365, 366, 367, 368, 369, 370, 372, 373, 374, 375, 376], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 96.42857142857143, "percent_covered_display": "96", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 14, "num_partial_branches": 1, "covered_branches": 13, "missing_branches": 1, "percent_branches_covered": 92.85714285714286, "percent_branches_covered_display": "93"}, "missing_lines": [], "excluded_lines": [], "start_line": 360, "executed_branches": [[362, 363], [362, 364], [364, 365], [364, 367], [367, 368], [367, 374], [368, 369], [368, 373], [369, 370], [369, 372], [374, 375], [375, -360], [375, 376]], "missing_branches": [[374, -360]]}, "MkDocsAdapter.__init__": {"executed_lines": [414, 415, 416, 417, 421, 425, 426, 427, 429, 430, 436, 441], "summary": {"covered_lines": 12, "num_statements": 13, "percent_covered": 88.23529411764706, "percent_covered_display": "88", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 92.3076923076923, "percent_statements_covered_display": "92", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 1, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75"}, "missing_lines": [442], "excluded_lines": [], "start_line": 406, "executed_branches": [[425, 426], [425, 429], [441, -406]], "missing_branches": [[441, 442]]}, "MkDocsAdapter.is_locale_dir": {"executed_lines": [454], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 452, "executed_branches": [], "missing_branches": []}, "MkDocsAdapter.resolve_asset": {"executed_lines": [472, 473, 474, 475], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 456, "executed_branches": [[472, 473], [472, 474]], "missing_branches": []}, "MkDocsAdapter.resolve_anchor": {"executed_lines": [507, 508, 509, 510, 511, 512], "summary": {"covered_lines": 6, "num_statements": 6, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 477, "executed_branches": [[507, 508], [507, 509], [510, 511], [510, 512]], "missing_branches": []}, "MkDocsAdapter.is_shadow_of_nav_page": {"executed_lines": [528, 531, 532, 533], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 514, "executed_branches": [[531, 532], [531, 533]], "missing_branches": []}, "MkDocsAdapter.get_ignored_patterns": {"executed_lines": [537], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 535, "executed_branches": [], "missing_branches": []}, "MkDocsAdapter.get_nav_paths": {"executed_lines": [541, 542, 543], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 539, "executed_branches": [], "missing_branches": []}, "MkDocsAdapter.has_engine_config": {"executed_lines": [552], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 545, "executed_branches": [], "missing_branches": []}, "MkDocsAdapter.map_url": {"executed_lines": [577, 580, 581, 582, 583, 586, 587, 588, 589, 590, 591, 592], "summary": {"covered_lines": 12, "num_statements": 14, "percent_covered": 83.33333333333333, "percent_covered_display": "83", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 85.71428571428571, "percent_statements_covered_display": "86", "num_branches": 10, "num_partial_branches": 2, "covered_branches": 8, "missing_branches": 2, "percent_branches_covered": 80.0, "percent_branches_covered_display": "80"}, "missing_lines": [578, 584], "excluded_lines": [], "start_line": 556, "executed_branches": [[577, 580], [583, 586], [586, 587], [586, 588], [588, 589], [588, 590], [590, 591], [590, 592]], "missing_branches": [[577, 578], [583, 584]]}, "MkDocsAdapter.classify_route": {"executed_lines": [618, 623, 624, 625, 626, 629, 630, 632, 633, 636, 637, 644, 645, 646, 649], "summary": {"covered_lines": 15, "num_statements": 16, "percent_covered": 93.33333333333333, "percent_covered_display": "93", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 93.75, "percent_statements_covered_display": "94", "num_branches": 14, "num_partial_branches": 1, "covered_branches": 13, "missing_branches": 1, "percent_branches_covered": 92.85714285714286, "percent_branches_covered_display": "93"}, "missing_lines": [647], "excluded_lines": [], "start_line": 594, "executed_branches": [[623, 624], [623, 629], [624, 625], [624, 626], [629, 630], [629, 632], [632, 633], [632, 636], [636, 637], [636, 644], [644, 645], [644, 649], [646, 649]], "missing_branches": [[646, 647]]}, "MkDocsAdapter.get_route_info": {"executed_lines": [661, 663, 664, 665, 669, 670, 671, 672, 673, 675], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 651, "executed_branches": [[670, 671], [670, 675], [672, 673], [672, 675]], "missing_branches": []}, "MkDocsAdapter.from_repo": {"executed_lines": [696, 697], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 682, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [10, 12, 13, 14, 15, 16, 18, 19, 21, 22, 23, 26, 37, 41, 58, 93, 105, 125, 126, 127, 129, 135, 165, 171, 186, 216, 248, 277, 304, 317, 360, 382, 406, 452, 456, 477, 514, 535, 539, 545, 556, 594, 651, 681, 682], "summary": {"covered_lines": 45, "num_statements": 45, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 4, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [29, 30, 31, 128], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"_PermissiveYamlLoader": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 37, "executed_branches": [], "missing_branches": []}, "MkDocsAdapter": {"executed_lines": [414, 415, 416, 417, 421, 425, 426, 427, 429, 430, 436, 441, 454, 472, 473, 474, 475, 507, 508, 509, 510, 511, 512, 528, 531, 532, 533, 537, 541, 542, 543, 552, 577, 580, 581, 582, 583, 586, 587, 588, 589, 590, 591, 592, 618, 623, 624, 625, 626, 629, 630, 632, 633, 636, 637, 644, 645, 646, 649, 661, 663, 664, 665, 669, 670, 671, 672, 673, 675, 696, 697], "summary": {"covered_lines": 71, "num_statements": 75, "percent_covered": 93.04347826086956, "percent_covered_display": "93", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 94.66666666666667, "percent_statements_covered_display": "95", "num_branches": 40, "num_partial_branches": 4, "covered_branches": 36, "missing_branches": 4, "percent_branches_covered": 90.0, "percent_branches_covered_display": "90"}, "missing_lines": [442, 578, 584, 647], "excluded_lines": [], "start_line": 382, "executed_branches": [[425, 426], [425, 429], [441, -406], [472, 473], [472, 474], [507, 508], [507, 509], [510, 511], [510, 512], [531, 532], [531, 533], [577, 580], [583, 586], [586, 587], [586, 588], [588, 589], [588, 590], [590, 591], [590, 592], [623, 624], [623, 629], [624, 625], [624, 626], [629, 630], [629, 632], [632, 633], [632, 636], [636, 637], [636, 644], [644, 645], [644, 649], [646, 649], [670, 671], [670, 675], [672, 673], [672, 675]], "missing_branches": [[441, 442], [577, 578], [583, 584], [646, 647]]}, "": {"executed_lines": [10, 12, 13, 14, 15, 16, 18, 19, 21, 22, 23, 26, 37, 41, 51, 52, 58, 69, 73, 74, 75, 77, 80, 81, 82, 84, 85, 87, 93, 98, 99, 105, 117, 118, 119, 125, 126, 127, 129, 135, 142, 143, 145, 146, 147, 148, 149, 150, 151, 152, 153, 155, 156, 157, 159, 165, 167, 168, 171, 173, 174, 175, 176, 177, 178, 179, 180, 186, 198, 199, 200, 201, 202, 203, 204, 205, 207, 208, 210, 211, 212, 213, 216, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 248, 268, 269, 270, 271, 272, 273, 274, 277, 296, 297, 298, 299, 301, 304, 310, 311, 313, 314, 317, 327, 328, 330, 331, 332, 333, 334, 335, 336, 337, 339, 340, 342, 343, 345, 346, 347, 348, 349, 354, 360, 362, 363, 364, 365, 366, 367, 368, 369, 370, 372, 373, 374, 375, 376, 382, 406, 452, 456, 477, 514, 535, 539, 545, 556, 594, 651, 681, 682], "summary": {"covered_lines": 167, "num_statements": 189, "percent_covered": 85.34201954397395, "percent_covered_display": "85", "missing_lines": 22, "excluded_lines": 5, "percent_statements_covered": 88.35978835978835, "percent_statements_covered_display": "88", "num_branches": 118, "num_partial_branches": 17, "covered_branches": 95, "missing_branches": 23, "percent_branches_covered": 80.50847457627118, "percent_branches_covered_display": "81"}, "missing_lines": [53, 54, 55, 70, 71, 76, 78, 83, 86, 90, 100, 101, 102, 120, 121, 122, 206, 300, 312, 329, 338, 341], "excluded_lines": [29, 30, 31, 128, 136], "start_line": 1, "executed_branches": [[51, 52], [69, 73], [73, 74], [75, 77], [77, 80], [81, 82], [81, 87], [82, 84], [85, 81], [98, 99], [117, 118], [145, 146], [145, 155], [146, 147], [146, 153], [147, 148], [147, 150], [150, 151], [151, 146], [151, 152], [155, 156], [155, 159], [156, 157], [156, 159], [174, 175], [174, 176], [199, 200], [199, 213], [200, 201], [200, 202], [202, 203], [202, 204], [204, 205], [204, 212], [205, 207], [207, 204], [207, 208], [210, 204], [210, 211], [232, 233], [232, 245], [233, 234], [233, 235], [235, 236], [235, 237], [237, 238], [237, 244], [238, 239], [238, 240], [240, 237], [240, 241], [242, 237], [242, 243], [268, 269], [268, 274], [269, 270], [269, 271], [271, 272], [271, 273], [296, 297], [296, 298], [299, 301], [310, 311], [310, 314], [311, 313], [327, -317], [327, 328], [328, 330], [330, 331], [330, 332], [332, 333], [332, 334], [336, 337], [336, 346], [337, 339], [340, 342], [342, 343], [342, 345], [346, 347], [346, 348], [348, 349], [348, 354], [362, 363], [362, 364], [364, 365], [364, 367], [367, 368], [367, 374], [368, 369], [368, 373], [369, 370], [369, 372], [374, 375], [375, -360], [375, 376]], "missing_branches": [[51, 53], [53, 54], [53, 55], [69, 70], [73, 90], [75, 76], [77, 78], [82, 83], [85, 86], [98, 100], [100, 101], [100, 102], [117, 120], [120, 121], [120, 122], [150, 146], [205, 206], [299, 300], [311, 312], [328, 329], [337, 338], [340, 341], [374, -360]]}}}, "src/zenzic/core/adapters/_utils.py": {"executed_lines": [14, 16, 17, 20, 62, 63, 64, 65, 66, 67, 68, 74, 77, 78, 79, 80, 81, 84, 99, 100, 101, 102, 103, 104, 105, 108, 114, 115, 117, 118, 121, 127, 128, 130, 131, 134, 140, 141, 143, 146, 147, 148, 149, 152, 153, 154, 155, 157, 162, 165, 166, 173, 174, 175, 176, 179, 212, 213, 214, 215, 220, 221, 222, 223, 225, 227, 228, 229, 230, 232, 238], "summary": {"covered_lines": 71, "num_statements": 76, "percent_covered": 90.0, "percent_covered_display": "90", "missing_lines": 5, "excluded_lines": 1, "percent_statements_covered": 93.42105263157895, "percent_statements_covered_display": "93", "num_branches": 24, "num_partial_branches": 5, "covered_branches": 19, "missing_branches": 5, "percent_branches_covered": 79.16666666666667, "percent_branches_covered_display": "79"}, "missing_lines": [116, 129, 142, 216, 217], "excluded_lines": [73], "executed_branches": [[66, 67], [66, 68], [100, 101], [100, 102], [103, 104], [103, 105], [115, 117], [128, 130], [141, 143], [147, 148], [147, 152], [153, 154], [153, 157], [213, 214], [213, 238], [220, 221], [220, 232], [222, 223], [229, 230]], "missing_branches": [[115, 116], [128, 129], [141, 142], [222, 232], [229, 232]], "functions": {"remap_to_default_locale": {"executed_lines": [62, 63, 64, 65, 66, 67, 68], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 20, "executed_branches": [[66, 67], [66, 68]], "missing_branches": []}, "extract_frontmatter_slug": {"executed_lines": [99, 100, 101, 102, 103, 104, 105], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 84, "executed_branches": [[100, 101], [100, 102], [103, 104], [103, 105]], "missing_branches": []}, "extract_frontmatter_draft": {"executed_lines": [114, 115, 117, 118], "summary": {"covered_lines": 4, "num_statements": 5, "percent_covered": 71.42857142857143, "percent_covered_display": "71", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 80.0, "percent_statements_covered_display": "80", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50"}, "missing_lines": [116], "excluded_lines": [], "start_line": 108, "executed_branches": [[115, 117]], "missing_branches": [[115, 116]]}, "extract_frontmatter_unlisted": {"executed_lines": [127, 128, 130, 131], "summary": {"covered_lines": 4, "num_statements": 5, "percent_covered": 71.42857142857143, "percent_covered_display": "71", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 80.0, "percent_statements_covered_display": "80", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50"}, "missing_lines": [129], "excluded_lines": [], "start_line": 121, "executed_branches": [[128, 130]], "missing_branches": [[128, 129]]}, "extract_frontmatter_tags": {"executed_lines": [140, 141, 143, 146, 147, 148, 149, 152, 153, 154, 155, 157], "summary": {"covered_lines": 12, "num_statements": 13, "percent_covered": 89.47368421052632, "percent_covered_display": "89", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 92.3076923076923, "percent_statements_covered_display": "92", "num_branches": 6, "num_partial_branches": 1, "covered_branches": 5, "missing_branches": 1, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83"}, "missing_lines": [142], "excluded_lines": [], "start_line": 134, "executed_branches": [[141, 143], [147, 148], [147, 152], [153, 154], [153, 157]], "missing_branches": [[141, 142]]}, "build_metadata_cache": {"executed_lines": [212, 213, 214, 215, 220, 221, 222, 223, 225, 227, 228, 229, 230, 232, 238], "summary": {"covered_lines": 15, "num_statements": 17, "percent_covered": 84.0, "percent_covered_display": "84", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 88.23529411764706, "percent_statements_covered_display": "88", "num_branches": 8, "num_partial_branches": 2, "covered_branches": 6, "missing_branches": 2, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75"}, "missing_lines": [216, 217], "excluded_lines": [], "start_line": 179, "executed_branches": [[213, 214], [213, 238], [220, 221], [220, 232], [222, 223], [229, 230]], "missing_branches": [[222, 232], [229, 232]]}, "": {"executed_lines": [14, 16, 17, 20, 74, 77, 78, 79, 80, 81, 84, 108, 121, 134, 162, 165, 166, 173, 174, 175, 176, 179], "summary": {"covered_lines": 22, "num_statements": 22, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 1, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [73], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"FileMetadata": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 166, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [14, 16, 17, 20, 62, 63, 64, 65, 66, 67, 68, 74, 77, 78, 79, 80, 81, 84, 99, 100, 101, 102, 103, 104, 105, 108, 114, 115, 117, 118, 121, 127, 128, 130, 131, 134, 140, 141, 143, 146, 147, 148, 149, 152, 153, 154, 155, 157, 162, 165, 166, 173, 174, 175, 176, 179, 212, 213, 214, 215, 220, 221, 222, 223, 225, 227, 228, 229, 230, 232, 238], "summary": {"covered_lines": 71, "num_statements": 76, "percent_covered": 90.0, "percent_covered_display": "90", "missing_lines": 5, "excluded_lines": 1, "percent_statements_covered": 93.42105263157895, "percent_statements_covered_display": "93", "num_branches": 24, "num_partial_branches": 5, "covered_branches": 19, "missing_branches": 5, "percent_branches_covered": 79.16666666666667, "percent_branches_covered_display": "79"}, "missing_lines": [116, 129, 142, 216, 217], "excluded_lines": [73], "start_line": 1, "executed_branches": [[66, 67], [66, 68], [100, 101], [100, 102], [103, 104], [103, 105], [115, 117], [128, 130], [141, 143], [147, 148], [147, 152], [153, 154], [153, 157], [213, 214], [213, 238], [220, 221], [220, 232], [222, 223], [229, 230]], "missing_branches": [[115, 116], [128, 129], [141, 142], [222, 232], [229, 232]]}}}, "src/zenzic/core/adapters/_vanilla.py": {"executed_lines": [5, 7, 8, 16, 27, 29, 31, 33, 35, 43, 45, 47, 49, 51, 53, 55, 57, 59, 61, 63, 64, 65, 67, 68, 69, 70, 71, 73, 79, 81, 87, 89], "summary": {"covered_lines": 32, "num_statements": 33, "percent_covered": 94.87179487179488, "percent_covered_display": "95", "missing_lines": 1, "excluded_lines": 3, "percent_statements_covered": 96.96969696969697, "percent_statements_covered_display": "97", "num_branches": 6, "num_partial_branches": 1, "covered_branches": 5, "missing_branches": 1, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83"}, "missing_lines": [66], "excluded_lines": [11, 12, 13], "executed_branches": [[65, 67], [67, 68], [67, 69], [69, 70], [69, 71]], "missing_branches": [[65, 66]], "functions": {"VanillaAdapter.is_locale_dir": {"executed_lines": [29], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 27, "executed_branches": [], "missing_branches": []}, "VanillaAdapter.resolve_asset": {"executed_lines": [33], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 31, "executed_branches": [], "missing_branches": []}, "VanillaAdapter.resolve_anchor": {"executed_lines": [43], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 35, "executed_branches": [], "missing_branches": []}, "VanillaAdapter.is_shadow_of_nav_page": {"executed_lines": [47], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 45, "executed_branches": [], "missing_branches": []}, "VanillaAdapter.get_ignored_patterns": {"executed_lines": [51], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 49, "executed_branches": [], "missing_branches": []}, "VanillaAdapter.get_nav_paths": {"executed_lines": [55], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 53, "executed_branches": [], "missing_branches": []}, "VanillaAdapter.has_engine_config": {"executed_lines": [59], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 57, "executed_branches": [], "missing_branches": []}, "VanillaAdapter.map_url": {"executed_lines": [63, 64, 65, 67, 68, 69, 70, 71], "summary": {"covered_lines": 8, "num_statements": 9, "percent_covered": 86.66666666666667, "percent_covered_display": "87", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 88.88888888888889, "percent_statements_covered_display": "89", "num_branches": 6, "num_partial_branches": 1, "covered_branches": 5, "missing_branches": 1, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83"}, "missing_lines": [66], "excluded_lines": [], "start_line": 61, "executed_branches": [[65, 67], [67, 68], [67, 69], [69, 70], [69, 71]], "missing_branches": [[65, 66]]}, "VanillaAdapter.classify_route": {"executed_lines": [79], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 73, "executed_branches": [], "missing_branches": []}, "VanillaAdapter.get_route_info": {"executed_lines": [87, 89], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 81, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [5, 7, 8, 16, 27, 31, 35, 45, 49, 53, 57, 61, 73, 81], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 3, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [11, 12, 13], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"VanillaAdapter": {"executed_lines": [29, 33, 43, 47, 51, 55, 59, 63, 64, 65, 67, 68, 69, 70, 71, 79, 87, 89], "summary": {"covered_lines": 18, "num_statements": 19, "percent_covered": 92.0, "percent_covered_display": "92", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 94.73684210526316, "percent_statements_covered_display": "95", "num_branches": 6, "num_partial_branches": 1, "covered_branches": 5, "missing_branches": 1, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83"}, "missing_lines": [66], "excluded_lines": [], "start_line": 16, "executed_branches": [[65, 67], [67, 68], [67, 69], [69, 70], [69, 71]], "missing_branches": [[65, 66]]}, "": {"executed_lines": [5, 7, 8, 16, 27, 31, 35, 45, 49, 53, 57, 61, 73, 81], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 3, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [11, 12, 13], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "src/zenzic/core/adapters/_zensical.py": {"executed_lines": [22, 24, 25, 26, 27, 29, 30, 31, 32, 35, 37, 58, 60, 61, 64, 66, 67, 69, 70, 71, 79, 95, 96, 97, 98, 99, 100, 101, 102, 103, 106, 112, 119, 120, 121, 123, 126, 129, 134, 137, 140, 143, 144, 146, 149, 152, 156, 186, 192, 193, 197, 198, 201, 202, 203, 205, 207, 210, 214, 216, 218, 220, 222, 223, 225, 253, 262, 264, 266, 268, 272, 301, 305, 306, 307, 309, 310, 311, 312, 313, 315, 333, 334, 335, 336, 337, 339, 350, 352, 358, 360, 361, 366, 367, 379, 380, 383, 384, 386, 387, 394, 395, 398], "summary": {"covered_lines": 103, "num_statements": 132, "percent_covered": 74.15730337078652, "percent_covered_display": "74", "missing_lines": 29, "excluded_lines": 3, "percent_statements_covered": 78.03030303030303, "percent_statements_covered_display": "78", "num_branches": 46, "num_partial_branches": 9, "covered_branches": 29, "missing_branches": 17, "percent_branches_covered": 63.04347826086956, "percent_branches_covered_display": "63"}, "missing_lines": [68, 72, 73, 104, 105, 124, 127, 132, 135, 138, 141, 147, 150, 153, 208, 221, 246, 247, 248, 249, 250, 251, 255, 258, 259, 260, 303, 308, 388], "excluded_lines": [50, 51, 52], "executed_branches": [[67, 69], [96, 97], [96, 106], [97, 98], [97, 100], [98, 99], [100, 101], [101, 96], [101, 102], [102, 103], [207, 210], [220, 222], [301, 305], [307, 309], [309, 310], [309, 311], [311, 312], [311, 313], [333, 334], [333, 335], [335, 336], [335, 337], [379, 380], [379, 383], [383, 384], [383, 398], [386, 387], [386, 394], [387, 386]], "missing_branches": [[67, 68], [98, 96], [100, 96], [102, 104], [104, 101], [104, 105], [207, 208], [220, 221], [246, 247], [246, 248], [249, 250], [249, 251], [258, 259], [258, 260], [301, 303], [307, 308], [387, 388]], "functions": {"find_zensical_config": {"executed_lines": [60, 61], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 58, "executed_branches": [], "missing_branches": []}, "_load_zensical_config": {"executed_lines": [66, 67, 69, 70, 71], "summary": {"covered_lines": 5, "num_statements": 8, "percent_covered": 60.0, "percent_covered_display": "60", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 62.5, "percent_statements_covered_display": "62", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50"}, "missing_lines": [68, 72, 73], "excluded_lines": [], "start_line": 64, "executed_branches": [[67, 69]], "missing_branches": [[67, 68]]}, "_extract_nav_paths": {"executed_lines": [95, 96, 97, 98, 99, 100, 101, 102, 103, 106], "summary": {"covered_lines": 10, "num_statements": 12, "percent_covered": 73.07692307692308, "percent_covered_display": "73", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 83.33333333333333, "percent_statements_covered_display": "83", "num_branches": 14, "num_partial_branches": 3, "covered_branches": 9, "missing_branches": 5, "percent_branches_covered": 64.28571428571429, "percent_branches_covered_display": "64"}, "missing_lines": [104, 105], "excluded_lines": [], "start_line": 79, "executed_branches": [[96, 97], [96, 106], [97, 98], [97, 100], [98, 99], [100, 101], [101, 96], [101, 102], [102, 103]], "missing_branches": [[98, 96], [100, 96], [102, 104], [104, 101], [104, 105]]}, "ZensicalLegacyProxy.__init__": {"executed_lines": [120, 121], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 119, "executed_branches": [], "missing_branches": []}, "ZensicalLegacyProxy.is_locale_dir": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [124], "excluded_lines": [], "start_line": 123, "executed_branches": [], "missing_branches": []}, "ZensicalLegacyProxy.resolve_asset": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [127], "excluded_lines": [], "start_line": 126, "executed_branches": [], "missing_branches": []}, "ZensicalLegacyProxy.resolve_anchor": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [132], "excluded_lines": [], "start_line": 129, "executed_branches": [], "missing_branches": []}, "ZensicalLegacyProxy.is_shadow_of_nav_page": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [135], "excluded_lines": [], "start_line": 134, "executed_branches": [], "missing_branches": []}, "ZensicalLegacyProxy.get_ignored_patterns": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [138], "excluded_lines": [], "start_line": 137, "executed_branches": [], "missing_branches": []}, "ZensicalLegacyProxy.get_nav_paths": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [141], "excluded_lines": [], "start_line": 140, "executed_branches": [], "missing_branches": []}, "ZensicalLegacyProxy.has_engine_config": {"executed_lines": [144], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 143, "executed_branches": [], "missing_branches": []}, "ZensicalLegacyProxy.map_url": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [147], "excluded_lines": [], "start_line": 146, "executed_branches": [], "missing_branches": []}, "ZensicalLegacyProxy.classify_route": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [150], "excluded_lines": [], "start_line": 149, "executed_branches": [], "missing_branches": []}, "ZensicalLegacyProxy.get_route_info": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [153], "excluded_lines": [], "start_line": 152, "executed_branches": [], "missing_branches": []}, "ZensicalAdapter.__init__": {"executed_lines": [192, 193, 197, 198, 201, 202, 203, 205, 207, 210], "summary": {"covered_lines": 10, "num_statements": 11, "percent_covered": 84.61538461538461, "percent_covered_display": "85", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 90.9090909090909, "percent_statements_covered_display": "91", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50"}, "missing_lines": [208], "excluded_lines": [], "start_line": 186, "executed_branches": [[207, 210]], "missing_branches": [[207, 208]]}, "ZensicalAdapter.is_locale_dir": {"executed_lines": [216], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 214, "executed_branches": [], "missing_branches": []}, "ZensicalAdapter.resolve_asset": {"executed_lines": [220, 222, 223], "summary": {"covered_lines": 3, "num_statements": 4, "percent_covered": 66.66666666666667, "percent_covered_display": "67", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 75.0, "percent_statements_covered_display": "75", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50"}, "missing_lines": [221], "excluded_lines": [], "start_line": 218, "executed_branches": [[220, 222]], "missing_branches": [[220, 221]]}, "ZensicalAdapter.resolve_anchor": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 6, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 4, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0"}, "missing_lines": [246, 247, 248, 249, 250, 251], "excluded_lines": [], "start_line": 225, "executed_branches": [], "missing_branches": [[246, 247], [246, 248], [249, 250], [249, 251]]}, "ZensicalAdapter.is_shadow_of_nav_page": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0"}, "missing_lines": [255, 258, 259, 260], "excluded_lines": [], "start_line": 253, "executed_branches": [], "missing_branches": [[258, 259], [258, 260]]}, "ZensicalAdapter.get_ignored_patterns": {"executed_lines": [264], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 262, "executed_branches": [], "missing_branches": []}, "ZensicalAdapter.has_engine_config": {"executed_lines": [268], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 266, "executed_branches": [], "missing_branches": []}, "ZensicalAdapter.map_url": {"executed_lines": [301, 305, 306, 307, 309, 310, 311, 312, 313], "summary": {"covered_lines": 9, "num_statements": 11, "percent_covered": 78.94736842105263, "percent_covered_display": "79", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 81.81818181818181, "percent_statements_covered_display": "82", "num_branches": 8, "num_partial_branches": 2, "covered_branches": 6, "missing_branches": 2, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75"}, "missing_lines": [303, 308], "excluded_lines": [], "start_line": 272, "executed_branches": [[301, 305], [307, 309], [309, 310], [309, 311], [311, 312], [311, 313]], "missing_branches": [[301, 303], [307, 308]]}, "ZensicalAdapter.classify_route": {"executed_lines": [333, 334, 335, 336, 337], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 315, "executed_branches": [[333, 334], [333, 335], [335, 336], [335, 337]], "missing_branches": []}, "ZensicalAdapter.get_nav_paths": {"executed_lines": [350], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 339, "executed_branches": [], "missing_branches": []}, "ZensicalAdapter.get_route_info": {"executed_lines": [358, 360, 361], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 352, "executed_branches": [], "missing_branches": []}, "ZensicalAdapter.from_repo": {"executed_lines": [379, 380, 383, 384, 386, 387, 394, 395, 398], "summary": {"covered_lines": 9, "num_statements": 10, "percent_covered": 88.88888888888889, "percent_covered_display": "89", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 90.0, "percent_statements_covered_display": "90", "num_branches": 8, "num_partial_branches": 1, "covered_branches": 7, "missing_branches": 1, "percent_branches_covered": 87.5, "percent_branches_covered_display": "88"}, "missing_lines": [388], "excluded_lines": [], "start_line": 367, "executed_branches": [[379, 380], [379, 383], [383, 384], [383, 398], [386, 387], [386, 394], [387, 386]], "missing_branches": [[387, 388]]}, "": {"executed_lines": [22, 24, 25, 26, 27, 29, 30, 31, 32, 35, 37, 58, 64, 79, 112, 119, 123, 126, 129, 134, 137, 140, 143, 146, 149, 152, 156, 186, 214, 218, 225, 253, 262, 266, 272, 315, 339, 352, 366, 367], "summary": {"covered_lines": 40, "num_statements": 40, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 3, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [50, 51, 52], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"ZensicalLegacyProxy": {"executed_lines": [120, 121, 144], "summary": {"covered_lines": 3, "num_statements": 12, "percent_covered": 25.0, "percent_covered_display": "25", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 25.0, "percent_statements_covered_display": "25", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [124, 127, 132, 135, 138, 141, 147, 150, 153], "excluded_lines": [], "start_line": 112, "executed_branches": [], "missing_branches": []}, "ZensicalAdapter": {"executed_lines": [192, 193, 197, 198, 201, 202, 203, 205, 207, 210, 216, 220, 222, 223, 264, 268, 301, 305, 306, 307, 309, 310, 311, 312, 313, 333, 334, 335, 336, 337, 350, 358, 360, 361, 379, 380, 383, 384, 386, 387, 394, 395, 398], "summary": {"covered_lines": 43, "num_statements": 58, "percent_covered": 70.45454545454545, "percent_covered_display": "70", "missing_lines": 15, "excluded_lines": 0, "percent_statements_covered": 74.13793103448276, "percent_statements_covered_display": "74", "num_branches": 30, "num_partial_branches": 5, "covered_branches": 19, "missing_branches": 11, "percent_branches_covered": 63.333333333333336, "percent_branches_covered_display": "63"}, "missing_lines": [208, 221, 246, 247, 248, 249, 250, 251, 255, 258, 259, 260, 303, 308, 388], "excluded_lines": [], "start_line": 156, "executed_branches": [[207, 210], [220, 222], [301, 305], [307, 309], [309, 310], [309, 311], [311, 312], [311, 313], [333, 334], [333, 335], [335, 336], [335, 337], [379, 380], [379, 383], [383, 384], [383, 398], [386, 387], [386, 394], [387, 386]], "missing_branches": [[207, 208], [220, 221], [246, 247], [246, 248], [249, 250], [249, 251], [258, 259], [258, 260], [301, 303], [307, 308], [387, 388]]}, "": {"executed_lines": [22, 24, 25, 26, 27, 29, 30, 31, 32, 35, 37, 58, 60, 61, 64, 66, 67, 69, 70, 71, 79, 95, 96, 97, 98, 99, 100, 101, 102, 103, 106, 112, 119, 123, 126, 129, 134, 137, 140, 143, 146, 149, 152, 156, 186, 214, 218, 225, 253, 262, 266, 272, 315, 339, 352, 366, 367], "summary": {"covered_lines": 57, "num_statements": 62, "percent_covered": 85.8974358974359, "percent_covered_display": "86", "missing_lines": 5, "excluded_lines": 3, "percent_statements_covered": 91.93548387096774, "percent_statements_covered_display": "92", "num_branches": 16, "num_partial_branches": 4, "covered_branches": 10, "missing_branches": 6, "percent_branches_covered": 62.5, "percent_branches_covered_display": "62"}, "missing_lines": [68, 72, 73, 104, 105], "excluded_lines": [50, 51, 52], "start_line": 1, "executed_branches": [[67, 69], [96, 97], [96, 106], [97, 98], [97, 100], [98, 99], [100, 101], [101, 96], [101, 102], [102, 103]], "missing_branches": [[67, 68], [98, 96], [100, 96], [102, 104], [104, 101], [104, 105]]}}}, "src/zenzic/core/cache.py": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 71, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 71, "excluded_lines": 3, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 8, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0"}, "missing_lines": [50, 52, 53, 54, 55, 56, 67, 78, 81, 96, 99, 119, 128, 129, 132, 157, 158, 159, 160, 166, 167, 170, 171, 172, 173, 174, 175, 178, 216, 217, 218, 219, 223, 234, 236, 237, 238, 239, 240, 241, 253, 262, 274, 275, 277, 278, 280, 281, 283, 287, 288, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 313, 326, 327, 328, 329, 330, 331, 332, 333, 334], "excluded_lines": [59, 60, 61], "executed_branches": [], "missing_branches": [[158, 159], [158, 160], [237, 238], [237, 240], [302, 303], [302, 304], [307, 308], [307, 309]], "functions": {"make_content_hash": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [78], "excluded_lines": [], "start_line": 67, "executed_branches": [], "missing_branches": []}, "make_config_hash": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [96], "excluded_lines": [], "start_line": 81, "executed_branches": [], "missing_branches": []}, "make_vsm_snapshot_hash": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 3, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [119, 128, 129], "excluded_lines": [], "start_line": 99, "executed_branches": [], "missing_branches": []}, "make_file_key": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0"}, "missing_lines": [157, 158, 159, 160], "excluded_lines": [], "start_line": 132, "executed_branches": [], "missing_branches": [[158, 159], [158, 160]]}, "CacheManager.__init__": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 3, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [217, 218, 219], "excluded_lines": [], "start_line": 216, "executed_branches": [], "missing_branches": []}, "CacheManager.get": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 7, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0"}, "missing_lines": [234, 236, 237, 238, 239, 240, 241], "excluded_lines": [], "start_line": 223, "executed_branches": [], "missing_branches": [[237, 238], [237, 240]]}, "CacheManager.put": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [262], "excluded_lines": [], "start_line": 253, "executed_branches": [], "missing_branches": []}, "CacheManager.hit_rate": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 2, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [277, 278], "excluded_lines": [], "start_line": 275, "executed_branches": [], "missing_branches": []}, "CacheManager.size": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [283], "excluded_lines": [], "start_line": 281, "executed_branches": [], "missing_branches": []}, "CacheManager.load": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 10, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 10, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 4, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0"}, "missing_lines": [302, 303, 304, 305, 306, 307, 308, 309, 310, 311], "excluded_lines": [], "start_line": 288, "executed_branches": [], "missing_branches": [[302, 303], [302, 304], [307, 308], [307, 309]]}, "CacheManager.save": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 9, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [326, 327, 328, 329, 330, 331, 332, 333, 334], "excluded_lines": [], "start_line": 313, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 29, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 29, "excluded_lines": 3, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [50, 52, 53, 54, 55, 56, 67, 81, 99, 132, 166, 167, 170, 171, 172, 173, 174, 175, 178, 216, 223, 253, 274, 275, 280, 281, 287, 288, 313], "excluded_lines": [59, 60, 61], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"_CachedEntry": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 167, "executed_branches": [], "missing_branches": []}, "CacheManager": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 33, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 33, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 6, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0"}, "missing_lines": [217, 218, 219, 234, 236, 237, 238, 239, 240, 241, 262, 277, 278, 283, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 326, 327, 328, 329, 330, 331, 332, 333, 334], "excluded_lines": [], "start_line": 178, "executed_branches": [], "missing_branches": [[237, 238], [237, 240], [302, 303], [302, 304], [307, 308], [307, 309]]}, "": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 38, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 38, "excluded_lines": 3, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0"}, "missing_lines": [50, 52, 53, 54, 55, 56, 67, 78, 81, 96, 99, 119, 128, 129, 132, 157, 158, 159, 160, 166, 167, 170, 171, 172, 173, 174, 175, 178, 216, 223, 253, 274, 275, 280, 281, 287, 288, 313], "excluded_lines": [59, 60, 61], "start_line": 1, "executed_branches": [], "missing_branches": [[158, 159], [158, 160]]}}}, "src/zenzic/core/discovery.py": {"executed_lines": [18, 20, 21, 22, 23, 25, 33, 36, 52, 53, 58, 59, 62, 105, 131, 132, 133, 134, 135, 136, 137, 138, 139], "summary": {"covered_lines": 23, "num_statements": 35, "percent_covered": 61.40350877192982, "percent_covered_display": "61", "missing_lines": 12, "excluded_lines": 3, "percent_statements_covered": 65.71428571428571, "percent_statements_covered_display": "66", "num_branches": 22, "num_partial_branches": 0, "covered_branches": 12, "missing_branches": 10, "percent_branches_covered": 54.54545454545455, "percent_branches_covered_display": "55"}, "missing_lines": [91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102], "excluded_lines": [28, 29, 68], "executed_branches": [[52, -36], [52, 53], [58, 52], [58, 59], [132, -105], [132, 133], [133, 134], [133, 135], [135, 136], [135, 137], [137, 138], [137, 139]], "missing_branches": [[91, 92], [91, 93], [94, -62], [94, 95], [95, 96], [95, 97], [97, 98], [97, 99], [99, 100], [99, 101]], "functions": {"walk_files": {"executed_lines": [52, 53, 58, 59], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 36, "executed_branches": [[52, -36], [52, 53], [58, 52], [58, 59]], "missing_branches": []}, "iter_locale_markdown_sources": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 12, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 12, "excluded_lines": 1, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 10, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 10, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0"}, "missing_lines": [91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102], "excluded_lines": [68], "start_line": 62, "executed_branches": [], "missing_branches": [[91, 92], [91, 93], [94, -62], [94, 95], [95, 96], [95, 97], [97, 98], [97, 99], [99, 100], [99, 101]]}, "iter_markdown_sources": {"executed_lines": [131, 132, 133, 134, 135, 136, 137, 138, 139], "summary": {"covered_lines": 9, "num_statements": 9, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 8, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 105, "executed_branches": [[132, -105], [132, 133], [133, 134], [133, 135], [135, 136], [135, 137], [137, 138], [137, 139]], "missing_branches": []}, "": {"executed_lines": [18, 20, 21, 22, 23, 25, 33, 36, 62, 105], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 2, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [28, 29], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [18, 20, 21, 22, 23, 25, 33, 36, 52, 53, 58, 59, 62, 105, 131, 132, 133, 134, 135, 136, 137, 138, 139], "summary": {"covered_lines": 23, "num_statements": 35, "percent_covered": 61.40350877192982, "percent_covered_display": "61", "missing_lines": 12, "excluded_lines": 3, "percent_statements_covered": 65.71428571428571, "percent_statements_covered_display": "66", "num_branches": 22, "num_partial_branches": 0, "covered_branches": 12, "missing_branches": 10, "percent_branches_covered": 54.54545454545455, "percent_branches_covered_display": "55"}, "missing_lines": [91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102], "excluded_lines": [28, 29, 68], "start_line": 1, "executed_branches": [[52, -36], [52, 53], [58, 52], [58, 59], [132, -105], [132, 133], [133, 134], [133, 135], [135, 136], [135, 137], [137, 138], [137, 139]], "missing_branches": [[91, 92], [91, 93], [94, -62], [94, 95], [95, 96], [95, 97], [97, 98], [97, 99], [99, 100], [99, 101]]}}}, "src/zenzic/core/exceptions.py": {"executed_lines": [20, 22, 25, 47, 48, 49, 50, 52, 53, 54, 55, 56, 59, 74, 95, 112, 128], "summary": {"covered_lines": 17, "num_statements": 17, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [[53, 54], [53, 56]], "missing_branches": [], "functions": {"ZenzicError.__init__": {"executed_lines": [48, 49, 50], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 47, "executed_branches": [], "missing_branches": []}, "ZenzicError.__str__": {"executed_lines": [53, 54, 55, 56], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 52, "executed_branches": [[53, 54], [53, 56]], "missing_branches": []}, "": {"executed_lines": [20, 22, 25, 47, 52, 59, 74, 95, 112, 128], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"ZenzicError": {"executed_lines": [48, 49, 50, 53, 54, 55, 56], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 25, "executed_branches": [[53, 54], [53, 56]], "missing_branches": []}, "ConfigurationError": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 59, "executed_branches": [], "missing_branches": []}, "EngineError": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 74, "executed_branches": [], "missing_branches": []}, "CheckError": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 95, "executed_branches": [], "missing_branches": []}, "NetworkError": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 112, "executed_branches": [], "missing_branches": []}, "PluginContractError": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 128, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [20, 22, 25, 47, 52, 59, 74, 95, 112, 128], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "src/zenzic/core/exclusion.py": {"executed_lines": [27, 29, 30, 31, 32, 33, 35, 45, 56, 57, 58, 60, 61, 62, 63, 65, 67, 68, 69, 70, 72, 73, 74, 82, 83, 84, 85, 86, 87, 89, 90, 91, 92, 94, 95, 96, 102, 103, 104, 105, 106, 107, 109, 110, 111, 116, 117, 119, 122, 123, 126, 127, 128, 129, 132, 147, 149, 150, 151, 152, 153, 154, 155, 156, 158, 159, 160, 161, 162, 163, 169, 170, 172, 173, 174, 175, 178, 179, 181, 188, 189, 192, 193, 196, 197, 199, 200, 201, 202, 203, 204, 205, 207, 208, 211, 212, 213, 216, 218, 220, 221, 224, 225, 228, 229, 230, 231, 232, 233, 237, 238, 239, 240, 244, 245, 246, 247, 248, 249, 252, 254, 256, 257, 258, 260, 263, 264, 265, 267, 269, 270, 274, 285, 302, 314, 323, 326, 327, 330, 331, 334, 335, 338, 339, 340, 343, 348, 349, 350, 351, 352, 353, 354, 355, 356, 358, 359, 360, 361, 362, 364, 365, 366, 367, 368, 369, 370, 371, 376, 378, 384, 385, 388, 389, 392, 393, 396, 397, 400, 406, 407, 410, 412, 417, 418, 419, 424, 425, 429, 430, 431, 434, 435, 439, 440, 444, 445, 449, 450, 451, 454, 455, 456, 459, 460, 464, 466, 467, 474], "summary": {"covered_lines": 209, "num_statements": 237, "percent_covered": 87.1313672922252, "percent_covered_display": "87", "missing_lines": 28, "excluded_lines": 4, "percent_statements_covered": 88.18565400843882, "percent_statements_covered_display": "88", "num_branches": 136, "num_partial_branches": 18, "covered_branches": 116, "missing_branches": 20, "percent_branches_covered": 85.29411764705883, "percent_branches_covered_display": "85"}, "missing_lines": [77, 78, 79, 93, 98, 99, 113, 114, 166, 167, 176, 177, 234, 241, 271, 272, 374, 375, 401, 402, 403, 420, 421, 426, 436, 441, 446, 461], "excluded_lines": [38, 39, 46, 101], "executed_branches": [[60, 61], [60, 119], [62, 63], [62, 84], [63, 65], [63, 82], [65, 67], [65, 70], [70, 72], [84, 85], [84, 87], [87, 89], [87, 107], [90, 91], [90, 92], [92, 94], [94, 95], [94, 96], [96, 102], [103, 104], [103, 105], [107, 109], [107, 116], [109, 110], [151, 152], [151, 155], [153, 151], [153, 154], [159, -149], [159, 160], [161, -149], [161, 162], [172, 173], [172, 174], [188, 189], [188, 192], [192, 193], [192, 196], [196, 197], [196, 199], [200, 201], [200, 205], [201, 202], [201, 203], [203, 200], [203, 204], [212, 213], [212, 216], [216, 218], [216, 224], [220, 221], [224, 225], [224, 228], [230, 231], [230, 237], [233, 237], [238, 239], [238, 244], [240, 244], [245, 246], [245, 248], [248, 249], [248, 252], [254, 256], [254, 263], [257, 258], [257, 260], [264, 265], [264, 267], [350, -314], [350, 351], [352, 353], [354, 355], [356, 358], [359, 360], [359, 361], [367, 368], [369, 370], [384, 385], [384, 388], [388, 389], [388, 392], [392, 393], [392, 396], [396, 397], [396, 400], [400, 406], [406, 407], [406, 410], [424, 425], [424, 429], [425, 424], [429, 430], [429, 434], [430, 431], [430, 434], [434, 435], [434, 439], [435, 434], [439, 440], [439, 444], [440, 439], [444, 445], [444, 449], [445, 444], [449, 450], [449, 454], [450, 451], [450, 454], [454, 455], [454, 459], [455, 456], [455, 459], [459, 460], [459, 464], [460, 459]], "missing_branches": [[70, 77], [92, 93], [96, 98], [109, 113], [220, 224], [233, 234], [240, 241], [352, 354], [354, 356], [356, -314], [367, 376], [369, 376], [400, 401], [402, 403], [402, 406], [425, 426], [435, 436], [440, 441], [445, 446], [460, 461]], "functions": {"_gitignore_glob_to_regex": {"executed_lines": [56, 57, 58, 60, 61, 62, 63, 65, 67, 68, 69, 70, 72, 73, 74, 82, 83, 84, 85, 86, 87, 89, 90, 91, 92, 94, 95, 96, 102, 103, 104, 105, 106, 107, 109, 110, 111, 116, 117, 119], "summary": {"covered_lines": 40, "num_statements": 48, "percent_covered": 84.21052631578948, "percent_covered_display": "84", "missing_lines": 8, "excluded_lines": 2, "percent_statements_covered": 83.33333333333333, "percent_statements_covered_display": "83", "num_branches": 28, "num_partial_branches": 4, "covered_branches": 24, "missing_branches": 4, "percent_branches_covered": 85.71428571428571, "percent_branches_covered_display": "86"}, "missing_lines": [77, 78, 79, 93, 98, 99, 113, 114], "excluded_lines": [46, 101], "start_line": 45, "executed_branches": [[60, 61], [60, 119], [62, 63], [62, 84], [63, 65], [63, 82], [65, 67], [65, 70], [70, 72], [84, 85], [84, 87], [87, 89], [87, 107], [90, 91], [90, 92], [92, 94], [94, 95], [94, 96], [96, 102], [103, 104], [103, 105], [107, 109], [107, 116], [109, 110]], "missing_branches": [[70, 77], [92, 93], [96, 98], [109, 113]]}, "VCSIgnoreParser.__init__": {"executed_lines": [150, 151, 152, 153, 154, 155, 156, 158, 159, 160, 161, 162, 163], "summary": {"covered_lines": 13, "num_statements": 15, "percent_covered": 91.30434782608695, "percent_covered_display": "91", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 86.66666666666667, "percent_statements_covered_display": "87", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 8, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [166, 167], "excluded_lines": [], "start_line": 149, "executed_branches": [[151, 152], [151, 155], [153, 151], [153, 154], [159, -149], [159, 160], [161, -149], [161, 162]], "missing_branches": []}, "VCSIgnoreParser.from_file": {"executed_lines": [172, 173, 174, 175, 178, 179], "summary": {"covered_lines": 6, "num_statements": 8, "percent_covered": 80.0, "percent_covered_display": "80", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 75.0, "percent_statements_covered_display": "75", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [176, 177], "excluded_lines": [], "start_line": 170, "executed_branches": [[172, 173], [172, 174]], "missing_branches": []}, "VCSIgnoreParser.is_excluded": {"executed_lines": [188, 189, 192, 193, 196, 197, 199, 200, 201, 202, 203, 204, 205], "summary": {"covered_lines": 13, "num_statements": 13, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 12, "num_partial_branches": 0, "covered_branches": 12, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 181, "executed_branches": [[188, 189], [188, 192], [192, 193], [192, 196], [196, 197], [196, 199], [200, 201], [200, 205], [201, 202], [201, 203], [203, 200], [203, 204]], "missing_branches": []}, "VCSIgnoreParser._parse_line": {"executed_lines": [211, 212, 213, 216, 218, 220, 221, 224, 225, 228, 229, 230, 231, 232, 233, 237, 238, 239, 240, 244, 245, 246, 247, 248, 249, 252, 254, 256, 257, 258, 260, 263, 264, 265, 267, 269, 270, 274], "summary": {"covered_lines": 38, "num_statements": 42, "percent_covered": 89.70588235294117, "percent_covered_display": "90", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 90.47619047619048, "percent_statements_covered_display": "90", "num_branches": 26, "num_partial_branches": 3, "covered_branches": 23, "missing_branches": 3, "percent_branches_covered": 88.46153846153847, "percent_branches_covered_display": "88"}, "missing_lines": [234, 241, 271, 272], "excluded_lines": [], "start_line": 208, "executed_branches": [[212, 213], [212, 216], [216, 218], [216, 224], [220, 221], [224, 225], [224, 228], [230, 231], [230, 237], [233, 237], [238, 239], [238, 244], [240, 244], [245, 246], [245, 248], [248, 249], [248, 252], [254, 256], [254, 263], [257, 258], [257, 260], [264, 265], [264, 267]], "missing_branches": [[220, 224], [233, 234], [240, 241]]}, "LayeredExclusionManager.__init__": {"executed_lines": [323, 326, 327, 330, 331, 334, 335, 338, 339, 340, 343, 348, 349, 350, 351, 352, 353, 354, 355, 356, 358, 359, 360, 361, 362, 364, 365, 366, 367, 368, 369, 370, 371, 376], "summary": {"covered_lines": 34, "num_statements": 36, "percent_covered": 86.0, "percent_covered_display": "86", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 94.44444444444444, "percent_statements_covered_display": "94", "num_branches": 14, "num_partial_branches": 5, "covered_branches": 9, "missing_branches": 5, "percent_branches_covered": 64.28571428571429, "percent_branches_covered_display": "64"}, "missing_lines": [374, 375], "excluded_lines": [], "start_line": 314, "executed_branches": [[350, -314], [350, 351], [352, 353], [354, 355], [356, 358], [359, 360], [359, 361], [367, 368], [369, 370]], "missing_branches": [[352, 354], [354, 356], [356, -314], [367, 376], [369, 376]]}, "LayeredExclusionManager.should_exclude_dir": {"executed_lines": [384, 385, 388, 389, 392, 393, 396, 397, 400, 406, 407, 410], "summary": {"covered_lines": 12, "num_statements": 15, "percent_covered": 79.3103448275862, "percent_covered_display": "79", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 80.0, "percent_statements_covered_display": "80", "num_branches": 14, "num_partial_branches": 1, "covered_branches": 11, "missing_branches": 3, "percent_branches_covered": 78.57142857142857, "percent_branches_covered_display": "79"}, "missing_lines": [401, 402, 403], "excluded_lines": [], "start_line": 378, "executed_branches": [[384, 385], [384, 388], [388, 389], [388, 392], [392, 393], [392, 396], [396, 397], [396, 400], [400, 406], [406, 407], [406, 410]], "missing_branches": [[400, 401], [402, 403], [402, 406]]}, "LayeredExclusionManager.should_exclude_file": {"executed_lines": [417, 418, 419, 424, 425, 429, 430, 431, 434, 435, 439, 440, 444, 445, 449, 450, 451, 454, 455, 456, 459, 460, 464], "summary": {"covered_lines": 23, "num_statements": 30, "percent_covered": 80.64516129032258, "percent_covered_display": "81", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 76.66666666666667, "percent_statements_covered_display": "77", "num_branches": 32, "num_partial_branches": 5, "covered_branches": 27, "missing_branches": 5, "percent_branches_covered": 84.375, "percent_branches_covered_display": "84"}, "missing_lines": [420, 421, 426, 436, 441, 446, 461], "excluded_lines": [], "start_line": 412, "executed_branches": [[424, 425], [424, 429], [425, 424], [429, 430], [429, 434], [430, 431], [430, 434], [434, 435], [434, 439], [435, 434], [439, 440], [439, 444], [440, 439], [444, 445], [444, 449], [445, 444], [449, 450], [449, 454], [450, 451], [450, 454], [454, 455], [454, 459], [455, 456], [455, 459], [459, 460], [459, 464], [460, 459]], "missing_branches": [[425, 426], [435, 436], [440, 441], [445, 446], [460, 461]]}, "LayeredExclusionManager.excluded_dirs": {"executed_lines": [474], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 467, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [27, 29, 30, 31, 32, 33, 35, 45, 122, 123, 126, 127, 128, 129, 132, 147, 149, 169, 170, 181, 207, 208, 285, 302, 314, 378, 412, 466, 467], "summary": {"covered_lines": 29, "num_statements": 29, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 2, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [38, 39], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"_GitignoreRule": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 123, "executed_branches": [], "missing_branches": []}, "VCSIgnoreParser": {"executed_lines": [150, 151, 152, 153, 154, 155, 156, 158, 159, 160, 161, 162, 163, 172, 173, 174, 175, 178, 179, 188, 189, 192, 193, 196, 197, 199, 200, 201, 202, 203, 204, 205, 211, 212, 213, 216, 218, 220, 221, 224, 225, 228, 229, 230, 231, 232, 233, 237, 238, 239, 240, 244, 245, 246, 247, 248, 249, 252, 254, 256, 257, 258, 260, 263, 264, 265, 267, 269, 270, 274], "summary": {"covered_lines": 70, "num_statements": 78, "percent_covered": 91.26984126984127, "percent_covered_display": "91", "missing_lines": 8, "excluded_lines": 0, "percent_statements_covered": 89.74358974358974, "percent_statements_covered_display": "90", "num_branches": 48, "num_partial_branches": 3, "covered_branches": 45, "missing_branches": 3, "percent_branches_covered": 93.75, "percent_branches_covered_display": "94"}, "missing_lines": [166, 167, 176, 177, 234, 241, 271, 272], "excluded_lines": [], "start_line": 132, "executed_branches": [[151, 152], [151, 155], [153, 151], [153, 154], [159, -149], [159, 160], [161, -149], [161, 162], [172, 173], [172, 174], [188, 189], [188, 192], [192, 193], [192, 196], [196, 197], [196, 199], [200, 201], [200, 205], [201, 202], [201, 203], [203, 200], [203, 204], [212, 213], [212, 216], [216, 218], [216, 224], [220, 221], [224, 225], [224, 228], [230, 231], [230, 237], [233, 237], [238, 239], [238, 244], [240, 244], [245, 246], [245, 248], [248, 249], [248, 252], [254, 256], [254, 263], [257, 258], [257, 260], [264, 265], [264, 267]], "missing_branches": [[220, 224], [233, 234], [240, 241]]}, "LayeredExclusionManager": {"executed_lines": [323, 326, 327, 330, 331, 334, 335, 338, 339, 340, 343, 348, 349, 350, 351, 352, 353, 354, 355, 356, 358, 359, 360, 361, 362, 364, 365, 366, 367, 368, 369, 370, 371, 376, 384, 385, 388, 389, 392, 393, 396, 397, 400, 406, 407, 410, 417, 418, 419, 424, 425, 429, 430, 431, 434, 435, 439, 440, 444, 445, 449, 450, 451, 454, 455, 456, 459, 460, 464, 474], "summary": {"covered_lines": 70, "num_statements": 82, "percent_covered": 82.3943661971831, "percent_covered_display": "82", "missing_lines": 12, "excluded_lines": 0, "percent_statements_covered": 85.36585365853658, "percent_statements_covered_display": "85", "num_branches": 60, "num_partial_branches": 11, "covered_branches": 47, "missing_branches": 13, "percent_branches_covered": 78.33333333333333, "percent_branches_covered_display": "78"}, "missing_lines": [374, 375, 401, 402, 403, 420, 421, 426, 436, 441, 446, 461], "excluded_lines": [], "start_line": 285, "executed_branches": [[350, -314], [350, 351], [352, 353], [354, 355], [356, 358], [359, 360], [359, 361], [367, 368], [369, 370], [384, 385], [384, 388], [388, 389], [388, 392], [392, 393], [392, 396], [396, 397], [396, 400], [400, 406], [406, 407], [406, 410], [424, 425], [424, 429], [425, 424], [429, 430], [429, 434], [430, 431], [430, 434], [434, 435], [434, 439], [435, 434], [439, 440], [439, 444], [440, 439], [444, 445], [444, 449], [445, 444], [449, 450], [449, 454], [450, 451], [450, 454], [454, 455], [454, 459], [455, 456], [455, 459], [459, 460], [459, 464], [460, 459]], "missing_branches": [[352, 354], [354, 356], [356, -314], [367, 376], [369, 376], [400, 401], [402, 403], [402, 406], [425, 426], [435, 436], [440, 441], [445, 446], [460, 461]]}, "": {"executed_lines": [27, 29, 30, 31, 32, 33, 35, 45, 56, 57, 58, 60, 61, 62, 63, 65, 67, 68, 69, 70, 72, 73, 74, 82, 83, 84, 85, 86, 87, 89, 90, 91, 92, 94, 95, 96, 102, 103, 104, 105, 106, 107, 109, 110, 111, 116, 117, 119, 122, 123, 126, 127, 128, 129, 132, 147, 149, 169, 170, 181, 207, 208, 285, 302, 314, 378, 412, 466, 467], "summary": {"covered_lines": 69, "num_statements": 77, "percent_covered": 88.57142857142857, "percent_covered_display": "89", "missing_lines": 8, "excluded_lines": 4, "percent_statements_covered": 89.6103896103896, "percent_statements_covered_display": "90", "num_branches": 28, "num_partial_branches": 4, "covered_branches": 24, "missing_branches": 4, "percent_branches_covered": 85.71428571428571, "percent_branches_covered_display": "86"}, "missing_lines": [77, 78, 79, 93, 98, 99, 113, 114], "excluded_lines": [38, 39, 46, 101], "start_line": 1, "executed_branches": [[60, 61], [60, 119], [62, 63], [62, 84], [63, 65], [63, 82], [65, 67], [65, 70], [70, 72], [84, 85], [84, 87], [87, 89], [87, 107], [90, 91], [90, 92], [92, 94], [94, 95], [94, 96], [96, 102], [103, 104], [103, 105], [107, 109], [107, 116], [109, 110]], "missing_branches": [[70, 77], [92, 93], [96, 98], [109, 113]]}}}, "src/zenzic/core/logging.py": {"executed_lines": [19, 21, 23, 26, 29, 48, 64, 65, 68, 75, 76, 77], "summary": {"covered_lines": 12, "num_statements": 16, "percent_covered": 65.0, "percent_covered_display": "65", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 75.0, "percent_statements_covered_display": "75", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 3, "percent_branches_covered": 25.0, "percent_branches_covered_display": "25"}, "missing_lines": [43, 44, 45, 66], "excluded_lines": [], "executed_branches": [[65, 68]], "missing_branches": [[43, 44], [43, 45], [65, 66]], "functions": {"get_logger": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 3, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0"}, "missing_lines": [43, 44, 45], "excluded_lines": [], "start_line": 29, "executed_branches": [], "missing_branches": [[43, 44], [43, 45]]}, "setup_cli_logging": {"executed_lines": [64, 65, 68, 75, 76, 77], "summary": {"covered_lines": 6, "num_statements": 7, "percent_covered": 77.77777777777777, "percent_covered_display": "78", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 85.71428571428571, "percent_statements_covered_display": "86", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50"}, "missing_lines": [66], "excluded_lines": [], "start_line": 48, "executed_branches": [[65, 68]], "missing_branches": [[65, 66]]}, "": {"executed_lines": [19, 21, 23, 26, 29, 48], "summary": {"covered_lines": 6, "num_statements": 6, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [19, 21, 23, 26, 29, 48, 64, 65, 68, 75, 76, 77], "summary": {"covered_lines": 12, "num_statements": 16, "percent_covered": 65.0, "percent_covered_display": "65", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 75.0, "percent_statements_covered_display": "75", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 3, "percent_branches_covered": 25.0, "percent_branches_covered_display": "25"}, "missing_lines": [43, 44, 45, 66], "excluded_lines": [], "start_line": 1, "executed_branches": [[65, 68]], "missing_branches": [[43, 44], [43, 45], [65, 66]]}}}, "src/zenzic/core/models.py": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 2, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [10, 13], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 2, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [10, 13], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 2, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [10, 13], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "src/zenzic/core/reporter.py": {"executed_lines": [5, 7, 8, 9, 11, 12, 13, 14, 15, 17, 20, 21, 24, 25, 26, 27, 28, 29, 30, 31, 34, 43, 59, 61, 64, 66, 67, 68, 69, 70, 74, 77, 79, 80, 81, 82, 83, 85, 86, 87, 90, 99, 100, 101, 103, 104, 105, 106, 108, 109, 110, 111, 113, 114, 115, 116, 117, 119, 120, 121, 125, 126, 127, 128, 129, 130, 131, 132, 134, 137, 140, 141, 142, 143, 145, 147, 149, 157, 189, 190, 193, 194, 197, 198, 199, 200, 202, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 218, 219, 220, 221, 237, 238, 249, 251, 252, 259, 260, 261, 268, 269, 279, 282, 283, 284, 286, 287, 288, 290, 291, 293, 294, 295, 297, 304, 305, 307, 313, 314, 315, 321, 322, 325, 326, 327, 328, 329, 330, 332, 335, 336, 337, 338, 339, 340, 344, 345, 348, 349, 352, 353, 356, 359, 360, 361, 362, 366, 367, 369, 370, 371, 380, 381, 392, 393, 397, 403, 404, 405, 406, 411, 412, 413], "summary": {"covered_lines": 174, "num_statements": 181, "percent_covered": 95.4356846473029, "percent_covered_display": "95", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 96.13259668508287, "percent_statements_covered_display": "96", "num_branches": 60, "num_partial_branches": 4, "covered_branches": 56, "missing_branches": 4, "percent_branches_covered": 93.33333333333333, "percent_branches_covered_display": "93"}, "missing_lines": [60, 84, 150, 151, 152, 153, 407], "excluded_lines": [], "executed_branches": [[59, 61], [66, 67], [66, 70], [68, 69], [68, 70], [83, 85], [100, 101], [100, 103], [108, 109], [108, 134], [115, 116], [115, 119], [125, 108], [125, 126], [127, 128], [197, 198], [197, 202], [208, 209], [208, 210], [210, 211], [210, 213], [213, 214], [213, 215], [218, 219], [218, 249], [219, 220], [219, 249], [249, 251], [249, 282], [259, 260], [259, 268], [283, 284], [283, 286], [287, 288], [287, 335], [293, 294], [293, 332], [294, 295], [294, 297], [313, 293], [313, 314], [321, 322], [321, 325], [339, 340], [339, 344], [344, 345], [344, 348], [348, 349], [348, 352], [361, 362], [361, 366], [369, 370], [369, 380], [406, 411], [411, 412], [411, 413]], "missing_branches": [[59, 60], [83, 84], [127, 108], [406, 407]], "functions": {"_obfuscate_secret": {"executed_lines": [59, 61], "summary": {"covered_lines": 2, "num_statements": 3, "percent_covered": 60.0, "percent_covered_display": "60", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 66.66666666666667, "percent_statements_covered_display": "67", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50"}, "missing_lines": [60], "excluded_lines": [], "start_line": 43, "executed_branches": [[59, 61]], "missing_branches": [[59, 60]]}, "_strip_prefix": {"executed_lines": [66, 67, 68, 69, 70], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 64, "executed_branches": [[66, 67], [66, 70], [68, 69], [68, 70]], "missing_branches": []}, "_read_snippet": {"executed_lines": [79, 80, 81, 82, 83, 85, 86, 87], "summary": {"covered_lines": 8, "num_statements": 9, "percent_covered": 81.81818181818181, "percent_covered_display": "82", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 88.88888888888889, "percent_statements_covered_display": "89", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50"}, "missing_lines": [84], "excluded_lines": [], "start_line": 77, "executed_branches": [[83, 85]], "missing_branches": [[83, 84]]}, "_render_snippet": {"executed_lines": [99, 100, 101, 103, 104, 105, 106, 108, 109, 110, 111, 113, 114, 115, 116, 117, 119, 120, 121, 125, 126, 127, 128, 129, 130, 131, 132, 134], "summary": {"covered_lines": 28, "num_statements": 28, "percent_covered": 97.36842105263158, "percent_covered_display": "97", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 10, "num_partial_branches": 1, "covered_branches": 9, "missing_branches": 1, "percent_branches_covered": 90.0, "percent_branches_covered_display": "90"}, "missing_lines": [], "excluded_lines": [], "start_line": 90, "executed_branches": [[100, 101], [100, 103], [108, 109], [108, 134], [115, 116], [115, 119], [125, 108], [125, 126], [127, 128]], "missing_branches": [[127, 108]]}, "SentinelReporter.__init__": {"executed_lines": [141, 142, 143], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 140, "executed_branches": [], "missing_branches": []}, "SentinelReporter._full_rel": {"executed_lines": [147], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 145, "executed_branches": [], "missing_branches": []}, "SentinelReporter._rel": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [150, 151, 152, 153], "excluded_lines": [], "start_line": 149, "executed_branches": [], "missing_branches": []}, "SentinelReporter.render": {"executed_lines": [189, 190, 193, 194, 197, 198, 199, 200, 202, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 218, 219, 220, 221, 237, 238, 249, 251, 252, 259, 260, 261, 268, 269, 279, 282, 283, 284, 286, 287, 288, 290, 291, 293, 294, 295, 297, 304, 305, 307, 313, 314, 315, 321, 322, 325, 326, 327, 328, 329, 330, 332, 335, 336, 337, 338, 339, 340, 344, 345, 348, 349, 352, 353, 356, 359, 360, 361, 362, 366, 367, 369, 370, 371, 380, 381, 392, 393], "summary": {"covered_lines": 88, "num_statements": 88, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 38, "num_partial_branches": 0, "covered_branches": 38, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 157, "executed_branches": [[197, 198], [197, 202], [208, 209], [208, 210], [210, 211], [210, 213], [213, 214], [213, 215], [218, 219], [218, 249], [219, 220], [219, 249], [249, 251], [249, 282], [259, 260], [259, 268], [283, 284], [283, 286], [287, 288], [287, 335], [293, 294], [293, 332], [294, 295], [294, 297], [313, 293], [313, 314], [321, 322], [321, 325], [339, 340], [339, 344], [344, 345], [344, 348], [348, 349], [348, 352], [361, 362], [361, 366], [369, 370], [369, 380]], "missing_branches": []}, "SentinelReporter.render_quiet": {"executed_lines": [403, 404, 405, 406, 411, 412, 413], "summary": {"covered_lines": 7, "num_statements": 8, "percent_covered": 83.33333333333333, "percent_covered_display": "83", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 87.5, "percent_statements_covered_display": "88", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 1, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75"}, "missing_lines": [407], "excluded_lines": [], "start_line": 397, "executed_branches": [[406, 411], [411, 412], [411, 413]], "missing_branches": [[406, 407]]}, "": {"executed_lines": [5, 7, 8, 9, 11, 12, 13, 14, 15, 17, 20, 21, 24, 25, 26, 27, 28, 29, 30, 31, 34, 43, 64, 74, 77, 90, 137, 140, 145, 149, 157, 397], "summary": {"covered_lines": 32, "num_statements": 32, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"Finding": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 21, "executed_branches": [], "missing_branches": []}, "SentinelReporter": {"executed_lines": [141, 142, 143, 147, 189, 190, 193, 194, 197, 198, 199, 200, 202, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 218, 219, 220, 221, 237, 238, 249, 251, 252, 259, 260, 261, 268, 269, 279, 282, 283, 284, 286, 287, 288, 290, 291, 293, 294, 295, 297, 304, 305, 307, 313, 314, 315, 321, 322, 325, 326, 327, 328, 329, 330, 332, 335, 336, 337, 338, 339, 340, 344, 345, 348, 349, 352, 353, 356, 359, 360, 361, 362, 366, 367, 369, 370, 371, 380, 381, 392, 393, 403, 404, 405, 406, 411, 412, 413], "summary": {"covered_lines": 99, "num_statements": 104, "percent_covered": 95.89041095890411, "percent_covered_display": "96", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 95.1923076923077, "percent_statements_covered_display": "95", "num_branches": 42, "num_partial_branches": 1, "covered_branches": 41, "missing_branches": 1, "percent_branches_covered": 97.61904761904762, "percent_branches_covered_display": "98"}, "missing_lines": [150, 151, 152, 153, 407], "excluded_lines": [], "start_line": 137, "executed_branches": [[197, 198], [197, 202], [208, 209], [208, 210], [210, 211], [210, 213], [213, 214], [213, 215], [218, 219], [218, 249], [219, 220], [219, 249], [249, 251], [249, 282], [259, 260], [259, 268], [283, 284], [283, 286], [287, 288], [287, 335], [293, 294], [293, 332], [294, 295], [294, 297], [313, 293], [313, 314], [321, 322], [321, 325], [339, 340], [339, 344], [344, 345], [344, 348], [348, 349], [348, 352], [361, 362], [361, 366], [369, 370], [369, 380], [406, 411], [411, 412], [411, 413]], "missing_branches": [[406, 407]]}, "": {"executed_lines": [5, 7, 8, 9, 11, 12, 13, 14, 15, 17, 20, 21, 24, 25, 26, 27, 28, 29, 30, 31, 34, 43, 59, 61, 64, 66, 67, 68, 69, 70, 74, 77, 79, 80, 81, 82, 83, 85, 86, 87, 90, 99, 100, 101, 103, 104, 105, 106, 108, 109, 110, 111, 113, 114, 115, 116, 117, 119, 120, 121, 125, 126, 127, 128, 129, 130, 131, 132, 134, 137, 140, 145, 149, 157, 397], "summary": {"covered_lines": 75, "num_statements": 77, "percent_covered": 94.73684210526316, "percent_covered_display": "95", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 97.40259740259741, "percent_statements_covered_display": "97", "num_branches": 18, "num_partial_branches": 3, "covered_branches": 15, "missing_branches": 3, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83"}, "missing_lines": [60, 84], "excluded_lines": [], "start_line": 1, "executed_branches": [[59, 61], [66, 67], [66, 70], [68, 69], [68, 70], [83, 85], [100, 101], [100, 103], [108, 109], [108, 134], [115, 116], [115, 119], [125, 108], [125, 126], [127, 128]], "missing_branches": [[59, 60], [83, 84], [127, 108]]}}}, "src/zenzic/core/resolver.py": {"executed_lines": [41, 43, 44, 45, 46, 52, 64, 67, 75, 78, 88, 89, 90, 93, 100, 104, 110, 139, 148, 154, 158, 159, 162, 165, 178, 179, 180, 181, 182, 183, 184, 185, 186, 190, 208, 210, 211, 212, 215, 221, 222, 225, 226, 227, 230, 231, 232, 233, 239, 243, 244, 258, 259, 260, 262, 263, 275, 277, 296, 297, 298, 301, 305, 306], "summary": {"covered_lines": 64, "num_statements": 66, "percent_covered": 94.31818181818181, "percent_covered_display": "94", "missing_lines": 2, "excluded_lines": 1, "percent_statements_covered": 96.96969696969697, "percent_statements_covered_display": "97", "num_branches": 22, "num_partial_branches": 3, "covered_branches": 19, "missing_branches": 3, "percent_branches_covered": 86.36363636363636, "percent_branches_covered_display": "86"}, "missing_lines": [300, 303], "excluded_lines": [191], "executed_branches": [[179, 180], [179, 186], [182, 183], [184, 179], [184, 185], [221, 222], [221, 225], [226, 227], [226, 230], [230, 231], [230, 239], [232, 233], [232, 239], [258, 259], [258, 260], [296, 297], [296, 298], [298, 301], [301, 305]], "missing_branches": [[182, 184], [298, 300], [301, 303]], "functions": {"InMemoryPathResolver.__init__": {"executed_lines": [154, 158, 159, 162, 165, 178, 179, 180, 181, 182, 183, 184, 185, 186], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 95.0, "percent_covered_display": "95", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 6, "num_partial_branches": 1, "covered_branches": 5, "missing_branches": 1, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83"}, "missing_lines": [], "excluded_lines": [], "start_line": 148, "executed_branches": [[179, 180], [179, 186], [182, 183], [184, 179], [184, 185]], "missing_branches": [[182, 184]]}, "InMemoryPathResolver.resolve": {"executed_lines": [208, 210, 211, 212, 215, 221, 222, 225, 226, 227, 230, 231, 232, 233, 239], "summary": {"covered_lines": 15, "num_statements": 15, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 1, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 8, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [191], "start_line": 190, "executed_branches": [[221, 222], [221, 225], [226, 227], [226, 230], [230, 231], [230, 239], [232, 233], [232, 239]], "missing_branches": []}, "InMemoryPathResolver._coerce_path": {"executed_lines": [258, 259, 260], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 244, "executed_branches": [[258, 259], [258, 260]], "missing_branches": []}, "InMemoryPathResolver._normalize_href": {"executed_lines": [275], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 263, "executed_branches": [], "missing_branches": []}, "InMemoryPathResolver._build_target": {"executed_lines": [296, 297, 298, 301, 305, 306], "summary": {"covered_lines": 6, "num_statements": 8, "percent_covered": 71.42857142857143, "percent_covered_display": "71", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 75.0, "percent_statements_covered_display": "75", "num_branches": 6, "num_partial_branches": 2, "covered_branches": 4, "missing_branches": 2, "percent_branches_covered": 66.66666666666667, "percent_branches_covered_display": "67"}, "missing_lines": [300, 303], "excluded_lines": [], "start_line": 277, "executed_branches": [[296, 297], [296, 298], [298, 301], [301, 305]], "missing_branches": [[298, 300], [301, 303]]}, "": {"executed_lines": [41, 43, 44, 45, 46, 52, 64, 67, 75, 78, 88, 89, 90, 93, 100, 104, 110, 139, 148, 190, 243, 244, 262, 263, 277], "summary": {"covered_lines": 25, "num_statements": 25, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"PathTraversal": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 52, "executed_branches": [], "missing_branches": []}, "FileNotFound": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 67, "executed_branches": [], "missing_branches": []}, "AnchorMissing": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 78, "executed_branches": [], "missing_branches": []}, "Resolved": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 93, "executed_branches": [], "missing_branches": []}, "InMemoryPathResolver": {"executed_lines": [154, 158, 159, 162, 165, 178, 179, 180, 181, 182, 183, 184, 185, 186, 208, 210, 211, 212, 215, 221, 222, 225, 226, 227, 230, 231, 232, 233, 239, 258, 259, 260, 275, 296, 297, 298, 301, 305, 306], "summary": {"covered_lines": 39, "num_statements": 41, "percent_covered": 92.06349206349206, "percent_covered_display": "92", "missing_lines": 2, "excluded_lines": 1, "percent_statements_covered": 95.1219512195122, "percent_statements_covered_display": "95", "num_branches": 22, "num_partial_branches": 3, "covered_branches": 19, "missing_branches": 3, "percent_branches_covered": 86.36363636363636, "percent_branches_covered_display": "86"}, "missing_lines": [300, 303], "excluded_lines": [191], "start_line": 110, "executed_branches": [[179, 180], [179, 186], [182, 183], [184, 179], [184, 185], [221, 222], [221, 225], [226, 227], [226, 230], [230, 231], [230, 239], [232, 233], [232, 239], [258, 259], [258, 260], [296, 297], [296, 298], [298, 301], [301, 305]], "missing_branches": [[182, 184], [298, 300], [301, 303]]}, "": {"executed_lines": [41, 43, 44, 45, 46, 52, 64, 67, 75, 78, 88, 89, 90, 93, 100, 104, 110, 139, 148, 190, 243, 244, 262, 263, 277], "summary": {"covered_lines": 25, "num_statements": 25, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "src/zenzic/core/rules.py": {"executed_lines": [62, 64, 65, 66, 67, 68, 69, 70, 82, 83, 97, 98, 103, 106, 107, 121, 122, 123, 124, 125, 126, 127, 128, 130, 131, 133, 139, 140, 171, 172, 173, 174, 175, 176, 177, 178, 180, 181, 183, 185, 187, 202, 230, 231, 232, 238, 239, 256, 305, 306, 333, 334, 335, 336, 337, 339, 340, 341, 342, 343, 347, 348, 349, 351, 353, 354, 355, 356, 357, 369, 375, 388, 390, 391, 392, 393, 410, 413, 435, 436, 438, 440, 441, 443, 444, 446, 447, 448, 449, 450, 451, 452, 453, 462, 464, 467, 492, 493, 494, 495, 496, 498, 500, 502, 517, 518, 519, 520, 521, 522, 534, 536, 564, 565, 566, 567, 568, 569, 570, 582, 589, 591, 594, 605, 606, 607, 608, 609, 610, 611, 612, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 628, 653, 667, 668, 669, 671, 673, 675, 705, 707, 709, 710, 711, 712, 719, 724, 725, 727, 728, 729, 742, 743, 757, 758, 773, 775, 809, 810, 812, 813, 814, 815, 822, 823, 824, 825, 826, 827, 828, 831, 834, 835, 838, 839, 841, 842, 843, 846, 852, 853, 864, 865, 866, 867, 870, 877, 878, 880, 882, 884, 886, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 906, 907, 916, 917, 919, 921, 924, 925, 926, 927, 929, 938, 940, 941, 942, 943, 944, 945, 946, 947, 948, 950, 951, 952, 953, 955, 956, 957, 962, 963, 964, 965, 967, 968, 970, 972, 973, 974, 980, 985, 988, 1000], "summary": {"covered_lines": 257, "num_statements": 265, "percent_covered": 96.50145772594752, "percent_covered_display": "97", "missing_lines": 8, "excluded_lines": 4, "percent_statements_covered": 96.98113207547169, "percent_statements_covered_display": "97", "num_branches": 78, "num_partial_branches": 4, "covered_branches": 74, "missing_branches": 4, "percent_branches_covered": 94.87179487179488, "percent_branches_covered_display": "95"}, "missing_lines": [299, 829, 830, 840, 844, 975, 976, 981], "excluded_lines": [73, 74, 76, 405], "executed_branches": [[354, 355], [354, 369], [356, 354], [356, 357], [440, 441], [440, 443], [448, 449], [448, 464], [493, 494], [493, 496], [518, 519], [518, 534], [565, 566], [565, 582], [607, 608], [607, 625], [609, 610], [609, 614], [610, 611], [610, 617], [614, 615], [614, 616], [618, 607], [618, 619], [620, 621], [620, 622], [623, 624], [707, 709], [707, 773], [709, 710], [709, 711], [711, 712], [711, 719], [724, 725], [724, 727], [728, 729], [728, 742], [742, 743], [742, 757], [757, 707], [757, 758], [814, 815], [814, 822], [822, 823], [822, 834], [825, 826], [825, 827], [834, 835], [834, 838], [839, 841], [841, 842], [841, 843], [843, 846], [889, 890], [889, 906], [893, 894], [893, 897], [906, 907], [906, 916], [925, 926], [925, 927], [942, 943], [942, 947], [944, 942], [944, 945], [947, 948], [947, 950], [951, 952], [951, 955], [956, 957], [956, 962], [963, 964], [963, 965], [980, 985]], "missing_branches": [[623, 618], [839, 840], [843, 844], [980, 981]], "functions": {"RuleFinding.is_error": {"executed_lines": [133], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 131, "executed_branches": [], "missing_branches": []}, "Violation.is_error": {"executed_lines": [183], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 181, "executed_branches": [], "missing_branches": []}, "Violation.as_finding": {"executed_lines": [187], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 185, "executed_branches": [], "missing_branches": []}, "BaseRule.rule_id": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 232, "executed_branches": [], "missing_branches": []}, "BaseRule.check": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 239, "executed_branches": [], "missing_branches": []}, "BaseRule.check_vsm": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [299], "excluded_lines": [], "start_line": 256, "executed_branches": [], "missing_branches": []}, "CustomRule.__post_init__": {"executed_lines": [340, 341, 342, 343], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 339, "executed_branches": [], "missing_branches": []}, "CustomRule.rule_id": {"executed_lines": [349], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 348, "executed_branches": [], "missing_branches": []}, "CustomRule.check": {"executed_lines": [353, 354, 355, 356, 357, 369], "summary": {"covered_lines": 6, "num_statements": 6, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 351, "executed_branches": [[354, 355], [354, 369], [356, 354], [356, 357]], "missing_branches": []}, "_assert_pickleable": {"executed_lines": [388, 390, 391, 392, 393], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 375, "executed_branches": [], "missing_branches": []}, "_assert_regex_canary": {"executed_lines": [435, 436, 438, 440, 441, 443, 446, 447, 448, 449, 450, 451, 452, 453, 462, 464], "summary": {"covered_lines": 16, "num_statements": 16, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 413, "executed_branches": [[440, 441], [440, 443], [448, 449], [448, 464]], "missing_branches": []}, "_assert_regex_canary._alarm": {"executed_lines": [444], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 443, "executed_branches": [], "missing_branches": []}, "AdaptiveRuleEngine.__init__": {"executed_lines": [493, 494, 495, 496], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 492, "executed_branches": [[493, 494], [493, 496]], "missing_branches": []}, "AdaptiveRuleEngine.__bool__": {"executed_lines": [500], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 498, "executed_branches": [], "missing_branches": []}, "AdaptiveRuleEngine.run": {"executed_lines": [517, 518, 519, 520, 521, 522, 534], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 502, "executed_branches": [[518, 519], [518, 534]], "missing_branches": []}, "AdaptiveRuleEngine.run_vsm": {"executed_lines": [564, 565, 566, 567, 568, 569, 570, 582], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 536, "executed_branches": [[565, 566], [565, 582]], "missing_branches": []}, "_extract_inline_links_with_lines": {"executed_lines": [605, 606, 607, 608, 609, 610, 611, 612, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625], "summary": {"covered_lines": 20, "num_statements": 20, "percent_covered": 97.05882352941177, "percent_covered_display": "97", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 14, "num_partial_branches": 1, "covered_branches": 13, "missing_branches": 1, "percent_branches_covered": 92.85714285714286, "percent_branches_covered_display": "93"}, "missing_lines": [], "excluded_lines": [], "start_line": 594, "executed_branches": [[607, 608], [607, 625], [609, 610], [609, 614], [610, 611], [610, 617], [614, 615], [614, 616], [618, 607], [618, 619], [620, 621], [620, 622], [623, 624]], "missing_branches": [[623, 618]]}, "VSMBrokenLinkRule.rule_id": {"executed_lines": [669], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 668, "executed_branches": [], "missing_branches": []}, "VSMBrokenLinkRule.check": {"executed_lines": [673], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 671, "executed_branches": [], "missing_branches": []}, "VSMBrokenLinkRule.check_vsm": {"executed_lines": [705, 707, 709, 710, 711, 712, 719, 724, 725, 727, 728, 729, 742, 743, 757, 758, 773], "summary": {"covered_lines": 17, "num_statements": 17, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 14, "num_partial_branches": 0, "covered_branches": 14, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 675, "executed_branches": [[707, 709], [707, 773], [709, 710], [709, 711], [711, 712], [711, 719], [724, 725], [724, 727], [728, 729], [728, 742], [742, 743], [742, 757], [757, 707], [757, 758]], "missing_branches": []}, "VSMBrokenLinkRule._to_canonical_url": {"executed_lines": [809, 810, 812, 813, 814, 815, 822, 823, 824, 825, 826, 827, 828, 831, 834, 835, 838, 839, 841, 842, 843, 846], "summary": {"covered_lines": 22, "num_statements": 26, "percent_covered": 85.0, "percent_covered_display": "85", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 84.61538461538461, "percent_statements_covered_display": "85", "num_branches": 14, "num_partial_branches": 2, "covered_branches": 12, "missing_branches": 2, "percent_branches_covered": 85.71428571428571, "percent_branches_covered_display": "86"}, "missing_lines": [829, 830, 840, 844], "excluded_lines": [], "start_line": 775, "executed_branches": [[814, 815], [814, 822], [822, 823], [822, 834], [825, 826], [825, 827], [834, 835], [834, 838], [839, 841], [841, 842], [841, 843], [843, 846]], "missing_branches": [[839, 840], [843, 844]]}, "PluginRegistry.__init__": {"executed_lines": [878], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 877, "executed_branches": [], "missing_branches": []}, "PluginRegistry._entry_points": {"executed_lines": [882, 884], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 880, "executed_branches": [], "missing_branches": []}, "PluginRegistry.list_rules": {"executed_lines": [888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 906, 907, 916, 917], "summary": {"covered_lines": 15, "num_statements": 15, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 6, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 886, "executed_branches": [[889, 890], [889, 906], [893, 894], [893, 897], [906, 907], [906, 916]], "missing_branches": []}, "PluginRegistry.load_core_rules": {"executed_lines": [921, 924, 925, 926, 927], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 919, "executed_branches": [[925, 926], [925, 927]], "missing_branches": []}, "PluginRegistry.load_selected_rules": {"executed_lines": [938, 940, 941, 942, 943, 944, 945, 946, 947, 948, 950, 951, 952, 953, 955, 956, 957, 962, 963, 964, 965], "summary": {"covered_lines": 21, "num_statements": 21, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 12, "num_partial_branches": 0, "covered_branches": 12, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 929, "executed_branches": [[942, 943], [942, 947], [944, 942], [944, 945], [947, 948], [947, 950], [951, 952], [951, 955], [956, 957], [956, 962], [963, 964], [963, 965]], "missing_branches": []}, "PluginRegistry._load_entry_point": {"executed_lines": [970, 972, 973, 974, 980, 985], "summary": {"covered_lines": 6, "num_statements": 9, "percent_covered": 63.63636363636363, "percent_covered_display": "64", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 66.66666666666667, "percent_statements_covered_display": "67", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50"}, "missing_lines": [975, 976, 981], "excluded_lines": [], "start_line": 968, "executed_branches": [[980, 985]], "missing_branches": [[980, 981]]}, "list_plugin_rules": {"executed_lines": [1000], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 988, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [62, 64, 65, 66, 67, 68, 69, 70, 82, 83, 97, 98, 103, 106, 107, 121, 122, 123, 124, 125, 126, 127, 128, 130, 131, 139, 140, 171, 172, 173, 174, 175, 176, 177, 178, 180, 181, 185, 202, 230, 231, 232, 238, 239, 256, 305, 306, 333, 334, 335, 336, 337, 339, 347, 348, 351, 375, 410, 413, 467, 492, 498, 502, 536, 589, 591, 594, 628, 653, 667, 668, 671, 675, 775, 852, 853, 864, 865, 866, 867, 870, 877, 880, 886, 919, 929, 967, 968, 988], "summary": {"covered_lines": 89, "num_statements": 89, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 4, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [73, 74, 76, 405], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"ResolutionContext": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 83, "executed_branches": [], "missing_branches": []}, "RuleFinding": {"executed_lines": [133], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 107, "executed_branches": [], "missing_branches": []}, "Violation": {"executed_lines": [183, 187], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 140, "executed_branches": [], "missing_branches": []}, "BaseRule": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 1, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [299], "excluded_lines": [], "start_line": 202, "executed_branches": [], "missing_branches": []}, "CustomRule": {"executed_lines": [340, 341, 342, 343, 349, 353, 354, 355, 356, 357, 369], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 306, "executed_branches": [[354, 355], [354, 369], [356, 354], [356, 357]], "missing_branches": []}, "AdaptiveRuleEngine": {"executed_lines": [493, 494, 495, 496, 500, 517, 518, 519, 520, 521, 522, 534, 564, 565, 566, 567, 568, 569, 570, 582], "summary": {"covered_lines": 20, "num_statements": 20, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 6, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 467, "executed_branches": [[493, 494], [493, 496], [518, 519], [518, 534], [565, 566], [565, 582]], "missing_branches": []}, "VSMBrokenLinkRule": {"executed_lines": [669, 673, 705, 707, 709, 710, 711, 712, 719, 724, 725, 727, 728, 729, 742, 743, 757, 758, 773, 809, 810, 812, 813, 814, 815, 822, 823, 824, 825, 826, 827, 828, 831, 834, 835, 838, 839, 841, 842, 843, 846], "summary": {"covered_lines": 41, "num_statements": 45, "percent_covered": 91.78082191780823, "percent_covered_display": "92", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 91.11111111111111, "percent_statements_covered_display": "91", "num_branches": 28, "num_partial_branches": 2, "covered_branches": 26, "missing_branches": 2, "percent_branches_covered": 92.85714285714286, "percent_branches_covered_display": "93"}, "missing_lines": [829, 830, 840, 844], "excluded_lines": [], "start_line": 628, "executed_branches": [[707, 709], [707, 773], [709, 710], [709, 711], [711, 712], [711, 719], [724, 725], [724, 727], [728, 729], [728, 742], [742, 743], [742, 757], [757, 707], [757, 758], [814, 815], [814, 822], [822, 823], [822, 834], [825, 826], [825, 827], [834, 835], [834, 838], [839, 841], [841, 842], [841, 843], [843, 846]], "missing_branches": [[839, 840], [843, 844]]}, "PluginRuleInfo": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 853, "executed_branches": [], "missing_branches": []}, "PluginRegistry": {"executed_lines": [878, 882, 884, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 906, 907, 916, 917, 921, 924, 925, 926, 927, 938, 940, 941, 942, 943, 944, 945, 946, 947, 948, 950, 951, 952, 953, 955, 956, 957, 962, 963, 964, 965, 970, 972, 973, 974, 980, 985], "summary": {"covered_lines": 50, "num_statements": 53, "percent_covered": 94.66666666666667, "percent_covered_display": "95", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 94.33962264150944, "percent_statements_covered_display": "94", "num_branches": 22, "num_partial_branches": 1, "covered_branches": 21, "missing_branches": 1, "percent_branches_covered": 95.45454545454545, "percent_branches_covered_display": "95"}, "missing_lines": [975, 976, 981], "excluded_lines": [], "start_line": 870, "executed_branches": [[889, 890], [889, 906], [893, 894], [893, 897], [906, 907], [906, 916], [925, 926], [925, 927], [942, 943], [942, 947], [944, 942], [944, 945], [947, 948], [947, 950], [951, 952], [951, 955], [956, 957], [956, 962], [963, 964], [963, 965], [980, 985]], "missing_branches": [[980, 981]]}, "": {"executed_lines": [62, 64, 65, 66, 67, 68, 69, 70, 82, 83, 97, 98, 103, 106, 107, 121, 122, 123, 124, 125, 126, 127, 128, 130, 131, 139, 140, 171, 172, 173, 174, 175, 176, 177, 178, 180, 181, 185, 202, 230, 231, 232, 238, 239, 256, 305, 306, 333, 334, 335, 336, 337, 339, 347, 348, 351, 375, 388, 390, 391, 392, 393, 410, 413, 435, 436, 438, 440, 441, 443, 444, 446, 447, 448, 449, 450, 451, 452, 453, 462, 464, 467, 492, 498, 502, 536, 589, 591, 594, 605, 606, 607, 608, 609, 610, 611, 612, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, 625, 628, 653, 667, 668, 671, 675, 775, 852, 853, 864, 865, 866, 867, 870, 877, 880, 886, 919, 929, 967, 968, 988, 1000], "summary": {"covered_lines": 132, "num_statements": 132, "percent_covered": 99.33333333333333, "percent_covered_display": "99", "missing_lines": 0, "excluded_lines": 4, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 18, "num_partial_branches": 1, "covered_branches": 17, "missing_branches": 1, "percent_branches_covered": 94.44444444444444, "percent_branches_covered_display": "94"}, "missing_lines": [], "excluded_lines": [73, 74, 76, 405], "start_line": 1, "executed_branches": [[440, 441], [440, 443], [448, 449], [448, 464], [607, 608], [607, 625], [609, 610], [609, 614], [610, 611], [610, 617], [614, 615], [614, 616], [618, 607], [618, 619], [620, 621], [620, 622], [623, 624]], "missing_branches": [[623, 618]]}}}, "src/zenzic/core/scanner.py": {"executed_lines": [15, 17, 18, 19, 20, 21, 22, 23, 24, 26, 27, 33, 34, 35, 36, 37, 38, 49, 53, 58, 61, 64, 65, 68, 71, 94, 95, 96, 97, 99, 100, 102, 111, 121, 124, 143, 144, 148, 160, 161, 162, 163, 164, 165, 166, 167, 170, 185, 186, 188, 189, 190, 192, 193, 194, 203, 204, 205, 206, 207, 218, 221, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 245, 255, 261, 279, 280, 282, 284, 285, 287, 288, 290, 291, 292, 293, 294, 295, 296, 297, 298, 300, 303, 323, 325, 326, 328, 329, 330, 331, 333, 334, 335, 343, 346, 367, 368, 370, 373, 374, 375, 376, 377, 378, 379, 380, 382, 383, 385, 387, 388, 394, 395, 396, 400, 401, 403, 404, 405, 406, 407, 408, 409, 410, 413, 414, 415, 426, 438, 441, 457, 458, 460, 461, 463, 464, 465, 466, 467, 469, 472, 474, 477, 501, 503, 504, 505, 508, 509, 510, 511, 513, 514, 515, 517, 520, 538, 539, 541, 543, 544, 545, 546, 547, 558, 559, 560, 561, 562, 563, 573, 576, 599, 600, 601, 602, 606, 637, 638, 639, 640, 641, 642, 645, 646, 647, 648, 649, 650, 651, 653, 654, 657, 660, 664, 665, 668, 669, 670, 671, 672, 674, 677, 681, 691, 693, 695, 697, 698, 699, 700, 701, 702, 703, 716, 720, 724, 741, 744, 745, 746, 757, 758, 759, 772, 783, 807, 808, 811, 812, 813, 816, 817, 818, 821, 826, 827, 828, 832, 833, 836, 847, 851, 852, 854, 855, 856, 865, 868, 869, 870, 871, 872, 874, 875, 877, 879, 882, 899, 901, 906, 907, 908, 909, 910, 912, 921, 990, 992, 993, 995, 996, 998, 999, 1005, 1006, 1014, 1015, 1017, 1019, 1021, 1022, 1023, 1025, 1026, 1029, 1033, 1034, 1035, 1036, 1037, 1043, 1046, 1051, 1052, 1053, 1060, 1061, 1078, 1079, 1081, 1082, 1083, 1084, 1087, 1088, 1089, 1096, 1098, 1102, 1106, 1107, 1110, 1114, 1123, 1130, 1133, 1170, 1202], "summary": {"covered_lines": 330, "num_statements": 390, "percent_covered": 81.75675675675676, "percent_covered_display": "82", "missing_lines": 60, "excluded_lines": 10, "percent_statements_covered": 84.61538461538461, "percent_statements_covered_display": "85", "num_branches": 202, "num_partial_branches": 16, "covered_branches": 154, "missing_branches": 48, "percent_branches_covered": 76.23762376237623, "percent_branches_covered_display": "76"}, "missing_lines": [145, 146, 336, 337, 340, 341, 381, 384, 416, 417, 420, 421, 422, 423, 424, 661, 662, 717, 718, 873, 878, 1007, 1008, 1011, 1012, 1038, 1039, 1040, 1041, 1047, 1048, 1049, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1085, 1099, 1100, 1101, 1108, 1111, 1112, 1113, 1147, 1148, 1150, 1161, 1180, 1181, 1183, 1193, 1221, 1222, 1223], "excluded_lines": [41, 42, 444, 470, 471, 480, 633, 837, 1030, 1134], "executed_branches": [[95, 96], [95, 99], [96, 95], [96, 97], [99, 100], [99, 102], [185, 186], [185, 188], [193, 194], [193, 203], [203, 204], [203, 218], [204, 203], [204, 205], [206, 204], [206, 207], [233, 234], [233, 242], [235, 236], [235, 237], [240, 233], [240, 241], [279, 280], [279, 282], [284, 285], [284, 287], [291, 292], [291, 300], [293, 294], [293, 295], [295, 296], [295, 297], [297, 291], [297, 298], [325, 326], [325, 328], [328, 329], [328, 333], [333, 334], [333, 343], [335, 343], [367, 368], [367, 370], [374, 375], [374, 387], [375, 376], [375, 377], [378, 379], [378, 380], [380, 382], [383, 385], [387, 388], [387, 394], [395, 396], [395, 400], [400, 401], [400, 403], [404, 405], [404, 413], [408, 409], [408, 410], [413, 414], [413, 426], [415, 426], [460, -441], [460, 461], [463, 464], [463, 469], [465, 466], [465, 469], [504, -477], [504, 505], [508, 509], [508, 513], [509, 510], [509, 517], [513, 514], [513, 515], [541, 543], [541, 573], [543, 544], [543, 558], [546, 543], [546, 547], [558, 541], [558, 559], [562, 558], [562, 563], [640, 641], [640, 645], [646, 647], [646, 677], [648, 649], [648, 668], [653, 654], [653, 664], [657, 660], [657, 665], [660, 657], [668, 646], [668, 669], [671, 672], [671, 674], [693, 695], [693, 720], [697, 698], [697, 716], [701, 697], [701, 702], [716, 693], [744, 745], [744, 757], [757, 758], [757, 772], [811, 812], [811, 816], [812, 811], [812, 813], [817, 818], [817, 821], [826, 827], [826, 832], [851, 852], [851, 854], [870, 871], [870, 877], [872, 874], [877, 879], [908, 909], [908, 912], [992, 993], [992, 995], [995, 996], [995, 998], [1006, 1014], [1014, 1015], [1014, 1017], [1021, 1022], [1021, 1078], [1035, 1036], [1035, 1043], [1046, 1051], [1052, 1053], [1060, 1061], [1081, 1082], [1081, 1087], [1084, 1081], [1088, 1089], [1088, 1096], [1096, 1098], [1096, 1106], [1098, 1102], [1107, 1110], [1110, 1114]], "missing_branches": [[335, 336], [336, 337], [336, 343], [337, 336], [337, 340], [380, 381], [383, 384], [415, 416], [416, 417], [416, 426], [417, 416], [417, 420], [422, 423], [422, 424], [660, 661], [716, 717], [872, 873], [877, 878], [1006, 1007], [1007, 1008], [1007, 1014], [1008, 1007], [1008, 1011], [1046, 1047], [1047, 1048], [1047, 1051], [1048, 1047], [1048, 1049], [1052, 1060], [1060, 1067], [1068, 1069], [1068, 1072], [1070, 1068], [1070, 1071], [1073, 1074], [1073, 1075], [1084, 1085], [1098, 1099], [1099, 1100], [1099, 1102], [1100, 1099], [1100, 1101], [1107, 1108], [1110, 1111], [1111, 1112], [1111, 1114], [1112, 1111], [1112, 1113]], "functions": {"find_repo_root": {"executed_lines": [94, 95, 96, 97, 99, 100, 102], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 6, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 71, "executed_branches": [[95, 96], [95, 99], [96, 95], [96, 97], [99, 100], [99, 102]], "missing_branches": []}, "calculate_orphans": {"executed_lines": [121], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 111, "executed_branches": [], "missing_branches": []}, "_map_shield_to_finding": {"executed_lines": [143, 144, 148], "summary": {"covered_lines": 3, "num_statements": 5, "percent_covered": 60.0, "percent_covered_display": "60", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 60.0, "percent_statements_covered_display": "60", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [145, 146], "excluded_lines": [], "start_line": 124, "executed_branches": [], "missing_branches": []}, "check_placeholder_content": {"executed_lines": [185, 186, 188, 189, 190, 192, 193, 194, 203, 204, 205, 206, 207, 218], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 10, "num_partial_branches": 0, "covered_branches": 10, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 170, "executed_branches": [[185, 186], [185, 188], [193, 194], [193, 203], [203, 204], [203, 218], [204, 203], [204, 205], [206, 204], [206, 207]], "missing_branches": []}, "check_asset_references": {"executed_lines": [232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 6, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 221, "executed_branches": [[233, 234], [233, 242], [235, 236], [235, 237], [240, 233], [240, 241]], "missing_branches": []}, "calculate_unused_assets": {"executed_lines": [255], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 245, "executed_branches": [], "missing_branches": []}, "find_orphans": {"executed_lines": [279, 280, 282, 284, 285, 287, 288, 290, 291, 292, 293, 294, 295, 296, 297, 298, 300], "summary": {"covered_lines": 17, "num_statements": 17, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 12, "num_partial_branches": 0, "covered_branches": 12, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 261, "executed_branches": [[279, 280], [279, 282], [284, 285], [284, 287], [291, 292], [291, 300], [293, 294], [293, 295], [295, 296], [295, 297], [297, 291], [297, 298]], "missing_branches": []}, "find_placeholders": {"executed_lines": [323, 325, 326, 328, 329, 330, 331, 333, 334, 335, 343], "summary": {"covered_lines": 11, "num_statements": 15, "percent_covered": 66.66666666666667, "percent_covered_display": "67", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 73.33333333333333, "percent_statements_covered_display": "73", "num_branches": 12, "num_partial_branches": 1, "covered_branches": 7, "missing_branches": 5, "percent_branches_covered": 58.333333333333336, "percent_branches_covered_display": "58"}, "missing_lines": [336, 337, 340, 341], "excluded_lines": [], "start_line": 303, "executed_branches": [[325, 326], [325, 328], [328, 329], [328, 333], [333, 334], [333, 343], [335, 343]], "missing_branches": [[335, 336], [336, 337], [336, 343], [337, 336], [337, 340]]}, "find_unused_assets": {"executed_lines": [367, 368, 370, 373, 374, 375, 376, 377, 378, 379, 380, 382, 383, 385, 387, 388, 394, 395, 396, 400, 401, 403, 404, 405, 406, 407, 408, 409, 410, 413, 414, 415, 426], "summary": {"covered_lines": 33, "num_statements": 42, "percent_covered": 75.67567567567568, "percent_covered_display": "76", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 78.57142857142857, "percent_statements_covered_display": "79", "num_branches": 32, "num_partial_branches": 3, "covered_branches": 23, "missing_branches": 9, "percent_branches_covered": 71.875, "percent_branches_covered_display": "72"}, "missing_lines": [381, 384, 416, 417, 420, 421, 422, 423, 424], "excluded_lines": [], "start_line": 346, "executed_branches": [[367, 368], [367, 370], [374, 375], [374, 387], [375, 376], [375, 377], [378, 379], [378, 380], [380, 382], [383, 385], [387, 388], [387, 394], [395, 396], [395, 400], [400, 401], [400, 403], [404, 405], [404, 413], [408, 409], [408, 410], [413, 414], [413, 426], [415, 426]], "missing_branches": [[380, 381], [383, 384], [415, 416], [416, 417], [416, 426], [417, 416], [417, 420], [422, 423], [422, 424]]}, "_skip_frontmatter": {"executed_lines": [457, 458, 460, 461, 463, 464, 465, 466, 467, 469, 472, 474], "summary": {"covered_lines": 12, "num_statements": 12, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 3, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 6, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [444, 470, 471], "start_line": 441, "executed_branches": [[460, -441], [460, 461], [463, 464], [463, 469], [465, 466], [465, 469]], "missing_branches": []}, "_iter_content_lines": {"executed_lines": [501, 503, 504, 505, 508, 509, 510, 511, 513, 514, 515, 517], "summary": {"covered_lines": 12, "num_statements": 12, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 1, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 8, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [480], "start_line": 477, "executed_branches": [[504, -477], [504, 505], [508, 509], [508, 513], [509, 510], [509, 517], [513, 514], [513, 515]], "missing_branches": []}, "check_image_alt_text": {"executed_lines": [538, 539, 541, 543, 544, 545, 546, 547, 558, 559, 560, 561, 562, 563, 573], "summary": {"covered_lines": 15, "num_statements": 15, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 10, "num_partial_branches": 0, "covered_branches": 10, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 520, "executed_branches": [[541, 543], [541, 573], [543, 544], [543, 558], [546, 543], [546, 547], [558, 541], [558, 559], [562, 558], [562, 563]], "missing_branches": []}, "ReferenceScanner.__init__": {"executed_lines": [600, 601, 602], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 599, "executed_branches": [], "missing_branches": []}, "ReferenceScanner.harvest": {"executed_lines": [637, 638, 639, 640, 641, 642, 645, 646, 647, 648, 649, 650, 651, 653, 654, 657, 660, 664, 665, 668, 669, 670, 671, 672, 674, 677], "summary": {"covered_lines": 26, "num_statements": 28, "percent_covered": 93.18181818181819, "percent_covered_display": "93", "missing_lines": 2, "excluded_lines": 1, "percent_statements_covered": 92.85714285714286, "percent_statements_covered_display": "93", "num_branches": 16, "num_partial_branches": 1, "covered_branches": 15, "missing_branches": 1, "percent_branches_covered": 93.75, "percent_branches_covered_display": "94"}, "missing_lines": [661, 662], "excluded_lines": [633], "start_line": 606, "executed_branches": [[640, 641], [640, 645], [646, 647], [646, 677], [648, 649], [648, 668], [653, 654], [653, 664], [657, 660], [657, 665], [660, 657], [668, 646], [668, 669], [671, 672], [671, 674]], "missing_branches": [[660, 661]]}, "ReferenceScanner.cross_check": {"executed_lines": [691, 693, 695, 697, 698, 699, 700, 701, 702, 703, 716, 720], "summary": {"covered_lines": 12, "num_statements": 14, "percent_covered": 86.36363636363636, "percent_covered_display": "86", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 85.71428571428571, "percent_statements_covered_display": "86", "num_branches": 8, "num_partial_branches": 1, "covered_branches": 7, "missing_branches": 1, "percent_branches_covered": 87.5, "percent_branches_covered_display": "88"}, "missing_lines": [717, 718], "excluded_lines": [], "start_line": 681, "executed_branches": [[693, 695], [693, 720], [697, 698], [697, 716], [701, 697], [701, 702], [716, 693]], "missing_branches": [[716, 717]]}, "ReferenceScanner.get_integrity_report": {"executed_lines": [741, 744, 745, 746, 757, 758, 759, 772], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 724, "executed_branches": [[744, 745], [744, 757], [757, 758], [757, 772]], "missing_branches": []}, "_scan_single_file": {"executed_lines": [807, 808, 811, 812, 813, 816, 817, 818, 821, 826, 827, 828, 832, 833], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 8, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 783, "executed_branches": [[811, 812], [811, 816], [812, 811], [812, 813], [817, 818], [817, 821], [826, 827], [826, 832]], "missing_branches": []}, "_build_rule_engine": {"executed_lines": [847, 851, 852, 854, 855, 856, 865, 868, 869, 870, 871, 872, 874, 875, 877, 879], "summary": {"covered_lines": 16, "num_statements": 18, "percent_covered": 84.61538461538461, "percent_covered_display": "85", "missing_lines": 2, "excluded_lines": 1, "percent_statements_covered": 88.88888888888889, "percent_statements_covered_display": "89", "num_branches": 8, "num_partial_branches": 2, "covered_branches": 6, "missing_branches": 2, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75"}, "missing_lines": [873, 878], "excluded_lines": [837], "start_line": 836, "executed_branches": [[851, 852], [851, 854], [870, 871], [870, 877], [872, 874], [877, 879]], "missing_branches": [[872, 873], [877, 878]]}, "_emit_telemetry": {"executed_lines": [899, 901, 906, 907, 908, 909, 910, 912], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 882, "executed_branches": [[908, 909], [908, 912]], "missing_branches": []}, "scan_docs_references": {"executed_lines": [990, 992, 993, 995, 996, 998, 999, 1005, 1006, 1014, 1015, 1017, 1019, 1021, 1022, 1023, 1025, 1026, 1029, 1033, 1034, 1035, 1036, 1037, 1043, 1046, 1051, 1052, 1053, 1060, 1061, 1078, 1079, 1081, 1082, 1083, 1084, 1087, 1088, 1089, 1096, 1098, 1102, 1106, 1107, 1110, 1114], "summary": {"covered_lines": 47, "num_statements": 75, "percent_covered": 55.03875968992248, "percent_covered_display": "55", "missing_lines": 28, "excluded_lines": 1, "percent_statements_covered": 62.666666666666664, "percent_statements_covered_display": "63", "num_branches": 54, "num_partial_branches": 8, "covered_branches": 24, "missing_branches": 30, "percent_branches_covered": 44.44444444444444, "percent_branches_covered_display": "44"}, "missing_lines": [1007, 1008, 1011, 1012, 1038, 1039, 1040, 1041, 1047, 1048, 1049, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1085, 1099, 1100, 1101, 1108, 1111, 1112, 1113], "excluded_lines": [1030], "start_line": 921, "executed_branches": [[992, 993], [992, 995], [995, 996], [995, 998], [1006, 1014], [1014, 1015], [1014, 1017], [1021, 1022], [1021, 1078], [1035, 1036], [1035, 1043], [1046, 1051], [1052, 1053], [1060, 1061], [1081, 1082], [1081, 1087], [1084, 1081], [1088, 1089], [1088, 1096], [1096, 1098], [1096, 1106], [1098, 1102], [1107, 1110], [1110, 1114]], "missing_branches": [[1006, 1007], [1007, 1008], [1007, 1014], [1008, 1007], [1008, 1011], [1046, 1047], [1047, 1048], [1047, 1051], [1048, 1047], [1048, 1049], [1052, 1060], [1060, 1067], [1068, 1069], [1068, 1072], [1070, 1068], [1070, 1071], [1073, 1074], [1073, 1075], [1084, 1085], [1098, 1099], [1099, 1100], [1099, 1102], [1100, 1099], [1100, 1101], [1107, 1108], [1110, 1111], [1111, 1112], [1111, 1114], [1112, 1111], [1112, 1113]]}, "_make_timeout_report": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 4, "excluded_lines": 1, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [1147, 1148, 1150, 1161], "excluded_lines": [1134], "start_line": 1133, "executed_branches": [], "missing_branches": []}, "_make_error_report": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 4, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 4, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [1180, 1181, 1183, 1193], "excluded_lines": [], "start_line": 1170, "executed_branches": [], "missing_branches": []}, "_worker": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 3, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [1221, 1222, 1223], "excluded_lines": [], "start_line": 1202, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [15, 17, 18, 19, 20, 21, 22, 23, 24, 26, 27, 33, 34, 35, 36, 37, 38, 49, 53, 58, 61, 64, 65, 68, 71, 111, 124, 160, 161, 162, 163, 164, 165, 166, 167, 170, 221, 245, 261, 303, 346, 438, 441, 477, 520, 576, 599, 606, 681, 724, 783, 836, 882, 921, 1123, 1130, 1133, 1170, 1202], "summary": {"covered_lines": 59, "num_statements": 59, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 2, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [41, 42], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"PlaceholderFinding": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 161, "executed_branches": [], "missing_branches": []}, "ReferenceScanner": {"executed_lines": [600, 601, 602, 637, 638, 639, 640, 641, 642, 645, 646, 647, 648, 649, 650, 651, 653, 654, 657, 660, 664, 665, 668, 669, 670, 671, 672, 674, 677, 691, 693, 695, 697, 698, 699, 700, 701, 702, 703, 716, 720, 741, 744, 745, 746, 757, 758, 759, 772], "summary": {"covered_lines": 49, "num_statements": 53, "percent_covered": 92.5925925925926, "percent_covered_display": "93", "missing_lines": 4, "excluded_lines": 1, "percent_statements_covered": 92.45283018867924, "percent_statements_covered_display": "92", "num_branches": 28, "num_partial_branches": 2, "covered_branches": 26, "missing_branches": 2, "percent_branches_covered": 92.85714285714286, "percent_branches_covered_display": "93"}, "missing_lines": [661, 662, 717, 718], "excluded_lines": [633], "start_line": 576, "executed_branches": [[640, 641], [640, 645], [646, 647], [646, 677], [648, 649], [648, 668], [653, 654], [653, 664], [657, 660], [657, 665], [660, 657], [668, 646], [668, 669], [671, 672], [671, 674], [693, 695], [693, 720], [697, 698], [697, 716], [701, 697], [701, 702], [716, 693], [744, 745], [744, 757], [757, 758], [757, 772]], "missing_branches": [[660, 661], [716, 717]]}, "": {"executed_lines": [15, 17, 18, 19, 20, 21, 22, 23, 24, 26, 27, 33, 34, 35, 36, 37, 38, 49, 53, 58, 61, 64, 65, 68, 71, 94, 95, 96, 97, 99, 100, 102, 111, 121, 124, 143, 144, 148, 160, 161, 162, 163, 164, 165, 166, 167, 170, 185, 186, 188, 189, 190, 192, 193, 194, 203, 204, 205, 206, 207, 218, 221, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 245, 255, 261, 279, 280, 282, 284, 285, 287, 288, 290, 291, 292, 293, 294, 295, 296, 297, 298, 300, 303, 323, 325, 326, 328, 329, 330, 331, 333, 334, 335, 343, 346, 367, 368, 370, 373, 374, 375, 376, 377, 378, 379, 380, 382, 383, 385, 387, 388, 394, 395, 396, 400, 401, 403, 404, 405, 406, 407, 408, 409, 410, 413, 414, 415, 426, 438, 441, 457, 458, 460, 461, 463, 464, 465, 466, 467, 469, 472, 474, 477, 501, 503, 504, 505, 508, 509, 510, 511, 513, 514, 515, 517, 520, 538, 539, 541, 543, 544, 545, 546, 547, 558, 559, 560, 561, 562, 563, 573, 576, 599, 606, 681, 724, 783, 807, 808, 811, 812, 813, 816, 817, 818, 821, 826, 827, 828, 832, 833, 836, 847, 851, 852, 854, 855, 856, 865, 868, 869, 870, 871, 872, 874, 875, 877, 879, 882, 899, 901, 906, 907, 908, 909, 910, 912, 921, 990, 992, 993, 995, 996, 998, 999, 1005, 1006, 1014, 1015, 1017, 1019, 1021, 1022, 1023, 1025, 1026, 1029, 1033, 1034, 1035, 1036, 1037, 1043, 1046, 1051, 1052, 1053, 1060, 1061, 1078, 1079, 1081, 1082, 1083, 1084, 1087, 1088, 1089, 1096, 1098, 1102, 1106, 1107, 1110, 1114, 1123, 1130, 1133, 1170, 1202], "summary": {"covered_lines": 281, "num_statements": 337, "percent_covered": 80.03913894324853, "percent_covered_display": "80", "missing_lines": 56, "excluded_lines": 9, "percent_statements_covered": 83.38278931750742, "percent_statements_covered_display": "83", "num_branches": 174, "num_partial_branches": 14, "covered_branches": 128, "missing_branches": 46, "percent_branches_covered": 73.5632183908046, "percent_branches_covered_display": "74"}, "missing_lines": [145, 146, 336, 337, 340, 341, 381, 384, 416, 417, 420, 421, 422, 423, 424, 873, 878, 1007, 1008, 1011, 1012, 1038, 1039, 1040, 1041, 1047, 1048, 1049, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, 1075, 1085, 1099, 1100, 1101, 1108, 1111, 1112, 1113, 1147, 1148, 1150, 1161, 1180, 1181, 1183, 1193, 1221, 1222, 1223], "excluded_lines": [41, 42, 444, 470, 471, 480, 837, 1030, 1134], "start_line": 1, "executed_branches": [[95, 96], [95, 99], [96, 95], [96, 97], [99, 100], [99, 102], [185, 186], [185, 188], [193, 194], [193, 203], [203, 204], [203, 218], [204, 203], [204, 205], [206, 204], [206, 207], [233, 234], [233, 242], [235, 236], [235, 237], [240, 233], [240, 241], [279, 280], [279, 282], [284, 285], [284, 287], [291, 292], [291, 300], [293, 294], [293, 295], [295, 296], [295, 297], [297, 291], [297, 298], [325, 326], [325, 328], [328, 329], [328, 333], [333, 334], [333, 343], [335, 343], [367, 368], [367, 370], [374, 375], [374, 387], [375, 376], [375, 377], [378, 379], [378, 380], [380, 382], [383, 385], [387, 388], [387, 394], [395, 396], [395, 400], [400, 401], [400, 403], [404, 405], [404, 413], [408, 409], [408, 410], [413, 414], [413, 426], [415, 426], [460, -441], [460, 461], [463, 464], [463, 469], [465, 466], [465, 469], [504, -477], [504, 505], [508, 509], [508, 513], [509, 510], [509, 517], [513, 514], [513, 515], [541, 543], [541, 573], [543, 544], [543, 558], [546, 543], [546, 547], [558, 541], [558, 559], [562, 558], [562, 563], [811, 812], [811, 816], [812, 811], [812, 813], [817, 818], [817, 821], [826, 827], [826, 832], [851, 852], [851, 854], [870, 871], [870, 877], [872, 874], [877, 879], [908, 909], [908, 912], [992, 993], [992, 995], [995, 996], [995, 998], [1006, 1014], [1014, 1015], [1014, 1017], [1021, 1022], [1021, 1078], [1035, 1036], [1035, 1043], [1046, 1051], [1052, 1053], [1060, 1061], [1081, 1082], [1081, 1087], [1084, 1081], [1088, 1089], [1088, 1096], [1096, 1098], [1096, 1106], [1098, 1102], [1107, 1110], [1110, 1114]], "missing_branches": [[335, 336], [336, 337], [336, 343], [337, 336], [337, 340], [380, 381], [383, 384], [415, 416], [416, 417], [416, 426], [417, 416], [417, 420], [422, 423], [422, 424], [872, 873], [877, 878], [1006, 1007], [1007, 1008], [1007, 1014], [1008, 1007], [1008, 1011], [1046, 1047], [1047, 1048], [1047, 1051], [1048, 1047], [1048, 1049], [1052, 1060], [1060, 1067], [1068, 1069], [1068, 1072], [1070, 1068], [1070, 1071], [1073, 1074], [1073, 1075], [1084, 1085], [1098, 1099], [1099, 1100], [1099, 1102], [1100, 1099], [1100, 1101], [1107, 1108], [1110, 1111], [1111, 1112], [1111, 1114], [1112, 1111], [1112, 1113]]}}}, "src/zenzic/core/scorer.py": {"executed_lines": [18, 20, 21, 22, 23, 28, 38, 44, 45, 48, 49, 50, 51, 52, 55, 56, 59, 60, 61, 63, 64, 65, 78, 84, 87, 103, 111, 112, 114, 115, 116, 117, 118, 128, 129, 134, 137, 142, 143, 144, 147, 152, 153, 154, 155, 156, 157, 159, 160, 161, 162, 163], "summary": {"covered_lines": 52, "num_statements": 52, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [[114, 115], [114, 128], [153, 154], [153, 155]], "missing_branches": [], "functions": {"ScoreReport.to_dict": {"executed_lines": [64, 65], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 63, "executed_branches": [], "missing_branches": []}, "_category_score": {"executed_lines": [84], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 78, "executed_branches": [], "missing_branches": []}, "compute_score": {"executed_lines": [103, 111, 112, 114, 115, 116, 117, 118, 128, 129], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 87, "executed_branches": [[114, 115], [114, 128]], "missing_branches": []}, "save_snapshot": {"executed_lines": [142, 143, 144], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 137, "executed_branches": [], "missing_branches": []}, "load_snapshot": {"executed_lines": [152, 153, 154, 155, 156, 157, 159, 160, 161, 162, 163], "summary": {"covered_lines": 11, "num_statements": 11, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 147, "executed_branches": [[153, 154], [153, 155]], "missing_branches": []}, "": {"executed_lines": [18, 20, 21, 22, 23, 28, 38, 44, 45, 48, 49, 50, 51, 52, 55, 56, 59, 60, 61, 63, 78, 87, 134, 137, 147], "summary": {"covered_lines": 25, "num_statements": 25, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"CategoryScore": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 45, "executed_branches": [], "missing_branches": []}, "ScoreReport": {"executed_lines": [64, 65], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 56, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [18, 20, 21, 22, 23, 28, 38, 44, 45, 48, 49, 50, 51, 52, 55, 56, 59, 60, 61, 63, 78, 84, 87, 103, 111, 112, 114, 115, 116, 117, 118, 128, 129, 134, 137, 142, 143, 144, 147, 152, 153, 154, 155, 156, 157, 159, 160, 161, 162, 163], "summary": {"covered_lines": 50, "num_statements": 50, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [[114, 115], [114, 128], [153, 154], [153, 155]], "missing_branches": []}}}, "src/zenzic/core/shield.py": {"executed_lines": [27, 29, 30, 31, 32, 33, 34, 40, 42, 44, 46, 47, 50, 75, 78, 81, 82, 84, 85, 86, 91, 106, 112, 113, 128, 129, 130, 131, 132, 133, 139, 158, 159, 160, 161, 162, 172, 203, 206, 207, 208, 210, 211, 212, 213, 214, 215, 216, 217, 221, 222, 232, 263, 264, 265, 267, 269, 270, 271, 272, 275, 276, 279, 281, 282, 283, 284, 285, 286, 287, 295, 298, 299, 305, 318, 319, 320, 326, 353, 354, 355], "summary": {"covered_lines": 81, "num_statements": 81, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 2, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 26, "num_partial_branches": 0, "covered_branches": 26, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [45, 83], "executed_branches": [[159, -139], [159, 160], [161, 159], [161, 162], [210, -172], [210, 211], [211, 210], [211, 212], [212, 213], [212, 214], [215, 211], [215, 216], [267, -232], [267, 269], [270, 271], [270, 275], [275, 276], [275, 298], [282, 283], [282, 298], [283, 284], [283, 285], [286, 282], [286, 287], [353, 354], [353, 355]], "missing_branches": [], "functions": {"_normalize_line_for_shield": {"executed_lines": [75, 78, 81, 82, 84, 85, 86], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 1, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [83], "start_line": 50, "executed_branches": [], "missing_branches": []}, "scan_url_for_secrets": {"executed_lines": [158, 159, 160, 161, 162], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 139, "executed_branches": [[159, -139], [159, 160], [161, 159], [161, 162]], "missing_branches": []}, "scan_line_for_secrets": {"executed_lines": [203, 206, 207, 208, 210, 211, 212, 213, 214, 215, 216, 217, 221, 222], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 8, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 172, "executed_branches": [[210, -172], [210, 211], [211, 210], [211, 212], [212, 213], [212, 214], [215, 211], [215, 216]], "missing_branches": []}, "scan_lines_with_lookback": {"executed_lines": [263, 264, 265, 267, 269, 270, 271, 272, 275, 276, 279, 281, 282, 283, 284, 285, 286, 287, 295, 298, 299], "summary": {"covered_lines": 21, "num_statements": 21, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 12, "num_partial_branches": 0, "covered_branches": 12, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 232, "executed_branches": [[267, -232], [267, 269], [270, 271], [270, 275], [275, 276], [275, 298], [282, 283], [282, 298], [283, 284], [283, 285], [286, 282], [286, 287]], "missing_branches": []}, "ShieldViolation.__init__": {"executed_lines": [319, 320], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 318, "executed_branches": [], "missing_branches": []}, "safe_read_line": {"executed_lines": [353, 354, 355], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 326, "executed_branches": [[353, 354], [353, 355]], "missing_branches": []}, "": {"executed_lines": [27, 29, 30, 31, 32, 33, 34, 40, 42, 44, 46, 47, 50, 91, 106, 112, 113, 128, 129, 130, 131, 132, 133, 139, 172, 232, 305, 318, 326], "summary": {"covered_lines": 29, "num_statements": 29, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 1, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [45], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"SecurityFinding": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 113, "executed_branches": [], "missing_branches": []}, "ShieldViolation": {"executed_lines": [319, 320], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 305, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [27, 29, 30, 31, 32, 33, 34, 40, 42, 44, 46, 47, 50, 75, 78, 81, 82, 84, 85, 86, 91, 106, 112, 113, 128, 129, 130, 131, 132, 133, 139, 158, 159, 160, 161, 162, 172, 203, 206, 207, 208, 210, 211, 212, 213, 214, 215, 216, 217, 221, 222, 232, 263, 264, 265, 267, 269, 270, 271, 272, 275, 276, 279, 281, 282, 283, 284, 285, 286, 287, 295, 298, 299, 305, 318, 326, 353, 354, 355], "summary": {"covered_lines": 79, "num_statements": 79, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 2, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 26, "num_partial_branches": 0, "covered_branches": 26, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [45, 83], "start_line": 1, "executed_branches": [[159, -139], [159, 160], [161, 159], [161, 162], [210, -172], [210, 211], [211, 210], [211, 212], [212, 213], [212, 214], [215, 211], [215, 216], [267, -232], [267, 269], [270, 271], [270, 275], [275, 276], [275, 298], [282, 283], [282, 298], [283, 284], [283, 285], [286, 282], [286, 287], [353, 354], [353, 355]], "missing_branches": []}}}, "src/zenzic/core/validator.py": {"executed_lines": [26, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 41, 42, 44, 45, 46, 53, 54, 55, 65, 69, 77, 80, 83, 84, 85, 86, 90, 93, 96, 99, 102, 106, 109, 113, 117, 123, 124, 125, 126, 127, 130, 131, 145, 146, 147, 148, 149, 150, 151, 153, 155, 163, 166, 177, 180, 195, 196, 197, 198, 200, 206, 207, 208, 209, 210, 213, 219, 220, 221, 223, 224, 225, 226, 227, 228, 229, 231, 232, 233, 234, 235, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 254, 257, 267, 268, 269, 270, 273, 278, 279, 280, 281, 292, 306, 307, 309, 310, 313, 314, 315, 316, 318, 319, 320, 323, 325, 326, 327, 330, 331, 332, 341, 344, 364, 366, 367, 369, 374, 375, 376, 377, 378, 379, 382, 394, 400, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 427, 428, 429, 432, 449, 450, 451, 452, 453, 454, 455, 456, 458, 459, 460, 461, 462, 463, 464, 465, 466, 468, 469, 470, 479, 491, 497, 519, 533, 537, 538, 539, 541, 548, 550, 551, 552, 554, 555, 560, 561, 566, 567, 568, 569, 570, 571, 573, 579, 601, 602, 605, 608, 609, 610, 611, 616, 626, 629, 630, 631, 633, 635, 636, 637, 642, 648, 653, 654, 655, 659, 660, 662, 664, 665, 666, 668, 669, 670, 672, 673, 675, 676, 678, 681, 682, 683, 687, 710, 711, 727, 734, 735, 739, 740, 755, 760, 765, 766, 770, 771, 774, 775, 779, 790, 796, 797, 798, 809, 811, 812, 831, 832, 833, 837, 838, 839, 843, 860, 862, 863, 864, 865, 868, 869, 875, 876, 886, 887, 889, 892, 910, 912, 913, 914, 915, 916, 918, 919, 920, 921, 923, 924, 925, 926, 928, 929, 932, 951, 953, 954, 955, 956, 957, 958, 959, 964, 965, 966, 967, 968, 970, 971, 973, 974, 977, 978, 979, 982, 983, 984, 987, 988, 990, 991, 992, 995, 996, 997, 1004, 1007, 1027, 1037, 1038, 1041, 1061, 1071, 1072, 1077, 1080, 1092, 1093, 1094, 1095, 1096, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1111, 1112, 1113, 1114, 1116, 1118, 1121, 1143, 1144, 1146, 1147, 1149, 1150, 1151, 1153, 1154, 1155, 1156, 1157, 1164, 1165, 1173, 1174, 1175, 1176, 1177, 1185, 1186, 1187, 1188, 1189, 1197, 1198, 1199, 1200, 1201, 1209, 1215, 1244, 1246, 1248, 1259, 1260, 1261, 1263, 1273, 1274, 1276, 1277, 1279, 1281, 1294, 1295, 1303, 1309, 1315, 1331, 1333, 1334, 1336, 1337, 1338, 1339, 1341], "summary": {"covered_lines": 427, "num_statements": 473, "percent_covered": 88.0, "percent_covered_display": "88", "missing_lines": 46, "excluded_lines": 6, "percent_statements_covered": 90.27484143763213, "percent_statements_covered_display": "90", "num_branches": 202, "num_partial_branches": 23, "covered_branches": 167, "missing_branches": 35, "percent_branches_covered": 82.67326732673267, "percent_branches_covered_display": "83"}, "missing_lines": [236, 237, 328, 368, 467, 480, 481, 482, 483, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 534, 612, 613, 688, 689, 690, 691, 702, 761, 834, 835, 870, 888, 917, 922, 960, 961, 969, 972, 985, 989, 993, 1297, 1301], "excluded_lines": [58, 59, 322, 708, 897, 1245], "executed_branches": [[196, 197], [196, 210], [197, 196], [197, 198], [200, 206], [200, 207], [208, 197], [208, 209], [223, 224], [223, 254], [224, 225], [224, 226], [231, 223], [231, 232], [235, 238], [238, 239], [238, 242], [242, 231], [242, 243], [309, 310], [309, 341], [313, 314], [313, 318], [314, 315], [314, 323], [318, 319], [318, 320], [325, 309], [325, 326], [327, 330], [331, 332], [367, 369], [415, 416], [415, 429], [417, 418], [417, 427], [418, 419], [418, 421], [422, 415], [422, 423], [424, 415], [424, 425], [427, 415], [427, 428], [451, 452], [451, 491], [453, 454], [453, 458], [454, 455], [454, 461], [458, 459], [458, 460], [462, 463], [462, 479], [466, 468], [469, 462], [469, 470], [479, 451], [533, 537], [538, 539], [538, 541], [566, 567], [566, 573], [567, 568], [567, 569], [570, 566], [570, 571], [601, 602], [601, 605], [609, 610], [609, 616], [629, 630], [629, 633], [668, 669], [668, 860], [672, 668], [672, 673], [675, 676], [675, 678], [681, 682], [681, 687], [687, 710], [710, 711], [710, 734], [735, 739], [735, 755], [755, 760], [755, 790], [760, 765], [766, 672], [766, 770], [770, 771], [770, 774], [775, 672], [775, 779], [790, 796], [790, 809], [796, 797], [796, 798], [809, 811], [811, 812], [811, 831], [831, 672], [831, 832], [839, 672], [839, 843], [862, 863], [862, 868], [863, 864], [863, 865], [869, 875], [887, 889], [913, 914], [913, 915], [915, 916], [915, 929], [916, 918], [921, 923], [923, 924], [923, 925], [925, 926], [925, 928], [955, 956], [955, 957], [966, 967], [967, 968], [968, 970], [971, 973], [984, 987], [987, 988], [987, 1004], [988, 990], [992, 995], [996, 987], [996, 997], [1098, 1099], [1098, 1118], [1100, 1101], [1100, 1111], [1101, 1098], [1101, 1102], [1104, 1098], [1104, 1105], [1111, 1112], [1111, 1116], [1143, 1144], [1143, 1146], [1149, 1150], [1149, 1209], [1150, 1151], [1150, 1153], [1153, 1154], [1153, 1173], [1173, 1174], [1173, 1185], [1185, 1186], [1185, 1197], [1197, 1198], [1259, 1260], [1259, 1261], [1273, -1263], [1273, 1274], [1294, 1295], [1333, 1334], [1333, 1336], [1336, 1337], [1336, 1341]], "missing_branches": [[235, 236], [327, 328], [331, 325], [367, 368], [466, 467], [479, 480], [482, 479], [482, 483], [506, 507], [506, 508], [508, 509], [508, 510], [510, 511], [510, 512], [533, 534], [687, 688], [688, 689], [688, 702], [690, 691], [690, 702], [760, 761], [809, 672], [869, 870], [887, 888], [916, 917], [921, 922], [966, 977], [967, 977], [968, 969], [971, 972], [984, 985], [988, 989], [992, 993], [1197, 1149], [1294, 1297]], "functions": {"LinkError.__str__": {"executed_lines": [155], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 153, "executed_branches": [], "missing_branches": []}, "_classify_traversal_intent": {"executed_lines": [177], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 166, "executed_branches": [], "missing_branches": []}, "_build_link_graph": {"executed_lines": [195, 196, 197, 198, 200, 206, 207, 208, 209, 210], "summary": {"covered_lines": 10, "num_statements": 10, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 8, "num_partial_branches": 0, "covered_branches": 8, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 180, "executed_branches": [[196, 197], [196, 210], [197, 196], [197, 198], [200, 206], [200, 207], [208, 197], [208, 209]], "missing_branches": []}, "_find_cycles_iterative": {"executed_lines": [219, 220, 221, 223, 224, 225, 226, 227, 228, 229, 231, 232, 233, 234, 235, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 254], "summary": {"covered_lines": 31, "num_statements": 33, "percent_covered": 93.33333333333333, "percent_covered_display": "93", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 93.93939393939394, "percent_statements_covered_display": "94", "num_branches": 12, "num_partial_branches": 1, "covered_branches": 11, "missing_branches": 1, "percent_branches_covered": 91.66666666666667, "percent_branches_covered_display": "92"}, "missing_lines": [236, 237], "excluded_lines": [], "start_line": 213, "executed_branches": [[223, 224], [223, 254], [224, 225], [224, 226], [231, 223], [231, 232], [235, 238], [238, 239], [238, 242], [242, 231], [242, 243]], "missing_branches": [[235, 236]]}, "_index_file_for_validation": {"executed_lines": [278, 279, 280, 281], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 273, "executed_branches": [], "missing_branches": []}, "extract_links": {"executed_lines": [306, 307, 309, 310, 313, 314, 315, 316, 318, 319, 320, 323, 325, 326, 327, 330, 331, 332, 341], "summary": {"covered_lines": 19, "num_statements": 20, "percent_covered": 91.17647058823529, "percent_covered_display": "91", "missing_lines": 1, "excluded_lines": 1, "percent_statements_covered": 95.0, "percent_statements_covered_display": "95", "num_branches": 14, "num_partial_branches": 2, "covered_branches": 12, "missing_branches": 2, "percent_branches_covered": 85.71428571428571, "percent_branches_covered_display": "86"}, "missing_lines": [328], "excluded_lines": [322], "start_line": 292, "executed_branches": [[309, 310], [309, 341], [313, 314], [313, 318], [314, 315], [314, 323], [318, 319], [318, 320], [325, 309], [325, 326], [327, 330], [331, 332]], "missing_branches": [[327, 328], [331, 325]]}, "slug_heading": {"executed_lines": [364, 366, 367, 369, 374, 375, 376, 377, 378, 379], "summary": {"covered_lines": 10, "num_statements": 11, "percent_covered": 84.61538461538461, "percent_covered_display": "85", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 90.9090909090909, "percent_statements_covered_display": "91", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50"}, "missing_lines": [368], "excluded_lines": [], "start_line": 344, "executed_branches": [[367, 369]], "missing_branches": [[367, 368]]}, "anchors_in_file": {"executed_lines": [394], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 382, "executed_branches": [], "missing_branches": []}, "_build_ref_map": {"executed_lines": [413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 427, 428, 429], "summary": {"covered_lines": 16, "num_statements": 16, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 12, "num_partial_branches": 0, "covered_branches": 12, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 400, "executed_branches": [[415, 416], [415, 429], [417, 418], [417, 427], [418, 419], [418, 421], [422, 415], [422, 423], [424, 415], [424, 425], [427, 415], [427, 428]], "missing_branches": []}, "extract_ref_links": {"executed_lines": [449, 450, 451, 452, 453, 454, 455, 456, 458, 459, 460, 461, 462, 463, 464, 465, 466, 468, 469, 470, 479, 491], "summary": {"covered_lines": 22, "num_statements": 27, "percent_covered": 80.0, "percent_covered_display": "80", "missing_lines": 5, "excluded_lines": 0, "percent_statements_covered": 81.48148148148148, "percent_statements_covered_display": "81", "num_branches": 18, "num_partial_branches": 2, "covered_branches": 14, "missing_branches": 4, "percent_branches_covered": 77.77777777777777, "percent_branches_covered_display": "78"}, "missing_lines": [467, 480, 481, 482, 483], "excluded_lines": [], "start_line": 432, "executed_branches": [[451, 452], [451, 491], [453, 454], [453, 458], [454, 455], [454, 461], [458, 459], [458, 460], [462, 463], [462, 479], [466, 468], [469, 462], [469, 470], [479, 451]], "missing_branches": [[466, 467], [479, 480], [482, 479], [482, 483]]}, "_ping_url": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 13, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 13, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 6, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0"}, "missing_lines": [504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516], "excluded_lines": [], "start_line": 497, "executed_branches": [], "missing_branches": [[506, 507], [506, 508], [508, 509], [508, 510], [510, 511], [510, 512]]}, "_check_external_links": {"executed_lines": [533, 537, 538, 539, 541, 548, 550, 554, 555, 560, 561, 566, 567, 568, 569, 570, 571, 573], "summary": {"covered_lines": 18, "num_statements": 19, "percent_covered": 93.10344827586206, "percent_covered_display": "93", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 94.73684210526316, "percent_statements_covered_display": "95", "num_branches": 10, "num_partial_branches": 1, "covered_branches": 9, "missing_branches": 1, "percent_branches_covered": 90.0, "percent_branches_covered_display": "90"}, "missing_lines": [534], "excluded_lines": [], "start_line": 519, "executed_branches": [[533, 537], [538, 539], [538, 541], [566, 567], [566, 573], [567, 568], [567, 569], [570, 566], [570, 571]], "missing_branches": [[533, 534]]}, "_check_external_links._bounded_ping": {"executed_lines": [551, 552], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 550, "executed_branches": [], "missing_branches": []}, "validate_links_async": {"executed_lines": [601, 602, 605, 608, 609, 610, 611, 616, 626, 629, 630, 631, 633, 635, 636, 637, 642, 648, 653, 654, 655, 659, 660, 662, 668, 669, 670, 672, 673, 675, 676, 678, 681, 682, 683, 687, 710, 711, 727, 734, 735, 739, 740, 755, 760, 765, 766, 770, 771, 774, 775, 779, 790, 796, 797, 798, 809, 811, 812, 831, 832, 833, 837, 838, 839, 843, 860, 862, 863, 864, 865, 868, 869, 875, 876, 886, 887, 889], "summary": {"covered_lines": 78, "num_statements": 90, "percent_covered": 85.41666666666667, "percent_covered_display": "85", "missing_lines": 12, "excluded_lines": 1, "percent_statements_covered": 86.66666666666667, "percent_statements_covered_display": "87", "num_branches": 54, "num_partial_branches": 5, "covered_branches": 45, "missing_branches": 9, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83"}, "missing_lines": [612, 613, 688, 689, 690, 691, 702, 761, 834, 835, 870, 888], "excluded_lines": [708], "start_line": 579, "executed_branches": [[601, 602], [601, 605], [609, 610], [609, 616], [629, 630], [629, 633], [668, 669], [668, 860], [672, 668], [672, 673], [675, 676], [675, 678], [681, 682], [681, 687], [687, 710], [710, 711], [710, 734], [735, 739], [735, 755], [755, 760], [755, 790], [760, 765], [766, 672], [766, 770], [770, 771], [770, 774], [775, 672], [775, 779], [790, 796], [790, 809], [796, 797], [796, 798], [809, 811], [811, 812], [811, 831], [831, 672], [831, 832], [839, 672], [839, 843], [862, 863], [862, 868], [863, 864], [863, 865], [869, 875], [887, 889]], "missing_branches": [[687, 688], [688, 689], [688, 702], [690, 691], [690, 702], [760, 761], [809, 672], [869, 870], [887, 888]]}, "validate_links_async._source_line": {"executed_lines": [664, 665, 666], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 662, "executed_branches": [], "missing_branches": []}, "generate_virtual_site_map": {"executed_lines": [910, 912, 913, 914, 915, 916, 918, 919, 920, 921, 923, 924, 925, 926, 928, 929], "summary": {"covered_lines": 16, "num_statements": 18, "percent_covered": 86.66666666666667, "percent_covered_display": "87", "missing_lines": 2, "excluded_lines": 1, "percent_statements_covered": 88.88888888888889, "percent_statements_covered_display": "89", "num_branches": 12, "num_partial_branches": 2, "covered_branches": 10, "missing_branches": 2, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83"}, "missing_lines": [917, 922], "excluded_lines": [897], "start_line": 892, "executed_branches": [[913, 914], [913, 915], [915, 916], [915, 929], [916, 918], [921, 923], [923, 924], [923, 925], [925, 926], [925, 928]], "missing_branches": [[916, 917], [921, 922]]}, "check_nav_contract": {"executed_lines": [951, 953, 954, 955, 956, 957, 958, 959, 964, 965, 966, 967, 968, 970, 971, 973, 974, 977, 978, 979, 982, 983, 984, 987, 988, 990, 991, 992, 995, 996, 997, 1004], "summary": {"covered_lines": 32, "num_statements": 39, "percent_covered": 76.27118644067797, "percent_covered_display": "76", "missing_lines": 7, "excluded_lines": 0, "percent_statements_covered": 82.05128205128206, "percent_statements_covered_display": "82", "num_branches": 20, "num_partial_branches": 7, "covered_branches": 13, "missing_branches": 7, "percent_branches_covered": 65.0, "percent_branches_covered_display": "65"}, "missing_lines": [960, 961, 969, 972, 985, 989, 993], "excluded_lines": [], "start_line": 932, "executed_branches": [[955, 956], [955, 957], [966, 967], [967, 968], [968, 970], [971, 973], [984, 987], [987, 988], [987, 1004], [988, 990], [992, 995], [996, 987], [996, 997]], "missing_branches": [[966, 977], [967, 977], [968, 969], [971, 972], [984, 985], [988, 989], [992, 993]]}, "validate_links": {"executed_lines": [1027, 1037, 1038], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1007, "executed_branches": [], "missing_branches": []}, "validate_links_structured": {"executed_lines": [1061, 1071, 1072], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1041, "executed_branches": [], "missing_branches": []}, "_extract_code_blocks": {"executed_lines": [1092, 1093, 1094, 1095, 1096, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1111, 1112, 1113, 1114, 1116, 1118], "summary": {"covered_lines": 22, "num_statements": 22, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 10, "num_partial_branches": 0, "covered_branches": 10, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1080, "executed_branches": [[1098, 1099], [1098, 1118], [1100, 1101], [1100, 1111], [1101, 1098], [1101, 1102], [1104, 1098], [1104, 1105], [1111, 1112], [1111, 1116]], "missing_branches": []}, "check_snippet_content": {"executed_lines": [1143, 1144, 1146, 1147, 1149, 1150, 1151, 1153, 1154, 1155, 1156, 1157, 1164, 1165, 1173, 1174, 1175, 1176, 1177, 1185, 1186, 1187, 1188, 1189, 1197, 1198, 1199, 1200, 1201, 1209], "summary": {"covered_lines": 30, "num_statements": 30, "percent_covered": 97.72727272727273, "percent_covered_display": "98", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 14, "num_partial_branches": 1, "covered_branches": 13, "missing_branches": 1, "percent_branches_covered": 92.85714285714286, "percent_branches_covered_display": "93"}, "missing_lines": [], "excluded_lines": [], "start_line": 1121, "executed_branches": [[1143, 1144], [1143, 1146], [1149, 1150], [1149, 1209], [1150, 1151], [1150, 1153], [1153, 1154], [1153, 1173], [1173, 1174], [1173, 1185], [1185, 1186], [1185, 1197], [1197, 1198]], "missing_branches": [[1197, 1149]]}, "LinkValidator.__init__": {"executed_lines": [1246], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1244, "executed_branches": [], "missing_branches": []}, "LinkValidator.register": {"executed_lines": [1259, 1260, 1261], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1248, "executed_branches": [[1259, 1260], [1259, 1261]], "missing_branches": []}, "LinkValidator.register_from_map": {"executed_lines": [1273, 1274], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1263, "executed_branches": [[1273, -1263], [1273, 1274]], "missing_branches": []}, "LinkValidator.unique_url_count": {"executed_lines": [1279], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1277, "executed_branches": [], "missing_branches": []}, "LinkValidator.validate_async": {"executed_lines": [1294, 1295], "summary": {"covered_lines": 2, "num_statements": 4, "percent_covered": 50.0, "percent_covered_display": "50", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 50.0, "percent_statements_covered_display": "50", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50"}, "missing_lines": [1297, 1301], "excluded_lines": [], "start_line": 1281, "executed_branches": [[1294, 1295]], "missing_branches": [[1294, 1297]]}, "LinkValidator.validate": {"executed_lines": [1309], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1303, "executed_branches": [], "missing_branches": []}, "validate_snippets": {"executed_lines": [1331, 1333, 1334, 1336, 1337, 1338, 1339, 1341], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1315, "executed_branches": [[1333, 1334], [1333, 1336], [1336, 1337], [1336, 1341]], "missing_branches": []}, "": {"executed_lines": [26, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 41, 42, 44, 45, 46, 53, 54, 55, 65, 69, 77, 80, 83, 84, 85, 86, 90, 93, 96, 99, 102, 106, 109, 113, 117, 123, 124, 125, 126, 127, 130, 131, 145, 146, 147, 148, 149, 150, 151, 153, 163, 166, 180, 213, 257, 267, 268, 269, 270, 273, 292, 344, 382, 400, 432, 497, 519, 579, 892, 932, 1007, 1041, 1077, 1080, 1121, 1215, 1244, 1248, 1263, 1276, 1277, 1281, 1303, 1315], "summary": {"covered_lines": 87, "num_statements": 87, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 3, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [58, 59, 1245], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"_PermissiveSafeLoader": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 65, "executed_branches": [], "missing_branches": []}, "LinkInfo": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 80, "executed_branches": [], "missing_branches": []}, "SnippetError": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 124, "executed_branches": [], "missing_branches": []}, "LinkError": {"executed_lines": [155], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 131, "executed_branches": [], "missing_branches": []}, "_ValidationPayload": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 257, "executed_branches": [], "missing_branches": []}, "LinkValidator": {"executed_lines": [1246, 1259, 1260, 1261, 1273, 1274, 1279, 1294, 1295, 1309], "summary": {"covered_lines": 10, "num_statements": 12, "percent_covered": 83.33333333333333, "percent_covered_display": "83", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 83.33333333333333, "percent_statements_covered_display": "83", "num_branches": 6, "num_partial_branches": 1, "covered_branches": 5, "missing_branches": 1, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83"}, "missing_lines": [1297, 1301], "excluded_lines": [], "start_line": 1215, "executed_branches": [[1259, 1260], [1259, 1261], [1273, -1263], [1273, 1274], [1294, 1295]], "missing_branches": [[1294, 1297]]}, "": {"executed_lines": [26, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 41, 42, 44, 45, 46, 53, 54, 55, 65, 69, 77, 80, 83, 84, 85, 86, 90, 93, 96, 99, 102, 106, 109, 113, 117, 123, 124, 125, 126, 127, 130, 131, 145, 146, 147, 148, 149, 150, 151, 153, 163, 166, 177, 180, 195, 196, 197, 198, 200, 206, 207, 208, 209, 210, 213, 219, 220, 221, 223, 224, 225, 226, 227, 228, 229, 231, 232, 233, 234, 235, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 254, 257, 267, 268, 269, 270, 273, 278, 279, 280, 281, 292, 306, 307, 309, 310, 313, 314, 315, 316, 318, 319, 320, 323, 325, 326, 327, 330, 331, 332, 341, 344, 364, 366, 367, 369, 374, 375, 376, 377, 378, 379, 382, 394, 400, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 427, 428, 429, 432, 449, 450, 451, 452, 453, 454, 455, 456, 458, 459, 460, 461, 462, 463, 464, 465, 466, 468, 469, 470, 479, 491, 497, 519, 533, 537, 538, 539, 541, 548, 550, 551, 552, 554, 555, 560, 561, 566, 567, 568, 569, 570, 571, 573, 579, 601, 602, 605, 608, 609, 610, 611, 616, 626, 629, 630, 631, 633, 635, 636, 637, 642, 648, 653, 654, 655, 659, 660, 662, 664, 665, 666, 668, 669, 670, 672, 673, 675, 676, 678, 681, 682, 683, 687, 710, 711, 727, 734, 735, 739, 740, 755, 760, 765, 766, 770, 771, 774, 775, 779, 790, 796, 797, 798, 809, 811, 812, 831, 832, 833, 837, 838, 839, 843, 860, 862, 863, 864, 865, 868, 869, 875, 876, 886, 887, 889, 892, 910, 912, 913, 914, 915, 916, 918, 919, 920, 921, 923, 924, 925, 926, 928, 929, 932, 951, 953, 954, 955, 956, 957, 958, 959, 964, 965, 966, 967, 968, 970, 971, 973, 974, 977, 978, 979, 982, 983, 984, 987, 988, 990, 991, 992, 995, 996, 997, 1004, 1007, 1027, 1037, 1038, 1041, 1061, 1071, 1072, 1077, 1080, 1092, 1093, 1094, 1095, 1096, 1098, 1099, 1100, 1101, 1102, 1103, 1104, 1105, 1106, 1107, 1108, 1111, 1112, 1113, 1114, 1116, 1118, 1121, 1143, 1144, 1146, 1147, 1149, 1150, 1151, 1153, 1154, 1155, 1156, 1157, 1164, 1165, 1173, 1174, 1175, 1176, 1177, 1185, 1186, 1187, 1188, 1189, 1197, 1198, 1199, 1200, 1201, 1209, 1215, 1244, 1248, 1263, 1276, 1277, 1281, 1303, 1315, 1331, 1333, 1334, 1336, 1337, 1338, 1339, 1341], "summary": {"covered_lines": 416, "num_statements": 460, "percent_covered": 88.10975609756098, "percent_covered_display": "88", "missing_lines": 44, "excluded_lines": 6, "percent_statements_covered": 90.43478260869566, "percent_statements_covered_display": "90", "num_branches": 196, "num_partial_branches": 22, "covered_branches": 162, "missing_branches": 34, "percent_branches_covered": 82.65306122448979, "percent_branches_covered_display": "83"}, "missing_lines": [236, 237, 328, 368, 467, 480, 481, 482, 483, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, 516, 534, 612, 613, 688, 689, 690, 691, 702, 761, 834, 835, 870, 888, 917, 922, 960, 961, 969, 972, 985, 989, 993], "excluded_lines": [58, 59, 322, 708, 897, 1245], "start_line": 1, "executed_branches": [[196, 197], [196, 210], [197, 196], [197, 198], [200, 206], [200, 207], [208, 197], [208, 209], [223, 224], [223, 254], [224, 225], [224, 226], [231, 223], [231, 232], [235, 238], [238, 239], [238, 242], [242, 231], [242, 243], [309, 310], [309, 341], [313, 314], [313, 318], [314, 315], [314, 323], [318, 319], [318, 320], [325, 309], [325, 326], [327, 330], [331, 332], [367, 369], [415, 416], [415, 429], [417, 418], [417, 427], [418, 419], [418, 421], [422, 415], [422, 423], [424, 415], [424, 425], [427, 415], [427, 428], [451, 452], [451, 491], [453, 454], [453, 458], [454, 455], [454, 461], [458, 459], [458, 460], [462, 463], [462, 479], [466, 468], [469, 462], [469, 470], [479, 451], [533, 537], [538, 539], [538, 541], [566, 567], [566, 573], [567, 568], [567, 569], [570, 566], [570, 571], [601, 602], [601, 605], [609, 610], [609, 616], [629, 630], [629, 633], [668, 669], [668, 860], [672, 668], [672, 673], [675, 676], [675, 678], [681, 682], [681, 687], [687, 710], [710, 711], [710, 734], [735, 739], [735, 755], [755, 760], [755, 790], [760, 765], [766, 672], [766, 770], [770, 771], [770, 774], [775, 672], [775, 779], [790, 796], [790, 809], [796, 797], [796, 798], [809, 811], [811, 812], [811, 831], [831, 672], [831, 832], [839, 672], [839, 843], [862, 863], [862, 868], [863, 864], [863, 865], [869, 875], [887, 889], [913, 914], [913, 915], [915, 916], [915, 929], [916, 918], [921, 923], [923, 924], [923, 925], [925, 926], [925, 928], [955, 956], [955, 957], [966, 967], [967, 968], [968, 970], [971, 973], [984, 987], [987, 988], [987, 1004], [988, 990], [992, 995], [996, 987], [996, 997], [1098, 1099], [1098, 1118], [1100, 1101], [1100, 1111], [1101, 1098], [1101, 1102], [1104, 1098], [1104, 1105], [1111, 1112], [1111, 1116], [1143, 1144], [1143, 1146], [1149, 1150], [1149, 1209], [1150, 1151], [1150, 1153], [1153, 1154], [1153, 1173], [1173, 1174], [1173, 1185], [1185, 1186], [1185, 1197], [1197, 1198], [1333, 1334], [1333, 1336], [1336, 1337], [1336, 1341]], "missing_branches": [[235, 236], [327, 328], [331, 325], [367, 368], [466, 467], [479, 480], [482, 479], [482, 483], [506, 507], [506, 508], [508, 509], [508, 510], [510, 511], [510, 512], [533, 534], [687, 688], [688, 689], [688, 702], [690, 691], [690, 702], [760, 761], [809, 672], [869, 870], [887, 888], [916, 917], [921, 922], [966, 977], [967, 977], [968, 969], [971, 972], [984, 985], [988, 989], [992, 993], [1197, 1149]]}}}, "src/zenzic/integrations/__init__.py": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "src/zenzic/integrations/mkdocs.py": {"executed_lines": [19, 21, 22, 23, 25, 26, 27, 28, 29, 30, 31, 33, 39, 40, 43, 46, 49, 50, 51, 52, 55, 69, 70, 71, 72, 73, 77, 79, 80, 81, 83, 84, 86, 87, 88, 89, 90, 92, 96, 97, 98, 102, 110, 114, 115, 117, 118, 119, 121, 122, 123, 127, 131, 144, 145, 147, 148, 149, 150, 151, 155, 156, 157, 158, 166, 167, 169, 170, 175, 179, 181, 182, 183, 184, 185, 191, 192], "summary": {"covered_lines": 77, "num_statements": 86, "percent_covered": 88.39285714285714, "percent_covered_display": "88", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 89.53488372093024, "percent_statements_covered_display": "90", "num_branches": 26, "num_partial_branches": 2, "covered_branches": 22, "missing_branches": 4, "percent_branches_covered": 84.61538461538461, "percent_branches_covered_display": "85"}, "missing_lines": [104, 105, 106, 124, 125, 172, 173, 186, 187], "excluded_lines": [], "executed_branches": [[87, 88], [87, 92], [89, 90], [114, 115], [114, 117], [121, 122], [121, 127], [148, 149], [148, 155], [149, 150], [149, 155], [155, 156], [155, 166], [156, 157], [156, 166], [166, 167], [166, 175], [182, 183], [183, 184], [183, 191], [191, -179], [191, 192]], "missing_branches": [[89, 96], [104, 105], [104, 106], [182, 191]], "functions": {"ZenzicPlugin.on_config": {"executed_lines": [79, 80, 81, 83, 84, 86, 87, 88, 89, 90, 92, 96, 97, 98], "summary": {"covered_lines": 14, "num_statements": 14, "percent_covered": 94.44444444444444, "percent_covered_display": "94", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 4, "num_partial_branches": 1, "covered_branches": 3, "missing_branches": 1, "percent_branches_covered": 75.0, "percent_branches_covered_display": "75"}, "missing_lines": [], "excluded_lines": [], "start_line": 77, "executed_branches": [[87, 88], [87, 92], [89, 90]], "missing_branches": [[89, 96]]}, "ZenzicPlugin.on_files": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 3, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 2, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0"}, "missing_lines": [104, 105, 106], "excluded_lines": [], "start_line": 102, "executed_branches": [], "missing_branches": [[104, 105], [104, 106]]}, "ZenzicPlugin.on_nav": {"executed_lines": [114, 115, 117, 118, 119, 121, 122, 123, 127], "summary": {"covered_lines": 9, "num_statements": 11, "percent_covered": 86.66666666666667, "percent_covered_display": "87", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 81.81818181818181, "percent_statements_covered_display": "82", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [124, 125], "excluded_lines": [], "start_line": 110, "executed_branches": [[114, 115], [114, 117], [121, 122], [121, 127]], "missing_branches": []}, "ZenzicPlugin.on_page_markdown": {"executed_lines": [144, 145, 147, 148, 149, 150, 151, 155, 156, 157, 158, 166, 167, 169, 170, 175], "summary": {"covered_lines": 16, "num_statements": 18, "percent_covered": 92.85714285714286, "percent_covered_display": "93", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 88.88888888888889, "percent_statements_covered_display": "89", "num_branches": 10, "num_partial_branches": 0, "covered_branches": 10, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [172, 173], "excluded_lines": [], "start_line": 131, "executed_branches": [[148, 149], [148, 155], [149, 150], [149, 155], [155, 156], [155, 166], [156, 157], [156, 166], [166, 167], [166, 175]], "missing_branches": []}, "ZenzicPlugin.on_post_build": {"executed_lines": [181, 182, 183, 184, 185, 191, 192], "summary": {"covered_lines": 7, "num_statements": 9, "percent_covered": 80.0, "percent_covered_display": "80", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 77.77777777777777, "percent_statements_covered_display": "78", "num_branches": 6, "num_partial_branches": 1, "covered_branches": 5, "missing_branches": 1, "percent_branches_covered": 83.33333333333333, "percent_branches_covered_display": "83"}, "missing_lines": [186, 187], "excluded_lines": [], "start_line": 179, "executed_branches": [[182, 183], [183, 184], [183, 191], [191, -179], [191, 192]], "missing_branches": [[182, 191]]}, "": {"executed_lines": [19, 21, 22, 23, 25, 26, 27, 28, 29, 30, 31, 33, 39, 40, 43, 46, 49, 50, 51, 52, 55, 69, 70, 71, 72, 73, 77, 102, 110, 131, 179], "summary": {"covered_lines": 31, "num_statements": 31, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"ZenzicPluginConfig": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 46, "executed_branches": [], "missing_branches": []}, "ZenzicPlugin": {"executed_lines": [79, 80, 81, 83, 84, 86, 87, 88, 89, 90, 92, 96, 97, 98, 114, 115, 117, 118, 119, 121, 122, 123, 127, 144, 145, 147, 148, 149, 150, 151, 155, 156, 157, 158, 166, 167, 169, 170, 175, 181, 182, 183, 184, 185, 191, 192], "summary": {"covered_lines": 46, "num_statements": 55, "percent_covered": 83.95061728395062, "percent_covered_display": "84", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 83.63636363636364, "percent_statements_covered_display": "84", "num_branches": 26, "num_partial_branches": 2, "covered_branches": 22, "missing_branches": 4, "percent_branches_covered": 84.61538461538461, "percent_branches_covered_display": "85"}, "missing_lines": [104, 105, 106, 124, 125, 172, 173, 186, 187], "excluded_lines": [], "start_line": 55, "executed_branches": [[87, 88], [87, 92], [89, 90], [114, 115], [114, 117], [121, 122], [121, 127], [148, 149], [148, 155], [149, 150], [149, 155], [155, 156], [155, 166], [156, 157], [156, 166], [166, 167], [166, 175], [182, 183], [183, 184], [183, 191], [191, -179], [191, 192]], "missing_branches": [[89, 96], [104, 105], [104, 106], [182, 191]]}, "": {"executed_lines": [19, 21, 22, 23, 25, 26, 27, 28, 29, 30, 31, 33, 39, 40, 43, 46, 49, 50, 51, 52, 55, 69, 70, 71, 72, 73, 77, 102, 110, 131, 179], "summary": {"covered_lines": 31, "num_statements": 31, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "src/zenzic/main.py": {"executed_lines": [5, 7, 8, 10, 11, 12, 13, 15, 16, 17, 18, 19, 22, 23, 28, 42, 43, 55, 58, 59, 60, 61, 62, 63, 65, 68, 86, 104, 106, 108, 109, 112, 115, 116], "summary": {"covered_lines": 34, "num_statements": 53, "percent_covered": 59.01639344262295, "percent_covered_display": "59", "missing_lines": 19, "excluded_lines": 2, "percent_statements_covered": 64.15094339622641, "percent_statements_covered_display": "64", "num_branches": 8, "num_partial_branches": 2, "covered_branches": 2, "missing_branches": 6, "percent_branches_covered": 25.0, "percent_branches_covered_display": "25"}, "missing_lines": [24, 25, 70, 71, 72, 73, 74, 75, 88, 101, 113, 117, 118, 119, 120, 125, 126, 127, 132], "excluded_lines": [137, 138], "executed_branches": [[23, -22], [112, 115]], "missing_branches": [[23, 24], [71, 72], [71, 75], [73, 74], [73, 75], [112, 113]], "functions": {"_version_callback": {"executed_lines": [23], "summary": {"covered_lines": 1, "num_statements": 3, "percent_covered": 40.0, "percent_covered_display": "40", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 33.333333333333336, "percent_statements_covered_display": "33", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50"}, "missing_lines": [24, 25], "excluded_lines": [], "start_line": 22, "executed_branches": [[23, -22]], "missing_branches": [[23, 24]]}, "_main": {"executed_lines": [55], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 43, "executed_branches": [], "missing_branches": []}, "_sentinel_alert": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 6, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 6, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 4, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0"}, "missing_lines": [70, 71, 72, 73, 74, 75], "excluded_lines": [], "start_line": 68, "executed_branches": [], "missing_branches": [[71, 72], [71, 75], [73, 74], [73, 75]]}, "_print_banner": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 2, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 2, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [88, 101], "excluded_lines": [], "start_line": 86, "executed_branches": [], "missing_branches": []}, "cli_main": {"executed_lines": [106, 108, 109, 112, 115, 116], "summary": {"covered_lines": 6, "num_statements": 15, "percent_covered": 41.1764705882353, "percent_covered_display": "41", "missing_lines": 9, "excluded_lines": 0, "percent_statements_covered": 40.0, "percent_statements_covered_display": "40", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50"}, "missing_lines": [113, 117, 118, 119, 120, 125, 126, 127, 132], "excluded_lines": [], "start_line": 104, "executed_branches": [[112, 115]], "missing_branches": [[112, 113]]}, "": {"executed_lines": [5, 7, 8, 10, 11, 12, 13, 15, 16, 17, 18, 19, 22, 28, 42, 43, 58, 59, 60, 61, 62, 63, 65, 68, 86, 104], "summary": {"covered_lines": 26, "num_statements": 26, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 2, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [137, 138], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [5, 7, 8, 10, 11, 12, 13, 15, 16, 17, 18, 19, 22, 23, 28, 42, 43, 55, 58, 59, 60, 61, 62, 63, 65, 68, 86, 104, 106, 108, 109, 112, 115, 116], "summary": {"covered_lines": 34, "num_statements": 53, "percent_covered": 59.01639344262295, "percent_covered_display": "59", "missing_lines": 19, "excluded_lines": 2, "percent_statements_covered": 64.15094339622641, "percent_statements_covered_display": "64", "num_branches": 8, "num_partial_branches": 2, "covered_branches": 2, "missing_branches": 6, "percent_branches_covered": 25.0, "percent_branches_covered_display": "25"}, "missing_lines": [24, 25, 70, 71, 72, 73, 74, 75, 88, 101, 113, 117, 118, 119, 120, 125, 126, 127, 132], "excluded_lines": [137, 138], "start_line": 1, "executed_branches": [[23, -22], [112, 115]], "missing_branches": [[23, 24], [71, 72], [71, 75], [73, 74], [73, 75], [112, 113]]}}}, "src/zenzic/models/__init__.py": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "src/zenzic/models/config.py": {"executed_lines": [5, 7, 8, 9, 10, 12, 16, 19, 35, 36, 37, 38, 44, 52, 53, 54, 58, 67, 75, 85, 108, 116, 119, 127, 131, 135, 164, 174, 182, 193, 203, 213, 221, 230, 241, 251, 255, 263, 271, 280, 289, 300, 306, 308, 312, 313, 315, 316, 322, 324, 325, 330, 331, 332, 346, 347, 348, 351, 352, 359, 361, 362, 387, 390, 391, 392, 393, 394, 395, 396, 403, 406, 407, 408, 409, 410, 411, 412, 419, 420, 421, 422, 425], "summary": {"covered_lines": 83, "num_statements": 86, "percent_covered": 94.11764705882354, "percent_covered_display": "94", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 96.51162790697674, "percent_statements_covered_display": "97", "num_branches": 16, "num_partial_branches": 1, "covered_branches": 13, "missing_branches": 3, "percent_branches_covered": 81.25, "percent_branches_covered_display": "81"}, "missing_lines": [333, 334, 342], "excluded_lines": [], "executed_branches": [[331, 332], [331, 346], [332, 331], [347, 348], [347, 351], [351, 352], [351, 359], [391, 392], [391, 406], [407, 408], [407, 425], [421, 422], [421, 425]], "missing_branches": [[332, 333], [333, 334], [333, 342]], "functions": {"ZenzicConfig.model_post_init": {"executed_lines": [308, 312, 313], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 306, "executed_branches": [], "missing_branches": []}, "ZenzicConfig._build_from_data": {"executed_lines": [322, 324, 325, 330, 331, 332, 346, 347, 348, 351, 352, 359], "summary": {"covered_lines": 12, "num_statements": 15, "percent_covered": 76.0, "percent_covered_display": "76", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 80.0, "percent_statements_covered_display": "80", "num_branches": 10, "num_partial_branches": 1, "covered_branches": 7, "missing_branches": 3, "percent_branches_covered": 70.0, "percent_branches_covered_display": "70"}, "missing_lines": [333, 334, 342], "excluded_lines": [], "start_line": 316, "executed_branches": [[331, 332], [331, 346], [332, 331], [347, 348], [347, 351], [351, 352], [351, 359]], "missing_branches": [[332, 333], [333, 334], [333, 342]]}, "ZenzicConfig.load": {"executed_lines": [387, 390, 391, 392, 393, 394, 395, 396, 403, 406, 407, 408, 409, 410, 411, 412, 419, 420, 421, 422, 425], "summary": {"covered_lines": 21, "num_statements": 21, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 6, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 362, "executed_branches": [[391, 392], [391, 406], [407, 408], [407, 425], [421, 422], [421, 425]], "missing_branches": []}, "": {"executed_lines": [5, 7, 8, 9, 10, 12, 16, 19, 35, 36, 37, 38, 44, 52, 53, 54, 58, 67, 75, 85, 108, 116, 119, 127, 131, 135, 164, 174, 182, 193, 203, 213, 221, 230, 241, 251, 255, 263, 271, 280, 289, 300, 306, 315, 316, 361, 362], "summary": {"covered_lines": 47, "num_statements": 47, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"CustomRuleConfig": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 19, "executed_branches": [], "missing_branches": []}, "BuildContext": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 44, "executed_branches": [], "missing_branches": []}, "ZenzicConfig": {"executed_lines": [308, 312, 313, 322, 324, 325, 330, 331, 332, 346, 347, 348, 351, 352, 359, 387, 390, 391, 392, 393, 394, 395, 396, 403, 406, 407, 408, 409, 410, 411, 412, 419, 420, 421, 422, 425], "summary": {"covered_lines": 36, "num_statements": 39, "percent_covered": 89.0909090909091, "percent_covered_display": "89", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 92.3076923076923, "percent_statements_covered_display": "92", "num_branches": 16, "num_partial_branches": 1, "covered_branches": 13, "missing_branches": 3, "percent_branches_covered": 81.25, "percent_branches_covered_display": "81"}, "missing_lines": [333, 334, 342], "excluded_lines": [], "start_line": 108, "executed_branches": [[331, 332], [331, 346], [332, 331], [347, 348], [347, 351], [351, 352], [351, 359], [391, 392], [391, 406], [407, 408], [407, 425], [421, 422], [421, 425]], "missing_branches": [[332, 333], [333, 334], [333, 342]]}, "": {"executed_lines": [5, 7, 8, 9, 10, 12, 16, 19, 35, 36, 37, 38, 44, 52, 53, 54, 58, 67, 75, 85, 108, 116, 119, 127, 131, 135, 164, 174, 182, 193, 203, 213, 221, 230, 241, 251, 255, 263, 271, 280, 289, 300, 306, 315, 316, 361, 362], "summary": {"covered_lines": 47, "num_statements": 47, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "src/zenzic/models/references.py": {"executed_lines": [20, 22, 23, 24, 35, 36, 58, 59, 60, 62, 74, 75, 76, 77, 78, 79, 81, 90, 91, 92, 93, 94, 96, 98, 99, 100, 102, 104, 105, 107, 109, 111, 113, 114, 116, 118, 119, 126, 127, 128, 134, 135, 151, 152, 153, 154, 155, 161, 162, 175, 176, 177, 178, 179, 181, 182, 184, 186, 187, 189, 190, 191], "summary": {"covered_lines": 62, "num_statements": 63, "percent_covered": 97.1830985915493, "percent_covered_display": "97", "missing_lines": 1, "excluded_lines": 3, "percent_statements_covered": 98.41269841269842, "percent_statements_covered_display": "98", "num_branches": 8, "num_partial_branches": 1, "covered_branches": 7, "missing_branches": 1, "percent_branches_covered": 87.5, "percent_branches_covered_display": "88"}, "missing_lines": [110], "excluded_lines": [27, 28, 29], "executed_branches": [[75, 76], [75, 78], [91, 92], [91, 94], [109, 111], [126, 127], [126, 128]], "missing_branches": [[109, 110]], "functions": {"ReferenceMap.add_definition": {"executed_lines": [74, 75, 76, 77, 78, 79], "summary": {"covered_lines": 6, "num_statements": 6, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 62, "executed_branches": [[75, 76], [75, 78]], "missing_branches": []}, "ReferenceMap.resolve": {"executed_lines": [90, 91, 92, 93, 94], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 81, "executed_branches": [[91, 92], [91, 94]], "missing_branches": []}, "ReferenceMap.get_definition_line": {"executed_lines": [98, 99, 100], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 96, "executed_branches": [], "missing_branches": []}, "ReferenceMap.__getitem__": {"executed_lines": [104, 105], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 102, "executed_branches": [], "missing_branches": []}, "ReferenceMap.__contains__": {"executed_lines": [109, 111], "summary": {"covered_lines": 2, "num_statements": 3, "percent_covered": 60.0, "percent_covered_display": "60", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 66.66666666666667, "percent_statements_covered_display": "67", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50"}, "missing_lines": [110], "excluded_lines": [], "start_line": 107, "executed_branches": [[109, 111]], "missing_branches": [[109, 110]]}, "ReferenceMap.orphan_definitions": {"executed_lines": [116], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 114, "executed_branches": [], "missing_branches": []}, "ReferenceMap.integrity_score": {"executed_lines": [126, 127, 128], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 2, "num_partial_branches": 0, "covered_branches": 2, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 119, "executed_branches": [[126, 127], [126, 128]], "missing_branches": []}, "IntegrityReport.is_secure": {"executed_lines": [184], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 182, "executed_branches": [], "missing_branches": []}, "IntegrityReport.has_errors": {"executed_lines": [189, 190, 191], "summary": {"covered_lines": 3, "num_statements": 3, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 187, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [20, 22, 23, 24, 35, 36, 58, 59, 60, 62, 81, 96, 102, 107, 113, 114, 118, 119, 134, 135, 151, 152, 153, 154, 155, 161, 162, 175, 176, 177, 178, 179, 181, 182, 186, 187], "summary": {"covered_lines": 36, "num_statements": 36, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 3, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [27, 28, 29], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"ReferenceMap": {"executed_lines": [74, 75, 76, 77, 78, 79, 90, 91, 92, 93, 94, 98, 99, 100, 104, 105, 109, 111, 116, 126, 127, 128], "summary": {"covered_lines": 22, "num_statements": 23, "percent_covered": 93.54838709677419, "percent_covered_display": "94", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 95.65217391304348, "percent_statements_covered_display": "96", "num_branches": 8, "num_partial_branches": 1, "covered_branches": 7, "missing_branches": 1, "percent_branches_covered": 87.5, "percent_branches_covered_display": "88"}, "missing_lines": [110], "excluded_lines": [], "start_line": 36, "executed_branches": [[75, 76], [75, 78], [91, 92], [91, 94], [109, 111], [126, 127], [126, 128]], "missing_branches": [[109, 110]]}, "ReferenceFinding": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 0, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 135, "executed_branches": [], "missing_branches": []}, "IntegrityReport": {"executed_lines": [184, 189, 190, 191], "summary": {"covered_lines": 4, "num_statements": 4, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 162, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [20, 22, 23, 24, 35, 36, 58, 59, 60, 62, 81, 96, 102, 107, 113, 114, 118, 119, 134, 135, 151, 152, 153, 154, 155, 161, 162, 175, 176, 177, 178, 179, 181, 182, 186, 187], "summary": {"covered_lines": 36, "num_statements": 36, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 3, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [27, 28, 29], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "src/zenzic/models/vsm.py": {"executed_lines": [16, 18, 19, 20, 25, 31, 32, 64, 65, 66, 67, 68, 72, 73, 75, 77, 78, 80, 88, 94, 106, 107, 108, 109, 110, 112, 118, 161, 164, 169, 170, 173, 174, 175, 176, 178, 179, 180, 181, 186, 192, 194, 196], "summary": {"covered_lines": 43, "num_statements": 46, "percent_covered": 91.07142857142857, "percent_covered_display": "91", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 93.47826086956522, "percent_statements_covered_display": "93", "num_branches": 10, "num_partial_branches": 2, "covered_branches": 8, "missing_branches": 2, "percent_branches_covered": 80.0, "percent_branches_covered_display": "80"}, "missing_lines": [171, 183, 184], "excluded_lines": [], "executed_branches": [[107, -94], [107, 108], [108, 109], [108, 112], [170, 173], [174, 175], [174, 194], [178, 179]], "missing_branches": [[170, 171], [178, 183]], "functions": {"Route.is_reachable": {"executed_lines": [75], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 73, "executed_branches": [], "missing_branches": []}, "Route.is_conflict": {"executed_lines": [80], "summary": {"covered_lines": 1, "num_statements": 1, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 78, "executed_branches": [], "missing_branches": []}, "_detect_collisions": {"executed_lines": [106, 107, 108, 109, 110, 112], "summary": {"covered_lines": 6, "num_statements": 6, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 4, "num_partial_branches": 0, "covered_branches": 4, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 94, "executed_branches": [[107, -94], [107, 108], [108, 109], [108, 112]], "missing_branches": []}, "build_vsm": {"executed_lines": [161, 164, 169, 170, 173, 174, 175, 176, 178, 179, 180, 181, 186, 192, 194, 196], "summary": {"covered_lines": 16, "num_statements": 19, "percent_covered": 80.0, "percent_covered_display": "80", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 84.21052631578948, "percent_statements_covered_display": "84", "num_branches": 6, "num_partial_branches": 2, "covered_branches": 4, "missing_branches": 2, "percent_branches_covered": 66.66666666666667, "percent_branches_covered_display": "67"}, "missing_lines": [171, 183, 184], "excluded_lines": [], "start_line": 118, "executed_branches": [[170, 173], [174, 175], [174, 194], [178, 179]], "missing_branches": [[170, 171], [178, 183]]}, "": {"executed_lines": [16, 18, 19, 20, 25, 31, 32, 64, 65, 66, 67, 68, 72, 73, 77, 78, 88, 94, 118], "summary": {"covered_lines": 19, "num_statements": 19, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"Route": {"executed_lines": [75, 80], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 32, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [16, 18, 19, 20, 25, 31, 32, 64, 65, 66, 67, 68, 72, 73, 77, 78, 88, 94, 106, 107, 108, 109, 110, 112, 118, 161, 164, 169, 170, 173, 174, 175, 176, 178, 179, 180, 181, 186, 192, 194, 196], "summary": {"covered_lines": 41, "num_statements": 44, "percent_covered": 90.74074074074075, "percent_covered_display": "91", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 93.18181818181819, "percent_statements_covered_display": "93", "num_branches": 10, "num_partial_branches": 2, "covered_branches": 8, "missing_branches": 2, "percent_branches_covered": 80.0, "percent_branches_covered_display": "80"}, "missing_lines": [171, 183, 184], "excluded_lines": [], "start_line": 1, "executed_branches": [[107, -94], [107, 108], [108, 109], [108, 112], [170, 173], [174, 175], [174, 194], [178, 179]], "missing_branches": [[170, 171], [178, 183]]}}}, "src/zenzic/rules.py": {"executed_lines": [16, 18, 20, 30, 41, 66, 67], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "executed_branches": [], "missing_branches": [], "functions": {"run_rule": {"executed_lines": [66, 67], "summary": {"covered_lines": 2, "num_statements": 2, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 41, "executed_branches": [], "missing_branches": []}, "": {"executed_lines": [16, 18, 20, 30, 41], "summary": {"covered_lines": 5, "num_statements": 5, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [16, 18, 20, 30, 41, 66, 67], "summary": {"covered_lines": 7, "num_statements": 7, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}}, "src/zenzic/ui.py": {"executed_lines": [11, 13, 14, 19, 20, 21, 22, 23, 24, 27, 28, 29, 30, 31, 36, 48, 49, 50, 51, 52, 54, 55, 57, 60, 64, 77, 79, 80, 82, 88, 102], "summary": {"covered_lines": 31, "num_statements": 48, "percent_covered": 57.142857142857146, "percent_covered_display": "57", "missing_lines": 17, "excluded_lines": 0, "percent_statements_covered": 64.58333333333333, "percent_statements_covered_display": "65", "num_branches": 8, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 7, "percent_branches_covered": 12.5, "percent_branches_covered_display": "12"}, "missing_lines": [81, 94, 95, 99, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136], "excluded_lines": [], "executed_branches": [[80, 82]], "missing_branches": [[80, 81], [128, 129], [128, 130], [130, 131], [130, 133], [133, 134], [133, 135]], "functions": {"_detect_capabilities": {"executed_lines": [48, 49, 50, 51, 52, 54, 55, 57], "summary": {"covered_lines": 8, "num_statements": 8, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 36, "executed_branches": [], "missing_branches": []}, "emoji": {"executed_lines": [79, 80, 82], "summary": {"covered_lines": 3, "num_statements": 4, "percent_covered": 66.66666666666667, "percent_covered_display": "67", "missing_lines": 1, "excluded_lines": 0, "percent_statements_covered": 75.0, "percent_statements_covered_display": "75", "num_branches": 2, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 1, "percent_branches_covered": 50.0, "percent_branches_covered_display": "50"}, "missing_lines": [81], "excluded_lines": [], "start_line": 77, "executed_branches": [[80, 82]], "missing_branches": [[80, 81]]}, "make_banner": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 3, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 3, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [94, 95, 99], "excluded_lines": [], "start_line": 88, "executed_branches": [], "missing_branches": []}, "make_sentinel_header": {"executed_lines": [], "summary": {"covered_lines": 0, "num_statements": 13, "percent_covered": 0.0, "percent_covered_display": "0", "missing_lines": 13, "excluded_lines": 0, "percent_statements_covered": 0.0, "percent_statements_covered_display": "0", "num_branches": 6, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 6, "percent_branches_covered": 0.0, "percent_branches_covered_display": "0"}, "missing_lines": [124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136], "excluded_lines": [], "start_line": 102, "executed_branches": [], "missing_branches": [[128, 129], [128, 130], [130, 131], [130, 133], [133, 134], [133, 135]]}, "": {"executed_lines": [11, 13, 14, 19, 20, 21, 22, 23, 24, 27, 28, 29, 30, 31, 36, 60, 64, 77, 88, 102], "summary": {"covered_lines": 20, "num_statements": 20, "percent_covered": 100.0, "percent_covered_display": "100", "missing_lines": 0, "excluded_lines": 0, "percent_statements_covered": 100.0, "percent_statements_covered_display": "100", "num_branches": 0, "num_partial_branches": 0, "covered_branches": 0, "missing_branches": 0, "percent_branches_covered": 100.0, "percent_branches_covered_display": "100"}, "missing_lines": [], "excluded_lines": [], "start_line": 1, "executed_branches": [], "missing_branches": []}}, "classes": {"": {"executed_lines": [11, 13, 14, 19, 20, 21, 22, 23, 24, 27, 28, 29, 30, 31, 36, 48, 49, 50, 51, 52, 54, 55, 57, 60, 64, 77, 79, 80, 82, 88, 102], "summary": {"covered_lines": 31, "num_statements": 48, "percent_covered": 57.142857142857146, "percent_covered_display": "57", "missing_lines": 17, "excluded_lines": 0, "percent_statements_covered": 64.58333333333333, "percent_statements_covered_display": "65", "num_branches": 8, "num_partial_branches": 1, "covered_branches": 1, "missing_branches": 7, "percent_branches_covered": 12.5, "percent_branches_covered_display": "12"}, "missing_lines": [81, 94, 95, 99, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136], "excluded_lines": [], "start_line": 1, "executed_branches": [[80, 82]], "missing_branches": [[80, 81], [128, 129], [128, 130], [130, 131], [130, 133], [133, 134], [133, 135]]}}}}, "totals": {"covered_lines": 3233, "num_statements": 3762, "percent_covered": 83.82692307692308, "percent_covered_display": "84", "missing_lines": 529, "excluded_lines": 69, "percent_statements_covered": 85.93833067517278, "percent_statements_covered_display": "86", "num_branches": 1438, "num_partial_branches": 170, "covered_branches": 1126, "missing_branches": 312, "percent_branches_covered": 78.30319888734353, "percent_branches_covered_display": "78"}} diff --git a/examples/docusaurus-v3-enterprise/README.md b/examples/docusaurus-v3-enterprise/README.md new file mode 100644 index 0000000..c59be43 --- /dev/null +++ b/examples/docusaurus-v3-enterprise/README.md @@ -0,0 +1,33 @@ +# Docusaurus v3 Enterprise โ€” Reference Fixture + +This example is the flagship Zenzic fixture. It demonstrates the full stack +of Docusaurus v3 analysis capabilities in a single coherent project. + +## What this example shows + +| Feature | File | Demonstrates | +|---|---|---| +| Current docs | `docs/intro.mdx` | Standard Docusaurus routing | +| @site/ alias | `docs/guide/deploy.mdx` | `@site/docs/` prefix resolution | +| Versioned docs | `versioned_docs/version-1.0.0/intro.md` | Cross-version alias link | +| Ghost Routing | `i18n/it/โ€ฆ/intro.mdx` | Bilingual route validation | + +## Key check โ€” versioned @site/ link + +In `versioned_docs/version-1.0.0/intro.md`: + +```markdown +Read the [current Introduction](@site/docs/intro.mdx) for the latest content. +``` + +Zenzic resolves `@site/docs/intro.mdx` โ†’ `docs/intro.mdx` โ†’ `REACHABLE`. +No Node.js process is ever invoked. + +## Run + +```bash +cd examples/docusaurus-v3-enterprise +zenzic check all +``` + +Expected: all checks pass, exit code 0. diff --git a/examples/docusaurus-v3-enterprise/docs/guide/deploy.mdx b/examples/docusaurus-v3-enterprise/docs/guide/deploy.mdx new file mode 100644 index 0000000..d6f19d1 --- /dev/null +++ b/examples/docusaurus-v3-enterprise/docs/guide/deploy.mdx @@ -0,0 +1,18 @@ +--- +title: Deployment +--- + +# Deployment Guide + +This page demonstrates `@site/` alias resolution. + +The following link uses the Docusaurus `@site/` virtual prefix to reference +a page from the current docs tree โ€” regardless of which versioned snapshot +includes this file: + +See the [Introduction](@site/docs/intro.mdx) for context. + +Zenzic resolves `@site/docs/` โ†’ `docs_root` and confirms the target exists +without executing the Docusaurus build pipeline. + +Return to the [Guide Index](index.mdx). diff --git a/examples/docusaurus-v3-enterprise/docs/guide/index.mdx b/examples/docusaurus-v3-enterprise/docs/guide/index.mdx new file mode 100644 index 0000000..71409c2 --- /dev/null +++ b/examples/docusaurus-v3-enterprise/docs/guide/index.mdx @@ -0,0 +1,14 @@ +--- +title: Guide +--- + +# Guide + +This section covers installation, configuration, and deployment. + +Zenzic validates all links in this guide tree without executing the Docusaurus +build pipeline. It reads `docusaurus.config.ts` as plain text to extract +`baseUrl` and `routeBasePath`, then maps each `.mdx` source file to its +canonical URL using pure Python. + +Navigate to [Deployment](deploy.mdx) or return to the [Introduction](../intro.mdx). diff --git a/examples/docusaurus-v3-enterprise/docs/intro.mdx b/examples/docusaurus-v3-enterprise/docs/intro.mdx new file mode 100644 index 0000000..f5e5b70 --- /dev/null +++ b/examples/docusaurus-v3-enterprise/docs/intro.mdx @@ -0,0 +1,19 @@ +--- +title: Introduction +--- + +# Welcome to Enterprise Docs + +This is the **current** version of the documentation. + +Zenzic validates this project without running Node.js. It maps every `.mdx` +source to its canonical Docusaurus URL using pure Python, resolving: + +- The `@site/` virtual prefix for cross-document links +- Versioned docs under `versioned_docs/version-1.0.0/` +- Italian ghost routes under `i18n/it/` + +## Quick links + +- [Deployment Guide](guide/deploy.mdx) +- [Guide Index](guide/index.mdx) diff --git a/examples/docusaurus-v3-enterprise/docusaurus.config.ts b/examples/docusaurus-v3-enterprise/docusaurus.config.ts new file mode 100644 index 0000000..410a5cc --- /dev/null +++ b/examples/docusaurus-v3-enterprise/docusaurus.config.ts @@ -0,0 +1,30 @@ +// SPDX-FileCopyrightText: 2026 PythonWoods +// SPDX-License-Identifier: Apache-2.0 +// +// Docusaurus v3 Enterprise config โ€” Zenzic reads this as plain text. +// Node.js is never invoked. + +const config = { + title: "Enterprise Docs", + url: "https://example.com", + baseUrl: "/", + + presets: [ + [ + "@docusaurus/preset-classic", + { + docs: { + routeBasePath: "docs", + sidebarPath: "./sidebars.ts", + }, + }, + ], + ], + + i18n: { + defaultLocale: "en", + locales: ["en", "it"], + }, +}; + +export default config; diff --git a/examples/docusaurus-v3-enterprise/i18n/it/docusaurus-plugin-content-docs/current/intro.mdx b/examples/docusaurus-v3-enterprise/i18n/it/docusaurus-plugin-content-docs/current/intro.mdx new file mode 100644 index 0000000..93bc1aa --- /dev/null +++ b/examples/docusaurus-v3-enterprise/i18n/it/docusaurus-plugin-content-docs/current/intro.mdx @@ -0,0 +1,13 @@ +--- +title: Introduzione +--- + +# Benvenuto nella Documentazione Enterprise + +Questa รจ la versione **corrente** della documentazione in italiano. + +Zenzic valida i link di questo progetto senza eseguire il build di Docusaurus. +Legge il file `docusaurus.config.ts` come testo semplice per estrarre `baseUrl` +e mappa ogni file `.mdx` al suo URL canonico tramite puro Python. + +Consulta la [Guida al Deployment](guide/deploy.mdx) per i dettagli operativi. diff --git a/examples/docusaurus-v3-enterprise/versioned_docs/version-1.0.0/guide/index.md b/examples/docusaurus-v3-enterprise/versioned_docs/version-1.0.0/guide/index.md new file mode 100644 index 0000000..a5654c6 --- /dev/null +++ b/examples/docusaurus-v3-enterprise/versioned_docs/version-1.0.0/guide/index.md @@ -0,0 +1,13 @@ +--- +--- + +# Guide โ€” v1.0.0 + +This is the guide section of the v1.0.0 documentation snapshot. + +The v1.0.0 release introduced the core adapter protocol and the Virtual Site Map +engine. All link validation, anchor checks, and Shield scans were available from +this version onward. No build pipeline was required. + +Return to the [v1.0.0 Introduction](../intro.md) or read the +[current Introduction](@site/docs/intro.mdx) for the latest version. diff --git a/examples/docusaurus-v3-enterprise/versioned_docs/version-1.0.0/intro.md b/examples/docusaurus-v3-enterprise/versioned_docs/version-1.0.0/intro.md new file mode 100644 index 0000000..e1196a8 --- /dev/null +++ b/examples/docusaurus-v3-enterprise/versioned_docs/version-1.0.0/intro.md @@ -0,0 +1,24 @@ +--- +--- + +# Welcome to Enterprise Docs โ€” v1.0.0 + +This is a **versioned snapshot** of the documentation. + +Zenzic discovers this file via `versioned_docs/version-1.0.0/` and the +`versions.json` manifest. It is served at `/docs/1.0.0/intro` in the live +Docusaurus site. + +## Cross-version alias link + +The following link uses `@site/docs/` to reference the **current** introduction +page, demonstrating that Zenzic resolves cross-version aliases correctly: + +Read the [current Introduction](@site/docs/intro.mdx) for the latest content. + +Zenzic maps `@site/docs/intro.mdx` โ†’ `docs/intro.mdx` โ†’ `REACHABLE` without +running a single Node.js process. + +## Navigation + +- [Guide (v1.0.0)](guide/index.md) diff --git a/examples/docusaurus-v3-enterprise/versions.json b/examples/docusaurus-v3-enterprise/versions.json new file mode 100644 index 0000000..64de05e --- /dev/null +++ b/examples/docusaurus-v3-enterprise/versions.json @@ -0,0 +1 @@ +["1.0.0"] diff --git a/examples/docusaurus-v3-enterprise/zenzic.toml b/examples/docusaurus-v3-enterprise/zenzic.toml new file mode 100644 index 0000000..934be9e --- /dev/null +++ b/examples/docusaurus-v3-enterprise/zenzic.toml @@ -0,0 +1,25 @@ +# SPDX-FileCopyrightText: 2026 PythonWoods +# SPDX-License-Identifier: Apache-2.0 +# zenzic.toml โ€” Docusaurus v3 Enterprise reference fixture. +# +# Demonstrates: +# โ€ข Versioned docs (versioned_docs/version-1.0.0/) with versions.json +# โ€ข @site/ alias resolution โ€” versioned page links to current /docs/intro +# โ€ข Ghost Routing โ€” Italian translations in i18n/it/ +# โ€ข Cross-version link resolution without Node.js +# +# Run: zenzic check all +# Expected: SUCCESS โ€” all links and aliases resolve + +docs_dir = "docs" +fail_under = 90 + +# Zenzic Shield โ€” built-in credential scanner (always active, no config required). +# Detected pattern families: openai-api-key, github-token, aws-access-key, +# stripe-live-key, slack-token, google-api-key, private-key, +# hex-encoded-payload (3+ consecutive \xNN sequences). +# All lines including fenced code blocks are scanned. Exit code 2 on detection. + +[build_context] +engine = "docusaurus" +locales = ["it"] diff --git a/examples/docusaurus-v3/docs/guide/install.mdx b/examples/docusaurus-v3/docs/guide/install.mdx index 5e3b20a..566240f 100644 --- a/examples/docusaurus-v3/docs/guide/install.mdx +++ b/examples/docusaurus-v3/docs/guide/install.mdx @@ -7,7 +7,7 @@ title: Installation Guide Install Zenzic with a single command: ```bash -uvx --pre zenzic check all --engine docusaurus +uvx zenzic check all --engine docusaurus ``` ## Prerequisites diff --git a/examples/docusaurus-v3/i18n/it/docusaurus-plugin-content-docs/current/guide/install.mdx b/examples/docusaurus-v3/i18n/it/docusaurus-plugin-content-docs/current/guide/install.mdx index 4aaac4b..3078f22 100644 --- a/examples/docusaurus-v3/i18n/it/docusaurus-plugin-content-docs/current/guide/install.mdx +++ b/examples/docusaurus-v3/i18n/it/docusaurus-plugin-content-docs/current/guide/install.mdx @@ -7,7 +7,7 @@ title: Guida all'Installazione Installa Zenzic con un singolo comando: ```bash -uvx --pre zenzic check all --engine docusaurus +uvx zenzic check all --engine docusaurus ``` ## Prerequisiti diff --git a/examples/mkdocs-basic/docs/api.md b/examples/mkdocs-basic/docs/api.md index 6e8a35d..e8e27a4 100644 --- a/examples/mkdocs-basic/docs/api.md +++ b/examples/mkdocs-basic/docs/api.md @@ -6,4 +6,9 @@ In this fixture the content remains intentionally concise, but long enough to exercise quality thresholds and demonstrate that page-level checks operate on source text independently from rendered templates or plugin runtime. +> **Demo finding โ€” broken anchor:** The following link points to an anchor that +> does not exist in `guide/index.md`. Zenzic reports `BROKEN_ANCHOR`. + +See [Advanced Configuration](guide/index.md#advanced-configuration) for details. + Back to the [Guide](guide/index.md) or [Home](index.md). diff --git a/examples/mkdocs-basic/docs/guide/index.md b/examples/mkdocs-basic/docs/guide/index.md index feae46e..3dcc259 100644 --- a/examples/mkdocs-basic/docs/guide/index.md +++ b/examples/mkdocs-basic/docs/guide/index.md @@ -7,3 +7,8 @@ consistently with MkDocs 1.x rules, including stable URL mapping and previous next navigation derivation from declared nav order rather than filesystem order. Continue with [Setup](setup.md) or return [Home](../index.md). + +> **Demo finding โ€” broken link:** The following link targets a file that does +> not exist in this fixture. Zenzic reports `FILE_NOT_FOUND`. + +See the [Deployment Guide](../deployment.md) for production setup. diff --git a/examples/mkdocs-basic/zenzic.toml b/examples/mkdocs-basic/zenzic.toml index bed8f8c..a4f5572 100644 --- a/examples/mkdocs-basic/zenzic.toml +++ b/examples/mkdocs-basic/zenzic.toml @@ -1,9 +1,19 @@ # SPDX-FileCopyrightText: 2026 PythonWoods # SPDX-License-Identifier: Apache-2.0 # zenzic.toml โ€” MkDocs 1.x baseline fixture. +# +# This example intentionally contains two demo findings to show Zenzic's +# detection capabilities: +# +# โ€ข FILE_NOT_FOUND โ€” guide/index.md links to ../deployment.md (absent) +# โ€ข BROKEN_ANCHOR โ€” api.md links to guide/index.md#advanced-configuration +# (anchor does not exist) +# +# Run: zenzic check all +# Expected: two findings reported, exit code 1 docs_dir = "docs" -fail_under = 90 +fail_under = 0 # Zenzic Shield โ€” built-in credential scanner (always active, no config required). # Detected pattern families: openai-api-key, github-token, aws-access-key, diff --git a/examples/run_demo.sh b/examples/run_demo.sh index b63ba1b..7377fff 100755 --- a/examples/run_demo.sh +++ b/examples/run_demo.sh @@ -4,14 +4,17 @@ # # run_demo.sh โ€” The Zenzic Philosophy Tour. # -# Five acts that cover the full spectrum of documentation integrity: +# Nine acts (Acts 0โ€“8) that cover the full spectrum of documentation integrity: # -# Act 0 โ€” MkDocs Baseline : mkdocs-basic must pass as 1.x reference. +# Act 0 โ€” Linter Demo : mkdocs-basic shows FILE_NOT_FOUND + BROKEN_ANCHOR. # Act 1 โ€” The Gold Standard : i18n-standard must pass with 100/100. # Act 2 โ€” The Broken Docs : broken-docs must fail, showing every error class. # Act 3 โ€” The Shield : security_lab must block traversal and absolute links. # Act 4 โ€” Single-File Target : single-file-target โ€” audit only README.md. # Act 5 โ€” Custom Dir Target : custom-dir-target โ€” audit content/ instead of docs/. +# Act 6 โ€” Transparent Proxy : zensical-bridge โ€” SENTINEL banner + bridge activation. +# Act 7 โ€” The Flagship : docusaurus-v3-enterprise โ€” versioned docs + @site/ + i18n. +# Act 8 โ€” Minimum Viable : vanilla-markdown โ€” MISSING_DIRECTORY_INDEX on bare .md. # # Usage (from repo root): # bash examples/run_demo.sh @@ -53,14 +56,15 @@ echo " i18n-standard assets are ghost artifacts โ€” excluded_build_artifacts ha # โ”€โ”€โ”€ Act 0: MkDocs baseline โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ -print_header "Act 0 โ€” MkDocs baseline (mkdocs-basic)" -echo " Expected: SUCCESS โ€” clean MkDocs 1.6-style fixture." +print_header "Act 0 โ€” Linter Demo (mkdocs-basic)" +echo " Expected: FAILURE โ€” FILE_NOT_FOUND (guide/index.md โ†’ ../deployment.md)" +echo " BROKEN_ANCHOR (api.md โ†’ guide/index.md#advanced-configuration)" echo "" if (cd "$REPO_ROOT/examples/mkdocs-basic" && uv run zenzic check all); then - print_result "mkdocs-basic check all" "PASS" + print_result "mkdocs-basic check all" "UNEXPECTED PASS" else - print_result "mkdocs-basic check all" "UNEXPECTED FAILURE" + print_result "mkdocs-basic check all (errors are the feature)" "FAIL" fi # โ”€โ”€โ”€ Act 1: Gold Standard โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ @@ -128,6 +132,45 @@ else print_result "custom-dir-target check all content/" "UNEXPECTED FAILURE" fi +# โ”€โ”€โ”€ Act 6: Transparent Proxy โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + +print_header "Act 6 โ€” Transparent Proxy (zensical-bridge)" +echo " engine = \"zensical\" declared, NO zensical.toml present โ€” only mkdocs.yml." +echo " Expected: SENTINEL banner printed + SUCCESS." +echo "" + +if (cd "$REPO_ROOT/examples/zensical-bridge" && uv run zenzic check all); then + print_result "zensical-bridge check all (SENTINEL banner + pass)" "PASS" +else + print_result "zensical-bridge check all" "UNEXPECTED FAILURE" +fi + +# โ”€โ”€โ”€ Act 7: The Flagship โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + +print_header "Act 7 โ€” The Flagship (docusaurus-v3-enterprise)" +echo " Versioned docs (versioned_docs/version-1.0.0/) + @site/ aliases + i18n." +echo " Expected: SUCCESS โ€” all cross-version alias links resolve." +echo "" + +if (cd "$REPO_ROOT/examples/docusaurus-v3-enterprise" && uv run zenzic check all); then + print_result "docusaurus-v3-enterprise check all" "PASS" +else + print_result "docusaurus-v3-enterprise check all" "UNEXPECTED FAILURE" +fi + +# โ”€โ”€โ”€ Act 8: Minimum Viable โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ + +print_header "Act 8 โ€” Minimum Viable (vanilla-markdown)" +echo " No build engine. docs/deep-folder/ has no index.md." +echo " Expected: MISSING_DIRECTORY_INDEX info finding + SUCCESS." +echo "" + +if (cd "$REPO_ROOT/examples/vanilla-markdown" && uv run zenzic check all --show-info); then + print_result "vanilla-markdown check all --show-info" "PASS" +else + print_result "vanilla-markdown check all --show-info" "UNEXPECTED FAILURE" +fi + # โ”€โ”€โ”€ Self-audit + score snapshot โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ print_header "Self-audit + Score Snapshot (main repo)" @@ -149,9 +192,13 @@ cat .zenzic-score.json echo "" print_header "Demo complete" -echo " Act 1 (Gold Standard) : must be green" -echo " Act 2 (Broken Docs) : must be red โ€” errors are the feature" -echo " Act 3 (Shield) : must be red โ€” attacks are blocked" -echo " Act 4 (Single-File Target): must be green โ€” 1 file audited" -echo " Act 5 (Custom Dir Target) : must be green โ€” content/ audited" +echo " Act 0 (Linter Demo) : must be red โ€” FILE_NOT_FOUND + BROKEN_ANCHOR shown" +echo " Act 1 (Gold Standard) : must be green" +echo " Act 2 (Broken Docs) : must be red โ€” errors are the feature" +echo " Act 3 (Shield) : must be red โ€” attacks are blocked" +echo " Act 4 (Single-File Target) : must be green โ€” 1 file audited" +echo " Act 5 (Custom Dir Target) : must be green โ€” content/ audited" +echo " Act 6 (Transparent Proxy) : must be green โ€” SENTINEL banner + bridge" +echo " Act 7 (Flagship) : must be green โ€” versioned @site/ + i18n" +echo " Act 8 (Minimum Viable) : must be green โ€” MISSING_DIRECTORY_INDEX fires" echo "" diff --git a/examples/standalone-markdown/README.md b/examples/standalone-markdown/README.md new file mode 100644 index 0000000..c948dd7 --- /dev/null +++ b/examples/standalone-markdown/README.md @@ -0,0 +1,41 @@ +# Vanilla Markdown โ€” MISSING_DIRECTORY_INDEX Demo + +This example demonstrates `MISSING_DIRECTORY_INDEX` detection on a bare Markdown +project with no build engine. + +## Structure + +```text +docs/ + index.md โ€” root landing page + guides/ + index.md โ€” properly indexed: no finding + setup.md + deep-folder/ โ€” NO index.md โ†’ MISSING_DIRECTORY_INDEX + advanced.md + internals.md +``` + +## What fires + +```bash +zenzic check all --show-info +``` + +```text +๐Ÿ’ก [MISSING_DIRECTORY_INDEX] Directory contains Markdown files but has +no index page โ€” the directory URL may return a 404. + docs/deep-folder +``` + +This is an **info-level** finding: exit code 0, quality score unaffected. +Add an `index.md` to `docs/deep-folder/` to resolve it. + +## Run + +```bash +cd examples/vanilla-markdown +zenzic check all --show-info +``` + +Expected: `MISSING_DIRECTORY_INDEX` info finding for `docs/deep-folder/`, all checks pass. diff --git a/examples/standalone-markdown/docs/deep-folder/advanced.md b/examples/standalone-markdown/docs/deep-folder/advanced.md new file mode 100644 index 0000000..3077632 --- /dev/null +++ b/examples/standalone-markdown/docs/deep-folder/advanced.md @@ -0,0 +1,15 @@ +# Advanced Topics + +This page lives in `docs/deep-folder/` โ€” a directory with **no `index.md`**. + +Zenzic reports `MISSING_DIRECTORY_INDEX` for this directory when you run: + +```bash +zenzic check all --show-info +``` + +This is an **info-level** finding: it does not affect the exit code or the +quality score. It highlights directories that may produce 404s when served +without an explicit nav configuration. + +See [Internals](internals.md) for implementation details. diff --git a/examples/standalone-markdown/docs/deep-folder/internals.md b/examples/standalone-markdown/docs/deep-folder/internals.md new file mode 100644 index 0000000..c1ddf54 --- /dev/null +++ b/examples/standalone-markdown/docs/deep-folder/internals.md @@ -0,0 +1,12 @@ +# Internals + +Technical notes on the vanilla engine mode. + +Zenzic's `VanillaAdapter` performs all checks without any build engine: + +- Link validation (relative `.md` paths resolved against the filesystem) +- Anchor resolution (heading IDs derived from heading text) +- Shield credential scan (9 pattern families, always active) +- `MISSING_DIRECTORY_INDEX` check (directories without `index.md`) + +Return to [Advanced Topics](advanced.md) or [Home](../index.md). diff --git a/examples/standalone-markdown/docs/guides/index.md b/examples/standalone-markdown/docs/guides/index.md new file mode 100644 index 0000000..dc15e93 --- /dev/null +++ b/examples/standalone-markdown/docs/guides/index.md @@ -0,0 +1,10 @@ +# Guides + +This section has an `index.md` โ€” Zenzic considers it properly indexed and +will not report a `MISSING_DIRECTORY_INDEX` finding for this directory. + +The directory index check fires only for subdirectories that contain Markdown +files but have no `index.md` landing page. Having an index guarantees that +visitors will always find a meaningful entry point when they navigate here. + +See [Setup](setup.md) to get started. diff --git a/examples/standalone-markdown/docs/guides/setup.md b/examples/standalone-markdown/docs/guides/setup.md new file mode 100644 index 0000000..489dd21 --- /dev/null +++ b/examples/standalone-markdown/docs/guides/setup.md @@ -0,0 +1,15 @@ +# Setup + +Install dependencies and run a check: + +```bash +pip install zenzic +zenzic check all --show-info +``` + +The `--show-info` flag reveals `MISSING_DIRECTORY_INDEX` findings for +directories that lack a landing page. These are info-level notices: they +do not affect the exit code or the quality score, but they highlight +potential 404 URLs in a live site. + +Return to the [Guides index](index.md) or [Home](../index.md). diff --git a/examples/standalone-markdown/docs/index.md b/examples/standalone-markdown/docs/index.md new file mode 100644 index 0000000..3a2c3ef --- /dev/null +++ b/examples/standalone-markdown/docs/index.md @@ -0,0 +1,13 @@ +# Vanilla Markdown Project + +A bare Markdown documentation tree โ€” no build engine, no framework, no +configuration file of any documentation system. + +Zenzic runs in Vanilla mode: links, snippets, Shield, and directory index +checks all operate without any engine-specific configuration. This makes +it suitable for Hugo, Sphinx, Astro, or any hand-written project. + +## Contents + +- [Guides](guides/index.md) +- [Deep Folder](deep-folder/advanced.md) โ€” no index.md in this section diff --git a/examples/standalone-markdown/zenzic.toml b/examples/standalone-markdown/zenzic.toml new file mode 100644 index 0000000..1d9d793 --- /dev/null +++ b/examples/standalone-markdown/zenzic.toml @@ -0,0 +1,26 @@ +# SPDX-FileCopyrightText: 2026 PythonWoods +# SPDX-License-Identifier: Apache-2.0 +# zenzic.toml โ€” Vanilla Markdown example. +# +# No build engine. No mkdocs.yml, no zensical.toml, no docusaurus.config.ts. +# Demonstrates that Zenzic protects bare Markdown projects too. +# +# Demo findings: +# โ€ข MISSING_DIRECTORY_INDEX โ€” docs/deep-folder/ contains .md files but +# has no index.md. Zenzic reports this via --show-info. +# +# Run: zenzic check all --show-info +# Expected: MISSING_DIRECTORY_INDEX info finding for docs/deep-folder/ +# All other checks pass, exit code 0 + +docs_dir = "docs" +fail_under = 80 + +# Zenzic Shield โ€” built-in credential scanner (always active, no config required). +# Detected pattern families: openai-api-key, github-token, aws-access-key, +# stripe-live-key, slack-token, google-api-key, private-key, +# hex-encoded-payload (3+ consecutive \xNN sequences). +# All lines including fenced code blocks are scanned. Exit code 2 on detection. + +[build_context] +engine = "vanilla" diff --git a/examples/zensical-bridge/README.md b/examples/zensical-bridge/README.md new file mode 100644 index 0000000..8254476 --- /dev/null +++ b/examples/zensical-bridge/README.md @@ -0,0 +1,36 @@ +# Zensical Bridge โ€” Transparent Proxy Example + +This example demonstrates Zenzic's **Transparent Proxy** mode. + +## Setup + +- `zenzic.toml` declares `engine = "zensical"` +- **No `zensical.toml`** is present โ€” only `mkdocs.yml` + +## What happens + +When `zenzic check all` runs, the **ZensicalLegacyProxy** activates and the +**Sentinel Banner** is printed: + +```text +SENTINEL: Zensical engine active via mkdocs.yml compatibility bridge. +``` + +All link validation, anchor checks, and Shield scans run via the MkDocs adapter +internally. Results are identical to running with `engine = "mkdocs"`. + +## Purpose + +This is not a silent fallback. The Sentinel Banner makes the bridge explicit, +preserving operator awareness of engine identity at all times. It provides a +frictionless migration path: add `zensical.toml` when ready, and Zenzic +automatically switches to native mode on the next run. + +## Run + +```bash +cd examples/zensical-bridge +zenzic check all +``` + +Expected output includes the Sentinel Banner followed by a clean check result. diff --git a/examples/zensical-bridge/docs/guide/index.md b/examples/zensical-bridge/docs/guide/index.md new file mode 100644 index 0000000..fd4daff --- /dev/null +++ b/examples/zensical-bridge/docs/guide/index.md @@ -0,0 +1,12 @@ +# Guide + +This guide demonstrates a project in Transparent Proxy mode. + +The `engine = "zensical"` is declared in `zenzic.toml`, but native +`zensical.toml` has not yet been created. Zenzic bridges seamlessly +via the existing `mkdocs.yml`. + +Continue with the [Migration Guide](migration.md) to learn how to +upgrade to native Zensical mode. + +Return [Home](../index.md). diff --git a/examples/zensical-bridge/docs/guide/migration.md b/examples/zensical-bridge/docs/guide/migration.md new file mode 100644 index 0000000..89ee199 --- /dev/null +++ b/examples/zensical-bridge/docs/guide/migration.md @@ -0,0 +1,28 @@ +# Migration Guide + +This section covers the migration path from MkDocs to native Zensical. + +## Step 1 โ€” Introduce `zensical.toml` + +Create a `zensical.toml` at the project root: + +```toml +[project] +site_name = "My Docs" +docs_dir = "docs" +nav = [ + "index.md", + {"Guide" = ["guide/index.md", {"Migration" = "guide/migration.md"}]}, +] +``` + +Once `zensical.toml` is present, the Transparent Proxy is deactivated and +Zenzic uses the native Zensical engine directly. The Sentinel Banner will no +longer appear. + +## Step 2 โ€” Remove `mkdocs.yml` + +After verifying all links pass with Zensical native mode, the `mkdocs.yml` +can be archived or removed. + +Return to [Home](../index.md). diff --git a/examples/zensical-bridge/docs/index.md b/examples/zensical-bridge/docs/index.md new file mode 100644 index 0000000..6fae20f --- /dev/null +++ b/examples/zensical-bridge/docs/index.md @@ -0,0 +1,18 @@ +# Welcome to the Zensical Bridge Demo + +This project declares `engine = "zensical"` in `zenzic.toml` but has **no +`zensical.toml`** โ€” only a `mkdocs.yml`. + +When you run `zenzic check all`, the **Transparent Proxy** activates +automatically and the **Sentinel Banner** is displayed: + +```text +SENTINEL: Zensical engine active via mkdocs.yml compatibility bridge. +``` + +This provides a seamless migration path from MkDocs to Zensical without +blocking your CI pipeline. Engine identity is always transparent. + +## Navigation + +- [Guide](guide/index.md) diff --git a/examples/zensical-bridge/mkdocs.yml b/examples/zensical-bridge/mkdocs.yml new file mode 100644 index 0000000..4d67a3f --- /dev/null +++ b/examples/zensical-bridge/mkdocs.yml @@ -0,0 +1,11 @@ +# SPDX-FileCopyrightText: 2026 PythonWoods +# SPDX-License-Identifier: Apache-2.0 + +site_name: Zensical Bridge Demo +site_url: https://example.com/docs/ + +nav: + - Home: index.md + - Guide: + - guide/index.md + - Migration: guide/migration.md diff --git a/examples/zensical-bridge/zenzic.toml b/examples/zensical-bridge/zenzic.toml new file mode 100644 index 0000000..035aa14 --- /dev/null +++ b/examples/zensical-bridge/zenzic.toml @@ -0,0 +1,29 @@ +# SPDX-FileCopyrightText: 2026 PythonWoods +# SPDX-License-Identifier: Apache-2.0 +# zenzic.toml โ€” Zensical Transparent Proxy (Bridge) example. +# +# engine = "zensical" is declared, but NO zensical.toml is present. +# Zenzic detects the mkdocs.yml and automatically activates the +# ZensicalLegacyProxy (Transparent Bridge), delegating all checks to +# MkDocsAdapter internally. +# +# The Sentinel Banner is printed on stdout at runtime: +# SENTINEL: Zensical engine active via mkdocs.yml compatibility bridge. +# +# This is NOT a silent fallback. The banner ensures engine identity is +# always transparent to the operator. +# +# Run: zenzic check all +# Expected: SENTINEL banner + all checks pass + +docs_dir = "docs" +fail_under = 90 + +# Zenzic Shield โ€” built-in credential scanner (always active, no config required). +# Detected pattern families: openai-api-key, github-token, aws-access-key, +# stripe-live-key, slack-token, google-api-key, private-key, +# hex-encoded-payload (3+ consecutive \xNN sequences). +# All lines including fenced code blocks are scanned. Exit code 2 on detection. + +[build_context] +engine = "zensical" diff --git a/pyproject.toml b/pyproject.toml index d8bcee6..8437570 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -7,7 +7,7 @@ build-backend = "hatchling.build" [project] name = "zenzic" -version = "0.6.1rc2" +version = "0.6.1" description = "Engineering-grade, engine-agnostic linter and security shield for Markdown documentation" readme = "README.md" requires-python = ">=3.11" @@ -49,7 +49,7 @@ zenzic = "zenzic.main:cli_main" docusaurus = "zenzic.core.adapters:DocusaurusAdapter" mkdocs = "zenzic.core.adapters:MkDocsAdapter" zensical = "zenzic.core.adapters:ZensicalAdapter" -vanilla = "zenzic.core.adapters:VanillaAdapter" +standalone = "zenzic.core.adapters:StandaloneAdapter" [project.entry-points."zenzic.rules"] broken-links = "zenzic.core.rules:VSMBrokenLinkRule" @@ -61,9 +61,9 @@ zenzic = "zenzic.integrations.mkdocs:ZenzicPlugin" [project.urls] Homepage = "https://zenzic.dev" -Documentation = "https://zenzic.dev/docs" +Documentation = "https://zenzic.dev/docs/" Repository = "https://github.com/PythonWoods/zenzic" -Changelog = "https://zenzic.dev/docs/changelog" +Changelog = "https://github.com/PythonWoods/zenzic/blob/main/CHANGELOG.md" Issues = "https://github.com/PythonWoods/zenzic/issues" # โ”€โ”€โ”€ Build โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ @@ -71,6 +71,9 @@ Issues = "https://github.com/PythonWoods/zenzic/issues" [tool.hatch.build.targets.wheel] packages = ["src/zenzic"] +[tool.hatch.build.targets.wheel.force-include] +"examples" = "zenzic/examples" + # โ”€โ”€โ”€ Development dependencies (PEP 735 โ€” managed by uv) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ [dependency-groups] @@ -183,7 +186,7 @@ pytest_add_cli_args = ["--import-mode=prepend"] # โ”€โ”€โ”€ Version bumping โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ [tool.bumpversion] -current_version = "0.6.1rc2" +current_version = "0.6.1" commit = true tag = true tag_name = "v{new_version}" diff --git a/src/zenzic/__init__.py b/src/zenzic/__init__.py index 7028f02..9e57e45 100644 --- a/src/zenzic/__init__.py +++ b/src/zenzic/__init__.py @@ -2,4 +2,4 @@ # SPDX-License-Identifier: Apache-2.0 """Zenzic โ€” engine-agnostic linter and security shield for Markdown documentation.""" -__version__ = "0.6.1rc2" +__version__ = "0.6.1" diff --git a/src/zenzic/cli.py b/src/zenzic/cli.py index f1a9233..3dad61c 100644 --- a/src/zenzic/cli.py +++ b/src/zenzic/cli.py @@ -19,11 +19,13 @@ from rich.text import Text from zenzic.core.adapters import list_adapter_engines +from zenzic.core.codes import normalize as _normalize_code from zenzic.core.exclusion import LayeredExclusionManager from zenzic.core.reporter import Finding, SentinelReporter from zenzic.core.scanner import ( PlaceholderFinding, _map_shield_to_finding, + find_missing_directory_indices, find_orphans, find_placeholders, find_repo_root, @@ -261,12 +263,17 @@ def check_links( show_info: bool = typer.Option( False, "--show-info", help="Show info-level findings (e.g. circular links) in the report." ), + offline: bool = typer.Option( + False, "--offline", help="Force flat URL resolution for offline builds." + ), ) -> None: """Check for broken internal links. Pass --strict to also validate external URLs.""" from zenzic import __version__ repo_root = find_repo_root() config, _ = ZenzicConfig.load(repo_root) + if offline: + config.build_context.offline_mode = True docs_root = (repo_root / config.docs_dir).resolve() exclusion_mgr = _build_exclusion_manager(config, repo_root, docs_root) @@ -290,7 +297,7 @@ def _rel(path: Path) -> str: Finding( rel_path=_rel(err.file_path), line_no=err.line_no, - code=err.error_type, + code=_normalize_code(err.error_type), severity=( "security_incident" if err.error_type == "PATH_TRAVERSAL_SUSPICIOUS" @@ -348,6 +355,9 @@ def check_orphans( show_info: bool = typer.Option( False, "--show-info", help="Show info-level findings (e.g. circular links) in the report." ), + offline: bool = typer.Option( + False, "--offline", help="Force flat URL resolution for offline builds." + ), ) -> None: """Detect .md files not listed in the nav.""" from zenzic import __version__ @@ -357,6 +367,8 @@ def check_orphans( if not loaded_from_file: _print_no_config_hint() config = _apply_engine_override(config, engine) + if offline: + config.build_context.offline_mode = True docs_root = (repo_root / config.docs_dir).resolve() exclusion_mgr = _build_exclusion_manager(config, repo_root, docs_root) @@ -368,7 +380,7 @@ def check_orphans( Finding( rel_path=str(path), line_no=0, - code="ORPHAN", + code="Z402", severity="warning", message="Physical file not listed in navigation.", ) @@ -440,7 +452,7 @@ def _rel(path: Path) -> str: Finding( rel_path=_rel(s_err.file_path), line_no=s_err.line_no, - code="SNIPPET", + code="Z503", severity="error", message=s_err.message, source_line=src, @@ -545,7 +557,7 @@ def _rel(path: Path) -> str: Finding( rel_path=rel, line_no=ref_f.line_no, - code=ref_f.issue, + code=_normalize_code(ref_f.issue), severity="warning" if ref_f.is_warning else "error", message=ref_f.detail, source_line=src, @@ -556,7 +568,7 @@ def _rel(path: Path) -> str: Finding( rel_path=rel, line_no=rule_f.line_no, - code=rule_f.rule_id, + code=_normalize_code(rule_f.rule_id), severity=rule_f.severity, message=rule_f.message, source_line=rule_f.matched_line or "", @@ -572,7 +584,7 @@ def _rel(path: Path) -> str: Finding( rel_path="(external-urls)", line_no=0, - code="LINK_URL", + code="Z101", severity="error", message=err_str, ) @@ -635,7 +647,7 @@ def check_assets( Finding( rel_path=str(path), line_no=0, - code="ASSET", + code="Z903", severity="warning", message="File not referenced in any documentation page.", ) @@ -747,7 +759,7 @@ def check_placeholders( Finding( rel_path=str(pf.file_path), line_no=pf.line_no, - code=pf.issue, + code=_normalize_code(pf.issue), severity="warning", message=pf.detail, source_line=src, @@ -783,6 +795,7 @@ class _AllCheckResults: nav_contract_errors: list[str] reference_reports: list[IntegrityReport] security_events: int + directory_index_issues: list[Path] @property def failed(self) -> bool: @@ -843,6 +856,9 @@ def _collect_all_results( nav_contract_errors=check_nav_contract(repo_root, exclusion_mgr), reference_reports=ref_reports, security_events=security_events, + directory_index_issues=find_missing_directory_indices( + docs_root, exclusion_mgr, repo_root=repo_root, config=config + ), ) @@ -861,7 +877,7 @@ def _rel(path: Path) -> str: Finding( rel_path=_rel(err.file_path), line_no=err.line_no, - code=err.error_type, + code=_normalize_code(err.error_type), severity=( "security_incident" if err.error_type == "PATH_TRAVERSAL_SUSPICIOUS" @@ -881,7 +897,7 @@ def _rel(path: Path) -> str: Finding( rel_path=str(path), line_no=0, - code="ORPHAN", + code="Z402", severity="warning", message="Physical file not listed in navigation.", ) @@ -900,7 +916,7 @@ def _rel(path: Path) -> str: Finding( rel_path=_rel(s_err.file_path), line_no=s_err.line_no, - code="SNIPPET", + code="Z503", severity="error", message=s_err.message, source_line=src, @@ -922,7 +938,7 @@ def _rel(path: Path) -> str: Finding( rel_path=str(pf.file_path), line_no=pf.line_no, - code=pf.issue, + code=_normalize_code(pf.issue), severity="warning", message=pf.detail, source_line=src, @@ -936,7 +952,7 @@ def _rel(path: Path) -> str: Finding( rel_path=str(path), line_no=0, - code="ASSET", + code="Z903", severity="warning", message="File not referenced in any documentation page.", ) @@ -947,7 +963,7 @@ def _rel(path: Path) -> str: Finding( rel_path="(nav)", line_no=0, - code="NAV", + code="Z904", severity="error", message=msg, ) @@ -970,7 +986,7 @@ def _rel(path: Path) -> str: Finding( rel_path=rel, line_no=ref_f.line_no, - code=ref_f.issue, + code=_normalize_code(ref_f.issue), severity="warning" if ref_f.is_warning else "error", message=ref_f.detail, source_line=src, @@ -981,7 +997,7 @@ def _rel(path: Path) -> str: Finding( rel_path=rel, line_no=rule_f.line_no, - code=rule_f.rule_id, + code=_normalize_code(rule_f.rule_id), severity=rule_f.severity, message=rule_f.message, source_line=rule_f.matched_line, @@ -995,6 +1011,20 @@ def _rel(path: Path) -> str: for sf in report.security_findings: findings.append(_map_shield_to_finding(sf, docs_root)) + for dir_path in results.directory_index_issues: + findings.append( + Finding( + rel_path=str(dir_path), + line_no=0, + code="Z401", + severity="info", + message=( + "Directory contains Markdown files but has no index page โ€” " + "the directory URL may return a 404." + ), + ) + ) + return findings @@ -1122,6 +1152,9 @@ def check_all( show_info: bool = typer.Option( False, "--show-info", help="Show info-level findings (e.g. circular links) in the report." ), + offline: bool = typer.Option( + False, "--offline", help="Force flat URL resolution for offline builds." + ), ) -> None: """Run all checks: links, orphans, snippets, placeholders, assets, references. @@ -1134,6 +1167,8 @@ def check_all( if not loaded_from_file and not quiet: _print_no_config_hint() config = _apply_engine_override(config, engine) + if offline: + config.build_context.offline_mode = True # โ”€โ”€ Target mode (single file OR custom directory) โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ _single_file: Path | None = None @@ -1521,7 +1556,7 @@ def init( Performs engine auto-detection: if ``mkdocs.yml`` is present the generated file pre-sets ``engine = "mkdocs"``; if ``zensical.toml`` is present it pre-sets ``engine = "zensical"``. Otherwise the ``[build_context]`` block - is omitted and the vanilla (engine-agnostic) defaults apply. + is omitted and the standalone (engine-agnostic) defaults apply. """ repo_root = find_repo_root(fallback_to_cwd=True) @@ -1560,7 +1595,7 @@ def _engine_feedback(detected_engine: str | None) -> str: if detected_engine: source = "mkdocs.yml" if detected_engine == "mkdocs" else "zensical.toml" return f" Engine pre-set to [bold cyan]{detected_engine}[/] (detected from {source}).\n" - return " No engine config file found โ€” using vanilla (engine-agnostic) defaults.\n" + return " No engine config file found โ€” using standalone (engine-agnostic) defaults.\n" def _init_standalone(repo_root: Path, force: bool) -> None: diff --git a/src/zenzic/core/adapter.py b/src/zenzic/core/adapter.py index 61f80ad..58cf85b 100644 --- a/src/zenzic/core/adapter.py +++ b/src/zenzic/core/adapter.py @@ -10,7 +10,7 @@ from zenzic.core.adapters import ( # noqa: F401 BaseAdapter, MkDocsAdapter, - VanillaAdapter, + StandaloneAdapter, ZensicalAdapter, _collect_nav_paths, _extract_i18n_fallback_to_default, diff --git a/src/zenzic/core/adapters/__init__.py b/src/zenzic/core/adapters/__init__.py index 6035435..05a4404 100644 --- a/src/zenzic/core/adapters/__init__.py +++ b/src/zenzic/core/adapters/__init__.py @@ -11,7 +11,7 @@ BaseAdapter โ€” ``@runtime_checkable`` Protocol every adapter must satisfy. MkDocsAdapter โ€” Folder-mode and suffix-mode i18n for MkDocs projects. ZensicalAdapter โ€” Native TOML-based adapter for Zensical projects. - VanillaAdapter โ€” No-op adapter for projects with no recognised engine. + StandaloneAdapter โ€” No-op adapter for projects with no recognised engine. Factory: get_adapter(context, docs_root, repo_root) โ†’ adapter instance. @@ -50,7 +50,7 @@ _validate_i18n_fallback_config, find_config_file, ) -from ._vanilla import VanillaAdapter +from ._standalone import StandaloneAdapter from ._zensical import ZensicalAdapter, _load_zensical_config, find_zensical_config @@ -62,7 +62,7 @@ "DocusaurusAdapter", "MkDocsAdapter", "ZensicalAdapter", - "VanillaAdapter", + "StandaloneAdapter", # Factory "get_adapter", "clear_adapter_cache", diff --git a/src/zenzic/core/adapters/_base.py b/src/zenzic/core/adapters/_base.py index 6d7e17e..fcdf57d 100644 --- a/src/zenzic/core/adapters/_base.py +++ b/src/zenzic/core/adapters/_base.py @@ -52,6 +52,7 @@ class RouteMetadata: pages auto-created by ``reconfigure_material`` or Docusaurus's i18n entry points). Proxy routes are ``REACHABLE`` but should not be checked for content integrity. + version: Optional version identifier for multi-version setups (e.g. Docusaurus versioned_docs). """ canonical_url: str @@ -59,6 +60,7 @@ class RouteMetadata: slug: str | None = None route_base_path: str = "/" is_proxy: bool = False + version: str | None = None # โ”€โ”€ BaseAdapter Protocol โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€ @@ -125,7 +127,7 @@ def get_nav_paths(self) -> frozenset[str]: def has_engine_config(self) -> bool: """Return ``True`` when a build-engine config was found and loaded. - ``VanillaAdapter`` returns ``False``. All concrete adapters return + ``StandaloneAdapter`` returns ``False``. All concrete adapters return ``True``. Callers use this to decide whether a nav-based check (e.g. orphan detection) can produce meaningful results. """ @@ -191,3 +193,23 @@ def get_route_info(self, rel: Path) -> RouteMetadata: :class:`RouteMetadata` with all routing fields populated. """ ... + + def provides_index(self, directory_path: Path) -> bool: + """Return ``True`` when the engine generates a landing page for *directory_path*. + + Called once per discovered directory during the I/O discovery phase + (never inside a per-link loop). Implementations may call + ``Path.exists()`` because this method is part of the I/O phase, not + the hot-path rule engine. + + Conservative default: ``False``. Adapters that generate directory + index pages must override this method. + + Args: + directory_path: Absolute path to the directory to check. + + Returns: + ``True`` if the engine will serve a valid page at the directory + URL (e.g. ``/docs/guides/``); ``False`` otherwise. + """ + ... diff --git a/src/zenzic/core/adapters/_docusaurus.py b/src/zenzic/core/adapters/_docusaurus.py index 717cd36..4af037b 100644 --- a/src/zenzic/core/adapters/_docusaurus.py +++ b/src/zenzic/core/adapters/_docusaurus.py @@ -254,13 +254,19 @@ def __init__( docs_root: Path, base_url: str = "/", route_base_path: str | None = None, + versions: list[str] | None = None, ) -> None: self._docs_root = docs_root + self._context = context self._base_url = base_url.rstrip("/") or "" # Docusaurus default routeBasePath is 'docs', but when docs are at # the site root it is ''. None means "not set in config" โ†’ use # no prefix (docs are already relative to docs_root). self._route_base_path = route_base_path + self._versions: tuple[str, ...] = tuple(versions or []) + # The first entry in versions.json is the "latest" version; it serves + # docs at the routeBasePath root (no version label in URL). + self._latest_version: str | None = versions[0] if versions else None # Locale configuration from BuildContext (zenzic.toml). self._locale_dirs: frozenset[str] = frozenset(context.locales) @@ -408,9 +414,14 @@ def map_url(self, rel: Path) -> str: slug = self._slug_map.get(rel_posix) if slug is not None: if slug.startswith("/"): - # Absolute slug: use as-is + # Absolute slug: always prefixed with routeBasePath. + # Docusaurus: permalink = normalizeUrl([versionMetadata.path, docSlug]) + # where versionMetadata.path IS the routeBasePath. + rbp = self._route_base_path if self._route_base_path is not None else "docs" url = slug.rstrip("/") or "" - return url + "/" + if rbp: + return "/" + rbp + url + "/" + return url + "/" if url else "/" # Relative slug: replace the last path segment parent = rel.parent if parent == Path("."): @@ -425,17 +436,56 @@ def map_url(self, rel: Path) -> str: stem = stem.with_suffix("") parts = list(stem.parts) - if not parts: - return "/" - # index files collapse to their parent directory - if parts[-1] == "index": - parts = parts[:-1] - - if not parts: - return "/" - - return "/" + "/".join(parts) + "/" + locale = None + if parts and parts[0] in self._locale_dirs: + locale = parts.pop(0) + + version = None + if parts and parts[0] == "_version_": + parts.pop(0) + if parts: + version = parts.pop(0) + + # isCategoryIndex: collapse when name is 'index', 'readme', or matches + # the immediate parent folder name (case-insensitive). + # Mirrors Docusaurus isCategoryIndex() logic exactly. + if parts: + file_name_lower = parts[-1].lower() + parent_name_lower = parts[-2].lower() if len(parts) >= 2 else None + if ( + file_name_lower == "index" + or file_name_lower == "readme" + or (parent_name_lower is not None and file_name_lower == parent_name_lower) + ): + parts = parts[:-1] + + url_parts = [] + if locale: + url_parts.append(locale) + + rbp = self._route_base_path if self._route_base_path is not None else "docs" + if rbp: + # Note: root routeBasePath is empty string + url_parts.append(rbp) + + # The latest version (first entry in versions.json) is served at the + # routeBasePath root โ€” no version label in the URL. + if version and version != self._latest_version: + url_parts.append(version) + + url_parts.extend(parts) + + use_dir = True + if getattr(self._context, "offline_mode", False): + use_dir = False + + if not url_parts: + return "/" if use_dir else "/index.html" + + if use_dir: + return "/" + "/".join(url_parts) + "/" + return "/" + "/".join(url_parts) + ".html" def classify_route(self, rel: Path, nav_paths: frozenset[str]) -> RouteStatus: """Classify a Docusaurus route. @@ -462,11 +512,18 @@ def classify_route(self, rel: Path, nav_paths: frozenset[str]) -> RouteStatus: ``RouteStatus`` literal (never ``'CONFLICT'``). """ # Rule 1: Private/meta files starting with _ - if any(part.startswith("_") for part in rel.parts): + # Exemption: _version_ sentinel prefix is injected by ZenzicAdapter โ€” not a real user dir. + non_sentinel_parts = [p for p in rel.parts if p != "_version_"] + if any(part.startswith("_") for part in non_sentinel_parts): return "IGNORED" # Draft files: check is deferred to frontmatter parsing (future). + # Version Ghost Routes: all files under a known versioned_docs tree are REACHABLE. + # The path sentinel prefix is _version_//... + if len(rel.parts) >= 2 and rel.parts[0] == "_version_": + return "REACHABLE" + # Rule 2: No explicit nav โ†’ auto-generated sidebar โ†’ all REACHABLE if not nav_paths: return "REACHABLE" @@ -518,14 +575,55 @@ def get_route_info(self, rel: Path) -> RouteMetadata: if locale_dir in self._locale_dirs: is_proxy = True + # Extract version from sentinel path prefix (_version_/