draftwright 0.4.32__tar.gz → 0.4.33__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 (713) hide show
  1. {draftwright-0.4.32 → draftwright-0.4.33}/PKG-INFO +2 -2
  2. {draftwright-0.4.32 → draftwright-0.4.33}/pyproject.toml +2 -2
  3. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/__init__.py +7 -1
  4. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/_warnings.py +4 -0
  5. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/annotations/_common.py +25 -4
  6. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/annotations/from_model.py +45 -6
  7. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/annotations/orchestrator.py +52 -12
  8. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/annotations/sections.py +42 -26
  9. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/builder.py +45 -0
  10. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/drawing.py +33 -5
  11. draftwright-0.4.33/src/draftwright/linting/envelope_coverage.py +211 -0
  12. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/quality.py +32 -2
  13. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/structural.py +38 -0
  14. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/model/detect.py +92 -36
  15. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/projection.py +73 -15
  16. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/recognition_ownership.py +51 -1
  17. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/repair.py +29 -3
  18. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/reporting.py +6 -1
  19. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/sheet.py +24 -0
  20. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/sheet_emit.py +10 -2
  21. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/view_plan.py +90 -0
  22. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_boss_ownership.py +153 -5
  23. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_compiled_plan_boundary.py +7 -1
  24. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_declare.py +36 -1
  25. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_detail_views.py +58 -1
  26. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_drawing_state.py +50 -1
  27. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_feature_edit_replay.py +14 -0
  28. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_flat_stock_identity.py +39 -1
  29. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1333_bounded_ink_repair.py +5 -1
  30. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1450_boss_blend_ownership.py +9 -16
  31. draftwright-0.4.33/tests/test_issue_1560_envelope_axes.py +221 -0
  32. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_lint_structural.py +9 -0
  33. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_prismatic_classification.py +24 -0
  34. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_repair.py +36 -0
  35. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_sheet_emit.py +50 -11
  36. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_strip_layout.py +157 -0
  37. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_through_step_semantics.py +2 -1
  38. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_view_plan.py +70 -0
  39. draftwright-0.4.32/tests/test_issue_1560_envelope_axes.py +0 -69
  40. {draftwright-0.4.32 → draftwright-0.4.33}/.gitignore +0 -0
  41. {draftwright-0.4.32 → draftwright-0.4.33}/CHANGELOG.md +0 -0
  42. {draftwright-0.4.32 → draftwright-0.4.33}/LICENSE +0 -0
  43. {draftwright-0.4.32 → draftwright-0.4.33}/README.md +0 -0
  44. {draftwright-0.4.32 → draftwright-0.4.33}/docs/adr/README.md +0 -0
  45. {draftwright-0.4.32 → draftwright-0.4.33}/docs/reference/recogniser-capabilities.md +0 -0
  46. {draftwright-0.4.32 → draftwright-0.4.33}/docs/reference/sheet.md +0 -0
  47. {draftwright-0.4.32 → draftwright-0.4.33}/docs/research/1062-repeating-radial-profile-evidence.md +0 -0
  48. {draftwright-0.4.32 → draftwright-0.4.33}/skills/SKILL.md +0 -0
  49. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/_build_profile.py +0 -0
  50. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/_core.py +0 -0
  51. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/_geometry.py +0 -0
  52. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/_pmi_part21.py +0 -0
  53. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/analysis.py +0 -0
  54. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/angular_geometry.py +0 -0
  55. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/annotate.py +0 -0
  56. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/annotations/__init__.py +0 -0
  57. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/annotations/angular.py +0 -0
  58. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/annotations/balloons.py +0 -0
  59. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/annotations/gears.py +0 -0
  60. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/annotations/holes.py +0 -0
  61. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/annotations/leaders.py +0 -0
  62. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/audit.py +0 -0
  63. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/blend_contract.py +0 -0
  64. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/cli.py +0 -0
  65. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/compose.py +0 -0
  66. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/document.py +0 -0
  67. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/document_evidence.py +0 -0
  68. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/document_input.py +0 -0
  69. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/evaluation/__init__.py +0 -0
  70. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/evaluation/step_analysis.py +0 -0
  71. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/export.py +0 -0
  72. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/feature_identity.py +0 -0
  73. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/fits.py +0 -0
  74. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/fonts/IBMPlexMono-Regular.ttf +0 -0
  75. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/fonts/IBMPlexSansCondensed-Regular.ttf +0 -0
  76. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/fonts/LICENSE-IBMPlexMono-OFL.txt +0 -0
  77. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/fonts/LICENSE-IBMPlexSansCondensed-OFL.txt +0 -0
  78. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/fonts/__init__.py +0 -0
  79. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/inspection.py +0 -0
  80. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/inspection_contract.py +0 -0
  81. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/intents.py +0 -0
  82. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/layout.py +0 -0
  83. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/leader_policy.py +0 -0
  84. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/__init__.py +0 -0
  85. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/_registry.py +0 -0
  86. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/angled_step_coverage.py +0 -0
  87. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/angular.py +0 -0
  88. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/blend_coverage.py +0 -0
  89. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/chamfer_coverage.py +0 -0
  90. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/channel_coverage.py +0 -0
  91. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/circular_blind_step_coverage.py +0 -0
  92. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/coverage.py +0 -0
  93. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/evidence.py +0 -0
  94. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/fillet_coverage.py +0 -0
  95. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/flat_coverage.py +0 -0
  96. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/gear_coverage.py +0 -0
  97. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/groove_coverage.py +0 -0
  98. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/gusset_rib_coverage.py +0 -0
  99. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/hole_coverage.py +0 -0
  100. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/ink_overlap.py +0 -0
  101. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/issues.py +0 -0
  102. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/oriented_slot_coverage.py +0 -0
  103. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/pad_coverage.py +0 -0
  104. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/paired_ramp_step_coverage.py +0 -0
  105. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/passage_coverage.py +0 -0
  106. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/plate_coverage.py +0 -0
  107. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/pmi_coverage.py +0 -0
  108. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/pocket_coverage.py +0 -0
  109. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/pocket_pattern_coverage.py +0 -0
  110. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/polygonal_boss_coverage.py +0 -0
  111. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/polygonal_stock_coverage.py +0 -0
  112. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/prismatic_pocket_coverage.py +0 -0
  113. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/profiled_bore_coverage.py +0 -0
  114. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/rectangular_blind_slot_coverage.py +0 -0
  115. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/requirements.py +0 -0
  116. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/round_bottom_blind_slot_coverage.py +0 -0
  117. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/schedule_evidence.py +0 -0
  118. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/section_recess_coverage.py +0 -0
  119. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/slot_coverage.py +0 -0
  120. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/suggest.py +0 -0
  121. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/through_step_coverage.py +0 -0
  122. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/linting/turned_step_coverage.py +0 -0
  123. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/location_contract.py +0 -0
  124. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/make_drawing.py +0 -0
  125. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/measurement_support.py +0 -0
  126. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/model/__init__.py +0 -0
  127. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/model/callout.py +0 -0
  128. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/model/compiled.py +0 -0
  129. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/model/declare.py +0 -0
  130. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/model/ir.py +0 -0
  131. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/model/planner.py +0 -0
  132. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/model/pmi_lowering.py +0 -0
  133. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/oriented_slot_contract.py +0 -0
  134. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/plate_correspondence.py +0 -0
  135. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/pmi.py +0 -0
  136. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/profile_angles.py +0 -0
  137. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/progress.py +0 -0
  138. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/py.typed +0 -0
  139. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/recogniser_contract.py +0 -0
  140. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/recogniser_policy.py +0 -0
  141. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/recogniser_schema.py +0 -0
  142. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/recognition/__init__.py +0 -0
  143. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/recognition_cache.py +0 -0
  144. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/recognition_frame.py +0 -0
  145. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/registry.py +0 -0
  146. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/replay_assessment.py +0 -0
  147. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/score.py +0 -0
  148. {draftwright-0.4.32 → draftwright-0.4.33}/src/draftwright/section_recess_contract.py +0 -0
  149. {draftwright-0.4.32 → draftwright-0.4.33}/tests/_burden_report.py +0 -0
  150. {draftwright-0.4.32 → draftwright-0.4.33}/tests/_corpus_cover.py +0 -0
  151. {draftwright-0.4.32 → draftwright-0.4.33}/tests/_drawing_helpers.py +0 -0
  152. {draftwright-0.4.32 → draftwright-0.4.33}/tests/_evidence_contract.py +0 -0
  153. {draftwright-0.4.32 → draftwright-0.4.33}/tests/_kernel.py +0 -0
  154. {draftwright-0.4.32 → draftwright-0.4.33}/tests/_layout_helpers.py +0 -0
  155. {draftwright-0.4.32 → draftwright-0.4.33}/tests/_layout_sig.py +0 -0
  156. {draftwright-0.4.32 → draftwright-0.4.33}/tests/_mutation_corpus.py +0 -0
  157. {draftwright-0.4.32 → draftwright-0.4.33}/tests/_parts.py +0 -0
  158. {draftwright-0.4.32 → draftwright-0.4.33}/tests/_recogniser_public_contract.py +0 -0
  159. {draftwright-0.4.32 → draftwright-0.4.33}/tests/_section_recess_cases.py +0 -0
  160. {draftwright-0.4.32 → draftwright-0.4.33}/tests/_tier_manifest.py +0 -0
  161. {draftwright-0.4.32 → draftwright-0.4.33}/tests/_unit_manifest.py +0 -0
  162. {draftwright-0.4.32 → draftwright-0.4.33}/tests/conftest.py +0 -0
  163. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/ap242_single_cylinder_diameter.step +0 -0
  164. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/README.md +0 -0
  165. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/ambiguous-open-semicircle.step +0 -0
  166. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/blind-hole.step +0 -0
  167. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/chamfer-asymmetric.step +0 -0
  168. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/chamfer-compound.step +0 -0
  169. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/chamfer-overlap.step +0 -0
  170. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/chamfer-plain.step +0 -0
  171. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/chamfer-planar-x.step +0 -0
  172. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/chamfer-planar-y.step +0 -0
  173. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/chamfer-planar-z.step +0 -0
  174. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/chamfer-topology-a.step +0 -0
  175. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/chamfer-topology-b.step +0 -0
  176. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/chamfer-turned.step +0 -0
  177. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/corpus-chamfers-v1.json +0 -0
  178. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/corpus-countersinks-v1.json +0 -0
  179. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/corpus-double-d-bores-v1.json +0 -0
  180. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/corpus-fillets-v1.json +0 -0
  181. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/corpus-flats-v1.json +0 -0
  182. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/corpus-grooves-v1.json +0 -0
  183. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/corpus-hole-patterns-v1.json +0 -0
  184. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/corpus-plates-v1.json +0 -0
  185. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/corpus-pocket-patterns-v1.json +0 -0
  186. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/corpus-pockets-v1.json +0 -0
  187. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/corpus-polygonal-bosses-v1.json +0 -0
  188. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/corpus-polygonal-stock-v1.json +0 -0
  189. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/corpus-rectangular-pads-v1.json +0 -0
  190. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/corpus-turned-steps-v1.json +0 -0
  191. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/corpus-v1.json +0 -0
  192. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/countersink-deburr.step +0 -0
  193. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/countersink-external-cone.step +0 -0
  194. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/countersink-mixed-pair.step +0 -0
  195. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/countersink-single.step +0 -0
  196. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/countersink-topology-a.step +0 -0
  197. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/countersink-topology-b.step +0 -0
  198. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/double-d-axis-x.step +0 -0
  199. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/double-d-axis-y.step +0 -0
  200. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/double-d-blind.step +0 -0
  201. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/double-d-coaxial-compound.step +0 -0
  202. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/double-d-opposed-blind.step +0 -0
  203. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/double-d-roll-30.step +0 -0
  204. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/double-d-round-bore.step +0 -0
  205. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/double-d-single-z.step +0 -0
  206. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/double-d-topology-a.step +0 -0
  207. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/double-d-topology-b.step +0 -0
  208. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/fillet-compound.step +0 -0
  209. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/fillet-overlap.step +0 -0
  210. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/fillet-plain.step +0 -0
  211. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/fillet-planar-x.step +0 -0
  212. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/fillet-planar-y.step +0 -0
  213. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/fillet-planar-z.step +0 -0
  214. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/fillet-repeated.step +0 -0
  215. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/fillet-topology-a.step +0 -0
  216. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/fillet-topology-b.step +0 -0
  217. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/fillet-turned.step +0 -0
  218. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/flat-coaxial.step +0 -0
  219. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/flat-double-d.step +0 -0
  220. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/flat-lone-d.step +0 -0
  221. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/flat-nonround.step +0 -0
  222. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/flat-slanted-double-d.step +0 -0
  223. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/flat-topology-a.step +0 -0
  224. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/flat-topology-b.step +0 -0
  225. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/groove-compound.step +0 -0
  226. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/groove-lone-x.step +0 -0
  227. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/groove-lone-y.step +0 -0
  228. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/groove-lone-z.step +0 -0
  229. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/groove-monotonic-negative.step +0 -0
  230. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/groove-narrow.step +0 -0
  231. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/groove-topology-a.step +0 -0
  232. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/groove-topology-b.step +0 -0
  233. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/pad-compound-equal.step +0 -0
  234. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/pad-detached-body-negative.step +0 -0
  235. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/pad-full-span-ledge-negative.step +0 -0
  236. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/pad-nested-staircase-negative.step +0 -0
  237. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/pad-topology-a.step +0 -0
  238. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/pad-topology-b.step +0 -0
  239. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/pad-x-negative.step +0 -0
  240. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/pad-x-positive.step +0 -0
  241. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/pad-y-negative.step +0 -0
  242. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/pad-y-positive.step +0 -0
  243. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/pad-z-negative.step +0 -0
  244. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/pad-z-positive.step +0 -0
  245. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/pattern-ambiguous.step +0 -0
  246. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/pattern-grid.step +0 -0
  247. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/pattern-topology-a.step +0 -0
  248. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/pattern-topology-b.step +0 -0
  249. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/plain-block.step +0 -0
  250. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/plate-compound-equal.step +0 -0
  251. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/plate-cross-topology-a.step +0 -0
  252. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/plate-cross-topology-b.step +0 -0
  253. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/plate-detached-negative.step +0 -0
  254. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/plate-rotational-negative.step +0 -0
  255. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/plate-single-negative.step +0 -0
  256. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/plate-t-xz.step +0 -0
  257. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/plate-t-yz.step +0 -0
  258. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/plate-thick-negative.step +0 -0
  259. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/plate-u-additive.step +0 -0
  260. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/plate-u-cut.step +0 -0
  261. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/pocket-compound.step +0 -0
  262. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/pocket-edge-anchored.step +0 -0
  263. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/pocket-lone.step +0 -0
  264. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/pocket-opposed.step +0 -0
  265. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/pocket-pattern-ambiguous.step +0 -0
  266. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/pocket-pattern-grid.step +0 -0
  267. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/pocket-pattern-linear.step +0 -0
  268. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/pocket-pattern-pair.step +0 -0
  269. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/pocket-pattern-topology-a.step +0 -0
  270. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/pocket-pattern-topology-b.step +0 -0
  271. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/pocket-prismatic-negative.step +0 -0
  272. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/pocket-side.step +0 -0
  273. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/pocket-through-negative.step +0 -0
  274. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/pocket-topology-a.step +0 -0
  275. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/pocket-topology-b.step +0 -0
  276. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/pocket-two-equal.step +0 -0
  277. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/polygonal-boss-compound-equal.step +0 -0
  278. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/polygonal-boss-detached-negative.step +0 -0
  279. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/polygonal-boss-in-plane-rotated.step +0 -0
  280. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/polygonal-boss-other-protrusions-negative.step +0 -0
  281. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/polygonal-boss-recess-negative.step +0 -0
  282. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/polygonal-boss-stock-negative.step +0 -0
  283. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/polygonal-boss-topology-a.step +0 -0
  284. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/polygonal-boss-topology-b.step +0 -0
  285. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/polygonal-boss-x.step +0 -0
  286. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/polygonal-boss-y.step +0 -0
  287. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/polygonal-boss-z.step +0 -0
  288. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/polygonal-stock-compound-negative.step +0 -0
  289. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/polygonal-stock-cylinder-negative.step +0 -0
  290. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/polygonal-stock-irregular-negative.step +0 -0
  291. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/polygonal-stock-octagon-negative.step +0 -0
  292. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/polygonal-stock-recess-negative.step +0 -0
  293. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/polygonal-stock-roll17.step +0 -0
  294. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/polygonal-stock-topology-a.step +0 -0
  295. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/polygonal-stock-topology-b.step +0 -0
  296. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/polygonal-stock-translated.step +0 -0
  297. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/polygonal-stock-x.step +0 -0
  298. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/polygonal-stock-y.step +0 -0
  299. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/topology-a.step +0 -0
  300. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/topology-b.step +0 -0
  301. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/turned-step-axis-x.step +0 -0
  302. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/turned-step-axis-y.step +0 -0
  303. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/turned-step-axis-z.step +0 -0
  304. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/turned-step-compound.step +0 -0
  305. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/turned-step-repeated-lengths.step +0 -0
  306. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/turned-step-through-bore.step +0 -0
  307. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/turned-step-topology-a.step +0 -0
  308. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/turned-step-topology-b.step +0 -0
  309. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/evaluation/turned-step-translated-blind-bore.step +0 -0
  310. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/grm03_thumbwheel_drive_screw.step +0 -0
  311. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/grm03_thumbwheel_drive_screw_ap242_pmi.step +0 -0
  312. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/grm04_drive_plate.step +0 -0
  313. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/if_step_flat_across_cylinder.step +0 -0
  314. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/issue_1058_wheel_rh.step +0 -0
  315. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/issue_1247_angled_blind_step.step +0 -0
  316. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/issue_1595_whistle_key_frame.step +0 -0
  317. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/issue_1595_whistle_key_lever.step +0 -0
  318. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/issue_909_basic_part_design_017_body.step +0 -0
  319. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/issue_915_case_study_2.step +0 -0
  320. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/nist_ctc_01_asme1_ap203.stp +0 -0
  321. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/nist_ctc_01_asme1_ap242.stp +0 -0
  322. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/nist_ctc_02_asme1_ap203.stp +0 -0
  323. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/nist_ctc_02_asme1_ap242.stp +0 -0
  324. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/nist_ctc_03_asme1_ap203.stp +0 -0
  325. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/nist_ctc_03_asme1_ap242.stp +0 -0
  326. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/nist_ctc_04_asme1_ap203.stp +0 -0
  327. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/nist_ctc_04_asme1_ap242.stp +0 -0
  328. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/nist_ctc_05_asme1_ap203.stp +0 -0
  329. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/nist_ctc_05_asme1_ap242.stp +0 -0
  330. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/tuner_jig_blind_obround_pockets.step +0 -0
  331. {draftwright-0.4.32 → draftwright-0.4.33}/tests/fixtures/whistle_frame_reference.step +0 -0
  332. {draftwright-0.4.32 → draftwright-0.4.33}/tests/refactor_golden/bracket_section.json +0 -0
  333. {draftwright-0.4.32 → draftwright-0.4.33}/tests/refactor_golden/centered_rebate.json +0 -0
  334. {draftwright-0.4.32 → draftwright-0.4.33}/tests/refactor_golden/chamfered.json +0 -0
  335. {draftwright-0.4.32 → draftwright-0.4.33}/tests/refactor_golden/filleted.json +0 -0
  336. {draftwright-0.4.32 → draftwright-0.4.33}/tests/refactor_golden/flange_dense.json +0 -0
  337. {draftwright-0.4.32 → draftwright-0.4.33}/tests/refactor_golden/grid_plate.json +0 -0
  338. {draftwright-0.4.32 → draftwright-0.4.33}/tests/refactor_golden/grooved_shaft.json +0 -0
  339. {draftwright-0.4.32 → draftwright-0.4.33}/tests/refactor_golden/hex_bar.json +0 -0
  340. {draftwright-0.4.32 → draftwright-0.4.33}/tests/refactor_golden/holed_slot.json +0 -0
  341. {draftwright-0.4.32 → draftwright-0.4.33}/tests/refactor_golden/pocketed.json +0 -0
  342. {draftwright-0.4.32 → draftwright-0.4.33}/tests/refactor_golden/prismatic_ladder.json +0 -0
  343. {draftwright-0.4.32 → draftwright-0.4.33}/tests/refactor_golden/scattered_plate.json +0 -0
  344. {draftwright-0.4.32 → draftwright-0.4.33}/tests/refactor_golden/side_drilled.json +0 -0
  345. {draftwright-0.4.32 → draftwright-0.4.33}/tests/refactor_golden/turned_stepped.json +0 -0
  346. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_add_dimension.py +0 -0
  347. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_adr0018_view_routing.py +0 -0
  348. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_adr0018_view_selection.py +0 -0
  349. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_adr_corpus.py +0 -0
  350. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_agent_improvement_canary_issue_1716.py +0 -0
  351. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_agents_guide.py +0 -0
  352. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_analysis_geometry.py +0 -0
  353. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_angle_patterns.py +0 -0
  354. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_angular_references.py +0 -0
  355. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_angular_rendering.py +0 -0
  356. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_annotation_box_composition.py +0 -0
  357. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_annotation_box_corpus.py +0 -0
  358. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_api_docs.py +0 -0
  359. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_architecture_docs.py +0 -0
  360. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_arrangement_gate.py +0 -0
  361. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_assessment_comparison_issue_1712.py +0 -0
  362. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_audit_differential.py +0 -0
  363. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_axial_dimensions.py +0 -0
  364. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_balloon_ring_standoff.py +0 -0
  365. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_build_drawing_entrypoints.py +0 -0
  366. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_build_profile_harness.py +0 -0
  367. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_burden_report.py +0 -0
  368. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_candidate_evidence_issue_1726.py +0 -0
  369. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_canonical_angles.py +0 -0
  370. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_carve_free_position_callers.py +0 -0
  371. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_channel_ownership.py +0 -0
  372. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_circular_blind_step_semantics.py +0 -0
  373. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_cli_behavior.py +0 -0
  374. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_cli_report_sidecar.py +0 -0
  375. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_clone_budget.py +0 -0
  376. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_compose_then_pack.py +0 -0
  377. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_corpus_cover.py +0 -0
  378. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_counting_calls.py +0 -0
  379. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_coverage_mode.py +0 -0
  380. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_declaration_identity_issue_1710.py +0 -0
  381. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_declaration_report_issue_1710.py +0 -0
  382. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_declared_recognition_gate.py +0 -0
  383. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_declared_report_issue_1688.py +0 -0
  384. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_deferred_edits.py +0 -0
  385. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_dense_sheet_canary.py +0 -0
  386. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_deprecation_dates.py +0 -0
  387. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_depth_estimators.py +0 -0
  388. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_detect_once.py +0 -0
  389. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_detect_registry.py +0 -0
  390. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_diameter_deduplication.py +0 -0
  391. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_diameter_leaders.py +0 -0
  392. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_dimension_lane_canary_issue_1757.py +0 -0
  393. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_dimension_role_vocabulary.py +0 -0
  394. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_document_build.py +0 -0
  395. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_document_claim_authority.py +0 -0
  396. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_document_claims.py +0 -0
  397. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_document_coverage.py +0 -0
  398. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_document_report.py +0 -0
  399. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_document_report_authority.py +0 -0
  400. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_drawing_encapsulation.py +0 -0
  401. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_drawing_operations.py +0 -0
  402. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_dynamic_corridors.py +0 -0
  403. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_e2e_slice.py +0 -0
  404. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_e2e_standards.py +0 -0
  405. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_equivalent_dimension_presentations_issue_1759.py +0 -0
  406. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_export_dxf_curves.py +0 -0
  407. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_export_dxf_zoom.py +0 -0
  408. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_export_formats.py +0 -0
  409. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_export_reproducible.py +0 -0
  410. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_export_shape.py +0 -0
  411. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_external_recognition_boundary.py +0 -0
  412. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_feature_edit_corridors.py +0 -0
  413. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_feature_edit_verbs.py +0 -0
  414. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_feature_leader_candidate_regions.py +0 -0
  415. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_feature_provenance.py +0 -0
  416. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_feature_queries.py +0 -0
  417. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_fillets_adjacency.py +0 -0
  418. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_fit_calculations.py +0 -0
  419. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_fits.py +0 -0
  420. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_flat_completeness.py +0 -0
  421. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_flat_stock_opposition.py +0 -0
  422. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_format_selector.py +0 -0
  423. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_formatting.py +0 -0
  424. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_framed_step_family_evidence.py +0 -0
  425. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_gdt_placement.py +0 -0
  426. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_geometry_graph_spike.py +0 -0
  427. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_grid_lattice_convention.py +0 -0
  428. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_groove_completeness_evidence.py +0 -0
  429. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_groove_profile.py +0 -0
  430. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_gusset_rib_semantics.py +0 -0
  431. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_hole_annotations.py +0 -0
  432. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_hole_pattern_callouts.py +0 -0
  433. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_hole_table.py +0 -0
  434. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_import_boundaries.py +0 -0
  435. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_inspection_contract.py +0 -0
  436. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_interior_label_placement.py +0 -0
  437. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_iso_layout.py +0 -0
  438. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_iso_nts_caption_placement.py +0 -0
  439. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_isometric_orientation.py +0 -0
  440. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_isometric_placement.py +0 -0
  441. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1000_envelope_reuse.py +0 -0
  442. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1006_measurement_comparison.py +0 -0
  443. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1058_wheel_profile.py +0 -0
  444. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1073_cross_body_patterns.py +0 -0
  445. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1082_polygonal_stock.py +0 -0
  446. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1086_declared_gears.py +0 -0
  447. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1116_ap242_hole_tolerance_lowering.py +0 -0
  448. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1126_requesting_less_never_scores_better.py +0 -0
  449. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1130_view_planning_evidence.py +0 -0
  450. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1132_turned_profile_span_is_reported.py +0 -0
  451. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1142_hole_leader_labels.py +0 -0
  452. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1143_hole_completeness.py +0 -0
  453. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1144_transactional_hole_table.py +0 -0
  454. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1146_scale_completeness.py +0 -0
  455. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1147_legibility_pair_aggregation.py +0 -0
  456. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1153_contradictory_dimensions.py +0 -0
  457. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1154_one_owner_per_measurement.py +0 -0
  458. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1155_grm04_sheet_use.py +0 -0
  459. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1157_no_implicit_general_tolerance.py +0 -0
  460. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1166_cross_pass_feature_leaders.py +0 -0
  461. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1176_quality_fidelity.py +0 -0
  462. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1177_angular_dimensions.py +0 -0
  463. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1187_unroutable_leaders.py +0 -0
  464. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1188_per_view_assignment.py +0 -0
  465. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1190_section_decision.py +0 -0
  466. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1196_deterministic_view_names.py +0 -0
  467. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1202_observed_drawing_consumer.py +0 -0
  468. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1204_multiscale_view_issues.py +0 -0
  469. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1209_linear_pmi_witnesses.py +0 -0
  470. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1215_envelope_tolerance.py +0 -0
  471. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1215_no_approved_tolerance_is_dropped.py +0 -0
  472. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1216_callout_reservation_measures_ink.py +0 -0
  473. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1216_pairwise_across_scale_groups.py +0 -0
  474. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1217_claimed_representations.py +0 -0
  475. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1217_the_facility_is_shared.py +0 -0
  476. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1219_location_claims_its_own_axis.py +0 -0
  477. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1229_ledger_member_keying.py +0 -0
  478. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1240_iso_above_strip_visibility.py +0 -0
  479. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1245_passage_disposition.py +0 -0
  480. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1246_prismatic_pocket_disposition.py +0 -0
  481. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1247_angled_step_disposition.py +0 -0
  482. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1254_turned_chamfers.py +0 -0
  483. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1260_view_constraints.py +0 -0
  484. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1262_automatic_turned_views.py +0 -0
  485. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1276_turned_leader_targets.py +0 -0
  486. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1281_turned_fillets.py +0 -0
  487. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1296_cylindrical_diameter_pmi.py +0 -0
  488. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1298_manufacturing_requirements.py +0 -0
  489. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1299_page_escalation.py +0 -0
  490. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1308_machined_leader_analytics.py +0 -0
  491. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1312_engine_costs.py +0 -0
  492. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1325_nominal_agreement.py +0 -0
  493. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1332_overlap_remedy.py +0 -0
  494. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1332_zone_labels.py +0 -0
  495. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1334_prevent_ink.py +0 -0
  496. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1336_grm03_ap242_pmi_fixture.py +0 -0
  497. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1338_scale_before_page_escalation.py +0 -0
  498. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1349_precision_display.py +0 -0
  499. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1350_detected_takeover.py +0 -0
  500. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1351_structured_note_coverage.py +0 -0
  501. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1352_searchable_pdf_text.py +0 -0
  502. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1353_cnc_authoritative_workflow.py +0 -0
  503. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1357_framed_activation.py +0 -0
  504. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1357_framed_boundary.py +0 -0
  505. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1357_plural_turned_profiles.py +0 -0
  506. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1357_pmi_frame.py +0 -0
  507. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1360_thread_depth.py +0 -0
  508. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1369_hole_completeness_evidence.py +0 -0
  509. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1370_countersink_completeness_evidence.py +0 -0
  510. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1370_double_d_completeness_evidence.py +0 -0
  511. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1370_hole_pattern_completeness_evidence.py +0 -0
  512. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1371_flat_completeness_evidence.py +0 -0
  513. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1371_polygonal_stock_completeness_evidence.py +0 -0
  514. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1373_plate_completeness_evidence.py +0 -0
  515. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1374_chamfer_completeness_evidence.py +0 -0
  516. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1374_fillet_completeness_evidence.py +0 -0
  517. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1374_turned_step_completeness_evidence.py +0 -0
  518. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1378_diameter_leader_targets.py +0 -0
  519. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1390_sheet_registration.py +0 -0
  520. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1392_recognisers_048.py +0 -0
  521. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1395_degenerate_iso_region.py +0 -0
  522. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1396_layout_advisories.py +0 -0
  523. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1397_unverifiable_requirement_message.py +0 -0
  524. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1421_rectangular_blind_slot_completeness.py +0 -0
  525. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1421_rectangular_blind_slot_semantics.py +0 -0
  526. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1421_round_bottom_blind_slot_completeness.py +0 -0
  527. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1421_round_bottom_blind_slot_semantics.py +0 -0
  528. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1432_adoption.py +0 -0
  529. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1432_boundary_failures.py +0 -0
  530. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1432_oriented_slot_semantics.py +0 -0
  531. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1433_blend_semantics.py +0 -0
  532. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1460_step_inspection.py +0 -0
  533. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1466_dimension_options.py +0 -0
  534. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1466_semantic_sides.py +0 -0
  535. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1479_radius_leader_targets.py +0 -0
  536. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1485_curved_pockets.py +0 -0
  537. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1485_quiddity_024_boundary.py +0 -0
  538. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1485_rounded_pockets.py +0 -0
  539. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1505_diameter_coverage.py +0 -0
  540. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1505_short_axial_chains.py +0 -0
  541. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1511_turned_boss_heights.py +0 -0
  542. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1514_projection_safeguard.py +0 -0
  543. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1515_first_angle.py +0 -0
  544. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1516_dimension_text.py +0 -0
  545. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1517_through_indicator.py +0 -0
  546. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1518_explicit_rear.py +0 -0
  547. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1524_tolerance_magnitude.py +0 -0
  548. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1530_section_provenance.py +0 -0
  549. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1531_semantic_hole_counts.py +0 -0
  550. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1532_authored_section_examples.py +0 -0
  551. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1533_review_diagnostics.py +0 -0
  552. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1534_build_progress.py +0 -0
  553. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1536_title_overflow.py +0 -0
  554. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1543_feature_schedules.py +0 -0
  555. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1543_schedule_requirements.py +0 -0
  556. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1544_frame_document_canary.py +0 -0
  557. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1555_turned_recognition_format_invariance.py +0 -0
  558. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1563_sheet_pmi_reconciliation.py +0 -0
  559. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1585_title_block_date.py +0 -0
  560. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1593_title_block_keepout.py +0 -0
  561. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1596_bolt_circle_corroboration.py +0 -0
  562. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1598_hex_pockets.py +0 -0
  563. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1599_duplicate_slot_widths.py +0 -0
  564. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1601_flat_precision.py +0 -0
  565. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1603_cli_output_paths.py +0 -0
  566. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1604_internal_section.py +0 -0
  567. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1612_frame_sergio_coverage.py +0 -0
  568. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1612_sheet_margins.py +0 -0
  569. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_1613_circular_channel.py +0 -0
  570. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_367_leader_ink.py +0 -0
  571. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_443_grm03_axial_coverage.py +0 -0
  572. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_563_placement_intent.py +0 -0
  573. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_676_polygonal_boss.py +0 -0
  574. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_676_polygonal_boss_declare.py +0 -0
  575. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_740_leader_assignment.py +0 -0
  576. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_798_floor_cardinality.py +0 -0
  577. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_798_material_field.py +0 -0
  578. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_798_silhouette_lint.py +0 -0
  579. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_827_real_part_canary.py +0 -0
  580. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_883_location_identity.py +0 -0
  581. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_885_prismatic_coverage.py +0 -0
  582. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_909_sloped_profile.py +0 -0
  583. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_915_dense_case.py +0 -0
  584. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_916_pocket_leader.py +0 -0
  585. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_917_open_channel.py +0 -0
  586. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_924_zero_length_shoulders.py +0 -0
  587. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_955_height_contingency.py +0 -0
  588. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_issue_958_cross_solid_recognition.py +0 -0
  589. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_label_provenance.py +0 -0
  590. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_layout.py +0 -0
  591. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_layout_cleanliness.py +0 -0
  592. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_layout_constants.py +0 -0
  593. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_layout_evidence_issue_1711.py +0 -0
  594. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_layout_generalisation.py +0 -0
  595. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_layout_hypothesis.py +0 -0
  596. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_layout_override_lane_issue_1757.py +0 -0
  597. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_layout_override_side_issue_1757.py +0 -0
  598. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_layout_property.py +0 -0
  599. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_leader_footprint.py +0 -0
  600. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_leader_region_policy.py +0 -0
  601. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_lint_box_cache.py +0 -0
  602. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_lint_coverage.py +0 -0
  603. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_lint_ink_overlap.py +0 -0
  604. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_lint_reconciliation.py +0 -0
  605. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_lint_suggestions.py +0 -0
  606. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_lint_summary.py +0 -0
  607. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_linting.py +0 -0
  608. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_location_dimensions.py +0 -0
  609. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_location_vocabulary.py +0 -0
  610. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_machined_feature_callouts.py +0 -0
  611. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_make_drawing_entrypoints.py +0 -0
  612. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_nested_recognition_ownership.py +0 -0
  613. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_note_verb.py +0 -0
  614. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_object_aspects.py +0 -0
  615. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_occupancy_boxes.py +0 -0
  616. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_occurrence_recognition_ownership.py +0 -0
  617. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_overall_height_coverage.py +0 -0
  618. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_pad_completeness_evidence.py +0 -0
  619. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_paired_ramp_semantics.py +0 -0
  620. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_parameter_id.py +0 -0
  621. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_pareto_loop_canary_issue_1753.py +0 -0
  622. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_part_classification.py +0 -0
  623. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_part_model.py +0 -0
  624. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_pattern_ownership.py +0 -0
  625. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_pitch_dim_footprint.py +0 -0
  626. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_place_dimension.py +0 -0
  627. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_plate_ownership.py +0 -0
  628. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_pmi.py +0 -0
  629. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_pmi_common_labels.py +0 -0
  630. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_pmi_datum_lowering.py +0 -0
  631. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_pmi_gtol_lowering.py +0 -0
  632. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_pmi_part21.py +0 -0
  633. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_pocket_completeness_evidence.py +0 -0
  634. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_pocket_pattern.py +0 -0
  635. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_pocket_pattern_completeness_evidence.py +0 -0
  636. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_pocket_pattern_recognition.py +0 -0
  637. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_polygonal_boss_completeness_evidence.py +0 -0
  638. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_principal_profile_classifier.py +0 -0
  639. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_prismatic_boss_diameter.py +0 -0
  640. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_prismatic_dimensions.py +0 -0
  641. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_private_test_attr_reads.py +0 -0
  642. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_private_test_imports.py +0 -0
  643. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_profile_angles.py +0 -0
  644. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_projection_symbol_default.py +0 -0
  645. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_quality_components.py +0 -0
  646. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_quiddity_lifecycle_boundary.py +0 -0
  647. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_real_part_fixtures.py +0 -0
  648. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_recogniser_adoption.py +0 -0
  649. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_recogniser_capabilities.py +0 -0
  650. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_recogniser_contract.py +0 -0
  651. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_recogniser_policy.py +0 -0
  652. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_recogniser_step_inventory.py +0 -0
  653. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_recognition_boundary_failures.py +0 -0
  654. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_recognition_evidence_schema.py +0 -0
  655. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_recognition_policy_dispositions.py +0 -0
  656. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_recognition_result.py +0 -0
  657. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_refactor_golden.py +0 -0
  658. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_registry.py +0 -0
  659. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_render_seam.py +0 -0
  660. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_repack_geometry_seam.py +0 -0
  661. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_replay_assessment_issue_1715.py +0 -0
  662. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_report_projection.py +0 -0
  663. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_report_status_reasons_issue_1618.py +0 -0
  664. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_report_writer.py +0 -0
  665. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_requirement_applicability.py +0 -0
  666. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_requirement_carriers.py +0 -0
  667. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_requirement_catalog.py +0 -0
  668. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_requirement_catalog_families.py +0 -0
  669. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_scale_policy.py +0 -0
  670. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_scale_selection.py +0 -0
  671. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_score.py +0 -0
  672. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_script_detail_parity.py +0 -0
  673. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_section_hatching.py +0 -0
  674. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_section_recess_contract.py +0 -0
  675. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_section_recess_pockets.py +0 -0
  676. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_shared_box_memo.py +0 -0
  677. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_shared_drawing_cache.py +0 -0
  678. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_sheet_furniture.py +0 -0
  679. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_sheet_gdt.py +0 -0
  680. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_sheet_generation_snapshot.py +0 -0
  681. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_sheet_identity_invariant.py +0 -0
  682. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_sheet_notes.py +0 -0
  683. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_sheet_of.py +0 -0
  684. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_sheet_section.py +0 -0
  685. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_sheet_tables.py +0 -0
  686. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_slanted_blind_step.py +0 -0
  687. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_slot_completeness.py +0 -0
  688. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_slot_pattern.py +0 -0
  689. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_slot_pattern_recognition.py +0 -0
  690. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_slot_recognition.py +0 -0
  691. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_soft_deprecation.py +0 -0
  692. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_solve_trace.py +0 -0
  693. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_step_analysis_evaluation.py +0 -0
  694. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_strip_zones.py +0 -0
  695. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_suite_shape.py +0 -0
  696. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_suppression_ledger.py +0 -0
  697. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_suppression_marks.py +0 -0
  698. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_through_step_ownership.py +0 -0
  699. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_tier_manifest.py +0 -0
  700. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_title_block_units_format.py +0 -0
  701. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_tolerances.py +0 -0
  702. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_turned_diameters.py +0 -0
  703. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_turned_lengths.py +0 -0
  704. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_turned_step_ownership.py +0 -0
  705. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_turned_steps.py +0 -0
  706. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_two_pass_layout.py +0 -0
  707. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_typ_dimensions.py +0 -0
  708. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_typed_remediation_projection_issue_1759.py +0 -0
  709. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_version_bump_ci.py +0 -0
  710. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_view_blocks.py +0 -0
  711. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_view_coordinates.py +0 -0
  712. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_witness_label_reconciliation.py +0 -0
  713. {draftwright-0.4.32 → draftwright-0.4.33}/tests/test_workflows.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: draftwright
3
- Version: 0.4.32
3
+ Version: 0.4.33
4
4
  Summary: Automated technical-drawing generation for build123d
5
5
  Project-URL: Homepage, https://github.com/pzfreo/draftwright
6
6
  Project-URL: Repository, https://github.com/pzfreo/draftwright
@@ -684,7 +684,7 @@ Classifier: Programming Language :: Python :: 3.14
684
684
  Classifier: Topic :: Scientific/Engineering
685
685
  Requires-Python: <3.15,>=3.10
686
686
  Requires-Dist: antlr4-python3-runtime<4.10
687
- Requires-Dist: build123d-drafting-helpers>=0.15.4
687
+ Requires-Dist: build123d-drafting-helpers>=0.15.5
688
688
  Requires-Dist: build123d<0.11,>=0.9.0; python_full_version < '3.13'
689
689
  Requires-Dist: build123d<0.12,>=0.11; python_full_version >= '3.13'
690
690
  Requires-Dist: cadquery-ocp-novtk!=7.9.3.1.1; python_full_version >= '3.13'
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "draftwright"
7
- version = "0.4.32"
7
+ version = "0.4.33"
8
8
  description = "Automated technical-drawing generation for build123d"
9
9
  readme = "README.md"
10
10
  license = { file = "LICENSE" }
@@ -22,7 +22,7 @@ dependencies = [
22
22
  # This novtk release lacks OCP.GccEnt on macOS. The exclusion must reach
23
23
  # published wheels, not only uv's development resolver constraints.
24
24
  "cadquery-ocp-novtk!=7.9.3.1.1 ; python_full_version >= '3.13'",
25
- "build123d-drafting-helpers>=0.15.4",
25
+ "build123d-drafting-helpers>=0.15.5",
26
26
  "quiddity==0.3.3",
27
27
  "numpy>=1.24",
28
28
  # PNG raster export (SVG→PDF→PNG). Both permissively licensed (Pillow HPND; pypdfium2
@@ -57,6 +57,7 @@ _LAZY = {
57
57
  # to reach, and the pytest filterwarnings entry naming it paid that on every invocation.
58
58
  "SoftDeprecationWarning": "draftwright._warnings",
59
59
  "ScaleCompletenessWarning": "draftwright._warnings",
60
+ "ProjectionGeometryWarning": "draftwright._warnings",
60
61
  }
61
62
 
62
63
 
@@ -93,7 +94,11 @@ _sys.modules[__name__].__class__ = _DraftwrightModule
93
94
 
94
95
 
95
96
  if TYPE_CHECKING: # static analysers / IDEs — no runtime import, no kernel cost
96
- from draftwright._warnings import ScaleCompletenessWarning, SoftDeprecationWarning
97
+ from draftwright._warnings import (
98
+ ProjectionGeometryWarning,
99
+ ScaleCompletenessWarning,
100
+ SoftDeprecationWarning,
101
+ )
97
102
  from draftwright.builder import ScaleIncompatibilityError, build_drawing, make_drawing
98
103
  from draftwright.compose import choose_scale
99
104
  from draftwright.document import Document, DocumentBuildError, DocumentResult
@@ -147,6 +152,7 @@ __all__ = [
147
152
  "Sheet",
148
153
  "ScaleIncompatibilityError",
149
154
  "ScaleCompletenessWarning",
155
+ "ProjectionGeometryWarning",
150
156
  "ViewPlanIncomplete",
151
157
  "ViewConstraints",
152
158
  "ViewSpec",
@@ -45,3 +45,7 @@ class ScaleCompletenessWarning(UserWarning):
45
45
  Callers can filter this policy decision independently of unrelated user warnings while
46
46
  still inspecting the complete machine-readable record on ``Drawing.scale_decision``.
47
47
  """
48
+
49
+
50
+ class ProjectionGeometryWarning(UserWarning):
51
+ """A projector emitted geometry outside the source shape's possible view envelope."""
@@ -3583,18 +3583,39 @@ def place_strip_candidates(
3583
3583
  todo = todo + rejected_total
3584
3584
  solved.extend(placed)
3585
3585
 
3586
- if len(solved) > 1:
3586
+ if solved:
3587
3587
  assert len({name for name, _dim_obj in solved}) == len(solved), (
3588
3588
  "strip survivor names must be unique before label selection"
3589
3589
  )
3590
3590
  natural_solved = dict(solved)
3591
- adjusted = prevent_dimension_label_ink(
3592
- solved,
3591
+ # Local dimensions already participate through strip occupancy, and dimensions
3592
+ # owned by another view retain their independent corridor/repair contract. The
3593
+ # missing class is non-dimension ink whose semantic owner is another view: an
3594
+ # outboard leader can physically enter this corridor even though the projected
3595
+ # view blocks are disjoint (#1781).
3596
+ committed = []
3597
+ for name, annotation in dwg.iter_annotations():
3598
+ owner = dwg.view_of(name)
3599
+ if (
3600
+ owner is not None
3601
+ and owner != view
3602
+ and not isinstance(annotation, (Dimension, SafeDimension, AngularDimension))
3603
+ and type(annotation).__name__ not in CROSSABLE_TYPES
3604
+ ):
3605
+ committed.append((name, annotation))
3606
+ committed_names = {name for name, _annotation in committed}
3607
+ adjusted_batch = prevent_dimension_label_ink(
3608
+ [*committed, *solved],
3593
3609
  page=(
3594
3610
  _drawing_bounds(dwg) if hasattr(dwg, "page_w") and hasattr(dwg, "page_h") else None
3595
3611
  ),
3596
- immutable={name for name, _dim_obj in solved if (anchored or {}).get(name, False)},
3612
+ immutable={
3613
+ *committed_names,
3614
+ *(name for name, _dim_obj in solved if (anchored or {}).get(name, False)),
3615
+ },
3616
+ perpendicular_step=tier + strip.spacing,
3597
3617
  )
3618
+ adjusted = adjusted_batch[len(committed) :]
3598
3619
  # A label shift normally stays inside the dimension's measured span and
3599
3620
  # therefore inside its already-validated footprint. Keep the validation
3600
3621
  # contract explicit nevertheless: if an unusual helper/style grows the real
@@ -990,8 +990,10 @@ def _obround_radius_candidates(
990
990
 
991
991
 
992
992
  # Corridor-ladder ordering (ADR 2 (was 0009) end state, #346): feature-SIZE dims sit nearer the
993
- # view (inner run), datum-referenced LOCATION dims stack outward (a single ascending chain
994
- # by datum distance). Segregating the two runs keeps a slot length from landing mid-ladder.
993
+ # view (inner run), while datum-referenced LOCATION dims form one ascending outer chain.
994
+ # Step-height rungs measure from the common height datum, so they belong to that value-ordered
995
+ # run rather than to producer registration order (#1779). Segregating ordinary feature sizes
996
+ # keeps a slot length or local boss height from landing mid-ladder.
995
997
  _SIZE_SUBCHAIN = 0
996
998
  _LOC_SUBCHAIN = 1
997
999
  _OVERALL_SUBCHAIN = 2
@@ -3729,6 +3731,37 @@ def _flat_label(across_text, sfx="") -> str:
3729
3731
  return f"{across_text}{sfx} A/F"
3730
3732
 
3731
3733
 
3734
+ def _flat_definition_count(members) -> int:
3735
+ """Count repeated flat definitions without counting one centred opposed set as many.
3736
+
3737
+ ``axis_line`` and ``stock_span`` identify the provider's stock region, but interrupted
3738
+ housing geometry can give several independent flat supports that share both. A true
3739
+ double-D or hex remains one definition because every support has its reflection through
3740
+ that stock axis; a non-centred family retains one instance per source support.
3741
+ """
3742
+
3743
+ if len(members) <= 1:
3744
+ return 1
3745
+ facts = members[0][0].facts
3746
+ transverse = tuple(index for index, axis in enumerate("xyz") if axis != facts.axis)
3747
+ centre = tuple(float(value) for value in facts.axis_line)
3748
+ points = tuple(
3749
+ tuple(float(member.facts.frame.origin[index]) for index in transverse)
3750
+ for member, _dimension in members
3751
+ )
3752
+ centred = all(
3753
+ any(
3754
+ all(
3755
+ abs(candidate[index] - (2.0 * centre[index] - point[index])) <= 0.01
3756
+ for index in range(2)
3757
+ )
3758
+ for candidate in points
3759
+ )
3760
+ for point in points
3761
+ )
3762
+ return 1 if centred else len(members)
3763
+
3764
+
3732
3765
  def render_flats(dwg, plan, a, *, ctx, only=None) -> int:
3733
3766
  """Render physical stock definitions, counting identical ones without counting faces.
3734
3767
 
@@ -3791,8 +3824,9 @@ def render_flats(dwg, plan, a, *, ctx, only=None) -> int:
3791
3824
  vb = dwg.view_bounds(view)
3792
3825
  if vb is None:
3793
3826
  continue
3794
- if len(stocks) > 1:
3795
- label = f"{len(stocks)}× {label}"
3827
+ definition_count = sum(_flat_definition_count(members) for _, members, _ in stocks)
3828
+ if definition_count > 1:
3829
+ label = f"{definition_count}× {label}"
3796
3830
  candidates = _flat_candidates(
3797
3831
  dwg,
3798
3832
  view,
@@ -6841,8 +6875,10 @@ def _render_height_ladder_in_view(dwg, plan, frame, *, ctx, detail_view, view) -
6841
6875
  # compiler's own number instead of re-deriving a convention from the rendered string,
6842
6876
  # which is the pattern ADR 4 (was 0016 Amendment 1) exists to stop.
6843
6877
  chain: list = []
6878
+ order_values: dict[str, float] = {}
6844
6879
  if rung_set is not None and rung_set.representative:
6845
6880
  (rep,) = rungs
6881
+ order_values["dim_step_typ"] = rep.value
6846
6882
  chain.append(
6847
6883
  (
6848
6884
  "dim_step_typ",
@@ -6933,6 +6969,7 @@ def _render_height_ladder_in_view(dwg, plan, frame, *, ctx, detail_view, view) -
6933
6969
  if has_shoulders and rung.value * frame.scale < _MIN_STEP_DIM_MM:
6934
6970
  short_rungs.append(rung)
6935
6971
  continue
6972
+ order_values[f"dim_step_{col}"] = rung.value
6936
6973
  chain.append(
6937
6974
  (
6938
6975
  f"dim_step_{col}",
@@ -7103,11 +7140,13 @@ def _render_height_ladder_in_view(dwg, plan, frame, *, ctx, detail_view, view) -
7103
7140
  build=_build,
7104
7141
  # Steps stack inner→outer in chain order; the overall height rides the
7105
7142
  # OVERALL subchain so it lands outermost by construction (as the envelope
7106
- # dims do), replacing the old carve's outermost=True.
7143
+ # dims do). Ordinary rungs join the same value-ordered baseline run as
7144
+ # off-axis-hole heights (#1779), outside the inner boss-size run, instead
7145
+ # of retaining producer registration order.
7107
7146
  order=(
7108
7147
  (_OVERALL_SUBCHAIN, 0, name)
7109
7148
  if name == "dim_height"
7110
- else (_SIZE_SUBCHAIN, k, name)
7149
+ else (_LOC_SUBCHAIN, order_values[name], name)
7111
7150
  ),
7112
7151
  on_place=lambda nm: None,
7113
7152
  on_drop=_drop,
@@ -125,16 +125,50 @@ from draftwright.model.planner import annotation_groups, internal_section_rows
125
125
  from draftwright.progress import stage
126
126
  from draftwright.registry import MeasurementCell
127
127
  from draftwright.repair import reconcile_witness_labels
128
- from draftwright.view_plan import ViewConstraints
128
+ from draftwright.view_plan import (
129
+ DERIVED_VIEW_IDENTIFIERS,
130
+ DerivedViewIdentifierPool,
131
+ ViewConstraints,
132
+ derived_view_identifier,
133
+ )
134
+
135
+
136
+ def _derived_view_identifier_pool(a) -> DerivedViewIdentifierPool:
137
+ """Reserve every authored section/detail identity before any derived view renders."""
138
+
139
+ constraints = a.view_constraints
140
+ if not isinstance(constraints, ViewConstraints):
141
+ return DerivedViewIdentifierPool(candidates=DERIVED_VIEW_IDENTIFIERS)
142
+ requested = (
143
+ constraints.derived
144
+ if constraints.derived_source == "authored"
145
+ else constraints.added_derived
146
+ )
147
+ identifiers = []
148
+ for item in requested:
149
+ identifier = derived_view_identifier(item.spec.kind, item.spec.name)
150
+ if identifier is None:
151
+ raise ValueError(
152
+ f"derived view {item.spec.name!r} from {item.source} has no canonical identifier"
153
+ )
154
+ identifiers.append(identifier)
155
+ return DerivedViewIdentifierPool(identifiers, candidates=DERIVED_VIEW_IDENTIFIERS)
129
156
 
130
157
 
131
- def _planned_sections(a, model, feature_keys) -> tuple[SectionPlan, ...]:
158
+ def _planned_sections(a, model, feature_keys, *, identifiers) -> tuple[SectionPlan, ...]:
132
159
  """Combine the automatic section candidate with ADR 2 (was 0018) authored/add requests."""
133
160
 
134
161
  constraints = a.view_constraints
135
162
  if not isinstance(constraints, ViewConstraints):
136
163
  automatic = plan_sections(model, feature_keys)
137
- return (automatic,) if automatic is not None else ()
164
+ if automatic is None:
165
+ return ()
166
+ label = identifiers.allocate()
167
+ if label is None:
168
+ raise ValueError(
169
+ "automatic section cannot be named: derived-view identifiers exhausted"
170
+ )
171
+ return (replace(automatic, label=label),)
138
172
 
139
173
  requested = (
140
174
  constraints.derived
@@ -158,8 +192,9 @@ def _planned_sections(a, model, feature_keys) -> tuple[SectionPlan, ...]:
158
192
  f"section {item.spec.name!r} from {item.source} cuts at y={cut_y:g}, outside "
159
193
  f"the part interior ({a.bb.min.Y:g}, {a.bb.max.Y:g})"
160
194
  )
161
- slug = item.spec.name.removeprefix("section_")
162
- label = slug[0].upper() if len(set(slug)) == 1 else slug.upper()
195
+ label = derived_view_identifier(item.spec.kind, item.spec.name)
196
+ if label is None:
197
+ raise ValueError(f"section {item.spec.name!r} has no canonical identifier")
163
198
  plans.append(
164
199
  SectionPlan(
165
200
  cut_y,
@@ -173,12 +208,13 @@ def _planned_sections(a, model, feature_keys) -> tuple[SectionPlan, ...]:
173
208
 
174
209
  if constraints.derived_source != "authored":
175
210
  automatic = plan_sections(model, feature_keys)
211
+ if automatic is not None and any(plan.cut_y == automatic.cut_y for plan in plans):
212
+ automatic = None
176
213
  if automatic is not None:
177
- used = {plan.label for plan in plans}
178
- auto_label = next((letter for letter in "ABCDEFGH" if letter not in used), None)
214
+ auto_label = identifiers.allocate()
179
215
  if auto_label is None:
180
216
  raise ValueError(
181
- "automatic section cannot be named: authored labels A-H are exhausted"
217
+ "automatic section cannot be named: derived-view identifiers exhausted"
182
218
  )
183
219
  plans.insert(0, replace(automatic, label=auto_label))
184
220
  return tuple(plans)
@@ -202,7 +238,9 @@ def _queue_authored_details(dwg, a, ctx, plan) -> None:
202
238
  if not (isinstance(target, tuple) and len(target) == 2 and target[0] == "feature"):
203
239
  raise ValueError(f"detail {item.spec.name!r} has no semantic feature target")
204
240
  feature = target[1]
205
- label = item.spec.name.removeprefix("detail_").upper()
241
+ label = derived_view_identifier(item.spec.kind, item.spec.name)
242
+ if label is None:
243
+ raise ValueError(f"detail {item.spec.name!r} has no canonical identifier")
206
244
  factor = item.spec.scale_factor or 2.0
207
245
  if queue_step_detail(
208
246
  dwg,
@@ -626,7 +664,8 @@ def _auto_annotate(dwg, a: Analysis, *, detail_view: bool = False):
626
664
  # Decide the section trigger + cut-plane row now (pure function of _model/
627
665
  # feature_keys, no placement dependency); the "reserve_section" stage reserves
628
666
  # its row and the "section" stage renders it.
629
- _sections = _planned_sections(a, _model, feature_keys)
667
+ _derived_identifiers = _derived_view_identifier_pool(a)
668
+ _sections = _planned_sections(a, _model, feature_keys, identifiers=_derived_identifiers)
630
669
  ctx.dense_internal_section = any(section.internal_detail for section in _sections)
631
670
 
632
671
  # ── the stage thunks, run in _PASS_SEQUENCE order (#699 slice b) ─────────
@@ -902,7 +941,8 @@ def _auto_annotate(dwg, a: Analysis, *, detail_view: bool = False):
902
941
  # still render after it and avoid the section view.
903
942
  if _sections:
904
943
  for section in _sections:
905
- _add_section_view(dwg, a, section, ctx=ctx)
944
+ if not _add_section_view(dwg, a, section, ctx=ctx):
945
+ _derived_identifiers.release(section.label)
906
946
  else:
907
947
  # Recorded, not left at the initial `not_evaluated`: the planner DID run and
908
948
  # found no counterbore/spotface/blind Z-hole, which is a different fact from
@@ -917,7 +957,7 @@ def _auto_annotate(dwg, a: Analysis, *, detail_view: bool = False):
917
957
  # crowded turned heads alike — through the one generic detailer, now that all
918
958
  # views and main-view annotations are placed (so the detail avoids them).
919
959
  _queue_authored_details(dwg, a, ctx, _compiled)
920
- _resolve_details(dwg, a, ctx=ctx)
960
+ _resolve_details(dwg, a, ctx=ctx, identifiers=_derived_identifiers)
921
961
 
922
962
  def _s_title_block():
923
963
  _add_title_block(dwg, a)
@@ -53,8 +53,7 @@ from draftwright.annotations._common import carve_free_segments, strip_obstacles
53
53
  from draftwright.annotations.leaders import feature_leader_fixed_conflicts
54
54
  from draftwright.model import plan_sections
55
55
  from draftwright.projection import project_view_geometry
56
-
57
- _DETAIL_LETTERS = "ABCDEFGH"
56
+ from draftwright.view_plan import DERIVED_VIEW_IDENTIFIERS, DerivedViewIdentifierPool
58
57
 
59
58
 
60
59
  def _section_identity(section) -> tuple[str, str, str]:
@@ -134,6 +133,8 @@ def add_section(dwg, model, a, *, ctx) -> list[str]:
134
133
  plan = plan_sections(model, feature_hole_keys(model, a))
135
134
  if plan is None:
136
135
  return [] # no qualifying internal detail — no section warranted
136
+ if _has_rendered_section(dwg, plan):
137
+ return []
137
138
  before = set(dwg.annotations())
138
139
  _add_section_view(
139
140
  dwg, a, plan, ctx=ctx
@@ -141,6 +142,17 @@ def add_section(dwg, model, a, *, ctx) -> list[str]:
141
142
  return sorted(set(dwg.annotations()) - before)
142
143
 
143
144
 
145
+ def _has_rendered_section(dwg, section) -> bool:
146
+ """Whether this semantic cut plane already owns a rendered section view."""
147
+
148
+ cut_y = float(section.cut_y)
149
+ return any(
150
+ getattr(annotation, "_dw_section_cut_y", None) == cut_y
151
+ and getattr(annotation, "_dw_section_view", None) in dwg.views
152
+ for _name, annotation in dwg.iter_annotations()
153
+ )
154
+
155
+
144
156
  def _section_hatch_edges(face, SX, SZ, spacing):
145
157
  """Return 45° ISO 128-50 hatch Edge objects for one cut face in page coords.
146
158
 
@@ -260,7 +272,7 @@ def _cut_section(body, cutter):
260
272
  return shape, faces
261
273
 
262
274
 
263
- def _add_section_view(dwg, a: Analysis, section, *, ctx):
275
+ def _add_section_view(dwg, a: Analysis, section, *, ctx) -> bool:
264
276
  """Render the planned full section A–A (#94, #207).
265
277
 
266
278
  The *trigger* + cut-plane row are decided by the planner (`plan_sections` →
@@ -324,7 +336,7 @@ def _add_section_view(dwg, a: Analysis, section, *, ctx):
324
336
  f"{2 * half_w:.1f} mm section within x<={right_limit:.1f}",
325
337
  section=section,
326
338
  )
327
- return
339
+ return False
328
340
  # The section's row dips into the title-block band only when its CAPTION does —
329
341
  # the view itself can clear the block while the caption at `-half_h - 7` does not,
330
342
  # which is exactly why GRM-01 is refused on A4 (view bottom y 49.5, caption y 42.5,
@@ -347,7 +359,7 @@ def _add_section_view(dwg, a: Analysis, section, *, ctx):
347
359
  f"y={_TB_CLEAR + _TB_H:.1f} out to x={tb_left:.1f}",
348
360
  section=section,
349
361
  )
350
- return
362
+ return False
351
363
  pos_x = usable[0][0] + half_w
352
364
 
353
365
  big = 4 * a.bbox_max
@@ -357,7 +369,7 @@ def _add_section_view(dwg, a: Analysis, section, *, ctx):
357
369
  solids = a.part.solids()
358
370
  if not solids:
359
371
  _skip_section(dwg, ctx, "no_solids", "no solid bodies to cut", section=section)
360
- return
372
+ return False
361
373
  body = solids[0] if len(solids) == 1 else Compound(children=list(solids))
362
374
  try:
363
375
  # Fuzzy boolean: the exact `body - Box(...)` aborts uncatchably
@@ -365,16 +377,16 @@ def _add_section_view(dwg, a: Analysis, section, *, ctx):
365
377
  cut = _cut_section(body, Pos(a.cx, y_star - big / 2, a.cz) * Box(big, big, big))
366
378
  except Exception as exc: # noqa: BLE001 — OCC booleans raise broadly
367
379
  _skip_section(dwg, ctx, "cut_failed", f"cut failed: {exc}", section=section)
368
- return
380
+ return False
369
381
  if cut is None:
370
382
  _skip_section(dwg, ctx, "cut_empty", "boolean cut produced no solid", section=section)
371
- return
383
+ return False
372
384
  keep_behind, cut_faces = cut
373
385
  if not cut_faces:
374
386
  _skip_section(
375
387
  dwg, ctx, "cut_no_intersection", "cut plane creates no section faces", section=section
376
388
  )
377
- return
389
+ return False
378
390
  # Resolve the final cutting-plane ink before committing the section view.
379
391
  # Optional section furniture yields if a required landed feature leader
380
392
  # consumed the conservative provisional row.
@@ -434,7 +446,7 @@ def _add_section_view(dwg, a: Analysis, section, *, ctx):
434
446
  + ", ".join(f"{leader}/{component}" for leader, component in conflicts),
435
447
  section=section,
436
448
  )
437
- return
449
+ return False
438
450
 
439
451
  camera = (dwg.look_at[0], dwg.look_at[1] - dwg.dist, dwg.look_at[2])
440
452
  dwg._add_view(view_name, keep_behind, camera, (0, 0, 1), (pos_x, a.FV_Y))
@@ -462,13 +474,17 @@ def _add_section_view(dwg, a: Analysis, section, *, ctx):
462
474
  hatch = Compound(children=hatch_edges)
463
475
  hatch.is_section_hatch = True # exempt from view_annotation_overlap lint
464
476
  ctx.place(hatch, f"{prefix}_hatch")
477
+ return True
465
478
 
466
479
 
467
480
  def _place_cutting_plane(dwg, y_page, x0, x1, *, section, ctx):
468
481
  """Place one complete, unmeasured cutting-plane furniture candidate."""
469
482
 
470
- _label, _view, prefix = _section_identity(section)
471
- ctx.place(Centerline((x0, y_page, 0), (x1, y_page, 0)), f"{prefix}_line")
483
+ _label, view_name, prefix = _section_identity(section)
484
+ line = Centerline((x0, y_page, 0), (x1, y_page, 0))
485
+ line._dw_section_cut_y = float(section.cut_y)
486
+ line._dw_section_view = view_name
487
+ ctx.place(line, f"{prefix}_line")
472
488
  _add_cutting_plane_arrows(dwg, y_page, x0, x1, section=section, ctx=ctx)
473
489
  _add_section_letters(dwg, y_page, x0, x1, section=section, ctx=ctx)
474
490
 
@@ -893,7 +909,7 @@ def _render_detail(
893
909
  return True
894
910
 
895
911
 
896
- def _resolve_details(dwg, a: Analysis, *, ctx) -> None:
912
+ def _resolve_details(dwg, a: Analysis, *, ctx, identifiers=None) -> None:
897
913
  """Resolve every queued :class:`DetailRequest` (#307) through the one generic
898
914
  detailer, lettering DETAIL A/B/… On a placement bail-out nothing is drawn for that
899
915
  request — the main view already carries the located head/block inline, so lint
@@ -901,10 +917,11 @@ def _resolve_details(dwg, a: Analysis, *, ctx) -> None:
901
917
  the queue."""
902
918
  reqs = list(ctx.detail_requests)
903
919
  ctx.detail_requests = []
904
- reserved = {req.label for req in reqs if req.label is not None}
905
- if len(reserved) != sum(req.label is not None for req in reqs):
906
- raise ValueError("authored detail labels must be unique")
907
- used: set[str] = set()
920
+ if identifiers is None:
921
+ identifiers = DerivedViewIdentifierPool(
922
+ (req.label for req in reqs if req.label is not None),
923
+ candidates=DERIVED_VIEW_IDENTIFIERS,
924
+ )
908
925
 
909
926
  def _record_prismatic_failure(req, message):
910
927
  if req.kind != "prismatic-steps":
@@ -918,14 +935,13 @@ def _resolve_details(dwg, a: Analysis, *, ctx) -> None:
918
935
  )
919
936
 
920
937
  for req in reqs:
921
- letter = req.label or next(
922
- (candidate for candidate in _DETAIL_LETTERS if candidate not in reserved | used), None
923
- )
938
+ automatic_identifier = req.label is None
939
+ letter = req.label or identifiers.allocate()
924
940
  if letter is None:
925
- _log.info("detail request '%s' dropped: detail letters A–H exhausted", req.kind)
941
+ _log.info("detail request '%s' dropped: derived-view identifiers exhausted", req.kind)
926
942
  _record_prismatic_failure(
927
943
  req,
928
- f"{req.kind} detail view requested but detail letters A–H are exhausted",
944
+ f"{req.kind} detail view requested but derived-view identifiers are exhausted",
929
945
  )
930
946
  continue
931
947
  view_name = req.view_name or f"detail_{letter.lower()}"
@@ -959,14 +975,12 @@ def _resolve_details(dwg, a: Analysis, *, ctx) -> None:
959
975
  # behind when it was added (Codex r2).
960
976
  ctx.place(hobj, hname)
961
977
  dwg.registry.reapply(hname, ident)
962
- if placed:
963
- used.add(letter)
964
- elif req.keep_without_annotations or req.view_name is not None:
978
+ if not placed and (req.keep_without_annotations or req.view_name is not None):
965
979
  raise ValueError(
966
980
  f"authored detail {letter!r} from {req.source} is infeasible on this sheet; "
967
981
  "its target, scale, or whole-view footprint was not relaxed"
968
982
  )
969
- elif req.kind == "prismatic-steps":
983
+ elif not placed and req.kind == "prismatic-steps":
970
984
  # (#630) The prismatic-steps request is queued when detail recovery is enabled
971
985
  # (_request_prismatic_detail's gate), so a bail-out here means the requested
972
986
  # recovery produced nothing. Say so — with an
@@ -990,6 +1004,8 @@ def _resolve_details(dwg, a: Analysis, *, ctx) -> None:
990
1004
  "sheet (the crowded band is too wide to enlarge and still fit); dimension "
991
1005
  "the feature manually or move it onto its own sheet",
992
1006
  )
1007
+ if not placed and automatic_identifier:
1008
+ identifiers.release(letter)
993
1009
 
994
1010
 
995
1011
  def _overall_height_name(dwg, a: Analysis) -> str | None:
@@ -12,6 +12,7 @@ from __future__ import annotations
12
12
 
13
13
  import collections
14
14
  import json
15
+ import math
15
16
  import os
16
17
  import warnings
17
18
  from collections.abc import Callable, Iterable, Sequence
@@ -2145,6 +2146,7 @@ def build_drawing(
2145
2146
  margin_bottom: float | None = None,
2146
2147
  title_block_width: float | None = None,
2147
2148
  leader_region: Literal["auto", "interior", "exterior"] = "auto",
2149
+ _replayed_scale: float | None = None,
2148
2150
  ) -> Drawing:
2149
2151
  """Build a drawing, protecting required annotations under an explicit scale.
2150
2152
 
@@ -2177,6 +2179,16 @@ def build_drawing(
2177
2179
  validate_projection(projection, projection_symbol=projection_symbol)
2178
2180
  _dimension_draft(text_position, text_orientation)
2179
2181
  leader_region = leader_region_policy(leader_region).value
2182
+ if _replayed_scale is not None:
2183
+ _replayed_scale = float(_replayed_scale)
2184
+ if not math.isfinite(_replayed_scale) or _replayed_scale <= 0:
2185
+ raise ValueError(
2186
+ f"_replayed_scale must be finite and positive, got {_replayed_scale!r}"
2187
+ )
2188
+ if scale is not None:
2189
+ raise ValueError("_replayed_scale cannot be combined with authored scale=")
2190
+ if page is None:
2191
+ raise ValueError("_replayed_scale requires the settled page")
2180
2192
  if scale_policy not in {"strict", "fallback", "permissive"}:
2181
2193
  raise ValueError(
2182
2194
  f"scale_policy must be 'strict', 'fallback', or 'permissive', got {scale_policy!r}"
@@ -2981,6 +2993,39 @@ def build_drawing(
2981
2993
  drawing = larger
2982
2994
  settled_issues = issues
2983
2995
  replanned = True
2996
+ if _replayed_scale is not None and abs(drawing.scale - _replayed_scale) > 1e-12:
2997
+ # Let the declared model take the complete automatic recovery path first. Most
2998
+ # replays (including detail-bearing step drawings) naturally recover the recorded
2999
+ # scale and must retain that measured history unchanged. Only a final scale drift
3000
+ # pays for one bounded rebuild under the already settled topology/arrangement.
3001
+ replayed = _build(
3002
+ _replayed_scale,
3003
+ arrangements=(settled_arrangement,),
3004
+ views=_principal_names(drawing),
3005
+ include_iso="iso" in drawing.views,
3006
+ retry_reason="replay_settled_scale",
3007
+ )
3008
+ replay_issues, replay_blockers, rejection = _qualify_candidate(
3009
+ replayed,
3010
+ require_axial_coverage=False,
3011
+ allow_recovery_detail=True,
3012
+ )
3013
+ if rejection is not None:
3014
+ raise ValueError(
3015
+ f"settled scale replay {_replayed_scale!r} is no longer valid: {rejection}; "
3016
+ f"issues={[(issue.code, issue.severity) for issue in replay_issues]}"
3017
+ )
3018
+ _record_attempt(
3019
+ replayed.scale,
3020
+ "complete",
3021
+ replay_blockers,
3022
+ reason="replay_settled_scale",
3023
+ candidate=replayed,
3024
+ )
3025
+ drawing = replayed
3026
+ settled_issues = replay_issues
3027
+ replanned = True
3028
+
2984
3029
  # The default record, set BEFORE the completeness pass so that pass can replace it.
2985
3030
  # It used to be assigned afterwards and silently overwrote whatever the pass had
2986
3031
  # decided, so an incomplete plan reported itself as an ordinary automatic one.