
    y'Sj/                   ^   U d dl mZ d dlZd dlZd dlZd dlZd dlZd dlZd dlm	Z	 d dl
Z
d dlZd dlZd dlZd dlZd dlZd dlmZmZ d dlmZmZ d dlmZmZ d dlmZmZ d dlmZmZmZ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, d dl-m.Z.m/Z/m0Z0m1Z1m2Z2 d dl3m4Z4 d dl5m6Z6m7Z7m8Z8m9Z9m:Z:m;Z; e!rd dl<m=Z= d dl>m?Z?  ej                  eA      ZBe!rd dlCmDZD eeEef   ZFe#d   ZGde0 dZHde/ dZIde0 dZJdZKdZLej                  j                  dd      ZOdZPdeQd<   ddgZRdeQd<   d e4 d!ZSd"ZTej                  j                  d#$      ZWe G d% d&             ZX G d' d(      ZY G d) d*      ZZd+Z[d,Z\d-Z] G d. d/      Z^ G d0 d1      Z_ G d2 d3e`      Zae G d4 d5ea             Zbe G d6 d7eaec             Zddd8Zee G d9 d:             Zfe G d; d<ef             Zge G d= d>ef             Zhe G d? d@ef             Zi edAB       G dC dD             ZjdEdFgZkddGZl edAB       G dH dI             ZmdJZndKZodLZpddMZqddNZrdOddP	 	 	 	 	 	 	 	 	 ddQZsdRdS	 	 	 	 	 	 	 	 	 ddTZtddUZu G dV dWev      ZwddXZxddYZy	 	 	 	 	 	 ddZZz	 	 	 	 	 	 dd[Z{e G d\ d]             Z|e G d^ d_             Z}e	 d	 	 	 	 	 dd`       Z~e	 d	 	 	 	 	 dda       Z	 	 	 	 	 	 	 	 	 	 ddbZ	 	 	 	 	 	 	 	 	 	 ddcZd-ZddZdeZg dfZg dgZddhZg f	 	 	 	 	 ddiZg fddjZ	 	 d	 	 	 	 	 	 	 	 	 	 	 ddkZg dl	 	 	 	 	 	 	 	 	 	 	 ddmZg dl	 	 	 	 	 	 	 	 	 	 	 ddnZddoZ	 	 	 	 	 	 	 	 ddpZddqZ	 	 	 	 	 	 ddrZddsZ	 	 	 	 	 	 	 	 	 	 	 	 ddtZ	 	 	 	 	 	 	 	 	 	 	 	 dduZ	 	 	 	 	 	 	 	 ddvZ	 	 	 	 	 	 	 	 	 	 	 	 ddwZ	 	 	 	 	 	 	 	 ddxZ	 	 	 	 	 	 	 	 	 	 	 	 ddyZ	 	 	 	 ddzZ	 	 	 	 dd{Zdd}ZddZ edAB       G d d|ej             Z edAB       G d d~ej             Z edAB       G d d             Z edAB       G d d             ZddZddZdddZy)    )annotationsN)Path)asynccontextmanagercontextmanager)datetimetimezone)	dataclassfield)cached_propertypartial)	AnyAsyncIteratorDictIteratorTYPE_CHECKINGOptionalLiteralCallableUnion)	urlencode)aconnect_sseconnect_sse)AuthCredentialsFAL_QUEUE_RUN_HOSTFAL_RUN_HOSTMissingCredentialsErrorfetch_auth_credentials)__version__)Priorityadd_priority_headeradd_timeout_headeradd_hint_headerREQUEST_TIMEOUT_TYPE_HEADERREQUEST_TIMEOUT_HEADER)WebSocketClientProtocol)
Connection)Image)fal_v3cdnfalzhttps:///zwss://zhttps://rest.fal.aizhttps://v3.fal.mediaFAL_CDN_HOSTzhttps://fal.mediar(   UploadRepositoryIdDEFAULT_UPLOAD_REPOSITORYr)   r*   list[UploadRepositoryId]"DEFAULT_UPLOAD_FALLBACK_REPOSITORYzfal-client/z	 (python)   FAL_CLIENT_EXECUTOR)thread_name_prefixc                  >    e Zd ZU ded<   ded<   ded<   ded<   d	dZy)
CDNTokenstrtoken
token_typebase_upload_urlr   
expires_atc                b    t        j                  t        j                        | j                  k\  S N)r   nowr   utcr:   selfs    D/root/.hermes/venv/lib/python3.12/site-packages/fal_client/client.py
is_expiredzCDNToken.is_expired[   s    ||HLL)T__<<    N)returnbool)__name__
__module____qualname____annotations__rB    rC   rA   r5   r5   T   s    JO=rC   r5   c                  $    e Zd ZddZddZddZy)CDNTokenManagerc                   || _         t        dddt        j                  j	                  t
        j                              | _        t        j                         | _
        t         d| _        | j                   j                  ddd| _        y N )tzinfor7   r8   r9   r:   z+/storage/auth/token?storage_type=fal-cdn-v3application/jsonAuthorizationAcceptContent-Type)_authr5   r   minreplacer   r>   _token	threadingLock_lockREST_URL_urlheader_value_headersr@   auths     rA   __init__zCDNTokenManager.__init__`   sr    
 (||++8<<+@	!
 &/^^%5
j KL	!ZZ44(.
rC   c           	     @   t        j                         5 }|j                  | j                  | j                  i       }|j                          |j                         }d d d        t        d   |d   |d   t        j                  |d               S # 1 sw Y   7xY wNheadersjsonr7   r8   base_urlr:   rQ   )
httpxClientpostr_   ra   raise_for_statusri   r5   r   fromisoformatr@   clientresponsedatas       rA   _refresh_tokenzCDNTokenManager._refresh_tokenp   s    \\^ 	#v{{499dmm"{MH%%'==?D	#
 w-L) ,--d<.@A	
 	
	# 	#s   A	BBc                    | j                   5  | j                  j                         r| j                         | _        | j                  cd d d        S # 1 sw Y   y xY wr<   r]   rZ   rB   rt   r?   s    rA   	get_tokenzCDNTokenManager.get_token}   sE    ZZ 	{{%%'"113;;	 	 	s   ;AANrc   r   rD   NonerD   r5   rF   rG   rH   rd   rt   rw   rJ   rC   rA   rL   rL   _       
 
rC   rL   c                  $    e Zd ZddZddZddZy)AsyncCDNTokenManagerc                   || _         t        dddt        j                  j	                  t
        j                              | _        t        j                         | _
        t         d| _        | j                   j                  ddd| _        y rN   )rW   r5   r   rX   rY   r   r>   rZ   asyncior\   r]   r^   r_   r`   ra   rb   s     rA   rd   zAsyncCDNTokenManager.__init__   sq    
 (||++8<<+@	!
 $+<<>
j KL	!ZZ44(.
rC   c           	       K   t        j                         4 d {   }|j                  | j                  | j                  i        d {   }|j                          |j                         }d d d       d {    t        d   |d   |d   t        j                  |d               S 7 7 d7 6# 1 d {  7  sw Y   FxY wwrf   )
rk   AsyncClientrm   r_   ra   rn   ri   r5   r   ro   rp   s       rA   rt   z#AsyncCDNTokenManager._refresh_token   s     $$& 	# 	#&#[[DMMPR[SSH%%'==?D	# 	#
 w-L) ,--d<.@A	
 	
	#S	# 	# 	# 	#sV   C	B.C	,B4B0$B40C	;B2<3C	0B42C	4C:B=;CC	c                  K   | j                   4 d {    | j                  j                         r| j                          d {   | _        | j                  cd d d       d {    S 7 X7 (7 	# 1 d {  7  sw Y   y xY wwr<   rv   r?   s    rA   rw   zAsyncCDNTokenManager.get_token   sj     :: 	 	{{%%'$($7$7$99;;	 	 	9	 	 	 	sV   BA,B.A2A.A2B&A0'B.A20B2B8A;9B BNrx   rz   r{   rJ   rC   rA   r~   r~      r|   rC   r~   i  @i   
   c                      e Zd Zdddd	 	 	 	 	 	 	 	 	 	 	 	 	 ddZedd       Zedd       Zedd       Zd ZddZ	dd	Z
edddd
	 	 	 	 	 	 	 	 	 	 	 	 	 dd       Zedddd	 	 	 	 	 	 	 	 	 	 	 	 	 dd       Zy)MultipartUploadN
chunk_sizecontent_typemax_concurrencyc                   || _         || _        || _        |xs t        | _        |xs d| _        |xs t        | _        d | _        d | _	        g | _
        y Napplication/octet-stream	file_name_client_token_managerMULTIPART_CHUNK_SIZEr   r   MULTIPART_MAX_CONCURRENCYr   _access_url
_upload_id_partsr@   r   rq   token_managerr   r   r   s          rA   rd   zMultipartUpload.__init__   Y     #+$<(<(F,F.K2K'+&*"$rC   c                H    | j                   st        d      | j                   S NzUpload not initiatedr   
ValueErrorr?   s    rA   
access_urlzMultipartUpload.access_url   #    344rC   c                H    | j                   st        d      | j                   S r   r   r   r?   s    rA   	upload_idzMultipartUpload.upload_id       344rC   c                r    | j                   j                         }|j                   d|j                   ddS N z	fal/0.1.0rT   z
User-Agentr   rw   r8   r7   r@   r7   s     rA   auth_headerszMultipartUpload.auth_headers   s<    ##--/ % 0 015;;-@%
 	
rC   c           
        | j                   j                         }|j                   d}t        | j                  d|i | j
                  d| j                  | j                  d      }|j                         }|d   | _	        |d   | _
        y Nz/files/upload/multipartPOSTrR   )rU   rV   X-Fal-File-Namerh   r   uploadId)r   rw   r9   _maybe_retry_requestr   r   r   r   ri   r   r   )r@   r7   urlrr   results        rA   createzMultipartUpload.create   s    ##--/&&''>?'LL##, $ 1 1#'>>		

 !,/ ,rC   c           	        | j                    d| j                   d| }t        | j                  d|i | j                  | j
                  dd|d       }|j                  d   }| j                  j                  ||d       y 	N/multipart/r+   PUTidentity)rV   zAccept-Encoding)rh   contenttimeoutetag)
partNumberr   )	r   r   _requestr   r   r   rh   r   append)r@   part_numberrs   r   rr   r   s         rA   upload_partzMultipartUpload.upload_part   s    !T^^,<Ak]KLL## $ 1 1#-
 
 ')	
rC   c                    | j                    d| j                   d}t        | j                  d|| j                  d| j
                  i       | j                   S Nr   z	/completer   partsrg   )r   r   r   r   r   r   )r@   r   s     rA   completezMultipartUpload.complete  sT    !T^^,<IFLL%%4;;'	
 rC   r   r   r   c          	     ~   dd l } | ||||||      }	|	j                          t        j                  t	        |      |	j
                  z        }
|j                  j                  |	j                        5 }g }t        d|
dz         D ]R  }|dz
  |	j
                  z  }||||	j
                  z    }|j                  |j                  |	j                  ||             T |j                  j                  |      D ]  }|j                           	 d d d        |	j                         S # 1 sw Y   |	j                         S xY w)Nr   r   rq   r   r   r   r   max_workersr1   )concurrent.futuresr   mathceillenr   futuresThreadPoolExecutorr   ranger   submitr   as_completedr   r   )clsrq   r   r   rs   r   r   r   
concurrent	multipartr   executorr   r   startfutures                   rA   savezMultipartUpload.save  s<    	"'!%+
	 			#d)i&:&::;22!11 3 
 	 G$Q	2 $qI,@,@@EEI,@,@$@AOOI$9$9;M %,,99'B   	  !!##	  !!##s   4BD$$D<c                  dd l }t        j                  j                        }t        j                  j	                        }	 | ||||||      j                          t        j                  |	j                  z        }
|j                  j                  j                        5 }g }t        d|
dz         D ]*  }dfd}|j                  |j                  ||             , |j                  j                  |      D ]  }|j!                           	 d d d        j#                         S # 1 sw Y   j#                         S xY w)Nr   r   r   r1   c                    t        d      5 }| dz
  j                  z  }|j                  |       |j                  j                        }j	                  | |       d d d        y # 1 sw Y   y xY wNrbr1   openr   seekreadr   )pnfr   rs   	file_pathr   s       rA   _upload_partz/MultipartUpload.save_file.<locals>._upload_partQ  sg    i. 8!!#a9+?+? ?u vvi&:&:;!--b$7	8 8 8s   AA((A1)r   intrD   ry   )r   ospathbasenamegetsizer   r   r   r   r   r   r   r   r   r   r   r   r   )r   rq   r   r   r   r   r   r   r   sizer   r   r   r   r   r   r   s      `            @rA   	save_filezMultipartUpload.save_file2  s2    	"GG$$Y/	wwy)'!%+
	 			$!5!55622!11 3 
 	 G$Q	2 	K8 x|[IJ	K %,,99'B   	   !!##!	   !!##s   +A/D33E)r   r6   rq   httpx.Clientr   rL   r   
int | Noner   
str | Noner   r   rD   ry   rD   r6   rD   dict[str, str]r   r   rs   bytesrD   ry   )rq   r   r   rL   r   r6   rs   r   r   r   r   r   r   r   )rq   r   r   rL   r   
str | Pathr   r   r   r   r   r   rD   r6   rF   rG   rH   rd   propertyr   r   r   r   r   r   classmethodr   r   rJ   rC   rA   r   r      sn    "&#'&*% % 	%
 '% % !% $% 
%(    
  
 
 
-$
0	  $(!%&*#$ #$ '	#$
 #$ #$ !#$ #$ $#$ #$J  "&#'&*($ ($ '	($
 ($ ($ !($ $($ 
($ ($rC   r   c                      e Zd Zdddd	 	 	 	 	 	 	 	 	 	 	 	 	 ddZedd       Zedd       Zedd       Zd ZddZ	dd	Z
edddd
	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dd       Zedddd	 	 	 	 	 	 	 	 	 	 	 	 	 dd       Zy)AsyncMultipartUploadNr   c                   || _         || _        || _        |xs t        | _        |xs d| _        |xs t        | _        d | _        d | _	        g | _
        y r   r   r   s          rA   rd   zAsyncMultipartUpload.__init___  r   rC   c                H    | j                   st        d      | j                   S r   r   r?   s    rA   r   zAsyncMultipartUpload.access_urls  r   rC   c                H    | j                   st        d      | j                   S r   r   r?   s    rA   r   zAsyncMultipartUpload.upload_idy  r   rC   c                   K   | j                   j                          d {   }|j                   d|j                   ddS 7 "wr   r   r   s     rA   r   z!AsyncMultipartUpload.auth_headers  sH     ))3355 % 0 015;;-@%
 	
 6s   AA#Ac           
     d  K   | j                   j                          d {   }|j                   d}| j                   d {   }t	        | j
                  d|i |d| j                  | j                  d       d {   }|j                         }|d   | _	        |d   | _
        y 7 7 h7 -wr   )r   rw   r9   r   _async_maybe_retry_requestr   r   r   ri   r   r   )r@   r7   r   rh   rr   r   s         rA   r   zAsyncMultipartUpload.create  s     ))3355&&''>?)))3LL, $ 1 1#'>>		

 

 !,/ ,! 6)

s3   B0B*"B0B,<B0 B.*B0,B0.B0c           	     :  K   | j                    d| j                   d| }| j                   d {   }t        | j                  d|i || j
                  dd|d        d {   }|j                  d   }| j                  j                  ||d       y 7 f7 4wr   )	r   r   r   _async_requestr   r   rh   r   r   )r@   r   rs   r   rh   rr   r   s          rA   r   z AsyncMultipartUpload.upload_part  s     !T^^,<Ak]K)))'LL $ 1 1#-
 
 
 ')	
! *
s!   .BB3B$B%3BBc                   K   | j                    d| j                   d}| j                   d {   }t        | j                  d||d| j
                  i       d {    | j                   S 7 >7 wr   )r   r   r   r  r   r   )r@   r   rh   s      rA   r   zAsyncMultipartUpload.complete  su     !T^^,<IF)))(LL4;;'
 	
 	
  *	
s!   ,A1A--A1A/A1/A1r   c                 K    | ||||||      j                          d {    t        j                  t              j                  z        }dfd}	t        d|dz         D 
cg c]  }
t        j                   |	|
             }}
t        j                  j                        fd}t        j                  |D cg c]
  } ||       c}  d {    j                          d {   S 7 c c}
w c c}w 7 (7 w)Nr   c                   K   | dz
  j                   z  }||j                   z    }j                  | |       d {    y 7 w)Nr1   )r   r   )r   r   chunkrs   r   s      rA   r   z.AsyncMultipartUpload.save.<locals>.upload_part  sH      1_	(<(<<E)=)=!=>E''U;;;s   :AAAr1   c                   K   4 d {    |  d {    d d d       d {    y 7 7 7 	# 1 d {  7  sw Y   y xY wwr<   rJ   tasksems    rA   bounded_uploadz1AsyncMultipartUpload.save.<locals>.bounded_upload  D       

     D   A*A0,0A.A0AA9AAr   r   rD   ry   )r   r   r   r   r   r   r   create_task	Semaphorer   gatherr   )r   rq   r   r   rs   r   r   r   r   r   r   tasksr  r
  r   r  s       `         @@rA   r   zAsyncMultipartUpload.save  s      '!%+
	    		#d)i&:&::;	<  %Q	2
 K 89
 
 	 9 9:	 nnF~d3FGGG'')))+ 	!
 GG)sL   "DC=AD/"C?9D
DD D	!D8D9D?DDc                 K   t         j                  j                        }t         j                  j                        } | ||||||      j	                          d {    t        j                  |j                  z        }	dfd}
t        d|	dz         D cg c]  }t        j                   |
|             }}t        j                  j                        fd}t        j                  |D cg c]
  } ||       c}  d {    j                          d {   S 7 c c}w c c}w 7 (7 w)Nr   c                  K   t        d      5 }| dz
  j                  z  }|j                  |       |j                  j                        }j	                  | |       d {    d d d        y 7 # 1 sw Y   y xY wwr   r   )r   r   r   rs   r   r   s       rA   r   z3AsyncMultipartUpload.save_file.<locals>.upload_part  s{     i& ?!$qI,@,@@uvvi223++K>>>	? ? ?	? ?s/   B AA4$A2%A4)	B 2A44A=9B r1   c                   K   4 d {    |  d {    d d d       d {    y 7 7 7 	# 1 d {  7  sw Y   y xY wwr<   rJ   r	  s    rA   r  z6AsyncMultipartUpload.save_file.<locals>.bounded_upload  r  r  r  )r   r   r   r   r   r   r   r   r   r   r  r  r   r  r   )r   rq   r   r   r   r   r   r   r   r   r   r   r  r  r
  r   r  s      `           @@rA   r   zAsyncMultipartUpload.save_file  s!     GG$$Y/	wwy)'!%+
	    		$!5!556	?  %Q	2
 K 89
 
 	 9 9:	 nnF~d3FGGG'')))/ 	!
 GG)sN   A E%D2&>E$"D49E?D9ED>E-E .E4E E)r   r6   rq   httpx.AsyncClientr   r~   r   r   r   r   r   r   rD   ry   r   r   r   )rq   r  r   r~   r   r6   rs   r   r   r   r   r   r   r   rD   r6   )rq   r  r   r~   r   r   r   r   r   r   r   r   rD   r6   r   rJ   rC   rA   r   r   ^  sx    "&#'&*% % "	%
 ,% % !% $% 
%(    
  
 
 
-&
2
  $(!%&*(* "(* ,	(*
 (* (* !(* (* $(* 
(* (*T  "&#'&*+* "+* ,	+*
 +* +* !+* $+* 
+* +*rC   r   c                      e Zd Zy)FalClientErrorNrF   rG   rH   rJ   rC   rA   r  r    s    rC   r  c                  >    e Zd ZU ded<   ded<   ded<   ded<   dd	Zy
)FalClientHTTPErrorr6   messager   status_coder   response_headershttpx.Responserr   c                    | j                    S r<   )r  r?   s    rA   __str__zFalClientHTTPError.__str__$  s    ,, rC   Nr   )rF   rG   rH   rI   r"  rJ   rC   rA   r  r    s    L$$!rC   r  c                  .    e Zd ZU ded<   dZded<   ddZy)FalClientTimeoutErrorfloatr   NOptional[str]
request_idc                t    | j                   d| j                   dS d| j                    d| j                   dS )NzRequest timed out after z secondszRequest z timed out after )r'  r   r?   s    rA   r"  zFalClientTimeoutError.__str__-  s>    ??"-dll^8DDdoo..?~XVVrC   r   )rF   rG   rH   rI   r'  r"  rJ   rC   rA   r$  r$  (  s    N $J$WrC   r$  c                "   	 | j                          y # t        j                  $ rh}	 | j                         d   }n!# t        t
        f$ r | j                  }Y nw xY wt        || j                  t        | j                        |       |d }~ww xY w)Ndetailrr   )rn   rk   HTTPStatusErrorri   r   KeyErrortextr  r  dictrh   )rr   excmsgs      rA   _raise_for_statusr2  4  s    !!#   	 --/(+CH% 	 --C	  !   !!"
 	s/    B;B	AB	A0B		Bc                      e Zd Zy)StatusNr  rJ   rC   rA   r4  r4  G  s    rC   r4  c                      e Zd ZU dZded<   y)QueuedzIndicates the request is enqueued and waiting to be processed. The position
    field indicates the relative position in the queue (0-indexed).r   positionN)rF   rG   rH   __doc__rI   rJ   rC   rA   r6  r6  K  s    G MrC   r6  c                  *    e Zd ZU dZ e       Zded<   y)
InProgresszIndicates the request is currently being processed. If the status operation called
    with the `with_logs` parameter set to True, the logs field will be a list of
    log objects.list[dict[str, Any]] | NonelogsN)rF   rG   rH   r8  r
   r<  rI   rJ   rC   rA   r:  r:  S  s    
 ).D
%/rC   r:  c                  B    e Zd ZU dZ e       Zded<    e       Zded<   y)	Completeda2  Indicates the request has been completed and the result can be gathered. The logs field will
    contain the logs if the status operation was called with the `with_logs` parameter set to True. Metrics
    might contain the inference time, and other internal metadata (number of tokens
    processed, etc.).r;  r<  dict[str, Any]metricsN)rF   rG   rH   r8  r
   r<  rI   r@  rJ   rC   rA   r>  r>  ]  s"    
 ).D
%/#gG^%rC   r>  T)frozenc                  t    e Zd ZU ded<    ed      Zded<    ed      Zded<    ed      Zded<   d
dZy	)_BaseRequestHandler6   r'  Freprresponse_url
status_url
cancel_urlc                    |d   dk(  rt        |d         S |d   dk(  rt        |d         S |d   dk(  r"|j                  d	i       }t        |d   |
      S t	        d|d          )NstatusIN_QUEUEqueue_position)r7  IN_PROGRESSr<  )r<  	COMPLETEDr@  )r<  r@  zUnknown status: )r6  r:  getr>  r   )r@   rs   r@  s      rA   _parse_statusz _BaseRequestHandle._parse_statuso  s    >Z'4(8#9::(^},4<00(^{*hhy"-G$v,@@/X/?@AArC   N)rs   AnyJSONrD   r4  )	rF   rG   rH   rI   r
   rF  rG  rH  rP  rJ   rC   rA   rC  rC  h  s:    O5)L#)'J''J'
BrC   rC  	workflowscomfyc                    dd l }| j                  d      }t        |      dkD  r| S |j                  d|       }|r|j	                         \  }}| d| S t        d|  d      )Nr   r+   r1   z^([0-9]+)-([a-zA-Z0-9-]+)$zInvalid app id: z*. Must be in the format <appOwner>/<appId>)resplitr   matchgroupsr   )idrU  r   rW  	app_ownerapp_ids         rA   _ensure_app_id_formatr\    sm    HHSME
5zA~	HH2B7E!LLN	6AfX&&
't+UV
WWrC   c                  H    e Zd ZU ded<   ded<   ded<   ded<   ed	d       Zy)
AppIdr6   owneraliasr&  r   	namespacec           	         t        |      }|j                  d      }|d   t        v r+ | |d   |d   dj                  |dd        xs d |d         S  | |d   |d   dj                  |dd        xs d d       S )Nr+   r   r1         )r_  r`  r   ra  )r\  rV  APP_NAMESPACESjoin)r   endpoint_idnormalized_idr   s       rA   from_endpoint_idzAppId.from_endpoint_id  s    -k:##C(8~%AhAhXXeABi(0D(	  ((%)$,	
 	
rC   N)rg  r6   rD   r^  )rF   rG   rH   rI   r   ri  rJ   rC   rA   r^  r^    s*    JJ

 
rC   r^  x   g     V@)r1   <   c                    | j                   r| j                    dnd}| j                  rd| j                   nd}| | j                   d| j                   | S )Nr+   rO   )ra  r   r_  r`  )r[  prefixsuffixs      rA   _format_app_pathro    sX    '-'7'7  !#RF"(++q2FXfll^1V\\N6(;;rC   c                n    | y t         \  }}|| cxk  r|k  sn t        d| d| d      t        |       S )Nzmax_buffering must be between z and z (inclusive))REALTIME_MAX_BUFFERINGr   r6   )value	min_value	max_values      rA   _serialize_max_bufferingru    sL    }1Iy+)+,YKuYK|T
 	
 u:rC   rO   r   max_bufferingc                   t         j                  |       }t        |      }t         | }|r|d|j	                  d      z   z  }i }|r||d<   t        |      }|||d<   |r| dt        |       S |S )Nr+   fal_jwt_tokenrw  ?)r^  ri  ro  REALTIME_URL_FORMATlstripru  r   )	applicationr7   r   rw  r[  app_pathr   queryserialized_bufferings	            rA   _build_runner_ws_urlr    s     ##K0F'H !(
,CsT[[%%%E!&o3MB'!5oa	%()**JrC   realtimer   c                    t        | |||      S )Nrv  )r  )r}  r7   rw  r   s       rA   _build_realtime_urlr    s      #	 rC   c                    t        | t              r| S t        | t              rHt        | j                  d      t              r| d   S t        | j                  d      t              r| d   S t	        d      )Nr7   r*  z)Unexpected realtime token response format)
isinstancer6   r/  rO  RuntimeError)rs   s    rA   _parse_token_responser    sa    $$dhhw'-= dhhx(#.>!
B
CCrC   c                  4     e Zd ZdZ	 	 d	 	 	 	 	 d fdZ xZS )RealtimeErrorz9Raised when the realtime endpoint sends an error payload.c                    || _         |xs d| _        |xs i | _        | j                  s|n| d| j                   }t        |   |       y )NrO   z: )errorreasonpayloadsuperrd   )r@   r  r  r  r  	__class__s        rA   rd   zRealtimeError.__init__  sK     
l}"#{{%5'DKK=0I!rC   )NN)r  r6   r  r   r  zOptional[dict[str, Any]])rF   rG   rH   r8  rd   __classcell__)r  s   @rA   r  r    s4    C
 ",0	
"
" 
" *	
" 
"rC   r  c                0    dd l }|j                  | d      S )Nr   F)raw)msgpackunpackbr  r  s     rA   msgpack_decode_messager    s    ??7?..rC   c                0    dd l }|j                  | d      S )Nr   T)use_bin_type)r  packbr  s     rA   msgpack_encode_messager    s    ==t=44rC   c                   t        | t              r| j                         } t        | t        t        f      r|xs t
        } ||       S t        | t              r`	 t        j                  |       }|j                  d      }|dk(  r,t        |j                  dd      |j                  d      |      |dk(  ry |S d	| iS # t        j                  $ r d| dcY S w xY w)
Nr.  )typer  r  zx-fal-errorr  UNKNOWN_ERRORr  zx-fal-messager  )r  
memoryviewtobytesr   	bytearrayr  r6   ri   loadsJSONDecodeErrorrO  r  )r  decode_messagedecoder  msg_types        rA   _decode_realtime_messager    s     ':&//#'E9-.9#9g'3	8jj)G ;;v&}$G_5H% 
 &w ## 	8"w77	8s   B= =CCc                &    |xs t         } ||       S r<   )r  )r  encode_messageencodes      rA   _encode_realtime_messager  -  s     55F'?rC   c                  `    e Zd ZU dZded<   dZded<   dZded<   dd	Zdd
ZddZ	ddZ
ddZy)RealtimeConnectionz(Synchronous realtime connection wrapper.z'Connection'_wsNCallable[[Any], bytes] | None_encode_messageCallable[[bytes], Any] | None_decode_messagec                f    t        || j                        }| j                  j                  |       y r<   r  r  r  sendr@   	argumentsr  s      rA   r  zRealtimeConnection.send=  s$    *9d6J6JKgrC   c                
   	 	 | j                   j                         }t        || j                        }|5|S # t        $ rA}ddlm}m} t        ||      rY d }~y t        ||      rt        dt        |            | d }~ww xY wNr   )ConnectionClosedConnectionClosedOKCONNECTION_CLOSEDr  recv	Exceptionwebsockets.exceptionsr  r  r  r  r6   r  r  r@   rr   r0  r  r  decodeds         rA   r  zRealtimeConnection.recvA  s    88==? /x9M9MNGN  

 c#56c#34'(;SXFCO
s   8 	BA=#A==Bc                X    t        | j                  dd       }t        |      r |        y y Nclosegetattrr  callabler@   r  s     rA   r  zRealtimeConnection.closeU  s%    '40E?G rC   c                    | S r<   rJ   r?   s    rA   	__enter__zRealtimeConnection.__enter__Z  s    rC   c                $    | j                          y r<   r  r@   exc_typer0  tbs       rA   __exit__zRealtimeConnection.__exit__]  s    

rC   r  r?  rD   ry   rD   dict[str, Any] | NonerD   ry   )rD   r  )rF   rG   rH   r8  rI   r  r  r  r  r  r  r  rJ   rC   rA   r  r  5  s:    2	59O2959O29(
rC   r  c                  `    e Zd ZU dZded<   dZded<   dZded<   dd	Zdd
ZddZ	ddZ
ddZy)AsyncRealtimeConnectionz)Asynchronous realtime connection wrapper.z'WebSocketClientProtocol'r  Nr  r  r  r  c                   K   t        || j                        }| j                  j                  |       d {    y 7 wr<   r  r  s      rA   r  zAsyncRealtimeConnection.sendi  s.     *9d6J6JKhhmmG$$$s   5?=?c                &  K   	 	 | j                   j                          d {   }t        || j                        }|=|S 7 # t        $ rA}ddlm}m} t        ||      rY d }~y t        ||      rt        dt        |            | d }~ww xY wwr  r  r  s         rA   r  zAsyncRealtimeConnection.recvm  s     !%0 /x9M9MNGN 1 

 c#56c#34'(;SXFCO
sC   BA AA BA 	BB	!B&#B		BBc                t   K   t        | j                  dd       }t        |      r |        d {    y y 7 wr  r  r  s     rA   r  zAsyncRealtimeConnection.close  s0     '40E?'MM s   -868c                   K   | S wr<   rJ   r?   s    rA   
__aenter__z"AsyncRealtimeConnection.__aenter__  s     s   c                @   K   | j                          d {    y 7 wr<   r  r  s       rA   	__aexit__z!AsyncRealtimeConnection.__aexit__  s     jjls   r  r  r  )rD   r  )rF   rG   rH   r8  rI   r  r  r  r  r  r  r  rJ   rC   rA   r  r  a  s:    3	""59O2959O29%(
rC   r  c              #  |   K   ddl m} |j                  | |t        d       5 }| d d d        y # 1 sw Y   y xY ww)Nr   )rq   additional_headersopen_timeoutmax_size)websockets.syncrq   connectREALTIME_OPEN_TIMEOUT)r   rh   rq   wss       rA   _connect_sync_wsr    sF      '	"*	 
 
 
 
  s    <0	<9<c                  K   dd l }|j                  | |t        d       4 d {   }| d d d       d {    y 7 7 # 1 d {  7  sw Y   y xY ww)Nr   r  )
websocketsr  r  )r   rh   r  r  s       rA   _connect_async_wsr    sc      !!"*	 "   
 
      s@   "A?AAAAAAA	A
AAc                D     | j                   ||fi |}t        |       |S r<   requestr2  rq   methodr   kwargsrr   s        rA   r   r     s(     v~~fc4V4HhOrC   c                `   K    | j                   ||fi | d {   }t        |       |S 7 wr<   r  r  s        rA   r  r    s4      $V^^FC:6::HhO ;s   .,.皙?   )i  i  i  )i  i    c                f    | j                   t        vryd| j                  v ryd| j                  v ryy)z-Tell apart ingress errors from client errors.Fzx-fal-request-idnginxT)r  INGRESS_ERROR_CODESrh   r.  r+  s    rA   _is_ingress_errorr    s;     #66X--- (--rC   c                    | j                   dk(  r | j                  j                  t              ryt	        |       ry| j                   t
        v s| j                   |v ryy)Nr  FT)r  rh   rO  r#   r  RETRY_CODES)rr   extra_retry_codess     rA   _should_retry_responser    sZ    
 s"x'7'7';';#( "{*h.B.BFW.WrC   c                n   t        | t        j                        r;	 | j                  }t        |t        j                        rt
        |j                  v ryyt        | t        j                        ryt        | t        j                  t        f      rt        | j                  |      S y# t        $ r Y yw xY w)NFT)r  rk   TimeoutExceptionr  Requestr$   rh   r  TransportErrorr,  r  r  rr   )r0  r  r  s      rA   _should_retryr    s    #u--.	kkG'5==1)W__<  #u++,#--/ABC%cll4EFF  		s   8B( (	B43B4c                    |dk(  rt        |d| dz
  z  z  |      }nt        ||      }|r|t        j                  dd      z  }t        ||      S )Nexponentialrc  r1   g      ?g      ?)rX   randomuniform)	num_retry
base_delay	max_delaybackoff_typejitterdelays         rA   _get_retry_delayr    sW     }$J!	A"67CJ	*S))ui  rC   )r  c                  t        dt        dz         D ]  }	 t        | ||fi |c S  t        d      # t        j                  t
        f$ rr}t        ||      r`|t        k  rWt        |t        t        dd      }t        j                  d| d| dt        |z
   d       t        j                  |       Y d }~ d }~ww xY w)	Nr1   r  TRetrying request to  due to  ( attempts left)Failed to perform request)r   MAX_ATTEMPTSr   rk   	HTTPErrorr  r  r  
BASE_DELAY	MAX_DELAYloggerdebugtimesleepr  rq   r  r   r  r  attemptr0  r  s           rA   r   r     s     L1,- 	FFC:6:: 2
33 !34 
	S"34<9O(ZM4 *3%xuB|g?U>VVef 

5!
	s   4B?A'B:9B::B?c                 K   t        dt        dz         D ]  }	 t        | ||fi | d {   c S  t        d
      7 # t        j                  t
        f$ rs}t        ||      ra|t        k  rXt        |dddd      }t        j                  d| d| dt        |z
   d	       t        j                  |       d {  7   Y d }~ d }~ww xY ww)Nr1   r  r   r  Tr  r  r  r  r  )r   r  r  rk   r  r  r  r  r  r  r   r  r  r  s           rA   r  r  (  s      L1,- 
	'FvFFF 2
33 G!34 	S"34<9O(#r=$O*3%xuB|g?U>VVef mmE***	sN   CA >A CA  CA"C;B><CCCCCc                r    | j                   j                         dk(  rd| j                   S | j                  S )NkeyzBearer )schemelowerr7   r`   rc   s    rA   _cdn_auth_headerr%  @  s4    {{e#%%rC   c                0    |t        |       d}|||d<   |S )N)rV   rT   r   )r%  )rc   r   r   rh   s       rA   _cdn_upload_headersr'  F  s*      ,>Nt>TUG%.!"NrC   c                "    | j                   dddS )NrR   rS   )r`   r$  s    rA   _storage_upload_headersr)  O  s    **$* rC   c                    h d}| t         } |t        }nt        |t              s|g}| g|}g }|D ]+  }||vrt	        d| d      ||vs|j                  |       - |S )N>   r)   r*   r(   zUnsupported upload repository '')r.   r0   r  listr   r   )
repositoryfallback_repositoryallowedordereddedupedentrys         rA   _normalize_upload_repositoriesr3  W  s     'G.
"@+T2230/0G(*G ">ugQGHHNN5!	"
 NrC   c                    | xs d|dS )N
upload.binr   r   rJ   r6  s     rA   _storage_upload_payloadr7  n  s    .,$ rC   c          	         t        | dt         dt        ||      t        |            }|j	                         }|d   }|d   }t        | d||d|id        |S 	Nr   z)/storage/upload/initiate?storage_type=gcs)ri   rh   
upload_urlfile_urlr   rV   )r   rh   r   )r   r^   r7  r)  ri   	rq   rc   rs   r   r   init_responseinit_resultr:  r;  s	            rA   _upload_via_storager?  u  s{     )*=>$Y='-M  $$&K\*J:&H. OrC   c          	        K   t        | dt         dt        ||      t        |             d {   }|j	                         }|d   }|d   }t        | d||d|id        d {    |S 7 ;7 wr9  )r  r^   r7  r)  ri   r<  s	            rA   _async_upload_via_storagerA    s      5*=>$Y='- M  $$&K\*J:&H
$.   O%s!   .A0A,4A0%A.&A0.A0c               V    t        | dt        dz   ||      }|j                         d   S Nr   z/files/upload)r   rh   r   )r   CDN_URLri   rq   rs   rh   rr   s       rA   
_upload_v3rF    s5     $/!H ==?<((rC   c               l    t        | dt        dz   |t        |||            }|j                         d   S rC  )r   FAL_CDN_FALLBACK_URLr'  ri   rq   rc   rs   r   r   rr   s         rA   _upload_cdnrJ    s>     $.#D,	BH ==?<((rC   c               r   K   t        | dt        dz   ||       d {   }|j                         d   S 7 wrC  )r  rD  ri   rE  s       rA   _async_upload_v3rL    sC      0/! H ==?<((s   757c                  K   t        | dt        dz   |t        |||             d {   }|j                         d   S 7 wrC  )r  rH  r'  ri   rI  s         rA   _async_upload_cdnrN    sL      0.#D,	B H ==?<((s   &AA Ac           	         t        |       D ]  \  }\  }}	  |       c S  t        d      # t        $ r=}|t        |       dz
  k\  r t        j	                  d|| |dz      d   |       Y d }~`d }~ww xY wNr1   z+Upload failed to %s, falling back to %s: %sr   zUpload attempts were exhausted)	enumerater  r   r  warningr  )attemptsidxlabelr  r0  s        rA   _try_upload_with_fallbackrV    s     "+8!4 eW
	9 7
88  	c(ma''NN=q!!$	 	s   +	A13A,,A1c           	     :  K   t        |       D ]4  \  }\  }}	  |       }t        j                  |      r| d {   c S |c S  t        d      7 # t        $ r=}|t	        |       dz
  k\  r t
        j                  d|| |dz      d   |       Y d }~d }~ww xY wwrP  )rQ  r   iscoroutiner  r   r  rR  r  )rS  rT  rU  r  r   r0  s         rA   _async_try_upload_with_fallbackrY    s      "+8!4 eW	YF""6*#|#M 7
88 $ 	c(ma''NN=q!!$	 	sI   B!AAAB ABA	B3BBBBSyncRequestHandlec                D    	 | j                          y # t        $ r Y y w xY wr<   cancelr  handles    rA   _maybe_cancel_requestr`    s"     s    	AsyncRequestHandlec                `   K   	 | j                          d {    y 7 # t        $ r Y y w xY wwr<   r\  r^  s    rA   _async_maybe_cancel_requestrc  !  s+     mmo s(   .  . 	+.+.c                      e Zd ZU  ed      Zded<   e	 	 	 	 	 	 	 	 dd       ZddddZddd		 	 	 	 	 dd
Z	ddZ
ddZy)rZ  FrD  r   rq   c                    t         j                  |      }|j                  r|j                   dnd}t         | |j                   d|j
                   d| } | |||dz   |dz   |      S Nr+   rO   z
/requests/z/statusz/cancelr'  rF  rG  rH  rq   r^  ri  ra  QUEUE_URL_FORMATr_  r`  r   rq   r}  r'  r[  rm  rj   s          rA   from_request_idz!SyncRequestHandle.from_request_id,       ''4+1+;+;F$$%Q'&'x~Qv||nJWaVbc!!)+)+
 	
rC   	with_logsc                   t        | j                  d| j                  d|i      }t        |       | j	                  |j                               S )Returns the status of the request (which can be one of the following:
        Queued, InProgress, Completed). If `with_logs` is True, logs will be included
        for InProgress and Completed statuses.GETr<  params)r   rq   rG  r2  rP  ri   r@   rn  rr   s      rA   rJ  zSyncRequestHandle.status>  sJ    
 (KKOO		
 	(#!!(--/22rC   r  rn  intervalc             #     K   	 | j                  |      }| t        |t              ryt        j                  |       =wzContinuously poll for the status of the request and yield it at each interval till
        the request is completed. If `with_logs` is True, logs will be included in the response.
        rm  N)rJ  r  r>  r  r  r@   rn  rv  rJ  s       rA   iter_eventszSyncRequestHandle.iter_eventsO  s>      [[9[5FL&),JJx  s   ?Ac                    | j                  d      D ]  } t        | j                  d| j                        }t	        |       |j                         S )zOWait till the request is completed and return the result of the inference call.Frm  rq  )rz  r   rq   rF  r2  ri   r@   _rr   s      rA   rO  zSyncRequestHandle.get^  sP    !!E!2 	A	 (UD<M<MN(#}}rC   c                \    t        | j                  d| j                        }t        |       yzCancel the request.r   N)r   rq   rH  r2  r@   rr   s     rA   r]  zSyncRequestHandle.cancelg  s'    'KKOO

 	(#rC   N)rq   r   r}  r6   r'  r6   rD   rZ  rn  rE   rD   r4  )rn  rE   rv  r%  rD   zIterator[Status]rD   rQ  r  rF   rG   rH   r
   rq   rI   r   rk  rJ  rz  rO  r]  rJ   rC   rA   rZ  rZ  (  s     e,FL,

 
 	

 

 
" +0 3$ $)C! !49!	!$rC   c                      e Zd ZU  ed      Zded<   e	 	 	 	 	 	 	 	 dd       ZddddZddd		 	 	 	 	 dd
Z	ddZ
ddZy)ra  FrD  r  rq   c                    t         j                  |      }|j                  r|j                   dnd}t         | |j                   d|j
                   d| } | |||dz   |dz   |      S rf  rh  rj  s          rA   rk  z"AsyncRequestHandle.from_request_idu  rl  rC   rm  c                  K   t        | j                  d| j                  d|i       d{   }t        |       | j	                  |j                               S 7 .w)rp  rq  r<  rr  N)r  rq   rG  r2  rP  ri   rt  s      rA   rJ  zAsyncRequestHandle.status  sX     
 4KKOO		
 
 	(#!!(--/22
s   )AA/Ar  ru  c                 K   	 | j                  |       d{   }| t        |t              ryt        j                  |       d{    N7 87 wrx  )rJ  r  r>  r   r  ry  s       rA   rz  zAsyncRequestHandle.iter_events  sP      ;;;;;FL&),--))) ;
 *s!   AA2AAAAc                   K   | j                  d      2 3 d{   }
7 6 t        | j                  d| j                         d{  7  }t	        |       |j                         S w)z9Wait till the request is completed and return the result.Frm  Nrq  )rz  r  rq   rF  r2  ri   r|  s      rA   rO  zAsyncRequestHandle.get  sn     ''%'8 	 	!	8 4KK
 
 

 	(#}}s+   A'!!A'!%A'A	 A'c                x   K   t        | j                  d| j                         d{   }t        |       y7 wr  )r  rq   rH  r2  r  s     rA   r]  zAsyncRequestHandle.cancel  s5     3KKOO
 

 	(#
s   %:8:N)rq   r  r}  r6   r'  r6   rD   ra  r  )rn  rE   rv  r%  rD   zAsyncIterator[Status]r  r  r  rJ   rC   rA   ra  ra  q  s     %5 1F1
!
 
 	

 

 
" 16 3$ $)C* *49*	*$rC   c            
         e Zd ZU  edd      Zded<   dZded<   ed*d	       Zd*d
Z	d+dZ
ed,d       Zed-d       Zd-dZed	 	 	 	 	 d.dZddddi d	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d/dZddddi dd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d0dZddddddi ddd		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d1dZd2dZdd	 	 	 	 	 	 	 d3dZd4dZd5dZddd	 	 	 	 	 	 	 	 	 d6dZ	 d7ddd 	 	 	 	 	 	 	 	 	 	 	 d8d!Zddd 	 	 	 	 	 	 	 d9d"Z	 d:ddd 	 	 	 	 	 	 	 	 	 d;d#Zed$d%deddd&	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d<d'       Zed$dded(	 	 	 	 	 	 	 	 	 	 	 d=d)       Zy)>r   NFdefaultrE  r   r!        ^@r%  default_timeoutc                Z    | j                   
t               S t        d| j                         S NKeyr!  r   r   r?   s    rA   rW   zAsyncClient._auth  &    88)++udhh//rC   c                    | j                   S r<   rW   r?   s    rA   	_get_authzAsyncClient._get_auth      zzrC   c                    | j                         }|j                  j                         dk7  rt        d      |j                  S Nr!  zZKey credentials are required for this operation. Set FAL_KEY or FAL_KEY_ID/FAL_KEY_SECRET.r  r"  r#  r   r7   rb   s     rA   _get_keyzAsyncClient._get_key  ?    ~~;;%')l  zzrC   c                4    t        | j                               S r<   )r~   r  r?   s    rA   r   zAsyncClient._token_manager  s    #DNN$455rC   c                    | j                         }t        j                  |j                  t        d| j
                        S )Nr   rh   r   )r  rk   r   r`   
USER_AGENTr  rb   s     rA   r   zAsyncClient._client  s=    ~~  !%!2!2( ((
 	
rC   c                   K   | j                   j                          d {   }t        j                  |j                   d|j
                   t        d| j                        S 7 EwNr   r   r  )r   rw   rk   r   r8   r7   r  r  r   s     rA   _get_cdn_clientzAsyncClient._get_cdn_client  sa     ))3355  $)$4$4#5Qu{{m!D( ((
 	
 6s   A(A&AA(token_expirationc                  K   t         j                  |      j                  g|d}t        | j                  dt
         d|       d {   }t        |j                               S 7 wN)allowed_appsr  r   z/tokens/)ri   )r^  ri  r`  r  r   r^   r  ri   r@   r}  r  r  rr   s        rA   _get_realtime_tokenzAsyncClient._get_realtime_token  si      #33K@FFG 0
 4LLj!	
 
 %X]]_55
s   AA)	A'
A)rO   r   r   start_timeouthintrh   c                 K   t         |z   }|r|d|j                  d      z   z  }i |}	|t        ||	       |t        ||	       t	        | j
                  d||||	       d{   }
t        |
       |
j                         S 7 w)ad  Run an application with the given arguments (which will be JSON serialized). The path parameter can be used to
        specify a subpath when applicable. This method will return the result of the inference call directly.

        Args:
            timeout: Client-side HTTP timeout in seconds. Controls how long the HTTP
                client waits for a response. Defaults to the client's default_timeout.
            start_timeout: Server-side request timeout in seconds. Limits total time spent
                waiting before processing starts. Does not apply once the application begins processing.
        r+   Nr   ri   r   rh   )RUN_URL_FORMATr|  r"   r!   r  r   r2  ri   r@   r}  r  r   r   r  r  rh   r   ra   rr   s              rA   runzAsyncClient.run  s     * {*3S)))C#.g; D(+$}h73LL
 
 	(#}}
s   A!B#B$ Br   r  webhook_urlpriorityrh   r  c                 K   t         |z   }	|r|	d|j                  d      z   z  }	||	dt        d|i      z   z  }	i |}
|t        ||
       |t	        ||
       |t        ||
       t        | j                  d|	|| j                  |
       d{   }t        |       |j                         }t        |d   |d   |d	   |d
   | j                        S 7 Ew)aP  Submit an application with the given arguments (which will be JSON serialized). The path parameter can be used to
        specify a subpath when applicable. This method will return a handle to the request that can be used to check the status
        and retrieve the result of the inference call when it is done.

        Args:
            start_timeout: Server-side request timeout in seconds. Limits total time spent
                waiting before processing starts (includes queue wait, retries, and
                routing). Does not apply once the application begins processing.
        r+   Nrz  fal_webhookr   r  r'  rF  rG  rH  rg  )ri  r|  r   r"   r    r!   r  r   r  r2  ri   ra  r@   r}  r  r   r  r  r  rh   r  r   ra   rr   rs   s                rA   r   zAsyncClient.submit-  s     , ,3S)))C"3M;#?@@@C#.g; D(+(3$}h73LL((
 
 	(#}}!L)n-L)L)<<
 	

s   BCCAC	r   r  rn  
on_enqueueon_queue_updater  rh   r  client_timeoutc       	           	
K   |-
|
n(
|kD  r#t        j                  d
 d| dt        d       dgd	 
fd}| |        d{   S 	 t        j                   |       |       d{   S 7 )7 # t        j
                  $ r<}d}d	   }| |j                  }t        |       d{  7   t        ||
      |d}~ww xY ww)<  Subscribe to an application and wait for the result.

        Args:
            start_timeout: Server-side request timeout in seconds. Limits total time spent
                waiting before processing starts (includes queue wait, retries, and
                routing). Does not apply once the application begins processing.
            client_timeout: Client-side total timeout in seconds. Limits the total time
                spent waiting for the entire request to complete (including queue wait
                and processing). If not set, waits indefinitely.
        Nstart_timeout ("s) is larger than client_timeout (Ts). The request may timeout on the client before the server-side timeout is reached.rc  
stacklevelc            	     
  K   j                  	
       d {   } | d<    | j                         $| j                        2 3 d {   } |       | j                          d {   S 7 [7 '6 7 
wN)r   r  r  rh   r  r   rm  r   r'  rz  rO  r_  eventr}  r  
handle_refrh   r  r  r  r   r  r@   r  rn  s     rA   _do_subscribez,AsyncClient.subscribe.<locals>._do_subscribe  s     ;;!+ '  F #JqM%6,,-*#)#5#5	#5#J + +%#E*%%%+#J &sE   BA;1BA?A=A?B6B7B=A??BBr   r   r   r'  r  )	warningswarnUserWarningr   wait_forTimeoutErrorr'  rc  r$  )r@   r}  r  r   r  rn  r  r  r  rh   r  r  r  er'  r_  r  s   ```````````     @rA   	subscribezAsyncClient.subscribei  s     2 %$ ./%m_4VWeVf gg g 	 ;?
	& 	& 	&* !&((	 ))-/>RRR ) S## 
	J]F!#..
1&999'&% 
	sT   ACBC$B B
B C
B C#CCCCCc                D    t         j                  | j                  ||      S r<   )ra  rk  r   r@   r}  r'  s      rA   
get_handlezAsyncClient.get_handle  s    !11$,,ZXXrC   rm  c               f   K   | j                  ||      }|j                  |       d {   S 7 wNrm  r  rJ  r@   r}  r'  rn  r_  s        rA   rJ  zAsyncClient.status  s/      j9]]Y]7777s   (1/1c                b   K   | j                  ||      }|j                          d {   S 7 wr<   r  rO  r@   r}  r'  r_  s       rA   r   zAsyncClient.result  s(     j9ZZ\!!!s   &/-/c                d   K   | j                  ||      }|j                          d {    y 7 wr<   r  r]  r  s       rA   r]  zAsyncClient.cancel  s%     j9mmos   &0.0/streamr   r   c              F  K   t         |z   }|r|d|j                  d      z   z  }t        | j                  d|||      4 d{   }|j	                         2 3 d{   }|j                          7 17 6 ddd      d{  7   y# 1 d{  7  sw Y   yxY wway  Stream the output of an application with the given arguments (which will be JSON serialized). This is only supported
        at a few select applications at the moment, so be sure to first consult with the documentation of individual applications
        to see if this is supported.

        The function will iterate over each event that is streamed from the server.
        r+   r   )ri   r   N)r  r|  r   r   	aiter_sseri   r@   r}  r  r   r   r   eventsr  s           rA   streamzAsyncClient.stream  s      {*3S)))CLL
 	# 	# %//1 # #ejjl"	##1	# 	# 	# 	# 	#sl   AB!A5B!BA9A7A9 B5B!7A99B:B!BB!BBBB!r-  r.  c                 K   | j                         }t        |t              r|j                  d      }t	        ||      }t        |      t        kD  rP|d   dk(  rH|d}| j                          d{   }t        j                  || j                  |||       d{   S d|i}	|||	d<   g }
|D ]  }|dk(  r=| j                          d{   }|
j                  dt        t        |||		      f       E|d
k(  r1|
j                  d
t        t        | j                  ||||      f       {|dk(  s|
j                  dt        t         | j                  ||||      f        t#        |
       d{   S 7 7 7 7 w)Upload the given data blob to the CDN and return the access URL. The content type should be specified
        as the second argument. Use upload_file or upload_image for convenience.utf-8r   r(   Nr5  rq   r   r   rs   r   rV   r   rs   rh   r)   rs   r   r   r*   )r  r  r6   r  r3  r   MULTIPART_THRESHOLDr  r   r   r   r   r   rL  rN  r   rA  rY  r@   rs   r   r   r-  r.  rc   repository_chainrq   rh   rS  repos               rA   uploadzAsyncClient.upload  s     ~~dC ;;w'D9+
 t9**/?/Bh/N (	//11F-22"11#) 3    "<0 )2G%&8:$ $	Dx#3355  0&tWU - LL !%)5&/
 5 LL !%)5&/
1$	L 5X>>>i 2 6H ?sP   A/F 1E72+F E:.F E<A$F 2A F 2E>3F :F <F >F c               0  K   t        j                  |      \  }}|d}t        ||      }t        j                  j                  |      t        kD  rT|d   dk(  rL| j                          d{   }t        j                  t        |      || j                  |       d{   S t        |d      5 }| j                  |j                         |t        j                  j                  |      ||       d{   cddd       S 7 7 e7 # 1 sw Y   yxY wwzMUpload a file from the local filesystem to the CDN and return the access URL.Nr   r   r(   )r   rq   r   r   r   )r   r-  r.  )	mimetypes
guess_typer3  r   r   r   r  r  r   r   r6   r   r   r  r   r   	r@   r   r-  r.  	mime_typer}  r  rq   files	            rA   upload_filezAsyncClient.upload_file2  s     !++D1	12I9+
 GGOOD!$77 #x///11F-77d)"11&	 8    $ 			''**40%$7 %  	 	 2	 	sO   A*D,D-3D D!D1AD
6D7D
:DDD

DDc                  K   t        j                         5 }|j                  ||       | j                  |j	                         d| ||       d{   cddd       S 7 # 1 sw Y   yxY wwzBUpload a pillow image object to the CDN and return the access URL.formatimage/r  NioBytesIOr   r  getvaluer@   imager  r-  r.  buffers         rA   upload_imagezAsyncClient.upload_imageY  sr      ZZ\ 	VJJvfJ-!!%$7	 %  	 		 	s.   A0=A$A"A$
A0"A$$A-)A0T	/realtimeuse_jwtr   rw  r  r  r  c              X  K   d }d }	|r| j                  ||       d {   }	n#| j                         }
|
j                  t        d}t	        ||	||      }t        ||      4 d {   }t        |||       d d d       d {    y 7 o7 (7 	# 1 d {  7  sw Y   y xY wwNr  r   r  r   )r  r  )r  r  r`   r  r  r  r  r@   r}  r  r   rw  r  r  r  rh   r7   rc   r   r  s                rA   r  zAsyncClient.realtimen  s      *. 22.> 3  E >>#D(,(9(9TG!+um$O$S': 	 	b)NN 	 	 		 	 	 	 	sX   B*BAB*(B)B*,B>B*	B
B*B*B*B'BB'#B*r  r   rw  r  c              @  K   d }d }|r| j                  ||       d {   }n#| j                         }|j                  t        d}t	        ||||      }	t        |	|      4 d {   }
|
 d d d       d {    y 7 c7 7 	# 1 d {  7  sw Y   y xY wwNr  r   rv  r   )r  r  r`   r  r  r  r@   r}  r  r   rw  r  rh   r7   rc   r   r  s              rA   
ws_connectzAsyncClient.ws_connect  s      *. 22.> 3  E >>#D(,(9(9TG"'	
 %S': 	 	bH	 	 		 	 	 	 	sX   BBAB(B)B,B	2B=B>BBB	BBBBrD   r   r   )rD   r~   )rD   r  r}  r6   r  r   rD   r6   r}  r6   r  rQ  r   r6   r   Optional[Union[int, float]]r  r  r  r   rh   r   rD   rQ  )r}  r6   r  rQ  r   r6   r  r   r  r   r  Optional[Priority]rh   r   r  r  rD   ra  r}  r6   r  rQ  r   r6   r  r   rn  rE   r  zOptional[Callable[[str], None]]r  z"Optional[Callable[[Status], None]]r  r  rh   r   r  r  r  r  rD   rQ  )r}  r6   r'  r6   rD   ra  r}  r6   r'  r6   rn  rE   rD   r4  r}  r6   r'  r6   rD   rQ  r}  r6   r'  r6   rD   ry   )
r}  r6   r  rQ  r   r6   r   float | NonerD   zAsyncIterator[dict[str, Any]]r<   rs   str | bytesr   r6   r   r   r-  UploadRepositoryId | Noner.  4UploadRepositoryId | list[UploadRepositoryId] | NonerD   r6   r   os.PathLiker-  r   r.  r!  rD   r6   jpeg
r  Image.Imager  r6   r-  r   r.  r!  rD   r6   )r}  r6   r  rE   r   r6   rw  r   r  r   r  r  r  r  rD   z&AsyncIterator[AsyncRealtimeConnection])r}  r6   r  rE   r   r6   rw  r   r  r   rD   (AsyncIterator['WebSocketClientProtocol'])rF   rG   rH   r
   r!  rI   r  r   rW   r  r  r   r   r  !REALTIME_TOKEN_EXPIRATION_SECONDSr  r  r   r  r  rJ  r   r]  r  r  r  r  r   r  r  rJ   rC   rA   r   r     s1   Du5C5"OU"0 0
 6 6 
 

 !B	66 	6
 
6. /359"$,, ,
 , -, 3, ,  , 
,f "&'+"$59:
:
 :

 :
 :
  :
 %:
  :
 3:
 
:
B 6:>B'+"$596:JJ J
 J J J 4J <J %J  J 3J 4J 
JXY GL88,/8?C8	8"  $## #
 # # 
'#B !%	M? 15 M?M? M? 	M? .M?M? 
M?f 15 %% .	%
% 
%T 
 15  
 . 
* 
 $( A8<8< 	
  "  6 6 
0 6 
 $( A 	
  "  
2 rC   r   c            
         e Zd ZU  edd      Zded<   dZded<   ed+d	       Zd+d
Z	d,dZ
ed-d       Zed.d       Zed/d       Zd-dZed	 	 	 	 	 d0dZddddi d	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d1dZddddi dd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d2dZddddddi ddd		 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d3dZd4dZdd	 	 	 	 	 	 	 d5dZd6dZd7dZddd	 	 	 	 	 	 	 	 	 d8d Z	 d9ddd!	 	 	 	 	 	 	 	 	 	 	 d:d"Zddd!	 	 	 	 	 	 	 d;d#Z	 d<ddd!	 	 	 	 	 	 	 	 	 d=d$Zed%d&deddd'	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d>d(       Zed%dded)	 	 	 	 	 	 	 	 	 	 	 d?d*       Zy)@
SyncClientNFr  r   r!  r  r%  r  c                Z    | j                   
t               S t        d| j                         S r  r  r?   s    rA   rW   zSyncClient._auth  r  rC   c                    | j                   S r<   r  r?   s    rA   r  zSyncClient._get_auth  r  rC   c                    | j                         }|j                  j                         dk7  rt        d      |j                  S r  r  rb   s     rA   r  zSyncClient._get_key  r  rC   c                    | j                         }t        j                  |j                  t        d| j
                  d      S )Nr   T)rh   r   follow_redirects)r  rk   rl   r`   r  r  rb   s     rA   r   zSyncClient._client  s>    ~~||!%!2!2( ((!
 	
rC   c                4    t        | j                               S r<   )rL   r  r?   s    rA   r   zSyncClient._token_manager  s    t~~/00rC   c                    t         S r<   )EXECUTORr?   s    rA   	_executorzSyncClient._executor  s    rC   c                    | j                   j                         }t        j                  |j                   d|j
                   t        d| j                        S r  )r   rw   rk   rl   r8   r7   r  r  r   s     rA   r  zSyncClient._get_cdn_client  sS    ##--/||$)$4$4#5Qu{{m!D( ((
 	
rC   r  c                   t         j                  |      j                  g|d}t        | j                  dt
         d|      }t        |j                               S r  )r^  ri  r`  r   r   r^   r  ri   r  s        rA   r  zSyncClient._get_realtime_token  s[     #33K@FFG 0
 (LLj!	
 %X]]_55rC   rO   r  c                   t         |z   }|r|d|j                  d      z   z  }i |}	|t        ||	       |t        ||	       t	        | j
                  d||||	      }
t        |
       |
j                         S )a  Run an application with the given arguments (which will be JSON serialized).

        Args:
            timeout: Client-side HTTP timeout in seconds. Controls how long the HTTP
                client waits for a response. Defaults to the client's default_timeout.
            start_timeout: Server-side request timeout in seconds. Limits total time spent
                waiting before processing starts. Does not apply once the application begins processing.
        r+   r   r  )r  r|  r"   r!   r   r   r2  ri   r  s              rA   r  zSyncClient.run  s    ( {*3S)))C#.g;D(+$}h7'LL
 	(#}}rC   r  c                  t         |z   }	|r|	d|j                  d      z   z  }	||	dt        d|i      z   z  }	i |}
|t        ||
       |t	        ||
       |t        ||
       t        | j                  d|	|| j                  |
      }t        |       |j                         }t        |d   |d   |d   |d	   | j                  
      S )ag  Submit an application with the given arguments (which will be JSON serialized).

        Args:
            start_timeout: Server-side request timeout in seconds. Limits total time spent
                waiting before processing starts (includes queue wait, retries, and
                routing). Does not apply once the application begins processing.
        r+   rz  r  r   r  r'  rF  rG  rH  rg  )ri  r|  r   r"   r    r!   r   r   r  r2  ri   rZ  r  s                rA   r   zSyncClient.submit  s    ( ,3S)))C"3M;#?@@@C#.g;D(+(3$}h7'LL((
 	(#}} L)n-L)L)<<
 	
rC   r  c       	           	
 |-
|
n(
|kD  r#t        j                  d
 d| dt        d       dgd	 
fd}| |       S  j                  j	                  |      }	 |j                  |      S # t        j                  j                  $ r3}d}d	   }||j                  }t        |       t        ||
      |d}~ww xY w)r  Nr  r  r  rc  r  c            	         j                  	
      } | d<    | j                         | j                        D ]
  } |        | j                         S r  r  r  s     rA   r  z+SyncClient.subscribe.<locals>._do_subscribew  s    [[!+ ! F #JqM%6,,-*#//)/D +E#E*+ ::<rC   r  r   r  r  )r  r  r  r4  r   r   r   r   r  r'  r`  r$  )r@   r}  r  r   r  rn  r  r  r  rh   r  r  r  r   r  r'  r_  r  s   ```````````      @rA   r  zSyncClient.subscribeQ  s    2 %$ ./%m_4VWeVf gg g 	 :>
	  	  	 * ! ?"&&}5	===88!!.. 
	J]F!#..
%f-'&% 
	s   5B C$.CCc                D    t         j                  | j                  ||      S r<   )rZ  rk  r   r  s      rA   r  zSyncClient.get_handle  s     00{JWWrC   rm  c               J    | j                  ||      }|j                  |      S r  r  r  s        rA   rJ  zSyncClient.status  s%     j9}}y}11rC   c                F    | j                  ||      }|j                         S r<   r  r  s       rA   r   zSyncClient.result  s    j9zz|rC   c                H    | j                  ||      }|j                          y r<   r  r  s       rA   r]  zSyncClient.cancel  s    j9rC   r  r  c             #     K   t         |z   }|r|d|j                  d      z   z  }t        | j                  d|||      5 }|j	                         D ]  }|j                           	 ddd       y# 1 sw Y   yxY wwr  )r  r|  r   r   iter_sseri   r  s           rA   r  zSyncClient.stream  s}      {*3S)))CLL&#Iw
 	#* #jjl"#	# 	# 	#s   =A=(A1(	A=1A:6A=r  c                  | j                         }t        |t              r|j                  d      }t	        ||      }t        |      t        kD  r@|d   dk(  r8|d}| j                         }t        j                  || j                  |||      S d|i}	|||	d<   g }
|D ]  }|dk(  r5| j                         }|
j                  dt        t        |||	      f       =|d	k(  r1|
j                  d	t        t        | j                  ||||
      f       s|dk(  sy|
j                  dt        t         | j                  ||||
      f        t#        |
      S )r  r  r   r(   r5  r  rV   r   r  r)   r  r*   )r  r  r6   r  r3  r   r  r  r   r   r   r   r   rF  rJ  r   r?  rV  r  s               rA   r  zSyncClient.upload  s    ~~dC ;;w'D9+
 t9**/?/Bh/N (	))+F"''"11#) (   "<0 )2G%&8:$ $	Dx--/ 
FwO ' LL !%)5&/
 / LL !%)5&/
1$	L )22rC   c                  t        j                  |      \  }}|d}t        ||      }t        j                  j                  |      t        kD  rD|d   dk(  r<| j                         }t        j                  t        |      || j                  |      S t        |d      5 }| j                  |j                         |t        j                  j                  |      ||      cddd       S # 1 sw Y   yxY wr  )r  r  r3  r   r   r   r  r  r   r   r6   r   r   r  r   r   r  s	            rA   r  zSyncClient.upload_file	  s     !++D1	12I9+
 GGOOD!$77 #x/))+F",,d)"11&	 -   $ 	;;		''**40%$7  	 	 	s   AC**C3c                   t        j                         5 }|j                  ||       | j                  |j	                         d| ||      cddd       S # 1 sw Y   yxY wr  r  r  s         rA   r  zSyncClient.upload_image>	  s_     ZZ\ 	VJJvfJ-;;!!%$7	  	 	 	s   9AA!Tr	  r
  c             #    K   d }d }	|r| j                  ||      }	n#| j                         }
|
j                  t        d}t	        ||	||      }t        ||      5 }t        |||       d d d        y # 1 sw Y   y xY wwr  )r  r  r`   r  r  r  r  r  s                rA   r  zSyncClient.realtimeS	  s      *. ,,.> - E >>#D(,(9(9TG!+um$Oc73 	r$NN 	 	 	s   ABA6-	B6A?;Br  c             #     K   d }d }|r| j                  ||      }n#| j                         }|j                  t        d}t	        ||||      }	t        |	|      5 }
|
 d d d        y # 1 sw Y   y xY wwr  )r  r  r`   r  r  r  r  s              rA   r  zSyncClient.ws_connecto	  s      *. ,,.> - E >>#D(,(9(9TG"'	
 c73 	rH	 	 	s   AA6A*!	A6*A3/A6r  r   )rD   r   )rD   rL   )rD   z%concurrent.futures.ThreadPoolExecutorr  r  )r}  r6   r  rQ  r   r6   r  r   r  r   r  r  rh   r   r  r  rD   rZ  r  )r}  r6   r'  r6   rD   rZ  r  r  r  )
r}  r6   r  rQ  r   r6   r   r  rD   zIterator[dict[str, Any]]r<   r  r"  r$  r&  )r}  r6   r  rE   r   r6   rw  r   r  r   r  r  r  r  rD   zIterator[RealtimeConnection])r}  r6   r  rE   r   r6   rw  r   r  r   rD   Iterator['Connection']) rF   rG   rH   r
   r!  rI   r  r   rW   r  r  r   r   r   r4  r  r)  r  r  r   r  r  rJ  r   r]  r  r  r  r  r   r  r  rJ   rC   rA   r+  r+    sD   Du5C5"OU"0 0
 	
 	
 1 1  
 !B	66 	6
 
6. /359"$(( (
 ( -( 3( (  ( 
(^ "&'+"$597
7
 7

 7
 7
  7
 %7
  7
 37
 
7
| 6:>B'+"$596:KK K
 K K K 4K <K %K  K 3K 4K 
KZX GL22,/2?C2	2  $## #
 # # 
"#: !%	M3 15 M3M3 M3 	M3 .M3M3 
M3f 15 %% .	%
% 
%T 
 15  
 . 
* 
 $( A8<8< 	
  "  6 6 
& 6 
 $( A 	
  "  
  rC   r+  c                    t        | t              r| j                  d      } d| dt        j                  |       j                          S )zIEncode the given data blob to a data URL with the specified content type.r  zdata:z;base64,)r  r6   r  base64	b64encoder  )rs   r   s     rA   r  r  	  sB    ${{7#<.)9)9$)?)F)F)H(IJJrC   c                    t        j                  |       \  }}|d}t        | d      5 }t        |j	                         |      cddd       S # 1 sw Y   yxY w)zUEncode a file from the local filesystem to a data URL with the inferred content type.Nr   r   )r  r  r   r  r   )r   r  r}  r  s       rA   encode_filerK  	  sR    ''-LIq.		dD	 .Tdiik9-. . .s   AAc                    t        j                         5 }| j                  ||       t        |j	                         d|       cddd       S # 1 sw Y   yxY w)zEEncode a pillow image object to a data URL with the specified format.r  r   N)r  r  r   r  r  )r  r  r  s      rA   encode_imagerM  	  sJ    	 <

6&
)foo'6&):;< < <s   0AA)rr   r   rD   ry   )rY  r6   rD   r6   )r[  r^  rD   r6   )rr  r   rD   r   )
r}  r6   r7   r   r   r6   rw  r   rD   r6   )
r}  r6   r7   r   rw  r   r   r6   rD   r6   )rs   r   rD   r6   )r  r   rD   r   )r  r   rD   r   )r  r   r  r  rD   r  )r  r?  r  r  rD   r   r<   )r   r6   rh   dict[str, str] | NonerD   rF  )r   r6   rh   rN  rD   r(  )
rq   r   r  r6   r   r6   r  r   rD   r   )
rq   r  r  r6   r   r6   r  r   rD   r   )rr   r   rD   rE   )rr   r   r  	list[int]rD   rE   )r0  r  r  rO  rD   rE   )r  F)r  r   r	  r%  r
  r%  r  zLiteral['exponential', 'fixed']r  rE   rD   r%  )rq   r   r  r6   r   r6   r  rO  r  r   rD   r   )rq   r  r  r6   r   r6   r  rO  r  r   rD   r   )rc   r   rD   r6   )rc   r   r   r6   r   r   rD   r   )rc   r   rD   r   )r-  r   r.  r!  rD   r/   )r   r   r   r6   rD   r   )rq   r   rc   r   rs   r   r   r6   r   r   rD   r6   )rq   r  rc   r   rs   r   r   r6   r   r   rD   r6   )rq   r   rs   r   rh   r   rD   r6   )rq   r  rs   r   rh   r   rD   r6   )rS  z#list[tuple[str, Callable[[], str]]]rD   r6   )rS  z#list[tuple[str, Callable[[], Any]]]rD   r6   )r_  rZ  rD   ry   )r_  ra  rD   ry   )rs   r  r   r6   rD   r6   )r   r#  rD   r6   r$  )r  r'  r  r6   rD   r6   )
__future__r   r  ri   r   r   r  r   pathlibr   r  r  rH  r[   loggingr   r   
contextlibr   r   r   r   dataclassesr	   r
   	functoolsr   r   typingr   r   r   r   r   r   r   r   r   urllib.parser   r  rk   	httpx_sser   r   fal_client.authr   r   r   r   r   fal_client._versionr   fal_client._headersr   r    r!   r"   r#   r$   websockets.clientr%   websockets.sync.connectionr&   	getLoggerrF   r  PILr'   r6   rQ  r-   r  ri  r{  r^   rD  environrO  rH  r.   rI   r0   r  MIN_REQUEST_TIMEOUT_SECONDSr   r   r3  r5   rL   r~   r  r   r   r   r   r  r  r  r  r$  r2  r4  r6  r:  r>  rC  re  r\  r^  r)  r  rq  ro  ru  r  r  r  r  r  r  r  r  r  r  r  r  r  r   r  r  r  r  r  r  r  r  r  r  r   r  r%  r'  r)  r3  r7  r?  rA  rF  rJ  rL  rN  rV  rY  r`  rc  rZ  ra  r   r+  r  rK  rM  rJ   rC   rA   <module>rb     s   " 	   	          : ' ( .
 
 
 #   /  ,  95			8	$
sCx.34 L>+013 |nA.  
 zz~~n6IJ 08 - 8@Eu~ "$< M;-y1
  00, 1 
 = = =" "J" "J ( '  m$ m$`x* x*v	Y 	 ! ! ! WNL W W&      V   0 0 0 & & & $B B B& w'X $
 
 
6 %( !   <	   $ 	
  	8  
  	D"L " /5  "?  >1  ( ( (V ( ( (V /3	,  /3	,- "%,/;>'*14@C 
	% & $&  
& BD 4 5B!!! ! 2	!
 ! !. $&444 
4
 !4 4 4> $&444 
4
 !4 4 40
),9C)M .
 	
   	:
 	
   	:)) ) 	)
 	) ))
) 	)
 ) ) 	)$)) ) 	)
 	) ))
) 	)
 ) ) 	)$9199$9199* $E$* E$ E$P $I$+ I$ I$X $f f fR $a a aHK.<rC   