ó
    /j-j«Ë  ã                  óø  • S r SSKJr  SSKrSSKrSSKrSSKrSSKrSSKrSSK	r	SSK
Jr  SSK
Jr  SSKJr  SSKJr  SSKrSSKrSSKr\R,                  S:¼  a  SS	KJr  SS
KJr  OSS	KJr  SS
KJr  SSKJr  SSKJr  SSKJr  SSKJ r   SSKJ!r!  Sr"Sr#/ SQr$/ SQr%\$\%-   r& " S S5      r' " S S\'5      r( " S S5      r) " S S\)5      r* " S S5      r+ " S S 5      r,S&S'S! jjr- " S" S#\5      r. " S$ S%5      r/g)(z6Contains the core functions to parse tables from PDFs.é    )ÚannotationsN)ÚIterable)ÚIterator)Ú
itemgetter)ÚAny)é   é   )Ú	TypedDict)ÚUnpacké   )ÚImageConversionBackend)Úundo_rotation)Úbuild_file_path_in_temp_dir)Úget_index_closest_point)Úget_textline_coordsé   é
   ©ÚleftÚrightÚmiddle)ÚtopÚbottomÚcenterc                  ó*   • \ rS rSrSrS rS rS rSrg)ÚTextAlignmenté1   aÇ  Represents a list of textlines sharing an alignment on a coordinate.

The alignment can be left/right/middle or top/bottom/center.
(PDF coordinate space)

Parameters
----------
coord : float
    coordinate of the initial text edge. Depending on the alignment
    it could be a vertical or horizontal coordinate.
textline : obj
    the original textline to start the alignment
align : str
    Name of the alignment (e.g. "left", "top", etc)

Attributes
----------
coord : float
    The coordinate aligned averaged out across textlines.  It can be along
    the x or y axis.
textlines : array
    Array of textlines that demonstrate this alignment.
align : str
    Name of the alignment (e.g. "left", "top", etc)
c                ó,   • Xl         U/U l        X0l        g ©N)ÚcoordÚ	textlinesÚalign©Úselfr    Útextliner"   s       ÚI/home/mande/repo/quber/.venv/lib/python3.13/site-packages/camelot/core.pyÚ__init__ÚTextAlignment.__init__L   s   € ØŒ
Ø"˜ˆŒØ�
ó    c                óÆ   • SR                  [        S U R                  S S 5      5      R                  SS5      nSU R                   S[        U R                  5       SU S	3$ )
Nz | c                ó"   • U R                  5       $ r   )Úget_text©Úxs    r&   Ú<lambda>Ú(TextAlignment.__repr__.<locals>.<lambda>S   s
   € ˜!Ÿ*™*œ,r)   é   Ú
Ú z<TextEdge coord=z tl=z textlines text='z...'>)ÚjoinÚmapr!   Úreplacer    Úlen)r$   Útext_insides     r&   Ú__repr__ÚTextAlignment.__repr__Q   si   € Ø—j‘jÜÑ&¨¯©°r¸Ð(:Ó;ó
ç
‰'�$˜Ó
ð 	ð ˜tŸz™z˜l¨$¬s°4·>±>Ó/BÐ.Cð DØ*˜m¨5ð2ð	
r)   c                óÒ   • U R                   [        U R                  5      -  U-   [        [        U R                  5      S-   5      -  U l         U R                  R	                  U5        g)z<Update new textline to this alignment, adapting its average.r   N)r    r7   r!   ÚfloatÚappend)r$   r%   r    s      r&   Úregister_aligned_textlineÚ'TextAlignment.register_aligned_textlineZ   sT   € ð —j‘j¤3 t§~¡~Ó#6Ñ6¸Ñ>Ä%Ü�—‘Ó !Ñ#óC
ñ 
ˆŒ
ð 	�‰×Ñ˜hÕ'r)   )r"   r    r!   N)	Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r'   r9   r>   Ú__static_attributes__© r)   r&   r   r   1   s   † ñò4ò

õ(r)   r   c                  ó<   ^ • \ rS rSrSrU 4S jrS rSS jrSrU =r	$ )ÚTextEdgeéd   a  Defines a text edge coordinates relative to a left-bottom origin.

(PDF coordinate space)
An edge is an alignment bounded over a segment.

Parameters
----------
coord : float
    coordinate of the text edge.  Can be x or y.
y0 : float
    y-coordinate of bottommost point.
y1 : float
    y-coordinate of topmost point.
align : string, optional (default: 'left')
    {'left', 'right', 'middle'}

Attributes
----------
is_valid: bool
    A text edge is valid if it intersects with at least
    TEXTEDGE_REQUIRED_ELEMENTS horizontal text rows.

c                óx   >• [         TU ]  XU5        UR                  U l        UR                  U l        SU l        g )NF)Úsuperr'   Úy0Úy1Úis_valid)r$   r    r%   r"   Ú	__class__s       €r&   r'   ÚTextEdge.__init__}   s/   ø€ Ü‰Ñ˜¨%Ô0Ø—+‘+ˆŒØ—+‘+ˆŒØˆ�r)   c                óÒ   • [        U R                  S5      n[        U R                  S5      n[        U R                  S5      nSU SU SU SU R                   SU R
                   S3$ )Nr1   z<TextEdge x=z y0=ú y1=z align=z valid=Ú>)Úroundr    rL   rM   r"   rN   )r$   r.   rL   rM   s       r&   r9   ÚTextEdge.__repr__ƒ   sd   € Ü�$—*‘*˜aÓ ˆÜ�4—7‘7˜AÓˆÜ�4—7‘7˜AÓˆà˜1˜#˜T "  T¨"¨¨W°T·Z±Z°LÀÈÏÉÀÐVWÐXð	
r)   c                óò   • [         R                  " U R                  UR                  US9(       aH  U R                  X!5        UR                  U l        [	        U R
                  5      [        :¼  a  SU l        ggg)zrUpdate text edge coordinates.

Update the text edge's x and bottom y coordinates and sets
the is_valid attribute.
©Úabs_tolTN)ÚmathÚiscloserL   r>   r7   r!   ÚTEXTEDGE_REQUIRED_ELEMENTSrN   )r$   r.   r%   Úedge_tols       r&   Úupdate_coordsÚTextEdge.update_coords‹   s\   € ô �<Š<˜Ÿ™ §¡°h×?Ø×*Ñ*¨8Ô7Ø—k‘kˆDŒGô �4—>‘>Ó"Ô&@Ó@Ø $�•ð Að @r)   )rN   rL   rM   ©é2   )
r@   rA   rB   rC   rD   r'   r9   r]   rE   Ú__classcell__©rO   s   @r&   rH   rH   d   s   ø† ñõ0ò
÷%ò %r)   rH   c                  ó:   • \ rS rSrSrS r\S 5       rS rS r	Sr
g)	ÚTextAlignmentséŸ   z9Defines a dict of text edges across reference alignments.c                óB   • 0 U l         U H  n/ U R                   U'   M     g r   ©Ú_text_alignments)r$   Úalignment_namesÚalignment_names      r&   r'   ÚTextAlignments.__init__¢   s$   € à "ˆÔÛ-ˆNØ46ˆD×!Ñ! .Ó1ò .r)   c                ó   • [        XU5      $ r   )r   )r    r%   r"   s      r&   Ú_create_new_text_alignmentÚ)TextAlignments._create_new_text_alignment¨   s   € ä˜U¨eÓ4Ð4r)   c                ó   • [         $ r   )ÚNotImplemented©r$   Ú	alignmentr    r%   s       r&   Ú_update_alignmentÚ TextAlignments._update_alignment¬   s   € ÜÐr)   c                ój  • [        U5      nU R                  R                  5        HŠ  u  p4X#   n[        XTS S9nSnUc  SnOFXF   R                  nUS-
  Us=:  a	  US-   :  a  O  OU R                  XF   XQ5        OX…:  a  US-   nOUnUc  Mg  U R                  XQU5      n	UR                  Xy5        MŒ     g)z1Update an existing text edge in the current dict.c                ó   • U R                   $ r   )r    r-   s    r&   r/   Ú3TextAlignments._register_textline.<locals>.<lambda>·   s   € °Q·W²Wr)   )ÚfnNr   g      à?r   )r   rh   Úitemsr   r    rs   rm   Úinsert)
r$   r%   ÚcoordsÚalignment_idÚalignment_arrayr    Úidx_closestÚ
idx_insertÚcoord_closestÚnew_alignments
             r&   Ú_register_textlineÚ!TextAlignments._register_textline¯   sÏ   € ä$ XÓ.ˆØ-1×-BÑ-B×-HÑ-HÖ-JÑ)ˆLØÑ(ˆEô 2ØÑ+<ñˆKð ˆJØÑ"Ø‘
à /Ñ <× BÑ B�à˜3‘; Õ<°¸±Ö<Ø×*Ñ*Ø'Ñ4°eõð #Ó*Ø!,¨q¡‘Jà!,�JØÓ%Ø $× ?Ñ ?Ø \ó!�ð  ×&Ñ& zÖAò9 .Kr)   rg   N)r@   rA   rB   rC   rD   r'   Ústaticmethodrm   rs   r‚   rE   rF   r)   r&   rd   rd   Ÿ   s)   † ÙCò7ð ñ5ó ð5òõBr)   rd   c                  ór   ^ • \ rS rSrSrSU 4S jjrS rS rS rS r	S r
S	 rS
 rS rS rS rS rSrU =r$ )Ú	TextEdgeséÑ   zíDefines a dict text edges on the PDF page.

The dict contains the left, right and middle text edges found on
the PDF page. The dict has three keys based on the alignments,
and each key's value is a list of camelot.core.TextEdge objects.
c                ó8   >• [         TU ]  [        5        Xl        g r   )rK   r'   ÚHORIZONTAL_ALIGNMENTSr\   )r$   r\   rO   s     €r&   r'   ÚTextEdges.__init__Ù   s   ø€ Ü‰ÑÔ.Ô/Ø �r)   c                ó   • [        XU5      $ r   )rH   r#   s       r&   rm   Ú$TextEdges._create_new_text_alignmentÝ   s   € ä˜¨Ó/Ð/r)   c                ód   • U R                  XU5      nU R                  U   R                  U5        g)z(Add a new text edge to the current dict.N)rm   rh   r=   )r$   r    r%   r"   Útes        r&   ÚaddÚTextEdges.addá   s-   € à×,Ñ,¨U¸eÓDˆØ×Ñ˜eÑ$×+Ñ+¨BÕ/r)   c                ó<   • UR                  X#U R                  5        g r   )r]   r\   rq   s       r&   rs   ÚTextEdges._update_alignmentæ   s   € Ø×Ñ °·±Õ?r)   c                ó’   • U HA  n[        UR                  5       R                  5       5      S:”  d  M0  U R                  U5        MC     g)z<Generates the text edges dict based on horizontal text rows.r   N)r7   r,   Ústripr‚   )r$   r!   Útls      r&   ÚgenerateÚTextEdges.generateé   s6   € ãˆBÜ�2—;‘;“=×&Ñ&Ó(Ó)¨AÕ-Ø×'Ñ'¨Ö+ò r)   c                óJ  • [        S U R                  S    5       5      [        S U R                  S    5       5      [        S U R                  S    5       5      S.n[        UR                  5       [	        S5      S	9S
   n[        [        S U R                  U   5      5      $ )z†Return the list of relevant text edges.

(all share the same alignment)
based on which list intersects horizontal text rows the most.
c              3  óp   #   • U  H,  oR                   (       d  M  [        UR                  5      v •  M.     g 7fr   ©rN   r7   r!   ©Ú.0rŽ   s     r&   Ú	<genexpr>Ú)TextEdges.get_relevant.<locals>.<genexpr>ö   s'   é € ð Ú,I bÏ[Í[Ó!”�B—L‘L×!Ð!Ò,Iùs   ‚6š6r   c              3  ór   #   • U  H-  nUR                   (       d  M  [        UR                  5      v •  M/     g 7fr   rš   r›   s     r&   r�   rž   ù   s,   é € ð â8�BØ—;•;ó "”�B—L‘L×!Ð!Ú8ùó   ‚7›7r   c              3  ór   #   • U  H-  nUR                   (       d  M  [        UR                  5      v •  M/     g 7fr   rš   r›   s     r&   r�   rž   þ   s,   é € ð â9�BØ—;•;ó "”�B—L‘L×!Ð!Ú9ùr    r   r   r   ©Úkeyr   c                ó   • U R                   $ r   )rN   ©rŽ   s    r&   r/   Ú(TextEdges.get_relevant.<locals>.<lambda>
  s   € ˜bŸkškr)   )Úsumrh   Úmaxry   r   ÚlistÚfilter)r$   Úintersections_sumÚrelevant_aligns      r&   Úget_relevantÚTextEdges.get_relevantï   s´   € ô ñ Ø,0×,AÑ,AÀ&Ò,Ióó ô ñ à×/Ñ/°Ò8óó ô
 ñ à×/Ñ/°Ò9óó ñ
Ðô& Ð.×4Ñ4Ó6¼JÀq»MÑJÈ1ÑMˆÜÜÑ)¨4×+@Ñ+@ÀÑ+PÓQó
ð 	
r)   c                óØ   • UR                  S S9  U R                  U5      nU R                  X15        U R                  U5      nU Vs0 s H  oPR	                  XT5      S_M     nnU$ s  snf )a¥  
Return a dict of interesting table areas on the PDF page.

The table areas are calculated using relevant text edges.

Parameters
----------
textlines : list
    List of text line objects that are relevant for determining table areas.
relevant_textedges : list
    List of relevant text edge objects used to identify table areas.

Returns
-------
dict
    A dictionary with padded table areas as keys and None as values.
c                ó4   • U R                   * U R                  4$ r   )rL   r    r¥   s    r&   r/   Ú+TextEdges.get_table_areas.<locals>.<lambda>   s   € °·±°¸¿¹Ñ/Ar)   r¢   N)ÚsortÚ_initialize_table_areasÚ"_extend_table_areas_with_textlinesÚ"_calculate_average_textline_heightÚ_pad)r$   r!   Úrelevant_textedgesÚtable_areasÚaverage_textline_heightÚareaÚpadded_table_areass          r&   Úget_table_areasÚTextEdges.get_table_areas  s}   € ð& 	×ÑÑ$AÐÑBà×2Ñ2Ð3EÓFˆØ×/Ñ/°ÔGð #'×"IÑ"IÈ)Ó"TÐáGRó
ÚGR¸t�I‰I�dÓ4°dÒ:Á{ð 	ð 
ð "Ð!ùò	
s   ÁA'c                ó°   • 0 nU HM  nU(       d2  SX#R                   UR                  UR                   UR                  4'   M<  U R                  X#5        MO     U$ )a
  
Initialize table areas based on relevant text edges.

Parameters
----------
relevant_textedges : list
    List of relevant text edge objects used to initialize table areas.

Returns
-------
dict
    A dictionary of table areas initialized from relevant text edges.
N)r    rL   rM   Ú_update_table_areas)r$   r·   r¸   rŽ   s       r&   r³   Ú!TextEdges._initialize_table_areas-  sM   € ð ˆÛ$ˆBÞØBF�ŸX™X r§u¡u¨b¯h©h¸¿¹Ð>Ó?à×(Ñ(¨Ö9ñ	 %ð Ðr)   c                ó   • SnU H/  nUR                   US   :¼  d  M  UR                  US   ::  d  M-  Un  O   Uc1  SXR                  UR                  UR                  UR                   4'   gUR                  U5        US   [	        UR                  US   5      [        US   UR                  5      [        US   UR                   5      4nSX'   g)zé
Update table areas by checking for overlaps with new text edges.

Parameters
----------
table_areas : dict
    Current table areas to be updated.
te : object
    The new text edge object to check for overlaps.

Returns
-------
None
Nr   r   r   r1   )rM   rL   r    ÚpopÚminr¨   )r$   r¸   rŽ   Úfoundrº   Úupdated_areas         r&   r¿   ÚTextEdges._update_table_areasD  s¼   € ð ˆÛˆDà�u‰u˜˜Q™Õ B§E¡E¨T°!©WÕ$4Ø�Ùñ	  ð ‰=Ø>BˆKŸ™ 2§5¡5¨"¯(©(°B·E±EÐ:Ò;à�O‰O˜EÔ"à�a‘Ü�B—E‘E˜5 ™8Ó$Ü�E˜!‘H˜bŸh™hÓ'Ü�E˜!‘H˜bŸe™eÓ$ð	ˆLð )-ˆKÒ%r)   c                ó|  • U H¶  nSnU H/  nUR                   US   :¼  d  M  UR                  US   ::  d  M-  Un  O   Uc  M?  UR                  U5        [        UR                  US   5      [        UR                   US   5      [        US   UR                  5      [        US   UR                  5      4nSX'   M¸     g)zü
Extend table areas based on text lines that overlap vertically.

Parameters
----------
table_areas : dict
    Current table areas to be extended.
textlines : list
    List of text line objects relevant for extending table areas.

Returns
-------
None
Nr   r   r   r1   )rL   rM   rÂ   rÃ   Úx0r¨   Úx1)r$   r¸   r!   r•   rÄ   rº   rÅ   s          r&   r´   Ú,TextEdges._extend_table_areas_with_textlinesf  s±   € ó ˆBØˆEÛ#�à—5‘5˜D ™GÕ#¨¯©°°a±Õ(8Ø �EÙñ	 $ð Ó Ø—‘ Ô&ä˜Ÿ™˜u Q™xÓ(Ü˜Ÿ™˜u Q™xÓ(Ü˜˜a™ "§%¡%Ó(Ü˜˜a™ "§%¡%Ó(ð	 �ð -1�Ó)ò! r)   c                óf   • [        S U 5       5      nU(       a  U[        [        U5      5      -  $ S$ )zµ
Calculate the average height of text lines.

Parameters
----------
textlines : list
    List of text line objects.

Returns
-------
float
    The average height of the text lines.
c              3  óR   #   • U  H  oR                   UR                  -
  v •  M     g 7fr   )rM   rL   )rœ   r•   s     r&   r�   Ú?TextEdges._calculate_average_textline_height.<locals>.<genexpr>•  s   é € Ð!Dº)°B§%¡%¨"¯%©%¦-º)ùs   ‚%'r   )r§   r<   r7   )r$   r!   Úsum_textline_heights      r&   rµ   Ú,TextEdges._calculate_average_textline_height‡  s1   € ô "Ñ!D¹)Ó!DÓDÐÞ>GÐ"¤U¬3¨y«>Ó%:Ñ:ÐNÈQÐNr)   c                óh   • US   [         -
  nUS   [         -
  nUS   [         -   nUS   US-  -   nX4XV4$ )zü
Pad a given area by a constant value.

Parameters
----------
area : tuple
    The area to be padded defined as (x0, y0, x1, y1).
average_row_height : float
    The average height of rows to use for padding.

Returns
-------
tuple
    The padded area.
r   r   r1   r   é   )ÚTABLE_AREA_PADDING)r$   rº   Úaverage_row_heightrÈ   rL   rÉ   rM   s          r&   r¶   ÚTextEdges._pad˜  sP   € ð  �!‰WÔ)Ñ)ˆØ�!‰WÔ)Ñ)ˆØ�!‰WÔ)Ñ)ˆà�!‰WÐ)¨AÑ-Ñ-ˆØ˜ÐÐr)   )r\   r_   )r@   rA   rB   rC   rD   r'   rm   r�   rs   r–   r­   r¼   r³   r¿   r´   rµ   r¶   rE   ra   rb   s   @r&   r†   r†   Ñ   sN   ø† ñ÷!ò0ò0ò
@ò,ò
ò<"ò@ò. -òD1òBO÷" ð  r)   r†   c                  ó�   • \ rS rSrSrS rS r\S 5       r\R                  S 5       r\SS j5       r
\SS j5       r\S	 5       rS
rg)ÚCelli°  a^  Defines a cell in a table.

With coordinates relative to a
left-bottom origin. (PDF coordinate space)

Parameters
----------
x1 : float
    x-coordinate of left-bottom point.
y1 : float
    y-coordinate of left-bottom point.
x2 : float
    x-coordinate of right-top point.
y2 : float
    y-coordinate of right-top point.

Attributes
----------
lb : tuple
    Tuple representing left-bottom coordinates.
lt : tuple
    Tuple representing left-top coordinates.
rb : tuple
    Tuple representing right-bottom coordinates.
rt : tuple
    Tuple representing right-top coordinates.
left : bool
    Whether or not cell is bounded on the left.
right : bool
    Whether or not cell is bounded on the right.
top : bool
    Whether or not cell is bounded on the top.
bottom : bool
    Whether or not cell is bounded on the bottom.
text : string
    Text assigned to cell.

c                óº   • Xl         X l        X0l        X@l        X4U l        X4U l        X24U l        X44U l        SU l        SU l	        SU l
        SU l        SU l        g )NFr3   )rÉ   rM   Úx2Úy2ÚlbÚltÚrbÚrtr   r   r   r   Ú_text©r$   rÉ   rM   rØ   rÙ   s        r&   r'   ÚCell.__init__Ø  s]   € ØŒØŒØŒØŒØ�(ˆŒØ�(ˆŒØ�(ˆŒØ�(ˆŒØˆŒ	ØˆŒ
ØˆŒØˆŒØˆ�
r)   c           	     óÈ   • [        U R                  5      n[        U R                  5      n[        U R                  5      n[        U R                  5      nSU SU SU SU S3	$ )Nz	<Cell x1=rR   z x2=z y2=rS   )rT   rÉ   rM   rØ   rÙ   rß   s        r&   r9   ÚCell.__repr__ç  sW   € Ü�4—7‘7‹^ˆÜ�4—7‘7‹^ˆÜ�4—7‘7‹^ˆÜ�4—7‘7‹^ˆØ˜2˜$˜d 2 $ d¨2¨$¨d°2°$°aÐ8Ð8r)   c                ó   • U R                   $ r   )rÞ   ©r$   s    r&   ÚtextÚ	Cell.textî  s   € à�z‰zÐr)   c                óH   • SR                  U R                  U/5      U l        g )Nr3   )r4   rÞ   )r$   Úts     r&   rå   ræ   ò  s   € à—W‘W˜dŸj™j¨!˜_Ó-ˆ�
r)   c                óT   • U R                   (       + =(       d    U R                  (       + $ )z'Whether or not cell spans horizontally.)r   r   rä   s    r&   ÚhspanÚ
Cell.hspanö  s   € ð —9‘9Œ}×. D§J¡J¤Ð.r)   c                óT   • U R                   (       + =(       d    U R                  (       + $ )z%Whether or not cell spans vertically.)r   r   rä   s    r&   ÚvspanÚ
Cell.vspanû  s   € ð —8‘8Œ|×. 4§;¡;œÐ.r)   c                óh   • U R                   U R                  -   U R                  -   U R                  -   $ )z1The number of sides on which the cell is bounded.)r   r   r   r   rä   s    r&   ÚboundÚ
Cell.bound   s)   € ð �x‰x˜$Ÿ+™+Ñ%¨¯	©	Ñ1°D·J±JÑ>Ð>r)   )rÞ   r   rÚ   r   rÛ   rÜ   r   rÝ   r   rÉ   rØ   rM   rÙ   N)ÚreturnÚbool)r@   rA   rB   rC   rD   r'   r9   Úpropertyrå   Úsetterrê   rí   rð   rE   rF   r)   r&   rÖ   rÖ   °  sz   † ñ%òNò9ð ñó ðð 
‡[�[ñ.ó ð.ð ó/ó ð/ð ó/ó ð/ð ñ?ó ó?r)   rÖ   c                  óø   • \ rS rSrSrS rS r\S 5       r\S 5       r	S r
S r\S	 5       r\S S
 j5       r\S 5       rS rS rS!S jrS rS rS rS rS rS rS"S jrS rS rS rS rS rS rS rS r Sr!g)#ÚTablei  a|  Defines a table with coordinates relative to a left-bottom origin.

(PDF coordinate space)

Parameters
----------
cols : list
    List of tuples representing column x-coordinates in increasing
    order.
rows : list
    List of tuples representing row y-coordinates in decreasing
    order.

Attributes
----------
df : :class:`pandas.DataFrame`
shape : tuple
    Shape of the table.
accuracy : float
    Accuracy with which text was assigned to the cell.
whitespace : float
    Percentage of whitespace in the table.
filename : str
    Path of the original PDF
order : int
    Table number on PDF page.
page : int
    PDF page number.

c                óô  • Xl         X l        U VVs/ s H-  o1 Vs/ s H  n[        US   US   US   US   5      PM     snPM/     snnU l        [        R
                  " 5       U l        SU l        SU l        SU l	        S U l
        S U l        S U l        SU l        S U l        S U l        S U l        S U l        S U l        S U l        S U l        S U l        S U l        S U l        S U l        SU l        g s  snf s  snnf )Nr   r   )r   r   r3   F)ÚcolsÚrowsrÖ   ÚcellsÚpdÚ	DataFrameÚdfÚshapeÚaccuracyÚ
whitespaceÚfilenameÚorderÚpageÚrotationÚflavorÚpdf_sizeÚ_bboxÚparseÚparse_detailsÚ_imageÚ_image_pathÚ_rows_np_cacheÚ_cols_np_cacheÚ_neg_y_tops_listÚ_col_widths_listÚ_rows_disjoint)r$   rù   rú   ÚrÚcs        r&   r'   ÚTable.__init__&  s÷   € ØŒ	ØŒ	ÙLPÔQÊDÀq¸TÓBºT¸”t˜A˜a™D ! A¡$¨¨!©¨a°©dÖ3¹TÔBÉDÒQˆŒ
Ü—,’,“.ˆŒØˆŒ
ØˆŒØˆŒØˆŒØˆŒ
ØˆŒ	ØˆŒØˆŒØˆŒØˆŒ
ØˆŒ
Ø!ˆÔàˆŒØˆÔð #ˆÔØ"ˆÔð
 !%ˆÔð !%ˆÔð
 $ˆÕùòO CùÓQs   ’	C4›$C/¿C4Ã/C4c                óH  ^• U R                   cŽ  U R                  m[        R                  " T[        R                  S9R                  SS5      U l         T Vs/ s H  oS   * PM
     snU l        [        U4S j[        [        T5      S-
  5       5       5      U l
        U R                  co  U R                  n[        R                  " U[        R                  S9R                  SS5      U l        U Vs/ s H  n[        US   US   -
  5      PM     snU l        ggs  snf s  snf )a+  Populate the search caches used by ``get_table_index``.

Idempotent: callers may invoke this every call (it short-circuits
on the first attribute that is already populated). The NumPy
arrays are part of the private interface and kept available so
future call sites can do their own bulk processing.
N)Údtypeéÿÿÿÿr1   r   c              3  óL   >#   • U  H  nTU   S    TUS -      S   :¬  v •  M     g7f)r   r   NrF   )rœ   Úirú   s     €r&   r�   Ú-Table._build_search_caches.<locals>.<genexpr>e  s.   øé € ð &Ú6J°��Q‘˜‘
˜d 1 q¡5™k¨!™nÖ,Ò6Jùs   ƒ!$r   )r  rú   ÚnpÚasarrayÚfloat64Úreshaper  ÚallÚranger7   r  r  rù   Úabsr  )r$   r  rù   r  rú   s       @r&   Ú_build_search_cachesÚTable._build_search_cachesR  sù   ø€ ð ×ÑÑ&Ø—9‘9ˆDÜ"$§*¢*¨T¼¿¹Ñ"D×"LÑ"LÈRÐQRÓ"SˆDÔñ 59Ó$9²D¨q¨¡d£U±DÑ$9ˆDÔ!ô #&ô &Ü6;¼CÀ»IÈ¹MÔ6Jó&ó #ˆDÔð ×ÑÑ&Ø—9‘9ˆDÜ"$§*¢*¨T¼¿¹Ñ"D×"LÑ"LÈRÐQRÓ"SˆDÔÙ?CÓ$Dºt¸!¤S¨¨1©°°!±©Ö%5¹tÑ$DˆDÕ!ð 'ùò %:ùò %Es   ÁDÃ2Dc                óT   • U R                   c  U R                  5         U R                   $ )zÃReturn rows as an ``(n_rows, 2)`` float64 NumPy array.

Lazily constructed on first access and cached. Each row is
``(y_top, y_bot)`` and rows preserve their original descending
``y_top`` order.
)r  r"  rä   s    r&   Ú_rows_npÚTable._rows_npm  s(   € ð ×ÑÑ&Ø×%Ñ%Ô'Ø×"Ñ"Ð"r)   c                óT   • U R                   c  U R                  5         U R                   $ )z�Return cols as an ``(n_cols, 2)`` float64 NumPy array.

Lazily constructed on first access and cached. Each column is
``(x_left, x_right)``.
)r  r"  rä   s    r&   Ú_cols_npÚTable._cols_npy  s(   € ð ×ÑÑ&Ø×%Ñ%Ô'Ø×"Ñ"Ð"r)   c                óP   • SU R                   R                   SU R                   S3$ )zXReturn a string representation of the class .

Returns
-------
[type]
    [description]
Ú<z shape=rS   )rO   r@   rÿ   rä   s    r&   r9   ÚTable.__repr__„  s(   € ð �4—>‘>×*Ñ*Ð+¨7°4·:±:°,¸aÐ@Ð@r)   c                ó¤   • U R                   UR                   :X  a  U R                  UR                  :  a  gU R                   UR                   :  a  gg)z Return True if the two pages are less than the current page .

Parameters
----------
other : [type]
    [description]

Returns
-------
[type]
    [description]
TN)r  r  )r$   Úothers     r&   Ú__lt__ÚTable.__lt__Ž  s?   € ð �9‰9˜Ÿ
™
Ó"Ø�z‰z˜EŸK™KÓ'ØØ�9‰9�u—z‘zÓ!Øð "r)   c                ó¬   • / nU R                    H<  nUR                  U Vs/ s H  o3R                  R                  5       PM     sn5        M>     U$ s  snf )z1Returns two-dimensional list of strings in table.)rû   r=   rå   r”   )r$   ÚdÚrowÚcells       r&   ÚdataÚ
Table.data¡  sE   € ð ˆØ—:”:ˆCØ�H‰H±CÓ8²C¨D—i‘i—o‘oÖ'±CÑ8Ö9ñ àˆùò 9s   ¡#A
c                óZ   • [        SU R                  S-  SU R                  S-  -
  -  5      $ )u¨  A unified per-table quality score in ``[0.0, 1.0]``.

Computed from the existing per-flavor signals as
``(accuracy / 100) * (1 - whitespace / 100)``. The intent is a
single number suitable for production filtering and automated
validation â€” ``confidence >= 0.8`` works as a reasonable
first-cut threshold; tune for the source PDFs.

Components and their meaning are identical across flavors:

- ``accuracy`` (0-100): how well the detected cells line up
  with the parser's structural hints (line joints for lattice,
  text alignments for stream/network/hybrid). Higher is better.
- ``whitespace`` (0-100): percentage of cells that are empty
  after stripping. Lower is better (a perfectly populated
  table is 0; a mostly-empty one trends toward 100).
- ``confidence`` (0-1): the composite. ``accuracy=90``,
  ``whitespace=10`` â†’ ``confidenceâ‰ˆ0.81``; either signal
  going to its worst value pulls ``confidence`` to 0.

See #659.
ç        ç      Y@g      ð?)r¨   r   r  rä   s    r&   Ú
confidenceÚTable.confidence©  s-   € ô0 �3˜Ÿ™¨Ñ.°3¸¿¹È5Ñ9PÑ3PÑQÓRÐRr)   c                ó²   • [        U R                  S5      [        U R                  S5      U R                  U R                  [        U R
                  S5      S.$ )uŠ  Per-table parsing report.

Standard keys across all flavors:

=================  ==============================================
``page``           1-based page number the table was found on.
``order``          1-based rank within that page (left-to-right /
                   top-to-bottom).
``accuracy``       Float in ``[0, 100]``. See ``confidence`` for
                   component-by-component definitions.
``whitespace``     Float in ``[0, 100]``.
``confidence``     Float in ``[0, 1]``. Unified quality score â€”
                   combines accuracy and whitespace.
=================  ==============================================

See #659.
r1   r   )r   r  r  r  r:  )rT   r   r  r  r  r:  rä   s    r&   Úparsing_reportÚTable.parsing_reportÃ  sF   € ô( ˜dŸm™m¨QÓ/Ü §¡°Ó3Ø—Z‘ZØ—I‘IÜ §¡°Ó3ñ
ð 	
r)   c                ó   • U R                   c¶  U R                  cp  [        [        R                  R                  U R                  5      S5      U l        [        SS9nUR                  U R                  U R                  U R                  S9  [        [        R                  " U R                  5      U R                  5      U l         U R                   $ )zCompute pdf image and cache it.z.pngT)Úuse_fallback)r  )r  r  r   ÚosÚpathÚbasenamer  r   Úconvertr  r   Úcv2Úimreadr  )r$   Úbackends     r&   Úget_pdf_imageÚTable.get_pdf_imageÞ  s”   € à�;‰;ÑØ×ÑÑ'Ü#>Ü—G‘G×$Ñ$ T§]¡]Ó3°Vó$�Ô ô 1¸dÑC�Ø—‘ §¡¨t×/?Ñ/?ÀdÇiÁi�ÑPÜ'¬¯
ª
°4×3CÑ3CÓ(DÀdÇmÁmÓTˆDŒKØ�{‰{Ðr)   c                óv   • U R                    H(  nU H  nS=Ul        =Ul        =Ul        Ul        M!     M*     U $ )zSet all table edges to True.T)rû   r   r   r   r   )r$   r3  r4  s      r&   Úset_all_edgesÚTable.set_all_edgesê  s=   € à—:”:ˆCÛ�ØBFÐF�”	ÐF˜DœJÐF¨¬°D¶Kó ñ ð ˆr)   c                óJ   • U R                  X5        U R                  X#5        U $ )aq  Set the edges of the joint.

Set a cell's edges to True depending on whether the cell's
coordinates overlap with the line's coordinates within a
tolerance.

Parameters
----------
vertical : list
    List of detected vertical lines.
horizontal : list
    List of detected horizontal lines.
joint_tol : int, optional
    Tolerance for determining proximity, by default 2
)Ú_set_vertical_edgesÚ_set_horizontal_edges)r$   ÚverticalÚ
horizontalÚ	joint_tols       r&   Ú	set_edgesÚTable.set_edgesñ  s%   € ð  	× Ñ  Ô5Ø×"Ñ" :Ô9Øˆr)   c                ón   • [        U5       H&  u  pE[        R                  " X%S   US9(       d  M$  Us  $    g )Nr   rW   )Ú	enumeraterY   rZ   )r$   r{   r    rR  r  rè   s         r&   Ú_find_close_pointÚTable._find_close_point  s2   € Ü˜fÖ%‰DˆAÜ�|Š|˜E Q¡4°×;Ñ;Ø’ñ &ð r)   c                ó4  • U H’  nU R                  U R                  US   U5      nUc  M(  U R                  U R                  US   U5      nUc  [        U R                  5      nU R                  U R                  US   U5      nU R	                  XEU5        M”     g )Nr   r   r   )rW  rú   r7   rù   Ú_update_vertical_edges)r$   rP  rR  ÚvÚstartÚendr  s          r&   rN  ÚTable._set_vertical_edges  sŒ   € ÛˆAð ×*Ñ*¨4¯9©9°a¸±d¸IÓFˆEØ‰}ÙØ×(Ñ(¨¯©°A°a±D¸)ÓDˆCØ‰{Ü˜$Ÿ)™)“n�Ø×&Ñ& t§y¡y°!°A±$¸	ÓBˆAØ×'Ñ'¨°AÖ6ò r)   c                ó‚  • UcI  [        U R                  5      S-
  nUS:¼  a*  [        X5       H  nSU R                  U   U   l        M     g g US:X  a*  [        X5       H  nSU R                  U   S   l        M     g [        X5       H4  nSU R                  U   U   l        SU R                  U   US-
     l        M6     g ©Nr   r   T)r7   rù   r   rû   r   r   ©r$   r\  r]  ÚindexÚjs        r&   rZ  ÚTable._update_vertical_edges  sµ   € Ø‰=Ü˜Ÿ	™	“N QÑ&ˆEØ˜‹zÜ˜uÖ*�AØ15�D—J‘J˜q‘M %Ñ(Ö.ò +ð ð �a‹ZÜ˜5Ö&�Ø(,�—
‘
˜1‘˜aÑ Ö%ò 'ô ˜5Ö&�Ø,0�—
‘
˜1‘˜eÑ$Ô)Ø15�—
‘
˜1‘˜e a™iÑ(Ö.ò 'r)   c                ó4  • U H’  nU R                  U R                  US   U5      nUc  M(  U R                  U R                  US   U5      nUc  [        U R                  5      nU R                  U R                  US   U5      nU R	                  XEU5        M”     g )Nr   r1   r   )rW  rù   r7   rú   Ú_update_horizontal_edges)r$   rQ  rR  Úhr\  r]  r  s          r&   rO  ÚTable._set_horizontal_edges&  sŒ   € ÛˆAð ×*Ñ*¨4¯9©9°a¸±d¸IÓFˆEØ‰}ÙØ×(Ñ(¨¯©°A°a±D¸)ÓDˆCØ‰{Ü˜$Ÿ)™)“n�Ø×&Ñ& t§y¡y°!°A±$¸	ÓBˆAØ×)Ñ)¨%°aÖ8ò r)   c                ó‚  • UcI  [        U R                  5      S-
  nUS:¼  a*  [        X5       H  nSU R                  U   U   l        M     g g US:X  a*  [        X5       H  nSU R                  S   U   l        M     g [        X5       H4  nSU R                  U   U   l        SU R                  US-
     U   l        M6     g r`  )r7   rú   r   rû   r   r   ra  s        r&   rf  ÚTable._update_horizontal_edges3  s¸   € Ø‰=Ü˜Ÿ	™	“N QÑ&ˆEØ˜‹zÜ˜uÖ*�AØ26�D—J‘J˜uÑ% aÑ(Ö/ò +ð ð �a‹ZÜ˜5Ö&�Ø'+�—
‘
˜1‘˜aÑ Ö$ò 'ô ˜5Ö&�Ø+/�—
‘
˜5Ñ! !Ñ$Ô(Ø26�—
‘
˜5 1™9Ñ% aÑ(Ö/ò 'r)   c                ó  ^• [        U R                  5      n[        U R                  5      mUS:X  d  TS:X  a  U $ [        U R                  5      U:w  d$  [	        U4S jU R                   5       5      (       a  [        S5      e[        U5       H4  nSU R                  U   S   l        SU R                  U   TS-
     l        M6     [        T5       H4  nSU R                  S   U   l	        SU R                  US-
     U   l
        M6     U $ )z Sets table border edges to True.r   c              3  ó@   >#   • U  H  n[        U5      T:g  v •  M     g 7fr   ©r7   )rœ   r3  Únum_colss     €r&   r�   Ú#Table.set_border.<locals>.<genexpr>K  s   øé € ð .
Ú,6 SŒC�‹H˜Ö ªJùs   ƒzQInconsistent cells structure: cells should match the dimensions of rows and cols.Tr   )r7   rú   rù   rû   ÚanyÚ
ValueErrorr   r   r   r   r   )r$   Únum_rowsÚ	row_indexÚ	col_indexrn  s       @r&   Ú
set_borderÚTable.set_borderA  sø   ø€ ä�t—y‘y“>ˆÜ�t—y‘y“>ˆð �q‹=˜H¨›MØˆKô ˆt�z‰z‹?˜hÓ&¬#ô .
Ø,0¯JªJó.
÷ +
ñ +
ô Øcóð ô
 ˜xžˆIØ,0ˆD�J‰J�yÑ! !Ñ$Ô)Ø8<ˆD�J‰J�yÑ! (¨Q¡,Ñ/Ö5ñ )ô
 ˜xžˆIØ+/ˆD�J‰J�q‰M˜)Ñ$Ô(Ø9=ˆD�J‰J�x !‘|Ñ$ YÑ/Ö6ñ )ð ˆr)   Nc                ó  • Uc  U $ U R                   U R                  S.n[        [        [	        U R
                  5      S5      S-  5       H>  nSnU H)  nUR                  U5      nUc  M  U" 5       (       d  M'  SnM+     U(       a  M=    U $    U $ )a  
Copies over text in empty spanning cells.

Parameters
----------
copy_text : list of str, optional (default: None)
    Select one or more of the following strings: {'h', 'v'} to specify
    the direction in which text should be copied over when a cell spans
    multiple rows or columns.

Returns
-------
camelot.core.Table
    The updated table with copied text in spanning cells.

Notes
-----
Iterates the directional copy passes until the table is stable.
A single pass-per-direction misses cells spanned in *both*
directions (a 2D span): the source cell from which the
2D-spanned cell would copy hasn't itself been filled yet, so
the empty string propagates through. Repeating the chosen
passes until no cell changes converges in O(spans) iterations
and fixes the symptom reported in #349.
)rg  r[  r   r1   FT)Ú_copy_horizontal_textÚ_copy_vertical_textr   r¨   r7   rû   Úget)r$   Ú	copy_textÚpassesÚ_ÚchangedÚ	directionÚpass_fns          r&   Úcopy_spanning_textÚTable.copy_spanning_text^  sŽ   € ð4 ÑØˆKà×1Ñ1¸×8PÑ8PÑQˆô ”sœ3˜tŸz™z›?¨AÓ.°Ñ2Ö3ˆAØˆGÛ&�	Ø Ÿ*™* YÓ/�ØÓ&©7¯9«9Ø"’Gñ '÷ �7Øàˆñ 4ð ˆr)   c                óÄ  • Sn[        [        U R                  5      5       H»  n[        [        U R                  U   5      5       H“  nU R                  U   U   nUR                  R	                  5       S:X  d  M5  UR
                  (       d  MH  UR                  (       a  M[  U R                  U   US-
     R                  nXTR                  :w  d  M‹  XTl        SnM•     M½     U$ )u  Copy text rightwards into empty horizontally-spanned cells.

Fills empty cells that span horizontally with the text from the
left adjacent cell. Returns ``True`` when at least one cell's
text was changed â€” used by :meth:`copy_spanning_text` to decide
whether another pass is needed.
Fr3   r   T)r   r7   rû   rå   r”   rê   r   ©r$   r~  r  rc  r4  Úsources         r&   rx  ÚTable._copy_horizontal_text‰  s¨   € ð ˆÜ”s˜4Ÿ:™:“Ö'ˆAÜœ3˜tŸz™z¨!™}Ó-Ö.�Ø—z‘z !‘} QÑ'�Ø—9‘9—?‘?Ó$¨Õ*¨t¯z¯z©zÀ$Ç)Ç)Á)Ø!ŸZ™Z¨™]¨1¨q©5Ñ1×6Ñ6�FØ§¡Õ*Ø$*œ	Ø"&šó /ñ (ð ˆr)   c                óÄ  • Sn[        [        U R                  5      5       H»  n[        [        U R                  U   5      5       H“  nU R                  U   U   nUR                  R	                  5       S:X  d  M5  UR
                  (       d  MH  UR                  (       a  M[  U R                  US-
     U   R                  nXTR                  :w  d  M‹  XTl        SnM•     M½     U$ )u  Copy text downwards into empty vertically-spanned cells.

Fills empty cells that span vertically with the text from the
top adjacent cell. Returns ``True`` when at least one cell's
text was changed â€” used by :meth:`copy_spanning_text` to decide
whether another pass is needed.
Fr3   r   T)r   r7   rû   rå   r”   rí   r   r„  s         r&   ry  ÚTable._copy_vertical_textœ  s©   € ð ˆÜ”s˜4Ÿ:™:“Ö'ˆAÜœ3˜tŸz™z¨!™}Ó-Ö.�Ø—z‘z !‘} QÑ'�Ø—9‘9—?‘?Ó$¨Õ*¨t¯z¯z©zÀ$Ç(Ç(Á(Ø!ŸZ™Z¨¨A©Ñ.¨qÑ1×6Ñ6�FØ§¡Õ*Ø$*œ	Ø"&šó /ñ (ð ˆr)   c                ón   • SSSSS.nUR                  U5        U R                  R                  " U40 UD6  g)z£Write Table(s) to a comma-separated values (csv) file.

For kwargs, check :meth:`pandas.DataFrame.to_csv`.

Parameters
----------
path : str
    Output filepath.

úutf-8Fr   )Úencodingrb  ÚheaderÚquotingN)Úupdaterþ   Úto_csv)r$   rB  ÚkwargsÚkws       r&   r�  ÚTable.to_csv¯  s3   € ð "¨E¸UÈqÑQˆØ
�	‰	�&ÔØ�‰�Š�tÑ"˜rÓ"r)   c                óö   • UR                  SS5      nSS0nUR                  U5        U R                  R                  " S0 UD6n[	        X5       nUR                  U5        SSS5        g! , (       d  f       g= f)a®  Write Table(s) to a JSON file.

For kwargs, check :meth:`pandas.DataFrame.to_json`. The
optional ``mode`` kwarg (``"w"`` to overwrite, ``"a"`` to
append) is consumed by the file-open call; the rest are
forwarded to ``DataFrame.to_json`` (#317).

Parameters
----------
path : str
    Output filepath.
mode : str, optional (default: 'w')
    File open mode. Pass ``"a"`` to append to an existing file
    rather than overwrite it.

ÚmodeÚwÚorientÚrecordsNrF   )rÂ   rŽ  rþ   Úto_jsonÚopenÚwrite)r$   rB  r�  r”  r‘  Újson_stringÚfs          r&   r˜  ÚTable.to_json¾  sa   € ð" �z‰z˜& #Ó&ˆØ˜	Ð"ˆØ
�	‰	�&ÔØ—g‘g—o’oÑ+¨Ñ+ˆÜ�$Ô Ø�G‰G�KÔ ÷ ×Öús   ÁA*Á*
A8c                ó&  • UR                  SS5      nSSS.nSU R                   SU R                   3nUR                  U5        [        R
                  " XS9 nU R                  R                  " U4SU0UD6  S	S	S	5        g	! , (       d  f       g	= f)
uÂ  Write Table(s) to an Excel file.

For kwargs, check :meth:`pandas.DataFrame.to_excel`. The
optional ``mode`` kwarg is forwarded to
:class:`pandas.ExcelWriter` (``"w"`` to overwrite, ``"a"`` to
append a new sheet to an existing workbook) â€” see #317.

Parameters
----------
path : str
    Output filepath.
mode : str, optional (default: 'w')
    ExcelWriter open mode. Use ``"a"`` to add a new sheet to
    an existing workbook (requires openpyxl).

r”  r•  F)rb  rŒ  úpage-ú-table-)r”  Ú
sheet_nameN)rÂ   r  r  rŽ  rü   ÚExcelWriterrþ   Úto_excel)r$   rB  r�  r”  r‘  r¡  Úwriters          r&   r£  ÚTable.to_excelÖ  s~   € ð" �z‰z˜& #Ó&ˆð ¨Ñ.ˆØ˜TŸY™Y˜K w¨t¯z©z¨lÐ;ˆ
Ø
�	‰	�&Ôô �^Š^˜DÒ,°Ø�G‰G×Ò˜VÑA°
ÐA¸bÒA÷ -×,Ö,ús   Á BÂ
Bc                óÊ   • UR                  SS5      nU R                  R                  " S0 UD6n[        XSS9 nUR	                  U5        SSS5        g! , (       d  f       g= f)aT  Write Table(s) to an HTML file.

For kwargs, check :meth:`pandas.DataFrame.to_html`. The
optional ``mode`` kwarg is consumed by the file-open call
(#317).

Parameters
----------
path : str
    Output filepath.
mode : str, optional (default: 'w')
    File open mode. Pass ``"a"`` to append to an existing file
    rather than overwrite it.

r”  r•  rŠ  ©r‹  NrF   )rÂ   rþ   Úto_htmlr™  rš  )r$   rB  r�  r”  Úhtml_stringrœ  s         r&   r¨  ÚTable.to_html÷  sM   € ð  �z‰z˜& #Ó&ˆØ—g‘g—o’oÑ/¨Ñ/ˆÜ�$ wÒ/°1Ø�G‰G�KÔ ÷ 0×/Ö/úó   ¹AÁ
A"c                óÊ   • UR                  SS5      nU R                  R                  " S0 UD6n[        XSS9 nUR	                  U5        SSS5        g! , (       d  f       g= f)u»  Write Table(s) to a Markdown file.

For kwargs, check :meth:`pandas.DataFrame.to_markdown`. The
optional ``mode`` kwarg is consumed by the file-open call â€”
passing ``mode="a"`` appends every successive call to the
same file rather than overwriting (#317).

Parameters
----------
path : str
    Output filepath.
mode : str, optional (default: 'w')
    File open mode. Pass ``"a"`` to append to an existing file
    rather than overwrite it.

r”  r•  rŠ  r§  NrF   )rÂ   rþ   Úto_markdownr™  rš  )r$   rB  r�  r”  Ú	md_stringrœ  s         r&   r­  ÚTable.to_markdown  sO   € ð" �z‰z˜& #Ó&ˆØ—G‘G×'Ò'Ñ1¨&Ñ1ˆ	Ü�$ wÒ/°1Ø�G‰G�IÔ÷ 0×/Ö/úr«  c                ó  • SSS.nUR                  U5        [        R                  " U5      nSU R                   SU R                   3nU R
                  R                  " XT40 UD6  UR                  5         UR                  5         g)z�Write Table(s) to sqlite database.

For kwargs, check :meth:`pandas.DataFrame.to_sql`.

Parameters
----------
path : str
    Output filepath.

r6   F)Ú	if_existsrb  rŸ  r   N)	rŽ  Úsqlite3Úconnectr  r  rþ   Úto_sqlÚcommitÚclose)r$   rB  r�  r‘  ÚconnÚ
table_names         r&   Ú	to_sqliteÚTable.to_sqlite"  si   € ð %¨uÑ5ˆØ
�	‰	�&ÔÜ�Š˜tÓ$ˆØ˜TŸY™Y˜K w¨t¯z©z¨lÐ;ˆ
Ø�‰�Š�zÑ.¨2Ò.Ø�‰ŒØ�
‰
�r)   )r  r  r  r  r  r  r  r  r   rû   rù   rþ   r  r  r  r  r	  r
  r  r  rú   rÿ   r  )rò   r<   )r1   r   )"r@   rA   rB   rC   rD   r'   r"  rô   r%  r(  r9   r/  r5  r:  r=  rH  rK  rS  rW  rN  rZ  rO  rf  ru  r�  rx  ry  r�  r˜  r£  r¨  r­  r¹  rE   rF   r)   r&   r÷   r÷     sá   † ñò>*$òXEð6 ñ	#ó ð	#ð ñ#ó ð#òAòð& ñó ðð óSó ðSð2 ñ
ó ð
ò4
òôò(ò7ò6ò9ò7òô:)òVò&ò&#ò!ò0BòB!ò*õ,r)   r÷   c                ó@  • [        U 5      S:X  a  [        R                  " U S   5      $ [        R                  " U S   5      nUR                  /nU SS  GH}  n[        R                  " U5      nUR                  Gb  UR                  Gbö  UR                  S   nUR                  S   nXg-
  nUR
                   V	V
s/ s H  u  pšX˜-   X¨-   4PM     sn
n	Ul        UR                   Hª  nU H¡  nU=R                  U-  sl        U=R                  U-  sl        UR                  UR                  4Ul
        UR                  UR                  4Ul        UR                  UR                  4Ul        UR                  UR                  4Ul        M£     M¬     UR                  S   UR                  S   U-   UR                  S   UR                  S   U-   4Ul        UR
                  UR
                  -   Ul        UR                  UR                  -   Ul        [        UR                  S   UR                  S   5      UR                  S   [!        UR                  S   UR                  S   5      UR                  S   4Ul        UR                  nU(       a-  UR"                  (       d  UR$                  SS R'                  SS9nUR)                  U5        GM€     [*        R,                  " USS9Ul        U  Vs/ s H  n[/        US	S5      c  M  UR0                  PM!     nnU  Vs/ s H  n[/        US
S5      c  M  UR2                  PM!     nnU(       a  [5        U5      [        U5      -  Ul        U(       a  [5        U5      [        U5      -  Ul        U$ s  sn
n	f s  snf s  snf )uÞ  Vertically concatenate a run of contiguous Tables (#628 POC).

All tables in ``run`` must share the same column count â€” the caller
(:meth:`TableList.stack_contiguous`) is responsible for that
invariant. A single-element run is returned via a deep copy so the
output never aliases the input.

Geometry:
    * The first table's ``rows`` / ``cells`` / ``_bbox`` stay in
      place. Each subsequent table's y-coordinates are shifted so
      its top sits at the previous table's bottom â€” the stacked
      result reads as one tall page even though source pages
      differ.

``parsing_report`` is mean-aggregated across the run (accuracy,
whitespace, confidence are averaged); ``page`` and ``order`` are
taken from the first table.
r   r   Nr   r1   T)Údrop)Úignore_indexr   r  )r7   ÚcopyÚdeepcopyrþ   r  rú   rû   rM   rÙ   rÉ   rÚ   rÛ   rØ   rÜ   rÝ   rÃ   r¨   ÚemptyÚilocÚreset_indexr=   rü   ÚconcatÚgetattrr   r  r§   )ÚrunÚdrop_repeated_headerÚoutÚout_dfsÚnxtÚnxt_copyÚ
out_bottomÚnxt_topÚdyÚr0Úr1r3  r4  Únxt_dfrè   ÚaccsÚwsss                    r&   Ú_vstack_runrÓ  6  sæ  € ô& ˆ3ƒx�1ƒ}Ü�}Š}˜S ™VÓ$Ð$ä
�-Š-˜˜A™Ó
€CØ�v‰vˆh€Gà�1�2ŒwˆÜ—=’= Ó%ˆð �9‰9Ò  X§^¡^Ò%?ØŸ™ 1™ˆJØ—n‘n QÑ'ˆGØÑ%ˆBØ@HÇÂÔNÂ±H°R˜b™g r¡wÓ/ÁÒNˆHŒMØ—~”~�Û�DØ—G’G˜r‘M•GØ—G’G˜r‘M•Gð  $Ÿw™w¨¯©Ð0�D”GØ#Ÿw™w¨¯©Ð0�D”GØ#Ÿw™w¨¯©Ð0�D”GØ#Ÿw™w¨¯©Ð0�D–Gó  ñ &ð —‘˜qÑ!Ø—‘˜qÑ! BÑ&Ø—‘˜qÑ!Ø—‘˜qÑ! BÑ&ð	ˆHŒNð —x‘x (§-¡-Ñ/ˆCŒHØŸ	™	 H§N¡NÑ2ˆCŒIä�C—I‘I˜a‘L (§.¡.°Ñ"3Ó4Ø—‘˜qÑ!Ü�C—I‘I˜a‘L (§.¡.°Ñ"3Ó4Ø—	‘	˜!‘ð	ˆCŒIð —‘ˆÞ¨¯¯Ø—[‘[  �_×0Ñ0°dÐ0Ð;ˆFØ�‰�v×ñ_ ôb �YŠY�w¨TÑ2€C„Fñ
 !$ÓP¢˜1¤w¨q°*¸dÓ'C‹JˆA�JŒJ¡€DÐPÙ!$Ó
S¢˜A¬°°<ÀÓ(F‹<ˆ1�<Œ<¡€CÐ
SÞÜ˜4“y¤3 t£9Ñ,ˆŒÞ
Ü˜S›¤C¨£HÑ,ˆŒà€JùóY OùòJ QùÚ
Ss   Â;NË4NÌ
NÌ NÌ6Nc                  óB   • \ rS rSr% SrS\S'   S\S'   S\S'   S\S'   S	rg
)Ú_Kwi�  z.Helper class to define file related arguments.zos.PathLike[Any] | strrB  ÚstrÚdirnameÚrootÚextrF   N)r@   rA   rB   rC   rD   Ú__annotations__rE   rF   r)   r&   rÕ  rÕ  �  s   ‡ Ù8à
 Ó ØƒLØ
ƒIØ	†Hr)   rÕ  c                  óÚ   • \ rS rSrSrSS jrS rS rSS jrSS jr	SS jr
\S	 5       r\SS
 j5       r    S         SS jjr  S     SS jjrSSS jjrSS jrSSS jjrSrg)Ú	TableListi˜  a  Defines a list of camelot.core.Table objects.

Each table can be accessed using its index.

Attributes
----------
n : int
    Number of tables in the list.

Examples
--------
>>> from camelot.core import TableList
>>> tables = TableList([])
>>> tables.n
0
>>> tables
<TableList n=0>

c                ó$   • [        U5      U l        g r   )r©   Ú_tables)r$   Útabless     r&   r'   ÚTableList.__init__­  s   € ô %)¨£Lˆ�r)   c                óP   • SU R                   R                   SU R                   S3$ )Nr+  z n=rS   )rO   r@   Únrä   s    r&   r9   ÚTableList.__repr__³  s&   € Ø�4—>‘>×*Ñ*Ð+¨3¨t¯v©v¨h°aÐ8Ð8r)   c                ó,   • [        U R                  5      $ r   )r7   rÞ  rä   s    r&   Ú__len__ÚTableList.__len__¶  s   € Ü�4—<‘<Ó Ð r)   c                ó    • U R                   U   $ r   ©rÞ  )r$   Úidxs     r&   Ú__getitem__ÚTableList.__getitem__¹  s   € ð �|‰|˜CÑ Ð r)   c                ó,   • [        U R                  5      $ r   )ÚiterrÞ  rä   s    r&   Ú__iter__ÚTableList.__iter__¿  s   € Ü�D—L‘LÓ!Ð!r)   c                ó   • [        U 5      $ r   )Únexträ   s    r&   Ú__next__ÚTableList.__next__Â  s   € Ü�D‹zÐr)   c                ó    • [        U SU 35      $ )NÚto_)rÄ  )Útablerœ  s     r&   Ú_format_funcÚTableList._format_funcÅ  s   € ä�u  A 3˜iÓ(Ð(r)   c                ó   • [        U 5      $ )z!The number of tables in the list.rm  rä   s    r&   râ  ÚTableList.nÉ  s   € ô �4‹yÐr)   c                óö   • U R                    Vs/ s HS  nUR                  S   U:¼  d  M  UR                  S   U:¼  d  M-  UR                  U:¼  d  M?  UR                  U::  d  MQ  UPMU     nn[	        U5      $ s  snf )uT  Return a new TableList keeping only tables that pass all thresholds.

A post-extraction convenience for dropping noise / low-quality
tables (single stray cells, mostly-empty regions, â€¦). Parsing is
unchanged â€” everything is still detected; this just selects from
the result. Every threshold defaults to a no-op, so calling
``filter()`` with no arguments returns an equivalent list and a
legitimate single-row or single-column table is never dropped
unless you ask for it.

Parameters
----------
min_rows : int, optional (default: 1)
    Drop tables with fewer than this many rows.
min_columns : int, optional (default: 1)
    Drop tables with fewer than this many columns.
min_accuracy : float, optional (default: 0.0)
    Drop tables whose ``parsing_report`` accuracy (0-100) is below
    this value.
max_whitespace : float, optional (default: 100.0)
    Drop tables whose ``parsing_report`` whitespace (0-100) is
    above this value.

Returns
-------
camelot.core.TableList
    A new list (the original is left untouched), so calls compose:
    ``tables.filter(min_rows=2).filter(min_accuracy=90)``.

r   r   )rÞ  rÿ   r   r  rÜ  )r$   Úmin_rowsÚmin_columnsÚmin_accuracyÚmax_whitespacerö  Úkepts          r&   rª   ÚTableList.filterÎ  s‰   € ðN Ÿšó
â%�Ø�{‰{˜1‰~ Ñ)ó ð —‘˜A‘ +Ñ-ó ð —‘ ,Ñ.ó	 ð
 × Ñ  NÑ2÷ Ù%ð 	ð 
ô ˜‹Ðùò
s   �A6ªA6¿A6ÁA6Á#A6c                óp  • US;  a  [        SU< 35      eU R                  (       d  [        / 5      $ / n/ nU R                   GH5  nU(       d  UR                  U5        M  US   n[	        UR
                  5      [	        UR
                  5      :H  nU=(       a‰    US:g  =(       d}    UR                  R                  (       d`  UR                  R                  (       dE  [        UR                  R                  S   5      [        UR                  R                  S   5      :H  OSnU(       a!  US:X  d  U(       a  UR                  U5        GM  UR                  [        UUS:H  =(       a    U(       + S95        U/nGM8     U(       a*  UR                  [        UUS:H  =(       a    U(       + S95        [        U5      $ )	u”  Vertically stack tables that look like continuations across pages.

Many PDF reports break a single logical table over several pages
â€” a header on every page, a footer on every page, body rows in
between. ``read_pdf`` returns one :class:`Table` per page; this
helper stitches contiguous ones back together so the resulting
:class:`TableList` has one entry per *logical* table instead of
one per *physical* page.

Parameters
----------
match : str, optional (default: 'column_count')
    How to decide whether two adjacent tables are continuations
    of each other.

    * ``'column_count'`` â€” same number of columns (the rule from
      #628's POC; the common case).
    * ``'first_row'`` â€” same column count *and* identical text
      in the first row (catches PDFs that repeat the header on
      every page).
keep_first_header : bool, optional (default: False)
    When ``match='first_row'``, the matching first row of every
    continuation table is dropped (so the stacked table has
    exactly one header row). Set to ``True`` to keep every
    page's header row in the stacked output.

Returns
-------
camelot.core.TableList
    A new TableList with continuation runs collapsed. Tables
    that don't continue from the previous one (different
    column count or different first row, depending on ``match``)
    are passed through unchanged. The originals in ``self`` are
    not mutated.

Notes
-----
Originally proposed by @TimothyOfDelphi in #628. Consolidates
#8 / #133 / #357 / #531.

Limitations:

* The stacked :class:`Table`'s ``page`` keeps the *first*
  stitched table's page number; ``order`` keeps the first
  table's order. Callers iterating with both shouldn't be
  surprised by a missing row-of-pages.
* ``parsing_report`` is averaged: ``accuracy`` and
  ``whitespace`` are mean-aggregated across the stitched
  tables; ``confidence`` is recomputed from the averaged
  accuracy + whitespace.
* Cell geometry (``_bbox``, ``cells``, ``rows``) is preserved
  via the y-shift trick from #628's POC, so downstream
  plotting on a single stitched table still works
  page-locally. Cells from the second-and-later tables are
  shifted to sit below the first table's bottom.
)Úcolumn_countÚ	first_rowz1match must be 'column_count' or 'first_row', got r  r  r   Fr  )rÆ  )rq  rÞ  rÜ  r=   r7   rù   rþ   rÀ  r©   rÁ  rÓ  )	r$   ÚmatchÚkeep_first_headerÚstitchedrÅ  rö  ÚheadÚ	same_colsÚsame_headers	            r&   Ústack_contiguousÚTableList.stack_contiguousý  so  € ðz Ð5Ó5ÜØCÀEÁ9ÐMóð ð �|�|Ü˜R“=Ð à "ˆØˆà—\•\ˆEÞØ—
‘
˜5Ô!ÙØ�r‘7ˆDÜ˜DŸI™I›¬#¨e¯j©j«/Ñ9ˆIØ#÷ Ø˜Ñ$÷ ð  Ÿ7™7Ÿ=Ÿ=°·±··ô ˜Ÿ™Ÿ™ a™Ó)¬T°%·(±(·-±-ÀÑ2BÓ-CÒCàð ö ˜e ~Ó5¾Ø—
‘
˜5×!à—‘ÜØØ.3°{Ñ.B÷ .2Ø 1Ô1ñôð �g“ñ1 "ö2 Ø�O‰OÜØØ*/°;Ñ*>÷ *.Ø-Ô-ñôô ˜Ó"Ð"r)   Nc                óø   • US   nUS   nUS   nU R                    H[  nU SUR                   SUR                   U 3n[        R                  R                  X75      nU R                  Xa5      n	U	" U5        M]     g )Nr×  rØ  rÙ  ú-page-r   )rÞ  r  r  rA  rB  r4   r÷  )
r$   rœ  r�  r×  rØ  rÙ  rö  r  ÚfilepathÚ	to_formats
             r&   Ú_write_fileÚTableList._write_fileh  sx   € Ø˜Ñ#ˆØ�f‰~ˆØ�U‰mˆØ—\”\ˆEØ˜˜v e§j¡j \°¸¿¹¸ÀcÀUÐKˆHÜ—w‘w—|‘| GÓ6ˆHØ×)Ñ)¨%Ó3ˆIÙ�hÖò	 "r)   c                ó  • US   nUS   nUS   nUS   n[         R                  R                  [         R                  R                  U5      U5      S-   n[        R
                  " USSS9 nU R                   Hq  nU S	UR                   S
UR                   U 3n	[         R                  R                  X95      n
UR                  U
[         R                  R                  U
5      5        Ms     S S S 5        g ! , (       d  f       g = f)NrB  r×  rØ  rÙ  ú.zipr•  T©Ú
allowZip64r  r   )rA  rB  r4   r×  ÚzipfileÚZipFilerÞ  r  r  rš  rC  )r$   r�  rB  r×  rØ  rÙ  ÚzipnameÚzrö  r  r  s              r&   Ú_compress_dirÚTableList._compress_dirr  sÊ   € Ø�f‰~ˆØ˜Ñ#ˆØ�f‰~ˆØ�U‰mˆÜ—'‘'—,‘,œrŸw™wŸ™¨tÓ4°dÓ;¸fÑDˆÜ�_Š_˜W c°dÒ;¸qØŸœ�Ø"˜V 6¨%¯*©*¨°W¸U¿[¹[¸MÈ#ÈÐO�ÜŸ7™7Ÿ<™<¨Ó:�Ø—‘˜¤"§'¡'×"2Ñ"2°8Ó"<Ö=ñ &÷ <×;Ö;ús   Á+BC6Ã6
Dc                óÈ  • [         R                  R                  U5      n[         R                  R                  U5      n[         R                  R	                  U5      u  pgU(       a  [
        R                  " 5       nXXgS.nUS;   a/  U R                  " SSU0UD6  U(       a  U R                  " S0 UD6  ggUS:X  Ga$  [         R                  R                  XE5      n	[        R                  " U	5      n
U R                   H8  nSUR                   SUR                   3nUR                  R!                  X¬S9  M:     U
R#                  5         U(       a�  [         R                  R                  [         R                  R                  U5      U5      S-   n[$        R&                  " US	S
S9 nUR)                  U	[         R                  R                  U	5      5        SSS5        ggUS:X  aÚ  [         R                  R                  XE5      n	U R                   H  nUR+                  U	5        M     U(       a�  [         R                  R                  [         R                  R                  U5      U5      S-   n[$        R&                  " US	S
S9 nUR)                  U	[         R                  R                  U	5      5        SSS5        ggg! , (       d  f       g= f! , (       d  f       g= f)zúExport the list of tables to specified file format.

Parameters
----------
path : str
    Output filepath.
f : str
    File format. Can be csv, excel, html, json, markdown or sqlite.
compress : bool
    Whether or not to add files to a ZIP archive.

)rB  r×  rØ  rÙ  )ÚcsvÚhtmlÚjsonÚmarkdownrœ  ÚexcelrŸ  r   )r¡  r  r•  Tr  NÚsqliterF   )rA  rB  r×  rC  ÚsplitextÚtempfileÚmkdtempr  r  r4   rü   r¢  rÞ  r  r  rþ   r£  r¶  r  r  rš  r¹  )r$   rB  rœ  Úcompressr×  rC  rØ  rÙ  r�  r  r¤  rö  r¡  r  r  s                  r&   ÚexportÚTableList.export~  s  € ô —'‘'—/‘/ $Ó'ˆÜ—7‘7×#Ñ# DÓ)ˆÜ—G‘G×$Ñ$ XÓ.‰	ˆÞÜ×&Ò&Ó(ˆGà#ÀÑRˆàÐ3Ó3Ø×ÒÑ+˜qÐ+ FÒ+ÞØ×"Ò"Ñ, VÓ,ð à�'Œ\Ü—w‘w—|‘| GÓ6ˆHÜ—^’^ HÓ-ˆFØŸœ�Ø$ U§Z¡Z L°¸¿¹°}ÐE�
Ø—‘×!Ñ! &Ð!Ó@ñ &ð �L‰LŒNÞÜŸ'™'Ÿ,™,¤r§w¡w§¡°tÓ'<¸dÓCÀfÑL�Ü—_’_ W¨c¸dÒCÀqØ—G‘G˜H¤b§g¡g×&6Ñ&6°xÓ&@ÔA÷ DÐCð ð �(‹]Ü—w‘w—|‘| GÓ6ˆHØŸœ�Ø—‘ Ö)ñ &æÜŸ'™'Ÿ,™,¤r§w¡w§¡°tÓ'<¸dÓCÀfÑL�Ü—_’_ W¨c¸dÒCÀqØ—G‘G˜H¤b§g¡g×&6Ñ&6°xÓ&@ÔA÷ DÐCð ð	 ÷ DÕCú÷ DÕCús   Æ'0KÊ0KË
KË
K!rè  )rß  zIterable[Table]rò   ÚNone)ré  Úintrò   r÷   )rò   zIterator[Table])rò   r÷   )rò   r+  )r   r   r8  r9  )
rü  r+  rý  r+  rþ  r<   rÿ  r<   rò   rÜ  )r  F)r  rÖ  r  ró   rò   rÜ  r   )r�  zUnpack[_Kw]rò   r*  )r  F)rB  rÖ  )r@   rA   rB   rC   rD   r'   r9   rå  rê  rî  rò  r„   r÷  rô   râ  rª   r  r  r  r(  rE   rF   r)   r&   rÜ  rÜ  ˜  sÕ   † ñô(1ò9ò!ô!ô"ôð ñ)ó ð)ð óó ðð ØØ!Ø %ð-àð-ð ð-ð ð	-ð
 ð-ð 
õ-ðb $Ø"'ði#àði#ð  ði#ð 
õ	i#öV ô
>÷+Bñ +Br)   rÜ  )F)rÅ  zlist[Table]rÆ  ró   rò   r÷   )0rD   Ú
__future__r   r¾  rY   rA  r²  Úsysr%  r  Úcollections.abcr   r   Úoperatorr   Útypingr   rE  Únumpyr  Úpandasrü   Úversion_infor
   r   Útyping_extensionsÚbackendsr   Úimage_processingr   Úutilsr   r   r   r[   rÒ   r‰   ÚVERTICAL_ALIGNMENTSÚALL_ALIGNMENTSr   rH   rd   r†   rÖ   r÷   rÓ  rÕ  rÜ  rF   r)   r&   Ú<module>r:     sö   ðÙ <å "ã Û Û 	Û Û 
Û Û Ý $Ý $Ý Ý ã 
Û Û à×Ñ�wÓÝ Þõ
 ,Ý(å ,Ý +Ý .Ý *Ý &ð Ð àÐ ò 4Ð Ú1Ð Ø&Ð)<Ñ<€÷0(ñ 0(ôf8%ˆ}ô 8%÷v/Bñ /Bôd\ �ô \ ÷~S?ñ S?÷lmñ mö`Vôrˆ)ô ÷QBò QBr)   