unifi-network-maps 1.4.9__tar.gz → 1.4.11__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/CHANGELOG.md +14 -1
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/PKG-INFO +2 -2
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/pyproject.toml +2 -2
- unifi_network_maps-1.4.11/src/unifi_network_maps/__init__.py +1 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/model/topology.py +70 -16
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/render/lldp_md.py +23 -11
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/render/svg.py +8 -2
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps.egg-info/PKG-INFO +2 -2
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps.egg-info/requires.txt +1 -1
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/tests/test_clients.py +7 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/tests/test_svg.py +27 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/tests/test_topology.py +21 -0
- unifi_network_maps-1.4.9/src/unifi_network_maps/__init__.py +0 -1
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/CONTRIBUTING.md +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/LICENSE +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/LICENSES.md +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/MANIFEST.in +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/README.md +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/RELEASING.md +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/SECURITY.md +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/setup.cfg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/__main__.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/adapters/__init__.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/adapters/config.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/adapters/unifi.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/__init__.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/__init__.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/access-point.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/ISOPACKS_LICENSE +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/block.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/cache.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/cardterminal.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/cloud.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/cronjob.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/cube.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/desktop.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/diamond.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/dns.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/document.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/firewall.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/function-module.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/image.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/laptop.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/loadbalancer.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/lock.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/mail.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/mailmultiple.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/mobiledevice.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/office.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/package-module.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/paymentcard.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/plane.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/printer.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/pyramid.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/queue.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/router.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/server.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/speech.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/sphere.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/storage.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/switch-module.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/tower.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/truck-2.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/truck.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/user.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/isometric/vm.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/laptop.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/router-network.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/server-network.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/icons/server.svg +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/themes/dark.yaml +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/themes/default.yaml +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/cli/__init__.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/cli/__main__.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/cli/args.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/cli/main.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/cli/render.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/cli/runtime.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/io/__init__.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/io/debug.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/io/export.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/io/mkdocs_assets.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/io/mock_data.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/io/mock_generate.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/model/__init__.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/model/labels.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/model/lldp.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/model/mock.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/model/ports.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/render/__init__.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/render/device_ports_md.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/render/legend.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/render/markdown_tables.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/render/mermaid.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/render/mermaid_theme.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/render/mkdocs.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/render/svg_theme.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/render/templates/device_port_block.md.j2 +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/render/templates/legend_compact.html.j2 +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/render/templates/lldp_device_section.md.j2 +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/render/templates/markdown_section.md.j2 +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/render/templates/mermaid_legend.mmd.j2 +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/render/templates/mkdocs_document.md.j2 +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/render/templates/mkdocs_dual_theme_style.html.j2 +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/render/templates/mkdocs_html_block.html.j2 +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/render/templates/mkdocs_legend.css.j2 +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/render/templates/mkdocs_legend.js.j2 +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/render/templates/mkdocs_mermaid_block.md.j2 +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/render/templating.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/render/theme.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps.egg-info/SOURCES.txt +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps.egg-info/dependency_links.txt +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps.egg-info/entry_points.txt +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps.egg-info/top_level.txt +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/tests/test_cli.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/tests/test_config.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/tests/test_contract_unifi.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/tests/test_contract_unifi_live.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/tests/test_debug.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/tests/test_device_ports_md.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/tests/test_export.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/tests/test_groups.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/tests/test_labels.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/tests/test_lldp.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/tests/test_lldp_md.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/tests/test_mermaid.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/tests/test_mock_generate.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/tests/test_svg_iso.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/tests/test_theme.py +0 -0
- {unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/tests/test_unifi.py +0 -0
|
@@ -5,6 +5,17 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.4.11] - 2026-01-19
|
|
9
|
+
### Added
|
|
10
|
+
- Add data-edge-left/right attributes to SVG paths
|
|
11
|
+
|
|
12
|
+
### Fixed
|
|
13
|
+
- Regression in identifying wireless/wired clients
|
|
14
|
+
|
|
15
|
+
## [1.4.10] - 2026-01-18
|
|
16
|
+
### Added
|
|
17
|
+
- Add speed and channel fields to Edge dataclass
|
|
18
|
+
|
|
8
19
|
## [1.4.9] - 2026-01-15
|
|
9
20
|
### Changed
|
|
10
21
|
- Declared support for Python 3.12+ (3.13 preferred) and added CI coverage for 3.12.
|
|
@@ -165,7 +176,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
|
|
165
176
|
- Introduced SVG renderer and tree layout fixes.
|
|
166
177
|
- Increased test coverage and added coverage tooling.
|
|
167
178
|
|
|
168
|
-
[Unreleased]: https://github.com/merlijntishauser/unifi-network-maps/compare/v1.4.
|
|
179
|
+
[Unreleased]: https://github.com/merlijntishauser/unifi-network-maps/compare/v1.4.11...HEAD
|
|
180
|
+
[1.4.11]:https://github.com/merlijntishauser/unifi-network-maps/compare/v1.4.10...v1.4.111
|
|
181
|
+
[1.4.10]:https://github.com/merlijntishauser/unifi-network-maps/compare/v1.4.9...v1.4.10
|
|
169
182
|
[1.4.9]: https://github.com/merlijntishauser/unifi-network-maps/compare/v1.4.8...v1.4.9
|
|
170
183
|
[1.4.8]: https://github.com/merlijntishauser/unifi-network-maps/compare/v1.4.7...v1.4.8
|
|
171
184
|
[1.4.7]: https://github.com/merlijntishauser/unifi-network-maps/compare/v1.4.6...v1.4.7
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: unifi-network-maps
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.11
|
|
4
4
|
Summary: Dynamic UniFi -> network maps in mermaid or svg
|
|
5
5
|
Author: Merlijn
|
|
6
6
|
License-Expression: MIT
|
|
@@ -32,7 +32,7 @@ Requires-Dist: pre-commit==4.5.1; extra == "dev"
|
|
|
32
32
|
Requires-Dist: pytest==9.0.2; extra == "dev"
|
|
33
33
|
Requires-Dist: pytest-cov==7.0.0; extra == "dev"
|
|
34
34
|
Requires-Dist: pyright==1.1.408; extra == "dev"
|
|
35
|
-
Requires-Dist: ruff==0.14.
|
|
35
|
+
Requires-Dist: ruff==0.14.13; extra == "dev"
|
|
36
36
|
Dynamic: license-file
|
|
37
37
|
|
|
38
38
|
# unifi-network-maps
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "unifi-network-maps"
|
|
7
|
-
version = "1.4.
|
|
7
|
+
version = "1.4.11"
|
|
8
8
|
description = "Dynamic UniFi -> network maps in mermaid or svg"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.12"
|
|
@@ -44,7 +44,7 @@ dev = [
|
|
|
44
44
|
"pytest==9.0.2",
|
|
45
45
|
"pytest-cov==7.0.0",
|
|
46
46
|
"pyright==1.1.408",
|
|
47
|
-
"ruff==0.14.
|
|
47
|
+
"ruff==0.14.13"
|
|
48
48
|
]
|
|
49
49
|
|
|
50
50
|
[project.scripts]
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "1.4.11"
|
{unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/model/topology.py
RENAMED
|
@@ -37,6 +37,8 @@ class Edge:
|
|
|
37
37
|
label: str | None = None
|
|
38
38
|
poe: bool = False
|
|
39
39
|
wireless: bool = False
|
|
40
|
+
speed: int | None = None
|
|
41
|
+
channel: int | None = None
|
|
40
42
|
|
|
41
43
|
|
|
42
44
|
type DeviceSource = object
|
|
@@ -64,6 +66,7 @@ class PortInfo:
|
|
|
64
66
|
|
|
65
67
|
type PortMap = dict[tuple[str, str], str]
|
|
66
68
|
type PoeMap = dict[tuple[str, str], bool]
|
|
69
|
+
type SpeedMap = dict[tuple[str, str], int]
|
|
67
70
|
type ClientPortMap = dict[str, list[tuple[int, str]]]
|
|
68
71
|
|
|
69
72
|
|
|
@@ -421,7 +424,15 @@ def _tree_edges_from_parent(
|
|
|
421
424
|
tree_edges.append(Edge(left=parent_name, right=child))
|
|
422
425
|
else:
|
|
423
426
|
tree_edges.append(
|
|
424
|
-
Edge(
|
|
427
|
+
Edge(
|
|
428
|
+
left=parent_name,
|
|
429
|
+
right=child,
|
|
430
|
+
label=original.label,
|
|
431
|
+
poe=original.poe,
|
|
432
|
+
wireless=original.wireless,
|
|
433
|
+
speed=original.speed,
|
|
434
|
+
channel=original.channel,
|
|
435
|
+
)
|
|
425
436
|
)
|
|
426
437
|
return tree_edges
|
|
427
438
|
|
|
@@ -471,20 +482,31 @@ def _client_uplink_mac(client: object) -> str | None:
|
|
|
471
482
|
|
|
472
483
|
|
|
473
484
|
def _client_uplink_port(client: object) -> int | None:
|
|
474
|
-
for
|
|
475
|
-
|
|
476
|
-
if
|
|
477
|
-
return
|
|
478
|
-
|
|
479
|
-
|
|
485
|
+
for value in _client_port_values(client):
|
|
486
|
+
parsed = _parse_port_value(value)
|
|
487
|
+
if parsed is not None:
|
|
488
|
+
return parsed
|
|
489
|
+
return None
|
|
490
|
+
|
|
491
|
+
|
|
492
|
+
def _client_port_values(client: object) -> Iterable[object | None]:
|
|
493
|
+
for key in ("uplink_remote_port", "sw_port", "ap_port", "port_idx"):
|
|
494
|
+
yield _client_field(client, key)
|
|
480
495
|
for key in ("uplink", "last_uplink"):
|
|
481
496
|
nested = _client_field(client, key)
|
|
482
497
|
if isinstance(nested, dict):
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
498
|
+
for nested_key in ("uplink_remote_port", "port_idx"):
|
|
499
|
+
yield nested.get(nested_key)
|
|
500
|
+
|
|
501
|
+
|
|
502
|
+
def _parse_port_value(value: object | None) -> int | None:
|
|
503
|
+
if isinstance(value, int):
|
|
504
|
+
return value
|
|
505
|
+
if isinstance(value, str):
|
|
506
|
+
stripped = value.strip()
|
|
507
|
+
if stripped.isdigit():
|
|
508
|
+
return int(stripped)
|
|
509
|
+
return extract_port_number(stripped)
|
|
488
510
|
return None
|
|
489
511
|
|
|
490
512
|
|
|
@@ -492,6 +514,16 @@ def _client_is_wired(client: object) -> bool:
|
|
|
492
514
|
return bool(_client_field(client, "is_wired"))
|
|
493
515
|
|
|
494
516
|
|
|
517
|
+
def _client_channel(client: object) -> int | None:
|
|
518
|
+
for key in ("channel", "radio_channel", "wifi_channel"):
|
|
519
|
+
value = _client_field(client, key)
|
|
520
|
+
if isinstance(value, int):
|
|
521
|
+
return value
|
|
522
|
+
if isinstance(value, str) and value.isdigit():
|
|
523
|
+
return int(value)
|
|
524
|
+
return None
|
|
525
|
+
|
|
526
|
+
|
|
495
527
|
def _client_matches_mode(client: object, mode: str) -> bool:
|
|
496
528
|
wired = _client_is_wired(client)
|
|
497
529
|
if mode == "all":
|
|
@@ -528,12 +560,15 @@ def build_client_edges(
|
|
|
528
560
|
key = (device_name, name)
|
|
529
561
|
if key in seen:
|
|
530
562
|
continue
|
|
563
|
+
is_wireless = not _client_is_wired(client)
|
|
564
|
+
channel = _client_channel(client) if is_wireless else None
|
|
531
565
|
edges.append(
|
|
532
566
|
Edge(
|
|
533
567
|
left=device_name,
|
|
534
568
|
right=name,
|
|
535
569
|
label=label,
|
|
536
|
-
wireless=
|
|
570
|
+
wireless=is_wireless,
|
|
571
|
+
channel=channel,
|
|
537
572
|
)
|
|
538
573
|
)
|
|
539
574
|
seen.add(key)
|
|
@@ -572,12 +607,14 @@ def build_edges(
|
|
|
572
607
|
seen: set[frozenset[str]] = set()
|
|
573
608
|
port_map: PortMap = {}
|
|
574
609
|
poe_map: PoeMap = {}
|
|
610
|
+
speed_map: SpeedMap = {}
|
|
575
611
|
|
|
576
612
|
devices_with_lldp_edges = _collect_lldp_links(
|
|
577
613
|
ordered_devices,
|
|
578
614
|
index,
|
|
579
615
|
port_map,
|
|
580
616
|
poe_map,
|
|
617
|
+
speed_map,
|
|
581
618
|
raw_links,
|
|
582
619
|
seen,
|
|
583
620
|
only_unifi=only_unifi,
|
|
@@ -597,6 +634,7 @@ def build_edges(
|
|
|
597
634
|
raw_links,
|
|
598
635
|
port_map,
|
|
599
636
|
poe_map,
|
|
637
|
+
speed_map,
|
|
600
638
|
device_by_name,
|
|
601
639
|
include_ports=include_ports,
|
|
602
640
|
)
|
|
@@ -614,12 +652,14 @@ def build_port_map(devices: Iterable[Device], *, only_unifi: bool = True) -> Por
|
|
|
614
652
|
seen: set[frozenset[str]] = set()
|
|
615
653
|
port_map: PortMap = {}
|
|
616
654
|
poe_map: PoeMap = {}
|
|
655
|
+
speed_map: SpeedMap = {}
|
|
617
656
|
|
|
618
657
|
devices_with_lldp_edges = _collect_lldp_links(
|
|
619
658
|
ordered_devices,
|
|
620
659
|
index,
|
|
621
660
|
port_map,
|
|
622
661
|
poe_map,
|
|
662
|
+
speed_map,
|
|
623
663
|
raw_links,
|
|
624
664
|
seen,
|
|
625
665
|
only_unifi=only_unifi,
|
|
@@ -661,11 +701,19 @@ def build_client_port_map(
|
|
|
661
701
|
return port_map
|
|
662
702
|
|
|
663
703
|
|
|
704
|
+
def _port_speed_by_idx(port_table: list[PortInfo], port_idx: int) -> int | None:
|
|
705
|
+
for port in port_table:
|
|
706
|
+
if port.port_idx == port_idx:
|
|
707
|
+
return port.speed
|
|
708
|
+
return None
|
|
709
|
+
|
|
710
|
+
|
|
664
711
|
def _collect_lldp_links(
|
|
665
712
|
devices: list[Device],
|
|
666
713
|
index: dict[str, str],
|
|
667
714
|
port_map: PortMap,
|
|
668
715
|
poe_map: PoeMap,
|
|
716
|
+
speed_map: SpeedMap,
|
|
669
717
|
raw_links: list[tuple[str, str]],
|
|
670
718
|
seen: set[frozenset[str]],
|
|
671
719
|
*,
|
|
@@ -704,8 +752,12 @@ def _collect_lldp_links(
|
|
|
704
752
|
label = local_port_label(entry_for_label)
|
|
705
753
|
if label:
|
|
706
754
|
port_map[(device.name, peer_name)] = label
|
|
707
|
-
if resolved_port_idx is not None
|
|
708
|
-
|
|
755
|
+
if resolved_port_idx is not None:
|
|
756
|
+
if resolved_port_idx in poe_ports:
|
|
757
|
+
poe_map[(device.name, peer_name)] = poe_ports[resolved_port_idx]
|
|
758
|
+
port_speed = _port_speed_by_idx(device.port_table, resolved_port_idx)
|
|
759
|
+
if port_speed is not None:
|
|
760
|
+
speed_map[(device.name, peer_name)] = port_speed
|
|
709
761
|
|
|
710
762
|
key = frozenset({device.name, peer_name})
|
|
711
763
|
if key in seen:
|
|
@@ -794,6 +846,7 @@ def _build_ordered_edges(
|
|
|
794
846
|
raw_links: list[tuple[str, str]],
|
|
795
847
|
port_map: PortMap,
|
|
796
848
|
poe_map: PoeMap,
|
|
849
|
+
speed_map: SpeedMap,
|
|
797
850
|
device_by_name: dict[str, Device],
|
|
798
851
|
*,
|
|
799
852
|
include_ports: bool,
|
|
@@ -820,8 +873,9 @@ def _build_ordered_edges(
|
|
|
820
873
|
poe = poe_map.get((left_name, right_name), False) or poe_map.get(
|
|
821
874
|
(right_name, left_name), False
|
|
822
875
|
)
|
|
876
|
+
speed = speed_map.get((left_name, right_name)) or speed_map.get((right_name, left_name))
|
|
823
877
|
label = compose_port_label(left_name, right_name, port_map) if include_ports else None
|
|
824
|
-
edges.append(Edge(left=left_name, right=right_name, label=label, poe=poe))
|
|
878
|
+
edges.append(Edge(left=left_name, right=right_name, label=label, poe=poe, speed=speed))
|
|
825
879
|
return edges
|
|
826
880
|
|
|
827
881
|
|
{unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/render/lldp_md.py
RENAMED
|
@@ -5,6 +5,7 @@ from __future__ import annotations
|
|
|
5
5
|
from collections.abc import Iterable
|
|
6
6
|
|
|
7
7
|
from ..model.lldp import LLDPEntry, local_port_label
|
|
8
|
+
from ..model.ports import extract_port_number
|
|
8
9
|
from ..model.topology import Device, build_client_port_map, build_device_index, build_port_map
|
|
9
10
|
from .device_ports_md import render_device_port_details
|
|
10
11
|
from .markdown_tables import markdown_table_lines
|
|
@@ -44,20 +45,31 @@ def _client_uplink_mac(client: object) -> str | None:
|
|
|
44
45
|
|
|
45
46
|
|
|
46
47
|
def _client_uplink_port(client: object) -> int | None:
|
|
47
|
-
for
|
|
48
|
-
|
|
49
|
-
if
|
|
50
|
-
return
|
|
51
|
-
|
|
52
|
-
|
|
48
|
+
for value in _client_port_values(client):
|
|
49
|
+
parsed = _parse_port_value(value)
|
|
50
|
+
if parsed is not None:
|
|
51
|
+
return parsed
|
|
52
|
+
return None
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
def _client_port_values(client: object) -> Iterable[object | None]:
|
|
56
|
+
for key in ("uplink_remote_port", "sw_port", "ap_port", "port_idx"):
|
|
57
|
+
yield _client_field(client, key)
|
|
53
58
|
for key in ("uplink", "last_uplink"):
|
|
54
59
|
nested = _client_field(client, key)
|
|
55
60
|
if isinstance(nested, dict):
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
+
for nested_key in ("uplink_remote_port", "port_idx"):
|
|
62
|
+
yield nested.get(nested_key)
|
|
63
|
+
|
|
64
|
+
|
|
65
|
+
def _parse_port_value(value: object | None) -> int | None:
|
|
66
|
+
if isinstance(value, int):
|
|
67
|
+
return value
|
|
68
|
+
if isinstance(value, str):
|
|
69
|
+
stripped = value.strip()
|
|
70
|
+
if stripped.isdigit():
|
|
71
|
+
return int(stripped)
|
|
72
|
+
return extract_port_number(stripped)
|
|
61
73
|
return None
|
|
62
74
|
|
|
63
75
|
|
|
@@ -547,8 +547,11 @@ def _render_svg_edges(
|
|
|
547
547
|
f"L {dst_cx} {mid_y} L {dst_cx} {dst_top}"
|
|
548
548
|
)
|
|
549
549
|
dash = ' stroke-dasharray="6 4"' if edge.wireless else ""
|
|
550
|
+
left_attr = _escape_attr(edge.left, quote=True)
|
|
551
|
+
right_attr = _escape_attr(edge.right, quote=True)
|
|
550
552
|
lines.append(
|
|
551
|
-
f'<path d="{path}" stroke="{color}" stroke-width="{width_px}" fill="none"{dash}
|
|
553
|
+
f'<path d="{path}" stroke="{color}" stroke-width="{width_px}" fill="none"{dash} '
|
|
554
|
+
f'data-edge-left="{left_attr}" data-edge-right="{right_attr}"/>'
|
|
552
555
|
)
|
|
553
556
|
if edge.poe:
|
|
554
557
|
icon_x = dst_cx
|
|
@@ -834,9 +837,12 @@ def _render_iso_edges(
|
|
|
834
837
|
dst_cy,
|
|
835
838
|
)
|
|
836
839
|
dash = ' stroke-dasharray="8 6"' if edge.wireless else ""
|
|
840
|
+
left_attr = _escape_attr(edge.left, quote=True)
|
|
841
|
+
right_attr = _escape_attr(edge.right, quote=True)
|
|
837
842
|
lines.append(
|
|
838
843
|
f'<path d="{" ".join(path_cmds)}" stroke="{color}" stroke-width="{width_px}" '
|
|
839
|
-
f'fill="none" stroke-linecap="round" stroke-linejoin="round"{dash}
|
|
844
|
+
f'fill="none" stroke-linecap="round" stroke-linejoin="round"{dash} '
|
|
845
|
+
f'data-edge-left="{left_attr}" data-edge-right="{right_attr}"/>'
|
|
840
846
|
)
|
|
841
847
|
if edge.poe:
|
|
842
848
|
icon_x = dst_cx
|
{unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps.egg-info/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: unifi-network-maps
|
|
3
|
-
Version: 1.4.
|
|
3
|
+
Version: 1.4.11
|
|
4
4
|
Summary: Dynamic UniFi -> network maps in mermaid or svg
|
|
5
5
|
Author: Merlijn
|
|
6
6
|
License-Expression: MIT
|
|
@@ -32,7 +32,7 @@ Requires-Dist: pre-commit==4.5.1; extra == "dev"
|
|
|
32
32
|
Requires-Dist: pytest==9.0.2; extra == "dev"
|
|
33
33
|
Requires-Dist: pytest-cov==7.0.0; extra == "dev"
|
|
34
34
|
Requires-Dist: pyright==1.1.408; extra == "dev"
|
|
35
|
-
Requires-Dist: ruff==0.14.
|
|
35
|
+
Requires-Dist: ruff==0.14.13; extra == "dev"
|
|
36
36
|
Dynamic: license-file
|
|
37
37
|
|
|
38
38
|
# unifi-network-maps
|
|
@@ -36,6 +36,13 @@ def test_build_client_edges_includes_wireless_when_requested():
|
|
|
36
36
|
assert edges[0].wireless is True
|
|
37
37
|
|
|
38
38
|
|
|
39
|
+
def test_build_client_edges_includes_channel_for_wireless():
|
|
40
|
+
device_index = {"aa:bb:cc:dd:ee:ff": "AP One"}
|
|
41
|
+
clients = [{"name": "Phone", "ap_mac": "aa:bb:cc:dd:ee:ff", "is_wired": False, "channel": 36}]
|
|
42
|
+
edges = build_client_edges(clients, device_index, client_mode="wireless")
|
|
43
|
+
assert edges[0].channel == 36
|
|
44
|
+
|
|
45
|
+
|
|
39
46
|
def test_build_client_edges_includes_uplink_port_label():
|
|
40
47
|
device_index = {"aa:bb:cc:dd:ee:ff": "Switch A"}
|
|
41
48
|
clients = [
|
|
@@ -263,3 +263,30 @@ def test_render_svg_isometric_nodes_reference_iso_node_prefix():
|
|
|
263
263
|
[Edge("A", "B")], node_types={"A": "switch", "B": "switch"}
|
|
264
264
|
)
|
|
265
265
|
assert 'fill="url(#iso-node-switch)"' in output
|
|
266
|
+
|
|
267
|
+
|
|
268
|
+
def test_render_svg_adds_edge_data_attributes():
|
|
269
|
+
output = svg_module.render_svg(
|
|
270
|
+
[Edge("Gateway", "Switch")],
|
|
271
|
+
node_types={"Gateway": "gateway", "Switch": "switch"},
|
|
272
|
+
)
|
|
273
|
+
assert 'data-edge-left="Gateway"' in output
|
|
274
|
+
assert 'data-edge-right="Switch"' in output
|
|
275
|
+
|
|
276
|
+
|
|
277
|
+
def test_render_svg_escapes_edge_data_attributes():
|
|
278
|
+
output = svg_module.render_svg(
|
|
279
|
+
[Edge('Node "A"', "Node <B>")],
|
|
280
|
+
node_types={'Node "A"': "gateway", "Node <B>": "switch"},
|
|
281
|
+
)
|
|
282
|
+
assert 'data-edge-left="Node "A""' in output
|
|
283
|
+
assert 'data-edge-right="Node <B>"' in output
|
|
284
|
+
|
|
285
|
+
|
|
286
|
+
def test_render_svg_isometric_adds_edge_data_attributes():
|
|
287
|
+
output = svg_module.render_svg_isometric(
|
|
288
|
+
[Edge("Gateway", "Switch")],
|
|
289
|
+
node_types={"Gateway": "gateway", "Switch": "switch"},
|
|
290
|
+
)
|
|
291
|
+
assert 'data-edge-left="Gateway"' in output
|
|
292
|
+
assert 'data-edge-right="Switch"' in output
|
|
@@ -181,6 +181,22 @@ def test_build_edges_sets_poe_with_port_poe():
|
|
|
181
181
|
assert edges[0].poe is True
|
|
182
182
|
|
|
183
183
|
|
|
184
|
+
def test_build_edges_sets_speed_from_port():
|
|
185
|
+
dev_switch = DummyDevice(
|
|
186
|
+
"Switch A",
|
|
187
|
+
"aa:bb:cc:dd:ee:01",
|
|
188
|
+
[LLDPEntry("aa:bb:cc:dd:ee:02", "eth1", local_port_idx=1)],
|
|
189
|
+
port_table=[{"port_idx": 1, "speed": 1000}],
|
|
190
|
+
)
|
|
191
|
+
dev_ap = DummyDevice(
|
|
192
|
+
"AP One",
|
|
193
|
+
"aa:bb:cc:dd:ee:02",
|
|
194
|
+
[LLDPEntry("aa:bb:cc:dd:ee:01", "eth0")],
|
|
195
|
+
)
|
|
196
|
+
edges = build_edges(normalize_devices([dev_switch, dev_ap]))
|
|
197
|
+
assert edges[0].speed == 1000
|
|
198
|
+
|
|
199
|
+
|
|
184
200
|
def test_coerce_device_uses_lldp_fallback():
|
|
185
201
|
class DeviceWithLldp:
|
|
186
202
|
name = "Device"
|
|
@@ -486,6 +502,11 @@ def test_client_uplink_port_direct_str_digit():
|
|
|
486
502
|
assert _client_uplink_port(client) == 7
|
|
487
503
|
|
|
488
504
|
|
|
505
|
+
def test_client_uplink_port_parses_port_label():
|
|
506
|
+
client = {"uplink_remote_port": "Port 9"}
|
|
507
|
+
assert _client_uplink_port(client) == 9
|
|
508
|
+
|
|
509
|
+
|
|
489
510
|
def test_client_uplink_port_nested_int():
|
|
490
511
|
client = {"uplink": {"uplink_remote_port": 8}}
|
|
491
512
|
assert _client_uplink_port(client) == 8
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
__version__ = "1.4.9"
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/adapters/__init__.py
RENAMED
|
File without changes
|
{unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/adapters/config.py
RENAMED
|
File without changes
|
{unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/adapters/unifi.py
RENAMED
|
File without changes
|
{unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/assets/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/cli/__init__.py
RENAMED
|
File without changes
|
{unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/cli/__main__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/cli/runtime.py
RENAMED
|
File without changes
|
{unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/io/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/io/mkdocs_assets.py
RENAMED
|
File without changes
|
{unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/io/mock_data.py
RENAMED
|
File without changes
|
{unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/io/mock_generate.py
RENAMED
|
File without changes
|
{unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/model/__init__.py
RENAMED
|
File without changes
|
{unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/model/labels.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/model/ports.py
RENAMED
|
File without changes
|
{unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/render/__init__.py
RENAMED
|
File without changes
|
|
File without changes
|
{unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/render/legend.py
RENAMED
|
File without changes
|
|
File without changes
|
{unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/render/mermaid.py
RENAMED
|
File without changes
|
|
File without changes
|
{unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/render/mkdocs.py
RENAMED
|
File without changes
|
{unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/render/svg_theme.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/render/templating.py
RENAMED
|
File without changes
|
{unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps/render/theme.py
RENAMED
|
File without changes
|
{unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps.egg-info/SOURCES.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{unifi_network_maps-1.4.9 → unifi_network_maps-1.4.11}/src/unifi_network_maps.egg-info/top_level.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|