
    exit                       U d dl mZmZmZmZmZm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mZ d dlmZmZmZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlm Z  d Z!dZ"i Z#ee$ee%ef   f   e&d<    ejN                         Z(de$de$dede$fdZ)de$dee   fdZ*de$defdZ+ G d de      Z,dede$de$defdZ-dede$de$de,dedefdZ.ded ededefd!Z/ded ededefd"Z0ded ededefd#Z1y)$    )AnyDictListOptionalTupleUnion)datetimeN)HTTPExceptionstatusRequest)Session)AddressDataBankStatementDataVehicleDocumentData)AddressMatchResponseMatchResultErrorResponse) MultiDocumentVerificationRequest)azure_openai_client)get_pdf_parser)	BaseModel)logger   _verification_cache	file_typefile_urlpayloadreturnc                 x    	 t        |j                               }|  d| d| S # t        $ r |  d| dcY S w xY w)N|z	|fallback)sorteditems	Exception)r   r   r   r"   s       M/var/www/html/BankruptcyAI-uat/bankruptcy-ai/src/modules/prompt/controller.py_build_cache_keyr%      sP    2w}}'AhZq00 2AhZy112s   "% 99keyc                 J  K   t        j                          }t        4 d {    t        j                  |       }|r:|\  }}||z
  t        k  r|cd d d       d {    S t        j                  | d        d d d       d {    y 7 f7 .7 	# 1 d {  7  sw Y   y xY ww)N)time_verification_cache_lockr   getCACHE_TTL_SECONDSpop)r&   nowentrytsdatas        r$   _get_cached_verificationr1   $   s     
))+C' 3 3#'',HBRx,,3 3 3 $''T23 3 3 3 3 3 3 3 sb   B#BB#*BB#B
B#!B7B#BB#
B#B#B BB B#r0   c                 d  K   t         4 d {    | t        vrOt        t              t        k\  r9t	        t        j                         d       d   }t        j                  |d        t        j                         |ft        | <   d d d       d {    y 7 7 # 1 d {  7  sw Y   y xY ww)Nc                     | d   d   S N   r    )kvs    r$   <lambda>z,_store_cached_verification.<locals>.<lambda>3   s    Aq     )r&   r   )r)   r   lenMAX_CACHE_ENTRIESminr"   r,   r(   )r&   r0   
oldest_keys      r$   _store_cached_verificationr>   0   s     ' 7 7))c2E.FJ[.[0668>QRSTUJ##J5$(IIK#6C 	7 7 7 7 7 7 7sE   B0BB0A5BB0BB0B0B-!B$"B-)B0c                   D    e Zd ZU eed<   ee   ed<   eeez  e	z     ed<   y)VerificationRequestr   	file_urlsr0   N)
__name__
__module____qualname__str__annotations__listr   r   r   r   r6   r9   r$   r@   r@   7   s(    NCy
;!225HH
IIr9   r@   openai_resultc           
      X  ! g }g }d}d}| j                  dg       }t        |t              sg }| j                  d      r| j                  d      }|D ]  }	 t        |t              st	        |j                  d      xs d      !t	        |j                  d      xs d      }	|j                  d      |j                  d      nd}
t        |j                  dd	            }t	        |j                  d
      xs d      }!st        !|	|
||      }|j                  |       |s&|	r|	nd}|
r|
nd}|j                  ! d| d| d        | j                  d      r|j                  | d          |dk7  r| j                  dd	      nd}| j                  dd      }| j                  dd      }| j                  dd	      }|dk(  rd|v rd}nd| d| d| d | }g }g }g }g }|D ]  }|j                  !|j                  }t        !fd!|D        i       }|j                  d"d	      }|r+|j                  !       |j                  !d#d$! d%d&       o|r+|j                  !       |j                  !d'd$! d(d&       |j                  !       |j                  !d)d$! d*d&        g }|rc|d+v rd,|vr|j                  d-| d.       nE|d/k(  rd0|vrd1|vr|j                  d-| d2       n"|dk(  rd3|vrd4|vr|j                  d-| d5       |r|j                  d6       |r-|j                  d7d8j                  t!        |             d9       |rg }|D ]  }|j                  |v s|j"                  t	        |j"                        t	        |j$                        k7  sK|j                  |j                   d:|j$                   d;|j"                   d<        |r'|j                  d=d>j                  |      z   d9z          n/|j                  d?d8j                  t!        |            z   d9z          |r-|j                  d@d8j                  t!        |             d9       |d+v r|j                  dA       n-|d/k(  r|j                  dB       n|dk(  r|j                  dC       |rdDj                  |      ndE}| j                  dF      xs |}t'        dYi dGdHdI|dJ|d|d|dK|d|dL|dM|d|dN| j                  dN      dO| j                  dO      dP| j                  dP      dQ|j)                  dR      D  cg c]#  } | j+                         s| j+                         % c} dSt!        |      t!        |      t!        |      dTdU| j                  dU      dV|dW|dF|dXt-        j.                         j1                         S # t        $ rI}t        j                  dt	        |              |j                  dt	        |              Y d}~d}~ww xY wc c} w )Za  
    Build AddressMatchResponse from raw OpenAI result.
    This is the same logic used in verify_address_with_document, extracted for reuse.
    
    Args:
        openai_result: Raw response dict from Azure OpenAI
        file_type: Document type (e.g., 'residence_documents', 'bank_statement')
        file_url: Source file URL(s) - can be comma-separated
    
    Returns:
        AddressMatchResponse with all fields populated
    Nanalysis_resultsvehicle_details
field_name provided_valuefound_in_documentis_matchF
confidencelowrL   rN   rO   rP   rQ   N/A	Not found: Expected '
', Found ''"Failed to process field analysis: mismatch_summarybank_statementoverall_matchconfidence_scoredocument_typeUnknownis_hazyErrorzContent filter triggeredzEPlease check the document and ensure it contains appropriate content.'Verification completed. Overall match: . Confidence: . Document type: . Hazy: c              3   L   K   | ]  }|j                  d       k(  s|  yw)rL   N)r*   ).0rrL   s     r$   	<genexpr>z4build_response_from_openai_result.<locals>.<genexpr>   s"     `aeeL>QU_>_1`s   $$partial_matchfully_matchedField 'z' matches the document.fieldr   explanationpartially_matchedz' partially matches.not_matched' not found or no match.)vehicle_documentsvehicle_registrationvehicle_insuranceVehicleThis looks like a , not a vehicle document.residence_documents	ResidenceAddressz, not a residence document.Bank	Statementz, not a bank statement.The image is a bit blurry.We found these matching: , . differs (expected '' vs found '')Differences: ; $Some fields are present but differ: Missing or not found: wPlease upload a clear vehicle registration or insurance document showing the vehicle number, model, mileage, and value.zEPlease upload a clear residence document showing the address details.zNPlease upload a clear bank statement showing account details and transactions. zNo fields analyzed.overall_feedback_textsuccessTmessager   mismatch_detailsdocument_type_detectedbank_statement_resultsaggregated_months_coveredaggregated_missing_monthsaggregated_months_completeoriginal_file_urls,feedbackrk   rp   rq   per_file_resultsfeedback_detailsfeedback_text	timestampr6   )r*   
isinstancerG   dictrE   boolr   appendr#   r   errorextendrL   rP   nextjoinr!   rO   rN   r   splitstripr	   r-   	isoformat)"rH   r   r   rJ   r   r   rK   analysis_results_rawresultrN   rO   rP   rQ   match_resultexpected_val	found_valresult_errorr\   r]   r^   r`   r   rk   rp   rq   r   
raw_resultrj   feedback_text_partsdiffsr   final_overall_feedback_texturL   s"                                    @r$   !build_response_from_openai_resultr   =   s[   " +-"$!O ),,-?D*D1! *+'++,=>& 	fd+VZZ5;<J ,<!=!CDNCI::NaCbCn

+> ?txFJJz59:HVZZ5>?J&%-"3!%L ##L11?~U1B-	 ''!l,|nJykQRS-> +,.@ AB BKN^A^M%%ou=dhM %(();UC!%%oyAM	51G $>BR$RS 	
 6m_ E+,,=m_HU\T]_ 	 MK" &&
??`&:`bde
">  ,###)!(4KL% 
 $$Z0###-!(4HI%  z*###'!(4LM% /<  ZZ_hp}_}&&);M?Jc'de//K}4TYbjwYw&&);M?Je'fg**v]/J{boOo&&);M?Ja'bc ""#?@ ""%>tyyP]I^?_>``a#bc & 	LF  $55&:R:R:^v//0C8M8M4NNLLF$5$5#66J6K`K`Jaamnt  oG  oG  nH  HJ  "K  L	L &&59I'IC'OP&&'MPTPYPYZ`arZsPt'twz'z{ ""%;DIIf[FY<Z;[[\#]^ VV""  $]  	^	+	+""#jk	&	&""#st5HCHH01NcM #0"3"34K"L"]P]   *	
 $ *   -  6 ( #0"3"34O"P #0"3"34O"P $1#4#45Q#R 08~~c/BP!aggiAGGIP  $M2!'(9!:!+.
( '**+=>)* *+, $-. :/0 ,,.**,1 c  	LL=c,>O=PQR##&H\IZH[$\]	~ Qs2   W'BWA	WX'X'	X$>XX$dbaddress_datarequestc                   K   	 |j                         }t        |||      }t        |       d{   }|t        j                         }	 t	        j
                  |||       d{   }|j                  dd      }	|	r@t        ||       d{    t        d| d| dt        j                         |z
  dd       n@t        j                  d	       t        d
| d| dt        j                         |z
  dd       n,t        j$                  d| d|        t        d| d|        g }g }d}d}t        dt'        |              t        dt)        |t               r|j+                         nd        t        d|j                  dd              	 	 |j                  dg       }t)        |t,              st        dt'        |              g }|j                  d      r|j                  d      }t/        |      D ]  \  }}	 t        d| d|        t)        |t               st        d| d|        ;t        |j                  d      xs d      }t        |j                  d      xs d      }|j                  d      |j                  d      nd}t1        |j                  d d            }t        |j                  d!      xs d"      }|st3        |||||#      }|j5                  |       |s&|r|nd$}|r|nd}|j5                  | d%| d&| d'       " |j                  d)      r|j9                  |d)          |d*k7  r|j                  d+d      nd}|j                  d,d$      }|j                  d-d.      }|j                  d/d      } d0| d1| d2| d3|  }!t        d|!||||| ||||j                  d4      |j                  d5      |j                  d6      |j;                  d7      D "cg c]#  }"|"j=                         s|"j=                         % c}"t        j                         j!                         8      S 7 7 7 # t        $ rq}
dt        |
       }t        d||g ddt        |
       gt        j                         j!                               }t        j"                  d|        |cY d}
~
S d}
~
ww xY w# t        $ rI}t        j6                  d(t        |              |j5                  d(t        |              Y d}~d}~ww xY wc c}"w # t>        $ r  t        $ r.}#t        d9t        |#              g }$|rg|d*k7  rb	 |j                         jA                         D ]0  \  }%}&|&s	|$j5                  t3        |%t        |&      ddd:#             2 n# t        $ r Y nw xY wt        dd;t        |#       ||d*k7  r|$ng |d*k7  rdndd<t        |#       gdddddd|j;                  d7      D "cg c]#  }"|"j=                         s|"j=                         % nc c}"w c}"t        j                         j!                         =      cY d}#~#S d}#~#ww xY ww)>zZVerification using separate params (file_type, file_url) and JSON body for address fields.N_llamaparse_successFz'PERF: OpenAI call (cache miss, cached) r   z in .2fszALlamaParse failed - skipping cache to allow retry on next requestz?PERF: OpenAI call (cache miss, NOT cached - LlamaParse failed) zFailed to analyze document: zAzure OpenAI API Error: )r   r   r   rJ   r\   r   r   zOPEN AI ERROR - zPERF: Cache hit zDEBUG: OpenAI result type: zDEBUG: OpenAI result keys: z
Not a dictzDEBUG: Analysis results: rJ   rU   Tz)WARNING: analysis_results is not a list: rK   zDEBUG: Processing result z: z"WARNING: Skipping non-dict result rL   rM   rN   rO   rP   rQ   rR   rS   rT   rV   rW   rX   rY   rZ   r[   r\   r]   r^   r_   r`   rb   rc   rd   re   r   r   r   r   )r   r   r   rJ   r\   r   r`   r   r   rK   r   r   r   r   r   z9ERROR: Unexpected error in verify_address_with_document: r   zError verifying address: zSystem Error: r   r   r   rJ   r\   r   r`   r   r   r   r   r   r   r   )!r   r%   r1   r(   r   verify_documentr*   r>   printr   warningr#   rE   r   r	   r-   r   criticalinfotyper   keysrG   	enumerater   r   r   r   r   r   r   r
   r"   )'r   r   r   r   r   address_dict	cache_keyrH   
start_callllamaparse_successopenai_errorerror_message	gor_errorrJ   r   r   rK   r   ir   rL   rN   rO   rP   rQ   r   r   r   r   r\   r]   r^   r`   r   r   efallback_resultsrn   values'                                          r$   verify_address_with_documentr     s    ^
#((* %Y,G	6yAA J!&9&I&I|X' ! &3%6%67Le%T"%4YNNNCI;aPXzY]^b^g^g^ilv^vwz]{{|}~NN%fh[\e[ffghpgqquvzvv  wB  EO  wO  PS  vT  TU  V  W KK*9+QxjAB$YKq
;< !% 	+D,?+@AB+J}^bDcM,>,>,@iu+vwx)-*;*;<NP[*\)]^_u	p #0#4#45G#L 2D9A$G[B\A]^_')$  !23"/"3"34E"F&';< 	65aS6(CD%fd3 B1#RxPQ !$VZZ%=%C!DJ%(4D)E)K%LNKQ::ViKjKv

3F(G  }A%#FJJz5$ABH!$VZZ%=%F!GJ% #.#-'5*;!)#-$L %++L9#9G~U9J$5P[	(//)l,|nJykYZ[1B /0##M2D$EF FORbEb))/5Ahl ),,-?G%))/9E##Iu5 6m_ E+,,=m_HU\T]_ 	
 $-'-#0#9+&3&7&78S&T&3&7&78S&T'4'8'89U'V3;>>#3FTa!'')	Tlln..0
 	
K	 B! O
  !">s<?P>Q R0 % -!))+&+,DSEVDW*X)Y"*,,.":":"<	 "29+ >?  !p ! LL#Ec,FWEX!YZ$++.PQTUaQbPc,deX  U   
I#a&RS.0	%55$0$5$5$7$=$=$? LE5(//',+.u:.2%*'.1   #/Ax81:>N1N-TV#,0@#@%d .s1vh78#'#'&*&*'+3;>>#3FTa!'')	TTlln..0
 	
!
s5  Y,+T( QT( Q %Q&'Q QA0Q >D	T( 2S:T( ;BST( A	S CT( 7T#"T#"(T( Y,T( Q Q 	SA&S ST( Y,ST( 	T >TT( T  T( (Y); Y$&V.*V.-Y$.	V:7Y$9V::AY$X1"X1"0.Y$Y)Y,$Y))Y,request_datac                 %  =>?K   	 |j                   }dj                  |j                  D cg c]  }t        |       c}      }|j                  }|dk7  rt        |j                        dkD  rt        j                         }|j                  D cg c]  }t        | |t        |      ||       }	}t        j                  |	  d{   }
g }g }d}d}g }g }t        |
|j                        D ]  \  }}|j                  r|j                  |j                         |j                  r|j                  |j                         |j                  rd}|j                  r|j!                  |j                         |j"                  du rd}g }g }g }|j                  r||j                  D ]m  }|j$                  r|j!                  |j&                         +|j(                  r|j!                  |j&                         S|j!                  |j&                         o t+        t-        |            t+        t-        |      t-        |      z
        t+        t-        |      t-        |      z
  t-        |      z
        d}g }|j                  r-d|j                  vr|j!                  d	|j                   d
       |j                  r|j!                  d       |j/                  d      r)|j!                  ddj                  |d         z   dz          |j/                  d      xs g }|rg }|j                  xs g D ]  }	 |j&                  |v ro|j(                  ct        |j(                        t        |j0                        k7  r8|j!                  |j&                   d|j0                   d|j(                   d        |r'|j!                  ddj                  |      z   dz          n&|j!                  ddj                  |      z   dz          |j/                  d      xs g }|r&|j!                  ddj                  |      z   dz          |dk7  r|j!                  d       dj                  |      }|j!                  t        |      |j                  xs g D cg c]  }|j5                          c}|j                  xs g |j"                  |j                  |j                  ||d        i }|D ]b  }|j/                  |j&                        }||||j&                  <   0dddd=d t6        f=fd!} ||       ||      kD  sT|||j&                  <   d t9        |j;                               }t        j                         |z
  } t=        d"t        |j                         d#| d$| d%d&       t?        dd'| d|||t+        t-        |            ||r|d(   nddddd|j                  D cg c]  }t        |       c}|tA        jB                         jE                         )      }!nKt        | ||||       d{   }!|!jF                  s(|j                  D cg c]  }t        |       c}|!_#        g }"g }#g }$|dk(  r|!jH                  r|!jH                  D ]D  }%tK        |%tL              s|%j/                  d*      xs i }&|&jO                         D ]*  \  }'}(|(r|"j!                  |'       |$j!                  |'       , |%j/                  d+      du r|"j!                  d,       n$|%j/                  d+      du r|$j!                  d,       |%j/                  d-      du r|"j!                  d.       n$|%j/                  d-      du r|$j!                  d.       |%j/                  d/      du r|"j!                  d0       |%j/                  d/      du s4|$j!                  d0       G t+        t-        |"            }"t+        t-        |$      t-        |"      z
        }$n|!j                  r||!j                  D ]m  }|j$                  r|"j!                  |j&                         +|j(                  r|#j!                  |j&                         S|$j!                  |j&                         o t+        t-        |"            }"t+        t-        |#      t-        |"      z
        }#t+        t-        |$      t-        |"      z
  t-        |#      z
        }$|"|#|$d|!_(        g >d[d1t        d2t        d3tR        t           d4tR        t           f>fd5})|dk(  r|!jH                  r|!jH                  D ]w  }%|%j/                  d6      xs i }*|*j/                  dg       D ]  }+ |)|+d        |*j/                  dg       D ]  }+ |)|+d        |*j/                  dg       D ]  }+ |)|+d        y nh|!j                  r\|!j                  D ]M  }|j&                  |"v rdn|j&                  |#v rdnd}, |)|j&                  |,|j0                  |j(                         O >|!_*        |dk7  rK|!jV                  s>	 |!jP                  r|!jP                  j/                  d      ng }-|!jP                  r|!jP                  j/                  d      ng }.|!jP                  r|!jP                  j/                  d      ng }/g }0|!j                  r-d|!j                  vr|0j!                  d	|!j                   d
       |!j                  r|0j!                  d       |-r&|0j!                  d7dj                  |-      z   dz          |.rg }|!j                  xs g D ]  }|j&                  |.v s|j(                  t        |j(                        t        |j0                        k7  sK|j!                  |j&                   d|j0                   d|j(                   d        |r'|0j!                  ddj                  |      z   dz          n&|0j!                  ddj                  |.      z   dz          |/r&|0j!                  ddj                  |/      z   dz          |dk7  r|0j!                  d       tY        |!d8dj                  |0             |dk(  r|!jH                  r	 |!jH                  xs g }1g }0t[        d9 |1D              }2|2r|0j!                  d:       n|0j!                  d;       g d<}3g }4g }5|3D ]9  ?t[        ?fd=|1D              r|4j!                  ?       )|5j!                  ?       ; |4r&|0j!                  d>dj                  |4      z   dz          |5r>t        |5      t        |3      k  r'|0j!                  d?dj                  |5      z   dz          n(t        |5      t        |3      k(  r|0j!                  d@       t[        dA |1D              r|0j!                  dB       n|0j!                  dC       t[        dD |1D              r|0j!                  dE       n|0j!                  dF       t]        dG |1D              }6|6d(k(  r$t[        dH |1D              r|0j!                  dI       n|6d(kD  r|0j!                  dJ|6 dK       |!j^                  du r|0j!                  dL       n8|!j`                  xs g }7|7r&|0j!                  dMdj                  |7      z   dz          t        |1      dk(  rS|1d(   }8tK        |8tL              rv|8j/                  dN      xs g }9|9r_|0j!                  dOdj                  |9      z   dz          n8|!jb                  xs g }:|:r&|0j!                  dPdj                  |:      z   dz          dj                  |0      |!_2        |dk7  rg }0	 ddQtg               v rr|d(   ndRvr&r$|0j!                  dSdj                  |       dT       dUtg               v rr|0j!                  dV       |"r&|0j!                  dWdj                  |"      z   dz          |#rg }|!j                  xs g D ]  }	 |j&                  |#v ro|j(                  ct        |j(                        t        |j0                        k7  r8|j!                  |j&                   d|j0                   d|j(                   d        |r'|0j!                  ddj                  |      z   dz          n&|0j!                  ddj                  |#      z   dz          |$r&|0j!                  ddj                  |$      z   dz          |dk7  r|0j!                  d       |!j5                         };dj                  |0      |;dX<   	 tY        |!dX|;dX          |!S |!S c c}w c c}w 7 # t2        $ r Y Pw xY wc c}w c c}w 7 _c c}w # t2        $ r Y w xY w# t2        $ r Y 5w xY w# t2        $ r Y w xY w# t2        $ r Y w xY w# t2        $ r Y |!S w xY w# t2        $ r}<t?        ddYt        |<       dg |j                   dk7  rdndt        |<      gdddddd|j                  D cg c]  }t        |       nc c}w c}tA        jB                         jE                         Z      cY d}<~<S d}<~<ww xY ww)\Process multi-document verification using a unified request body.

    Internally reuses existing verify_address_with_document logic by joining file URLs.
    r   r[   r5   NTFr   rv   rw   rx   r~   rk   r   r   r   rp   r   r   r   r   r   r   rq   r   real_estate_documentsr   r   r   rJ   r   r\   r`   r   r   r         highmediumrR   mc                 \    | j                   rdndj                  | j                  d      fS r4   rP   r*   rQ   r   
conf_orders    r$   scorez%verify_multi_documents.<locals>.score  &    %&ZZQ
q||UV8WXXr9   *PERF: Concurrent multi-file verification ( files, type=) in r   r   2Multi-file verification completed. Overall match: r   r   r   r   rJ   r\   r   r`   r   r   r   r   r   r   r   r   name_matchesbank_name_matches	bank_nameaccount_type_matchesaccount_typefinal_balance_matchesbalancern   r   providedfoundc                     |dk(  r|rd|  dnd|  d}n(|dk(  r|rd|  d| d| dnd|  d	}n|rd|  d
nd|  d}j                  | ||d       y Nrk   rl   z' matches exactly.z' verified.rp   z'' present but value differs (expected 'r   z').z' partially matched.rr   z
' missing.rm   r   rn   r   r   r   msgr   s        r$   explainz'verify_multi_documents.<locals>.explain&      (=Ew&89WUZT[[fKg..rzw&MhZWcdicjjmn  CJ  KP  JQ  Qe  AfCKw&>?SZ[`ZaakQl##evVY$Z[r9   r   	Matched: r   c              3   b   K   | ]'  }t        |t              xr |j                  d        ) ywr   Nr   r   r*   rg   its     r$   ri   z)verify_multi_documents.<locals>.<genexpr>c  *     'teg
2t(<(`H_A`(`'t   -/3Final balance matches the provided expected amount.6Final balance could not be verified or does not match.
first_namemiddle_name	last_namec              3      K   | ]M  }t        |t              xr7 t        |j                  d       t              xr |d    j                        du  O ywr   TNr   rg   r   nfs     r$   ri   z)verify_multi_documents.<locals>.<genexpr>n  k       X  IK:b$/  DJrvvn?UW[4\  Dacdrasawawxza{  @D  bD  D  X   AAName components matched: Name components not found: No name components matched.c              3   b   K   | ]'  }t        |t              xr |j                  d        ) ywr   Nr   r   s     r$   ri   z)verify_multi_documents.<locals>.<genexpr>y  *     _PRz"d+K7J0KK_r   Bank name matches.Bank name not matched.c              3   b   K   | ]'  }t        |t              xr |j                  d        ) ywr   Nr   r   s     r$   ri   z)verify_multi_documents.<locals>.<genexpr>}  *     bSUz"d+N7M0NNbr   Account type matches.Account type not matched.c              3   z   K   | ]3  }t        |t              st        |j                  d       xs g        5 ywarithmetic_inconsistenciesNr   r   r:   r*   r   s     r$   ri   z)verify_multi_documents.<locals>.<genexpr>  @       ,H`br|}  BF  sGC7S0T0ZXZ,[  ,H   ;#;c              3   b   K   | ]'  }t        |t              xr |j                  d        ) ywbalancesNr   r   s     r$   ri   z)verify_multi_documents.<locals>.<genexpr>  *     5ufhjT6J6arvvV`Oa6a5ur   5Arithmetic appears consistent across provided months.Arithmetic issues detected in 
 month(s).*All required recent months appear covered.Missing months: months_coveredMonths covered: Aggregated months covered: 	doc_typesrM   Some files appear to be   rather than a vehicle document.is_hazy_any#One or more files are a bit blurry.Matched fields: r   Error verifying documents: r   NN4r   r   rA   rE   r0   r:   r(   r   asynciogatherziprJ   r   r   r`   r   r   r\   rP   rL   rO   r!   setr*   rN   r#   
model_dumpr   rG   valuesr   r   r	   r-   r   r   r   r   r   r"   r   r   r   r   setattranysumr   r   r   r   locals@r   r   r   r   r   file_url_joinedparsedbatch_start
single_urltaskssingle_responsesaggregated_resultsaggregated_mismatchesoverall_match_allr+  r(  per_file_payloadsingle_resppf_fully
pf_partialpf_notrh   per_file_feedbacksummary_partspartialsr   missinguser_friendly_feedbackdedupexistingr   merged_resultselapsedbase_responsefullypartialrq   itemr   kvr   fbfldr   fully_localpartial_local	not_localsummary_bitsbs_itemsany_balance_matchname_fieldsmatched_namesmissing_namesinconsistencies_totalmissing_monthssinglecoveredagg_covbase_response_dictr   r   r   r  s@                                                                @@@r$   verify_multi_documentsrj  k  w    `
 **	 ((L4J4J#KqCF#KL ""((S1G1G-H1-L))+K vB  vL  vL  Mgq1"iZRXZab  ME  M%,^^U%;;46/1! $*/K#%I+-+./?AWAW+X @'Z//&--k.J.JK//)001M1MN&&"&K55$$[%G%GH,,5(-%&((*
$&//(99 <::$OOALL9 22 * 1 1!,, ? &all ;< &,CM%:)/J#h-0O)P#)#f+H*EJ*W#X%!
 ,.559KLnLn;n!((+=k>`>`=aaz){|&&!(()EF$((9!(()DtyyQbcrQsGt)twz)z{,001DEK')E)::@b %% ||x7A<O<O<[`cdedwdw`x|  AB  AQ  AQ  }R  aR %~=QRSRbRbQccopq  qD  qD  pE  EG  .H  !I% %,,_tyy?O-ORU-UV%,,-SVZV_V_`hVi-ilo-op+//>D"!(()ADIIgDV)VY\)\] 77!((  *c  d),-)@& '' #JBMB^B^Bdbd(fA(f(3(D(D(J%0%>%>*22.9.P.P 1%;	) 	o@B -/E' 	0 99Q\\2#*+E!,,'*+q!CJY YQx%/1./all+	0 "%,,.1NiikK/G>s<CYCY?Z>[[hirhssx  zA  BE  yF  FG  H  I0LM^L__`a(!//!',A(B!C#7@y|d'+*.*.+/4@4J4J#KqCF#K!1",,.224M$ #?r9o_egn"ooM 33DPDZDZ3[qCF3[0 !#((]-Q-Q%<< 2!$-#xx7=2(..0 .DAqQ#**1-	. 88/0D8LL-XX12e;&&{38823t;LL0XX45>&&~68834<LL+XX56%?&&y1+2. 3u:&E [!1CJ!>?K --&77 =AzzQ\\2..#NN1<<8'..q||<= 3u:&ES\CJ67G [!1CJ!>W!MNK #!(&"
 24	\3 	\ 	\x} 	\T\]`Ta 	\ ((]-Q-Q%<< 0XXj)/R66/26 2CC1266"5r: 6CC!45666-4 0CC/00 --&77 YA010E_cdcocoszczL_  ANFALL&!2B2BADWDWXY *:&((1O1OMZMcMcm4488IikS`SiSi 6 6 : :;N OoqIVI_I_M2266}Eeg	*, 77I]MqMq<q ''*<]=a=a<bb{(|} (( ''(DE ''dii6L(Ls(RS ')E+<<B E<<=8Q=P=P=\adefexexay  ~A  BC  BR  BR  ~S  bS!LLALL>9MaN^N^M__klmll  lA  AC  *D  EE $++Odii>N,NQT,TU$++,RUYU^U^_lUm,mps,st ''(@499YCW(WZ](]^ 77 ''  )b  c8NO ((]-Q-Q=(??E2*,$''tks't$t!$ ''(]^ ''(`aF " "% 1B  X  OW  X  X%,,R0%,,R01 ! ''(CdiiP]F^(^ad(de S%7#k:J%J ''(E		R_H`(`cf(fg'3{+;; ''(EF_V^__ ''(<= ''(@AbYabb ''(?@ ''(CD(+  ,Hfn  ,H  )H%(A-#5ult5u2u ''(_`*Q. ''*HI^H__i(jk ;;tC ''(TU%2%L%L%RPRN%$++,>>AZ,Z]`,`ax=A%%a[F!&$/"(**-=">"D""(//0BTYYwEW0WZ]0]^ ,EEKG$++,IDIIV]L^,^ad,de.1hh|.D+ ((&(L[FH5LQZYq\`bc $++.FtyyQZG[F\\|,}~ FH, ''(MN ##$659I$IC$OP#%'88>B !A!<<72q7J7J7V[^_`_r_r[swz{|  |L  |L  xM  \M!LLALL>9MaN^N^M__klmll  lA  AC  *D  E!  ''$))E:J(JS(PQ ''(NQUQZQZ[bQc(cfi(ij##$<tyy?U$UX[$[\33##  %^  _!.!9!9!;:=((<:P67'>@RSj@kl }U
 $L M;b  ) %$% )gF $L
 p 4\\  @     % ! !     
#1#a&:#/#9#9=M#M%SW!!fX#'#'&*&*'+0<0F0FG1AGGlln..0
 	

&  AJ%AG( AE)AAG( AE.1AG( AE3	I,AG( 6A=AE63CAG( AF&BAG( <B&AG( "AF 4=AG( 1AF2AG( AF"EAG( JAG( 	D AF *AF 7+AF #C#AF AG( K%AF( ?AG( AAF8 $?AG( @$A=AGB!B3AG( EAG E%AG( E&AJE'AG( E(AJE)AG( E6	AFE?AG( FAFFAG( FAG( F	AF%F!AG( F$AF%F%AG( F(	AF5F1AG( F4AF5F5AG( F8	AGGAG( GAGGAG( G	AGGAG( GAGGAG( G	AG%G!AG( G#AJG$AG%G%AG( G(	AJG1AAI=H7AI
"I	.AI=I7AJI8AJI=AJJAJc                 %  =>?K   	 |j                   }dj                  |j                  D cg c]  }t        |       c}      }|j                  }|dk7  rt        |j                        dkD  rt        j                         }|j                  D cg c]  }t        | |t        |      ||       }	}t        j                  |	  d{   }
g }g }d}d}g }g }t        |
|j                        D ]  \  }}|j                  r|j                  |j                         |j                  r|j                  |j                         |j                  rd}|j                  r|j!                  |j                         |j"                  du rd}g }g }g }|j                  r||j                  D ]m  }|j$                  r|j!                  |j&                         +|j(                  r|j!                  |j&                         S|j!                  |j&                         o t+        t-        |            t+        t-        |      t-        |      z
        t+        t-        |      t-        |      z
  t-        |      z
        d}g }|j                  r-d|j                  vr|j!                  d	|j                   d
       |j                  r|j!                  d       |j/                  d      r)|j!                  ddj                  |d         z   dz          |j/                  d      xs g }|rg }|j                  xs g D ]  }	 |j&                  |v ro|j(                  ct        |j(                        t        |j0                        k7  r8|j!                  |j&                   d|j0                   d|j(                   d        |r'|j!                  ddj                  |      z   dz          n&|j!                  ddj                  |      z   dz          |j/                  d      xs g }|r&|j!                  ddj                  |      z   dz          |dk7  r|j!                  d       dj                  |      }|j!                  t        |      |j                  xs g D cg c]  }|j5                          c}|j                  xs g |j"                  |j                  |j                  ||d        i }|D ]b  }|j/                  |j&                        }||||j&                  <   0dddd=d t6        f=fd!} ||       ||      kD  sT|||j&                  <   d t9        |j;                               }t        j                         |z
  } t=        d"t        |j                         d#| d$| d%d&       t?        dd'| d|||t+        t-        |            ||r|d(   nddddd|j                  D cg c]  }t        |       c}|tA        jB                         jE                         )      }!nKt        | ||||       d{   }!|!jF                  s(|j                  D cg c]  }t        |       c}|!_#        g }"g }#g }$|dk(  r|!jH                  r|!jH                  D ]D  }%tK        |%tL              s|%j/                  d*      xs i }&|&jO                         D ]*  \  }'}(|(r|"j!                  |'       |$j!                  |'       , |%j/                  d+      du r|"j!                  d,       n$|%j/                  d+      du r|$j!                  d,       |%j/                  d-      du r|"j!                  d.       n$|%j/                  d-      du r|$j!                  d.       |%j/                  d/      du r|"j!                  d0       |%j/                  d/      du s4|$j!                  d0       G t+        t-        |"            }"t+        t-        |$      t-        |"      z
        }$n|!j                  r||!j                  D ]m  }|j$                  r|"j!                  |j&                         +|j(                  r|#j!                  |j&                         S|$j!                  |j&                         o t+        t-        |"            }"t+        t-        |#      t-        |"      z
        }#t+        t-        |$      t-        |"      z
  t-        |#      z
        }$|"|#|$d|!_(        g >d[d1t        d2t        d3tR        t           d4tR        t           f>fd5})|dk(  r|!jH                  r|!jH                  D ]w  }%|%j/                  d6      xs i }*|*j/                  dg       D ]  }+ |)|+d        |*j/                  dg       D ]  }+ |)|+d        |*j/                  dg       D ]  }+ |)|+d        y nh|!j                  r\|!j                  D ]M  }|j&                  |"v rdn|j&                  |#v rdnd}, |)|j&                  |,|j0                  |j(                         O >|!_*        |dk7  rK|!jV                  s>	 |!jP                  r|!jP                  j/                  d      ng }-|!jP                  r|!jP                  j/                  d      ng }.|!jP                  r|!jP                  j/                  d      ng }/g }0|!j                  r-d|!j                  vr|0j!                  d	|!j                   d
       |!j                  r|0j!                  d       |-r&|0j!                  d7dj                  |-      z   dz          |.rg }|!j                  xs g D ]  }|j&                  |.v s|j(                  t        |j(                        t        |j0                        k7  sK|j!                  |j&                   d|j0                   d|j(                   d        |r'|0j!                  ddj                  |      z   dz          n&|0j!                  ddj                  |.      z   dz          |/r&|0j!                  ddj                  |/      z   dz          |dk7  r|0j!                  d       tY        |!d8dj                  |0             |dk(  r|!jH                  r	 |!jH                  xs g }1g }0t[        d9 |1D              }2|2r|0j!                  d:       n|0j!                  d;       g d<}3g }4g }5|3D ]9  ?t[        ?fd=|1D              r|4j!                  ?       )|5j!                  ?       ; |4r&|0j!                  d>dj                  |4      z   dz          |5r>t        |5      t        |3      k  r'|0j!                  d?dj                  |5      z   dz          n(t        |5      t        |3      k(  r|0j!                  d@       t[        dA |1D              r|0j!                  dB       n|0j!                  dC       t[        dD |1D              r|0j!                  dE       n|0j!                  dF       t]        dG |1D              }6|6d(k(  r$t[        dH |1D              r|0j!                  dI       n|6d(kD  r|0j!                  dJ|6 dK       |!j^                  du r|0j!                  dL       n8|!j`                  xs g }7|7r&|0j!                  dMdj                  |7      z   dz          t        |1      dk(  rS|1d(   }8tK        |8tL              rv|8j/                  dN      xs g }9|9r_|0j!                  dOdj                  |9      z   dz          n8|!jb                  xs g }:|:r&|0j!                  dPdj                  |:      z   dz          dj                  |0      |!_2        |dk7  rg }0	 ddQtg               v rr|d(   ndRvr&r$|0j!                  dSdj                  |       dT       dUtg               v rr|0j!                  dV       |"r&|0j!                  dWdj                  |"      z   dz          |#rg }|!j                  xs g D ]  }	 |j&                  |#v ro|j(                  ct        |j(                        t        |j0                        k7  r8|j!                  |j&                   d|j0                   d|j(                   d        |r'|0j!                  ddj                  |      z   dz          n&|0j!                  ddj                  |#      z   dz          |$r&|0j!                  ddj                  |$      z   dz          |dk7  r|0j!                  d       |!j5                         };dj                  |0      |;dX<   	 tY        |!dX|;dX          |!S |!S c c}w c c}w 7 # t2        $ r Y Pw xY wc c}w c c}w 7 _c c}w # t2        $ r Y w xY w# t2        $ r Y 5w xY w# t2        $ r Y w xY w# t2        $ r Y w xY w# t2        $ r Y |!S w xY w# t2        $ r}<t?        ddYt        |<       dg |j                   dk7  rdndt        |<      gdddddd|j                  D cg c]  }t        |       nc c}w c}tA        jB                         jE                         Z      cY d}<~<S d}<~<ww xY ww)\r   r   r[   r5   NTFr   rv   rw   rx   r~   rk   r   r   r   rp   r   r   r   r   r   r   rq   r   r   r   r   r   r   r   r   r   c                 \    | j                   rdndj                  | j                  d      fS r4   r   r   s    r$   r   z,verify_multi_documents_celery.<locals>.score?  r   r9   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rn   r   r   r   c                     |dk(  r|rd|  dnd|  d}n(|dk(  r|rd|  d| d| dnd|  d	}n|rd|  d
nd|  d}j                  | ||d       y r   r   r   s        r$   r   z.verify_multi_documents_celery.<locals>.explain  r   r9   r   r   r   c              3   b   K   | ]'  }t        |t              xr |j                  d        ) ywr   r   r   s     r$   ri   z0verify_multi_documents_celery.<locals>.<genexpr>  r   r   r   r   r   c              3      K   | ]M  }t        |t              xr7 t        |j                  d       t              xr |d    j                        du  O ywr  r   r  s     r$   ri   z0verify_multi_documents_celery.<locals>.<genexpr>  r  r  r	  r
  r  c              3   b   K   | ]'  }t        |t              xr |j                  d        ) ywr  r   r   s     r$   ri   z0verify_multi_documents_celery.<locals>.<genexpr>  r  r   r  r  c              3   b   K   | ]'  }t        |t              xr |j                  d        ) ywr  r   r   s     r$   ri   z0verify_multi_documents_celery.<locals>.<genexpr>  r  r   r  r  c              3   z   K   | ]3  }t        |t              st        |j                  d       xs g        5 ywr  r  r   s     r$   ri   z0verify_multi_documents_celery.<locals>.<genexpr>  r  r  c              3   b   K   | ]'  }t        |t              xr |j                  d        ) ywr  r   r   s     r$   ri   z0verify_multi_documents_celery.<locals>.<genexpr>  r  r   r   r!  r"  r#  r$  r%  r&  r'  r(  rM   r)  r*  r+  r,  r-  r   r.  r   r/  r0  r;  s@                                                                @@@r$   verify_multi_documents_celeryrv    rk  rl  c                 %  =>?K   	 |j                   }dj                  |j                  D cg c]  }t        |       c}      }|j                  }|dk7  rt        |j                        dkD  rt        j                         }|j                  D cg c]  }t        | |t        |      ||       }	}t        j                  |	  d{   }
g }g }d}d}g }g }t        |
|j                        D ]  \  }}|j                  r|j                  |j                         |j                  r|j                  |j                         |j                  rd}|j                  r|j!                  |j                         |j"                  du rd}g }g }g }|j                  r||j                  D ]m  }|j$                  r|j!                  |j&                         +|j(                  r|j!                  |j&                         S|j!                  |j&                         o t+        t-        |            t+        t-        |      t-        |      z
        t+        t-        |      t-        |      z
  t-        |      z
        d}g }|j                  r-d|j                  vr|j!                  d	|j                   d
       |j                  r|j!                  d       |j/                  d      r)|j!                  ddj                  |d         z   dz          |j/                  d      xs g }|rg }|j                  xs g D ]  }	 |j&                  |v ro|j(                  ct        |j(                        t        |j0                        k7  r8|j!                  |j&                   d|j0                   d|j(                   d        |r'|j!                  ddj                  |      z   dz          n&|j!                  ddj                  |      z   dz          |j/                  d      xs g }|r&|j!                  ddj                  |      z   dz          |dk7  r|j!                  d       dj                  |      }|j!                  t        |      |j                  xs g D cg c]  }|j5                          c}|j                  xs g |j"                  |j                  |j                  ||d        i }|D ]b  }|j/                  |j&                        }||||j&                  <   0dddd=d t6        f=fd!} ||       ||      kD  sT|||j&                  <   d t9        |j;                               }t        j                         |z
  } t=        d"t        |j                         d#| d$| d%d&       t?        dd'| d|||t+        t-        |            ||r|d(   nddddd|j                  D cg c]  }t        |       c}|tA        jB                         jE                         )      }!nKt        | ||||       d{   }!|!jF                  s(|j                  D cg c]  }t        |       c}|!_#        g }"g }#g }$|dk(  r|!jH                  r|!jH                  D ]D  }%tK        |%tL              s|%j/                  d*      xs i }&|&jO                         D ]*  \  }'}(|(r|"j!                  |'       |$j!                  |'       , |%j/                  d+      du r|"j!                  d,       n$|%j/                  d+      du r|$j!                  d,       |%j/                  d-      du r|"j!                  d.       n$|%j/                  d-      du r|$j!                  d.       |%j/                  d/      du r|"j!                  d0       |%j/                  d/      du s4|$j!                  d0       G t+        t-        |"            }"t+        t-        |$      t-        |"      z
        }$n|!j                  r||!j                  D ]m  }|j$                  r|"j!                  |j&                         +|j(                  r|#j!                  |j&                         S|$j!                  |j&                         o t+        t-        |"            }"t+        t-        |#      t-        |"      z
        }#t+        t-        |$      t-        |"      z
  t-        |#      z
        }$|"|#|$d|!_(        g >d[d1t        d2t        d3tR        t           d4tR        t           f>fd5})|dk(  r|!jH                  r|!jH                  D ]w  }%|%j/                  d6      xs i }*|*j/                  dg       D ]  }+ |)|+d        |*j/                  dg       D ]  }+ |)|+d        |*j/                  dg       D ]  }+ |)|+d        y nh|!j                  r\|!j                  D ]M  }|j&                  |"v rdn|j&                  |#v rdnd}, |)|j&                  |,|j0                  |j(                         O >|!_*        |dk7  rK|!jV                  s>	 |!jP                  r|!jP                  j/                  d      ng }-|!jP                  r|!jP                  j/                  d      ng }.|!jP                  r|!jP                  j/                  d      ng }/g }0|!j                  r-d|!j                  vr|0j!                  d	|!j                   d
       |!j                  r|0j!                  d       |-r&|0j!                  d7dj                  |-      z   dz          |.rg }|!j                  xs g D ]  }|j&                  |.v s|j(                  t        |j(                        t        |j0                        k7  sK|j!                  |j&                   d|j0                   d|j(                   d        |r'|0j!                  ddj                  |      z   dz          n&|0j!                  ddj                  |.      z   dz          |/r&|0j!                  ddj                  |/      z   dz          |dk7  r|0j!                  d       tY        |!d8dj                  |0             |dk(  r|!jH                  r	 |!jH                  xs g }1g }0t[        d9 |1D              }2|2r|0j!                  d:       n|0j!                  d;       g d<}3g }4g }5|3D ]9  ?t[        ?fd=|1D              r|4j!                  ?       )|5j!                  ?       ; |4r&|0j!                  d>dj                  |4      z   dz          |5r>t        |5      t        |3      k  r'|0j!                  d?dj                  |5      z   dz          n(t        |5      t        |3      k(  r|0j!                  d@       t[        dA |1D              r|0j!                  dB       n|0j!                  dC       t[        dD |1D              r|0j!                  dE       n|0j!                  dF       t]        dG |1D              }6|6d(k(  r$t[        dH |1D              r|0j!                  dI       n|6d(kD  r|0j!                  dJ|6 dK       |!j^                  du r|0j!                  dL       n8|!j`                  xs g }7|7r&|0j!                  dMdj                  |7      z   dz          t        |1      dk(  rS|1d(   }8tK        |8tL              rv|8j/                  dN      xs g }9|9r_|0j!                  dOdj                  |9      z   dz          n8|!jb                  xs g }:|:r&|0j!                  dPdj                  |:      z   dz          dj                  |0      |!_2        |dk7  rg }0	 ddQtg               v rr|d(   ndRvr&r$|0j!                  dSdj                  |       dT       dUtg               v rr|0j!                  dV       |"r&|0j!                  dWdj                  |"      z   dz          |#rg }|!j                  xs g D ]  }	 |j&                  |#v ro|j(                  ct        |j(                        t        |j0                        k7  r8|j!                  |j&                   d|j0                   d|j(                   d        |r'|0j!                  ddj                  |      z   dz          n&|0j!                  ddj                  |#      z   dz          |$r&|0j!                  ddj                  |$      z   dz          |dk7  r|0j!                  d       |!j5                         };dj                  |0      |;dX<   	 tY        |!dX|;dX          |!S |!S c c}w c c}w 7 # t2        $ r Y Pw xY wc c}w c c}w 7 _c c}w # t2        $ r Y w xY w# t2        $ r Y 5w xY w# t2        $ r Y w xY w# t2        $ r Y w xY w# t2        $ r Y |!S w xY w# t2        $ r}<t?        ddYt        |<       dg |j                   dk7  rdndt        |<      gdddddd|j                  D cg c]  }t        |       nc c}w c}tA        jB                         jE                         Z      cY d}<~<S d}<~<ww xY ww)\r   r   r[   r5   NTFr   rv   rw   rx   r~   rk   r   r   r   rp   r   r   r   r   r   r   rq   r   r   r   r   r   r   r   r   r   c                 \    | j                   rdndj                  | j                  d      fS r4   r   r   s    r$   r   z6verify_multi_documents_celery_withoutdb.<locals>.score  r   r9   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   rn   r   r   r   c                     |dk(  r|rd|  dnd|  d}n(|dk(  r|rd|  d| d| dnd|  d	}n|rd|  d
nd|  d}j                  | ||d       y r   r   r   s        r$   r   z8verify_multi_documents_celery_withoutdb.<locals>.explain  r   r9   r   r   r   c              3   b   K   | ]'  }t        |t              xr |j                  d        ) ywr   r   r   s     r$   ri   z:verify_multi_documents_celery_withoutdb.<locals>.<genexpr>A  r   r   r   r   r   c              3      K   | ]M  }t        |t              xr7 t        |j                  d       t              xr |d    j                        du  O ywr  r   r  s     r$   ri   z:verify_multi_documents_celery_withoutdb.<locals>.<genexpr>L  r  r  r	  r
  r  c              3   b   K   | ]'  }t        |t              xr |j                  d        ) ywr  r   r   s     r$   ri   z:verify_multi_documents_celery_withoutdb.<locals>.<genexpr>W  r  r   r  r  c              3   b   K   | ]'  }t        |t              xr |j                  d        ) ywr  r   r   s     r$   ri   z:verify_multi_documents_celery_withoutdb.<locals>.<genexpr>[  r  r   r  r  c              3   z   K   | ]3  }t        |t              st        |j                  d       xs g        5 ywr  r  r   s     r$   ri   z:verify_multi_documents_celery_withoutdb.<locals>.<genexpr>`  r  r  c              3   b   K   | ]'  }t        |t              xr |j                  d        ) ywr  r   r   s     r$   ri   z:verify_multi_documents_celery_withoutdb.<locals>.<genexpr>a  r  r   r   r!  r"  r#  r$  r%  r&  r'  r(  rM   r)  r*  r+  r,  r-  r   r.  r   r/  r0  r;  s@                                                                @@@r$   'verify_multi_documents_celery_withoutdbr  I  rk  rl  )2typingr   r   r   r   r   r   r	   r1  r(   fastapir
   r   r   sqlalchemy.ormr   #src.modules.prompt.schemas.requestsr   r   r   $src.modules.prompt.schemas.responsesr   r   r   r   src.utils.azure_openair   src.utils.pdf_parserr   pydanticr   src.core.loggingr   r+   r;   r   rE   floatrF   Lockr)   r%   r1   r>   r@   r   r   rj  rv  r  r6   r9   r$   <module>r     s   : : :    2 2 " c c a a P 6 /  #   57 T#uUD[112 7'7<<> 2 2s 2T 2c 2
 
 
7# 7T 7J) JBBB B 	BJf
f
f
 f
 &	f

 f
 f
Rj
j
2j
 j
 	j
\j
j
2j
 j
 	j
`j
j
2j
 j
 	j
r9   