+
    kHàjRš  ã                   ó  € R t ^ RIt^ RI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HtHt ^ RIHtHt ^ RIt^ RIHtHt ^ R	IHtHt ^ R
IHt ^ RI H!t!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RRRRRRRRRRRRR/t0RRRRRRR R!R"RR#R$R%R$/t1]Pd                  ! ]34      t4R&t5R't6R(t7R)t8R*t9R+R,.t:0 ];! R-R.4      m];! R/R04      mt<0 RQmt=]P|                  ! R14      t?]P|                  ! R24      t@]P|                  ! R34      tA]P|                  ! R44      tBR5tC0 RRmtDR6 R7 ltER8 R9 ltFR: R; ltGR< R= ltHR> R? ltIR@ tJ ! RA RB]!4      tKRCtLRD RE ltMRFRRGRRHRI/RJ RK lltNRL RM ltORNtPRO RP ltQR# )Sz¯BlueBubbles iMessage platform adapter: local BlueBubbles macOS server for outbound REST sends and
inbound webhooks (text, media attachments, typing indicators, read receipts).N)ÚOrderedDict)Úsuppress)Údatetime)ÚPath)ÚAnyÚDictÚListÚOptional)Úparse_qsÚquote)ÚPlatformÚPlatformConfig)Úextra_or_secretÚget_scoped_secret)Úconfig_connected_extra)ÚBasePlatformAdapterÚ
SendResultÚcache_image_from_bytes_asyncÚcache_audio_from_bytes_asyncÚcache_document_from_bytes_async)ÚMessageEventÚMessageType©Úext_for_mime)Úcompile_mention_patternsÚstrip_markdown)ÚTRUTHY_STRINGSz
image/jpegú.jpgz	image/pngz.pngz	image/gifz.gifz
image/webpz.webpz
image/heicz
image/heifz
image/tiffz	audio/mp3ú.mp3z
audio/mpegz	audio/oggz.oggz	audio/wavz.wavzaudio/x-cafz	audio/mp4z.m4az	audio/aacú	127.0.0.1i   iÅ!  z/bluebubbles-webhooki   z#(?<![\w@])@?hermes\s+agent\b[,:\-]?z(?<![\w@])@?hermes\b[,:\-]?iÐ  iÖ  i¸  i¾  z\+?\d{7,15}z[\w.+-]+@[\w-]+\.[\w.]+z\s*\(\d+/\d+\)$z^\+\d+iô  c                ó0   € V ^8„  d   QhR\         R\         /# ©é   ÚtextÚreturn©Ústr)Úformats   "ÚJ/home/ubuntu/.hermes/hermes-agent/plugins/platforms/bluebubbles/adapter.pyÚ__annotate__r)   F   s   € ÷ Jñ J”#ð Jœ#ñ Jó    c                óV   € \         P                  R\        P                  RV 4      4      # )z0Redact phone numbers and emails from log output.z
[REDACTED])Ú	_EMAIL_REÚsubÚ	_PHONE_RE©r#   s   &r(   Ú_redactr0   F   s   € ä�=‰=˜¤y§}¡}°\À4Ó'HÓIÐIr*   c                ó$   € V ^8„  d   QhR\         /# ©r"   r$   ©Úbool)r'   s   "r(   r)   r)   K   s   € ÷ ñ ¬ñ r*   c                  ó4   €  ^ RI p R#   \         d     R# i ; i)é    NFT)ÚaiohttpÚImportError)r7   s    r(   Úcheck_bluebubbles_requirementsr9   K   s#   € ðÛñ øô ô Úðús   ‚ ˆ–c                ó0   € V ^8„  d   QhR\         R\         /# ©r"   Úrawr$   r%   )r'   s   "r(   r)   r)   S   s   € ÷ ñ œsð ¤sñ r*   c                 óÌ   € T ;'       g    R P                  4       pV'       d3   \        P                  ! RV\        P                  R7      '       g   RV 2pVP	                  R4      # )Ú z
^https?://)Úflagsúhttp://Ú/)ÚstripÚreÚmatchÚ
IGNORECASEÚrstrip)r<   Úvalues   & r(   Ú_normalize_server_urlrH   S   sJ   € Ø�YˆY�B×ÑÓ€Eß”R—X’X˜m¨U¼"¿-¹-×HÓHØ˜%˜Ð!ˆØ�<‰<˜ÓÐr*   c                ój   € V ^8„  d   QhR\         R\        \         \         3,          R\         R\         /# )r"   ÚmimeÚ	overridesÚfallbackr$   )r&   Údict)r'   s   "r(   r)   r)   Z   s0   € ÷ 7ñ 7”cð 7¤d¬3´¨8¥nð 7Äð 7Ìñ 7r*   c                ó4   € \        WRRVR7      ;'       g    T# )zSHistorical maps were closed: unlisted mimes fall back without consulting mimetypes.F)rK   Úuse_defaultsÚuse_mimetypesrL   r   )rJ   rK   rL   s   &&&r(   Ú_closed_extrQ   Z   s&   € ä˜ÀÐUZØ!)ô+÷ 7ð 7Ø.6ð7r*   c                ó$   € V ^8„  d   QhR\         /# r2   r%   )r'   s   "r(   r)   r)   `   s   € ÷ 3ñ 3”Cñ 3r*   c                  óN   € R \         P                  ! 4       P                  4        2# )ztemp-)r   ÚutcnowÚ	timestamp© r*   r(   Ú
_temp_guidrW   `   s    € Ø”8—?’?Ó$×.Ñ.Ó0Ð1Ð2Ð2r*   c                 ó2   € ^ RI Hp  V P                  RR7      # )zLPlain ``ok`` acknowledgement for webhook events we accept but don't process.©ÚwebÚokr/   )r7   rZ   ÚResponserY   s    r(   Ú_okr]   d   s   € åØ�<‰<˜Tˆ<Ó"Ð"r*   c                   óê  a a€ ] tR t^jt oRt]P                  tRt]	t
RtV3R lV 3R lltV3R lR lt]V3R lR l4       tV3R	 lR
 ltV3R lR ltV3R lR ltV3R lR ltV3R lR ltV3R lR ltV3R lR ltRR/V3R lR lltV3R lR ltV3R lR lt]V3R lR l4       tV3R  lR! lt]V3R" lR# l4       t]V3R$ lR% l4       tV3R& lR' ltV3R( lR) lt V3R* lR+ lt!V3R, lR- lt"V3R. lR/ lt#]]	3V3R0 lR1 ll4       t$R]V3R2 lR3 llt%R^V3R4 lR5 llt&R_V3R6 lV 3R7 lllt'R]V3R8 lR9 llt(R]V3R: lR; llt)R]V3R< lR= llt*R_V3R> lR? llt+R_V3R@ lRA llt,R`V3RB lRC llt-V3RD lRE lt.V3RF lRG lt/V3RH lRI lt0V3RJ lRK lt1V3RL lRM lt2V3RN lRO lt3]V3RP lRQ l4       t4]V3RR lRS l4       t5V3RT lRU lt6V3RV lRW lt7V3RX lRY lt8RZ t9V3R[ lt:R\t;Vt<V ;t=# )aÚBlueBubblesAdapterTFc                ó    <€ V ^8„  d   QhRS[ /# )r"   Úconfig)r   )r'   Ú__classdict__s   "€r(   r)   ÚBlueBubblesAdapter.__annotate__r   s   ø€ ÷ @ñ @™~ñ @r*   c           
     ó�  <€ \         SV `  V\        P                  4       VP                  ;'       g    / p\        \        VR R4      4      V n        VP                  R4      ;'       g    \        RR4      V n
        \        VRR\        4      V n        \        \        VRR\        \        4      4      4      V n        \        \        VR	R
\"        4      4      pVP%                  R4      '       d   TMRV 2V n        \)        VP                  RR4      4      V n        VP                  R4      pVf   \        R4      p\        V4      P-                  4       P/                  4       \0        9   V n        T P5                  RV9   d
   VR,          M
\        R4      4      V n        RV n        RV n        RV n        RV n        \A        4       V n!        R# )Ú
server_urlÚBLUEBUBBLES_SERVER_URLÚpasswordÚBLUEBUBBLES_PASSWORDr>   Úwebhook_hostÚBLUEBUBBLES_WEBHOOK_HOSTÚwebhook_portÚBLUEBUBBLES_WEBHOOK_PORTÚwebhook_pathÚBLUEBUBBLES_WEBHOOK_PATHrA   Úsend_read_receiptsTÚrequire_mentionNÚBLUEBUBBLES_REQUIRE_MENTIONÚmention_patternsÚBLUEBUBBLES_MENTION_PATTERNSF)"ÚsuperÚ__init__r   ÚBLUEBUBBLESÚextrarH   Ú_extra_or_secretre   ÚgetÚ_get_scoped_secretrg   ÚDEFAULT_WEBHOOK_HOSTri   Úintr&   ÚDEFAULT_WEBHOOK_PORTrk   ÚDEFAULT_WEBHOOK_PATHÚ
startswithrm   r4   ro   rB   Úlowerr   rp   Ú_compile_mention_patternsÚ_mention_patternsÚclientÚ_runnerÚ_private_api_enabledÚ_helper_connectedr   Ú_guid_cache)Úselfra   rw   ÚpathÚ_require_mentionÚ	__class__s   &&   €r(   ru   ÚBlueBubblesAdapter.__init__r   sƒ  ø€ Ü‰Ñ˜¤×!5Ñ!5Ô6Ø—‘×"Ð" ˆÜ/Ô0@ÀÈÐVnÓ0oÓpˆŒØŸ	™	 *Ó-×_Ð_Ô1CÐDZÐ\^Ó1_ˆŒÜ,¨U°NÐD^Ô`tÓuˆÔÜÔ 0°¸ÐHbÔdgÔh|Ód}Ó ~ÓˆÔÜÔ# E¨>Ð;UÔWkÓlÓmˆØ$(§O¡O°C×$8Ò$8™DÀÀ$À¸jˆÔÜ"& u§y¡yÐ1EÀtÓ'LÓ"MˆÔØ Ÿ9™9Ð%6Ó7ÐØÒ#Ü1Ð2OÓPÐÜ"Ð#3Ó4×:Ñ:Ó<×BÑBÓDÌÑVˆÔØ!%×!?Ñ!?Ø);¸uÔ)DˆEÐ$Ö%ÔJ\Ð]{ÓJ|ó"~ˆÔà37ˆŒØˆŒØ48ˆÔ!Ø',ˆÔÜ2=³-ˆÖr*   c                ó&   <€ V ^8„  d   QhRS[ RS[ /# ©r"   r‰   r$   r%   )r'   rb   s   "€r(   r)   rc   Š   s   ø€ ÷ oñ o™Sð o¡Sñ or*   c           	     óh   € V P                    T R V9   d   RMR  R\        V P                  RR7       2# )Ú?Ú&z	password=r>   ©Úsafe)re   r   rg   ©rˆ   r‰   s   &&r(   Ú_api_urlÚBlueBubblesAdapter._api_urlŠ   s9   € Ø—/‘/Ð" 4 &°°t´©ÀÐ(EÀYÌuÐUY×UbÑUbÐikÔOlÐNmÐnÐnr*   c                óJ   <€ V ^8„  d   QhRS[ RS[S[P                  ,          /# r;   )r   ÚlistrC   ÚPattern)r'   rb   s   "€r(   r)   rc   Ž   s$   ø€ ÷ 8ñ 8¡sð 8©t±B·J±JÕ/?ñ 8r*   c                ó0   € \        V R\        \        R7      # )zˆCompile group-mention wake words; ``raw`` is a list, a raw env string (JSON list or
comma/newline-separated), or None (Hermes defaults).Úbluebubbles)Ú
log_prefixÚdefaultsÚlogger_)r   ÚDEFAULT_MENTION_PATTERNSÚlogger)r<   s   &r(   r�   Ú,BlueBubblesAdapter._compile_mention_patterns�   s   € ô (¨¸ÔPhÜ06ô8ð 	8r*   c                ó&   <€ V ^8„  d   QhRS[ RS[/# r!   ©r&   r4   )r'   rb   s   "€r(   r)   rc   ”   s   ø€ ÷ ^ñ ^±cð ^¹dñ ^r*   c                óÆ   a€ \        S4      ;'       dO    \        ;QJ d)    V3R  lV P                   4       F  '       g   K   R# 	  R# ! V3R  lV P                   4       4      # )c              3   óD   <"  € T F  qP                  S4      x € K  	  R # 5i©N)Úsearch)Ú.0Úpatternr#   s   & €r(   Ú	<genexpr>ÚGBlueBubblesAdapter._message_matches_mention_patterns.<locals>.<genexpr>•   s   øé € Ð!]ÑF\¸7§.¡.°×"6Ð"6ÓF\ùs   ƒ TF)r4   Úanyr‚   )rˆ   r#   s   &fr(   Ú!_message_matches_mention_patternsÚ4BlueBubblesAdapter._message_matches_mention_patterns”   sD   ø€ Ü�D‹z×]Ð]Ÿc›cÔ!]Àd×F\ÒF\Ó!]ŸcœcÐ]šcÐ]˜cÔ!]Àd×F\ÒF\Ó!]Ó]Ð]r*   c                ó&   <€ V ^8„  d   QhRS[ RS[ /# r!   r%   )r'   rb   s   "€r(   r)   rc   —   s   ø€ ÷ ñ ©ð ±ñ r*   c                óì   € T;'       g    RP                  4       pV P                   FI  pVP                  V4      ;p'       g   K  W$P                  4       R P                  R4      ;'       g    Tu # 	  V# )u   Strip a leading wake word only â€” patterns are regexes, so stripping anywhere later in the
prompt could delete ordinary words.r>   Nz ,:-)Úlstripr‚   rD   Úend)rˆ   r#   Ústrippedr©   rD   s   &&   r(   Ú_clean_mention_textÚ&BlueBubblesAdapter._clean_mention_text—   sj   € ð —J�J˜B×&Ñ&Ó(ˆØ×-Ô-ˆGØŸ™ hÓ/Ð/ˆu×/Ð/Ø§	¡	£ Ð-×4Ñ4°VÓ<×DÐDÀÒDñ .ð ˆr*   c                óB   <€ V ^8„  d   QhRS[ RS[ RS[S[ S[3,          /# )r"   Úmethodr‰   r$   ©r&   rM   r   )r'   rb   s   "€r(   r)   rc       s*   ø€ ÷ ñ ¡cð ±ð Á4ÉÉSÈÅ>ñ r*   c              ‹  óÖ   "  € V P                   f   Q h\        V P                   V4      ! V P                  V4      3/ VB G Rj  x€L
 pVP                  4        VP	                  4       #  L$5i)z_Authenticated request to the BlueBubbles REST API; raises on HTTP errors, returns decoded JSON.N)rƒ   Úgetattrr•   Úraise_for_statusÚjson)rˆ   r·   r‰   ÚkwargsÚress   &&&, r(   Ú	_api_jsonÚBlueBubblesAdapter._api_json    sY   é € à�{‰{Ò&Ð&Ð&Ü˜DŸK™K¨Ô0°·±¸tÓ1DÑOÈÑO×OˆØ×ÑÔØ�x‰x‹zÐñ Pùs   ‚A A)ÁA'Á%A)c                ó<   <€ V ^8„  d   QhRS[ RS[S[ S[3,          /# rŽ   r¸   )r'   rb   s   "€r(   r)   rc   §   s#   ø€ ÷ 1ñ 1¡3ð 1©4±±S°­>ñ 1r*   c              ƒ  óB   "  € V P                  R V4      G Rj  x€L
 #  L5i)ry   N©r¿   r”   s   &&r(   Ú_api_getÚBlueBubblesAdapter._api_get§   s   é € Ø—^‘^ E¨4Ó0×0Ð0Ñ0ùs   ‚˜™c                óX   <€ V ^8„  d   QhRS[ RS[S[ S[3,          RS[S[ S[3,          /# ©r"   r‰   Úpayloadr$   r¸   )r'   rb   s   "€r(   r)   rc   ª   s7   ø€ ÷ @ñ @¡Cð @±$±s¹C°xµ.ð @ÁTÉ#ÉsÈ(Å^ñ @r*   c              ƒ  óD   "  € V P                  R WR7      G Rj  x€L
 #  L5i)Úpost)r¼   NrÃ   )rˆ   r‰   rÈ   s   &&&r(   Ú	_api_postÚBlueBubblesAdapter._api_postª   s   é € Ø—^‘^ F¨D�^Ó?×?Ð?Ñ?ùó   ‚ ™š c                óB   <€ V ^8„  d   QhRS[ RS[S[ S[3,          RS[/# rÇ   )r&   rM   r   r   )r'   rb   s   "€r(   r)   rc   ­   s/   ø€ ÷ Sñ S©ð S±d¹3Á¸8µnð SÉñ Sr*   c              ƒ  ó¢  "  €  V P                  W4      G Rj  x€L
 pVP                  R4      ;'       g    / p\        VP                  R4      ;'       g    VP                  R4      ;'       g    R4      p\        RWSR7      #  Li  \         d>   p\        R\        T4      ;'       g    \        T4      P                  R	7      u Rp?# Rp?ii ; i5i)
z<POST a message payload and wrap the outcome as a SendResult.NÚdataÚguidÚmessageGuidr[   T©ÚsuccessÚ
message_idÚraw_responseF©rÔ   Úerror)rË   ry   r&   r   Ú	ExceptionÚtypeÚ__name__)rˆ   r‰   rÈ   r¾   rÐ   Úmsg_idÚexcs   &&&    r(   Ú_post_messageÚ BlueBubblesAdapter._post_message­   s¥   é € ð	SØŸ™ tÓ5×5ˆCØ—7‘7˜6“?×(Ð( bˆDÜ˜Ÿ™ &Ó)×LÐL¨T¯X©X°mÓ-D×LÐLÈÓMˆFÜ d°vÔPÐPñ 6øô ô 	SÜ e´3°s³8×3QÐ3Q¼tÀC»y×?QÑ?QÔRÕRûð	SüsU   ‚C„B ˜B™B µB ÁB Á.B ÂCÂB ÂCÂ2CÃCÃCÃCÃCc                ó2   <€ V ^8„  d   QhRS[ RS[ RS[ RS[/# )r"   Úchat_idÚactionr·   r$   r£   )r'   rb   s   "€r(   r)   rc   ·   s*   ø€ ÷ 	ñ 	±Cð 	Áð 	Écð 	ÑVZñ 	r*   c           
   ƒ  óØ  "  € V P                   '       d%   V P                  '       d   V P                  '       g   R# \        \        4      ;_uu_ 4        V P                  V4      G Rj  x€L
 ;p'       dT   V P                  R\        VRR7       RV 24      p\        V P                  V4      ! V^R7      G Rj  x€L
   RRR4       R#  RRR4       R#  Lj L  + '       g   i     R# ; i5i)	zMFire a private-API chat action (typing/read); True only if the call was made.FNú/api/v1/chat/r>   r’   rA   )ÚtimeoutT)	r…   r†   rƒ   r   rÙ   Ú_resolve_chat_guidr•   r   rº   )rˆ   rá   râ   r·   rÑ   Úurls   &&&&  r(   Ú_private_api_chat_callÚ)BlueBubblesAdapter._private_api_chat_call·   s¶   é € à×(×(Ð(°×0F×0FÐ0FÈdÏkÏkÈkÙÜ”i× Õ Ø!×4Ñ4°WÓ=×=Ð=ˆtÖ=Ø—m‘m m´E¸$ÀRÔ4HÐ3IÈÈ6È(Ð$SÓT�Ü˜dŸk™k¨6Ô2°3ÀÔB×BÐBØ÷	 !Ñ Ø=÷ !ñ
 ñ	 >áB÷ !Ö ñ
 üsX   ‚$C*§C*¹C*ÁCÁ'CÁ(CÁ4ACÂ7CÂ8CÂ=
C*Ã
C*ÃCÃCÃC'	Ã!	C*Úis_reconnectc                ó&   <€ V ^8„  d   QhRS[ RS[ /# )r"   rê   r$   r3   )r'   rb   s   "€r(   r)   rc   Ä   s   ø€ ÷ *ñ *©Tð *¹dñ *r*   c          	   ƒ  ód  a"  € V P                   '       d   V P                  '       g   \        P                  R 4       R# ^ RIHo ^ RIHp \        P                  ! RV! 4       R7      V n
         V P                  R4      G Rj  x€L
  V P                  R4      G Rj  x€L
 pT;'       g    / P                  R	/ 4      p\        VP                  R
4      4      V n        \        VP                  R4      4      V n        \        P!                  RV P                   V P                  V P                  4       SP'                  \(        R7      pTP*                  P-                  RT3R l4       TP*                  P/                  T P0                  T P2                  4       ^ RIHp T! YT P8                  T P:                  T P0                  RR7      G Rj  x€L
 T n        T P?                  4        T P<                  e7   \        P!                  RT P8                  T P:                  T P0                  4       T PA                  4       G Rj  x€L
  T PC                  R4       R#  ELÑ EL»  \"         dF   p\        P                  RT P                   T4       T P%                  4       G Rj  x€L 
   Rp?R# Rp?ii ; i Lá Lr5i)zJ[bluebubbles] BLUEBUBBLES_SERVER_URL and BLUEBUBBLES_PASSWORD are requiredFrY   )Úplatform_httpx_limitsg      >@)rå   Úlimitsz/api/v1/pingNz/api/v1/server/inforÐ   Úprivate_apiÚhelper_connectedz9[bluebubbles] connected to %s (private_api=%s, helper=%s)z+[bluebubbles] cannot reach server at %s: %s)Úclient_max_sizez/healthc                 ó(   <€ SP                  R R7      # )r[   r/   )r\   )Ú_rZ   s   &€r(   Ú<lambda>Ú,BlueBubblesAdapter.connect.<locals>.<lambda>ß   s   ø€ °·±À$°Ô0Gr*   )Úbind_listener)Ú
access_logz1[bluebubbles] webhook listening on http://%s:%s%sT)"re   rg   r    rØ   r7   rZ   Ú%gateway.platforms._http_client_limitsrí   ÚhttpxÚAsyncClientrƒ   rÄ   ry   r4   r…   r†   ÚinforÙ   Ú_close_clientÚApplicationÚ_WEBHOOK_MAX_BODY_BYTESÚrouterÚadd_getÚadd_postrm   Ú_handle_webhookÚ gateway.platforms.shared_ingressrö   ri   rk   r„   Ú_mark_connectedÚ_register_webhookÚ_wire_plugin_handlers)	rˆ   rê   rí   rû   Úserver_datarÝ   Úapprö   rZ   s	   &$      @r(   ÚconnectÚBlueBubblesAdapter.connectÄ   s  øé € Ø��ˆ d§m§m mÜ�L‰LÐeÔfÙÝõ 	PÜ×'Ò'°Ñ=RÓ=TÔUˆŒð	Ø—-‘- Ó/×/Ð/ØŸ™Ð'<Ó=×=ˆDØŸ:˜: 2×*Ñ*¨6°2Ó6ˆKÜ(,¨[¯_©_¸]Ó-KÓ(LˆDÔ%Ü%)¨+¯/©/Ð:LÓ*MÓ%NˆDÔ"Ü�K‰KÐSØŸ™¨×)BÑ)BÀD×DZÑDZô\ð �o‰oÔ.EˆoÓFˆØ�
‰
×Ñ˜9Ô&GÔHØ�
‰
×Ñ˜D×-Ñ-¨t×/CÑ/CÔDõ 	CÙ*Ø�t×(Ñ(¨$×*;Ñ*;¸T×=NÑ=NÐ[_ôa÷ aˆŒà×ÑÔØ�<‰<Ò#Ü�K‰KÐKÈT×M^ÑM^Ð`d×`qÑ`qØ×)Ñ)ô+à×$Ñ$Ó&×&Ð&à×"Ñ" 4Ô(ÙòA 0Ú=øô ô 	Ü�L‰LÐFÈÏÉÐY\Ô]Ø×$Ñ$Ó&×&Ñ&Ýûð	úñ añ 	'ùsŒ   ƒ$J0¨AJ0Á.I ÂIÂI ÂIÂI Â)BI Ä0BJ0Ç
J,ÇA0J0È;J.È<J0ÉI ÉI ÉJ)É$4J$ÊJÊJ$ÊJ0Ê$J)Ê)J0Ê.J0c                ó   <€ V ^8„  d   QhRR/# ©r"   r$   NrV   )r'   rb   s   "€r(   r)   rc   ð   s   ø€ ÷ ñ  Tñ r*   c              ƒ  óŒ   "  € V P                   '       d,   V P                   P                  4       G R j  x€L
  R V n         R # R #  L5ir¦   )rƒ   Úaclose©rˆ   s   &r(   rü   Ú BlueBubblesAdapter._close_clientð   s3   é € Ø�;�;ˆ;Ø—+‘+×$Ñ$Ó&×&Ð&ØˆDŽKñ Ù&ùs   ‚0A²A³Ac                ó   <€ V ^8„  d   QhRR/# r  rV   )r'   rb   s   "€r(   r)   rc   õ   s   ø€ ÷ "ñ " $ñ "r*   c              ƒ  ó  "  € V P                  4       G R j  x€L
  V P                  4       G R j  x€L
  V P                  '       d*   V P                  P                  4       G R j  x€L
  R V n        V P	                  4        R #  Li LS L!5ir¦   )Ú_unregister_webhookrü   r„   ÚcleanupÚ_mark_disconnectedr  s   &r(   Ú
disconnectÚBlueBubblesAdapter.disconnectõ   sf   é € Ø×&Ñ&Ó(×(Ð(Ø× Ñ Ó"×"Ð"Ø�<�<ˆ<Ø—,‘,×&Ñ&Ó(×(Ð(ØˆDŒLØ×ÑÖ!ñ 	)Ù"á(ùs7   ‚B–B —B®B¯BÁBÁ"BÁ#BÂBÂBc                ó    <€ V ^8„  d   QhRS[ /# r2   r%   )r'   rb   s   "€r(   r)   rc   þ   s   ø€ ÷ Gñ G™cñ Gr*   c                ó²   € \        V RR4      pV'       d   V# V P                  \        9   d   RMV P                  pRV RV P                   V P                   2# )uš   External webhook URL for BlueBubbles registration (local binds â†’ localhost). In
shared-listener mode it is the default listener's ``/p/<profile>/`` URL.Ú_shared_ingress_urlNÚ	localhostr@   Ú:)rº   ri   Ú_LOCAL_HOSTSrk   rm   )rˆ   ÚsharedÚhosts   &  r(   Ú_webhook_urlÚBlueBubblesAdapter._webhook_urlý   sZ   € ô ˜Ð4°dÓ;ˆßØˆMØ"×/Ñ/´<Ô?‰{ÀT×EVÑEVˆØ˜˜˜a × 1Ñ 1Ð2°4×3DÑ3DÐ2EÐFÐFr*   c                ó&   <€ V ^8„  d   QhRS[ RS[ /# )r"   Úpassword_paramr$   r%   )r'   rb   s   "€r(   r)   rc     s   ø€ ÷ hñ h¹ð hÁñ hr*   c                ó`   € V P                   '       d   V P                   R V 2# V P                  # )z
?password=)rg   r   )rˆ   r#  s   &&r(   Ú_webhook_register_url_withÚ-BlueBubblesAdapter._webhook_register_url_with  s/   € ØCGÇ=Ç=À=�$×#Ñ#Ð$ J¨~Ð.>Ð?ÐgÐVZ×VgÑVgÐgr*   c                ó    <€ V ^8„  d   QhRS[ /# r2   r%   )r'   rb   s   "€r(   r)   rc     s   ø€ ÷ Nñ N¡sñ Nr*   c                óN   € V P                  \        V P                  RR7      4      # )zØRegistered webhook URL with the password as a query param: BlueBubbles posts to the exact
registered URL and cannot set custom headers, so this is the only way to authenticate inbound
webhooks without disabling auth.r>   r’   )r%  r   rg   r  s   &r(   Ú_webhook_register_urlÚ(BlueBubblesAdapter._webhook_register_url
  s    € ð
 ×.Ñ.¬u°T·]±]ÈÔ/LÓMÐMr*   c                ó    <€ V ^8„  d   QhRS[ /# r2   r%   )r'   rb   s   "€r(   r)   rc     s   ø€ ÷ 6ñ 6©sñ 6r*   c                ó$   € V P                  R 4      # )z***)r%  r  s   &r(   Ú_webhook_register_url_for_logÚ0BlueBubblesAdapter._webhook_register_url_for_log  s   € à×.Ñ.¨uÓ5Ð5r*   c                ó&   <€ V ^8„  d   QhRS[ RS[/# )r"   rç   r$   )r&   r˜   )r'   rb   s   "€r(   r)   rc     s   ø€ ÷ ñ ±3ð ¹4ñ r*   c              ƒ  óh  "  € \        \        4      ;_uu_ 4        V P                  R4      G Rj  x€L
 P                  R4      p\	        V\
        4      '       d4   V Uu. uF  q3P                  R4      V8X  g   K  VNK  	  upuuRRR4       #  RRR4       . #  Lgu upi   + '       g   i     . # ; i5i)z1Return list of BB webhook entries matching *url*.ú/api/v1/webhookNrÐ   rç   )r   rÙ   rÄ   ry   Ú
isinstancer˜   )rˆ   rç   rÐ   Úwhs   &&  r(   Ú_find_registered_webhooksÚ,BlueBubblesAdapter._find_registered_webhooks  s‰   é € ä”i× Õ ØŸ-™-Ð(9Ó:×:×?Ñ?ÀÓGˆDÜ˜$¤×%Ò%Ù%)ÓB¡T˜r¯V©V°E«]¸cÑ-AŸ˜¡TÑB÷ !Ò à%÷ !ð ˆ	ñ ;ùâB÷ !Ö ð ˆ	üsJ   ‚B2šB¯B°-BÁBÁ9BÁ?BÂB2Â
B2ÂBÂBÂB/	Â)	B2c                ó    <€ V ^8„  d   QhRS[ /# r2   r3   )r'   rb   s   "€r(   r)   rc     s   ø€ ÷ ñ ©ñ r*   c              ƒ  ó<  "  € V P                   '       g   R# V P                  V P                  r!V P                  V4      G Rj  x€L
 '       d   \        P                  RV4       R#  V P                  RRVRRR	./4      G Rj  x€L
 pVP                  R
^ 4      p^ÈTu;8:  d   R8  d   M M\        P                  RV4       R# \        P                  RWCP                  R4      4       R#  L¦ Li  \         d"   p\        P                  RT4        Rp?R# Rp?ii ; i5i)uŠ   Register this webhook URL, reusing an existing registration if present (crash resilience â€”
avoids duplicates after an unclean shutdown).FNz,[bluebubbles] webhook already registered: %sTr1  rç   Úeventsúnew-messageúupdated-messageÚstatusi,  z0[bluebubbles] webhook registered with server: %sz9[bluebubbles] webhook registration returned status %s: %sÚmessagez8[bluebubbles] failed to register webhook with server: %s)
rƒ   r)  r-  r4  r    rû   rË   ry   ÚwarningrÙ   )rˆ   Úwebhook_urlÚlog_urlr¾   r;  rÝ   s   &     r(   r  Ú$BlueBubblesAdapter._register_webhook  sù   é € ð �{�{ˆ{ÙØ#×9Ñ9¸4×;]Ñ;]�WØ×/Ñ/°Ó<×<Ö<Ü�K‰KÐFÈÔPÙð	ØŸ™Ð'8Ø(-¨{¸HÀ}ÐVgÐFhÐ'iók÷ kˆCà—W‘W˜X qÓ)ˆFØ�fÖ"˜s×"Ü—‘ÐNÐPWÔXÙÜ�N‰NÐVÐX^×`gÑ`gÐhqÓ`rÔsÙñ =ñkøô ô 	Ü�N‰NÐUÐWZÔ[Ýûð	üs`   ‚A DÁC)Á	DÁDÁ&C- ÂC+Â>C- Ã DÃ%C- Ã'DÃ+C- Ã-DÃ8DÄDÄDÄDc                ó    <€ V ^8„  d   QhRS[ /# r2   r3   )r'   rb   s   "€r(   r)   rc   3  s   ø€ ÷ ñ ©4ñ r*   c              ƒ  ó  "  € V P                   '       g   R# Rp V P                  V P                  4      G Rj  x€L
  Fc  pVP                  R4      ;p'       g   K  V P                   P	                  V P                  RV 24      4      G Rj  x€L
 P                  4        RpKe  	  V'       d!   \        P                  RV P                  4       V#  L• LD  \         d"   p\        P                  RT4        Rp?T# Rp?ii ; i5i)zIRemove *all* registrations matching our URL (cleans up crash duplicates).FNÚidz/api/v1/webhook/Tz&[bluebubbles] webhook unregistered: %sz=[bluebubbles] failed to unregister webhook (non-critical): %s)rƒ   r4  r)  ry   Údeleter•   r»   r    rû   r-  rÙ   Údebug)rˆ   Úremovedr3  Úwh_idrÝ   s   &    r(   r  Ú&BlueBubblesAdapter._unregister_webhook3  sÝ   é € à�{�{ˆ{ÙØˆð	_Ø ×:Ñ:¸4×;UÑ;UÓV×VÒV�ØŸF™F 4›LÐ(�5×(Ð(ØŸ;™;×-Ñ-¨d¯m©mÐ>NÈuÈgÐ<VÓ.WÓX×X×jÑjÔlØ"’Gñ W÷ Ü—‘ÐDÀd×FhÑFhÔið ˆñ WáXøô ô 	_Ü�L‰LÐXÐZ]×^Ð^Øˆûð	_üs\   ‚DšC ¸C¹C Á0C ÂCÂC Â, C ÃDÃC ÃC ÃC>ÃC9Ã3DÃ9C>Ã>Dc                ó6   <€ V ^8„  d   QhRS[ RS[S[ ,          /# )r"   Útargetr$   )r&   r	   )r'   rb   s   "€r(   r)   rc   E  s   ø€ ÷ ñ ©sð ±xÁµ}ñ r*   c           	   ƒ  óT  "  € T;'       g    RP                  4       pV'       d   RV9   d   T;'       g    R# WP                  9   d/   V P                  P                  V4       V P                  V,          # \        \        4      ;_uu_ 4        V P                  RR^dR^ /4      G Rj  x€L
 pVP                  R. 4      ;'       g    .  F¼  pVP                  R4      ;'       g    VP                  R	4      V8w  d   K4  VP                  R
4      ;'       g    VP                  R4      ;p'       dK   W@P                  V&   \        V P                  4      \        8”  d   V P                  P                  RR7       K<  Vu uuRRR4       # 	  RRR4       R#  Lê  + '       g   i     R# ; i5i)ux  Resolve an email/phone to a chat GUID (raw ``a;-;b`` GUIDs pass through). Matches strictly on
``chatIdentifier`` / ``identifier``; participant membership is intentionally NOT a fallback â€”
the same contact appears in a 1:1 DM and any number of groups, so a participant match could
leak a DM reply into a group thread. ``None`` lets the caller create a fresh DM.

See #24157.
r>   Ú;Nz/api/v1/chat/queryÚlimitÚoffsetrÐ   ÚchatIdentifierÚ
identifierrÑ   ÚchatGuidF)Úlast)
rB   r‡   Úmove_to_endr   rÙ   rË   ry   ÚlenÚ_GUID_CACHE_SIZEÚpopitem)rˆ   rJ  rÈ   ÚchatrÑ   s   &&   r(   ræ   Ú%BlueBubblesAdapter._resolve_chat_guidE  sW  é € ð —,�,˜B×%Ñ%Ó'ˆß˜ œØ—>�>˜TÐ!Ø×%Ñ%Ô%Ø×Ñ×(Ñ(¨Ô0Ø×#Ñ# FÕ+Ð+Ü”i× Õ Ø ŸN™NÐ+?À'È3ÐPXÐZ[ÐA\Ó]×]ˆGØŸ™ F¨BÓ/×5Ð5°2Ò5�Ø—H‘HÐ-Ó.×HÐH°$·(±(¸<Ó2HÈVÔSÙØŸ8™8 FÓ+×CÐC¨t¯x©x¸
Ó/CÐC�4ÖCØ/3×$Ñ$ VÑ,Ü˜d×.Ñ.Ó/Ô2BÔBØ×(Ñ(×0Ñ0°eÐ0Ö<Ø‘÷ !Ò á5÷ !ñ ñ ^÷ !Ö ñ üs_   ‚"F(¥F(µAF(ÂFÂ'FÂ(FÃFÃ#0FÄFÄ.AFÅ;F(ÆFÆ
F(ÆFÆF%	Æ	F(c                ó,   <€ V ^8„  d   QhRS[ RS[ RS[/# )r"   Úaddressr<  r$   )r&   r   )r'   rb   s   "€r(   r)   rc   _  s'   ø€ ÷ hñ h±Sð hÁ3ð hÉ:ñ hr*   c           
   ƒ  ó`   "  € V P                  RRV.RVR\        4       /4      G Rj  x€L
 #  L5i)z<Create a new chat by sending the first message to *address*.z/api/v1/chat/newÚ	addressesr<  ÚtempGuidN)rÞ   rW   )rˆ   rZ  r<  s   &&&r(   Ú_create_chat_for_handleÚ*BlueBubblesAdapter._create_chat_for_handle_  s>   é € à×'Ñ'Ø ¨w¨i¸ÀGÈZÔYcÓYeÐ fóh÷ hð 	hñ hùs   ‚%.§,¨.c                ó<   <€ V ^8„  d   QhRS[ RS[RS[S[ ,          /# )r"   ÚcontentÚ
max_lengthr$   )r&   r|   r˜   )r'   rb   s   "€r(   r)   rc   g  s,   ø€ ÷ uñ u¡#ð u±3ð uÉTÑRUÍYñ ur*   c                ó€   € \         P                  ! W4       Uu. uF  p\        P                  R V4      NK  	  up# u upi )r>   )r   Útruncate_messageÚ_PAGINATION_SUFFIX_REr-   )ra  rb  Úcs   && r(   rd  Ú#BlueBubblesAdapter.truncate_messagef  s9   € ô ;N×:^Ò:^Ð_fÔ:sÓtÑ:s°QÔ%×)Ñ)¨"¨aÖ0Ñ:sÑtÐtùÒts   ™;c                ón   <€ V ^8„  d   QhRS[ RS[ RS[S[ ,          RS[S[S[ S[3,          ,          RS[/# )r"   rá   ra  Úreply_toÚmetadatar$   ©r&   r	   rM   r   r   )r'   rb   s   "€r(   r)   rc   k  sC   ø€ ÷ ñ ¡#ð ±ð ¹xÉ½}ð Ù%¡d©3±¨8¥nÕ5ðÙAKñr*   c              ƒ  óþ  "  € V P                  V4      pV'       g   \        R RR7      # \        P                  ! RV4       Uu. uF*  qfP	                  4       '       g   K  VP	                  4       NK,  	  up;'       g    V.pV UU	u. uFC  p\        V4      V P                  8:  d   V.MV P                  W€P                  4       F  q™NK  	  KE  	  p
pp	\        RR7      pV
 EF  pV P                  V4      G Rj  x€L
 pV'       gb   V P                  '       d>   RV9   g   \        P                  V4      '       d   V P                  W4      G Rj  x€L
 u # \        R RV 2R7      u # R	VR
\        4       RV/pV'       d9   V P                  '       d'   V P                  '       d   VP                  RV^ R7       V P!                  RV4      G Rj  x€L
 ;pP"                  '       d   EK  Vu # 	  V# u upi u up	pi  Lÿ L¬ L05i)FzBlueBubbles send requires textr×   z\n\s*\nT)rÔ   NÚ@z'BlueBubbles chat not found for target: rQ  r]  r<  zprivate-api)r·   ÚselectedMessageGuidÚ	partIndexz/api/v1/message/text)Úformat_messager   rC   ÚsplitrB   rT  ÚMAX_MESSAGE_LENGTHrd  ræ   r…   Ú_ADDRESS_RErD   r^  rW   r†   ÚupdaterÞ   rÔ   )rˆ   rá   ra  ri  rj  r#   ÚpÚ
paragraphsÚpararf  ÚchunksrR  ÚchunkrÑ   rÈ   s   &&&&&          r(   ÚsendÚBlueBubblesAdapter.sendk  sº  é € à×"Ñ" 7Ó+ˆßÜ eÐ3SÔTÐTä)+¯ª°*¸dÔ)CÓQÑ)C AÇwÁwÇy”i�a—g‘g–iÑ)CÑQ×[Ð[ÐVZÐU[ˆ
Ù *ô w¡
˜Ü˜$“i 4×#:Ñ#:Ô:ˆT‰FÀ×@UÑ@UÐVZ×\sÑ\sÓ@tÒtð 01’!Ùtñ ¡
ˆñ wä $Ô'ˆÜˆEØ×0Ñ0°Ó9×9ˆDßØ×,×,Ð,°#¸´.ÄK×DUÑDUÐV]×D^ÒD^Ø!%×!=Ñ!=¸gÓ!M×MÒMÜ!¨%Ð9`ÐahÐ`iÐ7jÔkÒkØ'1°4¸ÄZÃ\ÐS\Ð^cÐ&dˆGß˜D×5×5Ð5¸$×:P×:PÐ:PØ—‘ mÈÐ]^�Ô_Ø"&×"4Ñ"4Ð5KÈWÓ"U×UÐU�D×^×^Ó^Ø’ñ ð ˆùò Rùówñ :ñ Nñ
 Vùs€   ‚A G=ÁG,ÁG,Á2	G=Á<	G=ÂA	G1Ã)G=Ã7G7Ã8G=ÄG=Ä!G=Ä8G=ÅG9ÅAG=ÆG=Æ!)G=Ç
G;ÇG=Ç$G=Ç9G=Ç;G=c                ó^   <€ V ^8„  d   QhRS[ RS[ RS[S[ ,          RS[S[ ,          RS[RS[/# )r"   rá   Ú	file_pathÚfilenameÚcaptionÚis_audio_messager$   )r&   r	   r4   r   )r'   rb   s   "€r(   r)   rc   „  sC   ø€ ÷ ;ñ ;©cð ;¹cð ;ÉXÑVYÍ]ð ;Ù(0±­ð;ÙPTð;Ùakñ;r*   c           	   ƒ  óÐ  "  € V P                   '       g   \        RRR7      # \        P                  ! \        P
                  P                  V4      G Rj  x€L
 '       g   \        RRV 2R7      # V P                  V4      G Rj  x€L
 pV'       g   \        RRV 2R7      # T;'       g     \        P
                  P                  V4      p \        P                  ! \        V4      P                  4      G Rj  x€L
 pRVRVR	\        P                  ! 4       P                  /p	V'       d   R
V	R&   V P                   P                  V P                  R4      V	^xRWxR3/R7      G Rj  x€L
 p
V
P!                  4        V
P#                  4       pV'       d   V P%                  W4      G Rj  x€L
  VP'                  R4      ^È8X  dQ   VP'                  R4      ;'       g    / p\        R\)        V\*        4      '       d   VP'                  R4      MRVR7      # \        RVP'                  RR4      R7      #  EL× EL« EL; LÑ L’  \,         d!   p\        R\/        T4      R7      u Rp?# Rp?ii ; i5i)z8Send a file attachment via BlueBubbles multipart upload.FzNot connectedr×   NzFile not found: zChat not found: rQ  Únamer]  ÚtrueÚisAudioMessagez/api/v1/message/attachmentÚ
attachmentzapplication/octet-stream)rÐ   rå   Úfilesr;  rÐ   TrÑ   rÓ   r<  zAttachment upload failed)rƒ   r   ÚasyncioÚ	to_threadÚosr‰   Úisfileræ   Úbasenamer   Ú
read_bytesÚuuidÚuuid4ÚhexrÊ   r•   r»   r¼   rz  ry   r2  rM   rÙ   r&   )rˆ   rá   r}  r~  r  r€  rÑ   ÚfnamerÈ   rÐ   r¾   ÚresultÚrdataÚes   &&&&&&        r(   Ú_send_attachmentÚ#BlueBubblesAdapter._send_attachment„  s  é € ð �{�{ˆ{Ü e°?ÔCÐCÜ×&Ò&¤r§w¡w§~¡~°yÓA×AÖAÜ eÐ5EÀiÀ[Ð3QÔRÐRØ×,Ñ,¨WÓ5×5ˆßÜ eÐ5EÀgÀYÐ3OÔPÐPØ×7Ð7œBŸG™G×,Ñ,¨YÓ7ˆð	;ô $×-Ò-¬d°9«o×.HÑ.HÓI×IˆGØ$.°°f¸eÀZÔQU×Q[ÒQ[ÓQ]×QaÑQaÐ#bˆDßØ)/�Ð%Ñ&ØŸ™×(Ñ(¨¯©Ð7SÓ)TÐ[_ÐilØ0<¸uÐOiÐ>jÐ/kð )ó m÷ mˆCà× Ñ Ô"Ø—X‘X“ZˆFßØ—i‘i Ó1×1Ð1Ø�z‰z˜(Ó# sÔ*ØŸ
™
 6Ó*×0Ð0¨b�Ü!¨$ÔPZÐ[`Ôbf×PgÒPg¸5¿9¹9ÀVÔ;LÐmqØ/5ô7ð 7ä e°6·:±:¸iÐIcÓ3dÔeÐeò/ Bâ5ò Jñmñ
 2øô ô 	;Ü e´3°q³6Ô:Õ:ûð	;üsº   ‚AI&ÁH+Á	I&Á$I&ÂH.ÂI&ÂI&Â) I&Ã
,H8 Ã6H1Ã70H8 Ä(:H8 Å"H4Å#+H8 ÆH8 Æ#H6Æ$1H8 Ç7H8 ÈI&ÈH8 È*I&È.I&È1H8 È4H8 È6H8 È8I#ÉIÉI#ÉI&ÉI#É#I&c                ó„   <€ V ^8„  d   QhRS[ RS[ RS[S[ ,          RS[S[ ,          RS[S[S[ S[3,          ,          RS[/# )r"   rá   Ú	image_urlr  ri  rj  r$   rk  )r'   rb   s   "€r(   r)   rc   ¤  sZ   ø€ ÷ Sñ S©ð S¹ð SÁhÉsÅmð SÙ#+©C¥=ðSÙCKÉDÑQTÑVYÐQYÍNÕC[ðSÙgqñSr*   c              ƒ  óÈ   <"  €  ^ RI Hp T P                  Y! V4      G Rj  x€L
 VR7      G Rj  x€L
 #  L L  \         d    \        ST `  YY44      G Rj  x€L 
 u # i ; i5i)r6   )Úcache_image_from_urlN©r  )Úgateway.platforms.baser™  r”  rÙ   rt   Ú
send_image)rˆ   rá   r—  r  ri  rj  r™  r‹   s   &&&&&& €r(   rœ  ÚBlueBubblesAdapter.send_image¤  sc   øé € ð	SÝCØ×.Ñ.¨wÐ>RÐS\Ó>]×8]ÐgnÐ.Óo×oÐoÑ8]ÑoøÜô 	SÜ™Ñ+¨GÀÓR×RÐRÒRð	SüsI   ƒA"…8 ¡4
¢8 ¯6°8 ³A"´8 ¶8 ¸AÁAÁAÁA"ÁAÁA"c                ó    <€ V ^8„  d   QhRS[ /# r2   ©r   )r'   rb   s   "€r(   r)   rc   ¬  s   ø€ ÷ Qñ QÑ_iñ Qr*   c              ‹  óD   "  € V P                  WVR 7      G Rj  x€L
 #  L5i©rš  N©r”  )rˆ   rá   Ú
image_pathr  ri  Úkws   &&&&&,r(   Úsend_image_fileÚ"BlueBubblesAdapter.send_image_file¬  ó!   é € Ø×*Ñ*¨7ÈÐ*ÓP×PÐPÑPùrÍ   c                ó    <€ V ^8„  d   QhRS[ /# r2   rŸ  )r'   rb   s   "€r(   r)   rc   ¯  s   ø€ ÷ hñ hÑZdñ hr*   c              ‹  óF   "  € V P                  WVR R7      G Rj  x€L
 #  L5i)T)r  r€  Nr¢  )rˆ   rá   Ú
audio_pathr  ri  r¤  s   &&&&&,r(   Ú
send_voiceÚBlueBubblesAdapter.send_voice¯  s$   é € Ø×*Ñ*¨7ÈÐbfÐ*Óg×gÐgÑgùs   ‚!š›!c                ó    <€ V ^8„  d   QhRS[ /# r2   rŸ  )r'   rb   s   "€r(   r)   rc   ²  s   ø€ ÷ Qñ QÑZdñ Qr*   c              ‹  óD   "  € V P                  WVR 7      G Rj  x€L
 #  L5ir¡  r¢  )rˆ   rá   Ú
video_pathr  ri  r¤  s   &&&&&,r(   Ú
send_videoÚBlueBubblesAdapter.send_video²  r§  rÍ   c                ó    <€ V ^8„  d   QhRS[ /# r2   rŸ  )r'   rb   s   "€r(   r)   rc   µ  s   ø€ ÷ dñ dÑlvñ dr*   c              ‹  óD   "  € V P                  WWCR 7      G Rj  x€L
 #  L5i))r~  r  Nr¢  )rˆ   rá   r}  r  Ú	file_nameri  r¤  s   &&&&&&,r(   Úsend_documentÚ BlueBubblesAdapter.send_documentµ  s!   é € Ø×*Ñ*¨7È	Ð*Óc×cÐcÑcùrÍ   c                ó    <€ V ^8„  d   QhRS[ /# r2   rŸ  )r'   rb   s   "€r(   r)   rc   ¸  s   ø€ ÷ Zñ ZÑjtñ Zr*   c              ƒ  óD   "  € V P                  WW4V4      G R j  x€L
 #  L5ir¦   )rœ  )rˆ   rá   Úanimation_urlr  ri  rj  s   &&&&&&r(   Úsend_animationÚ!BlueBubblesAdapter.send_animation¸  s   é € Ø—_‘_ W¸WÐPXÓY×YÐYÑYùrÍ   c                ó$   <€ V ^8„  d   QhRS[ RR/# ©r"   rá   r$   Nr%   )r'   rb   s   "€r(   r)   rc   ½  s   ø€ ÷ Eñ E©ð EÀñ Er*   c              ƒ  óH   "  € V P                  VR R4      G Rj  x€L
  R#  L5i)ÚtypingrÊ   N©rè   )rˆ   rá   rj  s   &&&r(   Úsend_typingÚBlueBubblesAdapter.send_typing½  s   é € Ø×)Ñ)¨'°8¸VÓD×DÔDùó   ‚"™ š"c                ó$   <€ V ^8„  d   QhRS[ RR/# r½  r%   )r'   rb   s   "€r(   r)   rc   À  s   ø€ ÷ Gñ G©ð G°ñ Gr*   c              ƒ  óH   "  € V P                  VR R4      G Rj  x€L
  R#  L5i)r¿  rD  NrÀ  ©rˆ   rá   s   &&r(   Ústop_typingÚBlueBubblesAdapter.stop_typingÀ  s   é € Ø×)Ñ)¨'°8¸XÓF×FÔFùrÃ  c                ó&   <€ V ^8„  d   QhRS[ RS[/# ©r"   rá   r$   r£   )r'   rb   s   "€r(   r)   rc   Ã  s   ø€ ÷ Jñ J¡sð J©tñ Jr*   c              ƒ  óD   "  € V P                  VR R4      G Rj  x€L
 #  L5i)ÚreadrÊ   NrÀ  rÆ  s   &&r(   Ú	mark_readÚBlueBubblesAdapter.mark_readÃ  s    é € Ø×0Ñ0°¸&À&ÓI×IÐIÑIùrÍ   c                ó<   <€ V ^8„  d   QhRS[ RS[S[ S[3,          /# rÊ  r¸   )r'   rb   s   "€r(   r)   rc   È  s#   ø€ ÷ ñ ©3ð ±4¹¹S¸µ>ñ r*   c           
   ƒ  óÒ  "  € R T;'       g    R9   pRTRV'       d   RMR/p\        \        4      ;_uu_ 4        V P                  V4      G Rj  x€L
 ;p'       dæ   V P                  R\	        VRR7       R	24      G Rj  x€L
 pT;'       g    / P                  R
/ 4      pVP                  R4      ;'       g    VP                  R4      ;'       g    TVR&   VP                  R. 4      ;'       g    .  Uu. uF8  pVP                  R4      ;'       g    RP                  4       ;p'       g   K6  VNK:  	  p	pV	'       d   W“R&   RRR4       V#  Lû LÍu upi   + '       g   i     T# ; i5i)ú;+;r>   r‚  rÚ   ÚgroupÚdmNrä   r’   z?with=participantsrÐ   ÚdisplayNamerO  ÚparticipantsrZ  )r   rÙ   ræ   rÄ   r   ry   rB   )
rˆ   rá   Úis_grouprû   rÑ   r¾   rÐ   ru  ÚaddrrÕ  s
   &&        r(   Úget_chat_infoÚ BlueBubblesAdapter.get_chat_infoÈ  sB  é € Ø˜WŸ]˜]¨Ñ+ˆØ &¨°ÇH¹ÐRVÐWˆÜ”i× Õ Ø!×4Ñ4°WÓ=×=Ð=ˆtÖ=Ø ŸM™M¨M¼%ÀÈ2Ô:NÐ9OÐOaÐ*bÓc×c�ØŸ	˜	˜r—‘ v¨rÓ2�Ø#Ÿx™x¨Ó6×_Ð_¸$¿(¹(ÐCSÓ:T×_Ð_ÐX_��V‘Ø.2¯h©h°~ÀrÓ.J×.PÐ.PÈbÐ.Pó  OÑ.P¨Ø-.¯U©U°9Ó-=×-CÐ-CÀ×,JÑ,JÓ,LÐ$L DÓ$L÷ !% Ñ.P�ð  OçØ+7˜Ñ(÷ !ð ˆñ >Ùcùò O÷ !Ö ð ˆüs�   ‚E'�E'¹EÁE
ÁEÁ#EÁ>EÁ?EÂ*EÂ7EÃEÃ/EÃ4EÄEÄ,EÄ2EÅ 
E'Å
EÅEÅEÅE$	Å	E'c                ó&   <€ V ^8„  d   QhRS[ RS[ /# )r"   ra  r$   r%   )r'   rb   s   "€r(   r)   rc   Ö  s   ø€ ÷ ?ñ ?¡cð ?©cñ ?r*   c                ó   € \        VR R7      # )T)Úkeep_link_targets)r   )rˆ   ra  s   &&r(   rp  Ú!BlueBubblesAdapter.format_messageÖ  s   € Ü˜g¸Ô>Ð>r*   c                óR   <€ V ^8„  d   QhRS[ RS[S[ S[3,          RS[S[ ,          /# )r"   Úatt_guidÚatt_metar$   )r&   rM   r   r	   )r'   rb   s   "€r(   r)   rc   Û  s1   ø€ ÷ ñ ±3ð Á$ÁsÉCÀxÅ.ð ÑU]Ñ^aÕUbñ r*   c           
   ƒ  óZ  "  € V P                   '       g   R#  V P                   P                  V P                  R\        VRR7       R24      ^<RR7      G Rj  x€L
 pVP	                  4        VP
                  pVP                  R4      ;'       g    RP                  4       pVP                  R	4      '       d$   \        V\        V\        R
4      4      G Rj  x€L
 # VP                  R4      '       d$   \        V\        V\        R4      4      G Rj  x€L
 # \        YBP                  RR4      ;'       g*    R\        P                  ! 4       P                   R,           24      G Rj  x€L
 #  EL L• L] L  \"         d,   p\$        P'                  R\)        T4      T4        Rp?R# Rp?ii ; i5i)zKDownload an attachment and cache it locally; local path or None on failure.Nz/api/v1/attachment/r>   r’   z	/downloadT)rå   Úfollow_redirectsÚmimeTypeúimage/r   úaudio/r   ÚtransferNameÚfile_:Né   Nz2[bluebubbles] failed to download attachment %s: %s)rƒ   ry   r•   r   r»   ra  r€   r   r   rQ   Ú _BLUEBUBBLES_IMAGE_EXT_OVERRIDESr   Ú _BLUEBUBBLES_AUDIO_EXT_OVERRIDESr   r�  rŽ  r�  rÙ   r    r=  r0   )rˆ   rß  rà  ÚresprÐ   rJ   rÝ   s   &&&    r(   Ú_download_attachmentÚ'BlueBubblesAdapter._download_attachmentÛ  s{  é € à�{�{ˆ{Ùð	ØŸ™Ÿ™¨¯©Ð9LÌUÐS[ÐbdÔMeÐLfÐfoÐ7pÓ)qØ13Àdð )ó L÷ LˆDà×!Ñ!Ô#Ø—<‘<ˆDØ—L‘L Ó,×2Ð2°×9Ñ9Ó;ˆDØ�‰˜x×(Ò(Ü9¸$ÄÈDÔRrÐtzÓ@{Ó|×|Ð|Ø�‰˜x×(Ò(Ü9¸$ÄÈDÔRrÐtzÓ@{Ó|×|Ð|ä8¸¿|¹|ÈNÐ\^Ó?_÷  @Bð  @BÐejÔko×kuÒkuÓkw×k{Ñk{Ð|~Õkð  kAð  dBó  C÷  Cð  CòLñ }á|ñ CøÜô 	Ü�N‰NÐOÔQXÐYaÓQbÐdgÔhÝûð	üs¦   ‚F+˜?E2 ÁE)Á7E2 Â'E2 Â8E2 ÃE,ÃE2 ÃF+ÃE2 Ã2E2 ÄE.ÄE2 ÄF+ÄE2 Ä31E2 Å$E0Å%E2 Å(F+Å)E2 Å,E2 Å.E2 Å0E2 Å2F(Å= F#ÆF+Æ#F(Æ(F+c                ób   <€ V ^8„  d   QhRS[ S[S[3,          RS[S[ S[S[3,          ,          /# )r"   rÈ   r$   )rM   r&   r   r	   )r'   rb   s   "€r(   r)   rc   ñ  s3   ø€ ÷ >ñ >©t±C¹°H­~ð >Á(É4ÑPSÑUXÐPXÍ>ÕBZñ >r*   c                óZ  € VP                  R 4      p\        V\        4      '       d   V# \        V\        4      '       d   \	        R V 4       R4      ;p'       d   V# \        VP                  R4      \        4      '       d   VP                  R4      # \        V\        4      '       d   V# R# )rÐ   c              3   óV   "  € T F  p\        V\        4      '       g   K  Vx € K!  	  R # 5ir¦   )r2  rM   )r¨   Úis   & r(   rª   Ú=BlueBubblesAdapter._extract_payload_record.<locals>.<genexpr>õ  s   é € Ð5]Á¸AÌÐTUÔW[×I\·a²aÃùs   ‚)Ÿ
)Nr<  )ry   r2  rM   r˜   Únext)rˆ   rÈ   rÐ   Úfirsts   &&  r(   Ú_extract_payload_recordÚ*BlueBubblesAdapter._extract_payload_recordñ  sˆ   € Ø�{‰{˜6Ó"ˆÜ�dœD×!Ò!ØˆKÜ�dœD×!Ò!´Ñ5]ÁÓ5]Ð_cÓ0dÐ'd uÖ'dØˆLÜ�g—k‘k )Ó,¬d×3Ò3Ø—;‘;˜yÓ)Ð)Ü$ W¬d×3Ò3ˆwÐ=¸Ð=r*   c                ó6   <€ V ^8„  d   QhRS[ RS[S[,          /# )r"   Ú
candidatesr$   )r   r	   r&   )r'   rb   s   "€r(   r)   rc   ü  s#   ø€ ÷ _ñ _™Cð _¡H©S¥Mñ _r*   c                 ó(   € \        R  V  4       R4      # )c              3   ó¢   "  € T FE  p\        V\        4      '       g   K  VP                  4       '       g   K3  VP                  4       x € KG  	  R # 5ir¦   )r2  r&   rB   )r¨   rf  s   & r(   rª   Ú,BlueBubblesAdapter._value.<locals>.<genexpr>ý  s-   é € ÐW©
 1´jÀÄC×6H”YÈQÏWÉWÏY”Y�Q—W‘W—Y�Y«
ùs   ‚AŸA·AN)ró  )rø  s   *r(   Ú_valueÚBlueBubblesAdapter._valueû  s   € äÑW©
ÓWÐY]Ó^Ð^r*   c                ó&   <€ V ^8„  d   QhRS[ RS[/# r;   )Úbytesr   )r'   rb   s   "€r(   r)   rc      s   ø€ ÷ Bñ B¡ð B©3ñ Br*   c                ó|  € V P                  RRR7      p \        P                  ! V4      #   \         d†    \	        T4      pTP                  R4      ;'       g6    TP                  R4      ;'       g    TP                  R4      ;'       g    R.^ ,          pT'       d   \        P                  ! T4      u # / u # i ; i)zADecode a webhook body: JSON, else form-encoded with a JSON field.zutf-8Úreplace)ÚerrorsrÈ   rÐ   r<  r>   )Údecoder¼   ÚloadsrÙ   r
   ry   )r<   ÚbodyÚformÚpayload_strs   &   r(   Ú_parse_webhook_bodyÚ&BlueBubblesAdapter._parse_webhook_bodyÿ  s�   € ð �z‰z˜'¨)ˆzÓ4ˆð	BÜ—:’:˜dÓ#Ð#øÜô 	BÜ˜D“>ˆDØŸ8™8 IÓ.×aÐa°$·(±(¸6Ó2B×aÐaÀdÇhÁhÈyÓFY×aÐaÐ^`Ð]aÐcdÕeˆKß.9”4—:’:˜kÓ*ÒA¸rÒAð	Bús-   •+ «-B;ÁB;Á2B;ÂB;ÂB;Â6B;Â:B;c                ó6   <€ V ^8„  d   QhRS[ S[S[3,          /# )r"   Úrecord©rM   r&   r   )r'   rb   s   "€r(   r)   rc   
  s   ø€ ÷ 1ñ 1±±c¹3°hµñ 1r*   c              ƒ  óÂ  "  € . p. p\         P                  pVP                  R4      ;'       g    .  EFG  pVP                  RR4      pV'       d   V P                  We4      G Rj  x€L
 MRpV'       g   KC  VP                  R4      ;'       g    RP	                  4       pVP                  V4       VP                  V4       VP                  R4      ;'       g+    VP                  R4      ;'       g    RP                  R4      p	VP                  R	4      '       d   \         P                  MNV	'       d   \         P                  M6VP                  R
4      '       d   \         P                  M\         P                  pEKJ  	  \        V4      ^8”  dK   \        ;QJ d    R V 4       F  '       g   K   RM	  RM! R V 4       4      '       d   \         P                  pW#V3#  ELx5i)zJDownload inbound attachments; returns (media_urls, media_types, msg_type).ÚattachmentsrÑ   r>   Nrã  rå  ÚutiÚcafrä  zvideo/c              3   óV   "  € T F  qP                  R 4      ^ ,          R8H  x € K!  	  R# 5i)rA   ÚimageN)rq  )r¨   Úms   & r(   rª   Ú:BlueBubblesAdapter._collect_attachments.<locals>.<genexpr>  s   é € Ð&WÉ;Àa§w¡w¨s£|°A¥¸'Ö'AË;ùs   ‚')TF)r   ÚTEXTry   rì  r€   Úappendr   ÚendswithÚPHOTOÚVOICEÚVIDEOÚDOCUMENTrT  r¬   )
rˆ   r  Ú
media_urlsÚmedia_typesÚmsg_typeÚattrß  ÚcachedrJ   Úis_voices
   &&        r(   Ú_collect_attachmentsÚ'BlueBubblesAdapter._collect_attachments
  sg  é € à "ˆ
Ø!#ˆÜ×#Ñ#ˆØ—:‘:˜mÓ,×2Ð2°Ó2ˆCØ—w‘w˜v rÓ*ˆHßGO˜4×4Ñ4°XÓC×CÐCÐUYˆFßÙØ—G‘G˜JÓ'×-Ð-¨2×4Ñ4Ó6ˆDØ×Ñ˜fÔ%Ø×Ñ˜tÔ$Ø—‘ xÓ0×ZÐZ°S·W±W¸U³^×5IÐ5IÀr×4SÑ4SÐTYÓ4ZˆHØ-1¯_©_¸X×-FÒ-Fœ×)Ò)×aiÌK×L]ÒL]Ø26·/±/À(×2KÒ2Kœ[×.Ò.ÔQ\×QeÑQeó ñ 3ô ˆz‹?˜QÔ§3£3Ñ&WÉ;Ó&W§3§3¢3Ñ&WÉ;Ó&W×#WÒ#WÜ"×(Ñ(ˆHØ¨Ð0Ð0ò DùsO   ‚A"GÁ$GÁ%GÁ3GÂA
GÃGÃ1(GÄGÄ2&GÅ?GÆGÆ-GÇGc                ó0   <€ V ^8„  d   QhRS[ S[,          /# r2   )r	   r&   )r'   rb   s   "€r(   r)   rc     s   ø€ ÷ _ñ _©±#­ñ _r*   c                óP  € VP                   P                  R 4      ;'       g…    VP                   P                  R4      ;'       gb    VP                  P                  R4      ;'       g?    VP                  P                  R4      ;'       g    VP                  P                  R4      # )rg   rÑ   z
x-passwordzx-guidzx-bluebubbles-guid)Úqueryry   Úheaders)rˆ   Úrequests   &&r(   Ú_webhook_tokenÚ!BlueBubblesAdapter._webhook_token  s’   € Ø—‘×!Ñ! *Ó-÷ ^ð ^°·±×1BÑ1BÀ6Ó1J÷ ^ð ^ÈgÏoÉo×NaÑNaÐbnÓNo÷ ^ð ^Ø—?‘?×&Ñ& xÓ0÷^ð ^Ø4;·O±O×4GÑ4GÐH\Ó4]ð	_r*   c                óR   <€ V ^8„  d   QhRS[ S[S[3,          RS[ S[S[3,          /# )r"   rÈ   r  r  )r'   rb   s   "€r(   r)   rc   "  s,   ø€ ÷ 2ñ 2±±S¹#°Xµð 2ÉÉSÑRUÈXÍñ 2r*   c           	     ó¸  € V P                  VP                  R4      VP                  R4      VP                  R4      VP                  R4      VP                  R4      4      pVP                  R4      ;'       g    . pV'       g^   V'       dV   \        V^ ,          \        4      '       d9   V^ ,          P                  R4      ;'       g    V^ ,          P                  R4      pV P                  VP                  R4      VP                  R4      VP                  R4      VP                  R4      4      pVP                  R4      pT P                  \        V\        4      '       d   VP                  R4      MR	VP                  R
4      VP                  R4      VP                  R4      4      ;'       g    T;'       g    TpV'       g   V'       g   V'       d   TpW5V3# )zZReturns ``(chat_guid, chat_identifier, sender)`` from the many BlueBubbles payload shapes.rQ  Ú	chat_guidrÑ   ÚchatsrO  rP  ÚhandlerZ  NÚsenderÚfrom)rü  ry   r2  rM   )rˆ   rÈ   r  r-  Ú_chatsÚchat_identifierr/  r0  s   &&&     r(   Ú_resolve_chat_and_senderÚ+BlueBubblesAdapter._resolve_chat_and_sender"  su  € à—K‘K §
¡
¨:Ó 6¸¿¹ÀJÓ8OÐQW×Q[ÑQ[Ð\gÓQhØ '§¡¨KÓ 8¸'¿+¹+ÀfÓ:MóOˆ	ð —‘˜GÓ$×*Ð*¨ˆßŸV¬
°6¸!µ9¼d×(CÒ(CØ˜q�	Ÿ™ fÓ-×JÐJ°¸µ·±¸zÓ1JˆIØŸ+™+ f§j¡jÐ1AÓ&BÀFÇJÁJÈ|ÓD\Ø&-§k¡kÐ2BÓ&CÀWÇ[Á[ÐQ]ÓE^ó`ˆà—‘˜HÓ%ˆØ—+‘+´zÀ&Ì$×7OÒ7O˜fŸj™j¨Ô3ÐUYÐ[a×[eÑ[eÐfnÓ[oØ$Ÿj™j¨Ó0°&·*±*¸YÓ2GóI÷ ið iØL[÷ið iØ_hð 	çŸ_·&Ø$ˆOØ¨6Ð1Ð1r*   c              ƒ  óÄ  "  € ^ RI Hp V P                  V4      V P                  8w  d   VP	                  RR/RR7      #  T P                  VP                  4       G Rj  x€L
 4      pT P                  TP                  R
4      TP                  R4      4      ;'       g    RpT'       d   T\        9  d   \        4       # T P                  T4      ;'       g    / pTP                  R4      '       g/   TP                  R4      '       g   TP                  R4      '       d   \        4       # TP                  R4      p\        T\         4      '       d   T\"        9   d   \        4       # T P                  TP                  R4      TP                  R4      TP                  R4      4      ;'       g    RpT P%                  Y64      w  ršpT	;'       g    T
p\'        TP                  R4      4      ;'       g    RT	;'       g    R9   pT'       dZ   T P(                  '       dH   T P+                  T4      '       g    \        P-                  R4       \        4       # T P/                  T4      pT P1                  T4      G Rj  x€L
 w  rïpT'       g   T'       d   RpT'       d   T	'       g	   T
'       d	   T'       g   TP	                  RR/R	R7      # T P3                  YÊ;'       g    TT'       d   RMRY»T
R7      p\5        TTTTT P                  TP                  R4      TP                  R4      TP                  R4      4      T P                  TP                  R4      TP                  R 4      4      YïR!7      p\6        P8                  ! T P;                  T4      4      pT P<                  P?                  T4       TPA                  T P<                  PB                  4       T PD                  '       d.   T'       d&   \6        P8                  ! T PG                  T4      4       \        4       #  ELº  \         d6   p\        P                  RT4       TP	                  RR/R	R7      u Rp?# Rp?ii ; i ELê5i)"r6   rY   rØ   Úunauthorizedi‘  )r;  Nz%[bluebubbles] webhook parse error: %szinvalid payloadi�  rÚ   Úeventr>   ÚisFromMeÚfromMeÚ
is_from_meÚassociatedMessageTyper#   r<  r  ÚisGrouprÑ  zW[bluebubbles] ignoring group message (require_mention=true, no mention pattern matched)z(attachment)zmissing message fieldsrÒ  rÓ  )rá   Ú	chat_nameÚ	chat_typeÚuser_idÚ	user_nameÚchat_id_altrÑ   rÒ   rC  ÚthreadOriginatorGuidÚassociatedMessageGuid)r#   Úmessage_typeÚsourceÚraw_messagerÕ   Úreply_to_message_idr  r  )$r7   rZ   r)  rg   Újson_responser  rÌ  rÙ   r    rØ   rü  ry   Ú_MESSAGE_EVENTSr]   rõ  r2  r|   Ú_TAPBACK_CODESr4  r4   rp   r­   rE  r´   r"  Úbuild_sourcer   r‡  Úcreate_taskÚhandle_messageÚ_background_tasksÚaddÚadd_done_callbackÚdiscardro   rÍ  )rˆ   r(  rZ   rÈ   rÝ   Ú
event_typer  Ú
assoc_typer#   r-  r3  r0  Úsession_chat_idrÖ  r  r  r  rF  r8  Útasks   &&                  r(   r  Ú"BlueBubblesAdapter._handle_webhook3  sq  é € Ýà×Ñ˜wÓ'¨4¯=©=Ô8Ø×$Ñ$ g¨~Ð%>ÀsÐ$ÓKÐKð	OØ×.Ñ.°W·\±\³^×/CÓDˆGð —[‘[ §¡¨VÓ!4°g·k±kÀ'Ó6JÓK×QÐQÈrˆ
ß˜*¬OÔ;Ü“5ˆLØ×-Ñ-¨gÓ6×<Ð<¸"ˆØ�:‰:�j×!Ò! V§Z¡Z°×%9Ò%9¸V¿Z¹ZÈ×=UÒ=UÜ“5ˆLØ—Z‘ZÐ 7Ó8ˆ
Ü�j¤#×&Ò&¨:¼Ô+GÜ“5ˆLØ�{‰{˜6Ÿ:™: fÓ-¨v¯z©z¸)Ó/DÀfÇjÁjÐQWÓFXÓY×_Ð_Ð]_ˆØ-1×-JÑ-JÈ7Ó-[Ñ*ˆ	 FØ#×6Ð6 ˆÜ˜Ÿ
™
 9Ó-Ó.×NÐN°5¸Y¿_¸_È"Ñ3Mˆ÷ ˜×,×,Ð,Ø×9Ñ9¸$×?Ò?Ü—‘ÐvÔwÜ“u�Ø×+Ñ+¨DÓ1ˆDØ26×2KÑ2KÈFÓ2S×,SÑ)ˆ
 ßŸ
Ø!ˆDßŸi¯?Ç4Ø×$Ñ$ gÐ/GÐ%HÐQTÐ$ÓUÐUØ×"Ñ"¨?×F_ÐF_ÐY_ß8@©WÀdÐTZØ/>ð #ó @ˆô Ø H°VÈØ—{‘{ 6§:¡:¨fÓ#5°v·z±zÀ-Ó7PÐRX×R\ÑR\Ð]aÓRbÓcØ $§¡¨F¯J©JÐ7MÓ,NÐPV×PZÑPZÐ[rÓPsÓ tØ!ô	<ˆô
 ×"Ò" 4×#6Ñ#6°uÓ#=Ó>ˆØ×Ñ×"Ñ" 4Ô(Ø×Ñ˜t×5Ñ5×=Ñ=Ô>Ø×"×"Ð"§Ü×Ò §¡¨Ó ?Ô@Ü‹uˆòU 0DøÜô 	OÜ�L‰LÐ@À#ÔFØ×$Ñ$ gÐ/@Ð%AÈ#Ð$ÓNÕNûð	Oúò. -TùsÓ   ‚<Q ¿P ÁPÁP Á&6Q Â
Q Â(,Q ÃQ Ã/Q ÄQ ÄBQ Æ*Q Ç
#Q Ç.
Q Ç9Q ÈQ ÈQ È/AQ É3QÉ4Q Ê	Q ÊQ ÊQ Ê%Q Ê-(Q Ë	Q Ë DQ Ï(/Q ÐP ÐQÐ%*QÑQÑQ ÑQÑQ c                ó&   <€ V ^8„  d   Qh/ S[ ;R&   # )r"   Úserves_profile_prefixr3   )r'   rb   s   "€r(   r)   rc   j   s   ø‡ ‚ áÑ&ò r*   )r‡   r†   r‚   r…   r„   rƒ   rg   rp   ro   re   ri   rm   rk   )NN)NNF)NNNr¦   )>rÛ   Ú
__module__Ú__qualname__Ú__firstlineno__rY  r   rv   ÚplatformÚSUPPORTS_MESSAGE_EDITINGÚMAX_TEXT_LENGTHrr  Úsplits_long_messagesru   r•   Ústaticmethodr�   r­   r´   r¿   rÄ   rË   rÞ   rè   r	  rü   r  Úpropertyr   r%  r)  r-  r4  r  r  ræ   r^  rd  rz  r”  rœ  r¥  r«  r°  rµ  rº  rÁ  rÇ  rÍ  rØ  rp  rì  rõ  rü  r  r"  r)  r4  r  Ú__annotate_func__Ú__static_attributes__Ú__classdictcell__Ú__classcell__)r‹   rb   s   @@r(   r_   r_   j   sg  ù‡ € à"&ÐØ×#Ñ#€HØ$ÐØ(ÐØÐ÷@ó @÷0oð oð ÷8ó ð8÷^ð ^÷ð ÷ð ÷1ð 1÷@ð @÷Sð S÷	ð 	ð*°E÷ *ò *÷Xð ÷
"ð "ð ÷Gó ðG÷hð hð ÷Nó ðNð ÷6ó ð6÷ð ÷ð ÷,ð ÷$ð ÷4hð hð Ø9H÷ uñ uó ðu÷ò ÷2;ò ;÷@Sõ S÷Qò Q÷hò h÷Qò Q÷dò d÷Zò Z÷
Eò E÷Gð G÷Jð J÷
ð ÷?ð ?÷
ð ÷,>ð >ð ÷_ó ð_ð ÷Bó ðB÷1ð 1÷(_ð _÷2ð 2ò"0÷S … r*   r_   z`BlueBubbles: aiohttp/httpx missing or BLUEBUBBLES_SERVER_URL/BLUEBUBBLES_PASSWORD not configuredc                ó$   € V ^8„  d   QhR\         /# r2   r3   )r'   s   "r(   r)   r)   k  s   € ÷ yñ yœTñ yr*   c                ó  a€ \        V RR4      ;'       g    / pVP                  R4      '       d   VP                  R4      '       d   R# ^ RIHo \        ;QJ d    V3R lR 4       F  '       d   K   R# 	  R# ! V3R lR 4       4      # )	z^Server URL + password present in ``PlatformConfig.extra`` (the env table seeds it) or the env.rw   Nre   rg   Tc              3   óv   <"  € T F.  pSP                  V4      ;'       g    R P                  4       x € K0  	  R# 5i)r>   N)Úget_env_valuerB   )r¨   ÚnÚgateway_mods   & €r(   rª   Ú _is_connected.<locals>.<genexpr>q  s2   øé € ÐxÑEwÀ�×)Ñ)¨!Ó,×2Ð2°×9Ñ9×;Ð;ÓEwùs   ƒ9 9F)rf   rh   )rº   ry   Úhermes_cli.gatewayÚgatewayÚall)ra   rw   rl  s   & @r(   Ú_is_connectedrq  k  sg   ø€ ä�F˜G TÓ*×0Ð0¨b€EØ‡y�y�×Ò 5§9¡9¨Z×#8Ò#8ÙÝ,ß‹3ÔxÑEwÓx�3Œ3ÐxŠ3Ðxˆ3ÔxÑEwÓxÓxÐxr*   Ú	thread_idÚmedia_filesÚforce_documentFc                ó®   € V ^8„  d   QhR\         R\         R\        \         ,          R\        \        ,          R\        R\        \         \
        3,          /# )r"   rá   r<  rr  rs  rt  r$   )r&   r	   r˜   r4   rM   r   )r'   s   "r(   r)   r)   t  sN   € ÷ ;ñ ;¬Sð ;¼3ð ;ÌhÔWZÍmð ;Ü(0´­ð;ÜOSð;ÜgkÔloÔqtÐltÕguñ;r*   c             ‹  ó�  "  € ^ RI Hp \        4       '       g	   V! R4      #  \        \	        \        \        V RR4      ;'       g    / 4      R7      4      pVP                  4       G Rj  x€L
 '       g	   V! R4      #  VP                  W4      G Rj  x€L
 p	VP                  4       G Rj  x€L
  V	P                  '       g   V! RV	P                   24      # RR	R
RRVRV	P                  /#  L LY LC  TP                  4       G Rj  x€L 
  i ; i  \         d-   p
\        P                  RR	R7       T! RT
 24      u Rp
?
# Rp
?
ii ; i5i)u	  Out-of-process send (cron without a co-resident gateway): one-shot adapter connect â†’ send â†’
disconnect against the BlueBubbles REST API. Text only; ``thread_id``/``media_files``/
``force_document`` are signature parity (send_message drops media with a warning).)Ú
send_errorz8BlueBubbles requirements not met (need aiohttp + httpx).rw   N)rw   z(BlueBubbles: failed to connect to serverzBlueBubbles send failed: rÔ   Tr]  r›   rá   rÕ   z"BlueBubbles standalone send failed)Úexc_info)Úgateway.platforms._sharedrw  r9   r_   r   rM   rº   r	  rz  r  rÔ   rØ   rÕ   rÙ   r    rE  )Úpconfigrá   r<  rr  rs  rt  Ú_kwrw  Úadapterr‘  r“  s   &&&$$$,    r(   Ú_standalone_sendr}  t  s#  é € õ
 5Ü)×+Ò+ÙÐTÓUÐUð;Ü$¤^¼$¼wÀwÐPWÐY]Ó?^×?dÐ?dÐbdÓ:eÔ%fÓgˆØ—_‘_Ó&×&Ö&ÙÐHÓIÐIð	'Ø"Ÿ<™<¨Ó9×9ˆFà×$Ñ$Ó&×&Ð&Ø�~�~ˆ~ÙÐ 9¸&¿,¹,¸ÐHÓIÐIØ˜4 ¨]¸IÀwÐP\Ð^d×^oÑ^oÐpÐpñ 'ñ :á&ø�'×$Ñ$Ó&×&Ò&ûô ô ;Ü�‰Ð9ÀDˆÔIÙÐ5°a°SÐ9Ó:Õ:ûð;üs­   ‚E¢AD Á(C(Á)	D Á3D Á:EÁ<C. ÂC*ÂC. ÂD Â(C,Â)D Â?D ÃEÃD Ã'EÃ(D Ã*C. Ã,D Ã.D	ÄDÄD	Ä	D ÄEÄ!D>Ä8EÄ9EÄ>EÅEc                ó   € V ^8„  d   QhRR/# r  rV   )r'   s   "r(   r)   r)   Œ  s   € ÷ !Qñ !Q˜4ñ !Qr*   c            	     óª  € ^ RI Hp HpHpHpHp ^ RIHpHpH	pH
p V! R4       V! RRR4      '       d   R# V ! RR	R
RRRR4       RRRRR 3R&3 F  w  ršr¼pV! W©W½V R2R7      '       d   K   R# 	  V! R4       V ! RRRR4       V! RRRR4       V ! RRR4       V! RR4       V ! RR4       V! RR4      '       d   V! R V! R!4      R"4       V ! RR#R$R%4       R# )'zUConfigure BlueBubbles iMessage gateway (``hermes setup`` / ``hermes gateway setup``).)Ú_infoÚprint_headerÚprint_successÚpromptÚprompt_yes_no)Ú_prompt_allowlistÚ
_save_portÚdeclines_reconfigureÚsave_promptedúBlueBubbles (iMessage)ÚBlueBubbleszReconfigure BlueBubbles?rf   NuC   Connects Hermes to iMessage via BlueBubbles â€” a free, open-sourcez1macOS server that bridges iMessage to any device.z4   Requires a Mac running BlueBubbles Server v1.0.0+z%   Download: https://bluebubbles.app/uN   In BlueBubbles Server â†’ Settings â†’ API, note your Server URL and Password.z6BlueBubbles server URL (e.g. http://192.168.1.10:1234)Fz
Server URLc                 ó$   € V P                  R 4      # )rA   )rF   )Úvs   &r(   rô   Ú#interactive_setup.<locals>.<lambda>š  s   € �1—8‘8˜C”=r*   u+    is required â€” skipping BlueBubbles setup)rg   Ú	transformÚskip_msgzBlueBubbles credentials savedu0   ðŸ”’ Security: Restrict who can message your botzJ   Use iMessage addresses: email (user@icloud.com) or phone (+15551234567)ÚBLUEBUBBLES_ALLOWED_USERSzIAllowed iMessage addresses (comma-separated, leave empty for open access)z BlueBubbles allowlist configureduI   âš ï¸�  No allowlist set â€” anyone who can iMessage you can use the bot!uJ   ðŸ“¬ Home Channel: phone or email for cron job delivery and notifications.zD   You can also set this later with /set-home in your iMessage chat.ÚBLUEBUBBLES_HOME_CHANNELz/Home channel address (leave empty to set later)z6Advanced settings (defaults are fine for most setups):z$Configure webhook listener settings?rl   z%Webhook listener port (default: 8645)Ú8645zBRequires the BlueBubbles Private API helper for typing indicators,zGread receipts, and tapback reactions. Basic messaging works without it.zC   Install: https://docs.bluebubbles.app/helper-bundle/installation)zBlueBubbles server passwordrh   TÚPasswordN)Úhermes_cli.setupr€  r�  r‚  rƒ  r„  Úhermes_cli.setup_platformsr…  r†  r‡  rˆ  )r€  r�  r‚  rƒ  r„  r…  r†  r‡  rˆ  ÚlabelÚenv_varÚsecretÚwhatrŽ  s                 r(   Úinteractive_setuprš  Œ  s-  € çZÕZßmÓmÙÐ)Ô*Ù˜MÐ+EÐG_×`Ò`ÙÙ	Ð
OØ
=Ø
@Ø
1°4Ø
ZÐ\`ô	bð 
BÐC[Ð]bÐdpÙ	 ð	"àWó4Ñ/ˆ˜ iñ
 ˜W°fØ*.¨Ð/ZÐ'[÷]õ ]âñ4ñ Ð1Ô2Ù	ˆ$ÐBØ
VÐX\ô^áÐ1Ð3~Ø8ð  ;FôGá	ˆ$Ð\Ø
PôRáÐ,Ð._Ô`Ù	ˆ$ÐHÔIÙÐ;¸U×CÒCÙÐ-©vÐ6]Ó/^Ð`fÔgÙ	ˆ$ÐTØ
SØ
OöQr*   a‚  You are texting via iMessage (BlueBubbles). Replies arrive as plain text bubbles, so write like a person texting: short and conversational, answer first, no preamble or recap. Markdown does not render and is stripped, so skip headers, tables, code fences and backticks; for a few items use short lines or a sentence rather than nested bullets. Put a command or code snippet on its own line as plain text so it can be copied. Write links as bare URLs (iMessage auto-links them). You can send files natively: write MEDIA:/absolute/path/to/file in your response. Images (.jpg, .png, .heic) appear as photos and other files arrive as attachments.c                ó   € V ^8„  d   QhRR/# r  rV   )r'   s   "r(   r)   r)   ½  s   € ÷ ñ �Tñ r*   c           	     óF  € ^RI Hp V P                  ! R%/ RRbRRbR\        bRRbR	R
bRR&bR\        bR\
        bR\        RR4      bRRR.bR\        bR\        bRRbR\        bR^ bRRbRRbRRbR\        bR R!bR"VP                  bR#VP                  bVP                  B  R$# )'u:   Plugin entry point â€” called by the Hermes plugin system.)Úgateway_envr‚  r›   r–  r‰  Úadapter_factoryÚdashboard_descriptionz5Use Hermes through iMessage via a BlueBubbles server.Údocs_urlzhttps://bluebubbles.app/Údashboard_env_varsrf   rh   Úcheck_fnÚis_connectedÚconfig_connected_fnre   rg   Úrequired_envÚinstall_hintÚsetup_fnÚcron_deliver_env_varr‘  Ústandalone_sender_fnÚmax_message_lengthÚpii_safeTÚemojiu   ðŸ’¬Úallow_update_commandÚplatform_hintÚdisplay_tierÚlowÚenv_overridesÚenv_enable_credentialsNrV   )rf   rh   r�  )r>   r�  Úregister_platformr_   r9   rq  r   Ú_INSTALL_HINTrš  r}  Ú_PLATFORM_HINTÚENV_OVERRIDESÚENV_ENABLE_CREDENTIALSÚAUTHZ)Úctxr�  s   & r(   Úregisterrº  ½  s  € åØ×Òò ÙðÙ":ðÝL^ðáUðñ ,ðñ kð	õ
 0ðõ
 ?Lðô 3°<ÀÔLðð /Ð0FÑGðõ Wdðõ #ðñ 8ðõ .ðñ ðñ (,ðñ 4:ðñ QUðõ %ðñ ðð  "×/Ò/ð!ð"  +×AÒAÀ[×EVÑEVô#r*   >   r<  r9  r:  >   r  ú::ú0.0.0.0r   )RÚ__doc__r‡  r¼   Úloggingr‰  rC   r�  Úcollectionsr   Ú
contextlibr   r   Úpathlibr   r¿  r   r   r   r	   Úurllib.parser
   r   rù   Úgateway.configr   r   ry  r   rx   r   rz   r   r›  r   r   r   r   r   Úgateway.platforms.eventr   r   Úgateway.platforms.media_cacher   Úgateway.platforms.helpersr   r   Úutilsr   ré  rê  Ú	getLoggerrÛ   r    r{   rþ   r}   r~   r_  rŸ   ÚrangerK  rJ  Úcompiler.   r,   re  rs  rU  r  r0   r9   rH   rQ   rW   r]   r_   r´  rq  r}  rš  rµ  rº  rV   r*   r(   Ú<module>rË     sÆ  ðñQó Û Û Û 	Û 	Û Ý #Ý Ý Ý ß ,Ó ,ß (ã ç 3ß rÝ <÷õ ÷ >Ý 6ß NÝ  ð
 �&˜+ v¨{¸FÀLÐRYØ�&˜,¨°¸fð$Ð  ð
 �˜ v¨{¸FÀKÐQWØ�6˜;¨Ø�ð$Ð  ð 
×	Ò	˜8Ó	$€à"Ð ð $Ð ØÐ Ø-Ð Ø€ð CÐDbÐcÐ ð :‘5˜˜tÓ$Ð9¡u¨T°4Ó'8Ð9€Ú?€à�JŠJ�~Ó&€	Ø�JŠJÐ1Ó2€	ØŸ
š
Ð#5Ó6Ð Ø�jŠj˜Ó#€àÐ Ú:€õJõ
õõ7õ3ò#ôyÐ,ô yð| s€õyð;Ð^bð ;Ø9=ð;ØV[÷;õ0!QðNYð ÷r*   