§
    �’j“  ã                   ó~  — d Z ddlZddlZddlZdZd„ Zd„ Zd„ Zd„ Zd„ Z	d	„ Z
d
„ Zddœd„Zd„ Zd„ Zddœd„Zd„ Zd„ Zd„ Zd„ Zd„ Z	 dCdddddœd„Zd„ Zd„ Zd„ Zd d!d"d#d$œd%„Zd&„ Zdd'œd(„Zddd)œd*„Zd d!d"d#dd+œd,„Zd-„ Zd.„ Zd/„ Z d0„ Z!d1„ Z"d2„ Z#d3„ Z$d4d5d6œd7„Z%d4d8d5d9œd:„Z&dd;œd<„Z'd5d4d8d=œd>„Z(dd5d?œd@„Z)dA„ Z*dB„ Z+dS )Da  
Copyright (C) 2023 Artifex Software, Inc.

This file is part of PyMuPDF.

PyMuPDF is free software: you can redistribute it and/or modify it under the
terms of the GNU Affero General Public License as published by the Free
Software Foundation, either version 3 of the License, or (at your option)
any later version.

PyMuPDF is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more
details.

You should have received a copy of the GNU Affero General Public License
along with MuPDF. If not, see <https://www.gnu.org/licenses/agpl-3.0.en.html>

Alternative licensing terms are available from the licensor.
For commercial licensing, see <https://www.artifex.com/> or contact
Artifex Software, Inc., 39 Mesa Street, Suite 108A, San Francisco,
CA 94129, USA, for further information.

---------------------------------------------------------------------

PyMuPDF table grid refinement (opt-in extension).

Provides the refine_grid / refine_grid_structure / refine_grid_rows API that
refines a detected table's cell grid using page text and vector-graphics
geometry. Re-exported by pymupdf.table; never runs on the default
find_tables() path.
é    Ng      @c           
      óR  — g }|                       d¦  «        }|                     dg ¦  «        D ]ø}|                     d¦  «        dk    rŒ|                     dg ¦  «        D ]Å}|                     d¦  «        }|                     d¦  «        }|                     dg ¦  «        D ]‚}d	                     d
„ |                     dg ¦  «        D ¦   «         ¦  «        }|                     ¦   «         sŒJ|                     d„ |                     dg ¦  «        D ¦   «         |||dœ¦  «         ŒƒŒÆŒù|S )a
  Flattened rawdict text spans carrying line-direction metadata.

    Only used to locate vertical/rotated text so those words can be replaced by
    span-level bboxes in _refine_page_words. Minimal fields (bbox/text/dir/wmode)
    -- the only ones the consumers read.ÚrawdictÚblocksÚtyper   ÚlinesÚdirÚwmodeÚspansÚ c              3   ó\   K  — | ]'}t          |                     d d¦  «        ¦  «        V — Œ(dS )Úcr   N)ÚstrÚget©Ú.0Úchars     úCC:\Projects\DSCons\.venv\Lib\site-packages\pymupdf\_table_refine.pyú	<genexpr>z(_refine_rawdict_spans.<locals>.<genexpr>F   s8   è è € ÐXÐX¸$�s 4§8¢8¨C°Ñ#4Ô#4Ñ5Ô5ÐXÐXÐXÐXÐXÐXó    Úcharsc                 ó,   — g | ]}t          |¦  «        ‘ŒS © ©Úfloat)r   Úvs     r   ú
<listcomp>z)_refine_rawdict_spans.<locals>.<listcomp>K   s   € Ð HÐ HÐ H¨a¥ q¡¤Ð HÐ HÐ Hr   Úbbox)r   Útextr   r	   )Úget_textr   ÚjoinÚstripÚappend)	Úpager
   ÚrawÚblockÚlineÚ	directionr	   Úspanr   s	            r   Ú_refine_rawdict_spansr)   7   sK  € ð €EØ
�-Š-˜	Ñ
"Ô
"€CØ—’˜ 2Ñ&Ô&ð ð ˆØ�9Š9�VÑÔ Ò!Ð!ØØ—I’I˜g rÑ*Ô*ð 	ð 	ˆDØŸš ™œˆIØ—H’H˜WÑ%Ô%ˆEØŸš ¨"Ñ-Ô-ð ð �Ø—w’wÐXÐXÀ$Ç(Â(È7ÐTVÑBWÔBWÐXÑXÔXÑXÔX�Ø—z’z‘|”|ð ØØ—’à HÐ H°4·8²8¸FÀBÑ3GÔ3GÐ HÑ HÔ HØ $Ø(Ø!&ð	ð ñô ð ð ð	ð	ð €Lr   c                 óˆ  — |                       d¦  «        dvrdS |                       d¦  «        }t          |t          t          f¦  «        rt	          |¦  «        dk     rdS 	 t          t          |d         ¦  «        ¦  «        }t          t          |d         ¦  «        ¦  «        }n# t          t          f$ r Y dS w xY w||k    S )	zÈTrue when a rawdict span's direction indicates non-horizontal text flow.

    wmode != 0 is vertical; otherwise compare |dir_x| vs |dir_y| (a missing or
    unparsable direction counts as horizontal).r	   ©Nr   Tr   é   Fr   é   )	r   Ú
isinstanceÚlistÚtupleÚlenÚabsr   Ú	TypeErrorÚ
ValueError)r(   r'   ÚdxÚdys       r   Ú_refine_is_vertical_or_rotatedr7   T   sÃ   € ð
 ‡x‚x�ÑÔ 	Ð)Ð)ØˆtØ—’˜‘”€IÝ�i¥$­ Ñ/Ô/ð µ3°y±>´>ÀAÒ3EÐ3EØˆuðÝ•�y ”|Ñ$Ô$Ñ%Ô%ˆÝ•�y ”|Ñ$Ô$Ñ%Ô%ˆˆøÝ•zÐ"ð ð ð Øˆuˆuðøøøà�Š7€Ns   Á!AB& Â&B;Â:B;c                 ó  ‡— t          | dd¦  «        }|�|S d„ |                      d¦  «        D ¦   «         }d„ t          | ¦  «        D ¦   «         }|�rd„ |D ¦   «         }g }|D ]\}|\  }}}	}
}t          j        ||	z   dz  ||
z   dz  ¦  «        Št          ˆfd„|D ¦   «         ¦  «        rŒG|                     |¦  «         Œ]t          ||¦  «        D ]‚\  }}|j        rŒ|                     t          |j
        ¦  «        t          |j        ¦  «        t          |j        ¦  «        t          |j        ¦  «        t          |d	         ¦  «        f¦  «         Œƒt          |d
„ ¬¦  «        }	 t!          | d|¦  «         n# t"          $ r Y nw xY w|S )a1  Center-point word list for grid refinement, cached on the page object.

    Extract page words once (page.get_text("words")), then substitute vertical/
    rotated text: any horizontal word whose center falls inside a rotated span's
    bbox is dropped, and each rotated span is appended as a single word.Ú_refine_words_cacheNc           
      ó(  — g | ]�}t          |d          ¦  «                             ¦   «         ¯)t          |d         ¦  «        t          |d         ¦  «        t          |d         ¦  «        t          |d         ¦  «        t          |d          ¦  «        f‘Œ�S )é   r   r-   r,   é   )r   r!   r   )r   Úws     r   r   z&_refine_page_words.<locals>.<listcomp>o   s   € ð ð ð àÝˆq�Œt‰9Œ9�?Š?ÑÔðÝ	ˆq�Œt‰Œ•e˜A˜aœD‘k”k¥5¨¨1¬¡;¤;µ°a¸´d±´½SÀÀ1Ä¹Y¼YÐGðð ð r   Úwordsc                 óœ   — g | ]I}t          |¦  «        ¯t          |                     d ¦  «        pd¦  «                             ¦   «         ¯G|‘ŒJS )r   r   )r7   r   r   r!   ©r   r(   s     r   r   z&_refine_page_words.<locals>.<listcomp>t   se   € ð ð ð àÝ)¨$Ñ/Ô/ðõ 58¸¿ºÀÑ8HÔ8HÐ8NÈBÑ4OÔ4O×4UÒ4UÑ4WÔ4WðØðð ð r   c                 ó`   — g | ]+}t          j        |                     d ¦  «        pg ¦  «        ‘Œ,S )r   )ÚpymupdfÚRectr   r@   s     r   r   z&_refine_page_words.<locals>.<listcomp>z   s3   € ÐXÐXÐXÀ$�œ d§h¢h¨vÑ&6Ô&6Ð&<¸"Ñ=Ô=ÐXÐXÐXr   ç      à?c              3   óP   •K  — | ] }|j         °	|                     ‰¦  «        V — Œ!d S ©N)Úis_emptyÚcontains)r   ÚrectÚcenters     €r   r   z%_refine_page_words.<locals>.<genexpr>   s6   øè è € ÐXÐX¨TÈ$Ì-ÐX�4—=’= Ñ(Ô(ÐXÐXÐXÐXÐXÐXr   r   c                 ó"   — | d         | d         fS ©Nr-   r   r   ©Úitems    r   ú<lambda>z$_refine_page_words.<locals>.<lambda>ˆ   s   € ¨t°A¬w¸¸Q¼Ð.@€ r   ©Úkey)Úgetattrr   r)   rB   ÚPointÚanyr"   ÚziprG   r   Úx0Úy0Úx1Úy1r   ÚsortedÚsetattrÚ	Exception)r#   Úcacher>   Úrotated_spansÚrotated_rectsÚkeptÚwordÚwx0Úwy0Úwx1Úwy1Ú_r(   rI   rJ   s                 @r   Ú_refine_page_wordsrg   f   sï  ø€ õ �DÐ/°Ñ6Ô6€EØÐØˆðð à—’˜wÑ'Ô'ðñ ô €Eð
ð å)¨$Ñ/Ô/ðñ ô €Mð
 ñ BØXÐXÈ-ÐXÑXÔXˆØˆØð 	ð 	ˆDØ$(Ñ!ˆC��c˜3 Ý”] C¨#¡I°Ñ#4°s¸S±yÀCÑ6GÑHÔHˆFÝÐXÐXÐXÐX°]ÐXÑXÔXÑXÔXð ØØ�KŠK˜ÑÔÐÐÝ˜m¨]Ñ;Ô;ð 	ð 	‰JˆD�$ØŒ}ð ØØ�KŠKÝ�t”w‘”¥ t¤w¡¤µ°t´w±´ÅÀtÄwÁÄÕQTÐUYÐZ`ÔUaÑQbÔQbÐcñô ð ð õ �tÐ!@Ð!@ÐAÑAÔAˆðÝ�Ð+¨UÑ3Ô3Ð3Ð3øÝð ð ð Øˆðøøøà€Ls   Å%E7 Å7
FÆFc                 ób   — | |z   dz  }||z   dz  }	||cxk    o|k    nc o||	cxk    o|k    nc S )z‹Word-to-cell membership by CENTER point (inclusive), not clip-overlap.

    A word straddling a column line is claimed by exactly one cell.rD   r   )
rb   rc   rd   re   rV   rW   rX   rY   ÚcxÚcys
             r   Ú_refine_word_in_rectrk   �   sS   € ð �‰)�sÑ	€BØ
�‰)�sÑ	€BØ�ˆ>ˆ>Š>ˆ>�rŠ>ˆ>ˆ>ˆ>Ð,˜b B˜n˜nšn˜n¨"šn˜n˜n˜nÐ,r   c                 óì   ‡‡‡‡— t          |j        ¦  «        t          |j        ¦  «        t          |j        ¦  «        t          |j        ¦  «        f\  ŠŠŠŠˆˆˆˆfd„t          | ¦  «        D ¦   «         S )zGPage words whose center lies in rect, as (x0, y0, x1, y1, text) tuples.c                 óV   •— g | ]%\  }}}}}t          ||||‰‰‰‰	¦  «        ¯|||||f‘Œ&S r   )rk   )
r   rb   rc   rd   re   r   rV   rX   rW   rY   s
         €€€€r   r   z)_refine_words_in_rect.<locals>.<listcomp>œ   sZ   ø€ ð ð ð á$ˆC��c˜3 Ý  S¨#¨s°B¸¸BÀÑCÔCðØ	ˆc�3˜˜TÐ"ðð ð r   )r   rV   rW   rX   rY   rg   )r#   rI   rV   rX   rW   rY   s     @@@@r   Ú_refine_words_in_rectrn   ™   s~   øøøø€ å˜4œ7‘^”^¥U¨4¬7¡^¤^µU¸4¼7±^´^ÅUÈ4Ì7Á^Ä^ÐS�N€BˆˆB�ðð ð ð ð ð ð å(:¸4Ñ(@Ô(@ðñ ô ð r   c                 ój   — t          t          j        d|                      ¦   «         ¦  «        ¦  «        S )z8Loose value-like predicate: the text contains any digit.ú\d)ÚboolÚreÚsearchr!   ©r   s    r   Ú_refine_has_digitru   £   s$   € å•”	˜% §¢¡¤Ñ.Ô.Ñ/Ô/Ð/r   c                 ó¢   — |                       ¦   «         }t          t          j        d|¦  «        ¦  «        ot	          d„ |D ¦   «         ¦  «         S )z=Strict value-like predicate: contains a digit and no letters.rp   c              3   ó>   K  — | ]}|                      ¦   «         V — Œd S rF   )Úisalphar   s     r   r   z-_refine_has_digit_no_alpha.<locals>.<genexpr>«   s*   è è € Ð7\Ð7\È4¸¿º¹¼Ð7\Ð7\Ð7\Ð7\Ð7\Ð7\r   )r!   rq   rr   rs   rT   )r   Ústrippeds     r   Ú_refine_has_digit_no_alpharz   ¨   sI   € à�zŠz‰|Œ|€HÝ•”	˜% Ñ*Ô*Ñ+Ô+Ð\µCÐ7\Ð7\ÐS[Ð7\Ñ7\Ô7\Ñ4\Ô4\Ð0\Ð\r   çffffffî?)Ú	thresholdc                ó¾   — | €dS 	 | d d…         \  }}}n# t           $ r Y dS w xY wt          |¦  «        |k    o%t          |¦  «        |k    ot          |¦  «        |k    S )NTr<   )r\   r   )Úfillr|   ÚrÚgÚbs        r   Ú_refine_is_whiter‚   ¯   sy   € Ø€|ØˆtðØ�r˜�r”(‰ˆˆ1ˆaˆaøÝð ð ð Øˆtˆtðøøøå�‰8Œ8�iÒÐQ¥E¨!¡H¤H¨yÒ$8ÐQ½UÀ1¹X¼XÈ	Ò=QÐQs   † •
#¢#c                 óÜ   — |�t          j        |¦  «        }|j        s|S d„ | D ¦   «         }|sd S t          j        |d         ¦  «        }|dd …         D ]}|                     |¦  «         Œ|S )Nc                 óv   — g | ]6}|D ]1}|®t          j        |¦  «        j        °t          j        |¦  «        ‘Œ2Œ7S rF   )rB   rC   rG   ©r   ÚrowÚcells      r   r   z&_refine_table_rect.<locals>.<listcomp>¾   s[   € ð ð ð àØðð ð ØÐ¥G¤L°Ñ$6Ô$6Ô$?Ðõ 	Œ�TÑÔð ÐÐÐr   r   r-   )rB   rC   rG   Úinclude_rect)ÚcellsÚ
table_bboxrI   ÚrectsrN   s        r   Ú_refine_table_rectrŒ   ¹   s™   € ØÐÝŒ|˜JÑ'Ô'ˆØŒ}ð 	ØˆKðð àðñ ô €Eð ð ØˆtÝŒ<˜˜aœÑ!Ô!€DØ�a�b�b”	ð  ð  ˆØ×Ò˜$ÑÔÐÐØ€Kr   c                óä  — g }t          | j        j        ¦  «        }|                      ¦   «         D ]¿}t	          |                     d¦  «        ¦  «        rŒ%|                     dg ¦  «        D ]ƒ}|d         dk    rŒt          j        |d         ¦  «        }|                     ¦   «          |j        d|z  k    rŒL|j        |k     s|j	        |k     rŒc||z  j
        rŒn|                     |¦  «         Œ„ŒÀ|S )Nr~   Úitemsr   rr   r-   r{   )r   rI   ÚwidthÚget_drawingsr‚   r   rB   rC   Ú	normalizeÚheightrG   r"   )r#   Ú
table_rectÚmin_dimÚoutÚ
page_widthÚdrawingrN   rI   s           r   Ú_refine_raw_shaded_rectsr˜   Ì   s  € Ø
€CÝ�t”y”Ñ'Ô'€JØ×$Ò$Ñ&Ô&ð ð ˆÝ˜GŸKšK¨Ñ/Ô/Ñ0Ô0ð 	ØØ—K’K ¨Ñ,Ô,ð 	ð 	ˆDØ�AŒw˜$ŠˆØÝ”<  Q¤Ñ(Ô(ˆDØ�NŠNÑÔÐØŒz˜T JÑ.Ò.Ð.ØØŒz˜GÒ#Ð# t¤{°WÒ'<Ð'<ØØ�zÑ!Ô+ð ØØ�JŠJ�tÑÔÐÐð	ð €Jr   gÍÌÌÌÌÌì?)Úcontain_fracc                óö   ‡‡‡‡— g }t          | ¦  «        D ]b\  ŠŠ‰                     ¦   «         Š‰dk    rŒ t          ˆˆˆˆfd„t          | ¦  «        D ¦   «         ¦  «        }|s|                     ‰¦  «         Œc|S )Nr   c              3   óœ   •K  — | ]F\  }}|‰k    o8‰|z                        ¦   «         ‰‰z  k    o|                      ¦   «         ‰d z  k    V — ŒGdS )gÍÌÌÌÌÌð?N)Úget_area)r   Úother_indexÚotherÚarear™   ÚindexrI   s      €€€€r   r   z0_refine_cell_background_rects.<locals>.<genexpr>ç   s   øè è € ð 
ð 
ñ #�˜Uð ˜5Ò ð /Ø˜‘×'Ò'Ñ)Ô)¨\¸DÑ-@Ò@ð/à—’Ñ Ô  4¨$¡;Ò.ð
ð 
ð 
ð 
ð 
ð 
r   )Ú	enumeraterœ   rT   r"   )Ú	raw_rectsr™   ÚkeepÚnestedrŸ   r    rI   s    `  @@@r   Ú_refine_cell_background_rectsr¥   á   s¯   øøøø€ Ø€DÝ  Ñ+Ô+ð ð ‰ˆˆtØ�}Š}‰ŒˆØ�1Š9ˆ9ØÝð 
ð 
ð 
ð 
ð 
ð 
ð 
õ '0°	Ñ&:Ô&:ð	
ñ 
ô 
ñ 
ô 
ˆð ð 	Ø�KŠK˜ÑÔÐøØ€Kr   c                óN  — g }g }t          | ¦  «        D ]\}|rC||d         z
  |k    r4|                     t          |¦  «        t          |¦  «        z  ¦  «         g }|                     |¦  «         Œ]|r2|                     t          |¦  «        t          |¦  «        z  ¦  «         |S )Néÿÿÿÿ)rZ   r"   Úsumr1   )ÚvaluesÚ	toleranceÚclustersÚcurrentÚvalues        r   Ú_refine_clusterr®   ò   s©   € Ø€HØ€GÝ˜‘”ð ð ˆØð 	�u˜w rœ{Ñ*¨YÒ6Ð6Ø�OŠO�C ™LœL­3¨w©<¬<Ñ7Ñ8Ô8Ð8ØˆGØ�Š�uÑÔÐÐØð 5Ø�Š�˜G™œ¥s¨7¡|¤|Ñ3Ñ4Ô4Ð4Ø€Or   c                 óÐ  — t          ¦   «         }t          ¦   «         }|                      ¦   «         D �]}|                     d¦  «        dv }|                     dg ¦  «        D �]å}|d         }|dk    �rY|d         |d         }	}t          |j        |	j        z
  ¦  «        dk     r„t          |j        |	j        z
  ¦  «        d	k    rd|j        d
z
  |j        |	j        z   dz  cxk     r|j        d
z   k     r7n n4|                     t          |j        |	j        z   dz  d¦  «        ¦  «         n£t          |j        |	j        z
  ¦  «        dk     rƒt          |j        |	j        z
  ¦  «        d	k    rc|j
        d
z
  |j        |	j        z   dz  cxk     r|j        d
z   k     r6n n3|                     t          |j        |	j        z   dz  d¦  «        ¦  «         �Œk|dk    r�Œst          j        |d         ¦  «        }
|
                     ¦   «          |
|z  j        r�Œ­|
j        d
k     r@|
j        d	k    r5|                     t          |
j        |
j        z   dz  d¦  «        ¦  «         �Œø|
j        d
k     r@|
j        d	k    r5|                     t          |
j
        |
j        z   dz  d¦  «        ¦  «         �ŒC|r |                     t          |
j        d¦  «        ¦  «         |                     t          |
j        d¦  «        ¦  «         |                     t          |
j
        d¦  «        ¦  «         |                     t          |
j        d¦  «        ¦  «         �Œç�Œt%          |¦  «        t%          |¦  «        fS )Nr   )ÚsÚfsrŽ   r   Úlr-   r,   ç      ð?g      $@ç       @rD   rr   )Úsetr�   r   r2   ÚyÚxrW   rY   ÚaddÚroundrV   rX   rB   rC   r‘   rG   r’   r�   rZ   )r#   r“   ÚxsÚysr—   ÚstrokedrN   ÚkindÚp1Úp2rI   s              r   Ú_refine_border_linesrÀ   ÿ   s3  € Ý	‰Œ€BÝ	‰Œ€BØ×$Ò$Ñ&Ô&ð !*ñ !*ˆØ—+’+˜fÑ%Ô%¨Ð4ˆØ—K’K ¨Ñ,Ô,ð 	*ñ 	*ˆDØ˜”7ˆDØ�sŠ{‰{Ø˜aœ $ q¤'�B�å˜œ˜rœt™Ñ$Ô$ sÒ*Ð*Ý˜BœD 2¤4™KÑ(Ô(¨4Ò/Ð/Ø"œ¨Ñ+¨r¬t°b´d©{¸cÑ.AÐWÐWÒWÐWÀJÄMÐTWÑDWÒWÐWÐWÐWÐWà—F’F�5 "¤$¨¬¡+°Ñ!4°aÑ8Ô8Ñ9Ô9Ð9Ð9å˜œ˜rœt™Ñ$Ô$ sÒ*Ð*Ý˜BœD 2¤4™KÑ(Ô(¨4Ò/Ð/Ø"œ¨Ñ+¨r¬t°b´d©{¸cÑ.AÐWÐWÒWÐWÀJÄMÐTWÑDWÒWÐWÐWÐWÐWà—F’F�5 "¤$¨¬¡+°Ñ!4°aÑ8Ô8Ñ9Ô9Ð9ÙØ�tŠ|ˆ|ÙÝ”<  Q¤Ñ(Ô(ˆDØ�NŠNÑÔÐØ�zÑ!Ô+ð ÙØŒ{˜SÒ Ð  T¤Z°$Ò%6Ð%6Ø—’•u˜dœg¨¬Ñ/°3Ñ6¸Ñ:Ô:Ñ;Ô;Ð;Ñ;Ø”˜cÒ!Ð! d¤k°DÒ&8Ð&8Ø—’•u˜dœg¨¬Ñ/°3Ñ6¸Ñ:Ô:Ñ;Ô;Ð;Ñ;Øð *Ø—’•u˜TœW aÑ(Ô(Ñ)Ô)Ð)Ø—’•u˜TœW aÑ(Ô(Ñ)Ô)Ð)Ø—’•u˜TœW aÑ(Ô(Ñ)Ô)Ð)Ø—’•u˜TœW aÑ(Ô(Ñ)Ô)Ð)ùñ?	*õ@ �"‰:Œ:•v˜b‘z”zÐ!Ð!r   c                ó$   ‡‡— ˆˆfd„| D ¦   «         S )Nc                 óN   •‡— g | ] Št          ˆˆfd „‰D ¦   «         ¦  «        °‰‘Œ!S )c              3   óD   •K  — | ]}t          ‰|z
  ¦  «        ‰k    V — Œd S rF   )r2   )r   ÚborderÚedgerª   s     €€r   r   z/_refine_drop_near.<locals>.<listcomp>.<genexpr>(  s5   øè è € Ð-dÐ-dÐRX­c°$¸±-Ñ.@Ô.@ÀIÒ.MÐ-dÐ-dÐ-dÐ-dÐ-dÐ-dr   ©rT   )r   rÅ   Úbordersrª   s    @€€r   r   z%_refine_drop_near.<locals>.<listcomp>(  s@   øø€ ÐeÐeÐe�T­#Ð-dÐ-dÐ-dÐ-dÐ-dÐ\cÐ-dÑ-dÔ-dÑ*dÔ*dÐeˆDÐeÐeÐer   r   )ÚedgesrÇ   rª   s    ``r   Ú_refine_drop_nearrÉ   '  s!   øø€ ØeÐeÐeÐeÐe˜UÐeÑeÔeÐer   c                óÞ   — | D ]i\  }}}}	}
t          |
¦  «                             ¦   «         sŒ*||z   dz  }||	z   dz  }||z   |cxk     r	||z
  k     rn ŒP||z   |cxk     r	||z
  k     rn Œf dS ŒjdS )NrD   TF)r   r!   )r>   rV   rW   rX   rY   Úmarginrb   rc   rd   re   r   ri   rj   s                r   Ú_refine_has_textrÌ   +  s³   € Ø$)ð ð Ñ ˆˆS�#�s˜DÝ�4‰yŒy�ŠÑ Ô ð 	ØØ�C‰i˜3ÑˆØ�C‰i˜3ÑˆØ�‰;˜Ð)Ð)Ò)Ð)˜b 6™kÒ)Ð)Ð)Ð)Ð)¨b°6©k¸BÐ.LÐ.LÒ.LÐ.LÀÀfÁÒ.LÐ.LÐ.LÐ.LÐ.LØ�4�4øØˆ5r   c          
      ó’  ‡‡‡— t          ˆˆˆfd„|D ¦   «         ¦  «        }|r¤‰g|¢‰‘}d }	t          t          |¦  «        dz
  ¦  «        D ]*}
t          | |||
         |||
dz            ‰¬¦  «        s|
}	 nŒ+|	€nN|	t          |¦  «        k     r|                     |	¦  «         n#|	dz
  dk    r|                     |	dz
  ¦  «         nn|°¤|S )Nc              3   óH   •K  — | ]}‰‰z   |cxk     r	‰‰z
  k     ¯n n|V — Œd S rF   r   )r   rÅ   rË   rW   rY   s     €€€r   r   z3_refine_content_filter_row_edges.<locals>.<genexpr>7  sL   øè è € ÐSÐS˜D°"°v±+ÀÐ2RÐ2RÒ2RÐ2RÀrÈFÁ{Ò2RÐ2RÐ2RÐ2RÐ2R�4Ð2RÐ2RÐ2RÐ2RÐSÐSr   r-   ©rË   r   )rZ   Úranger1   rÌ   Úpop)r>   rW   rY   Ú
candidatesrV   rX   rË   rÈ   ÚboundsÚempty_indexr    s    ``   `    r   Ú _refine_content_filter_row_edgesrÕ   6  s  øøø€ ÝÐSÐSÐSÐSÐSÐS JÐSÑSÔSÑSÔS€EØ
ð ØÐ!�uÐ!˜bÐ!ˆØˆÝ�3˜v™;œ;¨™?Ñ+Ô+ð 	ð 	ˆEÝ# E¨2¨v°e¬}¸bÀ&ÈÐQRÉÔBSÐ\bÐcÑcÔcð Ø#�Ø�ðð ÐØØ�˜U™œÒ#Ð#Ø�IŠI�kÑ"Ô"Ð"Ð"Ø˜1‰_ Ò!Ð!Ø�IŠI�k A‘oÑ&Ô&Ð&Ð&àð ð ð €Lr   r´   g      @g      @)Úcluster_tolerancerË   r”   Úborder_tolerancec                óX  — t          ||¦  «        }|�|s|S t          | ||¬¦  «        }t          |¦  «        }	|	s|S t          d„ |	D ¦   «         |¬¦  «        }
t	          | |¦  «        \  }}t          |
||¬¦  «        }
|
s|S t          | ¦  «        }g }d}|D �]‹}d„ |D ¦   «         }|s|                     |¦  «         Œ't          d„ |D ¦   «         ¦  «        }t          d„ |D ¦   «         ¦  «        }t          d	„ |D ¦   «         ¦  «        }t          d
„ |D ¦   «         ¦  «        }t          ||||
|||¬¦  «        }|s|                     |¦  «         Œ¹|g|¢|‘}t          t          |¦  «        dz
  ¦  «        D ]–}g }|D ]z}|€|                     d¦  «         Œt          j        |¦  «        }|                     t          |j        ¦  «        ||         t          |j        ¦  «        ||dz            g¦  «         Œ{|                     |¦  «         Œ—|t          |¦  «        dz
  z  }�Œ�|dk    r|S |S )a;  Split rows the line grid merged but a cell background rectangle separates.

    Cell background-shading rectangles give row boundaries the border lines do
    not; candidate y-edges from those rectangles (minus edges that coincide with
    real borders, minus edges that would cut an empty band) subdivide each row.N)r”   c                 óh   — g | ]/}t          |j        ¦  «        t          |j        ¦  «        fD ]}|‘ŒŒ0S r   )r   rW   rY   )r   rI   rÅ   s      r   r   z&_split_shaded_rows.<locals>.<listcomp>c  s:   € ÐXÐXÐX�$½¸d¼g¹¼ÍÈdÌgÉÌÐ7WÐXÐX¨tˆÐXÐXÐXÐXr   )rª   r   c                 ó:   — g | ]}|®t          j        |¦  «        ‘ŒS rF   ©rB   rC   ©r   r‡   s     r   r   z&_split_shaded_rows.<locals>.<listcomp>o  s'   € ÐGÐGÐG t°dÐ6F•”˜TÑ"Ô"Ð6FÐ6FÐ6Fr   c              3   ó>   K  — | ]}t          |j        ¦  «        V — Œd S rF   )r   rW   rÜ   s     r   r   z%_split_shaded_rows.<locals>.<genexpr>s  ó*   è è € Ð2Ð2 T•%˜œ‘.”.Ð2Ð2Ð2Ð2Ð2Ð2r   c              3   ó>   K  — | ]}t          |j        ¦  «        V — Œd S rF   )r   rY   rÜ   s     r   r   z%_split_shaded_rows.<locals>.<genexpr>t  rÞ   r   c              3   ó>   K  — | ]}t          |j        ¦  «        V — Œd S rF   )r   rV   rÜ   s     r   r   z%_split_shaded_rows.<locals>.<genexpr>u  rÞ   r   c              3   ó>   K  — | ]}t          |j        ¦  «        V — Œd S rF   )r   rX   rÜ   s     r   r   z%_split_shaded_rows.<locals>.<genexpr>v  rÞ   r   rÏ   r-   r,   )rŒ   r˜   r¥   r®   rÀ   rÉ   rg   r"   ÚminÚmaxrÕ   rÐ   r1   rB   rC   r   rV   rX   )r#   r‰   rŠ   rÖ   rË   r”   r×   r“   r¢   Úbackground_rectsÚy_edgesÚ
_border_xsÚ	border_ysr>   Ú	new_cellsÚ
added_rowsr†   ÚliveÚry0Úry1Úrx0Úrx1ÚcutsrÓ   Ú
band_indexÚbandr‡   rI   s                               r   Ú_split_shaded_rowsrò   J  s²  € õ $ E¨:Ñ6Ô6€JØÐ ÐØˆå(¨¨zÀ7ÐKÑKÔK€IÝ4°YÑ?Ô?ÐØð ØˆåØXÐXÐ*ÐXÑXÔXØ#ðñ ô €Gõ 1°°zÑBÔBÑ€J�	Ý ¨Ð>NÐOÑOÔO€GØð Øˆå˜tÑ$Ô$€EØ€IØ€JØð &ñ &ˆØGÐG¨sÐGÑGÔGˆØð 	Ø×Ò˜SÑ!Ô!Ð!ØÝÐ2Ð2¨TÐ2Ñ2Ô2Ñ2Ô2ˆÝÐ2Ð2¨TÐ2Ñ2Ô2Ñ2Ô2ˆÝÐ2Ð2¨TÐ2Ñ2Ô2Ñ2Ô2ˆÝÐ2Ð2¨TÐ2Ñ2Ô2Ñ2Ô2ˆÝ/°°s¸CÀÈ#ÈsÐ[aÐbÑbÔbˆØð 	Ø×Ò˜SÑ!Ô!Ð!ØØÐ"˜Ð"˜cÐ"ˆÝ¥ F¡¤¨a¡Ñ0Ô0ð 
	#ð 
	#ˆJØˆDØð ð �Ø�<Ø—K’K Ñ%Ô%Ð%Ð%å"œ<¨Ñ-Ô-�DØ—K’KÝ˜tœw™œ¨°
Ô);½UÀ4Ä7¹^¼^ÈVÐT^ÐabÑTbÔMcÐdñô ð ð ð ×Ò˜TÑ"Ô"Ð"Ð"Ø•c˜&‘k”k A‘oÑ%ˆ
‰
à�Q‚€ØˆØÐr   c                 ó    — t          | ¦  «        S rF   )rz   rt   s    r   Ú_refine_value_likerô   �  s   € Ý% dÑ+Ô+Ð+r   c                 ó    — t          | ¦  «        S rF   )ru   rt   s    r   Ú_refine_span_value_likerö   “  s   € Ý˜TÑ"Ô"Ð"r   c          	      óø  — t          j        |¦  «        }g }t          | |¦  «        D ]×\  }}}}	}
t          |
¦  «                             ¦   «         }|sŒ,t          |¦  «        t          |¦  «        z   dz  }t          |¦  «        t          |	¦  «        z   dz  }|j        |cxk    r|j        k    rPn ŒŠ|j        |cxk    r|j	        k    r6n Œ¤| 
                    t          |¦  «        t          |¦  «        ||f¦  «         ŒØt          |¦  «        dk     rdS |                     d„ ¬¦  «         g }|d         g}|dd…         D ]K}|d         |d	         d         z
  |k    r| 
                    |¦  «         |g}Œ6| 
                    |¦  «         ŒL| 
                    |¦  «         |D ]Ö}|                     d
„ ¬¦  «         t          t          |¦  «        dz
  ¦  «        D ]�}||dz            d         ||         d         z
  |k    rŒ'd                     d„ |d|dz   …         D ¦   «         ¦  «        }d                     d„ ||dz   d…         D ¦   «         ¦  «        }t          |¦  «        rt          |¦  «        r  dS ŒžŒ×dS )z–True if a cell holds two value-like groups separated by a wide gap on one
    text line -- the signal that a single grid column packs several columns.r´   r,   Fc                 ó   — | d         S )Nr,   r   rM   s    r   rO   z*_refine_cell_span_signal.<locals>.<lambda>§  s
   €   Q¤€ r   rP   r   r-   Nr§   c                 ó   — | d         S r+   r   rM   s    r   rO   z*_refine_cell_span_signal.<locals>.<lambda>³  s
   €  4¨¤7€ r   ú c              3   ó&   K  — | ]}|d          V — ŒdS ©r<   Nr   ©r   ra   s     r   r   z+_refine_cell_span_signal.<locals>.<genexpr>·  s&   è è € ÐBÐB¨˜D œGÐBÐBÐBÐBÐBÐBr   c              3   ó&   K  — | ]}|d          V — ŒdS rü   r   rý   s     r   r   z+_refine_cell_span_signal.<locals>.<genexpr>¸  s&   è è € ÐCÐC¨˜T !œWÐCÐCÐCÐCÐCÐCr   T)rB   rC   rn   r   r!   r   rV   rX   rW   rY   r"   r1   ÚsortrÐ   r    rö   )r#   r‡   ÚgapÚline_tolerancerI   r>   rV   rW   rX   rY   r   ry   ri   rj   r   r¬   ra   r&   r    ÚleftÚrights                        r   Ú_refine_cell_span_signalr  —  s¶  € õ Œ<˜ÑÔ€DØ€EÝ 5°d¸DÑ AÔ Að ?ð ?ÑˆˆB��B˜Ý�t‘9”9—?’?Ñ$Ô$ˆØð 	ØÝ�B‰iŒi�% ™)œ)Ñ# sÑ*ˆÝ�B‰iŒi�% ™)œ)Ñ# sÑ*ˆØŒ7�bÐ#Ð#Ò#Ð#˜DœGÒ#Ð#Ð#Ð#Ð#¨¬°2Ð(@Ð(@Ò(@Ð(@¸¼Ò(@Ð(@Ð(@Ð(@Ð(@Ø�LŠL�% ™)œ)¥U¨2¡Y¤Y°°HÐ=Ñ>Ô>Ð>øÝ
ˆ5�z„z�A‚~€~Øˆuà	‡J‚JÐ'Ð'€JÑ(Ô(Ð(Ø€EØ�QŒxˆj€GØ�a�b�b”	ð !ð !ˆØ�Œ7�W˜R”[ ”^Ñ# nÒ4Ð4Ø�LŠL˜Ñ!Ô!Ð!Ø�fˆGˆGà�NŠN˜4Ñ Ô Ð Ð Ø	‡L‚L�ÑÔÐàð ð ˆØ�	Š	Ð*Ð*ˆ	Ñ+Ô+Ð+Ý�3˜t™9œ9 q™=Ñ)Ô)ð 	ð 	ˆEØ�E˜A‘IŒ˜qÔ! D¨¤K°¤NÑ2°cÒ9Ð9ØØ—8’8ÐBÐB°°[°u¸q±y°[Ô0AÐBÑBÔBÑBÔBˆDØ—H’HÐCÐC°°e¸a±i°k°kÔ1BÐCÑCÔCÑCÔCˆEÝ& tÑ,Ô,ð Õ1HÈÑ1OÔ1Oð Ø�t�t�tøð	ð ˆ5r   g      (@g      @g333333Ó?r,   ©r   r  Úsupport_ratioÚmin_supportc                óX  ‡— t          |¦  «        }t          |t          ||z  ¦  «        ¦  «        Ši }|D ]I}t          |¦  «        D ]7\  }	}
|
€Œt	          | |
||¬¦  «        r|                     |	d¦  «        dz   ||	<   Œ8ŒJt          ˆfd„|                     ¦   «         D ¦   «         ¦  «        S )z–Return the column indices that fire the under-segmentation gate: columns
    where enough rows carry the two-value-group signal (a support threshold).N)r   r  r   r-   c              3   ó.   •K  — | ]\  }}|‰k    ¯|V — Œd S rF   r   )r   ÚcolÚcountÚsupport_thresholds      €r   r   z._refine_detect_span_columns.<locals>.<genexpr>Ì  s2   øè è € ÐWÐW™*˜#˜u¸EÐEVÒ<VÐ<V�#Ð<VÐ<VÐ<VÐ<VÐWÐWr   )r1   rã   Úintr¡   r  r   rZ   rŽ   )r#   r‰   r   r  r  r  ÚrowsÚcol_hitsr†   Ú	col_indexr‡   r  s              @r   Ú_refine_detect_span_columnsr  ¾  sÓ   ø€ õ
 ˆu‰:Œ:€DÝ˜K­¨]¸TÑ-AÑ)BÔ)BÑCÔCÐØ€HØð Eð EˆÝ(¨™~œ~ð 	Eð 	E‰OˆI�tØˆ|ØÝ'¨¨d¸ÈNÐ[Ñ[Ô[ð EØ&.§l¢l°9¸aÑ&@Ô&@À1Ñ&D�˜Ñ#øð		Eõ
 ÐWÐWÐWÐW¨¯ªÑ(8Ô(8ÐWÑWÔWÑWÔWÐWr   c           	      ó²  — g }|D �]P}g }|t          |¦  «        k     �r||         ��t          j        ||         ¦  «        }t          | |¦  «        D ]á\  }}}	}
}t	          |¦  «                             ¦   «         sŒ*t          |¦  «        t          |	¦  «        z   dz  }t          |¦  «        t          |
¦  «        z   dz  }|j        |cxk    r|j        k    r\n Œˆ|j	        |cxk    r|j
        k    rBn Œ¢|                     t          |¦  «        t          |	¦  «        t	          |¦  «        f¦  «         Œâ|                     t          |¦  «        ¦  «         �ŒR|S )Nr´   )r1   rB   rC   rn   r   r!   r   rV   rX   rW   rY   r"   rZ   )r#   r‰   r
  r  r†   r>   rI   rV   rW   rX   rY   r   ri   rj   s                 r   Ú_refine_column_wordsr  Ï  sT  € Ø€DØð #ñ #ˆØˆØ•�S‘”Š>‰>˜c #œhÑ2Ý”<  C¤Ñ)Ô)ˆDÝ(=¸dÀDÑ(IÔ(Ið Dð DÑ$��B˜˜B Ý˜4‘y”y—’Ñ(Ô(ð ØÝ˜B‘i”i¥%¨¡)¤)Ñ+¨sÑ2�Ý˜B‘i”i¥%¨¡)¤)Ñ+¨sÑ2�Ø”7˜bÐ+Ð+Ò+Ð+ D¤GÒ+Ð+Ð+Ð+Ð+°´¸2Ð0HÐ0HÒ0HÐ0HÀÄÒ0HÐ0HÐ0HÐ0HÐ0HØ—L’L¥%¨¡)¤)­U°2©Y¬Y½¸D¹	¼	Ð!BÑCÔCÐCøØ�Š•F˜5‘M”MÑ"Ô"Ð"Ñ"Ø€Kr   ©Úbridge_tolerancec                óN  ‡‡— d„ t          | ¦  «        D ¦   «         }t          |¦  «        dk     rg S t          d„ |D ¦   «         ¦  «        }t          d„ |D ¦   «         ¦  «        }||z
  dk     rg S g }d }|Š‰|k    rdˆfd„|D ¦   «         }t          |¦  «        |k    r(|�%|                     |d         |d         f¦  «         d }n|€‰‰gn	|d         ‰g}‰dz  Š‰|k    °d|�#|                     |d         |d         f¦  «         g }|D �]�\  }	}
|	|dz   k    s	|
|dz
  k    rŒ|	|
z   d	z  Št          ˆfd
„| D ¦   «         ¦  «        }ˆfd„| D ¦   «         }dx}}dx}}dx}}g }g }|D ]ª}ˆfd„|D ¦   «         }ˆfd„|D ¦   «         }|rD|dz  }|dz  }|t          d                     |¦  «        ¦  «        z  }|                     |¦  «         |rD|dz  }|dz  }|t          d                     |¦  «        ¦  «        z  }|                     |¦  «         Œ«|dk     s|dk     r�Œ|dk    rGt          d                     |¦  «        ¦  «        r"t          d                     |¦  «        ¦  «        s�Œan|r	||z  dk     s|r||z  dk     r�Œz|                     ‰¦  «         �Œ‘t          |¦  «        S )Nc                 ó0   — g | ]\  }}|D ]\  }}}|||f‘ŒŒS r   r   )r   Ú	row_indexr>   rV   rX   rf   s         r   r   z"_refine_cut_xs.<locals>.<listcomp>á  s<   € ÐlÐlÐlÑ)9¨°EÐfkÐlÐlÑWbÐXZÐ\^Ð`a�"�b˜)Ð$ÐlÐlÐlÐlr   r,   c              3   ó"   K  — | ]
\  }}}|V — Œd S rF   r   )r   rV   rf   s      r   r   z!_refine_cut_xs.<locals>.<genexpr>å  s(   è è € Ð*Ð*‘H�B˜˜1ˆRÐ*Ð*Ð*Ð*Ð*Ð*r   c              3   ó"   K  — | ]
\  }}}|V — Œd S rF   r   )r   rf   rX   s      r   r   z!_refine_cut_xs.<locals>.<genexpr>æ  s(   è è € Ð*Ð*‘H�A�r˜1ˆRÐ*Ð*Ð*Ð*Ð*Ð*r   r-   c                 ó<   •— h | ]\  }}}|‰cxk     r|k     ¯n n|’ŒS r   r   )r   rV   rX   r  r·   s       €r   ú	<setcomp>z!_refine_cut_xs.<locals>.<setcomp>î  s6   ø€ ÐUÐUÐUÑ'8 r¨2¨yÈÈaÈÈÊÈÐRTÊÈÈÈÈ˜ÈÈÈr   r   r³   r´   c              3   óR   •K  — | ]!}t          ˆfd „|D ¦   «         ¦  «        ¯dV — Œ"dS )c              3   ó@   •K  — | ]\  }}}|‰cxk     o|k     nc V — Œd S rF   r   ©r   rV   rX   rf   Úcut_xs       €r   r   z+_refine_cut_xs.<locals>.<genexpr>.<genexpr>þ  óA   øè è € Ð=eÐ=eÑR[ÐRTÐVXÐZ[¸bÀ5¸o¸oºo¸oÈ2ºo¸o¸o¸oÐ=eÐ=eÐ=eÐ=eÐ=eÐ=er   r-   NrÆ   ©r   r>   r   s     €r   r   z!_refine_cut_xs.<locals>.<genexpr>þ  sF   øè è € ÐfÐf 5½#Ð=eÐ=eÐ=eÐ=eÐ_dÐ=eÑ=eÔ=eÑ:eÔ:eÐf˜QÐfÐfÐfÐfÐfÐfr   c                 óJ   •— g | ]}t          ˆfd „|D ¦   «         ¦  «        °|‘Œ S )c              3   ó@   •K  — | ]\  }}}|‰cxk     o|k     nc V — Œd S rF   r   r  s       €r   r   z,_refine_cut_xs.<locals>.<listcomp>.<genexpr>  r!  r   rÆ   r"  s     €r   r   z"_refine_cut_xs.<locals>.<listcomp>  s<   ø€ ÐfÐfÐf˜u½#Ð=eÐ=eÐ=eÐ=eÐ_dÐ=eÑ=eÔ=eÑ:eÔ:eÐf�UÐfÐfÐfr   c                 ó(   •— g | ]\  }}}|‰k    ¯|‘ŒS r   r   ©r   rV   rX   r   r   s       €r   r   z"_refine_cut_xs.<locals>.<listcomp>  s$   ø€ ÐBÐBÐB™\˜R  T°b¸E²k°k�D°k°k°kr   c                 ó(   •— g | ]\  }}}|‰k    ¯|‘ŒS r   r   r&  s       €r   r   z"_refine_cut_xs.<locals>.<listcomp>	  s$   ø€ ÐCÐCÐC™l˜b " d°r¸U²{°{�T°{°{°{r   rú   rD   )
r¡   r1   râ   rã   r"   r¨   rô   r    ÚextendrZ   )Ú
rows_wordsr  Ú	intervalsÚloÚhiÚchannelsr¬   Úcrossing_rowsrï   Ú	left_edgeÚ
right_edgeÚcrossing_countÚ	body_rowsÚ	left_rowsÚ
right_rowsÚleft_okÚright_okÚleft_nÚright_nÚleft_valuesÚright_valuesr>   r  r  r   r·   s                           @@r   Ú_refine_cut_xsr;  à  s|  øø€ ØlÐl½YÀzÑ=RÔ=RÐlÑlÔl€IÝ
ˆ9�~„~˜ÒÐØˆ	å	Ð*Ð* 	Ð*Ñ*Ô*Ñ	*Ô	*€BÝ	Ð*Ð* 	Ð*Ñ*Ô*Ñ	*Ô	*€BØ	ˆB�w�‚{€{Øˆ	à€HØ€GØ
€AØ
ˆrŠ'ˆ'ØUÐUÐUÐU¸IÐUÑUÔUˆÝˆ}ÑÔÐ 0Ò0Ð0ØÐ"Ø—’ ¨¤¨W°Q¬ZÐ 8Ñ9Ô9Ð9Ø�øà ' �q˜!�f�f°g¸a´jÀ!°_ˆGØ	ˆS‰ˆð ˆrŠ'ˆ'ð ÐØ�Š˜ œ W¨Q¤ZÐ0Ñ1Ô1Ð1à€DØ!)ð "ñ "Ñˆ	�:Ø˜˜Q™ÒÐ *°°Q±Ò"6Ð"6ØØ˜ZÑ'¨3Ñ.ˆÝÐfÐfÐfÐf¨JÐfÑfÔfÑfÔfˆð gÐfÐfÐf¨
ÐfÑfÔfˆ	Ø!"Ð"ˆ	�JØÐˆ�(ØÐˆ�ØˆØˆØð 	+ð 	+ˆEØBÐBÐBÐB¨UÐBÑBÔBˆDØCÐCÐCÐC¨eÐCÑCÔCˆEØð )Ø˜Q‘�	Ø˜!‘�ØÕ-¨c¯hªh°t©n¬nÑ=Ô=Ñ=�Ø×"Ò" 4Ñ(Ô(Ð(Øð +Ø˜a‘�
Ø˜1‘�ØÕ.¨s¯xªx¸©¬Ñ?Ô?Ñ?�Ø×#Ò# EÑ*Ô*Ð*øà�qŠ=ˆ=˜J¨šN˜NÙØ˜AÒÐÝ% c§h¢h¨{Ñ&;Ô&;Ñ<Ô<ð ÕDVÐWZ×W_ÒW_Ð`lÑWmÔWmÑDnÔDnð Ùðàð 	˜ 6Ñ)¨CÒ/Ð/°WÐ/ÀÈGÑASÐVYÒAYÐAYÙØ�Š�EÑÔÐÑå�$‰<Œ<Ðr   ©r  Úallowed_colsc          
      ó  ‡‡— t          d„ |D ¦   «         d¬¦  «        }|€d nt          |¦  «        }i }t          |¦  «        D ]0}|�||vrŒ	t          t	          | ||¦  «        |¬¦  «        }|r|||<   Œ1|s|S g }	|D �]}
g }t          |
¦  «        D ]Ø\  }}|                     |¦  «        }|s|                     |¦  «         Œ2|€*|                     d gt          |¦  «        dz   z  ¦  «         Œ^t          j        |¦  «        \  Š}Š}‰gˆˆfd„|D ¦   «         z   ‰gz   }t          t          |¦  «        dz
  ¦  «        D ]*}|                     ||         |||dz            |g¦  «         Œ+ŒÙ|	                     |¦  «         �Œ|	S )Nc              3   ó4   K  — | ]}t          |¦  «        V — Œd S rF   )r1   )r   r†   s     r   r   z(_refine_split_columns.<locals>.<genexpr>"  s(   è è € Ð+Ð+˜c•�S‘”Ð+Ð+Ð+Ð+Ð+Ð+r   r   )Údefaultr  r-   c                 ó4   •— g | ]}‰|cxk     r‰k     ¯n n|‘ŒS r   r   )r   r   rV   rX   s     €€r   r   z)_refine_split_columns.<locals>.<listcomp>:  s.   ø€ ÐHÐHÐH u¸¸U¸¸º¸ÀRº¸¸¸¸˜U¸¸¸r   )rã   rµ   rÐ   r;  r  r¡   r   r"   r(  r1   rB   rC   )r#   r‰   r  r=  ÚncolsÚactive_colsÚcol_cutsr
  rï   rè   r†   Únew_rowr‡   rW   rY   rº   r    rV   rX   s                    @@r   Ú_refine_split_columnsrF  !  sç  øø€ ÝÐ+Ð+ UÐ+Ñ+Ô+°QÐ7Ñ7Ô7€EØ&Ð.�$�$µC¸Ñ4EÔ4E€KØ€HÝ�U‰|Œ|ð !ð !ˆØÐ" s°+Ð'=Ð'=ØÝÕ2°4¸ÀÑDÔDÐWgÐhÑhÔhˆØð 	!Ø ˆH�S‰Møàð Øˆà€IØð "ñ "ˆØˆÝ" 3™œð 
	Gð 
	G‰IˆC�Ø—<’< Ñ$Ô$ˆDØð GØ—’˜tÑ$Ô$Ð$Ð$Ø�Ø—’ ˜v­¨T©¬°Q©Ñ7Ñ8Ô8Ð8Ð8å!(¤¨dÑ!3Ô!3‘��B˜˜BØ�TÐHÐHÐHÐHÐH°ÐHÑHÔHÑHÈBÈ4ÑO�Ý"¥3 r¡7¤7¨Q¡;Ñ/Ô/ð Gð G�EØ—N’N B u¤I¨r°2°e¸a±i´=À"Ð#EÑFÔFÐFÐFðGà×Ò˜Ñ!Ô!Ð!Ñ!àÐr   )r   r  r  r  r  c                ót   — t          | |||||¬¦  «        }|s|S t          | ||t          |¦  «        ¬¦  «        S )z‰Split under-segmented columns, but only those that fire the value-group
    gate -- so ordinary single-value columns are never disturbed.r  r<  )r  rF  rµ   )r#   r‰   r   r  r  r  r  Ú
fired_colss           r   Ú_split_undersegmented_columnsrI  B  s`   € õ -ØØØØ%Ø#Øðñ ô €Jð ð ØˆÝ ØˆeÐ&6ÅSÈÁ_Ä_ðñ ô ð r   c                 ó   — d„ | D ¦   «         S )Nc                 óD   — g | ]}|D ]}|®t          j        |¦  «        ‘ŒŒS rF   rÛ   r…   s      r   r   z,_refine_rects_from_cells.<locals>.<listcomp>_  s4   € ÐTÐTÐT 3¸CÐTÐT°DÀ4ÐCS�GŒL˜ÑÔÐCSÐCSÐCSÐCSr   r   )r‰   s    r   Ú_refine_rects_from_cellsrL  ^  s   € ØTÐT¨%ÐTÑTÔTÐTr   c                 ó†   — | sd S t          j        | d         ¦  «        }| dd …         D ]}|                     |¦  «         Œ|S )Nr   r-   )rB   rC   rˆ   )r‹   rI   rN   s      r   Ú_refine_union_rectrN  b  sU   € Øð ØˆtÝŒ<˜˜aœÑ!Ô!€DØ�a�b�b”	ð  ð  ˆØ×Ò˜$ÑÔÐÐØ€Kr   c                 ó^   — t          | d„ g ¬¦  «        }t          d„ |D ¦   «         ¦  «        }|S )Nc                 óR   — t          d„ | D ¦   «         ¦  «        t          | ¦  «        fS )Nc              3   ó   K  — | ]}|®dV — Œ	d S ©Nr-   r   rÜ   s     r   r   z?_refine_best_column_bounds.<locals>.<lambda>.<locals>.<genexpr>n  s'   è è € ÐCÐC 4°$Ð2B˜QÐ2BÐ2BÐ2BÐ2BÐCÐCr   )r¨   r1   )r†   s    r   rO   z,_refine_best_column_bounds.<locals>.<lambda>n  s(   € �ÐCÐC¨3ÐCÑCÔCÑCÔCÅSÈÁXÄXÐN€ r   )rQ   r@  c              3   ó²   K  — | ]R}|�Nt          j        |¦  «        }|j        |j        k    ¯(t	          |j        ¦  «        t	          |j        ¦  «        fV — ŒSd S rF   )rB   rC   rX   rV   r   )r   r‡   rI   s      r   r   z-_refine_best_column_bounds.<locals>.<genexpr>q  si   è è € ð ð àØÐÝ”\ $Ñ'Ô'ˆDØŒ7�T”WÒÐõ	 
ˆtŒw‰Œ�˜tœw™œÐ(ð ÐÐÐðð r   )rã   rZ   )r‰   Úbest_rowrÓ   s      r   Ú_refine_best_column_boundsrU  k  sV   € ÝØØNÐNØðñ ô €Hõ
 ð ð àðñ ô ñ ô €Fð €Mr   c                 ó¢  — | sg S t          | d„ ¬¦  «        } | d         gg}| d         d         | d         d         z   dz  }| dd…         D ]X}|d         |d         z   dz  }||z
  t          k    r|                     |g¦  «         n|d                              |¦  «         |}ŒYg }|D ]¦}|                     t          d	„ |D ¦   «         ¦  «        t          d
„ |D ¦   «         ¦  «        t	          d„ |D ¦   «         ¦  «        t	          d„ |D ¦   «         ¦  «        d                     d„ t          |d„ ¬¦  «        D ¦   «         ¦  «        dœ¦  «         Œ§|S )zyGroup center-point words into body "lines" by a fixed center-y gap,
    returning each line's union bbox and joined text.c                 ó:   — | d         | d         z   dz  | d         fS )Nr-   r<   r´   r   r   rM   s    r   rO   z,_refine_cluster_words_by_y.<locals>.<lambda>€  s!   € ¨T°!¬W°t¸A´wÑ->À#Ñ,EÀtÈAÄwÐ+O€ r   rP   r   r-   r<   r´   Nr§   c              3   ó&   K  — | ]}|d          V — ŒdS )r   Nr   rý   s     r   r   z-_refine_cluster_words_by_y.<locals>.<genexpr>�  ó&   è è € Ð6Ð6 d˜$˜qœ'Ð6Ð6Ð6Ð6Ð6Ð6r   c              3   ó&   K  — | ]}|d          V — ŒdS )r-   Nr   rý   s     r   r   z-_refine_cluster_words_by_y.<locals>.<genexpr>�  rY  r   c              3   ó&   K  — | ]}|d          V — ŒdS )r,   Nr   rý   s     r   r   z-_refine_cluster_words_by_y.<locals>.<genexpr>‘  rY  r   c              3   ó&   K  — | ]}|d          V — ŒdS rü   r   rý   s     r   r   z-_refine_cluster_words_by_y.<locals>.<genexpr>’  rY  r   rú   c              3   ó&   K  — | ]}|d          V — ŒdS )r;   Nr   rý   s     r   r   z-_refine_cluster_words_by_y.<locals>.<genexpr>“  s&   è è € Ð _Ð _¨T  a¤Ð _Ð _Ð _Ð _Ð _Ð _r   c                 ó   — | d         S r+   r   rM   s    r   rO   z,_refine_cluster_words_by_y.<locals>.<lambda>“  s   € ÐVZÐ[\ÔV]€ r   )rV   rW   rX   rY   r   )rZ   Ú_REFINE_LINE_GAPr"   râ   rã   r    )r>   r«   Úlast_centerra   rJ   r   Úclusters          r   Ú_refine_cluster_words_by_yrb  {  sŸ  € ð ð Øˆ	Ý�5ÐOÐOÐPÑPÔP€EØ�q”�
ˆ|€HØ˜”8˜A”;  q¤¨!¤Ñ,°Ñ3€KØ�a�b�b”	ð ð ˆØ�q”'˜D œGÑ# sÑ*ˆØ�KÑÕ"2Ò2Ð2Ø�OŠO˜T˜FÑ#Ô#Ð#Ð#à�RŒL×Ò Ñ%Ô%Ð%Øˆˆà€EØð 	
ð 	
ˆØ�ŠåÐ6Ð6¨gÐ6Ñ6Ô6Ñ6Ô6ÝÐ6Ð6¨gÐ6Ñ6Ô6Ñ6Ô6ÝÐ6Ð6¨gÐ6Ñ6Ô6Ñ6Ô6ÝÐ6Ð6¨gÐ6Ñ6Ô6Ñ6Ô6ØŸšÐ _Ð _µV¸GÐI]ÐI]Ð5^Ñ5^Ô5^Ð _Ñ _Ô _Ñ_Ô_ðð ñ	
ô 	
ð 	
ð 	
ð €Lr   c                 óN  — t          ¦   «         }t          | d         ¦  «        }t          | d         ¦  «        }||z   dz  }t          |¦  «        D ]T\  }\  }}t          ||¦  «        t	          ||¦  «        z
  }	|	dk    s||cxk    r|k    rn Œ?|                     |¦  «         ŒU|S )NrV   rX   r´   r   )rµ   r   r¡   râ   rã   r¸   )
r&   Ú
col_boundsÚcolsÚline_x0Úline_x1rJ   r    rV   rX   Úoverlaps
             r   Ú_refine_line_columnsri  ™  s¸   € Ý‰5Œ5€DÝ�D˜”JÑÔ€GÝ�D˜”JÑÔ€GØ˜Ñ 3Ñ&€FÝ$ ZÑ0Ô0ð ð ‰ˆ‰x��BÝ�g˜rÑ"Ô"¥S¨°"Ñ%5Ô%5Ñ5ˆØ�QŠ;ˆ;˜" Ð,Ð,Ò,Ð,¨"Ò,Ð,Ð,Ð,Ð,Ø�HŠH�U‰OŒOˆOøØ€Kr   c           	      ó"  — g }t          |j        ¦  «        t          |j        ¦  «        t          |j        ¦  «        t          |j        ¦  «        f\  }}}}t          | ¦  «        D ]©\  }}}	}
}||	z   dz  }||
z   dz  }||cxk    r|k    r„n Œ(||cxk    r|k    rtn Œ8t          |¦  «                             ¦   «         }|rN|                     t          |¦  «        t          |¦  «        t          |	¦  «        t          |
¦  «        |f¦  «         Œª|S )NrD   )	r   rV   rW   rX   rY   rg   r   r!   r"   )r#   rI   r>   rí   rë   rî   rì   rV   rW   rX   rY   r   ri   rj   s                 r   Ú_refine_page_words_in_rectrk  ¥  s  € Ø€EÝ˜tœw™œ­¨t¬w©¬½¸t¼w¹¼ÍÈtÌwÉÌÐWÑ€Cˆˆc�3Ý 2°4Ñ 8Ô 8ð Qð QÑˆˆB��B˜Ø�2‰g˜‰_ˆØ�2‰g˜‰_ˆØ�"ÐÐÒÐ˜ÒÐÐÐÐ  rÐ 0Ð 0Ò 0Ð 0¨SÒ 0Ð 0Ð 0Ð 0Ð 0Ý�t‘9”9—?’?Ñ$Ô$ˆDØð QØ—’�e B™iœi­¨r©¬µE¸"±I´I½uÀR¹y¼yÈ$ÐOÑPÔPÐPøØ€Lr   c                ó   — | sg S t          | ¦  «        }t          |d         d         ¦  «        t          |d         d         ¦  «        gg}|dd …         D ]î\  }}|d         }|d         t          |¦  «        z
  }t          |d         |d         z
  t          |¦  «        t          |¦  «        z
  ¦  «        }|dk    rV||z  |k    rMt          |d         t          |¦  «        ¦  «        |d<   t          |d         t          |¦  «        ¦  «        |d<   Œ½|                     t          |¦  «        t          |¦  «        g¦  «         Œïd„ |D ¦   «         S )Nr   r-   r§   c                 ó   — g | ]	\  }}||f‘Œ
S r   r   ©r   rW   rY   s      r   r   z3_refine_merge_overlapping_lines.<locals>.<listcomp>À  s    € Ð*Ð*Ð*™˜˜RˆR�ˆHÐ*Ð*Ð*r   )rZ   r   râ   rã   r"   )	r   ÚfracrŽ   ÚmergedrW   rY   r¬   rh  Ú
min_heights	            r   Ú_refine_merge_overlapping_linesrr  ²  s:  € Øð Øˆ	Ý�5‰MŒM€EÝ�U˜1”X˜a”[Ñ!Ô!¥5¨¨q¬°!¬Ñ#5Ô#5Ð6Ð7€FØ˜˜˜”)ð 2ð 2‰ˆˆBØ˜”*ˆØ˜!”*�u R™yœyÑ(ˆÝ˜ œ g¨a¤jÑ0µ%¸±)´)½eÀB¹i¼iÑ2GÑHÔHˆ
Ø˜Š>ˆ>˜g¨
Ñ2°dÒ:Ð:Ý˜W QœZ­¨r©¬Ñ3Ô3ˆG�A‰JÝ˜W QœZ­¨r©¬Ñ3Ô3ˆG�A‰JˆJà�MŠM�5 ™9œ9¥e¨B¡i¤iÐ0Ñ1Ô1Ð1Ð1Ø*Ð* 6Ð*Ñ*Ô*Ð*r   g333333ë?r-   ©Úclean_thresholdÚheader_row_countc          	      óŽ  — t          |¦  «        }|r8t          dt          t          |¦  «        t	          |¦  «        ¦  «        ¦  «        nd}t          dt	          |¦  «        |z
  ¦  «        }t	          |¦  «        |k    rdS t	          |¦  «        dk     rdS t          t          ||d…         ¦  «        ¦  «        }|�|j        rdS t          | |¦  «        }t          |¦  «        }|sdS t          dt	          |¦  «        dz   dz  ¦  «        }	g }
|D ]G}t          t          ||¦  «        ¦  «        }t	          |¦  «        |	k    r|
                     |¦  «         ŒHt	          |
¦  «        t	          |¦  «        z  }||k     rdS t	          |
¦  «        |k    rdS |j        |j        |j        |j        gd„ |D ¦   «         d„ |
D ¦   «         ||dœS )ay  Decide whether the body rows are over-merged. Returns the geometry needed
    to re-cut them (body bbox, column bounds, per-record y-bounds) or None.

    Fires only when the body text clusters into clean multi-column "record" lines
    (clean_ratio >= clean_threshold) and there are more records than existing body
    rows -- i.e. several records collapsed into one grid row.r-   r   Nr,   c                 óT   — g | ]%\  }}t          |d ¦  «        t          |d ¦  «        g‘Œ&S )r,   )r¹   ©r   rV   rX   s      r   r   z0_refine_detect_row_overmerge.<locals>.<listcomp>ê  s1   € ÐMÐMÐM¹¸¸B�˜b !™œ¥e¨B°¡l¤lÐ3ÐMÐMÐMr   c                 ób   — g | ],}t          |d          ¦  «        t          |d         ¦  «        g‘Œ-S )rW   rY   r   )r   r&   s     r   r   z0_refine_detect_row_overmerge.<locals>.<listcomp>ë  s5   € Ð_Ð_Ð_È$¥ d¨4¤jÑ 1Ô 1µ5¸¸d¼Ñ3DÔ3DÐEÐ_Ð_Ð_r   )Ú	body_bboxrd  Úrecord_line_boundsÚexisting_body_rowsru  )rU  rã   râ   r  r1   rN  rL  rG   rk  rb  rZ   ri  r"   rV   rW   rX   rY   )r#   r‰   rt  ru  rd  r|  Ú	body_rectr>   r   Úmin_colsÚrecord_linesr&   re  Úclean_ratios                 r   Ú_refine_detect_row_overmerger�  Ã  sì  € õ ,¨EÑ2Ô2€JØINÐU•s˜1�c¥#Ð&6Ñ"7Ô"7½¸U¹¼ÑDÔDÑEÔEÐEÐTUÐÝ˜Q¥ E¡
¤
Ð-=Ñ =Ñ>Ô>ÐÝ
ˆ5�z„zÐ%Ò%Ð%ØˆtÝ
ˆ:�„˜ÒÐØˆtå"Õ#;¸EÐBRÐBSÐBSÔ<TÑ#UÔ#UÑVÔV€IØÐ˜IÔ.ÐØˆtå& t¨YÑ7Ô7€EÝ& uÑ-Ô-€EØð Øˆtå�1•s˜:‘”¨Ñ*¨qÑ0Ñ1Ô1€HØ€LØð &ð &ˆÝÕ*¨4°Ñ<Ô<Ñ=Ô=ˆÝˆt‰9Œ9˜Ò Ð Ø×Ò Ñ%Ô%Ð%øå�lÑ#Ô#¥c¨%¡j¤jÑ0€KØ�_Ò$Ð$ØˆtÝ
ˆ<ÑÔÐ.Ò.Ð.Øˆtð  ”l I¤L°)´,À	ÄÐMØMÐMÀ*ÐMÑMÔMØ_Ð_ÐR^Ð_Ñ_Ô_Ø0Ø,ðð ð r   gffffffÖ?©rt  Úmerge_overlap_fracru  c          
      óü  — t          | |||¬¦  «        }|€|S t          j        |d         ¦  «        }d„ |d         D ¦   «         }d„ |d         D ¦   «         }t          ||¬¦  «        }	t	          |	¦  «        t          |d	         ¦  «        k    r|S d
„ |	D ¦   «         }
t          |j        ¦  «        g}t          |
|
dd…         ¦  «        D ] \  }}| 	                    ||z   dz  ¦  «         Œ!| 	                    t          |j
        ¦  «        ¦  «         |dt          |d         ¦  «        …         }g }t          t	          |	¦  «        ¦  «        D ]¬}||         }||dz            }g }|D ]}\  }}t          j        ||||¦  «        }| 	                    t          |j        ¦  «        t          |j        ¦  «        t          |j        ¦  «        t          |j
        ¦  «        g¦  «         Œ~| 	                    |¦  «         Œ­g |¢|¢S )a8  Re-cut over-merged body rows into one grid row per detected record.

    Keeps the header rows intact, then rebuilds the body as evenly-bounded rows
    (cut at the midpoints between consecutive record centers) across the detected
    column bounds. header_row_count is the number of leading header rows to keep.rs  Nrz  c                 óP   — g | ]#\  }}t          |¦  «        t          |¦  «        f‘Œ$S r   r   rx  s      r   r   z*_split_overmerged_rows.<locals>.<listcomp>   s-   € ÐJÐJÐJ©V¨R°•5˜‘9”9�e B™iœiÐ(ÐJÐJÐJr   rd  c                 óP   — g | ]#\  }}t          |¦  «        t          |¦  «        f‘Œ$S r   r   rn  s      r   r   z*_split_overmerged_rows.<locals>.<listcomp>  s-   € ÐWÐWÐW±&°"°b�˜b™	œ	¥5¨¡9¤9Ð-ÐWÐWÐWr   r{  )ro  r|  c                 ó$   — g | ]\  }}||z   d z  ‘ŒS )r´   r   rn  s      r   r   z*_split_overmerged_rows.<locals>.<listcomp>  s$   € Ð9Ð9Ð9¡6 2 r��R‘˜3‰Ð9Ð9Ð9r   r-   r´   ru  )r�  rB   rC   rr  r1   r  r   rW   rU   r"   rY   rÐ   rV   rX   )r#   r‰   rt  rƒ  ru  Úmetarz  rd  Úraw_line_boundsÚline_boundsÚcentersrÈ   ÚprevÚnxtÚheader_rowsÚnew_bodyr  rW   rY   rE  rV   rX   rI   s                          r   Ú_split_overmerged_rowsr�  ñ  s  € õ (Øˆe _ÐGWðñ ô €Dð €|Øˆå”˜T +Ô.Ñ/Ô/€IØJÐJ°t¸LÔ7IÐJÑJÔJ€JØWÐW¸DÐAUÔ<VÐWÑWÔW€OÝ1°/ÐHZÐ[Ñ[Ô[€KÝ
ˆ;ÑÔ�3˜tÐ$8Ô9Ñ:Ô:Ò:Ð:Øˆà9Ð9¨[Ð9Ñ9Ô9€GÝ�9”<Ñ Ô Ð!€EÝ˜ '¨!¨"¨"¤+Ñ.Ô.ð )ð )‰	ˆˆcØ�Š�d˜S‘j CÑ'Ñ(Ô(Ð(Ð(Ø	‡L‚L•�y”|Ñ$Ô$Ñ%Ô%Ð%àÐ7�#˜dÐ#5Ô6Ñ7Ô7Ð7Ô8€KØ€HÝ�3˜{Ñ+Ô+Ñ,Ô,ð !ð !ˆ	Ø�9ÔˆØ�9˜q‘=Ô!ˆØˆØ ð 	]ð 	]‰FˆB�Ý”<  B¨¨BÑ/Ô/ˆDØ�NŠN�E $¤'™NœN­E°$´'©N¬N½EÀ$Ä'¹N¼NÍEÐRVÔRYÉNÌNÐ[Ñ\Ô\Ð\Ð\Ø�Š˜Ñ Ô Ð Ð à$ˆ[Ð$˜8Ð$Ð$r   ©rŠ   c                óH   — t          | ||¦  «        }t          | |¦  «        }|S )aV  Structural half of refine_grid: split shaded rows, then under-segmented
    columns. Exposed separately so a caller that must know the header/body
    boundary of the post-structure grid can insert that computation between the
    two phases. table_bbox, when given, bounds the shaded-rectangle search;
    otherwise the cells' union is used.)rò   rI  )r#   r‰   rŠ   s      r   Úrefine_grid_structurer“    s)   € õ ˜t U¨JÑ7Ô7€EÝ)¨$°Ñ6Ô6€EØ€Lr   )ru  rt  rƒ  c                ó*   — t          | ||||¬¦  «        S )a  Row half of refine_grid: split body rows that collapsed several records
    into one grid row. header_row_count is the number of leading header rows to
    keep intact; callers that resolve a header region pass it in, and the default
    of 1 is a conservative single-header assumption.r‚  )r�  )r#   r‰   ru  rt  rƒ  s        r   Úrefine_grid_rowsr•  &  s*   € õ
 "ØØØ'Ø-Ø)ðñ ô ð r   )rŠ   ru  c                óN   — t          | ||¬¦  «        }t          | ||¬¦  «        }|S )aŸ  Refine a detected table's cell grid and return the refined grid.

    ``cells`` is a row-major grid: a list of rows, each a list of ``[x0, y0, x1,
    y1]`` cell rectangles (``None`` for a gap). The grid is refined in three
    stages -- split rows that cell background shading separates, split columns
    that jam several values into one cell, and split body rows that merged
    several records -- using the page's words and vector graphics. The result is
    a new grid in the same format (rows may be added and rows may widen).

    ``table_bbox`` optionally bounds the table (else the cells' union is used).
    ``header_row_count`` is the number of leading header rows to preserve when
    re-cutting body rows (default 1). This is the all-in-one convenience wrapper;
    a caller needing the header boundary of the intermediate grid can instead
    call :func:`refine_grid_structure` then :func:`refine_grid_rows`.
    r‘  )ru  )r“  r•  )r#   r‰   rŠ   ru  s       r   Úrefine_gridr—  4  s2   € õ  " $¨¸*ÐEÑEÔE€EÝ˜T 5Ð;KÐLÑLÔL€EØ€Lr   c           	      óð  — | sg S t          d„ | D ¦   «         ¦  «        }d„ t          |¦  «        D ¦   «         }g }t          | d„ ¬¦  «        }t          j        |d„ ¬¦  «        D ]“\  }}dgt	          |¦  «        z  }|D ]c}t          |d         ¦  «        t          |d         ¦  «        t          |d	         ¦  «        t          |d
         ¦  «        g|||d                  <   Œd|                     |¦  «         Œ”|S )zîConvert a Table's flat cell list into the row-major grid refine_grid wants.

    Mirrors Table.rows: columns are the sorted distinct left edges, rows are the
    cells grouped by top edge, each padded with None where a column has no cell.c                 ó   — h | ]
}|d          ’ŒS )r   r   )r   r   s     r   r  z(_refine_cells_to_grid.<locals>.<setcomp>P  s   € Ð%Ð%Ð%˜!��1”Ð%Ð%Ð%r   c                 ó   — i | ]\  }}||“Œ	S r   r   )r   Úir·   s      r   ú
<dictcomp>z)_refine_cells_to_grid.<locals>.<dictcomp>Q  s   € Ð0Ð0Ð0™$˜!˜Q��AÐ0Ð0Ð0r   c                 ó"   — | d         | d         fS rL   r   ©r   s    r   rO   z'_refine_cells_to_grid.<locals>.<lambda>S  s   € ¨1¨Q¬4°°1´¨,€ r   rP   c                 ó   — | d         S rR  r   rž  s    r   rO   z'_refine_cells_to_grid.<locals>.<lambda>T  s
   € À!ÀAÄ$€ r   Nr   r-   r,   r<   )rZ   r¡   Ú	itertoolsÚgroupbyr1   r   r"   )	r‰   rº   r  ÚgridÚorderedÚ_yÚ	row_cellsr†   r‡   s	            r   Ú_refine_cells_to_gridr¦  I  s  € ð
 ð Øˆ	Ý	Ð%Ð%˜uÐ%Ñ%Ô%Ñ	&Ô	&€BØ0Ð0¥)¨B¡-¤-Ð0Ñ0Ô0€IØ€DÝ�UÐ 6Ð 6Ð7Ñ7Ô7€GÝ"Ô*¨7¸¸ÐGÑGÔGð ð ‰ˆˆIØˆf•s˜2‘w”wÑˆØð 	gð 	gˆDÝ',¨T°!¬W¡~¤~µu¸TÀ!¼W±~´~ÅuÈTÐRSÌWÁ~Ä~ÕW\Ð]aÐbcÔ]dÑWeÔWeÐ&fˆC�	˜$˜qœ'Ô"Ñ#Ð#Ø�Š�CÑÔÐÐØ€Kr   c                 ó   — d„ | D ¦   «         S )zIFlatten a refined grid back to a Table's flat (x0, y0, x1, y1) cell list.c           
      óÀ   — g | ][}|D ]V}|®t          |d         ¦  «        t          |d         ¦  «        t          |d         ¦  «        t          |d         ¦  «        f‘ŒWŒ\S )Nr   r-   r,   r<   r   r…   s      r   r   z)_refine_grid_to_cells.<locals>.<listcomp>^  sp   € ð ð ð àØðð ð ØÐõ 
ˆt�AŒw‰Œ�˜t Aœw™œ­¨t°A¬w©¬½¸tÀA¼w¹¼ÐHð ÐÐÐr   r   )r¢  s    r   Ú_refine_grid_to_cellsr©  \  s#   € ðð àðñ ô ð r   rF   ),Ú__doc__r   rr   rB   r_  r)   r7   rg   rk   rn   ru   rz   r‚   rŒ   r˜   r¥   r®   rÀ   rÉ   rÌ   rÕ   rò   rô   rö   r  r  r  r;  rF  rI  rL  rN  rU  rb  ri  rk  rr  r�  r�  r“  r•  r—  r¦  r©  r   r   r   ú<module>r«     sš  ððð ðB Ð Ð Ð Ø 	€	€	€	Ø €€€ð Ð ðð ð ð:ð ð ð$'ð 'ð 'ðT-ð -ð -ðð ð ð0ð 0ð 0ð
]ð ]ð ]ð )-ð Rð Rð Rð Rð Rðð ð ð&ð ð ð* >Að ð ð ð ð ð"
ð 
ð 
ð%"ð %"ð %"ðPfð fð fðð ð ðð ð ð. ðAð
 ØØØðAð Að Að Að AðJ,ð ,ð ,ð#ð #ð #ð$ð $ð $ðP ¨SÀÐQRðXð Xð Xð Xð Xð"ð ð ð" 45ð >ð >ð >ð >ð >ðB <=È4ð ð ð ð ð ðJ 	ØØØØðð ð ð ð ð8Uð Uð Uðð ð ðð ð ð ð ð ð<	ð 	ð 	ð
ð 
ð 
ð+ð +ð +ð" BFÐXYð +ð +ð +ð +ð +ð^ %)¸TÐTUð&%ð &%ð &%ð &%ð &%ðT 6:ð ð ð ð ð ð 78ÈÐbfð ð ð ð ð ð ,0À!ð ð ð ð ð ð*ð ð ð&ð ð ð ð r   