+
    Ȝi                    :   ^ RI Ht ^ RIt^ RIt^ RIt^ RIt^ RIHt ^ RIH	t	 ^ RI
Ht ^ RIHt ^ RIHtHt ^ RIHt ^ R	IHtHtHtHtHtHtHt ^R
IHtHt ^RIHtHtH t H!t! ^RI"H#t#H$t$ ^RI%H&t& ^RI'H(t(H)t) ^RI*H+t+ ^RI%H,t,H-t- ]'       d   ^ RI.H/t/ ^RIH0t0 ^RI"H1t1 ^RI2H3t3 ^RI4H5t5 ^RI6H7t7H8t8H9t9 ^RI:H;t;H<t< ]! R4      t=]R]>]1.R3,          t?]R]]>]@3,          .R3,          tA]R]$.R3,          tB]R.R3,          tC]R]D]@.R3,          tE]F]]>]G3,          ]D3,          tH]F]>]]!]D3,          3,          tI]! ]R(R7      t ! R R]4      tJ ! R R]$4      tK ! R R ]K](4      tL ! R! R"]K])4      tM ! R# R$4      tN]R),          tO ! R% R]N4      tP ! R& R']N4      tQR# )*    )annotationsN)Callable)suppress)IntEnum)partial)dumpsloads)select)TYPE_CHECKINGAnyClassVarLiteralOptionalTypeVarUnion)CURL_SOCKET_BADget_selector)	CurlECodeCurlInfoCurlOpt
CurlWsFlag)Curl	CurlError)CurlCffiWarning)SessionClosedTimeout)Response)not_setset_curl_options)Self)CurlHttpVersion)CurlWsFrame)CookieTypes)HeaderTypes)BrowserTypeLiteralExtraFingerprintsExtraFpDict)AsyncSession	ProxySpecT	WebSocket)
separatorsc                  b    ] tR t^0tRtRtRtRtRtRt	Rt
RtR	tR
tRtRtRtRtRtRtRtRtRtRtR# )WsCloseCodez?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   N)__name__
__module____qualname____firstlineno____doc__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TIMEOUT__static_attributes__r0       f/Users/mibo/.openclaw/workspace/.venv-ak/lib/python3.14/site-packages/curl_cffi/requests/websockets.pyr.   r.   0   sc    I	BJNGLONOOKMLIGrI   r.   c                  6   a  ] tR t^GtRtRR V 3R llltRtV ;t# )WebSocketErrorzWebSocket-specific error.c                    V ^8  d   QhRRRR/# )   messagestrcodez)Union[WsCloseCode, CurlECode, Literal[0]]r0   )formats   "rJ   __annotate__WebSocketError.__annotate__J   s     ( (("K(rI   c                	&   < \         SV `  W4       R # N)super__init__)selfrO   rQ   	__class__s   &&&rJ   rX   WebSocketError.__init__J   s     	'rI   r0   )r   )r1   r2   r3   r4   r5   rX   rH   __classcell__rZ   s   @rJ   rL   rL   G   s    #( ( (rI   rL   c                      ] tR t^PtRtRtR# )WebSocketClosedzWebSocket is already closed.r0   Nr1   r2   r3   r4   r5   rH   r0   rI   rJ   r_   r_   P   s    &rI   r_   c                      ] tR t^TtRtRtR# )WebSocketTimeoutzWebSocket operation timed out.r0   Nr`   r0   rI   rJ   rb   rb   T   s    (rI   rb   c                      ] tR t^XtRtRRRR/R R llt]R 4       t]R R	 l4       t]R
 R l4       t	]
R R l4       t]
R R l4       tR tRtR# )BaseWebSocket	autoclosedebugTFc               $    V ^8  d   QhRRRRRR/# )rN   curlr   re   boolrf   r0   )rR   s   "rJ   rS   BaseWebSocket.__annotate__b   s!      T  T rI   c               	T    Wn         W n        R V n        R V n        W0n        RV n        R # )NF_curlre   _close_code_close_reasonrf   closed)rY   rh   re   rf   s   &&$$rJ   rX   BaseWebSocket.__init__b   s(    
(*.,0
rI   c                	x    V P                   \        J d   \        V P                  R 7      V n         V P                   # ))rf   )rm   r   r   rf   rY   s   &rJ   rh   BaseWebSocket.curlj   s(    :: DJJ/DJzzrI   c                   V ^8  d   QhRR/# )rN   returnzOptional[int]r0   )rR   s   "rJ   rS   rj   q   s        M  rI   c                    V P                   # )z<The WebSocket close code, if the connection has been closed.)rn   rs   s   &rJ   
close_codeBaseWebSocket.close_codep   s     rI   c                   V ^8  d   QhRR/# )rN   rv   Optional[str]r0   )rR   s   "rJ   rS   rj   v   s     " "m "rI   c                    V P                   # )z>The WebSocket close reason, if the connection has been closed.)ro   rs   s   &rJ   close_reasonBaseWebSocket.close_reasonu   s     !!!rI   c               $    V ^8  d   QhRRRRRR/# )rN   rQ   intreasonbytesrv   r0   )rR   s   "rJ   rS   rj   {   s!     0 0 0U 0u 0rI   c                	>    \         P                  ! R V 4      V,           # )!H)structpack)rQ   r   s   &&rJ   _pack_close_frameBaseWebSocket._pack_close_framez   s    {{4&//rI   c                    V ^8  d   QhRRRR/# )rN   framer   rv   ztuple[int, str]r0   )rR   s   "rJ   rS   rj      s      5 _ rI   c                	   \        V 4      ^8  d   \        P                  pRpW3#  \        P                  ! RV 4      ^ ,          pV R,          P                  4       pV\        P                  8X  g   VR8  g   VR8  d   \        RV 2\        P                  4      h W3#   \         d!   p\        R\        P                  4      ThRp?i\         d!   p\        R	\        P                  4      ThRp?ii ; i)
rN    r   :rN   NNr/   i  zInvalid close code: zInvalid close messageNzInvalid close frame)lenr.   r:   r   unpack_fromdecoderL   r8   UnicodeDecodeErrorr<   	Exception)r   rQ   r   es   &   rJ   _unpack_close_frame!BaseWebSocket._unpack_close_frame~   s    u:>&&DF$ |!))$6q9r))+ ;...$+(.tf5{7Q7Q  BN | & $+[-E-E  $);+E+Es)   5B   C4+CC4C4C//C4c                H    RV n         V P                  P                  4        R# )z$Terminate the underlying connection.TN)rp   rh   closers   s   &rJ   	terminateBaseWebSocket.terminate   s    		rI   )rn   ro   rm   re   rp   rf   Nrl   )r1   r2   r3   r4   	__slots__rX   propertyrh   rx   r}   staticmethodr   r   r   rH   r0   rI   rJ   rd   rd   X   s    I E   
     " " 0 0  .rI   rd   c                    a  ] tR t^tRtR5t]3RRRRRRRRR	RR
RRRRR/R V 3R lllltR R ltR R lt	R R lt
RRRR]R^RRRRRRRRRRRRRRR^ R3R R lltR R ltR R ltR R ltR]/R  R! llt]P$                  3R" R# lltR$ R% ltR& R' ltR( R) ltR*]/R+ R, lltR- R. ltR6R/ R0 llt]P8                  R13R2 R3 lltR4tV ;t# )7r+   z)A WebSocket implementation using libcurl.skip_utf8_validationre   TFrf   on_openNon_closeon_data
on_messageon_errorc               <    V ^8  d   QhRRRRRRRRRRR	R
RRRRRR/	# )rN   rh   zUnion[Curl, Any]re   ri   r   rf   r   zOptional[ON_OPEN_T]r   zOptional[ON_CLOSE_T]r   zOptional[ON_DATA_T]r   zOptional[ON_MESSAGE_T]r   zOptional[ON_ERROR_T]r0   )rR   s   "rJ   rS   WebSocket.__annotate__   sd     (/ (/(/ 	(/
 #(/ (/ %(/ '(/ %(/ +(/ '(/rI   c               2  < \         S
V `  WVR7       W0n        RV n        / V n        V'       d   WPP                  R&   V'       d   W`P                  R&   V'       d   WpP                  R&   V'       d   WP                  R&   V	'       d   WP                  R&   R# R# )	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)``
rh   re   rf   Fopenr   datarO   errorN)rW   rX   r   keep_running	_emitters)rY   rh   re   r   rf   r   r   r   r   r   rZ   s   &&$$$$$$$$rJ   rX   WebSocket.__init__   s|    4 	duE$8!!;=%,NN6"&.NN7#%,NN6"(2NN9%&.NN7# rI   c                   V ^8  d   QhRR/# )rN   rv   r+   r0   )rR   s   "rJ   rS   r      s      ) rI   c                	@    V P                   '       d   \        R 4      hV # )WebSocket is closedrp   r_   rs   s   &rJ   __iter__WebSocket.__iter__   s    ;;;!"788rI   c                   V ^8  d   QhRR/# rN   rv   r   r0   )rR   s   "rJ   rS   r      s      % rI   c                	p    V P                  4       w  rV\        P                  ,          '       d   \        hV# rV   )recvr   CLOSEStopIterationrY   msgflagss   &  rJ   __next__WebSocket.__next__   s+    YY[
:####
rI   c                    V ^8  d   QhRRRR/# )rN   
event_typeEventTypeLiteralrv   Noner0   )rR   s   "rJ   rS   r      s       0 D rI   c                	<   V P                   P                  V4      pV'       d    V! V .VO5!   R# R#   \         d^   pT P                   P                  R 4      pT'       d   T! Y4        Rp?R# \        P                  ! RT R2\
        ^R7        Rp?R# Rp?ii ; i)r   zWebSocket callback 'z' failed
stacklevelN)r   getr   warningswarnr   )rY   r   argscallbackr   error_callbacks   &&*   rJ   _emitWebSocket._emit   s    >>%%j1%%   	!%!3!3G!<!"4++MM.zl(C'#$ 	s   
3 B+B/!BBzgzip, deflate, brr   c          2     |    V ^8  d   Qh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RRRRRRRR RR!R"R#R$R%RR&R'R(RR)R*/# )+rN   urlrP   paramsz"Optional[Union[dict, list, tuple]]headerszOptional[HeaderTypes]cookieszOptional[CookieTypes]authzOptional[tuple[str, str]]timeoutz3Optional[Union[float, tuple[float, float], object]]allow_redirectsri   max_redirectsr   proxieszOptional[ProxySpec]proxyr{   
proxy_authverifyzOptional[bool]refereraccept_encodingimpersonatezOptional[BrowserTypeLiteral]ja3akamaiextra_fpz/Optional[Union[ExtraFingerprints, ExtraFpDict]]default_headersquotezUnion[str, Literal[False]]http_versionzOptional[CurlHttpVersion]	interfacecertz%Optional[Union[str, tuple[str, str]]]max_recv_speedcurl_optionszOptional[dict[CurlOpt, str]]r0   )rR   s   "rJ   rS   r      s!    k kk 3k '	k
 'k (k Ek k k %k k .k k k 'k  2!k" #k$ %k& B'k( )k* *+k, 0-k. !/k0 41k2 3k4 35krI   c                F   V P                   p\        R/ RVbRRbRVbRRV.bRRV.bRRV.bR	VbR
VbRVbRVbRRV	.bRV
bRVbRRV.bRVbRVbRVbRVbRVbRVbRVbRVbRVbRVbRVbRVbRVb  VP                  \        P                  ^4       VP                  4        V # )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.
    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.
    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 response content if charset is not
        found in headers. Defaults to "utf-8". Can be set to a callable for
        automatic detection.
    quote: Set characters to be quoted, i.e. percent-encoded. Default safe
        string is ``!#$%&'()*+,/:;=?@[]~``. If set to a sting, the character
        will be removed from the safe string, thus quoted. If set to False, the
        url will be kept as is, without any automatic percent-encoding, you must
        encode the URL yourself.
    curl_options: extra curl options to use.
    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.
rh   methodGETr   params_listNheaders_listcookies_listr   r   r   r   proxies_listr   r   verify_listr   r   r   r   r   r   r   r   r   r   r   r   r   r0   )rh   r   setoptr   CONNECT_ONLYperform)rY   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   rh   s   &&&&&&&&&&&&&&&&&&&&&&&&&& rJ   connectWebSocket.connect   sX   P yy 	
	
	
 	
 v		

 	
 	
 	
 	
 ,	
 (	
 	
 	
 "	
 v	
 	
  ,!	
" $#	
$ %	
& '	
( )	
* ,+	
, -	
. &/	
0  1	
2 *3	
4 5	
6 &7	
> 	G((!,rI   c                   V ^8  d   QhRR/# )rN   rv   ztuple[bytes, CurlWsFrame]r0   )rR   s   "rJ   rS   r   Z  s      8 rI   c                   V P                   '       d   \        R4      hV P                  P                  4       w  rVP                  \
        P                  ,          '       dB    V P                  V4      w  V n        V n	        T P                  '       d   T P                  4        W3#   \         d3   pTP                  T n        T P                  TP                  4       h Rp?ii ; i)z2Receive a single curl websocket fragment as bytes.WebSocket is already closedN)rp   r_   rh   ws_recvr   r   r   r   rn   ro   rL   rQ   r   re   )rY   chunkr   r   s   &   rJ   recv_fragmentWebSocket.recv_fragmentZ  s     ;;;!"?@@yy((*;;))))7;7O7OPU7V4 $"4 ~~~

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

166"s   "B% %C"0-CC"c                   V ^8  d   QhRR/# )rN   rv   ztuple[bytes, int]r0   )rR   s   "rJ   rS   r   p  s     ' '' 'rI   c                *   . p^ pV P                   P                  \        P                  4      pV\        8X  d   \        R\        P                  4      h  V P                  4       w  rEVP                  pVP                  V4       VP                  ^ 8X  d    V\        P                  ,          ^ 8X  d   MKa  Kc  RP%                  V4      V3#   \         d?   pTP                  \        P                   8X  d   \#        T.. . R4      w    p Rp?K  h Rp?ii ; i)zs
Receive a frame as bytes. libcurl splits frames into fragments, so we have to
collect all the chunks for a frame.
Invalid active socket      ?NrI   )rh   getinfor   ACTIVESOCKETr   rL   r   NO_CONNECTION_AVAILABLEr   r   append	bytesleftr   CONTr   rQ   AGAINr
   join)rY   chunksr   sock_fdr   r   r   _s   &       rJ   r   WebSocket.recvp  s    
 ))##H$9$9:o% ')J)J  #113e$??a'EJOO,Cq,H -I' xx&&  66Y__, %gYB<GAq!s   AC	 	D2DDDc                   V ^8  d   QhRR/# )rN   rv   rP   r0   )rR   s   "rJ   rS   r     s      # rI   c                    V P                  4       w  rV\        P                  ,          '       g   \        R\        P
                  4      hVP                  4       # )zReceive a text frame.zNot valid text frame)r   r   TEXTrL   r.   r<   r   )rY   r   r   s   &  rJ   recv_strWebSocket.recv_str  s>    iik
'' !79Q9QRR{{}rI   r	   c                    V ^8  d   QhRRRR/# )rN   r	   zCallable[[str], T]rv   r*   r0   )rR   s   "rJ   rS   r     s      "4  rI   c               2    V P                  4       pV! V4      # )zMReceive a JSON frame.

Args:
    loads: JSON decoder, default is json.loads.
)r  )rY   r	   r   s   &$ rJ   	recv_jsonWebSocket.recv_json  s     }}T{rI   c                    V ^8  d   QhRRRR/# )rN   payloadzUnion[str, bytes, memoryview]r   r   r0   )rR   s   "rJ   rS   r     s     - -.- -rI   c                   V\         P                  ,          '       d   RV n        V P                  '       d   \	        R4      h\        V\        4      '       d   VP                  4       pV P                  P                  \        P                  4      pV\        8X  d   \        R\        P                  4      h^ pV\!        V4      8  d+   WR p V P                  P#                  WR4      pYF,          pK:  V#   \$         dR   pTP&                  \        P(                  8X  d-   \+        . T.. R4      w  rpT	'       g   \        R4      Th Rp?K  h Rp?ii ; i)zUSend a data frame.

Args:
    payload: data to send.
    flags: flags for the frame.
Fr   r   Nr   zSocket write timeout)r   r   r   rp   r_   
isinstancerP   encoderh   r   r   r   r   rL   r   r  r   ws_sendr   rQ   r  r
   )
rY   r  r   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  66Y__,&,R'B&DOA!$,-CD!Ks   C4 4E?AE
EEc                   V ^8  d   QhRR/# rN   r  r   r0   )rR   s   "rJ   rS   r     s     5 55 5rI   c                B    V P                  V\        P                  4      # )z>Send a binary frame.

Args:
    payload: binary data to send.
r  r   BINARYrY   r  s   &&rJ   send_binaryWebSocket.send_binary       yy*"3"344rI   c                   V ^8  d   QhRR/# r!  r0   )rR   s   "rJ   rS   r     s     5 5% 5rI   c                B    V P                  V\        P                  4      # )z\Send a binary frame, alias of :meth:`send_binary`.

Args:
    payload: binary data to send.
r#  r%  s   &&rJ   
send_bytesWebSocket.send_bytes  r(  rI   c                   V ^8  d   QhRR/# )rN   r  rP   r0   )rR   s   "rJ   rS   r     s     3 3 3rI   c                B    V P                  V\        P                  4      # )z:Send a text frame.

Args:
    payload: text data to send.
r  r   r  r%  s   &&rJ   send_strWebSocket.send_str       yy*//22rI   r   c                    V ^8  d   QhRRRR/# )rN   r  r   r   Callable[[Any], str]r0   )rR   s   "rJ   rS   r     s     - - -0D -rI   c               0    V P                  V! V4      4      # )zeSend a JSON frame.

Args:
    payload: data to send.
    dumps: JSON encoder, default is json.dumps.
r0  rY   r  r   s   &&$rJ   	send_jsonWebSocket.send_json  s     }}U7^,,rI   c                   V ^8  d   QhRR/# rN   r  zUnion[str, bytes]r0   )rR   s   "rJ   rS   r     s     3 3- 3rI   c                B    V P                  V\        P                  4      # )z5Send a ping frame.

Args:
    payload: data to send.
r  r   PINGr%  s   &&rJ   pingWebSocket.ping  r2  rI   c                   V ^8  d   QhRR/# )rN   r   rP   r0   )rR   s   "rJ   rS   r     s     B Bs BrI   c                j   V'       d   V P                   ! V3/ VB  V P                  P                  \        P                  4      pV\
        8X  d   \        R\        P                  4      hV P                  R4       . pRV n
        V P                  '       Ed    V P                  4       w  rVVP                  pV P                  RWV4       VP                  V4       VP                  ^ 8X  d   V\        P                   ,          ^ 8X  g   K  RV P"                  9   d   RP%                  V4      pV\        P&                  ,          '       d$   V P(                  '       g    VP+                  4       pV\        P6                  ,          '       g   V\        P&                  ,          '       d   V P                  RV4       . pV\        P8                  ,          '       dF   R	V n
        T P                  R
V P2                  ;'       g    ^ V P:                  ;'       g    R4       EK  EK  R#   \,         dU   p	\.        P0                  T n        T P5                  \.        P0                  4       \        R\.        P0                  4      T	hRp	?	ii ; i  \<         d   p	T	P>                  \        P@                  8X  d   \C        T.. . R4      w    p
 Rp	?	EKA  T P                  RT	4       T PD                  '       gD   \.        PF                  p\I        T	\        4      '       d   T	P>                  pT P5                  T4       h Rp	?	ii ; i)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   rO   rI   zInvalid UTF-8NFr   r   r   r   )%r   rh   r   r   r   r   rL   r   r  r   r   r   r   r  r  r   r  r   r  r  r   r   r   r.   r<   rn   r   r$  r   ro   r   rQ   r  r
   rp   r:   r  )rY   r   kwargsr  r  r   r   r   r   r   r	  rQ   s   &&,         rJ   run_foreverWebSocket.run_forever  si    LL''))##H$9$9:o% ')J)J  	

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

650e$1,1HA1M .((6*C
//9R9R9R%"%**,C 
 1 111uz7N7N

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

4(
su   A.J >J J H *J J $0J %J ;J J I>*AI99I>>J L22L-#L-)AL--L2rI   c                    V ^8  d   QhRRRR/# )rN   rQ   r   rO   r   r0   )rR   s   "rJ   rS   r   <  s      #  rI   c                    V P                   \        J d   R# V P                  W4      pV P                  V\        P
                  4       V P                  4        R# )zNClose the connection.

Args:
    code: close code.
    message: close reason.
N)rh   r   r   r  r   r   r   )rY   rQ   rO   r   s   &&& rJ   r   WebSocket.close<  sC     99 $$T3		#z''(rI   )rn   ro   r   r   r   )r   r   r   )r   ) r1   r2   r3   r4   r5   r   r   rX   r   r   r   r   r   r   r  r	   r  r   r$  r  r&  r+  r0  r   r8  r?  rD  r.   r6   r   rH   r\   r]   s   @rJ   r+   r+      s6   3I ")(/ 	(/
 &+(/ (/ (,(/ *.(/ (,(/ .2(/ *.(/ (/T
& 6:)-)-*.GN $'+#04!%!%)<48! $DH $,.26#'6:595kZ,'@u  '---^553-u -3BH !,  rI   c                  .  a  ] tR tRt$ RtRRtRtR]R&   ^tR]R&   Rt	R	]R
&   RRRRRRRRRRRRRRRRRRR^?/
R V 3R lllt
]R R l4       t]R R l4       tR R  ltR! R" ltR# R$ ltR% R& ltR' R( ltR)R*/R+ R, lltR)R*/R- R. lltR/]R)R*/R0 R1 llt]P0                  3R2 R3 lltR4 R5 ltR6 R7 ltR8 R9 ltR:]/R; R< lltR= R> lt] PB                  R?R@3RA RB llt"RC V 3RD llt#RE RF lt$RG RH lt%RI RJ lt&RSRK RL llt'RM V 3RN llt(RO RP lt)RQt*V ;t+# )TAsyncWebSocketiN  z
An asyncio WebSocket implementation using libcurl.

NOTE: This object represents a single WebSocket connection. Once closed,
it cannot be reopened. A new instance must be created to reconnect.
retry_on_recv_errori  zClassVar[int]_MAX_CURL_FRAME_SIZE_MAX_RECV_RETRIESg333333?zClassVar[float]_RECV_RETRY_DELAYre   Trf   Frecv_queue_sizei   send_queue_size   max_send_batch_sizecoalesce_framesyield_intervalgMbP?fair_scheduling
yield_maskc               L    V ^8  d   Qh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/# )rN   sessionr(   rh   r   re   ri   rf   rO  r   rP  rR  rS  rK  rT  floatrU  rV  rv   r   r0   )rR   s   "rJ   rS   AsyncWebSocket.__annotate__q  s     L' L'L' L'
 L' L' L' L' !L' L' "L' L' L' L' 
L'rI   c       
          < \         SV `  W#VR7       Wn        RV n        RV n        \
        P                  ! 4       V n        \        P                  ! 4       V n	        \
        P                  ! 4       V n        RV n        RV n        RV n        \
        P                  ! VR7      V n        \
        P                  ! VR7      V n        Wpn        Wn        Wn        Wn        Wn        Wn        ^ V n        RV n        R# )ak  Initializes an Async WebSocket session.

This class should not be instantiated directly. It is intended to be created
via the `AsyncSession.ws_connect()` method, which correctly handles setup and
initialization of the underlying I/O tasks.

Important:
    This WebSocket implementation uses a decoupled I/O model. Network
    operations occur in background tasks. As a result, network-related
    errors that occur during a `send()` operation will not be raised by
    `send()`. Instead, they are placed into the receive queue and will be
    raised by the next call to `recv()`.

Args:
    session (AsyncSession): An instantiated AsyncSession object.
    curl (Curl): The underlying Curl to use.
    autoclose (bool, optional): Close the WS on receiving a close frame.
    debug (bool, optional): Enable debug messages. Defaults to False.
    recv_queue_size (int, optional): The maximum number of incoming WebSocket
        messages to buffer internally. This queue stores messages received
        by the Curl socket that are waiting to be consumed by calling `recv()`
    send_queue_size (int, optional): The maximum number of outgoing WebSocket
        messages to buffer before applying network backpressure. When you call
        `send(...)` the message is placed in this queue and transmitted when
        the Curl socket is next available for sending.
    max_send_batch_size (int, optional): The max number of messages per batch.
    coalesce_frames (bool, optional): Combine multiple frames into a batch.
    retry_on_recv_error (bool, optional): Retry recv on some transient errors.
    yield_interval (float, optional): How often to yield control in seconds.
    fair_scheduling (bool, optional): Change the ~5:1 ratio in favor
        of `recv`:`send` to a fairer 1:1 ratio. This decreases recv throughput.
    yield_mask (int, optional): A bitmask that sets the yield frequency for
        cooperative multitasking, checked every `yield_mask + 1` operations.
        Must be a power of two minus one (e.g., `63`, `127`, `255`) for
        efficient bitwise checks. Lower values increase fairness; higher values
        increase throughput.
r   N)maxsizeF)rW   rX   rX  _loop_sock_fdasyncioLock_close_lock	threading_terminate_lockEvent_terminated_event
_read_task_write_task_close_handleQueue_receive_queue_send_queue_max_send_batch_size_coalesce_framesrK  _yield_interval_use_fair_scheduling_yield_mask_recv_error_retries_terminated)rY   rX  rh   re   rf   rO  rP  rR  rS  rK  rT  rU  rV  rZ   s   &&&$$$$$$$$$$rJ   rX   AsyncWebSocket.__init__q  s    j 	duE/6:>
)0/8~~/?078<9=7;>Emm#?
 <C==#<
 *=!&5)< &4*9! *() !&rI   c                   V ^8  d   QhRR/# )rN   rv   zasyncio.AbstractEventLoopr0   )rR   s   "rJ   rS   rZ    s      / rI   c                |    V P                   f$   \        \        P                  ! 4       4      V n         V P                   # )z)Get a reference to the running event loop)r^  r   r`  get_running_looprs   s   &rJ   loopAsyncWebSocket.loop  s-     ::%g&>&>&@ADJzzrI   c                   V ^8  d   QhRR/# )rN   rv   r   r0   )rR   s   "rJ   rS   rZ    s     ( ( (rI   c                6    V P                   P                  4       # )z6Returns the current number of items in the send queue.)rl  qsizers   s   &rJ   rP  AsyncWebSocket.send_queue_size  s     %%''rI   c                   V ^8  d   QhRR/# )rN   rv   ri   r0   )rR   s   "rJ   rS   rZ    s     B B$ BrI   c                   V P                   '       g   V P                  '       d   R# V P                  '       d#   V P                  P                  4       '       d   R# V P                  ;'       d    V P                  P                  4       '       * # )a\  
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)rp   rs  rg  donerh  rs   s   &rJ   is_aliveAsyncWebSocket.is_alive  s_     ;;;$***???t3355$$@@)9)9)>)>)@AArI   c                   V ^8  d   QhRR/# rN   rv   r   r0   )rR   s   "rJ   rS   rZ    s       rI   c                    \        V RR4      '       d   R# \        \        4      ;_uu_ 4        \        P                  ! RV : R2\
        ^R7       RRR4       R#   + '       g   i     R# ; i)z1Warn if the user forgets to close the connection.rp   TNzUnclosed WebSocket zN was garbage collected. Always call await ws.close() to ensure clean shutdown.r   )getattrr   r   r   r   ResourceWarningrs   s   &rJ   __del__AsyncWebSocket.__del__  sU     44((i  MM%dX .I I	 !   s   #AA+	c                   V ^8  d   QhRR/# )rN   rv   r    r0   )rR   s   "rJ   rS   rZ    s      4 rI   c                	@    V P                   '       d   \        R 4      hV # )zWebSocket has been closedr   rs   s   &rJ   	__aiter__AsyncWebSocket.__aiter__  s    ;;;!"=>>rI   c                   V ^8  d   QhRR/# r   r0   )rR   s   "rJ   rS   rZ    s       rI   c                	   "   V P                  4       G R j  xL
 w  rVe   V\        P                  ,          '       d   \        hV#  L/5irV   )r   r   r   StopAsyncIterationr   s   &  rJ   	__anext__AsyncWebSocket.__anext__  s:     99;&
KUZ%5%555$$
 's   AA&A	Ac                   V ^8  d   QhRR/# r  r0   )rR   s   "rJ   rS   rZ    s     
 
 
rI   c                   V P                   e   R# V P                  P                  \        P                  4      V n        V P
                  \        8X  d   \        R\        P                  R7      hR\        V 4      R 2pV P                  P                  V P                  4       V R2R7      V n         V P                  P                  V P                  4       V R2R7      V n        R# )	zStart the read/write I/O loop tasks.
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Invalid active socket.)rQ   z
WebSocket-z#xz-read)namez-write)rg  rh   r   r   r   r_  r   rL   r   r  idrx  create_task
_read_loop_write_looprh  )rY   ws_ids   & rJ   _start_io_tasksAsyncWebSocket._start_io_tasks  s     ??& 		))(*?*?@==O+ (y/P/P 
 ""T(2/ ))//0A5'QV/X9900wf%5 1 
rI   r   Nc                    V ^8  d   QhRRRR/# )rN   r   Optional[float]rv   ztuple[Optional[bytes], int]r0   )rR   s   "rJ   rS   rZ    s     " ")"	$"rI   c                 "   V P                   '       d,   V P                  P                  4       '       d   \        R4      h \        P
                  ! V P                  P                  4       V4      G Rj  xL
 w  r#\        V\        4      '       d   VhW#3#  L!  \        P                   d!   p\        R\        P                  4      ThRp?ii ; i5i)aB  Receive a frame as bytes.

This method waits for and returns the next complete data frame from the
receive queue.

Args:
    timeout: how many seconds to wait before giving up.

Raises:
    WebSocketClosed: If `recv()` is called on a closed connection after
        the receive queue is empty.
    WebSocketTimeout: If the operation times out.
    WebSocketError: A protocol or network error that occurred in a
        background I/O task, including errors from previous `send()`
        operations.

Returns:
    tuple[bytes, int]: A tuple with the received payload and flags.
r   NzWebSocket recv() timed out)rp   rk  emptyr_   r`  wait_forr   r  r   TimeoutErrorrb   r   OPERATION_TIMEDOUT)rY   r   resultr   r   s   &$   rJ   r   AsyncWebSocket.recv  s     , ;;;4..4466!"788
	")"2"243F3F3J3J3Lg"VVMF&),,= 	 W ## 	",i.J.J	s@   2CC2B 3B4 B CB C,CCCc                    V ^8  d   QhRRRR/# )rN   r   r  rv   rP   r0   )rR   s   "rJ   rS   rZ  8  s       C rI   c               <  "   V P                  VR7      G Rj  xL
 w  r#Ve   V\        P                  ,          '       g   \        R\        P
                  4      h VP                  R4      #  LS  \         d!   p\        R\        P
                  4      ThRp?ii ; i5i)zUReceive a text frame.

Args:
    timeout: how many seconds to wait before giving up.
r   NzNot a valid text frameutf-8zInvalid UTF-8 in text frame)r   r   r  rL   r.   r<   r   r   )rY   r   r   r   r   s   &$   rJ   r  AsyncWebSocket.recv_str8  s      !IIgI66<
 7 7 !9;;S;STT	;;w''	 7
 " 	 -{/G/G	s9   BA,&B BA. +B.B9BBBr	   c               $    V ^8  d   QhRRRRRR/# )rN   r	   z Callable[[Union[str, bytes]], T]r   r  rv   r*   r0   )rR   s   "rJ   rS   rZ  H  s*       0 !	
 
rI   c               X  "   V P                  VR7      G Rj  xL
 w  r4Vf   \        R\        P                  4      hV\        P
                  ,          '       d    V! VP                  R4      4      # V! V4      #  La  \         d!   p\        R\        P                  4      ThRp?ii ; i5i)zReceive a JSON frame.

Args:
    loads: JSON decoder, default is json.loads.
    timeout: how many seconds to wait before giving up.
r  Nz(Received empty frame, cannot decode JSONr  z Invalid UTF-8 in JSON text frame)r   rL   r.   r<   r   r  r   r   )rY   r	   r   r   r   r   s   &$$   rJ   r  AsyncWebSocket.recv_jsonH  s      !IIgI66< :K<T<T  :??""T[[122
 T{ 7 & $68P8Ps4   B*A:A B*A< 1
B*<B'B""B''B*c                    V ^8  d   QhRRRR/# )rN   r  z(Union[str, bytes, bytearray, memoryview]r   r   r0   )rR   s   "rJ   rS   rZ  b  s     .9 .99.9 .9rI   c                  "   V P                   '       d   \        R4      h\        V\        4      '       d   VP	                  R4      pM'\        V\
        \        34      '       d   \        V4      p V P                  P                  W34       R#   \        P                   d*    T P                  P                  Y34      G Rj  xL 
   R# i ; i5i)a  Send a data frame.

This method is a lightweight, non-blocking call that places the payload
into a send queue. The actual network transmission is handled by a
background task.

To guarantee all your messages have been sent `await ws.flush(...)`.

The max frame size supported by libcurl is `65535` bytes. Larger frames
will be broken down and sent in chunks of that size.

Args:
    payload: data to send.
    flags: flags for the frame.

Raises:
    WebSocketClosed: The WebSocket is closed.

NOTE:
    Due to the asynchronous nature of this client, network errors
    (e.g., connection dropped) that occur during the actual transmission
    will NOT be raised by this method. They will be raised by a
    subsequent call to `recv()`. Always ensure you are actively
    receiving data to handle potential connection errors.

    Also: If the network is slow and the internal send queue becomes full,
    this method will block until there is space in the queue.
r   r  N)rp   r_   r  rP   r  	bytearray
memoryviewr   rl  
put_nowaitr`  	QueueFullput)rY   r  r   s   &&&rJ   r  AsyncWebSocket.sendb  s     D ;;;!"788 gs##nnW-G)Z!899GnG	9''(89   	9""&&'7888	9s6   A-C0B C4CCCCCCc                    V ^8  d   QhRRRR/# rN   r  r   rv   r   r0   )rR   s   "rJ   rS   rZ    s     ; ; ;4 ;rI   c                ^   "   V P                  V\        P                  4      G Rj  xL
 #  L5i)zpSend a binary frame.

Args:
    payload: binary data to send.

For more info, see the docstring for `send(...)`
Nr#  r%  s   &&rJ   r&  AsyncWebSocket.send_binary  $      YYw
(9(9::::   $-+-c                    V ^8  d   QhRRRR/# r  r0   )rR   s   "rJ   rS   rZ    s     ; ; ;$ ;rI   c                ^   "   V P                  V\        P                  4      G Rj  xL
 #  L5i)zSend a binary frame, alias of :meth:`send_binary`.

Args:
    payload: binary data to send.

For more info, see the docstring for `send(...)`
Nr#  r%  s   &&rJ   r+  AsyncWebSocket.send_bytes  r  r  c                    V ^8  d   QhRRRR/# )rN   r  rP   rv   r   r0   )rR   s   "rJ   rS   rZ    s     9 9c 9d 9rI   c                ^   "   V P                  V\        P                  4      G Rj  xL
 #  L5i)zlSend a text frame.

Args:
    payload: text data to send.

For more info, see the docstring for `send(...)`
Nr/  r%  s   &&rJ   r0  AsyncWebSocket.send_str  "      YYw
8888r  r   c               $    V ^8  d   QhRRRRRR/# )rN   r  r   r   r4  rv   r   r0   )rR   s   "rJ   rS   rZ    s$     3 33&:3	3rI   c               L   "   V P                  V! V4      4      G Rj  xL
 #  L5i)zSend a JSON frame.

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

For more info, see the docstring for `send(...)`
Nr6  r7  s   &&$rJ   r8  AsyncWebSocket.send_json  s       ]]5>2222s   $"$c                   V ^8  d   QhRR/# r;  r0   )rR   s   "rJ   rS   rZ    s     9 9"3 9rI   c                ^   "   V P                  V\        P                  4      G Rj  xL
 #  L5i)zgSend a ping frame.

Args:
    payload: data to send.

For more info, see the docstring for `send(...)`
Nr=  r%  s   &&rJ   r?  AsyncWebSocket.ping  r  r  rI   g      @c               (    V ^8  d   QhRRRRRRRR/# )	rN   rQ   r   rO   r   r   rY  rv   r   r0   )rR   s   "rJ   rS   rZ    s2     %S %S%S38%SIN%S	%SrI   c                h  "   V P                   ;_uu_4       GRj  xL
  V P                  '       d    RRR4      GRj  xL
  R# RV n         V P                  '       d   V P                  P                  4       '       g   V P	                  W4      p\        \        P                  4      ;_uu_ 4        \        P                  ! V P                  P                  V\        P                  34      VR7      G Rj  xL
  RRR4       \        \        \        4      ;_uu_ 4        V P                  V4      G Rj  xL
  RRR4       V P!                  4        \        \        P                  4      ;_uu_ 4        \        P                  ! V P"                  P%                  4       V4      G Rj  xL
  RRR4       RRR4      GRj  xL
  R#  EL EL L  + '       g   i     L; i L  + '       g   i     L; i LN  + '       g   i     LT; i  T P!                  4        \        \        P                  4      ;_uu_ 4        \        P                  ! T P"                  P%                  4       T4      G Rj  xL 
  RRR4       i   + '       g   i     i ; i; i L  + GRj  xL 
 '       g   i     R# ; i5i)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. This is
the recommended way to close the session.

Args:
    code (int, optional): Close code. Defaults to `WsCloseCode.OK`.
    message (bytes, optional): Close reason. Defaults to `b""`.
    timeout (float, optional): How long in seconds to wait closed.
NTr  )rb  rp   rh  r  r   r   r`  r  r  rl  r  r   r   rb   rL   flushr   rf  wait)rY   rQ   rO   r   close_frames   &&&& rJ   r   AsyncWebSocket.close  s     ####{{{ $## DKS###D,<,<,A,A,C,C"&"8"8"GK!'"6"677%.. ,,00+z?O?O1PQ$+   8
 ""2NCC"jj111 D   g2233!**4+A+A+F+F+H'RRR 4+ $## 87 2 DC S 43   g2233!**4+A+A+F+F+H'RRR 4333+ $###s,  J2GJ2JJ2GJ2JH	H	?2H	1AG	6G
7G	;$H	G!	4G5G!	9H	1J23G6	%G4&G6	*J2J2=J>J2J2
G	GH	G!	!G1,H	4G6	6HJ	2J;3I=.I1/I=4	J=JJJJ2J/	J
J/	'J/	)	J2c                   V ^8  d   QhRR/# r  r0   )rR   s   "rJ   rS   rZ    s     1 14 1rI   c                D  <a  S P                   ;_uu_ 4        S P                  '       d    RRR4       R# RS n        S P                  '       dF   S P                  P	                  4       '       d&   S P                  P                  V 3R l4      S n        Mq\        SS `!  4        S P                  '       dR   S P                  P                  '       g6   S P                  P                  R4       S P                  P                  4        RRR4       R#   + '       g   i     R# ; i)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.
NTc                 V   < S P                   P                  S P                  4       4      # rV   )rx  r  _terminate_helperrs   s   rJ   <lambda>*AsyncWebSocket.terminate.<locals>.<lambda>  s    DII11$2H2H2JKrI   )rd  rs  r^  rx  
is_runningcall_soon_threadsaferi  rW   r   rX  _closed	push_curlrf  set)rY   rZ   s   frJ   r   AsyncWebSocket.terminate  s     !!! "!  $D zzzdii2244%)YY%C%CK&" !#<<<(<(<(<LL**40**..0# "!!!s#   DDD.A D5DD	c                   V ^8  d   QhRR/# r  r0   )rR   s   "rJ   rS   rZ    s     BM BM$ BMrI   c           	     D  "   V P                   P                  pV P                  P                  pV P                  P                  pV P
                  pV P                  pV P                  pV P                  p. p^ p	 V P                  '       EgS   VP                  4       p
 VP                  V P                  V
P                  R4        T
G Rj  xL
  T P                  R8w  d   TP/                  T P                  4       TP1                  4       p  T! 4       w  rTP2                  pT P4                  ^ 8  d   ^ T n        T\6        P8                  ,          '       d   \        \         P"                  4      ;_uu_ 4        T! Y34       RRR4       T P;                  T4      G Rj  xL
   \        \         P"                  4      ;_uu_ 4        T! \-        R4      ^ 34       RRR4       R# TP=                  T4       TP>                  ^ 8:  dI   T\6        P@                  ,          ^ 8X  d-   RPC                  T4      pTPE                  4         T! TT34       T	^,          p	Y,          ^ 8H  pTP1                  4       T,
          T8  pT'       d   T'       g	   T'       dI   MT'       d=   T'       d2   \         PF                  ! ^ 4      G Rj  xL
  TP1                  4       pEK  EK  EK  EK   \        \         P"                  4      ;_uu_ 4        V! \-        R4      ^ 34       RRR4       R#   \         d   p\        \         P"                  4      ;_uu_ 4        T! \%        RT 2\&        P(                  4      ^ 34       RRR4       M  + '       g   i     M; iT P+                  4         Rp?\        \         P"                  4      ;_uu_ 4        T! \-        R4      ^ 34       RRR4       R#   + '       g   i     R# ; iRp?ii ; i EL1  T P                  R8w  d   TP/                  T P                  4       i i ; i  + '       g   i     EL; i EL  + '       g   i     R# ; i  \         P"                   d    T! TT34      G Rj  xL 
   EL9i ; i EL  \H         Ed   pTPJ                  \&        PL                  8X  d    Rp?EKF  TPJ                  \&        PN                  8X  d   T PP                  '       dv   T P4                  T PR                  8  d[   T ;P4                  ^,          un        \         PF                  ! T PT                  T P4                  ,          4      G Rj  xL 
   Rp?EKZ  \        \         P"                  4      ;_uu_ 4        T! T^ 34       RRR4       M  + '       g   i     M; iT P+                  4         Rp?\        \         P"                  4      ;_uu_ 4        T! \-        R4      ^ 34       RRR4       R#   + '       g   i     R# ; iRp?ii ; i  \         PV                   d     ELU\         dv   pT P                  '       gI   \        \         P"                  4      ;_uu_ 4        T! T^ 34       RRR4       M  + '       g   i     M; iT P+                  4         Rp?ELRp?ii ; i  + '       g   i     R# ; i  \        \         P"                  4      ;_uu_ 4        T! \-        R4      ^ 34       RRR4       i   + '       g   i     i ; i; i5i)a#  The main asynchronous task for reading incoming WebSocket frames.

This method is fully event-driven. 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.

To ensure cooperative multitasking during high-volume message streams,
the loop yields control to the asyncio event loop periodically.

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, even though the defaults are generous
and should be suitable for most use cases.
Nzadd_reader failed: zConnection closed.rI   r]  ),rm   r   rk  r  r  rx  rp  rq  ro  rp   create_future
add_readerr_  
set_resultr   r   r`  r  rL   r   r  r   r_   remove_readertimer   rr  r   r   _handle_close_framer  r  r  r  clearsleepr   rQ   r  
RECV_ERRORrK  rM  rN  CancelledError)rY   curl_ws_recvqueue_put_nowait	queue_putrx  rU  rV  rT  r  msg_counterread_futureexc
start_timer   r   r   rO   op_check
time_checkr   s   &                   rJ   r  AsyncWebSocket._read_loop  sK    & zz))..99''++	yy33%%
-- e	Mkkk"002OODMM;3I3I4P:%%% }}***4==9 "YY[
:'3~%*[[33a778D4 !:#3#333!)'*;*;!<!< 0% @ "="&":":5"AAA"r '++,, /2F"G!KL -,m e, !??a/UZ__5LQR4R&)hhv&6G"LLNB 0'51A B $q(*5*Bq)H+/99;+Cn+T
  / &"*z")--"222)-J 0:( *4y "D '++,, /2F"G!KL -,y ! !'"3"344( .&9#$?$-$E$E!" !" 5444 NN$` '++,, /2F"G!KL -,,,y & }}***4==9 + "=!<!<At -,,] $+#4#4 B&/%0@&A A AB 3 % 66Y__4! FFi&:&:: $ 8 8 8 $ 8 84;Q;Q Q 4494")-- $ 6 69Q9Q Q#   % &g&7&788,aV4 9888( '++,, /2F"G!KL -,,,?. %% 	 	;;;g//00$aV, 1000NN		 -,,'++,, /2F"G!KL -,,,sU  A7\ :X X 'L O? O<O? =X A	R !R 9
P1R Q R %!\ Q
\ $AR 
Q =R R R R %R >R?R X [  !\ Z7
\ O9*!O4&M:1	O4:N
O4X !!\ O 
\  O1	+	\ 4O99X <O? ?/P..X 1Q	<
R Q		\ "R>R?RR RR XX9X  0X1A(XUXX &!XV	XV+&X>X !\ #X7
\ X		\ XX Z42[ 5Z4>Z4?3Z/2Z=	Z/ZZ/)[ /Z44[ 7[		\ "\-\
		\
\\\ c                   V ^8  d   QhRR/# r  r0   )rR   s   "rJ   rS   rZ    s     Z! Z!4 Z!rI   c                p
  "   \         P                  \         P                  ,          pV P                  pV P                  P
                  pV P                  P                  p  V! 4       G Rj  xL
 w  rVWV3.pV\         P                  ,          '       gW   \        V4      V P                  8  d=    V! 4       w  rXVP                  WX34       V\         P                  ,          '       d   MKV   V P                  '       Ed   / p	V EFW  w  rXW,          '       Ed"   V	P                  4        F  w  rV! RP                  V4      V
4      G Rj  xL
 '       d   K-    \        \        V4      4       F  pV P                  P!                  4        K  	  V P"                  '       g   V P%                  4        R# R# 	  V	P'                  4        V! WX4      G Rj  xL
 '       g]    \        \        V4      4       F  pV P                  P!                  4        K  	  V P"                  '       g   V P%                  4        R# R# EK6  V	P)                  V. 4      P                  V4       EKZ  	  V	P                  4        F  w  rV! RP                  V4      V
4      G Rj  xL
 '       d   K-   \        \        V4      4       F  pV P                  P!                  4        K  	  V P"                  '       g   V P%                  4        R# R# 	  M}V Fw  w  rXV! WX4      G Rj  xL
 '       d   K   \        \        V4      4       F  pV P                  P!                  4        K  	  V P"                  '       g   V P%                  4        R# R# 	  \        \        V4      4       F  pV P                  P!                  4        K  	  VR,          ^,          \         P                  ,          '       g   EKy   T P"                  '       g   T P%                  4        R# R#  EL  \        P                   d     EK3  i ; i EL ELV EL EL  \        \        T4      4       F  pT P                  P!                  4        K  	  i ; i  \        P*                   d     L\,         d   pT P"                  '       gg   \/        \        P0                  4      ;_uu_ 4        T P2                  P5                  T^ 34       RRR4        Rp?EK    + '       g   i      Rp?EL"; i Rp?EL+Rp?ii ; i  T P"                  '       g   T P%                  4        i i ; i5i)a  
The high-level send manager. It efficiently gathers pending messages
from the send queue and orchestrates their transmission.

This method runs a continuous loop that consumes messages from the
`_send_queue`. To improve performance and reduce system call overhead,
it implements an adaptive batching strategy. It greedily gathers
multiple pending messages from the queue and then coalesces the
payloads of messages that share the same flags (e.g., all text frames)
into a single, larger payload, ONLY if `coalesce_frames=True` and the
frame is not a CONTROL frame, as the spec requires them to be whole.

It will batch as many as possible, then iterate over the batch and send
the frames, one at a time. This batching and coalescing significantly
improves throughput for high volumes of small messages where the message
boundaries do not matter. The final, consolidated payloads are then passed
to the `_send_payload` method for transmission.
NrI   r]  )r   r   r>  _send_payloadrl  r   
get_nowaitr   rm  r  r`  
QueueEmptyrn  itemsr  range	task_donerp   r   r  
setdefaultr  r   r   r  rk  r  )rY   control_frame_flagssend_payload	queue_getqueue_get_nowaitr  r   batchr   data_to_coalesceframe_grouppayloadsr	  r   s   &             rJ   r  AsyncWebSocket._write_loop  s    & $.#3#3joo#E))$$((	++66B	!'0{!2 ")*z////e*t'@'@@"-=-?NG!LL')9:$z'7'777 %  8 5,,,CE(.3NG$::=M=S=S=U$9K1=(+(:K2& ,& ,& ,& )/( #3u:.((224 /" ;;;  S >V
 !1 6 6 8-9'-I'I'I$*  #3u:.((224 /" ;;;  E (J !1 ; ;E2 F M Mg V /4  6F5K5K5M1K)5chhx6H+)V#V#V#V & #3u:.((224 /" ;;;  9 6N
 /4NG)5g)E#E#E#E & #3u:.((224 /" ;;;  / /4 #3u:.((224 / 9Q<*"2"222 ;;;   "3  '11 "!",& (J $W
 $F
 #3u:.((224 / %% 	 	;;;;g//00''22Aq6: 10000 	; ;;;  s~  AT6!Q' ,P-AQ' /8P 'Q' +P- >A	P- P!P- P- 5Q' &T61P- P$	P- P- 5Q' &T65AP- P'P- P- 5Q' &T67P- P*P- P- 5Q' &T65P- 7AQ' T &T6Q' PQ' PQ' !P- $P- 'P- *P- -7Q$$Q' 'T<T >TT3T;S(T!T (S=3T7T =T T TT %T33T6c               $    V ^8  d   QhRRRRRR/# )rN   r  r   r   r   rv   ri   r0   )rR   s   "rJ   rS   rZ    s&     M M5 M M MrI   c           
     N  "   V P                   P                  pV P                  P                  pV P                  p\        V4      p^ p^ pVP                  4       p	V\        V4      8  d   WP                  ,          ^ 8X  g'   VP                  4       V	,
          V P                  8  d/   \        P                  ! ^ 4      G Rj  xL
  VP                  4       p	 WgWpP                  ,            p
V! W4      pV^ 8X  dO   \        \        P                  4      ;_uu_ 4        V! \        R\         P"                  4      ^ 34       RRR4       R# W{,          pV^,          pEK  R#  L  + '       g   i     R# ; i  \$         Ed   pTP&                  \         P(                  8w  dO   \        \        P                  4      ;_uu_ 4        T! T^ 34       RRR4       M  + '       g   i     M; i Rp?R# TP+                  4       p TP-                  T P.                  TP0                  R4       M  \2         ds   p\        \        P                  4      ;_uu_ 4        T! \        RT 2\         P4                  4      ^ 34       RRR4       M  + '       g   i     M; i Rp? Rp?R# Rp?ii ; i TG Rj  xL 
  T P.                  R8w  d#   TP7                  T P.                  4        Rp?EK   Rp?EK    T P.                  R8w  d   TP7                  T P.                  4       i i ; iRp?ii ; i5i)a<  
The low-level I/O Handler. It transmits a single payload, handling
fragmentation, backpressure (EAGAIN), and cooperative multitasking.
Returns False on a non-recoverable error.

Args:
    payload: The complete byte payload to be sent.
    flags: The `CurlWsFlag` indicating the frame type (e.g., `TEXT`, `BINARY`).
Nzws_send returned 0 bytesFzadd_writer failed: Tr]  )rm   r  rk  r  rx  r  r  r   rq  ro  r`  r  rL  r   r  rL   r   
SEND_ERRORr   rQ   r  r  
add_writerr_  r  r   r  remove_writer)rY   r  r   curl_ws_sendr  rx  viewr  	write_opsr  r   r  r   write_futurer  s   &&&            rJ   r  AsyncWebSocket._send_payload  sv     zz))..99yy'"	 IIK
s4y ,,,2		j($$7% mmA&&&!YY[
/:f/H/H&HI%e3Q;!'"3"344( .$>$-$8$8!" !" 5 ! Q	@ g ' 54 !  :66Y__,!'"3"344(!Q0 5444   $113!OODMM<3J3JDQ  !!'"3"344( .&9#$?$-$E$E!" !" 5444 !5!:&&&}}***4==99 +t}}***4==9 +9:s   B>L% EL%AE3 #E=E3 L%E3 L%E0	*E3 .L%0E3 3L"?A L?G
	LG#L&L%,L='H%$L%J"0!J&J 	7	J JJLL%J""L&K++J.,K+1,LL%+/LLL""L%c                    V ^8  d   QhRRRR/# )rN   r   r  rv   r   r0   )rR   s   "rJ   rS   rZ  =  s     X X? Xd XrI   c                  "   V P                   '       dL   V P                   P                  4       '       d,   V P                  P                  4       '       g   \	        R4      h \
        P                  ! V P                  P                  4       VR7      G Rj  xL
  R#  L  \
        P                   d   p\        R4      ThRp?ii ; i5i)aO  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 (Optional[float], 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.
z6Cannot flush, writer task has terminated unexpectedly.r  Nz*Timed out waiting for send queue to flush.)
rh  r  rl  r  rL   r`  r  r  r  rb   )rY   r   r   s   && rJ   r  AsyncWebSocket.flush=  s     $   %%''$$**,, H 	X""4#3#3#8#8#:GLLL## 	X"#OPVWW	XsF   2CCC!3B BB CB C2B>>CCc                   V ^8  d   QhRR/# r  r0   )rR   s   "rJ   rS   rZ  \  s     /) /) /)rI   c           	       <"   \        4       p^p V P                  V P                  3 FG  p V'       d<   VP                  4       '       g$   VP	                  4        VP                  V4       KE  KG  KI  	  V'       d_   \        \        P                  4      ;_uu_ 4        \        P                  ! \        P                  ! VRR/ VR7      G Rj  xL
  RRR4       V P                  P                  4       '       g8    V P                  P                  4        V P                  P!                  4        KW  V P&                  R8w  d   \        \(        4      ;_uu_ 4        V P*                  P-                  V P&                  4       RRR4       \        \(        4      ;_uu_ 4        V P*                  P/                  V P&                  4       RRR4       RV n        \0        SV `e  4        V P4                  '       d8   V P4                  P6                  '       g   V P4                  P9                  R4       V P:                  P                  4        R#   \        P                  \        3 d     EK<  i ; i EL  + '       g   i     EL; i  \        P"                  \$        3 d     EKn  i ; i  + '       g   i     EL-; i  + '       g   i     L; i  T P:                  P                  4        i ; i5i)z)Utility method for connection terminationreturn_exceptionsTr  Nr]  )r  rg  rh  r  canceladdr`  r  RuntimeErrorr   r  r  gatherrl  r  r  r  r  
ValueErrorr_  r   rx  r  r  rW   r   rX  r  r  rf  )rY   tasks_to_cancelmax_timeoutio_taskrZ   s   &   rJ   r   AsyncWebSocket._terminate_helper\  s    365*	) OOT-=-=>w||~~('++G4 (6w ? g2233!**P4P +   4 &&,,..$$//1$$..0
 }}"i((II++DMM: )i((II++DMM: ) DM G|||DLL$8$8$8&&t, ""&&(G  ..=  433  **J7 
 )(((( ""&&(s   K)K
 I!I,K
 <!K
 0I,I)I,'K
 ;4J  /*K
 &J#?K
 &J7A
K
 K
 *K)I&!K
 %I&&K
 )I,,I=	7	K
  J K
 J  K
 #J4	.	K
 7K	K
 
K&&K)c                    V ^8  d   QhRRRR/# )rN   rO   r   rv   r   r0   )rR   s   "rJ   rS   rZ    s       4 rI   c                  "    V P                  V4      w  V n        V n        V P
                  '       dP   V P                  '       g>   T P                  V P                  ;'       g    \        P                  4      G Rj  xL
  R# V P                  4        R#   \         d   pTP                  T n         Rp?LRp?ii ; i LA5i)z<Unpack and handle the closing frame, then initiate shutdown.N)r   rn   ro   rL   rQ   re   rp   r   r.   r6   r   )rY   rO   r   s   && rJ   r  "AsyncWebSocket._handle_close_frame  s     	&373K3KG3T0Dd0 >>>$+++**T--??@@@ NN  	& vvD	& AsJ   C B C C C $C <B>=C B; B61C 6B;;C )rn   ri  rb  ro   rn  r^  rm  rg  rk  rr  rl  r_  rd  rs  rf  rp  rh  ro  rq  rp   rK  rX  )rX  r^  r_  rb  rd  rg  rh  ri  rk  rl  rm  rn  rK  ro  rp  rq  rr  rs  rf  rV   ),r1   r2   r3   r4   r5   r   rL  __annotations__rM  rN  rX   r   rx  rP  r  r  r  r  r  r   r  r	   r  r   r$  r  r&  r+  r0  r   r8  r?  r.   r6   r   r   r  r  r  r  r  r  rH   r\   r]   s   @rJ   rJ  rJ  N  s   I. +0-/'(}(),,L'
 L' L'  #L'  #L' $'L' !&L' %*L' !&L' !&L' L' L'\   ( (B&

:",0"H4   38 $(	: '--.9`;;93=B39 &..3QT%SN1 1@BMHZ!xM^X>/) /)b rI   rJ  ),:)r   r   r   rO   r   )R
__future__r   r`  r   rc  r   collections.abcr   
contextlibr   enumr   	functoolsr   jsonr   r	   r
   typingr   r   r   r   r   r   r   aior   r   constr   r   r   r   rh   r   r   utilsr   
exceptionsr   r   modelsr   r   r   typing_extensionsr    r!   r"   r   r#   r   r$   r   r%   r&   r'   rX  r(   r)   r*   r   	ON_DATA_TrP   ON_MESSAGE_T
ON_ERROR_T	ON_OPEN_Tr   
ON_CLOSE_Ttupler   RECV_QUEUE_ITEMSEND_QUEUE_ITEMr.   rL   r_   rb   rd   r   r+   rJ  r0   rI   rJ   <module>r7     s   "     $      R R R / < < " # .  ,&'"$$OO0A+uk:D@AI[%s
*;<dBCL;	2D89J+,-I;S1478JE%"23S89OE5S#99:O 	*-' .(Y ('nm ')~w )A AH FG l l^J] JrI   