
    N j                   \   % S r SSKJr  SSKrSSKrSSKrSSKrSSKJr  SSK	J
r
JrJr  SSKJr  SSKJrJr  SSKJr  SS	KJr  SS
KJr  SSKJr  SSK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&J'r'  SSK(J)r)J*r*J+r+J,r,J-r-  SSK.J/r/J0r0  SSK1J2r2  SSK3J4r4J5r5  SSK6J7r7  SSK1J8r8J9r9J:r:  \(       aw  SSK;J<r<  SSK(J=r=  SSK.J>r>  SSK?J@r@  SSKAJBrB  SSKCJDrDJErEJFrF  SSKGJHrHJIrI  \"" S5      rJ\S \K\>/S4   rL\S \K\M-  /S4   rN\S \0/S4   rO\S /S4   rP\S \Q\M/S4   rR\S\K\Q4   rT\S\K\-4   rU\" \S!S"9rVS#\WS$'   \ " S% S&5      5       rX " S' S(\5      rY " S) S*\05      rZ " S+ S,\Z\45      r[ " S- S.\Z\55      r\S8S/ jr] " S0 S15      r^\!S2   r_ " S3 S \^5      r`\$ " S4 S5\^5      5       ra\$ " S6 S75      5       rbg)9z0
The Curl CFFI WebSocket client implementation.
    )annotationsN)InvalidStateError)	AwaitableCallable	Generator)suppress)	dataclassfield)IntEnum)partialdumpsloads)uniform)select)TYPE_CHECKINGClassVarLiteralTypeVarcastfinal   )CURL_SOCKET_BADget_selector)	CurlECode
CurlFollowCurlInfoCurlOpt
CurlWsFlag)Curl	CurlError)CurlCffiWarning   )SessionClosedTimeout)Response)NOT_SET
NotSetTypeset_curl_options)Self)CurlHttpVersion)CurlWsFrame)CookieTypes)HeaderTypes)BrowserTypeLiteralExtraFingerprintsExtraFpDict)AsyncSession	ProxySpecT	WebSocket),:)
separatorszpartial[str]dumps_partialc                  \    \ rS rSr% SrSrS\S'   SrS\S'   S	rS
\S'   \	" S S9r
S\S'   Srg)WebSocketRetryStrategy8   u)  Configurable WebSocket policy for retrying failed message receives.

When enabled, each failed receive attempt will use exponential backoff with
jitter.

Calculation: ``delay * 2^(count - 1) ± 10%``

Args:
    retry: Enable or disable WebSocket message receive retry policy.
    delay: The base value (seconds) to compute the retry delay from.
    count: How many times to retry a receive operation before giving up.
    codes: Set of ``CurlECode`` values for which the receive operation
        should be retried. Default is ``CurlECode.RECV_ERROR``.
Fboolretryg333333?floatdelay   intcountc                 $    [         R                  1$ N)r   
RECV_ERROR     n/root/GenerationalWealth/GenerationalWealth/venv/lib/python3.13/site-packages/curl_cffi/requests/websockets.py<lambda>WebSocketRetryStrategy.<lambda>L   s    9;O;O:PrI   )default_factoryzset[CurlECode]codesrH   N)__name__
__module____qualname____firstlineno____doc__r?   __annotations__rA   rD   r
   rN   __static_attributes__rH   rI   rJ   r<   r<   8   s6     E4E5E3N!2PQE>QrI   r<   c                  `    \ rS rSrSrSrSrSrSrSr	Sr
S	rS
rSrSrSrSrSrSrSrSrSrSrSrg)WsCloseCodeO   z?See: https://www.iana.org/assignments/websocket/websocket.xhtml  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  i  rH   N)rO   rP   rQ   rR   rS   OK
GOING_AWAYPROTOCOL_ERRORUNSUPPORTED_DATAUNKNOWNABNORMAL_CLOSUREINVALID_DATAPOLICY_VIOLATIONMESSAGE_TOO_BIGMANDATORY_EXTENSIONINTERNAL_ERRORSERVICE_RESTARTTRY_AGAIN_LATERBAD_GATEWAYTLS_HANDSHAKEUNAUTHORIZED	FORBIDDENTIMEOUTrU   rH   rI   rJ   rW   rW   O   sc    I	BJNGLONOOKMLIGrI   rW   c                  @   ^  \ rS rSrSr S     SU 4S jjjrSrU =r$ )WebSocketErrorf   zWebSocket-specific error.c                $   > [         TU ]  X5        g rF   )super__init__)selfmessagecode	__class__s      rJ   rq   WebSocketError.__init__i   s     	'rI   rH   )r   )rs   strrt   z$WsCloseCode | CurlECode | Literal[0]returnNone)rO   rP   rQ   rR   rS   rq   rU   __classcell__ru   s   @rJ   rm   rm   f   s/    # JK(("F(	( (rI   rm   c                      \ rS rSrSrSrg)WebSocketClosedo   zWebSocket is already closed.rH   NrO   rP   rQ   rR   rS   rU   rH   rI   rJ   r}   r}   o   s     'rI   r}   c                      \ rS rSrSrSrg)WebSocketTimeoutu   zWebSocket operation timed out.rH   Nr   rH   rI   rJ   r   r   u   s     )rI   r   c                H     U R                  S5        g! [         a     gf = f)aN  
Called by the event loop when fd becomes readable/writable.

We try to set_result() and silently ignore InvalidStateError which is
raised if the future was already finished/cancelled concurrently.
This avoids spurious 'Exception in callback' traces in uvloop/asyncio.

Intentionally using try/except since this is frequently called.
N)
set_result_InvalidStateError)futs    rJ   _safe_set_resultr   {   s%    t s    
!!c                      \ rS rSr% SrS\S'   SSS.       SS jjr\SS	 j5       r\SS
 j5       r	\SS j5       r
\SS j5       r\SS j5       rSS jrSrg)BaseWebSocket   _curl	autoclose_close_code_close_reasondebugclosedztuple[str, ...]	__slots__TF)r   r   c               R    Xl         X l        S U l        S U l        X0l        SU l        g )NFr   )rr   curlr   r   s       rJ   rq   BaseWebSocket.__init__   s*     )-
('+)- 
!rI   c                    [        U R                  [        5      (       a  [        U R                  S9U l        U R                  $ )z;Return reference to Curl associated with current WebSocket.)r   )
isinstancer   r)   r!   r   rr   s    rJ   r   BaseWebSocket.curl   s/     djj*--DJJ/DJzzrI   c                    U R                   $ )z<The WebSocket close code, if the connection has been closed.)r   r   s    rJ   
close_codeBaseWebSocket.close_code   s     rI   c                    U R                   $ )z>The WebSocket close reason, if the connection has been closed.)r   r   s    rJ   close_reasonBaseWebSocket.close_reason   s     !!!rI   c                6    [         R                  " SU 5      U-   $ )N!H)structpack)rt   reasons     rJ   _pack_close_frameBaseWebSocket._pack_close_frame   s    {{4&//rI   c                   [        U 5      S:  a  [        R                  nSnX4$  [        R                  " SU 5      S   nU SS  R                  5       nU[        R                  :X  d  US:  d  US:  a  [        S	U 3[        R                  5      eX4$ ! [         a   n[        S[        R                  5      UeS nAf[         a   n[        S[        R                  5      UeS nAff = f)
Nr    r   r   zInvalid close messagezInvalid close framerY   i  zInvalid close code: )lenrW   r^   r   unpack_fromdecodeUnicodeDecodeErrorrm   r`   	Exceptionr\   )framert   r   es       rJ   _unpack_close_frame!BaseWebSocket._unpack_close_frame   s    u:>#++DF& |#
))$6q9qr))+ {***dTkTT\$*4&1;3M3M  | & $+[-E-E  $);+E+Es#   -B 
C%B88C%C  C%c                F    SU l         U R                  R                  5         g)z$Terminate the underlying connection.TN)r   r   closer   s    rJ   	terminateBaseWebSocket.terminate   s    		rI   )r   r   r   r   r   r   N)r   Curl | NotSetTyper   r>   r   r>   rx   ry   )rx   r!   )rx   z
int | None)rx   
str | None)rt   rC   r   bytesrx   r   )r   r   rx   ztuple[int, str]rx   ry   )rO   rP   rQ   rR   r   rT   rq   propertyr   r   r   staticmethodr   r   r   rU   rH   rI   rJ   r   r      s    "I  =APU"%"59"IM"	"       " " 0 0  0rI   r   )openr   datars   errorc                     ^  \ rS rSrSrSr\4SSSSSSSSS.                   S!U 4S jjjjrS"S	 jrS#S
 jr	      S$S j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%S jjrS&S jrS'S jrS(S jr\S.S)S jjr\R$                  4     S*S jjrS+S jrS,S jrS-S jr\S.     S.S jjrS/S jrS0S1S jjr\R8                  S4S2S jjrS rU =r$ )3r6      z)A WebSocket implementation using libcurl.)skip_utf8_validation	_emitterskeep_runningTFN)r   r   r   on_openon_closeon_data
on_messageon_errorc                 > [         T
U ]  XUS9  X0l        SU l        0 U l        U(       a  XPR                  S'   U(       a  X`R                  S'   U(       a  XpR                  S'   U(       a  XR                  S'   U	(       a  XR                  S'   gg)	a$  
Args:
    autoclose: whether to close the WebSocket after receiving a close frame.
    skip_utf8_validation: whether to skip UTF-8 validation for text frames in
        run_forever().
    debug: print extra curl debug info.

    on_open: open callback, ``def on_open(ws)``
    on_close: close callback, ``def on_close(ws, code, reason)``
    on_data: raw data receive callback, ``def on_data(ws, data, frame)``
    on_message: message receive callback, ``def on_message(ws, message)``
    on_error: error callback, ``def on_error(ws, exception)``
r   r   r   Fr   r   r   rs   r   N)rp   rq   r   r   r   )rr   r   r   r   r   r   r   r   r   r   ru   s             rJ   rq   WebSocket.__init__   s|    4 	duE*>!"'HJ%,NN6"&.NN7#%,NN6"(2NN9%&.NN7# rI   c                >    U R                   (       a  [        S5      eU $ )NWebSocket is closedr   r}   r   s    rJ   __iter__WebSocket.__iter__	  s    ;;!"788rI   c                f    U R                  5       u  pU[        R                  -  (       a  [        eU$ rF   )recvr    CLOSEStopIterationrr   msgflagss      rJ   __next__WebSocket.__next__  s(    YY[
:###
rI   c                &   U R                   R                  U5      nU(       a   U" U /UQ76 ng g ! [         aW  nU R                   R                  S5      nU(       a  U" X5      n S nAg [        R                  " SU S3[
        SS9   S nAg S nAff = f)Nr   zWebSocket callback 'z' failedr   )
stacklevel)r   getr   warningswarnr#   )rr   
event_typeargscallback_r   error_callbacks          rJ   _emitWebSocket._emit  s    
 261C1CJ1OT)D) 
  ?C~~?Q?Q@ "&t/AMM.zl(C'#$s   	/ 
B*B(BB   zgzip, deflate, brr   r   c                L   U R                   n[        S 0 SU_SS_SU_SSU/_SSU/_SSU/_S	U_S
U_SU_SU_SSU	/_SU
_SU_SSU/_SU_SU_SU_SU_SU_SU_SU_SU_SU_SU_SU_SU_SU_SU_6nUR                  [        R                  S5      nUR                  5         U $ )!a  Connect to the WebSocket.

libcurl automatically handles pings and pongs.
ref: https://curl.se/libcurl/c/libcurl-ws.html

Args:
    url: url for the requests.
    params: query string for the requests.
    headers: headers to send.
    cookies: cookies to use.
    auth: HTTP basic auth, a tuple of (username, password), only basic auth is
        supported.
    timeout: how many seconds to wait before giving up.
    allow_redirects: whether to allow redirection. Can be a bool, a
        ``CurlFollow`` value, or the string ``"safe"``.
    max_redirects: max redirect counts, default 30, use -1 for unlimited.
    proxies: dict of proxies to use, prefer to use ``proxy`` if they are the
        same. format: ``{"http": proxy_url, "https": proxy_url}``.
    proxy: proxy to use, format: "http://user@pass:proxy_url".
        Can't be used with `proxies` parameter.
    proxy_auth: HTTP basic auth for proxy, a tuple of (username, password).
    verify: whether to verify https certs.
    referer: shortcut for setting referer header.
    accept_encoding: shortcut for setting accept-encoding header.
    impersonate: which browser version to impersonate.
    ja3: ja3 string to impersonate.
    akamai: akamai string to impersonate.
    perk: perk string to impersonate.
    extra_fp: extra fingerprints options, in complement to ja3 and akamai str.
    default_headers: whether to set default browser headers.
    default_encoding: Encoding for decoding content if charset is not found.
        Defaults to "utf-8".
    quote: Set characters to be quoted (percent-encoded). Default safe
        string is ``!#$%&'()*+,/:;=?@[]~``. If set to a string, the characters
        will be removed from the safe string. If set to ``False``, the URL
        is used as-is (you must encode it yourself).
    http_version: Limiting http version, defaults to http2.
    interface: which interface to use.
    cert: a tuple of (cert, key) filenames for client cert.
    max_recv_speed: maximum receive speed, bytes per second.
    curl_options: extra curl options to use.
r   methodGETurlparams_listNheaders_listcookies_listauthtimeoutallow_redirectsmax_redirectsproxies_listproxy
proxy_authverify_listrefereraccept_encodingimpersonateja3akamaiperkextra_fpdefault_headersquotehttp_version	interfacemax_recv_speedcertcurl_optionsr   rH   )r   r*   setoptr   CONNECT_ONLYperform)rr   r   paramsheaderscookiesr   r   r   r   proxiesr   r   verifyr   r   r   r   r   r   r   r   r   r   r   r  r  r  r   r   s                                rJ   connectWebSocket.connect,  sg   Z YY 


 
 v	

 
 
 
 
 ,
 (
 
 
 "
 v
 
  ,!
" $#
$ %
& '
( )
* +
, ,-
. /
0 &1
2  3
4 *5
6 7
8 &9
@ KK,,a0rI   c                   U R                   (       a  [        S5      eU R                  R                  5       u  pUR                  [
        R                  -  (       a@   U R                  U5      u  U l        U l	        U R                  (       a  U R                  5         X4$ ! [         a2  nUR                  U l        U R                  UR                  5        e SnAff = f)z2Receive a single curl websocket fragment as bytes.WebSocket is already closedN)r   r}   r   ws_recvr   r    r   r   r   r   rm   rt   r   r   )rr   chunkr   r   s       rJ   recv_fragmentWebSocket.recv_fragment  s     ;;!"?@@yy((*;;)))7;7O7OPU7V4 $"4 ~~

| "  $%66 

166"s   B 
C(-CCc                   / nSnU R                   R                  [        R                  5      nU[        :X  a  [        S[        R                  5      e  U R                  5       u  pEUR                  nUR                  U5        UR                  S:X  a  U[        R                  -  S:X  a  OMZ  SR%                  U5      U4$ ! [         a<  nUR                  [        R                   :X  a  [#        U// / S5      u      n SnANUe SnAff = f)zs
Receive a frame as bytes. libcurl splits frames into fragments, so we have to
collect all the chunks for a frame.
r   Invalid active socket      ?NrI   )r   getinfor   ACTIVESOCKETr   rm   r   NO_CONNECTION_AVAILABLEr  r   append	bytesleftr    CONTr"   rt   AGAINr   join)rr   chunksr   sock_fdr  r   r   r   s           rJ   r   WebSocket.recv  s    
 !))##H$9$9:o% ')J)J  #113e$??a'EJOO,Cq,H   xx&&  66Y__, %gYB<GAq!s   AC   
D
1D DDc                    U R                  5       u  pU[        R                  -  (       d  [        S[        R
                  5      eUR                  S5      $ )zReceive a text frame.zNot valid text frameutf-8)r   r    TEXTrm   rW   r`   r   )rr   r   r   s      rJ   recv_strWebSocket.recv_str  s>    iik
' !79Q9QRR{{7##rI   r   c               2    U R                  5       nU" U5      $ )zMReceive a JSON frame.

Args:
    loads: JSON decoder, default is json.loads.
)r%  )rr   r   r   s      rJ   	recv_jsonWebSocket.recv_json  s     }}T{rI   c                   U[         R                  -  (       a  SU l        U R                  (       a  [	        S5      e[        U[        5      (       a  UR                  5       nU R                  R                  [        R                  5      nU[        :X  a  [        S[        R                  5      eSnU[!        U5      :  a5  XS n U R                  R#                  XR5      nXF-  nU[!        U5      :  a  M5  U$ ! [$         aO  nUR&                  [        R(                  :X  a+  [+        / U// S5      u  pnU	(       d  [        S5      Ue SnAM  e SnAff = f)zUSend a data frame.

Args:
    payload: data to send.
    flags: flags for the frame.
Fr  r  r   Nr  zSocket write timeout)r    r   r   r   r}   r   rw   encoder   r  r   r  r   rm   r   r  r   ws_sendr"   rt   r  r   )
rr   payloadr   r   offsetcurrent_buffern_sentr   r   	writeables
             rJ   sendWebSocket.send  s&    :### %D;;!"?@@ gs##nn&G))##H$9$9:o% ')J)J  s7|#$W-N**>A F s7|#   66Y__,&,R'B&DOA!$,-CD!Ks   C6 6
E AE
	E

Ec                B    U R                  U[        R                  5      $ )z>Send a binary frame.

Args:
    payload: binary data to send.
r2  r    BINARYrr   r-  s     rJ   send_binaryWebSocket.send_binary       yy*"3"344rI   c                B    U R                  U[        R                  5      $ )z\Send a binary frame, alias of :meth:`send_binary`.

Args:
    payload: binary data to send.
r5  r7  s     rJ   
send_bytesWebSocket.send_bytes  r:  rI   c                B    U R                  U[        R                  5      $ )z:Send a text frame.

Args:
    payload: text data to send.
r2  r    r$  r7  s     rJ   send_strWebSocket.send_str#       yy*//22rI   r   c               0    U R                  U" U5      5      $ )zeSend a JSON frame.

Args:
    payload: data to send.
    dumps: JSON encoder, default is json.dumps.
r@  rr   r-  r   s      rJ   	send_jsonWebSocket.send_json+  s     }}U7^,,rI   c                B    U R                  U[        R                  5      $ )z5Send a ping frame.

Args:
    payload: data to send.
)r2  r    PINGr7  s     rJ   pingWebSocket.ping6  rB  rI   c                <   U(       a  U R                   " U40 UD6nU R                  R                  [        R                  5      nU[
        :X  a  [        S[        R                  5      eU R                  S5        / nSU l
        U R                  (       Gaz   U R                  5       u  pgUR                  nU R                  SXg5        UR                  U5        UR                  S:X  a  U[        R                   -  S:X  d  M}  SU R"                  ;   a  SR%                  U5      n	U[        R&                  -  (       a#  U R(                  (       d   U	R+                  5       n
OU	n
U[        R6                  -  (       d  U[        R&                  -  (       a  U R                  SU
5        / nU[        R8                  -  (       a@  S
U l
        U R                  SU R2                  =(       d    SU R:                  =(       d    S5        U R                  (       a  GMy  g	g	! [,         aT  n[.        R0                  U l        U R5                  [.        R0                  5        [        S[.        R0                  5      UeS	nAff = f! [<         a  nUR>                  [        R@                  :X  a  [C        U// / S5      u      n S	nANU R                  SU5        U RD                  (       dB  [.        RF                  n[I        U[        5      (       a  UR>                  nU R5                  U5        e S	nAff = f)zRun the WebSocket forever. See :meth:`connect` for details on parameters.

libcurl automatically handles pings and pongs.
ref: https://curl.se/libcurl/c/libcurl-ws.html
r  r   Tr   r   rs   rI   zInvalid UTF-8NFr   r   r  r   )%r  r   r  r   r  r   rm   r   r  r   r   r  r   r  r  r    r  r   r  r$  r   r   r   rW   r`   r   r   r6  r   r   r"   rt   r  r   r   r^   r   )rr   r   kwargsr   r   r  r  r   r   r   emit_msgr   rt   s                rJ   run_foreverWebSocket.run_forever>  s^    S+F+A))##H$9$9:o% ')J)J  	

6 ! .#113

650e$1,1HA1M .((6*C
/9R9R%47JJLH $'
 1 11uz7N

9h7:+++(-D%JJw(8(8(=At?Q?Q?WUWXG $  2 %/:/G/GD, JJ{'?'?@"0 /1I1I##$%%&  
66Y__,$gYB<GAq!JJw*;;$/$7$7%a88#$66D

4(
sM   A(I0 ?A
I0 
H BI0 
I-AI((I--I0 0
L:1L0A&LLrI   c                    U R                  X5      nU R                  U[        R                  5      nU R	                  5         g)zNClose the connection.

Args:
    code: close code.
    message: close reason.
N)r   r2  r    r   r   )rr   rt   rs   r   r   s        rJ   r   WebSocket.close  s4     $$T3IIc:++,rI   )r   r   r   r   r   )r   r   r   r>   r   r>   r   r>   r   zON_OPEN_T | Noner   zON_CLOSE_T | Noner   zON_DATA_T | Noner   zON_MESSAGE_T | Noner   zON_ERROR_T | Nonerx   ry   )rx   r6   rx   r   )r   EventTypeLiteralr   z+str | bytes | int | CurlWsFrame | CurlErrorrx   ry   )6r   rw   r  z\dict[str, object] | list[object] | tuple[str, int | list[str] | dict[str, str | int]] | Noner  zHeaderTypes | Noner	  zCookieTypes | Noner   tuple[str, str] | Noner   z+float | tuple[float, float] | object | Noner   zbool | CurlFollow | strr   rC   r
  zProxySpec | Noner   r   r   rU  r  zbool | Noner   r   r   r   r   zBrowserTypeLiteral | Noner   r   r   r   r   r   r   z&ExtraFingerprints | ExtraFpDict | Noner   r>   r   zstr | Literal[False]r   zCurlHttpVersion | Noner   r   r  zstr | tuple[str, str] | Noner  rC   r  zdict[CurlOpt, str] | Nonerx   r+   )rx   ztuple[bytes, CurlWsFrame])rx   tuple[bytes, int])rx   rw   )r   zCallable[[str], T]rx   r5   )r-  str | bytesr   r    rx   rC   )r-  r   rx   rC   )r-  r   )r-  rw   rx   rC   )r-  objectr   Callable[..., str]rx   rC   )r-  rW  rx   rC   )r   )r   rw   rx   ry   )rt   rC   rs   r   ) rO   rP   rQ   rR   rS   r   r(   rq   r   r   r   r  r  r   r%  
json_loadsr(  r    r6  r2  r8  r<  r@  r:   rF  rJ  rO  rW   rZ   r   rU   rz   r{   s   @rJ   r6   r6      s   3I #*(/ %*$(&*$(*.&*(/(/ 	(/
 #(/ (/ "(/ $(/ "(/ ((/ $(/ 
(/ (/T
$ ; 
	@ &*&*'+?F37$( -1""&915!;? $&(/3 $-126App	p $p $p %p =p 1p p "p  !p" +#p$ %p& 'p( $)p* /+p, -p. /p0 1p2 93p4 5p6 $7p8 -9p: ;p< +=p> ?p@ 0ApB 
Cpd,'@$ 8B  '---- - 
	-^553 ?L	-	-);	-		-3EN !,  rI   c                  `  ^  \ rS rSr% SrSrSrS\S'   SSS	S
S	SSSSSSSS.                             S1U 4S jjjr\	S2S j5       r
\	S3S j5       rS4S jrS5S jr        S6S jrS5S jrS7S jrS8S jrS9S jrSS.S:S jjrSS.S;S jjr\SS.     S<S jjr\R0                  S4       S=S jjrS>S  jrS>S! jrS?S" jr\S#.     S@S$ jjrSAS% jr\ RB                  S&S'4       SBS( jjr"S9U 4S) jjr#S9S* jr$S9S+ jr%SCS, jr&SDSES- jjr'S9U 4S. jjr(SFS/ jr)S0r*U =r+$ )GAsyncWebSocketi  z4
An asyncio WebSocket implementation using libcurl.
)session_loop_sock_fd_close_lock_terminate_lock
_read_task_write_task_receive_queue_send_queue_max_send_batch_size_coalesce_frames_recv_time_slice_send_time_slice_terminated_terminated_eventws_retry_transport_exception_max_message_sizedrain_on_error_block_on_recv_queue_fulli   zClassVar[int]_MAX_CURL_FRAME_SIZETF       Ng{Gzt?gMbP?i  @ )r   r   recv_queue_sizesend_queue_sizemax_send_batch_sizecoalesce_framesrl  recv_time_slicesend_time_slicemax_message_sizero  block_on_recv_queue_fullc                 > [         TU ]  X#US9  Xl        SU l        SU l        SU l        [        R                  " 5       U l        [        R                  " 5       U l
        [        R                  " 5       U l        SU l        SU l        [        R                  " US9U l        [        R                  " US9U l        Xpl        Xl        U	=(       d
    [)        5       U l        Xl        Xl        SU l        Xl        Xl        Xl        g)a  Initializes an Async WebSocket session.

Do not instantiate this class directly. Use ``AsyncSession.ws_connect``.

This class implements an async context manager, closing the connection
automatically on exit:

::

    async with AsyncSession() as session:
        async with session.ws_connect("wss://api.example.com") as ws:
            await ws.send("Hello")
            msg = await ws.recv()

Note:
    Architecture: This uses a decoupled I/O model. Network operations run in
    background tasks. Errors are raised in subsequent calls to send() or recv().

    Performance: The time_slice defaults (5ms read / 1ms write) favor reading
    to compensate for libcurl's overhead. Increase these values to allocate more
    CPU time to I/O operations at the cost of event loop latency.

Args:
    session (AsyncSession): The parent session object.
    curl (Curl): The underlying Curl handle.
    autoclose (bool): Automatically close on receiving a close frame.
    debug (bool): Enable verbose debug logging.
    recv_queue_size (int): Max number of incoming messages to buffer.
    send_queue_size (int): Max number of outgoing messages to buffer.
    max_send_batch_size (int): Max frames to coalesce per transmission.
    coalesce_frames (bool): Combine small frame payloads to improve throughput.
    ws_retry (WebSocketRetryStrategy): Retry configuration for failed receives.
    recv_time_slice (float): Max seconds to read messages before yielding.
    send_time_slice (float): Max seconds to write messages before yielding.
    max_message_size (int): Max size (bytes) of a single received message.
    drain_on_error (bool): Yield buffered messages before raising errors.
    block_on_recv_queue_full (bool): Behavior when the receive queue is full.
        If True (default), the reader blocks (may cause timeouts).
        If False, the connection fails immediately to prevent data loss.

See also:
    - https://curl.se/libcurl/c/curl_ws_recv.html
    - https://curl.se/libcurl/c/curl_ws_send.html
r   NF)maxsize)rp   rq   r]  r^  r_  rj  asyncioLockr`  	threadingra  Eventrk  rb  rc  Queuerd  re  rf  rg  r<   rl  rh  ri  rm  rn  ro  rp  )rr   r]  r   r   r   rt  ru  rv  rw  rl  rx  ry  rz  ro  r{  ru   s                  rJ   rq   AsyncWebSocket.__init__  s    | 	duE/67;
!&)0/8~~/?07596:>Emm#?
 <C==#<
 *=!&5080T<R<T'6'66:!&6$2/G&rI   c                z    U R                   c#  [        [        R                  " 5       5      U l         U R                   $ )z)Get a reference to the running event loop)r^  r   r  get_running_loopr   s    rJ   loopAsyncWebSocket.loop  s-     ::%g&>&>&@ADJzzrI   c                6    U R                   R                  5       $ )z6Returns the current number of items in the send queue.)re  qsizer   s    rJ   ru  AsyncWebSocket.send_queue_size  s     %%''rI   c                   U R                   (       d  U R                  (       a  gU R                  (       a   U R                  R                  5       (       a  gU R                  =(       a    U R                  R                  5       (       + $ )ab  
Checks if the background I/O tasks are still running.

Returns ``False`` if either the read or write task has terminated due
to an error or a clean shutdown.

Note: This is a snapshot in time. A return value of ``True`` does not
guarantee the next network operation will succeed, but ``False``
definitively indicates the connection is no longer active.
F)r   rj  rb  donerc  r   s    rJ   is_aliveAsyncWebSocket.is_alive  sU     ;;$**??t3355$$@)9)9)>)>)@AArI   c                   #    U $ 7f)a  Enable context manager usage for automatic session management and closure.
This cannot be used to initiate a WebSocket connection, that must be done
beforehand using the :meth:`AsyncSession.ws_connect()` factory method.

Returns:
    Self: The instantiated AsyncWebSocket object.
rH   r   s    rJ   
__aenter__AsyncWebSocket.__aenter__+  s      s   c                @   #    U R                  5       I Sh  vN   g N7f)zA
On exiting the context manager, close the WebSocket connection.
N)r   )rr   exc_typeexc_valexc_tbs       rJ   	__aexit__AsyncWebSocket.__aexit__5  s      jjls   c                >    U R                   (       a  [        S5      eU $ )NzWebSocket has been closedr   r   s    rJ   	__aiter__AsyncWebSocket.__aiter__@  s    ;;!"=>>rI   c                   #     U R                  5       I S h  vN u  pU[        R                  -  (       a  [        eU$  N&! [         a    [        S ef = f7frF   )r   r}   StopAsyncIterationr    r   r   s      rJ   	__anext__AsyncWebSocket.__anext__E  sP     	/#yy{*JC :###$$
 + 	/$$.	/s)   AA  >A   AA   AAc                n    U R                   (       d  U R                  b  gXl        U R                  5         g)a  Finalize the connection into a terminal state.

This method is called for all terminal conditions, including:
- normal WebSocket closure
- protocol errors
- transport errors

After this method is called, no further messages will be delivered
and all ``recv()`` calls will fail. ``_finalize_connection()`` is intended
for event-loop context, but ``terminate()`` is thread-safe.

Args:
    exc (Exception): The exception object that gets raised. This does not
    have to be an error, enqueuing ``WebSocketClosed`` indicates closure.
N)r   rm  r   )rr   excs     rJ   _finalize_connection#AsyncWebSocket._finalize_connectionO  s)    " ;;$33?$'!rI   c                   U R                   b  gU R                  (       a  [        S5      e[        [        U R
                  R                  [        R                  5      5      U l	        U R                  [        :X  a  [        S[        R                  S9eS[        U 5      S 3nU R                  R!                  U R#                  5       U S3S9U l         U R                  R!                  U R%                  5       U S	3S9U l        g)
zStart the read/write I/O loop tasks.

NOTE: This should be called only once after object creation by the factory.
Once started, the tasks cannot be restarted again, this is a one-shot.

Raises:
    WebSocketError: The WebSocket FD was invalid.
NzWebSocket already terminatedzInvalid active socket.)rt   z
WebSocket-z#xz-read)namez-write)rb  rj  r}   r   rC   r   r  r   r  r_  r   rm   r   r  idr  create_task
_read_loop_write_looprc  )rr   ws_ids     rJ   _start_io_tasksAsyncWebSocket._start_io_tasksf  s     ??& !"@AA S$))"3"3H4I4I"JK==O+ (y/P/P 
 ""T(2/ ))//0A5'QV/X9900wf%5 1 
rI   r   c                 #    U R                   b  U R                  (       d  U R                   e U R                  R                  5       $ ! [        R
                   a     Of = fU R                   b  U R                   eU R                  b  U R                  R                  5       (       a  [        S5      e[        R                  " U R                  R                  5       5      n [        R                  " X R                  4[        R                  US9I Sh  vN  u  p4O}! [        R                   af    UR                  5       (       dO  UR                  5       n[        [        R                  5         UI Sh  vN    SSS5        e ! , (       d  f       e = fe f = fU(       d  UR                  5       n[        [        R                  5         UI Sh  vN    SSS5        O! , (       d  f       O= fU R                   b  U R                   e[!        S["        R$                  5      eX#;   a  UI Sh  vN  $ UR                  5       n[        [        R                  5         UI Sh  vN    SSS5        O! , (       d  f       O= fU R                  (       aN  [        [        R
                  5         U R                  R                  5       sSSS5        $ ! , (       d  f       O= fU R                   b  U R                   e[        S5      e7f)a  Receive a WebSocket message.

This method waits for and returns the next complete WebSocket message.

Args:
    timeout: How many seconds to wait for a message before raising
    a timeout error.

Returns:
    tuple[bytes, int]: A tuple with the received payload and flags.

Raises:
    WebSocketTimeout: If the timeout expires.
    WebSocketClosed: If the connection is closed.
    WebSocketError: If a network-level transport error occurs.

Notes:
    ``WebSocketError`` exceptions may have originated from a prior
    ``send()`` or ``recv()`` operation, since all operations
    share the same transport state once a failure occurs.

    This method does not wait for additional messages after a transport
    error is detected. If ``drain_on_error=True``, subsequent calls to
    ``recv()`` will return any messages that were buffered in the receive
    queue at the time the reader failed, before the connection error is raised.

    Concurrent calls to ``recv()`` are supported and safe; each caller
    awaits the next available message and will receive distinct messages
    in FIFO order.

    If this coroutine is cancelled while a message is being received,
    that message may be dropped. Cancellation is treated as abandoning
    the receive operation.
Nr   return_whenr   zWebSocket recv() timed outzConnection closed)rm  ro  rd  
get_nowaitr  
QueueEmptyrb  r  r}   r  r   waitFIRST_COMPLETEDCancelledErrorcancelr   r   r   OPERATION_TIMEDOUT)rr   r   queue_waiterr  r   s        rJ   r   AsyncWebSocket.recv  sd    H $$09L9L+++	&&1133!! 		 $$0+++??"doo&:&:&<&<!"788 7>6I6I##%7
	#LL/#33  GD! %% 	$$&& '')g445&&& 6 65E	 ##%A'001""" 211 ((4///",i.J.J 
 %%%% !g,,- .-- ',,-**557 .-- $$0+++122s   +LA LALABL!2D DD LAF.F4E75F:	F
F		F3L	GGG	L
G,(AL,H/-.LI0!I$"I0'	L0
I>:1L+K
L
K+Lc               "  #    U R                  US9I Sh  vN u  p#U[        R                  -  (       d  [        S[        R
                  5      e UR                  S5      $  NJ! [         a   n[        S[        R
                  5      UeSnAff = f7f)zUReceive a text frame.

Args:
    timeout: how many seconds to wait before giving up.
r  NzNot a valid text framer#  zInvalid UTF-8 in text frame)r   r    r$  rm   rW   r`   r   r   )rr   r   r   r   r   s        rJ   r%  AsyncWebSocket.recv_str  s      !IIgI66
' !9;;S;STT	;;w''	 7
 " 	 -{/G/G	s3   BA 8BA" B"
B,BBB)r   r   c               D  #    U R                  US9I Sh  vN u  p4U(       d  [        S[        R                  5      e U" U5      $  N0! [         a   n[        S[        R                  5      UeSnAf[
         a#  n[        SU 3[        R                  5      UeSnAff = f7f)zReceive a JSON frame.

Args:
    loads: JSON decoder, default is :meth:`json.loads`.
    timeout: how many seconds to wait before giving up.

Raises:
    WebSocketError: Received frame is invalid or failed to decode JSON.
r  Nz(Received empty frame, cannot decode JSONz Invalid UTF-8 in JSON text framezInvalid JSON payload: )r   rm   rW   r`   r   r   )rr   r   r   r   r   r   s         rJ   r(  AsyncWebSocket.recv_json  s      		'	22 :K<T<T 		; 3 " 	 2K4L4L  	 (,k.F.F	s>   B A'B A B 
BA--B:BBB c                  #    U R                   b  U R                   eU R                  (       a  [        S5      eU R                  b*  U R                  R	                  5       (       a  [        S5      e[        U[        5      (       a  UR                  S5      nO'[        U[        [        -  5      (       a  [        U5      n U R                  R                  X45        g! [        R                   a  nU R                  (       a  [        S5      UeU R                   b  U R                   UeUbd   [        R                   " U R                  R#                  X45      U5      I Sh  vN    OM! [        R$                   a  n['        S5      UeSnAff = fU R                  R#                  X45      I Sh  vN    U R                   b  U R                   Ue SnAgSnAff = f7f)a  Send a data frame.

Large payloads are automatically split into fragments but arrive as a
single logical message.

Args:
    payload: Data to send (``str``/``bytes``/``bytearray``/``memoryview``).
    flags: Frame type flags (e.g., ``CurlWsFlag.TEXT``).
    timeout: Max seconds to wait if the send queue is full.

Warning:
    This method is non-blocking. It queues the message for background
    transmission. Use ``await ws.flush()`` to ensure data is sent to
    the socket.
Nr   z(WebSocket writer terminated; cannot sendr#  z"WebSocket connection is terminatedz>Send queue full (network slow) - hit timeout enqueuing message)rm  r   r}   rc  r  r   rw   r+  	bytearray
memoryviewr   re  
put_nowaitr  	QueueFullrj  wait_forputTimeoutErrorr   )rr   r-  r   r   r  r   s         rJ   r2  AsyncWebSocket.send#  s    * $$0+++;;!"788 'D,<,<,A,A,C,C!"LMM gs##nnW-GZ!788GnG	9''(89   	9%&JKQTT ((4//S8"!**((,,g-=>   ++ *X
 &&**G+;<<< ((4//S8 5+	9sl   B;G>C GG/:G*4E%E!E%$G%F
9FF

"G,F/-GGGGc                ^   #    U R                  U[        R                  5      I Sh  vN $  N7f)zsSend a binary frame.

Args:
    payload: binary data to send.

For more info, see the docstring for :meth:`send()`
Nr5  r7  s     rJ   r8  AsyncWebSocket.send_binaryb  $      YYw
(9(9::::   $-+-c                ^   #    U R                  U[        R                  5      I Sh  vN $  N7f)zSend a binary frame, alias of :meth:`send_binary`.

Args:
    payload: binary data to send.

For more info, see the docstring for :meth:`send()`
Nr5  r7  s     rJ   r<  AsyncWebSocket.send_bytesl  r  r  c                ^   #    U R                  U[        R                  5      I Sh  vN $  N7f)zoSend a text frame.

Args:
    payload: text data to send.

For more info, see the docstring for :meth:`send()`
Nr?  r7  s     rJ   r@  AsyncWebSocket.send_strv  s"      YYw
8888r  r   c               L   #    U R                  U" U5      5      I Sh  vN $  N7f)zSend a JSON frame.

Args:
    payload: data to send.
    dumps: JSON encoder, default is :meth:`json.dumps()`.

For more info, see the docstring for :meth:`send()`
NrD  rE  s      rJ   rF  AsyncWebSocket.send_json  s       ]]5>2222s   $"$c                @  #    [        U[        5      (       a  UR                  S5      nO[        U5      n[	        U5      [        SS5      ;  a&  [        S[	        U5       3[        R                  5      eU R                  U[        R                  5      I Sh  vN $  N7f)zSend a ping frame.

Args:
    payload: data to send.

Raises:
    WebSocketError: The payload length is outside specification.

For more info, see the docstring for :meth:`send()`
r#  r   ~   zPing frame has invalid length: N)r   rw   r+  r   r   rangerm   r   	TOO_LARGEr2  r    rI  )rr   r-  payload_bytess      rJ   rJ  AsyncWebSocket.ping  s      gs###NN73M!'NM}U1c]2 1#m2D1EF## 
 YY}joo>>>>s   BBBBrI   g      @c           	       #    U R                    ISh  vN   U R                  (       a   SSS5      ISh  vN   gSU l         U R                  (       a  U R                  R                  5       (       d}  U R                  cp  U R                  X5      n[        R                  " U R                  R                  U[        R                  45      US9I Sh  vN   U R                  U5      I Sh  vN   U R                  5         [!        [        R                  5         [        R                  " U R"                  R%                  5       U5      I Sh  vN nSSS5        SSS5      ISh  vN   g GNW GN8 N N! [        R                  [        4 a     Nf = f NG! , (       d  f       NK= f! U R                  5         [!        [        R                  5         [        R                  " U R"                  R%                  5       U5      I Sh  vN  nSSS5        f ! , (       d  f       f = f= f N! , ISh  vN  (       d  f       g= f7f)a  
Performs a graceful WebSocket closing handshake and terminates the connection.

This method sends a WebSocket close frame to the peer, waits for queued
outgoing messages to be sent, and then shuts down the connection.

Args:
    code (int): Close code. Defaults to ``WsCloseCode.OK``.
    message (bytes): Close reason. Defaults to ``b""``.
    timeout (float): How long (in seconds) to wait for the connection to close
        gracefully before force-terminating.
NTr  )r`  r   rc  r  rm  r   r  r  re  r  r    r   flushr  rm   r   r   rk  r  )rr   rt   rs   r   close_framer   s         rJ   r   AsyncWebSocket.close  s     ###{{ $## DKW$$ ,,1133119 *.)?)?)NK!**((,,k:;K;K-LM '   **W---  g223%..t/E/E/J/J/LgVVA 45 $## .((.9  W 43  g223%..t/E/E/J/J/LgVVVA 4335 $###s  IE*IH)IE-IH)BE4E0E4+E2,E40)H)3FFFH)I$H'%I-I0E42E44FF'FF'F
F$	 H)'*H$3H	HH	
	H$
H!H$$H)'I)I /H20I <Ic                  > U R                      U R                  (       a
   SSS5        gSU l        U R                  n [        R                  " 5       n Uc  [        S5      eUb$  X!L a   UR                  U R                  5       5      nO&[        R                  " U R                  5       U5      n SSS5        g! [
         a    Sn Nsf = f! [         a     [        TU ]-  5         U R                  (       a6  U R                  R                  (       d  U R                  R                  S5        U R                  R!                  5          N! U R                  R!                  5         f = ff = f! , (       d  f       g= f)a  
Immediately terminates the connection without a graceful handshake.

This method is a forceful shutdown that cancels all background I/O tasks
and cleans up resources. It should be used for final cleanup or after an
unrecoverable error. Unlike ``close()``, it does not attempt to send a close
frame or wait for pending messages. It schedules the cleanup to run on the
event loop and returns immediately. It does not wait for cleanup completion.

This method is thread-safe, task-safe, and idempotent.
NTzEvent loop not available)ra  rj  r^  r  r  RuntimeErrorr  _terminate_helperrun_coroutine_threadsafer   rp   r   r]  _closed	push_curlrk  set)rr   r  current_loopr   ru   s       rJ   r   AsyncWebSocket.terminate  s4    !! "!  $D59ZZD$,,. 1<&'ABB  +0D(()?)?)ABA889O9O9QSWXA/ "!   $#$  11G%'||DLL,@,@..t4**..0D**..015 "!sp   E)E)B84C
E)	%C
.E)8CE)CE)

E&AE*E&E)E""E&&E))
E7c           	       ^-#    U R                   R                  nU R                  R                  nU R                  R                  nU R
                  nUR                  nUR                  nUR                  nUR                  nU R                  n	U" 5       U	-   n
U R                  R                  nU R                  R                  nU R                  R                  n[        U R                  R                   5      n["        R$                  n["        R&                  n["        R(                  n[*        R,                  n[*        R.                  n[*        R0                  nUU-  nU R2                  nU R4                  nSnSn[6        nSn/ nSnUR8                  nUR:                  n U R<                  (       Gdd   U" 5       u  n n!U!Rd                  n*US:  a  SnU*U-  (       d  U[g        U 5      -  nUU:  a8  U" 5         U RS                  [Y        SU SU S3["        Rh                  5      5        gU" U 5        U*U-  (       dJ  U!Rj                  (       d9  [g        U5      S:X  a  US   OSRm                  U5      n+U" 5         Sn U" U+U*45        U" 5       =n,U
:  a#  [^        R`                  " S5      I Sh  vN   U,U	-   n
GM  U*U-  (       a,  U" 5          U" U U*45        U Rs                  U 5      I Sh  vN   gU*U-  (       a   U" U U*45        U R<                  (       d  GMc  gg! [>         Ga_  n"Sn#U"R@                  U:X  a  Sn#OU"R@                  U:X  a6  [C        U"5      RE                  5       m-[G        U-4S jU 5       5      (       a  Sn#ONU"R@                  U:X  a>  [I        S[J        RL                  5      n$U"U$l'        SU$l(        U RS                  U$5         Sn"A"gU#(       Ga!  U" 5       n% U" U RT                  UU%5        U%I Sh  vN    O! [V         av  n&U RS                  [Y        S	U& 3["        RZ                  5      5         Sn&A&U RT                  S
:w  a,   U" U RT                  5      n' Sn"A"g! [V         a      Sn"A"gf = f Sn"A"gSn&A&ff = f U RT                  S
:w  a$   U" U RT                  5      n'OJ! [V         a     O>f = fO9! U RT                  S
:w  a$   U" U RT                  5      n'f ! [V         a     f f = ff = f Sn"A"GMT  U(       ak  U"R@                  U;   a[  UU:  aU  US-  nUSUS-
  -  -  n(U(S-  n)U([]        U)* U)5      -  n([^        R`                  " [c        SU(5      5      I Sh  vN     Sn"A"GM  U RS                  U"5         Sn"A"gSn"A"ff = f! [^        Rn                   aI    U(       d+  U RS                  [Y        U["        Rp                  5      5         gU" U+U*45      I Sh  vN     GN]f = f GN;! [^        Rn                   aI    U(       d+  U RS                  [Y        U["        Rp                  5      5         gU" U U*45      I Sh  vN     GNqf = f GNa! [^        Rn                   aI    U(       d+  U RS                  [Y        U["        Rp                  5      5         gU" U U*45      I Sh  vN     GNf = f! [^        Rt                   a     g[V         a  n"U RS                  U"5         Sn"A"gSn"A"ff = f7f)a)  
The main asynchronous task for reading incoming WebSocket frames.

Attempts to read immediately and only registers an event loop reader if
the socket returns EAGAIN (empty). It waits for the underlying socket to
become readable, and upon being woken by the event loop, it drains all
buffered data from libcurl until it receives an EAGAIN error. This error
signals that the buffer is empty, and the loop returns to an idle state,
waiting for the next readability event. This is "optimistic reading".

To ensure cooperative multitasking during high-volume message streams,
the loop yields control to the asyncio event loop periodically which
is tracked using an operation counter.

If the receive queue becomes full, ``await self._receive_queue.put()`` will
block the reader loop and stall the socket read task. Thus, appropriate queue
sizes should be set by the user, to match the speed at which they are expected
to be consumed. If latency is a factor, a smaller queue size should be used.
Conversely, a larger queue size provides burst message handling capacity.
)zerrno 11z resource temporarily unavailablezDReceive queue full; failing connection to preserve message integrityr   FTc              3  ,   >#    U  H	  oT;   v   M     g 7frF   rH   ).0r   err_msgs     rJ   	<genexpr>,AsyncWebSocket._read_loop.<locals>.<genexpr>S  s     G#g~s   z.Connection closed unexpectedly by server (EOF)NzSocket closed unexpectedly: r}  r$   r   g?g        zMessage too large: z bytes (limit zF bytes). Consider increasing max_message_size or chunking the message.rI   );r   r  rd  r  r  r  timecreate_future
add_readerremove_readerrh  rl  r?   rN   rD   r@   rA   r   r  rG   GOT_NOTHINGr    r   r  rI  rn  rp  r   r  clearr   r"   rt   rw   loweranyr}   rW   r_   	__cause____suppress_context__r  r_  r   rm   r  r   r  sleepmaxr   r   r  r  r  r  OUT_OF_MEMORY_handle_close_framer  ).rr   curl_ws_recvqueue_put_nowait	queue_putr  	loop_timer  r  r  
time_slice
next_yieldretry_on_errorretry_codesmax_retries
retry_basee_again
e_recv_err	e_nothing
close_flag	cont_flag	ping_flagcontrol_maskmax_msg_sizeblock_on_recverrno_11_msgsqueue_full_errset_fut_resultrecv_error_retriesr  msg_sizechunks_appendchunks_clearr  r   r   should_retry	final_excread_futurer  r   retry_delayjitterr   rs   nowr  s.                                                @rJ   r  AsyncWebSocket._read_loop  sp    . AE		@Q@Q** 	 ## 	 +/)))-	<@<N<N*.//
-1-?-? 11
%K*4
#}}22&*mm&9&9==..!$--"5"56
&__ ) 4 4
(44	%%
OO	OO	%
2 22"<<*

 S 	 BR #$ 17+1<<f	)kkkI#/>LE5T #[[%))*& ,E
*H,.$11*&9( D..:^ <<%<
 !* 3 3
  "%( "I-),V)9F1Isxx?O   %#$
>,gu-=>  ){*z9%mmA...%(:%5
 :% N	8(%8 225999 9$	8(%8m kkk ! F).L vv('+ :-'*1v||~GGGG+/L 9,5DL'886	 /0	+9=	611)<#<IO)&t}}nkR"---  ) # 55 .&B3%$H$-$E$E!" #  $}}2!)(5dmm(DA'0 !)$(!)	  3# .  $}}2!)(5dmm(DA'0 !)$(!)	  3t}}2!)(5dmm(DA'0 !)$(!)	  3 ! 'FFk1.<*a/* '!0BQ0F*GH $ )4c(9#ww'??%mmC[,ABBB  --a0MFX  '00 >#0 $ 9 9$2(6	8O8O%&!"
 !'"+We,<"===> / #,, 8, 55 .~y?V?V W #'7778 : #,, 8, 55 .~y?V?V W #'7778 %% 	  	)%%a((	)sw  F[&Z) 2
L <A)Z) %[&&AZ) 8
V &Z) (W#)Z) 
W& Z) %Y&Z) *[&+
Z) 6
Y	  Z) [&V !B$U;Z) 	[&
U;O:3O64O:9R3:
Q:,Q50R34U;QZ) [&
Q-&U;'Z) +[&,Q--U;0Z) 4[&5Q::R3>U;R"!U;"
R/,U;.R//U;3S)SS)
S%	"S)$S%	%S))U;,Z) 3A%U;UU;Z) %U;6Z) :[&;V  Z) AW Z) [&	W WW Z) W  Z) &AY*Z) +[&,Y9X<:Y?Z) YZ) 	AZ&Z) [&Z&ZZ&"Z) %Z&&Z) )[#=[&?	[#[[&[##[&c                
  #    [         R                  [         R                  -  nU R                  nU R                  R
                  nU R                  R                  nU R                  R                  nU R                  nUR                  nU R                  nU" 5       U-   n	 U R                  (       d   U" 5       I Sh  vN u  p U" X5      I Sh  vN (       d+   U" 5         U R                  (       d  U R                  5         ggU[         R                  -  (       a
   U" 5         GO(U" 5       =o:  a"  [        R                  " S5      I Sh  vN   X-   n	U" 5         M   U" 5       I Sh  vN u  pX4/nU[         R                  -  (       dj  [!        U5      U R"                  :  aQ   U" 5       u  pUR%                  X45        U[         R                  -  (       a  O [!        U5      U R"                  :  a  MQ   0 nU GH  u  pX-  (       GaU  UR)                  5        H  u  nnU" SR+                  U5      U5      I Sh  vN (       dG      [-        [!        U5      5       H
  nU" 5         M     U R                  (       d  U R                  5         ggU" 5       =o:  d  M  [        R                  " S5      I Sh  vN   X-   n	M     UR/                  5         U" X5      I Sh  vN (       dF    [-        [!        U5      5       H
  nU" 5         M     U R                  (       d  U R                  5         ggU" 5       =o:  a%  [        R                  " S5      I Sh  vN   X-   n	GMb  GMe  UR1                  U/ 5      R%                  U
5        GM     UR)                  5        Hq  u  nnU" SR+                  U5      U5      I Sh  vN (       a  M-    [-        [!        U5      5       H
  nU" 5         M     U R                  (       d  U R                  5         gg   [-        [!        U5      5       H
  nU" 5         M     US   S   [         R                  -  (       a  OGM  U R                  (       d  U R                  5         gg GN GN GN,! U" 5         f = f GN! [        R&                   a     GM  f = f GNj GN GN GN^ N! [-        [!        U5      5       H
  nU" 5         M     f = f! [        R2                   a     N[4         a  nU R7                  U5         SnANSnAff = f! U R                  (       d  U R                  5         f f = f7f)a  
The background task responsible for consuming the send queue
and transmitting frames.

To maximize performance, this loop hoists the configuration
check and enters one of two distinct processing strategies:

1. Standard Mode (No Coalescing):
    The default, low-latency path. Messages are consumed one-by-one
    from the queue and transmitted immediately. This guarantees that one
    ``send()`` call results in exactly one WebSocket message, preserving
    logical message boundaries.

2. Coalescing Mode:
    An optimized throughput path for chatty streams. The loop greedily gathers
    multiple pending messages from the queue (up to ``max_send_batch_size``
    and merges their payloads into a single transmission if they share the
    same flags (e.g., multiple text frames). This reduces system call
    overhead but does not preserve individual message boundaries.

Features:
- Cooperative Multitasking: Yields to the event loop periodically to prevent
    the writer from starving the reader task during high-volume transmission.
- Control Frame Priority: PING and CLOSE frames are never coalesced; they
    trigger an immediate flush of any pending batched data before being sent.
- Lifecycle Management: Automatically terminates the connection cleanly upon
    transmitting a CLOSE frame.
Nr   rI   r}  r$   )r    r   rI  _send_payloadre  r   r  	task_doner  r  ri  rg  r   r   r  r  r   rf  r  r  itemsr  r  r  
setdefaultr  r   r  )rr   control_frame_flagssend_payload	queue_getqueue_get_nowait
queue_doner  r  r  r  r-  r   r  batchr   data_to_coalesceframe_grouppayloadsr   r   s                       rJ   r  AsyncWebSocket._write_loop  s    : $.#3#3joo#E7;7I7I>B>N>N>R>R	:>:J:J:U:U)-)9)9)C)C
*.)))-	 11
%K*4
]	!((+4;%6NG%%1'%AAA" #P ;;  c !:#3#33! # $-;.C=")--"222),)9J #! ( +4;%6NG ?F=M<NE!J$4$44!%j4+D+DD&1A1C %g-= >#(:+;+;#;$) $<	 "%j4+D+DD%)JL(.3NG$::=M=S=S=U$9K1=(+(:K2& ,& ,& )/6 "'s5z!2A&L "3  ;;  Q 09{(:'I.5mmA.>(>(>585E
 >V !1 6 6 8-9'-I'I'I$*" "'s5z!2A&L "3  ;;  = ,5;$6C#E*1--*:$:$:141AJ $F
 !1 ; ;E2 F M Mg V3 /48 6F5K5K5M1K)5chhx6H+)V#V#V & "'s5z!2A&L "3  ;;  - 6N "'s5z!2A&L "3 Ry|j&6&66s H ;;  o &7  B 3 #
 &7 $+#5#5 & %&,& )?
 (J
 %; $W
 "'s5z!2A&L "3 %% 	  	)%%a((	)
 ;;  s  BT?!S =Q2>S Q; Q5	Q; S "#T?Q; S %T '%Q; Q8Q; S )R*;S &3R
 S 7AR4 <R&=R4 "S *#T?
R4 R4 4R)5'R4 R,
R4 '"S 	#T?,%R4 R/A%R4 7R28R4 R4 "S &#T?	R4 A S T S #T?2S 5Q; 8Q; ;	RS 
R#S "R##S &R4 )R4 ,R4 /R4 2R4 4$SS T/T 1	T:TT TT $T<<T?c                  #    U R                   R                  nU R                  nUR                  nUR                  nUR
                  nUR                  n[        n	U R                  n
U R                  nU" 5       U-   nU R                  n[        R                  n[        R                  nSnX/) -  n[        U5      n[!        U5      nSnSnUU:  d  US:X  a  US:X  a  UUU[#        UU-
  U5      -    n[!        U5      nUnUU-   U:  a  UU-  n U" UU5      nUS:X  aR  US:X  a  gUS:  aE  US-  nUU:  a.  U R%                  ['        SU S3[        R(                  5      5        g[+        SU5      eU(       a  SnUU-  nU" 5       =nU:  a#  [,        R.                  " S5      I S	h  vN   UU-   nUU:  a  M  US:X  a  US:X  a  M  g N ! [*         Ga  nUR0                  U:X  a  U" 5       n U" XU5        UI S	h  vN    Oo! [2         ab  nU R%                  ['        S
U 3[        R4                  5      5         S	nAU
S:w  a"   U" U
5      n S	nAg! [2         a      S	nAgf = f S	nAgS	nAff = f U
S:w  a   U" U
5      nO6! [2         a     O*f = fO%! U
S:w  a   U" U
5      nf ! [2         a     f f = ff = f S	nAGM  U R%                  U5         S	nAgS	nAff = f7f)z6
Optimized low-level sender with fragmentation logic.
rB   r   Tr$   zWriter stalled (z attempts).Fz0 bytes sentNz)Socket closed unexpectedly during write: r}  )r   r,  r  r  r  
add_writerremove_writerr   r_  ri  rq  r   r  r    r  r  r   minr  rm   WRITE_ERRORr"   r  r  rt   r   r  )rr   r-  r   curl_ws_sendr  r  r  r)  r*  r  r   r  r  max_frame_sizer  r  max_zero_writes
base_flagsviewtotal_bytesr.  write_retriesr  	chunk_lencurrent_flagsr0  r  r   write_futurer  r   s                                  rJ   r  AsyncWebSocket._send_payloadr  s    
 GKiiFWFW*.)))-	<@<N<N*.//
-1-?-?AQ}} 11
%K*4
"77&__ *	   *,
%g.t9 {"v{{a7G $#kF&:N"KK!E !ZI /9M"k1*@*5-@Q; A~# !1}%*(O; 55 .'7k%R$-$9$9!" $)'@@ $%M&  %;&C:5!--***!$z!1JW {"v{{a7G\ I +  66W$9FL%"7LI*** % %11*"KC5 Q ) A A  % #b=%$1'$:#, % $%	 )% + #b=%$1'$:#, % $%	 )7b=%$1'$:#, % $%	 )  ))!,?s9  D
KG "K#>G !K"A G "G#	G ,K4KKG KK(G=6G97G=<J=
I),I$3J7K>IK
IKKIKK$I))J-K4I=<K=
J
K	J

KJ0JJ0
J,	)J0+J,	,J00K3K:KKKKc                N  #    U R                   c  g[        R                  " U R                  R	                  5       5      n [        R
                  " X R                   1[        R                  US9I Sh  vN u  p4U(       d  [        S5      eX#;   aT   UR                  5       (       d=  UR                  5       n[        [        R                  5         UI Sh  vN   SSS5        ggU R                   U;   a   U R                   R                  5         U R                  R                  5       (       aT   UR                  5       (       d=  UR                  5       n[        [        R                  5         UI Sh  vN   SSS5        gg[        S5      e UR                  5       (       d=  UR                  5       n[        [        R                  5         UI Sh  vN   SSS5        gg GNo GN! , (       d  f       g= f! [         a  n[        S5      UeSnAff = f N! , (       d  f       g= f NV! , (       d  f       g= f! UR                  5       (       dO  UR                  5       n[        [        R                  5         UI Sh  vN    SSS5        f ! , (       d  f       f = ff = f7f)aL  Waits until all items in the send queue have been processed.

This ensures that all messages passed to `send()` have been handed off to the
underlying socket for transmission. It does not guarantee that the data has
been received by the remote peer.

Args:
    timeout (float | None, optional): The maximum number of seconds to wait
    for the queue to drain.

Raises:
    WebSocketTimeout:  If the send queue is not fully processed within the
    specified ``timeout`` period.
    WebSocketError: If the writer task has already terminated while unsent
    messages remain in the queue.
Nr  z*Timed out waiting for send queue to flush.z#Writer task crashed while flushing.z0Writer task stopped unexpectedly while flushing.)rc  r  r  re  r  r  r  r   r  r  r   r  resultr   rm   empty)rr   r   	join_taskr  r   r  s         rJ   r  AsyncWebSocket.flush  s)    " # )0(;(;D<L<L<Q<Q<S(T	 	$#LL,,-#33 GD &'STT  " >>##$$&g445#OO 65 $ 4'Y$$++-
 ##))++ >>##$$&g445#OO 65 $	 %%WXX ( >>##$$&g445#OO 65 $9> $ 65 ! Y()NOUXXY $ 65# 65 >>##$$&g445#OO 655 $s  =J% 2H< 2G!3H< >J%G'G$G'
J%$H< 5G8 H< />J%-H3H4H8
J%H< >J%H+H)H+
J%!H< $G''
G51J%8
HHHH< H
H&"J%)H++
H95J%<?J";JJ
J	J"
JJ""J%c                *  >#    U R                   U R                  4 Vs1 s H!  nUc  M  UR                  5       (       a  M  UiM#     nnSn U H  nUR                  5       nM     U(       aG  [        R
                  " UU[        R                  S9I Sh  vN u  pVU H  nUR                  5       nM     U R                  R                  5       (       dV   U R                  R                  5       nU R                  R                  5         U R                  R                  5       (       d  MV  U R                  S:w  az  [        [        5         U R                   R#                  U R                  5      nSSS5        [        [        5         U R                   R%                  U R                  5      nSSS5        SU l        [&        TU ]Q  5         U R*                  (       a6  U R*                  R,                  (       d  U R*                  R/                  S5        U R0                  R3                  5         gs  snf  GN! [        R                  [        4 a     GM'  f = f! , (       d  f       N= f! , (       d  f       N= f! U R0                  R3                  5         f = f7f)z)Utility method for connection terminationNr   )r   r  r}  )rb  rc  r  r  r  r  ALL_COMPLETEDre  r:  r  r  r  
ValueErrorr_  r   r   r  r  r*  rp   r   r]  r  r  rk  r  )	rr   ttasks_to_cancelmax_timeoutio_taskr   pendingpru   s	           rJ   r   AsyncWebSocket._terminate_helper  s     oot'7'784
8 %&VVX 8 	 4

 (	)*NN$ + #*<<#' ' 5 5$ 
 !A
A ! &&,,..((335A$$..0 &&,,.. }}"i(		//>A )i(		//>A ) DM G||DLL$8$8&&t, ""&&(_4
  **J7 
 )((( ""&&(s   JH(H( H(JAI4 H->I4 4H0 I4 'I4 &I,I4 &I#)A$I4  J-I4 0I
I4 II4 
I I4 #
I1-I4 4JJc                x  #     U R                  U5      u  U l        U l        U R
                  (       aL  U R                  (       d;  U R                  U R                  =(       d    [        R                  5      I Sh  vN   gU R                  5         g! [         a  nUR                  U l         SnANSnAff = f N>7f)z<Unpack and handle the closing frame, then initiate shutdown.N)r   r   r   rm   rt   r   r   r   rW   rZ   r   )rr   rs   r   s      rJ   r  "AsyncWebSocket._handle_close_frameJ  s     	&373K3KG3T0Dd0 >>$++**T--?@@@ NN  	& vvD	& As:   B:B AB:9B8:B:
B5B0+B:0B55B:)rp  r   r`  r   rg  r^  rn  rf  rb  rd  rh  re  ri  r_  ra  rj  rk  rm  rc  r   ro  r]  rl  )r]  r3   r   r!   r   r>   r   r>   rt  rC   ru  rC   rv  rC   rw  r>   rl  zWebSocketRetryStrategy | Nonerx  r@   ry  r@   rz  rC   ro  r>   r{  r>   rx   ry   )rx   zasyncio.AbstractEventLoop)rx   rC   )rx   r>   )rx   r+   )r  type[BaseException] | Noner  BaseException | Noner  object | Nonerx   ry   rS  )r  r   rx   ry   r   )r   float | Nonerx   rV  )r   rL  rx   rw   )r   zCallable[[str | bytes], T]r   rL  rx   r5   )r-  z$str | bytes | bytearray | memoryviewr   r    r   rL  rx   ry   )r-  r   rx   ry   )r-  rw   rx   ry   )r-  rX  r   rY  rx   ry   )r-  rW  rx   ry   )rt   rC   rs   r   r   r@   rx   ry   )r-  r   r   zCurlWsFlag | intrx   r>   rF   )r   rL  rx   ry   )rs   r   rx   ry   ),rO   rP   rQ   rR   rS   r   rq  rT   rq   r   r  ru  r  r  r  r  r  r  r  r   r%  rZ  r(  r    r6  r2  r8  r<  r@  r:   rF  rJ  rW   rZ   r   r   r  r  r  r  r  r  rU   rz   r{   s   @rJ   r\  r\    s   I. +0-/ !!#% %26!&!& /$)-!VHVH VH
 VH VH VH VH !VH VH 0VH VH VH VH VH  #'!VH" 
#VH VHp   ( (B&	,	 &	 		
 
	
. 
D 59 i3V 9= & -7 $	 * 	
 
F '-- $	=95=9 =9 	=9
 
=9~;;9 ?L33);3	3?4 &..3QT*W*W38*WIN*W	*WX.1`h)TD!LjX7$r1)f rI   r\  c                  T    \ rS 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)AsyncWebSocketContextiX  z.Helper to enable simpler context manager usage_coro_objc                    Xl         S U l        g rF   rO  )rr   coros     rJ   rq   AsyncWebSocketContext.__init__^  s    04
+/	rI   c                6    U R                   R                  5       $ rF   )rP  	__await__r   s    rJ   rV  AsyncWebSocketContext.__await__b  s    zz##%%rI   c                X   #    U R                   I S h  vN U l        U R                  $  N7frF   rO  r   s    rJ   r   AsyncWebSocketContext.__aenter__e  s"     **$	yy %s   *(*c                x   #    U R                   (       a#  U R                   R                  5       I S h  vN   g g  N7frF   )rQ  r   )rr   r  r  tbs       rJ   r  AsyncWebSocketContext.__aexit__i  s*      99))//### #s   /:8:N)rS  zAwaitable[AsyncWebSocket]rx   ry   )rx   z)Generator[object, object, AsyncWebSocket])rx   r\  )r  rI  r  rJ  r[  rK  rx   ry   )rO   rP   rQ   rR   rS   r   rq   rV  r  r  rU   rH   rI   rJ   rN  rN  X  sD    8!I0&$,$ "$ 	$
 
$rI   rN  )r   zasyncio.Future[None]rx   ry   )crS   
__future__r   r  r   r  r   r   r   collections.abcr   r   r   
contextlibr   dataclassesr	   r
   enumr   	functoolsr   jsonr   
json_dumpsr   rZ  randomr   r   typingr   r   r   r   r   r   aior   r   constr   r   r   r   r    r   r!   r"   utilsr#   
exceptionsr%   r&   modelsr'   r(   r)   r*   typing_extensionsr+   r,   r-   r	  r.   r  r/   r   r0   r1   r2   r]  r3   r4   r5   r   	ON_DATA_Trw   ON_MESSAGE_T
ON_ERROR_T	ON_OPEN_TrC   
ON_CLOSE_TtupleRECV_QUEUE_ITEMSEND_QUEUE_ITEMr:   rT   r<   rW   rm   r}   r   r   r   rT  r6   r\  rN  rH   rI   rJ   <module>ru     s   #     ; : :  (   $ $   I I / H H " # .  8 8&'"$$OO0A+uk:D@AI[%#+6<=L;	2D89J+,-I;S1478JE3J'OE:-.O &jZH| H R R R,' .(Y ('M')G) E EP FG | |~ ]  D& $ $ $rI   