gea-program 0.63.0__tar.gz → 0.64.0__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 (373) hide show
  1. {gea_program-0.63.0/gea_program.egg-info → gea_program-0.64.0}/PKG-INFO +5 -1
  2. {gea_program-0.63.0 → gea_program-0.64.0}/README.md +4 -0
  3. {gea_program-0.63.0 → gea_program-0.64.0}/gea/__init__.py +1 -1
  4. {gea_program-0.63.0 → gea_program-0.64.0}/gea/__main__.py +1 -1
  5. {gea_program-0.63.0 → gea_program-0.64.0}/gea/acceptance_tests.py +191 -6
  6. {gea_program-0.63.0 → gea_program-0.64.0}/gea/casing_design.py +339 -63
  7. {gea_program-0.63.0 → gea_program-0.64.0}/gea/declarations.py +65 -51
  8. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/casing.md +3 -1
  9. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/declare.md +1 -1
  10. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/hydraulics.md +1 -1
  11. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/rig-time.md +2 -2
  12. {gea_program-0.63.0 → gea_program-0.64.0}/gea/hydraulics.py +28 -4
  13. {gea_program-0.63.0 → gea_program-0.64.0}/gea/rig_state.py +12 -32
  14. {gea_program-0.63.0 → gea_program-0.64.0}/gea/web/app.html +13 -8
  15. {gea_program-0.63.0 → gea_program-0.64.0/gea_program.egg-info}/PKG-INFO +5 -1
  16. {gea_program-0.63.0 → gea_program-0.64.0}/pyproject.toml +1 -1
  17. {gea_program-0.63.0 → gea_program-0.64.0}/LICENSE +0 -0
  18. {gea_program-0.63.0 → gea_program-0.64.0}/gea/BENCH_TEST_PROTOCOL.md +0 -0
  19. {gea_program-0.63.0 → gea_program-0.64.0}/gea/accuracy_statement.py +0 -0
  20. {gea_program-0.63.0 → gea_program-0.64.0}/gea/alarm_engine.py +0 -0
  21. {gea_program-0.63.0 → gea_program-0.64.0}/gea/alerts.py +0 -0
  22. {gea_program-0.63.0 → gea_program-0.64.0}/gea/backup.py +0 -0
  23. {gea_program-0.63.0 → gea_program-0.64.0}/gea/bench.py +0 -0
  24. {gea_program-0.63.0 → gea_program-0.64.0}/gea/blind_harness.py +0 -0
  25. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/acex_lomonosov_age_depth_model.provenance.json +0 -0
  26. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/acex_lomonosov_age_depth_model.txt +0 -0
  27. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/agassiz77_canada_temperature.csv +0 -0
  28. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/agassiz77_canada_temperature.provenance.json +0 -0
  29. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/barbados_110_consolidation.provenance.json +0 -0
  30. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/barbados_110_consolidation.txt +0 -0
  31. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/bengal_u1452_grain_size.provenance.json +0 -0
  32. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/bengal_u1452_grain_size.txt +0 -0
  33. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/blake_164_methane_isotopes.provenance.json +0 -0
  34. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/blake_164_methane_isotopes.txt +0 -0
  35. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.provenance.json +0 -0
  36. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/chicxulub_m0077a_pwave_velocity.txt +0 -0
  37. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/collingwood_1_28_ks_complete.las +0 -0
  38. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/collingwood_1_28_ks_complete.provenance.json +0 -0
  39. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/costa_rica_odp_friction_envelope.provenance.json +0 -0
  40. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/costa_rica_odp_friction_envelope.txt +0 -0
  41. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.provenance.json +0 -0
  42. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/dead_sea_5017_debrite_xrf_ms.txt +0 -0
  43. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/dsdp_504b_physical_properties.provenance.json +0 -0
  44. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/dsdp_504b_physical_properties.txt +0 -0
  45. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/dsdp_504b_sound_velocity.provenance.json +0 -0
  46. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/dsdp_504b_sound_velocity.txt +0 -0
  47. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/elgygytgyn_5011_turbidites.provenance.json +0 -0
  48. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/elgygytgyn_5011_turbidites.txt +0 -0
  49. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/epica_domec_co2_800kyr.provenance.json +0 -0
  50. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/epica_domec_co2_800kyr.txt +0 -0
  51. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/fram_909_organic_petrography.provenance.json +0 -0
  52. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/fram_909_organic_petrography.txt +0 -0
  53. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/gbr_325_coral_uth_ages.provenance.json +0 -0
  54. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/gbr_325_coral_uth_ages.txt +0 -0
  55. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/gisp2_greenland_temperature.csv +0 -0
  56. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/gisp2_greenland_temperature.provenance.json +0 -0
  57. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/gom_308_t2p_insitu.provenance.json +0 -0
  58. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/gom_308_t2p_insitu.txt +0 -0
  59. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/guaymas_385_dom_d13c.provenance.json +0 -0
  60. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/guaymas_385_dom_d13c.txt +0 -0
  61. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/hikurangi_u1520_friction_insitu.provenance.json +0 -0
  62. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/hikurangi_u1520_friction_insitu.txt +0 -0
  63. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.provenance.json +0 -0
  64. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/hydrate_ridge_204_ncr_hydrate.txt +0 -0
  65. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/iodp_u1324_pore_pressure.provenance.json +0 -0
  66. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/iodp_u1324_pore_pressure.txt +0 -0
  67. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/jfast_c0019_slow_slip_events.provenance.json +0 -0
  68. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/jfast_c0019_slow_slip_events.txt +0 -0
  69. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/kennetcook_2_p129_excerpt.las +0 -0
  70. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/kennetcook_2_p129_excerpt.provenance.json +0 -0
  71. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/ktb_hb_bhgm_density.dat +0 -0
  72. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/ktb_hb_bhgm_density.provenance.json +0 -0
  73. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/ktb_hb_complog_6020_excerpt.provenance.json +0 -0
  74. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/ktb_hb_complog_6020_excerpt.txt +0 -0
  75. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/ktb_hb_hlog246_temperature.dat +0 -0
  76. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/ktb_hb_hlog246_temperature.provenance.json +0 -0
  77. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/ktb_hb_rockmech_compress.dat +0 -0
  78. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/ktb_hb_rockmech_compress.provenance.json +0 -0
  79. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.dat +0 -0
  80. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/ktb_hb_tvd_0_9080_excerpt.provenance.json +0 -0
  81. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/ktb_vb_rockmech_compress.dat +0 -0
  82. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/ktb_vb_rockmech_compress.provenance.json +0 -0
  83. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/ktb_vb_vlog251_temperature.dat +0 -0
  84. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/ktb_vb_vlog251_temperature.provenance.json +0 -0
  85. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/l06_06_nl_survey.csv +0 -0
  86. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/l06_06_nl_survey.provenance.json +0 -0
  87. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/l07_01_nl_excerpt.las +0 -0
  88. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/l07_01_nl_excerpt.provenance.json +0 -0
  89. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/mariana_1200_serpentinite_geochem.provenance.json +0 -0
  90. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/mariana_1200_serpentinite_geochem.txt +0 -0
  91. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/med_160_sapropels.provenance.json +0 -0
  92. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/med_160_sapropels.txt +0 -0
  93. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/nankai_megasplay_shear_strength.provenance.json +0 -0
  94. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/nankai_megasplay_shear_strength.txt +0 -0
  95. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/odp_1027b_thermal_conductivity.provenance.json +0 -0
  96. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/odp_1027b_thermal_conductivity.txt +0 -0
  97. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/odp_1027c_cork_temperature.provenance.json +0 -0
  98. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/odp_1027c_cork_temperature.txt +0 -0
  99. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/odp_1165b_thermal_conductivity.provenance.json +0 -0
  100. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/odp_1165b_thermal_conductivity.txt +0 -0
  101. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.provenance.json +0 -0
  102. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/odp_1274a_mantle_peridotite_mad.txt +0 -0
  103. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/odp_504b_dike_elastic_moduli.provenance.json +0 -0
  104. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/odp_504b_dike_elastic_moduli.txt +0 -0
  105. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/odp_504b_leg137_borehole_fluids.provenance.json +0 -0
  106. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/odp_504b_leg137_borehole_fluids.txt +0 -0
  107. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.provenance.json +0 -0
  108. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/odp_735b_gabbro_elastic_moduli.txt +0 -0
  109. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/peru_201_sulfate_reduction.provenance.json +0 -0
  110. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/peru_201_sulfate_reduction.txt +0 -0
  111. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/scorpio_e1_sa_excerpt.las +0 -0
  112. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/scorpio_e1_sa_excerpt.provenance.json +0 -0
  113. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/sumatra_362_cohesion.provenance.json +0 -0
  114. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/sumatra_362_cohesion.txt +0 -0
  115. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/university_6_17_no1_tx_excerpt.las +0 -0
  116. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/university_6_17_no1_tx_excerpt.provenance.json +0 -0
  117. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/ursa_308_xrd_mineralogy.provenance.json +0 -0
  118. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/ursa_308_xrd_mineralogy.txt +0 -0
  119. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/volve_15_9_19_sr_excerpt.las +0 -0
  120. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/volve_15_9_19_sr_excerpt.provenance.json +0 -0
  121. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/volve_15_9_19a_core_excerpt.csv +0 -0
  122. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/volve_15_9_19a_core_excerpt.provenance.json +0 -0
  123. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/volve_f12_f14_production_excerpt.csv +0 -0
  124. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/volve_f12_f14_production_excerpt.provenance.json +0 -0
  125. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/walvis_208_petm_carbonate.provenance.json +0 -0
  126. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/walvis_208_petm_carbonate.txt +0 -0
  127. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/woodlark_1109_rock_eval.provenance.json +0 -0
  128. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog/woodlark_1109_rock_eval.txt +0 -0
  129. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog_map.py +0 -0
  130. {gea_program-0.63.0 → gea_program-0.64.0}/gea/catalog_register.py +0 -0
  131. {gea_program-0.63.0 → gea_program-0.64.0}/gea/certificates.py +0 -0
  132. {gea_program-0.63.0 → gea_program-0.64.0}/gea/cli.py +0 -0
  133. {gea_program-0.63.0 → gea_program-0.64.0}/gea/client_reports.py +0 -0
  134. {gea_program-0.63.0 → gea_program-0.64.0}/gea/collision.py +0 -0
  135. {gea_program-0.63.0 → gea_program-0.64.0}/gea/config_versioning.py +0 -0
  136. {gea_program-0.63.0 → gea_program-0.64.0}/gea/conformance.py +0 -0
  137. {gea_program-0.63.0 → gea_program-0.64.0}/gea/control_room.py +0 -0
  138. {gea_program-0.63.0 → gea_program-0.64.0}/gea/correlation.py +0 -0
  139. {gea_program-0.63.0 → gea_program-0.64.0}/gea/dashboard.py +0 -0
  140. {gea_program-0.63.0 → gea_program-0.64.0}/gea/decline.py +0 -0
  141. {gea_program-0.63.0 → gea_program-0.64.0}/gea/deviation.py +0 -0
  142. {gea_program-0.63.0 → gea_program-0.64.0}/gea/dlis.py +0 -0
  143. {gea_program-0.63.0 → gea_program-0.64.0}/gea/dnp3.py +0 -0
  144. {gea_program-0.63.0 → gea_program-0.64.0}/gea/doctor.py +0 -0
  145. {gea_program-0.63.0 → gea_program-0.64.0}/gea/dossier.py +0 -0
  146. {gea_program-0.63.0 → gea_program-0.64.0}/gea/dossier_verify.py +0 -0
  147. {gea_program-0.63.0 → gea_program-0.64.0}/gea/downhole_engine.py +0 -0
  148. {gea_program-0.63.0 → gea_program-0.64.0}/gea/drift_monitor.py +0 -0
  149. {gea_program-0.63.0 → gea_program-0.64.0}/gea/drill_string.py +0 -0
  150. {gea_program-0.63.0 → gea_program-0.64.0}/gea/earth_model.py +0 -0
  151. {gea_program-0.63.0 → gea_program-0.64.0}/gea/economics.py +0 -0
  152. {gea_program-0.63.0 → gea_program-0.64.0}/gea/ed25519.py +0 -0
  153. {gea_program-0.63.0 → gea_program-0.64.0}/gea/edr.py +0 -0
  154. {gea_program-0.63.0 → gea_program-0.64.0}/gea/elevation.py +0 -0
  155. {gea_program-0.63.0 → gea_program-0.64.0}/gea/etp.py +0 -0
  156. {gea_program-0.63.0 → gea_program-0.64.0}/gea/etp12_schemas.json +0 -0
  157. {gea_program-0.63.0 → gea_program-0.64.0}/gea/example_register_map.json +0 -0
  158. {gea_program-0.63.0 → gea_program-0.64.0}/gea/fat_sat.py +0 -0
  159. {gea_program-0.63.0 → gea_program-0.64.0}/gea/files.py +0 -0
  160. {gea_program-0.63.0 → gea_program-0.64.0}/gea/fixtures/README.md +0 -0
  161. {gea_program-0.63.0 → gea_program-0.64.0}/gea/fixtures/comcat_delaware_basin_2026-09.txt +0 -0
  162. {gea_program-0.63.0 → gea_program-0.64.0}/gea/fixtures/comcat_mahoning_1990-2026.txt +0 -0
  163. {gea_program-0.63.0 → gea_program-0.64.0}/gea/fixtures/comcat_youngstown_2011-2012.txt +0 -0
  164. {gea_program-0.63.0 → gea_program-0.64.0}/gea/fixtures/ne_110m_coastline.json +0 -0
  165. {gea_program-0.63.0 → gea_program-0.64.0}/gea/follower.py +0 -0
  166. {gea_program-0.63.0 → gea_program-0.64.0}/gea/forward_model.py +0 -0
  167. {gea_program-0.63.0 → gea_program-0.64.0}/gea/frac_hits.py +0 -0
  168. {gea_program-0.63.0 → gea_program-0.64.0}/gea/friction_priors.py +0 -0
  169. {gea_program-0.63.0 → gea_program-0.64.0}/gea/gamma.py +0 -0
  170. {gea_program-0.63.0 → gea_program-0.64.0}/gea/gauge_aging.py +0 -0
  171. {gea_program-0.63.0 → gea_program-0.64.0}/gea/gauge_specs.py +0 -0
  172. {gea_program-0.63.0 → gea_program-0.64.0}/gea/geodesy.py +0 -0
  173. {gea_program-0.63.0 → gea_program-0.64.0}/gea/geomag.py +0 -0
  174. {gea_program-0.63.0 → gea_program-0.64.0}/gea/gravity_reference.py +0 -0
  175. {gea_program-0.63.0 → gea_program-0.64.0}/gea/hartip.py +0 -0
  176. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/IT_SECURITY.md +0 -0
  177. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/TESTER_GUIDE.md +0 -0
  178. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/alarms.md +0 -0
  179. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/alerts.md +0 -0
  180. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/audit-update.md +0 -0
  181. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/backup.md +0 -0
  182. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/catalog.md +0 -0
  183. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/charts.md +0 -0
  184. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/collision.md +0 -0
  185. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/company-sign-in.md +0 -0
  186. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/conformance.md +0 -0
  187. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/control-room.md +0 -0
  188. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/data-in.md +0 -0
  189. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/decline.md +0 -0
  190. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/dlis.md +0 -0
  191. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/doctor.md +0 -0
  192. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/dossier.md +0 -0
  193. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/drift.md +0 -0
  194. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/drillstring.md +0 -0
  195. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/economics.md +0 -0
  196. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/edr.md +0 -0
  197. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/etp.md +0 -0
  198. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/field-ports.md +0 -0
  199. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/files.md +0 -0
  200. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/frac-hits.md +0 -0
  201. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/historian.md +0 -0
  202. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/https.md +0 -0
  203. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/instruments.md +0 -0
  204. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/interval.md +0 -0
  205. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/invoice-check.md +0 -0
  206. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/map.md +0 -0
  207. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/month-end.md +0 -0
  208. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/notifications.md +0 -0
  209. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/opseis.md +0 -0
  210. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/osdu.md +0 -0
  211. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/pad-summary.md +0 -0
  212. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/patches.md +0 -0
  213. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/penetrator.md +0 -0
  214. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/plan.md +0 -0
  215. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/pore-pressure.md +0 -0
  216. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/ppdm.md +0 -0
  217. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/quakeml.md +0 -0
  218. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/quality.md +0 -0
  219. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/report-history.md +0 -0
  220. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/seedlink.md +0 -0
  221. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/seismic.md +0 -0
  222. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/setup.md +0 -0
  223. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/simulation.md +0 -0
  224. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/site.md +0 -0
  225. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/sites.md +0 -0
  226. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/slip.md +0 -0
  227. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/soak.md +0 -0
  228. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/sra.md +0 -0
  229. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/start.md +0 -0
  230. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/structure.md +0 -0
  231. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/tools.md +0 -0
  232. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/torque-drag.md +0 -0
  233. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/transients.md +0 -0
  234. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/upkeep.md +0 -0
  235. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/vibration.md +0 -0
  236. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/well-report.md +0 -0
  237. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/well-tests.md +0 -0
  238. {gea_program-0.63.0 → gea_program-0.64.0}/gea/help/well3d.md +0 -0
  239. {gea_program-0.63.0 → gea_program-0.64.0}/gea/helplib.py +0 -0
  240. {gea_program-0.63.0 → gea_program-0.64.0}/gea/housekeeping.py +0 -0
  241. {gea_program-0.63.0 → gea_program-0.64.0}/gea/interval.py +0 -0
  242. {gea_program-0.63.0 → gea_program-0.64.0}/gea/inverse_engine.py +0 -0
  243. {gea_program-0.63.0 → gea_program-0.64.0}/gea/invoice_check.py +0 -0
  244. {gea_program-0.63.0 → gea_program-0.64.0}/gea/jobs.py +0 -0
  245. {gea_program-0.63.0 → gea_program-0.64.0}/gea/live_ports.py +0 -0
  246. {gea_program-0.63.0 → gea_program-0.64.0}/gea/loadtest.py +0 -0
  247. {gea_program-0.63.0 → gea_program-0.64.0}/gea/matplotlib_demo.py +0 -0
  248. {gea_program-0.63.0 → gea_program-0.64.0}/gea/modbus.py +0 -0
  249. {gea_program-0.63.0 → gea_program-0.64.0}/gea/modbus_rtu.py +0 -0
  250. {gea_program-0.63.0 → gea_program-0.64.0}/gea/model_card.py +0 -0
  251. {gea_program-0.63.0 → gea_program-0.64.0}/gea/month_end.py +0 -0
  252. {gea_program-0.63.0 → gea_program-0.64.0}/gea/mqtt_port.py +0 -0
  253. {gea_program-0.63.0 → gea_program-0.64.0}/gea/notify.py +0 -0
  254. {gea_program-0.63.0 → gea_program-0.64.0}/gea/oidc.py +0 -0
  255. {gea_program-0.63.0 → gea_program-0.64.0}/gea/oidc_mock.py +0 -0
  256. {gea_program-0.63.0 → gea_program-0.64.0}/gea/op_seismicity.py +0 -0
  257. {gea_program-0.63.0 → gea_program-0.64.0}/gea/opcua_port.py +0 -0
  258. {gea_program-0.63.0 → gea_program-0.64.0}/gea/operator_app.py +0 -0
  259. {gea_program-0.63.0 → gea_program-0.64.0}/gea/osdu.py +0 -0
  260. {gea_program-0.63.0 → gea_program-0.64.0}/gea/pad_summary.py +0 -0
  261. {gea_program-0.63.0 → gea_program-0.64.0}/gea/patches.py +0 -0
  262. {gea_program-0.63.0 → gea_program-0.64.0}/gea/pdf_report.py +0 -0
  263. {gea_program-0.63.0 → gea_program-0.64.0}/gea/penetrator.py +0 -0
  264. {gea_program-0.63.0 → gea_program-0.64.0}/gea/permits.py +0 -0
  265. {gea_program-0.63.0 → gea_program-0.64.0}/gea/piwebapi.py +0 -0
  266. {gea_program-0.63.0 → gea_program-0.64.0}/gea/pore_pressure.py +0 -0
  267. {gea_program-0.63.0 → gea_program-0.64.0}/gea/ports.py +0 -0
  268. {gea_program-0.63.0 → gea_program-0.64.0}/gea/ppdm.py +0 -0
  269. {gea_program-0.63.0 → gea_program-0.64.0}/gea/profile_catalog.py +0 -0
  270. {gea_program-0.63.0 → gea_program-0.64.0}/gea/project.py +0 -0
  271. {gea_program-0.63.0 → gea_program-0.64.0}/gea/qt6_downhole_app.py +0 -0
  272. {gea_program-0.63.0 → gea_program-0.64.0}/gea/quakeml.py +0 -0
  273. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reconciler.py +0 -0
  274. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/IU_ANMO_10_BHZ_response.provenance.json +0 -0
  275. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/IU_ANMO_10_BHZ_response.xml +0 -0
  276. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/WMM2025.COF +0 -0
  277. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/eia_henry_hub_daily.csv.gz +0 -0
  278. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/eia_prices.provenance.json +0 -0
  279. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/eia_wti_daily.csv.gz +0 -0
  280. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/iscwsa_rev4_example.json +0 -0
  281. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/iscwsa_rev5_example.json +0 -0
  282. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/l0701_sonic_gr.las.gz +0 -0
  283. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/l0701_sonic_gr.provenance.json +0 -0
  284. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/libmseed_steim.provenance.json +0 -0
  285. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/libmseed_steim1_4096.mseed +0 -0
  286. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/libmseed_steim2_4096.mseed +0 -0
  287. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/libmseed_steim2_512.mseed +0 -0
  288. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/mahoning_example.json +0 -0
  289. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/mud_motor_specs.json +0 -0
  290. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/owsg_tool_models.json +0 -0
  291. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/penetrator_ratings.json +0 -0
  292. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/seismicity_protocols.json +0 -0
  293. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/tool_sources.json +0 -0
  294. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/us_outline.json +0 -0
  295. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/us_outline.provenance.json +0 -0
  296. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/volve_3d.provenance.json +0 -0
  297. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/volve_f4_interpretation.las.gz +0 -0
  298. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/volve_f4_logs.provenance.json +0 -0
  299. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/volve_f4_lwd.las.gz +0 -0
  300. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/volve_surfaces.json.gz +0 -0
  301. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/volve_traj_F-10.xml.gz +0 -0
  302. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/volve_traj_F-4.xml.gz +0 -0
  303. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/volve_traj_F-5_12.25in.xml.gz +0 -0
  304. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/volve_traj_F-5_17.5in.xml.gz +0 -0
  305. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/volve_traj_F-5_36in.xml.gz +0 -0
  306. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/volve_traj_F-5_8.5in.xml.gz +0 -0
  307. {gea_program-0.63.0 → gea_program-0.64.0}/gea/reference/volve_well_picks.csv.gz +0 -0
  308. {gea_program-0.63.0 → gea_program-0.64.0}/gea/report_history.py +0 -0
  309. {gea_program-0.63.0 → gea_program-0.64.0}/gea/rock_inventory.py +0 -0
  310. {gea_program-0.63.0 → gea_program-0.64.0}/gea/sample_record.py +0 -0
  311. {gea_program-0.63.0 → gea_program-0.64.0}/gea/sample_well_profile.csv +0 -0
  312. {gea_program-0.63.0 → gea_program-0.64.0}/gea/sbom.py +0 -0
  313. {gea_program-0.63.0 → gea_program-0.64.0}/gea/seedlink.py +0 -0
  314. {gea_program-0.63.0 → gea_program-0.64.0}/gea/segy.py +0 -0
  315. {gea_program-0.63.0 → gea_program-0.64.0}/gea/seismic.py +0 -0
  316. {gea_program-0.63.0 → gea_program-0.64.0}/gea/seismic_array.py +0 -0
  317. {gea_program-0.63.0 → gea_program-0.64.0}/gea/seismic_assoc.py +0 -0
  318. {gea_program-0.63.0 → gea_program-0.64.0}/gea/seismic_detect.py +0 -0
  319. {gea_program-0.63.0 → gea_program-0.64.0}/gea/seismic_film.py +0 -0
  320. {gea_program-0.63.0 → gea_program-0.64.0}/gea/seismic_harmonic.py +0 -0
  321. {gea_program-0.63.0 → gea_program-0.64.0}/gea/seismic_qc.py +0 -0
  322. {gea_program-0.63.0 → gea_program-0.64.0}/gea/seismic_response.py +0 -0
  323. {gea_program-0.63.0 → gea_program-0.64.0}/gea/seismic_signature.py +0 -0
  324. {gea_program-0.63.0 → gea_program-0.64.0}/gea/seismic_track.py +0 -0
  325. {gea_program-0.63.0 → gea_program-0.64.0}/gea/seismic_uncertainty.py +0 -0
  326. {gea_program-0.63.0 → gea_program-0.64.0}/gea/seismic_unlisted.py +0 -0
  327. {gea_program-0.63.0 → gea_program-0.64.0}/gea/seismic_watch.py +0 -0
  328. {gea_program-0.63.0 → gea_program-0.64.0}/gea/sensor_swap.py +0 -0
  329. {gea_program-0.63.0 → gea_program-0.64.0}/gea/series_cache.py +0 -0
  330. {gea_program-0.63.0 → gea_program-0.64.0}/gea/service.py +0 -0
  331. {gea_program-0.63.0 → gea_program-0.64.0}/gea/service_life.py +0 -0
  332. {gea_program-0.63.0 → gea_program-0.64.0}/gea/setup_checklist.py +0 -0
  333. {gea_program-0.63.0 → gea_program-0.64.0}/gea/shapefile.py +0 -0
  334. {gea_program-0.63.0 → gea_program-0.64.0}/gea/shell.py +0 -0
  335. {gea_program-0.63.0 → gea_program-0.64.0}/gea/shut_in.py +0 -0
  336. {gea_program-0.63.0 → gea_program-0.64.0}/gea/simulation.py +0 -0
  337. {gea_program-0.63.0 → gea_program-0.64.0}/gea/site_map.py +0 -0
  338. {gea_program-0.63.0 → gea_program-0.64.0}/gea/sla_report.py +0 -0
  339. {gea_program-0.63.0 → gea_program-0.64.0}/gea/slip.py +0 -0
  340. {gea_program-0.63.0 → gea_program-0.64.0}/gea/soak.py +0 -0
  341. {gea_program-0.63.0 → gea_program-0.64.0}/gea/sra.py +0 -0
  342. {gea_program-0.63.0 → gea_program-0.64.0}/gea/store_forward.py +0 -0
  343. {gea_program-0.63.0 → gea_program-0.64.0}/gea/strata_join.py +0 -0
  344. {gea_program-0.63.0 → gea_program-0.64.0}/gea/structure.py +0 -0
  345. {gea_program-0.63.0 → gea_program-0.64.0}/gea/supervisor.py +0 -0
  346. {gea_program-0.63.0 → gea_program-0.64.0}/gea/survey_cmd.py +0 -0
  347. {gea_program-0.63.0 → gea_program-0.64.0}/gea/survey_view.py +0 -0
  348. {gea_program-0.63.0 → gea_program-0.64.0}/gea/telemetry.py +0 -0
  349. {gea_program-0.63.0 → gea_program-0.64.0}/gea/timestamp.py +0 -0
  350. {gea_program-0.63.0 → gea_program-0.64.0}/gea/tls.py +0 -0
  351. {gea_program-0.63.0 → gea_program-0.64.0}/gea/tool_catalog.py +0 -0
  352. {gea_program-0.63.0 → gea_program-0.64.0}/gea/tool_library.py +0 -0
  353. {gea_program-0.63.0 → gea_program-0.64.0}/gea/tool_taxonomy.py +0 -0
  354. {gea_program-0.63.0 → gea_program-0.64.0}/gea/torque_drag.py +0 -0
  355. {gea_program-0.63.0 → gea_program-0.64.0}/gea/transient.py +0 -0
  356. {gea_program-0.63.0 → gea_program-0.64.0}/gea/vibration.py +0 -0
  357. {gea_program-0.63.0 → gea_program-0.64.0}/gea/well3d.py +0 -0
  358. {gea_program-0.63.0 → gea_program-0.64.0}/gea/well_assembler.py +0 -0
  359. {gea_program-0.63.0 → gea_program-0.64.0}/gea/well_report.py +0 -0
  360. {gea_program-0.63.0 → gea_program-0.64.0}/gea/well_test_validation.py +0 -0
  361. {gea_program-0.63.0 → gea_program-0.64.0}/gea/wellplan.py +0 -0
  362. {gea_program-0.63.0 → gea_program-0.64.0}/gea/wellpos.py +0 -0
  363. {gea_program-0.63.0 → gea_program-0.64.0}/gea/wits0.py +0 -0
  364. {gea_program-0.63.0 → gea_program-0.64.0}/gea/witsml.py +0 -0
  365. {gea_program-0.63.0 → gea_program-0.64.0}/gea/workspace.py +0 -0
  366. {gea_program-0.63.0 → gea_program-0.64.0}/gea/xlsx_read.py +0 -0
  367. {gea_program-0.63.0 → gea_program-0.64.0}/gea_program.egg-info/SOURCES.txt +0 -0
  368. {gea_program-0.63.0 → gea_program-0.64.0}/gea_program.egg-info/dependency_links.txt +0 -0
  369. {gea_program-0.63.0 → gea_program-0.64.0}/gea_program.egg-info/entry_points.txt +0 -0
  370. {gea_program-0.63.0 → gea_program-0.64.0}/gea_program.egg-info/requires.txt +0 -0
  371. {gea_program-0.63.0 → gea_program-0.64.0}/gea_program.egg-info/top_level.txt +0 -0
  372. {gea_program-0.63.0 → gea_program-0.64.0}/setup.cfg +0 -0
  373. {gea_program-0.63.0 → gea_program-0.64.0}/tests/test_acceptance.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gea-program
3
- Version: 0.63.0
3
+ Version: 0.64.0
4
4
  Summary: GEA-Program: downhole gauge monitoring - canonical measurement records, quality rules, drift evaluation with a re-fit change log, well-test validation, alarm management, model cards, store-and-forward, monthly SLA measurement, FAT/SAT protocols and a dashboard, generated from live objects in the client's reporting outline.
5
5
  Author: Daniel T. Murphy
6
6
  License: MPL-2.0
@@ -695,6 +695,10 @@ http://timestamp.digicert.com --timestamp on`; `gea help dossier`.
695
695
 
696
696
  ### Casing design and kick tolerance
697
697
 
698
+ A well's casing is declared once, as its casing program (the Casing &
699
+ kick tolerance tab, `gea casing`, or the declarations sheet's `[casing]`):
700
+ rig time, hydraulics and torque and drag read the same strings, and a
701
+ string needs only its size and shoe until it is to be checked.
698
702
  Each casing string's burst, collapse and tension ratings by API TR 5C3,
699
703
  from its size, weight and grade, against the loads the hole can put on it
700
704
  - gas to the surface held by the shoe, an emptied string, the buoyed
@@ -656,6 +656,10 @@ http://timestamp.digicert.com --timestamp on`; `gea help dossier`.
656
656
 
657
657
  ### Casing design and kick tolerance
658
658
 
659
+ A well's casing is declared once, as its casing program (the Casing &
660
+ kick tolerance tab, `gea casing`, or the declarations sheet's `[casing]`):
661
+ rig time, hydraulics and torque and drag read the same strings, and a
662
+ string needs only its size and shoe until it is to be checked.
659
663
  Each casing string's burst, collapse and tension ratings by API TR 5C3,
660
664
  from its size, weight and grade, against the loads the hole can put on it
661
665
  - gas to the surface held by the shoe, an emptied string, the buoyed
@@ -123,7 +123,7 @@ from .profile_catalog import (
123
123
  read_pangaea_txt,
124
124
  )
125
125
 
126
- __version__ = "0.63.0"
126
+ __version__ = "0.64.0"
127
127
  __all__ = [
128
128
  "aging_rate", "rate_psi_yr", "accuracy_psi",
129
129
  "Sensor", "SimulatorConfig", "DownholeEngine",
@@ -2972,7 +2972,7 @@ def main(argv=None) -> int:
2972
2972
  if not a.well:
2973
2973
  raise ValueError("--casing needs --well")
2974
2974
  c_ = _RS.set_casing(ws, a.actor, a.well, a.casing, a.shoe_md, a.source, a.set_time)
2975
- print(f"casing {c_['size']} in, shoe at {c_['shoe_md_ft']:,.0f} ft MD ({c_['source']})")
2975
+ print(f"casing {c_['size']} in, shoe at {c_['shoe_md_ft']:,.0f} ft MD ({c_['source']}) - in the well's casing program (gea casing)")
2976
2976
  return 0
2977
2977
  if a.w2w_min is not None or a.trip_in is not None or a.trip_out is not None or a.block_weight is not None:
2978
2978
  if a.block_weight is not None and not a.well:
@@ -10992,7 +10992,7 @@ def section_cq_tied_together(tmp: str) -> None:
10992
10992
  p_x = DC.plan(ws, XR.text_of((d / "decl.xlsx").read_bytes()))
10993
10993
  p_w = DC.apply(ws, sheet, "tester", write=True)
10994
10994
  p_rt = DC.plan(ws, DC.template(ws))
10995
- p_bad = DC.plan(ws, "[contract],operating,source\n,30000,\n[settings],setting,value\n,watch_mode,sometimes\n,colour,blue\n[casing],well,size_in,shoe_md_ft,source\n,RIG-1,9 5/8,100,x\n,NOPE,7,100,x\n")
10995
+ p_bad = DC.plan(ws, "[contract],operating,source\n,30000,\n[settings],setting,value\n,watch_mode,sometimes\n,colour,blue\n[casing],well,size_in,shoe_md_ft,source\n,RIG-1,nine,100,x\n,NOPE,7,100,x\n")
10996
10996
  pad = RS.pad(ws)
10997
10997
  W1 = next(w for w in pad["wells"] if w["display"] == "RIG-1")
10998
10998
  secs = [c["section"] for c in W1["connection_list"]]
@@ -11002,7 +11002,7 @@ def section_cq_tied_together(tmp: str) -> None:
11002
11002
  IC.attach(ws, "tester", wi["id"], "invoice", "inv.xlsx", (d / "inv.xlsx").read_bytes(), "invoice as a workbook")
11003
11003
  ic = IC.check(ws, wi["id"])
11004
11004
  c2 = {
11005
- "xlsx_sheet": p_x["counts"]["NEW"] == 6 and p_x["counts"]["CHANGE"] == 3 and not p_x["errors"],
11005
+ "xlsx_sheet": p_x["counts"]["NEW"] == 5 and p_x["counts"]["CHANGE"] == 3 and not p_x["errors"], # (v0.64) a well's casing rows are one step: its program
11006
11006
  "written": p_w["applied"] and IC.terms(ws)["rates_usd_per_day"] == {"operating": 30000.0, "standby": 25000.0, "repair": 0.0}
11007
11007
  and RS.settings(ws)["targets"] == {"trip_in_ft_h": 2800.0} and RS.settings(ws)["block_weight_klbf"] == {w2["id"]: 42.0}
11008
11008
  and [x["size"] for x in RS.casing(ws)[w1["id"]]] == ["13-3/8", "9-5/8"] and SW.settings(ws)["every_min"] == 10
@@ -11051,7 +11051,7 @@ def section_cq_tied_together(tmp: str) -> None:
11051
11051
  and [x["well"] for x in g["rig_time"]] == ["RIG-1", "RIG-2"] and all(x["connections"] == 3 and x["date"] == "2026-08-01" for x in g["rig_time"])
11052
11052
  and all(x["lost_usd"] is not None for x in g["rig_time"]),
11053
11053
  "dossier": v1["status"] == "VALID" and {"declarations/economics/invoices/terms.json", "declarations/economics/invoices/files.json",
11054
- "declarations/drillstring/rig_time.json", "declarations/drillstring/casing.json"} <= names
11054
+ "declarations/drillstring/rig_time.json", "declarations/drillstring/casing_design.json"} <= names
11055
11055
  and any(n.startswith(f"declarations/economics/invoices/{wi['id']}/") and n.endswith("_inv.xlsx") for n in names)
11056
11056
  and icj["status"] == "DIFFERS" and len(rt["wells"]) == 3 and rt["targets"]["trip_in_ft_h"]["value"] == 2800,
11057
11057
  }
@@ -11085,7 +11085,7 @@ def section_cq_tied_together(tmp: str) -> None:
11085
11085
  try:
11086
11086
  V, O = opener("v", "viewer-pass-1"), opener("op", "op-pass-123")
11087
11087
  s_vc, _ = call(V, "POST", "/api/rig-time/casing", {"well_id": w2["id"], "size": "7", "shoe_md_ft": 9000, "source": "x"})
11088
- s_oc, ocj = call(O, "POST", "/api/rig-time/casing", {"well_id": w2["id"], "size": "7", "shoe_md_ft": 9000, "source": "tally"})
11088
+ s_oc, ocj = call(O, "POST", "/api/rig-time/casing", {"well_id": w2["id"], "size": "7", "shoe_md_ft": 11000, "source": "tally"}) # below its 9-5/8 (v0.64 checks the nesting)
11089
11089
  s_ob, _ = call(O, "POST", "/api/rig-time/casing", {"well_id": w2["id"], "size": "seven", "shoe_md_ft": 9000, "source": "tally"})
11090
11090
  s_or, _ = call(O, "POST", "/api/rig-time/casing/remove", {"well_id": w2["id"], "size": "7"})
11091
11091
  s_dx, dxj = call(O, "POST", "/api/declare", {"content_b64": _b64.b64encode((d / "decl.xlsx").read_bytes()).decode()})
@@ -11099,7 +11099,7 @@ def section_cq_tied_together(tmp: str) -> None:
11099
11099
  cli_d = _sp.run([sys.executable, "-m", "gea", "declare", "--workspace", wsp, "--file", str(d / "decl.xlsx")], capture_output=True, text=True, cwd=str(pkg.parent))
11100
11100
  page_src = (pkg / "web" / "app.html").read_text(encoding="utf-8")
11101
11101
  c4 = {
11102
- "api": s_vc == 403 and s_oc == 200 and ocj["shoe_md_ft"] == 9000 and s_ob == 400 and s_or == 200 and s_dx == 200 and dxj["counts"]["SAME"] == 9
11102
+ "api": s_vc == 403 and s_oc == 200 and ocj["shoe_md_ft"] == 11000 and s_ob == 400 and s_or == 200 and s_dx == 200 and dxj["counts"]["SAME"] == 8
11103
11103
  and s_ia == 200 and iaj["lines"] == 7 and s_al == 200 and "invoice.differs" in alj["events"],
11104
11104
  "cli": cli_c.returncode == 0 and "13-3/8 in, shoe at 2,000 ft" in cli_c.stdout and cli_d.returncode == 0 and "already declared" in cli_d.stdout,
11105
11105
  "page": all(x in page_src for x in ("rtC", "/api/rig-time/casing", ".xlsx", "content_b64: DC.b64", "'invoice.differs': 'Invoice differs'")),
@@ -13486,7 +13486,7 @@ def section_dd_casing_design(tmp: str) -> None:
13486
13486
  "cli": cli.returncode == 0 and "2 string(s)" in cli.stdout,
13487
13487
  "survey": r1 and r1["path_from"] == "survey" and r1["strings"][1]["shoe_tvd_ft"] < 6000.0 - 100.0 and len(r1["kicks"]) == 2
13488
13488
  and r1["kicks"][1]["bottom_md_ft"] == 10000.0 and r1["kicks"][1].get("volume_bbl") is not None,
13489
- "sheet": not pl["errors"] and [s_["action"] for s_ in pl["steps"] if s_["table"] in ("casing_design", "casing_loads")] == ["NEW", "NEW"]
13489
+ "sheet": not pl["errors"] and [s_["action"] for s_ in pl["steps"] if s_["table"] in ("casing", "casing_loads")] == ["NEW", "NEW"] # [casing_design] is read as [casing] (v0.64)
13490
13490
  and pw["applied"] and not again["errors"] and again["counts"]["NEW"] == 0 and again["counts"]["CHANGE"] == 0
13491
13491
  and not tmpl["errors"] and tmpl["counts"]["NEW"] == 0 and tmpl["counts"]["CHANGE"] == 0,
13492
13492
  "sheet_bad": bool(pb["errors"]) and any("[casing_design]" in e and "the grade is one of" in e for e in pb["errors"]) and not pb["written"],
@@ -14027,6 +14027,190 @@ def section_df_trusted_timestamp(tmp: str) -> None:
14027
14027
  + (f" [failed: {', '.join(failed4)}]" if failed4 else ""))
14028
14028
 
14029
14029
 
14030
+ def section_dg_casing_program(tmp: str) -> None:
14031
+ """Section DG - one casing program: rig time, hydraulics, torque and drag and the casing design read the same strings;
14032
+ shoes declared for rig time before v0.64 are carried in, and what disagrees is listed; a string needs only its size
14033
+ and shoe; hydraulics' hole comes from the program (each depth's innermost bore, then the bit), and declaring it twice
14034
+ is answered; the declarations sheet's [casing] is the program, [casing_design] read the same; the tab, the API, the
14035
+ command line and the help."""
14036
+ import csv as _csv
14037
+ import http.cookiejar
14038
+ import io as _io
14039
+ import subprocess as _sp
14040
+ import urllib.error
14041
+ import urllib.request
14042
+ from . import casing_design as CSG
14043
+ from . import declarations as DC
14044
+ from . import helplib as H
14045
+ from . import hydraulics as HY
14046
+ from . import rig_state as RS
14047
+ from . import torque_drag as TND
14048
+ from .service import Service, Users
14049
+ from .workspace import Workspace
14050
+ pkg = Path(__file__).parent
14051
+ d = Path(tmp, "casing_program"); d.mkdir()
14052
+ wsp = str(d / "ws"); ws = Workspace.create(wsp, "Pad 3", actor="tester")
14053
+ def well(name): # a well the casing and hydraulics are declared for; no record needed
14054
+ return ws._register({"id": name, "display": name, "kind": "file", "files": [], "source": {}}, "tester")["id"]
14055
+ w1, w2 = well("SWD-1"), well("SWD-2")
14056
+
14057
+ # -- DG1 one program, carried over -------------------------------------------------------------------------------------------
14058
+ Path(wsp, "drillstring").mkdir(exist_ok=True)
14059
+ Path(wsp, "drillstring", "casing.json").write_text(json.dumps({"schema": 1, "wells": { # as v0.50 to v0.63 kept rig time's shoes
14060
+ w1: [{"size": "13-3/8", "shoe_md_ft": 1500.0, "set": None, "source": "tally"}, {"size": "9-5/8", "shoe_md_ft": 7000.0, "set": "2026-06-01T10:00", "source": "tally"}],
14061
+ w2: [{"size": "13-3/8", "shoe_md_ft": 1450.0, "set": None, "source": "old tally"}]}}), encoding="utf-8")
14062
+ pr0 = CSG.program(ws, w1)
14063
+ view0 = RS.casing(ws)
14064
+ RS.set_casing(ws, "tester", w1, "7", "9900", "tally 2")
14065
+ pr1 = CSG.program(ws, w1)
14066
+ legacy1 = json.loads(Path(wsp, "drillstring", "casing.json").read_text(encoding="utf-8"))["wells"]
14067
+ CSG.upsert_string(ws, "tester", w1, {"od_in": "9-5/8", "weight_lbft": 47, "grade": "N80", "hole_in": 12.25, "mw_ppg": 10}, "BHA report")
14068
+ RS.set_casing(ws, "tester", w1, "9-5/8", "7010", "tally 3") # the shoe moved: the design kept
14069
+ s95 = next(x for x in CSG.program(ws, w1)["strings"] if x["size"] == "9-5/8")
14070
+ CSG.set_well(ws, "tester", w2, "program", "surface:13-3/8:54.5:J55:0-1500:17.5:9") # declared on the Casing tab: the old shoe differs
14071
+ pr2 = CSG.program(ws, w2)
14072
+ Path(wsp, "drillstring", "casing.json").write_text(json.dumps({"schema": 1, "wells": {w2: [{"size": "13-3/8", "shoe_md_ft": 1450.0, "source": "old tally"}]}}),
14073
+ encoding="utf-8")
14074
+ pr2c = CSG.program(ws, w2)
14075
+ cc2 = CSG.crosscheck(ws, w2)
14076
+ RS.remove_casing(ws, "tester", w1, "7")
14077
+ c1 = {
14078
+ "carried": pr0["from"] == "carried over from the rig-time shoes" and [x["size"] for x in pr0["strings"]] == ["13-3/8", "9-5/8"]
14079
+ and view0[w1][1]["set"] == "2026-06-01T10:00" and view0[w2][0]["shoe_md_ft"] == 1450.0,
14080
+ "rig_time_writes_program": pr1["from"] == "declared" and [x["size"] for x in pr1["strings"]] == ["13-3/8", "9-5/8", "7"] and w1 not in legacy1
14081
+ and pr1["strings"][1]["set"] == "2026-06-01T10:00",
14082
+ "kept": s95["shoe_md_ft"] == 7010.0 and s95["weight_lbft"] == 47.0 and s95["grade"] == "N80" and s95["id_in"] == 8.681 and s95["source"] == "tally 3",
14083
+ "partial": pr1["strings"][2]["design_missing"] and pr1["strings"][2]["id_in"] is None and CSG.od_text(13.375) == "13-3/8" and CSG.od_text(4.5) == "4-1/2",
14084
+ "conflict": pr2["from"] == "declared" and pr2c["conflicts"] and pr2c["conflicts"][0]["rig_time_shoe_md_ft"] == 1450.0
14085
+ and any(not x["ok"] and "rig time 1,450 ft" in x["detail"] for x in cc2["items"]),
14086
+ "removed": [x["size"] for x in CSG.program(ws, w1)["strings"]] == ["13-3/8", "9-5/8"],
14087
+ "torque_drag": RS.casing(ws)[w1][-1]["shoe_md_ft"] == 7010.0,
14088
+ }
14089
+ failed1 = [k for k, v in c1.items() if not v]
14090
+ ok(not failed1,
14091
+ "DG1 one casing program per well: shoes declared for rig time before v0.64 carried into it (with when they were set), and a shoe declared on "
14092
+ "the Rig time tab written into it, keeping that string's weight, grade and mud; a string with only its size and shoe kept and not checked; a "
14093
+ "rig-time shoe that disagrees with a declared string listed, not carried; removed from one place" + (f" [failed: {', '.join(failed1)}]" if failed1 else ""))
14094
+
14095
+ # -- DG2 hydraulics reads its hole from the program ---------------------------------------------------------------------------------
14096
+ CSG.set_well(ws, "tester", w1, "program", [{"what": "surface", "od_in": "13-3/8", "weight_lbft": 54.5, "top_md_ft": 0, "shoe_md_ft": 1500},
14097
+ {"what": "intermediate", "od_in": "9-5/8", "weight_lbft": 47, "shoe_md_ft": 7000},
14098
+ {"what": "liner", "od_in": 7, "weight_lbft": 29, "top_md_ft": 6800, "shoe_md_ft": 9900}])
14099
+ HY.set_well(ws, "tester", w1, "mud report (test)", string="BHA:350:4.75:2.25; drill pipe::3.5:2.764", fann={"600": 60, "300": 38, "100": 21, "3": 6},
14100
+ bit_in=6.125, mw_ppg=11, flow_gpm=250)
14101
+ hc = HY.program_config(ws, w1)
14102
+ try:
14103
+ HY.set_well(ws, "tester", w1, "x", hole="x:100:8; oh::8")
14104
+ twice = ""
14105
+ except ValueError as e:
14106
+ twice = str(e)
14107
+ w5, w6 = well("SWD-5"), well("SWD-6")
14108
+ for w_, hole_ in ((w5, "13-3/8 casing:1500:12.615; open hole::12.25"), (w6, "13-3/8 casing:1600:12.5; open hole::12.25")):
14109
+ HY.set_well(ws, "tester", w_, "mud report (test)", hole=hole_, bit_in=12.25) # declared for hydraulics before the program
14110
+ CSG.set_well(ws, "tester", w_, "program", "surface:13-3/8:54.5:J55:0-1500:17.5:9")
14111
+ agree, differ = CSG.crosscheck(ws, w5), CSG.crosscheck(ws, w6)
14112
+ w3 = well("SWD-3")
14113
+ HY.set_well(ws, "tester", w3, "mud report (test)", hole="9-5/8 casing:3500:8.681; open hole::8.5")
14114
+ no_prog = HY.program_config(ws, w3)
14115
+ holes, why = CSG.hole_sections(CSG.check_strings([{"od_in": "9-5/8", "shoe_md_ft": 7000}]), 8.5)
14116
+ c2 = {
14117
+ "sections": [(x["what"], x["bottom_md_ft"], x["id_in"]) for x in hc["hole"]] == [("intermediate", 6800.0, 8.681), ("liner", 9900.0, 6.184), ("6.125 in open hole", None, 6.125)]
14118
+ and hc["hole_from"] == "from the casing program",
14119
+ "twice": "comes from its casing program" in twice,
14120
+ "crosscheck": any(x["what"] == "hydraulics hole" and x["ok"] and "agrees" in x["detail"] for x in agree["items"])
14121
+ and any(x["what"] == "hydraulics hole" and not x["ok"] and "differs" in x["detail"] for x in differ["items"])
14122
+ and HY.program_config(ws, w6)["hole_from"] == "from the casing program",
14123
+ "fallback": no_prog["hole_from"] == "as declared for hydraulics" and no_prog["hole"][0]["bottom_md_ft"] == 3500.0,
14124
+ "needs_bore": holes is None and "weight (or the inside diameter)" in why,
14125
+ }
14126
+ failed2 = [k for k, v in c2.items() if not v]
14127
+ ok(not failed2,
14128
+ "DG2 hydraulics reads its hole from the casing program - each depth's innermost bore (the intermediate to the liner's top, the liner to its "
14129
+ "shoe), then the bit - and declaring the hole again is answered with where to change it; a hole declared before is set against the program's, "
14130
+ "agreeing or not, and the program wins; a well with no program keeps its declared hole; a string with no weight gives no bore, said so"
14131
+ + (f" [failed: {', '.join(failed2)}]" if failed2 else ""))
14132
+
14133
+ # -- DG3 the declarations sheet -------------------------------------------------------------------------------------------------------
14134
+ w4 = well("SWD-4")
14135
+
14136
+ def sheet(rows):
14137
+ buf = _io.StringIO(); _csv.writer(buf).writerows(rows); return buf.getvalue()
14138
+ cols = DC.TABLES["casing"]["cols"]
14139
+ full = sheet([["[casing]", *cols],
14140
+ [""] + [{"well": "SWD-4", "what": "surface", "size_in": "13-3/8", "weight_lbft": "54.5", "grade": "J55", "shoe_md_ft": "1500", "hole_in": "17.5",
14141
+ "mw_ppg": "9", "source": "casing tally (test)"}.get(c, "") for c in cols],
14142
+ [""] + [{"well": "SWD-4", "what": "intermediate", "size_in": "9-5/8", "shoe_md_ft": "7000", "set": "2026-06-12T14:00",
14143
+ "source": "casing tally (test)"}.get(c, "") for c in cols]])
14144
+ p1 = DC.apply(ws, full, "tester", str(d))
14145
+ p2 = DC.apply(ws, full, "tester", str(d), write=True)
14146
+ p3 = DC.apply(ws, full, "tester", str(d))
14147
+ p4 = DC.apply(ws, DC.template(ws), "tester", str(d))
14148
+ old5 = sheet([["[casing]", "well", "size_in", "shoe_md_ft", "set", "source"], ["", "SWD-4", "9-5/8", "7000", "2026-06-12T14:00", "casing tally (test)"]])
14149
+ p5 = DC.apply(ws, old5, "tester", str(d))
14150
+ alias = sheet([["[casing_design]", "well", "what", "od_in", "weight_lbft", "grade", "shoe_md_ft", "hole_in", "mw_ppg", "source"],
14151
+ ["", "SWD-4", "surface", "13-3/8", "54.5", "J55", "1500", "17.5", "9", "casing tally (test)"],
14152
+ ["", "SWD-4", "intermediate", "9-5/8", "47", "N80", "7000", "12.25", "10", "casing tally (test)"]])
14153
+ p6 = DC.apply(ws, alias, "tester", str(d))
14154
+ hcols = DC.TABLES["hydraulics"]["cols"]
14155
+ hyd = sheet([["[hydraulics]", *hcols], [""] + [{"well": "SWD-4", "hole": "x:100:8; open hole::8", "source": "mud report (test)"}.get(c, "") for c in hcols]])
14156
+ p7 = DC.apply(ws, hyd, "tester", str(d))
14157
+ prog4 = CSG.program(ws, w4)["strings"]
14158
+ c3 = {
14159
+ "new": not p1["errors"] and [s_["action"] for s_ in p1["steps"] if s_["table"] == "casing"] == ["NEW"] and p2["applied"]
14160
+ and [x["size"] for x in prog4] == ["13-3/8", "9-5/8"] and prog4[0]["burst_psi"] == 2730 and prog4[1]["set"] == "2026-06-12T14:00",
14161
+ "same": not p3["errors"] and p3["counts"]["NEW"] == 0 and p3["counts"]["CHANGE"] == 0 and not p4["errors"] and p4["counts"]["NEW"] == 0 and p4["counts"]["CHANGE"] == 0,
14162
+ "old_layout": not p5["errors"] and any(s_["table"] == "casing" and s_["action"] == "CHANGE" and "no longer listed: 13-3/8 in" in s_["what"] for s_ in p5["steps"]),
14163
+ "alias": not p6["errors"] and any(s_["table"] == "casing" and s_["action"] == "CHANGE" and "47 lb/ft N80" in s_["what"] for s_ in p6["steps"]),
14164
+ "hydraulics_hole": any("[hydraulics]" in e and "comes from its casing program" in e for e in p7["errors"]),
14165
+ "template_one_table": "[casing]," in DC.template(ws) and "[casing_design]" not in DC.template(ws),
14166
+ }
14167
+ failed3 = [k for k, v in c3.items() if not v]
14168
+ ok(not failed3,
14169
+ "DG3 the declarations sheet's [casing] is the casing program - a well's rows together, planned NEW, written, then SAME and from the template; "
14170
+ "the old layout (size and shoe only) and [casing_design] read as the same table, a string no longer listed said so; a hole for hydraulics "
14171
+ "beside a casing program answered with its row" + (f" [failed: {', '.join(failed3)}]" if failed3 else ""))
14172
+
14173
+ # -- DG4 the tab, the API, the command line, the help ----------------------------------------------------------------------------------
14174
+ cli = _sp.run([sys.executable, "-m", "gea", "rig-time", "--workspace", wsp, "--well", w4, "--casing", "7", "--shoe-md", "7900", "--source", "tally (test)"],
14175
+ capture_output=True, text=True, cwd=str(pkg.parent))
14176
+ cli2 = _sp.run([sys.executable, "-m", "gea", "casing", "--workspace", wsp, "--well", w4], capture_output=True, text=True, cwd=str(pkg.parent))
14177
+ Users(str(Path(wsp, "users.json"))).add("op", "op-pass-123", "operator")
14178
+ svc = Service(wsp, port=0, scheduler=False).start()
14179
+ base_url = svc.url.rstrip("/")
14180
+ o = urllib.request.build_opener(urllib.request.HTTPCookieProcessor(http.cookiejar.CookieJar()))
14181
+
14182
+ def call(method, path, body=None):
14183
+ rq = urllib.request.Request(base_url + path, method=method, data=(json.dumps(body).encode() if body is not None else None))
14184
+ rq.add_header("Content-Type", "application/json"); rq.add_header("X-GEA-Action", "1")
14185
+ try:
14186
+ with o.open(rq, timeout=120) as rr_:
14187
+ return rr_.status, json.loads(rr_.read())
14188
+ except urllib.error.HTTPError as e:
14189
+ return e.code, json.loads(e.read())
14190
+ try:
14191
+ call("POST", "/api/login", {"name": "op", "password": "op-pass-123"})
14192
+ st_c, cp = call("POST", "/api/rig-time/casing", {"well_id": w2, "size": "9-5/8", "shoe_md_ft": 6500, "source": "tally (test)"})
14193
+ st_g, gp = call("GET", f"/api/casing-design?well={w2}")
14194
+ st_h, hp = call("GET", f"/api/hydraulics?well={w1}")
14195
+ finally:
14196
+ svc.stop()
14197
+ page_src = (pkg / "web" / "app.html").read_text(encoding="utf-8")
14198
+ c4 = {
14199
+ "cli": cli.returncode == 0 and "in the well's casing program" in cli.stdout and [x["size"] for x in CSG.program(ws, w4)["strings"]] == ["13-3/8", "9-5/8", "7"]
14200
+ and cli2.returncode == 0 and "7 in casing: 7 in to 7,900 ft MD - not checked" in cli2.stdout,
14201
+ "api": st_c == 200 and st_g == 200 and [x["size"] for x in gp["wells"][[w["id"] for w in gp["wells"]].index(w2)]["config"]["strings"]] == ["13-3/8", "9-5/8"]
14202
+ and "crosscheck" in gp and st_h == 200 and next(w_ for w_ in hp["wells"] if w_["id"] == w1)["hole_from"] == "from the casing program",
14203
+ "page": all(x in page_src for x in ("The casing program against what else was declared", "the one place this well's casing is declared",
14204
+ "goes into the well's casing program", "cur.hole_from === 'from the casing program'", "s.incomplete")),
14205
+ "help": not H.check("casing") and not H.check("hydraulics") and not H.check("rig-time") and "one place" in (H.page("casing") or "")
14206
+ and "read from the well's casing program" in (H.page("hydraulics") or "") and "casing program" in (H.page("declare") or ""),
14207
+ }
14208
+ failed4 = [k for k, v in c4.items() if not v]
14209
+ ok(not failed4,
14210
+ "DG4 a shoe from the command line and the Rig time tab's API lands in the program; the Casing tab shows what is not yet checked and the "
14211
+ "cross-check; hydraulics says its hole comes from the program; the help pages name one place" + (f" [failed: {', '.join(failed4)}]" if failed4 else ""))
14212
+
14213
+
14030
14214
  def PR_read_ok(path) -> bool:
14031
14215
  from . import pdf_report as PR
14032
14216
  try:
@@ -14148,6 +14332,7 @@ def main() -> int:
14148
14332
  section_dd_casing_design(tmp)
14149
14333
  section_de_real_gas(tmp)
14150
14334
  section_df_trusted_timestamp(tmp)
14335
+ section_dg_casing_program(tmp)
14151
14336
  if _FAILS:
14152
14337
  print(f"[ACCEPTANCE] {len(_FAILS)} FAILURES ({_PASS} passed):")
14153
14338
  for f in _FAILS: