ó
    e€;j  ã                  ó*  • S r SSKJr  SSKrSSKJr  SSKJrJrJ	r	J
r
  SSKJ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KJr  SSKJr  SSKJrJrJr  SSK J!r!  SSK"J#r#  SSK$J%r%J&r&  \
\'\'\'\'4   r( " S S5      r)SS jr*        SS jr+g)uõ  Run both extractions and reconcile them into the two corrected outputs.

The entry point for the consolidation. It parses the document with docling and
runs the Set-of-Mark/Camelot extraction (concurrently â€” they are independent),
matches the two by overlap, splits any region SoM merged, annotates charts and
image tables, and grafts the Camelot bodies into the docling spine.

The result carries both corrected outputs: the SoM/Camelot tables (split,
annotated) and the unified `DoclingDocument`.
é    )ÚannotationsN)ÚPath)ÚDictÚListÚOptionalÚTuple)ÚCoordOrigin)Ú	TableItem)Úlogger)Ú	LLMClientÚget_llm_client)ÚExtractedTable)Úcamelot_bbox_to_norm)ÚSetOfMarkExtractor)Úsplit_table)ÚParserÚParseResultÚparser_for_preset)Úbuild_unified_document)Úmatch_tables)ÚReconcileResultÚRegionMatchc                  ór   • \ rS rSrSr    S	         S
S jjrSS jrSS jr          SS jrSr	g)ÚSpineReconcileré#   zÚReconcile docling's spine with the Set-of-Mark/Camelot tables.

Holds the parser, the table extractor, and the LLM client used by the split
pass. `reconcile` runs the whole flow; `reconcile_sync` wraps it for the CLI.
Nc                óª   • U=(       d    [        U5      U l        U=(       d    [        S 5      U l        U=(       d    [	        U R                  S9U l        g )N)Úllm)r   Úparserr   r   r   Ú	extractor)Úselfr   r   r   Úpresets        Ú?/home/mande/repo/quber/src/quber/core/reconcile/orchestrator.pyÚ__init__ÚSpineReconciler.__init__*   s=   € ð ×9Ô 1°&Ó 9ˆŒØ×.œ.¨Ó.ˆŒØ"×FÔ&8¸T¿X¹XÑ&Fˆ�ó    c              ƒ  óÂ  #   • [         R                  " U R                  R                  U5      nU R                  R                  U5      I S h  v•N nUI S h  v•N nUR                   Vs0 s H%  oUR                  UR                  UR                  4_M'     nnUR                  R                   Vs0 s H  owR                  U_M     nn[        XC5      n	U R                  X“X†5      I S h  v•N u  p:U
(       a  [        XC5      n	[        X“5        [!        UR                  X9U5      u  p¼U H  n["        R$                  " SU5        M     ['        X³XœS9$  GN Nús  snf s  snf  Nu7f)Nzreconcile: {})ÚdocumentÚtablesÚmatchesÚerrors)ÚasyncioÚ	to_threadr   Úparser   Úextract_tablesÚpagesÚpage_noÚwidthÚheightr'   r(   Úself_refr   Ú_split_merged_regionsÚ	_annotater   r   Úerrorr   )r    ÚsourceÚ
parse_taskÚ
som_tablesr-   ÚpÚ	page_dimsÚtÚtables_by_refr)   Ú	split_anyÚunifiedr*   Úerrs                 r"   Ú	reconcileÚSpineReconciler.reconcile5   s&  é € ä×&Ò& t§{¡{×'8Ñ'8¸&ÓAˆ
ØŸ>™>×8Ñ8¸Ó@×@ˆ
Ø#-×-ˆà=B¿[º[ÓIº[¸—Y‘Y §¡¨!¯(©(Ð 3Ò3¹[ˆ	ÐIØ05·±×0EÒ0EÓFÒ0E¨1Ÿ™ QšÑ0EˆÐFä˜uÓ1ˆð
 '+×&@Ñ&@Ø ó'
÷ !
Ñˆ
ö Ü" 5Ó5ˆGô 	�'Ô&ô 1°·±ÀÐV_Ó`‰ˆÛˆCÜ�LŠL˜¨#Ö.ñ ô ¨ÈGÑcÐcò3 AÙ-ùâIùÚFñ!
ùsO   ‚A
EÁEÁ	EÁEÁEÁ),EÂEÂ/EÃ"EÃ'EÃ(A'EÅEÅEc                óL   • [         R                  " U R                  U5      5      $ )N)r+   ÚrunrA   )r    r7   s     r"   Úreconcile_syncÚSpineReconciler.reconcile_syncS   s   € Ü�{Š{˜4Ÿ>™>¨&Ó1Ó2Ð2r%   c           	   ƒ  óÖ  #   • [        U5      nSnU GHC  nUR                  S:w  d  [        UR                  5      S:w  a  M/  UR                  S   n[        UR                  5      n	UR                   V
s/ s H"  n
X£;   d  M
  [        X:   XGR                  5      PM$     nn
U Vs/ s H	  oÌc  M  UPM     nn[        U5      U	:w  a  M³  [        XX   X›U R                  5      I Sh  v•N n[        U5      S:”  d  Må  US   XX'   [        USS SS9 H  u  pïUR                  XŽ-   U5        M     Sn[        R                  " SUR                  [        U5      5        GMF     XV4$ s  sn
f s  snf  N…7f)	a  Replace each SoM-merged table with the tables `split_table` recovers.

Only the single-SoM-table case is handled (one fused region docling sees
as several); a region with more than one SoM table is too ambiguous to
split and is left for the graft pass to report.
FÚ
som_mergedé   r   N)ÚstartTz<reconcile: split SoM-merged region on page {} into {} tables)ÚlistÚkindÚlenÚsom_indicesÚdocling_table_refsÚ_docling_norm_boxÚpager   r   Ú	enumerateÚinsertr   Úinfo)r    r)   r9   r=   r;   Úoutr>   ÚmatchÚidxÚcountÚrÚ
boundariesÚbÚsplitsÚoffsetÚextras                   r"   r4   Ú%SpineReconciler._split_merged_regionsV   sZ  é € ô �:ÓˆØˆ	ÜˆEØ�z‰z˜\Ó)¬S°×1BÑ1BÓ-CÀqÓ-HÙØ×#Ñ# AÑ&ˆCÜ˜×0Ñ0Ó1ˆEð ×1Ò1óâ1�AØÑ%ó KÔ! -Ñ"2°I¿z¹zÖJÙ1ð ð ñ
 &0ÓA¢Z Ÿ!¡ZˆJÐAÜ�:‹ %Ó'ÙÜ& s¡x°ÀDÇHÁHÓM×MˆFÜ�6‹{˜Q�Ø! !™9�‘ä%.¨v°a°b¨zÀÔ%C‘M�FØ—J‘J˜s™|¨UÖ3ñ &Dà �	Ü—’ØRØ—J‘JÜ˜“K÷ñ) ð2 ˆ~Ðùò)ùò
 Bñ Nùs=   ‚A1E)Á3	EÂ EÂE)Â"E"Â,E"Â2/E)Ã!E'Ã"E)Ã7A1E))r   r   r   )NNNztuned-financial)
r   zOptional[Parser]r   zOptional[SetOfMarkExtractor]r   zOptional[LLMClient]r!   ÚstrÚreturnÚNone)r7   r   ra   r   )
r)   úList[RegionMatch]r9   úList[ExtractedTable]r=   zDict[str, TableItem]r;   úDict[int, Tuple[float, float]]ra   z!Tuple[List[ExtractedTable], bool])
Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r#   rA   rE   r4   Ú__static_attributes__© r%   r"   r   r   #   s�   † ñð $(Ø26Ø#'Ø'ð	Gà ð	Gð 0ð	Gð !ð		Gð
 ð	Gð 
õ	Gôdô<3ð(à"ð(ð )ð(ð ,ð	(ð
 2ð(ð 
+÷(r%   r   c                óÎ   • U  H_  nUR                   S:X  a  UR                   H  nSX   l         M     M1  UR                   S:X  d  MC  UR                   H  nSX   l         M     Ma     g)zGSet `ExtractedTable.kind` for image tables and charts from the matches.Úimage_tableÚchartN)rL   rN   )r)   r9   rV   Úis       r"   r5   r5   �   sX   € ãˆØ�:‰:˜Ó&Ø×&Ô&�Ø%2�
‘Ö"ó 'à�Z‰Z˜7Õ"Ø×&Ô&�Ø%,�
‘Ö"ó 'ò r%   c                ó   • U R                   (       d  gUR                  US5      u  p4U R                   S   R                  nUR                  [        R
                  :X  a:  UR                  U-  UR                  U-  UR                  U-  UR                  U-  4$ [        UR                  UR                  UR                  UR                  4X45      $ )zKA docling table's box in the normalized top-left frame split_table expects.N)g      ƒ@g     Àˆ@r   )ÚprovÚgetÚbboxÚcoord_originr	   ÚTOPLEFTÚlr<   rY   r[   r   )Útabler;   rQ   r1   r2   rt   s         r"   rP   rP   Œ   sœ   € ð �:�:ØØ—M‘M $¨Ó7�M€EØ�:‰:�a‰=×Ñ€DØ×ÑœK×/Ñ/Ó/Ø—‘˜‘ §¡¨¡°·±¸%±ÀÇÁÈ&ÁÐQÐQÜ §¡¨¯©°·±¸¿¹Ð @À%ÓPÐPr%   )r)   rc   r9   rd   ra   rb   )rx   r
   r;   re   rQ   Úintra   zOptional[NormBox]),rj   Ú
__future__r   r+   Úpathlibr   Útypingr   r   r   r   Údocling_core.types.doc.baser	   Údocling_core.types.doc.documentr
   Úlogurur   Úquber.agents.llm_clientr   r   Úquber.core.extractors.baser   Ú5quber.core.extractors.camelot.correspondence.geometryr   Ú!quber.core.extractors.set_of_markr   Ú'quber.core.extractors.set_of_mark.splitr   Úquber.core.parsersr   r   r   Úquber.core.reconcile.graftr   Úquber.core.reconcile.matchingr   Úquber.core.reconcile.modelsr   r   ÚfloatÚNormBoxr   r5   rP   rl   r%   r"   Ú<module>r‹      s‘   ðñ	õ #ã Ý ß .Ó .å 3Ý 5Ý ç =Ý 5Ý VÝ @Ý ?ß EÑ EÝ =Ý 6ß Dà
��u˜e UÐ*Ñ
+€÷[ñ [ô|-ð
QØð
QØ!?ð
QØGJð
Qàõ
Qr%   