
    Ipj                    ~   S 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	\	R                  " S5      r\	R                  " S\	R                  5      r\	R                  " S	\	R                  5      r\	R                  " S
5      r\	R                  " S5      r\	R                  " S5      r\	R                  " S\	R                  5      r\	R                  " S5      r\	R                  " S5      r\	R                  " S5      rSr1 Skr1 SkrSNS jrSNS jrSOS jrSPS jrSPS jrSQS jrSRS jrSRS jr SSS jr!SRS jr"STS jr#STS jr$STS  jr%STS! jr&STS" jr'SUS# jr(STS$ jr)STS% jr*SVS& jr+SWS' jr,STS( jr-SXS) jr.STS* jr/STS+ jr0SXS, jr1SYS- jr2SYS. jr3SYS/ jr4STS0 jr5STS1 jr6STS2 jr7STS3 jr8SZS4 jr9S[S5 jr:S\S6 jr;S]S7 jr< S^       S_S8 jjr=S`S9 jr>SaS: jr?          SbS; jr@    ScS< jrASdS= jrBSYS> jrCSTS? jrDSeS@ jrESASB.       SfSC jjrF    SgSD jrG\" SESF9 " SG SH5      5       rHShSI jrISQSJ jrJSQSK jrKSQSL jrLSiSjSM jjrMg)kaw  
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 header detection and HTML serialization (opt-in extension).

Pure text-grid module (no pymupdf import): the header-region rules operate on a
row-major ``[[cell text]]`` grid, and the serializer turns a tagged placement
grid into an HTML ``<table>``. Used only by find_tables(refine=True) (via
pymupdf.table) and Table.to_html(); never runs on the default detection path.
    )annotations)	dataclass)mean)AnyNu2   [A-Za-z]+|\d+(?:[.,:/-]\d+)*|[%$€£¥()–—-]+zE\b(?:jan|feb|mar|apr|may|jun|jul|aug|sep|sept|oct|nov|dec)[a-z]*\.?\bu.   (?:[$€£¥]\s*[-(]?\d|(?:usd|eur|gbp|jpy)\b)z[-(]?\d+(?:\.\d+)?\s*%z\b(?:19|20)\d{2}\bz:^(?=.*[A-Za-z])(?=.*\d)[A-Za-z0-9][A-Za-z0-9._/# -]{0,24}$u:   (?:>=|<=|<|>| thru | through | to |\b\d+\s*[-–]\s*\d+\b)z^\s*\d+(?:\.\d+){2,}\bz)[\[(]\s*\d{1,2}\s*[\])]|\[\s*\d{1,2}\s*\)z^[\s\d\[\]\(\)=+\-*/xX.]+$)z
in millionzin thousandz
in billionz$ inusdz'000%>   moneynumberpercent>   unitcode_id	long_text
text_labeldate_periodc                &    [        S U  5       5      $ )Nc              3  R   #    U  H  oR                  5       (       d  M  S v   M     g7f   Nisalpha.0chars     R/var/www/html/pdf-tiff/venv/lib/python3.13/site-packages/pymupdf/_table_headers.py	<genexpr>count_alpha.<locals>.<genexpr>=        4TT\\^qqT   '	'sumtexts    r   count_alphar#   <       4T444    c                &    [        S U  5       5      $ )Nc              3  R   #    U  H  oR                  5       (       d  M  S v   M     g7fr   )isdigitr   s     r   r   count_digit.<locals>.<genexpr>A   r   r   r   r!   s    r   count_digitr*   @   r$   r%   c                ,    [         R                  U 5      $ N)	_TOKEN_REfindallr!   s    r   tokensr/   D   s    T""r%   c                    U R                  5       nU(       d  g[        U5      n[        U5      nUS:X  a  g[        R	                  U5      (       a  gU[        SX#-   5      -  S:*  $ )NFr   r   333333?)stripr#   r*   	_MONTH_REsearchmax)r"   strippedalphadigits       r   numeric_liker9   H   s^    zz|H!E!Ez!!3q%-((D00r%   c                    U R                  5       nU(       d  g[        [        R                  U5      =(       d&    [        R                  " SU[        R
                  5      5      $ )NFz#\b(?:q[1-4]|fy|year|month|period)\b)r2   boolr3   r4   reI)r"   r6   s     r   date_or_period_liker>   U   sD    zz|H	  *obii8^`hjljnjn.oppr%   c                   SR                  U R                  5       R                  5       5      nU(       d  g[        U5      n[	        U5      n[        [        U5      5      nUR                  5       n[        R                  U5      (       a  g[        R                  U5      (       d"  UR                  S5      (       a  US:  a  US:X  a  g[        U5      (       d   [        R                  U5      (       a  US:X  a  g[        R                  U5      (       a  US:  a  US	::  a  g
[!        U5      (       a  gUS;   a  g["        R%                  U5      (       a  US::  a  gUS:  a  US:  a  US::  a  gUS	:  a  gg)N emptyr	   r   r   r   r   r      ranger
   >
   $r   eurgbpr   rateratioamount$m$000r      r      r   r   )joinr2   splitr#   r*   lenr/   lower	_MONEY_REr4   _PERCENT_RE	fullmatchendswithr>   _YEAR_RE	_RANGE_REr9   _CODE_REmatch)r"   r6   r7   r8   token_countlowereds         r   	cell_typer\   \   s:   xx

**,-H!E!EfX&'KnnG!!X&&8+<+<S+A+AeaiTY]^T^8$$););H)E)E+YZJZ!!eaiK14DHZZ~~hK1$4qyUQY;!#3ar%   c           	        U  Vs/ s H$  oR                  5       (       d  M  [        U5      PM&     nnU(       d	  SSSSSSS.$ [        U5      n[        S U 5       5      U-  [        S U 5       5      U-  [        S U 5       5      U-  [        S U 5       5      U-  [        S U 5       5      U-  [        S U 5       5      U-  S.$ s  snf )	N        )value_type_ratiolabel_type_ratiolong_text_type_ratiocode_type_ratiodate_period_type_ratiorange_type_ratioc              3  <   #    U  H  o[         ;   d  M  S v   M     g7fr   VALUE_TYPESr   items     r   r   #cell_type_ratios.<locals>.<genexpr>        Tnd@Sn   	c              3  <   #    U  H  o[         ;   d  M  S v   M     g7fr   LABEL_TYPESrh   s     r   r   rj      rk   rl   c              3  4   #    U  H  oS :X  d  M
  Sv   M     g7fr   r   N rh   s     r   r   rj      s     #X.$KDWAA.   		c              3  4   #    U  H  oS :X  d  M
  Sv   M     g7f)r   r   Nrr   rh   s     r   r   rj      s     Q^Ty?Pqq^rs   c              3  4   #    U  H  oS :X  d  M
  Sv   M     g7fr   r   Nrr   rh   s     r   r   rj      s     %\NDmF[aaNrs   c              3  4   #    U  H  oS :X  d  M
  Sv   M     g7f)rC   r   Nrr   rh   s     r   r   rj      s     Pndnrs   )r2   r\   rP   r    )textsr"   nonempty_typestotals       r   cell_type_ratiosr{   {   s    27H%$::<oio%NH # #$'"&) #
 	
 ETnTTW\\TnTTW\\ ##X.#X X[` `Q^QQTYY"%%\N%\"\_d"dPnPPSXX  Is
   CCc                   U  Vs/ s H  oR                  5       (       d  M  UPM     nnU (       d  SSSSSSSSS.[        / 5      E$ [        [        U 5      5      [        [        U5      5      [        U5      [        U 5      -  [        U 5      [        U5      -
  [        U 5      -  [	        S U 5       5      [        S[        U5      5      -  [	        S U 5       5      [        S[        U5      5      -  [	        S U 5       5      [        S[        U5      5      -  U(       a.  [        U Vs/ s H  n[        [        U5      5      PM     sn5      OSS.[        U 5      E$ s  snf s  snf )Nr^   )
cell_countnonempty_countnonempty_ratioempty_rationumeric_ratioalpha_ratiodate_period_ratio
avg_tokensc              3  J   #    U  H  n[        U5      (       d  M  S v   M     g7fr   r9   r   r"   s     r   r   row_features.<locals>.<genexpr>   s     J84|D7IQQ8   #	#r   c              3  H   #    U  H  n[        U5      S :  d  M  Sv   M     g7fr   r   Nr#   r   s     r   r   r      s     K[5F5J11   "	"c              3  J   #    U  H  n[        U5      (       d  M  S v   M     g7fr   )r>   r   s     r   r   r      s      Uxt;Nt;Txr   )r2   r{   floatrP   r    r5   r   r/   )rx   r"   nonemptys      r   row_featuresr      sC   !&7**,H7!! !$

 r"

 
	
 CJ'H.h-#e*4E
S]2c%j@J8JJSQRTWX`TaMbbKKKcRSUXYaUbNcc  Ux UUX[\]_bck_lXmmHPd(C($Ct-(CDVY
 5
!
 
 8* Ds   EE)E"c                ,    U[        U 5      :  a  X   $ S$ )N rP   )rowcols     r   column_textr      s    SX~38-2-r%   c                n   [        U 5      n[        U S5      nU SS   Vs/ s H  o3R                  5       (       d  M  UPM     nnU Vs/ s H  n[        U5      PM     nn[	        UR                  5       5      n0 UEU(       a  SOS[        U5      S:  a  SOS[        U5      (       a  SOS[        U5      [        ;   a  SOS[        U5      [        ;   a  SOS[        S U 5       5      [        S[        U5      5      -  [        S U 5       5      [        S[        U5      5      -  [        S U 5       5      [        S[        U5      5      -  [        S U 5       5      [        S[        U5      5      -  [        S	 U 5       5      [        S[        U5      5      -  [        SUS
   S-  5      S.E$ s  snf s  snf )Nr   r   r^   g      ?c              3  J   #    U  H  n[        U5      (       d  M  S v   M     g7fr   r   r   s     r   r   row_vector.<locals>.<genexpr>   s     !KT8J!!r   c              3  H   #    U  H  n[        U5      S :  d  M  Sv   M     g7fr   r   r   s     r   r   r      s     Lddk$6G!6Kdr   c              3  <   #    U  H  o[         ;   d  M  S v   M     g7fr   rf   rh   s     r   r   r           $U:4ATQQ:rl   c              3  <   #    U  H  o[         ;   d  M  S v   M     g7fr   rn   rh   s     r   r   r      r   rl   c              3  4   #    U  H  oS :X  d  M
  Sv   M     g7frq   rr   rh   s     r   r   r      s     (Yzt[EXzrs   r          @)first_emptyfirst_alphafirst_numericfirst_value_typefirst_label_typerest_numeric_ratiorest_alpha_ratiorest_value_type_ratiorest_label_type_ratiorest_long_text_type_ratioavg_tokens_norm)r   r   r2   r\   r;   r#   r9   rg   ro   r    r5   rP   min)rx   featuresfirstr"   rest
rest_typesfirst_nonemptys          r   
row_vectorr      s   E"Hq!E"12Y7YT**,DYD7.23dd)D/dJ3%++-(N
,s#)%014s# ,U 3 3#,U#3{#BC#,U#3{#BC!!K!KKcRSUXY]U^N__LdLLsSTVYZ^V_O``!$$U:$U!UX[\]_bcm_nXo!o!$$U:$U!UX[\]_bcm_nXo!o%((Yz(Y%Y\_`acfgqcr\s%ssH\$:S$@A  83s   F-F-F2c                p    [        U 5      nUS   S:X  a  gUS   S:*  =(       d    US   S:  n[        U5      $ )Nr~   r   Fr   g      @r   皙?r   r;   )r   r   short_or_sparses      r   header_candidate_rowr      sG    C H !Q&|,3Vx7NRV7VO  r%   c                   [        U 5      nUS   S:X  a  gU  Vs/ s H  o"R                  5       PM     nnU Vs/ s H  o"(       d  M  UPM     nnU Vs1 s H  o"R                  5       iM     nn[        U5      S:  =(       a$    [        U5      [	        S[        U5      S-  5      :*  nUS   S:  =(       d    US	   S
:*  n[        U=(       d    U5      $ s  snf s  snf s  snf )Nr}   r   F   r      r   r   r   ffffff?)r   r2   rQ   rP   r5   r;   )r   r   r"   rx   r   unique_nonemptyrepeated_labelssparse_labelss           r   grouped_header_scaffoldr      s    C H"&)*cdZZ\cE*!&/$H/089zz|O9(mq(_S-ASCPXM]^L^E_-_O]+t3Yx@P7QUY7YM011 +/9s   C
CCCc                    [        U 5      n[        US   S:  =(       a&    US   S:H  =(       a    US   S:  =(       a    US   S:  5      $ )Nr   r   r   r   ffffff?r         ?r   r;   r   vectors     r   data_row_liker      s^    _F}! 	,?#q(	,'(D0	, ?#t+	 r%   c                X    [        U 5      n[        US   S:  =(       a    US   S:*  5      $ )Nr   r   r   r   r   r   s     r   dense_numeric_row_liker      s/    _F'4/QF=4IT4QRRr%   c                    U  Vs/ s H$  oR                  5       (       d  M  [        U5      PM&     nnU(       d  g[        S U 5       5      [        U5      -  S:  $ s  snf )NFc              3  4   #    U  H  oS ;   d  M
  Sv   M     g7f)>   r	   r   r   Nrr   rh   s     r   r   )money_or_percent_heavy.<locals>.<genexpr>   s     CUT.B&BqqUrs   r   )r2   r\   r    rP   )r   r"   typess      r   money_or_percent_heavyr      sM    ),=

_Yt_E=CUCCc%jPTXXX >s
   AAc                    U SS   Vs/ s H  oR                  5       (       d  M  UPM     nnU(       d  g[        S U 5       5      [        U5      -  $ s  snf )Nr   r^   c              3  H   #    U  H  n[        U5      S :X  d  M  Sv   M     g7frv   )r\   )r   cells     r   r   )rest_date_period_ratio.<locals>.<genexpr>   s     FTTYt_%EqqTr   )r2   r    rP   )r   r   r   s      r   rest_date_period_ratior      sG     W5WT

DWD5FTFFTRR 6s
   AAc                d    [        U 5      n[        US   S:  =(       d    [        U 5      S:  5      $ )Nrc   r   r   )r   r;   r   r   r   s     r   first_row_period_restore_guardr      s4    C H12d:a>TUX>Y]a>abbr%   c                  ^ U SS   Vs/ s H  oR                  5       (       d  M  UPM     nnU(       d  gU Vs/ s H  n[        U5      PM     nn[        S U 5       5      [        U5      -  n[	        S U 5       5      nSR                  U 5      R                  5       m[	        U4S j[         5       5      n[        US:  =(       d    U=(       a    U(       + 5      $ s  snf s  snf )Nr   Fc              3  4   #    U  H  oS ;   d  M
  Sv   M     g7f)>   r   r   r   Nrr   rh   s     r   r   7first_row_date_or_unit_restore_guard.<locals>.<genexpr>  s     Tjd<S4Sjrs   c              3  *   #    U  H	  oS ;   v   M     g7f)>   r	   r   Nrr   rh   s     r   r   r     s     OJD#77J   r@   c              3  ,   >#    U  H	  oT;   v   M     g 7fr,   rr   )r   termrow_texts     r   r   r     s     @8#s         ?)	r2   r\   r    rP   anyrN   rQ   _UNIT_ROW_TERMSr;   )r   r   r   r   dp_unit_ratiomoney_or_percentunit_rowr   s          @r   $first_row_date_or_unit_restore_guardr      s     W5WT

DWD5.23dd)D/dJ3TjTTWZ[eWffMOJOOxx}""$H@@@H$&2(L<L8LMM 6 4s   CCC"c                    / n[        U 5      (       a  UR                  S5        [        U 5      (       a  UR                  S5        U$ )Nfirst_row_period_restorefirst_row_date_or_unit_restore)r   appendr   )r   guardss     r   first_row_restore_guardsr     s<    F%c**01+C0067Mr%   c                T   [        U 5      S:  a  gU S   nU Vs/ s H2  o"(       d  M  UR                  5       (       d  M"  UR                  5       PM4     nnU(       a  [        R                  US   5      (       d  g[	        U5      n[        US   S:  =(       d    US   S:  5      $ s  snf )Nr   Fr   ra   r   r   g      @)rP   r2   _DOTTED_ENUM_REr4   r   r;   )rowsr   r   cellsr   s        r   headerless_dotted_enum_guardr     s    
4y1}
q'C&)CcdT\djjl\TZZ\cEC..uQx88C H/0D8YH\<RVY<YZZ	 Ds   
B%B%B%c                @   [        U 5      nUS   S::  d	  US   S:  a  g/ nU SS   Vs/ s H)  o3R                  5       (       d  M  UR                  5       PM+     sn H;  n[        R                  " SU5      (       d    gUR	                  [        U5      5        M=     [        U5      S:  a  gU[        U5      :H  n[        [        U5      5      [        U5      :H  n[        U5      [        U5      -
  [        U5      S-
  :H  n[        U=(       a    U=(       a    U5      $ s  snf )Nr   r   r   Fr   \d{1,2}r   )r   r2   r<   rT   r   intrP   sortedsetr5   r   r;   )r   r   valuesr"   orderedunique
contiguouss          r   simple_integer_enum_header_liker     s    _F !Q&&1C*Dq*HF*-ab'B'$ZZ\'B||J--c$i  C 6{Qv&GVV,FVs6{*c&kAo=J1F1z22 Cs   DDc                R   U  Vs/ s H)  o"R                  5       (       d  M  UR                  5       PM+     nn[        U5      S:  a  g[        S U 5       5      (       a  g[        S U 5       5      (       a  g[        S U 5       5      (       d  gU Vs/ s H!  n[        R                  U5      (       d  M  UPM#     nnU Vs/ s H1  nSU;   d  M  [        [        R                  U5      5      S:  d  M/  UPM3     nn[        U5      [        U5      -  S:  a  gU(       d  [        U5      S	:  a  g[        U5      S:  a  g[        U5      n[        US
5      n[        U5      (       a  gUS
   S   (       a&  [        U5      S:  a  [        US5      n[        U5      $ gs  snf s  snf s  snf )zMA bracket/formula reference row under a grouped header, e.g. [3] = [1] * [2].r   Fc              3  F   #    U  H  n[        S  U 5       5      v   M     g7f)c              3  @   #    U  H  oR                  5       v   M     g 7fr,   r   r   s     r   r   >reference_formula_header_row_like.<locals>.<genexpr>.<genexpr>4  s     /$$||~~$   N)r   r   s     r   r   4reference_formula_header_row_like.<locals>.<genexpr>4  s     
EHD3/$///Hs   !c              3  \   #    U  H"  nS U;   =(       d    SU;   =(       d    SU;   v   M$     g7f)rD   r   ,Nrr   r   s     r   r   r   6  s)     
L84C4K53$;5#+58s   *,c              3  L   #    U  H  n[         R                  U5      v   M     g 7fr,   )_REF_FORMULA_ALLOWED_RErY   r   s     r   r   r   8  s     Hxt&,,T22x   "$=r         ?rL   r   Tsection_label_rowr   )
r2   rP   r   all_REF_TOKEN_REr4   r.   row_profiles"body_window_features_from_profilesbody_window_is_stable)		candidatefollowing_rowsr"   r   	ref_cellsformula_cellsfollowing_profilesbody_featuresshifteds	            r   !reference_formula_header_row_liker  /  sj   )2Cjjl

HC
8}q

EH
EEE

L8
LLLHxHHH"*I($m.B.B4.H(II&.hhd#+T#mF[F[\`FaBbfgBgThMh
9~H%,S^a/
>Q%n567I1MM]++!01c:L6MQR6R45GK$W--3 D Jhs(   FFF5F
F$ F$3F$c                   / nSnU  Vs/ s H)  o3R                  5       (       d  M  UR                  5       PM+     nnU HY  n[        R                  " SU5      (       a  UR                  [	        U5      5        M;  [        S U 5       5      (       a  US-  nMY    g   [        U5      S:  a  g[        [        U5      5      nU[        [        US   US   S-   5      5      :w  a  gUS   S;  a  gU[        S	[        U5      S-  5      :  a  gg
s  snf )Nr   r   c              3  @   #    U  H  oR                  5       v   M     g 7fr,   r   r   s     r   r   .dense_integer_axis_row_like.<locals>.<genexpr>T  s     1DDDr   r   F   >   r   r   rL   T)r2   r<   rT   r   r   r   rP   r   r   listrC   r5   )r   r   alpha_cellsr"   r   r   s         r   dense_integer_axis_row_liker  M  s    FK),=



H=<<
D))MM#d)$1D1111K  6{QCK FeF1IvbzA~677aySCMQ.//# >s
   D	D	c                    [        U 5      nUS   S:X  a  gUS   S::  a  US   S:  =(       d    US   S:  $ US	   S
:  a  g[        US   S:  =(       d    US   S:  5      $ )Nr~   r   Fr   r   r   r   r   r   r   r   r   s     r   #sparse_prefix_extension_prefix_liker  d  s    C H !Q& !Q&&$.W(;N2OSW2WW%'4/X8<O3PTX3XYYr%   c                @   [        U 5      n[        U 5      nUS   S:  a  gUS   S:  d	  US   S:  a  g[        U 5      (       a  g[        X5      (       a  gUS	   S
:  a  g[	        US   US   5      nUS   S:  =(       d    US:  =(       d    US   S:  nU(       d  g[        U5      S:  a  g[        U5      n[        US5      n[        U5      (       d  gUS   S:  d	  US	   S:  a  US   S::  a  US:  a  gUS   S:  a  gU  Vs/ s H$  oR                  5       (       d  M  [        U5      PM&     n	n[        U	5      n
U
(       d  g[        S U	 5       5      U
-  n[        S U	 5       5      U
-  nUS	   S:  a  [        U 5      $ US:  a  US:  a  [        U 5      $ gs  snf )Nr~   r   Fr   g      @ra   r   Tr_   g333333?r   rc   r   r1   r   r   r   r   r   r   c              3  4   #    U  H  oS :X  d  M
  Sv   M     g7frv   rr   rh   s     r   r   .next_header_row_value_guard.<locals>.<genexpr>  s     G1F!!rs   c              3  4   #    U  H  oS ;   d  M
  Sv   M     g7f)>   rC   r
   r   r   Nrr   rh   s     r   r   r!    s     !`A_9_!!rs   r   )r   r   r   r  r5   rP   r
  r  r  r2   r\   r    r   )r  r  r   r   date_period_signalhas_label_signalr  r  r"   r   
type_countdate_type_ratiocode_range_number_ratios                r   next_header_row_value_guardr(  o  s   I&H	"F !A%#x0F'G4'Oi(((CC"#d* X&9:HE]<^_4' 	*%	*$%) 
 
>Q%n567I1MM // D(H5G,HD,P$%*/AD/H$%))2Cjjl_Yt_ECUJGGG*TO!!`!``cmm"#d*.y99$&?T+A.y99 Ds   F!Fc                ^   US:w  d  [        U 5      S:  a  gU S   nU S   n[        U5      n[        U5      nUS   S:  a  gUS   S:  a
  US   S:  a  g[        U5      (       d  gUS	   S:  a  gUS
   S:  a  g[        U5      (       a  g[	        U SS  5      n[        US5      n[        U5      $ )Nr   r   Fr   r   r   r~   r   r`   r_   r   )rP   r   r  section_label_row_liker
  r  r  )r   top_header_rowsprefixr  prefix_featurescandidate_featuresr  r  s           r   *sparse_prefix_conservative_extension_guardr/    s    !s4y1}!WFQI"6*O%i0}%,*+a/4FGZ4[^b4b.v66,-4,-5i((%d12h/67I1MM //r%   c                J    US:  d  U[        U 5      S-
  :  a  g[        X5      $ )zNReturn True when the first body row should be included as a second header row.r   F)rP   r/  )r   r+  s     r   sparse_prefix_next_header_guardr1    s'    oTQ>5dLLr%   c                   US:w  d  [        U 5      S:  a  g[        S U  5       SS9nUS:  a  gU S   nU S   n[        U5      n[        U5      n[        U5      n[        U5      U:  n[	        US5      R                  5       (       a  U(       d  g[        U5      U:  =(       a$    [        U5      [        S[        US-  5      5      :*  n	[        U5      (       d  US	   S
:  d  U	(       d  gUS   [        S[        US-  5      5      :  a  gUS   S:  d	  US   S
:  a  gUS   S:  a
  US   S:  a  g[        U5      (       d  [        U5      (       a  g[        U SS 5      n
[        U
S5      n[        U5      $ )zPromote a leaf-label row under a sparse/grouped rowspan header scaffold.

An empty first cell in the candidate row is the textual shadow of the row-0
rowspan label; treat it as header only when later rows form a stable body.
r   r   Fc              3  8   #    U  H  n[        U5      v   M     g 7fr,   r   r   r   s     r   r   ,rowspan_leaf_header_guard.<locals>.<genexpr>       -CHH   r   defaultr   r   r   r   r~   ?r_   r   r   r   r   N)rP   r5   r   r   r   r2   r   r   r*  r   r
  r  r  )r   r+  max_colsr,  r  r-  r.  candidate_vectorshifted_by_rowspansparse_rowspan_prefixr  r  s               r   rowspan_leaf_header_guardr?    s    !s4y1}--q9H!|!WFQI"6*O%i0!),Y(29a &&((1CK(2bs6{c!SQY\`Q`MaFb7b#F++}/MQU/UYn*+c!SD5I.JJ,-48J?8[^b8b/047<N}<]`d<di((,B9,M,M%d12h/67I1MM //r%   c                   [        U 5      nUS   S:  a  gUS   S:  =(       a    US   S:H  nUS   S:  =(       d    US	   S:  nUS
   S:  =(       d    US   S:  n[        U=(       a"    U=(       a    U=(       a    [        U 5      (       + 5      $ )Nr~   r   Fr   r   r   r   r   r   r   r   r_   )r   r;   r   )r   r   first_is_labelrest_is_valuesvalue_heavys        r   leading_body_record_likerD    s    _F!#./!3W?Q8RVW8WN01T9dVD[=\`d=dN)T1WV<N5OSW5WKf>fkfJabeJfFfggr%   c                    [        U 5      n[        US   S:  =(       a&    US   S:  =(       a    US   S:*  =(       a    US   S:*  5      $ )	Nr~   rL   ra   r1   r_   r   r   r   r   r   s     r   leading_long_form_row_likerF    s`    _F A% 	*)*d2	*%&$.	* =!T)	 r%   c                   [        U 5      S:  a  g[        U 5      n[        U S5      R                  5       nU  Vs/ s H  o3R                  5       (       d  M  UPM     nn[	        U=(       a1    U SS   Vs/ s H  o3R                  5       (       d  M  UPM     sn(       + 5      nUS   S:*  =(       a    US   S:  =(       a    US	   S
:  n[	        U=(       d    U=(       a    U5      $ s  snf s  snf )Nr   Fr   r   r~   r   r   333333?r   r   )rP   r   r   r2   r;   )r   r   r   r"   r   
first_onlysparse_labels          r   r*  r*    s    
3x!|C HQ%%'E!$5

H5eNc!"g$NgdTg$N NOJ!"a' 	,]#t+	,]#t+ 
 
9x8L:: 6$Ns   C$C$3C)C)c                   [        U 5      (       d  g[        U 5       VVs/ s H  u  pUR                  5       (       d  M  UPM      nnn[        [	        U5      S:H  =(       a    US   S:  =(       a    [	        U 5      S:  5      $ s  snnf )NFr   r   r   )r*  	enumerater2   r;   rP   )r   idxr"   nonempty_indicess       r   centered_section_label_row_likerO  
  sm    !#&&-6s^L^	tzz|^L$%*X/?/BQ/FX3s8WX=YY Ms
   BBc                D   / n[        U SU 5       H  u  p4US:X  d  [        U5      (       d  M  U Vs/ s H)  oUR                  5       (       d  M  UR                  5       PM+     nn[        U5      S:w  a  Md  [        U5      S:  a  Mu  UR	                  U5        M     U$ s  snf )zGReturn sparse section-label rows inside the detected top header prefix.Nr   r   r   )rL  rO  r2   rP   r   )r   r+  section_rowsrow_idxr   r"   r   s          r   section_header_rowsrS    s    L!$'7"89a<>sCC-0ASTJJLLDJJLSAx=As8a<G$ :  Bs   BBc                   [        U 5      n[        U 5      nUS   S:  =(       a&    US   S:H  =(       a    US   S:  =(       a    US   S:  nUS   S:  =(       a    US	   S:*  nUS
   S:  =(       a5    US   S:H  =(       a&    US   S:  =(       a    US   S:*  =(       a    US   S:*  nU(       a  SnSnSnUUUS   S:  UUUU=(       d    U=(       d    UU[        U 5      [        U 5      [	        U 5      [        U 5      [        U 5      S.$ )Nr   r   r   r   r   r   r   r   r   r   r   r   r   r_   r   Fr~   )indexr   r   body_value_rowbody_dense_rowbody_long_form_rowbody_like_rowcoordinate_header_rowleading_body_record_rowleading_long_form_rowr  r   header_candidate)r   r  rD  rF  r*  r   r   )r   rU  r   rZ  rV  rW  rX  s          r   row_profiler^     sY   _F7<}! 	,?#q(	,'(D0	, ?#t+	  O,4V9NRV9VN!"Q& 	*%&!+	*./47	* %&$.	* =!T)  "+,q0((0'O>O=O!6#;C#@!;C!@3C8#:3#?05 r%   c                `    [        U 5       VVs/ s H  u  p[        X!5      PM     snn$ s  snnf r,   )rL  r^  )r   rU  r   s      r   r
  r
  F  s%    6?oFo
K#oFFFs   *c                   U (       d  SSSSSSSSSSSSSS.$ [        [        U 5      5      [        S U  5       5      [        U 5      -  [        S U  5       5      [        U 5      -  [        S U  5       5      [        U 5      -  [        S U  5       5      [        U 5      -  [        S U  5       5      [        U 5      -  [        S U  5       5      [        U 5      -  [        S	 U  5       5      [        U 5      -  [        S
 U  5       5      [        U 5      -  [        S U  5       5      [        U 5      -  [        S U  5       5      [        U 5      -  [        S U  5       5      [        U 5      -  [        S U  5       5      [        U 5      -  S.$ )Nr^   )countfirst_label_ratior   r   r   r   body_row_ratiodense_numeric_row_ratiolong_form_row_ratior_   r   r   ra   c              3  P   #    U  H  oS    S:  d  M  US   S:X  d  M  Sv   M     g7f)r   r   r   r   Nrr   rh   s     r   r   'combine_body_vectors.<locals>.<genexpr>]  s/      ywt?Q:RUV:V[_`r[swx[xw   &&	&c              3  *   #    U  H	  oS    v   M     g7f)r   Nrr   rh   s     r   r   rg  _  s     !Q';"<r   c              3  *   #    U  H	  oS    v   M     g7f)r   Nrr   rh   s     r   r   rg  `  s     Gwt/2wr   c              3  *   #    U  H	  oS    v   M     g7f)r   Nrr   rh   s     r   r   rg  a  s     C74.7r   c              3  *   #    U  H	  oS    v   M     g7f)r   Nrr   rh   s     r   r   rg  b  s     K74$567r   c              3  *   #    U  H	  oS    v   M     g7f)r_   Nrr   rh   s     r   r   rg  c  s     MWT%7 8Wr   c              3  *   #    U  H	  oS    v   M     g7f)r   Nrr   rh   s     r   r   rg  d  s     $Wwt*A%Bwr   c              3  *   #    U  H	  oS    v   M     g7f)r   Nrr   rh   s     r   r   rg  e  s     (_W^t.I)JW^r   c              3  *   #    U  H	  oS    v   M     g7f)ra   Nrr   rh   s     r   r   rg  f  s     #UWT)?$@Wr   c              3     #    U  HA  nUS    S:  a  US   S:X  a  US   S:  a	  US   S:  d  US   S:  d  M2  US   S::  d  M=  S	v   MC     g
7f)r   r   r   r   r   r   r   r   r   r   Nrr   rh   s     r   r   rg  g  so      

]#a')Q.-.$6)T1_%-  37}2E2M As   1AA	Ac              3  P   #    U  H  oS    S:  d  M  US   S::  d  M  Sv   M     g7f)r   r   r   r   r   Nrr   rh   s     r   r   rg  s  s.      '
!$/%:d%BAtMGZ^bGbAA'rh  c              3     #    U  H>  nUS    S:  d  M  US   S:X  d  M  US   S:  d  M$  US   S::  d  M/  US   S::  d  M:  S	v   M@     g
7f)r   r   r   r   r   r_   r   r   r   r   Nrr   rh   s     r   r   rg  w  sz      
#
'(1,  +,1	 
 45=  +,4  '4/ As   AAAAA	A)ra  rb  r   r   r   r   r_   r   r   ra   rc  rd  re  )r   rP   r    )vectorss    r   combine_body_vectorsru  J  s   !$"% "!'*#& #%(),$'
 	
  s7|$  yw yy
g,!!Q!QQTWX_T``GwGG#g,VC7CCc'lRK7KKcRYlZMWMMPST[P\\!$$Ww$W!WZ]^eZf!f%((_W^(_%_befmbn%n ##UW#U UX[\cXd d 



 

 g, $' '
!'
 $
 g,$  # 
#

#
 
 
 g, 9( (r%   c                j    XX-     Vs/ s H  o3S   (       d  M  US   PM     nn[        U5      $ s  snf )Nr   r   )ru  )profilesstartsizeprofilert  s        r   r  r    s@     190Nf0NWZdRe wx 0NGf(( gs   0	0c                ^   U S   S:  a  gU S   S:  =(       a    U S   S:  =(       a    U S   S	:  nU S
   S:  =(       a    U S   S:  =(       a    U S   S:*  nU S   S:  =(       a5    U S   S:  =(       a&    U S   S:  =(       a    U S   S:*  =(       a    U S   S:*  nU=(       d    U=(       d    U$ )Nra  r   Frc  r   r   r:  rb  r   rd  r   rH  r   g?re  r   r_   r   rr   )r   
value_bodydense_numeric_bodylong_form_bodys       r   r  r    s    1!"d* 	2)*d2	2()T1  	*+t3 	,_%-	,]#t+  	&'4/ 	.()T1	.01T9	. '(D0	. _%-  =+=~=r%   c                (   [        U 5      nSnU[        US   US   -
  5      -  nU[        US   US   -
  5      -  nU[        US   US   -
  5      -  nU[        US   US   -
  5      -  nUS[        US   US   -
  5      -  -  nUS	   S
:  a  US-  nU$ )Nr^   r   r   r   r   rb  r   r   r   r   r   )r   abs)
header_rowr  headerdistances       r   boundary_distancer    s    
#FHF?+mO.LLMMHF=)M-,HHIIHF/0=AU3VVWWHF=)M:M,NNOOHc&!23mDU6VVWWWHm$DOr%   c                  ^  / nUS::  a  gUS:  a  gUSU nU(       d  g[        U 4S jU 5       5      n[        S U 5       5      n/ nU H  n	U	S   (       d  M  [        U	S   5      n
U=(       aS    XS-
  :H  =(       aE    U	S	   =(       a9    U	S
   (       + =(       a(    U	S   S   S:*  =(       a    U
S:  =(       a
    XS-
     S	   n[        T U
   5      (       a  M  U(       a  M  UR	                  U	5        M     [        S U 5       5      (       a   U(       d  U(       a  UR	                  S5        OU(       a  UR	                  S5        [        S U 5       5      (       a  UR	                  S5        [        S U 5       5      (       d  UR	                  S5        XS-
     nXS-
     n[        T US-
     U5      nUS:X  a3  US   S   S:X  a'  US   S   S:  a  US   (       d  UR	                  S5        US   (       a  US   (       d  UR	                  S5        US   S   S:  a  US   (       d  UR	                  S5        US :  a  UR	                  S!5        U(       + $ )"Nr   Tr  Fc              3  F   >#    U  H  n[        TUS       5      v   M     g7f)rU  N)rO  )r   rz  r   s     r   r   #header_prefix_ok.<locals>.<genexpr>  s'      {hz]d!@ggFVAW!X!Xhzs   !c              3  D   #    U  H  oR                  S S5      v   M     g7f)rZ  FNgetr   rz  s     r   r   r    s     jWiGKK(?GGWis    r  rU  r]  rY  r   r~   r   c              3  *   #    U  H	  oS    v   M     g7f)r  Nrr   r  s     r   r   r    s     
J7IG&'7Ir   section_label_before_bodyc              3  *   #    U  H	  oS    v   M     g7f)rY  Nrr   r  s     r   r   r    s     
F3E?#3Er   body_like_row_before_bodyc              3  *   #    U  H	  oS    v   M     g7f)r]  Nrr   r  s     r   r   r    s     M:Lw)*:Lr    non_header_candidate_before_bodyr   r   r   r   r^   r   (numeric_first_row_without_group_scaffoldrW  &dense_candidate_without_group_scaffoldr   r   *low_alpha_candidate_without_group_scaffoldg?weak_header_body_contrast)r  r   r   rO  r   r  )r   rw  
body_startr  reasonscandidate_profilesallowed_section_prefixcoordinate_prefixdisallowed_section_profilesrz  rM  sparse_coordinate_tailpreviouslast_candidatecontrasts   `              r   header_prefix_okr    s`    GQA~!!J/  {hz {{jWijj"$%*+''"# 6A~%6*+6 O,,6 !"23q8	6
 a6 q!"45 	 /tCy99BXBX'..w7 & 
J7I
JJJSi&NN67	$23

F3E
FFF23M:LMMM9:Q'H1n-N j1n!5}EHa8$]3q88$_5;23AB&'9R0S?@h.5hG`>aCD$23;r%   c           	     
   / n[        S[        U 5      S-
  5      n[        SUS-   5       HU  n[        X5      nX   S   nU=(       a    [	        U5      n[        S U SU  5       5      nUR                  UUUUUS.5        MW     U$ )Nr  r   r   rY  c              3  h   #    U  H(  nUS    =(       a    UR                  SS5      (       + v   M*     g7f)rY  rZ  FNr  r  s     r   r   (body_start_candidates.<locals>.<genexpr>  s4      
, O$XW[[9PRW-X)XX,s   02)r  	body_likestart_row_body_likeprior_body_seenbody)r   rP   rC   r  r  r   r   )rw  
candidates	max_startrx  r  r  stabler  s           r   body_start_candidatesr    s     JAs8}q()Iq)a-(:8K&oo>$M)>})M 
#Ae,
 
 	##':#2%	
 )" r%   c                    [        [        U[        U 5      5      5       Vs1 s H%  n[        X5      R	                  5       (       d  M#  UiM'     sn$ s  snf r,   )rC   r   rP   r   r2   )r   r;  rM  s      r   _nonempty_col_indicesr  
  s<     Xs3x!89[9C[=R=X=X=ZC9[[[s   "AAc                   US::  a  g[        S U  5       SS9nUS:  a  g[        5       nU S U  H  nUR                  [        XB5      5        M     [	        U5      U:  =(       a$    [	        U5      [        S[        US-  5      5      :*  $ )Nr   Fc              3  8   #    U  H  n[        U5      v   M     g 7fr,   r   r4  s     r   r   ,_header_column_incomplete.<locals>.<genexpr>  r6  r7  r8  r   r   r  )r5   r   updater  rP   r   )r   r+  r;  filledr   s        r   _header_column_incompleter    s    !--q9H!|uF$_%+C:; &v;!Qc&kSC4<P5Q&QQr%   c                    U  Vs/ s H)  oR                  5       (       d  M  UR                  5       PM+     nn[        U5      S:  a  g[        S U 5       5      $ s  snf )Nr   Fc              3  L   #    U  H  n[         R                  U5      v   M     g 7fr,   )rV   rT   r   s     r   r   ,_bare_year_value_row_like.<locals>.<genexpr>  s     =HDx!!$''Hr  )r2   rP   r  )r   r"   r   s      r   _bare_year_value_row_liker    sI    ),=



H=
8}q=H=== >s
   AAc           	     H   [        U 5      n[        U S5      n[        [        X5      5      n[	        S[        U[        U 5      5      5       Vs/ s H.  n[        X5      R                  5       (       d  M#  [        X5      PM0     nn/ nUS   S:  d  [        U5      S:  a  UR                  S5        [        U5      S:  a  UR                  S5        US   (       d   [        U 5      (       d  [        U 5      (       a  UR                  S5        [        U 5      (       d  US   S	:  d	  US
   S:  a  UR                  S5        [        U 5      (       a  UR                  S5        [        U 5      (       a  UR                  S5        US   S:  d	  US   S	:  a  UR                  S5        [        U5      S:  a8  [        U5      n	[!        U	S5      n
[#        U
5      (       d  UR                  S5        US   S:  =(       d    US   S:  nU(       d  UR                  S5        U(       + $ s  snf )Nr   r   r~   r   single_or_sparse_row!no_column_header_cells_after_stubrY  r_   r   r   r   strong_value_rowbare_year_value_rowr  r   r   ra   long_text_rowfollowing_body_not_stabler   r   r   r   weak_label_signal)r   r^  r   r  rC   r   rP   r   r2   r   r   r   r   r  r*  r
  r  r  )r   r  r;  r   rz  filled_colsr   nonempty_after_stubr  r  r  label_signals               r   _undertag_extension_candidater  !  s   C H#q!G.s=>K<A!SSVWZS[E\<]<]Salmpava|a|a~0;s0<]G !A%[)9A)=-.
!#:;=#5#59OPS9T9T'c""h/A&BT&IXVeMfimMm)* %%,-c""*+#x0F'G4'O'
>a).9:;MqQ$]33NN67M*d2[h?R6SW[6[L*+;7 @s   "H3Hr   )capc               B   [        S U  5       SS9nUS::  a  U$ U[        U 5      :  a  U$ [        X5      (       d  U$ Un[        U[	        [        U 5      X-   5      5       H;  nU[        U 5      S-
  :  a    U$ [        X   XS-   S U5      nU(       d    U$ US-   nM=     U$ )zLPromote under-tagged column-header rows immediately below the base boundary.c              3  8   #    U  H  n[        U5      v   M     g 7fr,   r   r4  s     r   r   )extend_header_undertag.<locals>.<genexpr>J  r6  r7  r   r8  r   N)r5   rP   r  rC   r   r  )r   r+  r  r;  new_toprR  oks          r   extend_header_undertagr  C  s     --q9H!#d)#$T;;G#c$i9N*OPc$i!m# N +4=${}:MxX N A+ Q Nr%   c                p   U (       d  g[        U 5      S:X  a  g[        U 5      n[        U5      nU H  n[        US   5      nUS   (       a
  US   (       a  M'  US:X  a  US   S   (       a  [	        U S   5      nU(       a    g  g[        U 5      (       a    g[        U S5      (       a    g[        U S5      (       a    g[        U 5      S:  a  [        U S   U SS  5      (       a    g  g[        XXCS	   5      (       d  M  Us  $    [        U 5      (       a  g[        U S5      (       a  g[        U S5      (       a  gg)
Nr   r   r  r  r  r[  r   r   r  )
rP   r
  r  r   r   r   r1  r?  r(  r  )r   rw  r  r  r  restore_guardss         r   #find_top_header_rows_by_body_changer  ^  s&    
4yA~D!H&x0J	<01
%3D)E?{45!9$q'!B!+D11.tQ77(q11 4yA~"=d1gtABx"P"PDJ&8IJJ1  4 $D))&tQ// q))r%   T)frozenc                  *    \ rS rSr% S\S'   S\S'   Srg)HeaderRegioni  r   r+  ztuple[int, ...]rS  rr   N)__name__
__module____qualname____firstlineno____annotations____static_attributes__rr   r%   r   r  r    s    ((r%   r  c                j    [        U 5      n[        X5      n[        [        X5      5      n[	        UUS9$ )N)r+  rS  )r  r  tuplerS  r  )r   r+  rQ  s      r   find_header_regionr    s;    9$?O -TCO,TCDL'( r%   c                @    SR                  U R                  5       5      $ )zMWhitespace-collapse a cell's text (runs of whitespace/newlines -> one space).r@   )rN   rO   r!   s    r   collapse_cell_wsr    s    88DJJL!!r%   c                f    U R                  SS5      R                  SS5      R                  SS5      $ )zNEscape a cell's text for the serializer: only ``& < >`` (quotes left literal).&z&amp;<z&lt;>z&gt;)replacer!   s    r   escape_html_textr    s-    <<W%--c6:BB3OOr%   c                N    SR                  S U R                  5        5       5      $ )zAA cell's inner HTML: escaped non-empty lines joined by ``<br/>``.z<br/>c              3     #    U  H4  oR                  5       (       d  M  [        UR                  5       5      v   M6     g 7fr,   )r2   r  )r   parts     r   r   _cell_inner.<locals>.<genexpr>  s-     eCT4XbXbXd6(66CTs   > >)rN   
splitlinesr!   s    r   _cell_innerr    s    <<e4??CTeeer%   c                >   [        U=(       d    S5      nS/n[        U 5       GHP  u  pEXB;   a  U Vs/ s H4  n[        UR                  5      (       d  M  [        UR                  5      PM6     nn[	        U5      S:X  a<  [	        U5      S:  a-  UR                  S[	        U5      [        US   5      4-  5        M  UR                  S5        U H  nSnUR                  S:  a  US	UR                  -  -  nUR                  S:  a  US
UR                  -  -  nUR                  SUR                  < U< S[        UR                  5      < SUR                  < S35        M     UR                  S5        GMS     UR                  S5        SR                  U5      $ s  snf )a  Serialize a tagged placement grid to its final ``<table>`` HTML in one pass.

``rows`` is a row-major grid of cells duck-typed with ``text`` / ``colspan``
/ ``rowspan`` / ``tag`` (e.g. :class:`pymupdf.table.SpanCell`): each cell
emits its tag, its ``colspan`` / ``rowspan`` attributes and its ``<br/>``-
joined escaped inner HTML. A row whose index is in ``section_header_rows``
and that carries a single non-empty label collapses to one
``<th colspan=N>`` spanning the row.rr   z<table>r   r   z!<tr><th colspan="%d">%s</th></tr>r   z<tr>r   z colspan="%d"z rowspan="%d"r  r  z</z</tr>z</table>)r   rL  r  r"   rP   r   r  colspanrowspantagr  rN   )	r   rS  rQ  partsrR  r   r   r   attrss	            r   render_table_htmlr    sY    *0b1LKE#D/"@EeIYZ^ZcZcId3(3He8}!c%jAo75z#3HQK#@AB VDE||a4<<77||a4<<77LL#'88UK		4JDHHU  	W' *( 
LL775>' fs   FF)r"   strreturnr   )r"   r  r  	list[str])r"   r  r  r;   )r"   r  r  r  )rx   r  r  dict[str, float])r   r  r   r   r  r  )r   r  r  r;   )r   r  r  r   )r   r  r  r  )r   list[list[str]]r  r;   )r  r  r  r  r  r;   )r   r  r+  r   r  r;   )r   r  r+  r   r  z	list[int])r   r  rU  r   r  zdict[str, Any])r   r  r  list[dict[str, Any]])rt  zlist[dict[str, float]]r  r  )rL   )rw  r  rx  r   ry  r   r  r  )r   r  r  r;   )r  r  r  r  r  r   )
r   r  rw  r  r  r   r  r  r  r;   )rw  r  r  r  )r   r  r;  r   r  zset[int])r   r  r  r  r;  r   r  r;   )r   r  r+  r   r  r   r  r   )r   r  r  r   )r   r  r  r  )rr   )r  r  )N__doc__
__future__r   dataclassesr   
statisticsr   typingr   r<   compiler-   
IGNORECASEr3   rR   rS   rV   rX   rW   r   r	  r  r   rg   ro   r#   r*   r/   r9   r>   r\   r{   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r(  r/  r1  r?  rD  rF  r*  rO  rS  r^  r
  ru  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  r  rr   r%   r   <module>r     s  @ # !   	 JJLM	JJLMM	 JJH"--X	jj23::+,::STJJTVXVcVcd	**67

GH**%BC Y,K55#
1q>,6.,!	2S
YSc
	N[3"<.Z1h00M"0Jh;Z#LG9z =>)")+.)69))>.
=
="= = $	=
 
=@"2\	R>L 	
 
	
 	6-
--` $) ) )
	"
P
f
 r%   