s3dgraphy 1.6.0.dev7__tar.gz → 1.6.0.dev9__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 (168) hide show
  1. {s3dgraphy-1.6.0.dev7/src/s3dgraphy.egg-info → s3dgraphy-1.6.0.dev9}/PKG-INFO +37 -20
  2. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/README.md +36 -19
  3. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/pyproject.toml +1 -1
  4. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/__init__.py +1 -1
  5. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/edges/edge.py +6 -0
  6. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/exporter/graphml/graphml_patcher.py +7 -4
  7. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/importer/import_graphml.py +7 -6
  8. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/nodes/hdt_node.py +7 -5
  9. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/sync/graph_projector.py +14 -2
  10. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/sync/graphml_writer.py +2 -1
  11. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/sync/group_projector.py +5 -5
  12. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/sync/paradata_store.py +4 -3
  13. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/sync/rapporti.py +167 -5
  14. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/sync/yed_import_pipeline.py +2 -2
  15. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/sync/yed_rapporti_policy.py +2 -1
  16. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/sync/yed_table_parser.py +6 -5
  17. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9/src/s3dgraphy.egg-info}/PKG-INFO +37 -20
  18. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/LICENSE +0 -0
  19. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/MANIFEST.in +0 -0
  20. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/setup.cfg +0 -0
  21. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/em.ttl +0 -0
  22. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/em_document_types.json +0 -0
  23. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/em_extractor_types.json +0 -0
  24. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/em_palette_icons.json +0 -0
  25. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/em_qualia_types.json +0 -0
  26. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/em_qualia_types_additions.json +0 -0
  27. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/em_visual_rules.json +0 -0
  28. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/hdto_extension.ttl +0 -0
  29. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/new_qualia_template.json +0 -0
  30. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/outdated_s3dgraphy.ttl +0 -0
  31. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/outdated_s3dgraphy_nomapping.ttl +0 -0
  32. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/s3Dgraphy_connections_datamodel.json +0 -0
  33. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/s3Dgraphy_connections_datamodel.json.v155.bak +0 -0
  34. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/s3Dgraphy_node_datamodel.json +0 -0
  35. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/2D/RSF.png +0 -0
  36. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/2D/RSF.svg +0 -0
  37. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/2D/SF.png +0 -0
  38. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/2D/TSU.png +0 -0
  39. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/2D/US.png +0 -0
  40. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/2D/USD.png +0 -0
  41. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/2D/USVn.png +0 -0
  42. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/2D/USVs.png +0 -0
  43. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/2D/VSF.png +0 -0
  44. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/2D/combiner.png +0 -0
  45. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/2D/continuity.png +0 -0
  46. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/2D/document.png +0 -0
  47. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/2D/extractor.png +0 -0
  48. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/2D/property.png +0 -0
  49. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/2D/serSU.png +0 -0
  50. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/2D/serUSD.png +0 -0
  51. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/2D/serUSV.png +0 -0
  52. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/3D/RSF.glb +0 -0
  53. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/3D/SF.glb +0 -0
  54. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/3D/TSU.glb +0 -0
  55. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/3D/US.glb +0 -0
  56. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/3D/USD.glb +0 -0
  57. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/3D/USVn.glb +0 -0
  58. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/3D/USVs.glb +0 -0
  59. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/3D/VSF.glb +0 -0
  60. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/3D/combiner.glb +0 -0
  61. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/3D/continuity.glb +0 -0
  62. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/3D/document.glb +0 -0
  63. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/3D/extractor.glb +0 -0
  64. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/3D/property.glb +0 -0
  65. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/3D/serSU.glb +0 -0
  66. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/3D/serUSD.glb +0 -0
  67. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/JSON_config/src/3D/serUSV.glb +0 -0
  68. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/classification.py +0 -0
  69. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/data/StratiMiner_Extraction_Prompt.md +0 -0
  70. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/diagnostics.py +0 -0
  71. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/edges/__init__.py +0 -0
  72. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/edges/connections_loader.py +0 -0
  73. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/exporter/__init__.py +0 -0
  74. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/exporter/graphml/__init__.py +0 -0
  75. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/exporter/graphml/canvas_generator.py +0 -0
  76. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/exporter/graphml/edge_generator.py +0 -0
  77. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/exporter/graphml/epoch_generator.py +0 -0
  78. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/exporter/graphml/graphml_exporter.py +0 -0
  79. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/exporter/graphml/group_node_generator.py +0 -0
  80. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/exporter/graphml/node_generator.py +0 -0
  81. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/exporter/graphml/node_registry.py +0 -0
  82. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/exporter/graphml/palette_resources.py +0 -0
  83. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/exporter/graphml/paradata_generator.py +0 -0
  84. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/exporter/graphml/paradata_image_generator.py +0 -0
  85. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/exporter/graphml/paradata_node_generators.py +0 -0
  86. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/exporter/graphml/table_node_generator.py +0 -0
  87. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/exporter/graphml/utils.py +0 -0
  88. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/exporter/json_exporter.py +0 -0
  89. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/exporter/rdf_exporter.py +0 -0
  90. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/exporter/unified_xlsx_exporter.py +0 -0
  91. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/graph.py +0 -0
  92. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/importer/__init__.py +0 -0
  93. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/importer/base_importer.py +0 -0
  94. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/importer/mapped_xlsx_importer.py +0 -0
  95. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/importer/pyarchinit_importer.py +0 -0
  96. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/importer/qualia_importer.py +0 -0
  97. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/importer/unified_xlsx_importer.py +0 -0
  98. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/importer/xlsx_importer.py +0 -0
  99. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/indices.py +0 -0
  100. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/mappings/__init__.py +0 -0
  101. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/mappings/emdb/generic_specialfind_mapping.json +0 -0
  102. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/mappings/emdb/site_properties_mapping.json +0 -0
  103. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/mappings/emdb/usm_mapping.json +0 -0
  104. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/mappings/generic/excel_to_graphml_mapping.json +0 -0
  105. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/mappings/pyarchinit/pyarchinit_us_mapping.json +0 -0
  106. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/mappings/registry.py +0 -0
  107. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/mappings/template_emdb_mapping.json +0 -0
  108. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/mappings/template_pyarchinit_mapping.json +0 -0
  109. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/merge/__init__.py +0 -0
  110. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/merge/graph_merger.py +0 -0
  111. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/multigraph/__init__.py +0 -0
  112. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/multigraph/multigraph.py +0 -0
  113. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/nodes/__init__.py +0 -0
  114. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/nodes/author_node.py +0 -0
  115. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/nodes/base_node.py +0 -0
  116. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/nodes/combiner_node.py +0 -0
  117. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/nodes/document_node.py +0 -0
  118. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/nodes/embargo_node.py +0 -0
  119. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/nodes/epoch_node.py +0 -0
  120. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/nodes/extractor_node.py +0 -0
  121. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/nodes/geo_position_node.py +0 -0
  122. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/nodes/graph_node.py +0 -0
  123. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/nodes/group_node.py +0 -0
  124. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/nodes/license_node.py +0 -0
  125. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/nodes/link_node.py +0 -0
  126. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/nodes/paradata_node.py +0 -0
  127. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/nodes/property_node.py +0 -0
  128. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/nodes/representation_node.py +0 -0
  129. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/nodes/semantic_shape_node.py +0 -0
  130. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/nodes/stratigraphic_node.py +0 -0
  131. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/resolvers/__init__.py +0 -0
  132. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/resolvers/builtin_rules.py +0 -0
  133. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/resolvers/property_resolver.py +0 -0
  134. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/sync/__init__.py +0 -0
  135. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/sync/_db_handle.py +0 -0
  136. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/sync/_legacy_paradata_svgs.py +0 -0
  137. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/sync/_workspace.py +0 -0
  138. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/sync/conflict_resolver.py +0 -0
  139. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/sync/edge_registry.py +0 -0
  140. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/sync/graph_ingestor.py +0 -0
  141. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/sync/group_store.py +0 -0
  142. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/sync/ingest_result.py +0 -0
  143. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/sync/pyarchinit_pg_importer.py +0 -0
  144. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/sync/uuid7.py +0 -0
  145. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/sync/vocab_provider_core.py +0 -0
  146. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/sync/vocab_types.py +0 -0
  147. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/sync/yed_classifier.py +0 -0
  148. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/sync/yed_detector.py +0 -0
  149. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/sync/yed_group_walker.py +0 -0
  150. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/templates/em_data_template.xlsx +0 -0
  151. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/templates/em_palette_template.graphml +0 -0
  152. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/temporal/__init__.py +0 -0
  153. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/temporal/inference_engine.py +0 -0
  154. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/transforms/__init__.py +0 -0
  155. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/transforms/aux_tracking.py +0 -0
  156. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/transforms/compact.py +0 -0
  157. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/transforms/materialize_continuity.py +0 -0
  158. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/utils/__init__.py +0 -0
  159. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/utils/utils.py +0 -0
  160. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy/utils/visual_layout.py +0 -0
  161. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy.egg-info/SOURCES.txt +0 -0
  162. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy.egg-info/dependency_links.txt +0 -0
  163. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy.egg-info/requires.txt +0 -0
  164. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/src/s3dgraphy.egg-info/top_level.txt +0 -0
  165. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/tests/test_composite_node_name.py +0 -0
  166. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/tests/test_filtered_import.py +0 -0
  167. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/tests/test_lossless_roundtrip.py +0 -0
  168. {s3dgraphy-1.6.0.dev7 → s3dgraphy-1.6.0.dev9}/tests/test_pg_importer.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: s3dgraphy
3
- Version: 1.6.0.dev7
3
+ Version: 1.6.0.dev9
4
4
  Summary: 3D Stratigraphic Graph Management Library for archaeological and heritage applications
5
5
  Author-email: Emanuel Demetrescu <emanuel.demetrescu@cnr.it>
6
6
  Maintainer-email: Emanuel Demetrescu <emanuel.demetrescu@cnr.it>
@@ -97,30 +97,47 @@ pip install s3dgraphy[full] # All optional dependencies
97
97
  ## 🔧 Quick Start
98
98
 
99
99
  ```python
100
- import s3dgraphy
100
+ from s3dgraphy import Graph
101
+ from s3dgraphy.nodes import StratigraphicUnit, DocumentNode
101
102
 
102
- # Create a new stratigraphic graph
103
- graph = s3dgraphy.Graph()
103
+ # Create a new stratigraphic graph (graph_id is required)
104
+ graph = Graph("my_excavation")
104
105
 
105
- # Add stratigraphic units
106
- us1 = graph.add_node("US001", node_type="US",
107
- properties={"period": "Roman", "material": "pottery"})
108
- us2 = graph.add_node("US002", node_type="US",
109
- properties={"period": "Medieval", "material": "stone"})
106
+ # Build node objects, then add them with add_node()
107
+ wall = StratigraphicUnit("US001", name="US001", description="Stone wall foundation")
108
+ floor = StratigraphicUnit("US002", name="US002", description="Mosaic floor")
109
+ graph.add_node(wall)
110
+ graph.add_node(floor)
110
111
 
111
- # Add stratigraphic relationships
112
- graph.add_edge(us1, us2, edge_type="ABOVE",
113
- properties={"certainty": "high"})
112
+ # Add a stratigraphic relationship.
113
+ # Canonical direction is recent -> ancient: the floor (US002) is more
114
+ # recent than the wall (US001), so US002 is_after US001.
115
+ graph.add_edge("e1", "US002", "US001", "is_after")
116
+
117
+ # Attach documentation
118
+ doc = DocumentNode("DOC001", name="DOC001", description="Field photo")
119
+ graph.add_node(doc)
120
+ graph.add_edge("e2", "US001", "DOC001", "has_documentation")
114
121
 
115
122
  # Query the graph
116
- print(f"Graph contains {len(graph.nodes)} stratigraphic units")
117
- print(f"Relationships: {len(graph.edges)}")
123
+ print(f"Graph contains {len(graph.nodes)} nodes and {len(graph.edges)} edges")
124
+ us_units = graph.get_nodes_by_type("US")
118
125
 
119
- # Export to different formats
120
- graph.export_graphml("stratigraphy.graphml")
121
- graph.export_json("stratigraphy.json")
126
+ # Export to GraphML (yEd round-trip) — the exporter takes the graph directly
127
+ from s3dgraphy.exporter.graphml import GraphMLExporter
128
+ GraphMLExporter(graph).export("my_excavation.graphml")
122
129
  ```
123
130
 
131
+ > **Note on the API.** Nodes are *objects* (`StratigraphicUnit`,
132
+ > `DocumentNode`, …) created first and then added with `graph.add_node()`.
133
+ > Edges are created with `graph.add_edge(edge_id, source_id, target_id,
134
+ > edge_type)` using a **canonical** edge type from the connections
135
+ > datamodel (e.g. `is_after`, `has_property`, `has_documentation`). Invalid
136
+ > connections are downgraded to `generic_connection` with a warning rather
137
+ > than silently accepted. See the
138
+ > [API reference](https://docs.extendedmatrix.org/projects/s3dgraphy/) for
139
+ > the full node and edge catalogs.
140
+
124
141
  ## 📚 Core Features
125
142
 
126
143
  ### 🏛️ Archaeological Stratigraphic Modeling
@@ -328,12 +345,12 @@ The GPL-3.0 license ensures that s3dgraphy remains free and open source, promoti
328
345
  If you use s3dgraphy in your research, please cite:
329
346
 
330
347
  ```bibtex
331
- @software{s3dgraphy2024,
348
+ @software{s3dgraphy,
332
349
  title={s3dgraphy: 3D Stratigraphic Graph Management Library},
333
350
  author={Demetrescu, Emanuel},
334
- year={2024},
351
+ year={2026},
335
352
  url={https://github.com/zalmoxes-laran/s3dgraphy},
336
- version={0.1.1},
353
+ version={1.6.0},
337
354
  institution={CNR-ISPC (National Research Council - Institute of Heritage Science)}
338
355
  }
339
356
  ```
@@ -29,30 +29,47 @@ pip install s3dgraphy[full] # All optional dependencies
29
29
  ## 🔧 Quick Start
30
30
 
31
31
  ```python
32
- import s3dgraphy
32
+ from s3dgraphy import Graph
33
+ from s3dgraphy.nodes import StratigraphicUnit, DocumentNode
33
34
 
34
- # Create a new stratigraphic graph
35
- graph = s3dgraphy.Graph()
35
+ # Create a new stratigraphic graph (graph_id is required)
36
+ graph = Graph("my_excavation")
36
37
 
37
- # Add stratigraphic units
38
- us1 = graph.add_node("US001", node_type="US",
39
- properties={"period": "Roman", "material": "pottery"})
40
- us2 = graph.add_node("US002", node_type="US",
41
- properties={"period": "Medieval", "material": "stone"})
38
+ # Build node objects, then add them with add_node()
39
+ wall = StratigraphicUnit("US001", name="US001", description="Stone wall foundation")
40
+ floor = StratigraphicUnit("US002", name="US002", description="Mosaic floor")
41
+ graph.add_node(wall)
42
+ graph.add_node(floor)
42
43
 
43
- # Add stratigraphic relationships
44
- graph.add_edge(us1, us2, edge_type="ABOVE",
45
- properties={"certainty": "high"})
44
+ # Add a stratigraphic relationship.
45
+ # Canonical direction is recent -> ancient: the floor (US002) is more
46
+ # recent than the wall (US001), so US002 is_after US001.
47
+ graph.add_edge("e1", "US002", "US001", "is_after")
48
+
49
+ # Attach documentation
50
+ doc = DocumentNode("DOC001", name="DOC001", description="Field photo")
51
+ graph.add_node(doc)
52
+ graph.add_edge("e2", "US001", "DOC001", "has_documentation")
46
53
 
47
54
  # Query the graph
48
- print(f"Graph contains {len(graph.nodes)} stratigraphic units")
49
- print(f"Relationships: {len(graph.edges)}")
55
+ print(f"Graph contains {len(graph.nodes)} nodes and {len(graph.edges)} edges")
56
+ us_units = graph.get_nodes_by_type("US")
50
57
 
51
- # Export to different formats
52
- graph.export_graphml("stratigraphy.graphml")
53
- graph.export_json("stratigraphy.json")
58
+ # Export to GraphML (yEd round-trip) — the exporter takes the graph directly
59
+ from s3dgraphy.exporter.graphml import GraphMLExporter
60
+ GraphMLExporter(graph).export("my_excavation.graphml")
54
61
  ```
55
62
 
63
+ > **Note on the API.** Nodes are *objects* (`StratigraphicUnit`,
64
+ > `DocumentNode`, …) created first and then added with `graph.add_node()`.
65
+ > Edges are created with `graph.add_edge(edge_id, source_id, target_id,
66
+ > edge_type)` using a **canonical** edge type from the connections
67
+ > datamodel (e.g. `is_after`, `has_property`, `has_documentation`). Invalid
68
+ > connections are downgraded to `generic_connection` with a warning rather
69
+ > than silently accepted. See the
70
+ > [API reference](https://docs.extendedmatrix.org/projects/s3dgraphy/) for
71
+ > the full node and edge catalogs.
72
+
56
73
  ## 📚 Core Features
57
74
 
58
75
  ### 🏛️ Archaeological Stratigraphic Modeling
@@ -260,12 +277,12 @@ The GPL-3.0 license ensures that s3dgraphy remains free and open source, promoti
260
277
  If you use s3dgraphy in your research, please cite:
261
278
 
262
279
  ```bibtex
263
- @software{s3dgraphy2024,
280
+ @software{s3dgraphy,
264
281
  title={s3dgraphy: 3D Stratigraphic Graph Management Library},
265
282
  author={Demetrescu, Emanuel},
266
- year={2024},
283
+ year={2026},
267
284
  url={https://github.com/zalmoxes-laran/s3dgraphy},
268
- version={0.1.1},
285
+ version={1.6.0},
269
286
  institution={CNR-ISPC (National Research Council - Institute of Heritage Science)}
270
287
  }
271
288
  ```
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "s3dgraphy"
7
- version = "1.6.0.dev7"
7
+ version = "1.6.0.dev9"
8
8
  description = "3D Stratigraphic Graph Management Library for archaeological and heritage applications"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.9"
@@ -1,4 +1,4 @@
1
- __version__ = "1.6.0.dev7"
1
+ __version__ = "1.6.0.dev9"
2
2
  __datamodel_version__ = "1.5.5" # s3Dgraphy connections datamodel version
3
3
 
4
4
  # s3Dgraphy/__init__.py
@@ -17,6 +17,12 @@ def _build_legacy_edge_types():
17
17
  return edge_types
18
18
 
19
19
  EDGE_TYPES = _build_legacy_edge_types()
20
+ """Legacy mapping ``edge_type -> {"label", "description"}``.
21
+
22
+ Rebuilt from the connections datamodel for backward compatibility; new
23
+ code should query :func:`s3dgraphy.edges.connections_loader.get_connections_datamodel`
24
+ instead. ``Edge`` validates ``edge_type`` against the keys of this dict.
25
+ """
20
26
 
21
27
  class Edge:
22
28
  """
@@ -3,10 +3,11 @@ GraphML Patcher for s3dgraphy.
3
3
 
4
4
  Patches an existing GraphML file on disk with changes from an in-memory Graph.
5
5
  Supports:
6
- - Updating existing nodes (description, name, EMID, URI)
7
- - Adding new nodes that were created in-memory
8
- - Adding new edges
9
- - EMID validation and duplicate detection
6
+
7
+ - Updating existing nodes (description, name, EMID, URI)
8
+ - Adding new nodes that were created in-memory
9
+ - Adding new edges
10
+ - EMID validation and duplicate detection
10
11
 
11
12
  This is the "twin" of the importer: it uses the same dynamic key mapping
12
13
  and the same conventions to write back what the importer can read.
@@ -1429,11 +1430,13 @@ class GraphMLPatcher:
1429
1430
  Add new edges to the GraphML XML.
1430
1431
 
1431
1432
  For each edge in the graph that does NOT have an original_edge_id:
1433
+
1432
1434
  - Generates a new edge ID
1433
1435
  - Creates <edge> XML with correct line style for the edge type
1434
1436
  - Resolves source/target using original_id or generated ID
1435
1437
 
1436
1438
  Skips:
1439
+
1437
1440
  - Edges with original_edge_id (already in the XML)
1438
1441
  - Structural edges (represented by XML nesting, not <edge> elements)
1439
1442
  - Derived has_property edges where the target PropertyNode is inside
@@ -2616,12 +2616,13 @@ class GraphMLImporter:
2616
2616
  """
2617
2617
  Verifica se un nodo è un nodo di continuità (BR).
2618
2618
  Usa una detection multi-segnale:
2619
- A) '_continuity' nel campo URL o description
2620
- B) ShapeNode con shape type 'diamond'
2621
- C) SVGNode il cui SVGContent refid punta alla risorsa
2622
- ``continuity.svg`` (refid risolto dinamicamente, vedi
2623
- build_svg_resource_map — yEd numera le Resource per ordine
2624
- di serializzazione, non c'è un id fisso)
2619
+
2620
+ A) '_continuity' nel campo URL o description
2621
+ B) ShapeNode con shape type 'diamond'
2622
+ C) SVGNode il cui SVGContent refid punta alla risorsa
2623
+ ``continuity.svg`` (refid risolto dinamicamente, vedi
2624
+ build_svg_resource_map — yEd numera le Resource per ordine
2625
+ di serializzazione, non c'è un id fisso)
2625
2626
 
2626
2627
  Args:
2627
2628
  node_element: Elemento XML del nodo
@@ -9,12 +9,14 @@ formal propositions) about a heritage entity (HC1). HDTs are hierarchically
9
9
  composable — a city HDT contains district HDTs which contain monument HDTs.
10
10
 
11
11
  Granularity connectors (declared in s3Dgraphy_connections_datamodel.json):
12
- * has_digital_twin — Node → HDTNode (HP1)
13
- * has_digital_twin_component — HDTNode → HDTNode (HP3 inverse, transitive)
14
- * contains_proposition_set — HDTNode → GraphNode (HP33)
15
- * has_digital_object_part — HDTNode → RepresentationModel* / LinkNode (HP29)
16
12
 
17
- Use case (the Colosseo example):
13
+ * has_digital_twin — Node → HDTNode (HP1)
14
+ * has_digital_twin_component — HDTNode → HDTNode (HP3 inverse, transitive)
15
+ * contains_proposition_set — HDTNode → GraphNode (HP33)
16
+ * has_digital_object_part — HDTNode → RepresentationModel* / LinkNode (HP29)
17
+
18
+ Use case (the Colosseo example)::
19
+
18
20
  colosseo_overall = HDTNode("hdt_colosseo_overall", name="Colosseo HDT")
19
21
  colosseo_flavian = HDTNode("hdt_colosseo_flavian", name="Colosseo Flavian phase")
20
22
  colosseo_medieval = HDTNode("hdt_colosseo_medieval", name="Colosseo medieval fortress")
@@ -578,6 +578,11 @@ class GraphProjector:
578
578
  except Exception:
579
579
  period_datazione = {}
580
580
 
581
+ # Localized US/USM → canonical alias map (the single source in
582
+ # sync.rapporti) so non-Italian unita_tipo codes are recognised as
583
+ # stratigraphic units in the gating + node-class factory below.
584
+ from .rapporti import canonical_unita_tipo
585
+
581
586
  for (us_val, node_uuid, sito_v, area, unita_tipo,
582
587
  periodo_ini, fase_ini, rapporti_raw, d_strat,
583
588
  d_interp, attivita, struttura,
@@ -586,6 +591,13 @@ class GraphProjector:
586
591
  if not us_name:
587
592
  continue
588
593
  ut_str = str(unita_tipo) if unita_tipo is not None else ""
594
+ # Canonical US/USM code for the structural decisions below
595
+ # (stratigraphic gating + node-class factory), so localized
596
+ # codes (SU/WSU/SE/…) are recognised as real stratigraphic
597
+ # units. attributes['unita_tipo'] keeps the ORIGINAL code
598
+ # (set further down) for round-trip + the language-aware
599
+ # rapporti dispatch.
600
+ ut_canon = canonical_unita_tipo(ut_str)
589
601
  node = None
590
602
  # Direct hit by composite key (paradata that the bridge
591
603
  # correctly classified OR a stratigraphic node already
@@ -602,14 +614,14 @@ class GraphProjector:
602
614
  # order (e.g. yEd document order interleaves US01 and
603
615
  # DOC.01 — DOC.01 might claim the bridge's '01' placeholder
604
616
  # before US01 row is iterated).
605
- if node is None and ut_str in (
617
+ if node is None and ut_canon in (
606
618
  "US", "USM", "USD", "USV", "USVs", "USVn", "USVc",
607
619
  "SF", "VSF", "RSF",
608
620
  ):
609
621
  node = nodes_by_key.pop((us_name, "__STRAT__"), None)
610
622
  if node is None:
611
623
  node = _create_stratigraphic_node_for_unita_tipo(
612
- ut_str, us_name, node_uuid or us_name,
624
+ ut_canon, us_name, node_uuid or us_name,
613
625
  )
614
626
  if node is not None:
615
627
  try:
@@ -1,7 +1,8 @@
1
1
  """Pure-Python wrapper over s3dgraphy.PyArchInitImporter +
2
2
  s3dgraphy.exporter.graphml.GraphMLExporter.
3
3
 
4
- Public API:
4
+ Public API::
5
+
5
6
  export_graphml(db_path, mapping, output_path,
6
7
  *, site_filter=None, persist_auxiliary=False) -> ExportResult
7
8
 
@@ -1,10 +1,10 @@
1
1
  """Pure-functional helpers for AI06 node grouping.
2
2
 
3
- build_groups_from_sql: scan us_table for the requested grouping
4
- dimensions, emit one GroupSpec per (dim, value) pair.
5
- merge_adhoc_groups: append GroupSpec instances from a GroupStore.
6
- dimensions_with_data: return the subset of 7 grouping columns
7
- that have at least one non-empty value in us_table for sito.
3
+ - ``build_groups_from_sql``: scan us_table for the requested grouping
4
+ dimensions, emit one GroupSpec per (dim, value) pair.
5
+ - ``merge_adhoc_groups``: append GroupSpec instances from a GroupStore.
6
+ - ``dimensions_with_data``: return the subset of 7 grouping columns
7
+ that have at least one non-empty value in us_table for sito.
8
8
 
9
9
  UUID generation: deterministic UUID5 from (sito, group_kind, name)
10
10
  so re-export with the same SQL state produces identical UUIDs
@@ -2,9 +2,10 @@
2
2
 
3
3
  AI05 Phase 2 closure. Manages the 3 node types without an SQL
4
4
  counterpart in pyarchinit:
5
- - AuthorNode (authorship metadata)
6
- - LicenseNode (rights / SPDX licence)
7
- - EmbargoNode (embargo dates)
5
+
6
+ - AuthorNode (authorship metadata)
7
+ - LicenseNode (rights / SPDX licence)
8
+ - EmbargoNode (embargo dates)
8
9
 
9
10
  File location: {db_path.parent}/paradata_{sito_slug}.graphml
10
11
  where sito_slug is `re.sub(r'\\W+', '_', sito).lower()`.
@@ -87,9 +87,84 @@ RAPPORTI_TO_EDGE_TYPE: dict[str, str] = {
87
87
  "same as": "is_physically_equal_to",
88
88
  "bonds with": "is_bonded_to",
89
89
  "abuts": "abuts",
90
+ "supports": "is_abutted_by", # English reciprocal of "Abuts"
90
91
  }
91
92
 
92
93
 
94
+ # ---------------------------------------------------------------------------
95
+ # Full multilingual coverage
96
+ # ---------------------------------------------------------------------------
97
+ # pyArchInit (and any EM tool with a localized UI) stores relationship labels
98
+ # in the user's language, so parse_rapporti must recognise them all —
99
+ # otherwise a graph projected from a non-IT/EN site builds no edges, and a
100
+ # reciprocity round-trip (e.g. the reciprocal of "Abuts" is "Supports" =
101
+ # is_abutted_by) silently fails. The 10×10 table below mirrors the EM/
102
+ # pyArchInit stratigraphic-relationship vocabulary (10 relations × 10 UI
103
+ # languages: it/en/de/es/fr/ar/ca/ro/pt/el).
104
+ #
105
+ # Index → canonical edge type (same order as each language's term list):
106
+ _REL_INDEX_EDGE_TYPE: tuple[str, ...] = (
107
+ "is_physically_equal_to", # 0 Uguale a / Same as
108
+ "is_bonded_to", # 1 Si lega a / Connected to
109
+ "overlies", # 2 Copre / Covers
110
+ "is_overlain_by", # 3 Coperto da / Covered by
111
+ "fills", # 4 Riempie / Fills
112
+ "is_filled_by", # 5 Riempito da / Filled by
113
+ "cuts", # 6 Taglia / Cuts
114
+ "is_cut_by", # 7 Tagliato da / Cut by
115
+ "abuts", # 8 Si appoggia a / Abuts
116
+ "is_abutted_by", # 9 Gli si appoggia / Supports
117
+ )
118
+
119
+ #: 10 relationship terms per language (same indices as _REL_INDEX_EDGE_TYPE).
120
+ _REL_TERMS_BY_LANG: dict[str, tuple[str, ...]] = {
121
+ "it": ("Uguale a", "Si lega a", "Copre", "Coperto da", "Riempie",
122
+ "Riempito da", "Taglia", "Tagliato da", "Si appoggia a",
123
+ "Gli si appoggia"),
124
+ "en": ("Same as", "Connected to", "Covers", "Covered by", "Fills",
125
+ "Filled by", "Cuts", "Cut by", "Abuts", "Supports"),
126
+ "de": ("Entspricht", "Bindet an", "Liegt über", "Liegt unter",
127
+ "Verfüllt", "Wird verfüllt durch", "Schneidet",
128
+ "Wird geschnitten", "Stützt sich auf", "Wird gestützt von"),
129
+ "es": ("Igual a", "Se liga a", "Cubre", "Cubierto por", "Rellena",
130
+ "Rellenado por", "Corta", "Cortado por", "Se apoya en",
131
+ "Le se apoya"),
132
+ "fr": ("Égal à", "Se lie à", "Couvre", "Couvert par",
133
+ "Remplit", "Rempli par", "Coupe", "Coupé par",
134
+ "S’appuie sur", "Lui s’appuie"),
135
+ "ar": ("مساوي ل", "يرتبط ب",
136
+ "يغطي", "مغطى من",
137
+ "يملأ", "ممتلئ من",
138
+ "يقطع", "مقطوع من",
139
+ "يستند إلى",
140
+ "يستند عليه"),
141
+ "ca": ("Igual a", "Es lliga a", "Cobreix", "Cobert per", "Omple",
142
+ "Omplert per", "Talla", "Tallat per", "S’recolza en",
143
+ "Li es recolza"),
144
+ "ro": ("Egal cu", "Se leagă de", "Acoperă", "Acoperit de",
145
+ "Umple", "Umplut de", "Taie", "Tăiat de",
146
+ "Se sprijină pe", "I se sprijină"),
147
+ "pt": ("Igual a", "Liga-se a", "Cobre", "Coberto por", "Preenche",
148
+ "Preenchido por", "Corta", "Cortado por", "Apoia-se em",
149
+ "Apoiado por"),
150
+ "el": ("Ίσο με", "Συνδέεται με",
151
+ "Καλύπτει",
152
+ "Καλύπτεται από",
153
+ "Γεμίζει",
154
+ "Γεμίζεται από",
155
+ "Τέμνει", "Τέμνεται από",
156
+ "Εφάπτεται", "Υποστηρίζει"),
157
+ }
158
+
159
+ # Fold every language's terms into RAPPORTI_TO_EDGE_TYPE (keys lowercased to
160
+ # match parse_rapporti's lookup). setdefault keeps the explicit aliases above
161
+ # (e.g. "bonds with").
162
+ for _terms in _REL_TERMS_BY_LANG.values():
163
+ for _i, _term in enumerate(_terms):
164
+ RAPPORTI_TO_EDGE_TYPE.setdefault(_term.lower(), _REL_INDEX_EDGE_TYPE[_i])
165
+ del _terms, _i, _term
166
+
167
+
93
168
  # ---------------------------------------------------------------------------
94
169
  # Inverse: canonical edge type → verbose Italian rapporti label
95
170
  # ---------------------------------------------------------------------------
@@ -186,9 +261,41 @@ EDGE_TYPE_DIRECTION_FORWARD: dict[str, bool] = {
186
261
  # ---------------------------------------------------------------------------
187
262
  # Unit-type frozensets driving the verbose-vs-shorthand dispatch
188
263
  # ---------------------------------------------------------------------------
189
- #: Unit types where both endpoints get the verbose Italian dispatch
190
- #: ("Copre", "Coperto da", ...). Stratigraphic Harris atoms only.
191
- CANONICAL_UNIT_TYPES: frozenset[str] = frozenset({"US", "USM"})
264
+ #: Localized US / USM ``unita_tipo`` code → canonical code. pyArchInit
265
+ #: localizes ONLY the US / USM abbreviations per UI language (its
266
+ #: ``pyarchinit_i18n_stratigraphic.UNIT_TYPE_ABBREV`` is the source of
267
+ #: truth). This module is the pyArchInit↔canonical bridge, and the
268
+ #: prefix-strip regex above already enumerates SU|SE|WSU|MSE|UE|…, so the
269
+ #: gating set lives here too. The mapping doubles as the normalization
270
+ #: source: any code path that needs the canonical form calls
271
+ #: :func:`canonical_unita_tipo`. ``attributes['unita_tipo']`` is kept
272
+ #: VERBATIM (original code) elsewhere so round-trip stays byte-identical;
273
+ #: only the verbose/shorthand dispatch and the projector's stratigraphic
274
+ #: gating read through this alias map.
275
+ #:
276
+ #: US → US (it/fr/ro) · SU (en/ar) · SE (de) · UE (es/ca/pt) · ΣΜ (el)
277
+ #: USM → USM (it/fr) · WSU (en/ar) · MSE (de) · UEM (es/ca/pt) ·
278
+ #: USZ (ro) · ΤΣΜ (el)
279
+ UNITA_TIPO_CANONICAL: dict[str, str] = {
280
+ "US": "US", "SU": "US", "SE": "US", "UE": "US", "ΣΜ": "US",
281
+ "USM": "USM", "WSU": "USM", "MSE": "USM", "UEM": "USM",
282
+ "USZ": "USM", "ΤΣΜ": "USM",
283
+ }
284
+
285
+
286
+ def canonical_unita_tipo(unita_tipo) -> str:
287
+ """Map a (possibly localized) US/USM code to its canonical form.
288
+
289
+ Non-US/USM codes (USV*, SF, CON, DOC, …) and unknown values pass
290
+ through unchanged.
291
+ """
292
+ return UNITA_TIPO_CANONICAL.get(unita_tipo, unita_tipo)
293
+
294
+
295
+ #: Unit types where both endpoints get the verbose dispatch ("Copre"/
296
+ #: "Covers"/…, "Coperto da"/"Covered by"/…). All language variants of the
297
+ #: Harris US/USM atoms, derived from the alias map so the two never drift.
298
+ CANONICAL_UNIT_TYPES: frozenset[str] = frozenset(UNITA_TIPO_CANONICAL)
192
299
 
193
300
 
194
301
  #: Continuity unit type. Single-arrow shorthand ``>`` / ``<`` is
@@ -464,6 +571,49 @@ def _coerce_to_list(value):
464
571
  return []
465
572
 
466
573
 
574
+ #: Arrow tokens emitted by :func:`select_rapporti_label` for
575
+ #: non-canonical endpoints. When the dispatch returns one of these we do
576
+ #: NOT override it with a verbose row term (virtual units keep ``>>`` /
577
+ #: ``<<``, continuity keeps ``>`` / ``<``).
578
+ _SHORTHAND_TOKENS: frozenset[str] = frozenset({">", "<", ">>", "<<"})
579
+
580
+
581
+ def _source_rapporti_label(src_node, target_us: str, edge_type: str):
582
+ """Original pyArchInit ``rapporti`` term on *src_node* for *target_us*.
583
+
584
+ The d13 packed string is wire format that should byte-match the
585
+ originating ``us_table.rapporti``, so for a verbose relation we anchor
586
+ the label on the source row's own stored term (in the site's UI
587
+ language — "Covers" / "Couvre" / "Copre" / …) rather than the canonical
588
+ Italian. The label language can't be reconstructed from ``edge_type``
589
+ alone (e.g. "US" is shared by it / fr / ro), so the node's own term is
590
+ the only reliable source.
591
+
592
+ Returned in the canonical display casing (first letter upper, rest
593
+ lower — the form pyArchInit shows). Matching prefers the entry whose
594
+ label maps to the SAME canonical ``edge_type`` (disambiguates multiple
595
+ relations to one target), falling back to any verbose entry pointing at
596
+ ``target_us``. Returns ``None`` when the node carries no usable
597
+ ``rapporti`` attribute (e.g. a yEd-imported graph) — the caller then
598
+ keeps the canonical dispatch label.
599
+ """
600
+ attrs = getattr(src_node, "attributes", None) or {}
601
+ fallback = None
602
+ for entry in _coerce_to_list(attrs.get("rapporti")):
603
+ if not isinstance(entry, (list, tuple)) or len(entry) < 2:
604
+ continue
605
+ lbl = str(entry[0]).strip()
606
+ tgt = str(entry[1]).strip()
607
+ if tgt != str(target_us) or not lbl or lbl in _SHORTHAND_TOKENS:
608
+ continue
609
+ lbl = lbl.capitalize()
610
+ if RAPPORTI_TO_EDGE_TYPE.get(lbl.lower()) == edge_type:
611
+ return lbl
612
+ if fallback is None:
613
+ fallback = lbl
614
+ return fallback
615
+
616
+
467
617
  def serialize_rapporti_from_edges(graph, default_sito: str):
468
618
  """Walk *graph*'s edges and produce per-US rapporti lists ready
469
619
  for the pyarchinit ``us_table.rapporti`` column.
@@ -512,8 +662,6 @@ def serialize_rapporti_from_edges(graph, default_sito: str):
512
662
  continue
513
663
  src_unita_tipo = resolve_unita_tipo_for_dispatch(src_node)
514
664
  tgt_unita_tipo = resolve_unita_tipo_for_dispatch(tgt_node)
515
- rapporti_label = select_rapporti_label(
516
- et, src_unita_tipo, tgt_unita_tipo)
517
665
  tgt_attrs = getattr(tgt_node, "attributes", None) or {}
518
666
  tgt_us = tgt_attrs.get("us")
519
667
  if not tgt_us:
@@ -521,6 +669,18 @@ def serialize_rapporti_from_edges(graph, default_sito: str):
521
669
  if not tgt_name:
522
670
  continue
523
671
  tgt_us = strip_us_prefix(str(tgt_name))
672
+ rapporti_label = select_rapporti_label(
673
+ et, src_unita_tipo, tgt_unita_tipo)
674
+ # For a verbose relation (both endpoints real US/USM, any language)
675
+ # anchor the term on the source row's own rapporti column so the
676
+ # packed string byte-matches the DB in the site's UI language;
677
+ # fall back to the canonical label when the source carries no
678
+ # rapporti attribute (e.g. yEd-imported graphs). Virtual units
679
+ # (``>>`` / ``<<``) and continuity (``>`` / ``<``) keep shorthand.
680
+ if rapporti_label not in _SHORTHAND_TOKENS:
681
+ original = _source_rapporti_label(src_node, str(tgt_us), et)
682
+ if original:
683
+ rapporti_label = original
524
684
  tgt_area = str(tgt_attrs.get("area") or "1")
525
685
  tgt_sito = default_sito
526
686
  rapporto = [rapporti_label, str(tgt_us), tgt_area, tgt_sito]
@@ -536,6 +696,8 @@ __all__ = [
536
696
  "EDGE_TYPE_TO_RAPPORTI_IT",
537
697
  "RAPPORTI_SHORTHAND",
538
698
  "EDGE_TYPE_DIRECTION_FORWARD",
699
+ "UNITA_TIPO_CANONICAL",
700
+ "canonical_unita_tipo",
539
701
  "CANONICAL_UNIT_TYPES",
540
702
  "CONTINUITY_UNIT_TYPES",
541
703
  "NON_RAPPORTI_EDGE_TYPES",
@@ -6,12 +6,12 @@ SQLite and PostgreSQL backends through the `DbHandle` abstraction
6
6
  (Foundation 5.6.2-alpha) — all SQL is expressed as SQLAlchemy
7
7
  ``text()`` statements with named bind parameters.
8
8
 
9
- Public API:
9
+ Public API::
10
10
 
11
11
  import_yed_raw(handle, graphml_path, sito, drafts, *,
12
12
  policy=SKIP, dry_run=False) -> IngestResult
13
13
 
14
- Internal helpers (testable in isolation):
14
+ Internal helpers (testable in isolation)::
15
15
 
16
16
  _classify_destination(classified)
17
17
  _flatten_members(folder, all_folders)
@@ -16,7 +16,7 @@ Self-loop folder edges (source == target) are filtered out of ALL
16
16
  policies before policy application — they arise from nested folder
17
17
  member edges authored in yEd and would otherwise produce noise.
18
18
 
19
- Public API:
19
+ Public API::
20
20
 
21
21
  FolderEdgePolicy (StrEnum: skip / fan_out / representative / synthetic)
22
22
  FolderEdge (dataclass: src, tgt, src_is_folder, tgt_is_folder, edge_type)
@@ -26,6 +26,7 @@ Public API:
26
26
  apply_policy(report, policy, *, all_folders, classified) -> ExpandedRapporti
27
27
 
28
28
  Implementation notes:
29
+
29
30
  * `analyze_edges` parses <edge> elements via lxml (falling back to
30
31
  stdlib `xml.etree.ElementTree`) and classifies each endpoint as a
31
32
  folder or a leaf based on the dataclass lookups passed in.
@@ -3,11 +3,12 @@
3
3
  Reads the top-level <y:TableNode configuration="YED_TABLE_NODE"> of a
4
4
  yEd-raw graphml and extracts archaeological period candidates from
5
5
  its swimlane rows. Each row produces a PeriodCandidate with:
6
- - auto_label from <y:NodeLabel> text
7
- - auto_periodo from 1-based row ordinal
8
- - auto_fase always 1 (yEd table rows don't encode phases)
9
- - member_yed_ids from leaf nodes whose Y-coordinate falls in the
10
- row's Y-range
6
+
7
+ - auto_label from <y:NodeLabel> text
8
+ - auto_periodo from 1-based row ordinal
9
+ - auto_fase always 1 (yEd table rows don't encode phases)
10
+ - member_yed_ids from leaf nodes whose Y-coordinate falls in the
11
+ row's Y-range
11
12
 
12
13
  datazione_iniziale / datazione_finale are NOT extracted (yEd doesn't
13
14
  encode dates on table rows) — user fills them later in the