ó
    À‘´j¨r  ã                  ób  • S r SSK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Jr  SSKJr  SSKJr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  SSK J!r!J"r"J#r#  SSK$J%r%J&r&J'r'  SSK(J)r)J*r*  SSK+J,r,J-r-J.r.  SSK/J0r0  Sr1Sr2Sr3Sr4Sr5Sr6Sr7S\1SS4             S)S jjr8          S*S jr9      S+S jr:S,S jr;                S-S jr< S.       S/S  jjr=            S0S! jr>S1S" jr?S2S# jr@S3S$ jrA                S4S% jrBS5S& jrCS6S' jrDS7S( jrEg)8a¶  Put each figure's text onto the picture the parse already found.

The placeholder is already in the document. Every picture the parse detected sits
in the body in reading order carrying its page and its box, and nomination read
that placeholder rather than creating it. Grafting fills it in: the picture that
was always there now carries the figure's content.

So a chart is not a new kind of element competing with tables for a position. It
carries no cells and no per-value location, and is not shaped like a table.

The text lands as the picture's description, the document model's own field for
what a picture depicts, and the scan's identity lands in the picture's metadata
so a picture can be traced back to the scan that read it and a model change is
visible without re-reading the text. Each record is given the reference of the
picture it filled, so a plotted value traces back to the element that holds it.

The two counts do not always agree. The scan decides, because it looked at the
page and the box it drew is already a source coordinate, while the parse is
working from a layout model. So a region ends up holding exactly as many pictures
as the scan returned figures:

- One picture the scan read as several figures is split into one per figure. The
  parse draws a single region over two charts printed side by side.
- Several pictures the scan read as one figure become one. The parse splits a
  chart pair the scan describes together.
- A region already agreeing keeps the box and bitmap the parse measured.
- A figure over no picture at all is surfaced as an error and never dropped,
  since a figure the scan read that nothing holds is a value that vanishes.

Figures and pictures are grouped by overlap before anything is assigned, so the
order the figures arrive in never decides an outcome.

What a picture *is* remains the parse's call, not the scan's. The scan describes a
wordmark as readily as a chart, and a branded deck prints one on every page, so a
region the parse classified as page furniture is dropped with its records. That
judgement reads a class the parse already published rather than a rule written
against a description that has no fixed shape.

The text the parse lifted out of a picture is removed once the scan has read it,
except for items whose label the caller names in `preserve`. Those fragments
are bare numbers with nothing saying what they measure, and the description now
carries the same values with their series and their axes. Keeping both would put
two readings of one chart in the document.

This module attaches no titles or notes to a picture. One note commonly serves
several charts on a page, and nothing here matches a superscript to the note it
points at. The correction sweep in `quber.core.figures.correct` writes each
figure's markers and page notes onto its picture's metadata under
`FOOTNOTE_MARKS_FIELD` and `FOOTNOTES_FIELD`. On the dpt-3 track,
`quber.core.figures.dpt3.footnotes` then resolves each marker to its note.

A table read off a page image goes into the table the parse already found for it,
the same way. The element stays a table; only its body changes, from the parse's
own reading of the image to the scan's, along with the title, subtitle, units and
footnotes read off the page with it.

`graft_figures` never mutates the document it is given and returns a clone.
`graft_tables` mutates the document it is given. The orchestrator runs it first,
on its own copy of the parse, and then hands that copy to `graft_figures`.
é    )Úannotations)ÚPath)Ú
CollectionÚDictÚListÚOptionalÚTuple)ÚBoundingBoxÚCoordOrigin)ÚDescriptionMetaField)ÚImageRefÚProvenanceItem)ÚDoclingDocumentÚPictureItemÚPictureMetaÚTextItem)ÚDocItemLabel)Úlogger)ÚExtractedTable)Úcoverage_fraction)ÚNormBoxÚnorm_boxÚprov_box)ÚFigureRecordÚPageScanÚScannedTable)ÚFURNITURE_CLASSESÚpicture_classes)ÚREAD_BY_FIELDÚattach_attributionÚmarkdown_to_table_data)Úrender_regiongš™™™™™É?gš™™™™™©?zquber-chart-scanÚadeÚquber__footnote_marksÚquber__footnoteséH   N© c                óZ  ^• U R                  SS9n[        U=(       d    0 5      nUR                  R                  5        HI  u  p‰X‡;  d  M  U	R                  c  M  U	R                  R
                  U	R                  R                  4Xx'   MK     0 n
UR                   HN  nUR                  (       d  M  U
R                  UR                  S   R                  / 5      R                  U5        MP     / n/ nU Hî  mUR                  TR                  S5      u  pïU
R                  TR                  / 5      n[        TR                  UXïU5      u  nnU H<  nUR                  STR                   SUR                    SUR"                   S35        M>     U HN  u  nn[%        U5      (       a  ['        TUU5        M%  UR)                  U4S	 j[+        UUUTXïU5       5       5        MP     Mð     U H  u  nnm[-        UUT5        M     [/        Xm VVVs/ s H	  u  nnnUPM     snnnU5        Xl4$ s  snnnf )
aN  Carry each scan's figure text onto the matching picture in a clone of `document`.

`page_dims` gives each page's width and height in points, used to bring the
parse's picture boxes into the scan's normalized frame. Pages absent from it
fall back to the document's own page sizes.

`source` is the document the parse was made from. Splitting a picture moves
the boundaries its stored bitmap was cut to, so each part's bitmap is cut
again from the page. Without the source a split part carries no bitmap and the
loss is logged.

`preserve` names text labels that survive under a picture the scan has read.
The scan's reading supersedes the parse's stray content fragments, but an
item the parse labelled a footnote or a caption is native page text with a
known role, not a reading of the figure, and a caller passing its label
keeps it in the document.

Returns the refined document and one error string per figure that overlaps no
picture. The records in `scans` are given the reference of the picture each
one filled, and a record whose region the parse called page furniture is
removed from the scan.
T©Údeepr   ©g      ƒ@g     Àˆ@úpage z : the scan returned a figure at z, that overlaps no picture in the parse (job z)); its text is in the figure records onlyc              3  ó0   >#   • U  H  u  pXT4v •  M     g 7f©Nr'   )Ú.0ÚpictureÚchartÚscans      €Ú6/home/mande/repo/quber/src/quber/core/figures/graft.pyÚ	<genexpr>Ú graft_figures.<locals>.<genexpr>³   s   øé € ð â&g‘N�Gð  Õ&Ú&gùs   ƒ)Ú
model_copyÚdictÚpagesÚitemsÚsizeÚwidthÚheightÚpicturesÚprovÚ
setdefaultÚpage_noÚappendÚgetÚpageÚ_regionsÚfiguresÚboxÚjob_idÚ_is_furnitureÚ_discardÚextendÚ_reshapeÚ_attachÚ_discard_superseded)ÚdocumentÚscansÚ	page_dimsÚmatch_fractionÚsourceÚpreserveÚrefinedÚdimsr@   rC   Úpictures_by_pager0   ÚerrorsÚpairsr;   r<   Ú
candidatesÚregionsÚ	unmatchedr1   r=   rE   Ú_cÚ_sr2   s                           @r3   Úgraft_figuresr^   w   sý  ø€ ð< ×!Ñ! tÐ!Ð,€GÜ�	—˜RÓ €DØ Ÿ™×,Ñ,Ö.‰ˆØÕ 4§9¡9Ó#8Ø!ŸY™YŸ_™_¨d¯i©i×.>Ñ.>Ð?ˆD‹Mñ /ð 68ÐØ×#Ô#ˆØ�<�<‰<Ø×'Ñ'¨¯©°Q©×(?Ñ(?ÀÓD×KÑKÈGÖTñ $ð €Fð ?A€EÛˆØŸ™ §¡¨NÓ;‰ˆØ%×)Ñ)¨$¯)©)°RÓ8ˆ
Ü% d§l¡l°JÀÈ~Ó^Ñˆ�ãˆEØ�M‰MØ˜Ÿ	™	�{Ð"BÀ5Ç9Á9À+ð N-Ø-2¯\©\¨NÐ:cðeöñ ó
 ")ÑˆH�gÜ˜X×&Ñ&Ü˜˜w¨Ô1ÙØ�L‰Lô ä&.¨w¸À'È4ÐQVÐ`fÔ&góö ó	 ")ñ ó& !&Ñˆ�˜Ü�˜ Ö%ñ !&ô ˜ÀÕ!GÂ©o¨g°r¸2£'ÁÓ!GÈÔRØˆ?Ðùô "Hs   È	H&c                óD  • U Vs0 s H"  oDR                   (       d  M  UR                   U_M$     nnU R                   Vs0 s H  oDR                  U_M     nn/ nU R                   Vs0 s H  oˆR                  U_M     n	nU GHŒ  n
U
R                   GHw  nUR                   c  M  UR                  c  UR
                  b  [        X
X¹XSU5        M=  UR                  c  ML  UR                  UR                  5      nUR                  UR                   5      nUb  Uc;  UR                  SU
R                   SUR                    SUR                   S35        MÃ  UR                  =(       d    SR                  5       (       d/  UR                  SU
R                   SUR                   S35        GM  [        R                  " SU
R                  UR                  UR                   5        [        UR                  5      Ul        [!        XXÓ5        GMz     GM�     U$ s  snf s  snf s  snf )	u®  Put each table read off a page image into the parse table it was read for.

The element stays a table. Nothing is relabelled: a balance sheet is a table
whichever tool read it, and calling it an image so it could travel a
picture-shaped path would bend the document to suit the code.

The extracted body replaces the parse's own reading of the image, and the
title, subtitle, units and footnotes the correction read off the page are
attached with it, exactly as they are for a table the table engine produced.
Nothing is lost by replacing: the page's raw response is stored as it came
back, so what was read and by which model version stays on record.

Mutates `document` in place â€” the caller owns the clone â€” and returns one
error per scanned table it could not put in: one whose parse table or
extraction cannot be found, one whose extraction has an empty body, and one
read over a picture that cannot be resolved or produced no body.
r,   z%: the table read off the page image (z) has no home in the parse (z"); it is in the table records onlyÚ z!: the scan returned a table over zK with no cells in it; the parse's own reading of the image is left standingz>Table graft: page {} replacing {} with the scan's reading ({}))Útable_idÚtablesÚself_refr=   Ú	table_refÚpicture_refÚ_add_beside_picturerB   rA   rC   ÚmarkdownÚstripr   Úinfor!   Údatar    )rN   rO   rb   rP   ÚtÚby_idÚby_refrW   ÚpÚ
by_picturer2   ÚscannedÚ
table_itemÚ	extracteds                 r3   Úgraft_tablesrs   À   sî  € ñ. %+Ó9¢F˜q¯j­j‹]ˆQ�Z‰Z˜Š]¡F€EÐ9Ø%-§_¢_Ó5¢_ �j‰j˜!Šm¡_€FÐ5à€FØ)1×):Ò):Ó;Ò): A—*‘*˜a’-Ñ):€JÐ;äˆØ—{•{ˆGØ×ÑÑ'ÙØ× Ñ Ñ(¨W×-@Ñ-@Ñ-LÜ# H°GÈÐ[aÔbÙØ× Ñ Ñ(ÙØŸ™ G×$5Ñ$5Ó6ˆJØŸ	™	 '×"2Ñ"2Ó3ˆIØÑ! YÑ%6Ø—‘Ø˜DŸI™I˜;Ð&KÈG×L\ÑL\ÐK]ð ^-Ø-4×->Ñ->Ð,?Ð?aðcôñ Ø×&Ñ&×,¨"×3Ñ3×5Ñ5Ø—‘Ø˜DŸI™I˜;Ð&GÈ×HYÑHYÐGZð [Yð Yôò Ü�KŠKØPØ—	‘	Ø×!Ñ!Ø× Ñ ô	ô 5°Y×5GÑ5GÓHˆJŒOÜ˜x°Y×Jô; #ñ ð> €MùòK :ùÚ5ùò <s   …H�H¾HÁ&Hc                óÒ  ^
• / n0 nU R                    Hu  nUR                  (       d  M  UR                  S   R                  nUR                  US5      u  pg[	        XFU5      m
T
c  MT  UR                  U/ 5      R                  T
5        Mw     U R                   GHK  nUR                  (       d  M  [        U5      n	U	(       a  [        S U	 5       5      (       a  MB  UR                  (       a;  UR                  R                  (       a   UR                  R                  R                  OSR                  5       (       a  M¥  UR                  S   R                  nUR                  US5      u  pg[	        X†U5      m
T
b-  [        U
4S jUR                  U/ 5       5       5      (       a  GM  UR                  SU SUR                   SS	R!                  U	5      =(       d    S
 S35        GMN     U$ )uš  One error per picture the run left with nothing in it.

A figure the scan returned that covers no picture is already reported, so a
value the scan read never disappears quietly. The reverse was not: a picture
the scan returned nothing over ended the run empty and said nothing about it.
That is how a fourteen-row table of property sales went missing on a page the
run reported no errors for â€” the parse had filed the region as a picture, and
a picture nothing claimed was indistinguishable from a picture correctly left
alone.

A picture is accounted for when it carries a description, or when a table
in the document shares any area with it on its page. Full coverage is not
required. The second case is a region the parse detected twice, once as a
table and once as a picture; the table holds the content and the picture is
a duplicate outline of it.

Page furniture is not reported. A logo is never read on purpose.
r   r+   c              3  ó2   #   • U  H  o[         ;   v •  M     g 7fr.   ©r   ©r/   Úcs     r3   r4   Ú"unread_pictures.<locals>.<genexpr>$  s   é € ÐCº7°aÔ 1Ö1º7ùó   ‚r`   c              3  ó<   >#   • U  H  n[        TU5      v •  M     g 7fr.   )Ú	_overlaps)r/   ÚotherrF   s     €r3   r4   ry   +  s   øé € Ð"cÒFb¸U¤9¨S°%×#8Ð#8ÒFbùs   ƒr,   z
: picture z (ú, Úunclassifiedu�   ) was read by nothing â€” the scan returned no figure over it and the document holds no table there; whatever it shows is not in the document)rb   r>   r@   rB   r   r?   rA   r=   r   ÚallÚmetaÚdescriptionÚtextrh   Úanyrc   Újoin)rN   rP   rW   Útables_by_pageÚtablerC   r;   r<   r0   ÚclassesrF   s             @r3   Úunread_picturesr‰   ÿ   s�  ø€ ð, €FØ/1€NØ—”ˆØ�z�zÙØ�z‰z˜!‰}×$Ñ$ˆØ!Ÿ™ d¨NÓ;‰ˆÜ�u VÓ,ˆØ‹?Ø×%Ñ% d¨BÓ/×6Ñ6°sÖ;ñ !ð ×$Õ$ˆØ�|�|ÙÜ! 'Ó*ˆÞ”sÑC¹7ÓC×CÑCÙØ-4¯\¯\¸g¿l¹l×>V×>VˆG�L‰L×$Ñ$×)Ò)Ð\^×eÑe×gÑgÙØ�|‰|˜A‰×&Ñ&ˆØ!Ÿ™ d¨NÓ;‰ˆÜ�w vÓ.ˆØ‰?œsÔ"cÀn×FXÑFXÐY]Ð_aÔFbÓ"c×cÑcÚØ�‰Ø�D�6˜ G×$4Ñ$4Ð#5ð 6Ø—	‘	˜'Ó"×4 nÐ5ð 6ð÷	
ñ %ð& €Mó    c                ó¤   • [        U S   US   5      [        U S   US   5      :„  =(       a%    [        U S   US   5      [        U S   US   5      :„  $ )z'Do the two boxes share any area at all?é   r   é   é   )ÚminÚmax)Úoner}   s     r3   r|   r|   6  sZ   € äˆs�1‰v�u˜Q‘xÓ ¤3 s¨1¡v¨u°Q©xÓ#8Ñ8×j¼SÀÀQÁÈÈqÉÓ=RÔUXÐY\Ð]^ÑY_ÐafÐghÑaiÓUjÑ=jÐjrŠ   c                óV  • UR                  UR                  =(       d    S5      nUR                  UR                  =(       d    S5      nUb+  Ub(  UR                  =(       d    SR	                  5       (       d-  UR                  SUR                   SUR                   S35        g[        R                  " SUR                  UR                  UR                  5        U R                  [        UR                  5      UR                  (       a  UR                  S   OSS9n	[        X	X…5        g)	a(  Put a table the parse filed as a picture into the document as a table.

The parse detected the region and called it a picture. The scan read it and
returned a grid, so the page prints a table and the document should hold one.
It is added rather than swapped in, because the picture is a real element and
the printed image is what the values were read from.

Nothing else about it is special. The body is the corrected grid every other
scanned table carries, attached the same way, on a provenance box taken from
the picture the table was printed over.
r`   Nr,   z%: the scan read a table over picture zm, which the parse holds no table for, and the grid produced no body; the values are in the table records onlyzDTable graft: page {} adding the scan's reading of {} as a table ({})r   )rj   r>   )rB   re   ra   rg   rh   rA   rC   r   ri   Ú	add_tabler!   r>   r    )
rN   r2   rp   ro   rl   rP   rW   r0   rr   rq   s
             r3   rf   rf   ;  sú   € ð( �n‰n˜W×0Ñ0×6°BÓ7€GØ—	‘	˜'×*Ñ*×0¨bÓ1€IØ�˜)Ñ+°I×4FÑ4F×4LÈ"×3SÑ3S×3UÑ3UØ�‰Ø�D—I‘I�;ÐCÀG×DWÑDWÐCXð Yð ô	
ð
 	Ü
‡K‚KØNØ�	‰	Ø×ÑØ×Ñô	ð ×#Ñ#Ü# I×$6Ñ$6Ó7Ø '§§ˆW�\‰\˜!Š_°$ð $ð €Jô �x¨YÕBrŠ   c                ól  • / nU Ha  nUR                    HN  nUR                  U 5      n[        U[        5      (       d  M+  UR                  U;  d  M=  UR                  U5        MP     Mc     U(       d  g[        R                  " S[        U5      [        U5      5        U R                  US9  [        U5      $ )ui  Remove the text the parse pulled out of a picture the scan has now read.

A picture the parse detected carries the fragments it managed to lift off the
image as its own children â€” a chart's plotted labels arrive as `$0.05`,
`$0.02`, `$0.06`, bare numbers with nothing saying which series or which year
they belong to. Once the scan has read the figure, those fragments are the
same region read worse, and keeping them puts two readings of one chart in
the document with only one of them saying what the numbers mean.

An item whose label is in `preserve` stays: it is native page text with a
role the parse named, not a reading of the figure.

This is the same replacement a table gets. A table read off a page image has
its body replaced rather than doubled, for the same reason and with the same
justification: the raw response is on disk, so nothing is unrecoverable.
r   z`Figure graft: removing {} text fragment(s) the parse lifted from {} picture(s) the scan has read©Ú
node_items)
ÚchildrenÚresolveÚ
isinstancer   ÚlabelrA   r   ri   ÚlenÚdelete_items)rN   r=   rS   Údoomedr0   ÚchildÚitems          r3   rM   rM   e  s—   € ð* €FÛˆØ×%Ô%ˆEØ—=‘= Ó*ˆDÜ˜$¤×)Ó)¨d¯j©jÀÕ.HØ—‘˜dÖ#ó &ñ ö
 ØÜ
‡K‚KØjÜˆF‹ÜˆH‹ôð
 ×Ñ VÐÑ,Üˆv‹;ÐrŠ   c                ó´  ^^^^• UU4S jU 5        VVs/ s H  u  pVU(       d  M  XV4PM     nnn[        U5       VVV	s0 s H  u  nu  pYUR                  U_M     sn	nnm0 n
0 n[        U 5       H¦  u  pŒ[        UR                  5      nUc  M  U H�  u  pï[	        [        Xß5      [        Xý5      5      nUU:¼  d  M+  U
R                  UR                  / 5      R                  U5        UR                  U/ 5      R                  UR                  5        Mƒ     M¨     [        U 5       VVs/ s H  u  pŒX‹;  d  M  UPM     nnnU VV	s0 s H  u  pYUR                  U_M     sn	nm/ n[        5       n[        5       nU GH:  u  nnUR                  U;   d  UR                  U
;  a  M)  UR                  1n[        5       nUR                  /nU(       aŽ  UR                  5       nU
R                  U/ 5       H_  nUU;   a  M  UR                  U5        UR                  U/ 5       H-  nUU;  d  M  UR                  U5        UR                  U5        M/     Ma     U(       a  MŽ  UU-  nUU-  nUR                  [        U4S jU 5       U4S jS9[        [        U5       Vs/ s H  o€U   PM	     sn5      45        GM=     UU4$ s  snnf s  sn	nnf s  snnf s  sn	nf s  snf )uÑ  Group figures and pictures that overlap into regions, one region per subject.

Every figure is scored against every picture before anything is grouped, so
the order the figures arrive in never decides an assignment. Overlap is
transitive: a figure joins every picture it overlaps and a picture joins every
figure that overlaps it, and the connected result is one region. A region can
then hold any mix â€” one to one, one picture the scan read as several figures,
several pictures the scan read as one figure, or a tangle of both.

Returns the regions in the pictures' document order, each region's pictures in
document order and its figures in reading order, plus the figures that overlap
no picture past the threshold.
c              3  ó@   >#   • U  H  o[        UTT5      4v •  M     g 7fr.   )r   )r/   rn   r<   r;   s     €€r3   r4   Ú_regions.<locals>.<genexpr>Ÿ  s   øé € Ð$YÊjÈ¬°!°U¸FÓ)CÕ%DÊjùs   ƒc              3  ó.   >#   • U  H
  nTU   v •  M     g 7fr.   r'   )r/   Úrrm   s     €r3   r4   r¢   Ê  s   øé € Ð0ª4 a˜˜qž	ª4ùs   ƒc                ó"   >• TU R                      $ r.   ©rc   )rn   Úorders    €r3   Ú<lambda>Ú_regions.<locals>.<lambda>Ê  s   ø€ ÀÀaÇjÁjÒ@QrŠ   ©Úkey)Ú	enumeraterc   r   rF   r�   r   r?   rA   ÚsetÚpoprB   ÚaddÚsortedÚ_reading_order)rE   rY   r;   r<   rQ   rn   rF   ÚboxedÚiÚ_bÚoverÚunderr1   Úcboxr0   ÚpboxÚcovr[   rZ   Úseen_picturesÚseen_chartsÚ_boxÚrefsÚidxsÚfrontierÚrefr}   rm   r§   s     ``                       @@r3   rD   rD   ‹  sƒ  û€ õ( %ZÉjÔ$YÔaÒ$Y™&˜!Ô]`‹Xˆa‹XÑ$Y€EÑaÜ-6°uÔ-=Õ>Ò-=™z˜q¡' 1ˆQ�Z‰Z˜Š]Ñ-=Ó>€Eð "$€DØ"$€EÜ˜gÖ&‰ˆÜ˜Ÿ	™	Ó"ˆØ‰<ÙÛ"‰MˆGÜÔ'¨Ó3Ô5FÀtÓ5RÓSˆCØ�nÕ$Ø—‘ × 0Ñ 0°"Ó5×<Ñ<¸QÔ?Ø× Ñ   BÓ'×.Ñ.¨w×/?Ñ/?Ö@ó	 #ñ	 'ô (1°Ô'9ÔLÒ'9™8˜1¸Q¹^—Ñ'9€IÑLá).Ô/ª¡ ˆa�j‰j˜!Šm©Ò/€FØBD€GÜ!›e€MÜ›E€KÜ‰ˆ�Ø×Ñ˜}Ó,°×0@Ñ0@ÈÓ0LÙà× Ñ Ð!ˆÜ›ˆØ×$Ñ$Ð%ˆÞØ—,‘,“.ˆCØ—X‘X˜c 2Ö&�Ø˜“9ÙØ—‘˜”Ø"ŸY™Y q¨"Ö-�EØ DÕ(ØŸ™ œØ Ÿ™¨Ö.ó .ñ	 '÷ ˆhð 	˜ÑˆØ�tÑˆØ�‰äÔ0©4Ó0Ô6QÑRÜ´F¸4´LÓA²L¨q¨¤
±LÑAÓBð÷	
ñ' ð2 �IÐÐùó_ bùÜ>ùó Mùã/ùò4  Bs'   •J<¦J<¿KÄ'K	Ä6K	ÅKÊKc                ó   • SS jn[        XS9$ )zFFigures in the order the page prints them: down the page, then across.c                ór   • [        U R                  5      =(       d    Sn[        US   [        -  5      US   4$ )N)ç        rÃ   rÃ   rÃ   rŽ   r   )r   rF   ÚroundÚROW_BAND)r1   rF   s     r3   r«   Ú_reading_order.<locals>.keyÔ  s3   € Ü�u—y‘yÓ!×9Ð%9ˆÜ�c˜!‘fœxÑ'Ó(¨#¨a©&Ð1Ð1rŠ   rª   )r1   r   ÚreturnzTuple[int, float])r°   )rE   r«   s     r3   r±   r±   Ñ  s   € ô2ô �'Ñ#Ð#rŠ   c                ó¢   • U  VVs/ s H  n[        U5        H  o"PM     M     nnn[        U5      =(       a    [        S U 5       5      $ s  snnf )uÁ  True when the parse called every picture in the region page furniture.

A logo or an icon is the same mark on every page of a deck, and the scan
describes it as readily as it describes a chart. The parse's class is the
signal for what a picture is, and it is trusted here rather than reading the
scan's description to guess â€” one is a prediction the parse already made and
published, the other is a rule written against prose with no fixed shape.
c              3  ó2   #   • U  H  o[         ;   v •  M     g 7fr.   rv   rw   s     r3   r4   Ú _is_furniture.<locals>.<genexpr>å  s   é € Ð IÂ¸AÔ&7Ö!7Âùrz   )r   Úboolr€   )r=   r0   rx   rˆ   s       r3   rH   rH   Û  sF   € ñ !)ÔK¢�W´/À'×2J¨QŠqÑ2J‰q¡€GÑKÜ�‹=×IœSÑ IÁÓ IÓIÐIùó Ls   †Ac                ó   • [         R                  " SU R                  [        U5      SR	                  [        U VVs1 s H  n[        U5        H  oDiM     M     snn5      5      5        U H/  nXPR                  ;   d  M  U R                  R                  U5        M1     U R                  (       d  U R                  S:X  a  SU l	        gggs  snnf )aE  Drop the records for a region the parse called page furniture.

The scan read the region and was right about it, so nothing is being
corrected. The record is dropped because a description of a wordmark is not
document content, and keeping it would put a figure on every page of a branded
deck and count it among the figures.
zDFigure graft: page {} dropping {} record(s) over page furniture ({})r~   rE   ÚemptyN)
r   ri   rC   r›   r…   r°   r   rE   ÚremoveÚstatus)r2   rE   r=   rn   rx   r1   s         r3   rI   rI   è  sŸ   € ô ‡K‚KØNØ�	‰	ÜˆG‹Ø�	‰	”&¡XÔJ¢X ´Àq×7I°!š!Ñ7I™!¡XÒJÓKÓLô	ó ˆØ—L‘LÕ Ø�L‰L×Ñ Ö&ñ ð �<�<˜DŸK™K¨9Ó4Øˆ�ð 5ˆ<ùó Ks   ¼C
c                ó0  • US   nUR                   nUR                  b  UR                  R                  O[        n	[	        S U 5       5      n
[        U5      S:„  =(       d    [        U5      S:„  nU(       d  XrS   4/$ [        U5      S:”  ah  [        R                  " SUR                  SR                  S U 5       5      [        U5      UR                  5        U R                  [        USS 5      S9  [        U5      [        U5      :”  a@  [        R                  " S	UR                  UR                  [        U5      [        U5      5        [        US   UR                  XE5      /Ul        U
(       a  [        XcR                  US   U	5      OSUl        XrS   4/nUnUSS  Ho  nU R!                  U[        XãR                  XE5      U
(       a  [        XcR                  Xé5      OSS
S9nUb  UR#                  S
S9Ul         UR%                  XÞ45        Mq     U$ )uµ  Make the region hold one picture per figure the scan returned.

The scan is the authority on how many figures a region holds and where each
one sits. It looked at the page, and the box it draws is already a source
coordinate, so the parse's count yields to it in both directions: a picture
the scan read as several figures becomes several, and several pictures the
scan read as one figure become one. A region already agreeing is returned
unchanged.

The first picture in document order survives, so the reading-order position
the parse gave the region is kept, and any others are removed. Extra figures
are inserted behind the survivor. Each resulting picture carries the parse's
class prediction for the region.

Only a region whose shape actually changed takes the scan's boxes, and its
bitmaps are then cut again from those boxes, because a bitmap cut to the old
boundary depicts a region that is no longer an element. A region the two sides
already agree on keeps the box and bitmap the parse measured â€” there is nothing
to correct, and replacing them would discard a good crop for no gain.

Returns the picture paired with its figure, for the caller to attach once
every region has been reshaped.
r   Nc              3  ó<   #   • U  H  oR                   S Lv •  M     g 7fr.   )Úimage©r/   rn   s     r3   r4   Ú_reshape.<locals>.<genexpr>   s   é € Ð=²H¨q—w‘w dÕ*²Hùs   ‚rŽ   zGFigure graft: page {} the scan read {} as {} figure(s); merging into {}r~   c              3  ó8   #   • U  H  oR                   v •  M     g 7fr.   r¦   rÓ   s     r3   r4   rÔ   )  s   é € Ð3ª( Q—j–jª(ùs   ‚r•   zeFigure graft: page {} picture {} covers {} figures the scan returned separately; splitting it into {}T)Úsiblingr>   rÒ   Úafterr)   )r�   rÒ   ÚdpiÚDEFAULT_CROP_DPIr„   r›   r   ri   rC   r…   rc   rœ   ÚlistÚ_provr>   Ú_cropÚinsert_picturer6   rA   )rN   r=   rE   r2   r;   r<   rR   ÚsurvivorÚtemplate_metarØ   Úwanted_imageÚreshapedrX   Úanchorr1   s                  r3   rK   rK   ý  sÝ  € ð@ ˜‰{€HØ—M‘M€MØ (§¡Ñ :ˆ(�.‰.×
Ò
Ô@P€CÜÑ=±HÓ=Ó=€LÜ�8‹}˜qÑ ×4¤C¨£L°1Ñ$4€HÞØ 1™:Ð&Ð'Ð'ä
ˆ8ƒ}�qÓÜ�ŠØUØ�I‰IØ�I‰IÑ3©(Ó3Ó3Ü�‹LØ×Ñô	
ð 	×Ñ¬¨h°q°r¨lÓ);ÐÑ<Ü
ˆ7ƒ|”c˜(“mÓ#Ü�Šð#à�I‰IØ×ÑÜ�‹LÜ�‹Lô	
ô ˜7 1™: t§y¡y°%Ó@ÐA€H„MÞBN”U˜6§9¡9¨g°a©j¸#Ô>ÐTX€H„NØ ™
Ð#Ð$€Eà"€FØ˜˜“ˆØ×(Ñ(ØÜ�uŸi™i¨Ó7Þ:F”%˜§	¡	¨5Ô6ÈDØð	 )ð 
ˆð Ñ$Ø'×2Ñ2¸Ð2Ð=ˆFŒKØ�‰�f�_Ö%ñ ð €LrŠ   c           	     óf  • [        UR                  5      nU b  Uc)  [        R                  " SUUR                  U c  SOS5        g [
        R                  " [        XXC5      US9$ ! [         aA  n[        R                  " SUUR                  [        U5      R                  U5         SnAgSnAff = f)a.  The part's own bitmap, cut from the page at the resolution the parse used.

Returns None when there is no source to cut from or the cut fails, so a split
still happens and the part carries a box with no bitmap rather than one that
depicts the wrong region. Either way the loss is logged, never silent.
NzIFigure graft: page {} figure {} keeps no bitmap ({}); its box is recordedzno source document to cut fromzthe scan returned no box)rÒ   rØ   zYFigure graft: page {} figure {} keeps no bitmap; cutting it from the page failed ({}: {}))r   rF   r   ÚwarningÚchunk_idr   Úfrom_pilr"   Ú	ExceptionÚtypeÚ__name__)rR   rC   r1   rØ   rF   Úexcs         r3   rÜ   rÜ   J  s¢   € ô �5—9‘9Ó
€CØ�~˜™Ü�ŠØWØØ�N‰NØ06±Ñ,ÐD^ô		
ð ð
Ü× Ò ¤}°VÀ3Ó'LÐRUÑVÐVøÜó Ü�ŠØgØØ�N‰NÜ�‹I×ÑØô	
ô ûðús   ÁA% Á%
B0Á/7B+Â+B0c                ój  • U R                   =(       d
    [        5       nUR                  S[        UR                  [
        S9SUR                  SUR                  SUR                  SUR                  [        / [        U[        S5      =(       d    / Q[        / S.P0S	9U l         U R                  Ul        g)
u³  Carry the figure's text and the scan's identity onto one picture.

Both ride on `meta`. The text goes in its description field, the document
model's own place for what a picture depicts, and the scan's identity goes in
alongside â€” the meta model allows extra fields, so they serialize with the
document. The picture's existing metadata, its class prediction included, is
kept. The record is given this picture's reference in return.
r‚   )rƒ   Ú
created_byÚquber__figure_job_idÚquber__figure_modelÚquber__figure_versionÚquber__figure_chunk_idN)ÚreaderÚproduced)Úupdate)r�   r   r6   r   rƒ   ÚDESCRIPTION_AUTHORrG   ÚmodelÚversionrå   r   ÚgetattrÚADErc   re   )r0   r1   r2   Úbases       r3   rL   rL   g  s™   € ð �<‰<×(œ;›=€DØ—?‘?àÔ/°U·Z±ZÔL^Ñ_Ø" D§K¡KØ! 4§:¡:Ø# T§\¡\Ø$ e§n¡nÜÐiœg d¬M¸4Ó@×FÀBÐiÔTWÐegÑIhÐið
ð #ð 	€G„Lð  ×(Ñ(€EÕrŠ   c                ó®   • [        U R                  5      =(       d    Su  pEpg[        XB-  Xb-  SU-
  U-  SU-
  U-  [        R                  S9n[        XSS9$ )zBA provenance record for one figure, its box in bottom-left points.)rÃ   rÃ   ç      ð?rû   rû   )Úlr¤   rk   ÚbÚcoord_origin)r   r   )r@   ÚbboxÚcharspan)r   rF   r
   r   Ú
BOTTOMLEFTr   )	r1   rC   r;   r<   Úx1Úy1Úx2Úy2rÿ   s	            r3   rÛ   rÛ   ~  s^   € ä˜eŸi™iÓ(×@Ð,@�N€BˆBÜØ
‰*Ø
‰*Ø�‰8�vÑ
Ø�‰8�vÑ
Ü ×+Ñ+ñ€Dô  $¸FÑCÐCrŠ   )rN   r   rO   úList[PageScan]rP   z(Optional[Dict[int, Tuple[float, float]]]rQ   ÚfloatrR   úOptional[Path]rS   úCollection[DocItemLabel]rÇ   z!Tuple[DoclingDocument, List[str]])
rN   r   rO   r  rb   zList[ExtractedTable]rP   úDict[int, Tuple[float, float]]rÇ   ú	List[str])rN   r   rP   r
  rÇ   r  )r‘   r   r}   r   rÇ   rË   )rN   r   r2   r   rp   r   ro   zDict[str, PictureItem]rl   zDict[str, ExtractedTable]rP   r
  rW   r  rÇ   ÚNone)r'   )rN   r   r=   úList[PictureItem]rS   r	  rÇ   Úint)rE   úList[FigureRecord]rY   r  r;   r  r<   r  rQ   r  rÇ   zMTuple[List[Tuple[List[PictureItem], List[FigureRecord]]], List[FigureRecord]])rE   r  rÇ   r  )r=   r  rÇ   rË   )r2   r   rE   r  r=   r  rÇ   r  )rN   r   r=   r  rE   r  r2   r   r;   r  r<   r  rR   r  rÇ   z&List[Tuple[PictureItem, FigureRecord]])
rR   r  rC   r  r1   r   rØ   r  rÇ   zOptional[ImageRef])r0   r   r1   r   r2   r   rÇ   r  )
r1   r   rC   r  r;   r  r<   r  rÇ   r   )FÚ__doc__Ú
__future__r   Úpathlibr   Útypingr   r   r   r   r	   Údocling_core.types.doc.baser
   r   Ú"docling_core.types.doc.common.metar   Ú'docling_core.types.doc.common.referencer   r   Údocling_core.types.doc.documentr   r   r   r   Údocling_core.types.doc.labelsr   Úlogurur   Úquber.core.extractors.baser   Ú5quber.core.extractors.camelot.correspondence.geometryr   Úquber.core.figures.geometryr   r   r   Úquber.core.figures.modelsr   r   r   Úquber.core.figures.nominater   r   Úquber.core.fusion.graftr   r    r!   Úquber.files.pdfr"   ÚMATCH_FRACTIONrÅ   rô   rø   ÚFOOTNOTE_MARKS_FIELDÚFOOTNOTES_FIELDrÙ   r^   rs   r‰   r|   rf   rM   rD   r±   rH   rI   rK   rÜ   rL   rÛ   r'   rŠ   r3   Ú<module>r$     sƒ  ðñ;õz #å ß :Õ :ç @Ý Cß Lß _Ó _Ý 6Ý å 5Ý Sß CÑ Cß JÑ Jß Jß ]Ñ ]Ý )ð €ð
 €ð (Ð ð €ð /Ð ð %€ð
 Ð ð ;?Ø*Ø!Ø)+ðFØðFàðFð 8ðFð ð	Fð
 ðFð 'ðFð 'õFðR<Øð<àð<ð !ð<ð .ð	<ð
 ô<ð~4Øð4à-ð4ð ô4ônkð
'CØð'Cà
ð'Cð ð'Cð 'ð	'Cð
 %ð'Cð .ð'Cð ð'Cð 
ô'CðZ *,ð#Øð#àð#ð 'ð#ð 	õ	#ðLCØðCà!ðCð ðCð ð	Cð
 ðCð SôCôL$ô
Jôð*JØðJàðJð  ðJð ð	Jð
 ðJð ðJð ðJð ,ôJôZô:)õ.
DrŠ   