ó
    é›tjx  ã                  óÊ   • S r SSKJr  SSKrSSKrSSKJr  SSKJrJ	r	J
r
Jr  SSKrSSKJr  SSKJr  SSKJrJr  SS	KJr  SS
KJr  SS jrSS jr\S:X  a  \" \" 5       5      eg)u?  In-place tightening of stored table-cell grounding boxes.

Documents already in the library were extracted before cell rectangles were
tightened at acquisition, so their stored boxes are still structural grid
geometry â€” the column's x-extent crossed with the row band. Re-extracting
would cost LLM passes and re-ingesting would wipe curation, so this backfill
corrects the one thing that is wrong: for every tableCell grounding whose
text can be found in the staged PDF's text layer near the stored box, the
row's bbox is updated to the printed extent. No other column is touched;
unmatched cells keep their boxes.

Run:
  uv run python -m quber.playground.backfill_boxes [doc_key ...]

With no arguments every document in the library is processed. A document
whose staged PDF is missing is reported and skipped, never silently.
é    )ÚannotationsN)ÚPath)ÚAnyÚDictÚListÚTuple)ÚJsonb)Ú
page_words)Ú
ink_extentÚtighten_box)Údb)Úget_settingsc                ó¼  • U R                  SU45      R                  5       n0 nU H'  nUR                  US   / 5      R                  U5        M)     S=pgUR	                  5        HÔ  u  p‰ [        X(S-   5      u  p«nU	 H·  u  pÞnn[        U[        5      (       a  UO[        R                  " U5      nUS   U
-  US   U-  US   U
-  US   U-  4n[        UUU5      =(       d    [        UU5      nUc  US-  nM|  Uu  nnnnU R                  S[        UU
-  UU-  UU
-  UU-  S	.5      UU45        US-  nM¹     MÖ     Xg4$ ! [         a    U[        U	5      -  n Mö  f = f)
zFTighten one document's cell boxes in place. Returns (tightened, kept).zÄSELECT ref_id, page, bbox, cell_text FROM ade_playground.groundings
           WHERE document_id = %s AND ref_type = 'tableCell'
             AND bbox IS NOT NULL AND coalesce(cell_text, '') <> ''é   r   ÚleftÚtopÚrightÚbottomzhUPDATE ade_playground.groundings SET bbox = %s
                   WHERE document_id = %s AND ref_id = %s)r   r   r   r   )ÚexecuteÚfetchallÚ
setdefaultÚappendÚitemsr
   Ú
IndexErrorÚlenÚ
isinstanceÚdictÚjsonÚloadsr   r   r	   )ÚconnÚdoc_idÚpdf_pathÚrowsÚby_pageÚrÚ	tightenedÚkeptÚpage0Ú	page_rowsÚwÚhÚwordsÚref_idÚ_ÚbboxÚ	cell_textÚboxÚpointsÚtightÚx1Úy1Úx2Úy2s                           Ú=/home/mande/repo/quber/src/quber/playground/backfill_boxes.pyÚbackfill_documentr9   #   sŸ  € à�<‰<ð	Gð 
ˆ	ó	÷
 �hƒjð 	ð 13€GÛˆØ×Ñ˜1˜Q™4 Ó$×+Ñ+¨AÖ.ñ ð Ð€IØ#ŸM™MžOÑˆð	Ü$ X°q©yÓ9‰KˆA�%ó +4Ñ&ˆF�t˜YÜ$ T¬4×0Ñ0‘$´d·j²jÀÓ6FˆCØ˜&‘k A‘o s¨5¡z°A¡~°s¸7±|ÀaÑ7GÈÈXÉÐYZÑIZÐ[ˆFÜ ¨	°5Ó9×V¼ZÈÐPUÓ=VˆEØ‰}Ø˜‘	�ÙØ"‰NˆB��B˜Ø�L‰Lð=ô  2¨¡6°"°q±&À2ÈÁ6ÐUWÐZ[ÑU[Ñ\Ó]ØØðôð ˜‰NŠIó# +4ñ ,ð0 ˆ?Ðøô+ ó 	Ø”C˜	“NÑ"ˆDÚð	ús   Á*D?Ä?EÅEc                 ó  • [         R                  " SS9n U R                  SSSS9  U R                  5       n[	        5       R
                  R                  nS=p4/ n[        R                  " 5        nUR                  S5      R                  5       nU HŒ  u  p‰n
UR                  (       a  X‘R                  ;  a  M(  X) S	3-  nUR                  5       (       d  UR                  U	 S
U
 S35        M]  [        XhU5      u  pÍX<-  nXM-  n[        SU	 SUS SUS SU
 35        MŽ     S S S 5        [        SU SU 35        U(       a/  [        S[!        U5       S35        U H  n[        SU 35        M     g! , (       d  f       NV= f)Nz2Tighten stored table-cell grounding boxes in place)ÚdescriptionÚdoc_keysÚ*z'doc_key values to backfill; default all)ÚnargsÚhelpr   zWSELECT id, doc_key, coalesce(title, filename) FROM ade_playground.documents ORDER BY idz.pdfz (Ú)z  z  tightened z>5z  kept z>4z
total tightened z, kept u$   
SKIPPED â€” staged PDF missing for z document(s):)ÚargparseÚArgumentParserÚadd_argumentÚ
parse_argsr   Ú
playgroundÚdata_dirr   Úconnectr   r   r<   Úexistsr   r9   Úprintr   )ÚparserÚargsrF   Útotal_tightenedÚ
total_keptÚmissingr    Údocsr!   Údoc_keyÚlabelr"   r&   r'   Úms                  r8   ÚmainrS   K   su  € Ü×$Ò$Ð1eÑf€FØ
×Ñ˜
¨#Ð4]ÐÑ^Ø×ÑÓ€Dä‹~×(Ñ(×1Ñ1€HØ#$Ð$€OØ€GÜ	�ŠŒ˜Ø�|‰|Øeó
ç
‰(‹*ð 	ó '+Ñ"ˆF˜UØ�}�} ·±Ó!=ÙØ I¨TÐ"2Ñ2ˆHØ—?‘?×$Ñ$Ø—‘ ' ¨"¨U¨G°1Ð5Ô6ÙÜ/°¸hÓG‰OˆIØÑ(ˆOØÑˆJÜ�B�w�i˜|¨I°b¨>¸ÀÀbÀ	ÈÈEÈ7ÐSÖTñ '+÷	 
ô  
Ð˜Ð/¨w°z°lÐ
CÔDÞÜÐ5´c¸'³l°^À=ÐQÔRÛˆAÜ�B�q�c�(ŽOñ à÷+ 
�ús   Á.B2E0Å0
E>Ú__main__)r    zpsycopg.Connectionr!   Úintr"   r   ÚreturnzTuple[int, int])rV   rU   )Ú__doc__Ú
__future__r   rA   r   Úpathlibr   Útypingr   r   r   r   ÚpsycopgÚpsycopg.types.jsonr	   Úquber.agents.completenessr
   Ú%quber.core.extractors.camelot.tightenr   r   Úquber.playgroundr   Úquber.settingsr   r9   rS   Ú__name__Ú
SystemExit© ó    r8   Ú<module>re      sX   ðñõ$ #ã Û Ý ß )Ó )ã Ý $å 0ß IÝ Ý 'ô%ôPð@ ˆzÓÙ
‘T“VÓ
Ðð rd   