
    iF                     D
   % S SK JrJr  SSKr\R                  \R                  " \R                  5      :w  d  \c  \	" S5      e\R                  " 5       (       d  \	" S5      eS SKJr  S SKJrJrJr  S SKJr  SSKrSSKrSSKrSS	KJrJr  SS
KJr  SSKJrJrJrJrJrJ r   SSK!J"r"  \#\$\%4   r&\#\$\%\%\%4   r'\RP                  r(\RR                  r)\RT                  r*\RV                  r+\RX                  r,\RZ                  r-\R\                  r.\R^                  r/\R`                  r0\Rb                  r1\Rd                  r2\Rf                  r3\Rh                  r4\Rj                  r5\Rl                  r6\Rn                  r7\Rp                  r8\Rr                  r9\Rt                  r:\Rv                  r;\Rx                  r<\Rz                  r=\R|                  r>\R~                  r?\R                  r@\R                  rA\R                  rC\R                  rE\R                  rG\R                  rI\R                  rK\R                  rM\R                  rO\R                  rQ\R                  rS\R                  rU\R                  rW\R                  rY\R                  r[\R                  r]\R                  r_\R                  ra\R                  rc\R                  re\R                  rg\R                  ri\" \R                  " \R                  " \R                  5      5      5      rmSrn " S S\o5      rp0 rq\\S4   \rS'   \R                  " 5       S 5       rt\R                  " 5       S 5       ru\R                  " 5       S 5       rv\R                  " 5       S 5       rw\R                  " 5       S 5       rxS ryS rzS r{ " S S5      r|\|" 5       r} " S S5      r~\ " S S5      5       r\ " S S 5      5       r\ " S! S"5      5       r\ " S# S$5      5       r\ " S% S&5      5       r\ " S' S(5      5       r\ " S) S*5      5       r\ " S+ S,5      5       r\ " S- S.5      5       r\ " S/ S05      5       r\ " S1 S25      5       r\ " S3 S45      5       r\ " S5 S65      5       r\ " S7 S85      5       r\ " S9 S:5      5       r\ " S; S<5      5       r\ " S= S>5      5       r\ " S? S@5      5       r\ " SA SB5      5       r\ " SC SD5      5       r\ " SE SF5      5       rSG\4SH jrSG\4SI jrSG\4SJ jrSG\4SK jrSG\4SL jrSMrg)N   )ffilib    NzCould not initialize c-aresz&c-ares is not built with thread safety)errno)ascii_bytes	maybe_str
parse_name)__version__)CallableIterable)	dataclass)Anyr   LiteralOptionalDictUnion)SimpleQueue   c                       \ rS rSrSrg)	AresErrorV    N)__name__
__module____qualname____firstlineno____static_attributes__r       =/app/mltbenv/lib/python3.13/site-packages/pycares/__init__.pyr   r   V   s    r   r   Channel_handle_to_channelc                 B    [         R                  " U 5      nU" XU5        g N)_ffifrom_handle)data	socket_fdreadablewritablesock_state_cbs        r   _sock_state_cbr+   _   s     $$T*M)x0r   c                     U [         ;  a  g [        R                  " U 5      nU[        R                  :w  a  S nO[        U5      nS nU" XQ5        [         R                  U S 5        g r#   )r!   r$   r%   _libARES_SUCCESSparse_hostentpop)argstatustimeoutshostentcallbackresults         r   _host_cbr7   f   sZ     $$$H"""w'V3%r   c                     U [         ;  a  g [        R                  " U 5      nU[        R                  :w  a  S nO[        X45      nS nU" Xa5        [         R                  U S 5        g r#   )r!   r$   r%   r-   r.   parse_nameinfor0   )r1   r2   r3   nodeservicer5   r6   s          r   _nameinfo_cbr<   w   sZ     $$$H""".V3%r   c                     U [         ;  a  g[        R                  " U 5      nU[        R                  :w  a  SnO[        U5      u  pVUb  UnOSnU" XQ5        [         R                  U S5        g)z'Callback for new DNS record API queriesN)r!   r$   r%   r-   r.   parse_dnsrecr0   )r1   r2   r3   dnsrecr5   r6   parse_statuss          r   _query_dnsrec_cbrA      sj     $$$H"""+F3#!F FV3%r   c                     U [         ;  a  g [        R                  " U 5      nU[        R                  :w  a  S nO[        U5      nS nU" XQ5        [         R                  U S 5        g r#   )r!   r$   r%   r-   r.   parse_addrinfor0   )r1   r2   r3   resr5   r6   s         r   _addrinfo_cbrE      sZ     $$$H"""$V3%r   c                    [         R                  " X5      nUS:X  a  / $ / n[        U5       H  n[        R                  " S5      n[        R                  " S5      n[         R
                  " XXEU5      nUS   [        R                  :w  a'  [        [        R                  " US   US   5      5      nOSnUR                  Xx45        M     U$ )zIExtract OPT params as list of (key, value) tuples for HTTPS/SVCB records.r   zunsigned char **size_t *r   )
r-   ares_dns_rr_get_opt_cntranger$   newares_dns_rr_get_optNULLbytesbufferappend)	rrkeyopt_cntparamsival_ptrval_lenopt_keyvals	            r   _extract_opt_paramsrY      s    **23G!|	F7^((-.((:&**2AH1:"GAJ
;<CCwn%  Mr   c                    U[         R                  :X  a  [         R                  " U [         R                  5      n[        R
                  " S[         R                  5      n[         R                  " [        R                  X#[         R                  5        [        [        [        R                  " U5      5      S9$ U[         R                  :X  a  [         R                  " U [         R                  5      n[        R
                  " S[         R                  5      n[         R                  " [        R                   X#[         R                  5        [#        [        [        R                  " U5      5      S9$ U[         R$                  :X  aq  [         R&                  " U [         R(                  5      n[         R*                  " U [         R,                  5      n[/        U[        [        R                  " U5      5      S9$ U[         R0                  :X  a  [         R2                  " U [         R4                  5      n/ n[7        U5       H  n[        R
                  " S5      n	[         R8                  " U [         R4                  X5      n
U
[        R:                  :w  d  MU  UR=                  [        R>                  " XS   5      SS 5        M     [A        SRC                  U5      S9$ U[         RD                  :X  a  [         RF                  " U [         RH                  5      n[         R*                  " U [         RJ                  5      n[        R
                  " S5      n	[         RL                  " U [         RN                  U	5      n[        [        R>                  " XS   5      SS 5      n[Q        U[        [        R                  " U5      5      US	9$ U[         RR                  :X  aK  [         R*                  " U [         RT                  5      n[W        [        [        R                  " U5      5      S
9$ U[         RX                  :X  Ga`  [         R&                  " U [         RZ                  5      n[         R&                  " U [         R\                  5      n[         R*                  " U [         R^                  5      n[         R*                  " U [         R`                  5      n[         R*                  " U [         Rb                  5      n[         R*                  " U [         Rd                  5      n[g        UU[        [        R                  " U5      5      [        [        R                  " U5      5      [        [        R                  " U5      5      [        [        R                  " U5      5      S9$ U[         Rh                  :X  aK  [         R*                  " U [         Rj                  5      n[m        [        [        R                  " U5      5      S9$ U[         Rn                  :X  aK  [         R*                  " U [         Rp                  5      n[s        [        [        R                  " U5      5      S9$ U[         Rt                  :X  GaL  [         R*                  " U [         Rv                  5      n[         R*                  " U [         Rx                  5      n[         Rz                  " U [         R|                  5      n[         Rz                  " U [         R~                  5      n[         Rz                  " U [         R                  5      n[         Rz                  " U [         R                  5      n[         Rz                  " U [         R                  5      n[        [        [        R                  " U5      5      [        [        R                  " U5      5      UUUUUS9$ U[         R                  :X  a  [         R&                  " U [         R                  5      n[         R&                  " U [         R                  5      n[         R&                  " U [         R                  5      n [         R*                  " U [         R                  5      n![        UUU [        [        R                  " U!5      5      S9$ U[         R                  :X  a  [         RF                  " U [         R                  5      n"[         RF                  " U [         R                  5      n#[         RF                  " U [         R                  5      n$[        R
                  " S5      n%[         RL                  " U [         R                  U%5      n&U&[        R:                  :w  a#  [        [        R>                  " U&U%S   5      5      OSn'[        U"U#U$U'S9$ U[         R                  :X  a  [         R&                  " U [         R                  5      n[         R*                  " U [         R                  5      n![        U [         R                  5      n([        U[        [        R                  " U!5      5      U(S9$ U[         R                  :X  a  [         R&                  " U [         R                  5      n[         R&                  " U [         R                  5      n[         R*                  " U [         R                  5      n![        UU[        [        R                  " U!5      5      S9$ [        SU 35      e)zVExtract type-specific data from a DNS resource record and return appropriate dataclasschar[])addr)priorityexchangerG   r   Nr   )r&   )criticaltagvalue)cname)order
preferenceflagsr;   regexpreplacement)nsdname)dname)mnamernameserialrefreshretryexpireminimum)r]   weightporttarget)
cert_usageselectormatching_typecert_association_data)r]   rs   rS   )r]   rq   rs   zUnsupported DNS record type: )]r-   ARES_REC_TYPE_Aares_dns_rr_get_addrARES_RR_A_ADDRr$   rJ   INET6_ADDRSTRLENares_inet_ntopsocketAF_INETARecordDatar   stringARES_REC_TYPE_AAAAares_dns_rr_get_addr6ARES_RR_AAAA_ADDRAF_INET6AAAARecordDataARES_REC_TYPE_MXares_dns_rr_get_u16ARES_RR_MX_PREFERENCEares_dns_rr_get_strARES_RR_MX_EXCHANGEMXRecordDataARES_REC_TYPE_TXTares_dns_rr_get_abin_cntARES_RR_TXT_DATArI   ares_dns_rr_get_abinrL   rO   rN   TXTRecordDatajoinARES_REC_TYPE_CAAares_dns_rr_get_u8ARES_RR_CAA_CRITICALARES_RR_CAA_TAGares_dns_rr_get_binARES_RR_CAA_VALUECAARecordDataARES_REC_TYPE_CNAMEARES_RR_CNAME_CNAMECNAMERecordDataARES_REC_TYPE_NAPTRARES_RR_NAPTR_ORDERARES_RR_NAPTR_PREFERENCEARES_RR_NAPTR_FLAGSARES_RR_NAPTR_SERVICESARES_RR_NAPTR_REGEXPARES_RR_NAPTR_REPLACEMENTNAPTRRecordDataARES_REC_TYPE_NSARES_RR_NS_NSDNAMENSRecordDataARES_REC_TYPE_PTRARES_RR_PTR_DNAMEPTRRecordDataARES_REC_TYPE_SOAARES_RR_SOA_MNAMEARES_RR_SOA_RNAMEares_dns_rr_get_u32ARES_RR_SOA_SERIALARES_RR_SOA_REFRESHARES_RR_SOA_RETRYARES_RR_SOA_EXPIREARES_RR_SOA_MINIMUMSOARecordDataARES_REC_TYPE_SRVARES_RR_SRV_PRIORITYARES_RR_SRV_WEIGHTARES_RR_SRV_PORTARES_RR_SRV_TARGETSRVRecordDataARES_REC_TYPE_TLSAARES_RR_TLSA_CERT_USAGEARES_RR_TLSA_SELECTORARES_RR_TLSA_MATCHARES_RR_TLSA_DATArM   TLSARecordDataARES_REC_TYPE_HTTPSARES_RR_HTTPS_PRIORITYARES_RR_HTTPS_TARGETrY   ARES_RR_HTTPS_PARAMSHTTPSRecordDataARES_REC_TYPE_URIARES_RR_URI_PRIORITYARES_RR_URI_WEIGHTARES_RR_URI_TARGETURIRecordData
ValueError))rP   record_typer\   bufr]   r^   cntchunksrT   lengthr&   r_   r`   ra   	value_strrb   rc   rd   re   r;   rf   rg   rh   ri   rj   rk   rl   rm   rn   ro   rp   rq   rr   rs   rt   ru   rv   data_lendata_ptr	cert_datarS   s)                                            r   extract_record_datar      s   d***((T-@-@Ahhx!6!67FNNDt7L7LM	$++c*: ;<<	//	/))"d.D.DEhhx!6!67FOOT8M8MN9T[[-=#>??	--	-++B0J0JK++B0H0HIX	$++hBW8XYY	..	.++B0E0EFsAXXj)F,,R1F1FRDtyy dkk$q	:1=>	 
 #((6"233	..	.**2t/H/HI&&r4+?+?@*%((T-C-CVLdkk%;A>?	hIdkk#>N4OW`aa	00	0((T-E-EFYt{{5/A%BCC	00	0((T-E-EF--b$2O2OP
((T-E-EF**2t/J/JK))"d.G.GH..r43Q3QR!DKK./dkk'23T[[01!$++k":;
 	
 
--	-**2t/F/FGIdkk'.B$CDD	..	.((T-C-CD9T[[-?#@AA	..	.((T-C-CD((T-C-CD))"d.E.EF**2t/G/GH((T-C-CD))"d.E.EF**2t/G/GHDKK./DKK./
 	
 
..	.++B0I0IJ))"d.E.EF''D,A,AB))"d.E.EFT[[01	
 	
 
//	/,,R1M1MN
**2t/I/IJ//D4K4KL88J'++B0F0FQAITYYAVE$++h<=\_	!'"+	
 	
 
00	0++B0K0KL))"d.G.GH$R)B)BCT[[01
 	
 
..	.++B0I0IJ))"d.E.EF))"d.E.EFT[[01
 	
 8FGGr   c                 h   U [         R                  :X  a  S[        R                  4$ / n/ n/ n[        R                  " U [        R
                  5      n[        U5       H  n[        R                  " U [        R
                  U5      nU[         R                  :w  d  M?  [        [         R                  " [        R                  " U5      5      5      n[        R                  " U5      n[        R                  " U5      n	[        R                  " U5      n
 [        Xh5      nUR                  [!        UUU	U
US95        M     [        R                  " U [        R&                  5      n[        U5       H  n[        R                  " U [        R&                  U5      nU[         R                  :w  d  M?  [        [         R                  " [        R                  " U5      5      5      n[        R                  " U5      n[        R                  " U5      n	[        R                  " U5      n
 [        Xh5      nUR                  [!        UUU	U
US95        M     [        R                  " U [        R(                  5      n[        U5       H  n[        R                  " U [        R(                  U5      nU[         R                  :w  d  M?  [        [         R                  " [        R                  " U5      5      5      n[        R                  " U5      n[        R                  " U5      n	[        R                  " U5      n
 [        Xh5      nUR                  [!        UUU	U
US95        M     [+        UUUS9nUS4$ ! ["        [$        4 a     GM#  f = f! ["        [$        4 a     GM+  f = f! ["        [$        4 a     GM3  f = f)z8Parse ares_dns_record_t into DNSResult with all sectionsN)nametyperecord_classttlr&   )answer	authority
additional)r$   rL   r-   ARES_EBADRESPares_dns_record_rr_cntARES_SECTION_ANSWERrI   ares_dns_record_rr_get_constr   r   ares_dns_rr_get_nameares_dns_rr_get_typeares_dns_rr_get_classares_dns_rr_get_ttlr   rO   	DNSRecordr   	ExceptionARES_SECTION_AUTHORITYARES_SECTION_ADDITIONAL	DNSResult)r?   answer_recordsauthority_recordsadditional_recordsanswer_countrT   rP   r   rec_type	rec_classr   r&   authority_countadditional_countr6   s                  r   r>   r>   K  s   T''''N ..vt7O7OPL< ..vt7O7OQRS?T[[)B)B2)FGHD004H2226I**2.C*28%%i!!*'  !, 11&$:U:UVO?#..vt7R7RTUV?T[[)B)B2)FGHD004H2226I**2.C*28!((!!**  $, 2264;W;WX#$..vt7S7SUVW?T[[)B)B2)FGHD004H2226I**2.C*28")))!!*+  %* #%F 4<q 	* . 	* . 	* s6   'M,"'N2'N,N NNNN10N1c                   @    \ rS rSrSrS	S jrS	S jrS	S jrS	S jrSr	g)
_ChannelShutdownManageri  zLManages channel destruction in a single background thread using SimpleQueue.Nc                 d    [        5       U l        S U l        [        R                  " 5       U l        g r#   )r   _queue_thread	threadingLock_start_lockselfs    r   __init__ _ChannelShutdownManager.__init__  s!    #.=37$>>+r   c                      U R                   R                  5       u  p[        R                  " US   5        [        R                  " US   S5        Ub  [        R
                  " US   5        Mm  )z4Process channel destruction requests from the queue.r   )r   getr-   ares_cancelares_queue_wait_emptyares_destroy)r   channel_s      r   _run_safe_shutdown_loop/_ChannelShutdownManager._run_safe_shutdown_loop  s`    *JG WQZ( &&wqz26 "!!'!*- r   c                    U R                   b  gU R                     U R                   b
   SSS5        g[        R                  " U R                  SS9U l         U R                   R                  5         SSS5        g! , (       d  f       g= f)z3Start the background thread if not already started.NT)rs   daemon)r   r   r   Threadr  startr   s    r   r  _ChannelShutdownManager.start  sf    <<#||'  %++43O3OX\]DLLL  s   A:>A::
Bc                 <    U R                   R                  X45        g)a  
Schedule channel destruction on the background thread.

The socket state callback handle is passed along to ensure it remains
alive until the channel is destroyed.

Thread Safety and Synchronization:
This method uses SimpleQueue which is thread-safe for putting items
from multiple threads. The background thread processes channels
sequentially waiting for queries to end before each destruction.
N)r   put)r   r  sock_state_cb_handles      r   destroy_channel'_ChannelShutdownManager.destroy_channel  s     	78r   )r   r   r   returnN)
r   r   r   r   __doc__r   r  r  r  r   r   r   r   r   r     s    V,
. 	!9r   r   c            $          \ rS rSr\R
                  \R                  \R                  \R                  \R                  \R                  \R                  \R                  \R                  \R                  \R                  \R                   \R"                  \R$                  \R&                  4r\R*                  \R,                  \R.                  \R0                  \R2                  4rSSSSSSSSSSSSSSSSS.S\\   S\\   S\\   S\\   S	\\   S
\\   S\\\\ \!4         S\\\\ \!4         S\\ \!S4   S\\"\\#\#/S4      S\\   S\\   S\#S\\ \!S4   S\\    S\\ \!S4   SS4"S jjr$S;S jr%S r&S;S jr'S;S jr(\)S\*\    4S j5       r+\+RX                  S\\\ \!4      SS4S j5       r+S\S\SS4S jr-S\SS4S  jr.S\SS4S! jr/S<S" jr0S#\ S$\"\1\/S4   SS4S% jr2S&S&S&S&S'.S(\ S)\\   S*\3Rh                  S+\S,\S\S$\"\1\/S4   SS4S- jjr5\6S..S/\ S0\S1\S$\"\1\/S4   SS4
S2 jjr7\6S..S/\ S0\S1\S$\"\1\/S4   SS4
S3 jjr8S4 r9S5\\:\;4   S\S$\"\1\/S4   SS4S6 jr<S7 r=S;S8 jr>S<S\S\#4S9 jjr?S:r@g)=r    i  NF)re   timeouttriesndotstcp_portudp_portserversdomainslookupsr*   socket_send_buffer_sizesocket_receive_buffer_sizerotatelocal_ip	local_devresolvconf_pathre   r  r  r  r  r  r  r  r  r*   r  r  r   r!  r"  r#  r  c          	      L   S U l         Ub  UOSU l        [        R                  " S5      n[        R                  " S5      nSnUb  UUl        U[
        R                  -  nUb&  [        US-  5      Ul        U[
        R                  -  nUb  UUl
        U[
        R                  -  nUb  UUl        U[
        R                  -  nUb  UUl        U[
        R                  -  nUb  UUl        U[
        R"                  -  nUb  UUl        U[
        R&                  -  nUb  UUl        U[
        R*                  -  nU
(       ah  [-        U
5      (       d  [/        S5      e[        R0                  " U
5      nUU l        [
        R4                  Ul        UUl        U[
        R:                  -  nO/S U l        U[
        R<                  -  n[
        R>                  Ul         U	(       a8  [        R                  " S[C        U	5      5      Ul"        U[
        RF                  -  nU(       a  U Vs/ s H#  n[        R                  " S[C        U5      5      PM%     nn[        R                  " S[I        U5      S-   -  5      n[K        [I        U5      5       H  nUU   UU'   M     UUl&        [I        U5      Ul'        U[
        RP                  -  nU(       a  U[
        RR                  -  nUb8  U[
        RT                  -  n[        R                  " S[C        U5      5      Ul+        [
        RX                  " UUU5      nU[
        RZ                  :w  a  []        S	5      eUU l         U(       a  Xpl/        U(       a  U Ra                  U5        U(       a  U Rc                  U5        [d        Rg                  5         g s  snf )
Nr   zares_channel *zstruct ares_options *  zsock_state_cb is not callabler[   z
char *[%d]r   z#Failed to initialize c-ares channel)4_channel_flagsr$   rJ   re   r-   ARES_OPT_FLAGSintr  ARES_OPT_TIMEOUTMSr  ARES_OPT_TRIESr  ARES_OPT_NDOTSr  ARES_OPT_TCP_PORTr  ARES_OPT_UDP_PORTr  ARES_OPT_SOCK_SNDBUFr  ARES_OPT_SOCK_RCVBUFcallable	TypeError
new_handle_sock_state_cb_handler+   r*   sock_state_cb_dataARES_OPT_SOCK_STATE_CBARES_OPT_EVENT_THREADARES_EVSYS_DEFAULTevsysr   r  ARES_OPT_LOOKUPSlenrI   r  ndomainsARES_OPT_DOMAINSARES_OPT_ROTATEARES_OPT_RESOLVCONFr#  ares_init_optionsr.   r   r  set_local_ipset_local_dev_shutdown_managerr  )r   re   r  r  r  r  r  r  r  r  r*   r  r  r   r!  r"  r#  r  optionsoptmaskuserdatarT   strscrs                            r   r   Channel.__init__  s   (   %0ea((+,((23!GM 3 33G!'D.1GO 7 77G!GM!4!44G!GM!4!44G'G!7!77G'G!7!77G"..EG+!:!::G%11KG.!:!::GM** ?@@}5H *2D&$($7$7G!)1G&!<!<<G)-D&!;!;;G 33GM"hhxW1EFGO!6!66G@GH1DHHX{1~6DHW)9:;A3w<(1gqt )  GO"7|G!6!66G!5!55G&!9!99G&*hhx_9U&VG#""7GW=!!!ABB"Lh'y) 	!? Is   *N!c                 $    U R                  5         g)z;Ensure the channel is destroyed when the object is deleted.N)closer   s    r   __del__Channel.__del__P  s    

r   c                 t    U R                   c  [        S5      e[        R                  " U5      nU [        U'   U$ )a  
Create a callback handle and register it for tracking.

This ensures that:
1. The callback data is wrapped in a CFFI handle
2. The handle is mapped to this channel to keep it alive

Args:
    callback_data: The data to pass to the callback (usually a callable or tuple)

Returns:
    The CFFI handle that can be passed to C functions

Raises:
    RuntimeError: If the channel is destroyed

z,Channel is destroyed, no new queries allowed)r&  RuntimeErrorr$   r3  r!   )r   callback_datarF  s      r   _create_callback_handleChannel._create_callback_handleT  s8    $ == MNN??=1'+8$r   c                 J    [         R                  " U R                  S   5        g Nr   )r-   r  r&  r   s    r   cancelChannel.cancelm  s    q)*r   c                     [         R                  " U R                  S   5      nU[         R                  :w  a   [	        U[
        R                  " U5      5      eg rU  )r-   ares_reinitr&  r.   r   r   strerror)r   rI  s     r   reinitChannel.reinitp  sD    T]]1-.!!!Au~~a011 "r   c                    [         R                  " U R                  S   5      nU[        R                  :X  a<  [        [         R                  [        R                  " [         R                  5      5      e/ n[        [        R                  " U5      5      n[         R                  " U5        UR                  S5       Vs/ s H  oDR                  5       PM     nnU$ s  snf )Nr   ,)r-   ares_get_servers_csvr&  r$   rL   r   ARES_ENOMEMr   rZ  r   r   ares_free_stringsplitstrip)r   csv_strserver_list
csv_stringss        r   r  Channel.serversu  s    ++DMM!,<=diiD,,ennT=M=M.NOOt{{734
g&*4*:*:3*?@*?Qwwy*?@ As   >Cc                    U Vs/ s H4  n[        U[        5      (       a  [        U5      R                  S5      OUPM6     nnSR	                  U5      n[
        R                  " U R                  S   UR                  S5      5      nU[
        R                  :w  a   [        U[        R                  " U5      5      eg s  snf )Nasciir^  r   )
isinstancerM   r   decoder   r-   ares_set_servers_csvr&  encoder.   r   r   rZ  )r   r  rg  re  rd  rI  s         r   r  rh    s    ^ef^eYZAu9M9M{1~,,W5STT^ef((;'%%dmmA&6w8OP!!!Au~~a011 "	 gs   ;B;read_fdwrite_fdc                     [         R                  " U R                  S   [        R                  " SU5      [        R                  " SU5      5        g Nr   ares_socket_t)r-   ares_process_fdr&  r$   cast)r   ro  rp  s      r   
process_fdChannel.process_fd  s8    T]]1-tyy'/RTXT]T]^mowTxyr   c                     [         R                  " U R                  S   [        R                  " SU5      [        R                  " S[
        5      5        g rr  r-   rt  r&  r$   ru  ARES_SOCKET_BAD)r   ro  s     r   process_read_fdChannel.process_read_fd  s;    T]]1-tyy'/RTXT]T]^mo~T  	Ar   c                     [         R                  " U R                  S   [        R                  " S[
        5      [        R                  " SU5      5        g rr  ry  )r   rp  s     r   process_write_fdChannel.process_write_fd  s?    T]]1-tyy//Z\`\e\efuw  ]A  	Br   c                    [         R                  n[         R                  " S5      nUbt  US:  ac  [         R                  " S5      n[        [        R
                  " U5      5      Ul        [        [        R                  " US5      S-  5      Ul        O[        S5      e[        R                  " U R                  S   X#5        U[         R                  :X  a  gUR                  UR                  S-  -   $ )Nzstruct timeval*g        g      ?i@B z-timeout needs to be a positive number or Noner   g    .A)r$   rL   rJ   r)  mathfloortv_secfmodtv_usecr   r-   ares_timeoutr&  )r   tmaxtvtvs       r   r  Channel.timeout  s    		XX'(=Cx!23"4::a=1 #DIIa$5$? @ !PQQ$--*E6?		BJJ223r   r\   r5   c                |   [        U5      (       d  [        S5      e[        R                  " S5      n[        R                  " S5      n[        R
                  " [        R                  [        U5      U5      S:X  a  Un[        R                  nOQ[        R
                  " [        R                  [        U5      U5      S:X  a  Un[        R                  nO[        S5      eU R                  U5      n[        R                  " U R                  S   U[        R                  " US   5      U[        R                  U5        g )Na callable is requiredstruct in_addr*struct ares_in6_addr*r   invalid IP addressr   )r1  r2  r$   rJ   r-   ares_inet_ptonr}   r~   r   r   r   rR  ares_gethostbyaddrr&  sizeofr7   )r   r\   r5   addr4addr6addressfamilyrF  s           r   gethostbyaddrChannel.gethostbyaddr  s    !!455*+01v~~{4/@5JaOG^^F  +d2CeMQRRG__F122//9a 0'4;;wqz;RTZ\`\i\ikstr   r   )r  r   protore   hostrr   r  r   r  c                   [        U5      (       d  [        S5      eUc  [        R                  nO;[	        U[
        5      (       a  [        U5      R                  S5      nO[        U5      nU R                  U5      n	[        R                  " S5      n
Xjl        X:l        XJl        XZl        [        R                   " U R"                  S   [%        U5      X[        R&                  U	5        g )Nr  rj  zstruct ares_addrinfo_hints*r   )r1  r2  r$   rL   rk  r)  strrn  r   rR  rJ   ai_flags	ai_familyai_socktypeai_protocolr-   ares_getaddrinfor&  r	   rE   )r   r  rr   r  r   r  re   r5   r;   rF  hintss              r   getaddrinfoChannel.getaddrinfo  s     !!455<iiGc""$i&&w/G!$'G//967  !dmmA.
40@'RVRcRcemnr   )query_classr   
query_typer  c          	         [        U5      (       d  [        S5      eX R                  ;  a  [        S5      eX0R                  ;  a  [        S5      eU R                  U5      n[        R                  " S5      n[        R                  " U R                  S   [        U5      UU[        R                  UU5      nU[        R                  :w  a6  [        R                  US5        [!        U["        R$                  " U5      5      eg)a`  
Perform a DNS query.

Args:
    name: Domain name to query
    query_type: Type of query (e.g., QUERY_TYPE_A, QUERY_TYPE_AAAA, etc.)
    query_class: Query class (default: QUERY_CLASS_IN)
    callback: Callback function that receives (result, errno)

The callback will receive a DNSResult object containing answer, authority, and additional sections.
r  invalid query type specifiedinvalid query class specifiedzunsigned short *r   N)r1  r2  
__qtypes__r   __qclasses__rR  r$   rJ   r-   ares_query_dnsrecr&  r	   rA   r.   r!   r0   r   r   rZ  )r   r   r  r  r5   rF  qidr2   s           r   queryChannel.query  s     !!455__,;<<///<==//9hh)*''MM!t!!
 T&&&""8T2FENN6$:;; 'r   c                L  ^
^ [        U5      (       d  [        S5      eX R                  ;  a  [        S5      eX0R                  ;  a  [        S5      eU R
                  [        R                  -  (       a  SO[        R                  n[        R                  " S5      n[        R                  " USU[        R                  [        R                  5      nU[        R                  :w  a   [        U[         R"                  " U5      5      eUS   m
[        R$                  " T
['        U5      UU5      nU[        R                  :w  a6  [        R(                  " T
5        [        U[         R"                  " U5      5      eUmU
U4S jnU R+                  U5      n	[        R,                  " U R.                  S   T
[        R0                  U	5      nU[        R                  :w  aL  [2        R5                  U	S5        [        R(                  " T
5        [        U[         R"                  " U5      5      eg)a  
Perform a DNS search (honors resolv.conf search domains).

Args:
    name: Domain name to search
    query_type: Type of query (e.g., QUERY_TYPE_A, QUERY_TYPE_AAAA, etc.)
    query_class: Query class (default: QUERY_CLASS_IN)
    callback: Callback function that receives (result, errno)

The callback will receive a DNSResult object containing answer, authority, and additional sections.
r  r  r  r   zares_dns_record_t **c                 z   >  T" X5        [         R                  " T5        g ! [         R                  " T5        f = fr#   )r-   ares_dns_record_destroy)r6   errorr?   original_callbacks     r   cleanup_callback(Channel.search.<locals>.cleanup_callback/  s/    5!&0 ,,V4,,V4s   " :N)r1  r2  r  r   r  r'  r-   ARES_FLAG_NORECURSEARES_FLAG_RDr$   rJ   ares_dns_record_createARES_OPCODE_QUERYARES_RCODE_NOERRORr.   r   r   rZ  ares_dns_record_query_addr	   r  rR  ares_search_dnsrecr&  rA   r!   r0   )r   r   r  r  r5   	dns_flagsdnsrec_pr2   r  rF  r?   r  s             @@r   searchChannel.search  s    !!455__,;<<///<== ++(@(@@AtGXGX	8823,,""##
 T&&&FENN6$:;;! //t	
 T&&&((0FENN6$:;; %	5 //0@A((MM!!!	
 T&&&""8T2((0FENN6$:;; 'r   c                    [         R                  " S5      n[         R                  " S5      n[        R                  " [        R
                  [        U5      U5      S:X  aC  [        R                  " U R                  S   [        R                  " UR                  5      5        g [        R                  " [        R                  [        U5      U5      S:X  a%  [        R                  " U R                  S   U5        g [        S5      e)Nr  r  r   r   r  )r$   rJ   r-   r  r}   r~   r   ares_set_local_ip4r&  ntohls_addrr   ares_set_local_ip6r   )r   ipr  r  s       r   rA  Channel.set_local_ipC  s    *+01v~~{2F!K##DMM!$4fll5<<6PQ  +b/5IQN##DMM!$4e<122r   r  c                f   [        U5      (       d  [        S5      e[        U5      S:X  a  Uu  pE[        R                  " S5      n[
        R                  " [        R                  [        U5      [        R                  " UR                  5      5      S:w  a  [        SU-  5      e[        R                  Ul        [        R                  " U5      Ul        UnO[        U5      S:X  a  Uu  pEp[        R                  " S5      n
[
        R                  " [        R                   [        U5      [        R                  " U
R"                  5      5      S:w  a  [        SU-  5      e[        R                   U
l        [        R                  " U5      U
l        [        R(                  " U5      U
l        Xl        U
nO[        S	5      eU R/                  U5      n[
        R0                  " U R2                  S
   [        R4                  " SU5      [        R6                  " US
   5      U[
        R8                  U5        g )Nr     struct sockaddr_in*r   zInvalid IPv4 address %r   struct sockaddr_in6*zInvalid IPv6 address %rzInvalid address argumentr   zstruct sockaddr*)r1  r2  r;  r$   rJ   r-   r  r}   r~   r   	addressofsin_addrr   
sin_familyhtonssin_portr   	sin6_addrsin6_family	sin6_porthtonlsin6_flowinfosin6_scope_idrR  ares_getnameinfor&  ru  r  r<   )r   r  re   r5   r  rr   sa4saflowinfoscope_idsa6rF  s               r   getnameinfoChannel.getnameinfoM  s   !!455w<1 JR((01C""6>>;r?DNNSVS_S_D`aeff !:R!?@@#^^CN!<<-CLB\Q-4*Rx((12C""6??KOT^^TWTaTaEbcghh !:R!?@@$ooCO"LL.CM &X 6C (B788//9dmmA.		:Lb0QSWS^S^_abc_dSeglnrnn  BJ  	Kr   c                 L    [         R                  " U R                  S   U5        g rU  )r-   ares_set_local_devr&  )r   devs     r   rB  Channel.set_local_devi  s    a 0#6r   c                     U R                   c  gU R                   Ssol         [        R                  XR                  5        g)av  
Close the channel as soon as it's safe to do so.

This method can be called from any thread. The channel will be destroyed
safely using a background thread with a 1-second delay to ensure c-ares
has completed its cleanup.

Note: Once close() is called, no new queries can be started. Any pending
queries will be cancelled and their callbacks will receive ARES_ECANCELLED.

N)r&  rC  r  r4  )r   r  s     r   rL  Channel.closel  s7     ==  "&))'3M3MNr   c                    [         R                  " U R                  S   Ub  US:  a  [        US-  5      OS5      nU[         R                  :X  a  gU[         R
                  :X  a  g[        U[        R                  " U5      5      e)z
Wait until all pending queries are complete or timeout occurs.

Args:
    timeout: Maximum time to wait in seconds. Use -1 for infinite wait.
r   r%  r   TF)	r-   r  r&  r)  r.   ARES_ETIMEOUTr   r   rZ  )r   r  rI  s      r   waitChannel.wait  sr     &&t}}Q'7QXQdiptuiu#gn:M{}~!!!$$$$Au~~a011r   )r&  r'  r4  r  r  r#   )Ar   r   r   r   r-   rx   r   ARES_REC_TYPE_ANYr   r   r   r   r   r   r   r   r   r   r   r   r  ARES_CLASS_INARES_CLASS_CHAOSARES_CLASS_HESOIDARES_CLASS_NONEARES_CLASS_ANYr  r   r)  floatr   r   r  rM   r   boolr   rM  rR  rV  r[  propertylistr  setterrv  r{  r~  r  r   r  r}   AddressFamilyr  QUERY_CLASS_INr  r  rA  IP4IP6r  rB  rL  r  r   r   r   r   r    r      s&   &&(?(?AWAWY]YoYoqu  rJ  rJ  LP  Ld  Ld  fj  f{  f{  }A  }U  }U  W[  Wl  Wl  nr  nD  nD  FJ  F\  F\  ^b  ^t  ^t  vz  vM  vM  OS  Oe  Oe  gk  g}  g}  ~J&&(=(=t?U?UW[WkWkmq  nA  nA  BL )-,0(,(,+/+/BFBF48NR:>=A %59,0<@#r" r" #5/r" !	r"
 !r" $C=r" $C=r" #8E#u*,=#>?r" #8E#u*,=#>?r"  UD 01r" !)3d2CT2I)J Kr" +33-r" .6c]r" r" !eT!12r"  %SM!r"" #(UD(8"9#r"" FJ#r"h2+2
 c   ^^2xc5j(9: 2t 2 2z# z z zAc Ad AB B B4&u# uHc3Z=M4N uSW u. ()oo smo
 $$o o o o C:t+,o 
o< GU "<# "<3 "< "<`hjmorisuyiy`z "<  @D "<H HV E<3 E<C E< E<aiknpsjtvzjza{ E<  AE E<N3K5c? K3 KXWZ\_V`bfVfMg Klp K87O.2E 24 2 2r   c                   $    \ rS rSr% Sr\\S'   Srg)r   i  z Data for A (IPv4 address) recordr\   r   Nr   r   r   r   r  r  __annotations__r   r   r   r   r   r     s
    *
Ir   r   c                   $    \ rS rSr% Sr\\S'   Srg)r   i  z#Data for AAAA (IPv6 address) recordr\   r   Nr  r   r   r   r   r     s
    -
Ir   r   c                   .    \ rS rSr% Sr\\S'   \\S'   Srg)r   i  z"Data for MX (mail exchange) recordr]   r^   r   N	r   r   r   r   r  r)  r  r  r   r   r   r   r   r     s    ,MMr   r   c                   $    \ rS rSr% Sr\\S'   Srg)r   i  zData for TXT (text) recordr&   r   N)r   r   r   r   r  rM   r  r   r   r   r   r   r     s
    $
Kr   r   c                   8    \ rS rSr% Sr\\S'   \\S'   \\S'   Srg)r   i  z;Data for CAA (certification authority authorization) recordr_   r`   ra   r   Nr  r   r   r   r   r     s    EM	HJr   r   c                   $    \ rS rSr% Sr\\S'   Srg)r   i  z&Data for CNAME (canonical name) recordrb   r   Nr  r   r   r   r   r     s
    0Jr   r   c                   V    \ rS rSr% Sr\\S'   \\S'   \\S'   \\S'   \\S'   \\S'   S	rg
)r   i  z0Data for NAPTR (naming authority pointer) recordrc   rd   re   r;   rf   rg   r   Nr  r   r   r   r   r     s$    :JOJLKr   r   c                   $    \ rS rSr% Sr\\S'   Srg)r   i  z Data for NS (name server) recordrh   r   Nr  r   r   r   r   r     s
    *Lr   r   c                   $    \ rS rSr% Sr\\S'   Srg)r   i  zData for PTR (pointer) recordri   r   Nr  r   r   r   r   r     s
    'Jr   r   c                   `    \ rS rSr% Sr\\S'   \\S'   \\S'   \\S'   \\S'   \\S'   \\S	'   S
rg)r   i  z(Data for SOA (start of authority) recordrj   rk   rl   rm   rn   ro   rp   r   N)	r   r   r   r   r  r  r  r)  r   r   r   r   r   r     s(    2JJKLJKLr   r   c                   B    \ rS rSr% Sr\\S'   \\S'   \\S'   \\S'   Srg)	r   i  zData for SRV (service) recordr]   rq   rr   rs   r   Nr  r   r   r   r   r     s    'MK
IKr   r   c                   B    \ rS rSr% Sr\\S'   \\S'   \\S'   \\S'   Srg)	r   i  z9Data for TLSA (DANE TLS authentication) record - RFC 6698rt   ru   rv   rw   r   N)	r   r   r   r   r  r)  r  rM   r   r   r   r   r   r     s    COM  r   r   c                   8    \ rS rSr% Sr\\S'   \\S'   \\S'   Sr	g)r   i  z2Data for HTTPS (service binding) record - RFC 9460r]   rs   rS   r   N)
r   r   r   r   r  r)  r  r  r  r   r   r   r   r   r     s    <MKLr   r   c                   8    \ rS rSr% Sr\\S'   \\S'   \\S'   Srg)r   i  z<Data for URI (Uniform Resource Identifier) record - RFC 7553r]   rq   rs   r   Nr  r   r   r   r   r     s    FMKKr   r   c                   n    \ rS rSr% Sr\\S'   \\S'   \\S'   \\S'   \\	\
\\\\\\\\\\\\4   \S'   Srg	)
r   i  z'Represents a single DNS resource recordr   r   r   r   r&   r   N)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     sK    1
I
I	H
^\=m]M. / /r   r   c                   J    \ rS rSr% Sr\\   \S'   \\   \S'   \\   \S'   Srg)r   i   z8Represents a complete DNS query result with all sectionsr   r   r   r   N)	r   r   r   r   r  r  r   r  r   r   r   r   r   r      s#    BOIYr   r   c                   D    \ rS rSr% Sr\\S'   \\   \S'   \\   \S'   Srg)
HostResulti
  z%Result from gethostbyaddr() operationr   aliases	addressesr   N)	r   r   r   r   r  r  r  r  r   r   r   r   r  r  
  s    /
I#YCyr   r  c                   4    \ rS rSr% Sr\\S'   \\   \S'   Srg)NameInfoResulti  z#Result from getnameinfo() operationr:   r;   r   N)	r   r   r   r   r  r  r  r   r   r   r   r   r  r    s    -
Ic]r   r  c                   V    \ rS rSr% Sr\\S'   \\S'   \\S'   \\S'   \\S'   \\S'   S	rg
)AddrInfoNodei  z-Single address node from getaddrinfo() resultr   re   r  socktypeprotocolr\   r   N)	r   r   r   r   r  r)  r  tupler   r   r   r   r  r    s#    7	HJKMM
Kr   r  c                   8    \ rS rSr% Sr\\S'   \\S'   \\S'   Srg)AddrInfoCnamei!  z+CNAME information from getaddrinfo() resultr   aliasr   r   Nr  r   r   r   r  r  !  s    5	HJ
Ir   r  c                   :    \ rS rSr% Sr\\   \S'   \\   \S'   Sr	g)AddrInfoResulti(  z,Complete result from getaddrinfo() operationcnamesnodesr   N)
r   r   r   r   r  r  r  r  r  r   r   r   r   r  r  (  s    6r   r  r  c                 v   [        [        R                  " U R                  5      5      n/ n/ nSnU R                  U   [        R
                  :w  ac  UR                  [        [        R                  " U R                  U   5      5      5        US-  nU R                  U   [        R
                  :w  a  Mc  SnU R                  U   [        R
                  :w  a  [        R                  " S[        R                  5      n[        R
                  [        R                  " U R                  U R                  U   U[        R                  5      :w  a=  UR                  [        [        R                  " U[        R                  5      5      5        US-  nU R                  U   [        R
                  :w  a  M  [        XUS9$ )z.Parse c-ares hostent structure into HostResultr   r   r[   )r   r  r  )r   r$   r   h_name	h_aliasesrL   rO   h_addr_listrJ   r-   r{   r|   
h_addrtyper  )r4   r   r  r  rT   r   s         r   r/   r/   1  sF   T[[01DGI	A


A
$))
+yW->->q-A!BCD	Q 

A
$))
+ 	
A


a
 DII
-hhx!6!6799++G,>,>@S@STU@VX[]a]r]rssYt{{38M8M'NOP	Q	 

a
 DII
- 4IFFr   c                     [        [        R                  " U 5      5      nU[        R                  :w  a  [        [        R                  " U5      5      OSn[	        X#S9$ )z)Parse c-ares nameinfo into NameInfoResultN)r:   r;   )r   r$   r   rL   r  )r:   r;   node_strservice_strs       r   r9   r9   F  s@    T*+H5<		5I)DKK01tKx==r   c           	      2   U R                   nU R                  nU R                  nU R                  nU R                  nUR
                  U R                  :X  d   e[        R                  " S[        R                  5      nUR
                  [        R                  :X  a  [        R                  n[        R                  " SU5      n[        R                  [        R                  " UR                   [        R"                  " UR$                  5      U[        R                  5      :w  aG  [        R&                  " U[        R                  5      [        R(                  " UR*                  5      4n	GO#[-        S5      eUR
                  [        R.                  :X  a  [        R.                  n[        R                  " SU5      n[        R                  [        R                  " UR0                  [        R"                  " UR2                  5      U[        R                  5      :w  a\  [        R&                  " U[        R                  5      [        R(                  " UR4                  5      UR6                  UR8                  4n	O[-        S5      e[-        S5      e[;        XXsXIS9$ )z5Parse a single c-ares addrinfo node into AddrInfoNodezchar []r  zfailed to convert IPv4 addressr  zfailed to convert IPv6 addresszinvalid sockaddr family)r   re   r  r  r  r\   )ai_ttlr  r  r  ai_addr	sa_familyr  r$   rJ   r-   r{   r}   r~   ru  rL   r|   r  r  r  r   ntohsr  r   r   r  r  r  r  r  r  )
	ares_noder   re   r  r  addr_structr  r  rg  r\   s
             r   parse_addrinfo_noder.  M  s   


CE$$H$$H##K  I$7$7777	)T22	3B.II+[999++ALL$..:TVXZ^ZoZoppKKD$9$9:FLL<TUD=>>			&//	1II,k:99++AMM4>>!++;VXZ\`\q\qrrKKD$9$9:FLL<UWXWfWfhihwhwxD=>>233CVYammr   c           	          [        U R                  [        [        R                  " U R
                  5      5      [        [        R                  " U R                  5      5      S9$ )z7Parse a single c-ares addrinfo cname into AddrInfoCname)r   r  r   )r  r   r   r$   r   r  r   )
ares_cnames    r   parse_addrinfo_cnamer1  n  sB    NNJ$4$456t{{:??34 r   c                    / n/ nU R                   nU[        R                  :w  a<  UR                  [	        U5      5        UR
                  nU[        R                  :w  a  M<  U R                  nU[        R                  :w  a<  UR                  [        U5      5        UR                  nU[        R                  :w  a  M<  [        R                  " U 5        [        XS9$ )z3Parse c-ares addrinfo structure into AddrInfoResult)r  r  )r  r$   rL   rO   r1  nextr  r.  ai_nextr-   ares_freeaddrinfor  )ares_addrinfor  r  	cname_ptrnode_ptrs        r   rC   rC   w  s    FE$$I
tyy
 *956NN	 tyy
  ""H
dii
(23## dii
 	=)55r   )HARES_FLAG_USEVCARES_FLAG_PRIMARYARES_FLAG_IGNTCr  ARES_FLAG_STAYOPENARES_FLAG_NOSEARCHARES_FLAG_NOALIASESARES_FLAG_NOCHECKRESPARES_FLAG_EDNSARES_FLAG_NO_DFLT_SVRARES_NI_NOFQDNARES_NI_NUMERICHOSTARES_NI_NAMEREQDARES_NI_NUMERICSERVARES_NI_DGRAMARES_NI_TCPARES_NI_UDPARES_NI_SCTPARES_NI_DCCPARES_NI_NUMERICSCOPEARES_NI_LOOKUPHOSTARES_NI_LOOKUPSERVICEARES_NI_IDNARES_NI_IDN_ALLOW_UNASSIGNED ARES_NI_IDN_USE_STD3_ASCII_RULESrz  QUERY_TYPE_AQUERY_TYPE_AAAAQUERY_TYPE_ANYQUERY_TYPE_CAAQUERY_TYPE_CNAMEQUERY_TYPE_HTTPSQUERY_TYPE_MXQUERY_TYPE_NAPTRQUERY_TYPE_NSQUERY_TYPE_PTRQUERY_TYPE_SOAQUERY_TYPE_SRVQUERY_TYPE_TLSAQUERY_TYPE_TXTQUERY_TYPE_URIr  QUERY_CLASS_CHAOSQUERY_CLASS_HSQUERY_CLASS_NONEQUERY_CLASS_ANYARES_VERSIONr   r    r   r
   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  )_caresr   r$   r   r-   _cffi_backendr.   ares_library_initARES_LIB_INIT_ALLrP  ares_threadsafety r   utilsr   r   r	   _versionr
   r  r}   r   collections.abcr   r   dataclassesr   typingr   r   r   r   r   queuer   r  r  r)  r  r  r9  r:  r;  r  r<  r=  r>  r?  r@  rA  rB  rC  rD  rE  rF  rG  rH  rI  rJ  rK  rL  rM  rN  rO  rP  rz  rx   rQ  r   rR  r  rS  r   rT  r   rU  r   rW  r   rX  r   rY  r   rZ  r   r[  r   r\  r   r^  r   r]  r   rV  r   r_  r  r  r  r`  r  ra  r  rb  r  rc  r   ares_versionrL   rd  PYCARES_ADDRTTL_SIZEr   r   r!   r  
def_externr+   r7   r<   rA   rE   rY   r   r>   r   rC  r    r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r/   r9   r.  r1  rC   __all__r   r   r   <module>ru     s   , , ..t/E/EFF$,
4
55
?
@@  5 5 !    . ! @ @ CHoCc3 &&** &&.. ,, ,, .. 22 $$22  $$.. (( .. ""    00 ,, 22 #@@ #'#H#H   && ##))''''++ %%++ %%''''''''))++ '' ##)) '''' %%T%6%6tyy%ABC 		 	 ,. Di( - 1 1 & &  & &  & &, & &"&DHNTn/9 /9f ,- x2 x2|         
                         ! ! !       	/ 	/ 	/            
         Gj G*>^ >nl nB 6^ 6(Xr   