s3dgraphy 1.6.0.dev14__tar.gz → 1.6.0.dev15__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 (359) hide show
  1. {s3dgraphy-1.6.0.dev14/src/s3dgraphy.egg-info → s3dgraphy-1.6.0.dev15}/PKG-INFO +1 -1
  2. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/pyproject.toml +1 -1
  3. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/s3Dgraphy_connections_datamodel.json +13 -10
  4. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/__init__.py +1 -1
  5. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/api.py +398 -15
  6. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/container.py +64 -7
  7. s3dgraphy-1.6.0.dev15/src/s3dgraphy/contract/__init__.py +49 -0
  8. s3dgraphy-1.6.0.dev15/src/s3dgraphy/contract/connector.py +576 -0
  9. s3dgraphy-1.6.0.dev15/src/s3dgraphy/contract/consumer.py +481 -0
  10. s3dgraphy-1.6.0.dev15/src/s3dgraphy/contract/core.py +350 -0
  11. s3dgraphy-1.6.0.dev15/src/s3dgraphy/contract/reference.py +93 -0
  12. s3dgraphy-1.6.0.dev15/src/s3dgraphy/dtc/__init__.py +80 -0
  13. s3dgraphy-1.6.0.dev15/src/s3dgraphy/dtc/corpus.py +295 -0
  14. s3dgraphy-1.6.0.dev15/src/s3dgraphy/dtc/ingest.py +639 -0
  15. s3dgraphy-1.6.0.dev15/src/s3dgraphy/exporter/html_exporter.py +249 -0
  16. s3dgraphy-1.6.0.dev15/src/s3dgraphy/exporter/ipynb_exporter.py +306 -0
  17. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/exporter/latex_exporter.py +170 -23
  18. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/exporter/rdf_exporter.py +14 -0
  19. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/geometry/__init__.py +14 -2
  20. s3dgraphy-1.6.0.dev15/src/s3dgraphy/geometry/store_backed.py +276 -0
  21. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/iiif.py +62 -2
  22. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/narrative/bake.py +95 -4
  23. s3dgraphy-1.6.0.dev15/src/s3dgraphy/narrative/query.py +357 -0
  24. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/narrative/site_story.py +95 -26
  25. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/publication.py +80 -16
  26. s3dgraphy-1.6.0.dev15/src/s3dgraphy/rights.py +522 -0
  27. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/study.py +139 -1
  28. s3dgraphy-1.6.0.dev15/src/s3dgraphy/tools/consumer_drift.py +188 -0
  29. s3dgraphy-1.6.0.dev15/src/s3dgraphy/tools/wheel_drift.py +256 -0
  30. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15/src/s3dgraphy.egg-info}/PKG-INFO +1 -1
  31. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy.egg-info/SOURCES.txt +25 -0
  32. s3dgraphy-1.6.0.dev15/tests/test_asset_dtc_protocol.py +209 -0
  33. s3dgraphy-1.6.0.dev15/tests/test_consumer_drift.py +99 -0
  34. s3dgraphy-1.6.0.dev15/tests/test_contract.py +399 -0
  35. s3dgraphy-1.6.0.dev15/tests/test_contract_consumer.py +491 -0
  36. s3dgraphy-1.6.0.dev15/tests/test_dtc_corpus.py +291 -0
  37. s3dgraphy-1.6.0.dev15/tests/test_dtc_ingest.py +388 -0
  38. s3dgraphy-1.6.0.dev15/tests/test_ipynb_exporter.py +141 -0
  39. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_latex_exporter.py +55 -7
  40. s3dgraphy-1.6.0.dev15/tests/test_narrative_figures.py +371 -0
  41. s3dgraphy-1.6.0.dev15/tests/test_narrative_query.py +221 -0
  42. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_narrative_scaffolder.py +37 -7
  43. s3dgraphy-1.6.0.dev15/tests/test_store_backed_geometry.py +203 -0
  44. s3dgraphy-1.6.0.dev15/tests/test_wheel_drift.py +184 -0
  45. s3dgraphy-1.6.0.dev14/src/s3dgraphy/dtc/__init__.py +0 -34
  46. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/LICENSE +0 -0
  47. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/MANIFEST.in +0 -0
  48. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/README.md +0 -0
  49. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/setup.cfg +0 -0
  50. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/acquisition_descriptor.schema.json +0 -0
  51. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/acquisition_mappings/ercolano.json +0 -0
  52. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/acquisition_mappings/fs.json +0 -0
  53. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/datamodel_translations.json +0 -0
  54. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/em.ttl +0 -0
  55. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/em_document_types.json +0 -0
  56. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/em_extractor_types.json +0 -0
  57. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/em_palette_icons.json +0 -0
  58. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/em_qualia_types.json +0 -0
  59. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/em_qualia_types_additions.json +0 -0
  60. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/em_visual_rules.json +0 -0
  61. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/hdto_extension.ttl +0 -0
  62. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/new_qualia_template.json +0 -0
  63. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/node_registry.generated.json +0 -0
  64. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/outdated_s3dgraphy.ttl +0 -0
  65. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/outdated_s3dgraphy_nomapping.ttl +0 -0
  66. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/s3Dgraphy_connections_datamodel.json.v155.bak +0 -0
  67. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/s3Dgraphy_node_datamodel.json +0 -0
  68. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/ActivityNodeGroup.svg +0 -0
  69. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/EMNarrative.png +0 -0
  70. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/EMNarrative.svg +0 -0
  71. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/EpochNode.svg +0 -0
  72. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/ParadataNodeGroup.svg +0 -0
  73. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/RSF.png +0 -0
  74. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/RSF.svg +0 -0
  75. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/SE.svg +0 -0
  76. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/SE_old.png +0 -0
  77. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/SE_old.svg +0 -0
  78. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/SF.png +0 -0
  79. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/SF.svg +0 -0
  80. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/TSU.png +0 -0
  81. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/US.png +0 -0
  82. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/US.svg +0 -0
  83. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/USD.png +0 -0
  84. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/USD.svg +0 -0
  85. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/USVn.png +0 -0
  86. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/USVn.svg +0 -0
  87. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/USVs.png +0 -0
  88. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/USVs.svg +0 -0
  89. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/UTR.svg +0 -0
  90. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/VSF.png +0 -0
  91. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/VSF.svg +0 -0
  92. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/author.png +0 -0
  93. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/author.svg +0 -0
  94. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/author_ai.png +0 -0
  95. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/combiner.png +0 -0
  96. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/combiner.svg +0 -0
  97. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/continuity.png +0 -0
  98. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/continuity.svg +0 -0
  99. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/document.png +0 -0
  100. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/document.svg +0 -0
  101. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/dtc/00_transformation.svg +0 -0
  102. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/dtc/01_topographicnetwork.svg +0 -0
  103. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/dtc/02_pointcloud.svg +0 -0
  104. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/dtc/03_mesh.svg +0 -0
  105. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/dtc/04_points.svg +0 -0
  106. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/dtc/05_lines.svg +0 -0
  107. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/dtc/06_polygons.svg +0 -0
  108. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/dtc/07_DEM.svg +0 -0
  109. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/dtc/08_ortophoto.svg +0 -0
  110. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/dtc/09_photos.svg +0 -0
  111. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/dtc/10_laserscanner.svg +0 -0
  112. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/embargo.png +0 -0
  113. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/extractor.png +0 -0
  114. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/extractor.svg +0 -0
  115. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/generic_node.svg +0 -0
  116. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/geo_position.svg +0 -0
  117. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/license.png +0 -0
  118. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/link.svg +0 -0
  119. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/narrative.png +0 -0
  120. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/play.svg +0 -0
  121. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/property.png +0 -0
  122. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/property.svg +0 -0
  123. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/representation_model.svg +0 -0
  124. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/representation_model_doc.svg +0 -0
  125. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/representation_model_sf.svg +0 -0
  126. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/semantic_shape.svg +0 -0
  127. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/serSU.png +0 -0
  128. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/serSU.svg +0 -0
  129. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/serUSD.png +0 -0
  130. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/serUSV.png +0 -0
  131. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/serUSVn.svg +0 -0
  132. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/2D/serUSVs.svg +0 -0
  133. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/3D/RSF.glb +0 -0
  134. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/3D/SF.glb +0 -0
  135. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/3D/TSU.glb +0 -0
  136. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/3D/US.glb +0 -0
  137. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/3D/USD.glb +0 -0
  138. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/3D/USVn.glb +0 -0
  139. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/3D/USVs.glb +0 -0
  140. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/3D/VSF.glb +0 -0
  141. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/3D/combiner.glb +0 -0
  142. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/3D/continuity.glb +0 -0
  143. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/3D/document.glb +0 -0
  144. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/3D/extractor.glb +0 -0
  145. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/3D/property.glb +0 -0
  146. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/3D/serSU.glb +0 -0
  147. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/3D/serUSD.glb +0 -0
  148. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/JSON_config/src/3D/serUSV.glb +0 -0
  149. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/acquisition/__init__.py +0 -0
  150. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/acquisition/acquire.py +0 -0
  151. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/acquisition/descriptor.py +0 -0
  152. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/acquisition/mapping.py +0 -0
  153. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/annotation/__init__.py +0 -0
  154. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/annotation/paradata.py +0 -0
  155. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/authorities/__init__.py +0 -0
  156. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/authorities/resolver.py +0 -0
  157. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/authorities/snapshots/LICENSE +0 -0
  158. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/authorities/snapshots/chronontology.jsonld +0 -0
  159. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/authorities/snapshots/getty_aat.jsonld +0 -0
  160. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/authorities/snapshots/getty_tgn.jsonld +0 -0
  161. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/authorities/snapshots/periodo.jsonld +0 -0
  162. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/authorities/snapshots/provenance.json +0 -0
  163. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/classification.py +0 -0
  164. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/crdt.py +0 -0
  165. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/data/StratiMiner_Extraction_Prompt.md +0 -0
  166. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/diagnostics.py +0 -0
  167. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/dissemination.py +0 -0
  168. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/dtc/residency.py +0 -0
  169. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/edges/__init__.py +0 -0
  170. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/edges/connection_resolver.py +0 -0
  171. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/edges/connections_loader.py +0 -0
  172. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/edges/edge.py +0 -0
  173. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/editorial.py +0 -0
  174. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/exporter/__init__.py +0 -0
  175. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/exporter/docx_exporter.py +0 -0
  176. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/exporter/emjson_exporter.py +0 -0
  177. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/exporter/graphml/__init__.py +0 -0
  178. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/exporter/graphml/canvas_generator.py +0 -0
  179. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/exporter/graphml/edge_generator.py +0 -0
  180. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/exporter/graphml/epoch_generator.py +0 -0
  181. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/exporter/graphml/graphml_exporter.py +0 -0
  182. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/exporter/graphml/graphml_patcher.py +0 -0
  183. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/exporter/graphml/group_node_generator.py +0 -0
  184. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/exporter/graphml/node_generator.py +0 -0
  185. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/exporter/graphml/node_registry.py +0 -0
  186. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/exporter/graphml/palette_resources.py +0 -0
  187. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/exporter/graphml/paradata_generator.py +0 -0
  188. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/exporter/graphml/paradata_image_generator.py +0 -0
  189. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/exporter/graphml/paradata_node_generators.py +0 -0
  190. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/exporter/graphml/table_node_generator.py +0 -0
  191. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/exporter/graphml/utils.py +0 -0
  192. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/exporter/json_exporter.py +0 -0
  193. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/exporter/unified_xlsx_exporter.py +0 -0
  194. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/geometry/migrate.py +0 -0
  195. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/geometry/proxy.py +0 -0
  196. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/graph.py +0 -0
  197. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/importer/__init__.py +0 -0
  198. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/importer/base_importer.py +0 -0
  199. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/importer/emjson_importer.py +0 -0
  200. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/importer/import_graphml.py +0 -0
  201. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/importer/mapped_xlsx_importer.py +0 -0
  202. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/importer/pyarchinit_importer.py +0 -0
  203. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/importer/qualia_importer.py +0 -0
  204. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/importer/rdf_importer.py +0 -0
  205. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/importer/source_text.py +0 -0
  206. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/importer/unified_xlsx_importer.py +0 -0
  207. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/importer/xlsx_importer.py +0 -0
  208. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/indices.py +0 -0
  209. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/mappings/__init__.py +0 -0
  210. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/mappings/emdb/generic_specialfind_mapping.json +0 -0
  211. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/mappings/emdb/site_properties_mapping.json +0 -0
  212. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/mappings/emdb/usm_mapping.json +0 -0
  213. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/mappings/generic/excel_to_graphml_mapping.json +0 -0
  214. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/mappings/pyarchinit/pyarchinit_us_mapping.json +0 -0
  215. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/mappings/registry.py +0 -0
  216. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/mappings/source_list/source_list_mapping.json +0 -0
  217. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/mappings/template_emdb_mapping.json +0 -0
  218. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/mappings/template_pyarchinit_mapping.json +0 -0
  219. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/merge/__init__.py +0 -0
  220. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/merge/graph_merger.py +0 -0
  221. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/multigraph/__init__.py +0 -0
  222. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/multigraph/multigraph.py +0 -0
  223. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/narrative/__init__.py +0 -0
  224. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/narrative/generation.py +0 -0
  225. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/narrative/registry.py +0 -0
  226. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/nodes/__init__.py +0 -0
  227. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/nodes/annotation_region_node.py +0 -0
  228. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/nodes/author_node.py +0 -0
  229. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/nodes/base_node.py +0 -0
  230. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/nodes/combiner_node.py +0 -0
  231. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/nodes/document_node.py +0 -0
  232. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/nodes/dtc_acquisition_node.py +0 -0
  233. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/nodes/dtc_node.py +0 -0
  234. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/nodes/dtc_process_node.py +0 -0
  235. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/nodes/embargo_node.py +0 -0
  236. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/nodes/epoch_node.py +0 -0
  237. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/nodes/extractor_node.py +0 -0
  238. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/nodes/geo_position_node.py +0 -0
  239. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/nodes/graph_node.py +0 -0
  240. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/nodes/group_node.py +0 -0
  241. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/nodes/hdt_node.py +0 -0
  242. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/nodes/heritage_entity_node.py +0 -0
  243. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/nodes/license_node.py +0 -0
  244. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/nodes/narrative_node.py +0 -0
  245. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/nodes/paradata_node.py +0 -0
  246. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/nodes/project_node.py +0 -0
  247. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/nodes/property_node.py +0 -0
  248. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/nodes/representation_node.py +0 -0
  249. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/nodes/resource_node.py +0 -0
  250. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/nodes/semantic_shape_node.py +0 -0
  251. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/nodes/stratigraphic_node.py +0 -0
  252. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/nodes/study_node.py +0 -0
  253. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/resolvers/__init__.py +0 -0
  254. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/resolvers/builtin_rules.py +0 -0
  255. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/resolvers/property_resolver.py +0 -0
  256. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/resources/__init__.py +0 -0
  257. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/resources/fs_backend.py +0 -0
  258. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/resources/minio_backend.py +0 -0
  259. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/resources/resolver.py +0 -0
  260. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/shelf/__init__.py +0 -0
  261. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/shelf/core.py +0 -0
  262. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/sync/__init__.py +0 -0
  263. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/sync/_db_handle.py +0 -0
  264. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/sync/_legacy_paradata_svgs.py +0 -0
  265. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/sync/_workspace.py +0 -0
  266. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/sync/conflict_resolver.py +0 -0
  267. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/sync/edge_registry.py +0 -0
  268. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/sync/graph_ingestor.py +0 -0
  269. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/sync/graph_projector.py +0 -0
  270. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/sync/graphml_writer.py +0 -0
  271. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/sync/group_projector.py +0 -0
  272. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/sync/group_store.py +0 -0
  273. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/sync/ingest_result.py +0 -0
  274. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/sync/paradata_store.py +0 -0
  275. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/sync/pyarchinit_pg_importer.py +0 -0
  276. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/sync/rapporti.py +0 -0
  277. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/sync/uuid7.py +0 -0
  278. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/sync/vocab_provider_core.py +0 -0
  279. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/sync/vocab_types.py +0 -0
  280. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/sync/yed_classifier.py +0 -0
  281. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/sync/yed_detector.py +0 -0
  282. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/sync/yed_group_walker.py +0 -0
  283. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/sync/yed_import_pipeline.py +0 -0
  284. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/sync/yed_rapporti_policy.py +0 -0
  285. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/sync/yed_table_parser.py +0 -0
  286. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/templates/em_data_template.xlsx +0 -0
  287. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/templates/em_palette_template.graphml +0 -0
  288. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/temporal/__init__.py +0 -0
  289. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/temporal/inference_engine.py +0 -0
  290. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/tools/__init__.py +0 -0
  291. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/tools/datamodel_i18n.py +0 -0
  292. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/tools/sync_node_datamodel.py +0 -0
  293. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/transforms/__init__.py +0 -0
  294. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/transforms/aux_tracking.py +0 -0
  295. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/transforms/compact.py +0 -0
  296. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/transforms/materialize_continuity.py +0 -0
  297. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/utils/__init__.py +0 -0
  298. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/utils/utils.py +0 -0
  299. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy/utils/visual_layout.py +0 -0
  300. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy.egg-info/dependency_links.txt +0 -0
  301. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy.egg-info/requires.txt +0 -0
  302. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/src/s3dgraphy.egg-info/top_level.txt +0 -0
  303. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_acquisition.py +0 -0
  304. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_acquisition_fs.py +0 -0
  305. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_api_surface.py +0 -0
  306. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_authority_projection.py +0 -0
  307. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_authority_resolver.py +0 -0
  308. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_canonical_document_rename.py +0 -0
  309. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_canvas_metadata_import.py +0 -0
  310. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_composite_node_name.py +0 -0
  311. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_connection_resolver.py +0 -0
  312. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_container.py +0 -0
  313. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_convert_command.py +0 -0
  314. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_crdt.py +0 -0
  315. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_datamodel_i18n.py +0 -0
  316. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_deterministic_ids.py +0 -0
  317. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_dissemination_tombstones.py +0 -0
  318. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_dtc_projection.py +0 -0
  319. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_dtc_residency.py +0 -0
  320. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_editorial.py +0 -0
  321. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_emjson_roundtrip.py +0 -0
  322. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_emjson_schema_version.py +0 -0
  323. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_epoch_undated_import.py +0 -0
  324. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_explicit_node_type_marker.py +0 -0
  325. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_filtered_import.py +0 -0
  326. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_fs_backend.py +0 -0
  327. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_functional_units.py +0 -0
  328. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_georeference_scene.py +0 -0
  329. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_graph_scope_migration.py +0 -0
  330. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_hdto_projection.py +0 -0
  331. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_header_key_aliases.py +0 -0
  332. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_iiif.py +0 -0
  333. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_importer_edge_hygiene.py +0 -0
  334. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_lossless_roundtrip.py +0 -0
  335. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_material_color.py +0 -0
  336. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_merge_conflicts.py +0 -0
  337. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_migrate_legacy_proxy.py +0 -0
  338. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_minio_backend.py +0 -0
  339. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_narrative_authorship.py +0 -0
  340. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_narrative_bake_docx.py +0 -0
  341. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_narrative_generation.py +0 -0
  342. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_narrative_node.py +0 -0
  343. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_node_datamodel_registry.py +0 -0
  344. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_pg_importer.py +0 -0
  345. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_promotion.py +0 -0
  346. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_pyarchinit_tier2.py +0 -0
  347. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_rdf_roundtrip.py +0 -0
  348. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_recompute_warnings.py +0 -0
  349. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_reproject.py +0 -0
  350. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_resource_layer.py +0 -0
  351. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_shelf.py +0 -0
  352. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_shelf_facets.py +0 -0
  353. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_shelf_hatting.py +0 -0
  354. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_source_list_mapping.py +0 -0
  355. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_source_text.py +0 -0
  356. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_stratiminer_api.py +0 -0
  357. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_study_metadata.py +0 -0
  358. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_ttl_roundtrip.py +0 -0
  359. {s3dgraphy-1.6.0.dev14 → s3dgraphy-1.6.0.dev15}/tests/test_xlsx_importer_graph_init.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: s3dgraphy
3
- Version: 1.6.0.dev14
3
+ Version: 1.6.0.dev15
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>
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "s3dgraphy"
7
- version = "1.6.0.dev14"
7
+ version = "1.6.0.dev15"
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,6 +1,6 @@
1
1
  {
2
- "s3Dgraphy_connections_model_version": "1.6.10",
3
- "description": "s3Dgraphy connections datamodel including edge types with CIDOC-CRM mappings. v1.6.8 (MIG1-A): graph-scope rights metadata become first-class nodes (DP-65). is_in_paradata_nodegroup.source += AuthorNode/LicenseNode/EmbargoNode and has_paradata_nodegroup.source += GraphNode, so the graph-self node (GraphNode) owns a graph-scope ParadataNodeGroup whose members are the AuthorNode/LicenseNode/EmbargoNode (+ the DP-65 GeoPositionNode shift), replacing the legacy graph.data['author_name'/'license'/'embargo'] fields. The Data Funnel canvas tier now reads these member nodes (one reader per scope); a one-shot load-time migration materialises the legacy fields into nodes. v1.6.7 (BUGFIX-CONN3): closes the two silent follow-ups of CONN2. has_documentation.source gains PropertyNode (judicious widening): the honest reading of a legacy yEd dashed PropertyNode→Document connector is P70i_is_documented_in ('the property is documented in this source'), NOT has_visual_reference (which CONN2 moved to PropertyNode→ResourceNode). The import heuristic (import_graphml.enhance_edge_type) now routes PropertyNode→Document to has_documentation and the rarer CombinerNode/ParadataNode→Document to generic_connection+warning (a combiner aggregates extractors and cites no document; the DTC chain is NOT synthesised at import). Shelf: hat_as_document no longer offers has_visual_reference (a Document attaches via has_documentation/extracted_from); a new hat_as_visual_resource attaches a ResourceNode image via has_visual_reference from a PropertyNode — the correct home after CONN2. No illegal edge is produced or expected. v1.6.6 (BUGFIX-CONN2): closes the two open domain questions on has_visual_reference (E.D. 2026-08-05). SOURCE narrowed to exactly [PropertyNode]: only a property (an asserted quale) is what a visual reference illustrates; the generic ParadataNode entry is dropped, which — because ExtractorNode, CombinerNode and DocumentNode are all subclasses of ParadataNode — now excludes them by class hierarchy (a PropertyNode is neither a sibling nor a parent of the others). The extractor/combiner denied_edges from v1.6.5 are therefore REDUNDANT for this edge but are KEPT as a defensive guard (they still bite if the source is ever broadened back to ParadataNode). TARGET changed from [DocumentNode] to [ResourceNode]: the oddity was that a visual reference pointed at a source-document (E31) rather than at a visual resource. It now points at the resource-layer image node (ResourceNode = E73 Information Object / ExternalResourceReference — the same P67 hinge RM/RMDoc use via has_linked_resource), keeping DocumentNode = fonte. CIDOC stays P138i_has_representation with the target co-typed E36 Visual Item: E36 is a subclass of E73, so co-typing a ResourceNode as E36 is range-consistent (it was NOT, strictly, for an E31 Document). FOLLOW-UPS flagged for E.D. (see end-of report): (a) import_graphml.enhance_edge_type still hardcodes PropertyNode/Combiner/Paradata→DocumentNode ⇒ has_visual_reference (legacy yEd heuristic, now produces an edge this datamodel refuses) — needs a domain decision on what legacy paradata→document edges become; (b) shelf.hat_as_document lists has_visual_reference among the Document-attach edges — it can no longer validate (target is ResourceNode), so a paradata attach silently no longer attaches; a hat_as_visual_resource(ResourceNode)+has_visual_reference path is the proper home. v1.6.5 (BUGFIX-CONN): has_visual_reference is no longer offered FROM an ExtractorNode or a CombinerNode. An extractor toward a document expresses ONLY extracted_from (its relation to the source is the extraction, not an illustration); a combiner aggregates extractors and illustrates nothing. Because ExtractorNode, CombinerNode and PropertyNode are all subclasses of ParadataNode, and has_visual_reference.source lists ParadataNode, simply dropping the two subtypes from the source list would not exclude them (they still match via the parent class). So this is expressed with node_type_restrictions (keyed by RUNTIME node_type, like USNt) using a new denied_edges blacklist (the mirror of allowed_edges): extractor/combiner deny has_visual_reference. PropertyNode and any other legitimate ParadataNode source keep it unchanged. OPEN domain question for E.D.: which paradata node-types may legitimately have a visual reference (today source = PropertyNode/ExtractorNode/CombinerNode/ParadataNode) — extractor/combiner removed; the rest left as-is, not invented. v1.6.1: has_paradata_nodegroup source extended to include EpochNode — an epoch can now own a ParadataNodeGroup holding its temporal-definition properties (e.g. absolute_time_start/end as PropertyNodes with paradata provenance), mirroring how a StratigraphicNode carries its paradata group. v1.6.0 (paired with node datamodel v1.6.0) introduces: bug fix on is_in_paradata_nodegroup (typo 'ProperrtyNOde' → 'PropertyNode'); semantic fix on has_documentation (P104_is_subject_to → P70i_is_documented_in — P104 means 'subject to a legal right', not 'has documentation'); deprecation of has_timebranch as duplicate of is_in_timebranch (the latter is the canonical one — used by import_graphml.py and graphml_patcher.py; the former exists only in config JSON); component list aligned with node datamodel (HDT-O, PROV-O added). HDT-O containment properties (hdto:contains_HDT, hdto:contains_SU, hdto:isPrimary) and physical-relation discriminator subproperties (em:abuts, em:cuts, em:fills, em:overlies, em:bonded_to, em:equals as rdfs:subPropertyOf crmarchaeo:AP11_has_physical_relation) to be added in v1.6.1. v1.5.3 introduced canonical/reverse directionality with verb-based labels for clear socket identification in node editors. v1.5.4 added 'has_visual_reference' edge type. v1.5.5 added 'is_in_location' edge type with context-sensitive CIDOC mapping (P53 for node→location, P89 for the recursive location→location hierarchy) and an optional 'is_primary' boolean attribute (s3d:isPrimary, proposed). v1.6.3: added node_type_restrictions — a per-node-type narrowing of the class-level edge rules (POL5): USN (the NEUTRAL stratigraphic unit, a risparmio) takes is_after/is_before and nothing else, because a void cannot cut, fill, abut or bond. v1.6.4 (POL6): the same restriction, moved to USNt — the tokens went back to their conventional meanings, USN = US negativa (all relations, it is a unit of the sequence) and USNt = US neutra (sequence only).",
2
+ "s3Dgraphy_connections_model_version": "1.6.11",
3
+ "description": "s3Dgraphy connections datamodel including edge types with CIDOC-CRM mappings. v1.6.11 (batch ingestion, 2026-08-17): two widenings for bulk assets. has_author.source DTCProcessNode -> DTCNode, so an ACQUISITION event (D12) can carry the author of a whole lot; dtc_had_input.target += DTCNode, so a DECLARED derivation can name a whole acquisition as its input (one input, not 500 edges) — that case projects as prov:wasInformedBy, not prov:used/L10, which range over digital objects and would be wrong for an event. v1.6.8 (MIG1-A): graph-scope rights metadata become first-class nodes (DP-65). is_in_paradata_nodegroup.source += AuthorNode/LicenseNode/EmbargoNode and has_paradata_nodegroup.source += GraphNode, so the graph-self node (GraphNode) owns a graph-scope ParadataNodeGroup whose members are the AuthorNode/LicenseNode/EmbargoNode (+ the DP-65 GeoPositionNode shift), replacing the legacy graph.data['author_name'/'license'/'embargo'] fields. The Data Funnel canvas tier now reads these member nodes (one reader per scope); a one-shot load-time migration materialises the legacy fields into nodes. v1.6.7 (BUGFIX-CONN3): closes the two silent follow-ups of CONN2. has_documentation.source gains PropertyNode (judicious widening): the honest reading of a legacy yEd dashed PropertyNode→Document connector is P70i_is_documented_in ('the property is documented in this source'), NOT has_visual_reference (which CONN2 moved to PropertyNode→ResourceNode). The import heuristic (import_graphml.enhance_edge_type) now routes PropertyNode→Document to has_documentation and the rarer CombinerNode/ParadataNode→Document to generic_connection+warning (a combiner aggregates extractors and cites no document; the DTC chain is NOT synthesised at import). Shelf: hat_as_document no longer offers has_visual_reference (a Document attaches via has_documentation/extracted_from); a new hat_as_visual_resource attaches a ResourceNode image via has_visual_reference from a PropertyNode — the correct home after CONN2. No illegal edge is produced or expected. v1.6.6 (BUGFIX-CONN2): closes the two open domain questions on has_visual_reference (E.D. 2026-08-05). SOURCE narrowed to exactly [PropertyNode]: only a property (an asserted quale) is what a visual reference illustrates; the generic ParadataNode entry is dropped, which — because ExtractorNode, CombinerNode and DocumentNode are all subclasses of ParadataNode — now excludes them by class hierarchy (a PropertyNode is neither a sibling nor a parent of the others). The extractor/combiner denied_edges from v1.6.5 are therefore REDUNDANT for this edge but are KEPT as a defensive guard (they still bite if the source is ever broadened back to ParadataNode). TARGET changed from [DocumentNode] to [ResourceNode]: the oddity was that a visual reference pointed at a source-document (E31) rather than at a visual resource. It now points at the resource-layer image node (ResourceNode = E73 Information Object / ExternalResourceReference — the same P67 hinge RM/RMDoc use via has_linked_resource), keeping DocumentNode = fonte. CIDOC stays P138i_has_representation with the target co-typed E36 Visual Item: E36 is a subclass of E73, so co-typing a ResourceNode as E36 is range-consistent (it was NOT, strictly, for an E31 Document). FOLLOW-UPS flagged for E.D. (see end-of report): (a) import_graphml.enhance_edge_type still hardcodes PropertyNode/Combiner/Paradata→DocumentNode ⇒ has_visual_reference (legacy yEd heuristic, now produces an edge this datamodel refuses) — needs a domain decision on what legacy paradata→document edges become; (b) shelf.hat_as_document lists has_visual_reference among the Document-attach edges — it can no longer validate (target is ResourceNode), so a paradata attach silently no longer attaches; a hat_as_visual_resource(ResourceNode)+has_visual_reference path is the proper home. v1.6.5 (BUGFIX-CONN): has_visual_reference is no longer offered FROM an ExtractorNode or a CombinerNode. An extractor toward a document expresses ONLY extracted_from (its relation to the source is the extraction, not an illustration); a combiner aggregates extractors and illustrates nothing. Because ExtractorNode, CombinerNode and PropertyNode are all subclasses of ParadataNode, and has_visual_reference.source lists ParadataNode, simply dropping the two subtypes from the source list would not exclude them (they still match via the parent class). So this is expressed with node_type_restrictions (keyed by RUNTIME node_type, like USNt) using a new denied_edges blacklist (the mirror of allowed_edges): extractor/combiner deny has_visual_reference. PropertyNode and any other legitimate ParadataNode source keep it unchanged. OPEN domain question for E.D.: which paradata node-types may legitimately have a visual reference (today source = PropertyNode/ExtractorNode/CombinerNode/ParadataNode) — extractor/combiner removed; the rest left as-is, not invented. v1.6.1: has_paradata_nodegroup source extended to include EpochNode — an epoch can now own a ParadataNodeGroup holding its temporal-definition properties (e.g. absolute_time_start/end as PropertyNodes with paradata provenance), mirroring how a StratigraphicNode carries its paradata group. v1.6.0 (paired with node datamodel v1.6.0) introduces: bug fix on is_in_paradata_nodegroup (typo 'ProperrtyNOde' → 'PropertyNode'); semantic fix on has_documentation (P104_is_subject_to → P70i_is_documented_in — P104 means 'subject to a legal right', not 'has documentation'); deprecation of has_timebranch as duplicate of is_in_timebranch (the latter is the canonical one — used by import_graphml.py and graphml_patcher.py; the former exists only in config JSON); component list aligned with node datamodel (HDT-O, PROV-O added). HDT-O containment properties (hdto:contains_HDT, hdto:contains_SU, hdto:isPrimary) and physical-relation discriminator subproperties (em:abuts, em:cuts, em:fills, em:overlies, em:bonded_to, em:equals as rdfs:subPropertyOf crmarchaeo:AP11_has_physical_relation) to be added in v1.6.1. v1.5.3 introduced canonical/reverse directionality with verb-based labels for clear socket identification in node editors. v1.5.4 added 'has_visual_reference' edge type. v1.5.5 added 'is_in_location' edge type with context-sensitive CIDOC mapping (P53 for node→location, P89 for the recursive location→location hierarchy) and an optional 'is_primary' boolean attribute (s3d:isPrimary, proposed). v1.6.3: added node_type_restrictions — a per-node-type narrowing of the class-level edge rules (POL5): USN (the NEUTRAL stratigraphic unit, a risparmio) takes is_after/is_before and nothing else, because a void cannot cut, fill, abut or bond. v1.6.4 (POL6): the same restriction, moved to USNt — the tokens went back to their conventional meanings, USN = US negativa (all relations, it is a unit of the sequence) and USNt = US neutra (sequence only).",
4
4
  "components": [
5
5
  "CIDOC-CRM",
6
6
  "CRMarchaeo",
@@ -682,7 +682,7 @@
682
682
  "has_author": {
683
683
  "name": "has_author",
684
684
  "label": "Has author",
685
- "description": "Represents the connection of a node with its author. Target can be an AuthorNode (human) or AuthorAINode (AI-assisted authoring). Source covers the full range of EM node types so that the resolver can walk from any scope level down to the author.",
685
+ "description": "Represents the connection of a node with its author. Target can be an AuthorNode (human) or AuthorAINode (AI-assisted authoring). Source covers the full range of EM node types so that the resolver can walk from any scope level down to the author. SOURCE WIDENED 2026-08-16 (asset DTC protocol): ResourceNode joins the list. 'Who took this photograph' is exactly prov:wasAttributedTo on an information object, and the mapping is already domain-neutral — the omission was an oversight of scope, not a semantic boundary: the list exists so the resolver can walk from ANY scope down to the author, and a resource is a scope somebody attributes. It is also the shape the asset enrichment protocol needs, where the AUTHOR of the bytes (possibly absent, possibly dead) is declared by an ATTRIBUTOR who is somebody else (s3dgraphy.rights.enrich_asset_dtc, docs/asset-dtc-protocol.md).",
686
686
  "reverse": {
687
687
  "name": "is_author_of",
688
688
  "label": "Is author of"
@@ -705,13 +705,15 @@
705
705
  "CombinerNode",
706
706
  "PropertyNode",
707
707
  "EpochNode",
708
- "DTCProcessNode",
709
- "NarrativeNode"
708
+ "DTCNode",
709
+ "NarrativeNode",
710
+ "ResourceNode"
710
711
  ],
711
712
  "target": [
712
713
  "AuthorNode",
713
714
  "AuthorAINode"
714
- ]
715
+ ],
716
+ "_note": "SOURCE WIDENED 2026-08-17 (batch ingestion): DTCProcessNode -> DTCNode, the DTC event BASE class, so an ACQUISITION (DTCAcquisitionNode, D12) can carry an author too — the same fix already applied to dtc_had_input/dtc_had_output for the same reason. A campaign of four hundred photographs is attributed ONCE, on the event that brought them in, and the reader (s3dgraphy.rights) already walks the chain to find it; without this the batch attribution silently degraded to generic_connection and the licence became unreadable."
715
717
  }
716
718
  },
717
719
  "has_geoposition": {
@@ -1320,15 +1322,16 @@
1320
1322
  "cidoc_extension": "CRMdig",
1321
1323
  "extension_mapping": "prov:used",
1322
1324
  "extension_name": "PROV-O",
1323
- "rationale": "crmdig:L10_had_input (D7 Digital Machine Event -> input digital object). Dual-emitted with prov:used (Activity used Entity) — same direction (Process -> input Resource) — so CRMdig and PROV-O readers both see the acquisition consumption. Target is the Resource (ResourceNode); the input is a resource, symmetric to the output."
1325
+ "rationale": "crmdig:L10_had_input (D7 Digital Machine Event -> input digital object). Dual-emitted with prov:used (Activity used Entity) — same direction (Process -> input Resource) — so CRMdig and PROV-O readers both see the acquisition consumption. Target is the Resource (ResourceNode); the input is a resource, symmetric to the output. TARGET WIDENED 2026-08-17: when the target is a DTC EVENT (an acquisition consumed as a whole lot) neither L10_had_input nor prov:used holds — both range over digital OBJECTS, and an event is not one. That case projects as prov:wasInformedBy (activity -> activity), applied in the RDF exporter (_serialize_edge); the property-graph edge stays the one edge type, because 'this output came from that input' is one sentence whether the input is a file or a campaign."
1324
1326
  },
1325
1327
  "allowed_connections": {
1326
- "_note": "Source is the DTC event BASE class: both chunk types link to their Resources — DTCProcessNode (genesis, D7) and DTCAcquisitionNode (acquisition/ingestion, D12), per the dtc_nodes section note. Listing only DTCProcessNode used to pass by accident, because the old validator could not resolve the name and fell back to accepting anything.",
1328
+ "_note": "Source is the DTC event BASE class: both chunk types link to their Resources — DTCProcessNode (genesis, D7) and DTCAcquisitionNode (acquisition/ingestion, D12), per the dtc_nodes section note. Listing only DTCProcessNode used to pass by accident, because the old validator could not resolve the name and fell back to accepting anything. TARGET 2026-08-17: DTCNode joins ResourceNode so a DECLARED derivation can name a whole ACQUISITION as its input — the serial node exists precisely so a campaign of 500 photographs is one input and not 500 edges. The RDF projection distinguishes the two cases (see mapping.rationale); dtc_derived_from stays resource -> resource, because a shortcut between files cannot be written to an event, and that is reported rather than faked.",
1327
1329
  "source": [
1328
1330
  "DTCNode"
1329
1331
  ],
1330
1332
  "target": [
1331
- "ResourceNode"
1333
+ "ResourceNode",
1334
+ "DTCNode"
1332
1335
  ]
1333
1336
  }
1334
1337
  },
@@ -1402,4 +1405,4 @@
1402
1405
  }
1403
1406
  }
1404
1407
  }
1405
- }
1408
+ }
@@ -1,4 +1,4 @@
1
- __version__ = "1.6.0.dev14"
1
+ __version__ = "1.6.0.dev15"
2
2
  __datamodel_version__ = "1.5.5" # s3Dgraphy connections datamodel version
3
3
 
4
4
  # s3Dgraphy/__init__.py
@@ -445,9 +445,19 @@ def promote_resource(graph: Graph, resource_id: str, *, url: str, sha256: str,
445
445
  author: Optional[str] = None, at: Optional[str] = None,
446
446
  source_id: Optional[str] = None,
447
447
  link_to: Optional[str] = None,
448
- name: Optional[str] = None) -> Dict[str, Any]:
449
- """Publish a resource: `residency="reference"` + url + checksum, and record
450
- the genesis as a DTC transformation (crmdig:D7), attributed and dated.
448
+ name: Optional[str] = None,
449
+ residency: str = "reference",
450
+ corpus: Optional[Graph] = None) -> Dict[str, Any]:
451
+ """Publish a resource: url + checksum + a residency, and record the genesis
452
+ as a DTC transformation (crmdig:D7), attributed and dated.
453
+
454
+ `residency` says which true sentence this is — `reference` (a store the study
455
+ points at, the default and the original DP-76 one) or `resident` (the ROOM's
456
+ store: em-server is in the bytes' path, so the gate and the licence travel
457
+ with them). `corpus` is the offline→online moment: hand it the container's
458
+ DOCUMENTATION member and the D7 event is recorded THERE, with the asset
459
+ mirrored into it under its own id — the shared leaf between the study and its
460
+ provenance.
451
461
 
452
462
  The inverse of `import_geometry` and the activation of DP-76: the model stops
453
463
  living inside a .blend and becomes an asset the study POINTS AT. Returns the
@@ -457,7 +467,87 @@ def promote_resource(graph: Graph, resource_id: str, *, url: str, sha256: str,
457
467
  from .publication import promote_resource as _promote
458
468
  return _promote(graph, resource_id, url=url, sha256=sha256,
459
469
  media_type=media_type, author=author, at=at,
460
- source_id=source_id, link_to=link_to, name=name).as_dict()
470
+ source_id=source_id, link_to=link_to, name=name,
471
+ residency=residency, corpus=corpus).as_dict()
472
+
473
+
474
+ # ── the DOCUMENTATION member: the DTC corpus ─────────────────────────────────
475
+ #
476
+ # A study's provenance is a graph of a different KIND — acquisitions,
477
+ # transformations and the files they are about, a forest that shares its leaves.
478
+ # It travels as a container member of its own (`em_collection: "DTCCorpus"`), the
479
+ # way the shelf does. On the api surface because the tools author it: EMStudio's
480
+ # Documentation tab, EMtools at promotion, an ingest.
481
+
482
+ def dtc_corpus(container: Any, *, create: bool = True) -> Optional[Graph]:
483
+ """The container's documentation member — found by its marker, or made.
484
+
485
+ `create=False` answers "is there one?" without making one: a panel that
486
+ showed an empty corpus it had just invented would be reporting its own side
487
+ effect. See :mod:`s3dgraphy.dtc.corpus`.
488
+ """
489
+ from .dtc.corpus import corpus_of
490
+ return corpus_of(container, create=create)
491
+
492
+
493
+ def merge_corpus(resident: Any, incoming: Any) -> Dict[str, Any]:
494
+ """Fold one DTC corpus into another, per UUID. Returns the report as a dict.
495
+
496
+ On the api surface because another PROCESS performs it: em-server merges a
497
+ project's **file** corpus into the instance's **resident** one when a study is
498
+ promoted or joins a room, and it must not invent a second answer to "who
499
+ wins". Same merge the container uses. See :mod:`s3dgraphy.dtc.corpus`.
500
+ """
501
+ from .dtc.corpus import merge_corpus as _merge
502
+ return _merge(resident, incoming)
503
+
504
+
505
+ def is_dtc_corpus(graph: Any) -> bool:
506
+ """Is this graph (or raw member section) a DTC corpus?"""
507
+ from .dtc.corpus import is_dtc_corpus as _is
508
+ return _is(graph)
509
+
510
+
511
+ def new_dtc_corpus(graph_id: Optional[str] = None,
512
+ name: Optional[str] = None) -> Graph:
513
+ """An empty corpus, tagged as one — for a caller building a container."""
514
+ from .dtc.corpus import DTC_CORPUS_MEMBER_ID, new_corpus
515
+ return new_corpus(graph_id or DTC_CORPUS_MEMBER_ID, name)
516
+
517
+
518
+ def dtc_corpus_summary(corpus: Any) -> Dict[str, Any]:
519
+ """What is in the corpus, in its own terms: roots (acquisitions),
520
+ transformations, resources, outputs, **shared leaves** (a file more than one
521
+ event consumed — what a matrix could not draw), orphans, and anything
522
+ FOREIGN that does not belong in a corpus at all."""
523
+ from .dtc.corpus import dtc_corpus_summary as _summary
524
+ return _summary(corpus)
525
+
526
+
527
+ def store_backed_geometry(graph: Graph) -> List[Dict[str, Any]]:
528
+ """The geometry this graph describes that LIVES in the store — resident only.
529
+
530
+ The consuming half of DP-76, and the answer a 3D tool needs before it can
531
+ materialise anything: one record per (facet, resource), each with the digest
532
+ to fetch by and the epochs/units to bind to. On the api surface because the
533
+ caller is another PROCESS (EMtools in Blender, a headless publisher), and
534
+ because the walk belongs to the library — a consumer that re-derived
535
+ `has_linked_resource` would drift the day a facet is added.
536
+
537
+ `reference` resources are deliberately absent: their bytes are outside the
538
+ store (and outside em-server's gate), so a digest cannot fetch them and a
539
+ path is meaningful on one machine only. See
540
+ :mod:`s3dgraphy.geometry.store_backed`.
541
+ """
542
+ from .geometry.store_backed import store_backed_geometry as _geometry
543
+ return _geometry(graph)
544
+
545
+
546
+ def geometry_summary(graph: Graph) -> Dict[str, Any]:
547
+ """What is fetchable, and what the graph describes that is NOT — so a panel
548
+ can show the whole truth rather than the smaller half of it."""
549
+ from .geometry.store_backed import geometry_summary as _summary
550
+ return _summary(graph)
461
551
 
462
552
 
463
553
  def promotion_delta(graph: Graph, result: Dict[str, Any]) -> Dict[str, Any]:
@@ -472,6 +562,61 @@ def promotion_delta(graph: Graph, result: Dict[str, Any]) -> Dict[str, Any]:
472
562
  ))
473
563
 
474
564
 
565
+ # ── narrative queries (DP-79 P4) ──────────────────────────────────────────────
566
+ #
567
+ # The point of authoring a study ON the graph: the interpretation and the
568
+ # evidence are one dataset, so questions that cross them have answers. These
569
+ # read the em.json in memory — the same content the RDF projection restates as
570
+ # `P67_refers_to` — so there is no index to rebuild and no answer that can be
571
+ # stale. See :mod:`s3dgraphy.narrative.query`.
572
+
573
+ def narrative_citations(graph: Graph) -> List[Dict[str, Any]]:
574
+ """Every embed in every narrative, flattened, with its chapter/block position."""
575
+ from .narrative.query import citations
576
+ return citations(graph)
577
+
578
+
579
+ def narratives_citing(graph: Graph, node_id: str) -> List[Dict[str, Any]]:
580
+ """Where a node is cited, **in reading order**.
581
+
582
+ SPARQL over the projection answers the set version of this; only the
583
+ property graph can answer the ordered one, because the chapters are
584
+ deliberately not reified in RDF.
585
+ """
586
+ from .narrative.query import narratives_citing as _q
587
+ return _q(graph, node_id)
588
+
589
+
590
+ def narratives_on_retracted_sources(graph: Graph) -> List[Dict[str, Any]]:
591
+ """Citations that no longer stand — a withdrawn source, or a reference that
592
+ does not resolve at all. Reported together, separated by `reason`: they need
593
+ different work."""
594
+ from .narrative.query import narratives_on_retracted_sources as _q
595
+ return _q(graph)
596
+
597
+
598
+ def interpretive_coverage(graph: Graph, *, kind: str = "epoch"
599
+ ) -> List[Dict[str, Any]]:
600
+ """How much has been WRITTEN about each epoch (or activity), counting a
601
+ citation of a member as covering the whole. `narratives: 0` is the row
602
+ people are actually looking for."""
603
+ from .narrative.query import interpretive_coverage as _q
604
+ return _q(graph, kind=kind)
605
+
606
+
607
+ def unexplained_reconstructions(graph: Graph) -> List[Dict[str, Any]]:
608
+ """3D somebody built and nobody explained: a model with a scene that no
609
+ narrative cites, directly or through the unit it represents."""
610
+ from .narrative.query import unexplained_reconstructions as _q
611
+ return _q(graph)
612
+
613
+
614
+ def narrative_report(graph: Graph) -> Dict[str, Any]:
615
+ """All four answers in one deterministic dict."""
616
+ from .narrative.query import narrative_report as _q
617
+ return _q(graph)
618
+
619
+
475
620
  # ── the study, as a catalogue sees it ─────────────────────────────────────────
476
621
  def study_metadata(container: Any, *, study_id: Optional[str] = None
477
622
  ) -> Dict[str, Any]:
@@ -492,20 +637,166 @@ def study_metadata(container: Any, *, study_id: Optional[str] = None
492
637
  return _card(container, study_id=study_id)
493
638
 
494
639
 
640
+ # ── one asset's rights, read off the graph ────────────────────────────────────
641
+ def asset_rights(document: Any, digest: str, *, today: Any = None
642
+ ) -> Optional[Dict[str, Any]]:
643
+ """What the graph says about the asset with this digest — licence, embargo,
644
+ authors — or `None` when it has never heard of it.
645
+
646
+ On the api surface for the same reason `study_metadata` is: another PROCESS
647
+ asks it. An asset store must decide whether to serve bytes, and the decision
648
+ belongs to the graph — em-server CONSULTS this rather than keeping a second
649
+ copy of an embargo that lives in a document people edit.
650
+
651
+ See :mod:`s3dgraphy.rights` for how the walk works and why the rights are
652
+ read both directly off the resource and through its DTC chain.
653
+ """
654
+ from .rights import rights_for_digest
655
+ return rights_for_digest(document, digest, today=today)
656
+
657
+
658
+ def enrich_asset_dtc(graph: Any, checksum: str, *, attributor: Optional[str],
659
+ author: Any = None, license: Any = None, embargo: Any = None,
660
+ at: Optional[str] = None, author_name: Optional[str] = None,
661
+ reason: Optional[str] = None) -> Dict[str, Any]:
662
+ """Declare an asset's rights — as an ACT, signed by whoever declares it.
663
+
664
+ The writing half of `asset_rights`. On the api surface because it is a
665
+ PROTOCOL other tools perform: EMStudio at upload, EMtools, the field
666
+ chatbot, an ECHOES/ECCCH ingest. The contract is written down once, in
667
+ `docs/asset-dtc-protocol.md`, so those tools do not each invent their own.
668
+
669
+ The distinction it exists for: the **author** is who made the data, the
670
+ **attributor** is who says so, and they are frequently not the same person —
671
+ attribution happens later, sometimes posthumously, usually by a cataloguer.
672
+ See :mod:`s3dgraphy.rights`.
673
+ """
674
+ from .rights import enrich_asset_dtc as _enrich
675
+ return _enrich(graph, checksum, attributor=attributor, author=author,
676
+ license=license, embargo=embargo, at=at,
677
+ author_name=author_name, reason=reason)
678
+
679
+
680
+ # ── ingestion in bulk: a lot, a declared chain, and who uses a file ──────────
681
+ #
682
+ # The plural of the act above. On the api surface for the same reason: several
683
+ # tools ingest (EMStudio's Assets tab, EMtools, a field ingest), and a rule that
684
+ # lived in one of them would be re-invented differently by the next.
685
+ # See :mod:`s3dgraphy.dtc.ingest`.
686
+
687
+ def bucket_acquisition(graph: Graph, resources: Any, *,
688
+ acquisition_id: Optional[str] = None,
689
+ name: Optional[str] = None,
690
+ dtc_kind: Optional[str] = None,
691
+ metadata: Optional[Dict[str, Any]] = None,
692
+ author: Optional[str] = None,
693
+ at: Optional[str] = None) -> Dict[str, Any]:
694
+ """Group N resources (ids or digests) under ONE acquisition event (D12).
695
+
696
+ The serial node: a campaign of four hundred photographs is one thing in the
697
+ graph, not four hundred top-level entries. The membership is the
698
+ `dtc_had_output` edges; `data.member_count` is a cache of their number.
699
+ """
700
+ from .dtc.ingest import DEFAULT_ACQUISITION_KIND, bucket_acquisition as _bucket
701
+ return _bucket(graph, list(resources or ()), acquisition_id=acquisition_id,
702
+ name=name, dtc_kind=dtc_kind or DEFAULT_ACQUISITION_KIND,
703
+ metadata=metadata, author=author, at=at)
704
+
705
+
706
+ def acquisition_members(graph: Graph, acquisition_id: str) -> List[str]:
707
+ """The resources an acquisition brought in — live, read off the edges."""
708
+ from .dtc.ingest import acquisition_members as _members
709
+ return _members(graph, acquisition_id)
710
+
711
+
712
+ def declare_derivation(graph: Graph, output: str, inputs: Any, *,
713
+ tool: Optional[str] = None,
714
+ process_id: Optional[str] = None,
715
+ name: Optional[str] = None,
716
+ author: Optional[str] = None,
717
+ at: Optional[str] = None) -> Dict[str, Any]:
718
+ """Declare that `output` came out of `inputs`, with `tool` named.
719
+
720
+ DECLARED, never inferred: nobody guesses that an orthophoto came from that
721
+ flight because the dates line up. An input may be a resource or a whole
722
+ acquisition.
723
+ """
724
+ from .dtc.ingest import declare_derivation as _declare
725
+ return _declare(graph, output, list(inputs or ()), tool=tool,
726
+ process_id=process_id, name=name, author=author, at=at)
727
+
728
+
729
+ def derivation_chain(graph: Graph, resource: str) -> Dict[str, Any]:
730
+ """What made this file and what consumed it — one hop each way."""
731
+ from .dtc.ingest import derivation_chain as _chain
732
+ return _chain(graph, resource)
733
+
734
+
735
+ def attribute_batch(graph: Graph, acquisition_id: str, *,
736
+ attributor: Optional[str], author: Any = None,
737
+ author_name: Optional[str] = None, license: Any = None,
738
+ embargo: Any = None, reason: Optional[str] = None,
739
+ at: Optional[str] = None,
740
+ propagate: bool = False) -> Dict[str, Any]:
741
+ """Licence / author / embargo for a whole lot, signed by its attributor.
742
+
743
+ The batch twin of `enrich_asset_dtc`, hung on the acquisition — which is how
744
+ `asset_rights` already reads it. `propagate=True` also stamps each member,
745
+ which is a copy and can therefore disagree: off by default.
746
+ """
747
+ from .dtc.ingest import attribute_batch as _attribute
748
+ return _attribute(graph, acquisition_id, attributor=attributor,
749
+ author=author, author_name=author_name, license=license,
750
+ embargo=embargo, reason=reason, at=at,
751
+ propagate=propagate)
752
+
753
+
754
+ def resource_usages(graph: Graph, resource: str) -> List[Dict[str, Any]]:
755
+ """Every live node that refers to this asset, classified by HOW.
756
+
757
+ The question to answer before replacing a file — and the inspector's
758
+ "used by…". Roles: reference / annotation / chain / rights / other.
759
+ """
760
+ from .dtc.ingest import resource_usages as _usages
761
+ return _usages(graph, resource)
762
+
763
+
764
+ def unused_resources(graph: Graph) -> List[Dict[str, Any]]:
765
+ """Files nothing points at. Not a fault — a list somebody may want."""
766
+ from .dtc.ingest import unused_resources as _unused
767
+ return _unused(graph)
768
+
769
+
770
+ def batch_summary(graph: Graph, acquisition_id: str) -> Dict[str, Any]:
771
+ """One acquisition as a panel shows it: the event, its members, their
772
+ rights (inherited or their own). Read-only."""
773
+ from .dtc.ingest import batch_summary as _summary
774
+ return _summary(graph, acquisition_id)
775
+
776
+
495
777
  # ── IIIF: the image layer, as a projection ────────────────────────────────────
496
778
  def iiif_manifest(graph: Graph, target_id: str, *, image_base: str,
497
779
  manifest_id: Optional[str] = None,
498
780
  sizes: Optional[Dict[str, Any]] = None,
499
- label: Optional[str] = None) -> Dict[str, Any]:
781
+ label: Optional[str] = None,
782
+ document: Any = None,
783
+ withhold_embargoed: bool = True) -> Dict[str, Any]:
500
784
  """A IIIF **Presentation 3** manifest for a resource or a document.
501
785
 
502
786
  One canvas per image, with the graph's annotation regions projected onto it
503
787
  as W3C Web Annotations. The graph is the source; the manifest is a view, and
504
788
  nothing about it is written back. See :mod:`s3dgraphy.iiif`.
789
+
790
+ `document` (the container this graph came from) turns on the RIGHTS half:
791
+ each image's licence travels in the manifest, and an image under a running
792
+ embargo is left out with the fact recorded. Without it the manifest is
793
+ exactly what it was before — a caller that knows nothing about rights is not
794
+ made to care.
505
795
  """
506
796
  from .iiif import iiif_manifest as _manifest
507
797
  return _manifest(graph, target_id, image_base=image_base,
508
- manifest_id=manifest_id, sizes=sizes, label=label)
798
+ manifest_id=manifest_id, sizes=sizes, label=label,
799
+ document=document, withhold_embargoed=withhold_embargoed)
509
800
 
510
801
 
511
802
  def iiif_image_service(resource, base: str) -> Optional[Dict[str, Any]]:
@@ -862,13 +1153,20 @@ def write_ai_draft(graph: Graph, target: str, text: str, *, model: str,
862
1153
 
863
1154
 
864
1155
  # ── EM Narrative — print projection (L1) ──────────────────────────────────────
865
- def export_narrative_latex(graph: Graph, narrative_id: str) -> Dict[str, str]:
1156
+ def export_narrative_latex(graph: Graph, narrative_id: str, *,
1157
+ fragment: bool = False,
1158
+ figures: Optional[Dict[str, Any]] = None,
1159
+ figure_suffix: str = ".pdf") -> Dict[str, str]:
866
1160
  """Project a NarrativeNode to LaTeX + BibTeX: ``{"tex": …, "bib": …}``.
867
1161
 
868
1162
  An **exporter, not a renderer**: it returns two strings and needs no LaTeX
869
- engine. ``tex`` is a body to ``\\input{}`` into your own preamble (chapters →
870
- ``\\section``/``\\subsection``, prose → prose, embeds → figures or
871
- ``\\cite``), ``bib`` one entry per cited source with keys derived
1163
+ engine. ``tex`` is a **complete, compilable document** — a minimal preamble
1164
+ (inputenc/fontenc/babel/graphicx/hyperref), the chapters as ``\\section``s,
1165
+ and the cited sources as an inline ``thebibliography`` so one file yields one
1166
+ PDF. ``fragment=True`` returns the old BODY instead, to ``\\input{}`` into
1167
+ your own preamble (chapters become ``\\subsection``s under your title).
1168
+
1169
+ ``bib`` is one entry per cited source with keys derived
872
1170
  deterministically from the node ids (:func:`bib_key`), so citations and
873
1171
  entries cannot drift and a re-export is stable.
874
1172
 
@@ -879,7 +1177,8 @@ def export_narrative_latex(graph: Graph, narrative_id: str) -> Dict[str, str]:
879
1177
 
880
1178
  Raises ``KeyError`` if ``narrative_id`` names no narrative in the graph."""
881
1179
  from .exporter.latex_exporter import export_narrative_latex as _e
882
- return _e(graph, narrative_id)
1180
+ return _e(graph, narrative_id, fragment=fragment, figures=figures,
1181
+ figure_suffix=figure_suffix)
883
1182
 
884
1183
 
885
1184
  def bib_key(node_id: str) -> str:
@@ -890,7 +1189,9 @@ def bib_key(node_id: str) -> str:
890
1189
 
891
1190
 
892
1191
  def bake_narrative(graph: Graph, narrative_id: str, *,
893
- base_dir: Optional[str] = None) -> Any:
1192
+ base_dir: Optional[str] = None,
1193
+ figures: Optional[Dict[str, bytes]] = None,
1194
+ figure_suffix: str = ".png") -> Any:
894
1195
  """Resolve a live narrative into a **static snapshot** (``BakedNarrative``).
895
1196
 
896
1197
  A narrative's embeds mean "whatever this node says now" — which is what makes
@@ -911,13 +1212,86 @@ def bake_narrative(graph: Graph, narrative_id: str, *,
911
1212
  ``base_dir`` is what relative image locators resolve against (normally the
912
1213
  folder holding the em.json). Raises ``KeyError`` if ``narrative_id`` names no
913
1214
  narrative.
1215
+
1216
+ ``figures`` are images a CLIENT rendered, keyed by
1217
+ :func:`s3dgraphy.narrative.bake.figure_key` — see there for why a matrix
1218
+ arrives from outside instead of being drawn here.
1219
+
914
1220
  """
915
1221
  from .narrative.bake import bake_narrative as _b
916
- return _b(graph, narrative_id, base_dir=base_dir)
1222
+ return _b(graph, narrative_id, base_dir=base_dir, figures=figures,
1223
+ figure_suffix=figure_suffix)
1224
+
1225
+
1226
+ def export_narrative_html(graph: Graph, narrative_id: str, *,
1227
+ base_dir: Optional[str] = None,
1228
+ generated_at: str = "",
1229
+ figures: Optional[Dict[str, bytes]] = None,
1230
+ figure_suffix: str = ".png") -> str:
1231
+ """Render a narrative to **one self-contained HTML file** — the format for
1232
+ the reader who is simply handed a link or an attachment.
1233
+
1234
+ The third rendering of the same bake (:func:`bake_narrative`), which is why
1235
+ it cannot disagree with the DocX or the LaTeX about what the narrative said.
1236
+ Images are inlined as data URIs and the CSS travels in the file: a folder of
1237
+ loose assets is a document that arrives broken the first time it is emailed.
1238
+
1239
+ Needs nothing beyond the standard library — unlike DocX, it cannot be
1240
+ unavailable. `generated_at` is stamped into the footer when given; it is a
1241
+ parameter rather than a call to the clock so the same bake renders to the
1242
+ same bytes twice.
1243
+
1244
+ ``figures``/``figure_suffix`` carry images a CLIENT rendered (keyed by
1245
+ :func:`s3dgraphy.narrative.bake.figure_key`, e.g. ``"matrix:EP1"``): a matrix
1246
+ is drawn by the layout engine, the layout engine lives in the client, and this
1247
+ library does not grow a browser. Without them the visual embeds stay
1248
+ placeholders — the export never breaks, it just says less.
1249
+
1250
+ """
1251
+ from .exporter.html_exporter import render_html
1252
+ return render_html(bake_narrative(graph, narrative_id, base_dir=base_dir,
1253
+ figures=figures,
1254
+ figure_suffix=figure_suffix),
1255
+ generated_at=generated_at)
1256
+
1257
+
1258
+ def export_narrative_ipynb(graph: Graph, narrative_id: str, *,
1259
+ emjson_url: Optional[str] = None,
1260
+ figures: Optional[Dict[str, bytes]] = None,
1261
+ figure_suffix: str = ".png") -> str:
1262
+ """Render a narrative to a **Jupyter notebook** — the fourth output, and the
1263
+ only LIVE one.
1264
+
1265
+ The other three (DocX, LaTeX, HTML) are snapshots: they resolve the embeds
1266
+ once and freeze them. This one does the opposite — the prose becomes
1267
+ markdown and every embed becomes a **code cell that queries the graph**, so
1268
+ the notebook contains the questions and the reader runs them. Re-run it in a
1269
+ year and it says what the study says then.
1270
+
1271
+ `emjson_url` is written into the loader cell (the Catalog's `/emjson` route,
1272
+ typically). Without it the cell names a local file and the reader edits one
1273
+ line. The notebook deliberately carries **no copy of the graph**: a copy is
1274
+ what would make it a snapshot again.
1275
+
1276
+ Needs nothing beyond the standard library — the notebook is a dict and
1277
+ `json` is the whole serialiser.
1278
+
1279
+ ``figures``/``figure_suffix`` carry images a CLIENT rendered (keyed by
1280
+ :func:`s3dgraphy.narrative.bake.figure_key`, e.g. ``"matrix:EP1"``): a matrix
1281
+ is drawn by the layout engine, the layout engine lives in the client, and this
1282
+ library does not grow a browser. Without them the visual embeds stay
1283
+ placeholders — the export never breaks, it just says less.
1284
+
1285
+ """
1286
+ from .exporter.ipynb_exporter import export_narrative_ipynb as _e
1287
+ return _e(graph, narrative_id, emjson_url=emjson_url, figures=figures,
1288
+ figure_suffix=figure_suffix)
917
1289
 
918
1290
 
919
1291
  def export_narrative_docx(graph: Graph, narrative_id: str, *,
920
- base_dir: Optional[str] = None) -> bytes:
1292
+ base_dir: Optional[str] = None,
1293
+ figures: Optional[Dict[str, bytes]] = None,
1294
+ figure_suffix: str = ".png") -> bytes:
921
1295
  """Render a narrative to **.docx** bytes — the format for the normal reader.
922
1296
 
923
1297
  Bakes first (:func:`bake_narrative`), then places the result: chapter
@@ -933,9 +1307,18 @@ def export_narrative_docx(graph: Graph, narrative_id: str, *,
933
1307
  Raises :class:`MissingDependency` if python-docx is not installed — the bake
934
1308
  itself does not need it, so ``bake_narrative`` keeps working and only the
935
1309
  rendering is unavailable.
1310
+
1311
+ ``figures``/``figure_suffix`` carry images a CLIENT rendered (keyed by
1312
+ :func:`s3dgraphy.narrative.bake.figure_key`, e.g. ``"matrix:EP1"``): a matrix
1313
+ is drawn by the layout engine, the layout engine lives in the client, and this
1314
+ library does not grow a browser. Without them the visual embeds stay
1315
+ placeholders — the export never breaks, it just says less.
1316
+
936
1317
  """
937
1318
  from .exporter.docx_exporter import render_docx
938
- return render_docx(bake_narrative(graph, narrative_id, base_dir=base_dir))
1319
+ return render_docx(bake_narrative(graph, narrative_id, base_dir=base_dir,
1320
+ figures=figures,
1321
+ figure_suffix=figure_suffix))
939
1322
 
940
1323
 
941
1324
  # ── XLSX mapping ──────────────────────────────────────────────────────────────