Ë
    éƒtjl}  ã                  ó~  — d Z ddlmZ ddlZddlZddlmZmZmZ ddl	m
Z
 ddlmZmZ ddlZed   Zed   Ze G d	„ d
«      «       Ze G d„ d«      «       Z ej&                  dej(                  «      ZdZ ej&                  dez   «      Z ej&                  dez   «      Z ej&                  d«      Z ej&                  d«      Zd+d„Zd,d„Zd-d„Zd.d„Zd/d„Zd0d„Z ddddœ	 	 	 	 	 	 	 d1d„Z!d2d3d„Z" ej&                  d«      Z# ej&                  d«      Z$dZ%d4d „Z&d5d!„Z'd6d"„Z(d7d#„Z)d$d%œd8d&„Z*d9d'„Z+d5d(„Z,d:d;d)„Z-d<d=d*„Z.y)>uþ   PDF extraction for accounting calculations.

Accuracy policy:
- Digital text PDFs â†’ extract tables, validate, may mark trusted
- Scanned PDFs â†’ OCR draft only; calculations blocked until user confirms
- Calculations never run on unconfirmed OCR data
é    )ÚannotationsN)ÚasdictÚ	dataclassÚfield)ÚPath)ÚAnyÚLiteral)ÚdigitalÚscannedÚmixedÚempty)Úbank_statementÚbalance_sheetÚunknownc                  óp   — e Zd ZU dZded<   dZded<   dZded<   dZded<   dZd	ed
<   dZ	d	ed<   dZ
ded<   y)ÚExtractedRowÚ ÚstrÚdescriptionNúfloat | NoneÚdebitÚcreditÚamountú
str | NoneÚdateÚaccountÚraw)Ú__name__Ú
__module__Ú__qualname__r   Ú__annotations__r   r   r   r   r   r   © ó    ú+/var/www/html/CA-Chatbot/app/pdf/extract.pyr   r      sG   … à€K�ÓØ€Eˆ<ÓØ€FˆLÓØ€FˆLÓØ€Dˆ*ÓØ€GˆZÓØ€Cˆ„Mr#   r   c                  óð   — e Zd ZU ded<   ded<   ded<   ded<   ded<    ee¬	«      Zd
ed<   dZded<   dZded<    ee¬	«      Z	ded<    ee
¬	«      Zded<   dZded<   dZded<    ee
¬	«      Zded<   dd„Zy)ÚExtractionResultr   Újob_idÚfilenameÚ
SourceTypeÚsource_typeÚboolÚtrustedÚneeds_confirm)Údefault_factoryúlist[ExtractedRow]Úrowsr   Útext_previewÚdocument_textz	list[str]Úwarningsúdict[str, Any]Ú
validationFÚocr_usedr   ÚDocumentKindÚdocument_kindÚstatement_totalsc                ó   — t        | «      }|S ©N)r   )ÚselfÚdatas     r$   Úto_dictzExtractionResult.to_dict2   s   € Ü�d‹|ˆØˆr#   N)Úreturnr4   )r   r   r    r!   r   Úlistr0   r1   r2   r3   Údictr5   r6   r8   r9   r>   r"   r#   r$   r&   r&   "   sˆ   … àƒKØƒMØÓØƒMØÓÙ$°TÔ:€DÐ
Ó:Ø€L�#ÓØ€M�3ÓÙ°Ô5€HˆiÓ5Ù!&°tÔ!<€J�Ó<Ø€HˆdÓØ"+€M�<Ó+Ù',¸TÔ'BÐ�nÓBôr#   r&   ux   (?<![\w.])([+-])?\s*(?:â‚¹|rs\.?|inr|usd|\$|â‚¬|Â£)?\s*(-?\d{1,3}(?:,\d{3})*(?:\.\d{1,2})?|-?\d+(?:\.\d{1,2})?)(?![\w.])u0   (?:â‚¹|rs\.?|inr|usd|\$|â‚¬|Â£)\s*([\d,]+\.?\d*)z«(?i)(?:total\s+(?:money\s+)?(?:paid|spent|debit(?:s|ed)?|withdrawal(?:s)?|payments?\s+made|outflow)|(?:money|amount)\s+paid|total\s+debits?|sum\s+of\s+debits?)\s*[:\-]?\s*z¶(?i)(?:total\s+(?:money\s+)?(?:received|credited|credit(?:s)?|deposit(?:s)?|payments?\s+received|inflow)|(?:money|amount)\s+received|total\s+credits?|sum\s+of\s+credits?)\s*[:\-]?\s*u`   (?i)-\s*(?:â‚¹|rs\.?|\$|â‚¬|Â£)\s*([\d,]+\.?\d*)\s*\+\s*(?:â‚¹|rs\.?|\$|â‚¬|Â£)\s*([\d,]+\.?\d*)z;(?i)(\d+)\s+payments?\s+made.*?(\d+)\s+payments?\s+receivedc                ó†  — | €yt        | t        t        f«      rt        | «      S t        | «      j	                  «       }|r|dv ryd}|j                  d«      r&|j                  d«      rd}|dd j	                  «       }d	}t        j                  d
|«      }|r(|j                  d«      dv rd}||j                  «       d }|j                  dd«      j                  dd«      j                  dd«      j                  dd«      j                  dd«      }t        j                  dd|«      j	                  «       }|j                  d«      s|j                  d«      rd}|dd j	                  «       }n$|j                  d«      r|dd j	                  «       }	 t        |«      }|rt        |«       n|}||z  S # t        $ r Y yw xY w)zJParse currency amounts, including signed values ('- Rs.381.93', '+ $528').N>   õ   â€“õ   â€”Ú+Ú-õ   âˆ’FÚ(Ú)Té   éÿÿÿÿg      ð?u   ^([+-]|âˆ’)\s*>   rF   rG   g      ð¿Ú,r   u   â‚¹Ú$u   â‚¬ô   Â£z(?i)^(rs\.?|inr|usd|eur|gbp)\s*rF   rG   rE   )Ú
isinstanceÚintÚfloatr   ÚstripÚ
startswithÚendswithÚreÚmatchÚgroupÚendÚreplaceÚsubÚabsÚ
ValueError)ÚvalueÚtextÚnegÚsignÚsign_mÚnums         r$   Ú_parse_moneyrc   R   s£  € à€}ØÜ�%œ#œu˜Ô&Ü�U‹|ÐÜˆu‹:×ÑÓ€DÙ�4Ð:Ñ:Øð €CØ‡��sÔ §¡¨cÔ 2ØˆØ�A�bˆz×ÑÓ!ˆð €DÜ�X‰XÐ'¨Ó.€FÙØ�<‰<˜‹?˜lÑ*ØˆDØ�F—J‘J“L�NÐ#ˆØ�<‰<˜˜RÓ ×(Ñ(¨°Ó3×;Ñ;¸CÀÓD×LÑLÈUÐTVÓW×_Ñ_Ð`dÐfhÓi€DÜ�6‰6Ð4°b¸$Ó?×EÑEÓG€Dà‡��sÔ˜tŸ™¨uÔ5ØˆØ�A�Bˆx�~‰~Ó‰Ø	�‰˜Ô	Ø�A�Bˆx�~‰~ÓˆðÜ�D‹kˆÙŒs�3‹x‰i CˆØ�c‰zÐøÜò Ùðús   ÆF4 Æ4	G Æ?G c                ót  — | sy| dd }dx}}t         j                  |«      }t        j                  |«      }|rt        |j	                  d«      «      }|rt        |j	                  d«      «      }|�|€Ot
        j                  |«      }|r8|€t        |j	                  d«      «      }|€t        |j	                  d«      «      }|�t        |«      }|�t        |«      }t        j                  |«      }|rt        |j	                  d«      «      nd}|rt        |j	                  d«      «      nd}	|€|€y||||	ddœS )uÒ   Extract labeled money-in / money-out totals from statement text when present.

    Works across bank, card, and wallet statements â€” values always come from the PDF text,
    never from hardcoded amounts.
    Ni   rJ   é   Ústatement_header)Ú	money_outÚmoney_inÚpayments_madeÚpayments_receivedÚsource)	Ú_LABELED_OUT_REÚsearchÚ_LABELED_IN_RErc   rW   Ú_SIGNED_PAIR_REr[   Ú_PAYMENT_COUNT_RErP   )
r^   ÚheadÚpaidÚreceivedÚout_mÚin_mÚpairÚcountsÚpaid_nÚrecv_ns
             r$   Úparse_statement_header_totalsrz   z   s7  € ñ ØØ��ˆ;€DØÐ€Dˆ8ä×"Ñ" 4Ó(€EÜ× Ñ  Ó&€DÙÜ˜EŸK™K¨›NÓ+ˆÙÜ §
¡
¨1£Ó.ˆð €|�xÐ'Ü×%Ñ% dÓ+ˆÙØˆ|Ü# D§J¡J¨q£MÓ2�ØÐÜ'¨¯
©
°1«Ó6�àÐÜ�4‹yˆØÐÜ�x“=ˆä×%Ñ% dÓ+€FÙ%+ŒS�—‘˜a“Ô!°€FÙ%+ŒS�—‘˜a“Ô!°€FØ€|˜Ð(ØàØØØ#Ø$ñð r#   c                ób   — | j                  «       xs dj                  «       }t        |«      dk\  S )Nr   é(   )Úextract_textrR   Úlen)Úpager^   s     r$   Ú_page_has_textr€   ¨   s,   € Ø×ÑÓÒ% 2×,Ñ,Ó.€DÜˆt‹9˜‰?Ðr#   c                ó6  — t        j                  t        | «      «      5 }|j                  s
	 d d d «       yt	        d„ |j                  D «       «      }t        |j                  «      }|dk(  r
	 d d d «       y||k(  r
	 d d d «       y	 d d d «       y# 1 sw Y   y xY w)Nr   c              3  ó8   K  — | ]  }t        |«      sŒd –— Œ y­w©rJ   N)r€   )Ú.0Úps     r$   Ú	<genexpr>z%detect_source_type.<locals>.<genexpr>±   s   è ø€ ÐC¡I˜q´ÀÕ1Bœ¡Iùs   ‚“r   r   r
   r   )Ú
pdfplumberÚopenr   ÚpagesÚsumr~   )Úpdf_pathÚpdfÚ
text_pagesÚtotals       r$   Údetect_source_typer�   ­   s�   € Ü	�‰œ˜X›Ô	'¨3Ø�yŠyØ÷ 
(Ð	'ô ÑC C§I¢IÓCÓCˆ
Ü�C—I‘I“ˆØ˜Š?Ø÷ 
(Ð	'ð ˜ÒØ÷ 
(Ð	'ð ÷ 
(×	'Ñ	'ús   ŸB¶7BÁ6BÂBÂBc                ó‚   — t        j                  ddt        | xs d«      j                  «       j	                  «       «      S )Nú\s+Ú r   )rU   rZ   r   rR   Úlower)Úcells    r$   Ú_normalize_headerr•   º   s/   € Ü�6‰6�&˜#œs 4¢:¨2›×4Ñ4Ó6×<Ñ<Ó>Ó?Ð?r#   c                ó²  ‡— i }t        | «      D ]Å  \  }}t        |«      Š‰sŒt        ˆfd„dD «       «      s‰dv r||d<   Œ2t        ˆfd„dD «       «      s‰dv r||d<   ŒPt        ˆfd	„d
D «       «      r||d<   Œj‰dv sd‰v rd‰vr
d‰vr||d<   Œ€d‰v sd‰v sd‰v sd‰v r||d<   Œ–d‰v sd‰v sd‰v sd‰v r||d<   Œ¬t        ˆfd„dD «       «      sŒÁ||d<   ŒÇ |S )Nc              3  ó&   •K  — | ]  }|‰v –— Œ
 y ­wr;   r"   ©r„   ÚkÚhs     €r$   r†   z%_map_table_headers.<locals>.<genexpr>Å   s!   øè ø€ ð 
ñ�ð �ŒFñùó   ƒ)Ú
withdrawalÚwithdrawalsÚ	withdrawnr   z	dr amountz	money outzpaid outúpayment madez
money paidzamount paidzamount debited>   ÚdrÚwdlúwithdrawal amtr   c              3  ó&   •K  — | ]  }|‰v –— Œ
 y ­wr;   r"   r˜   s     €r$   r†   z%_map_table_headers.<locals>.<genexpr>Ï   s!   øè ø€ ð 
ñ�ð �ŒFñùr›   )
ÚdepositÚdepositsr   z	cr amountzmoney inzpaid inÚreceiptúpayment receivedúmoney receivedzamount credited>   Úcrr   c              3  ó&   •K  — | ]  }|‰v –— Œ
 y ­wr;   r"   r˜   s     €r$   r†   z%_map_table_headers.<locals>.<genexpr>Ø   s   øè ø€ ÐKÑ!J˜A��a”Ñ!Jùr›   )Úbalancezclosing balzrunning balr«   >   ÚamtrŽ   r]   r   r   r    r©   r   ú
value dateztxn dateÚpostingr   Úledgerza/czyour accountc              3  ó&   •K  — | ]  }|‰v –— Œ
 y ­wr;   r"   r˜   s     €r$   r†   z%_map_table_headers.<locals>.<genexpr>â   s!   øè ø€ ð 
ñ�ð �ŒFñùr›   )ÚdescÚ
particularÚ	narrationÚdetailsÚitemÚremarkÚtransactionznarration / particularsr   )Ú	enumerater•   Úany)Ú
header_rowÚmappingÚidxr”   rš   s       @r$   Ú_map_table_headersr½   ¾   s5  ø€ Ø €GÜ˜zÖ*‰	ˆˆTÜ˜dÓ#ˆÙØäó 
ñó
ô 
ð Ð1Ñ1Ø"ˆG�GÒäó 
ñó
ô 
ð �&‰[Ø #ˆG�HÒÜÓKÑ!JÓKÔKØ!$ˆG�IÒØÐ5Ñ5Ø˜‰M˜d¨!™m°¸A±à #ˆG�HÒØ�q‰[˜L¨AÑ-°¸q±ÀIÐQRÁNØ!ˆG�FŠOØ˜!‰^˜x¨1™}°¸±
¸nÐPQÑ>QØ!$ˆG�IÒÜó 
ñó
õ 
ð &)ˆG�MÒ"ðS +ðT €Nr#   r   ©r(   r^   Úheader_hintsc                ó:  ‡‡— | › d|dd › d|› �j                  «       Št        ˆfd„dD «       «      }t        ˆfd„dD «       «      }| j                  «       Št        ˆfd„d	D «       «      r|d
z  }d‰v sd‰v sd‰v r|dz  }|d
k\  r||kD  ry|dk\  r||k\  ry|dk\  ryy)z6Heuristic: bank statement vs balance sheet vs unknown.Ú
Ni@  c              3  ó*   •K  — | ]
  }|‰v rd –— Œ y­wrƒ   r"   ©r„   r™   Úblobs     €r$   r†   z'detect_document_kind.<locals>.<genexpr>ö   s&   øè ø€ ð  ñ
ˆAð: �‰9ô= 	
ñ
ùó   ƒ)zbank statementzaccount statementústatement of accountzopening balanceúclosing balancerœ   r¤   r³   ztransaction dater­   zavailable balanceza/c nozaccount numberÚifscÚupiÚneftÚimpsÚchequeÚchqÚpaytmÚphonepeÚgpayz
google payútotal money paidztotal money receivedzpayments madeúpassbook paymentsc              3  ó*   •K  — | ]
  }|‰v rd –— Œ y­wrƒ   r"   rÃ   s     €r$   r†   z'detect_document_kind.<locals>.<genexpr>  s&   øè ø€ ð ñ

ˆAð �‰9ô 	
ñ

ùrÅ   )	zbalance sheetzstatement of financial positionztotal assetsztotal liabilitieszshareholders' equityzstockholders' equityzretained earningszcurrent assetsznon-current assetsc              3  ó&   •K  — | ]  }|‰v –— Œ
 y ­wr;   r"   )r„   r™   Únames     €r$   r†   z'detect_document_kind.<locals>.<genexpr>(  s!   øè ø€ ð ñ
ˆAð 	
ˆTŒ	ñ
ùr›   )	ÚbankÚ	statementÚpassbookÚtxnr·   rÉ   ÚwalletÚcardr   re   r   Úbalancesheetzbalance-sheeté   r   rJ   r   )r“   rŠ   r¹   )r(   r^   r¿   Ú	bank_hitsÚ
sheet_hitsrÄ   rÕ   s        @@r$   Údetect_document_kindrà   í   sÝ   ù€ ð ˆZ�r˜$˜u ˜+˜ b¨¨Ð7×=Ñ=Ó?€Däó  ñ
ó ó  €IôB ó ñ

óó €Jð  �>‰>Ó€DÜ
ó ñ
óô ð 	�Q‰ˆ	Ø˜$Ñ .°DÑ"8¸OÈtÑ<SØ�a‰ˆ
à�A‚~˜) jÒ0ØØ�Q‚˜:¨Ò2Øà�A‚~ØØr#   c                ó  ‡— | › d|› �j                  «       Št        j                  d‰«      ryt        j                  d‰«      ryd}d}t        ˆfd„|D «       «      ryt        ˆfd	„|D «       «      ryt        j                  d
‰«      rd‰vryy)z?Return 'out', 'in', or None from Paytm/UPI/bank narration cues.r’   zA\b(?:neft|imps|rtgs)\s*cr\b|\bupi[-\s]?cr\b|\bcredit\s+interest\bÚinz+\b(?:neft|imps|rtgs)\s*dr\b|\bupi[-\s]?dr\bÚout)	zpaid toz
money sentztransferred tozsent tor   rŸ   zrecharge ofÚwithdrawzpaid via)zreceived fromr¨   r¤   r§   ÚrefundÚsalaryc              3  ó&   •K  — | ]  }|‰v –— Œ
 y ­wr;   r"   rÃ   s     €r$   r†   z-_infer_direction_from_text.<locals>.<genexpr>M  s   øè ø€ Ð
'™h˜ˆ1�Œ9™hùr›   c              3  ó&   •K  — | ]  }|‰v –— Œ
 y ­wr;   r"   rÃ   s     €r$   r†   z-_infer_direction_from_text.<locals>.<genexpr>O  s   øè ø€ Ð
&™g˜ˆ1�Œ9™gùr›   z\bcredits?\bzcredit cardN)r“   rU   rm   r¹   )r   r   Úout_keysÚin_keysrÄ   s       @r$   Ú_infer_direction_from_textrë   =  sŽ   ø€ àˆ]˜!˜C˜5Ð!×'Ñ'Ó)€Dä	‡y�yÐUÐW[Ô\ØÜ	‡y�yÐ?ÀÔFØð€Hð€Gô Ó
'™hÓ
'Ô'ØÜ
Ó
&™gÓ
&Ô&Øä	‡y�y� $Ô'¨MÀÑ,EØØr#   zq(?i)^(?:(?P<ref>\d{10,18})\s+)?(?P<vdate>\d{2}/\d{2}/\d{2})\s+(?P<amt>[\d,]+\.\d{2})\s+(?P<bal>[\d,]+\.\d{2})\s*$z^\d{2}/\d{2}/\d{2}\bg    „×‡Ac                óz   — | €yt        t        | «      «      }|dk  ry|t        kD  ry|dk\  r|t        |«      k(  ryy)zCReject ID-like integers (account nos, UPI RRNs) mistaken for money.Fr   g    eÍÍAT)r[   rQ   Ú_PLAUSIBLE_TXN_MAXrP   )r   Úabs_amts     r$   Ú_is_plausible_txn_amountrï   c  sF   € à€~ØÜ”%˜“-Ó €GØ�!‚|ØØÔ#Ò#Øà�#‚~˜'¤S¨£\Ò1ØØr#   c                óè  ‡‡— | sg S | j                  «       Št        ˆfd„dD «       «      sg S | j                  «       D �cg c]#  }|j                  «       sŒ|j                  «       ‘Œ% }}g }g }d}t	        «       }d}d}|D �]j  }|j                  «       Št        ˆfd„|D «       «      rŒ)t        j                  d|j                  dd	«      «      rŒPt        j                  |«      }	|	�rˆt        |	j                  d
«      «      }
t        |	j                  d«      «      }|	j                  d«      }|
�|�t        |
«      sg }d}ŒÁdj                  |«      j                  «       }g }t        j                  dd	|«      j                  «       }t        j                  dd|«      }d}|�5t        ||
z
  |z
  «      dk  }t        ||
z   |z
  «      dk  }|r|sd}n|r|sd}|€t!        ||«      xs d}|› d|
d›d|d›d|dd › �j                  «       }||v r|}d}�Œ“|j#                  |«       |j%                  t'        |xs d|dk(  r|
nd|dk(  r|
ndd||› d|› �j                  d«      ¬«      «       |}d}�Œð|rt(        j                  |«      rd}|g}�Œt(        j                  |«      r|g}�Œ(|r&t+        |«      dkD  r|dd }|j%                  |«       �ŒPt        j,                  d|«      s�Œh|g}�Œm |S c c}w )zGParse HDFC-style multi-line narrations ending in `date amount balance`.c              3  ó&   •K  — | ]  }|‰v –— Œ
 y ­wr;   r"   ©r„   r™   Úlows     €r$   r†   z5_extract_rows_from_hdfc_style_text.<locals>.<genexpr>x  s!   øè ø€ ð 
ñ
ˆAð 	
ˆSŒñ
ùr›   )r¢   rÇ   rÆ   zchq./refzvalue dtúdeposit amtNF)úpage z	hdfc bankzstatement ofz--------zdate narrationrô   úfor any queriesz
**continuezaccount branchújoint holdersÚ
nominationÚcurrencyúcust idzod limitzbranch codezproduct codez	rtgs/neftza/c openzstatement fromÚaddresszphone noÚemailzcity :zstate :c              3  ó@   •K  — | ]  }‰j                  |«      –— Œ y ­wr;   )rS   )r„   r…   Úlow_lns     €r$   r†   z5_extract_rows_from_hdfc_style_text.<locals>.<genexpr>«  s   øè ø€ Ð;©]¨ˆv× Ñ  ×#©]ùs   ƒz-+r’   r   r¬   ÚbalÚvdateTz^\d{2}/\d{2}/\d{2}\s+r‘   gš™™™™™©?rã   râ   Ú|z.2féP   ÚTransactionú | z |©r   r   r   r   r   r   é   iúÿÿÿz/(?i)\b(?:upi|neft|imps|rtgs|ach|nach|pos|atm)\b)r“   r¹   Ú
splitlinesrR   ÚsetrU   Ú	fullmatchrY   Ú_HDFC_AMT_BAL_RErV   rc   rW   rï   ÚjoinrZ   r[   rë   ÚaddÚappendr   Ú_HDFC_DATE_START_REr~   rm   )r^   ÚlnÚlinesr0   Únarr_bufÚprev_balÚseenÚ
skip_wrapsÚskip_prefixesÚmr   rÿ   r   r³   Ú	directionÚas_outÚas_inÚkeyró   rþ   s                     @@r$   Ú"_extract_rows_from_hdfc_style_textr  r  s  ù€ áØˆ	à
�*‰*‹,€CÜó 
ñ
ó
ô 
ð ˆ	à"&§/¡/Ô"3ÓBÑ"3˜B°r·x±xµzˆR�X‰X�ZÐ"3€EÐBØ!€DØ€HØ!€HÜ“U€Dð €Jð€Mô6 ˆØ—‘“ˆÜÓ;©]Ó;Ô;ØÜ�<‰<˜˜rŸz™z¨#¨rÓ2Ô3Øä×"Ñ" 2Ó&ˆÚÜ! !§'¡'¨%£.Ó1ˆFÜ˜qŸw™w u›~Ó.ˆCØ—G‘G˜GÓ$ˆEØˆ~  Ô4LÈVÔ4TØ�Ø!�
ØàŸ™ Ó*×0Ñ0Ó2ˆIØˆHäŸ™Ð7¸¸YÓG×MÑMÓOˆIÜŸ™˜v s¨IÓ6ˆIà$(ˆIØÐ#Ü˜h¨Ñ/°3Ñ6Ó7¸$Ñ>�Ü˜X¨Ñ.°#Ñ5Ó6¸Ñ=�Ù¡%Ø %‘IÙ¡6Ø $�IØÐ Ü6°yÀ"ÓEÒNÈ�	à�G˜1˜V C˜L¨¨#¨c¨°!°I¸c¸r°NÐ3CÐD×JÑJÓLˆCØ�d‰{Ø�Ø!�
ÙØ�H‰H�SŒMà�K‰KÜØ )Ò :¨]Ø$-°Ò$6™&¸DØ%.°$Ò%6™6¸DØØØ$˜+ S¨¨Ð-×3Ñ3°DÓ9ôô	ð ˆHØˆJÙáÜ"×(Ñ(¨Ô,Ø"�
Ø˜4�áô ×$Ñ$ RÔ(Ø�tŠHÙÜ�8‹}˜rÒ!Ø# B C˜=�Ø�O‰O˜BÖÜ�Y‰YÐIÈ2ÖNØ�tŠHðM ðP €KùòY Cs   ¿K/ÁK/c           	     óX  ‡ ‡‡— dˆ ˆfd„}t         |d«      xs d«      j                  «       }t         |d«      xs d«      j                  «       xs d }t         |d«      xs d«      j                  «       xs d }t         |d«      «      }t         |d«      «      }t         |d«      «      }d	j                  d
„ ‰ D «       «      }	|€¦|€¤|€¢dj                  d„ ‰ D «       «      }
g }t        j                  |
«      D ]g  }|j                  d«      xs d}t        |j                  d«      «      }|€Œ5|dk(  rt        |«       }n|dk(  rt        |«      }|j                  |«       Œi |r|d   }ny |�R|€P|€Nt        ||	«      }|dk  s|dk(  rt        |«      }d }n*|dkD  r|dk(  rt        |«      }d }n|dk  rt        |«      }d }|s|xs d}|j                  «       Št        ˆfd„dD «       «      ry t        j                  d|	t        j                  «      r|€|€y t        |||||||	¬«      S )Nc                óR   •— ‰j                  | «      }|�|t        ‰«      k\  ry ‰|   S r;   )Úgetr~   )r  r¼   Úcellsr»   s     €€r$   r  z_row_from_cells.<locals>.getõ  s.   ø€ Ø�k‰k˜#ÓˆØˆ;˜#¤ U£Ò+ØØ�S‰zÐr#   r   r   r   r   r   r   r   r  c              3  ó8   K  — | ]  }|€Œt        |«      –— Œ y ­wr;   ©r   ©r„   Úcs     r$   r†   z"_row_from_cells.<locals>.<genexpr>  s   è ø€ Ð<¡U ¨a©m”S˜—V¡Uùó   ‚Šr’   c              3  ó8   K  — | ]  }|sŒt        |«      –— Œ y ­wr;   r!  r"  s     r$   r†   z"_row_from_cells.<locals>.<genexpr>  s   è ø€ Ð5©% Q²1œ#˜aŸ&©%ùr$  rJ   re   rF   rE   rK   r   rã   râ   ú	Line itemc              3  ó&   •K  — | ]  }|‰v –— Œ
 y ­wr;   r"   )r„   r™   Údesc_ls     €r$   r†   z"_row_from_cells.<locals>.<genexpr>(  s!   øè ø€ ð ñ
ˆAð 	
ˆVŒñ
ùr›   )rÒ   rŸ   r§   rÑ   rõ   rö   z\(\d+\s+payments?\))r   r   r   r   r   r   r   )r  r   r?   r   )r   rR   rc   r  Ú	_MONEY_REÚfinditerrW   r[   r  rë   r“   r¹   rU   rm   Ú
IGNORECASEr   )r  r»   r  r   r   r   r   r   r   r   ÚjoinedÚmoneyr  Úsign_prefixrb   r  r(  s   ``              @r$   Ú_row_from_cellsr/  ô  s5  ú€ öô ‘c˜-Ó(Ò.¨BÓ/×5Ñ5Ó7€KÜ‘#�i“.Ò& BÓ'×-Ñ-Ó/Ò7°4€GÜ‰s�6‹{Ò ˜bÓ!×'Ñ'Ó)Ò1¨T€DÜ™˜W›Ó&€EÜ™#˜h›-Ó(€FÜ™#˜h›-Ó(€FØ
�*‰*Ñ<¡UÓ<Ó
<€Cà€~˜%˜-¨F¨Nà—‘Ñ5©%Ó5Ó5ˆØˆÜ×#Ñ# FÖ+ˆAØŸ'™' !›*Ò*¨ˆKÜ˜qŸw™w q›zÓ*ˆCØˆ{ØØ˜cÒ!Ü˜3“x�i‘Ø Ò#Ü˜#“h�Ø�L‰L˜Õð ,ñ Ø˜2‘Y‰Fàð Ð˜e˜m°°Ü.¨{¸CÓ@ˆ	Ø�AŠ:˜ eÒ+Ü˜“KˆEØ‰FØ�aŠZ˜I¨Ò-Ü˜“[ˆFØ‰FØ�aŠZÜ˜“KˆEØˆFáØÒ, ˆð ×ÑÓ €FÜ
ó ñ
óô ð Ü	‡y�yÐ'¨¬b¯m©mÔ<ÀÀÐSYÐSaàäØØØØØØØôð r#   c                ó°   — d}i }t        dt        | «      «      }t        |«      D ],  }t        | |   «      }t        |«      t        |«      kD  sŒ)|}|}Œ. ||fS )zTLocate the best header row in a pdfplumber table (title rows may sit above headers).r   é   )Úminr~   Úranger½   )ÚtableÚbest_iÚbest_mapÚscanÚir»   s         r$   Ú_find_table_header_indexr9  ?  s_   € à€FØ!€HÜˆq”#�e“*Ó€DÜ�4Ž[ˆÜ$ U¨1¡XÓ.ˆÜˆw‹<œ#˜h›-Ó'ØˆHØ‰Fð	 ð
 �8ÐÐr#   éà.  ©Ú	max_charsc               óò  — g }t        j                  t        | «      «      5 }t        |j                  d¬«      D ]A  \  }}|j                  «       xs dj                  «       }|sŒ+|j                  d|› d|› �«       ŒC 	 ddd«       dj                  |«      j                  «       }t        |«      |kD  r8|dz  }||z
  d	z
  }	|d| j                  «       d
z   ||	 d j                  «       z   S |S # 1 sw Y   ŒpxY w)z:Pull readable text from the PDF pages for the LLM to read.rJ   )Ústartr   z	--- Page z ---
Nú

re   r|   u"   

â€¦[middle pages truncated]â€¦

)r‡   rˆ   r   r¸   r‰   r}   rR   r  r  r~   ÚrstripÚlstrip)
r‹   r<  ÚbitsrŒ   r8  r   Ú	page_textr^   rq   Útails
             r$   Úextract_document_textrE  L  sð   € à€DÜ	�‰œ˜X›Ô	'¨3Ü  §¡°!×4‰GˆAˆtØ×*Ñ*Ó,Ò2°×9Ñ9Ó;ˆIÚØ—‘˜i¨ s¨&°°Ð<Õ=ñ 5÷ 
(ð
 �;‰;�tÓ×"Ñ"Ó$€DÜ
ˆ4ƒy�9Òà˜A‰~ˆØ˜4Ñ "Ñ$ˆØ�E�Tˆ{×!Ñ!Ó#Ð&NÑNÐQUÐW[ÐV[ÐV\ÐQ]×QdÑQdÓQfÑfÐfØ€K÷ 
(Ð	'ús   ¡AC-Á$C-Ã-C6c                óf  ‡— g }g }t        «       }t        j                  t        | «      «      5 }|j                  D �]n  }|j                  «       xs dj                  «       }|r|j                  |«       |j                  «       xs g }|D �]  }|rt        |«      dk  rŒt        |«      \  }	}
|
r|	dz   nd}|
s8dt        dt        |d   «      dz
  «      dœ}
t        |d   «      dk\  rdddddœ}
d}||d  D ]¯  }|rt        d	„ |D «       «      rŒt        |«      }|rt        |«      d
k\  rŒ4t        t        |«      |
«      }|sŒLt!        j"                  dd|j$                  «      j                  «       j'                  «       }||v rŒŽ|j)                  |«       |j                  |«       Œ± �Œ �Œq 	 d d d «       dj+                  |«      }t        |«      dk  r&|r$t-        |«      }t        |«      t        |«      kD  r|}t        |«      dk  r&|r$t/        |«      }t        |«      t        |«      kD  r|}|�sf|�rc|j1                  «       D �]O  }|j                  «       }t        |«      dk  rŒ#|j'                  «       Št3        ˆfd„dD «       «      rŒHt        t!        j4                  d|«      «      }|xs: t6        j5                  |«      D �cg c]  }d|j9                  d
«      xs dv r|‘Œ c}}|sŒ¨|d   }t;        |j9                  d«      xs d|j9                  d
«      xs dz   «      }|€t;        |j9                  d
«      «      }t=        |«      s�Œ
t6        j#                  d|«      j                  d«      }|j                  t?        |xs d||¬«      «       �ŒR |d d }||fS # 1 sw Y   �ŒõxY wc c}w )Nr   rJ   r   )r   r   é   rÝ   r1  )r   r   r   r   c              3  ó`   K  — | ]&  }|d u xs t        |«      j                  «       dk(  –— Œ( y ­w)Nr   )r   rR   r"  s     r$   r†   z)extract_digital_tables.<locals>.<genexpr>{  s/   è ø€ Ð)]ÑU\ÐPQ¨!¨t¨)Ò*K´s¸1³v·|±|³~ÈÑ7KÓ*KÑU\ùs   ‚,.re   r‘   r’   r?  é   c              3  ó&   •K  — | ]  }|‰v –— Œ
 y ­wr;   r"   rò   s     €r$   r†   z)extract_digital_tables.<locals>.<genexpr>ž  s!   øè ø€ ð ñ�Að �S”ñùr›   )z
account norú   ÚphoneÚmicrrÈ   zpin coder÷   zpage nouU   (?i)([+-])?\s*(?:â‚¹|rs\.?|inr)\s*(-?\d{1,3}(?:,\d{3})*(?:\.\d{1,2})?|-?\d+\.\d{1,2})Ú.rK   õ
    -â€“â€”|	r&  ©r   r   r   r:  ) r  r‡   rˆ   r   r‰   r}   rR   r  Úextract_tablesr~   r9  ÚmaxÚallr½   r/  r@   rU   rZ   r   r“   r  r  r  Ú!_extract_rows_from_statement_textr  r¹   r*  r)  rW   rc   rï   r   )r‹   r0   Ú	text_bitsÚseen_rawrŒ   r   rC  Útablesr4  Úheader_ir»   r>  Úraw_rowÚrow_mapÚparsedr  Ú	full_textÚ	hdfc_rowsÚ	text_rowsÚlineÚcur_matchesr  r-  r   r±   Úpreviewró   s                             @r$   Úextract_digital_tablesra  ]  s„  ø€ Ø!€DØ€IÜ›€Hä	�‰œ˜X›Ô	'¨3Ø—I•IˆDØ×*Ñ*Ó,Ò2°×9Ñ9Ó;ˆIÙØ× Ñ  Ô+à×(Ñ(Ó*Ò0¨bˆFÜ�Ù¤ E£
¨Q¢ØÜ$<¸UÓ$CÑ!�˜'Ù(/˜ 1š°Q�Ùà./¼3¸qÄ#ÀeÈAÁhÃ-ÐRSÑBSÓ;TÑU�Gä˜5 ™8“}¨Ò)à$%Ø+,Ø'(Ø&'ñ	#˜ð �EØ$ U V›}�GÙ"¤cÑ)]ÑU\Ó)]Ô&]Ø ä0°Ó9�GÙ¤3 w£<°1Ò#4Ø Ü,¬T°'«]¸GÓD�FÙ!Ø ÜŸ&™& ¨¨f¯j©jÓ9×?Ñ?ÓA×GÑGÓI�CØ˜h‘Ø Ø—L‘L Ô%Ø—K‘K Õ'ò  -ò#  ñ ÷ 
(ðP —‘˜IÓ&€Iä
ˆ4ƒy�2‚~™)Ü6°yÓAˆ	Üˆy‹>œC ›IÒ%ØˆDô ˆ4ƒy�2‚~™)Ü5°iÓ@ˆ	Üˆy‹>œC ›IÒ%ØˆDò ’IØ×(Ñ(×*ˆDØ—:‘:“<ˆDÜ�4‹y˜1Š}ØØ—*‘*“,ˆCÜó ñóô ð äÜ—‘ØlØóóˆKð  ò ä"×+Ñ+¨DÔ1ó$á1�AØ˜1Ÿ7™7 1›:Ò+¨Ñ,ò Ø1ñ$ˆEñ
 ØØ�b‘	ˆAÜ! 1§7¡7¨1£:Ò#3°¸¿¹À»
Ò8HÀbÑ"IÓJˆFØˆ~Ü% a§g¡g¨a£jÓ1�Ü+¨FÔ3ÙÜ—=‘=  TÓ*×0Ñ0°Ó?ˆDØ�K‰KÜØ $Ò 3¨Ø!ØôöðE +ðT ˜˜Ð€GØ�ˆ=Ð÷E 
(Ñ	'üòV$s   ®E?N!Ë N.Î!N+c                óî  ‡— g }| j                  «       D �cg c]#  }|j                  «       sŒ|j                  «       ‘Œ% }}d}g }|D �]  }|j                  «       Š‰j                  d«      s"‰j                  d«      s‰j                  d«      r|r|j	                  |«       d}Œ]t        j                  d|«      s%t        j                  d|t
        j                  «      r|r|j	                  |«       |}Œ®|r|› d|› �}t        ˆfd„d	D «       «      s&t        j                  d
|t
        j                  «      sŒñ|sŒô|j	                  |«       d}�Œ	 |r|j	                  |«       t        «       }|D �]}  }t        j                  d|j                  «       «      }|st        j                  d|«      }|sŒCt        |j                  d«      «      }	|	€Œ`t        |	«      }	|j                  d«      }
|d|j                  «        j                  «       }d}t        j                  d|t
        j                  «      }|r2|j                  d«      }||j                  «       d j                  «       }|
dk(  rdnd}t!        |«      }|r|}t        j"                  dd|«      j                  «       }||v r�Œ;|j%                  |«       |j	                  t'        |xs d|dk(  r|	nd|dk(  r|	ndd||¬«      «       �Œ€ |S c c}w )zAParse statement lines from plain text when tables are fragmented.r   rõ   rö   znote:z^\d{1,2}\s+[A-Za-z]{3}\bz^\d{1,2}:\d{2}\s*(AM|PM)\br’   c              3  ó&   •K  — | ]  }|‰v –— Œ
 y ­wr;   r"   rò   s     €r$   r†   z4_extract_rows_from_statement_text.<locals>.<genexpr>Ý  s   øè ø€ ð 
á^�ð �ŒHÙ^ùr›   )zupi refzref noztxn idztransaction idrÊ   rË   Úrtgsu    [+-]\s*(?:â‚¹|rs\.?|\$)\s*[\d,]+uC   (?i)(?P<signed>[+-])\s*(?:â‚¹|rs\.?|\$)\s*(?P<amt>[\d,]+\.?\d*)\s*$u?   (?i)(?P<signed>[+-])\s*(?:â‚¹|rs\.?|\$)\s*(?P<amt>[\d,]+\.?\d*)r¬   NÚsignedz9^(\d{1,2}\s+[A-Za-z]{3}(?:\s+\d{1,2}:\d{2}\s*(?:AM|PM))?)rJ   rF   rã   râ   r‘   r  r  )r  rR   r“   rS   r  rU   rV   ÚIr¹   rm   r  rc   rW   r[   r>  rX   rë   rZ   r  r   )r^   r0   r  r  ÚbufÚ
candidatesr  Úcandr  r   re  Úbodyr   Údmr  Únarr_dirr  ró   s                    @r$   rS  rS  Ç  s´  ø€ à!€Dà"&§/¡/Ô"3ÓBÑ"3˜B°r·x±xµzˆR�X‰X�ZÐ"3€EÐBà
€CØ€JÜˆØ�h‰h‹jˆØ�>‰>˜'Ô" c§n¡nÐ5FÔ&GÈ3Ï>É>ÐZaÔKbÙØ×!Ñ! #Ô&Ø�ØÜ�8‰8Ð/°Ô4¼¿¹ÐA^Ð`bÔdf×dhÑdhÔ8iÙØ×!Ñ! #Ô&ØˆCØÙØ�E˜˜2˜$�-ˆCÜó 
á^ó
ô 
ô �Y‰YÐ:¸BÄÇÁÕEÚØ×!Ñ! #Ô&Ø’ð) ñ* Ø×Ñ˜#Ôä“U€DÜˆÜ�I‰IØRØ�J‰J‹Ló
ˆñ Ü—	‘	ØRØóˆAñ ØÜ˜aŸg™g e›nÓ-ˆØˆ>ØÜ�V“ˆØ—‘˜Ó"ˆØ�K�a—g‘g“iÐ ×&Ñ&Ó(ˆØˆÜ�X‰XÐRÐTXÔZ\×Z^ÑZ^Ó_ˆÙØ—8‘8˜A“;ˆDØ˜Ÿ™›˜
Ð#×)Ñ)Ó+ˆDØ# sš]‘E°ˆ	Ü-¨dÓ3ˆÙØ ˆIÜ�f‰f�V˜S $Ó'×-Ñ-Ó/ˆØ�$‰;ÙØ�‰�ŒØ�‰ÜØ Ò1 MØ )¨UÒ 2‘f¸Ø!*¨dÒ!2‘v¸ØØØôö		
ð? ðR €KùòM Cs
   –K2¬K2c           	     ó  — g }	 ddl m} 	 ddl}	  |t	        | «      dd|¬	«      }g }g }|D �]   }		 |j                  |	«      xs d}
|
j                  «       }
|
r|j                  |
«       |
j                  «       D ]Ñ  }|j                  «       }t        t        j                  |«      «      }|sŒ4|d   }t        |j                  d«      xs d|j                  d«      xs dz   «      }|€t        |j                  d«      «      }|€ŒŒt        j                  d|«      j                  d«      }|j                  t!        |xs d||¬«      «       ŒÓ �Œ# |j                  d«       t#        |«      |k\  r|j                  d|› d�«       |dj%                  |«      dd |fS # t        $ r	 g ddgfcY S w xY w# t        $ r	 g ddgfcY S w xY w# t
        $ r}g dd
|› �gfcY d}~S d}~ww xY w# t
        $ r}|j                  d|› �«       Y d}~�ŒÛd}~ww xY w)z;OCR draft for scanned PDFs. Never trusted for calculations.r   )Úconvert_from_pathr   z¡OCR packages not installed. Install: pip install pdf2image pytesseract and system packages poppler-utils + tesseract-ocr. Or enter numbers manually after upload.Nzapytesseract not installed. Run: pip install pytesseract and install system package tesseract-ocr.éÈ   rJ   )ÚdpiÚ
first_pageÚ	last_pagez6Could not render PDF for OCR (is poppler installed?): zTesseract failed: rK   re   rN  zOCR linerO  zLOCR output is a draft only. Confirm or edit every amount before calculating.zOCR limited to first z pages for speed.r?  r:  )Ú	pdf2imagern  ÚImportErrorÚpytesseractr   Ú	ExceptionÚimage_to_stringr  rR   r  r@   r)  r*  rc   rW   rZ   r   r~   r  )r‹   Ú	max_pagesr3   rn  ru  ÚimagesÚexcrT  r0   Úimgr^   r^  r-  r  r   r±   s                   r$   Úextract_ocr_draftr|    s:  € à€Hð
Ý/ð
ÛðXÙ"¤3 x£=°cÀaÐS\Ô]ˆð €IØ!€DÜˆð	Ø×.Ñ.¨sÓ3Ò9°rˆDð �z‰z‹|ˆÙØ×Ñ˜TÔ"Ø—O‘OÖ%ˆDØ—:‘:“<ˆDÜœ×+Ñ+¨DÓ1Ó2ˆEÙØØ�b‘	ˆAÜ! 1§7¡7¨1£:Ò#3°¸¿¹À»
Ò8HÀbÑ"IÓJˆFØˆ~Ü% a§g¡g¨a£jÓ1�Øˆ~ØÜ—=‘=  TÓ*×0Ñ0°Ó?ˆDØ�K‰Kœ°Ò1C¸ÈFÐX\Ô]Õ^ò &ð ð. ‡O�OØVôô ˆ6ƒ{�iÒØ�‰Ð/°	¨{Ð:KÐLÔMà�—‘˜YÓ'¨¨Ð/°Ð9Ð9øôg ò 
Ø�2ð6ð
ð 
ò 	
ð
ûô ò 
Ø�2ð8ð
ð 
ò 	
ð
ûô ò XØ�2ÐPÐQTÐPUÐVÐWÐWÕWûðXûô ò 	Ø�O‰OÐ0°°Ð6Ô7Ýûð	úsV   „F ‹F/ �G °G#ÆF,Æ+F,Æ/GÇ GÇ	G ÇGÇG ÇG Ç#	HÇ,HÈHc                óô  — t        t        j                  «       «      }|xs | j                  }t	        | «      }g }g }d}d}|dv r$t        | «      \  }}|dk(  r|j                  d«       |dk(  s|dk(  rC|sAt        | «      \  }	}
}|j                  |«       |	r	|	}d}|s|
}n|dk(  r|j                  d«       |d	k(  r|j                  d
«       d}|dv rt        | d¬«      }|s|}t        ||xs |dj                  d„ |d d D «       «      ¬«      }t        |xs |«      xs i }|r|dk(  rd}|j                  d«       |dk(  r|j                  d«       nS|dk(  rNt        |«      dk\  r@t        d„ |D «       «      }|t        dt        |«      dz  «      k\  rd}|j                  d«       |dk(  xr t!        |«      xr | }| }|sd}d}|s|r|dk(  xr | }| }t#        |||||||xs |d d |xs |||||¬«      }|S )Nr   F>   r   r
   r   zDPDF has mixed text/image pages. Prefer confirming extracted amounts.r   TzKNo amounts extracted. Enter line items manually, then confirm to calculate.r   zPDF appears empty.iÀ]  r;  r’   c              3  óB   K  — | ]  }|j                   xs d dd –— Œ y­w)r   Nr|   )r   ©r„   Úrs     r$   r†   zextract_pdf.<locals>.<genexpr>w  s!   è ø€ ÐLÁ)¸Q˜qŸ}™}Ò2°°C°RÔ8Á)ùs   ‚é   r¾   r   r   zCDetected wallet/UPI statement totals (money paid / money received).zpDetected as a bank / account statement. Totals use money-in vs money-out (not balance-sheet assets/liabilities).é   c              3  ó:   K  — | ]  }|j                   sŒd –— Œ y­wrƒ   )r   r  s     r$   r†   zextract_pdf.<locals>.<genexpr>…  s   è ø€ Ð.™t˜! q§v£v”A™tùs   ‚”rG  zGTreating this PDF as a transaction statement based on dated line items.r
   i¸  )r'   r(   r*   r,   r-   r0   r1   r2   r3   r6   r8   r9   )r   ÚuuidÚuuid4rÕ   r�   ra  r  r|  ÚextendrE  rà   r  rz   r~   rŠ   rQ  r+   r&   )r‹   r(   r'   rÕ   rk   r3   r0   r`  r6   Úocr_rowsÚocr_previewÚocr_warningsr2   Úkindr9   Údatedr,   r-   Úresults                      r$   Úextract_pdfr�  O  sc  € Ü”—‘“Ó€FØÒ$�x—}‘}€DÜ Ó)€FØ€HØ!€DØ€GØ€HàÐ%Ñ%Ü.¨xÓ8‰ˆˆgØ�WÒØ�O‰OÐbÔcà�Ò˜v¨Ò0¹Ü.?ÀÓ.IÑ+ˆ�+˜|Ø�‰˜Ô%ÙØˆDØˆHÙØ%‘Ø�yÒ Ø�O‰OØ]ôð �ÒØ�‰Ð,Ô-ð €MØÐ%Ñ%Ü-¨hÀ%ÔHˆÙØˆäØØÒ%˜gØ—X‘XÑLÀ$ÀsÈÁ)ÓLÓLô€Dô
 5°]Ò5MÀgÓNÒTÐRTÐÙ˜D IÒ-ØˆØ�‰ØQô	
ð ÐÒØ�‰ð6õ	
ð 
�Ò	œs 4›y¨BšÜÑ.™tÓ.Ó.ˆØ”C˜œ3˜t›9¨™>Ó*Ò*Ø#ˆDØ�O‰OØYôð
 ˜	Ñ!ÒA¤d¨4£jÒA¸°\€GØ�K€MáØˆØˆñ Ñ$Ø˜IÑ%Ò6¨h¨,ˆØ#˜ˆäØØØØØ#ØØÒ. °°Ð6Ø#Ò. wØØØØ)ô€Fð €Mr#   )r]   r   r?   r   )r^   r   r?   z$dict[str, float | int | None] | None)r?   r+   )r‹   r   r?   r)   )r”   r   r?   r   )rº   ú	list[Any]r?   údict[str, int])r(   r   r^   r   r¿   r   r?   r7   )r   )r   r   r   r   r?   r   )r   r   r?   r+   )r^   r   r?   r/   )r  rŽ  r»   r�  r?   zExtractedRow | None)r4  zlist[list[Any]]r?   ztuple[int, dict[str, int]])r‹   r   r<  rP   r?   r   )r‹   r   r?   ztuple[list[ExtractedRow], str])rG  )r‹   r   rx  rP   r?   z)tuple[list[ExtractedRow], str, list[str]]r;   )r‹   r   r(   r   r?   r&   )/Ú__doc__Ú
__future__r   rU   r„  Údataclassesr   r   r   Úpathlibr   Útypingr   r	   r‡   r)   r7   r   r&   Úcompiler+  r)  Ú_CUR_AMTrl   rn   ro   rp   rc   rz   r€   r�   r•   r½   rà   rë   r
  r  rí   rï   r  r/  r9  rE  ra  rS  r|  r�  r"   r#   r$   Ú<module>r—     sÊ  ðñõ #ã 	Û ß 0Ñ 0Ý ß ã àÐ;Ñ<€
ØÐCÑD€ð ÷ð ó ðð ÷ð ó ðð( ˆB�J‰JØØ‡M�Mó€	ð ?€Ø�"—*‘*ð7à9AñBó€ð
 �—‘ð9à;CñDó€ð �"—*‘*Øgó€ð �B—J‘JØBóÐ ó
%óP+ó\ó

ó@ó,ðb ØØñ	MàðMð ðMð ð	Mð
 óMô`ð8 �2—:‘:ð"óÐ ð !�b—j‘jÐ!8Ó9Ð Ø!Ð óóóDHóV
ð ?Dõ ó"góTJôZ8:õvXr#   