pyegeria 5.2.1.1__py3-none-any.whl → 5.3__py3-none-any.whl

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 (311) hide show
  1. commands/cat/.DS_Store +0 -0
  2. commands/cat/Dr-Egeria_md-orig.py +166 -0
  3. commands/cat/__init__.py +23 -0
  4. commands/cat/dr_egeria_jupyter.py +122 -0
  5. commands/cat/dr_egeria_md.py +247 -0
  6. {pyegeria/commands → commands}/cat/exp_list_glossaries.py +3 -4
  7. {pyegeria/commands → commands}/cat/get_asset_graph.py +4 -4
  8. {pyegeria/commands → commands}/cat/get_collection.py +8 -9
  9. {pyegeria/commands → commands}/cat/get_project_dependencies.py +6 -8
  10. {pyegeria/commands → commands}/cat/get_project_structure.py +6 -8
  11. {pyegeria/commands → commands}/cat/get_tech_type_elements.py +13 -15
  12. {pyegeria/commands → commands}/cat/glossary_actions.py +184 -34
  13. {pyegeria/commands → commands}/cat/list_assets.py +9 -6
  14. commands/cat/list_categories.py +192 -0
  15. {pyegeria/commands → commands}/cat/list_cert_types.py +6 -6
  16. {pyegeria/commands → commands}/cat/list_collections.py +62 -19
  17. commands/cat/list_data_structures.py +223 -0
  18. {pyegeria/commands → commands}/cat/list_deployed_catalogs.py +9 -8
  19. {pyegeria/commands → commands}/cat/list_deployed_database_schemas.py +10 -9
  20. {pyegeria/commands → commands}/cat/list_deployed_databases.py +9 -8
  21. pyegeria/commands/cat/list_servers_deployed_imp.py → commands/cat/list_deployed_servers.py +3 -3
  22. {pyegeria/commands → commands}/cat/list_glossaries.py +57 -15
  23. {pyegeria/commands → commands}/cat/list_projects.py +5 -5
  24. {pyegeria/commands → commands}/cat/list_tech_type_elements.py +3 -3
  25. {pyegeria/commands → commands}/cat/list_tech_types.py +4 -4
  26. {pyegeria/commands → commands}/cat/list_terms.py +93 -45
  27. {pyegeria/commands → commands}/cat/list_todos.py +3 -3
  28. {pyegeria/commands → commands}/cat/list_user_ids.py +9 -8
  29. {pyegeria/commands → commands}/cli/__init__.py +1 -1
  30. {pyegeria/commands → commands}/cli/egeria.py +506 -250
  31. {pyegeria/commands → commands}/cli/egeria_cat.py +127 -50
  32. {pyegeria/commands → commands}/cli/egeria_login_tui.py +15 -17
  33. {pyegeria/commands → commands}/cli/egeria_my.py +22 -15
  34. {pyegeria/commands → commands}/cli/egeria_ops.py +54 -55
  35. {pyegeria/commands → commands}/cli/egeria_tech.py +364 -152
  36. {pyegeria/commands → commands}/cli/ops_config.py +11 -4
  37. commands/cli/txt_custom_v2.tcss +19 -0
  38. commands/my/__init__.py +22 -0
  39. {pyegeria/commands → commands}/my/list_my_profile.py +6 -8
  40. {pyegeria/commands → commands}/my/list_my_roles.py +4 -4
  41. {pyegeria/commands → commands}/my/monitor_my_todos.py +7 -7
  42. {pyegeria/commands → commands}/my/monitor_open_todos.py +7 -7
  43. {pyegeria/commands → commands}/my/todo_actions.py +3 -2
  44. commands/ops/__init__.py +23 -0
  45. {pyegeria/commands → commands}/ops/gov_server_actions.py +5 -4
  46. {pyegeria/commands → commands}/ops/list_archives.py +7 -6
  47. {pyegeria/commands → commands}/ops/list_catalog_targets.py +4 -4
  48. {pyegeria/commands → commands}/ops/load_archive.py +4 -2
  49. {pyegeria/commands → commands}/ops/monitor_asset_events.py +8 -7
  50. {pyegeria/commands → commands}/ops/monitor_engine_activity.py +5 -5
  51. {pyegeria/commands → commands}/ops/monitor_engine_activity_c.py +3 -3
  52. {pyegeria/commands → commands}/ops/monitor_gov_eng_status.py +3 -2
  53. {pyegeria/commands → commands}/ops/monitor_integ_daemon_status.py +23 -15
  54. {pyegeria/commands → commands}/ops/monitor_platform_status.py +5 -4
  55. {pyegeria/commands → commands}/ops/monitor_server_startup.py +7 -7
  56. {pyegeria/commands → commands}/ops/monitor_server_status.py +16 -11
  57. {pyegeria/commands → commands}/ops/orig_monitor_server_list.py +2 -2
  58. {pyegeria/commands → commands}/ops/orig_monitor_server_status.py +3 -3
  59. {pyegeria/commands → commands}/ops/refresh_integration_daemon.py +4 -4
  60. {pyegeria/commands → commands}/ops/restart_integration_daemon.py +3 -3
  61. {pyegeria/commands → commands}/ops/table_integ_daemon_status.py +3 -3
  62. commands/tech/__init__.py +22 -0
  63. commands/tech/generic_actions.py +74 -0
  64. {pyegeria/commands → commands}/tech/get_element_info.py +5 -7
  65. {pyegeria/commands → commands}/tech/get_guid_info.py +4 -5
  66. {pyegeria/commands → commands}/tech/get_tech_details.py +8 -9
  67. {pyegeria/commands → commands}/tech/get_tech_type_template.py +4 -4
  68. pyegeria/commands/tech/list_elements.py → commands/tech/list_all_om_type_elements.py +11 -10
  69. pyegeria/commands/tech/list_elements_x.py → commands/tech/list_all_om_type_elements_x.py +11 -12
  70. pyegeria/commands/tech/list_related_elements.py → commands/tech/list_all_related_elements.py +11 -9
  71. {pyegeria/commands → commands}/tech/list_anchored_elements.py +16 -16
  72. {pyegeria/commands → commands}/tech/list_asset_types.py +4 -4
  73. commands/tech/list_elements_by_classification_by_property_value.py +200 -0
  74. commands/tech/list_elements_by_property_value.py +180 -0
  75. commands/tech/list_elements_by_property_value_x.py +201 -0
  76. {pyegeria/commands → commands}/tech/list_elements_for_classification.py +11 -9
  77. {pyegeria/commands → commands}/tech/list_gov_action_processes.py +5 -6
  78. commands/tech/list_information_supply_chains.py +167 -0
  79. {pyegeria/commands → commands}/tech/list_registered_services.py +3 -3
  80. commands/tech/list_related_elements_with_prop_value.py +221 -0
  81. {pyegeria/commands → commands}/tech/list_related_specification.py +3 -3
  82. {pyegeria/commands → commands}/tech/list_relationship_types.py +4 -5
  83. {pyegeria/commands → commands}/tech/list_relationships.py +3 -3
  84. commands/tech/list_solution_blueprints.py +181 -0
  85. commands/tech/list_solution_components.py +185 -0
  86. commands/tech/list_solution_roles.py +184 -0
  87. {pyegeria/commands → commands}/tech/list_tech_templates.py +3 -3
  88. {pyegeria/commands → commands}/tech/list_valid_metadata_values.py +5 -6
  89. {pyegeria/commands → commands}/tech/table_tech_templates.py +16 -13
  90. {pyegeria/commands → commands}/tech/x_list_related_elements.py +6 -4
  91. md_processing/__init__.py +49 -0
  92. md_processing/data/commands.json +3252 -0
  93. md_processing/dr_egeria_inbox/archive/dr_egeria_intro.md +254 -0
  94. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_more_terms.md +696 -0
  95. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part1.md +254 -0
  96. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part2.md +298 -0
  97. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part3.md +608 -0
  98. md_processing/dr_egeria_inbox/archive/dr_egeria_intro_part4.md +94 -0
  99. md_processing/dr_egeria_inbox/archive/freddie_intro.md +284 -0
  100. md_processing/dr_egeria_inbox/archive/freddie_intro_orig.md +275 -0
  101. md_processing/dr_egeria_inbox/archive/test-term.md +110 -0
  102. md_processing/dr_egeria_inbox/cat_test.md +100 -0
  103. md_processing/dr_egeria_inbox/data_field.md +54 -0
  104. md_processing/dr_egeria_inbox/data_spec.md +77 -0
  105. md_processing/dr_egeria_inbox/data_spec_test.md +2406 -0
  106. md_processing/dr_egeria_inbox/data_test.md +86 -0
  107. md_processing/dr_egeria_inbox/dr_egeria_intro_categories.md +168 -0
  108. md_processing/dr_egeria_inbox/dr_egeria_intro_part1.md +280 -0
  109. md_processing/dr_egeria_inbox/dr_egeria_intro_part2.md +313 -0
  110. md_processing/dr_egeria_inbox/dr_egeria_intro_part3.md +1073 -0
  111. md_processing/dr_egeria_inbox/dr_egeria_isc1.md +44 -0
  112. md_processing/dr_egeria_inbox/glossary_creation_experiment.ipynb +341 -0
  113. md_processing/dr_egeria_inbox/glossary_test1.md +324 -0
  114. md_processing/dr_egeria_inbox/rel.md +8 -0
  115. md_processing/dr_egeria_inbox/sb.md +119 -0
  116. md_processing/dr_egeria_inbox/search_test.md +39 -0
  117. md_processing/dr_egeria_inbox/solution-components.md +154 -0
  118. md_processing/dr_egeria_inbox/solution_blueprints.md +118 -0
  119. md_processing/dr_egeria_inbox/synonym_test.md +42 -0
  120. md_processing/dr_egeria_inbox/t2.md +268 -0
  121. md_processing/dr_egeria_outbox/processed-2025-05-15 19:52-data_test.md +94 -0
  122. md_processing/dr_egeria_outbox/processed-2025-05-16 07:39-data_test.md +88 -0
  123. md_processing/dr_egeria_outbox/processed-2025-05-17 16:01-data_field.md +56 -0
  124. md_processing/dr_egeria_outbox/processed-2025-05-18 15:51-data_test.md +103 -0
  125. md_processing/dr_egeria_outbox/processed-2025-05-18 16:47-data_test.md +94 -0
  126. md_processing/dr_egeria_outbox/processed-2025-05-19 07:14-data_test.md +96 -0
  127. md_processing/dr_egeria_outbox/processed-2025-05-19 07:20-data_test.md +100 -0
  128. md_processing/dr_egeria_outbox/processed-2025-05-19 07:22-data_test.md +88 -0
  129. md_processing/dr_egeria_outbox/processed-2025-05-19 09:26-data_test.md +91 -0
  130. md_processing/dr_egeria_outbox/processed-2025-05-19 10:27-data_test.md +91 -0
  131. md_processing/dr_egeria_outbox/processed-2025-05-19 14:04-data_test.md +91 -0
  132. md_processing/md_commands/__init__.py +3 -0
  133. md_processing/md_commands/blueprint_commands.py +303 -0
  134. md_processing/md_commands/data_designer_commands.py +1182 -0
  135. md_processing/md_commands/glossary_commands.py +1144 -0
  136. md_processing/md_commands/project_commands.py +163 -0
  137. md_processing/md_processing_utils/__init__.py +4 -0
  138. md_processing/md_processing_utils/common_md_proc_utils.py +724 -0
  139. md_processing/md_processing_utils/common_md_utils.py +172 -0
  140. md_processing/md_processing_utils/extraction_utils.py +486 -0
  141. md_processing/md_processing_utils/md_processing_constants.py +128 -0
  142. md_processing/md_processing_utils/message_constants.py +19 -0
  143. pyegeria/.DS_Store +0 -0
  144. pyegeria/__init__.py +231 -146
  145. pyegeria/_client.py +36 -13
  146. pyegeria/_exceptions.py +55 -46
  147. pyegeria/_globals.py +11 -1
  148. pyegeria/_validators.py +5 -5
  149. pyegeria/asset_catalog_omvs.py +78 -21
  150. pyegeria/automated_curation_omvs.py +11 -6
  151. pyegeria/classification_manager_omvs.py +41 -37
  152. pyegeria/collection_manager_omvs.py +722 -705
  153. pyegeria/core_omag_server_config.py +1 -1
  154. pyegeria/create_tech_guid_lists.py +13 -13
  155. pyegeria/data_designer_omvs.py +5104 -0
  156. pyegeria/dr.egeria spec.md +9 -0
  157. pyegeria/egeria_cat_client.py +5 -8
  158. pyegeria/egeria_client.py +39 -24
  159. pyegeria/egeria_config_client.py +2 -1
  160. pyegeria/egeria_my_client.py +4 -4
  161. pyegeria/egeria_tech_client.py +40 -18
  162. pyegeria/feedback_manager_omvs.py +1 -1
  163. pyegeria/full_omag_server_config.py +5 -3
  164. pyegeria/glossary_browser_omvs.py +1915 -694
  165. pyegeria/glossary_manager_omvs.py +685 -1842
  166. pyegeria/m_test.py +118 -0
  167. pyegeria/md_processing_helpers.py +58 -0
  168. pyegeria/md_processing_utils.py +2147 -0
  169. pyegeria/md_processing_utils_orig.py +1103 -0
  170. pyegeria/mermaid_utilities.py +1194 -14
  171. pyegeria/metadata_explorer_omvs.py +5 -50
  172. pyegeria/my_profile_omvs.py +3 -2
  173. pyegeria/output_formatter.py +389 -0
  174. pyegeria/platform_services.py +5 -5
  175. pyegeria/project_manager_omvs.py +97 -18
  176. pyegeria/runtime_manager_omvs.py +8 -10
  177. pyegeria/server_operations.py +2 -2
  178. pyegeria/solution_architect_omvs.py +2156 -0
  179. pyegeria/template_manager_omvs.py +13 -13
  180. pyegeria/utils.py +3 -1
  181. pyegeria/valid_metadata_omvs.py +5 -4
  182. pyegeria/x_action_author_omvs.py +3 -6
  183. {pyegeria-5.2.1.1.dist-info → pyegeria-5.3.dist-info}/METADATA +9 -8
  184. pyegeria-5.3.dist-info/RECORD +196 -0
  185. {pyegeria-5.2.1.1.dist-info → pyegeria-5.3.dist-info}/WHEEL +1 -1
  186. pyegeria-5.3.dist-info/entry_points.txt +99 -0
  187. pyegeria/commands/README.md +0 -47
  188. pyegeria/commands/__init__.py +0 -22
  189. pyegeria/commands/cat/__init__.py +0 -1
  190. pyegeria/commands/doc/README.md +0 -145
  191. pyegeria/commands/doc/Visual Command Reference/README.md +0 -511
  192. pyegeria/commands/doc/Visual Command Reference/cat/show/assets/asset-graph 2024-11-20 at 15.56.42.png +0 -0
  193. pyegeria/commands/doc/Visual Command Reference/cat/show/assets/assets-in-domain 2024-11-20 at 15.49.55@2x.png +0 -0
  194. pyegeria/commands/doc/Visual Command Reference/cat/show/assets/elements-of-type 2024-11-20 at 16.01.35.png +0 -0
  195. pyegeria/commands/doc/Visual Command Reference/cat/show/assets/tech-type-elements 2024-11-20 at 16.05.05.png +0 -0
  196. pyegeria/commands/doc/Visual Command Reference/cat/show/deployed-data/deployed-data-catalogs 2024-12-17 at 15.43.27@2x.png +0 -0
  197. pyegeria/commands/doc/Visual Command Reference/cat/show/deployed-data/deployed-data-catalogs-2024-11-20 at 16.17.43@2x.png +0 -0
  198. pyegeria/commands/doc/Visual Command Reference/cat/show/deployed-data/deployed-schemas 2024-11-25 at 20.14.50@2x.png +0 -0
  199. pyegeria/commands/doc/Visual Command Reference/cat/show/deployed-data/deployed-schemas 2024-12-17 at 15.48.38@2x.png +0 -0
  200. pyegeria/commands/doc/Visual Command Reference/cat/show/deployed-data/deployed-servers 2024-11-25 at 20.21.25@2x.png +0 -0
  201. pyegeria/commands/doc/Visual Command Reference/cat/show/deployed-data/deployed-servers 2024-12-17 at 15.52.16@2x.png +0 -0
  202. pyegeria/commands/doc/Visual Command Reference/cat/show/deployed-data/deployed_databases 2024-12-16 at 16.40.31@2x.png +0 -0
  203. pyegeria/commands/doc/Visual Command Reference/cat/show/glossary/list-glossaries 2024-11-25 at 20.30.02.png +0 -0
  204. pyegeria/commands/doc/Visual Command Reference/cat/show/glossary/list-terms 2024-11-25 at 20.32.11.png +0 -0
  205. pyegeria/commands/doc/Visual Command Reference/cat/show/info/asset-types 2024-11-25 at 20.34.19@2x.png +0 -0
  206. pyegeria/commands/doc/Visual Command Reference/cat/show/info/certification-types 2024-11-25 at 20.37.07.png +0 -0
  207. pyegeria/commands/doc/Visual Command Reference/cat/show/info/collection-graph 2024-12-12 at 11.33.18@2x.png +0 -0
  208. pyegeria/commands/doc/Visual Command Reference/cat/show/info/list-collections 2024-12-10 at 14.25.51@2x.png +0 -0
  209. pyegeria/commands/doc/Visual Command Reference/cat/show/info/list-todos 2024-12-12 at 11.46.30@2x.png +0 -0
  210. pyegeria/commands/doc/Visual Command Reference/cat/show/info/list-user-ids 2024-12-12 at 11.51.09@2x.png +0 -0
  211. pyegeria/commands/doc/Visual Command Reference/cat/show/info/tech-types 2024-12-12 at 11.37.20@2x.png +0 -0
  212. pyegeria/commands/doc/Visual Command Reference/cat/show/projects/project_dependencies 2024-12-14 at 16.24.39@2x.png +0 -0
  213. pyegeria/commands/doc/Visual Command Reference/cat/show/projects/project_structure 2024-12-14 at 16.21.35@2x.png +0 -0
  214. pyegeria/commands/doc/Visual Command Reference/cat/show/projects/projects 2024-12-14 at 16.18.10@2x.png +0 -0
  215. pyegeria/commands/doc/Visual Command Reference/hey_egeria tui 2024-12-16 at 16.58.22@2x.png +0 -0
  216. pyegeria/commands/doc/Visual Command Reference/my/show/my_profile 2024-12-14 at 16.29.27@2x.png +0 -0
  217. pyegeria/commands/doc/Visual Command Reference/my/show/my_roles 2024-12-14 at 16.32.10@2x.png +0 -0
  218. pyegeria/commands/doc/Visual Command Reference/my/show/my_todos 2024-12-15 at 16.24.13@2x.png +0 -0
  219. pyegeria/commands/doc/Visual Command Reference/my/show/open_todos 2024-12-14 at 16.36.12@2x.png +0 -0
  220. pyegeria/commands/doc/Visual Command Reference/ops/show/engines/list_engine_activity compressed 2024-12-15 at 16.48.48@2x.png +0 -0
  221. pyegeria/commands/doc/Visual Command Reference/ops/show/engines/monitor_engine_activity 2024-12-15 at 16.32.55@2x.png +0 -0
  222. pyegeria/commands/doc/Visual Command Reference/ops/show/engines/monitor_engine_activity compressed 2024-12-15 at 16.38.29@2x.png +0 -0
  223. pyegeria/commands/doc/Visual Command Reference/ops/show/engines/monitor_engine_status 2024-12-15 at 16.51.26.jpeg +0 -0
  224. pyegeria/commands/doc/Visual Command Reference/ops/show/integrations/monitor_integration_daemon_status 2024-12-15 at 16.57.12@2x.png +0 -0
  225. pyegeria/commands/doc/Visual Command Reference/ops/show/integrations/monitor_integration_targets 2024-12-15 at 17.02.19@2x.png +0 -0
  226. pyegeria/commands/doc/Visual Command Reference/ops/show/platforms/monitor_platform_status 2024-12-15 at 19.53.18@2x.png +0 -0
  227. pyegeria/commands/doc/Visual Command Reference/ops/show/servers/monitor_server_status 2024-12-15 at 19.59.39@2x.png +0 -0
  228. pyegeria/commands/doc/Visual Command Reference/ops/show/servers/monitor_server_status full 2024-12-15 at 20.01.57@2x.png +0 -0
  229. pyegeria/commands/doc/Visual Command Reference/ops/show/servers/monitor_startup_servers 2024-12-15 at 19.56.07@2x.png +0 -0
  230. pyegeria/commands/doc/Visual Command Reference/tech/show/elements/get_anchored_elements 2024-12-15 at 21.25.41@2x.png +0 -0
  231. pyegeria/commands/doc/Visual Command Reference/tech/show/elements/get_elements_of_om_type 2024-12-16 at 14.39.59@2x.png +0 -0
  232. pyegeria/commands/doc/Visual Command Reference/tech/show/elements/info_for_guid 2024-12-16 at 11.35.29@2x.png +0 -0
  233. pyegeria/commands/doc/Visual Command Reference/tech/show/elements/list_elements_by_om-type 2024-12-16 at 14.24.18@2x.png +0 -0
  234. pyegeria/commands/doc/Visual Command Reference/tech/show/elements/list_elements_by_om-type extended 2024-12-16 at 14.28.46@2x.png +0 -0
  235. pyegeria/commands/doc/Visual Command Reference/tech/show/elements/list_elements_of_om_type_by_classification 2024-12-16 at 14.35.26@2x.png +0 -0
  236. pyegeria/commands/doc/Visual Command Reference/tech/show/elements/related_elements 2024-12-16 at 14.55.01@2x.png +0 -0
  237. pyegeria/commands/doc/Visual Command Reference/tech/show/elements/show_related_specifications 2024-12-16 at 15.04.55@2x.png +0 -0
  238. pyegeria/commands/doc/Visual Command Reference/tech/show/tech-info/asset_types 2024-12-16 at 15.10.16@2x.png +0 -0
  239. pyegeria/commands/doc/Visual Command Reference/tech/show/tech-info/detailed_governance_action_processes 2024-12-16 at 15.16.26@2x.png +0 -0
  240. pyegeria/commands/doc/Visual Command Reference/tech/show/tech-info/governance_action_processes 2024-12-16 at 15.13.01@2x.png +0 -0
  241. pyegeria/commands/doc/Visual Command Reference/tech/show/tech-info/registered_services 2024-12-16 at 16.44.54@2x.png +0 -0
  242. pyegeria/commands/doc/Visual Command Reference/tech/show/tech-info/relationship_types 2024-12-16 at 16.20.34@2x.png +0 -0
  243. pyegeria/commands/doc/Visual Command Reference/tech/show/tech-info/relationship_types 2024-12-19 at 10.51.54@2x.png +0 -0
  244. pyegeria/commands/doc/Visual Command Reference/tech/show/tech-info/valid_metadata_values 2024-12-16 at 15.31.56@2x.png +0 -0
  245. pyegeria/commands/doc/Visual Command Reference/tech/show/tech-types/list_tech_type_template_specs 2024-12-16 at 16.03.22@2x.png +0 -0
  246. pyegeria/commands/doc/Visual Command Reference/tech/show/tech-types/list_technology_types 2024-12-16 at 15.39.20@2x.png +0 -0
  247. pyegeria/commands/doc/Visual Command Reference/tech/show/tech-types/tech_type_details 2024-12-16 at 15.37.21@2x.png +0 -0
  248. pyegeria/commands/doc/Visual Command Reference/tech/show/tech-types/tech_type_templates 2024-12-16 at 16.11.48@2x.png +0 -0
  249. pyegeria/commands/doc/glossary/basic-glossary-tui.md +0 -109
  250. pyegeria/commands/doc/glossary/images/delete-glossary-step1 2024-11-06 at 15.47.23@2x.png +0 -0
  251. pyegeria/commands/doc/glossary/images/delete-glossary-step2 2024-11-06 at 15.51.29@2x.png +0 -0
  252. pyegeria/commands/doc/glossary/images/delete-glossary-step3 2024-11-06 at 15.53.19@2x.png +0 -0
  253. pyegeria/commands/doc/glossary/images/delete-glossary-step4 2024-11-06 at 15.55.11@2x.png +0 -0
  254. pyegeria/commands/doc/glossary/images/out-create-glossary example 2024-11-05 at 20.38.04@2x.png +0 -0
  255. pyegeria/commands/doc/glossary/images/out-create-term 2024-11-06 at 20.48.29.png +0 -0
  256. pyegeria/commands/doc/glossary/images/out-delete-term 2024-11-07 at 03.57.25.png +0 -0
  257. pyegeria/commands/doc/glossary/images/out-display-terms-for-glossary-test 2024-11-06 at 20.51.28.png +0 -0
  258. pyegeria/commands/doc/glossary/images/out-export-example 2024-11-07 at 09.54.57.png +0 -0
  259. pyegeria/commands/doc/glossary/images/out-exported-terms 2024-11-06 at 21.06.32.png +0 -0
  260. pyegeria/commands/doc/glossary/images/out-glossary-list example 2024-11-05 at 20.41.02@2x.png +0 -0
  261. pyegeria/commands/doc/glossary/images/out-import-terms 2024-11-07 at 08.15.18.png +0 -0
  262. pyegeria/commands/doc/glossary/images/out-list-all-terms 2024-11-06 at 16.22.20@2x.png +0 -0
  263. pyegeria/commands/doc/glossary/images/out-list-terms-for-example 2024-11-06 at 16.40.12.png +0 -0
  264. pyegeria/commands/doc/glossary/images/out-list-terms-second 2024-11-06 at 16.45.13.png +0 -0
  265. pyegeria/commands/doc/glossary/images/out-pipx install pyegeria 2024-11-10 at 18.12.21.png +0 -0
  266. pyegeria/commands/doc/glossary/images/out-server-status-full 2024-11-10 at 18.25.14.png +0 -0
  267. pyegeria/commands/doc/glossary/images/out-servers-status 2024-11-10 at 18.15.42.png +0 -0
  268. pyegeria/commands/doc/glossary/images/out-upsert-import 2024-11-07 at 19.37.00.png +0 -0
  269. pyegeria/commands/doc/glossary/images/tui-2024-11-10 at 18.26.29.png +0 -0
  270. pyegeria/commands/doc/glossary/images/tui-create-glossary example 2024-11-05 at 20.34.24@2x.png +0 -0
  271. pyegeria/commands/doc/glossary/images/tui-create-term 2024-11-06 at 20.46.35.png +0 -0
  272. pyegeria/commands/doc/glossary/images/tui-delete-term 2024-11-07 at 03.51.57.png +0 -0
  273. pyegeria/commands/doc/glossary/images/tui-display-terms-for-example 2024-11-06 at 20.56.49.png +0 -0
  274. pyegeria/commands/doc/glossary/images/tui-export-example 2024-11-07 at 09.52.59.png +0 -0
  275. pyegeria/commands/doc/glossary/images/tui-hey-egeria 2024-11-10 at 18.31.01.png +0 -0
  276. pyegeria/commands/doc/glossary/images/tui-import-upsert-example 2024-11-07 at 10.08.37.png +0 -0
  277. pyegeria/commands/doc/glossary/images/tui-list-terms-second 2024-11-06 at 16.46.34.png +0 -0
  278. pyegeria/commands/doc/glossary/images/tui-load-archive.png +0 -0
  279. pyegeria/commands/doc/glossary/images/tui-server-status-full 2024-11-10 at 19.14.36.png +0 -0
  280. pyegeria/commands/doc/glossary/images/tui-show-glossaries 2024-11-07 at 20.00.05.png +0 -0
  281. pyegeria/commands/doc/glossary/images/tui-show-glossary-terms 2024-11-05 at 19.37.53@2x.png +0 -0
  282. pyegeria/commands/doc/glossary/images/tui-upsert 2024-11-07 at 11.49.04.png +0 -0
  283. pyegeria/commands/doc/glossary/images/upsert-example.om-terms 2024-11-07 at 11.44.05.png +0 -0
  284. pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/README.md +0 -346
  285. pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/CleanShot 2024-11-18 at 21.32.03@2x.png +0 -0
  286. pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/Xmind 1731421782704.png +0 -0
  287. pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/Xmind 1731422134920.png +0 -0
  288. pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/hey_egeria 2024-11-12 at 20.38.43.png +0 -0
  289. pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/hey_egeria cat 2024-11-12 at 21.41.43.png +0 -0
  290. pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/out-integ-status-list 2024-11-12 at 16.45.26.png +0 -0
  291. pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/out-integ-status-live 2024-11-12 at 16.44.12@2x.png +0 -0
  292. pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/out-server-status 2024-11-10 at 18.15.42@2x.png +0 -0
  293. pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/out-server-status-full 2024-11-10 at 18.25.14@2x.png +0 -0
  294. pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/short-cut commands 2024-11-12 at 22.22.13.png +0 -0
  295. pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/tui-hey-egeria.png +0 -0
  296. pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/tui-integration-status-paging.png +0 -0
  297. pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/tui-load-archive 2024-11-10 at 19.19.09@2x.png +0 -0
  298. pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/tui-show-server-status 2024-11-10 at 18.52.01@2x.png +0 -0
  299. pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/tui-show-server-status-full 2024-11-10.png +0 -0
  300. pyegeria/commands/doc/hey_egeria: a pyegeria command line interface/images/tui-status-paging 2024-11-12 at 16.26.14@2x.png +0 -0
  301. pyegeria/commands/ops/__init__.py +0 -22
  302. pyegeria/commands/tech/__init__.py +0 -0
  303. pyegeria-5.2.1.1.dist-info/RECORD +0 -231
  304. pyegeria-5.2.1.1.dist-info/entry_points.txt +0 -81
  305. {pyegeria/commands → commands}/cat/README.md +0 -0
  306. {pyegeria/commands → commands}/my/README.md +0 -0
  307. {pyegeria/commands → commands}/ops/README.md +0 -0
  308. {pyegeria/commands → commands}/ops/x_engine_actions.py +0 -0
  309. {pyegeria/commands → commands}/tech/README.md +0 -0
  310. /pyegeria/commands/my/__init__.py → /md_processing/dr_egeria_inbox/t1.md +0 -0
  311. {pyegeria-5.2.1.1.dist-info → pyegeria-5.3.dist-info}/LICENSE +0 -0
@@ -10,26 +10,29 @@ A running Egeria environment is needed to run these functions.
10
10
  These functions have been tested in a Jupyter notebook - but may work in other environments.
11
11
 
12
12
  """
13
-
13
+ import html
14
14
  import os
15
15
  import time
16
+ import uuid
16
17
 
17
18
  import nest_asyncio
18
19
 
19
20
  nest_asyncio.apply()
20
- from pyegeria import (
21
- AutomatedCuration,
21
+ from IPython.display import HTML, display
22
+ from rich.console import Console
23
+
24
+ from pyegeria.automated_curation_omvs import AutomatedCuration
25
+ from pyegeria._exceptions import (
22
26
  InvalidParameterException,
23
27
  PropertyServerException,
24
28
  UserNotAuthorizedException,
25
29
  )
26
- from IPython.display import display, HTML
27
- from rich.console import Console
30
+ from pyegeria._globals import NO_ELEMENTS_FOUND
28
31
 
29
32
  EGERIA_METADATA_STORE = os.environ.get("EGERIA_METADATA_STORE", "active-metadata-store")
30
33
  EGERIA_KAFKA_ENDPOINT = os.environ.get("KAFKA_ENDPOINT", "localhost:9092")
31
34
  EGERIA_PLATFORM_URL = os.environ.get("EGERIA_PLATFORM_URL", "https://localhost:9443")
32
- EGERIA_VIEW_SERVER = os.environ.get("VIEW_SERVER", "view-server")
35
+ EGERIA_VIEW_SERVER = os.environ.get("EGERIA_VIEW_SERVER", "view-server")
33
36
  EGERIA_VIEW_SERVER_URL = os.environ.get(
34
37
  "EGERIA_VIEW_SERVER_URL", "https://localhost:9443"
35
38
  )
@@ -40,27 +43,44 @@ EGERIA_USER = os.environ.get("EGERIA_USER", "erinoverview")
40
43
  EGERIA_USER_PASSWORD = os.environ.get("EGERIA_USER_PASSWORD", "secret")
41
44
  EGERIA_JUPYTER = bool(os.environ.get("EGERIA_JUPYTER", "False"))
42
45
  EGERIA_WIDTH = int(os.environ.get("EGERIA_WIDTH", "200"))
46
+ EGERIA_MERMAID_FOLDER = os.environ.get("EGERIA_MERMAID_FOLDER", "./work/mermaid_graphs")
43
47
 
44
48
 
45
49
  def load_mermaid():
46
50
  """Inject Mermaid.js library"""
51
+ # Alternative CDN URL via unpkg
47
52
  mermaid_js = """
48
- <script type="text/javascript">
49
- if (!window.mermaid) {
50
- var mermaidScript = document.createElement('script');
51
- mermaidScript.src = "https://cdnjs.cloudflare.com/ajax/libs/mermaid/10.9.1/mermaid.min.js";
52
- document.head.appendChild(mermaidScript);
53
- }
53
+ <script src="https://unpkg.com/mermaid@11.6.0/dist/mermaid.min.js"></script>
54
+ <script>
55
+ document.addEventListener('DOMContentLoaded', function() {
56
+ mermaid.initialize({startOnLoad: true},
57
+ {maxTextSize: 300000});
58
+ });
54
59
  </script>
60
+
55
61
  """
62
+
56
63
  display(HTML(mermaid_js))
57
64
 
58
65
 
59
66
  def render_mermaid(mermaid_code):
60
- """Function to display a Mermaid diagram in a Jupyter notebook"""
67
+ title_label, guid, mermaid_code = parse_mermaid_code(mermaid_code)
68
+ graph_id = f"mermaid-graph-{guid}-{str(uuid.uuid4())[:4]}"
69
+ escaped_header = html.escape(title_label) if title_label else "" # Sanitize the header safely
70
+ escaped_mermaid_code = html.escape(mermaid_code)
71
+ header_html = f"""
72
+ <h3 id="{graph_id}-heading" style="margin: 20px 0; font-size: 1.5em; text-align: center;">
73
+ {escaped_header}
74
+ </h3>
75
+ <p id="{graph_id}-subheading" style="margin: 0; padding: 5px; font-size: 1em; text-align: center; color: gray; flex: 0 0 auto;">
76
+ GUID: {guid}
77
+ </p>
78
+ """ if title_label else ""
79
+
61
80
  mermaid_html = f"""
81
+ <div>{header_html}</div>
62
82
  <div class="mermaid">
63
- {mermaid_code}
83
+ {escaped_mermaid_code}
64
84
  </div>
65
85
  <script type="text/javascript">
66
86
  if (window.mermaid) {{
@@ -72,6 +92,1166 @@ def render_mermaid(mermaid_code):
72
92
  display(HTML(mermaid_html))
73
93
 
74
94
 
95
+ def render_mermaid_adv(mermaid_code):
96
+ return display(HTML(construct_mermaid_web(mermaid_code)),)
97
+
98
+ def parse_mermaid_code(mermaid_code):
99
+ parts = mermaid_code.split("---", maxsplit=3)
100
+ guid = None
101
+ if len(parts) == 3:
102
+ full_title = parts[1].strip()
103
+ if "[" in full_title:
104
+ title_l = full_title.split("[")[0]
105
+ title = title_l.replace("title: ", "")
106
+ guid = full_title.split("[")[1].split("]")[0]
107
+ else:
108
+ title = full_title.replace("title: ", "")
109
+ mermaid_code = parts[2].strip()
110
+ else:
111
+ title = None
112
+ if guid is None:
113
+ guid = str(uuid.uuid4())[:8]
114
+ return title, guid, mermaid_code
115
+
116
+
117
+ def construct_mermaid_web(mermaid_str: str) -> str:
118
+ """Function to display a HTML code in a Jupyter notebook"""
119
+ title_label, guid, mermaid_code = parse_mermaid_code(mermaid_str)
120
+
121
+ html_section1 = """
122
+ <!DOCTYPE html>
123
+ <html>
124
+ <head>
125
+ <style type="text/css">
126
+ #mySvgId {
127
+ width: 100%;
128
+ height: 1200px;
129
+ overflow: scroll;
130
+ border: 2px solid #ccc;
131
+ position: relative;
132
+ margin-bottom: 10px;
133
+ }
134
+ svg {
135
+ cursor: grab;
136
+ }
137
+
138
+ </style>
139
+ </head>
140
+ """
141
+ html_section2 = f"""
142
+ <title>{title_label}</title>
143
+ <h3>{title_label}</h3>
144
+ GUID : {guid}
145
+
146
+ """
147
+ html_section3 = """
148
+ <body>
149
+
150
+ <div id="graphDiv"></div>
151
+ <script src="https://bumbu.me/svg-pan-zoom/dist/svg-pan-zoom.min.js"></script>
152
+ <script type="module">
153
+ import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
154
+
155
+ mermaid.initialize({startOnLoad: false});
156
+ await mermaid.run({
157
+ querySelector: '.mermaid',
158
+ postRenderCallback: (id) => {
159
+ const container = document.getElementById("diagram-container");
160
+ const svgElement = container.querySelector("svg");
161
+
162
+ // Initialize Panzoom
163
+ const panzoomInstance = Panzoom(svgElement, {
164
+ maxScale: 5,
165
+ minScale: 0.5,
166
+ step: 0.1,
167
+ });
168
+
169
+ // Add mouse wheel zoom
170
+ container.addEventListener("wheel", (event) => {
171
+ panzoomInstance.zoomWithWheel(event);
172
+ });
173
+ }
174
+ });
175
+
176
+
177
+ const drawDiagram = async function () {
178
+ const element = document.querySelector('#graphDiv');
179
+ const graphDefinition = `
180
+ """
181
+
182
+ html_section4 = r"""`;
183
+ const {svg} = await mermaid.render('mySvgId', graphDefinition);
184
+ element.innerHTML = svg.replace(/( )*max-width:( 0-9\.)*px;/i, '');
185
+
186
+ var doPan = false;
187
+ var eventsHandler;
188
+ var panZoom;
189
+ var mousepos;
190
+
191
+ eventsHandler = {
192
+ haltEventListeners: ['mousedown', 'mousemove', 'mouseup']
193
+
194
+ , mouseDownHandler: function (ev) {
195
+ if (event.target.className == "[object SVGAnimatedString]") {
196
+ doPan = true;
197
+ mousepos = {x: ev.clientX, y: ev.clientY}
198
+ }
199
+ ;
200
+ }
201
+
202
+ , mouseMoveHandler: function (ev) {
203
+ if (doPan) {
204
+ panZoom.panBy({x: ev.clientX - mousepos.x, y: ev.clientY - mousepos.y});
205
+ mousepos = {x: ev.clientX, y: ev.clientY};
206
+ window.getSelection().removeAllRanges();
207
+ }
208
+ }
209
+
210
+ , mouseUpHandler: function (ev) {
211
+ doPan = false;
212
+ }
213
+
214
+ , init: function (options) {
215
+ options.svgElement.addEventListener('mousedown', this.mouseDownHandler, false);
216
+ options.svgElement.addEventListener('mousemove', this.mouseMoveHandler, false);
217
+ options.svgElement.addEventListener('mouseup', this.mouseUpHandler, false);
218
+ }
219
+
220
+ , destroy: function (options) {
221
+ options.svgElement.removeEventListener('mousedown', this.mouseDownHandler, false);
222
+ options.svgElement.removeEventListener('mousemove', this.mouseMoveHandler, false);
223
+ options.svgElement.removeEventListener('mouseup', this.mouseUpHandler, false);
224
+ }
225
+ }
226
+ panZoom = svgPanZoom('#mySvgId', {
227
+ zoomEnabled: true
228
+ , controlIconsEnabled: true
229
+ , fit: 1
230
+ , center: 1
231
+ , customEventsHandler: eventsHandler
232
+ })
233
+ };
234
+ await drawDiagram();
235
+ </script>
236
+ </body>
237
+ """
238
+
239
+ return html_section1 + html_section2 + html_section3 + mermaid_code + html_section4
240
+
241
+ def construct_mermaid_jup(mermaid_str: str) -> str:
242
+ """Function to display a HTML code in a Jupyter notebook
243
+
244
+ Constructs HTML for a single Mermaid graph with pan and zoom support.
245
+ Each call overwrites the previous graph.
246
+
247
+ :param mermaid_code: The Mermaid code for the graph.
248
+ :param graph_id: An optional unique graph ID (default is 'mermaid-graph').
249
+ :return: The HTML content for the Mermaid graph with pan and zoom enabled.
250
+
251
+ """
252
+ title_label, guid, mermaid_code = parse_mermaid_code(mermaid_str)
253
+
254
+ graph_id = f"mermaid-graph-{guid}-{str(uuid.uuid4())[:4]}"
255
+ escaped_header = html.escape(title_label) if title_label else "" # Sanitize the header safely
256
+ escaped_mermaid_code = html.escape(mermaid_code)
257
+ header_html = f"""
258
+ <h3 id="{graph_id}-heading" style="margin: 20px 0; font-size: 1.5em; text-align: center;">
259
+ {escaped_header}
260
+ </h3>
261
+ <p id="{graph_id}-subheading" style="margin: 0; padding: 5px; font-size: 1em; text-align: center; color: gray; flex: 0 0 auto;">
262
+ GUID: {guid}
263
+ </p>
264
+ """ if title_label else ""
265
+
266
+ html_content = f"""
267
+ <style>
268
+ /* Style for the diagram container */
269
+ .diagram-container {{
270
+ position: relative;
271
+ width: 100%; /* Adjust the diagram container width */
272
+ height: 500px; /* Set a fixed height for the container */
273
+ margin: 0 auto;
274
+ border: 1px solid #ccc; /* Optional border for visualization */
275
+ overflow: hidden; /* Prevent content overflow outside the container */
276
+ }}
277
+
278
+ /* Style for zoom controls */
279
+ .svg-pan-zoom_controls {{
280
+ position: absolute;
281
+ top: 10px;
282
+ right: 10px;
283
+ display: flex;
284
+ flex-direction: column;
285
+ gap: 5px;
286
+ }}
287
+ .svg-pan-zoom_controls button {{
288
+ background-color: #007bff;
289
+ color: white;
290
+ border: none;
291
+ padding: 5px 10px;
292
+ border-radius: 3px;
293
+ cursor: pointer;
294
+ font-size: 14px;
295
+ }}
296
+ .svg-pan-zoom_controls button:hover {{
297
+ background-color: #0056b3;
298
+ }}
299
+ </style>
300
+
301
+ <div id="{graph_id}-container" class="diagram-container">
302
+ <!-- Mermaid diagram will be dynamically rendered here -->
303
+ {header_html}
304
+ <div id="{graph_id}" class="mermaid">
305
+ {escaped_mermaid_code}
306
+ </div>
307
+ </div>
308
+
309
+ <script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
310
+ <script src="https://cdn.jsdelivr.net/npm/svg-pan-zoom@3.6.1/dist/svg-pan-zoom.min.js"></script>
311
+ <script>
312
+ document.addEventListener("DOMContentLoaded", () => {{
313
+ // Initialize Mermaid and Pan-Zoom functionality
314
+ const graph_id = "{graph_id}";
315
+
316
+ function initializeMermaid(graph_id) {{
317
+ const containerElement = document.getElementById(`${{graph_id}}-container`);
318
+
319
+ if (!containerElement) {{
320
+ console.error(`Container with ID "${{graph_id}}-container" not found.`);
321
+ return;
322
+ }}
323
+
324
+ // Configure Mermaid
325
+ mermaid.initialize({{ startOnLoad: false, logLevel: "debug" }});
326
+ mermaid.init(undefined, `#${{graph_id}}`);
327
+
328
+ setTimeout(() => {{
329
+ const svg = containerElement.querySelector("svg");
330
+ if (!svg) {{
331
+ console.error(`SVG not rendered for ID "${{graph_id}}".`);
332
+ return;
333
+ }}
334
+
335
+ // Set initial size
336
+ svg.setAttribute("width", "100%");
337
+ svg.setAttribute("height", "100%");
338
+
339
+ // Initialize Pan-Zoom
340
+ const panZoom = svgPanZoom(svg, {{
341
+ zoomEnabled: true,
342
+ controlIconsEnabled: false,
343
+ fit: true,
344
+ center: true,
345
+ minZoom: 0.5,
346
+ maxZoom: 10,
347
+ contain: true
348
+ }});
349
+
350
+ // Add custom controls
351
+ const controlsContainer = document.createElement("div");
352
+ controlsContainer.className = "svg-pan-zoom_controls";
353
+ controlsContainer.innerHTML = `
354
+ <button id="${{graph_id}}-zoom-in">+</button>
355
+ <button id="${{graph_id}}-zoom-out">-</button>
356
+ <button id="${{graph_id}}-reset">Reset</button>
357
+ `;
358
+ containerElement.appendChild(controlsContainer);
359
+
360
+ // Handle controls
361
+ document.getElementById(`${{graph_id}}-zoom-in`).addEventListener("click", () => panZoom.zoomIn());
362
+ document.getElementById(`${{graph_id}}-zoom-out`).addEventListener("click", () => panZoom.zoomOut());
363
+ document.getElementById(`${{graph_id}}-reset`).addEventListener("click", () => {{
364
+ panZoom.resetZoom();
365
+ panZoom.center();
366
+ }});
367
+ }}, 500);
368
+ }}
369
+
370
+ if (typeof mermaid === "undefined") {{
371
+ const script = document.createElement('script');
372
+ script.src = "https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js";
373
+ script.onload = () => initializeMermaid(graph_id);
374
+ document.head.appendChild(script);
375
+ }} else {{
376
+ initializeMermaid(graph_id);
377
+ }}
378
+ }});
379
+ </script>
380
+
381
+ """
382
+ return html_content
383
+
384
+
385
+
386
+
387
+ def not_working_construct_mermaid_html(mermaid_str: str) -> str:
388
+ """Function to display a HTML code in a Jupyter notebook
389
+
390
+ Constructs HTML for a single Mermaid graph with pan and zoom support.
391
+ Each call overwrites the previous graph.
392
+
393
+ :param mermaid_code: The Mermaid code for the graph.
394
+ :param graph_id: An optional unique graph ID (default is 'mermaid-graph').
395
+ :return: The HTML content for the Mermaid graph with pan and zoom enabled.
396
+
397
+ """
398
+ title_label, guid, mermaid_code = parse_mermaid_code(mermaid_str)
399
+
400
+ graph_id = f"mermaid-graph-{guid}-{str(uuid.uuid4())[:4]}"
401
+ escaped_header = html.escape(title_label) if title_label else "" # Sanitize the header safely
402
+ escaped_mermaid_code = html.escape(mermaid_code)
403
+ header_html = f"""
404
+ <h3 id="{graph_id}-heading" style="margin: 20px 0; font-size: 1.5em; text-align: center;">
405
+ {escaped_header}
406
+ </h3>
407
+ <p id="{graph_id}-subheading" style="margin: 0; padding: 5px; font-size: 1em; text-align: center; color: gray; flex: 0 0 auto;">
408
+ GUID: {guid}
409
+ </p>
410
+ """ if title_label else ""
411
+
412
+ html_content = f"""
413
+ <style>
414
+ /* Style for the diagram container */
415
+ .diagram-container {{
416
+ position: relative;
417
+ width: 100%; /* Adjust the diagram container width */
418
+ height: 500px; /* Set a fixed height for the container */
419
+ margin: 0 auto;
420
+ border: 1px solid #ccc; /* Optional border for visualization */
421
+ overflow: hidden; /* Prevent content overflow outside the container */
422
+ }}
423
+
424
+ /* Style for zoom controls */
425
+ .svg-pan-zoom_controls {{
426
+ position: absolute;
427
+ top: 10px;
428
+ right: 10px;
429
+ display: flex;
430
+ flex-direction: column;
431
+ gap: 5px;
432
+ }}
433
+ .svg-pan-zoom_controls button {{
434
+ background-color: #007bff;
435
+ color: white;
436
+ border: none;
437
+ padding: 5px 10px;
438
+ border-radius: 3px;
439
+ cursor: pointer;
440
+ font-size: 14px;
441
+ }}
442
+ .svg-pan-zoom_controls button:hover {{
443
+ background-color: #0056b3;
444
+ }}
445
+ </style>
446
+
447
+ <div id="{graph_id}-container" class="diagram-container">
448
+ <!-- Mermaid diagram will be dynamically rendered here -->
449
+ {header_html}
450
+ <div id="{graph_id}" class="mermaid">
451
+ {escaped_mermaid_code}
452
+ </div>
453
+ </div>
454
+
455
+ <script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
456
+ <script src="https://cdn.jsdelivr.net/npm/svg-pan-zoom@3.6.1/dist/svg-pan-zoom.min.js"></script>
457
+ <script>
458
+ document.addEventListener("DOMContentLoaded", () => {{
459
+ // Initialize Mermaid and Pan-Zoom functionality
460
+ const graph_id = "{graph_id}";
461
+
462
+ function initializeMermaid(graph_id) {{
463
+ const containerElement = document.getElementById(`${{graph_id}}-container`);
464
+
465
+ if (!containerElement) {{
466
+ console.error(`Container with ID "${{graph_id}}-container" not found.`);
467
+ return;
468
+ }}
469
+
470
+ // Configure Mermaid
471
+ mermaid.initialize({{ startOnLoad: false, logLevel: "debug" }});
472
+ mermaid.init(undefined, `#${{graph_id}}`);
473
+
474
+ setTimeout(() => {{
475
+ const svg = containerElement.querySelector("svg");
476
+ if (!svg) {{
477
+ console.error(`SVG not rendered for ID "${{graph_id}}".`);
478
+ return;
479
+ }}
480
+
481
+ // Set initial size
482
+ svg.setAttribute("width", "100%");
483
+ svg.setAttribute("height", "100%");
484
+
485
+ // Initialize Pan-Zoom
486
+ const panZoom = svgPanZoom(svg, {{
487
+ zoomEnabled: true,
488
+ controlIconsEnabled: false,
489
+ fit: true,
490
+ center: true,
491
+ minZoom: 0.5,
492
+ maxZoom: 10,
493
+ contain: true
494
+ }});
495
+
496
+ // Add custom controls
497
+ const controlsContainer = document.createElement("div");
498
+ controlsContainer.className = "svg-pan-zoom_controls";
499
+ controlsContainer.innerHTML = `
500
+ <button id="${{graph_id}}-zoom-in">+</button>
501
+ <button id="${{graph_id}}-zoom-out">-</button>
502
+ <button id="${{graph_id}}-reset">Reset</button>
503
+ `;
504
+ containerElement.appendChild(controlsContainer);
505
+
506
+ // Handle controls
507
+ document.getElementById(`${{graph_id}}-zoom-in`).addEventListener("click", () => panZoom.zoomIn());
508
+ document.getElementById(`${{graph_id}}-zoom-out`).addEventListener("click", () => panZoom.zoomOut());
509
+ document.getElementById(`${{graph_id}}-reset`).addEventListener("click", () => {{
510
+ panZoom.resetZoom();
511
+ panZoom.center();
512
+ }});
513
+ }}, 500);
514
+ }}
515
+
516
+ if (typeof mermaid === "undefined") {{
517
+ const script = document.createElement('script');
518
+ script.src = "https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js";
519
+ script.onload = () => initializeMermaid(graph_id);
520
+ document.head.appendChild(script);
521
+ }} else {{
522
+ initializeMermaid(graph_id);
523
+ }}
524
+ }});
525
+ </script>
526
+
527
+ """
528
+ #
529
+ # return html_content
530
+ # This one almost works - no controls and diagram too small
531
+ # html_content = f"""
532
+ # <!DOCTYPE html>
533
+ # <html>
534
+ # <head>
535
+ # <style>
536
+ # /* Set consistent sizing and prevent shrinking for the container and parents */
537
+ # html, body, #{graph_id}-wrapper {{
538
+ # margin: 0;
539
+ # padding: 0;
540
+ # height: 100%; /* Ensure the entire root hierarchy respects 100% height */
541
+ # width: 100%;
542
+ # }}
543
+ #
544
+ # /* Ensure diagram container maintains full height and prevents overflow */
545
+ # #{graph_id}-container {{
546
+ # position: relative;
547
+ # width: 100%;
548
+ # height: 100%;
549
+ # overflow: hidden; /* Prevent content from breaking layout */
550
+ # display: flex;
551
+ # align-items: center; /* Centers the diagram vertically */
552
+ # justify-content: center; /* Centers the diagram horizontally */
553
+ # }}
554
+ #
555
+ # /* Ensure SVG always stretches to match container */
556
+ # #{graph_id} svg {{
557
+ # width: 100%;
558
+ # height: 100%;
559
+ # display: block; /* Avoid unwanted inline space issues */
560
+ # }}
561
+ #
562
+ # /* Optional custom pan/zoom controls (if dynamically added) */
563
+ # .svg-pan-zoom_controls {{
564
+ # position: absolute;
565
+ # bottom: 10px; /* Adjust based on desired placement */
566
+ # right: 10px;
567
+ # z-index: 10;
568
+ # display: flex;
569
+ # gap: 5px;
570
+ # }}
571
+ #
572
+ # .svg-pan-zoom_controls button {{
573
+ # border: 1px solid #ccc;
574
+ # background-color: #fff;
575
+ # color: #000;
576
+ # padding: 5px 10px;
577
+ # cursor: pointer;
578
+ # font-size: 16px;
579
+ # }}
580
+ #
581
+ # .svg-pan-zoom_controls button:hover {{
582
+ # background-color: #f0f0f0;
583
+ # }}
584
+ # </style>
585
+ # </head>
586
+ # <body>
587
+ # <div id="{graph_id}-wrapper">
588
+ # <!-- Title/Heading (optional; include as needed) -->
589
+ # {escaped_header if escaped_header else ""}
590
+ #
591
+ # <!-- Mermaid Diagram Container -->
592
+ # <div id="{graph_id}-container">
593
+ # <div id="{graph_id}" class="mermaid">
594
+ # {escaped_mermaid_code}
595
+ # </div>
596
+ # </div>
597
+ # </div>
598
+ #
599
+ # <script src="https://cdn.jsdelivr.net/npm/svg-pan-zoom@3.6.1/dist/svg-pan-zoom.min.js"></script>
600
+ # <script>
601
+ # document.addEventListener("DOMContentLoaded", () => {{
602
+ # // Define the graph ID dynamically passed via Python
603
+ # const graph_id = "{graph_id}";
604
+ #
605
+ # // Function to load external scripts dynamically
606
+ # function loadScript(url, callback) {{
607
+ # const script = document.createElement('script');
608
+ # script.src = url;
609
+ # script.async = true;
610
+ # script.onload = callback;
611
+ # script.onerror = () => console.error("Error loading script:", url);
612
+ # document.head.appendChild(script);
613
+ # }}
614
+ #
615
+ # // Function to initialize Mermaid
616
+ # function initializeMermaid(graph_id) {{
617
+ # // Look for the container ID generated dynamically by the template
618
+ # const containerElement = document.getElementById(`${{graph_id}}-container`);
619
+ # if (!containerElement) {{
620
+ # console.error(`Container element with id "${{graph_id}}-container" not found.`);
621
+ # return;
622
+ # }}
623
+ #
624
+ # // Initialize Mermaid.js with default configuration
625
+ # mermaid.initialize({{ startOnLoad: false, logLevel: "debug" }});
626
+ # mermaid.init(undefined, `#${{graph_id}}`); // Initialize element with id matching `graph_id`
627
+ #
628
+ # // Add a timeout to ensure the SVG is rendered
629
+ # setTimeout(() => {{
630
+ # const svg = containerElement.querySelector("svg");
631
+ #
632
+ # // Handle errors if SVG rendering fails
633
+ # if (!svg) {{
634
+ # console.error(`SVG not rendered for ID "${{graph_id}}". Check Mermaid syntax or rendering issues.`);
635
+ # console.log("Container content:", containerElement.innerHTML); // Log the container's content
636
+ # return;
637
+ # }}
638
+ #
639
+ # // Set SVG attributes for full container fit
640
+ # svg.setAttribute("width", "100%");
641
+ # svg.setAttribute("height", "100%");
642
+ #
643
+ # // Initialize SVG Pan-Zoom functionality
644
+ # const panZoom = svgPanZoom(svg, {{
645
+ # zoomEnabled: true,
646
+ # controlIconsEnabled: true, // Display default controls if enabled
647
+ # fit: true, // Fit diagram within the container
648
+ # center: true, // Center the diagram
649
+ # minZoom: 0.5, // Prevent too much zooming out
650
+ # maxZoom: 10, // Prevent extreme zooming in
651
+ # contain: true // Keep the diagram fully within bounds
652
+ # }});
653
+ #
654
+ # // Optional: Add custom pan/zoom controls dynamically
655
+ # const controlsContainer = document.createElement("div");
656
+ # controlsContainer.classList.add("svg-pan-zoom_controls");
657
+ # controlsContainer.innerHTML = `
658
+ # <button id="${{graph_id}}-zoom-in">+</button>
659
+ # <button id="${{graph_id}}-zoom-out">-</button>
660
+ # <button id="${{graph_id}}-reset">Reset</button>
661
+ # `;
662
+ # containerElement.appendChild(controlsContainer);
663
+ #
664
+ # // Add event listeners for the custom controls
665
+ # document.getElementById(`${{graph_id}}-zoom-in`).addEventListener("click", () => panZoom.zoomIn());
666
+ # document.getElementById(`${{graph_id}}-zoom-out`).addEventListener("click", () => panZoom.zoomOut());
667
+ # document.getElementById(`${{graph_id}}-reset`).addEventListener("click", () => {{
668
+ # panZoom.resetZoom();
669
+ # panZoom.center();
670
+ # }});
671
+ # }}, 500); // Short delay to ensure SVG rendering is complete
672
+ # }}
673
+ #
674
+ # // Load Mermaid.js if not already loaded
675
+ # if (typeof mermaid === "undefined") {{
676
+ # loadScript("https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js", () => {{
677
+ # console.log("Mermaid.js loaded successfully");
678
+ # initializeMermaid(graph_id); // Call initialization after Mermaid.js is loaded
679
+ # }});
680
+ # }} else {{
681
+ # initializeMermaid(graph_id); // If Mermaid.js is already loaded, proceed immediately
682
+ # }}
683
+ # }});
684
+ # </script>
685
+ #
686
+ #
687
+ # </body>
688
+ # </html>
689
+ # """
690
+
691
+
692
+
693
+
694
+
695
+ return html_content
696
+
697
+ # // Check if Mermaid and SVG-Pan-Zoom are loaded
698
+ # const loadMermaid = typeof mermaid === "undefined";
699
+ # const loadSvgPanZoom = typeof svgPanZoom === "undefined";
700
+ #
701
+ # if (loadMermaid || loadSvgPanZoom) {{
702
+ # const promises = [];
703
+ #
704
+ # // Load Mermaid.js if not already loaded
705
+ # if (loadMermaid) {{
706
+ # promises.push(new Promise((resolve) => {{
707
+ # const script = document.createElement("script");
708
+ # script.src = "https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js";
709
+ # script.onload = resolve;
710
+ # document.head.appendChild(script);
711
+ # }}));
712
+ # }}
713
+ #
714
+ # // Load SVG-Pan-Zoom if not already loaded
715
+ # if (loadSvgPanZoom) {{
716
+ # promises.push(new Promise((resolve) => {{
717
+ # const script = document.createElement("script");
718
+ # script.src = "https://cdn.jsdelivr.net/npm/svg-pan-zoom@3.6.1/dist/svg-pan-zoom.min.js";
719
+ # script.onload = resolve;
720
+ # document.head.appendChild(script);
721
+ # }}));
722
+ # }}
723
+ #
724
+ # Promise.all(promises).then(() => initializeMermaid(graph_id));
725
+ # }} else {{
726
+ # initializeMermaid(graph_id);
727
+ # }}
728
+ # }})();
729
+
730
+
731
+ # html_content = f"""
732
+ # <style>
733
+ # /* Style for the diagram container */
734
+ # .diagram-container {{
735
+ # position: relative;
736
+ # width: 100%; /* Adjust the diagram container width */
737
+ # height: 500px; /* Set a fixed height for the container */
738
+ # margin: 0 auto;
739
+ # border: 1px solid #ccc; /* Optional border for visualization */
740
+ # overflow: hidden; /* Prevent content overflow outside the container */
741
+ # }}
742
+ #
743
+ # /* Style for zoom controls */
744
+ # .svg-pan-zoom_controls {{
745
+ # position: absolute;
746
+ # top: 10px;
747
+ # right: 10px;
748
+ # display: flex;
749
+ # flex-direction: column;
750
+ # gap: 5px;
751
+ # }}
752
+ # .svg-pan-zoom_controls button {{
753
+ # background-color: #007bff;
754
+ # color: white;
755
+ # border: none;
756
+ # padding: 5px 10px;
757
+ # border-radius: 3px;
758
+ # cursor: pointer;
759
+ # font-size: 14px;
760
+ # }}
761
+ # .svg-pan-zoom_controls button:hover {{
762
+ # background-color: #0056b3;
763
+ # }}
764
+ # </style>
765
+ #
766
+ # <div id="{graph_id}-container" class="diagram-container">
767
+ # <!-- Mermaid diagram will be dynamically rendered here -->
768
+ # <div id="{graph_id}" class="mermaid">
769
+ # {mermaid_code}
770
+ # </div>
771
+ # </div>
772
+ #
773
+ # <script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
774
+ # <script src="https://cdn.jsdelivr.net/npm/svg-pan-zoom@3.6.1/dist/svg-pan-zoom.min.js"></script>
775
+ # <script>
776
+ # document.addEventListener("DOMContentLoaded", () => {{
777
+ # // Initialize Mermaid and Pan-Zoom functionality
778
+ # const graph_id = "{graph_id}";
779
+ #
780
+ # function initializeMermaid(graph_id) {{
781
+ # const containerElement = document.getElementById(`${{graph_id}}-container`);
782
+ #
783
+ # if (!containerElement) {{
784
+ # console.error(`Container with ID "${{graph_id}}-container" not found.`);
785
+ # return;
786
+ # }}
787
+ #
788
+ # // Configure Mermaid
789
+ # mermaid.initialize({{ startOnLoad: false, logLevel: "debug" }});
790
+ # mermaid.init(undefined, `#${{graph_id}}`);
791
+ #
792
+ # setTimeout(() => {{
793
+ # const svg = containerElement.querySelector("svg");
794
+ # if (!svg) {{
795
+ # console.error(`SVG not rendered for ID "${{graph_id}}".`);
796
+ # return;
797
+ # }}
798
+ #
799
+ # // Set initial size
800
+ # svg.setAttribute("width", "100%");
801
+ # svg.setAttribute("height", "100%");
802
+ #
803
+ # // Initialize Pan-Zoom
804
+ # const panZoom = svgPanZoom(svg, {{
805
+ # zoomEnabled: true,
806
+ # controlIconsEnabled: false,
807
+ # fit: true,
808
+ # center: true,
809
+ # minZoom: 0.5,
810
+ # maxZoom: 10,
811
+ # contain: true
812
+ # }});
813
+ #
814
+ # // Add custom controls
815
+ # const controlsContainer = document.createElement("div");
816
+ # controlsContainer.className = "svg-pan-zoom_controls";
817
+ # controlsContainer.innerHTML = `
818
+ # <button id="${{graph_id}}-zoom-in">+</button>
819
+ # <button id="${{graph_id}}-zoom-out">-</button>
820
+ # <button id="${{graph_id}}-reset">Reset</button>
821
+ # `;
822
+ # containerElement.appendChild(controlsContainer);
823
+ #
824
+ # // Handle controls
825
+ # document.getElementById(`${{graph_id}}-zoom-in`).addEventListener("click", () => panZoom.zoomIn());
826
+ # document.getElementById(`${{graph_id}}-zoom-out`).addEventListener("click", () => panZoom.zoomOut());
827
+ # document.getElementById(`${{graph_id}}-reset`).addEventListener("click", () => {{
828
+ # panZoom.resetZoom();
829
+ # panZoom.center();
830
+ # }});
831
+ # }}, 500);
832
+ # }}
833
+ #
834
+ # if (typeof mermaid === "undefined") {{
835
+ # const script = document.createElement('script');
836
+ # script.src = "https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js";
837
+ # script.onload = () => initializeMermaid(graph_id);
838
+ # document.head.appendChild(script);
839
+ # }} else {{
840
+ # initializeMermaid(graph_id);
841
+ # }}
842
+ # }});
843
+ # </script>
844
+ #
845
+ # """
846
+ #
847
+ # return html_content
848
+ # This one almost works - no controls and diagram too small
849
+ # html_content = f"""
850
+ # <!DOCTYPE html>
851
+ # <html>
852
+ # <head>
853
+ # <style>
854
+ # /* Set consistent sizing and prevent shrinking for the container and parents */
855
+ # html, body, #{graph_id}-wrapper {{
856
+ # margin: 0;
857
+ # padding: 0;
858
+ # height: 100%; /* Ensure the entire root hierarchy respects 100% height */
859
+ # width: 100%;
860
+ # }}
861
+ #
862
+ # /* Ensure diagram container maintains full height and prevents overflow */
863
+ # #{graph_id}-container {{
864
+ # position: relative;
865
+ # width: 100%;
866
+ # height: 100%;
867
+ # overflow: hidden; /* Prevent content from breaking layout */
868
+ # display: flex;
869
+ # align-items: center; /* Centers the diagram vertically */
870
+ # justify-content: center; /* Centers the diagram horizontally */
871
+ # }}
872
+ #
873
+ # /* Ensure SVG always stretches to match container */
874
+ # #{graph_id} svg {{
875
+ # width: 100%;
876
+ # height: 100%;
877
+ # display: block; /* Avoid unwanted inline space issues */
878
+ # }}
879
+ #
880
+ # /* Optional custom pan/zoom controls (if dynamically added) */
881
+ # .svg-pan-zoom_controls {{
882
+ # position: absolute;
883
+ # bottom: 10px; /* Adjust based on desired placement */
884
+ # right: 10px;
885
+ # z-index: 10;
886
+ # display: flex;
887
+ # gap: 5px;
888
+ # }}
889
+ #
890
+ # .svg-pan-zoom_controls button {{
891
+ # border: 1px solid #ccc;
892
+ # background-color: #fff;
893
+ # color: #000;
894
+ # padding: 5px 10px;
895
+ # cursor: pointer;
896
+ # font-size: 16px;
897
+ # }}
898
+ #
899
+ # .svg-pan-zoom_controls button:hover {{
900
+ # background-color: #f0f0f0;
901
+ # }}
902
+ # </style>
903
+ # </head>
904
+ # <body>
905
+ # <div id="{graph_id}-wrapper">
906
+ # <!-- Title/Heading (optional; include as needed) -->
907
+ # {escaped_header if escaped_header else ""}
908
+ #
909
+ # <!-- Mermaid Diagram Container -->
910
+ # <div id="{graph_id}-container">
911
+ # <div id="{graph_id}" class="mermaid">
912
+ # {escaped_mermaid_code}
913
+ # </div>
914
+ # </div>
915
+ # </div>
916
+ #
917
+ # <script src="https://cdn.jsdelivr.net/npm/svg-pan-zoom@3.6.1/dist/svg-pan-zoom.min.js"></script>
918
+ # <script>
919
+ # document.addEventListener("DOMContentLoaded", () => {{
920
+ # // Define the graph ID dynamically passed via Python
921
+ # const graph_id = "{graph_id}";
922
+ #
923
+ # // Function to load external scripts dynamically
924
+ # function loadScript(url, callback) {{
925
+ # const script = document.createElement('script');
926
+ # script.src = url;
927
+ # script.async = true;
928
+ # script.onload = callback;
929
+ # script.onerror = () => console.error("Error loading script:", url);
930
+ # document.head.appendChild(script);
931
+ # }}
932
+ #
933
+ # // Function to initialize Mermaid
934
+ # function initializeMermaid(graph_id) {{
935
+ # // Look for the container ID generated dynamically by the template
936
+ # const containerElement = document.getElementById(`${{graph_id}}-container`);
937
+ # if (!containerElement) {{
938
+ # console.error(`Container element with id "${{graph_id}}-container" not found.`);
939
+ # return;
940
+ # }}
941
+ #
942
+ # // Initialize Mermaid.js with default configuration
943
+ # mermaid.initialize({{ startOnLoad: false, logLevel: "debug" }});
944
+ # mermaid.init(undefined, `#${{graph_id}}`); // Initialize element with id matching `graph_id`
945
+ #
946
+ # // Add a timeout to ensure the SVG is rendered
947
+ # setTimeout(() => {{
948
+ # const svg = containerElement.querySelector("svg");
949
+ #
950
+ # // Handle errors if SVG rendering fails
951
+ # if (!svg) {{
952
+ # console.error(`SVG not rendered for ID "${{graph_id}}". Check Mermaid syntax or rendering issues.`);
953
+ # console.log("Container content:", containerElement.innerHTML); // Log the container's content
954
+ # return;
955
+ # }}
956
+ #
957
+ # // Set SVG attributes for full container fit
958
+ # svg.setAttribute("width", "100%");
959
+ # svg.setAttribute("height", "100%");
960
+ #
961
+ # // Initialize SVG Pan-Zoom functionality
962
+ # const panZoom = svgPanZoom(svg, {{
963
+ # zoomEnabled: true,
964
+ # controlIconsEnabled: true, // Display default controls if enabled
965
+ # fit: true, // Fit diagram within the container
966
+ # center: true, // Center the diagram
967
+ # minZoom: 0.5, // Prevent too much zooming out
968
+ # maxZoom: 10, // Prevent extreme zooming in
969
+ # contain: true // Keep the diagram fully within bounds
970
+ # }});
971
+ #
972
+ # // Optional: Add custom pan/zoom controls dynamically
973
+ # const controlsContainer = document.createElement("div");
974
+ # controlsContainer.classList.add("svg-pan-zoom_controls");
975
+ # controlsContainer.innerHTML = `
976
+ # <button id="${{graph_id}}-zoom-in">+</button>
977
+ # <button id="${{graph_id}}-zoom-out">-</button>
978
+ # <button id="${{graph_id}}-reset">Reset</button>
979
+ # `;
980
+ # containerElement.appendChild(controlsContainer);
981
+ #
982
+ # // Add event listeners for the custom controls
983
+ # document.getElementById(`${{graph_id}}-zoom-in`).addEventListener("click", () => panZoom.zoomIn());
984
+ # document.getElementById(`${{graph_id}}-zoom-out`).addEventListener("click", () => panZoom.zoomOut());
985
+ # document.getElementById(`${{graph_id}}-reset`).addEventListener("click", () => {{
986
+ # panZoom.resetZoom();
987
+ # panZoom.center();
988
+ # }});
989
+ # }}, 500); // Short delay to ensure SVG rendering is complete
990
+ # }}
991
+ #
992
+ # // Load Mermaid.js if not already loaded
993
+ # if (typeof mermaid === "undefined") {{
994
+ # loadScript("https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js", () => {{
995
+ # console.log("Mermaid.js loaded successfully");
996
+ # initializeMermaid(graph_id); // Call initialization after Mermaid.js is loaded
997
+ # }});
998
+ # }} else {{
999
+ # initializeMermaid(graph_id); // If Mermaid.js is already loaded, proceed immediately
1000
+ # }}
1001
+ # }});
1002
+ # </script>
1003
+ #
1004
+ #
1005
+ # </body>
1006
+ # </html>
1007
+ # """
1008
+
1009
+
1010
+
1011
+ # mermaid_html = f"""
1012
+ # <h2 style="text-align: center; color: #007acc; margin-bottom: 16px;">
1013
+ # {escaped_header}
1014
+ # </h2>
1015
+ # """ if header else ""
1016
+ # # <div class="diagram-container" style="width: 90%; max-width: 800px; margin: auto; padding: 20px; background: white; border: 1px solid #ddd; border-radius: 12px; position: relative;">
1017
+ # # {header_html}
1018
+ # # <div class="pan-zoom-container" style="width: 100%; height: 500px; overflow: hidden; position: relative; background: #f9f9f9; border: 1px solid #ccc; cursor: grab;">
1019
+ # # <div id="{graph_id}" class="mermaid pan-zoom-content" style="position: absolute; transform-origin: 0 0; cursor: grab;">
1020
+ # # {escaped_mermaid_code}
1021
+ # # </div>
1022
+ # # </div>
1023
+ # # </div>
1024
+ # # <script src="https://cdn.jsdelivr.net/npm/mermaid/dist/mermaid.min.js"></script>
1025
+ # # <script>
1026
+ # # // Initialize Mermaid.js and set up pan/zoom
1027
+ # # mermaid.initialize({{ startOnLoad: true }});
1028
+ # #
1029
+ # # const container = document.querySelector('.pan-zoom-container');
1030
+ # # const content = document.querySelector('.pan-zoom-content');
1031
+ # # const rect = content.getBoundingClientRect();
1032
+ # #
1033
+ # # let scale = 1; // Current zoom level
1034
+ # # let panX = 0; // X-axis pan offset
1035
+ # # let panY = 0; // Y-axis pan offset
1036
+ # # let isDragging = false;
1037
+ # # let startX, startY;
1038
+ # #
1039
+ # # // Helper: Apply transformations
1040
+ # # const applyTransform = () => {{
1041
+ # # content.style.transform = `translate(${{panX}}px, ${{panY}}px) scale(${{scale}})`;
1042
+ # # }};
1043
+ # #
1044
+ # # // Helper: Center the diagram and fit it to the container
1045
+ # # const centerAndFitDiagram = () => {{
1046
+ # # const containerRect = container.getBoundingClientRect();
1047
+ # # const rect = content.getBoundingClientRect();
1048
+ # #
1049
+ # # scale = Math.min(
1050
+ # # containerRect.width / rect.width,
1051
+ # # containerRect.height / rect.height
1052
+ # # );
1053
+ # #
1054
+ # # panX = (containerRect.width - rect.width * scale) / 2;
1055
+ # # panY = (containerRect.height - rect.height * scale) / 2;
1056
+ # #
1057
+ # # applyTransform();
1058
+ # # console.log("Diagram centered and fitted.");
1059
+ # # }};
1060
+ # #
1061
+ # # // Add zoom functionality
1062
+ # # container.addEventListener('wheel', function(event) {{
1063
+ # # event.preventDefault();
1064
+ # # const zoomSpeed = 0.1;
1065
+ # # const previousScale = scale;
1066
+ # #
1067
+ # # if (event.deltaY < 0) {{
1068
+ # # scale = Math.min(scale + zoomSpeed, 4);
1069
+ # # }} else {{
1070
+ # # scale = Math.max(scale - zoomSpeed, 0.5);
1071
+ # # }}
1072
+ # #
1073
+ # # const zoomRatio = scale / previousScale;
1074
+ # # panX -= (event.clientX - container.getBoundingClientRect().left) * (zoomRatio - 1);
1075
+ # # panY -= (event.clientY - container.getBoundingClientRect().top) * (zoomRatio - 1);
1076
+ # #
1077
+ # # applyTransform();
1078
+ # # }});
1079
+ # #
1080
+ # # // Add drag functionality for panning
1081
+ # # container.addEventListener('mousedown', function(event) {{
1082
+ # # isDragging = true;
1083
+ # # startX = event.clientX - panX;
1084
+ # # startY = event.clientY - panY;
1085
+ # # container.style.cursor = "grabbing";
1086
+ # # }});
1087
+ # #
1088
+ # # container.addEventListener('mousemove', function(event) {{
1089
+ # # if (!isDragging) return;
1090
+ # #
1091
+ # # panX = event.clientX - startX;
1092
+ # # panY = event.clientY - startY;
1093
+ # #
1094
+ # # applyTransform();
1095
+ # # }});
1096
+ # #
1097
+ # # container.addEventListener('mouseup', function() {{
1098
+ # # isDragging = false;
1099
+ # # container.style.cursor = "grab";
1100
+ # # }});
1101
+ # #
1102
+ # # container.addEventListener('mouseleave', function() {{
1103
+ # # isDragging = false;
1104
+ # # container.style.cursor = "grab";
1105
+ # # }});
1106
+ # #
1107
+ # # // Center diagram after rendering by Mermaid
1108
+ # # setTimeout(centerAndFitDiagram, 200);
1109
+ # # </script>
1110
+ # # """
1111
+ #
1112
+ # return mermaid_html
1113
+
1114
+
1115
+
1116
+ def save_mermaid_html(
1117
+ title: str, mermaid_str: str, folder: str = EGERIA_MERMAID_FOLDER
1118
+ ):
1119
+ """Save a Mermaid diagram to a file"""
1120
+ if not os.path.exists(folder):
1121
+ os.makedirs(folder)
1122
+ mermaid_file = os.path.join(folder, title + ".html")
1123
+
1124
+ payload = construct_mermaid_web(mermaid_str)
1125
+
1126
+ with open(mermaid_file, "w") as f:
1127
+ f.write(payload)
1128
+ return mermaid_file
1129
+
1130
+
1131
+ def save_mermaid_graph(title, mermaid_str, folder: str = EGERIA_MERMAID_FOLDER):
1132
+ """Save a Mermaid diagram to a file"""
1133
+ if not os.path.exists(folder):
1134
+ os.makedirs(folder)
1135
+ mermaid_file = os.path.join(folder, title + ".html")
1136
+
1137
+ title, mermaid_code = parse_mermaid_code(mermaid_str)
1138
+
1139
+ html_prefix = """
1140
+ <html>
1141
+ <head>
1142
+ <style type="text/css">
1143
+ #mySvgId {
1144
+ width: 100%;
1145
+ height: 100%;
1146
+ overflow: hidden;
1147
+ border: 1px solid #ccc;
1148
+ position: relative;
1149
+ margin-bottom: 10px;
1150
+ }
1151
+ svg {
1152
+ cursor: grab;
1153
+ }
1154
+
1155
+ </style>
1156
+ </head>
1157
+
1158
+ <body>
1159
+ <div id="graphDiv"></div>
1160
+ <script src="https://bumbu.me/svg-pan-zoom/dist/svg-pan-zoom.min.js"></script>
1161
+ <script type="module">
1162
+ import mermaid from 'https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs';
1163
+
1164
+ mermaid.initialize({startOnLoad: false});
1165
+ await mermaid.run({
1166
+ querySelector: '.mermaid',
1167
+ postRenderCallback: (id) => {
1168
+ const container = document.getElementById("diagram-container");
1169
+ const svgElement = container.querySelector("svg");
1170
+
1171
+ // Initialize Panzoom
1172
+ const panzoomInstance = Panzoom(svgElement, {
1173
+ maxScale: 5,
1174
+ minScale: 0.5,
1175
+ step: 0.1,
1176
+ });
1177
+
1178
+ // Add mouse wheel zoom
1179
+ container.addEventListener("wheel", (event) => {
1180
+ panzoomInstance.zoomWithWheel(event);
1181
+ });
1182
+ }
1183
+ });
1184
+
1185
+
1186
+ const drawDiagram = async function () {
1187
+ const element = document.querySelector('#graphDiv');
1188
+ const graphDefinition = `
1189
+ """
1190
+
1191
+ html_postfix = r"""`;
1192
+ const {svg} = await mermaid.render('mySvgId', graphDefinition);
1193
+ element.innerHTML = svg.replace(/( )*max-width:( 0-9\.)*px;/i, '');
1194
+
1195
+ var doPan = false;
1196
+ var eventsHandler;
1197
+ var panZoom;
1198
+ var mousepos;
1199
+
1200
+ eventsHandler = {
1201
+ haltEventListeners: ['mousedown', 'mousemove', 'mouseup']
1202
+
1203
+ , mouseDownHandler: function (ev) {
1204
+ if (event.target.className == "[object SVGAnimatedString]") {
1205
+ doPan = true;
1206
+ mousepos = {x: ev.clientX, y: ev.clientY}
1207
+ }
1208
+ ;
1209
+ }
1210
+
1211
+ , mouseMoveHandler: function (ev) {
1212
+ if (doPan) {
1213
+ panZoom.panBy({x: ev.clientX - mousepos.x, y: ev.clientY - mousepos.y});
1214
+ mousepos = {x: ev.clientX, y: ev.clientY};
1215
+ window.getSelection().removeAllRanges();
1216
+ }
1217
+ }
1218
+
1219
+ , mouseUpHandler: function (ev) {
1220
+ doPan = false;
1221
+ }
1222
+
1223
+ , init: function (options) {
1224
+ options.svgElement.addEventListener('mousedown', this.mouseDownHandler, false);
1225
+ options.svgElement.addEventListener('mousemove', this.mouseMoveHandler, false);
1226
+ options.svgElement.addEventListener('mouseup', this.mouseUpHandler, false);
1227
+ }
1228
+
1229
+ , destroy: function (options) {
1230
+ options.svgElement.removeEventListener('mousedown', this.mouseDownHandler, false);
1231
+ options.svgElement.removeEventListener('mousemove', this.mouseMoveHandler, false);
1232
+ options.svgElement.removeEventListener('mouseup', this.mouseUpHandler, false);
1233
+ }
1234
+ }
1235
+ panZoom = svgPanZoom('#mySvgId', {
1236
+ zoomEnabled: true
1237
+ , controlIconsEnabled: true
1238
+ , fit: 1
1239
+ , center: 1
1240
+ , customEventsHandler: eventsHandler
1241
+ })
1242
+ };
1243
+ await drawDiagram();
1244
+ </script>
1245
+ </body>
1246
+ """
1247
+
1248
+ payload = html_prefix + mermaid_code + html_postfix
1249
+
1250
+ with open(mermaid_file, "w") as f:
1251
+ f.write(payload)
1252
+ return mermaid_file
1253
+
1254
+
75
1255
  def generate_process_graph(
76
1256
  process_guid: str,
77
1257
  view_server: str = EGERIA_VIEW_SERVER,