ea 0.4.0 → 0.5.0

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 (529) hide show
  1. checksums.yaml +4 -4
  2. data/Rakefile +3 -0
  3. data/TODO.complete/01-t-xref-parsing.md +91 -0
  4. data/TODO.complete/02-per-label-geometry.md +50 -0
  5. data/TODO.complete/03-object-properties-constraints.md +57 -0
  6. data/TODO.complete/04-operation-params.md +37 -0
  7. data/TODO.complete/05-pdata-flag-matrix.md +52 -0
  8. data/TODO.complete/06-emf-image-rendering.md +34 -0
  9. data/TODO.complete/07-auxiliary-tables.md +47 -0
  10. data/TODO.complete/10-mdg-stereotype-registry.md +40 -0
  11. data/TODO.complete/11-gml-xsd-generation.md +42 -0
  12. data/TODO.complete/13-shapescript-interpreter.md +28 -0
  13. data/TODO.complete/20-cli-diff.md +46 -0
  14. data/TODO.complete/21-cli-render.md +26 -0
  15. data/TODO.complete/22-cli-export.md +29 -0
  16. data/TODO.complete/23-cli-mdg.md +23 -0
  17. data/TODO.complete/30-headerlines-ocp-refactor.md +72 -0
  18. data/TODO.complete/31-public-send-cleanup.md +61 -0
  19. data/TODO.complete/32-spec-coverage.md +33 -0
  20. data/TODO.complete/33-blocked-parity-gaps.md +41 -0
  21. data/TODO.complete/36-stereotype-icon-wiring.md +32 -0
  22. data/TODO.complete/37-cli-lint.md +32 -0
  23. data/TODO.complete/38-cli-query.md +26 -0
  24. data/TODO.complete/39-cli-info.md +23 -0
  25. data/TODO.complete/40-ocl-evaluator.md +31 -0
  26. data/TODO.complete/41-round-trip-spec.md +18 -0
  27. data/TODO.complete/42-html-diff-report.md +18 -0
  28. data/TODO.complete/43-json-schema-export.md +20 -0
  29. data/TODO.complete/44-remaining-qea-tables.md +40 -0
  30. data/TODO.complete/45-shapescript-extensions.md +25 -0
  31. data/TODO.complete/46-xsd-consolidation.md +20 -0
  32. data/TODO.complete/47-headerlines-legacy-removal.md +20 -0
  33. data/TODO.complete/STATUS.md +109 -0
  34. data/TODO.diagrams/01-svg-measurement-harness.md +31 -0
  35. data/TODO.diagrams/02-polygon-over-rendering.md +29 -0
  36. data/TODO.diagrams/03-text-over-rendering.md +30 -0
  37. data/TODO.diagrams/04-rect-under-rendering.md +33 -0
  38. data/TODO.diagrams/05-canvas-dimension-parity.md +51 -0
  39. data/TODO.diagrams/06-group-layering-parity.md +39 -0
  40. data/TODO.diagrams/07-text-content-fidelity.md +65 -0
  41. data/TODO.diagrams/08-qea-direct-pipeline.md +46 -0
  42. data/TODO.diagrams/12-connector-labels.md +40 -0
  43. data/TODO.diagrams/12-per-entity-svg-layer-ordering.md +24 -0
  44. data/TODO.diagrams/13-marker-polygon-vs-path-dispatch.md +20 -0
  45. data/TODO.diagrams/13-per-text-type-font-sizes.md +33 -0
  46. data/TODO.diagrams/14-center-header-text.md +33 -0
  47. data/TODO.diagrams/14-filter-diagram-frame-elements.md +18 -0
  48. data/TODO.diagrams/15-deep-dead-code-audit.md +47 -0
  49. data/TODO.diagrams/15-per-element-font-from-style.md +24 -0
  50. data/TODO.diagrams/16-canvas-marker-extent.md +30 -0
  51. data/TODO.diagrams/16-document-remaining-parity-gaps.md +91 -0
  52. data/TODO.diagrams/17-italic-abstract-classes.md +28 -0
  53. data/TODO.diagrams/17-remaining-parity-gaps.md +90 -0
  54. data/TODO.diagrams/18-canvas-from-image-bounds.md +20 -0
  55. data/TODO.diagrams/18-property-lookup-index.md +42 -0
  56. data/TODO.diagrams/19-connector-sx-sy-routing.md +27 -0
  57. data/TODO.diagrams/19-replace-respond-to-with-is-a.md +31 -0
  58. data/TODO.diagrams/20-split-labels-emitter.md +56 -0
  59. data/TODO.diagrams/20-visibility-glyph-font-encoding.md +27 -0
  60. data/TODO.diagrams/21-aggregation-navigability-arrow.md +21 -0
  61. data/TODO.diagrams/21-auto-generated-legend-block.md +65 -0
  62. data/TODO.diagrams/22-ghost-element-discriminator.md +57 -0
  63. data/TODO.diagrams/22-style-based-path-grouping.md +28 -0
  64. data/TODO.diagrams/23-marker-polygon-deduplication.md +47 -0
  65. data/TODO.diagrams/23-multiplicity-label-positioning.md +29 -0
  66. data/TODO.diagrams/24-marker-anchor-structural.md +35 -0
  67. data/TODO.diagrams/24-track-marker-anchors-structurally.md +66 -0
  68. data/TODO.diagrams/24-truncate-properties-to-fit-box.md +24 -0
  69. data/TODO.diagrams/26-phantom-general-parent-rendering.md +59 -0
  70. data/TODO.diagrams/27-path-grouping-mode-detection.md +43 -0
  71. data/TODO.diagrams/28-architecture-cleanup-batch.md +47 -0
  72. data/TODO.diagrams/30-decompose-elements-groups-for.md +52 -0
  73. data/TODO.diagrams/32-examples-coverage-batch.md +78 -0
  74. data/TODO.diagrams/36-instance-specification-model.md +42 -0
  75. data/TODO.diagrams/37-element-icon-decorations.md +41 -0
  76. data/TODO.diagrams/38-html-note-and-receptions.md +32 -0
  77. data/TODO.diagrams/39-property-stereotype-discriminator.md +40 -0
  78. data/TODO.diagrams/40-standalone-1-discriminator.md +38 -0
  79. data/TODO.diagrams/41-xmi-to-svg-pipeline.md +113 -0
  80. data/TODO.diagrams/42-close-all-parity-deltas.md +69 -0
  81. data/TODO.diagrams/43-marker-deduplication-strategy.md +54 -0
  82. data/TODO.diagrams/44-element-icon-decorations.md +34 -0
  83. data/TODO.diagrams/45-phantom-parent-class-boxes.md +40 -0
  84. data/TODO.diagrams/46-user-drawn-legend-swatches.md +44 -0
  85. data/TODO.diagrams/47-attribute-line-fidelity.md +72 -0
  86. data/TODO.diagrams/48-spec-coverage-critical-emitter-components.md +45 -0
  87. data/TODO.diagrams/49-spec-coverage-orchestrators.md +25 -0
  88. data/TODO.diagrams/50-examples-parity.md +85 -0
  89. data/TODO.diagrams/51-property-oy-gap-and-remaining-gaps.md +48 -0
  90. data/TODO.diagrams/52-marker-registration-architecture.md +89 -0
  91. data/TODO.diagrams/53-remaining-example-gaps.md +86 -0
  92. data/TODO.diagrams/54-display-name-nested-classes.md +40 -0
  93. data/TODO.diagrams/55-visibility-icon-discriminator.md +58 -0
  94. data/TODO.diagrams/56-package-contents-rendering.md +148 -0
  95. data/TODO.diagrams/57-instance-specification-model.md +100 -0
  96. data/TODO.diagrams/58-domain-model-note-text.md +67 -0
  97. data/TODO.diagrams/59-classes-arrow-discriminator.md +57 -0
  98. data/TODO.diagrams/60-testschema-association-marker.md +40 -0
  99. data/TODO.diagrams/61-legend-block-rendering.md +55 -0
  100. data/TODO.diagrams/61-plateau-parity-gaps.md +59 -0
  101. data/TODO.diagrams/62-ghost-element-rendering.md +56 -0
  102. data/TODO.diagrams/63-qualified-name-wrap.md +36 -0
  103. data/TODO.diagrams/64-property-stereotype-labels.md +22 -0
  104. data/TODO.diagrams/65-path-coordinate-frame.md +62 -0
  105. data/TODO.diagrams/67-path-coordinate-frame.md +62 -0
  106. data/TODO.diagrams/68-inherited-attributes.md +65 -0
  107. data/TODO.diagrams/69-package-anchor-conditional.md +29 -0
  108. data/TODO.diagrams/70-mdg-technology-support.md +68 -0
  109. data/TODO.diagrams/71-off-canvas-parent-ghost.md +45 -0
  110. data/TODO.diagrams/72-basic-attr-divider-paths.md +39 -0
  111. data/TODO.diagrams/73-plateau-polygon-gap.md +69 -0
  112. data/TODO.diagrams/74-plateau-rect-gap.md +22 -0
  113. data/TODO.diagrams/75-plateau-text-gap.md +39 -0
  114. data/TODO.diagrams/76-basic-poly-path-gaps.md +41 -0
  115. data/TODO.diagrams/77-basic-text-overrender.md +40 -0
  116. data/TODO.diagrams/78-headerlines-ocp-refactor.md +65 -0
  117. data/TODO.diagrams/79-architecture-backlog.md +65 -0
  118. data/TODO.diagrams/80-basic-triangle-polygons.md +51 -0
  119. data/TODO.diagrams/81-plateau-path-overrender.md +53 -0
  120. data/TODO.diagrams/82-appearance-canvas-offset.md +54 -0
  121. data/TODO.diagrams/83-3d-diagram-subtitle.md +58 -0
  122. data/TODO.diagrams/84-canvas-offset-mismatches.md +61 -0
  123. data/TODO.diagrams/85-phantom-property-overrender.md +95 -0
  124. data/TODO.diagrams/86-foreign-package-rule.md +62 -0
  125. data/TODO.diagrams/87-internal-tech-encryption.md +80 -0
  126. data/TODO.diagrams/EXAMPLES_STATUS.md +88 -0
  127. data/TODO.diagrams/README.md +69 -0
  128. data/TODO.diagrams/STATUS.md +73 -0
  129. data/TODO.fixup/01-default-grouped-paths.md +34 -0
  130. data/TODO.fixup/02-marker-consolidation-per-connector.md +20 -0
  131. data/TODO.fixup/03-diagram-font-inference.md +28 -0
  132. data/TODO.fixup/04-extract-bounds-calculator.md +25 -0
  133. data/TODO.fixup/05-marker-registry-ocp.md +32 -0
  134. data/TODO.fixup/06-connector-path-bend-routing.md +28 -0
  135. data/TODO.fixup/07-edge-attachment-formula.md +22 -0
  136. data/TODO.fixup/08-visual-diff-harness.md +28 -0
  137. data/TODO.fixup/09-extract-element-compartments.md +34 -0
  138. data/TODO.fixup/10-canvas-width-overshoot-fix.md +20 -0
  139. data/TODO.fixup/11-layer-sequencer-extraction.md +18 -0
  140. data/TODO.fixup/12-path-style-harmony.md +23 -0
  141. data/TODO.fixup/13-datatype-stereotype-fallback.md +28 -0
  142. data/TODO.fixup/14-ea-exe-reverse-engineering-notes.md +56 -0
  143. data/TODO.fixup/15-enumeration-literal-rendering.md +30 -0
  144. data/TODO.fixup/16-operation-compartment-rendering.md +42 -0
  145. data/TODO.fixup/17-path-count-calibration.md +27 -0
  146. data/TODO.fixup/18-polygon-count-calibration.md +32 -0
  147. data/TODO.fixup/19-rect-count-undershoot-investigation.md +40 -0
  148. data/TODO.fixup/20-stereotype-color-from-classifier.md +18 -0
  149. data/TODO.fixup/21-visibility-filter-for-properties.md +24 -0
  150. data/TODO.fixup/22-multiplicity-display-rule-calibration.md +25 -0
  151. data/TODO.fixup/23-diagram-frame-title-element.md +31 -0
  152. data/TODO.fixup/24-note-element-rendering.md +23 -0
  153. data/TODO.fixup/25-ea-exe-disassembly-findings.md +177 -0
  154. data/TODO.fixup/26-svg-renderer-architecture.md +78 -0
  155. data/TODO.fixup/27-svg-element-emitters-disassembly.md +135 -0
  156. data/TODO.fixup/28-geometry-parser-identification.md +57 -0
  157. data/TODO.fixup/29-qea-svg-xmi-triple-comparison.md +185 -0
  158. data/TODO.fixup/30-theme-system-stub.md +46 -0
  159. data/TODO.fixup/31-theme-value-object-registry.md +17 -0
  160. data/TODO.fixup/32-styleex-on-diagram-model.md +22 -0
  161. data/TODO.fixup/33-text-encoding-decimals-rotation.md +29 -0
  162. data/TODO.fixup/34-per-type-fill-via-theme.md +18 -0
  163. data/TODO.fixup/35-stroke-width-per-theme.md +7 -0
  164. data/TODO.fixup/36-qea-rect-coord-normalization.md +24 -0
  165. data/TODO.fixup/37-package-shape-rendering.md +22 -0
  166. data/TODO.fixup/38-note-element-rendering.md +15 -0
  167. data/TODO.fixup/39-styleex-flag-honoring.md +25 -0
  168. data/TODO.fixup/40-connector-dashed-lines.md +15 -0
  169. data/TODO.fixup/41-diagram-frame-showborder-detection.md +23 -0
  170. data/TODO.fixup/42-textrenderer-centralization.md +10 -0
  171. data/TODO.fixup/43-colorresolver-unification.md +24 -0
  172. data/TODO.fixup/44-theme-aware-textrenderer.md +17 -0
  173. data/TODO.fixup/45-theme-aware-fontresolver.md +22 -0
  174. data/TODO.fixup/46-style-parameterized-by-theme.md +21 -0
  175. data/TODO.fixup/47-canvas-frame-inset.md +19 -0
  176. data/TODO.fixup/48-background-rect-format.md +15 -0
  177. data/TODO.fixup/49-all-samples-integration-test.md +17 -0
  178. data/TODO.fixup/50-svg-emitter-architecture-docs.md +33 -0
  179. data/TODO.fixup/51-promote-theme-to-ea-namespace.md +28 -0
  180. data/TODO.fixup/52-theme-definition-integrated-fills.md +26 -0
  181. data/TODO.fixup/53-theme-registry-yaml-loading.md +50 -0
  182. data/TODO.fixup/54-diagram-theme-api.md +50 -0
  183. data/TODO.fixup/55-update-eaemitter-to-ea-theme.md +23 -0
  184. data/TODO.fixup/56-theme-yaml-files.md +65 -0
  185. data/TODO.fixup/57-theme-specs-and-integration.md +27 -0
  186. data/TODO.fixup/58-ea-entry-point-theme-autoload.md +20 -0
  187. data/TODO.fixup/59-thread-theme-through-all-renderers.md +29 -0
  188. data/TODO.fixup/60-cli-theme-option.md +22 -0
  189. data/TODO.fixup/61-theme-validation.md +28 -0
  190. data/TODO.fixup/62-theme-builder-dsl.md +31 -0
  191. data/TODO.fixup/63-theme-integration-rendering-spec.md +24 -0
  192. data/TODO.fixup/64-theme-writeback-styleex.md +21 -0
  193. data/TODO.fixup/65-remove-dead-eaemitter-theme-files.md +30 -0
  194. data/TODO.fixup/66-styleex-writeback.md +22 -0
  195. data/TODO.fixup/67-delete-dead-code.md +28 -0
  196. data/TODO.fixup/68-figure-parity-status.md +82 -0
  197. data/TODO.fixup/69-package-polygon-rendering.md +54 -0
  198. data/TODO.fixup/70-tagged-values-compartment.md +39 -0
  199. data/TODO.fixup/71-auto-detect-theme-from-xmi.md +37 -0
  200. data/TODO.fixup/72-sample-exports-as-regression-specs.md +37 -0
  201. data/TODO.fixup/73-delete-dead-transformations.md +14 -0
  202. data/TODO.fixup/74-delete-dead-diagram-renderers.md +18 -0
  203. data/TODO.fixup/75-visibility-legend-icons.md +23 -0
  204. data/TODO.fixup/76-plateau-text-undershoot.md +27 -0
  205. data/TODO.fixup/77-canvas-frame-margins.md +28 -0
  206. data/TODO.fixup/78-note-element-rendering.md +30 -0
  207. data/TODO.fixup/79-operation-compartment-rendering.md +27 -0
  208. data/TODO.fixup/80-tagged-value-stereotype-visibility.md +37 -0
  209. data/TODO.fixup/81-figure-parity-current-state.md +63 -0
  210. data/config/qea_schema.yml +356 -0
  211. data/config/themes/119.yml +98 -0
  212. data/config/themes/default.yml +14 -0
  213. data/examples/exports/20251010_current_plateau_v5/UML_EA.DTD +6856 -0
  214. data/examples/exports/20251010_current_plateau_v5/model.xml +96709 -0
  215. data/examples/exports/ArcGISWorkspace_template/UML_EA.DTD +6856 -0
  216. data/examples/exports/ArcGISWorkspace_template/model.xml +1427 -0
  217. data/examples/exports/UmlModel_template/UML_EA.DTD +6856 -0
  218. data/examples/exports/UmlModel_template/model.xml +23 -0
  219. data/examples/exports/basic/UML_EA.DTD +6856 -0
  220. data/examples/exports/basic/model.xml +8039 -0
  221. data/examples/exports/simple/UML_EA.DTD +6856 -0
  222. data/examples/exports/simple/model.xml +585 -0
  223. data/examples/exports/simple_example/UML_EA.DTD +6856 -0
  224. data/examples/exports/simple_example/model.xml +23 -0
  225. data/examples/exports/test/UML_EA.DTD +6856 -0
  226. data/examples/exports/test/model.xml +1638 -0
  227. data/examples/qea/basic.qea +0 -0
  228. data/frontend/README.md +51 -0
  229. data/frontend/dist/app.iife.js +24 -0
  230. data/frontend/dist/style.css +1 -0
  231. data/frontend/index.html +26 -0
  232. data/frontend/package-lock.json +2359 -0
  233. data/frontend/package.json +26 -0
  234. data/frontend/src/App.vue +59 -0
  235. data/frontend/src/app.ts +8 -0
  236. data/frontend/src/components/AppHeader.vue +127 -0
  237. data/frontend/src/components/AppSidebar.vue +119 -0
  238. data/frontend/src/components/ClassDetails.vue +247 -0
  239. data/frontend/src/components/DiagramView.vue +79 -0
  240. data/frontend/src/components/PackageDetails.vue +92 -0
  241. data/frontend/src/components/PackageTreeNode.vue +64 -0
  242. data/frontend/src/components/SearchResults.vue +48 -0
  243. data/frontend/src/components/WelcomeView.vue +87 -0
  244. data/frontend/src/shims-vue.d.ts +5 -0
  245. data/frontend/src/stores/dataStore.ts +79 -0
  246. data/frontend/src/stores/uiStore.ts +167 -0
  247. data/frontend/src/styles/main.css +1566 -0
  248. data/frontend/src/types.ts +221 -0
  249. data/frontend/tests/e2e/__screenshots__/new-dark-mode.png +0 -0
  250. data/frontend/tests/e2e/__screenshots__/new-package-details.png +0 -0
  251. data/frontend/tests/e2e/__screenshots__/new-search-modal.png +0 -0
  252. data/frontend/tests/e2e/__screenshots__/new-sidebar-collapsed.png +0 -0
  253. data/frontend/tests/e2e/__screenshots__/new-welcome.png +0 -0
  254. data/frontend/tests/e2e/render.spec.ts +188 -0
  255. data/frontend/tsconfig.json +20 -0
  256. data/frontend/vite.config.ts +26 -0
  257. data/frontend/vitest.config.ts +8 -0
  258. data/lib/ea/cli/app.rb +57 -2
  259. data/lib/ea/cli/command/diagrams.rb +37 -28
  260. data/lib/ea/cli/command/diff.rb +46 -0
  261. data/lib/ea/cli/command/export.rb +80 -0
  262. data/lib/ea/cli/command/info.rb +75 -0
  263. data/lib/ea/cli/command/lint.rb +48 -0
  264. data/lib/ea/cli/command/mdg.rb +98 -0
  265. data/lib/ea/cli/command/query.rb +34 -0
  266. data/lib/ea/cli/command/render.rb +135 -0
  267. data/lib/ea/cli/command/svg.rb +8 -15
  268. data/lib/ea/cli/command.rb +7 -0
  269. data/lib/ea/diagram/display_config.rb +184 -0
  270. data/lib/ea/diagram.rb +4 -41
  271. data/lib/ea/diff/change.rb +30 -0
  272. data/lib/ea/diff/comparator.rb +82 -0
  273. data/lib/ea/diff/html_reporter.rb +91 -0
  274. data/lib/ea/diff.rb +15 -0
  275. data/lib/ea/export/json/generator.rb +42 -0
  276. data/lib/ea/export/json.rb +12 -0
  277. data/lib/ea/export/json_schema/generator.rb +77 -0
  278. data/lib/ea/export/json_schema.rb +12 -0
  279. data/lib/ea/export/plantuml/generator.rb +73 -0
  280. data/lib/ea/export/plantuml.rb +12 -0
  281. data/lib/ea/export/xmi/generator.rb +77 -0
  282. data/lib/ea/export/xmi.rb +11 -0
  283. data/lib/ea/export/xsd/class_mapping.rb +65 -0
  284. data/lib/ea/export/xsd/generator.rb +142 -0
  285. data/lib/ea/export/xsd/namespace_registry.rb +82 -0
  286. data/lib/ea/export/xsd.rb +19 -0
  287. data/lib/ea/export.rb +14 -0
  288. data/lib/ea/image/emf_renderer.rb +42 -0
  289. data/lib/ea/image.rb +12 -0
  290. data/lib/ea/lint/engine.rb +30 -0
  291. data/lib/ea/lint/lint_rule.rb +38 -0
  292. data/lib/ea/lint/offense.rb +18 -0
  293. data/lib/ea/lint/rules/cyclic_generalization.rb +62 -0
  294. data/lib/ea/lint/rules/duplicate_name.rb +28 -0
  295. data/lib/ea/lint/rules/missing_stereotype.rb +35 -0
  296. data/lib/ea/lint/rules/naming_convention.rb +44 -0
  297. data/lib/ea/lint/rules/orphan_element.rb +28 -0
  298. data/lib/ea/lint/rules.rb +14 -0
  299. data/lib/ea/lint.rb +13 -0
  300. data/lib/ea/mdg/document.rb +120 -0
  301. data/lib/ea/mdg/loader.rb +118 -0
  302. data/lib/ea/mdg/registry.rb +98 -0
  303. data/lib/ea/mdg/stereotype_alias_registry.rb +77 -0
  304. data/lib/ea/mdg/xml/applies_to.rb +18 -0
  305. data/lib/ea/mdg/xml/apply.rb +18 -0
  306. data/lib/ea/mdg/xml/content.rb +18 -0
  307. data/lib/ea/mdg/xml/documentation.rb +24 -0
  308. data/lib/ea/mdg/xml/stereotype.rb +28 -0
  309. data/lib/ea/mdg/xml/stereotypes.rb +18 -0
  310. data/lib/ea/mdg/xml/tag.rb +28 -0
  311. data/lib/ea/mdg/xml/tagged_values.rb +18 -0
  312. data/lib/ea/mdg/xml/technology.rb +28 -0
  313. data/lib/ea/mdg/xml/uml_profile.rb +22 -0
  314. data/lib/ea/mdg/xml/uml_profiles.rb +18 -0
  315. data/lib/ea/mdg/xml.rb +24 -0
  316. data/lib/ea/mdg.rb +25 -0
  317. data/lib/ea/model/classifier.rb +4 -0
  318. data/lib/ea/model/constraint.rb +24 -0
  319. data/lib/ea/model/diagram.rb +85 -0
  320. data/lib/ea/model/diagram_connector.rb +34 -0
  321. data/lib/ea/model/diagram_element.rb +16 -0
  322. data/lib/ea/model/document.rb +47 -2
  323. data/lib/ea/model/ghost_label.rb +32 -0
  324. data/lib/ea/model/instance_specification.rb +34 -0
  325. data/lib/ea/model/legend.rb +43 -0
  326. data/lib/ea/model/legend_item.rb +26 -0
  327. data/lib/ea/model/note.rb +28 -0
  328. data/lib/ea/model/operation.rb +2 -0
  329. data/lib/ea/model/property.rb +2 -0
  330. data/lib/ea/model/relationship.rb +2 -0
  331. data/lib/ea/model/signal.rb +14 -0
  332. data/lib/ea/model/slot.rb +19 -0
  333. data/lib/ea/model.rb +8 -0
  334. data/lib/ea/ocl/evaluator.rb +94 -0
  335. data/lib/ea/ocl/nodes.rb +30 -0
  336. data/lib/ea/ocl/parser.rb +133 -0
  337. data/lib/ea/ocl/unsupported_error.rb +7 -0
  338. data/lib/ea/ocl.rb +13 -0
  339. data/lib/ea/qea/factory/document_builder.rb +24 -10
  340. data/lib/ea/qea/factory/generalization_builder.rb +9 -11
  341. data/lib/ea/qea/infrastructure/table_reader.rb +9 -0
  342. data/lib/ea/qea/models/ea_author.rb +35 -0
  343. data/lib/ea/qea/models/ea_glossary.rb +34 -0
  344. data/lib/ea/qea/models/ea_image.rb +53 -0
  345. data/lib/ea/qea/models/ea_implement.rb +32 -0
  346. data/lib/ea/qea/models/ea_list.rb +42 -0
  347. data/lib/ea/qea/models/ea_object_effort.rb +34 -0
  348. data/lib/ea/qea/models/ea_object_problem.rb +37 -0
  349. data/lib/ea/qea/models/ea_object_require.rb +34 -0
  350. data/lib/ea/qea/models/ea_object_resource.rb +34 -0
  351. data/lib/ea/qea/models/ea_object_risk.rb +34 -0
  352. data/lib/ea/qea/models/ea_object_scenario.rb +34 -0
  353. data/lib/ea/qea/models/ea_object_test.rb +35 -0
  354. data/lib/ea/qea/models/ea_object_trx.rb +34 -0
  355. data/lib/ea/qea/models/ea_operation.rb +7 -0
  356. data/lib/ea/qea/models/ea_palette.rb +30 -0
  357. data/lib/ea/qea/models/ea_palette_item.rb +36 -0
  358. data/lib/ea/qea/models/ea_phase.rb +40 -0
  359. data/lib/ea/qea/models/ea_role_constraint.rb +32 -0
  360. data/lib/ea/qea/models/ea_secrypt.rb +34 -0
  361. data/lib/ea/qea/models/ea_version.rb +39 -0
  362. data/lib/ea/qea/models/ea_xref.rb +11 -1
  363. data/lib/ea/qea/models.rb +19 -0
  364. data/lib/ea/qea/services/database_loader.rb +22 -1
  365. data/lib/ea/query/builder.rb +108 -0
  366. data/lib/ea/query.rb +9 -0
  367. data/lib/ea/render/image_converter.rb +101 -0
  368. data/lib/ea/render.rb +10 -0
  369. data/lib/ea/shapescript/parser.rb +208 -0
  370. data/lib/ea/shapescript/renderer.rb +74 -0
  371. data/lib/ea/shapescript/shape.rb +34 -0
  372. data/lib/ea/shapescript.rb +24 -0
  373. data/lib/ea/sources/qea/adapter.rb +22 -5
  374. data/lib/ea/sources/qea/classifier_builder.rb +184 -7
  375. data/lib/ea/sources/qea/diagram_builder.rb +352 -24
  376. data/lib/ea/sources/qea/id_normalizer.rb +16 -1
  377. data/lib/ea/sources/qea/instance_builder.rb +113 -0
  378. data/lib/ea/sources/qea/legend_builder.rb +137 -0
  379. data/lib/ea/sources/qea/note_builder.rb +58 -0
  380. data/lib/ea/sources/qea/object_classifier_map.rb +6 -1
  381. data/lib/ea/sources/qea/operation_builder.rb +1 -0
  382. data/lib/ea/sources/qea/package_builder.rb +16 -0
  383. data/lib/ea/sources/qea/relationship_builder.rb +21 -5
  384. data/lib/ea/sources/qea/tagged_value_builder.rb +28 -9
  385. data/lib/ea/sources/qea/xref/legend_definition.rb +35 -0
  386. data/lib/ea/sources/qea/xref/parser.rb +150 -0
  387. data/lib/ea/sources/qea/xref/property_definition.rb +29 -0
  388. data/lib/ea/sources/qea/xref/record.rb +41 -0
  389. data/lib/ea/sources/qea/xref/stereotype_application.rb +37 -0
  390. data/lib/ea/sources/qea/xref.rb +27 -0
  391. data/lib/ea/sources/qea.rb +4 -0
  392. data/lib/ea/sources/xmi/adapter.rb +80 -2
  393. data/lib/ea/sources/xmi/classifier_builder.rb +10 -1
  394. data/lib/ea/sources/xmi/diagram_builder.rb +95 -18
  395. data/lib/ea/sources/xmi/extension_geometry_parser.rb +19 -2
  396. data/lib/ea/sources/xmi/extension_style_parser.rb +15 -2
  397. data/lib/ea/sources/xmi/note_builder.rb +46 -0
  398. data/lib/ea/sources/xmi/property_builder.rb +9 -0
  399. data/lib/ea/sources/xmi/stereotype_builder.rb +54 -0
  400. data/lib/ea/sources/xmi/tag_builder.rb +45 -0
  401. data/lib/ea/sources/xmi/umldi_keyword_extractor.rb +87 -0
  402. data/lib/ea/sources/xmi.rb +4 -0
  403. data/lib/ea/spa/output/sharded_multi_file_strategy.rb +18 -3
  404. data/lib/ea/spa/output/single_file_strategy.rb +8 -2
  405. data/lib/ea/spa/output/strategy.rb +34 -0
  406. data/lib/ea/svg/connector_router.rb +134 -0
  407. data/lib/ea/svg/ea_emitter/background.rb +2 -3
  408. data/lib/ea/svg/ea_emitter/bounds_calculator.rb +142 -0
  409. data/lib/ea/svg/ea_emitter/canvas.rb +56 -33
  410. data/lib/ea/svg/ea_emitter/color_resolver.rb +56 -0
  411. data/lib/ea/svg/ea_emitter/compartment/attributes.rb +28 -0
  412. data/lib/ea/svg/ea_emitter/compartment/constraints.rb +30 -0
  413. data/lib/ea/svg/ea_emitter/compartment/enum_literals.rb +86 -0
  414. data/lib/ea/svg/ea_emitter/compartment/header.rb +32 -0
  415. data/lib/ea/svg/ea_emitter/compartment/header_divider.rb +57 -0
  416. data/lib/ea/svg/ea_emitter/compartment/instance_slots.rb +96 -0
  417. data/lib/ea/svg/ea_emitter/compartment/instance_underline.rb +67 -0
  418. data/lib/ea/svg/ea_emitter/compartment/note_body.rb +52 -0
  419. data/lib/ea/svg/ea_emitter/compartment/note_text.rb +102 -0
  420. data/lib/ea/svg/ea_emitter/compartment/operations.rb +38 -0
  421. data/lib/ea/svg/ea_emitter/compartment/package_contents.rb +72 -0
  422. data/lib/ea/svg/ea_emitter/compartment/package_from_parent.rb +136 -0
  423. data/lib/ea/svg/ea_emitter/compartment/shape.rb +82 -0
  424. data/lib/ea/svg/ea_emitter/compartment/tagged_values.rb +30 -0
  425. data/lib/ea/svg/ea_emitter/compartment.rb +58 -0
  426. data/lib/ea/svg/ea_emitter/connectors.rb +46 -12
  427. data/lib/ea/svg/ea_emitter/diagram_frame.rb +143 -0
  428. data/lib/ea/svg/ea_emitter/document.rb +15 -24
  429. data/lib/ea/svg/ea_emitter/element/attribute_line_builder.rb +117 -0
  430. data/lib/ea/svg/ea_emitter/element/attribute_renderer.rb +119 -0
  431. data/lib/ea/svg/ea_emitter/element/bcol_decoder.rb +29 -0
  432. data/lib/ea/svg/ea_emitter/element/compartment_geometry.rb +113 -0
  433. data/lib/ea/svg/ea_emitter/element/constraint_renderer.rb +53 -0
  434. data/lib/ea/svg/ea_emitter/element/divider_renderer.rb +17 -0
  435. data/lib/ea/svg/ea_emitter/element/enumeration_literal_renderer.rb +34 -0
  436. data/lib/ea/svg/ea_emitter/element/filter.rb +44 -0
  437. data/lib/ea/svg/ea_emitter/element/hand_draw_shape_renderer.rb +77 -0
  438. data/lib/ea/svg/ea_emitter/element/header_line_pipeline.rb +43 -0
  439. data/lib/ea/svg/ea_emitter/element/header_line_provider/instance_spec.rb +27 -0
  440. data/lib/ea/svg/ea_emitter/element/header_line_provider/name.rb +76 -0
  441. data/lib/ea/svg/ea_emitter/element/header_line_provider/parent_ghost.rb +25 -0
  442. data/lib/ea/svg/ea_emitter/element/header_line_provider/stereotype_label.rb +68 -0
  443. data/lib/ea/svg/ea_emitter/element/header_line_provider.rb +19 -0
  444. data/lib/ea/svg/ea_emitter/element/header_lines.rb +27 -0
  445. data/lib/ea/svg/ea_emitter/element/header_renderer.rb +48 -0
  446. data/lib/ea/svg/ea_emitter/element/icon_renderer.rb +109 -0
  447. data/lib/ea/svg/ea_emitter/element/legend_renderer.rb +177 -0
  448. data/lib/ea/svg/ea_emitter/element/note_shape_renderer.rb +112 -0
  449. data/lib/ea/svg/ea_emitter/element/operation_renderer.rb +100 -0
  450. data/lib/ea/svg/ea_emitter/element/package_shape_renderer.rb +181 -0
  451. data/lib/ea/svg/ea_emitter/element/row_icon_renderer.rb +156 -0
  452. data/lib/ea/svg/ea_emitter/element/shape_renderer.rb +17 -0
  453. data/lib/ea/svg/ea_emitter/element/stereotype_icon_renderer.rb +82 -0
  454. data/lib/ea/svg/ea_emitter/element/tagged_value_renderer.rb +50 -0
  455. data/lib/ea/svg/ea_emitter/element/text_escape.rb +20 -0
  456. data/lib/ea/svg/ea_emitter/element.rb +37 -0
  457. data/lib/ea/svg/ea_emitter/elements.rb +283 -95
  458. data/lib/ea/svg/ea_emitter/font_resolver.rb +111 -0
  459. data/lib/ea/svg/ea_emitter/ghost_labels.rb +66 -0
  460. data/lib/ea/svg/ea_emitter/label/end_label.rb +266 -0
  461. data/lib/ea/svg/ea_emitter/label/midpoint_label.rb +101 -0
  462. data/lib/ea/svg/ea_emitter/label/registry.rb +50 -0
  463. data/lib/ea/svg/ea_emitter/label.rb +23 -0
  464. data/lib/ea/svg/ea_emitter/labels.rb +93 -27
  465. data/lib/ea/svg/ea_emitter/layer.rb +20 -0
  466. data/lib/ea/svg/ea_emitter/layer_sequencer.rb +93 -0
  467. data/lib/ea/svg/ea_emitter/marker/arrow_path.rb +52 -0
  468. data/lib/ea/svg/ea_emitter/marker/diamond.rb +57 -0
  469. data/lib/ea/svg/ea_emitter/marker/kind.rb +35 -0
  470. data/lib/ea/svg/ea_emitter/marker/open_triangle.rb +27 -0
  471. data/lib/ea/svg/ea_emitter/marker/package_import.rb +39 -0
  472. data/lib/ea/svg/ea_emitter/marker/plus.rb +40 -0
  473. data/lib/ea/svg/ea_emitter/marker/registry.rb +42 -0
  474. data/lib/ea/svg/ea_emitter/marker.rb +37 -0
  475. data/lib/ea/svg/ea_emitter/markers.rb +351 -64
  476. data/lib/ea/svg/ea_emitter/render_context.rb +52 -0
  477. data/lib/ea/svg/ea_emitter/style.rb +15 -0
  478. data/lib/ea/svg/ea_emitter/text_renderer.rb +92 -0
  479. data/lib/ea/svg/ea_emitter.rb +33 -11
  480. data/lib/ea/svg/parity/checker.rb +105 -0
  481. data/lib/ea/svg/parity/source.rb +59 -0
  482. data/lib/ea/svg/parity/suite.rb +113 -0
  483. data/lib/ea/svg/parity.rb +14 -0
  484. data/lib/ea/svg.rb +2 -15
  485. data/lib/ea/theme/definition.rb +176 -0
  486. data/lib/ea/theme/loader.rb +125 -0
  487. data/lib/ea/theme/registry.rb +96 -0
  488. data/lib/ea/theme.rb +37 -0
  489. data/lib/ea/transformations.rb +5 -88
  490. data/lib/ea/version.rb +4 -1
  491. data/lib/ea.rb +14 -4
  492. data/lib/tasks/svg_bench.rake +87 -0
  493. data/lutaml-uml-0.5.1.gem +0 -0
  494. data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-1-themes-list.png +0 -0
  495. data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-1-themes.png +0 -0
  496. data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-2-gradients.png +0 -0
  497. data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-3-colors.png +0 -0
  498. data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-4-appearance-fonts.png +0 -0
  499. data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-4-appearance.png +0 -0
  500. data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-5-behavior.png +0 -0
  501. data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram-6-sequence.png +0 -0
  502. data/reference-docs/enterprise-architect-appearance-dialogs/appearance-1-diagram.png +0 -0
  503. data/reference-docs/enterprise-architect-appearance-dialogs/appearance-2-objects.png +0 -0
  504. data/reference-docs/enterprise-architect-appearance-dialogs/appearance-3-links.png +0 -0
  505. metadata +449 -26
  506. data/lib/ea/diagram/configuration.rb +0 -379
  507. data/lib/ea/diagram/element_renderers/base_renderer.rb +0 -77
  508. data/lib/ea/diagram/element_renderers/class_renderer.rb +0 -323
  509. data/lib/ea/diagram/element_renderers/connector_renderer.rb +0 -41
  510. data/lib/ea/diagram/element_renderers/package_renderer.rb +0 -61
  511. data/lib/ea/diagram/element_renderers.rb +0 -43
  512. data/lib/ea/diagram/extractor.rb +0 -566
  513. data/lib/ea/diagram/layout_engine.rb +0 -170
  514. data/lib/ea/diagram/path_builder.rb +0 -202
  515. data/lib/ea/diagram/style_parser.rb +0 -42
  516. data/lib/ea/diagram/style_resolver.rb +0 -291
  517. data/lib/ea/diagram/svg_renderer.rb +0 -274
  518. data/lib/ea/diagram/util.rb +0 -73
  519. data/lib/ea/svg/bounds_calculator.rb +0 -74
  520. data/lib/ea/svg/connector_path.rb +0 -138
  521. data/lib/ea/svg/element_box.rb +0 -256
  522. data/lib/ea/svg/renderer.rb +0 -77
  523. data/lib/ea/svg/style_resolver.rb +0 -72
  524. data/lib/ea/transformations/configuration.rb +0 -333
  525. data/lib/ea/transformations/format_registry.rb +0 -366
  526. data/lib/ea/transformations/parsers/base_parser.rb +0 -482
  527. data/lib/ea/transformations/parsers/qea_parser.rb +0 -401
  528. data/lib/ea/transformations/parsers/xmi_parser.rb +0 -243
  529. data/lib/ea/transformations/transformation_engine.rb +0 -390
@@ -0,0 +1,41 @@
1
+ # TODO-D 76: basic.qea polygon under-render (-6) and path over-render (+6)
2
+
3
+ ## Status: open
4
+
5
+ After the aggregation arrow fix (TODO-D 73), basic.qea reached
6
+ 22/22 diagrams matched within tolerance, but two aggregate deltas
7
+ remain:
8
+
9
+ - polygon: ours=95, ref=101 (-6)
10
+ - path: ours=208, ref=202 (+6)
11
+
12
+ ## Per-diagram pattern
13
+
14
+ - Package Dependencies (0EDEA6EF): polygon +3
15
+ - Basic Class Diagram with Attributes (4F421236): polygon -2
16
+ - Basic Class Diagram with Operations (2AAB709F): polygon -2
17
+ - Basic Class Diagram with Receptions (4DBDAB9E): polygon -2
18
+ - Basic Class Diagram with Attributes and Operations (D2FA55D3): polygon -2
19
+ - Basic Class Diagram with Multiplicities (78030266): polygon -1
20
+ - Basic Class Diaram with Roles (6E95B74E): polygon -1
21
+ - Domain Model (E325B9D8): polygon +1
22
+
23
+ ## Likely cause (Basic Class Diagram family)
24
+
25
+ For the 4 diagrams with polygon=-2, we're missing 2 small triangle
26
+ polygon markers per diagram. These are likely Generalization arrow
27
+ triangles that we suppress somewhere.
28
+
29
+ The +3 polygon overshoot on "Package Dependencies" is likely a
30
+ package-import marker (anchor shape) that EA omits.
31
+
32
+ ## Path over-render (+6)
33
+
34
+ After the aggregation arrow fix, the +16 path over-render on the
35
+ outlier closed (to 0). The remaining +6 paths are likely from
36
+ similar marker issues on the diagrams above.
37
+
38
+ ## Next step
39
+
40
+ For each affected diagram, compare our markers vs ref's markers.
41
+ Identify which marker emission is incorrect.
@@ -0,0 +1,40 @@
1
+ # TODO-D 77: basic.qea text over-render (+2)
2
+
3
+ ## Status: open
4
+
5
+ basic.qea's two diagrams overshoot text by 1 each:
6
+
7
+ - Classes: +1
8
+ - Composition with Substitution: +1
9
+
10
+ ## Composition with Substitution diff
11
+
12
+ Ours has:
13
+ +1 "Class B.3" (split qualified name part)
14
+ +1 "Class B.2"
15
+ +1 "Class B.1"
16
+ +1 "«property»" (spurious property stereotype)
17
+
18
+ Ref has:
19
+ +1 "Class B::Class B.1" (single qualified name line)
20
+ +1 "Class B::Class B.2"
21
+ +1 "Class B::Class B.3"
22
+
23
+ So our qualified-name wrap is incorrectly splitting "Class B::X"
24
+ into two lines for these nested classes. The qualified name should
25
+ render as ONE line per element, not as "Class B::" + "X".
26
+
27
+ The spurious "«property»" text appears to come from a connector
28
+ SourceRole label that we render but ref doesn't on this diagram.
29
+
30
+ ## Classes diff
31
+
32
+ Need to identify what specific text differs on the Classes diagram.
33
+
34
+ ## Next step
35
+
36
+ 1. Inspect why qualified-name wrap triggers for "Class B::Class B.X"
37
+ (likely a width estimation mismatch).
38
+ 2. Identify the connector whose SourceRole produces "«property»"
39
+ and apply the right suppression (similar to aggregation arrow
40
+ fix — only render on specific directions).
@@ -0,0 +1,65 @@
1
+ # TODO-D 78: Refactor HeaderLines into provider chain (OCP)
2
+
3
+ ## Status: open (architecture improvement)
4
+
5
+ The current `HeaderLines.for` accepts a growing list of kwargs:
6
+
7
+ ```ruby
8
+ def for(classifier,
9
+ diagram_package_id: nil,
10
+ visually_nested: false,
11
+ umldi_keyword: nil,
12
+ bounds_width: nil,
13
+ font_size: 9,
14
+ off_canvas_parent_name: nil) # added in TODO-D 71
15
+ ...
16
+ end
17
+ ```
18
+
19
+ Adding the off-canvas parent line required:
20
+ 1. A new kwarg on `for`
21
+ 2. New logic inside `for` to prepend the line
22
+ 3. Threading the value from `Elements#build_context` through `RenderContext`
23
+
24
+ This is OCP-violating: each new header line variant (e.g., "realized
25
+ interfaces", "template parameters", "constraint summary") would
26
+ require modifying `HeaderLines.for` again.
27
+
28
+ ## Proposed refactor
29
+
30
+ Convert `HeaderLines` into a chain of line providers, each
31
+ contributing 0+ lines to the header. New line types = new provider
32
+ class, registered into the chain (no modification of existing
33
+ code).
34
+
35
+ ```ruby
36
+ module Element
37
+ module HeaderLineProvider
38
+ ALL = [
39
+ StereotypeLine, # «FeatureType» line (when present)
40
+ ParentClassLine, # italic off-canvas parent (TODO-D 71)
41
+ QualifiedNameLine, # the bold class name (with optional wrap)
42
+ ].freeze
43
+
44
+ def self.lines_for(classifier, context:)
45
+ ALL.flat_map { |provider| provider.lines_for(classifier, context) }
46
+ end
47
+ end
48
+ end
49
+ ```
50
+
51
+ Where `context` is a small Struct carrying the inputs each provider
52
+ may need (diagram_package_id, visually_nested, off_canvas_parent_name,
53
+ bounds_width, font_size, etc.).
54
+
55
+ ## Benefit
56
+
57
+ Adding a new line type (e.g., "interface signatures" on Interface
58
+ classifiers) becomes a single new provider class — `HeaderLines.for`
59
+ never changes.
60
+
61
+ ## Migration
62
+
63
+ Incremental: extract one provider at a time, starting with the
64
+ off-canvas parent line (the most recent addition). Each extraction
65
+ is independently shippable.
@@ -0,0 +1,65 @@
1
+ # TODO-D 79: Architecture improvements backlog
2
+
3
+ ## Status: open (rolling)
4
+
5
+ A list of architecture / code-quality improvements surfaced while
6
+ closing parity gaps. Each is shippable independently.
7
+
8
+ ## 1. Elements#build_context decomposition
9
+
10
+ `Elements#build_context` (lib/ea/svg/ea_emitter/elements.rb) is
11
+ ~50 lines and growing. It now also resolves the off-canvas parent
12
+ name, adding a new concern. Extract collaborators:
13
+
14
+ - `HeaderInputResolver` — gathers inputs for HeaderLines
15
+ (visually_nested, parent_name, umldi_keyword, bounds_width).
16
+ - `CompartmentInputResolver` — gathers attr_lines/op_lines/etc.
17
+
18
+ Each returns a small Struct; `build_context` just assembles them
19
+ into the RenderContext.
20
+
21
+ ## 2. RenderContext struct field count
22
+
23
+ RenderContext carries 23 keyword fields. Some are mutually relevant
24
+ (e.g., `attr_lines` and `geometry.attr_lines_count`). Consider
25
+ grouping:
26
+
27
+ - `HeaderInput` struct (header_lines, off_canvas_parent_name)
28
+ - `CompartmentInput` struct (attr_lines, op_lines, enum_literals,
29
+ tagged_values, constraints, package_content_lines)
30
+
31
+ Fewer top-level fields, clearer purpose per group.
32
+
33
+ ## 3. Phantom connector label boxes
34
+
35
+ `DiagramBuilder::DEFAULT_LABEL_BOXES` is a constant in the builder.
36
+ The geometry belongs on the synthesized DiagramConnector model
37
+ field (e.g., `default_label_offsets: true`). Currently the
38
+ `has_geometry_offsets` flag conveys this for one case; generalize.
39
+
40
+ ## 4. LayerSequencer dependency threading
41
+
42
+ LayerSequencer takes `document:` and threads it to multiple
43
+ collaborators (Labels, Elements). The collaborators individually
44
+ re-fetch relationships from the document. A precomputed per-diagram
45
+ "parent_index" (child_id → parent_id) built once at DiagramBuilder
46
+ time would remove the per-render relationship scan.
47
+
48
+ ## 5. public_send in Qea::Repositories::BaseRepository
49
+
50
+ `BaseRepository` uses `public_send(attr)` for dynamic attribute
51
+ dispatch. This is intentional metaprogramming (the attribute name
52
+ is data), not type-checking. But it's worth documenting with a
53
+ comment so future readers don't mistake it for the forbidden
54
+ private-send pattern.
55
+
56
+ ## 6. Spec coverage for new code
57
+
58
+ New code added in TODO-D 71 (off-canvas parent ghost line):
59
+ - `Elements#off_canvas_parent_name_for` — no spec
60
+ - `Elements#parent_generalization_for` — no spec
61
+ - `Elements#parent_package_represented_on_diagram?` — no spec
62
+ - `HeaderLines` italic prepend — covered indirectly via existing
63
+ header_lines_spec.
64
+
65
+ Add specs for the three Elements methods.
@@ -0,0 +1,51 @@
1
+ # TODO-D 80: Basic.qea Generalization triangle markers as polygons
2
+
3
+ ## Status: open (initial hypothesis disproven)
4
+
5
+ On 4 basic.qea diagrams ("Basic Class Diagram with Attributes",
6
+ "Operations", "Receptions", "Attributes and Operations"), ref
7
+ shows 2 extra triangle `<polygon>` markers per diagram that we
8
+ emit as `<path>` arrows instead.
9
+
10
+ ## Per-diagram delta
11
+
12
+ - Attributes: -2 polygons (and +2 paths)
13
+ - Operations: -2 polygons (and +2 paths)
14
+ - Receptions: -2 polygons (and +2 paths)
15
+ - Attributes+Operations: -2 polygons (and +2 paths)
16
+ - Multiplicities: -1 polygon
17
+ - Roles: -1 polygon
18
+ - Package Dependencies: +3 polygons (over-render — likely
19
+ package_import marker issue)
20
+ - Domain Model: +1 polygon
21
+
22
+ Net basic polygon delta: -6.
23
+
24
+ ## Initial hypothesis (DISPROVEN)
25
+
26
+ Tried: emit `:triangle` instead of `:arrow` for Association with
27
+ direction="Unspecified".
28
+
29
+ Result: Over-corrected. basic polygons went from -6 to +15 because
30
+ many basic.qea "Unspecified" Associations DO want arrow markers,
31
+ not triangles. The discriminator must be narrower.
32
+
33
+ ## Next investigation
34
+
35
+ The 4 failing diagrams share: 2 Association connectors, both
36
+ "Unspecified", connecting Class A → Class B.
37
+
38
+ Inspect what distinguishes these from other "Unspecified"
39
+ Associations on basic.qea that DO render arrows correctly.
40
+ Possibilities:
41
+ - The connector's sourcecard/destcard (multiplicity)
42
+ - The connector's sourceaccess/destaccess
43
+ - The presence of a Name vs anonymous
44
+ - The t_diagramlinks geometry (Path=, SX/SY/EX/EY)
45
+
46
+ ## Related
47
+
48
+ basic.qea path over-render (+6) is the mirror image — same 6
49
+ markers counted as paths instead of polygons. Closing one closes
50
+ the other.
51
+
@@ -0,0 +1,53 @@
1
+ # TODO-D 81: Plateau path over-render on ifc_3 (+3) and similar diagrams
2
+
3
+ ## Status: open
4
+
5
+ Several plateau diagrams render extra short horizontal `<path>`
6
+ elements (110-300px wide) that don't appear in EA's reference
7
+ SVG. The paths look like compartment dividers but appear at
8
+ positions where ref doesn't emit them.
9
+
10
+ ## Per-diagram delta
11
+
12
+ - ifc_3: +3 paths
13
+ - utility network: -4 paths (different issue — missing phantom
14
+ connector paths)
15
+ - GenericObject: -5 paths (same as utility network)
16
+ - cons_1: +2 paths
17
+ - bldg:Buildingの拡張属性(LOD4): +2 paths
18
+ - bldg:Roomの拡張属性(LOD4): +2 paths
19
+ - udx: +2 paths
20
+ - Urban Planning ADE2: +1 path
21
+ - CityObjectGroupの拡張属性: +1
22
+ - その他の構造物: +1
23
+ - 位置図_C09_2: +1
24
+
25
+ ## Pattern analysis (ifc_3)
26
+
27
+ Our extra paths at the same x range (218-438), varying y:
28
+ - M 218 394 L 438 394
29
+ - M 218 438 L 438 438
30
+ - M 218 463 L 438 463
31
+ - M 218 507 L 438 507
32
+
33
+ These look like 4 dividers in 4 different elements stacked
34
+ vertically. Ref's element layout differs (different y values),
35
+ suggesting our canvas/element y-offsets diverge from EA's.
36
+
37
+ ## Hypothesis
38
+
39
+ Either:
40
+ 1. Our divider emission logic fires for elements that EA treats
41
+ as header-only (no divider).
42
+ 2. Our canvas y-offset is off for some diagrams, causing dividers
43
+ to land at "wrong" y values that don't match ref.
44
+
45
+ ## Next step
46
+
47
+ For each affected diagram:
48
+ 1. Compare element bounds (our placement vs ref's).
49
+ 2. Compare divider_y values.
50
+ 3. Identify whether it's a positioning issue or a divider-logic
51
+ issue.
52
+
53
+ This is the largest remaining path-delta contributor.
@@ -0,0 +1,54 @@
1
+ # TODO-D 82: Plateau Appearance diagram — canvas offset mismatch
2
+
3
+ ## Status: open
4
+
5
+ The "Appearance" diagram (BC1F7E00 / C31C1314 — there are 2
6
+ versions) has 2 extra `<rect>` elements at positions that don't
7
+ match EA's reference.
8
+
9
+ ## Symptom
10
+
11
+ Our rects: Ref rects:
12
+ (35, 379) w=214 h=70 (35, 680) w=214 h=70
13
+ (45, 479) w=208 h=70 (45, 580) w=208 h=70
14
+
15
+ Both elements (TransformationMatrix3x4 and TransformationMatrix2x2)
16
+ are placed on the diagram (stereotype="dataType", 16 placed
17
+ elements total). Ref renders them at y=580/680, we render at
18
+ y=379/479 — a delta of ~200 px.
19
+
20
+ ## Root cause hypothesis
21
+
22
+ My `BoundsCalculator` computes canvas min_y = -1169 (lowest
23
+ element y -1154 minus MARKER_EXTENT 15). Reference's implied
24
+ min_y = -1470 (calculated from element model y -830 + render y 680
25
+ + inset 40).
26
+
27
+ The 301-px difference suggests EA includes additional geometry
28
+ (extended labels, image-bounds padding, or some other source) in
29
+ its canvas bound computation that we don't.
30
+
31
+ ## Why fixing this is hard
32
+
33
+ The BoundsCalculator is shared across all diagrams. A change here
34
+ affects every diagram's canvas. If the missing bound source is
35
+ diagram-specific (e.g., only DataType elements with certain
36
+ styles trigger it), the fix would need conditional logic.
37
+
38
+ ## Likely related
39
+
40
+ - Polygon positions on Appearance also differ — triangles at
41
+ different anchors (might be connector endpoint mismatch
42
+ due to wrong canvas translate).
43
+ - Other diagrams with rect_delta > 0 may share the same offset
44
+ issue.
45
+
46
+ ## Next step
47
+
48
+ 1. Identify what additional geometry EA's bounds include for
49
+ Appearance. Candidates:
50
+ - Connector label box extents (LLB/LRT geometry)
51
+ - Element image_bounds vs logical bounds handling
52
+ - Phantom connector waypoint contributions
53
+ 2. Test by adding the candidate source to BoundsCalculator and
54
+ verifying the canvas min_y matches.
@@ -0,0 +1,58 @@
1
+ # TODO-D 83: 3D diagram subtitle over-render (3 phantom subtitles)
2
+
3
+ ## Status: open
4
+
5
+ The "3D都市モデル応用スキーマと他のスキーマとの関係" diagram
6
+ shows 4 placed packages:
7
+
8
+ - Inner "3D都市モデル" (parent: outer "3D都市モデル")
9
+ - i-UR (parent: Conceptual Models)
10
+ - CityGML2.0 (parent: Conceptual Models)
11
+ - gml (parent: Conceptual Models)
12
+
13
+ EA reference renders 0 "(from X)" subtitles. Our code renders
14
+ 3 (the inner 3D都市モデル was suppressed by the name-match rule
15
+ in commit cf3dcf2; the other 3 still over-render).
16
+
17
+ ## Compared to udx
18
+
19
+ udx diagram shows 3 placed packages:
20
+
21
+ - 都市計画データ (parent: 3D都市モデル)
22
+ - i-UR (parent: Conceptual Models)
23
+ - CityGML2.0 (parent: Conceptual Models)
24
+
25
+ EA reference renders 3 subtitles. So udx and 3D have similar
26
+ structure but opposite subtitle behavior.
27
+
28
+ ## What differs
29
+
30
+ The diagrams have similar PDATA/StyleEx (both Package type,
31
+ HideParents=0). The ONLY visible difference: 3D includes a
32
+ placed element (inner 3D都市モデル) whose parent shares its name
33
+ with itself.
34
+
35
+ ## Hypothesis (untested)
36
+
37
+ When ANY placed package has a parent whose name collides with
38
+ another package's name in the diagram, EA suppresses all
39
+ subtitle rendering for that diagram. The reasoning: name
40
+ collisions confuse subtitle interpretation, so safer to omit.
41
+
42
+ Alternatively: a flag in t_diagram or t_diagramobjects that
43
+ we're not yet parsing.
44
+
45
+ ## Investigation block
46
+
47
+ This rule cannot be safely derived from one example. Closing
48
+ this gap requires either:
49
+ 1. Finding the rule from additional EA reference outputs (with
50
+ different package-name configurations).
51
+ 2. Reverse-engineering EA's source code for the subtitle logic.
52
+ 3. Per-diagram manual tuning (not scalable).
53
+
54
+ ## Related
55
+
56
+ - TODO-D 75: plateau text under-render (-36 / -37 after this
57
+ fix). The 3D diagram contributes +3 (or +4 pre-fix) to the
58
+ text count discrepancy.
@@ -0,0 +1,61 @@
1
+ # TODO-D 84: Per-diagram canvas-offset / positioning mismatches
2
+
3
+ ## Status: open (rolling)
4
+
5
+ Multiple plateau diagrams have small per-shape deltas (1-5 shapes
6
+ each) where my rendered positions differ from EA's reference.
7
+ The shape COUNTS are correct, but specific shapes are at the wrong
8
+ coordinates.
9
+
10
+ ## Affected diagrams (sample)
11
+
12
+ - utility network: -4 paths (canvas height off: ours 1156 vs ref 1156)
13
+ - GenericObject: -5 paths (canvas width off: ours 872 vs ref 772)
14
+ - ifc_3: +3 paths (frame dimensions match but divider y-positions off)
15
+ - Appearance: +2 rects (canvas height off by 36px)
16
+ - cons_1: +2 paths
17
+ - bldg:Buildingの拡張属性(LOD4): +2 paths
18
+ - bldg:Roomの拡張属性(LOD4): +2 paths
19
+
20
+ ## Common pattern
21
+
22
+ Canvas dimensions or coordinate offsets differ by a small amount
23
+ (10-300 px). Once the canvas offset differs, every shape's
24
+ position shifts, producing both "extra" and "missing" paths at
25
+ slightly different coordinates.
26
+
27
+ ## Likely root cause areas
28
+
29
+ 1. `BoundsCalculator` includes element + connector + marker +
30
+ package_tab points. EA may include ADDITIONAL geometry (label
31
+ boxes, image bounds extensions, etc.) that we miss.
32
+
33
+ 2. The MARKER_EXTENT padding (15 px) may differ from EA's actual
34
+ padding for certain connector/marker combinations.
35
+
36
+ 3. Element `image_bounds` handling: when an element has image
37
+ bounds below its logical bounds, my code includes those points.
38
+ EA may handle this conditionally.
39
+
40
+ ## Why this is hard to fix incrementally
41
+
42
+ A change to BoundsCalculator affects EVERY diagram's canvas. A
43
+ fix that improves one diagram may regress others. Requires
44
+ identifying the precise missing bound source and applying
45
+ conditionally.
46
+
47
+ ## Strategy
48
+
49
+ 1. Pick one diagram (e.g. Appearance).
50
+ 2. Reverse-engineer its canvas height from the reference.
51
+ 3. Identify what geometry would produce that canvas height.
52
+ 4. Add the missing bound source to BoundsCalculator.
53
+ 5. Verify no regression on other diagrams.
54
+
55
+ Repeat for each affected diagram pattern.
56
+
57
+ ## Related
58
+
59
+ - TODO-D 82: Appearance-specific investigation
60
+ - TODO-D 81: path over-render investigation
61
+ - TODO-D 73: polygon under-render
@@ -0,0 +1,95 @@
1
+ # TODO-D 85: Phantom connector «property» over-render on selected diagrams
2
+
3
+ ## Status: open
4
+
5
+ Several plateau diagrams over-render the «property» stereotype
6
+ text (and associated role + multiplicity labels) for PHANTOM
7
+ Aggregation connectors — synthesized when both endpoints are
8
+ placed but no t_diagramlinks entry exists.
9
+
10
+ ## Per-diagram «property» delta
11
+
12
+ | Diagram | Ours | Ref | Diff |
13
+ |---|---|---|---|
14
+ | indoor | 10 | 10 | 0 ✓ |
15
+ | brid_1 | 12 | 11 | +1 |
16
+ | CityGMLCore | 4 | 2 | +2 |
17
+ | veg | 16 | 11 | +5 |
18
+
19
+ ## What's known
20
+
21
+ - Phantom Aggregation connectors get `DEFAULT_LABEL_BOXES`
22
+ (LLT/LLB geometry) in `DiagramBuilder#build_phantom_connector`.
23
+ - This geometry triggers `EndLabel#texts` to emit role +
24
+ «property» + multiplicity labels.
25
+ - The `property_label?` check gates on direction
26
+ ("Source -> Destination" or "Destination -> Source" → render;
27
+ "Unspecified" / "Bi-Directional" → suppress).
28
+ - On indoor, all 9 phantom Aggregations with non-empty
29
+ SourceRole correctly render «property» in ref.
30
+ - On brid_1, 3 phantom Aggregations have non-empty SourceRole
31
+ but ref renders «property» for only 2 of them.
32
+
33
+ ## Discriminator candidates (untested)
34
+
35
+ 1. Source class stereotype — maybe «dataType» sources render
36
+ «property» but other stereotypes don't.
37
+ 2. Source class's attribute compartment visibility — maybe
38
+ sources with hidden attribute compartments don't render
39
+ «property» labels.
40
+ 3. Destination class's attribute compartment — similar.
41
+ 4. A specific t_connector flag (SourceAccess, DestAccess,
42
+ Pursposes, etc.) that we don't yet parse.
43
+ 5. Connector has a Style flag indicating label visibility.
44
+
45
+ ## Investigation update (2026-08-02)
46
+
47
+ brid_1's over-render is NOT from phantom connectors — brid_1
48
+ has 11 EXPLICIT t_diagramlinks for Aggregations. The over-render
49
+ is from the role-fallback logic in `EndLabel#texts`:
50
+
51
+ Connector 424 (DataQualityAttribute -> _AbstractBridge):
52
+ - Geometry has LLT/LLB (source end) AND LRT (target end)
53
+ - SourceRole = "bridDataQualityAttribute"
54
+ - DestRole = empty
55
+
56
+ My code:
57
+ - Source end: LLT present + role present → renders role + «property»
58
+ - Target end: LRT present + role empty → FALLBACK to source role
59
+ → renders role + «property» AGAIN at LRT position
60
+
61
+ Ref:
62
+ - Source end: renders role + «property» (matches my code)
63
+ - Target end: NOTHING (despite LRT geometry present)
64
+
65
+ ## Tested fix (REVERTED)
66
+
67
+ Tried restricting role fallback to only fire when text_box is
68
+ also missing. Result: text delta went from -40 to -154 — the
69
+ fallback is needed for many OTHER cases (114 valid labels rely
70
+ on it).
71
+
72
+ ## The actual discriminator (needed)
73
+
74
+ EA likely considers LRT geometry "stale" when:
75
+ - The geometry has unusual offset (e.g., OY=315 for connector
76
+ 424, vs typical ±50)
77
+ - OR the connector's direction makes the target end non-navigable
78
+
79
+ The "unusual offset" rule is fragile. A more principled rule
80
+ would require parsing additional t_diagramlinks fields or
81
+ comparing against EA's internal "dirty" flag.
82
+
83
+ ## Strategy
84
+
85
+ For each affected diagram, identify which connectors have LRT
86
+ geometry but no target role, and trace the LRT offset. If a
87
+ threshold rule (e.g., |OY| > 100) cleanly separates valid from
88
+ invalid, apply it.
89
+
90
+ ## Related
91
+
92
+ - TODO-D 75: plateau text under-render (current -40)
93
+ - TODO-D 81: plateau path over-render
94
+ - lib/ea/svg/ea_emitter/label/end_label.rb (property_label?)
95
+ - lib/ea/sources/qea/diagram_builder.rb (DEFAULT_LABEL_BOXES)
@@ -0,0 +1,62 @@
1
+ # TODO-D 86: Foreign-package rule over-suppression (parent-ghost)
2
+
3
+ ## Status: open (rolling)
4
+
5
+ The current `parent_package_represented_on_diagram?` check in
6
+ `lib/ea/svg/ea_emitter/elements.rb` suppresses the off-canvas
7
+ parent-class italic ghost line when ANY placed element shares
8
+ the parent's package. This rule was added to fix the Building
9
+ diagram's spurious _Feature/_AbstractGeometricAggregate ghosts.
10
+
11
+ ## Trade-off
12
+
13
+ | Rule state | Text delta | Effect |
14
+ |---|---|---|
15
+ | Rule ENABLED (current) | -40 | Some valid ghosts suppressed |
16
+ | Rule DISABLED | +60 | Some invalid ghosts rendered |
17
+
18
+ Net: rule removes 100 ghosts total (60 invalid + 40 valid).
19
+
20
+ ## Hypotheses tested (all DISPROVEN)
21
+
22
+ 1. **Package match** (current rule) — over-suppresses
23
+ 2. **Parent name in diagram name** — too narrow
24
+ 3. **Parent stereotype vs child stereotype** — all cases have
25
+ identical stereotypes, no discriminator
26
+ 4. **Parent abstract flag** — both abstract and non-abstract
27
+ parents render on indoor; both don't on Building
28
+ 5. **Parent's package_id is top-level** — all parents are
29
+ top-level; no discriminator
30
+
31
+ ## Valid vs invalid samples
32
+
33
+ | Diagram | Child | Parent | Parent pkg | Renders in ref? |
34
+ |---|---|---|---|---|
35
+ | indoor | Room | _CityObject | core | YES |
36
+ | indoor | _AbstractBuilding | _Site | core | YES |
37
+ | tran_2 | TrafficVolumeAttribute | RoadAttribute | uro | YES |
38
+ | bldg_1 | BuildingDetailAttribute | BuildingAttribute | uro | YES |
39
+ | Building | Address | _Feature | gml | NO |
40
+ | Building | _CityObject | _Feature | gml | NO |
41
+ | Building | _Solid | _GeometricPrimitive | gml | NO |
42
+
43
+ The discriminator between YES (render) and NO (suppress) cases
44
+ is NOT in t_object, t_connector, or any field we currently parse.
45
+
46
+ ## Remaining candidates (untested)
47
+
48
+ 1. A per-element flag in t_diagramlinks or t_diagramobjects
49
+ (e.g., a per-element "show parent" flag).
50
+ 2. A diagram-level StyleEx flag we haven't decoded.
51
+ 3. The depth of the inheritance chain (immediate parent vs
52
+ grandparent).
53
+ 4. A Package-level attribute (e.g., "abstract package" vs
54
+ "concrete package").
55
+
56
+ ## Strategic block
57
+
58
+ The discriminator requires either EA source access or
59
+ significant reference-SVG triangulation. Each additional rule
60
+ attempted in this conversation has either over-suppressed
61
+ valid cases or under-suppressed invalid ones. The current rule
62
+ is the best trade-off found.