ó
    À‘´j \  ã                  ó  • S r SSKJr  SSKrSSKrSSKrSSKrSSKJrJ	r	  SSK
Jr  SSKJrJrJrJrJr  SSKJr  SSKJr  SS	KJrJr  SS
KJrJr  SSKJr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)J*r*  SSK+J,r,  SSK-J.r.J/r/J0r0  SSK1J2r2J3r3J4r4  SSK5J6r6J7r7J8r8  SSK9J:r:J;r;J<r<  SSK=J>r>J?r?J@r@  SSKAJBrBJCrC  SSKDJErE  SSKFJGrG  SrHSrISrJ\ " S S5      5       rKS\:\HS SSSSSSS4                               S,S! jjrLS\:\HS SSSSSSS4                               S,S" jjrM              S-S# jrN            S.S$ jrOS/S% jrPS0S& jrQS1S' jrRS(rSS2S) jrTS3S* jrUS4S+ jrVg)5aá	  Run the figure workflow end to end.

The workflow is independent of the rest of the pipeline. It takes a parse and
the source document, and gives back an enriched copy of that parse, plus the
page scans. Nothing about it depends on being called from inside a larger run,
so a parse produced earlier can be enriched without reproducing it, and
sequencing is a matter of calling the steps in order rather than a flag inside
a monolithic run.

The enriched parse is written under the filename it was read from, so pointing
`output_dir` at the parse's own directory replaces it in place. The parse is an
input every later stage reads by name, and enriching it under that name means
no stage has to be told which of two files to pick up. Run this after fusion,
which is what makes the chart values reach the document the rest of the
pipeline reads.

Pages are nominated from the parse and the PDF's text layer (`nominate`): a
page holding a picture the parse did not class as page furniture, or a table
with no usable text layer under it. Every nominated page is scanned whole, and
no judgement sits between nomination and scan. `pages="all"` adds every other
page of the document, for documents whose content the parse cannot be trusted
to point at. The scans then feed a copy of the parse in the order `run_figures`
sets and explains: tables, figures, and the removal of text a figure was read
over. Figure values are read last, when the caller supplies the page cells and
both value readers, and go to their own artifact, not into the parse.

A page is scanned once when `output_dir` is local. Its stored response is what
a later run reads instead of paying to scan the page again, provided the
stored response's format matches the requested model's generation. A
mismatched one is moved aside rather than deleted. With an `s3://`
`output_dir` no stored response is found, so every page is scanned and billed
again and the upload overwrites the stored response.

The model selects the reading path. A dpt-3 model's responses are digested,
grafted and footnoted by the `dpt3` package. The dpt-3 path also reads any
other page whose dpt-3 response is already stored, and inserts grids the scan
found over empty regions as new tables. Any other model runs the original
path.

Every nominated page reaches the output, as a page scan or, when its scan
failed, as an error. A chart is often where a filing states a number that
appears nowhere else, so a page that was nominated and produced nothing is
exactly what someone needs to see.
é    )ÚannotationsN)Ú	dataclassÚfield)ÚPath)ÚAnyÚDictÚListÚOptionalÚTuple)ÚDoclingDocument)Úlogger)Ú
CellReaderÚget_cell_reader)ÚFigureCorrectorÚget_figure_corrector)Ú	LLMClientÚget_llm_client)ÚStatusInspectorÚget_status_inspector)ÚExtractedTable)ÚTableAssembly)Údpt3)ÚCAPTURE_DPIÚcapture_tables)Úcorrect_figures)Úgraft_figuresÚgraft_tablesÚunread_pictures)Ú	FigureRunÚFigureValueRunÚPageScan)ÚNominatedPageÚnominate_pagesÚtable_verdicts)ÚSCAN_DEFAULT_MODELÚ	page_scanÚ	scan_page)ÚLocalValueReaderÚScanValueParserÚread_figure_values)Úoutput_sinkÚwrite_completion_marker)Úrender_page)Úis_v2_modelé   é   )Ú	nominatedÚallc                  ó~   • \ rS rSr% SrS\S'   S\S'   \" \S9rS\S	'   \" \S9r	S
\S'   Sr
S\S'   \" \S9rS\S'   Srg)ÚChartOutputéZ   zCWhere one figure run's artifacts landed, and what the run produced.r   Úrunr   Údocument)Údefault_factoryzList[ExtractedTable]Útablesz	List[str]Ú	artifactsNzOptional[FigureValueRun]ÚvalueszDict[int, dpt3.PageDigest]Údigests© )Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__Ú__annotations__r   Úlistr9   r:   r;   Údictr<   Ú__static_attributes__r=   ó    Ú=/home/mande/repo/quber/src/quber/core/figures/orchestrator.pyr4   r4   Z   sJ   ‡ áMà	ƒNØÓÙ#(¸Ñ#>€FÐ Ó>Ù °Ñ6€IˆyÓ6Ø'+€FÐ$Ó+Ù*/ÀÑ*E€GÐ'ÖErG   r4   Úoutputr1   c              ƒ  ón  #   • U[         ;  a  [        S[          SU< 35      e[        U[        X5      5      n[        R
                  " SU[        U5      [        UR                  5      U Vs/ s H  nUR                  PM     sn5        US:X  a  [        X5      n[        U5      nU(       az  [        X$U Vs1 s H  nUR                  iM     sn5      nU(       aL  [        R
                  " SU[        U5      U Vs/ s H  nUR                  PM     sn5        [        / UQUQS S9nUb  UO
[        S5      nU	b  U	O	[        5       n	U
b  U
O	[        5       n
Ub  UO	[!        5       n[#        XXõXF5      I Sh  v•N u  nnnUR%                  S	 S9  ['        UUUS
9n[)        U5      nUR+                  SS9n[-        X[.        R0                  " [2        5      [4        U	5      n[7        UUU UUU
US9I Sh  v•N u  nnUR8                  R;                  U5        UR8                  R;                  [=        UUUU5      5        U(       a2  UR8                  R;                  [>        R@                  " UUUU5      5        U(       a  [>        RB                  " UUUU S9u  nnO[C        UUUU S9u  nnUR8                  R;                  U5        [E        UUUX5      I Sh  v•N Ul#        U(       a{  UR8                  R;                  [>        RH                  " UUU5      5        [>        RJ                  " UUUU5        UR8                  R;                  [>        RL                  " UUU5      5        UR8                  R;                  [O        UU5      5        SnU(       aÎ  UbË  UbÈ  [        U Vs1 s H"  nURP                  (       d  M  UR                  iM$     sn5      n[R        RT                  " 5        n 0 n!U H-  n"[W        U 5      SU"S S3-  n#[Y        U U"[4        U#5        U#U!U"'   M/     [[        UUU!XÞU5      I Sh  v•N nSSS5        UR8                  R;                  UR8                  5        U Vs/ s H"  nUR\                  (       d  M  UR\                  PM$     n$n[_        U5       n%U%U S3-  n&U&Ra                  URc                  SS9SS9  U%U-  n'U'Ra                  [d        Rf                  " URi                  5       SS9SS9  U$R;                  U&Rj                  U'Rj                  /5        U(       ad  U%U S3-  n(U(Ra                  [d        Rf                  " U V)s/ s H  n)U)Rm                  SS9PM     sn)SS9SS9  U$Ro                  U(Rj                  5        Ub@  U%U S3-  n*U*Ra                  URc                  SS9SS9  U$Ro                  U*Rj                  5        U(       ap  U%U S3-  n+U+Ra                  [d        Rf                  " [        U5       V,s/ s H  n,UU,   Rm                  SS9PM     sn,SS9SS9  U$Ro                  U+Rj                  5        SSS5        [        R
                  " SUURp                  URr                  URt                  URv                  [        URP                  5      [        U5      URx                  5	        UR8                   H  n-[        Rz                  " SU-5        M     [}        UUUU$UUS9$ s  snf s  snf s  snf  GN GN GN+s  snf  GNÝ! , (       d  f       GNâ= fs  snf s  sn)f s  sn,f ! , (       d  f       Nó= f7f)ak  Read the page scans into a copy of `document`; write the scans and the refined parse.

`document` itself is not changed. The refined copy is returned as
`ChartOutput.document` and written under `parse_name`, the filename the
parse was read from. The parse is an input the rest of the pipeline reads
by name, and this step enriches it rather than producing a variant, so the
name never changes and no later step has to be told which file to pick up.
Pointing `output_dir` at the directory the parse came from therefore
replaces it. Pointing it elsewhere leaves the original alone.

Each page's raw response is written as soon as it is scanned. A page whose
scan fails is reported as an error and the run goes on, so the refined
parse is then written from the pages that did scan. A step that raises
after the scans stops the run before the run record or the parse is
written.
zpages must be one of z, not z-Figure run: {} nominated {} page(s) of {}: {}r2   zBFigure run: {} reading {} page(s) with a stored dpt-3 response: {}c                ó   • U R                   $ ©N©Úpage©Úns    rH   Ú<lambda>Úrun_figures.<locals>.<lambda>¡   s   € ÀAÇFÂFrG   ©ÚkeyNc                ó   • U R                   $ rL   rM   )Úss    rH   rQ   rR   ¨   s   € ˜QŸVšVrG   )r7   ÚscansÚerrorsT)Údeep)Úorphans)Úsourcezvalues-pÚ04dz.pngz.figures.jsoné   ©Úindentúutf-8©Úencodingz.scanned-tables.jsonÚjson)Úmodez.figure-values.jsonz.figure-digest.jsonzlFigure run complete: {} nominated={} scanned={} submitted={} with_figures={} records={} tables={} credits={}z  - {})r6   r7   r9   r:   r;   r<   )?ÚPAGE_SCOPESÚ
ValueErrorr#   r$   r   ÚinfoÚlenÚpagesrN   Úwiden_to_all_pagesr.   Ú_stored_track_pagesÚsortedr   r   r   r   Ú_scan_pagesÚsortr   Ú
_page_dimsÚ
model_copyr   ÚasyncioÚ	SemaphoreÚCORRECT_CONCURRENCYr   r   rX   Úextendr   r   Úinsert_orphan_tablesr   r   ÚremovedÚresolve_figure_footnotesÚgroup_scanned_textÚunhomed_tablesr   ÚfiguresÚtempfileÚTemporaryDirectoryr   r-   r*   Úresponse_artifactr+   Ú
write_textÚmodel_dump_jsonrc   ÚdumpsÚexport_to_dictÚnameÚ
model_dumpÚappendr1   ÚscannedÚ	submittedÚwith_figuresÚcreditsÚerrorr4   ).r[   r7   ÚbaseÚ
parse_nameÚ
output_dirÚmodelÚconcurrencyri   ÚllmÚ	inspectorÚcell_readerÚ	correctorÚcells_pagesÚvalue_parserÚvalue_readerr1   rP   ÚtrackÚstoredrW   r<   rX   r6   ÚdimsÚrefinedÚassemblyr9   Úcapture_errorsÚgraft_errorsÚ
values_runrV   Úfigure_pagesÚtmpÚpage_imagesÚpage_noÚ
image_pathr:   ÚoutÚcharts_pathÚ
parse_pathÚtables_pathÚtÚvalues_pathÚdigest_pathrN   Úerrs.                                                 rH   Úrun_figuresr«   f   s‚  é € ðB ”KÓÜÐ0´°¸VÀEÁ9ÐMÓNÐNÜ˜x¬¸Ó)IÓJ€IÜ
‡K‚KØ7ØÜˆI‹ÜˆH�N‰NÓÙ"Ó#š�Aˆ�Œ™Ñ#ôð �ƒ~Ü& xÓ;ˆ	Ü˜Ó€EÞô
 % TÉ	Ó7RÊ	À1¸¿¼É	Ñ7RÓSˆÞÜ�KŠKØTØÜ�F“Ù!'Ó(¢˜A�—”¡Ñ(ô	ô Ð4 Ð4¨VÐ4Ñ:JÑKˆIØ‘‰#¤n°TÓ&:€CØ&Ñ2‘	Ô8LÓ8N€IØ!,Ñ!8‘+¼oÓ>O€KØ&Ñ2‘	Ô8LÓ8N€Iä#.¨v¸YÈzÓ#g×gÑ€Eˆ7�FØ	‡J�JÑ#€JÑ$ä
˜T¨°vÑ
>€CÜ�hÓ€Dð ×!Ñ! tÐ!Ð,€GÜ˜V¬'×*;Ò*;Ô<OÓ*PÔR]Ð_hÓi€HÜ#1Ø�˜  h°ÀUñ$÷ Ñ€FˆNð ‡J�J×Ñ�nÔ%Ø‡J�J×Ñ”l 7¨E°6¸4Ó@ÔAÞð 	�
‰
×Ñœ$×3Ò3°G¸UÀFÈDÓQÔRæÜ $× 2Ò 2°7¸EÀ4ÐPVÑ WÑˆ‘ä -¨g°u¸dÈ6Ñ RÑˆ�Ø‡J�J×Ñ�lÔ#ô (¨°¸¸fÓP×P€C„KÞð 	�
‰
×Ñœ$×7Ò7¸ÀÈÓPÔQä×Ò ¨°¸Ô>Ø�
‰
×Ñœ$×-Ò-¨e°W¸dÓCÔDð ‡J�J×Ñ”o g¨tÓ4Ô5ð ,0€JÞ�|Ñ/°LÑ4LÜ©uÓBªu¨!¸¿	½	›v˜qŸvœv©uÑBÓCˆÜ×(Ò(Ô*¨cØ+-ˆKÛ'�Ü! #›Y¨8°G¸C°=ÀÐ)EÑE�
Ü˜F G¬[¸*ÔEØ'1�˜GÓ$ñ (ô  2Ø�{ K°ÈTó ÷ ˆJ÷ +ð 	�
‰
×Ñ˜*×+Ñ+Ô,á.3ÓKªe¨°q×7JÕ7JÓ$�×$Ô$©e€IÐKÜ	�ZÔ	  CØ˜t˜f MÐ2Ñ2ˆØ×Ñ˜s×2Ñ2¸!Ð2Ð<ÀwÐÑOØ˜:Ñ%ˆ
Ø×ÑœdŸjšj¨×)?Ñ)?Ó)AÈ!ÑLÐW^ÐÑ_Ø×Ñ˜+×*Ñ*¨J¯O©OÐ<Ô=ÞØ 4 &Ð(<Ð =Ñ=ˆKØ×"Ñ"Ü—
’
¹vÓFºv¸!˜AŸL™L¨f˜LÓ5¹vÑFÈqÑQÐ\cð #ñ ð ×Ñ˜[×-Ñ-Ô.ØÑ!Ø 4 &Ð(;Ð <Ñ<ˆKØ×"Ñ" :×#=Ñ#=ÀQÐ#=Ð#GÐRYÐ"ÑZØ×Ñ˜[×-Ñ-Ô.Þð  4 &Ð(;Ð <Ñ<ˆKØ×"Ñ"Ü—
’
ÌfÐU\ÌoÓ^ÊoÀd˜G D™M×4Ñ4¸&Ð4ÓAÉoÑ^ÐghÑiØ ð #ñ ð ×Ñ˜[×-Ñ-Ô.÷1 
!ô4 ‡K‚Kð	*àØ�‰Ø�‰Ø�‰Ø×ÑÜˆC�K‰KÓÜˆF‹Ø�‰ôð �zŒzˆÜ�Š�X˜sÖ#ñ äØØØØØØñð ùòs 	$ùò 8Sùò )ò hòò" Qùò" Cò÷ +Ö*üò Lùò Gùò _÷+ 
!Õ	 üsì   ‚A*\5Á,[#Â4\5Â6[(Ã.\5Ã:[-ÄA#\5Å3[2Å4A9\5Ç-[5Ç.C\5Ë[8ËC\5Î[;Î/[;Î?\5ÏA\Ð#\ Ð$\Ð(1\5Ñ\Ñ2\Ò\5ÒB1\$Õ \ÕB\$×7\Ø$\$Ø7B<\5Û5\5Û8\5Û;\5Ü \Ü
\Ü\5Ü
\$Ü$
\2Ü.\5c                ó\   • [         R                  " [        U UUUUUUUUU	U
UUUU5      5      $ )z'`run_figures` for a synchronous caller.)rq   r6   r«   )r[   r7   rŠ   r‹   rŒ   r�   rŽ   ri   r�   r�   r‘   r’   r“   r”   r•   s                  rH   Úrun_figures_syncr­     sJ   € ô$ �;Š;ÜØØØØØØØØØØØØØØØó	
óð rG   c              ƒ  óØ  ^ ^^^^^^#   • U(       d  / 0 / 4$ [         R                  " U5      m[        T5      m    SUUUUU U4S jjm[         R                  " U4S jU 5       6 I Sh  v•N nU VVV	s/ s H  u  pxo—c  M
  UPM     n
nnn	U VVV	s0 s H  u  p¼oœc  M
  UR                  U_M     nnnn	U VVVs/ s H  u  p¸oîc  M
  UPM     nnnnX­U4$  Njs  sn	nnf s  sn	nnf s  snnnf 7f)a  Scan every page in `kept`, writing each raw response before reading it.

This is where the model selects the path: a dpt-3 model's responses are
digested by the track and the digests are returned beside the scans. Any
other model's are read by `page_scan`.

A page whose scan raises, or whose dpt-3 response cannot be digested, is
surfaced as an error and gets no record, so the failure is visible rather
than looking like a page with no chart. A failure in `page_scan` or in the
dpt-3 projection is not caught and stops the run.
c              “  ó`  >#   • T
 IS h  v•N    [        TTU R                  TT	5      I S h  v•N u  pnS S S 5      IS h  v•N   T(       ad   [
        R                  " WU R                  TW5      n[
        R                  " XPR                  UW5      n[        U R                  5      Ul
        XeS 4$ [        WU R                  TU R                  WW5      n[        U R                  5      Ul
        US S 4$  Nç NÇ! [         aH  nS S SU R                   S[        U5      R                   SU S34s S nAsS S S 5      IS h  v•N    $ S nAff = f GN! , IS h  v•N  (       d  f       GN"= f! [         a8  nS S SU R                   S[        U5      R                   SU SW 34s S nA$ S nAff = f7f)Nzpage z: figure scan failed (z: z0); the page holds a chart the parse did not readz:: the scan was billed and its response could not be read (z!); the raw response is stored as )Ú_page_responserN   Ú	ExceptionÚtyper>   r   Údigest_pageÚproject_scanÚpicture_classesrD   Ú
table_refsr&   )Ú
nominationÚresponseÚartifactÚreusedÚexcÚdigestÚscanrŠ   r�   rŒ   Ú	semaphorer[   r–   s          €€€€€€rH   ÚoneÚ_scan_pages.<locals>.oneR  s¤  øé € ÷ ’9ðÜ3AØ˜D *§/¡/°5¸*ó4÷ .Ñ*� F÷ —9ö ð
Ü×)Ò)¨(°J·O±OÀUÈHÓU�ô ×$Ò$ V×-GÑ-GÈÐSYÓZˆDÜ" :×#8Ñ#8Ó9ˆDŒOØ Ð%Ð%Ü˜ :§?¡?°E¸:×;UÑ;UÐW_ÐagÓhˆÜ˜z×4Ñ4Ó5ˆŒØ�T˜4ÐÐñ? ñ.øô ó àØà 
§¡Ð0Ð0FÄtÈCÃy×GYÑGYÐFZÐZ\Ð]`Ð\að bHð Hð	ô ÷ —9’9ûð
ú÷ —9—9’9ûô" ó àØà 
§¡Ð0ð 1!Ü!% c£×!3Ñ!3Ð 4°B°s°eÐ;\Ð]eÐ\fðhð	õ ûðüs¾   ƒF.ŠC2‹F.ŽE�C6¬C4­C6´F.¿EÁ F.Á#E) Á/BF.Ã4C6Ã6
EÄ +EÄ+EÄ,EÄ0F.Ä<D?Ä=F.ÅEÅEÅF.ÅE&ÅEÅE&Å!F.Å)
F+Å3-F&Æ F+Æ!F.Æ&F+Æ+F.c              3  ó4   >#   • U  H  nT" U5      v •  M     g 7frL   r=   )Ú.0rP   r¿   s     €rH   Ú	<genexpr>Ú_scan_pages.<locals>.<genexpr>v  s   øé € Ð$:²T°¡S¨§V V²Tùs   ƒN)r·   r"   ÚreturnzCTuple[Optional[PageScan], Optional[dpt3.PageDigest], Optional[str]])rq   rr   r.   ÚgatherrN   )r[   rŠ   Úkeptr�   rŒ   rŽ   ÚresultsrV   Ú_dÚ_erW   Ú_sÚdr<   ÚerX   r¿   r¾   r–   s   `` ``           @@@rH   rm   rm   9  sÐ   þé € ö& Ø�2�rˆzÐä×!Ò! +Ó.€IÜ˜Ó€Eð" Ø!ð" à	L÷" ô " ôH —N’NÔ$:±TÓ$:Ð;×;€GÙ 'Õ9¢‘9�1˜"�Q¡€EÒ9Ù*1ÕCª'™Y˜R B‹yˆq�v‰v�qŠy©'€GÒCÙ!(Õ:¢‘I�B˜A�a¡€FÒ:Ø˜6Ð!Ð!ñ	 <ùÜ9ùÜCùÜ:ùsN   ‰AC*Á(CÁ)
C*Á3	CÂ CÂ
C*Â	CÂCÂ.
C*Â8	C#ÃC#Ã	C*ÃC*c              ƒ  óZ  #   • U SU S3n[        U5      (       a  SOSn[        U5       nXu-  nUR                  5       (       Gak  [        R                  " UR                  SS95      n	[        R                  " U	5      n
X¦:X  a$  [        R                  " SX%5        X•S4sS	S	S	5        $ U
c  [        S
U SU S35      eXq SU SU
 S3-  nXq SU SU S3-  nUR                  5       (       a�  [        R                  " UR                  SS95      n[        R                  " U5      U:X  aS  UR                  U5        UR                  U5        [        R                  " SUU
UR                  U5        XÕS4sS	S	S	5        $ UR                  U5        [        R                  " SUU
UR                  U5        S	S	S	5        [        XUS9I S	h  v•N n	[        U5       nXu-  R                  [        R                  " U	SS9SS9  S	S	S	5        X•S4$ ! , (       d  f       N]= f NR! , (       d  f       N%= f7f)u}  The raw response for one page, and whether it came from a stored scan.

The stored response is named the way a single-page ADE run names it, so a
scan of that page from either path is reused instead of paid for again.
Stored responses are found only in a local `output_dir`. An `s3://` sink
starts empty, so there every page is scanned again.

Reuse is keyed on the model: a stored response is reused only when its
format matches the requested model's generation, which the file itself
shows â€” a chunks list is dpt-2, a structure tree is dpt-3. A mismatched
file is moved aside to `{base}.p{N}.ade.{generation}.json`, replacing any
file already there. If a response of the requested generation is waiting
under `{base}.p{N}.ade.{requested}.json`, it is swapped in and reused.
Otherwise the page is rescanned. A stored file in neither format raises,
so a billed page can never pass as blank.
z.pz	.ade.jsonr   Údpt2r`   ra   z9Figure scan: reusing the stored response for page {} ({})TNzthe stored response z (model z`) holds neither a dpt-2 chunks list nor a dpt-3 structure tree; move it aside to rescan the pagez.ade.z.jsonzjFigure scan: page {} stored response is {}; moved aside to {} and reusing the {} response already paid forzTFigure scan: page {} stored response is {}; moved aside to {} and rescanning with {})r�   é   r^   F)r.   r+   Úexistsrc   ÚloadsÚ	read_textr   Úresponse_generationr   rg   rf   Úreplacer‚   r'   r~   r€   )r[   rŠ   rN   r�   rŒ   r¹   Ú	requestedr£   r—   r¸   Ú
generationÚasideÚwantedÚ	candidates                 rH   r°   r°   }  s  é € ð. ��r˜$˜˜yÐ)€HÜ% e×,Ñ,‘°&€IÜ	�ZÔ	  CØ‘ˆØ�=‰=�?Š?Ü—z’z &×"2Ñ"2¸GÐ"2Ð"DÓEˆHÜ×1Ò1°(Ó;ˆJØÓ&Ü—’ÐWÐY]ÔhØ¨4Ð/÷ 
!Ñ	 ð Ñ!Ü Ø*¨8¨*°H¸U¸Gð DXð Xóð ð ˜F " T F¨%°
¨|¸5ÐAÑAˆEØ˜V 2 d V¨5°°¸5ÐAÑAˆFØ�}‰}�‰Ü ŸJšJ v×'7Ñ'7ÀÐ'7Ð'IÓJ�	Ü×+Ò+¨IÓ6¸)ÓCØ—N‘N 5Ô)Ø—N‘N 6Ô*Ü—K’KðCàØ"ØŸ
™
Ø!ôð %°Ð4÷9 
!Ñ	 ð: �N‰N˜5Ô!Ü�KŠKØiØØØ—
‘
Øô÷= 
!ôL ˜v°5Ñ9×9€HÜ	�ZÔ	  CØ	‰×#Ñ#¤D§J¢J¨xÀÑ$BÈWÐ#ÑU÷ 
!à˜uÐ$Ð$÷S 
!Õ	 úñL :ß	 Õ	 üsZ   ‚(H+ªA3HÂ
H+Â'C
HÅ1
H+Å;5HÆ0H+ÇHÇH+Ç&HÇ;H+È
HÈH+È
H(È$H+c                ó^  • U Vs1 s H  o"R                   iM     nn[        U R                  5       Vs/ s H  oDU;  d  M
  [        US9PM     nnU(       a;  [        R
                  " S[        U5      U Vs/ s H  o"R                   PM     sn5        [        / UQUQS S9$ s  snf s  snf s  snf )uí   Every page of the document, keeping what nominated the nominated ones.

A page the parse pointed at keeps its picture and table refs; every other
page joins bare â€” no refs, just the page â€” and is scanned whole through
the same flow.
rM   z@Figure run: scanning {} un-nominated page(s) under pages=all: {}c                ó   • U R                   $ rL   rM   rO   s    rH   rQ   Ú$widen_to_all_pages.<locals>.<lambda>Ñ  s   € °a·f²frG   rS   )rN   rl   ri   r"   r   rg   rh   )r7   r1   rP   ÚcoveredÚpÚextras         rH   rj   rj   Â  s›   € ñ  )Ó)šy˜!�vŒv™y€GÐ)Ü,2°8·>±>Ô,BÓWÒ,B qÈwÑFVÓ"Œ] Ô"Ñ,B€EÐWÞÜ�ŠØNÜ�‹JÙ"Ó#šU˜�VŒV™UÑ#ô	
ô
 Ð&�IÐ& Ð&Ñ,<Ñ=Ð=ùò *ùÚWùò
 $s   …B ³	B%Á B%Á5B*c                óL  • [         R                  " [         R                  " U 5       S35      n/ n[        U5       n[	        UR                  U  S35      5       Hœ  nUR                  UR                  5      nUc  M#  [        UR                  S5      5      nX‚;   a  MD   [        R                  " UR                  SS95      n	[        R                  " U	5      S:X  d  M„  UR!                  [#        US95        Mž     SSS5        U$ ! [         a     M·  f = f! , (       d  f       U$ = f)	u®  Pages beyond nomination whose stored dpt-3 response already sits in a local `output_dir`.

Reading one costs nothing â€” the response was paid for by whichever run made
it, `quber ade --page` included, and it is named the way this workflow
names its own. Only a response already in the dpt-3 format qualifies: a
dpt-2 response here would be rescanned at a price, and a page nobody
nominated must never be billed by the back door.
z\.p(\d+)\.ade\.jsonz.p*.ade.jsonNrÐ   r`   ra   r   rM   )ÚreÚcompileÚescaper+   rl   ÚglobÚ	fullmatchr‚   ÚintÚgrouprc   rÒ   rÓ   rf   r   rÔ   r„   r"   )
rŠ   rŒ   r1   ÚpatternÚfoundr£   ÚpathÚmatchrN   r¸   s
             rH   rk   rk   Ô  sü   € ô �jŠjœRŸYšY t›_Ð-Ð-@ÐAÓB€GØ!#€EÜ	�ZÔ	  CÜ˜3Ÿ8™8 t f¨LÐ$9Ó:Ö;ˆDØ×%Ñ% d§i¡iÓ0ˆEØ‰}ÙÜ�u—{‘{ 1“~Ó&ˆDØÓ ÙðÜŸ:š: d§n¡n¸g nÐ&FÓG�ô ×'Ò'¨Ó1°VÕ;Ø—‘œ]°Ñ5Ö6ñ <÷ 
!ð €Løô	 ó Úðú÷ 
!Ô	 ð €Lús6   »A"DÂ#DÃDÃDÄ
DÄDÄDÄDÄ
D#c                óÞ   • U R                   R                  5        VVs0 s H@  u  pUR                  c  M  XR                  R                  UR                  R                  4_MB     snn$ s  snnf )zCEach page's width and height in points, as the parse recorded them.)ri   ÚitemsÚsizeÚwidthÚheight)r7   r¡   rN   s      rH   ro   ro   ð  s[   € ð &Ÿ^™^×1Ñ1Ô3ôâ3‰MˆGØ�9‰9ó 	5ˆ—)‘)—/‘/ 4§9¡9×#3Ñ#3Ð4Ò4Ù3òð ùó s
   žA)µ0A))zunified.jsonzdocling.jsonc                óN  ^• [        U 5      nUR                  5       (       d%  UR                  5       (       d  [        SU 35      eU$ [         H&  nUT SU 3-  nUR                  5       (       d  M$  Us  $    SR                  U4S j[         5       5      n[        SU SU 35      e)z´The parse file to refine, from a JSON file or a directory holding one.

A file is taken as given. A directory is searched for `<base>.unified.json`
and then `<base>.docling.json`.
zno parse to refine at Ú.z or c              3  ó2   >#   • U  H  nT S U 3v •  M     g7f)ró   Nr=   )rÂ   rP   rŠ   s     €rH   rÃ   Ú resolve_parse.<locals>.<genexpr>  s   øé € Ð<²¨1˜D˜6  1 #�²ùs   ƒzno parse to refine in z: expected )r   Úis_dirrÑ   ÚFileNotFoundErrorÚPARSE_NAMESÚjoin)ÚparserŠ   rë   r‚   rÚ   rÙ   s    `    rH   Úresolve_parserû      sŸ   ø€ ô �‹;€DØ�;‰;�=‰=Ø�{‰{�}‰}Ü#Ð&<¸T¸FÐ$CÓDÐDØˆßˆØ˜d˜V 1 T FÐ+Ñ+ˆ	Ø×Ñ×ÓØÒñ ð �[‰[Ô<µÓ<Ó<€FÜ
Ð4°T°F¸+ÀfÀXÐNÓ
OÐOrG   c                ó\   • [        X5      n[        R                  " U5      UR                  4$ )z6The parse to refine and the filename it was read from.)rû   r   Úload_from_jsonr‚   )rú   rŠ   rë   s      rH   Úload_documentrþ     s&   € ä˜Ó%€DÜ×)Ò)¨$Ó/°·±Ð:Ð:rG   c                ó"   • [        X S3U5        g)zGWrite the figure run's completion marker, strictly after its artifacts.z.figure.complete.jsonN)r,   )rŒ   rŠ   Úpayloads      rH   Úwrite_markerr    s   € ä˜J¨&Ð0EÐ(FÈÕPrG   ) r[   r   r7   r   rŠ   Ústrr‹   r  rŒ   r  r�   r  rŽ   rç   ri   r  r�   zOptional[LLMClient]r�   zOptional[StatusInspector]r‘   zOptional[CellReader]r’   zOptional[FigureCorrector]r“   zOptional[Dict[int, dict]]r”   zOptional[ScanValueParser]r•   zOptional[LocalValueReader]rÅ   r4   )r[   r   rŠ   r  rÇ   úList[NominatedPage]r�   r  rŒ   r  rŽ   rç   rÅ   z<Tuple[List[PageScan], Dict[int, dpt3.PageDigest], List[str]])r[   r   rŠ   r  rN   rç   r�   r  rŒ   r  rÅ   z Tuple[Dict[str, Any], str, bool])r7   r   r1   r  rÅ   r  )rŠ   r  rŒ   r  r1   zset[int]rÅ   r  )r7   r   rÅ   zDict[int, Tuple[float, float]])rú   r  rŠ   r  rÅ   r   )rú   r  rŠ   r  rÅ   zTuple[DoclingDocument, str])rŒ   r  rŠ   r  r   zDict[str, Any]rÅ   ÚNone)WrB   Ú
__future__r   rq   rc   râ   r{   Údataclassesr   r   Úpathlibr   Útypingr   r   r	   r
   r   Údocling_core.types.doc.documentr   Úlogurur   Úquber.agents.cell_readerr   r   Úquber.agents.figure_correctionr   r   Úquber.agents.llm_clientr   r   Úquber.agents.status_inspectorr   r   Úquber.core.extractors.baser   Ú*quber.core.extractors.set_of_mark.assembler   Úquber.core.figuresr   Úquber.core.figures.capturer   r   Úquber.core.figures.correctr   Úquber.core.figures.graftr   r   r   Úquber.core.figures.modelsr   r    r!   Úquber.core.figures.nominater"   r#   r$   Úquber.core.figures.scanr%   r&   r'   Úquber.core.figures.valuesr(   r)   r*   Úquber.files.outputr+   r,   Úquber.files.pdfr-   Úquber.providers.landing.clientr.   ÚSCAN_CONCURRENCYrs   re   r4   r«   r­   rm   r°   rj   rk   ro   rø   rû   rþ   r  r=   rG   rH   Ú<module>r     sû  ðñ+õZ #ã Û Û 	Û ß (Ý ß 3Õ 3å ;Ý ç @ß Pß =ß OÝ 5Ý DÝ #ß BÝ 6ß QÑ Qß IÑ Iß UÑ Uß LÑ Lß [Ñ [ß CÝ 'Ý 6ð Ð ð Ð ð
 #€ð ÷Fð Fó ðFð  Ø#Ø'ØØ#Ø+/Ø(,Ø+/Ø-1Ø.2Ø/3ðiØðiàðið ðið ð	ið
 ðið ðið ðið ðið 
ðið )ðið &ðið )ðið +ðið ,ðið -ðið  õ!iðb Ø#Ø'ØØ#Ø+/Ø(,Ø+/Ø-1Ø.2Ø/3ð$Øð$àð$ð ð$ð ð	$ð
 ð$ð ð$ð ð$ð ð$ð 
ð$ð )ð$ð &ð$ð )ð$ð +ð$ð ,ð$ð -ð$ð  õ!$ðNA"ØðA"à
ðA"ð ðA"ð ð	A"ð
 ðA"ð ðA"ð BôA"ðHB%ØðB%à
ðB%ð ðB%ð ð	B%ð
 ðB%ð &ôB%ôJ>ô$ô8ð /€ôPô&;õQrG   