From 62d3222bd10039844e16b8453cf376b06dcb2c29 Mon Sep 17 00:00:00 2001 From: Andrea-Devold-Fjeld Date: Mon, 6 Oct 2025 15:56:36 +0200 Subject: [PATCH 1/4] Initial commit of csv2geoJson --- nrl-sdk-lib/pyproject.toml | 2 +- .../src/nrl_sdk_lib/converters/__init__.py | 5 + .../nrl_sdk_lib/converters/csv_to_geojson.py | 405 +++++++++++++ nrl-sdk-lib/tests/files/1_bardun.geojson | 1 + nrl-sdk-lib/tests/files/1_bardun_xlsx.xlsx | Bin 0 -> 10551 bytes nrl-sdk-lib/tests/files/1_luftspenn.geojson | 1 + nrl-sdk-lib/tests/files/1_luftspenn_xlsx.xlsx | Bin 0 -> 10402 bytes nrl-sdk-lib/tests/files/1_mast.geojson | 1 + nrl-sdk-lib/tests/files/1_mast.xlsx | Bin 0 -> 10962 bytes nrl-sdk-lib/tests/test_csv_to_geojson.py | 430 ++++++++++++++ nrl-sdk-lib/uv.lock | 293 +++++----- uv.lock | 532 ------------------ 12 files changed, 1004 insertions(+), 666 deletions(-) create mode 100644 nrl-sdk-lib/src/nrl_sdk_lib/converters/__init__.py create mode 100644 nrl-sdk-lib/src/nrl_sdk_lib/converters/csv_to_geojson.py create mode 100644 nrl-sdk-lib/tests/files/1_bardun.geojson create mode 100644 nrl-sdk-lib/tests/files/1_bardun_xlsx.xlsx create mode 100644 nrl-sdk-lib/tests/files/1_luftspenn.geojson create mode 100644 nrl-sdk-lib/tests/files/1_luftspenn_xlsx.xlsx create mode 100644 nrl-sdk-lib/tests/files/1_mast.geojson create mode 100644 nrl-sdk-lib/tests/files/1_mast.xlsx create mode 100644 nrl-sdk-lib/tests/test_csv_to_geojson.py delete mode 100644 uv.lock diff --git a/nrl-sdk-lib/pyproject.toml b/nrl-sdk-lib/pyproject.toml index 8edf042..86b388c 100644 --- a/nrl-sdk-lib/pyproject.toml +++ b/nrl-sdk-lib/pyproject.toml @@ -83,6 +83,6 @@ format = "uv run ruff format" lint = "uv run ruff check --fix" check-types = "uv run ty check ." check-deps = "uv run deptry ." -audit = "uv run pip-audit" +audit = "uv run pip-audit --ignore-vuln GHSA-4xh5-x5gv-qwph" test = "uv run pytest --doctest-modules -s --cov --cov-report=term-missing --cov-report=html" release = ["lint", "check-types", "check-deps", "audit", "test"] diff --git a/nrl-sdk-lib/src/nrl_sdk_lib/converters/__init__.py b/nrl-sdk-lib/src/nrl_sdk_lib/converters/__init__.py new file mode 100644 index 0000000..1eac654 --- /dev/null +++ b/nrl-sdk-lib/src/nrl_sdk_lib/converters/__init__.py @@ -0,0 +1,5 @@ +"""Csv to GeoJson converter.""" + +from .csv_to_geojson import csv_to_geojson + +__all__ = ["csv_to_geojson"] diff --git a/nrl-sdk-lib/src/nrl_sdk_lib/converters/csv_to_geojson.py b/nrl-sdk-lib/src/nrl_sdk_lib/converters/csv_to_geojson.py new file mode 100644 index 0000000..8dbaef0 --- /dev/null +++ b/nrl-sdk-lib/src/nrl_sdk_lib/converters/csv_to_geojson.py @@ -0,0 +1,405 @@ +"""Convert CSV data to GeoJSON FeatureCollections.""" + +import csv +import logging +import sys +import uuid +from pathlib import Path +from typing import IO, Any, Literal, cast + +from nrl_sdk_lib.models import ( + Crs, + CrsProperties, + Feature, + FeatureCollection, + FeatureStatus, + Høydereferanse, #noqa: PLC2403 + KomponentReferanse, + LineString, + LuftfartsHinderLyssetting, + LuftfartsHinderMerking, + LuftspennType, + MastType, + NrlLuftspenn, + NrlMast, + Point, +) + +logging.basicConfig( + level=logging.INFO, format="%(asctime)s %(levelname)s %(name)s %(message)s" +) +logger = logging.getLogger(__name__) + +# Mapping dictionaries +LUFTSPENN_TYPE_MAP = { + "Ledning, høyspent": LuftspennType.høgspent, + "Ledning, lavspent": LuftspennType.lavspent, + "Ledning, regionalnett": LuftspennType.regional, +} + +MAST_TYPE_MAP = { + "Mast, høyspent": MastType.høgspentmast, + "Mast, lavspent": MastType.lavspentmast, + "Mast, regionalnett": MastType.regionalmast, +} + +FEATURE_STATUS_MAP = { + "Eksisterende": FeatureStatus.eksisterende, + "Planlagt oppført": FeatureStatus.planlagt_oppført, + "Planlagt fjernet": FeatureStatus.planlagt_fjernet, + "Fjernet": FeatureStatus.fjernet, + "planlagtOppført": FeatureStatus.planlagt_oppført, + "planlagtFjernet": FeatureStatus.planlagt_fjernet, + "eksisterende": FeatureStatus.eksisterende, + "fjernet": FeatureStatus.fjernet, +} + +LIGHTING_KIND_MAP = { + "Lyssatt": LuftfartsHinderLyssetting.lyssatt, + "Mellomintensitet, type A": LuftfartsHinderLyssetting.mellomintensitet_type_a, + "Mellomintensitet, type B": LuftfartsHinderLyssetting.mellomintensitet_type_b, + "Mellomintensitet, type C": LuftfartsHinderLyssetting.mellomintensitet_type_c, + "Lavintensitet, type A": LuftfartsHinderLyssetting.lavintensitet_type_a, + "Lavintensitet, type B": LuftfartsHinderLyssetting.lavintensitet_type_b, + "Høyintensitet, type A": LuftfartsHinderLyssetting.høyintensitet_type_a, + "Høyintensitet, type B": LuftfartsHinderLyssetting.høyintensitet_type_b, +} + +MARKING_KIND_MAP = { + "Fargemerking": LuftfartsHinderMerking.fargermerking, + "Markør": LuftfartsHinderMerking.markør, +} + +LOCATION_METHOD_MAP = { + "FOR-2020-10-16-2068, §5(1)": "20230101_5-1", +} + + +def csv_to_geojson(file: str | Path | IO[str] | None = None) -> list[FeatureCollection]: + """Convert CSV file to GeoJSON FeatureCollections grouped by CRS. + + Args: + file: Can be: + - None: reads from stdin + - str or Path: path to CSV file + - IO[str]: file-like object (already opened file) + + Returns: + List of FeatureCollections grouped by CRS + + Examples: + # From file path + result = csv_to_geojson("data.csv") + + # From stdin + result = csv_to_geojson() + + # From file object + with open("data.csv") as f: + result = csv_to_geojson(f) + + """ + if file is None: + # Read from stdin + logger.info("Reading CSV from stdin") + return _process_csv_file(sys.stdin) + if isinstance(file, (str, Path)): + msg = f"Reading CSV from file: {file}" + logger.info(msg) + with Path(file).open(newline="", encoding="utf-8-sig") as csvfile: + return _process_csv_file(csvfile) + else: + # Use provided file object + logger.info("Reading CSV from file object") + return _process_csv_file(file) + + +def _process_csv_file(csvfile: IO[str]) -> list[FeatureCollection]: + """Process CSV file and return FeatureCollections grouped by CRS.""" + feature_by_crs = {} + reader = csv.DictReader(csvfile, dialect="excel", delimiter=";") + + for row in reader: + feature, crs = process_row(row) + crs_name = crs.properties.name + feature_by_crs.setdefault(crs_name, []).append(feature) + + return [ + FeatureCollection( + crs=Crs(properties=CrsProperties(name=crs_name)), features=features + ) + for crs_name, features in feature_by_crs.items() + ] + +def process_row(row: dict[str, str]) -> tuple[Feature, Crs]: + """Process a single CSV row and return the appropriate feature.""" + table_id = row.get("Tabell ID") + + if table_id == "261": + return ( + convert_guy_segments_rows(row) + if row["Betegnelse"] == "Bardunline" + else convert_ac_linesegments_rows(row) + ) + if table_id == "109": + return convert_overhead_structure_rows(row) + + msg = f"Unknown Tabell ID: {table_id}" + logger.warning(msg) + raise ValueError(msg) + + +def get_uuid(row: dict[str, str], *fields: str) -> uuid.UUID: + """Extract and validate UUID from row fields.""" + for field in fields: + value = row.get(field) + if value: + try: + return uuid.UUID(value) + except ValueError: + continue + msg = f"No valid UUID found in fields: {fields}" + raise ValueError(msg) + + +def parse_float(value: str | None, field_name: str) -> float: + """Parse float value with error handling.""" + if value is None: + msg = f"Missing {field_name}" + raise ValueError(msg) + try: + return float(value.replace(",", ".")) + except (ValueError, AttributeError) as e: + msg = f"{field_name} is not a valid number: {value}" + raise ValueError(msg) from e + + +def parse_coordinates(coords: list[str | None]) -> list[float]: + """Parse and convert coordinate strings to floats.""" + return [ + float(c.replace(",", ".")) + for c in coords if isinstance(c, str) and c != ""] + + +def create_geometry( + coordinates: list[list[str | None]], *,is_line: bool = True +) -> tuple[LineString | Point, Crs]: + """Create LineString or Point geometry with appropriate CRS.""" + has_z = all(coord[2] not in [None, ""] for coord in coordinates) + len_coordinates_value =2 + if is_line and len(coordinates) != len_coordinates_value: + msg = "LineString requires exactly 2 points" + raise ValueError(msg) + + try: + if has_z: + if is_line: + coords = [ + [ + parse_float(c[1], "y"), + parse_float(c[0], "x"), + parse_float(c[2], "z"), + ] + for c in coordinates + ] + geometry = LineString(type="LineString", coordinates=coords) + else: + x, y, z = parse_coordinates(coordinates[0]) + geometry = Point(type="Point", coordinates=[y, x, z]) + crs = Crs(properties=CrsProperties(name="EPSG:5972")) + else: + if is_line: + coords = [ + [parse_float(c[1], "y"), parse_float(c[0], "x")] + for c in coordinates + ] + geometry = LineString(type="LineString", coordinates=coords) + else: + x, y = parse_coordinates(coordinates[0][:2]) + geometry = Point(type="Point", coordinates=[y, x]) + crs = Crs(properties=CrsProperties(name="EPSG:25832")) + except ValueError as e: + msg = f"Invalid coordinate values: {e}" + raise ValueError(msg) from e + + return geometry, crs + + +def map_value( + value: str | None, + mapping: dict, + field_name: str, + *, + allow_none: bool = False) -> Any: # noqa: ANN401 + """Map a value using a dictionary with error handling.""" + if not value: + if allow_none: + return None + msg = f"Missing {field_name}" + raise ValueError(msg) + + result = mapping.get(value) + if result is None and not allow_none: + msg = f"Unknown {field_name}: {value}" + raise ValueError(msg) + return result + + +def convert_overhead_structure_rows(row: dict[str, str]) -> tuple[Feature, Crs]: + """Convert overhead structure (mast) rows to NrlMast feature.""" + komponentident = get_uuid(row, "OverheadStructure_uuid", "ID") + masttype = map_value(row.get("Masttype (NRL)"), MAST_TYPE_MAP, "Masttype") + feature_status = map_value(row.get("Status (NRL)"), FEATURE_STATUS_MAP, "Status") + nøyaktighet = LOCATION_METHOD_MAP.get( + row.get("Verifisert nøyaktighet (NRL)", ""), "0" + ) + + lyssetting = map_value( + row.get("Luftfartshinderlyssetting(NRL)", ""), + LIGHTING_KIND_MAP, + "Lighting", + allow_none=True, + ) + merking = map_value( + row.get("Luftfartshindermerking (NRL)", ""), + MARKING_KIND_MAP, + "Marking", + allow_none=True, + ) + + høydereferanse = None + if row.get("Hoydereferanse (NRL)"): + høydereferanse = ( + Høydereferanse.topp + if row["Hoydereferanse (NRL)"].lower() == "topp" + else Høydereferanse.fot + if row["Hoydereferanse (NRL)"].lower() == "fot" + else None + ) + + max_height = ( + parse_float(row["Vertikalavstand meter (NRL)"], "Vertikalavstand") + if row.get("Vertikalavstand meter (NRL)") + else None + ) + + point, crs = create_geometry( + [[row["x"], row["y"], row.get("z", "")]], is_line=False + ) + + return Feature( + geometry=point, + properties=NrlMast( + komponentident=komponentident, + status=feature_status, + verifisert_rapporteringsnøyaktighet=nøyaktighet, + feature_type="NrlMast", + mast_type=masttype, + luftfartshinderlyssetting=lyssetting if lyssetting is not None else None, + luftfartshindermerking=merking if merking is not None else None, + høydereferanse=høydereferanse if høydereferanse is not None else None, + vertikal_avstand=max_height if max_height is not None else None, + ), + ), crs + + +def convert_guy_segments_rows(row: dict[str, str]) -> tuple[Feature, Crs]: + """Convert guy wire segments to NrlLuftspenn feature.""" + komponentident = get_uuid(row, "Guy_uuid") + feature_status = map_value(row.get("Status (NRL)"), FEATURE_STATUS_MAP, "Status") + nøyaktighet = LOCATION_METHOD_MAP.get( + row.get("Verifisert nøyaktighet (NRL)", ""), "0" + ) + + linestring, crs = create_geometry( + [ + [row["x1"], row["y1"], row.get("z1", "")], + [row["x2"], row["y2"], row.get("z2", "")], + ] + ) + + komponentreferanse = ( + KomponentReferanse(komponentkodeverdi=row.get("ID", "")) + if row.get("ID") + else None + ) + + return Feature( + geometry=linestring, + properties=NrlLuftspenn( + luftspenn_type=LuftspennType.bardun, + komponentident=komponentident, + status=feature_status, + verifisert_rapporteringsnøyaktighet=nøyaktighet, + feature_type="NrlLuftspenn", + referanse=komponentreferanse, + ), + ), crs + + +def convert_ac_linesegments_rows(row: dict[str, str]) -> tuple[Feature, Crs]: + """Convert AC line segments to NrlLuftspenn feature.""" + komponentident = get_uuid(row, "ACLineSegmentSpan_uuid", "ID") + feature_status = map_value(row.get("Status (NRL)"), FEATURE_STATUS_MAP, "Status") + luftspennstype = map_value( + row.get("Luftspenntype (NRL)"), LUFTSPENN_TYPE_MAP, "Luftspenntype" + ) + nøyaktighet_str = LOCATION_METHOD_MAP.get( + row.get("Verifisert nøyaktighet (NRL)", ""), "0" + ) + nøyaktighet: Literal["20230101_5-1", "0"] = cast( + "Literal['20230101_5-1', '0']", nøyaktighet_str + ) + + lyssetting = map_value( + row.get("Luftfartshinderlyssetting(NRL)", ""), + LIGHTING_KIND_MAP, + "Lighting", + allow_none=True, + ) + merking = map_value( + row.get("Luftfartshindermerking (NRL)", ""), + MARKING_KIND_MAP, + "Marking", + allow_none=True, + ) + + linestring, crs = create_geometry( + [ + [row["x1"], row["y1"], row.get("z1", "")], + [row["x2"], row["y2"], row.get("z2", "")], + ] + ) + + mast = [ + uuid.UUID(row[f"Mast_{i}_ObjectID"]) + for i in [1, 2] + if row.get(f"Mast_{i}_ObjectID") + ] + + komponentreferanse = ( + KomponentReferanse(komponentkodeverdi=row.get("ID", "")) + if row.get("ID") + else None + ) + anleggsbredde = ( + parse_float(row["Anleggsbredde meter (NRL)"], "Anleggsbredde") + if row.get("Anleggsbredde meter (NRL)") + else None + ) + + return Feature( + geometry=linestring, + properties=NrlLuftspenn( + luftspenn_type=luftspennstype, + komponentident=komponentident, + nrl_mast=mast, + status=feature_status, + verifisert_rapporteringsnøyaktighet=nøyaktighet, + feature_type="NrlLuftspenn", + referanse=komponentreferanse, + luftfartshinderlyssetting=lyssetting if lyssetting is not None else None, + luftfartshindermerking=merking if merking is not None else None, + anleggsbredde=anleggsbredde if anleggsbredde is not None else None, + ), + ), crs diff --git a/nrl-sdk-lib/tests/files/1_bardun.geojson b/nrl-sdk-lib/tests/files/1_bardun.geojson new file mode 100644 index 0000000..2d30d92 --- /dev/null +++ b/nrl-sdk-lib/tests/files/1_bardun.geojson @@ -0,0 +1 @@ +{"crs":{"type":"name","properties":{"name":"EPSG:5972"}},"features":[{"geometry":{"type":"LineString","coordinates":[[559404.72265625,6539567.99609375,-99999.0],[559419.76171875,6539579.28125,-99999.0]]},"properties":{"featureType":"NrlLuftspenn","luftspennType":"bardun","status":"eksisterende","komponentident":"0291c89b-8294-4c5c-9061-445149e68330","referanse":{"komponentkodeverdi":"188488519"},"navn":"188488519","informasjon":"","verifisertRapporteringsnøyaktighet":"0"}}]} \ No newline at end of file diff --git a/nrl-sdk-lib/tests/files/1_bardun_xlsx.xlsx b/nrl-sdk-lib/tests/files/1_bardun_xlsx.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..5d9a81c9058dfff5f03e5555d7bbe7d43e509ec1 GIT binary patch literal 10551 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 literal 0 HcmV?d00001 diff --git a/nrl-sdk-lib/tests/files/1_luftspenn.geojson b/nrl-sdk-lib/tests/files/1_luftspenn.geojson new file mode 100644 index 0000000..ae778bd --- /dev/null +++ b/nrl-sdk-lib/tests/files/1_luftspenn.geojson @@ -0,0 +1 @@ +{"crs":{"type":"name","properties":{"name":"EPSG:5972"}},"features":[{"geometry":{"type":"LineString","coordinates":[[582430.5569299466,6544040.344467209,-99999.0],[582087.7992964027,6544042.579778018,-99999.0]]},"properties":{"featureType":"NrlLuftspenn","luftspennType":"lavspent","status":"eksisterende","komponentident":"1a085da3-6029-4703-8c3b-af6600238b51","referanse":{"komponentkodeverdi":"d6716fda-aac4-4229-9e2d-690a32dc5214"},"navn":"Luftnett","informasjon":"","verifisertRapporteringsnøyaktighet":"0"}}]} \ No newline at end of file diff --git a/nrl-sdk-lib/tests/files/1_luftspenn_xlsx.xlsx b/nrl-sdk-lib/tests/files/1_luftspenn_xlsx.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..cba92f017412c863afd52523a5e758ef53f7b156 GIT binary patch literal 10402 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 N1;OYWgZ{U-{{wOEdItai literal 0 HcmV?d00001 diff --git a/nrl-sdk-lib/tests/files/1_mast.geojson b/nrl-sdk-lib/tests/files/1_mast.geojson new file mode 100644 index 0000000..2883dfa --- /dev/null +++ b/nrl-sdk-lib/tests/files/1_mast.geojson @@ -0,0 +1 @@ +{"crs":{"type":"name","properties":{"name":"EPSG:25832"}},"features":[{"geometry":{"type":"Point","coordinates":[585243.7955070778,6544773.145291722]},"properties":{"featureType":"NrlMast","mastType":"lavspentmast","status":"eksisterende","komponentident":"9631125f-3e72-45b0-a098-6f7cd3bf8811","referanse":{"komponentkodeverdi":"fa1bf202-345c-49f0-831b-5d5a12103612"},"navn":"LM83700","kvalitet":{},"informasjon":"","verifisertRapporteringsnøyaktighet":"0"}}]} \ No newline at end of file diff --git a/nrl-sdk-lib/tests/files/1_mast.xlsx b/nrl-sdk-lib/tests/files/1_mast.xlsx new file mode 100644 index 0000000000000000000000000000000000000000..10669fecaa9031ecdcb405640f3df5d8c7654286 GIT binary patch literal 10962 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 ZtrQic;UKdM03bm=J`l^zOZ8jr{{f<1o)rK9 literal 0 HcmV?d00001 diff --git a/nrl-sdk-lib/tests/test_csv_to_geojson.py b/nrl-sdk-lib/tests/test_csv_to_geojson.py new file mode 100644 index 0000000..35cf525 --- /dev/null +++ b/nrl-sdk-lib/tests/test_csv_to_geojson.py @@ -0,0 +1,430 @@ +"""Tests for csv_to_geojson converter.""" +import csv +import io +import os +import sys +import tempfile +import uuid +from pathlib import Path +from unittest.mock import patch + +import pytest + +from nrl_sdk_lib.converters.csv_to_geojson import ( + FEATURE_STATUS_MAP, + create_geometry, + csv_to_geojson, + get_uuid, + map_value, + parse_float, +) + + +@pytest.mark.anyio +def test_csv_to_geojson_1_mast() -> None: + """Should create a valid geojson file from csv with 1 mast.""" + input_csv = "tests/files/1_mast.csv" + output_geojson = "tests/files/1_mast.geojson" + + csv_to_geojson(input_csv) + + with Path(output_geojson).open(encoding="utf-8") as f: + expected_content = f.read() + + with Path(output_geojson).open(encoding="utf-8") as f: + actual_content = f.read() + + assert expected_content == actual_content + + +@pytest.mark.anyio +def test_csv_to_geojson_1_luftspenn() -> None: + """Should create a valid geojson file from csv with 1 luftspenn.""" + input_csv = "tests/files/1_luftspenn.csv" + output_geojson = "tests/files/1_luftspenn.geojson" + + csv_to_geojson(input_csv) + + with Path(output_geojson).open(encoding="utf-8") as f: + expected_content = f.read() + + with Path(output_geojson).open(encoding="utf-8") as f: + actual_content = f.read() + + assert expected_content == actual_content + + +@pytest.mark.anyio +def test_csv_to_geojson_1_bardun() -> None: + """Should create a valid geojson file from csv with 1 bardun.""" + input_csv = "tests/files/1_bardun.csv" + output_geojson = "tests/files/1_bardun.geojson" + + csv_to_geojson(input_csv) + + with Path(output_geojson).open(encoding="utf-8") as f: + expected_content = f.read() + + with Path(output_geojson).open(encoding="utf-8") as f: + actual_content = f.read() + + assert expected_content == actual_content + + +def test_csv_to_geojson_file_object() -> None: + """Should read from file-like object.""" + gen_uuid = uuid.uuid4() + csv_content = ("Tabell ID;" + "x;" + "y;" + "z;" + "OverheadStructure_uuid;" + "Masttype (NRL);" + "Status (NRL)\n" + f"109;100;200;10;{gen_uuid};Mast, lavspent;Eksisterende\n") + file_obj = io.StringIO(csv_content) + result = csv_to_geojson(file_obj) + assert len(result) > 0 + assert result[0].features[0].properties.feature_type == "NrlMast" + +def test_csv_to_geojson_reads_from_stdin() -> None: + """Should read from stdin if no filename is given.""" + gen_uuid = uuid.uuid4() + csv_content = ("Tabell ID;" + "x;" + "y;" + "z;" + "OverheadStructure_uuid;" + "Masttype (NRL);" + "Status (NRL)\n" + f"109;100;200;10;{gen_uuid};Mast, lavspent;Eksisterende\n") + fake_stdin = io.StringIO(csv_content) + with patch.object(sys, "stdin", fake_stdin): + result = csv_to_geojson(None) + assert len(result) > 0 + assert result[0].features[0].properties.feature_type == "NrlMast" + +def test_get_uuid_valid() -> None: + """Test UUID extraction with valid UUID.""" + row = {"field1": "550e8400-e29b-41d4-a716-446655440000", "field2": "other"} + result = get_uuid(row, "field1", "field2") + assert str(result) == "550e8400-e29b-41d4-a716-446655440000" + + +def test_get_uuid_fallback() -> None: + """Test UUID extraction with fallback field.""" + row = {"field1": "invalid", "field2": "550e8400-e29b-41d4-a716-446655440000"} + result = get_uuid(row, "field1", "field2") + assert str(result) == "550e8400-e29b-41d4-a716-446655440000" + + +def test_get_uuid_missing() -> None: + """Test UUID extraction when no valid UUID exists.""" + row = {"field1": "invalid", "field2": "also-invalid"} + with pytest.raises(ValueError, match="No valid UUID found"): + get_uuid(row, "field1", "field2") + + +def test_parse_float_valid() -> None: + """Test parsing valid float.""" + assert parse_float("123.45", "test_field") == 123.45 + + +def test_parse_float_comma_decimal() -> None: + """Test parsing float with comma as decimal separator.""" + assert parse_float("123,45", "test_field") == 123.45 + + +def test_parse_float_invalid() -> None: + """Test parsing invalid float.""" + with pytest.raises(ValueError, match="not a valid number"): + parse_float("not_a_number", "test_field") + + +def test_create_geometry_line_with_z() -> None: + """Test creating LineString with z coordinates.""" + coords = [["100", "200", "10"], ["300", "400", "20"]] + geometry, crs = create_geometry(coords, is_line=True) + + assert geometry.type == "LineString" + assert isinstance(geometry.coordinates[0], list) + assert len(geometry.coordinates) == 2 + assert len(geometry.coordinates[0]) == 3 # Has z + assert crs.properties.name == "EPSG:5972" + + +def test_create_geometry_line_without_z() -> None: + """Test creating LineString without z coordinates.""" + coords = [["100", "200", ""], ["300", "400", ""]] + geometry, crs = create_geometry(coords, is_line=True) + + assert geometry.type == "LineString" + assert isinstance(geometry.coordinates[0], list) + assert len(geometry.coordinates) == 2 + assert len(geometry.coordinates[0]) == 2 # No z + assert crs.properties.name == "EPSG:25832" + + +def test_create_geometry_point_with_z() -> None: + """Test creating Point with z coordinate.""" + coords = [["100", "200", "10"]] + geometry, crs = create_geometry(coords, is_line=False) + + assert geometry.type == "Point" + assert len(geometry.coordinates) == 3 # Has z + assert crs.properties.name == "EPSG:5972" + + +def test_create_geometry_point_without_z() -> None: + """Test creating Point without z coordinate.""" + coords = [["100", "200", ""]] + geometry, crs = create_geometry(coords, is_line=False) + + assert geometry.type == "Point" + assert len(geometry.coordinates) == 2 # No z + assert crs.properties.name == "EPSG:25832" + + +def test_create_geometry_invalid_coords() -> None: + """Test creating geometry with invalid coordinates.""" + coords = [["not", "numbers", "10"], ["300", "400", "20"]] + with pytest.raises(ValueError, match="Invalid coordinate values"): + create_geometry(coords, is_line=True) + + +def test_map_value_valid() -> None: + """Test mapping valid value.""" + result = map_value("Eksisterende", FEATURE_STATUS_MAP, "Status") + assert result is not None + + +def test_map_value_missing() -> None: + """Test mapping with missing value.""" + with pytest.raises(ValueError, match="Missing Status"): + map_value("", FEATURE_STATUS_MAP, "Status", allow_none=False) + + +def test_map_value_unknown() -> None: + """Test mapping with unknown value.""" + with pytest.raises(ValueError, match="Unknown Status"): + map_value("InvalidStatus", FEATURE_STATUS_MAP, "Status", allow_none=False) + + +def test_map_value_allow_none() -> None: + """Test mapping with allow_none=True.""" + result = map_value("", FEATURE_STATUS_MAP, "Status", allow_none=True) + assert result is None + + +def create_test_csv(content: list[dict], filename: str | None) -> str | None: + """Create a temporary CSV file.""" + if filename is None: + fd, filename = tempfile.mkstemp(suffix=".csv") + os.close(fd) + + with Path(filename).open("w", newline="", encoding="utf-8-sig") as f: + if content: + writer = csv.DictWriter(f, fieldnames=content[0].keys(), delimiter=";") + writer.writeheader() + writer.writerows(content) + + return filename + + +def test_csv_invalid_mast_type() -> None: + """Test handling invalid mast type.""" + content = [ + { + "Tabell ID": "109", + "OverheadStructure_uuid": "550e8400-e29b-41d4-a716-446655440000", + "Masttype (NRL)": "InvalidType", + "Status (NRL)": "Eksisterende", + "x": "100", + "y": "200", + "z": "10", + } + ] + + filename = create_test_csv(content, filename=None) + + with pytest.raises(ValueError, match="Unknown Masttype"): + csv_to_geojson(filename) + + +def test_csv_missing_status() -> None: + """Test handling missing status field.""" + content = [ + { + "Tabell ID": "109", + "OverheadStructure_uuid": "550e8400-e29b-41d4-a716-446655440000", + "Masttype (NRL)": "Mast, høyspent", + "Status (NRL)": "", + "x": "100", + "y": "200", + "z": "10", + } + ] + + filename = create_test_csv(content, filename=None) + + with pytest.raises(ValueError, match="Missing Status"): + csv_to_geojson(filename) + +def test_no_tabell_id() -> None: + """Test handling missing Tabell ID.""" + content = [ + { + "OverheadStructure_uuid": "550e8400-e29b-41d4-a716-446655440000", + "Masttype (NRL)": "Mast, høyspent", + "Status (NRL)": "Eksisterende", + "x": "100", + "y": "200", + "z": "10", + } + ] + + filename = create_test_csv(content, filename=None) + + with pytest.raises(ValueError, match="Unknown Tabell ID:"): + csv_to_geojson(filename) + +def test_parse_float_none_value() -> None: + """Test parsing None value.""" + with pytest.raises(ValueError, match="Missing test_field"): + parse_float(None, "test_field") + +def test_create_geometry_line_invalid_number_of_points() -> None: + """Test creating LineString with invalid number of points.""" + coords = [["100", "200", "10"]] + with pytest.raises(ValueError, match="LineString requires exactly 2 points"): + create_geometry(coords, is_line=True) + +def test_csv_optional_lighting_and_marking() -> None: + """Test handling optional lighting and marking fields.""" + content = [ + { + "Tabell ID": "109", + "OverheadStructure_uuid": "550e8400-e29b-41d4-a716-446655440000", + "Masttype (NRL)": "Mast, høyspent", + "Status (NRL)": "Eksisterende", + "Luftfartshinderlyssetting(NRL)": "Lyssatt", + "Luftfartshindermerking (NRL)": "Fargemerking", + "x": "100", + "y": "200", + "z": "10", + } + ] + + filename = create_test_csv(content, filename=None) + result = csv_to_geojson(filename) + + assert len(result) > 0 + feature = result[0].features[0] + assert feature.properties.luftfartshinderlyssetting is not None + assert feature.properties.luftfartshindermerking is not None + + +def test_csv_guy_segment_missing_uuid() -> None: + """Test guy segment with missing UUID.""" + content = [ + { + "Tabell ID": "261", + "Betegnelse": "Bardunline", + "Guy_uuid": "", + "Status (NRL)": "Eksisterende", + "x1": "100", + "y1": "200", + "z1": "10", + "x2": "300", + "y2": "400", + "z2": "20", + } + ] + + filename = create_test_csv(content, filename=None) + + with pytest.raises(ValueError, match="No valid UUID found"): + csv_to_geojson(filename) + + +def test_csv_luftspenn_invalid_type() -> None: + """Test luftspenn with invalid type.""" + content = [ + { + "Tabell ID": "261", + "Betegnelse": "Ledning", + "ACLineSegmentSpan_uuid": "550e8400-e29b-41d4-a716-446655440000", + "Status (NRL)": "Eksisterende", + "Luftspenntype (NRL)": "InvalidType", + "x1": "100", + "y1": "200", + "z1": "10", + "x2": "300", + "y2": "400", + "z2": "20", + } + ] + + filename = create_test_csv(content, filename=None) + + with pytest.raises(ValueError, match="Unknown Luftspenntype"): + csv_to_geojson(filename) + + +def test_csv_multiple_crs() -> None: + """Test CSV with features in different CRS.""" + content = [ + { + "Tabell ID": "109", + "OverheadStructure_uuid": "550e8400-e29b-41d4-a716-446655440000", + "Masttype (NRL)": "Mast, høyspent", + "Status (NRL)": "Eksisterende", + "x": "100", + "y": "200", + "z": "10", + }, + { + "Tabell ID": "109", + "OverheadStructure_uuid": "550e8400-e29b-41d4-a716-446655440001", + "Masttype (NRL)": "Mast, høyspent", + "Status (NRL)": "Eksisterende", + "x": "100", + "y": "200", + "z": "", # No z = different CRS + }, + ] + + filename = create_test_csv(content, filename=None) + result = csv_to_geojson(filename) + + # Should create 2 FeatureCollections (one per CRS) + assert len(result) == 2 + + +def test_csv_with_anleggsbredde() -> None: + """Test luftspenn with anleggsbredde field.""" + content = [ + { + "Tabell ID": "261", + "Betegnelse": "Ledning", + "ACLineSegmentSpan_uuid": "550e8400-e29b-41d4-a716-446655440000", + "Status (NRL)": "Eksisterende", + "Luftspenntype (NRL)": "Ledning, høyspent", + "Anleggsbredde meter (NRL)": "5.5", + "x1": "100", + "y1": "200", + "z1": "10", + "x2": "300", + "y2": "400", + "z2": "20", + } + ] + + filename = create_test_csv(content, filename=None) + result = csv_to_geojson(filename) + + assert len(result) > 0 + feature = result[0].features[0] + + assert hasattr(feature.properties, "anleggsbredde") + assert feature.properties.anleggsbredde == 5.5 diff --git a/nrl-sdk-lib/uv.lock b/nrl-sdk-lib/uv.lock index f45363f..c39bf72 100644 --- a/nrl-sdk-lib/uv.lock +++ b/nrl-sdk-lib/uv.lock @@ -1,5 +1,5 @@ version = 1 -revision = 3 +revision = 2 requires-python = ">=3.13" [[package]] @@ -13,15 +13,15 @@ wheels = [ [[package]] name = "anyio" -version = "4.10.0" +version = "4.11.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "idna" }, { name = "sniffio" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f1/b4/636b3b65173d3ce9a38ef5f0522789614e590dab6a8d505340a4efe4c567/anyio-4.10.0.tar.gz", hash = "sha256:3f3fae35c96039744587aa5b8371e7e8e603c0702999535961dd336026973ba6", size = 213252, upload-time = "2025-08-04T08:54:26.451Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c6/78/7d432127c41b50bccba979505f272c16cbcadcc33645d5fa3a738110ae75/anyio-4.11.0.tar.gz", hash = "sha256:82a8d0b81e318cc5ce71a5f1f8b5c4e63619620b63141ef8c995fa0db95a57c4", size = 219094, upload-time = "2025-09-23T09:19:12.58Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6f/12/e5e0282d673bb9746bacfb6e2dba8719989d3660cdb2ea79aee9a9651afb/anyio-4.10.0-py3-none-any.whl", hash = "sha256:60e474ac86736bbfd6f210f7a61218939c318f43f9972497381f1c5e930ed3d1", size = 107213, upload-time = "2025-08-04T08:54:24.882Z" }, + { url = "https://files.pythonhosted.org/packages/15/b3/9b1a8074496371342ec1e796a96f99c82c945a339cd81a8e73de28b4cf9e/anyio-4.11.0-py3-none-any.whl", hash = "sha256:0287e96f4d26d4149305414d4e3bc32f0dcd0862365a4bddea19d7a1ec38c4fc", size = 109097, upload-time = "2025-09-23T09:19:10.601Z" }, ] [[package]] @@ -62,11 +62,11 @@ filecache = [ [[package]] name = "certifi" -version = "2025.8.3" +version = "2025.10.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/dc/67/960ebe6bf230a96cda2e0abcf73af550ec4f090005363542f0765df162e0/certifi-2025.8.3.tar.gz", hash = "sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407", size = 162386, upload-time = "2025-08-03T03:07:47.08Z" } +sdist = { url = "https://files.pythonhosted.org/packages/4c/5b/b6ce21586237c77ce67d01dc5507039d444b630dd76611bbca2d8e5dcd91/certifi-2025.10.5.tar.gz", hash = "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43", size = 164519, upload-time = "2025-10-05T04:12:15.808Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/e5/48/1549795ba7742c948d2ad169c1c8cdbae65bc450d6cd753d124b17c8cd32/certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5", size = 161216, upload-time = "2025-08-03T03:07:45.777Z" }, + { url = "https://files.pythonhosted.org/packages/e4/37/af0d2ef3967ac0d6113837b44a4f0bfe1328c2b9763bd5b1744520e5cfed/certifi-2025.10.5-py3-none-any.whl", hash = "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de", size = 163286, upload-time = "2025-10-05T04:12:14.03Z" }, ] [[package]] @@ -102,14 +102,14 @@ wheels = [ [[package]] name = "click" -version = "8.2.1" +version = "8.3.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/60/6c/8ca2efa64cf75a977a0d7fac081354553ebe483345c734fb6b6515d96bbc/click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202", size = 286342, upload-time = "2025-05-20T23:19:49.832Z" } +sdist = { url = "https://files.pythonhosted.org/packages/46/61/de6cd827efad202d7057d93e0fed9294b96952e188f7384832791c7b2254/click-8.3.0.tar.gz", hash = "sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4", size = 276943, upload-time = "2025-09-18T17:32:23.696Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/85/32/10bb5764d90a8eee674e9dc6f4db6a0ab47c8c4d0d83c27f7c39ac415a4d/click-8.2.1-py3-none-any.whl", hash = "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b", size = 102215, upload-time = "2025-05-20T23:19:47.796Z" }, + { url = "https://files.pythonhosted.org/packages/db/d3/9dcc0f5797f070ec8edf30fbadfb200e71d9db6b84d211e3b2085a7589a0/click-8.3.0-py3-none-any.whl", hash = "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc", size = 107295, upload-time = "2025-09-18T17:32:22.42Z" }, ] [[package]] @@ -123,55 +123,63 @@ wheels = [ [[package]] name = "coverage" -version = "7.10.6" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/14/70/025b179c993f019105b79575ac6edb5e084fb0f0e63f15cdebef4e454fb5/coverage-7.10.6.tar.gz", hash = "sha256:f644a3ae5933a552a29dbb9aa2f90c677a875f80ebea028e5a52a4f429044b90", size = 823736, upload-time = "2025-08-29T15:35:16.668Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/bd/e7/917e5953ea29a28c1057729c1d5af9084ab6d9c66217523fd0e10f14d8f6/coverage-7.10.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ffea0575345e9ee0144dfe5701aa17f3ba546f8c3bb48db62ae101afb740e7d6", size = 217351, upload-time = "2025-08-29T15:33:45.438Z" }, - { url = "https://files.pythonhosted.org/packages/eb/86/2e161b93a4f11d0ea93f9bebb6a53f113d5d6e416d7561ca41bb0a29996b/coverage-7.10.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:95d91d7317cde40a1c249d6b7382750b7e6d86fad9d8eaf4fa3f8f44cf171e80", size = 217600, upload-time = "2025-08-29T15:33:47.269Z" }, - { url = "https://files.pythonhosted.org/packages/0e/66/d03348fdd8df262b3a7fb4ee5727e6e4936e39e2f3a842e803196946f200/coverage-7.10.6-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3e23dd5408fe71a356b41baa82892772a4cefcf758f2ca3383d2aa39e1b7a003", size = 248600, upload-time = "2025-08-29T15:33:48.953Z" }, - { url = "https://files.pythonhosted.org/packages/73/dd/508420fb47d09d904d962f123221bc249f64b5e56aa93d5f5f7603be475f/coverage-7.10.6-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:0f3f56e4cb573755e96a16501a98bf211f100463d70275759e73f3cbc00d4f27", size = 251206, upload-time = "2025-08-29T15:33:50.697Z" }, - { url = "https://files.pythonhosted.org/packages/e9/1f/9020135734184f439da85c70ea78194c2730e56c2d18aee6e8ff1719d50d/coverage-7.10.6-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:db4a1d897bbbe7339946ffa2fe60c10cc81c43fab8b062d3fcb84188688174a4", size = 252478, upload-time = "2025-08-29T15:33:52.303Z" }, - { url = "https://files.pythonhosted.org/packages/a4/a4/3d228f3942bb5a2051fde28c136eea23a761177dc4ff4ef54533164ce255/coverage-7.10.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:d8fd7879082953c156d5b13c74aa6cca37f6a6f4747b39538504c3f9c63d043d", size = 250637, upload-time = "2025-08-29T15:33:53.67Z" }, - { url = "https://files.pythonhosted.org/packages/36/e3/293dce8cdb9a83de971637afc59b7190faad60603b40e32635cbd15fbf61/coverage-7.10.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:28395ca3f71cd103b8c116333fa9db867f3a3e1ad6a084aa3725ae002b6583bc", size = 248529, upload-time = "2025-08-29T15:33:55.022Z" }, - { url = "https://files.pythonhosted.org/packages/90/26/64eecfa214e80dd1d101e420cab2901827de0e49631d666543d0e53cf597/coverage-7.10.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:61c950fc33d29c91b9e18540e1aed7d9f6787cc870a3e4032493bbbe641d12fc", size = 250143, upload-time = "2025-08-29T15:33:56.386Z" }, - { url = "https://files.pythonhosted.org/packages/3e/70/bd80588338f65ea5b0d97e424b820fb4068b9cfb9597fbd91963086e004b/coverage-7.10.6-cp313-cp313-win32.whl", hash = "sha256:160c00a5e6b6bdf4e5984b0ef21fc860bc94416c41b7df4d63f536d17c38902e", size = 219770, upload-time = "2025-08-29T15:33:58.063Z" }, - { url = "https://files.pythonhosted.org/packages/a7/14/0b831122305abcc1060c008f6c97bbdc0a913ab47d65070a01dc50293c2b/coverage-7.10.6-cp313-cp313-win_amd64.whl", hash = "sha256:628055297f3e2aa181464c3808402887643405573eb3d9de060d81531fa79d32", size = 220566, upload-time = "2025-08-29T15:33:59.766Z" }, - { url = "https://files.pythonhosted.org/packages/83/c6/81a83778c1f83f1a4a168ed6673eeedc205afb562d8500175292ca64b94e/coverage-7.10.6-cp313-cp313-win_arm64.whl", hash = "sha256:df4ec1f8540b0bcbe26ca7dd0f541847cc8a108b35596f9f91f59f0c060bfdd2", size = 219195, upload-time = "2025-08-29T15:34:01.191Z" }, - { url = "https://files.pythonhosted.org/packages/d7/1c/ccccf4bf116f9517275fa85047495515add43e41dfe8e0bef6e333c6b344/coverage-7.10.6-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:c9a8b7a34a4de3ed987f636f71881cd3b8339f61118b1aa311fbda12741bff0b", size = 218059, upload-time = "2025-08-29T15:34:02.91Z" }, - { url = "https://files.pythonhosted.org/packages/92/97/8a3ceff833d27c7492af4f39d5da6761e9ff624831db9e9f25b3886ddbca/coverage-7.10.6-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:8dd5af36092430c2b075cee966719898f2ae87b636cefb85a653f1d0ba5d5393", size = 218287, upload-time = "2025-08-29T15:34:05.106Z" }, - { url = "https://files.pythonhosted.org/packages/92/d8/50b4a32580cf41ff0423777a2791aaf3269ab60c840b62009aec12d3970d/coverage-7.10.6-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:b0353b0f0850d49ada66fdd7d0c7cdb0f86b900bb9e367024fd14a60cecc1e27", size = 259625, upload-time = "2025-08-29T15:34:06.575Z" }, - { url = "https://files.pythonhosted.org/packages/7e/7e/6a7df5a6fb440a0179d94a348eb6616ed4745e7df26bf2a02bc4db72c421/coverage-7.10.6-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:d6b9ae13d5d3e8aeca9ca94198aa7b3ebbc5acfada557d724f2a1f03d2c0b0df", size = 261801, upload-time = "2025-08-29T15:34:08.006Z" }, - { url = "https://files.pythonhosted.org/packages/3a/4c/a270a414f4ed5d196b9d3d67922968e768cd971d1b251e1b4f75e9362f75/coverage-7.10.6-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:675824a363cc05781b1527b39dc2587b8984965834a748177ee3c37b64ffeafb", size = 264027, upload-time = "2025-08-29T15:34:09.806Z" }, - { url = "https://files.pythonhosted.org/packages/9c/8b/3210d663d594926c12f373c5370bf1e7c5c3a427519a8afa65b561b9a55c/coverage-7.10.6-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:692d70ea725f471a547c305f0d0fc6a73480c62fb0da726370c088ab21aed282", size = 261576, upload-time = "2025-08-29T15:34:11.585Z" }, - { url = "https://files.pythonhosted.org/packages/72/d0/e1961eff67e9e1dba3fc5eb7a4caf726b35a5b03776892da8d79ec895775/coverage-7.10.6-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:851430a9a361c7a8484a36126d1d0ff8d529d97385eacc8dfdc9bfc8c2d2cbe4", size = 259341, upload-time = "2025-08-29T15:34:13.159Z" }, - { url = "https://files.pythonhosted.org/packages/3a/06/d6478d152cd189b33eac691cba27a40704990ba95de49771285f34a5861e/coverage-7.10.6-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:d9369a23186d189b2fc95cc08b8160ba242057e887d766864f7adf3c46b2df21", size = 260468, upload-time = "2025-08-29T15:34:14.571Z" }, - { url = "https://files.pythonhosted.org/packages/ed/73/737440247c914a332f0b47f7598535b29965bf305e19bbc22d4c39615d2b/coverage-7.10.6-cp313-cp313t-win32.whl", hash = "sha256:92be86fcb125e9bda0da7806afd29a3fd33fdf58fba5d60318399adf40bf37d0", size = 220429, upload-time = "2025-08-29T15:34:16.394Z" }, - { url = "https://files.pythonhosted.org/packages/bd/76/b92d3214740f2357ef4a27c75a526eb6c28f79c402e9f20a922c295c05e2/coverage-7.10.6-cp313-cp313t-win_amd64.whl", hash = "sha256:6b3039e2ca459a70c79523d39347d83b73f2f06af5624905eba7ec34d64d80b5", size = 221493, upload-time = "2025-08-29T15:34:17.835Z" }, - { url = "https://files.pythonhosted.org/packages/fc/8e/6dcb29c599c8a1f654ec6cb68d76644fe635513af16e932d2d4ad1e5ac6e/coverage-7.10.6-cp313-cp313t-win_arm64.whl", hash = "sha256:3fb99d0786fe17b228eab663d16bee2288e8724d26a199c29325aac4b0319b9b", size = 219757, upload-time = "2025-08-29T15:34:19.248Z" }, - { url = "https://files.pythonhosted.org/packages/d3/aa/76cf0b5ec00619ef208da4689281d48b57f2c7fde883d14bf9441b74d59f/coverage-7.10.6-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:6008a021907be8c4c02f37cdc3ffb258493bdebfeaf9a839f9e71dfdc47b018e", size = 217331, upload-time = "2025-08-29T15:34:20.846Z" }, - { url = "https://files.pythonhosted.org/packages/65/91/8e41b8c7c505d398d7730206f3cbb4a875a35ca1041efc518051bfce0f6b/coverage-7.10.6-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:5e75e37f23eb144e78940b40395b42f2321951206a4f50e23cfd6e8a198d3ceb", size = 217607, upload-time = "2025-08-29T15:34:22.433Z" }, - { url = "https://files.pythonhosted.org/packages/87/7f/f718e732a423d442e6616580a951b8d1ec3575ea48bcd0e2228386805e79/coverage-7.10.6-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0f7cb359a448e043c576f0da00aa8bfd796a01b06aa610ca453d4dde09cc1034", size = 248663, upload-time = "2025-08-29T15:34:24.425Z" }, - { url = "https://files.pythonhosted.org/packages/e6/52/c1106120e6d801ac03e12b5285e971e758e925b6f82ee9b86db3aa10045d/coverage-7.10.6-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:c68018e4fc4e14b5668f1353b41ccf4bc83ba355f0e1b3836861c6f042d89ac1", size = 251197, upload-time = "2025-08-29T15:34:25.906Z" }, - { url = "https://files.pythonhosted.org/packages/3d/ec/3a8645b1bb40e36acde9c0609f08942852a4af91a937fe2c129a38f2d3f5/coverage-7.10.6-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:cd4b2b0707fc55afa160cd5fc33b27ccbf75ca11d81f4ec9863d5793fc6df56a", size = 252551, upload-time = "2025-08-29T15:34:27.337Z" }, - { url = "https://files.pythonhosted.org/packages/a1/70/09ecb68eeb1155b28a1d16525fd3a9b65fbe75337311a99830df935d62b6/coverage-7.10.6-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:4cec13817a651f8804a86e4f79d815b3b28472c910e099e4d5a0e8a3b6a1d4cb", size = 250553, upload-time = "2025-08-29T15:34:29.065Z" }, - { url = "https://files.pythonhosted.org/packages/c6/80/47df374b893fa812e953b5bc93dcb1427a7b3d7a1a7d2db33043d17f74b9/coverage-7.10.6-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:f2a6a8e06bbda06f78739f40bfb56c45d14eb8249d0f0ea6d4b3d48e1f7c695d", size = 248486, upload-time = "2025-08-29T15:34:30.897Z" }, - { url = "https://files.pythonhosted.org/packages/4a/65/9f98640979ecee1b0d1a7164b589de720ddf8100d1747d9bbdb84be0c0fb/coverage-7.10.6-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:081b98395ced0d9bcf60ada7661a0b75f36b78b9d7e39ea0790bb4ed8da14747", size = 249981, upload-time = "2025-08-29T15:34:32.365Z" }, - { url = "https://files.pythonhosted.org/packages/1f/55/eeb6603371e6629037f47bd25bef300387257ed53a3c5fdb159b7ac8c651/coverage-7.10.6-cp314-cp314-win32.whl", hash = "sha256:6937347c5d7d069ee776b2bf4e1212f912a9f1f141a429c475e6089462fcecc5", size = 220054, upload-time = "2025-08-29T15:34:34.124Z" }, - { url = "https://files.pythonhosted.org/packages/15/d1/a0912b7611bc35412e919a2cd59ae98e7ea3b475e562668040a43fb27897/coverage-7.10.6-cp314-cp314-win_amd64.whl", hash = "sha256:adec1d980fa07e60b6ef865f9e5410ba760e4e1d26f60f7e5772c73b9a5b0713", size = 220851, upload-time = "2025-08-29T15:34:35.651Z" }, - { url = "https://files.pythonhosted.org/packages/ef/2d/11880bb8ef80a45338e0b3e0725e4c2d73ffbb4822c29d987078224fd6a5/coverage-7.10.6-cp314-cp314-win_arm64.whl", hash = "sha256:a80f7aef9535442bdcf562e5a0d5a5538ce8abe6bb209cfbf170c462ac2c2a32", size = 219429, upload-time = "2025-08-29T15:34:37.16Z" }, - { url = "https://files.pythonhosted.org/packages/83/c0/1f00caad775c03a700146f55536ecd097a881ff08d310a58b353a1421be0/coverage-7.10.6-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:0de434f4fbbe5af4fa7989521c655c8c779afb61c53ab561b64dcee6149e4c65", size = 218080, upload-time = "2025-08-29T15:34:38.919Z" }, - { url = "https://files.pythonhosted.org/packages/a9/c4/b1c5d2bd7cc412cbeb035e257fd06ed4e3e139ac871d16a07434e145d18d/coverage-7.10.6-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:6e31b8155150c57e5ac43ccd289d079eb3f825187d7c66e755a055d2c85794c6", size = 218293, upload-time = "2025-08-29T15:34:40.425Z" }, - { url = "https://files.pythonhosted.org/packages/3f/07/4468d37c94724bf6ec354e4ec2f205fda194343e3e85fd2e59cec57e6a54/coverage-7.10.6-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:98cede73eb83c31e2118ae8d379c12e3e42736903a8afcca92a7218e1f2903b0", size = 259800, upload-time = "2025-08-29T15:34:41.996Z" }, - { url = "https://files.pythonhosted.org/packages/82/d8/f8fb351be5fee31690cd8da768fd62f1cfab33c31d9f7baba6cd8960f6b8/coverage-7.10.6-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:f863c08f4ff6b64fa8045b1e3da480f5374779ef187f07b82e0538c68cb4ff8e", size = 261965, upload-time = "2025-08-29T15:34:43.61Z" }, - { url = "https://files.pythonhosted.org/packages/e8/70/65d4d7cfc75c5c6eb2fed3ee5cdf420fd8ae09c4808723a89a81d5b1b9c3/coverage-7.10.6-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:2b38261034fda87be356f2c3f42221fdb4171c3ce7658066ae449241485390d5", size = 264220, upload-time = "2025-08-29T15:34:45.387Z" }, - { url = "https://files.pythonhosted.org/packages/98/3c/069df106d19024324cde10e4ec379fe2fb978017d25e97ebee23002fbadf/coverage-7.10.6-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:0e93b1476b79eae849dc3872faeb0bf7948fd9ea34869590bc16a2a00b9c82a7", size = 261660, upload-time = "2025-08-29T15:34:47.288Z" }, - { url = "https://files.pythonhosted.org/packages/fc/8a/2974d53904080c5dc91af798b3a54a4ccb99a45595cc0dcec6eb9616a57d/coverage-7.10.6-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:ff8a991f70f4c0cf53088abf1e3886edcc87d53004c7bb94e78650b4d3dac3b5", size = 259417, upload-time = "2025-08-29T15:34:48.779Z" }, - { url = "https://files.pythonhosted.org/packages/30/38/9616a6b49c686394b318974d7f6e08f38b8af2270ce7488e879888d1e5db/coverage-7.10.6-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:ac765b026c9f33044419cbba1da913cfb82cca1b60598ac1c7a5ed6aac4621a0", size = 260567, upload-time = "2025-08-29T15:34:50.718Z" }, - { url = "https://files.pythonhosted.org/packages/76/16/3ed2d6312b371a8cf804abf4e14895b70e4c3491c6e53536d63fd0958a8d/coverage-7.10.6-cp314-cp314t-win32.whl", hash = "sha256:441c357d55f4936875636ef2cfb3bee36e466dcf50df9afbd398ce79dba1ebb7", size = 220831, upload-time = "2025-08-29T15:34:52.653Z" }, - { url = "https://files.pythonhosted.org/packages/d5/e5/d38d0cb830abede2adb8b147770d2a3d0e7fecc7228245b9b1ae6c24930a/coverage-7.10.6-cp314-cp314t-win_amd64.whl", hash = "sha256:073711de3181b2e204e4870ac83a7c4853115b42e9cd4d145f2231e12d670930", size = 221950, upload-time = "2025-08-29T15:34:54.212Z" }, - { url = "https://files.pythonhosted.org/packages/f4/51/e48e550f6279349895b0ffcd6d2a690e3131ba3a7f4eafccc141966d4dea/coverage-7.10.6-cp314-cp314t-win_arm64.whl", hash = "sha256:137921f2bac5559334ba66122b753db6dc5d1cf01eb7b64eb412bb0d064ef35b", size = 219969, upload-time = "2025-08-29T15:34:55.83Z" }, - { url = "https://files.pythonhosted.org/packages/44/0c/50db5379b615854b5cf89146f8f5bd1d5a9693d7f3a987e269693521c404/coverage-7.10.6-py3-none-any.whl", hash = "sha256:92c4ecf6bf11b2e85fd4d8204814dc26e6a19f0c9d938c207c5cb0eadfcabbe3", size = 208986, upload-time = "2025-08-29T15:35:14.506Z" }, +version = "7.10.7" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/51/26/d22c300112504f5f9a9fd2297ce33c35f3d353e4aeb987c8419453b2a7c2/coverage-7.10.7.tar.gz", hash = "sha256:f4ab143ab113be368a3e9b795f9cd7906c5ef407d6173fe9675a902e1fffc239", size = 827704, upload-time = "2025-09-21T20:03:56.815Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9a/94/b765c1abcb613d103b64fcf10395f54d69b0ef8be6a0dd9c524384892cc7/coverage-7.10.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:981a651f543f2854abd3b5fcb3263aac581b18209be49863ba575de6edf4c14d", size = 218320, upload-time = "2025-09-21T20:01:56.629Z" }, + { url = "https://files.pythonhosted.org/packages/72/4f/732fff31c119bb73b35236dd333030f32c4bfe909f445b423e6c7594f9a2/coverage-7.10.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:73ab1601f84dc804f7812dc297e93cd99381162da39c47040a827d4e8dafe63b", size = 218575, upload-time = "2025-09-21T20:01:58.203Z" }, + { url = "https://files.pythonhosted.org/packages/87/02/ae7e0af4b674be47566707777db1aa375474f02a1d64b9323e5813a6cdd5/coverage-7.10.7-cp313-cp313-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:a8b6f03672aa6734e700bbcd65ff050fd19cddfec4b031cc8cf1c6967de5a68e", size = 249568, upload-time = "2025-09-21T20:01:59.748Z" }, + { url = "https://files.pythonhosted.org/packages/a2/77/8c6d22bf61921a59bce5471c2f1f7ac30cd4ac50aadde72b8c48d5727902/coverage-7.10.7-cp313-cp313-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:10b6ba00ab1132a0ce4428ff68cf50a25efd6840a42cdf4239c9b99aad83be8b", size = 252174, upload-time = "2025-09-21T20:02:01.192Z" }, + { url = "https://files.pythonhosted.org/packages/b1/20/b6ea4f69bbb52dac0aebd62157ba6a9dddbfe664f5af8122dac296c3ee15/coverage-7.10.7-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c79124f70465a150e89340de5963f936ee97097d2ef76c869708c4248c63ca49", size = 253447, upload-time = "2025-09-21T20:02:02.701Z" }, + { url = "https://files.pythonhosted.org/packages/f9/28/4831523ba483a7f90f7b259d2018fef02cb4d5b90bc7c1505d6e5a84883c/coverage-7.10.7-cp313-cp313-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:69212fbccdbd5b0e39eac4067e20a4a5256609e209547d86f740d68ad4f04911", size = 249779, upload-time = "2025-09-21T20:02:04.185Z" }, + { url = "https://files.pythonhosted.org/packages/a7/9f/4331142bc98c10ca6436d2d620c3e165f31e6c58d43479985afce6f3191c/coverage-7.10.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7ea7c6c9d0d286d04ed3541747e6597cbe4971f22648b68248f7ddcd329207f0", size = 251604, upload-time = "2025-09-21T20:02:06.034Z" }, + { url = "https://files.pythonhosted.org/packages/ce/60/bda83b96602036b77ecf34e6393a3836365481b69f7ed7079ab85048202b/coverage-7.10.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b9be91986841a75042b3e3243d0b3cb0b2434252b977baaf0cd56e960fe1e46f", size = 249497, upload-time = "2025-09-21T20:02:07.619Z" }, + { url = "https://files.pythonhosted.org/packages/5f/af/152633ff35b2af63977edd835d8e6430f0caef27d171edf2fc76c270ef31/coverage-7.10.7-cp313-cp313-musllinux_1_2_riscv64.whl", hash = "sha256:b281d5eca50189325cfe1f365fafade89b14b4a78d9b40b05ddd1fc7d2a10a9c", size = 249350, upload-time = "2025-09-21T20:02:10.34Z" }, + { url = "https://files.pythonhosted.org/packages/9d/71/d92105d122bd21cebba877228990e1646d862e34a98bb3374d3fece5a794/coverage-7.10.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:99e4aa63097ab1118e75a848a28e40d68b08a5e19ce587891ab7fd04475e780f", size = 251111, upload-time = "2025-09-21T20:02:12.122Z" }, + { url = "https://files.pythonhosted.org/packages/a2/9e/9fdb08f4bf476c912f0c3ca292e019aab6712c93c9344a1653986c3fd305/coverage-7.10.7-cp313-cp313-win32.whl", hash = "sha256:dc7c389dce432500273eaf48f410b37886be9208b2dd5710aaf7c57fd442c698", size = 220746, upload-time = "2025-09-21T20:02:13.919Z" }, + { url = "https://files.pythonhosted.org/packages/b1/b1/a75fd25df44eab52d1931e89980d1ada46824c7a3210be0d3c88a44aaa99/coverage-7.10.7-cp313-cp313-win_amd64.whl", hash = "sha256:cac0fdca17b036af3881a9d2729a850b76553f3f716ccb0360ad4dbc06b3b843", size = 221541, upload-time = "2025-09-21T20:02:15.57Z" }, + { url = "https://files.pythonhosted.org/packages/14/3a/d720d7c989562a6e9a14b2c9f5f2876bdb38e9367126d118495b89c99c37/coverage-7.10.7-cp313-cp313-win_arm64.whl", hash = "sha256:4b6f236edf6e2f9ae8fcd1332da4e791c1b6ba0dc16a2dc94590ceccb482e546", size = 220170, upload-time = "2025-09-21T20:02:17.395Z" }, + { url = "https://files.pythonhosted.org/packages/bb/22/e04514bf2a735d8b0add31d2b4ab636fc02370730787c576bb995390d2d5/coverage-7.10.7-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:a0ec07fd264d0745ee396b666d47cef20875f4ff2375d7c4f58235886cc1ef0c", size = 219029, upload-time = "2025-09-21T20:02:18.936Z" }, + { url = "https://files.pythonhosted.org/packages/11/0b/91128e099035ece15da3445d9015e4b4153a6059403452d324cbb0a575fa/coverage-7.10.7-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:dd5e856ebb7bfb7672b0086846db5afb4567a7b9714b8a0ebafd211ec7ce6a15", size = 219259, upload-time = "2025-09-21T20:02:20.44Z" }, + { url = "https://files.pythonhosted.org/packages/8b/51/66420081e72801536a091a0c8f8c1f88a5c4bf7b9b1bdc6222c7afe6dc9b/coverage-7.10.7-cp313-cp313t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:f57b2a3c8353d3e04acf75b3fed57ba41f5c0646bbf1d10c7c282291c97936b4", size = 260592, upload-time = "2025-09-21T20:02:22.313Z" }, + { url = "https://files.pythonhosted.org/packages/5d/22/9b8d458c2881b22df3db5bb3e7369e63d527d986decb6c11a591ba2364f7/coverage-7.10.7-cp313-cp313t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:1ef2319dd15a0b009667301a3f84452a4dc6fddfd06b0c5c53ea472d3989fbf0", size = 262768, upload-time = "2025-09-21T20:02:24.287Z" }, + { url = "https://files.pythonhosted.org/packages/f7/08/16bee2c433e60913c610ea200b276e8eeef084b0d200bdcff69920bd5828/coverage-7.10.7-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:83082a57783239717ceb0ad584de3c69cf581b2a95ed6bf81ea66034f00401c0", size = 264995, upload-time = "2025-09-21T20:02:26.133Z" }, + { url = "https://files.pythonhosted.org/packages/20/9d/e53eb9771d154859b084b90201e5221bca7674ba449a17c101a5031d4054/coverage-7.10.7-cp313-cp313t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:50aa94fb1fb9a397eaa19c0d5ec15a5edd03a47bf1a3a6111a16b36e190cff65", size = 259546, upload-time = "2025-09-21T20:02:27.716Z" }, + { url = "https://files.pythonhosted.org/packages/ad/b0/69bc7050f8d4e56a89fb550a1577d5d0d1db2278106f6f626464067b3817/coverage-7.10.7-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:2120043f147bebb41c85b97ac45dd173595ff14f2a584f2963891cbcc3091541", size = 262544, upload-time = "2025-09-21T20:02:29.216Z" }, + { url = "https://files.pythonhosted.org/packages/ef/4b/2514b060dbd1bc0aaf23b852c14bb5818f244c664cb16517feff6bb3a5ab/coverage-7.10.7-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:2fafd773231dd0378fdba66d339f84904a8e57a262f583530f4f156ab83863e6", size = 260308, upload-time = "2025-09-21T20:02:31.226Z" }, + { url = "https://files.pythonhosted.org/packages/54/78/7ba2175007c246d75e496f64c06e94122bdb914790a1285d627a918bd271/coverage-7.10.7-cp313-cp313t-musllinux_1_2_riscv64.whl", hash = "sha256:0b944ee8459f515f28b851728ad224fa2d068f1513ef6b7ff1efafeb2185f999", size = 258920, upload-time = "2025-09-21T20:02:32.823Z" }, + { url = "https://files.pythonhosted.org/packages/c0/b3/fac9f7abbc841409b9a410309d73bfa6cfb2e51c3fada738cb607ce174f8/coverage-7.10.7-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:4b583b97ab2e3efe1b3e75248a9b333bd3f8b0b1b8e5b45578e05e5850dfb2c2", size = 261434, upload-time = "2025-09-21T20:02:34.86Z" }, + { url = "https://files.pythonhosted.org/packages/ee/51/a03bec00d37faaa891b3ff7387192cef20f01604e5283a5fabc95346befa/coverage-7.10.7-cp313-cp313t-win32.whl", hash = "sha256:2a78cd46550081a7909b3329e2266204d584866e8d97b898cd7fb5ac8d888b1a", size = 221403, upload-time = "2025-09-21T20:02:37.034Z" }, + { url = "https://files.pythonhosted.org/packages/53/22/3cf25d614e64bf6d8e59c7c669b20d6d940bb337bdee5900b9ca41c820bb/coverage-7.10.7-cp313-cp313t-win_amd64.whl", hash = "sha256:33a5e6396ab684cb43dc7befa386258acb2d7fae7f67330ebb85ba4ea27938eb", size = 222469, upload-time = "2025-09-21T20:02:39.011Z" }, + { url = "https://files.pythonhosted.org/packages/49/a1/00164f6d30d8a01c3c9c48418a7a5be394de5349b421b9ee019f380df2a0/coverage-7.10.7-cp313-cp313t-win_arm64.whl", hash = "sha256:86b0e7308289ddde73d863b7683f596d8d21c7d8664ce1dee061d0bcf3fbb4bb", size = 220731, upload-time = "2025-09-21T20:02:40.939Z" }, + { url = "https://files.pythonhosted.org/packages/23/9c/5844ab4ca6a4dd97a1850e030a15ec7d292b5c5cb93082979225126e35dd/coverage-7.10.7-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:b06f260b16ead11643a5a9f955bd4b5fd76c1a4c6796aeade8520095b75de520", size = 218302, upload-time = "2025-09-21T20:02:42.527Z" }, + { url = "https://files.pythonhosted.org/packages/f0/89/673f6514b0961d1f0e20ddc242e9342f6da21eaba3489901b565c0689f34/coverage-7.10.7-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:212f8f2e0612778f09c55dd4872cb1f64a1f2b074393d139278ce902064d5b32", size = 218578, upload-time = "2025-09-21T20:02:44.468Z" }, + { url = "https://files.pythonhosted.org/packages/05/e8/261cae479e85232828fb17ad536765c88dd818c8470aca690b0ac6feeaa3/coverage-7.10.7-cp314-cp314-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:3445258bcded7d4aa630ab8296dea4d3f15a255588dd535f980c193ab6b95f3f", size = 249629, upload-time = "2025-09-21T20:02:46.503Z" }, + { url = "https://files.pythonhosted.org/packages/82/62/14ed6546d0207e6eda876434e3e8475a3e9adbe32110ce896c9e0c06bb9a/coverage-7.10.7-cp314-cp314-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:bb45474711ba385c46a0bfe696c695a929ae69ac636cda8f532be9e8c93d720a", size = 252162, upload-time = "2025-09-21T20:02:48.689Z" }, + { url = "https://files.pythonhosted.org/packages/ff/49/07f00db9ac6478e4358165a08fb41b469a1b053212e8a00cb02f0d27a05f/coverage-7.10.7-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:813922f35bd800dca9994c5971883cbc0d291128a5de6b167c7aa697fcf59360", size = 253517, upload-time = "2025-09-21T20:02:50.31Z" }, + { url = "https://files.pythonhosted.org/packages/a2/59/c5201c62dbf165dfbc91460f6dbbaa85a8b82cfa6131ac45d6c1bfb52deb/coverage-7.10.7-cp314-cp314-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:93c1b03552081b2a4423091d6fb3787265b8f86af404cff98d1b5342713bdd69", size = 249632, upload-time = "2025-09-21T20:02:51.971Z" }, + { url = "https://files.pythonhosted.org/packages/07/ae/5920097195291a51fb00b3a70b9bbd2edbfe3c84876a1762bd1ef1565ebc/coverage-7.10.7-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:cc87dd1b6eaf0b848eebb1c86469b9f72a1891cb42ac7adcfbce75eadb13dd14", size = 251520, upload-time = "2025-09-21T20:02:53.858Z" }, + { url = "https://files.pythonhosted.org/packages/b9/3c/a815dde77a2981f5743a60b63df31cb322c944843e57dbd579326625a413/coverage-7.10.7-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:39508ffda4f343c35f3236fe8d1a6634a51f4581226a1262769d7f970e73bffe", size = 249455, upload-time = "2025-09-21T20:02:55.807Z" }, + { url = "https://files.pythonhosted.org/packages/aa/99/f5cdd8421ea656abefb6c0ce92556709db2265c41e8f9fc6c8ae0f7824c9/coverage-7.10.7-cp314-cp314-musllinux_1_2_riscv64.whl", hash = "sha256:925a1edf3d810537c5a3abe78ec5530160c5f9a26b1f4270b40e62cc79304a1e", size = 249287, upload-time = "2025-09-21T20:02:57.784Z" }, + { url = "https://files.pythonhosted.org/packages/c3/7a/e9a2da6a1fc5d007dd51fca083a663ab930a8c4d149c087732a5dbaa0029/coverage-7.10.7-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:2c8b9a0636f94c43cd3576811e05b89aa9bc2d0a85137affc544ae5cb0e4bfbd", size = 250946, upload-time = "2025-09-21T20:02:59.431Z" }, + { url = "https://files.pythonhosted.org/packages/ef/5b/0b5799aa30380a949005a353715095d6d1da81927d6dbed5def2200a4e25/coverage-7.10.7-cp314-cp314-win32.whl", hash = "sha256:b7b8288eb7cdd268b0304632da8cb0bb93fadcfec2fe5712f7b9cc8f4d487be2", size = 221009, upload-time = "2025-09-21T20:03:01.324Z" }, + { url = "https://files.pythonhosted.org/packages/da/b0/e802fbb6eb746de006490abc9bb554b708918b6774b722bb3a0e6aa1b7de/coverage-7.10.7-cp314-cp314-win_amd64.whl", hash = "sha256:1ca6db7c8807fb9e755d0379ccc39017ce0a84dcd26d14b5a03b78563776f681", size = 221804, upload-time = "2025-09-21T20:03:03.4Z" }, + { url = "https://files.pythonhosted.org/packages/9e/e8/71d0c8e374e31f39e3389bb0bd19e527d46f00ea8571ec7ec8fd261d8b44/coverage-7.10.7-cp314-cp314-win_arm64.whl", hash = "sha256:097c1591f5af4496226d5783d036bf6fd6cd0cbc132e071b33861de756efb880", size = 220384, upload-time = "2025-09-21T20:03:05.111Z" }, + { url = "https://files.pythonhosted.org/packages/62/09/9a5608d319fa3eba7a2019addeacb8c746fb50872b57a724c9f79f146969/coverage-7.10.7-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:a62c6ef0d50e6de320c270ff91d9dd0a05e7250cac2a800b7784bae474506e63", size = 219047, upload-time = "2025-09-21T20:03:06.795Z" }, + { url = "https://files.pythonhosted.org/packages/f5/6f/f58d46f33db9f2e3647b2d0764704548c184e6f5e014bef528b7f979ef84/coverage-7.10.7-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:9fa6e4dd51fe15d8738708a973470f67a855ca50002294852e9571cdbd9433f2", size = 219266, upload-time = "2025-09-21T20:03:08.495Z" }, + { url = "https://files.pythonhosted.org/packages/74/5c/183ffc817ba68e0b443b8c934c8795553eb0c14573813415bd59941ee165/coverage-7.10.7-cp314-cp314t-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:8fb190658865565c549b6b4706856d6a7b09302c797eb2cf8e7fe9dabb043f0d", size = 260767, upload-time = "2025-09-21T20:03:10.172Z" }, + { url = "https://files.pythonhosted.org/packages/0f/48/71a8abe9c1ad7e97548835e3cc1adbf361e743e9d60310c5f75c9e7bf847/coverage-7.10.7-cp314-cp314t-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:affef7c76a9ef259187ef31599a9260330e0335a3011732c4b9effa01e1cd6e0", size = 262931, upload-time = "2025-09-21T20:03:11.861Z" }, + { url = "https://files.pythonhosted.org/packages/84/fd/193a8fb132acfc0a901f72020e54be5e48021e1575bb327d8ee1097a28fd/coverage-7.10.7-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6e16e07d85ca0cf8bafe5f5d23a0b850064e8e945d5677492b06bbe6f09cc699", size = 265186, upload-time = "2025-09-21T20:03:13.539Z" }, + { url = "https://files.pythonhosted.org/packages/b1/8f/74ecc30607dd95ad50e3034221113ccb1c6d4e8085cc761134782995daae/coverage-7.10.7-cp314-cp314t-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:03ffc58aacdf65d2a82bbeb1ffe4d01ead4017a21bfd0454983b88ca73af94b9", size = 259470, upload-time = "2025-09-21T20:03:15.584Z" }, + { url = "https://files.pythonhosted.org/packages/0f/55/79ff53a769f20d71b07023ea115c9167c0bb56f281320520cf64c5298a96/coverage-7.10.7-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:1b4fd784344d4e52647fd7857b2af5b3fbe6c239b0b5fa63e94eb67320770e0f", size = 262626, upload-time = "2025-09-21T20:03:17.673Z" }, + { url = "https://files.pythonhosted.org/packages/88/e2/dac66c140009b61ac3fc13af673a574b00c16efdf04f9b5c740703e953c0/coverage-7.10.7-cp314-cp314t-musllinux_1_2_i686.whl", hash = "sha256:0ebbaddb2c19b71912c6f2518e791aa8b9f054985a0769bdb3a53ebbc765c6a1", size = 260386, upload-time = "2025-09-21T20:03:19.36Z" }, + { url = "https://files.pythonhosted.org/packages/a2/f1/f48f645e3f33bb9ca8a496bc4a9671b52f2f353146233ebd7c1df6160440/coverage-7.10.7-cp314-cp314t-musllinux_1_2_riscv64.whl", hash = "sha256:a2d9a3b260cc1d1dbdb1c582e63ddcf5363426a1a68faa0f5da28d8ee3c722a0", size = 258852, upload-time = "2025-09-21T20:03:21.007Z" }, + { url = "https://files.pythonhosted.org/packages/bb/3b/8442618972c51a7affeead957995cfa8323c0c9bcf8fa5a027421f720ff4/coverage-7.10.7-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:a3cc8638b2480865eaa3926d192e64ce6c51e3d29c849e09d5b4ad95efae5399", size = 261534, upload-time = "2025-09-21T20:03:23.12Z" }, + { url = "https://files.pythonhosted.org/packages/b2/dc/101f3fa3a45146db0cb03f5b4376e24c0aac818309da23e2de0c75295a91/coverage-7.10.7-cp314-cp314t-win32.whl", hash = "sha256:67f8c5cbcd3deb7a60b3345dffc89a961a484ed0af1f6f73de91705cc6e31235", size = 221784, upload-time = "2025-09-21T20:03:24.769Z" }, + { url = "https://files.pythonhosted.org/packages/4c/a1/74c51803fc70a8a40d7346660379e144be772bab4ac7bb6e6b905152345c/coverage-7.10.7-cp314-cp314t-win_amd64.whl", hash = "sha256:e1ed71194ef6dea7ed2d5cb5f7243d4bcd334bfb63e59878519be558078f848d", size = 222905, upload-time = "2025-09-21T20:03:26.93Z" }, + { url = "https://files.pythonhosted.org/packages/12/65/f116a6d2127df30bcafbceef0302d8a64ba87488bf6f73a6d8eebf060873/coverage-7.10.7-cp314-cp314t-win_arm64.whl", hash = "sha256:7fe650342addd8524ca63d77b2362b02345e5f1a093266787d210c70a50b471a", size = 220922, upload-time = "2025-09-21T20:03:28.672Z" }, + { url = "https://files.pythonhosted.org/packages/ec/16/114df1c291c22cac3b0c127a73e0af5c12ed7bbb6558d310429a0ae24023/coverage-7.10.7-py3-none-any.whl", hash = "sha256:f7941f6f2fe6dd6807a1208737b8a0cbcf1cc6d7b07d24998ad2d63590868260", size = 209952, upload-time = "2025-09-21T20:03:53.918Z" }, ] [[package]] @@ -463,7 +471,7 @@ wheels = [ [[package]] name = "pydantic" -version = "2.11.7" +version = "2.11.10" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "annotated-types" }, @@ -471,9 +479,9 @@ dependencies = [ { name = "typing-extensions" }, { name = "typing-inspection" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/00/dd/4325abf92c39ba8623b5af936ddb36ffcfe0beae70405d456ab1fb2f5b8c/pydantic-2.11.7.tar.gz", hash = "sha256:d989c3c6cb79469287b1569f7447a17848c998458d49ebe294e975b9baf0f0db", size = 788350, upload-time = "2025-06-14T08:33:17.137Z" } +sdist = { url = "https://files.pythonhosted.org/packages/ae/54/ecab642b3bed45f7d5f59b38443dcb36ef50f85af192e6ece103dbfe9587/pydantic-2.11.10.tar.gz", hash = "sha256:dc280f0982fbda6c38fada4e476dc0a4f3aeaf9c6ad4c28df68a666ec3c61423", size = 788494, upload-time = "2025-10-04T10:40:41.338Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/6a/c0/ec2b1c8712ca690e5d61979dee872603e92b8a32f94cc1b72d53beab008a/pydantic-2.11.7-py3-none-any.whl", hash = "sha256:dde5df002701f6de26248661f6835bbe296a47bf73990135c7d07ce741b9623b", size = 444782, upload-time = "2025-06-14T08:33:14.905Z" }, + { url = "https://files.pythonhosted.org/packages/bd/1f/73c53fcbfb0b5a78f91176df41945ca466e71e9d9d836e5c522abda39ee7/pydantic-2.11.10-py3-none-any.whl", hash = "sha256:802a655709d49bd004c31e865ef37da30b540786a46bfce02333e0e24b5fe29a", size = 444823, upload-time = "2025-10-04T10:40:39.055Z" }, ] [[package]] @@ -515,16 +523,16 @@ wheels = [ [[package]] name = "pyparsing" -version = "3.2.3" +version = "3.2.5" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/bb/22/f1129e69d94ffff626bdb5c835506b3a5b4f3d070f17ea295e12c2c6f60f/pyparsing-3.2.3.tar.gz", hash = "sha256:b9c13f1ab8b3b542f72e28f634bad4de758ab3ce4546e4301970ad6fa77c38be", size = 1088608, upload-time = "2025-03-25T05:01:28.114Z" } +sdist = { url = "https://files.pythonhosted.org/packages/f2/a5/181488fc2b9d093e3972d2a472855aae8a03f000592dbfce716a512b3359/pyparsing-3.2.5.tar.gz", hash = "sha256:2df8d5b7b2802ef88e8d016a2eb9c7aeaa923529cd251ed0fe4608275d4105b6", size = 1099274, upload-time = "2025-09-21T04:11:06.277Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/05/e7/df2285f3d08fee213f2d041540fa4fc9ca6c2d44cf36d3a035bf2a8d2bcc/pyparsing-3.2.3-py3-none-any.whl", hash = "sha256:a749938e02d6fd0b59b356ca504a24982314bb090c383e3cf201c95ef7e2bfcf", size = 111120, upload-time = "2025-03-25T05:01:24.908Z" }, + { url = "https://files.pythonhosted.org/packages/10/5e/1aa9a93198c6b64513c9d7752de7422c06402de6600a8767da1524f9570b/pyparsing-3.2.5-py3-none-any.whl", hash = "sha256:e38a4f02064cf41fe6593d328d0512495ad1f3d8a91c4f73fc401b3079a59a5e", size = 113890, upload-time = "2025-09-21T04:11:04.117Z" }, ] [[package]] name = "pytest" -version = "8.4.1" +version = "8.4.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "colorama", marker = "sys_platform == 'win32'" }, @@ -533,23 +541,23 @@ dependencies = [ { name = "pluggy" }, { name = "pygments" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/08/ba/45911d754e8eba3d5a841a5ce61a65a685ff1798421ac054f85aa8747dfb/pytest-8.4.1.tar.gz", hash = "sha256:7c67fd69174877359ed9371ec3af8a3d2b04741818c51e5e99cc1742251fa93c", size = 1517714, upload-time = "2025-06-18T05:48:06.109Z" } +sdist = { url = "https://files.pythonhosted.org/packages/a3/5c/00a0e072241553e1a7496d638deababa67c5058571567b92a7eaa258397c/pytest-8.4.2.tar.gz", hash = "sha256:86c0d0b93306b961d58d62a4db4879f27fe25513d4b969df351abdddb3c30e01", size = 1519618, upload-time = "2025-09-04T14:34:22.711Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/29/16/c8a903f4c4dffe7a12843191437d7cd8e32751d5de349d45d3fe69544e87/pytest-8.4.1-py3-none-any.whl", hash = "sha256:539c70ba6fcead8e78eebbf1115e8b589e7565830d7d006a8723f19ac8a0afb7", size = 365474, upload-time = "2025-06-18T05:48:03.955Z" }, + { url = "https://files.pythonhosted.org/packages/a8/a4/20da314d277121d6534b3a980b29035dcd51e6744bd79075a6ce8fa4eb8d/pytest-8.4.2-py3-none-any.whl", hash = "sha256:872f880de3fc3a5bdc88a11b39c9710c3497a547cfa9320bc3c5e62fbf272e79", size = 365750, upload-time = "2025-09-04T14:34:20.226Z" }, ] [[package]] name = "pytest-cov" -version = "6.2.1" +version = "7.0.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "coverage" }, { name = "pluggy" }, { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/18/99/668cade231f434aaa59bbfbf49469068d2ddd945000621d3d165d2e7dd7b/pytest_cov-6.2.1.tar.gz", hash = "sha256:25cc6cc0a5358204b8108ecedc51a9b57b34cc6b8c967cc2c01a4e00d8a67da2", size = 69432, upload-time = "2025-06-12T10:47:47.684Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5e/f7/c933acc76f5208b3b00089573cf6a2bc26dc80a8aece8f52bb7d6b1855ca/pytest_cov-7.0.0.tar.gz", hash = "sha256:33c97eda2e049a0c5298e91f519302a1334c26ac65c1a483d6206fd458361af1", size = 54328, upload-time = "2025-09-09T10:57:02.113Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/bc/16/4ea354101abb1287856baa4af2732be351c7bee728065aed451b678153fd/pytest_cov-6.2.1-py3-none-any.whl", hash = "sha256:f5bc4c23f42f1cdd23c70b1dab1bbaef4fc505ba950d53e0081d0730dd7e86d5", size = 24644, upload-time = "2025-06-12T10:47:45.932Z" }, + { url = "https://files.pythonhosted.org/packages/ee/49/1377b49de7d0c1ce41292161ea0f721913fa8722c19fb9c1e3aa0367eecb/pytest_cov-7.0.0-py3-none-any.whl", hash = "sha256:3b8e9558b16cc1479da72058bdecf8073661c7f57f7d3c5f22a1c23507f2d861", size = 22424, upload-time = "2025-09-09T10:57:00.695Z" }, ] [[package]] @@ -567,31 +575,50 @@ wheels = [ [[package]] name = "pytest-mock" -version = "3.14.1" +version = "3.15.1" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "pytest" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/71/28/67172c96ba684058a4d24ffe144d64783d2a270d0af0d9e792737bddc75c/pytest_mock-3.14.1.tar.gz", hash = "sha256:159e9edac4c451ce77a5cdb9fc5d1100708d2dd4ba3c3df572f14097351af80e", size = 33241, upload-time = "2025-05-26T13:58:45.167Z" } +sdist = { url = "https://files.pythonhosted.org/packages/68/14/eb014d26be205d38ad5ad20d9a80f7d201472e08167f0bb4361e251084a9/pytest_mock-3.15.1.tar.gz", hash = "sha256:1849a238f6f396da19762269de72cb1814ab44416fa73a8686deac10b0d87a0f", size = 34036, upload-time = "2025-09-16T16:37:27.081Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/b2/05/77b60e520511c53d1c1ca75f1930c7dd8e971d0c4379b7f4b3f9644685ba/pytest_mock-3.14.1-py3-none-any.whl", hash = "sha256:178aefcd11307d874b4cd3100344e7e2d888d9791a6a1d9bfe90fbc1b74fd1d0", size = 9923, upload-time = "2025-05-26T13:58:43.487Z" }, + { url = "https://files.pythonhosted.org/packages/5a/cc/06253936f4a7fa2e0f48dfe6d851d9c56df896a9ab09ac019d70b760619c/pytest_mock-3.15.1-py3-none-any.whl", hash = "sha256:0a25e2eb88fe5168d535041d09a4529a188176ae608a6d249ee65abc0949630d", size = 10095, upload-time = "2025-09-16T16:37:25.734Z" }, ] [[package]] name = "pyyaml" -version = "6.0.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload-time = "2024-08-06T20:33:50.674Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309, upload-time = "2024-08-06T20:32:43.4Z" }, - { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679, upload-time = "2024-08-06T20:32:44.801Z" }, - { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428, upload-time = "2024-08-06T20:32:46.432Z" }, - { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361, upload-time = "2024-08-06T20:32:51.188Z" }, - { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523, upload-time = "2024-08-06T20:32:53.019Z" }, - { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660, upload-time = "2024-08-06T20:32:54.708Z" }, - { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597, upload-time = "2024-08-06T20:32:56.985Z" }, - { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527, upload-time = "2024-08-06T20:33:03.001Z" }, - { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" }, +version = "6.0.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/05/8e/961c0007c59b8dd7729d542c61a4d537767a59645b82a0b521206e1e25c2/pyyaml-6.0.3.tar.gz", hash = "sha256:d76623373421df22fb4cf8817020cbb7ef15c725b9d5e45f17e189bfc384190f", size = 130960, upload-time = "2025-09-25T21:33:16.546Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/11/0fd08f8192109f7169db964b5707a2f1e8b745d4e239b784a5a1dd80d1db/pyyaml-6.0.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8da9669d359f02c0b91ccc01cac4a67f16afec0dac22c2ad09f46bee0697eba8", size = 181669, upload-time = "2025-09-25T21:32:23.673Z" }, + { url = "https://files.pythonhosted.org/packages/b1/16/95309993f1d3748cd644e02e38b75d50cbc0d9561d21f390a76242ce073f/pyyaml-6.0.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:2283a07e2c21a2aa78d9c4442724ec1eb15f5e42a723b99cb3d822d48f5f7ad1", size = 173252, upload-time = "2025-09-25T21:32:25.149Z" }, + { url = "https://files.pythonhosted.org/packages/50/31/b20f376d3f810b9b2371e72ef5adb33879b25edb7a6d072cb7ca0c486398/pyyaml-6.0.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ee2922902c45ae8ccada2c5b501ab86c36525b883eff4255313a253a3160861c", size = 767081, upload-time = "2025-09-25T21:32:26.575Z" }, + { url = "https://files.pythonhosted.org/packages/49/1e/a55ca81e949270d5d4432fbbd19dfea5321eda7c41a849d443dc92fd1ff7/pyyaml-6.0.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a33284e20b78bd4a18c8c2282d549d10bc8408a2a7ff57653c0cf0b9be0afce5", size = 841159, upload-time = "2025-09-25T21:32:27.727Z" }, + { url = "https://files.pythonhosted.org/packages/74/27/e5b8f34d02d9995b80abcef563ea1f8b56d20134d8f4e5e81733b1feceb2/pyyaml-6.0.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:0f29edc409a6392443abf94b9cf89ce99889a1dd5376d94316ae5145dfedd5d6", size = 801626, upload-time = "2025-09-25T21:32:28.878Z" }, + { url = "https://files.pythonhosted.org/packages/f9/11/ba845c23988798f40e52ba45f34849aa8a1f2d4af4b798588010792ebad6/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f7057c9a337546edc7973c0d3ba84ddcdf0daa14533c2065749c9075001090e6", size = 753613, upload-time = "2025-09-25T21:32:30.178Z" }, + { url = "https://files.pythonhosted.org/packages/3d/e0/7966e1a7bfc0a45bf0a7fb6b98ea03fc9b8d84fa7f2229e9659680b69ee3/pyyaml-6.0.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:eda16858a3cab07b80edaf74336ece1f986ba330fdb8ee0d6c0d68fe82bc96be", size = 794115, upload-time = "2025-09-25T21:32:31.353Z" }, + { url = "https://files.pythonhosted.org/packages/de/94/980b50a6531b3019e45ddeada0626d45fa85cbe22300844a7983285bed3b/pyyaml-6.0.3-cp313-cp313-win32.whl", hash = "sha256:d0eae10f8159e8fdad514efdc92d74fd8d682c933a6dd088030f3834bc8e6b26", size = 137427, upload-time = "2025-09-25T21:32:32.58Z" }, + { url = "https://files.pythonhosted.org/packages/97/c9/39d5b874e8b28845e4ec2202b5da735d0199dbe5b8fb85f91398814a9a46/pyyaml-6.0.3-cp313-cp313-win_amd64.whl", hash = "sha256:79005a0d97d5ddabfeeea4cf676af11e647e41d81c9a7722a193022accdb6b7c", size = 154090, upload-time = "2025-09-25T21:32:33.659Z" }, + { url = "https://files.pythonhosted.org/packages/73/e8/2bdf3ca2090f68bb3d75b44da7bbc71843b19c9f2b9cb9b0f4ab7a5a4329/pyyaml-6.0.3-cp313-cp313-win_arm64.whl", hash = "sha256:5498cd1645aa724a7c71c8f378eb29ebe23da2fc0d7a08071d89469bf1d2defb", size = 140246, upload-time = "2025-09-25T21:32:34.663Z" }, + { url = "https://files.pythonhosted.org/packages/9d/8c/f4bd7f6465179953d3ac9bc44ac1a8a3e6122cf8ada906b4f96c60172d43/pyyaml-6.0.3-cp314-cp314-macosx_10_13_x86_64.whl", hash = "sha256:8d1fab6bb153a416f9aeb4b8763bc0f22a5586065f86f7664fc23339fc1c1fac", size = 181814, upload-time = "2025-09-25T21:32:35.712Z" }, + { url = "https://files.pythonhosted.org/packages/bd/9c/4d95bb87eb2063d20db7b60faa3840c1b18025517ae857371c4dd55a6b3a/pyyaml-6.0.3-cp314-cp314-macosx_11_0_arm64.whl", hash = "sha256:34d5fcd24b8445fadc33f9cf348c1047101756fd760b4dacb5c3e99755703310", size = 173809, upload-time = "2025-09-25T21:32:36.789Z" }, + { url = "https://files.pythonhosted.org/packages/92/b5/47e807c2623074914e29dabd16cbbdd4bf5e9b2db9f8090fa64411fc5382/pyyaml-6.0.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:501a031947e3a9025ed4405a168e6ef5ae3126c59f90ce0cd6f2bfc477be31b7", size = 766454, upload-time = "2025-09-25T21:32:37.966Z" }, + { url = "https://files.pythonhosted.org/packages/02/9e/e5e9b168be58564121efb3de6859c452fccde0ab093d8438905899a3a483/pyyaml-6.0.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:b3bc83488de33889877a0f2543ade9f70c67d66d9ebb4ac959502e12de895788", size = 836355, upload-time = "2025-09-25T21:32:39.178Z" }, + { url = "https://files.pythonhosted.org/packages/88/f9/16491d7ed2a919954993e48aa941b200f38040928474c9e85ea9e64222c3/pyyaml-6.0.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c458b6d084f9b935061bc36216e8a69a7e293a2f1e68bf956dcd9e6cbcd143f5", size = 794175, upload-time = "2025-09-25T21:32:40.865Z" }, + { url = "https://files.pythonhosted.org/packages/dd/3f/5989debef34dc6397317802b527dbbafb2b4760878a53d4166579111411e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:7c6610def4f163542a622a73fb39f534f8c101d690126992300bf3207eab9764", size = 755228, upload-time = "2025-09-25T21:32:42.084Z" }, + { url = "https://files.pythonhosted.org/packages/d7/ce/af88a49043cd2e265be63d083fc75b27b6ed062f5f9fd6cdc223ad62f03e/pyyaml-6.0.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:5190d403f121660ce8d1d2c1bb2ef1bd05b5f68533fc5c2ea899bd15f4399b35", size = 789194, upload-time = "2025-09-25T21:32:43.362Z" }, + { url = "https://files.pythonhosted.org/packages/23/20/bb6982b26a40bb43951265ba29d4c246ef0ff59c9fdcdf0ed04e0687de4d/pyyaml-6.0.3-cp314-cp314-win_amd64.whl", hash = "sha256:4a2e8cebe2ff6ab7d1050ecd59c25d4c8bd7e6f400f5f82b96557ac0abafd0ac", size = 156429, upload-time = "2025-09-25T21:32:57.844Z" }, + { url = "https://files.pythonhosted.org/packages/f4/f4/a4541072bb9422c8a883ab55255f918fa378ecf083f5b85e87fc2b4eda1b/pyyaml-6.0.3-cp314-cp314-win_arm64.whl", hash = "sha256:93dda82c9c22deb0a405ea4dc5f2d0cda384168e466364dec6255b293923b2f3", size = 143912, upload-time = "2025-09-25T21:32:59.247Z" }, + { url = "https://files.pythonhosted.org/packages/7c/f9/07dd09ae774e4616edf6cda684ee78f97777bdd15847253637a6f052a62f/pyyaml-6.0.3-cp314-cp314t-macosx_10_13_x86_64.whl", hash = "sha256:02893d100e99e03eda1c8fd5c441d8c60103fd175728e23e431db1b589cf5ab3", size = 189108, upload-time = "2025-09-25T21:32:44.377Z" }, + { url = "https://files.pythonhosted.org/packages/4e/78/8d08c9fb7ce09ad8c38ad533c1191cf27f7ae1effe5bb9400a46d9437fcf/pyyaml-6.0.3-cp314-cp314t-macosx_11_0_arm64.whl", hash = "sha256:c1ff362665ae507275af2853520967820d9124984e0f7466736aea23d8611fba", size = 183641, upload-time = "2025-09-25T21:32:45.407Z" }, + { url = "https://files.pythonhosted.org/packages/7b/5b/3babb19104a46945cf816d047db2788bcaf8c94527a805610b0289a01c6b/pyyaml-6.0.3-cp314-cp314t-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:6adc77889b628398debc7b65c073bcb99c4a0237b248cacaf3fe8a557563ef6c", size = 831901, upload-time = "2025-09-25T21:32:48.83Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cc/dff0684d8dc44da4d22a13f35f073d558c268780ce3c6ba1b87055bb0b87/pyyaml-6.0.3-cp314-cp314t-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a80cb027f6b349846a3bf6d73b5e95e782175e52f22108cfa17876aaeff93702", size = 861132, upload-time = "2025-09-25T21:32:50.149Z" }, + { url = "https://files.pythonhosted.org/packages/b1/5e/f77dc6b9036943e285ba76b49e118d9ea929885becb0a29ba8a7c75e29fe/pyyaml-6.0.3-cp314-cp314t-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:00c4bdeba853cc34e7dd471f16b4114f4162dc03e6b7afcc2128711f0eca823c", size = 839261, upload-time = "2025-09-25T21:32:51.808Z" }, + { url = "https://files.pythonhosted.org/packages/ce/88/a9db1376aa2a228197c58b37302f284b5617f56a5d959fd1763fb1675ce6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_aarch64.whl", hash = "sha256:66e1674c3ef6f541c35191caae2d429b967b99e02040f5ba928632d9a7f0f065", size = 805272, upload-time = "2025-09-25T21:32:52.941Z" }, + { url = "https://files.pythonhosted.org/packages/da/92/1446574745d74df0c92e6aa4a7b0b3130706a4142b2d1a5869f2eaa423c6/pyyaml-6.0.3-cp314-cp314t-musllinux_1_2_x86_64.whl", hash = "sha256:16249ee61e95f858e83976573de0f5b2893b3677ba71c9dd36b9cf8be9ac6d65", size = 829923, upload-time = "2025-09-25T21:32:54.537Z" }, + { url = "https://files.pythonhosted.org/packages/f0/7a/1c7270340330e575b92f397352af856a8c06f230aa3e76f86b39d01b416a/pyyaml-6.0.3-cp314-cp314t-win_amd64.whl", hash = "sha256:4ad1906908f2f5ae4e5a8ddfce73c320c2a1429ec52eafd27138b7f1cbe341c9", size = 174062, upload-time = "2025-09-25T21:32:55.767Z" }, + { url = "https://files.pythonhosted.org/packages/f1/12/de94a39c2ef588c7e6455cfbe7343d3b2dc9d6b6b2f40c4c6565744c873d/pyyaml-6.0.3-cp314-cp314t-win_arm64.whl", hash = "sha256:ebc55a14a21cb14062aa4162f906cd962b28e2e9ea38f9b4391244cd8de4ae0b", size = 149341, upload-time = "2025-09-25T21:32:56.828Z" }, ] [[package]] @@ -636,28 +663,28 @@ wheels = [ [[package]] name = "ruff" -version = "0.12.11" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/de/55/16ab6a7d88d93001e1ae4c34cbdcfb376652d761799459ff27c1dc20f6fa/ruff-0.12.11.tar.gz", hash = "sha256:c6b09ae8426a65bbee5425b9d0b82796dbb07cb1af045743c79bfb163001165d", size = 5347103, upload-time = "2025-08-28T13:59:08.87Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d6/a2/3b3573e474de39a7a475f3fbaf36a25600bfeb238e1a90392799163b64a0/ruff-0.12.11-py3-none-linux_armv6l.whl", hash = "sha256:93fce71e1cac3a8bf9200e63a38ac5c078f3b6baebffb74ba5274fb2ab276065", size = 11979885, upload-time = "2025-08-28T13:58:26.654Z" }, - { url = "https://files.pythonhosted.org/packages/76/e4/235ad6d1785a2012d3ded2350fd9bc5c5af8c6f56820e696b0118dfe7d24/ruff-0.12.11-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b8e33ac7b28c772440afa80cebb972ffd823621ded90404f29e5ab6d1e2d4b93", size = 12742364, upload-time = "2025-08-28T13:58:30.256Z" }, - { url = "https://files.pythonhosted.org/packages/2c/0d/15b72c5fe6b1e402a543aa9d8960e0a7e19dfb079f5b0b424db48b7febab/ruff-0.12.11-py3-none-macosx_11_0_arm64.whl", hash = "sha256:d69fb9d4937aa19adb2e9f058bc4fbfe986c2040acb1a4a9747734834eaa0bfd", size = 11920111, upload-time = "2025-08-28T13:58:33.677Z" }, - { url = "https://files.pythonhosted.org/packages/3e/c0/f66339d7893798ad3e17fa5a1e587d6fd9806f7c1c062b63f8b09dda6702/ruff-0.12.11-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:411954eca8464595077a93e580e2918d0a01a19317af0a72132283e28ae21bee", size = 12160060, upload-time = "2025-08-28T13:58:35.74Z" }, - { url = "https://files.pythonhosted.org/packages/03/69/9870368326db26f20c946205fb2d0008988aea552dbaec35fbacbb46efaa/ruff-0.12.11-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6a2c0a2e1a450f387bf2c6237c727dd22191ae8c00e448e0672d624b2bbd7fb0", size = 11799848, upload-time = "2025-08-28T13:58:38.051Z" }, - { url = "https://files.pythonhosted.org/packages/25/8c/dd2c7f990e9b3a8a55eee09d4e675027d31727ce33cdb29eab32d025bdc9/ruff-0.12.11-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8ca4c3a7f937725fd2413c0e884b5248a19369ab9bdd850b5781348ba283f644", size = 13536288, upload-time = "2025-08-28T13:58:40.046Z" }, - { url = "https://files.pythonhosted.org/packages/7a/30/d5496fa09aba59b5e01ea76775a4c8897b13055884f56f1c35a4194c2297/ruff-0.12.11-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:4d1df0098124006f6a66ecf3581a7f7e754c4df7644b2e6704cd7ca80ff95211", size = 14490633, upload-time = "2025-08-28T13:58:42.285Z" }, - { url = "https://files.pythonhosted.org/packages/9b/2f/81f998180ad53445d403c386549d6946d0748e536d58fce5b5e173511183/ruff-0.12.11-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5a8dd5f230efc99a24ace3b77e3555d3fbc0343aeed3fc84c8d89e75ab2ff793", size = 13888430, upload-time = "2025-08-28T13:58:44.641Z" }, - { url = "https://files.pythonhosted.org/packages/87/71/23a0d1d5892a377478c61dbbcffe82a3476b050f38b5162171942a029ef3/ruff-0.12.11-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4dc75533039d0ed04cd33fb8ca9ac9620b99672fe7ff1533b6402206901c34ee", size = 12913133, upload-time = "2025-08-28T13:58:47.039Z" }, - { url = "https://files.pythonhosted.org/packages/80/22/3c6cef96627f89b344c933781ed38329bfb87737aa438f15da95907cbfd5/ruff-0.12.11-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4fc58f9266d62c6eccc75261a665f26b4ef64840887fc6cbc552ce5b29f96cc8", size = 13169082, upload-time = "2025-08-28T13:58:49.157Z" }, - { url = "https://files.pythonhosted.org/packages/05/b5/68b3ff96160d8b49e8dd10785ff3186be18fd650d356036a3770386e6c7f/ruff-0.12.11-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:5a0113bd6eafd545146440225fe60b4e9489f59eb5f5f107acd715ba5f0b3d2f", size = 13139490, upload-time = "2025-08-28T13:58:51.593Z" }, - { url = "https://files.pythonhosted.org/packages/59/b9/050a3278ecd558f74f7ee016fbdf10591d50119df8d5f5da45a22c6afafc/ruff-0.12.11-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:0d737b4059d66295c3ea5720e6efc152623bb83fde5444209b69cd33a53e2000", size = 11958928, upload-time = "2025-08-28T13:58:53.943Z" }, - { url = "https://files.pythonhosted.org/packages/f9/bc/93be37347db854806904a43b0493af8d6873472dfb4b4b8cbb27786eb651/ruff-0.12.11-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:916fc5defee32dbc1fc1650b576a8fed68f5e8256e2180d4d9855aea43d6aab2", size = 11764513, upload-time = "2025-08-28T13:58:55.976Z" }, - { url = "https://files.pythonhosted.org/packages/7a/a1/1471751e2015a81fd8e166cd311456c11df74c7e8769d4aabfbc7584c7ac/ruff-0.12.11-py3-none-musllinux_1_2_i686.whl", hash = "sha256:c984f07d7adb42d3ded5be894fb4007f30f82c87559438b4879fe7aa08c62b39", size = 12745154, upload-time = "2025-08-28T13:58:58.16Z" }, - { url = "https://files.pythonhosted.org/packages/68/ab/2542b14890d0f4872dd81b7b2a6aed3ac1786fae1ce9b17e11e6df9e31e3/ruff-0.12.11-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:e07fbb89f2e9249f219d88331c833860489b49cdf4b032b8e4432e9b13e8a4b9", size = 13227653, upload-time = "2025-08-28T13:59:00.276Z" }, - { url = "https://files.pythonhosted.org/packages/22/16/2fbfc61047dbfd009c58a28369a693a1484ad15441723be1cd7fe69bb679/ruff-0.12.11-py3-none-win32.whl", hash = "sha256:c792e8f597c9c756e9bcd4d87cf407a00b60af77078c96f7b6366ea2ce9ba9d3", size = 11944270, upload-time = "2025-08-28T13:59:02.347Z" }, - { url = "https://files.pythonhosted.org/packages/08/a5/34276984705bfe069cd383101c45077ee029c3fe3b28225bf67aa35f0647/ruff-0.12.11-py3-none-win_amd64.whl", hash = "sha256:a3283325960307915b6deb3576b96919ee89432ebd9c48771ca12ee8afe4a0fd", size = 13046600, upload-time = "2025-08-28T13:59:04.751Z" }, - { url = "https://files.pythonhosted.org/packages/84/a8/001d4a7c2b37623a3fd7463208267fb906df40ff31db496157549cfd6e72/ruff-0.12.11-py3-none-win_arm64.whl", hash = "sha256:bae4d6e6a2676f8fb0f98b74594a048bae1b944aab17e9f5d504062303c6dbea", size = 12135290, upload-time = "2025-08-28T13:59:06.933Z" }, +version = "0.13.3" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/c7/8e/f9f9ca747fea8e3ac954e3690d4698c9737c23b51731d02df999c150b1c9/ruff-0.13.3.tar.gz", hash = "sha256:5b0ba0db740eefdfbcce4299f49e9eaefc643d4d007749d77d047c2bab19908e", size = 5438533, upload-time = "2025-10-02T19:29:31.582Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d2/33/8f7163553481466a92656d35dea9331095122bb84cf98210bef597dd2ecd/ruff-0.13.3-py3-none-linux_armv6l.whl", hash = "sha256:311860a4c5e19189c89d035638f500c1e191d283d0cc2f1600c8c80d6dcd430c", size = 12484040, upload-time = "2025-10-02T19:28:49.199Z" }, + { url = "https://files.pythonhosted.org/packages/b0/b5/4a21a4922e5dd6845e91896b0d9ef493574cbe061ef7d00a73c61db531af/ruff-0.13.3-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:2bdad6512fb666b40fcadb65e33add2b040fc18a24997d2e47fee7d66f7fcae2", size = 13122975, upload-time = "2025-10-02T19:28:52.446Z" }, + { url = "https://files.pythonhosted.org/packages/40/90/15649af836d88c9f154e5be87e64ae7d2b1baa5a3ef317cb0c8fafcd882d/ruff-0.13.3-py3-none-macosx_11_0_arm64.whl", hash = "sha256:fc6fa4637284708d6ed4e5e970d52fc3b76a557d7b4e85a53013d9d201d93286", size = 12346621, upload-time = "2025-10-02T19:28:54.712Z" }, + { url = "https://files.pythonhosted.org/packages/a5/42/bcbccb8141305f9a6d3f72549dd82d1134299177cc7eaf832599700f95a7/ruff-0.13.3-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c9e6469864f94a98f412f20ea143d547e4c652f45e44f369d7b74ee78185838", size = 12574408, upload-time = "2025-10-02T19:28:56.679Z" }, + { url = "https://files.pythonhosted.org/packages/ce/19/0f3681c941cdcfa2d110ce4515624c07a964dc315d3100d889fcad3bfc9e/ruff-0.13.3-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5bf62b705f319476c78891e0e97e965b21db468b3c999086de8ffb0d40fd2822", size = 12285330, upload-time = "2025-10-02T19:28:58.79Z" }, + { url = "https://files.pythonhosted.org/packages/10/f8/387976bf00d126b907bbd7725219257feea58650e6b055b29b224d8cb731/ruff-0.13.3-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:78cc1abed87ce40cb07ee0667ce99dbc766c9f519eabfd948ed87295d8737c60", size = 13980815, upload-time = "2025-10-02T19:29:01.577Z" }, + { url = "https://files.pythonhosted.org/packages/0c/a6/7c8ec09d62d5a406e2b17d159e4817b63c945a8b9188a771193b7e1cc0b5/ruff-0.13.3-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:4fb75e7c402d504f7a9a259e0442b96403fa4a7310ffe3588d11d7e170d2b1e3", size = 14987733, upload-time = "2025-10-02T19:29:04.036Z" }, + { url = "https://files.pythonhosted.org/packages/97/e5/f403a60a12258e0fd0c2195341cfa170726f254c788673495d86ab5a9a9d/ruff-0.13.3-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:17b951f9d9afb39330b2bdd2dd144ce1c1335881c277837ac1b50bfd99985ed3", size = 14439848, upload-time = "2025-10-02T19:29:06.684Z" }, + { url = "https://files.pythonhosted.org/packages/39/49/3de381343e89364c2334c9f3268b0349dc734fc18b2d99a302d0935c8345/ruff-0.13.3-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6052f8088728898e0a449f0dde8fafc7ed47e4d878168b211977e3e7e854f662", size = 13421890, upload-time = "2025-10-02T19:29:08.767Z" }, + { url = "https://files.pythonhosted.org/packages/ab/b5/c0feca27d45ae74185a6bacc399f5d8920ab82df2d732a17213fb86a2c4c/ruff-0.13.3-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc742c50f4ba72ce2a3be362bd359aef7d0d302bf7637a6f942eaa763bd292af", size = 13444870, upload-time = "2025-10-02T19:29:11.234Z" }, + { url = "https://files.pythonhosted.org/packages/50/a1/b655298a1f3fda4fdc7340c3f671a4b260b009068fbeb3e4e151e9e3e1bf/ruff-0.13.3-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:8e5640349493b378431637019366bbd73c927e515c9c1babfea3e932f5e68e1d", size = 13691599, upload-time = "2025-10-02T19:29:13.353Z" }, + { url = "https://files.pythonhosted.org/packages/32/b0/a8705065b2dafae007bcae21354e6e2e832e03eb077bb6c8e523c2becb92/ruff-0.13.3-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:6b139f638a80eae7073c691a5dd8d581e0ba319540be97c343d60fb12949c8d0", size = 12421893, upload-time = "2025-10-02T19:29:15.668Z" }, + { url = "https://files.pythonhosted.org/packages/0d/1e/cbe7082588d025cddbb2f23e6dfef08b1a2ef6d6f8328584ad3015b5cebd/ruff-0.13.3-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:6b547def0a40054825de7cfa341039ebdfa51f3d4bfa6a0772940ed351d2746c", size = 12267220, upload-time = "2025-10-02T19:29:17.583Z" }, + { url = "https://files.pythonhosted.org/packages/a5/99/4086f9c43f85e0755996d09bdcb334b6fee9b1eabdf34e7d8b877fadf964/ruff-0.13.3-py3-none-musllinux_1_2_i686.whl", hash = "sha256:9cc48a3564423915c93573f1981d57d101e617839bef38504f85f3677b3a0a3e", size = 13177818, upload-time = "2025-10-02T19:29:19.943Z" }, + { url = "https://files.pythonhosted.org/packages/9b/de/7b5db7e39947d9dc1c5f9f17b838ad6e680527d45288eeb568e860467010/ruff-0.13.3-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:1a993b17ec03719c502881cb2d5f91771e8742f2ca6de740034433a97c561989", size = 13618715, upload-time = "2025-10-02T19:29:22.527Z" }, + { url = "https://files.pythonhosted.org/packages/28/d3/bb25ee567ce2f61ac52430cf99f446b0e6d49bdfa4188699ad005fdd16aa/ruff-0.13.3-py3-none-win32.whl", hash = "sha256:f14e0d1fe6460f07814d03c6e32e815bff411505178a1f539a38f6097d3e8ee3", size = 12334488, upload-time = "2025-10-02T19:29:24.782Z" }, + { url = "https://files.pythonhosted.org/packages/cf/49/12f5955818a1139eed288753479ba9d996f6ea0b101784bb1fe6977ec128/ruff-0.13.3-py3-none-win_amd64.whl", hash = "sha256:621e2e5812b691d4f244638d693e640f188bacbb9bc793ddd46837cea0503dd2", size = 13455262, upload-time = "2025-10-02T19:29:26.882Z" }, + { url = "https://files.pythonhosted.org/packages/fe/72/7b83242b26627a00e3af70d0394d68f8f02750d642567af12983031777fc/ruff-0.13.3-py3-none-win_arm64.whl", hash = "sha256:9e9e9d699841eaf4c2c798fa783df2fabc680b72059a02ca0ed81c460bc58330", size = 12538484, upload-time = "2025-10-02T19:29:28.951Z" }, ] [[package]] @@ -689,27 +716,27 @@ wheels = [ [[package]] name = "ty" -version = "0.0.1a19" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/c0/04/281c1a3c9c53dae5826b9d01a3412de653e3caf1ca50ce1265da66e06d73/ty-0.0.1a19.tar.gz", hash = "sha256:894f6a13a43989c8ef891ae079b3b60a0c0eae00244abbfbbe498a3840a235ac", size = 4098412, upload-time = "2025-08-19T13:29:58.559Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/3e/65/a61cfcc7248b0257a3110bf98d3d910a4729c1063abdbfdcd1cad9012323/ty-0.0.1a19-py3-none-linux_armv6l.whl", hash = "sha256:e0e7762f040f4bab1b37c57cb1b43cc3bc5afb703fa5d916dfcafa2ef885190e", size = 8143744, upload-time = "2025-08-19T13:29:13.88Z" }, - { url = "https://files.pythonhosted.org/packages/02/d9/232afef97d9afa2274d23a4c49a3ad690282ca9696e1b6bbb6e4e9a1b072/ty-0.0.1a19-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:cd0a67ac875f49f34d9a0b42dcabf4724194558a5dd36867209d5695c67768f7", size = 8305799, upload-time = "2025-08-19T13:29:17.322Z" }, - { url = "https://files.pythonhosted.org/packages/20/14/099d268da7a9cccc6ba38dfc124f6742a1d669bc91f2c61a3465672b4f71/ty-0.0.1a19-py3-none-macosx_11_0_arm64.whl", hash = "sha256:ff8b1c0b85137333c39eccd96c42603af8ba7234d6e2ed0877f66a4a26750dd4", size = 7901431, upload-time = "2025-08-19T13:29:21.635Z" }, - { url = "https://files.pythonhosted.org/packages/c2/cd/3f1ca6e1d7f77cc4d08910a3fc4826313c031c0aae72286ae859e737670c/ty-0.0.1a19-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4fef34a29f4b97d78aa30e60adbbb12137cf52b8b2b0f1a408dd0feb0466908a", size = 8051501, upload-time = "2025-08-19T13:29:23.741Z" }, - { url = "https://files.pythonhosted.org/packages/47/72/ddbec39f48ce3f5f6a3fa1f905c8fff2873e59d2030f738814032bd783e3/ty-0.0.1a19-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b0f219cb43c0c50fc1091f8ebd5548d3ef31ee57866517b9521d5174978af9fd", size = 7981234, upload-time = "2025-08-19T13:29:25.839Z" }, - { url = "https://files.pythonhosted.org/packages/f2/0f/58e76b8d4634df066c790d362e8e73b25852279cd6f817f099b42a555a66/ty-0.0.1a19-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:22abb6c1f14c65c1a2fafd38e25dd3c87994b3ab88cb0b323235b51dbad082d9", size = 8916394, upload-time = "2025-08-19T13:29:27.932Z" }, - { url = "https://files.pythonhosted.org/packages/70/30/01bfd93ccde11540b503e2539e55f6a1fc6e12433a229191e248946eb753/ty-0.0.1a19-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:5b49225c349a3866e38dd297cb023a92d084aec0e895ed30ca124704bff600e6", size = 9412024, upload-time = "2025-08-19T13:29:30.942Z" }, - { url = "https://files.pythonhosted.org/packages/a8/a2/2216d752f5f22c5c0995f9b13f18337301220f2a7d952c972b33e6a63583/ty-0.0.1a19-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:88f41728b3b07402e0861e3c34412ca963268e55f6ab1690208f25d37cb9d63c", size = 9032657, upload-time = "2025-08-19T13:29:33.933Z" }, - { url = "https://files.pythonhosted.org/packages/24/c7/e6650b0569be1b69a03869503d07420c9fb3e90c9109b09726c44366ce63/ty-0.0.1a19-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:33814a1197ec3e930fcfba6fb80969fe7353957087b42b88059f27a173f7510b", size = 8812775, upload-time = "2025-08-19T13:29:36.505Z" }, - { url = "https://files.pythonhosted.org/packages/35/c6/b8a20e06b97fe8203059d56d8f91cec4f9633e7ba65f413d80f16aa0be04/ty-0.0.1a19-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d71b7f2b674a287258f628acafeecd87691b169522945ff6192cd8a69af15857", size = 8631417, upload-time = "2025-08-19T13:29:38.837Z" }, - { url = "https://files.pythonhosted.org/packages/be/99/821ca1581dcf3d58ffb7bbe1cde7e1644dbdf53db34603a16a459a0b302c/ty-0.0.1a19-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:3a7f8ef9ac4c38e8651c18c7380649c5a3fa9adb1a6012c721c11f4bbdc0ce24", size = 7928900, upload-time = "2025-08-19T13:29:41.08Z" }, - { url = "https://files.pythonhosted.org/packages/08/cb/59f74a0522e57565fef99e2287b2bc803ee47ff7dac250af26960636939f/ty-0.0.1a19-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:60f40e72f0fbf4e54aa83d9a6cb1959f551f83de73af96abbb94711c1546bd60", size = 8003310, upload-time = "2025-08-19T13:29:43.165Z" }, - { url = "https://files.pythonhosted.org/packages/4c/b3/1209b9acb5af00a2755114042e48fb0f71decc20d9d77a987bf5b3d1a102/ty-0.0.1a19-py3-none-musllinux_1_2_i686.whl", hash = "sha256:64971e4d3e3f83dc79deb606cc438255146cab1ab74f783f7507f49f9346d89d", size = 8496463, upload-time = "2025-08-19T13:29:46.136Z" }, - { url = "https://files.pythonhosted.org/packages/a2/d6/a4b6ba552d347a08196d83a4d60cb23460404a053dd3596e23a922bce544/ty-0.0.1a19-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:9aadbff487e2e1486e83543b4f4c2165557f17432369f419be9ba48dc47625ca", size = 8700633, upload-time = "2025-08-19T13:29:49.351Z" }, - { url = "https://files.pythonhosted.org/packages/96/c5/258f318d68b95685c8d98fb654a38882c9d01ce5d9426bed06124f690f04/ty-0.0.1a19-py3-none-win32.whl", hash = "sha256:00b75b446357ee22bcdeb837cb019dc3bc1dc5e5013ff0f46a22dfe6ce498fe2", size = 7811441, upload-time = "2025-08-19T13:29:52.077Z" }, - { url = "https://files.pythonhosted.org/packages/fb/bb/039227eee3c0c0cddc25f45031eea0f7f10440713f12d333f2f29cf8e934/ty-0.0.1a19-py3-none-win_amd64.whl", hash = "sha256:aaef76b2f44f6379c47adfe58286f0c56041cb2e374fd8462ae8368788634469", size = 8441186, upload-time = "2025-08-19T13:29:54.53Z" }, - { url = "https://files.pythonhosted.org/packages/74/5f/bceb29009670ae6f759340f9cb434121bc5ed84ad0f07bdc6179eaaa3204/ty-0.0.1a19-py3-none-win_arm64.whl", hash = "sha256:893755bb35f30653deb28865707e3b16907375c830546def2741f6ff9a764710", size = 8000810, upload-time = "2025-08-19T13:29:56.796Z" }, +version = "0.0.1a21" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b7/0f/65606ccee2da5a05a3c3362f5233f058e9d29d3c5521697c7ae79545d246/ty-0.0.1a21.tar.gz", hash = "sha256:e941e9a9d1e54b03eeaf9c3197c26a19cf76009fd5e41e16e5657c1c827bd6d3", size = 4263980, upload-time = "2025-09-19T06:54:06.412Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d3/7a/c87a42d0a45cfa2d5c06c8d66aa1b243db16dc31b25e545fb0263308523b/ty-0.0.1a21-py3-none-linux_armv6l.whl", hash = "sha256:1f276ceab23a1410aec09508248c76ae0989c67fb7a0c287e0d4564994295531", size = 8421116, upload-time = "2025-09-19T06:53:35.029Z" }, + { url = "https://files.pythonhosted.org/packages/99/c2/721bf4fa21c84d4cdae0e57a06a88e7e64fc2dca38820232bd6cbeef644f/ty-0.0.1a21-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3c3bc66fcae41eff133cfe326dd65d82567a2fb5d4efe2128773b10ec2766819", size = 8512556, upload-time = "2025-09-19T06:53:37.455Z" }, + { url = "https://files.pythonhosted.org/packages/6c/58/b0585d9d61673e864a87e95760dfa2a90ac15702e7612ab064d354f6752a/ty-0.0.1a21-py3-none-macosx_11_0_arm64.whl", hash = "sha256:cc0880ec344fbdf736b05d8d0da01f0caaaa02409bd9a24b68d18d0127a79b0e", size = 8109188, upload-time = "2025-09-19T06:53:39.469Z" }, + { url = "https://files.pythonhosted.org/packages/ea/08/edf7b59ba24bb1a1af341207fc5a0106eb1fe4264c1d7fb672c171dd2daf/ty-0.0.1a21-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:334d2a212ebf42a0e55d57561926af7679fe1e878175e11dcb81ad8df892844e", size = 8279000, upload-time = "2025-09-19T06:53:41.309Z" }, + { url = "https://files.pythonhosted.org/packages/05/8e/4b5e562623e0aa24a3972510287b4bc5d98251afb353388d14008ea99954/ty-0.0.1a21-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a8c769987d00fbc33054ff7e342633f475ea10dc43bc60fb9fb056159d48cb90", size = 8243261, upload-time = "2025-09-19T06:53:42.736Z" }, + { url = "https://files.pythonhosted.org/packages/c3/09/6476fa21f9962d5b9c8e8053fd0442ed8e3ceb7502e39700ab1935555199/ty-0.0.1a21-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:218d53e7919e885bd98e9196d9cb952d82178b299aa36da6f7f39333eb7400ed", size = 9150228, upload-time = "2025-09-19T06:53:44.242Z" }, + { url = "https://files.pythonhosted.org/packages/d2/96/49c158b6255fc1e22a5701c38f7d4c1b7f8be17a476ce9226fcae82a7b36/ty-0.0.1a21-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:84243455f295ed850bd53f7089819321807d4e6ee3b1cbff6086137ae0259466", size = 9628323, upload-time = "2025-09-19T06:53:45.998Z" }, + { url = "https://files.pythonhosted.org/packages/f4/65/37a8a5cb7b3254365c54b5e10f069e311c4252ed160b86fabd1203fbca5c/ty-0.0.1a21-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:87a200c21e02962e8a27374d9d152582331d57d709672431be58f4f898bf6cad", size = 9251233, upload-time = "2025-09-19T06:53:48.042Z" }, + { url = "https://files.pythonhosted.org/packages/a3/30/5b06120747da4a0f0bc54a4b051b42172603033dbee0bcf51bce7c21ada9/ty-0.0.1a21-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:be8f457d7841b7ead2a3f6b65ba668abc172a1150a0f1f6c0958af3725dbb61a", size = 8996186, upload-time = "2025-09-19T06:53:49.753Z" }, + { url = "https://files.pythonhosted.org/packages/af/fc/5aa122536b1acb57389f404f6328c20342242b78513a60459fee9b7d6f27/ty-0.0.1a21-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1474d883129bb63da3b2380fc7ead824cd3baf6a9551e6aa476ffefc58057af3", size = 8722848, upload-time = "2025-09-19T06:53:51.566Z" }, + { url = "https://files.pythonhosted.org/packages/3a/c1/456dcc65a149df8410b1d75f0197a31d4beef74b7bb44cce42b03bf074e8/ty-0.0.1a21-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:0efba2e52b58f536f4198ba5c4a36cac2ba67d83ec6f429ebc7704233bcda4c3", size = 8220727, upload-time = "2025-09-19T06:53:53.753Z" }, + { url = "https://files.pythonhosted.org/packages/a4/86/b37505d942cd68235be5be407e43e15afa36669aaa2db9b6e5b43c1d9f91/ty-0.0.1a21-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:5dfc73299d441cc6454e36ed0a976877415024143dfca6592dc36f7701424383", size = 8279114, upload-time = "2025-09-19T06:53:55.343Z" }, + { url = "https://files.pythonhosted.org/packages/55/fe/0d9816f36d258e6b2a3d7518421be17c68954ea9a66b638de49588cc2e27/ty-0.0.1a21-py3-none-musllinux_1_2_i686.whl", hash = "sha256:ba13d03b9e095216ceb4e4d554a308517f28ab0a6e4dcd07cfe94563e4c2c489", size = 8701798, upload-time = "2025-09-19T06:53:57.17Z" }, + { url = "https://files.pythonhosted.org/packages/4e/7a/70539932e3e5a36c54bd5432ff44ed0c301c41a528365d8de5b8f79f4317/ty-0.0.1a21-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:9463cac96b8f1bb5ba740fe1d42cd6bd152b43c5b159b2f07f8fd629bcdded34", size = 8872676, upload-time = "2025-09-19T06:53:59.357Z" }, + { url = "https://files.pythonhosted.org/packages/ea/94/809d85f6982841fe28526ace3b282b0458d0a96bbc6b1a982d9269a5e481/ty-0.0.1a21-py3-none-win32.whl", hash = "sha256:ecf41706b803827b0de8717f32a434dad1e67be9f4b8caf403e12013179ea06a", size = 8003866, upload-time = "2025-09-19T06:54:01.393Z" }, + { url = "https://files.pythonhosted.org/packages/50/16/b3e914cec2a6344d2c30d3780ca6ecd39667173611f8776cecfd1294eab9/ty-0.0.1a21-py3-none-win_amd64.whl", hash = "sha256:7505aeb8bf2a62f00f12cfa496f6c965074d75c8126268776565284c8a12d5dd", size = 8675300, upload-time = "2025-09-19T06:54:02.893Z" }, + { url = "https://files.pythonhosted.org/packages/16/0b/293be6bc19f6da5e9b15e615a7100504f307dd4294d2c61cee3de91198e5/ty-0.0.1a21-py3-none-win_arm64.whl", hash = "sha256:21f708d02b6588323ffdbfdba38830dd0ecfd626db50aa6006b296b5470e52f9", size = 8193800, upload-time = "2025-09-19T06:54:04.583Z" }, ] [[package]] @@ -723,14 +750,14 @@ wheels = [ [[package]] name = "typing-inspection" -version = "0.4.1" +version = "0.4.2" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "typing-extensions" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/f8/b1/0c11f5058406b3af7609f121aaa6b609744687f1d158b3c3a5bf4cc94238/typing_inspection-0.4.1.tar.gz", hash = "sha256:6ae134cc0203c33377d43188d4064e9b357dba58cff3185f22924610e70a9d28", size = 75726, upload-time = "2025-05-21T18:55:23.885Z" } +sdist = { url = "https://files.pythonhosted.org/packages/55/e3/70399cb7dd41c10ac53367ae42139cf4b1ca5f36bb3dc6c9d33acdb43655/typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464", size = 75949, upload-time = "2025-10-01T02:14:41.687Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/17/69/cd203477f944c353c31bade965f880aa1061fd6bf05ded0726ca845b6ff7/typing_inspection-0.4.1-py3-none-any.whl", hash = "sha256:389055682238f53b04f7badcb49b989835495a96700ced5dab2d8feae4b26f51", size = 14552, upload-time = "2025-05-21T18:55:22.152Z" }, + { url = "https://files.pythonhosted.org/packages/dc/9b/47798a6c91d8bdb567fe2698fe81e0c6b7cb7ef4d13da4114b41d239f65d/typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7", size = 14611, upload-time = "2025-10-01T02:14:40.154Z" }, ] [[package]] diff --git a/uv.lock b/uv.lock deleted file mode 100644 index 2d4ede6..0000000 --- a/uv.lock +++ /dev/null @@ -1,532 +0,0 @@ -version = 1 -revision = 3 -requires-python = ">=3.13" - -[[package]] -name = "babel" -version = "2.17.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/7d/6b/d52e42361e1aa00709585ecc30b3f9684b3ab62530771402248b1b1d6240/babel-2.17.0.tar.gz", hash = "sha256:0c54cffb19f690cdcc52a3b50bcbf71e07a808d1c80d549f2459b9d2cf0afb9d", size = 9951852, upload-time = "2025-02-01T15:17:41.026Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/b8/3fe70c75fe32afc4bb507f75563d39bc5642255d1d94f1f23604725780bf/babel-2.17.0-py3-none-any.whl", hash = "sha256:4d0b53093fdfb4b21c92b5213dba5a1b23885afa8383709427046b21c366e5f2", size = 10182537, upload-time = "2025-02-01T15:17:37.39Z" }, -] - -[[package]] -name = "backrefs" -version = "5.9" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/eb/a7/312f673df6a79003279e1f55619abbe7daebbb87c17c976ddc0345c04c7b/backrefs-5.9.tar.gz", hash = "sha256:808548cb708d66b82ee231f962cb36faaf4f2baab032f2fbb783e9c2fdddaa59", size = 5765857, upload-time = "2025-06-22T19:34:13.97Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/19/4d/798dc1f30468134906575156c089c492cf79b5a5fd373f07fe26c4d046bf/backrefs-5.9-py310-none-any.whl", hash = "sha256:db8e8ba0e9de81fcd635f440deab5ae5f2591b54ac1ebe0550a2ca063488cd9f", size = 380267, upload-time = "2025-06-22T19:34:05.252Z" }, - { url = "https://files.pythonhosted.org/packages/55/07/f0b3375bf0d06014e9787797e6b7cc02b38ac9ff9726ccfe834d94e9991e/backrefs-5.9-py311-none-any.whl", hash = "sha256:6907635edebbe9b2dc3de3a2befff44d74f30a4562adbb8b36f21252ea19c5cf", size = 392072, upload-time = "2025-06-22T19:34:06.743Z" }, - { url = "https://files.pythonhosted.org/packages/9d/12/4f345407259dd60a0997107758ba3f221cf89a9b5a0f8ed5b961aef97253/backrefs-5.9-py312-none-any.whl", hash = "sha256:7fdf9771f63e6028d7fee7e0c497c81abda597ea45d6b8f89e8ad76994f5befa", size = 397947, upload-time = "2025-06-22T19:34:08.172Z" }, - { url = "https://files.pythonhosted.org/packages/10/bf/fa31834dc27a7f05e5290eae47c82690edc3a7b37d58f7fb35a1bdbf355b/backrefs-5.9-py313-none-any.whl", hash = "sha256:cc37b19fa219e93ff825ed1fed8879e47b4d89aa7a1884860e2db64ccd7c676b", size = 399843, upload-time = "2025-06-22T19:34:09.68Z" }, - { url = "https://files.pythonhosted.org/packages/fc/24/b29af34b2c9c41645a9f4ff117bae860291780d73880f449e0b5d948c070/backrefs-5.9-py314-none-any.whl", hash = "sha256:df5e169836cc8acb5e440ebae9aad4bf9d15e226d3bad049cf3f6a5c20cc8dc9", size = 411762, upload-time = "2025-06-22T19:34:11.037Z" }, - { url = "https://files.pythonhosted.org/packages/41/ff/392bff89415399a979be4a65357a41d92729ae8580a66073d8ec8d810f98/backrefs-5.9-py39-none-any.whl", hash = "sha256:f48ee18f6252b8f5777a22a00a09a85de0ca931658f1dd96d4406a34f3748c60", size = 380265, upload-time = "2025-06-22T19:34:12.405Z" }, -] - -[[package]] -name = "certifi" -version = "2025.8.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/dc/67/960ebe6bf230a96cda2e0abcf73af550ec4f090005363542f0765df162e0/certifi-2025.8.3.tar.gz", hash = "sha256:e564105f78ded564e3ae7c923924435e1daa7463faeab5bb932bc53ffae63407", size = 162386, upload-time = "2025-08-03T03:07:47.08Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e5/48/1549795ba7742c948d2ad169c1c8cdbae65bc450d6cd753d124b17c8cd32/certifi-2025.8.3-py3-none-any.whl", hash = "sha256:f6c12493cfb1b06ba2ff328595af9350c65d6644968e5d3a2ffd78699af217a5", size = 161216, upload-time = "2025-08-03T03:07:45.777Z" }, -] - -[[package]] -name = "charset-normalizer" -version = "3.4.3" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/83/2d/5fd176ceb9b2fc619e63405525573493ca23441330fcdaee6bef9460e924/charset_normalizer-3.4.3.tar.gz", hash = "sha256:6fce4b8500244f6fcb71465d4a4930d132ba9ab8e71a7859e6a5d59851068d14", size = 122371, upload-time = "2025-08-09T07:57:28.46Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/65/ca/2135ac97709b400c7654b4b764daf5c5567c2da45a30cdd20f9eefe2d658/charset_normalizer-3.4.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:14c2a87c65b351109f6abfc424cab3927b3bdece6f706e4d12faaf3d52ee5efe", size = 205326, upload-time = "2025-08-09T07:56:24.721Z" }, - { url = "https://files.pythonhosted.org/packages/71/11/98a04c3c97dd34e49c7d247083af03645ca3730809a5509443f3c37f7c99/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:41d1fc408ff5fdfb910200ec0e74abc40387bccb3252f3f27c0676731df2b2c8", size = 146008, upload-time = "2025-08-09T07:56:26.004Z" }, - { url = "https://files.pythonhosted.org/packages/60/f5/4659a4cb3c4ec146bec80c32d8bb16033752574c20b1252ee842a95d1a1e/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:1bb60174149316da1c35fa5233681f7c0f9f514509b8e399ab70fea5f17e45c9", size = 159196, upload-time = "2025-08-09T07:56:27.25Z" }, - { url = "https://files.pythonhosted.org/packages/86/9e/f552f7a00611f168b9a5865a1414179b2c6de8235a4fa40189f6f79a1753/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:30d006f98569de3459c2fc1f2acde170b7b2bd265dc1943e87e1a4efe1b67c31", size = 156819, upload-time = "2025-08-09T07:56:28.515Z" }, - { url = "https://files.pythonhosted.org/packages/7e/95/42aa2156235cbc8fa61208aded06ef46111c4d3f0de233107b3f38631803/charset_normalizer-3.4.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:416175faf02e4b0810f1f38bcb54682878a4af94059a1cd63b8747244420801f", size = 151350, upload-time = "2025-08-09T07:56:29.716Z" }, - { url = "https://files.pythonhosted.org/packages/c2/a9/3865b02c56f300a6f94fc631ef54f0a8a29da74fb45a773dfd3dcd380af7/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:6aab0f181c486f973bc7262a97f5aca3ee7e1437011ef0c2ec04b5a11d16c927", size = 148644, upload-time = "2025-08-09T07:56:30.984Z" }, - { url = "https://files.pythonhosted.org/packages/77/d9/cbcf1a2a5c7d7856f11e7ac2d782aec12bdfea60d104e60e0aa1c97849dc/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:fdabf8315679312cfa71302f9bd509ded4f2f263fb5b765cf1433b39106c3cc9", size = 160468, upload-time = "2025-08-09T07:56:32.252Z" }, - { url = "https://files.pythonhosted.org/packages/f6/42/6f45efee8697b89fda4d50580f292b8f7f9306cb2971d4b53f8914e4d890/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:bd28b817ea8c70215401f657edef3a8aa83c29d447fb0b622c35403780ba11d5", size = 158187, upload-time = "2025-08-09T07:56:33.481Z" }, - { url = "https://files.pythonhosted.org/packages/70/99/f1c3bdcfaa9c45b3ce96f70b14f070411366fa19549c1d4832c935d8e2c3/charset_normalizer-3.4.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:18343b2d246dc6761a249ba1fb13f9ee9a2bcd95decc767319506056ea4ad4dc", size = 152699, upload-time = "2025-08-09T07:56:34.739Z" }, - { url = "https://files.pythonhosted.org/packages/a3/ad/b0081f2f99a4b194bcbb1934ef3b12aa4d9702ced80a37026b7607c72e58/charset_normalizer-3.4.3-cp313-cp313-win32.whl", hash = "sha256:6fb70de56f1859a3f71261cbe41005f56a7842cc348d3aeb26237560bfa5e0ce", size = 99580, upload-time = "2025-08-09T07:56:35.981Z" }, - { url = "https://files.pythonhosted.org/packages/9a/8f/ae790790c7b64f925e5c953b924aaa42a243fb778fed9e41f147b2a5715a/charset_normalizer-3.4.3-cp313-cp313-win_amd64.whl", hash = "sha256:cf1ebb7d78e1ad8ec2a8c4732c7be2e736f6e5123a4146c5b89c9d1f585f8cef", size = 107366, upload-time = "2025-08-09T07:56:37.339Z" }, - { url = "https://files.pythonhosted.org/packages/8e/91/b5a06ad970ddc7a0e513112d40113e834638f4ca1120eb727a249fb2715e/charset_normalizer-3.4.3-cp314-cp314-macosx_10_13_universal2.whl", hash = "sha256:3cd35b7e8aedeb9e34c41385fda4f73ba609e561faedfae0a9e75e44ac558a15", size = 204342, upload-time = "2025-08-09T07:56:38.687Z" }, - { url = "https://files.pythonhosted.org/packages/ce/ec/1edc30a377f0a02689342f214455c3f6c2fbedd896a1d2f856c002fc3062/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b89bc04de1d83006373429975f8ef9e7932534b8cc9ca582e4db7d20d91816db", size = 145995, upload-time = "2025-08-09T07:56:40.048Z" }, - { url = "https://files.pythonhosted.org/packages/17/e5/5e67ab85e6d22b04641acb5399c8684f4d37caf7558a53859f0283a650e9/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:2001a39612b241dae17b4687898843f254f8748b796a2e16f1051a17078d991d", size = 158640, upload-time = "2025-08-09T07:56:41.311Z" }, - { url = "https://files.pythonhosted.org/packages/f1/e5/38421987f6c697ee3722981289d554957c4be652f963d71c5e46a262e135/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:8dcfc373f888e4fb39a7bc57e93e3b845e7f462dacc008d9749568b1c4ece096", size = 156636, upload-time = "2025-08-09T07:56:43.195Z" }, - { url = "https://files.pythonhosted.org/packages/a0/e4/5a075de8daa3ec0745a9a3b54467e0c2967daaaf2cec04c845f73493e9a1/charset_normalizer-3.4.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:18b97b8404387b96cdbd30ad660f6407799126d26a39ca65729162fd810a99aa", size = 150939, upload-time = "2025-08-09T07:56:44.819Z" }, - { url = "https://files.pythonhosted.org/packages/02/f7/3611b32318b30974131db62b4043f335861d4d9b49adc6d57c1149cc49d4/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:ccf600859c183d70eb47e05a44cd80a4ce77394d1ac0f79dbd2dd90a69a3a049", size = 148580, upload-time = "2025-08-09T07:56:46.684Z" }, - { url = "https://files.pythonhosted.org/packages/7e/61/19b36f4bd67f2793ab6a99b979b4e4f3d8fc754cbdffb805335df4337126/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_ppc64le.whl", hash = "sha256:53cd68b185d98dde4ad8990e56a58dea83a4162161b1ea9272e5c9182ce415e0", size = 159870, upload-time = "2025-08-09T07:56:47.941Z" }, - { url = "https://files.pythonhosted.org/packages/06/57/84722eefdd338c04cf3030ada66889298eaedf3e7a30a624201e0cbe424a/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_s390x.whl", hash = "sha256:30a96e1e1f865f78b030d65241c1ee850cdf422d869e9028e2fc1d5e4db73b92", size = 157797, upload-time = "2025-08-09T07:56:49.756Z" }, - { url = "https://files.pythonhosted.org/packages/72/2a/aff5dd112b2f14bcc3462c312dce5445806bfc8ab3a7328555da95330e4b/charset_normalizer-3.4.3-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:d716a916938e03231e86e43782ca7878fb602a125a91e7acb8b5112e2e96ac16", size = 152224, upload-time = "2025-08-09T07:56:51.369Z" }, - { url = "https://files.pythonhosted.org/packages/b7/8c/9839225320046ed279c6e839d51f028342eb77c91c89b8ef2549f951f3ec/charset_normalizer-3.4.3-cp314-cp314-win32.whl", hash = "sha256:c6dbd0ccdda3a2ba7c2ecd9d77b37f3b5831687d8dc1b6ca5f56a4880cc7b7ce", size = 100086, upload-time = "2025-08-09T07:56:52.722Z" }, - { url = "https://files.pythonhosted.org/packages/ee/7a/36fbcf646e41f710ce0a563c1c9a343c6edf9be80786edeb15b6f62e17db/charset_normalizer-3.4.3-cp314-cp314-win_amd64.whl", hash = "sha256:73dc19b562516fc9bcf6e5d6e596df0b4eb98d87e4f79f3ae71840e6ed21361c", size = 107400, upload-time = "2025-08-09T07:56:55.172Z" }, - { url = "https://files.pythonhosted.org/packages/8a/1f/f041989e93b001bc4e44bb1669ccdcf54d3f00e628229a85b08d330615c5/charset_normalizer-3.4.3-py3-none-any.whl", hash = "sha256:ce571ab16d890d23b5c278547ba694193a45011ff86a9162a71307ed9f86759a", size = 53175, upload-time = "2025-08-09T07:57:26.864Z" }, -] - -[[package]] -name = "click" -version = "8.2.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "colorama", marker = "sys_platform == 'win32'" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/60/6c/8ca2efa64cf75a977a0d7fac081354553ebe483345c734fb6b6515d96bbc/click-8.2.1.tar.gz", hash = "sha256:27c491cc05d968d271d5a1db13e3b5a184636d9d930f148c50b038f0d0646202", size = 286342, upload-time = "2025-05-20T23:19:49.832Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/85/32/10bb5764d90a8eee674e9dc6f4db6a0ab47c8c4d0d83c27f7c39ac415a4d/click-8.2.1-py3-none-any.whl", hash = "sha256:61a3265b914e850b85317d0b3109c7f8cd35a670f963866005d6ef1d5175a12b", size = 102215, upload-time = "2025-05-20T23:19:47.796Z" }, -] - -[[package]] -name = "colorama" -version = "0.4.6" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697, upload-time = "2022-10-25T02:36:22.414Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335, upload-time = "2022-10-25T02:36:20.889Z" }, -] - -[[package]] -name = "fieldz" -version = "0.1.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "typing-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/90/62/698c5cc2e7d4c8c89e63033e2e9d3c74902a1bf28782712eacb0653097ce/fieldz-0.1.2.tar.gz", hash = "sha256:0448ed5dacb13eaa49da0db786e87fae298fbd2652d26c510e5d7aea6b6bebf4", size = 17277, upload-time = "2025-06-30T18:06:40.881Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/6d/8c/8958392cade27a272daf45d09a08473073dedeccad94b097dfeb898d969f/fieldz-0.1.2-py3-none-any.whl", hash = "sha256:e25884d2821a2d5638ef8d4d8bce5d1039359cfcb46d0f93df8cb1f7c2eb3a2e", size = 17878, upload-time = "2025-06-30T18:06:39.322Z" }, -] - -[[package]] -name = "ghp-import" -version = "2.1.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "python-dateutil" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/d9/29/d40217cbe2f6b1359e00c6c307bb3fc876ba74068cbab3dde77f03ca0dc4/ghp-import-2.1.0.tar.gz", hash = "sha256:9c535c4c61193c2df8871222567d7fd7e5014d835f97dc7b7439069e2413d343", size = 10943, upload-time = "2022-05-02T15:47:16.11Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/f7/ec/67fbef5d497f86283db54c22eec6f6140243aae73265799baaaa19cd17fb/ghp_import-2.1.0-py3-none-any.whl", hash = "sha256:8337dd7b50877f163d4c0289bc1f1c7f127550241988d568c1db512c4324a619", size = 11034, upload-time = "2022-05-02T15:47:14.552Z" }, -] - -[[package]] -name = "griffe" -version = "1.13.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "colorama" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/c6/b5/23b91f22b7b3a7f8f62223f6664946271c0f5cb4179605a3e6bbae863920/griffe-1.13.0.tar.gz", hash = "sha256:246ea436a5e78f7fbf5f24ca8a727bb4d2a4b442a2959052eea3d0bfe9a076e0", size = 412759, upload-time = "2025-08-26T13:27:11.422Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/aa/8c/b7cfdd8dfe48f6b09f7353323732e1a290c388bd14f216947928dc85f904/griffe-1.13.0-py3-none-any.whl", hash = "sha256:470fde5b735625ac0a36296cd194617f039e9e83e301fcbd493e2b58382d0559", size = 139365, upload-time = "2025-08-26T13:27:09.882Z" }, -] - -[[package]] -name = "griffe-fieldz" -version = "0.3.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "fieldz" }, - { name = "griffe" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/c5/6a/94754bf39fd63ba424c667b2abf0ade78e3878e223591d1fb9c3e8a77bce/griffe_fieldz-0.3.0.tar.gz", hash = "sha256:42e7707dac51d38e26fb7f3f7f51429da9b47e98060bfeb81a4287456d5b8a89", size = 10149, upload-time = "2025-07-30T21:43:10.042Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/4d/33/cc527c11132a6274724a04938d50e1ff2b54a5f5943cd0480427571e1adb/griffe_fieldz-0.3.0-py3-none-any.whl", hash = "sha256:52e02fdcbdf6dea3c8c95756d1e0b30861569f871d19437fda702776fde4e64d", size = 6577, upload-time = "2025-07-30T21:43:09.073Z" }, -] - -[[package]] -name = "griffe-pydantic" -version = "1.1.6" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "griffe" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/ff/0a/61b2fa8abe04208682bcdb9fba3ae61b1ba879fd17be9e523622f1aa9afb/griffe_pydantic-1.1.6.tar.gz", hash = "sha256:d33413bf44b01b2f9348ea3328fdfe34ad7b2aabb4005a18d36cc0ca0ade908e", size = 42613, upload-time = "2025-08-06T09:30:57.796Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/7b/03/699f059a54b7873a11bf53389236c06640bf47be590aa87a521d7c4bb044/griffe_pydantic-1.1.6-py3-none-any.whl", hash = "sha256:57a838dd1c3b5842a7ebada8fd80f2585a25b69c37f73ede19ca20fa9af055e6", size = 12671, upload-time = "2025-08-06T09:30:56.616Z" }, -] - -[[package]] -name = "idna" -version = "3.10" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490, upload-time = "2024-09-15T18:07:39.745Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442, upload-time = "2024-09-15T18:07:37.964Z" }, -] - -[[package]] -name = "jinja2" -version = "3.1.6" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "markupsafe" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/df/bf/f7da0350254c0ed7c72f3e33cef02e048281fec7ecec5f032d4aac52226b/jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d", size = 245115, upload-time = "2025-03-05T20:05:02.478Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/62/a1/3d680cbfd5f4b8f15abc1d571870c5fc3e594bb582bc3b64ea099db13e56/jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67", size = 134899, upload-time = "2025-03-05T20:05:00.369Z" }, -] - -[[package]] -name = "markdown" -version = "3.8.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/d7/c2/4ab49206c17f75cb08d6311171f2d65798988db4360c4d1485bd0eedd67c/markdown-3.8.2.tar.gz", hash = "sha256:247b9a70dd12e27f67431ce62523e675b866d254f900c4fe75ce3dda62237c45", size = 362071, upload-time = "2025-06-19T17:12:44.483Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/96/2b/34cc11786bc00d0f04d0f5fdc3a2b1ae0b6239eef72d3d345805f9ad92a1/markdown-3.8.2-py3-none-any.whl", hash = "sha256:5c83764dbd4e00bdd94d85a19b8d55ccca20fe35b2e678a1422b380324dd5f24", size = 106827, upload-time = "2025-06-19T17:12:42.994Z" }, -] - -[[package]] -name = "markupsafe" -version = "3.0.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b2/97/5d42485e71dfc078108a86d6de8fa46db44a1a9295e89c5d6d4a06e23a62/markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0", size = 20537, upload-time = "2024-10-18T15:21:54.129Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/83/0e/67eb10a7ecc77a0c2bbe2b0235765b98d164d81600746914bebada795e97/MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd", size = 14274, upload-time = "2024-10-18T15:21:24.577Z" }, - { url = "https://files.pythonhosted.org/packages/2b/6d/9409f3684d3335375d04e5f05744dfe7e9f120062c9857df4ab490a1031a/MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430", size = 12352, upload-time = "2024-10-18T15:21:25.382Z" }, - { url = "https://files.pythonhosted.org/packages/d2/f5/6eadfcd3885ea85fe2a7c128315cc1bb7241e1987443d78c8fe712d03091/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094", size = 24122, upload-time = "2024-10-18T15:21:26.199Z" }, - { url = "https://files.pythonhosted.org/packages/0c/91/96cf928db8236f1bfab6ce15ad070dfdd02ed88261c2afafd4b43575e9e9/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396", size = 23085, upload-time = "2024-10-18T15:21:27.029Z" }, - { url = "https://files.pythonhosted.org/packages/c2/cf/c9d56af24d56ea04daae7ac0940232d31d5a8354f2b457c6d856b2057d69/MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79", size = 22978, upload-time = "2024-10-18T15:21:27.846Z" }, - { url = "https://files.pythonhosted.org/packages/2a/9f/8619835cd6a711d6272d62abb78c033bda638fdc54c4e7f4272cf1c0962b/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a", size = 24208, upload-time = "2024-10-18T15:21:28.744Z" }, - { url = "https://files.pythonhosted.org/packages/f9/bf/176950a1792b2cd2102b8ffeb5133e1ed984547b75db47c25a67d3359f77/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca", size = 23357, upload-time = "2024-10-18T15:21:29.545Z" }, - { url = "https://files.pythonhosted.org/packages/ce/4f/9a02c1d335caabe5c4efb90e1b6e8ee944aa245c1aaaab8e8a618987d816/MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c", size = 23344, upload-time = "2024-10-18T15:21:30.366Z" }, - { url = "https://files.pythonhosted.org/packages/ee/55/c271b57db36f748f0e04a759ace9f8f759ccf22b4960c270c78a394f58be/MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1", size = 15101, upload-time = "2024-10-18T15:21:31.207Z" }, - { url = "https://files.pythonhosted.org/packages/29/88/07df22d2dd4df40aba9f3e402e6dc1b8ee86297dddbad4872bd5e7b0094f/MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f", size = 15603, upload-time = "2024-10-18T15:21:32.032Z" }, - { url = "https://files.pythonhosted.org/packages/62/6a/8b89d24db2d32d433dffcd6a8779159da109842434f1dd2f6e71f32f738c/MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c", size = 14510, upload-time = "2024-10-18T15:21:33.625Z" }, - { url = "https://files.pythonhosted.org/packages/7a/06/a10f955f70a2e5a9bf78d11a161029d278eeacbd35ef806c3fd17b13060d/MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb", size = 12486, upload-time = "2024-10-18T15:21:34.611Z" }, - { url = "https://files.pythonhosted.org/packages/34/cf/65d4a571869a1a9078198ca28f39fba5fbb910f952f9dbc5220afff9f5e6/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c", size = 25480, upload-time = "2024-10-18T15:21:35.398Z" }, - { url = "https://files.pythonhosted.org/packages/0c/e3/90e9651924c430b885468b56b3d597cabf6d72be4b24a0acd1fa0e12af67/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d", size = 23914, upload-time = "2024-10-18T15:21:36.231Z" }, - { url = "https://files.pythonhosted.org/packages/66/8c/6c7cf61f95d63bb866db39085150df1f2a5bd3335298f14a66b48e92659c/MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe", size = 23796, upload-time = "2024-10-18T15:21:37.073Z" }, - { url = "https://files.pythonhosted.org/packages/bb/35/cbe9238ec3f47ac9a7c8b3df7a808e7cb50fe149dc7039f5f454b3fba218/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5", size = 25473, upload-time = "2024-10-18T15:21:37.932Z" }, - { url = "https://files.pythonhosted.org/packages/e6/32/7621a4382488aa283cc05e8984a9c219abad3bca087be9ec77e89939ded9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a", size = 24114, upload-time = "2024-10-18T15:21:39.799Z" }, - { url = "https://files.pythonhosted.org/packages/0d/80/0985960e4b89922cb5a0bac0ed39c5b96cbc1a536a99f30e8c220a996ed9/MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9", size = 24098, upload-time = "2024-10-18T15:21:40.813Z" }, - { url = "https://files.pythonhosted.org/packages/82/78/fedb03c7d5380df2427038ec8d973587e90561b2d90cd472ce9254cf348b/MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6", size = 15208, upload-time = "2024-10-18T15:21:41.814Z" }, - { url = "https://files.pythonhosted.org/packages/4f/65/6079a46068dfceaeabb5dcad6d674f5f5c61a6fa5673746f42a9f4c233b3/MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f", size = 15739, upload-time = "2024-10-18T15:21:42.784Z" }, -] - -[[package]] -name = "mergedeep" -version = "1.3.4" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/3a/41/580bb4006e3ed0361b8151a01d324fb03f420815446c7def45d02f74c270/mergedeep-1.3.4.tar.gz", hash = "sha256:0096d52e9dad9939c3d975a774666af186eda617e6ca84df4c94dec30004f2a8", size = 4661, upload-time = "2021-02-05T18:55:30.623Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/2c/19/04f9b178c2d8a15b076c8b5140708fa6ffc5601fb6f1e975537072df5b2a/mergedeep-1.3.4-py3-none-any.whl", hash = "sha256:70775750742b25c0d8f36c55aed03d24c3384d17c951b3175d898bd778ef0307", size = 6354, upload-time = "2021-02-05T18:55:29.583Z" }, -] - -[[package]] -name = "mkdocs" -version = "1.6.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "click" }, - { name = "colorama", marker = "sys_platform == 'win32'" }, - { name = "ghp-import" }, - { name = "jinja2" }, - { name = "markdown" }, - { name = "markupsafe" }, - { name = "mergedeep" }, - { name = "mkdocs-get-deps" }, - { name = "packaging" }, - { name = "pathspec" }, - { name = "pyyaml" }, - { name = "pyyaml-env-tag" }, - { name = "watchdog" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/bc/c6/bbd4f061bd16b378247f12953ffcb04786a618ce5e904b8c5a01a0309061/mkdocs-1.6.1.tar.gz", hash = "sha256:7b432f01d928c084353ab39c57282f29f92136665bdd6abf7c1ec8d822ef86f2", size = 3889159, upload-time = "2024-08-30T12:24:06.899Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/22/5b/dbc6a8cddc9cfa9c4971d59fb12bb8d42e161b7e7f8cc89e49137c5b279c/mkdocs-1.6.1-py3-none-any.whl", hash = "sha256:db91759624d1647f3f34aa0c3f327dd2601beae39a366d6e064c03468d35c20e", size = 3864451, upload-time = "2024-08-30T12:24:05.054Z" }, -] - -[[package]] -name = "mkdocs-autorefs" -version = "1.4.3" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "markdown" }, - { name = "markupsafe" }, - { name = "mkdocs" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/51/fa/9124cd63d822e2bcbea1450ae68cdc3faf3655c69b455f3a7ed36ce6c628/mkdocs_autorefs-1.4.3.tar.gz", hash = "sha256:beee715b254455c4aa93b6ef3c67579c399ca092259cc41b7d9342573ff1fc75", size = 55425, upload-time = "2025-08-26T14:23:17.223Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9f/4d/7123b6fa2278000688ebd338e2a06d16870aaf9eceae6ba047ea05f92df1/mkdocs_autorefs-1.4.3-py3-none-any.whl", hash = "sha256:469d85eb3114801d08e9cc55d102b3ba65917a869b893403b8987b601cf55dc9", size = 25034, upload-time = "2025-08-26T14:23:15.906Z" }, -] - -[[package]] -name = "mkdocs-get-deps" -version = "0.2.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "mergedeep" }, - { name = "platformdirs" }, - { name = "pyyaml" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/98/f5/ed29cd50067784976f25ed0ed6fcd3c2ce9eb90650aa3b2796ddf7b6870b/mkdocs_get_deps-0.2.0.tar.gz", hash = "sha256:162b3d129c7fad9b19abfdcb9c1458a651628e4b1dea628ac68790fb3061c60c", size = 10239, upload-time = "2023-11-20T17:51:09.981Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/9f/d4/029f984e8d3f3b6b726bd33cafc473b75e9e44c0f7e80a5b29abc466bdea/mkdocs_get_deps-0.2.0-py3-none-any.whl", hash = "sha256:2bf11d0b133e77a0dd036abeeb06dec8775e46efa526dc70667d8863eefc6134", size = 9521, upload-time = "2023-11-20T17:51:08.587Z" }, -] - -[[package]] -name = "mkdocs-material" -version = "9.6.18" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "babel" }, - { name = "backrefs" }, - { name = "click" }, - { name = "colorama" }, - { name = "jinja2" }, - { name = "markdown" }, - { name = "mkdocs" }, - { name = "mkdocs-material-extensions" }, - { name = "paginate" }, - { name = "pygments" }, - { name = "pymdown-extensions" }, - { name = "requests" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/e6/46/db0d78add5aac29dfcd0a593bcc6049c86c77ba8a25b3a5b681c190d5e99/mkdocs_material-9.6.18.tar.gz", hash = "sha256:a2eb253bcc8b66f8c6eaf8379c10ed6e9644090c2e2e9d0971c7722dc7211c05", size = 4034856, upload-time = "2025-08-22T08:21:47.575Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/22/0b/545a4f8d4f9057e77f1d99640eb09aaae40c4f9034707f25636caf716ff9/mkdocs_material-9.6.18-py3-none-any.whl", hash = "sha256:dbc1e146a0ecce951a4d84f97b816a54936cdc9e1edd1667fc6868878ac06701", size = 9232642, upload-time = "2025-08-22T08:21:44.52Z" }, -] - -[[package]] -name = "mkdocs-material-extensions" -version = "1.3.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/79/9b/9b4c96d6593b2a541e1cb8b34899a6d021d208bb357042823d4d2cabdbe7/mkdocs_material_extensions-1.3.1.tar.gz", hash = "sha256:10c9511cea88f568257f960358a467d12b970e1f7b2c0e5fb2bb48cab1928443", size = 11847, upload-time = "2023-11-22T19:09:45.208Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/5b/54/662a4743aa81d9582ee9339d4ffa3c8fd40a4965e033d77b9da9774d3960/mkdocs_material_extensions-1.3.1-py3-none-any.whl", hash = "sha256:adff8b62700b25cb77b53358dad940f3ef973dd6db797907c49e3c2ef3ab4e31", size = 8728, upload-time = "2023-11-22T19:09:43.465Z" }, -] - -[[package]] -name = "mkdocs-open-in-new-tab" -version = "1.0.8" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "mkdocs" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/0a/0e/f72a506a21bdb27b807124e00c688226848a388d1fd3980b80ae3cc27203/mkdocs_open_in_new_tab-1.0.8.tar.gz", hash = "sha256:3e0dad08cc9938b0b13097be8e0aa435919de1eeb2d1a648e66b5dee8d57e048", size = 5791, upload-time = "2024-11-18T13:15:13.977Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/21/94/44f3c868495481c868d08eea065c82803f1affd8553d3383b782f497613c/mkdocs_open_in_new_tab-1.0.8-py3-none-any.whl", hash = "sha256:051d767a4467b12d89827e1fea0ec660b05b027c726317fe4fceee5456e36ad2", size = 7717, upload-time = "2024-11-18T13:15:12.286Z" }, -] - -[[package]] -name = "mkdocstrings" -version = "0.30.0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "jinja2" }, - { name = "markdown" }, - { name = "markupsafe" }, - { name = "mkdocs" }, - { name = "mkdocs-autorefs" }, - { name = "pymdown-extensions" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/e2/0a/7e4776217d4802009c8238c75c5345e23014a4706a8414a62c0498858183/mkdocstrings-0.30.0.tar.gz", hash = "sha256:5d8019b9c31ddacd780b6784ffcdd6f21c408f34c0bd1103b5351d609d5b4444", size = 106597, upload-time = "2025-07-22T23:48:45.998Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/de/b4/3c5eac68f31e124a55d255d318c7445840fa1be55e013f507556d6481913/mkdocstrings-0.30.0-py3-none-any.whl", hash = "sha256:ae9e4a0d8c1789697ac776f2e034e2ddd71054ae1cf2c2bb1433ccfd07c226f2", size = 36579, upload-time = "2025-07-22T23:48:44.152Z" }, -] - -[package.optional-dependencies] -python = [ - { name = "mkdocstrings-python" }, -] - -[[package]] -name = "mkdocstrings-python" -version = "1.18.2" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "griffe" }, - { name = "mkdocs-autorefs" }, - { name = "mkdocstrings" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/95/ae/58ab2bfbee2792e92a98b97e872f7c003deb903071f75d8d83aa55db28fa/mkdocstrings_python-1.18.2.tar.gz", hash = "sha256:4ad536920a07b6336f50d4c6d5603316fafb1172c5c882370cbbc954770ad323", size = 207972, upload-time = "2025-08-28T16:11:19.847Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/d5/8f/ce008599d9adebf33ed144e7736914385e8537f5fc686fdb7cceb8c22431/mkdocstrings_python-1.18.2-py3-none-any.whl", hash = "sha256:944fe6deb8f08f33fa936d538233c4036e9f53e840994f6146e8e94eb71b600d", size = 138215, upload-time = "2025-08-28T16:11:18.176Z" }, -] - -[[package]] -name = "nrl-sdk" -version = "0.1.0" -source = { virtual = "." } -dependencies = [ - { name = "griffe-fieldz" }, - { name = "griffe-pydantic" }, - { name = "mkdocs" }, - { name = "mkdocs-material" }, - { name = "mkdocs-open-in-new-tab" }, - { name = "mkdocstrings", extra = ["python"] }, -] - -[package.metadata] -requires-dist = [ - { name = "griffe-fieldz", specifier = ">=0.3.0" }, - { name = "griffe-pydantic", specifier = ">=1.1.6" }, - { name = "mkdocs", specifier = ">=1.6.1" }, - { name = "mkdocs-material", specifier = ">=9.6.15" }, - { name = "mkdocs-open-in-new-tab", specifier = ">=1.0.8" }, - { name = "mkdocstrings", extras = ["python"], specifier = ">=0.29.1" }, -] - -[[package]] -name = "packaging" -version = "25.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" }, -] - -[[package]] -name = "paginate" -version = "0.5.7" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ec/46/68dde5b6bc00c1296ec6466ab27dddede6aec9af1b99090e1107091b3b84/paginate-0.5.7.tar.gz", hash = "sha256:22bd083ab41e1a8b4f3690544afb2c60c25e5c9a63a30fa2f483f6c60c8e5945", size = 19252, upload-time = "2024-08-25T14:17:24.139Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/90/96/04b8e52da071d28f5e21a805b19cb9390aa17a47462ac87f5e2696b9566d/paginate-0.5.7-py2.py3-none-any.whl", hash = "sha256:b885e2af73abcf01d9559fd5216b57ef722f8c42affbb63942377668e35c7591", size = 13746, upload-time = "2024-08-25T14:17:22.55Z" }, -] - -[[package]] -name = "pathspec" -version = "0.12.1" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043, upload-time = "2023-12-10T22:30:45Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191, upload-time = "2023-12-10T22:30:43.14Z" }, -] - -[[package]] -name = "platformdirs" -version = "4.4.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/23/e8/21db9c9987b0e728855bd57bff6984f67952bea55d6f75e055c46b5383e8/platformdirs-4.4.0.tar.gz", hash = "sha256:ca753cf4d81dc309bc67b0ea38fd15dc97bc30ce419a7f58d13eb3bf14c4febf", size = 21634, upload-time = "2025-08-26T14:32:04.268Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/40/4b/2028861e724d3bd36227adfa20d3fd24c3fc6d52032f4a93c133be5d17ce/platformdirs-4.4.0-py3-none-any.whl", hash = "sha256:abd01743f24e5287cd7a5db3752faf1a2d65353f38ec26d98e25a6db65958c85", size = 18654, upload-time = "2025-08-26T14:32:02.735Z" }, -] - -[[package]] -name = "pygments" -version = "2.19.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, -] - -[[package]] -name = "pymdown-extensions" -version = "10.16.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "markdown" }, - { name = "pyyaml" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/55/b3/6d2b3f149bc5413b0a29761c2c5832d8ce904a1d7f621e86616d96f505cc/pymdown_extensions-10.16.1.tar.gz", hash = "sha256:aace82bcccba3efc03e25d584e6a22d27a8e17caa3f4dd9f207e49b787aa9a91", size = 853277, upload-time = "2025-07-28T16:19:34.167Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/e4/06/43084e6cbd4b3bc0e80f6be743b2e79fbc6eed8de9ad8c629939fa55d972/pymdown_extensions-10.16.1-py3-none-any.whl", hash = "sha256:d6ba157a6c03146a7fb122b2b9a121300056384eafeec9c9f9e584adfdb2a32d", size = 266178, upload-time = "2025-07-28T16:19:31.401Z" }, -] - -[[package]] -name = "python-dateutil" -version = "2.9.0.post0" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "six" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/66/c0/0c8b6ad9f17a802ee498c46e004a0eb49bc148f2fd230864601a86dcf6db/python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3", size = 342432, upload-time = "2024-03-01T18:36:20.211Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" }, -] - -[[package]] -name = "pyyaml" -version = "6.0.2" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload-time = "2024-08-06T20:33:50.674Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309, upload-time = "2024-08-06T20:32:43.4Z" }, - { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679, upload-time = "2024-08-06T20:32:44.801Z" }, - { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428, upload-time = "2024-08-06T20:32:46.432Z" }, - { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361, upload-time = "2024-08-06T20:32:51.188Z" }, - { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523, upload-time = "2024-08-06T20:32:53.019Z" }, - { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660, upload-time = "2024-08-06T20:32:54.708Z" }, - { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597, upload-time = "2024-08-06T20:32:56.985Z" }, - { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527, upload-time = "2024-08-06T20:33:03.001Z" }, - { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" }, -] - -[[package]] -name = "pyyaml-env-tag" -version = "1.1" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "pyyaml" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/eb/2e/79c822141bfd05a853236b504869ebc6b70159afc570e1d5a20641782eaa/pyyaml_env_tag-1.1.tar.gz", hash = "sha256:2eb38b75a2d21ee0475d6d97ec19c63287a7e140231e4214969d0eac923cd7ff", size = 5737, upload-time = "2025-05-13T15:24:01.64Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/04/11/432f32f8097b03e3cd5fe57e88efb685d964e2e5178a48ed61e841f7fdce/pyyaml_env_tag-1.1-py3-none-any.whl", hash = "sha256:17109e1a528561e32f026364712fee1264bc2ea6715120891174ed1b980d2e04", size = 4722, upload-time = "2025-05-13T15:23:59.629Z" }, -] - -[[package]] -name = "requests" -version = "2.32.5" -source = { registry = "https://pypi.org/simple" } -dependencies = [ - { name = "certifi" }, - { name = "charset-normalizer" }, - { name = "idna" }, - { name = "urllib3" }, -] -sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, -] - -[[package]] -name = "six" -version = "1.17.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031, upload-time = "2024-12-04T17:35:28.174Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050, upload-time = "2024-12-04T17:35:26.475Z" }, -] - -[[package]] -name = "typing-extensions" -version = "4.15.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/72/94/1a15dd82efb362ac84269196e94cf00f187f7ed21c242792a923cdb1c61f/typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466", size = 109391, upload-time = "2025-08-25T13:49:26.313Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/18/67/36e9267722cc04a6b9f15c7f3441c2363321a3ea07da7ae0c0707beb2a9c/typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548", size = 44614, upload-time = "2025-08-25T13:49:24.86Z" }, -] - -[[package]] -name = "urllib3" -version = "2.5.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" }, -] - -[[package]] -name = "watchdog" -version = "6.0.0" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/db/7d/7f3d619e951c88ed75c6037b246ddcf2d322812ee8ea189be89511721d54/watchdog-6.0.0.tar.gz", hash = "sha256:9ddf7c82fda3ae8e24decda1338ede66e1c99883db93711d8fb941eaa2d8c282", size = 131220, upload-time = "2024-11-01T14:07:13.037Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/68/98/b0345cabdce2041a01293ba483333582891a3bd5769b08eceb0d406056ef/watchdog-6.0.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:490ab2ef84f11129844c23fb14ecf30ef3d8a6abafd3754a6f75ca1e6654136c", size = 96480, upload-time = "2024-11-01T14:06:42.952Z" }, - { url = "https://files.pythonhosted.org/packages/85/83/cdf13902c626b28eedef7ec4f10745c52aad8a8fe7eb04ed7b1f111ca20e/watchdog-6.0.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:76aae96b00ae814b181bb25b1b98076d5fc84e8a53cd8885a318b42b6d3a5134", size = 88451, upload-time = "2024-11-01T14:06:45.084Z" }, - { url = "https://files.pythonhosted.org/packages/fe/c4/225c87bae08c8b9ec99030cd48ae9c4eca050a59bf5c2255853e18c87b50/watchdog-6.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a175f755fc2279e0b7312c0035d52e27211a5bc39719dd529625b1930917345b", size = 89057, upload-time = "2024-11-01T14:06:47.324Z" }, - { url = "https://files.pythonhosted.org/packages/a9/c7/ca4bf3e518cb57a686b2feb4f55a1892fd9a3dd13f470fca14e00f80ea36/watchdog-6.0.0-py3-none-manylinux2014_aarch64.whl", hash = "sha256:7607498efa04a3542ae3e05e64da8202e58159aa1fa4acddf7678d34a35d4f13", size = 79079, upload-time = "2024-11-01T14:06:59.472Z" }, - { url = "https://files.pythonhosted.org/packages/5c/51/d46dc9332f9a647593c947b4b88e2381c8dfc0942d15b8edc0310fa4abb1/watchdog-6.0.0-py3-none-manylinux2014_armv7l.whl", hash = "sha256:9041567ee8953024c83343288ccc458fd0a2d811d6a0fd68c4c22609e3490379", size = 79078, upload-time = "2024-11-01T14:07:01.431Z" }, - { url = "https://files.pythonhosted.org/packages/d4/57/04edbf5e169cd318d5f07b4766fee38e825d64b6913ca157ca32d1a42267/watchdog-6.0.0-py3-none-manylinux2014_i686.whl", hash = "sha256:82dc3e3143c7e38ec49d61af98d6558288c415eac98486a5c581726e0737c00e", size = 79076, upload-time = "2024-11-01T14:07:02.568Z" }, - { url = "https://files.pythonhosted.org/packages/ab/cc/da8422b300e13cb187d2203f20b9253e91058aaf7db65b74142013478e66/watchdog-6.0.0-py3-none-manylinux2014_ppc64.whl", hash = "sha256:212ac9b8bf1161dc91bd09c048048a95ca3a4c4f5e5d4a7d1b1a7d5752a7f96f", size = 79077, upload-time = "2024-11-01T14:07:03.893Z" }, - { url = "https://files.pythonhosted.org/packages/2c/3b/b8964e04ae1a025c44ba8e4291f86e97fac443bca31de8bd98d3263d2fcf/watchdog-6.0.0-py3-none-manylinux2014_ppc64le.whl", hash = "sha256:e3df4cbb9a450c6d49318f6d14f4bbc80d763fa587ba46ec86f99f9e6876bb26", size = 79078, upload-time = "2024-11-01T14:07:05.189Z" }, - { url = "https://files.pythonhosted.org/packages/62/ae/a696eb424bedff7407801c257d4b1afda455fe40821a2be430e173660e81/watchdog-6.0.0-py3-none-manylinux2014_s390x.whl", hash = "sha256:2cce7cfc2008eb51feb6aab51251fd79b85d9894e98ba847408f662b3395ca3c", size = 79077, upload-time = "2024-11-01T14:07:06.376Z" }, - { url = "https://files.pythonhosted.org/packages/b5/e8/dbf020b4d98251a9860752a094d09a65e1b436ad181faf929983f697048f/watchdog-6.0.0-py3-none-manylinux2014_x86_64.whl", hash = "sha256:20ffe5b202af80ab4266dcd3e91aae72bf2da48c0d33bdb15c66658e685e94e2", size = 79078, upload-time = "2024-11-01T14:07:07.547Z" }, - { url = "https://files.pythonhosted.org/packages/07/f6/d0e5b343768e8bcb4cda79f0f2f55051bf26177ecd5651f84c07567461cf/watchdog-6.0.0-py3-none-win32.whl", hash = "sha256:07df1fdd701c5d4c8e55ef6cf55b8f0120fe1aef7ef39a1c6fc6bc2e606d517a", size = 79065, upload-time = "2024-11-01T14:07:09.525Z" }, - { url = "https://files.pythonhosted.org/packages/db/d9/c495884c6e548fce18a8f40568ff120bc3a4b7b99813081c8ac0c936fa64/watchdog-6.0.0-py3-none-win_amd64.whl", hash = "sha256:cbafb470cf848d93b5d013e2ecb245d4aa1c8fd0504e863ccefa32445359d680", size = 79070, upload-time = "2024-11-01T14:07:10.686Z" }, - { url = "https://files.pythonhosted.org/packages/33/e8/e40370e6d74ddba47f002a32919d91310d6074130fe4e17dabcafc15cbf1/watchdog-6.0.0-py3-none-win_ia64.whl", hash = "sha256:a1914259fa9e1454315171103c6a30961236f508b9b623eae470268bbcc6a22f", size = 79067, upload-time = "2024-11-01T14:07:11.845Z" }, -] From 3b8e5c099c9d09fd099c395979a83ddf979f2cee Mon Sep 17 00:00:00 2001 From: Andrea-Devold-Fjeld Date: Tue, 7 Oct 2025 11:34:50 +0200 Subject: [PATCH 2/4] Add support to use column ID as komponentident --- nrl-sdk-lib/pyproject.toml | 4 + .../nrl_sdk_lib/converters/csv_to_geojson.py | 201 +++++++++--------- nrl-sdk-lib/tests/test_csv_to_geojson.py | 36 ++-- nrl-sdk-lib/uv.lock | 6 +- 4 files changed, 123 insertions(+), 124 deletions(-) diff --git a/nrl-sdk-lib/pyproject.toml b/nrl-sdk-lib/pyproject.toml index 86b388c..278187f 100644 --- a/nrl-sdk-lib/pyproject.toml +++ b/nrl-sdk-lib/pyproject.toml @@ -20,6 +20,9 @@ build-backend = "hatchling.build" [tool.hatch.build.targets.wheel] packages = ["src/nrl_sdk_lib"] +[tool.deptry] +known_first_party = ["nrl_sdk_lib"] + [dependency-groups] dev = [ "anyio>=4.9.0", @@ -59,6 +62,7 @@ ignore = [ "PLR2004", # Magic values allowed in tests ] + [tool.ruff.lint.isort] # so it knows to group first-party stuff last known-first-party = ["src"] diff --git a/nrl-sdk-lib/src/nrl_sdk_lib/converters/csv_to_geojson.py b/nrl-sdk-lib/src/nrl_sdk_lib/converters/csv_to_geojson.py index 8dbaef0..39cb601 100644 --- a/nrl-sdk-lib/src/nrl_sdk_lib/converters/csv_to_geojson.py +++ b/nrl-sdk-lib/src/nrl_sdk_lib/converters/csv_to_geojson.py @@ -5,7 +5,7 @@ import sys import uuid from pathlib import Path -from typing import IO, Any, Literal, cast +from typing import IO, Literal from nrl_sdk_lib.models import ( Crs, @@ -30,50 +30,83 @@ ) logger = logging.getLogger(__name__) -# Mapping dictionaries -LUFTSPENN_TYPE_MAP = { - "Ledning, høyspent": LuftspennType.høgspent, - "Ledning, lavspent": LuftspennType.lavspent, - "Ledning, regionalnett": LuftspennType.regional, -} - -MAST_TYPE_MAP = { - "Mast, høyspent": MastType.høgspentmast, - "Mast, lavspent": MastType.lavspentmast, - "Mast, regionalnett": MastType.regionalmast, -} - -FEATURE_STATUS_MAP = { - "Eksisterende": FeatureStatus.eksisterende, - "Planlagt oppført": FeatureStatus.planlagt_oppført, - "Planlagt fjernet": FeatureStatus.planlagt_fjernet, - "Fjernet": FeatureStatus.fjernet, - "planlagtOppført": FeatureStatus.planlagt_oppført, - "planlagtFjernet": FeatureStatus.planlagt_fjernet, - "eksisterende": FeatureStatus.eksisterende, - "fjernet": FeatureStatus.fjernet, -} - -LIGHTING_KIND_MAP = { - "Lyssatt": LuftfartsHinderLyssetting.lyssatt, - "Mellomintensitet, type A": LuftfartsHinderLyssetting.mellomintensitet_type_a, - "Mellomintensitet, type B": LuftfartsHinderLyssetting.mellomintensitet_type_b, - "Mellomintensitet, type C": LuftfartsHinderLyssetting.mellomintensitet_type_c, - "Lavintensitet, type A": LuftfartsHinderLyssetting.lavintensitet_type_a, - "Lavintensitet, type B": LuftfartsHinderLyssetting.lavintensitet_type_b, - "Høyintensitet, type A": LuftfartsHinderLyssetting.høyintensitet_type_a, - "Høyintensitet, type B": LuftfartsHinderLyssetting.høyintensitet_type_b, -} - -MARKING_KIND_MAP = { - "Fargemerking": LuftfartsHinderMerking.fargermerking, - "Markør": LuftfartsHinderMerking.markør, -} - -LOCATION_METHOD_MAP = { - "FOR-2020-10-16-2068, §5(1)": "20230101_5-1", -} +def map_luftspenn_type(value: str | None) -> LuftspennType: + """Map CSV value to LuftspennType.""" + mapping = { + "Ledning, høyspent": LuftspennType.høgspent, + "Ledning, lavspent": LuftspennType.lavspent, + "Ledning, regionalnett": LuftspennType.regional, + } + result = mapping.get(value) + if result is None: + msg = f"Unknown Luftspenntype: {value}" + raise ValueError(msg) + return result + +def map_mast_type(value: str | None) -> MastType: + """Map CSV value to MastType.""" + mapping = { + "Mast, høyspent": MastType.høgspentmast, + "Mast, lavspent": MastType.lavspentmast, + "Mast, regionalnett": MastType.regionalmast, + } + result = mapping.get(value) + if result is None: + msg = f"Unknown Masttype: {value}" + raise ValueError(msg) + return result + +def map_feature_status(value: str | None) -> FeatureStatus: + """Map CSV value to FeatureStatus.""" + mapping = { + "Eksisterende": FeatureStatus.eksisterende, + "eksisterende": FeatureStatus.eksisterende, + "Planlagt oppført": FeatureStatus.planlagt_oppført, + "planlagtOppført": FeatureStatus.planlagt_oppført, + "Planlagt fjernet": FeatureStatus.planlagt_fjernet, + "planlagtFjernet": FeatureStatus.planlagt_fjernet, + "Fjernet": FeatureStatus.fjernet, + "fjernet": FeatureStatus.fjernet, + } + result = mapping.get(value) + if result is None: + msg = f"Unknown Status: {value}" + raise ValueError(msg) + return result + +def map_lighting_kind(value: str | None) -> LuftfartsHinderLyssetting | None: + """Map CSV value to LuftfartsHinderLyssetting (optional).""" + mapping = { + "Lyssatt": LuftfartsHinderLyssetting.lyssatt, + "Mellomintensitet, type A": LuftfartsHinderLyssetting.mellomintensitet_type_a, + "Mellomintensitet, type B": LuftfartsHinderLyssetting.mellomintensitet_type_b, + "Mellomintensitet, type C": LuftfartsHinderLyssetting.mellomintensitet_type_c, + "Lavintensitet, type A": LuftfartsHinderLyssetting.lavintensitet_type_a, + "Lavintensitet, type B": LuftfartsHinderLyssetting.lavintensitet_type_b, + "Høyintensitet, type A": LuftfartsHinderLyssetting.høyintensitet_type_a, + "Høyintensitet, type B": LuftfartsHinderLyssetting.høyintensitet_type_b, + } + if not value: + return None + return mapping.get(value) + + +def map_marking_kind(value: str | None) -> LuftfartsHinderMerking | None: + """Map CSV value to LuftfartsHinderMerking (optional).""" + mapping = { + "Fargemerking": LuftfartsHinderMerking.fargermerking, + "Markør": LuftfartsHinderMerking.markør, + } + if not value: + return None + return mapping.get(value) + +def map_location_method(value: str | None) -> Literal["20230101_5-1", "0"]: + """Map CSV value to location method string.""" + if value == "FOR-2020-10-16-2068, §5(1)": + return "20230101_5-1" + return "0" def csv_to_geojson(file: str | Path | IO[str] | None = None) -> list[FeatureCollection]: """Convert CSV file to GeoJSON FeatureCollections grouped by CRS. @@ -224,48 +257,15 @@ def create_geometry( return geometry, crs - -def map_value( - value: str | None, - mapping: dict, - field_name: str, - *, - allow_none: bool = False) -> Any: # noqa: ANN401 - """Map a value using a dictionary with error handling.""" - if not value: - if allow_none: - return None - msg = f"Missing {field_name}" - raise ValueError(msg) - - result = mapping.get(value) - if result is None and not allow_none: - msg = f"Unknown {field_name}: {value}" - raise ValueError(msg) - return result - - def convert_overhead_structure_rows(row: dict[str, str]) -> tuple[Feature, Crs]: """Convert overhead structure (mast) rows to NrlMast feature.""" komponentident = get_uuid(row, "OverheadStructure_uuid", "ID") - masttype = map_value(row.get("Masttype (NRL)"), MAST_TYPE_MAP, "Masttype") - feature_status = map_value(row.get("Status (NRL)"), FEATURE_STATUS_MAP, "Status") - nøyaktighet = LOCATION_METHOD_MAP.get( - row.get("Verifisert nøyaktighet (NRL)", ""), "0" - ) + masttype = map_mast_type(row.get("Masttype (NRL)")) + feature_status = map_feature_status(row.get("Status (NRL)")) + nøyaktighet = map_location_method(row.get("Verifisert nøyaktighet (NRL)")) - lyssetting = map_value( - row.get("Luftfartshinderlyssetting(NRL)", ""), - LIGHTING_KIND_MAP, - "Lighting", - allow_none=True, - ) - merking = map_value( - row.get("Luftfartshindermerking (NRL)", ""), - MARKING_KIND_MAP, - "Marking", - allow_none=True, - ) + lyssetting = map_lighting_kind(row.get("Luftfartshinderlyssetting(NRL)")) + merking = map_marking_kind(row.get("Luftfartshindermerking (NRL)")) høydereferanse = None if row.get("Hoydereferanse (NRL)"): @@ -305,11 +305,9 @@ def convert_overhead_structure_rows(row: dict[str, str]) -> tuple[Feature, Crs]: def convert_guy_segments_rows(row: dict[str, str]) -> tuple[Feature, Crs]: """Convert guy wire segments to NrlLuftspenn feature.""" - komponentident = get_uuid(row, "Guy_uuid") - feature_status = map_value(row.get("Status (NRL)"), FEATURE_STATUS_MAP, "Status") - nøyaktighet = LOCATION_METHOD_MAP.get( - row.get("Verifisert nøyaktighet (NRL)", ""), "0" - ) + komponentident = get_uuid(row, "Guy_uuid", "ID") + feature_status = map_feature_status(row.get("Status (NRL)")) + nøyaktighet = map_location_method(row.get("Vertikalavstand meter (NRL)")) linestring, crs = create_geometry( [ @@ -340,28 +338,21 @@ def convert_guy_segments_rows(row: dict[str, str]) -> tuple[Feature, Crs]: def convert_ac_linesegments_rows(row: dict[str, str]) -> tuple[Feature, Crs]: """Convert AC line segments to NrlLuftspenn feature.""" komponentident = get_uuid(row, "ACLineSegmentSpan_uuid", "ID") - feature_status = map_value(row.get("Status (NRL)"), FEATURE_STATUS_MAP, "Status") - luftspennstype = map_value( - row.get("Luftspenntype (NRL)"), LUFTSPENN_TYPE_MAP, "Luftspenntype" - ) - nøyaktighet_str = LOCATION_METHOD_MAP.get( - row.get("Verifisert nøyaktighet (NRL)", ""), "0" + feature_status = map_feature_status(row.get("Status (NRL)")) + luftspennstype: LuftspennType = map_luftspenn_type( + row.get("Luftspenntype (NRL)") ) - nøyaktighet: Literal["20230101_5-1", "0"] = cast( - "Literal['20230101_5-1', '0']", nøyaktighet_str + + nøyaktighet: Literal["20230101_5-1","0"] = map_location_method( + row.get("Verifisert nøyaktighet (NRL)" + ) ) - lyssetting = map_value( - row.get("Luftfartshinderlyssetting(NRL)", ""), - LIGHTING_KIND_MAP, - "Lighting", - allow_none=True, + lyssetting: LuftfartsHinderLyssetting | None = map_lighting_kind( + "Luftfartshinderlyssetting(NRL)" ) - merking = map_value( - row.get("Luftfartshindermerking (NRL)", ""), - MARKING_KIND_MAP, - "Marking", - allow_none=True, + merking: LuftfartsHinderMerking | None = map_marking_kind( + "Luftfartshindermerking(NRL)" ) linestring, crs = create_geometry( diff --git a/nrl-sdk-lib/tests/test_csv_to_geojson.py b/nrl-sdk-lib/tests/test_csv_to_geojson.py index 35cf525..39667c6 100644 --- a/nrl-sdk-lib/tests/test_csv_to_geojson.py +++ b/nrl-sdk-lib/tests/test_csv_to_geojson.py @@ -11,11 +11,12 @@ import pytest from nrl_sdk_lib.converters.csv_to_geojson import ( - FEATURE_STATUS_MAP, create_geometry, csv_to_geojson, get_uuid, - map_value, + map_feature_status, + map_lighting_kind, + map_location_method, parse_float, ) @@ -192,29 +193,32 @@ def test_create_geometry_invalid_coords() -> None: create_geometry(coords, is_line=True) -def test_map_value_valid() -> None: +def test_map_feature_status_valid() -> None: """Test mapping valid value.""" - result = map_value("Eksisterende", FEATURE_STATUS_MAP, "Status") + result = map_feature_status("Eksisterende") assert result is not None - -def test_map_value_missing() -> None: +def test_map_feature_status_missing() -> None: """Test mapping with missing value.""" - with pytest.raises(ValueError, match="Missing Status"): - map_value("", FEATURE_STATUS_MAP, "Status", allow_none=False) - + with pytest.raises(ValueError, match="Unknown Status"): + map_feature_status("") -def test_map_value_unknown() -> None: +def test_map_feature_status_unknown() -> None: """Test mapping with unknown value.""" with pytest.raises(ValueError, match="Unknown Status"): - map_value("InvalidStatus", FEATURE_STATUS_MAP, "Status", allow_none=False) - + map_feature_status("InvalidStatus") -def test_map_value_allow_none() -> None: - """Test mapping with allow_none=True.""" - result = map_value("", FEATURE_STATUS_MAP, "Status", allow_none=True) +def test_map_lighting_kind_allow_none() -> None: + """Test mapping with allow_none (returns None for empty value).""" + result = map_lighting_kind("") assert result is None +def test_map_location_kind() -> None: + """Test both location kinds.""" + result = map_location_method("FOR-2020-10-16-2068, §5(1)") + assert result == "20230101_5-1" + result = map_location_method("Some other value") + assert result == "0" def create_test_csv(content: list[dict], filename: str | None) -> str | None: """Create a temporary CSV file.""" @@ -267,7 +271,7 @@ def test_csv_missing_status() -> None: filename = create_test_csv(content, filename=None) - with pytest.raises(ValueError, match="Missing Status"): + with pytest.raises(ValueError, match="Unknown Status:"): csv_to_geojson(filename) def test_no_tabell_id() -> None: diff --git a/nrl-sdk-lib/uv.lock b/nrl-sdk-lib/uv.lock index c39bf72..29989d9 100644 --- a/nrl-sdk-lib/uv.lock +++ b/nrl-sdk-lib/uv.lock @@ -26,11 +26,11 @@ wheels = [ [[package]] name = "attrs" -version = "25.3.0" +version = "25.4.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/5a/b0/1367933a8532ee6ff8d63537de4f1177af4bff9f3e829baf7331f595bb24/attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b", size = 812032, upload-time = "2025-03-13T11:10:22.779Z" } +sdist = { url = "https://files.pythonhosted.org/packages/6b/5c/685e6633917e101e5dcb62b9dd76946cbb57c26e133bae9e0cd36033c0a9/attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11", size = 934251, upload-time = "2025-10-06T13:54:44.725Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/77/06/bb80f5f86020c4551da315d78b3ab75e8228f89f0162f2c3a819e407941a/attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3", size = 63815, upload-time = "2025-03-13T11:10:21.14Z" }, + { url = "https://files.pythonhosted.org/packages/3a/2a/7cc015f5b9f5db42b7d48157e23356022889fc354a2813c15934b7cb5c0e/attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373", size = 67615, upload-time = "2025-10-06T13:54:43.17Z" }, ] [[package]] From 496cf5f6ea8ac80fb1e62806c87dcccaa3f40305 Mon Sep 17 00:00:00 2001 From: Andrea-Devold-Fjeld Date: Tue, 7 Oct 2025 15:04:25 +0200 Subject: [PATCH 3/4] Assert all the parameters of the different features --- .../nrl_sdk_lib/converters/csv_to_geojson.py | 18 ++- nrl-sdk-lib/tests/test_csv_to_geojson.py | 144 ++++++++++++++---- 2 files changed, 130 insertions(+), 32 deletions(-) diff --git a/nrl-sdk-lib/src/nrl_sdk_lib/converters/csv_to_geojson.py b/nrl-sdk-lib/src/nrl_sdk_lib/converters/csv_to_geojson.py index 39cb601..0d78c4c 100644 --- a/nrl-sdk-lib/src/nrl_sdk_lib/converters/csv_to_geojson.py +++ b/nrl-sdk-lib/src/nrl_sdk_lib/converters/csv_to_geojson.py @@ -37,6 +37,7 @@ def map_luftspenn_type(value: str | None) -> LuftspennType: "Ledning, høyspent": LuftspennType.høgspent, "Ledning, lavspent": LuftspennType.lavspent, "Ledning, regionalnett": LuftspennType.regional, + "Bardun": LuftspennType.bardun, } result = mapping.get(value) if result is None: @@ -267,6 +268,7 @@ def convert_overhead_structure_rows(row: dict[str, str]) -> tuple[Feature, Crs]: lyssetting = map_lighting_kind(row.get("Luftfartshinderlyssetting(NRL)")) merking = map_marking_kind(row.get("Luftfartshindermerking (NRL)")) + navn = row.get("Betegnelse") høydereferanse = None if row.get("Hoydereferanse (NRL)"): høydereferanse = ( @@ -277,6 +279,9 @@ def convert_overhead_structure_rows(row: dict[str, str]) -> tuple[Feature, Crs]: else None ) + referanse = KomponentReferanse( + komponentkodeverdi=row.get("ID", "") + ) if row.get("ID") else None max_height = ( parse_float(row["Vertikalavstand meter (NRL)"], "Vertikalavstand") if row.get("Vertikalavstand meter (NRL)") @@ -299,6 +304,8 @@ def convert_overhead_structure_rows(row: dict[str, str]) -> tuple[Feature, Crs]: luftfartshindermerking=merking if merking is not None else None, høydereferanse=høydereferanse if høydereferanse is not None else None, vertikal_avstand=max_height if max_height is not None else None, + navn=navn if navn is not None else None, + referanse=referanse if referanse is not None else None, ), ), crs @@ -308,7 +315,9 @@ def convert_guy_segments_rows(row: dict[str, str]) -> tuple[Feature, Crs]: komponentident = get_uuid(row, "Guy_uuid", "ID") feature_status = map_feature_status(row.get("Status (NRL)")) nøyaktighet = map_location_method(row.get("Vertikalavstand meter (NRL)")) - + luftspennstype: LuftspennType = map_luftspenn_type( + row.get("Luftspenntype (NRL)") + ) linestring, crs = create_geometry( [ [row["x1"], row["y1"], row.get("z1", "")], @@ -321,16 +330,18 @@ def convert_guy_segments_rows(row: dict[str, str]) -> tuple[Feature, Crs]: if row.get("ID") else None ) + navn = row.get("Betegnelse") return Feature( geometry=linestring, properties=NrlLuftspenn( - luftspenn_type=LuftspennType.bardun, + luftspenn_type=luftspennstype, komponentident=komponentident, status=feature_status, verifisert_rapporteringsnøyaktighet=nøyaktighet, feature_type="NrlLuftspenn", referanse=komponentreferanse, + navn=navn if navn is not None else None ), ), crs @@ -355,6 +366,8 @@ def convert_ac_linesegments_rows(row: dict[str, str]) -> tuple[Feature, Crs]: "Luftfartshindermerking(NRL)" ) + navn = row.get("Betegnelse") + linestring, crs = create_geometry( [ [row["x1"], row["y1"], row.get("z1", "")], @@ -392,5 +405,6 @@ def convert_ac_linesegments_rows(row: dict[str, str]) -> tuple[Feature, Crs]: luftfartshinderlyssetting=lyssetting if lyssetting is not None else None, luftfartshindermerking=merking if merking is not None else None, anleggsbredde=anleggsbredde if anleggsbredde is not None else None, + navn=navn if navn is not None else None ), ), crs diff --git a/nrl-sdk-lib/tests/test_csv_to_geojson.py b/nrl-sdk-lib/tests/test_csv_to_geojson.py index 39667c6..a0faa95 100644 --- a/nrl-sdk-lib/tests/test_csv_to_geojson.py +++ b/nrl-sdk-lib/tests/test_csv_to_geojson.py @@ -19,57 +19,141 @@ map_location_method, parse_float, ) +from nrl_sdk_lib.models import FeatureCollection, Høydereferanse # noqa:PLC2403 @pytest.mark.anyio def test_csv_to_geojson_1_mast() -> None: """Should create a valid geojson file from csv with 1 mast.""" input_csv = "tests/files/1_mast.csv" - output_geojson = "tests/files/1_mast.geojson" - csv_to_geojson(input_csv) - - with Path(output_geojson).open(encoding="utf-8") as f: - expected_content = f.read() - - with Path(output_geojson).open(encoding="utf-8") as f: - actual_content = f.read() - - assert expected_content == actual_content + actual_content = csv_to_geojson(input_csv) + + assert len(actual_content) == 1 + assert isinstance(actual_content[0], FeatureCollection) + assert actual_content[0].crs.properties.name == "EPSG:25832" + assert actual_content[0].features[0].geometry.coordinates == pytest.approx( + [585243.7955, 6544773.145] + , rel=1e-6) + assert actual_content[0].features[0].geometry.type == "Point" + assert actual_content[0].features[0].properties.feature_type == "NrlMast" + assert (actual_content[0] + .features[0] + .properties + .høydereferanse + ) == Høydereferanse.topp + assert (actual_content[0] + .features[0] + .properties + .komponentident + ) == uuid.UUID("fa1bf202-345c-49f0-831b-5d5a12103612") + assert hasattr(actual_content[0].features[0].properties, "mast_type") + assert actual_content[0].features[0].properties.mast_type == "lavspentmast" + assert actual_content[0].features[0].properties.status == "planlagtOppført" + assert actual_content[0].features[0].properties.navn == "LM83700" + assert hasattr(actual_content[0] + .features[0] + .properties + .referanse, "komponentkodeverdi") + assert (actual_content[0] + .features[0] + .properties + .referanse.komponentkodeverdi + ) == "fa1bf202-345c-49f0-831b-5d5a12103612" + assert (actual_content[0] + .features[0] + .properties + .verifisert_rapporteringsnøyaktighet) == "0" @pytest.mark.anyio def test_csv_to_geojson_1_luftspenn() -> None: """Should create a valid geojson file from csv with 1 luftspenn.""" input_csv = "tests/files/1_luftspenn.csv" - output_geojson = "tests/files/1_luftspenn.geojson" - - csv_to_geojson(input_csv) - - with Path(output_geojson).open(encoding="utf-8") as f: - expected_content = f.read() - with Path(output_geojson).open(encoding="utf-8") as f: - actual_content = f.read() - - assert expected_content == actual_content + actual_content = csv_to_geojson(input_csv) + + assert len(actual_content) == 1 + assert isinstance(actual_content[0], FeatureCollection) + assert actual_content[0].crs.properties.name == "EPSG:25832" + assert actual_content[0].features[0].geometry.coordinates[0] == pytest.approx( + [582430.5569299466,6544040.344467209] + , rel=1e-4 + ) + assert actual_content[0].features[0].geometry.coordinates[1] == pytest.approx( + [582087.7992964027,6544042.579778018] + , rel=1e-4 + ) + assert actual_content[0].features[0].geometry.type == "LineString" + assert actual_content[0].features[0].properties.feature_type == "NrlLuftspenn" + assert (actual_content[0] + .features[0] + .properties + .komponentident + ) == uuid.UUID("d6716fda-aac4-4229-9e2d-690a32dc5214") + assert hasattr(actual_content[0].features[0].properties, "luftspenn_type") + assert actual_content[0].features[0].properties.luftspenn_type == "lavspent" + assert actual_content[0].features[0].properties.status == "planlagtOppført" + assert hasattr( + actual_content[0].features[0].properties.referanse, + "komponentkodeverdi" + ) + assert (actual_content[0] + .features[0] + .properties + .referanse + .komponentkodeverdi + ) == "d6716fda-aac4-4229-9e2d-690a32dc5214" + assert actual_content[0].features[0].properties.navn == "Luftnett" + assert (actual_content[0] + .features[0] + .properties + .verifisert_rapporteringsnøyaktighet + ) == "0" @pytest.mark.anyio def test_csv_to_geojson_1_bardun() -> None: """Should create a valid geojson file from csv with 1 bardun.""" input_csv = "tests/files/1_bardun.csv" - output_geojson = "tests/files/1_bardun.geojson" - - csv_to_geojson(input_csv) - - with Path(output_geojson).open(encoding="utf-8") as f: - expected_content = f.read() - - with Path(output_geojson).open(encoding="utf-8") as f: - actual_content = f.read() - assert expected_content == actual_content + actual_content = csv_to_geojson(input_csv) + + assert len(actual_content) == 1 + assert isinstance(actual_content[0], FeatureCollection) + assert actual_content[0].crs.properties.name == "EPSG:5972" + assert actual_content[0].features[0].geometry.coordinates[0] == pytest.approx( + [559404.7227,6539567.9961,0.0] + ,rel=1e-4 + ) + assert actual_content[0].features[0].geometry.coordinates[1] == pytest.approx( + [559419.7617,6539579.2813,0.0] + , rel=1e-4 + ) + assert actual_content[0].features[0].geometry.type == "LineString" + assert actual_content[0].features[0].properties.feature_type == "NrlLuftspenn" + assert hasattr(actual_content[0].features[0].properties, "luftspenn_type") + assert actual_content[0].features[0].properties.luftspenn_type == "bardun" + assert actual_content[0].features[0].properties.status == "eksisterende" + assert hasattr( + actual_content[0].features[0].properties.referanse, + "komponentkodeverdi" + ) + assert (actual_content[0] + .features[0] + .properties + .komponentident) == uuid.UUID( + "0291c89b-8294-4c5c-9061-445149e68330" + ) + assert (actual_content[0] + .features[0] + .properties + .referanse.komponentkodeverdi) == "188488519" + assert actual_content[0].features[0].properties.navn == "Bardunline" + assert (actual_content[0] + .features[0] + .properties + .verifisert_rapporteringsnøyaktighet) == "0" def test_csv_to_geojson_file_object() -> None: From 8c83225f1b991f1435efe03f797fd6bbf15fcddf Mon Sep 17 00:00:00 2001 From: Andrea-Devold-Fjeld Date: Tue, 7 Oct 2025 15:11:39 +0200 Subject: [PATCH 4/4] Testfiles in csv, and removed files no longer needed --- nrl-sdk-lib/tests/files/1_bardun.csv | 2 ++ nrl-sdk-lib/tests/files/1_bardun.geojson | 1 - nrl-sdk-lib/tests/files/1_bardun_xlsx.xlsx | Bin 10551 -> 0 bytes nrl-sdk-lib/tests/files/1_luftspenn.csv | 2 ++ nrl-sdk-lib/tests/files/1_luftspenn.geojson | 1 - nrl-sdk-lib/tests/files/1_luftspenn_xlsx.xlsx | Bin 10402 -> 0 bytes nrl-sdk-lib/tests/files/1_mast.csv | 2 ++ nrl-sdk-lib/tests/files/1_mast.geojson | 1 - nrl-sdk-lib/tests/files/1_mast.xlsx | Bin 10962 -> 0 bytes 9 files changed, 6 insertions(+), 3 deletions(-) create mode 100644 nrl-sdk-lib/tests/files/1_bardun.csv delete mode 100644 nrl-sdk-lib/tests/files/1_bardun.geojson delete mode 100644 nrl-sdk-lib/tests/files/1_bardun_xlsx.xlsx create mode 100644 nrl-sdk-lib/tests/files/1_luftspenn.csv delete mode 100644 nrl-sdk-lib/tests/files/1_luftspenn.geojson delete mode 100644 nrl-sdk-lib/tests/files/1_luftspenn_xlsx.xlsx create mode 100644 nrl-sdk-lib/tests/files/1_mast.csv delete mode 100644 nrl-sdk-lib/tests/files/1_mast.geojson delete mode 100644 nrl-sdk-lib/tests/files/1_mast.xlsx diff --git a/nrl-sdk-lib/tests/files/1_bardun.csv b/nrl-sdk-lib/tests/files/1_bardun.csv new file mode 100644 index 0000000..8fd5326 --- /dev/null +++ b/nrl-sdk-lib/tests/files/1_bardun.csv @@ -0,0 +1,2 @@ +ID;Tabell ID;Klasse;Klasse;Father ID;x1;y1;z1;x2;y2;z2;Lengde (m);Bryterens tilstand 1;Bryterens tilstand 2;Betegnelse;Betegnelse x;Betegnelse y;LabelDirection;Planbetegnelse;Brukernavn;Operativt område;Endret;Driftsstatus;Arbeidets ID;Statistic;Datakilde;Status;Planlagt endring;Opprinnelig plan;Systemoperatør;Ekstern ID;Eksternt område-ID;Konstruksjon ID;Teknisk type-ID;CutId;Område;Eier;Guy_uuid;Miljø;Dybde (cm);Tverrsnitt-ID;Merknad;HREF (Lidar);SmartGIS verfisert;ObjektID (Lidar);Mast_2_ObjectID;Mast_1_ObjectID;Luftspenntype (NRL);Rapportering (NRL);Hoydereferanse (NRL);Vertikalavstand meter (NRL);Verifisert nøyaktighet (NRL);Status (NRL);Kvalitet (Lidar);Brannklasse;NRL Datavask merknad Lede;NRL Datavask kommentar Lede;NRL Datavask Komponentident;NRL Datavask - Kommentar Kartv;NRL Datavask - Eiermatch;UUIDv4;Anleggsbredde meter (NRL);Luftfartshinderlyssetting(NRL);Luftfartshindermerking (NRL);Typebetegnelse Fiber rør;Prosjektansvarlig selskap;Stikkledning;Stedfestingsarsak;Datafangstdato;Vertikalniva;Maks avvik horisontalt (cm);Maks avvik vertikalt (cm);Hoydereferanse;Stedfestingsforhold;Noyaktighet hoyde (cm);Malemetode hoyde (cm);Malemetode;Hovedbruk;NRL_Eiermatch;Ytre hoyde (cm);Ytre bredde (cm);Regional_Nett;UBW-nummer;Typebetegnelse;Tverrsnitt;Create User;Create Date;Noyaktighet;Id på gml. erstattet komponent +188488519;261;11029;Bardunline;0;6539567,996;559404,7227;0;6539579,281;559419,7617;0;18,80234433;0;0;Bardunline;0;0;3,141592654;KGASLVLVLV;KGAS;70564885;19.09.2025;I bruk;0;0;Innmålt NRL;0;0;MAHEPOIENDRINGE;Lede AS;0;0;0;0;0;Larvik;Lede AS;0291c89b-8294-4c5c-9061-445149e68330;Ikke bestemt;0;0;;;;;;;Bardun;Rapporteres NRL;Velg;0;Ingen;Eksisterende;;Velg;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;MAHE2;08.11.2024;; \ No newline at end of file diff --git a/nrl-sdk-lib/tests/files/1_bardun.geojson b/nrl-sdk-lib/tests/files/1_bardun.geojson deleted file mode 100644 index 2d30d92..0000000 --- a/nrl-sdk-lib/tests/files/1_bardun.geojson +++ /dev/null @@ -1 +0,0 @@ -{"crs":{"type":"name","properties":{"name":"EPSG:5972"}},"features":[{"geometry":{"type":"LineString","coordinates":[[559404.72265625,6539567.99609375,-99999.0],[559419.76171875,6539579.28125,-99999.0]]},"properties":{"featureType":"NrlLuftspenn","luftspennType":"bardun","status":"eksisterende","komponentident":"0291c89b-8294-4c5c-9061-445149e68330","referanse":{"komponentkodeverdi":"188488519"},"navn":"188488519","informasjon":"","verifisertRapporteringsnøyaktighet":"0"}}]} \ No newline at end of file diff --git a/nrl-sdk-lib/tests/files/1_bardun_xlsx.xlsx b/nrl-sdk-lib/tests/files/1_bardun_xlsx.xlsx deleted file mode 100644 index 5d9a81c9058dfff5f03e5555d7bbe7d43e509ec1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10551 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 diff --git a/nrl-sdk-lib/tests/files/1_luftspenn.csv b/nrl-sdk-lib/tests/files/1_luftspenn.csv new file mode 100644 index 0000000..a30b819 --- /dev/null +++ b/nrl-sdk-lib/tests/files/1_luftspenn.csv @@ -0,0 +1,2 @@ +ID;Tabell ID;Klasse;Klasse;Father ID;x1;y1;z1;x2;y2;z2;Lengde (m);Bryterens tilstand 1;Bryterens tilstand 2;Betegnelse;Betegnelse x;Betegnelse y;LabelDirection;Planbetegnelse;Brukernavn;Operativt område;Endret;Driftsstatus;Arbeidets ID;Statistic;Datakilde;Status;Planlagt endring;Opprinnelig plan;Systemoperatør;Ekstern ID;Eksternt område-ID;Konstruksjon ID;Teknisk type-ID;CutId;Område;Eier;Miljø;Dybde (cm);Tverrsnitt-ID;Merknad;Luftspenntype (NRL);Rapportering (NRL);Hoydereferanse (NRL);Vertikalavstand meter (NRL);Verifisert nøyaktighet (NRL);Status (NRL);ObjektID (Lidar);Kvalitet (Lidar);NRL Datavask merknad Lede;NRL Datavask kommentar Lede;NRL Datavask Komponentident;NRL Datavask - Kommentar Kartv;NRL Datavask - Eiermatch;UUIDv4;Anleggsbredde meter (NRL);Luftfartshinderlyssetting(NRL);Luftfartshindermerking (NRL);Typebetegnelse Fiber rør;Prosjektansvarlig selskap;Stikkledning;Stedfestingsarsak;Datafangstdato;Vertikalniva;Maks avvik horisontalt (cm);Maks avvik vertikalt (cm);Hoydereferanse;Stedfestingsforhold;Noyaktighet hoyde (cm);Malemetode hoyde (cm);Malemetode;Hovedbruk;NRL_Eiermatch;Ytre hoyde (cm);Ytre bredde (cm);Regional_Nett;UBW-nummer;Typebetegnelse;Tverrsnitt;Create User;Create Date;Noyaktighet;Id på gml. erstattet komponent +d6716fda-aac4-4229-9e2d-690a32dc5214;261;11011;Luftnett LS trase;0;6544040,344;582430,5569;;6544042,58;582087,7993;;34276,49223;0;0;Luftnett;0;0;200;MABJLIDARNRL;INGEB;70564885;25.02.2025;I bruk;0;0;0;64;0;;Lede AS;0;0;0;0;0;Ski;Lede AS;Ikke bestemt;0;0;;Ledning, lavspent;Rapportering NRL utført;topp;;1;planlagtOppført;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; \ No newline at end of file diff --git a/nrl-sdk-lib/tests/files/1_luftspenn.geojson b/nrl-sdk-lib/tests/files/1_luftspenn.geojson deleted file mode 100644 index ae778bd..0000000 --- a/nrl-sdk-lib/tests/files/1_luftspenn.geojson +++ /dev/null @@ -1 +0,0 @@ -{"crs":{"type":"name","properties":{"name":"EPSG:5972"}},"features":[{"geometry":{"type":"LineString","coordinates":[[582430.5569299466,6544040.344467209,-99999.0],[582087.7992964027,6544042.579778018,-99999.0]]},"properties":{"featureType":"NrlLuftspenn","luftspennType":"lavspent","status":"eksisterende","komponentident":"1a085da3-6029-4703-8c3b-af6600238b51","referanse":{"komponentkodeverdi":"d6716fda-aac4-4229-9e2d-690a32dc5214"},"navn":"Luftnett","informasjon":"","verifisertRapporteringsnøyaktighet":"0"}}]} \ No newline at end of file diff --git a/nrl-sdk-lib/tests/files/1_luftspenn_xlsx.xlsx b/nrl-sdk-lib/tests/files/1_luftspenn_xlsx.xlsx deleted file mode 100644 index cba92f017412c863afd52523a5e758ef53f7b156..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10402 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 N1;OYWgZ{U-{{wOEdItai diff --git a/nrl-sdk-lib/tests/files/1_mast.csv b/nrl-sdk-lib/tests/files/1_mast.csv new file mode 100644 index 0000000..81cb9ab --- /dev/null +++ b/nrl-sdk-lib/tests/files/1_mast.csv @@ -0,0 +1,2 @@ +ID;Tabell ID;Klasse;Klasse;Father ID;x;y;z;Retning;Tilstand;Betegnelse;Betegnelse x;Betegnelse y;LabelDirection;Planbetegnelse;Brukernavn;Operativt område;Endret;Driftsstatus;Arbeidets ID;Statistic;Datakilde;Status;Planlagt endring;Opprinnelig plan;Område;Eier;Systemoperatør;Ekstern ID;Eksternt område-ID;Konstruksjon ID;Teknisk type-ID;Kombinert bruk;Installasjonsår;HSp-linje;LSp-linje;Totalhøyde (m);Høyde 2;Stolpeklasse;Synlig høyde (m);Stolpetype;Impregnering;Fundament-type;Type 1;Materiale 1;Isolator 1;Jordbånddiameter (mm);Kombinert bruk 1;Kombinert bruk 2;Kombinert bruk 3;Kombinert bruk 4;Kombinert bruk 5;Kombinert bruk 6;Merknad;Masttype (NRL);Utskiftningsår travers;UUIDv4;Rapportering (NRL);Hoydereferanse (NRL);Luftfartshinderlyssetting(NRL);Luftfartshindermerking (NRL);Vertikalavstand meter (NRL);Verifisert nøyaktighet (NRL);Status (NRL);Aktør 4;Aktør 5;Aktør 6;Søknads nr Aktør 4;Søknads nr Aktør 5;Søknads nr Aktør 6;Aktør Veilys;Kryssende luftspenn;GPS Longitude;GPS Latitude;UBW-nummer;Regional_Nett;INVKLASSE;SAMMENFØYINGITOPP;Create User;Create Date;Søknadsnr :;Søker :;Veilys mastnr :;Driftsmerking :;Fellesføring nr :;Avgrening;Hovedlinje;Bardun antall (Stk);Anleggsbidrag;Grunnforhold fundament;IsolatorType :;Bardun type;Jordelektrode (Type, mm2);MMS Tekst;Byggeklausulert bredde (m);Ryddeklausulert bredde (m);Horisontal faseavstand (m);Antall isolatorskåler (stk);Jordbånd dim. (cm);Samsvarserklæring;Årstall venstrebein;Årstall høyrebein;Årstall mitrebein;KILE_B;Aktør 1;Aktør 2;Aktør 3;Søknads nr Aktør 1;Søknads nr Aktør 2;Søknads nr Aktør 3;PD: Skalltykkelse(mm);PD: Min frisk diameter(mm);PD: Min diameter(mm);Stagtvinge bardun;Til plan (MMS);PD: Underdimisjonert;PD: Råtten/Byttes;Avgang;Stasjon;Id på gml. erstattet komponent;Risikoindeks +fa1bf202-345c-49f0-831b-5d5a12103612;109;650;LS Stolpe;0;6544773,145;585243,7955;;81;0;LM83700;0;0;0;MABJLIDARNRL;THORH;70564885;25.02.2025;I bruk;0;0;8501;64;0;;Kristiansand;Lede AS;Lede AS;0;0;0;0;Nei;2001;0;650;0;0;0;11;Tre;Salt;Stolpe på fjell;;;;180;Udefinert;Udefinert;Udefinert;Udefinert;Udefinert;Udefinert;;Mast, lavspent;;;Rapportering NRL utført;topp;;;;1;planlagtOppført;;;;;;;;;11.62986;67.77285;;;;;;;;;;;;;;;;;;;;;;;;;18;;;;;;;;;;;;;;;;;;;;;; \ No newline at end of file diff --git a/nrl-sdk-lib/tests/files/1_mast.geojson b/nrl-sdk-lib/tests/files/1_mast.geojson deleted file mode 100644 index 2883dfa..0000000 --- a/nrl-sdk-lib/tests/files/1_mast.geojson +++ /dev/null @@ -1 +0,0 @@ -{"crs":{"type":"name","properties":{"name":"EPSG:25832"}},"features":[{"geometry":{"type":"Point","coordinates":[585243.7955070778,6544773.145291722]},"properties":{"featureType":"NrlMast","mastType":"lavspentmast","status":"eksisterende","komponentident":"9631125f-3e72-45b0-a098-6f7cd3bf8811","referanse":{"komponentkodeverdi":"fa1bf202-345c-49f0-831b-5d5a12103612"},"navn":"LM83700","kvalitet":{},"informasjon":"","verifisertRapporteringsnøyaktighet":"0"}}]} \ No newline at end of file diff --git a/nrl-sdk-lib/tests/files/1_mast.xlsx b/nrl-sdk-lib/tests/files/1_mast.xlsx deleted file mode 100644 index 10669fecaa9031ecdcb405640f3df5d8c7654286..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 10962 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 ZtrQic;UKdM03bm=J`l^zOZ8jr{{f<1o)rK9