§
    ŒWêjõ‡  ã                   óÀ  — d Z ddlZddlZddlmZmZ ddlmZ ddlZdZ	 G d„ d¦  «        Z
d„ 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	 dId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/œd0„Z$d&d'd(d)dd1œd2„Z%d3„ Z&d4„ Z'd5„ Z(d6„ Z)d7„ Z*d8„ Z+d9„ Z,d:d;d<œd=„Z-d:d>d;d?œd@„Z.ddAœdB„Z/d;d:d>dCœdD„Z0dd;dEœdF„Z1dG„ Z2dH„ Z3dS )Ja  
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.
é    N)Úbisect_leftÚbisect_right)Úisfiniteg      @c                   ó   — e Zd ZdZd„ Zd„ ZdS )Ú_WordCenterIndexa~  Two sorted word-center axes over a read-only page word list.

    ``candidates(rect)`` returns a superset of the words whose center lies in
    ``rect``, so every consumer still applies its own membership, blank-text and
    claiming rules. The original word indices are preserved, including order and
    duplicates, because they are what identifies a word to its owning cell.
    c                 ól  — g g }}t          |¦  «        D ]v\  }\  }}}}}	||z   dz  ||z   dz  }}
t          |
¦  «        rt          |¦  «        st          d¦  «        ‚|                     |
|f¦  «         |                     ||f¦  «         Œwt	          |¦  «        t	          |¦  «        c| _        | _        d S )Nç      à?znonfinite word center)Ú	enumerater   Ú
ValueErrorÚappendÚsortedÚxsÚys)ÚselfÚwordsr   r   ÚiÚx0Úy0Úx1Úy1Ú_textÚxÚys               ú‡/Users/tedpeters/Documents/Projects/Claude Projects/TPC Houses/house-viewer/.venv/lib/python3.11/site-packages/pymupdf/_table_refine.pyÚ__init__z_WordCenterIndex.__init__B   sÄ   € Ø�RˆBˆÝ*3°EÑ*:Ô*:ð 	ð 	Ñ&ˆAÑ&��B˜˜B Ø˜‘G˜s‘? R¨"¡W°¡OˆqˆAÝ˜Q‘K”Kð :¥H¨Q¡K¤Kð :Ý Ð!8Ñ9Ô9Ð9Ø�IŠI�q˜!�fÑÔÐØ�IŠI�q˜!�fÑÔÐÐÝ! "™:œ:¥v¨b¡z¤zÐˆŒ�”��ó    c           	      ó”  — t          |j        ¦  «        t          |j        ¦  «        t          |j        ¦  «        t          |j        ¦  «        f\  }}}}t          | j        ¦  «        }t          t          t          ||||f¦  «        ¦  «        st          |¦  «        S ||k    s||k    rg S t          | j        |df¦  «        t          | j        ||f¦  «        }}t          | j        |df¦  «        t          | j        ||f¦  «        }
}	||z
  |
|	z
  k    r| j        ||…         n| j        |	|
…         }t          d„ |D ¦   «         ¦  «        S )Néÿÿÿÿc              3   ó    K  — | ]	\  }}|V — Œ
d S ©N© )Ú.0Ú_centerr   s      r   ú	<genexpr>z._WordCenterIndex.candidates.<locals>.<genexpr>W   s&   è è € Ð2Ð2™J˜G Q�aÐ2Ð2Ð2Ð2Ð2Ð2r   )Úfloatr   r   r   r   Úlenr   ÚallÚmapr   Úranger   r   r   r   )r   Úrectr   r   r   r   ÚnÚxlÚxrÚylÚyrÚentriess               r   Ú
candidatesz_WordCenterIndex.candidatesL   s'  € Ý˜tœw™œ­¨t¬w©¬½¸t¼w¹¼ÍÈtÌwÉÌÐW‰ˆˆB��BÝ�”‰LŒLˆÝ•3•x " b¨"¨bÐ!1Ñ2Ô2Ñ3Ô3ð 	Ý˜‘8”8ˆOØ�Š7ˆ7�b˜2’g�gØˆIÝ˜TœW r¨2 hÑ/Ô/µ¸d¼gÈÈAÀwÑ1OÔ1OˆBˆÝ˜TœW r¨2 hÑ/Ô/µ¸d¼gÈÈAÀwÑ1OÔ1OˆBˆà$&¨¡G¨r°B©wÒ$6Ð$6�$”'˜"˜R˜%”.�.¸D¼GÀBÀrÀE¼NˆÝÐ2Ð2¨'Ð2Ñ2Ô2Ñ2Ô2Ð2r   N)Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r1   r!   r   r   r   r   9   s<   € € € € € ðð ð2ð 2ð 2ð3ð 3ð 3ð 3ð 3r   r   c                 óú   — t          | dd¦  «        }|�|d         |u r|d         S 	 t          |¦  «        }n# t          t          t          f$ r d}Y nw xY w	 t          | d||f¦  «         n# t          $ r Y nw xY w|S )a…  The page word list's center index, cached on the page object.

    Keyed on the word list's identity: _refine_page_words returns one stable list
    per page and a fresh extraction produces a new list, so a changed text state
    builds a new index. In-place edits of a cached word list are not supported.
    Returns None for word lists the index cannot represent (see candidates()).
    Ú_table_word_index_cacheNr   é   )Úgetattrr   Ú	TypeErrorr   ÚOverflowErrorÚsetattrÚ	Exception)Úpager   ÚcachedÚindexs       r   Ú_refine_word_indexrA   Z   s·   € õ �TÐ4°dÑ;Ô;€FØÐ˜f Qœi¨5Ð0Ð0Ø�aŒyÐðÝ  Ñ'Ô'ˆˆøÝ•z¥=Ð1ð ð ð ØˆˆˆðøøøðÝ�Ð/°%¸°Ñ@Ô@Ð@Ð@øÝð ð ð Øˆðøøøà€Ls!   §7 ·AÁAÁA+ Á+
A8Á7A8c                 ó�   ‡— | �t          | ‰¦  «        nd}|€t          ‰¦  «        S ˆfd„|                     |¦  «        D ¦   «         S )zF(index, word) pairs that may lie in rect -- a superset of the members.Nc              3   ó,   •K  — | ]}|‰|         fV — Œd S r    r!   )r"   r   r   s     €r   r$   z*_refine_word_candidates.<locals>.<genexpr>u   s+   øè è € Ð:Ð:˜aˆQ��a”ˆMÐ:Ð:Ð:Ð:Ð:Ð:r   )rA   r
   r1   )r>   r   r*   r@   s    `  r   Ú_refine_word_candidatesrD   p   sX   ø€ à/3Ð/?Õ˜t UÑ+Ô+Ð+ÀT€EØ€}Ý˜ÑÔÐØ:Ð:Ð:Ð: 5×#3Ò#3°DÑ#9Ô#9Ð:Ñ:Ô:Ð:r   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 )ÚcrM   N)ÚstrÚget©r"   Úchars     r   r$   z(_refine_rawdict_spans.<locals>.<genexpr>ˆ   s8   è è € ÐXÐX¸$�s 4§8¢8¨C°Ñ#4Ô#4Ñ5Ô5ÐXÐXÐXÐXÐXÐXr   Úcharsc                 ó,   — g | ]}t          |¦  «        ‘ŒS r!   ©r%   )r"   Úvs     r   ú
<listcomp>z)_refine_rawdict_spans.<locals>.<listcomp>�   s   € Ð HÐ HÐ H¨a¥ q¡¤Ð HÐ HÐ Hr   Úbbox)rY   ÚtextrJ   rK   )Úget_textrQ   ÚjoinÚstripr   )	r>   rL   ÚrawÚblockÚlineÚ	directionrK   ÚspanrZ   s	            r   Ú_refine_rawdict_spansrc   y   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).rK   ©Nr   TrJ   é   Fr   r8   )	rQ   Ú
isinstanceÚlistÚtupler&   Úabsr%   r:   r   )rb   ra   ÚdxÚdys       r   Ú_refine_is_vertical_or_rotatedrm   –   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   r8   rf   é   )rP   r]   r%   )r"   Úws     r   rX   z&_refine_page_words.<locals>.<listcomp>±   s   € ð ð ð àÝˆq�Œt‰9Œ9�?Š?ÑÔðÝ	ˆq�Œt‰Œ•e˜A˜aœD‘k”k¥5¨¨1¬¡;¤;µ°a¸´d±´½SÀÀ1Ä¹Y¼YÐGðð ð r   r   c                 óœ   — g | ]I}t          |¦  «        ¯t          |                     d ¦  «        pd¦  «                             ¦   «         ¯G|‘ŒJS )rZ   rM   )rm   rP   rQ   r]   ©r"   rb   s     r   rX   z&_refine_page_words.<locals>.<listcomp>¶   se   € ð ð ð àÝ)¨$Ñ/Ô/ðõ 58¸¿ºÀÑ8HÔ8HÐ8NÈBÑ4OÔ4O×4UÒ4UÑ4WÔ4WðØðð ð r   c                 ó`   — g | ]+}t          j        |                     d ¦  «        pg ¦  «        ‘Œ,S )rY   )ÚpymupdfÚRectrQ   ru   s     r   rX   z&_refine_page_words.<locals>.<listcomp>¼   s3   € ÐXÐXÐXÀ$�œ d§h¢h¨vÑ&6Ô&6Ð&<¸"Ñ=Ô=ÐXÐXÐXr   r	   c              3   óP   •K  — | ] }|j         °	|                     ‰¦  «        V — Œ!d S r    )Úis_emptyÚcontains)r"   r*   Úcenters     €r   r$   z%_refine_page_words.<locals>.<genexpr>Á   s6   øè è € ÐXÐX¨TÈ$Ì-ÐX�4—=’= Ñ(Ô(ÐXÐXÐXÐXÐXÐXr   rZ   c                 ó"   — | d         | d         fS ©Nr8   r   r!   ©Úitems    r   ú<lambda>z$_refine_page_words.<locals>.<lambda>Ê   s   € ¨t°A¬w¸¸Q¼Ð.@€ r   ©Úkey)r9   r[   rc   rw   ÚPointÚanyr   Úziprz   r%   r   r   r   r   rP   r   r<   r=   )r>   Úcacher   Úrotated_spansÚrotated_rectsÚkeptÚwordÚwx0Úwy0Úwx1Úwy1Ú_rb   r*   r|   s                 @r   Ú_refine_page_wordsr‘   ¨   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.r	   r!   )
rŒ   r�   rŽ   r�   r   r   r   r   ÚcxÚcys
             r   Ú_refine_word_in_rectr•   Ò   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          | t          | ¦  «        |¦  «        D ¦   «         S )zGPage words whose center lies in rect, as (x0, y0, x1, y1, text) tuples.c                 ó\   •— g | ](\  }\  }}}}}t          ||||‰‰	‰‰
¦  «        ¯!|||||f‘Œ)S r!   )r•   )r"   r�   rŒ   r�   rŽ   r�   rZ   r   r   r   r   s          €€€€r   rX   z)_refine_words_in_rect.<locals>.<listcomp>Þ   sa   ø€ ð ð ð á)ˆAÑ)��S˜#˜s Dõ    S¨#¨s°B¸¸BÀÑCÔCðØ	ˆc�3˜˜TÐ"ðð ð r   )r%   r   r   r   r   rD   r‘   )r>   r*   r   r   r   r   s     @@@@r   Ú_refine_words_in_rectr˜   Û   s�   øøøø€ å˜4œ7‘^”^¥U¨4¬7¡^¤^µU¸4¼7±^´^ÅUÈ4Ì7Á^Ä^ÐS�N€BˆˆB�ðð ð ð ð ð ð å-DØÕ$ TÑ*Ô*¨Dñ.
ô .
ðñ ô ð r   c                 ój   — t          t          j        d|                      ¦   «         ¦  «        ¦  «        S )z8Loose value-like predicate: the text contains any digit.ú\d)ÚboolÚreÚsearchr]   ©rZ   s    r   Ú_refine_has_digitrŸ   ç   s$   € å•”	˜% §¢¡¤Ñ.Ô.Ñ/Ô/Ð/r   c                 ó¢   — |                       ¦   «         }t          t          j        d|¦  «        ¦  «        ot	          d„ |D ¦   «         ¦  «         S )z=Strict value-like predicate: contains a digit and no letters.rš   c              3   ó>   K  — | ]}|                      ¦   «         V — Œd S r    )ÚisalpharR   s     r   r$   z-_refine_has_digit_no_alpha.<locals>.<genexpr>ï   s*   è è € Ð7\Ð7\È4¸¿º¹¼Ð7\Ð7\Ð7\Ð7\Ð7\Ð7\r   )r]   r›   rœ   r�   r…   )rZ   Ústrippeds     r   Ú_refine_has_digit_no_alphar¤   ì   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 )NTrr   )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 r    )rw   rx   rz   ©r"   ÚrowÚcells      r   rX   z&_refine_table_rect.<locals>.<listcomp>  s[   € ð ð ð àØðð ð ØÐ¥G¤L°Ñ$6Ô$6Ô$?Ðõ 	Œ�TÑÔð ÐÐÐr   r   r8   )rw   rx   rz   Úinclude_rect)ÚcellsÚ
table_bboxr*   Úrectsr€   s        r   Ú_refine_table_rectr¶   ý   s™   € ØÐÝŒ|˜JÑ'Ô'ˆØŒ}ð 	ØˆKðð àðñ ô €Eð ð ØˆtÝŒ<˜˜aœÑ!Ô!€DØ�a�b�b”	ð  ð  ˆØ×Ò˜$ÑÔÐÐØ€Kr   c                óÞ  — ddl m} 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   ©Ú_get_table_drawingsr¨   Úitemsrœ   r8   r¥   )Úpymupdf.tabler¹   r%   r*   Úwidthr¬   rQ   rw   rx   Ú	normalizeÚheightrz   r   )	r>   Ú
table_rectÚmin_dimr¹   ÚoutÚ
page_widthÚdrawingr€   r*   s	            r   Ú_refine_raw_shaded_rectsrÄ     s  € Ø1Ð1Ð1Ð1Ð1Ð1à
€CÝ�t”y”Ñ'Ô'€JØ&Ð& tÑ,Ô,ð ð ˆÝ˜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Å   r@   r*   s      €€€€r   r$   z0_refine_cell_background_rects.<locals>.<genexpr>-  s   øè è € ð 
ð 
ñ #�˜Uð ˜5Ò ð /Ø˜‘×'Ò'Ñ)Ô)¨\¸DÑ-@Ò@ð/à—’Ñ Ô  4¨$¡;Ò.ð
ð 
ð 
ð 
ð 
ð 
r   )r
   rÈ   r…   r   )Ú	raw_rectsrÅ   ÚkeepÚnestedrË   r@   r*   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 )Nr   )r   r   Úsumr&   )ÚvaluesÚ	toleranceÚclustersÚcurrentÚvalues        r   Ú_refine_clusterr×   8  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                 óÊ  — ddl m} 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   r¸   rH   )ÚsÚfsrº   Úlr8   rf   ç      ð?g      $@ç       @r	   rœ   )r»   r¹   ÚsetrQ   rj   r   r   r   r   ÚaddÚroundr   r   rw   rx   r½   rz   r¾   r¼   r   )r>   r¿   r¹   r   r   rÃ   Ústrokedr€   ÚkindÚp1Úp2r*   s               r   Ú_refine_border_linesrå   E  sD  € Ø1Ð1Ð1Ð1Ð1Ð1å	‰Œ€BÝ	‰Œ€BØ&Ð& tÑ,Ô,ð !*ñ !*ˆØ—+’+˜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 r    )rj   )r"   ÚborderÚedgerÓ   s     €€r   r$   z/_refine_drop_near.<locals>.<listcomp>.<genexpr>p  s5   øè è € Ð-dÐ-dÐRX­c°$¸±-Ñ.@Ô.@ÀIÒ.MÐ-dÐ-dÐ-dÐ-dÐ-dÐ-dr   ©r…   )r"   rê   ÚbordersrÓ   s    @€€r   rX   z%_refine_drop_near.<locals>.<listcomp>p  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î   o  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 )Nr	   TF)rP   r]   )r   r   r   r   r   ÚmarginrŒ   r�   rŽ   r�   rZ   r“   r”   s                r   Ú_refine_has_textrñ   s  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 r    r!   )r"   rê   rð   r   r   s     €€€r   r$   z3_refine_content_filter_row_edges.<locals>.<genexpr>  sL   øè è € ÐSÐS˜D°"°v±+ÀÐ2RÐ2RÒ2RÐ2RÀrÈFÁ{Ò2RÐ2RÐ2RÐ2RÐ2R�4Ð2RÐ2RÐ2RÐ2RÐSÐSr   r8   ©rð   r   )r   r)   r&   rñ   Úpop)r   r   r   r1   r   r   rð   rí   ÚboundsÚempty_indexr@   s    ``   `    r   Ú _refine_content_filter_row_edgesrø   ~  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%   r   r   )r"   r*   rê   s      r   rX   z&_split_shaded_rows.<locals>.<listcomp>«  s:   € ÐXÐXÐX�$½¸d¼g¹¼ÍÈdÌgÉÌÐ7WÐXÐX¨tˆÐXÐXÐXÐXr   )rÓ   r   c                 ó:   — g | ]}|®t          j        |¦  «        ‘ŒS r    ©rw   rx   ©r"   r±   s     r   rX   z&_split_shaded_rows.<locals>.<listcomp>·  s'   € ÐGÐGÐG t°dÐ6F•”˜TÑ"Ô"Ð6FÐ6FÐ6Fr   c              3   ó>   K  — | ]}t          |j        ¦  «        V — Œd S r    )r%   r   rÿ   s     r   r$   z%_split_shaded_rows.<locals>.<genexpr>»  ó*   è è € Ð2Ð2 T•%˜œ‘.”.Ð2Ð2Ð2Ð2Ð2Ð2r   c              3   ó>   K  — | ]}t          |j        ¦  «        V — Œd S r    )r%   r   rÿ   s     r   r$   z%_split_shaded_rows.<locals>.<genexpr>¼  r  r   c              3   ó>   K  — | ]}t          |j        ¦  «        V — Œd S r    )r%   r   rÿ   s     r   r$   z%_split_shaded_rows.<locals>.<genexpr>½  r  r   c              3   ó>   K  — | ]}t          |j        ¦  «        V — Œd S r    )r%   r   rÿ   s     r   r$   z%_split_shaded_rows.<locals>.<genexpr>¾  r  r   rô   r8   rf   )r¶   rÄ   rÏ   r×   rå   rî   r‘   r   ÚminÚmaxrø   r)   r&   rw   rx   r%   r   r   )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±   r*   s                               r   Ú_split_shaded_rowsr  ’  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 r    )r¤   rž   s    r   Ú_refine_value_liker  ×  s   € Ý% dÑ+Ô+Ð+r   c                 ó    — t          | ¦  «        S r    )rŸ   rž   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Ý   rf   Fc                 ó   — | d         S )Nrf   r!   r   s    r   r�   z*_refine_cell_span_signal.<locals>.<lambda>ï  s
   €   Q¤€ r   r‚   r   r8   Nr   c                 ó   — | d         S re   r!   r   s    r   r�   z*_refine_cell_span_signal.<locals>.<lambda>û  s
   €  4¨¤7€ r   ú c              3   ó&   K  — | ]}|d          V — ŒdS ©rr   Nr!   ©r"   r‹   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)rw   rx   r˜   rP   r]   r%   r   r   r   r   r   r&   Úsortr)   r\   r  )r>   r±   ÚgapÚline_tolerancer*   r   r   r   r   r   rZ   r£   r“   r”   rI   rÕ   r‹   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Ó?rf   ©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   r8   c              3   ó.   •K  — | ]\  }}|‰k    ¯|V — Œd S r    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   )r&   r  Úintr
   r'  rQ   r   rº   )r>   r³   r#  r$  r)  r*  ÚrowsÚcol_hitsr°   Ú	col_indexr±   r/  s              @r   Ú_refine_detect_span_columnsr4    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Ý   )r&   rw   rx   r˜   rP   r]   r%   r   r   r   r   r   r   )r>   r³   r-  r1  r°   r   r*   r   r   r   r   rZ   r“   r”   s                 r   Ú_refine_column_wordsr6    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   r   r   r�   s         r   rX   z"_refine_cut_xs.<locals>.<listcomp>)  s<   € ÐlÐlÐlÑ)9¨°EÐfkÐlÐlÑWbÐXZÐ\^Ð`a�"�b˜)Ð$ÐlÐlÐlÐlr   rf   c              3   ó"   K  — | ]
\  }}}|V — Œd S r    r!   )r"   r   r�   s      r   r$   z!_refine_cut_xs.<locals>.<genexpr>-  s(   è è € Ð*Ð*‘H�B˜˜1ˆRÐ*Ð*Ð*Ð*Ð*Ð*r   c              3   ó"   K  — | ]
\  }}}|V — Œd S r    r!   )r"   r�   r   s      r   r$   z!_refine_cut_xs.<locals>.<genexpr>.  s(   è è € Ð*Ð*‘H�A�r˜1ˆRÐ*Ð*Ð*Ð*Ð*Ð*r   r8   c                 ó<   •— h | ]\  }}}|‰cxk     r|k     ¯n n|’ŒS r!   r!   )r"   r   r   r;  r   s       €r   ú	<setcomp>z!_refine_cut_xs.<locals>.<setcomp>6  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 r    r!   ©r"   r   r   r�   Úcut_xs       €r   r$   z+_refine_cut_xs.<locals>.<genexpr>.<genexpr>F  óA   øè è € Ð=eÐ=eÑR[ÐRTÐVXÐZ[¸bÀ5¸o¸oºo¸oÈ2ºo¸o¸o¸oÐ=eÐ=eÐ=eÐ=eÐ=eÐ=er   r8   Nrë   ©r"   r   rC  s     €r   r$   z!_refine_cut_xs.<locals>.<genexpr>F  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 r    r!   rB  s       €r   r$   z,_refine_cut_xs.<locals>.<listcomp>.<genexpr>I  rD  r   rë   rE  s     €r   rX   z"_refine_cut_xs.<locals>.<listcomp>I  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"   r   r   rZ   rC  s       €r   rX   z"_refine_cut_xs.<locals>.<listcomp>P  s$   ø€ ÐBÐBÐB™\˜R  T°b¸E²k°k�D°k°k°kr   c                 ó(   •— g | ]\  }}}|‰k    ¯|‘ŒS r!   r!   rI  s       €r   rX   z"_refine_cut_xs.<locals>.<listcomp>Q  s$   ø€ ÐCÐCÐC™l˜b " d°r¸U²{°{�T°{°{°{r   r  r	   )
r
   r&   r  r  r   rÑ   r  r\   Úextendr   )Ú
rows_wordsr8  Ú	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&  rC  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   ©r8  Ú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 r    )r&   )r"   r°   s     r   r$   z(_refine_split_columns.<locals>.<genexpr>j  s(   è è € Ð+Ð+˜c•�S‘”Ð+Ð+Ð+Ð+Ð+Ð+r   r   )Údefaultr7  r8   c                 ó4   •— g | ]}‰|cxk     r‰k     ¯n n|‘ŒS r!   r!   )r"   rC  r   r   s     €€r   rX   z)_refine_split_columns.<locals>.<listcomp>‚  s.   ø€ ÐHÐHÐH u¸¸U¸¸º¸ÀRº¸¸¸¸˜U¸¸¸r   )r  rÞ   r)   r^  r6  r
   rQ   r   rK  r&   rw   rx   )r>   r³   r8  r`  ÚncolsÚactive_colsÚcol_cutsr-  r  r  r°   Únew_rowr±   r   r   r   r@   r   r   s                    @@r   Ú_refine_split_columnsri  i  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*  r8  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_  )r4  ri  rÞ   )r>   r³   r#  r$  r)  r*  r8  Ú
fired_colss           r   Ú_split_undersegmented_columnsrl  Š  s`   € õ -ØØØØ%Ø#Øðñ ô €Jð ð ØˆÝ ØˆeÐ&6ÅSÈÁ_Ä_ðñ ô ð r   c                 ó   — d„ | D ¦   «         S )Nc                 óD   — g | ]}|D ]}|®t          j        |¦  «        ‘ŒŒS r    rþ   r¯   s      r   rX   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_cellsro  ¦  s   € ØTÐT¨%ÐTÑTÔTÐTr   c                 ó†   — | sd S t          j        | d         ¦  «        }| dd …         D ]}|                     |¦  «         Œ|S )Nr   r8   )rw   rx   r²   )rµ   r*   r€   s      r   Ú_refine_union_rectrq  ª  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 ©Nr8   r!   rÿ   s     r   r$   z?_refine_best_column_bounds.<locals>.<lambda>.<locals>.<genexpr>¶  s'   è è € ÐCÐC 4°$Ð2B˜QÐ2BÐ2BÐ2BÐ2BÐCÐCr   )rÑ   r&   )r°   s    r   r�   z,_refine_best_column_bounds.<locals>.<lambda>¶  s(   € �ÐCÐC¨3ÐCÑCÔCÑCÔCÅSÈÁXÄXÐN€ r   )rƒ   rc  c              3   ó²   K  — | ]R}|�Nt          j        |¦  «        }|j        |j        k    ¯(t	          |j        ¦  «        t	          |j        ¦  «        fV — ŒSd S r    )rw   rx   r   r   r%   )r"   r±   r*   s      r   r$   z-_refine_best_column_bounds.<locals>.<genexpr>¹  si   è è € ð ð àØÐÝ”\ $Ñ'Ô'ˆDØŒ7�T”WÒÐõ	 
ˆtŒw‰Œ�˜tœw™œÐ(ð ÐÐÐðð r   )r  r   )r³   Úbest_rowrö   s      r   Ú_refine_best_column_boundsrx  ³  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 )Nr8   rr   rÝ   r   r!   r   s    r   r�   z,_refine_cluster_words_by_y.<locals>.<lambda>È  s!   € ¨T°!¬W°t¸A´wÑ->À#Ñ,EÀtÈAÄwÐ+O€ r   r‚   r   r8   rr   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 )r8   Nr!   r   s     r   r$   z-_refine_cluster_words_by_y.<locals>.<genexpr>Ø  r|  r   c              3   ó&   K  — | ]}|d          V — ŒdS )rf   Nr!   r   s     r   r$   z-_refine_cluster_words_by_y.<locals>.<genexpr>Ù  r|  r   c              3   ó&   K  — | ]}|d          V — ŒdS r  r!   r   s     r   r$   z-_refine_cluster_words_by_y.<locals>.<genexpr>Ú  r|  r   r  c              3   ó&   K  — | ]}|d          V — ŒdS )rq   Nr!   r   s     r   r$   z-_refine_cluster_words_by_y.<locals>.<genexpr>Û  s&   è è € Ð _Ð _¨T  a¤Ð _Ð _Ð _Ð _Ð _Ð _r   c                 ó   — | d         S re   r!   r   s    r   r�   z,_refine_cluster_words_by_y.<locals>.<lambda>Û  s   € ÐVZÐ[\ÔV]€ r   )r   r   r   r   rZ   )r   Ú_REFINE_LINE_GAPr   r  r  r\   )r   rÔ   Úlast_centerr‹   r|   rI   Úclusters          r   Ú_refine_cluster_words_by_yr…  Ã  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 )Nr   r   rÝ   r   )rÞ   r%   r
   r  r  rß   )
r`   Ú
col_boundsÚcolsÚline_x0Úline_x1r|   r@   r   r   Úoverlaps
             r   Ú_refine_line_columnsrŒ  á  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 )Nr	   )	r%   r   r   r   r   r‘   rP   r]   r   )r>   r*   r   r  r  r  r  r   r   r   r   rZ   r“   r”   s                 r   Ú_refine_page_words_in_rectrŽ  í  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   r8   r   c                 ó   — g | ]	\  }}||f‘Œ
S r!   r!   ©r"   r   r   s      r   rX   z3_refine_merge_overlapping_lines.<locals>.<listcomp>  s    € Ð*Ð*Ð*™˜˜RˆR�ˆHÐ*Ð*Ð*r   )r   r%   r  r  r   )	rI   Úfracrº   Úmergedr   r   rÕ   r‹  Ú
min_heights	            r   Ú_refine_merge_overlapping_linesr•  ú  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ë?r8   ©Ú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.r8   r   Nrf   c                 óT   — g | ]%\  }}t          |d ¦  «        t          |d ¦  «        g‘Œ&S )rf   )rà   ©r"   r   r   s      r   rX   z0_refine_detect_row_overmerge.<locals>.<listcomp>2  s1   € ÐMÐMÐM¹¸¸B�˜b !™œ¥e¨B°¡l¤lÐ3ÐMÐMÐMr   c                 ób   — g | ],}t          |d          ¦  «        t          |d         ¦  «        g‘Œ-S )r   r   rV   )r"   r`   s     r   rX   z0_refine_detect_row_overmerge.<locals>.<listcomp>3  s5   € Ð_Ð_Ð_È$¥ d¨4¤jÑ 1Ô 1µ5¸¸d¼Ñ3DÔ3DÐEÐ_Ð_Ð_r   )Ú	body_bboxr‡  Úrecord_line_boundsÚexisting_body_rowsr˜  )rx  r  r  r0  r&   rq  ro  rz   rŽ  r…  r   rŒ  r   r   r   r   r   )r>   r³   r—  r˜  r‡  rŸ  Ú	body_rectr   rI   Úmin_colsÚrecord_linesr`   rˆ  Ú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Ö?©r—  Úmerge_overlap_fracr˜  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.r–  Nr�  c                 óP   — g | ]#\  }}t          |¦  «        t          |¦  «        f‘Œ$S r!   rV   r›  s      r   rX   z*_split_overmerged_rows.<locals>.<listcomp>H  s-   € ÐJÐJÐJ©V¨R°•5˜‘9”9�e B™iœiÐ(ÐJÐJÐJr   r‡  c                 óP   — g | ]#\  }}t          |¦  «        t          |¦  «        f‘Œ$S r!   rV   r‘  s      r   rX   z*_split_overmerged_rows.<locals>.<listcomp>I  s-   € ÐWÐWÐW±&°"°b�˜b™	œ	¥5¨¡9¤9Ð-ÐWÐWÐWr   rž  )r’  rŸ  c                 ó$   — g | ]\  }}||z   d z  ‘ŒS )rÝ   r!   r‘  s      r   rX   z*_split_overmerged_rows.<locals>.<listcomp>N  s$   € Ð9Ð9Ð9¡6 2 r��R‘˜3‰Ð9Ð9Ð9r   r8   rÝ   r˜  )r¤  rw   rx   r•  r&   r0  r%   r   r†   r   r   r)   r   r   )r>   r³   r—  r¦  r˜  Úmetar�  r‡  Úraw_line_boundsÚline_boundsÚcentersrí   ÚprevÚnxtÚheader_rowsÚnew_bodyr;  r   r   rh  r   r   r*   s                          r   Ú_split_overmerged_rowsr³  9  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  rl  )r>   r³   r´   s      r   Úrefine_grid_structurer¶  c  s)   € õ ˜t U¨JÑ7Ô7€EÝ)¨$°Ñ6Ô6€EØ€Lr   )r˜  r—  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³   r˜  r—  r¦  s        r   Úrefine_grid_rowsr¸  n  s*   € õ
 "ØØØ'Ø-Ø)ðñ ô ð r   )r´   r˜  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´  )r˜  )r¶  r¸  )r>   r³   r´   r˜  s       r   Úrefine_gridrº  |  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"   rO   s     r   r?  z(_refine_cells_to_grid.<locals>.<setcomp>˜  s   € Ð%Ð%Ð%˜!��1”Ð%Ð%Ð%r   c                 ó   — i | ]\  }}||“Œ	S r!   r!   )r"   r   r   s      r   ú
<dictcomp>z)_refine_cells_to_grid.<locals>.<dictcomp>™  s   € Ð0Ð0Ð0™$˜!˜Q��AÐ0Ð0Ð0r   c                 ó"   — | d         | d         fS r~   r!   ©rO   s    r   r�   z'_refine_cells_to_grid.<locals>.<lambda>›  s   € ¨1¨Q¬4°°1´¨,€ r   r‚   c                 ó   — | d         S ru  r!   rÀ  s    r   r�   z'_refine_cells_to_grid.<locals>.<lambda>œ  s
   € À!ÀAÄ$€ r   Nr   r8   rf   rr   )r   r
   Ú	itertoolsÚgroupbyr&   r%   r   )	r³   r   r3  ÚgridÚorderedÚ_yÚ	row_cellsr°   r±   s	            r   Ú_refine_cells_to_gridrÈ  ‘  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   r8   rf   rr   rV   r¯   s      r   rX   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   r    )4r5   rÂ  rœ   Úbisectr   r   Úmathr   rw   r‚  r   rA   rD   rc   rm   r‘   r•   r˜   rŸ   r¤   r¬   r¶   rÄ   rÏ   r×   rå   rî   rñ   rø   r  r  r  r'  r4  r6  r^  ri  rl  ro  rq  rx  r…  rŒ  rŽ  r•  r¤  r³  r¶  r¸  rº  rÈ  rË  r!   r   r   ú<module>rÎ     s  ððð ðB Ð Ð Ð Ø 	€	€	€	Ø ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ð ,Ø Ð Ð Ð Ð Ð Ø €€€ð Ð ð3ð 3ð 3ð 3ð 3ñ 3ô 3ð 3ðBð ð ð,;ð ;ð ;ðð ð ð:ð ð ð$'ð 'ð 'ðT-ð -ð -ð	ð 	ð 	ð0ð 0ð 0ð
]ð ]ð ]ð )-ð Rð Rð Rð Rð Rðð ð ð&ð ð ð. >Að ð ð ð ð ð"
ð 
ð 
ð'"ð '"ð '"ðT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   