unifi-network-maps 1.4.14__tar.gz → 1.5.0__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.
Files changed (200) hide show
  1. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/CHANGELOG.md +48 -1
  2. unifi_network_maps-1.5.0/CONTRIBUTING.md +170 -0
  3. unifi_network_maps-1.5.0/LICENSES.md +77 -0
  4. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/PKG-INFO +107 -31
  5. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/README.md +101 -29
  6. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/pyproject.toml +18 -3
  7. unifi_network_maps-1.5.0/src/unifi_network_maps/__init__.py +1 -0
  8. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/adapters/unifi.py +83 -101
  9. unifi_network_maps-1.5.0/src/unifi_network_maps/assets/icons/modern/ap.svg +9 -0
  10. unifi_network_maps-1.5.0/src/unifi_network_maps/assets/icons/modern/camera.svg +9 -0
  11. unifi_network_maps-1.5.0/src/unifi_network_maps/assets/icons/modern/client.svg +9 -0
  12. unifi_network_maps-1.5.0/src/unifi_network_maps/assets/icons/modern/game_console.svg +10 -0
  13. unifi_network_maps-1.5.0/src/unifi_network_maps/assets/icons/modern/gateway.svg +17 -0
  14. unifi_network_maps-1.5.0/src/unifi_network_maps/assets/icons/modern/iot.svg +9 -0
  15. unifi_network_maps-1.5.0/src/unifi_network_maps/assets/icons/modern/nas.svg +9 -0
  16. unifi_network_maps-1.5.0/src/unifi_network_maps/assets/icons/modern/other.svg +10 -0
  17. unifi_network_maps-1.5.0/src/unifi_network_maps/assets/icons/modern/phone.svg +10 -0
  18. unifi_network_maps-1.5.0/src/unifi_network_maps/assets/icons/modern/printer.svg +9 -0
  19. unifi_network_maps-1.5.0/src/unifi_network_maps/assets/icons/modern/speaker.svg +10 -0
  20. unifi_network_maps-1.5.0/src/unifi_network_maps/assets/icons/modern/switch.svg +10 -0
  21. unifi_network_maps-1.5.0/src/unifi_network_maps/assets/icons/modern/tv.svg +10 -0
  22. unifi_network_maps-1.5.0/src/unifi_network_maps/assets/icons/modern-flat/ap.svg +5 -0
  23. unifi_network_maps-1.5.0/src/unifi_network_maps/assets/icons/modern-flat/camera.svg +5 -0
  24. unifi_network_maps-1.5.0/src/unifi_network_maps/assets/icons/modern-flat/client.svg +5 -0
  25. unifi_network_maps-1.5.0/src/unifi_network_maps/assets/icons/modern-flat/game_console.svg +6 -0
  26. unifi_network_maps-1.5.0/src/unifi_network_maps/assets/icons/modern-flat/gateway.svg +13 -0
  27. unifi_network_maps-1.5.0/src/unifi_network_maps/assets/icons/modern-flat/iot.svg +5 -0
  28. unifi_network_maps-1.5.0/src/unifi_network_maps/assets/icons/modern-flat/nas.svg +5 -0
  29. unifi_network_maps-1.5.0/src/unifi_network_maps/assets/icons/modern-flat/other.svg +6 -0
  30. unifi_network_maps-1.5.0/src/unifi_network_maps/assets/icons/modern-flat/phone.svg +6 -0
  31. unifi_network_maps-1.5.0/src/unifi_network_maps/assets/icons/modern-flat/printer.svg +5 -0
  32. unifi_network_maps-1.5.0/src/unifi_network_maps/assets/icons/modern-flat/speaker.svg +6 -0
  33. unifi_network_maps-1.5.0/src/unifi_network_maps/assets/icons/modern-flat/switch.svg +6 -0
  34. unifi_network_maps-1.5.0/src/unifi_network_maps/assets/icons/modern-flat/tv.svg +6 -0
  35. unifi_network_maps-1.5.0/src/unifi_network_maps/assets/themes/dark.yaml +93 -0
  36. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/themes/default.yaml +34 -0
  37. unifi_network_maps-1.5.0/src/unifi_network_maps/assets/themes/minimal-dark.yaml +98 -0
  38. unifi_network_maps-1.5.0/src/unifi_network_maps/assets/themes/minimal.yaml +92 -0
  39. unifi_network_maps-1.5.0/src/unifi_network_maps/assets/themes/unifi-dark.yaml +97 -0
  40. unifi_network_maps-1.5.0/src/unifi_network_maps/assets/themes/unifi.yaml +92 -0
  41. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/cli/args.py +54 -0
  42. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/cli/main.py +18 -7
  43. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/cli/render.py +79 -27
  44. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/cli/runtime.py +29 -15
  45. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/io/debug.py +2 -1
  46. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/io/export.py +19 -13
  47. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/io/mock_data.py +5 -3
  48. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/io/paths.py +5 -3
  49. unifi_network_maps-1.5.0/src/unifi_network_maps/model/classify.py +199 -0
  50. unifi_network_maps-1.5.0/src/unifi_network_maps/model/clients.py +271 -0
  51. unifi_network_maps-1.5.0/src/unifi_network_maps/model/connection.py +37 -0
  52. unifi_network_maps-1.5.0/src/unifi_network_maps/model/diff.py +544 -0
  53. unifi_network_maps-1.5.0/src/unifi_network_maps/model/edges.py +558 -0
  54. unifi_network_maps-1.5.0/src/unifi_network_maps/model/helpers.py +64 -0
  55. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/model/lldp.py +20 -25
  56. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/model/mock.py +110 -23
  57. unifi_network_maps-1.5.0/src/unifi_network_maps/model/snapshot.py +294 -0
  58. unifi_network_maps-1.5.0/src/unifi_network_maps/model/topology.py +205 -0
  59. unifi_network_maps-1.5.0/src/unifi_network_maps/model/topology_coerce.py +339 -0
  60. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/model/vlans.py +32 -46
  61. unifi_network_maps-1.5.0/src/unifi_network_maps/model/wan.py +132 -0
  62. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/render/device_ports_md.py +39 -97
  63. unifi_network_maps-1.5.0/src/unifi_network_maps/render/device_summary.py +53 -0
  64. unifi_network_maps-1.5.0/src/unifi_network_maps/render/lldp_md.py +261 -0
  65. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/render/markdown_tables.py +8 -0
  66. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/render/mermaid.py +11 -2
  67. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/render/mkdocs.py +2 -1
  68. unifi_network_maps-1.5.0/src/unifi_network_maps/render/svg.py +893 -0
  69. unifi_network_maps-1.5.0/src/unifi_network_maps/render/svg_icons.py +231 -0
  70. unifi_network_maps-1.4.14/src/unifi_network_maps/render/svg.py → unifi_network_maps-1.5.0/src/unifi_network_maps/render/svg_isometric.py +521 -560
  71. unifi_network_maps-1.5.0/src/unifi_network_maps/render/svg_labels.py +184 -0
  72. unifi_network_maps-1.5.0/src/unifi_network_maps/render/svg_theme.py +198 -0
  73. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/render/theme.py +86 -1
  74. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps.egg-info/PKG-INFO +107 -31
  75. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps.egg-info/SOURCES.txt +59 -2
  76. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps.egg-info/requires.txt +5 -1
  77. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/tests/test_cli.py +27 -12
  78. unifi_network_maps-1.5.0/tests/test_cli_render.py +461 -0
  79. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/tests/test_clients.py +60 -1
  80. unifi_network_maps-1.5.0/tests/test_connection.py +73 -0
  81. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/tests/test_contract_unifi.py +10 -8
  82. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/tests/test_contract_unifi_live.py +2 -0
  83. unifi_network_maps-1.5.0/tests/test_device_summary.py +178 -0
  84. unifi_network_maps-1.5.0/tests/test_diff.py +526 -0
  85. unifi_network_maps-1.5.0/tests/test_export.py +61 -0
  86. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/tests/test_groups.py +3 -7
  87. unifi_network_maps-1.5.0/tests/test_legend.py +67 -0
  88. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/tests/test_lldp_md.py +16 -8
  89. unifi_network_maps-1.5.0/tests/test_paths.py +342 -0
  90. unifi_network_maps-1.5.0/tests/test_runtime.py +308 -0
  91. unifi_network_maps-1.5.0/tests/test_smoketest_validation.py +410 -0
  92. unifi_network_maps-1.5.0/tests/test_snapshot.py +271 -0
  93. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/tests/test_svg.py +224 -27
  94. unifi_network_maps-1.5.0/tests/test_svg_advanced.py +309 -0
  95. unifi_network_maps-1.5.0/tests/test_svg_groups.py +192 -0
  96. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/tests/test_svg_iso.py +1 -1
  97. unifi_network_maps-1.5.0/tests/test_svg_labels.py +277 -0
  98. unifi_network_maps-1.5.0/tests/test_theme.py +132 -0
  99. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/tests/test_topology.py +389 -27
  100. unifi_network_maps-1.5.0/tests/test_topology_coerce.py +362 -0
  101. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/tests/test_unifi.py +2 -0
  102. unifi_network_maps-1.5.0/tests/test_visual_regression.py +189 -0
  103. unifi_network_maps-1.5.0/tests/test_vlans.py +191 -0
  104. unifi_network_maps-1.4.14/CONTRIBUTING.md +0 -90
  105. unifi_network_maps-1.4.14/LICENSES.md +0 -10
  106. unifi_network_maps-1.4.14/src/unifi_network_maps/__init__.py +0 -1
  107. unifi_network_maps-1.4.14/src/unifi_network_maps/assets/icons/isometric/printer.svg +0 -122
  108. unifi_network_maps-1.4.14/src/unifi_network_maps/assets/themes/dark.yaml +0 -50
  109. unifi_network_maps-1.4.14/src/unifi_network_maps/model/topology.py +0 -993
  110. unifi_network_maps-1.4.14/src/unifi_network_maps/render/lldp_md.py +0 -451
  111. unifi_network_maps-1.4.14/src/unifi_network_maps/render/svg_theme.py +0 -64
  112. unifi_network_maps-1.4.14/tests/test_export.py +0 -12
  113. unifi_network_maps-1.4.14/tests/test_theme.py +0 -39
  114. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/LICENSE +0 -0
  115. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/MANIFEST.in +0 -0
  116. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/RELEASING.md +0 -0
  117. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/SECURITY.md +0 -0
  118. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/setup.cfg +0 -0
  119. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/__main__.py +0 -0
  120. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/adapters/__init__.py +0 -0
  121. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/adapters/config.py +0 -0
  122. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/__init__.py +0 -0
  123. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/__init__.py +0 -0
  124. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/access-point.svg +0 -0
  125. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/ISOPACKS_LICENSE +0 -0
  126. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/block.svg +0 -0
  127. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/cache.svg +0 -0
  128. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/cardterminal.svg +0 -0
  129. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/cloud.svg +0 -0
  130. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/cronjob.svg +0 -0
  131. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/cube.svg +0 -0
  132. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/desktop.svg +0 -0
  133. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/diamond.svg +0 -0
  134. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/dns.svg +0 -0
  135. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/document.svg +0 -0
  136. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/firewall.svg +0 -0
  137. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/function-module.svg +0 -0
  138. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/image.svg +0 -0
  139. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/laptop.svg +0 -0
  140. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/loadbalancer.svg +0 -0
  141. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/lock.svg +0 -0
  142. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/mail.svg +0 -0
  143. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/mailmultiple.svg +0 -0
  144. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/mobiledevice.svg +0 -0
  145. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/office.svg +0 -0
  146. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/package-module.svg +0 -0
  147. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/paymentcard.svg +0 -0
  148. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/plane.svg +0 -0
  149. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/pyramid.svg +0 -0
  150. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/queue.svg +0 -0
  151. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/router.svg +0 -0
  152. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/server.svg +0 -0
  153. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/speech.svg +0 -0
  154. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/sphere.svg +0 -0
  155. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/storage.svg +0 -0
  156. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/switch-module.svg +0 -0
  157. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/tower.svg +0 -0
  158. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/truck-2.svg +0 -0
  159. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/truck.svg +0 -0
  160. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/user.svg +0 -0
  161. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/isometric/vm.svg +0 -0
  162. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/laptop.svg +0 -0
  163. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/router-network.svg +0 -0
  164. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/server-network.svg +0 -0
  165. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/assets/icons/server.svg +0 -0
  166. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/cli/__init__.py +0 -0
  167. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/cli/__main__.py +0 -0
  168. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/io/__init__.py +0 -0
  169. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/io/mkdocs_assets.py +0 -0
  170. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/io/mock_generate.py +0 -0
  171. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/model/__init__.py +0 -0
  172. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/model/labels.py +0 -0
  173. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/model/ports.py +0 -0
  174. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/render/__init__.py +0 -0
  175. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/render/legend.py +0 -0
  176. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/render/mermaid_theme.py +0 -0
  177. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/render/templates/device_port_block.md.j2 +0 -0
  178. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/render/templates/legend_compact.html.j2 +0 -0
  179. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/render/templates/lldp_device_section.md.j2 +0 -0
  180. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/render/templates/markdown_section.md.j2 +0 -0
  181. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/render/templates/mermaid_legend.mmd.j2 +0 -0
  182. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/render/templates/mkdocs_document.md.j2 +0 -0
  183. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/render/templates/mkdocs_dual_theme_style.html.j2 +0 -0
  184. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/render/templates/mkdocs_html_block.html.j2 +0 -0
  185. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/render/templates/mkdocs_legend.css.j2 +0 -0
  186. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/render/templates/mkdocs_legend.js.j2 +0 -0
  187. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/render/templates/mkdocs_mermaid_block.md.j2 +0 -0
  188. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps/render/templating.py +0 -0
  189. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps.egg-info/dependency_links.txt +0 -0
  190. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps.egg-info/entry_points.txt +0 -0
  191. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/src/unifi_network_maps.egg-info/top_level.txt +0 -0
  192. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/tests/test_config.py +0 -0
  193. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/tests/test_debug.py +0 -0
  194. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/tests/test_device_ports_md.py +0 -0
  195. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/tests/test_labels.py +0 -0
  196. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/tests/test_lldp.py +0 -0
  197. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/tests/test_mermaid.py +0 -0
  198. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/tests/test_mkdocs.py +0 -0
  199. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/tests/test_mock_generate.py +0 -0
  200. {unifi_network_maps-1.4.14 → unifi_network_maps-1.5.0}/tests/test_vlan_info.py +0 -0
@@ -5,6 +5,51 @@ 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
+ ## [Unreleased]
9
+
10
+ ## [1.5.0] - 2026-02-05
11
+ ### Added
12
+ - Add wireless connection quality metrics to edge data for Home Assistant integration (#24)
13
+ - Signal strength (dBm), noise floor, TX/RX rates, satisfaction score
14
+ - Automatic quality classification (excellent/good/fair/poor)
15
+ - Add `minimal-dark` theme with grayscale monochromatic styling
16
+ - Add topology diff API for change detection (#21)
17
+ - New `Topology` class with `to_dict()`, `from_dict()`, and `diff()` methods
18
+ - `compare_topologies()` function for stateless comparison
19
+ - Event-style change list with human-readable descriptions
20
+ - JSON serialization support for persistence and MQTT transmission
21
+ - Add SVG grouped layout mode (`--svg-layout-mode grouped`) with visual boundaries for network segments (#19)
22
+ - Add VLAN information to edge metadata with color-coded visualization (#20)
23
+ - Add `--theme` CLI argument for built-in themes: `unifi`, `unifi-dark`, `minimal`, `classic`, `classic-dark` (#22)
24
+ - Add theme properties: background, text colors, status indicators, WAN globe, grid color
25
+ - Add WAN upstream visualization with ISP label, link speed, and status indicator (`--wan-label`, `--wan-speed`, `--wan2-label`, `--wan2-speed`)
26
+ - Add `--icon-set` CLI argument for selectable icon sets: `isometric`, `modern` (#23)
27
+ - Add modern icon set with minimalistic isometric device icons
28
+ - Add themeable isometric grid color (`grid_color`) for per-theme floor grid styling
29
+ - Add `--max-vlan-colors` and `--include-vlan-legend` options for VLAN visualization
30
+ - Add `--collapse-clients` to group clients by uplink into cluster nodes with count badges
31
+ - Add theme matrix generator script (`make theme-matrix`) with composite PNG overview
32
+ - Theme YAML schema now supports `icon_set` and `grid_color` fields
33
+
34
+ ### Changed
35
+ - Align UniFi light/dark themes with official ui.com color palette from techspecs.ui.com/brand
36
+ - SVG renderer now uses theme-aware colors for background, text labels, and WAN box
37
+ - WAN port detection uses `wan_networkconf_id` field instead of hardcoded port numbers
38
+ - Light theme isometric grids use darker grid lines for better contrast (blue-tinted for UniFi, grey for others)
39
+
40
+ ### Removed
41
+ - Remove flat (Heroicons) and outline (Lucide) icon sets; consolidate to `isometric` and `modern`
42
+
43
+ ### Fixed
44
+ - Normalize gateway WAN port speeds from Gbps to Mbps for correct display (e.g., "10GbE" instead of "10MbE")
45
+
46
+ ## [1.4.15] - 2026-02-01
47
+ ### Changed
48
+ - Displaying of friendly device/model names
49
+
50
+ ### Fixed
51
+ - Handle disabled WAN interfaces gracefully (avoid unifi-controller-api model parse errors)
52
+
8
53
  ## [1.4.14] - 2026-02-01
9
54
  ### Added
10
55
  - JSON output with VLAN inventory
@@ -199,7 +244,9 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
199
244
  - Introduced SVG renderer and tree layout fixes.
200
245
  - Increased test coverage and added coverage tooling.
201
246
 
202
- [Unreleased]: https://github.com/merlijntishauser/unifi-network-maps/compare/v1.4.14...HEAD
247
+ [Unreleased]: https://github.com/merlijntishauser/unifi-network-maps/compare/v1.5.0...HEAD
248
+ [1.5.0]: https://github.com/merlijntishauser/unifi-network-maps/compare/v1.4.15...v1.5.0
249
+ [1.4.15]:https://github.com/merlijntishauser/unifi-network-maps/compare/v1.4.14...v1.4.15
203
250
  [1.4.14]:https://github.com/merlijntishauser/unifi-network-maps/compare/v1.4.11...v1.4.14
204
251
  [1.4.13]:https://github.com/merlijntishauser/unifi-network-maps/compare/v1.4.11...v1.4.13
205
252
  [1.4.12]:https://github.com/merlijntishauser/unifi-network-maps/compare/v1.4.11...v1.4.12
@@ -0,0 +1,170 @@
1
+ # Contributing
2
+
3
+ Thanks for considering a contribution!
4
+
5
+ ## Project Overview
6
+
7
+ **unifi-network-maps** is a Python CLI tool that generates network diagrams from UniFi Network Controller data via LLDP topology discovery.
8
+
9
+ ## Architecture
10
+
11
+ The project follows a clean pipeline architecture:
12
+
13
+ ```
14
+ ┌─────────────────────────────────────────────────────────────────────────────┐
15
+ │ Data Flow │
16
+ ├─────────────────────────────────────────────────────────────────────────────┤
17
+ │ │
18
+ │ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
19
+ │ │ Source │───▶│ Model │───▶│ Render │───▶│ Export │ │
20
+ │ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
21
+ │ │ │ │ │ │
22
+ │ UniFi API Topology Mermaid/SVG Files/ │
23
+ │ Mock data Devices MkDocs stdout │
24
+ │ Edges JSON │
25
+ │ VLANs │
26
+ │ │
27
+ └────────────────────────────────────────────────────────────────────────────┘
28
+ ```
29
+
30
+ ### Module Structure
31
+
32
+ ```
33
+ src/unifi_network_maps/
34
+ ├── cli/ # CLI entry point
35
+ │ ├── args.py # Argument definitions
36
+ │ ├── main.py # Entry point, orchestration
37
+ │ ├── render.py # Render dispatch logic
38
+ │ └── runtime.py # Runtime context management
39
+
40
+ ├── adapters/ # External data sources
41
+ │ ├── config.py # Environment/config loading
42
+ │ └── unifi.py # UniFi API adapter
43
+
44
+ ├── model/ # Core domain models
45
+ │ ├── topology.py # Device, Edge, Topology dataclasses
46
+ │ ├── clients.py # Client device handling
47
+ │ ├── connection.py # Wireless connection quality metrics
48
+ │ ├── lldp.py # LLDP neighbor parsing
49
+ │ ├── labels.py # Label generation utilities
50
+ │ ├── ports.py # Port handling and mapping
51
+ │ ├── vlans.py # VLAN inventory management
52
+ │ ├── mock.py # Mock data structures
53
+ │ ├── snapshot.py # Topology serialization
54
+ │ └── diff.py # Topology change detection
55
+
56
+ ├── render/ # Output renderers
57
+ │ ├── mermaid.py # Mermaid diagram output
58
+ │ ├── mermaid_theme.py # Mermaid theming
59
+ │ ├── svg.py # SVG output (orthogonal + isometric)
60
+ │ ├── svg_theme.py # SVG theming dataclass
61
+ │ ├── theme.py # Theme loading and resolution
62
+ │ ├── legend.py # Legend rendering
63
+ │ ├── mkdocs.py # MkDocs format output
64
+ │ ├── lldp_md.py # LLDP markdown tables
65
+ │ └── templating.py # Jinja2 template utilities
66
+
67
+ ├── io/ # File I/O operations
68
+ │ ├── export.py # File export utilities
69
+ │ ├── mock_data.py # Mock data loading
70
+ │ ├── mock_generate.py # Mock data generation (Faker)
71
+ │ ├── paths.py # Path resolution utilities
72
+ │ └── debug.py # Debug dump utilities
73
+
74
+ └── assets/ # Static assets
75
+ ├── icons/ # SVG device icons (isometric, modern, modern-flat)
76
+ └── themes/ # Theme YAML files
77
+ ```
78
+
79
+ ### Key Concepts
80
+
81
+ - **Topology**: Collection of `Device` nodes and `Edge` connections
82
+ - **Device**: Network device with type, name, MAC, model, ports
83
+ - **Edge**: Connection between devices with PoE status, VLAN, port info
84
+ - **ConnectionInfo**: Wireless quality metrics (signal, noise, rates)
85
+ - **Theme**: Visual styling for both Mermaid and SVG output
86
+
87
+ ## Development Setup
88
+
89
+ ```bash
90
+ python -m venv .venv
91
+ source .venv/bin/activate
92
+ pip install -r requirements-build.txt
93
+ pip install -r requirements-dev.txt -c constraints.txt
94
+ pre-commit install
95
+ ```
96
+
97
+ Editable install:
98
+
99
+ ```bash
100
+ pip install -e .
101
+ ```
102
+
103
+ ## Running Checks
104
+
105
+ ```bash
106
+ ruff check . # Linting
107
+ ruff format . # Formatting
108
+ pyright # Type checking
109
+ pytest # Unit tests
110
+ behave # BDD tests
111
+ ```
112
+
113
+ Or run everything with:
114
+
115
+ ```bash
116
+ make ci
117
+ ```
118
+
119
+ ### Testing Overview
120
+
121
+ | Type | Location | Command | Purpose |
122
+ |------|----------|---------|---------|
123
+ | Unit | `tests/` | `pytest` | Core logic |
124
+ | BDD | `features/` | `behave` | User scenarios |
125
+ | Contract | `tests/test_contract_unifi.py` | `pytest` | API fixtures |
126
+ | Visual | `tests/test_visual_regression.py` | `pytest` | SVG rendering |
127
+ | Smoketest | `scripts/smoketest.sh` | `make smoketest-mock` | End-to-end |
128
+
129
+ Notes:
130
+ - Live contract tests require `UNIFI_CONTRACT_LIVE=1` plus UniFi env vars.
131
+ - Visual regression uses `cairosvg` + `Pillow` for pixel comparison.
132
+ - Update visual baselines with `make visual-baselines` after intentional changes.
133
+
134
+ ## Useful Make Targets
135
+
136
+ ```bash
137
+ make ci # Run all checks
138
+ make smoketest-mock # End-to-end with mock data
139
+ make visual-regression # Compare SVG output
140
+ make visual-baselines # Update baseline images
141
+ make theme-matrix # Generate theme preview image
142
+ make mock-data # Generate mock JSON
143
+ make makefile-help # List all targets
144
+ ```
145
+
146
+ ## Release
147
+
148
+ ```bash
149
+ git tag -a vX.Y.Z -m "vX.Y.Z"
150
+ git push origin vX.Y.Z
151
+ python -m build
152
+ twine upload dist/*
153
+ ```
154
+
155
+ See `LICENSES.md` for third-party license info.
156
+
157
+ ## Code Guidelines
158
+
159
+ - Clear, intention-revealing names
160
+ - Small, focused functions (>15 lines is a code smell)
161
+ - Type annotations throughout
162
+ - No prints in core modules (use `logging`)
163
+ - Pure functions where possible
164
+ - Add tests for behavior changes
165
+ - Run `make ci` before opening a PR
166
+
167
+ ## Related Projects
168
+
169
+ - **Home Assistant integration**: [unifi-network-maps-ha](https://github.com/merlijntishauser/unifi-network-maps-ha)
170
+
@@ -0,0 +1,77 @@
1
+ # Third-Party Licenses
2
+
3
+ This document lists the licenses for third-party assets used in this project.
4
+
5
+ ## Icon Sets
6
+
7
+ ### Isometric Icon Set (Default)
8
+
9
+ #### markmanx/isopacks (MIT)
10
+
11
+ Isometric SVG icons in the isometric set are vendored under `src/unifi_network_maps/assets/icons/isometric/`.
12
+ The upstream MIT license is included at:
13
+
14
+ ```
15
+ src/unifi_network_maps/assets/icons/isometric/ISOPACKS_LICENSE
16
+ ```
17
+
18
+ ### Modern Icon Set
19
+
20
+ The modern icon set (`src/unifi_network_maps/assets/icons/modern/`) combines custom isometric
21
+ base shapes with Heroicons rendered on top using isometric matrix transforms.
22
+
23
+ #### Isometric Base Shapes (MIT)
24
+
25
+ Custom isometric base shapes created for this project, using the isopacks color palette
26
+ (#CDD9EE light, #B5C5DC medium, #6885A9 dark, #231F20 outline).
27
+
28
+ #### Heroicons (MIT)
29
+
30
+ Icon symbols from [Heroicons](https://heroicons.com/) by Tailwind Labs.
31
+
32
+ - Source: https://github.com/tailwindlabs/heroicons
33
+ - License: MIT License
34
+ - Icons used: globe-alt, server, wifi, computer-desktop
35
+
36
+ | Icon | Base Shape | Heroicon |
37
+ |------|------------|----------|
38
+ | gateway.svg | Cube | globe-alt |
39
+ | switch.svg | 1U rack | server |
40
+ | ap.svg | Disc | wifi |
41
+ | client.svg | Cube | computer-desktop |
42
+ | other.svg | Cube | server |
43
+
44
+ ## Fonts
45
+
46
+ ### Inter (SIL Open Font License 1.1)
47
+
48
+ The [Inter](https://rsms.me/inter/) typeface by Rasmus Andersson is used in the UniFi and UniFi Dark themes.
49
+ Variable WOFF2 files are vendored under `src/unifi_network_maps/assets/fonts/`.
50
+
51
+ - Source: https://github.com/rsms/inter
52
+ - License: SIL Open Font License 1.1
53
+ - License file: `src/unifi_network_maps/assets/fonts/INTER_LICENSE`
54
+
55
+ ### Space Grotesk (SIL Open Font License 1.1)
56
+
57
+ The [Space Grotesk](https://floriankarsten.github.io/space-grotesk/) typeface by Florian Karsten is used in the Minimal theme.
58
+ Variable WOFF2 files are vendored under `src/unifi_network_maps/assets/fonts/`.
59
+
60
+ - Source: https://github.com/floriankarsten/space-grotesk
61
+ - License: SIL Open Font License 1.1
62
+ - License file: `src/unifi_network_maps/assets/fonts/SPACE_GROTESK_LICENSE`
63
+
64
+ ## License Compatibility
65
+
66
+ When sourcing icons for this project, use license-compatible sources:
67
+
68
+ **Compatible licenses:**
69
+ - Public Domain / CC0
70
+ - MIT License
71
+ - Apache 2.0
72
+ - CC-BY (with attribution)
73
+ - BSD
74
+
75
+ **Not compatible:**
76
+ - CC-NC (Non-Commercial)
77
+ - GPL/LGPL (copyleft)
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: unifi-network-maps
3
- Version: 1.4.14
3
+ Version: 1.5.0
4
4
  Summary: Dynamic UniFi -> network maps in mermaid or svg
5
5
  Author: Merlijn
6
6
  License-Expression: MIT
@@ -26,13 +26,17 @@ Requires-Dist: python-dotenv==1.2.1
26
26
  Requires-Dist: PyYAML==6.0.3
27
27
  Requires-Dist: Jinja2==3.1.6
28
28
  Provides-Extra: dev
29
+ Requires-Dist: cairosvg==2.8.2; extra == "dev"
29
30
  Requires-Dist: Faker==40.1.2; extra == "dev"
30
31
  Requires-Dist: behave==1.3.3; extra == "dev"
32
+ Requires-Dist: Pillow==12.1.0; extra == "dev"
31
33
  Requires-Dist: pre-commit==4.5.1; extra == "dev"
32
34
  Requires-Dist: pytest==9.0.2; extra == "dev"
33
35
  Requires-Dist: pytest-cov==7.0.0; extra == "dev"
34
36
  Requires-Dist: pyright==1.1.408; extra == "dev"
35
- Requires-Dist: ruff==0.14.14; extra == "dev"
37
+ Requires-Dist: radon==6.0.1; extra == "dev"
38
+ Requires-Dist: ruff==0.15.0; extra == "dev"
39
+ Requires-Dist: xenon==0.9.3; extra == "dev"
36
40
  Dynamic: license-file
37
41
 
38
42
  # unifi-network-maps
@@ -158,6 +162,54 @@ unifi-network-maps --format json --output ./payload.json
158
162
  The live Home Assistant integration (Config Flow + coordinator + custom card) lives in a separate repo:
159
163
  - https://github.com/merlijntishauser/unifi-network-maps-ha
160
164
 
165
+ ## Programmatic API
166
+
167
+ Beyond the CLI, you can use the library programmatically for topology comparison and change detection.
168
+
169
+ ### Topology Diff API
170
+
171
+ Compare two topology snapshots to detect network changes:
172
+
173
+ ```python
174
+ from unifi_network_maps.model.topology import Topology
175
+
176
+ # Create or load topologies
177
+ old_topology = Topology.from_dict(json.load(open("old_snapshot.json")))
178
+ new_topology = Topology(devices=devices, clients=clients, edges=edges)
179
+
180
+ # Compare and get structured change events
181
+ diff = old_topology.diff(new_topology)
182
+
183
+ for event in diff.events:
184
+ print(f"{event.event_type}: {event.description}")
185
+ # Example: "node_added: Device 'switch-2' appeared on network"
186
+ # Example: "node_changed: Client 'laptop' changed VLAN from 10 to 20"
187
+
188
+ # Serialize for persistence or MQTT
189
+ json_str = diff.to_json()
190
+ ```
191
+
192
+ Event types:
193
+ - `node_added` / `node_removed` / `node_changed` - Device or client changes
194
+ - `edge_added` / `edge_removed` / `edge_changed` - Connection changes
195
+
196
+ Each event includes:
197
+ - `event_type`, `entity_type` (device/client), `identifier` (MAC)
198
+ - `name`, `description` (human-readable)
199
+ - `details` (full snapshot or change dict)
200
+
201
+ Serialize topology snapshots for storage:
202
+
203
+ ```python
204
+ # Save snapshot
205
+ snapshot = topology.to_dict()
206
+ json.dump(snapshot, open("topology.json", "w"))
207
+
208
+ # Load snapshot
209
+ data = json.load(open("topology.json"))
210
+ topology = Topology.from_dict(data)
211
+ ```
212
+
161
213
  ## Examples (mock data)
162
214
 
163
215
  These examples are generated from `examples/mock_data.json` (safe, anonymized fixture).
@@ -178,6 +230,13 @@ unifi-network-maps --mock-data examples/mock_data.json --include-ports --inclu
178
230
 
179
231
  ![Isometric network example](examples/output/network_ports_clients_iso.svg)
180
232
 
233
+ ### Themes & Icon Sets
234
+
235
+ Built-in themes (`--theme`) and icon sets (`--icon-set`) can be combined freely.
236
+ Regenerate this overview with `make theme-matrix`.
237
+
238
+ ![Theme × icon-set matrix](examples/themes/theme_matrix.png)
239
+
181
240
  Mermaid example with ports:
182
241
 
183
242
  ```mermaid
@@ -204,9 +263,6 @@ graph TB
204
263
  See `examples/mkdocs/` for a ready-to-use setup that renders Mermaid diagrams
205
264
  with Material for MkDocs, including a sample `unifi-network` page and legend.
206
265
 
207
- The built-in themes live at `src/unifi_network_maps/assets/themes/default.yaml` and
208
- `src/unifi_network_maps/assets/themes/dark.yaml`.
209
-
210
266
 
211
267
  ## Options
212
268
 
@@ -220,44 +276,63 @@ Source:
220
276
  Mock:
221
277
  - `--generate-mock`: write mock data JSON and exit.
222
278
  - `--mock-seed`: seed for deterministic mock generation.
223
- - `--mock-switches`: number of switches to generate.
224
- - `--mock-aps`: number of access points to generate.
225
- - `--mock-wired-clients`: number of wired clients to generate.
226
- - `--mock-wireless-clients`: number of wireless clients to generate.
279
+ - `--mock-switches`: number of switches to generate (default 1).
280
+ - `--mock-aps`: number of access points to generate (default 2).
281
+ - `--mock-wired-clients`: number of wired clients to generate (default 2).
282
+ - `--mock-wireless-clients`: number of wireless clients to generate (default 2).
227
283
 
228
284
  Functional:
229
285
  - `--include-ports`: show port labels (Mermaid shows both ends; SVG shows compact labels).
230
- - `--include-clients`: add active wired clients as leaf nodes.
286
+ - `--include-clients`: add active clients as leaf nodes.
231
287
  - `--client-scope wired|wireless|all`: which client types to include (default wired).
232
- - `--only-unifi`: only include neighbors that are UniFi devices; when clients are included, filters to UniFi-managed clients (by explicit UniFi flags or vendor/OUI).
288
+ - `--collapse-clients`: group clients by uplink device into cluster nodes with count badges.
289
+ - `--only-unifi`: only include neighbors that are UniFi devices; when clients are included, filters to UniFi-managed clients.
233
290
  - `--no-cache`: disable UniFi API cache reads and writes.
234
291
 
235
292
  Mermaid:
236
- - `--direction LR|TB`: diagram direction for Mermaid (default TB).
237
- - `--group-by-type`: group nodes by gateway/switch/AP in Mermaid subgraphs.
238
- - `--legend-scale`: scale legend font/link sizes for Mermaid outputs (default 1.0).
293
+ - `--direction LR|TB`: diagram direction (default TB).
294
+ - `--group-by-type`: group nodes by gateway/switch/AP in subgraphs.
295
+ - `--legend-scale`: scale legend font/link sizes (default 1.0).
239
296
  - `--legend-style auto|compact|diagram`: legend rendering mode (auto uses compact for mkdocs).
240
- - `--legend-only`: render just the legend as a separate Mermaid graph (Mermaid only).
297
+ - `--legend-only`: render just the legend as a separate Mermaid graph.
241
298
 
242
299
  SVG:
243
300
  - `--svg-width/--svg-height`: override SVG output dimensions.
244
- - `--theme-file`: load a YAML theme for Mermaid + SVG colors (see `examples/theme.yaml` and `examples/theme-dark.yaml`).
301
+ - `--theme`: built-in theme (`unifi`, `unifi-dark`, `minimal`, `classic`, `classic-dark`).
302
+ - `--theme-file`: custom theme YAML (takes priority over `--theme`; see `examples/theme.yaml`).
303
+ - `--icon-set isometric|modern`: icon set to use (default: determined by theme, or `isometric`).
304
+ - `--svg-layout-mode physical|grouped`: layout mode for SVG output (default physical).
305
+ - `--wan-label/--wan-speed`: WAN1 ISP name and provisioned speed.
306
+ - `--wan2-label/--wan2-speed`: WAN2 ISP name and provisioned speed.
307
+ - `--max-vlan-colors`: limit VLAN colors shown on edges (default: no limit).
308
+ - `--include-vlan-legend`: add VLAN color legend to SVG output.
245
309
 
246
310
  Output:
247
311
  - `--format mermaid|svg|svg-iso|lldp-md|mkdocs|json`: output format (default mermaid).
248
312
  - `--stdout`: write output to stdout.
249
- - `--markdown`: wrap Mermaid output in a code fence.
250
- - `--mkdocs-sidebar-legend`: write assets to place the compact legend in the MkDocs right sidebar.
313
+ - `--output`: write output to file.
314
+ - `--markdown`: wrap Mermaid output in a code fence for notes tools like Obsidian.
315
+ - `--mkdocs-sidebar-legend`: write sidebar legend assets next to the output file.
251
316
  - `--mkdocs-dual-theme`: render light/dark Mermaid blocks for Material theme switching.
252
- - `--mkdocs-timestamp-zone`: timezone for mkdocs timestamp (`Europe/Amsterdam` default; use `off` to disable).
317
+ - `--mkdocs-timestamp-zone`: timezone for mkdocs timestamp (default `Europe/Amsterdam`; use `off` to disable).
253
318
 
254
319
  Debug:
255
320
  - `--debug-dump`: dump gateway + sample devices to stderr for debugging.
256
321
  - `--debug-sample N`: number of non-gateway devices in debug dump (default 2).
257
322
 
258
- ## Theme file
323
+ ## Themes
324
+
325
+ Five built-in themes are available via `--theme`:
259
326
 
260
- Example theme YAML (override only the values you want):
327
+ | Theme | Style | Default icon set |
328
+ |-------|-------|-----------------|
329
+ | `unifi` | Clean light theme based on the [ui.com](https://ui.com) color palette | modern |
330
+ | `unifi-dark` | Dark variant using official Ubiquiti dark surface colors | modern |
331
+ | `minimal` | Neutral grey tones, understated | isometric |
332
+ | `classic` | Warm default palette with distinct device colors | isometric |
333
+ | `classic-dark` | Dark variant of classic | modern |
334
+
335
+ For custom colors, create a theme YAML and pass it with `--theme-file`. Override only the values you need:
261
336
 
262
337
  ```yaml
263
338
  mermaid:
@@ -267,28 +342,29 @@ mermaid:
267
342
  stroke: "#d98300"
268
343
  poe_link: "#1e88e5"
269
344
  svg:
345
+ icon_set: modern
346
+ grid_color: "#c0c8d0"
347
+ background: "#f9fafa"
270
348
  links:
271
349
  standard:
272
- from: "#2ecc71"
273
- to: "#1b8f4a"
274
- poe:
275
- from: "#1e88e5"
276
- to: "#0d47a1"
350
+ from: "#006fff"
351
+ to: "#0560d4"
277
352
  nodes:
278
353
  switch:
279
- from: "#d6ecff"
280
- to: "#b6dcff"
354
+ from: "#4dd88a"
355
+ to: "#38cc65"
281
356
  ```
282
357
 
358
+ See `examples/theme.yaml` and `examples/theme-dark.yaml` for full examples.
359
+
283
360
  ## Notes
284
361
 
285
362
  - Default output is top-to-bottom (TB) and rendered as a hop-based tree from the gateway(s).
286
363
  - Nodes are color-coded by type (gateway/switch/AP/client) with a sensible default palette.
287
- - PoE links are highlighted in blue and annotated with a power icon when detected from `port_table`.
364
+ - PoE links are annotated with a power icon when detected from `port_table`.
288
365
  - Wireless client links render as dashed lines to indicate the last-known upstream.
289
- - SVG output uses vendored device glyphs from `src/unifi_network_maps/assets/icons`.
290
- - Isometric SVG output uses MIT-licensed icons from `markmanx/isopacks`.
291
366
  - SVG port labels render inside child nodes for readability.
367
+ - Icon licenses and attribution are documented in [LICENSES.md](LICENSES.md).
292
368
 
293
369
 
294
370
  ## AI Disclosure