+
    lHàjØ@  ã                  óN  € R t ^ RIHt ^ RIt^ RIt^ RIHt ^ RIHt ^ RI	H
t
Ht ^ RIHt ]P                  ! R4      tRR	R
R	RRRRRRRRRR/t]! 0 R,m4      tR R ltR-tR R ltR R ltR R ltR R ltR R  ltR! R" ltR# R$ lt^dtR%t]]3R& R' lltR( R) ltR.R* R+ llt R# )/aC  Image format detection, normalization and region cropping for vision tools.

Everything here runs BEFORE an image is base64-embedded: a vision tool result is
baked into immutable history and re-sent every turn, so an unsupported media type
or corrupt bytes would wedge the session with a non-retryable 400 on every resume.
)ÚannotationsN)ÚBytesIO)ÚPath)ÚAnyÚOptional)Úget_hermes_dirztools.vision_toolsz.jpgú
image/jpegz.jpegú.pngú	image/pngz.gifú	image/gifz.bmpú	image/bmpz.webpú
image/webpú.svgúimage/svg+xmlc               ó    € V ^8„  d   QhRRRR/# ©é   ÚurlÚstrÚreturnúOptional[str]© )Úformats   "ÚB/home/ubuntu/.hermes/hermes-agent/tools/vision_tools_image_prep.pyÚ__annotate__r   #   s   € ÷ 	Rñ 	R¨Sð 	R°]ñ 	Ró    c                ó4  € V P                  R4      ^ ,          P                  4       pVP                  R4      '       g   R# V\        R4      R P	                  R^4      ^ ,          P                  4       ;'       g    RpVR8X  d   RMRV 2pV\        9   d   R# T# )	zÍ``image/<subtype>`` of a ``data:image/...`` URL the inline-image wire paths reject
(``image/jpg`` counts as JPEG); None for accepted rasters and for non-data URLs (the
provider owns remote-URL validation).Ú,zdata:image/NÚ;ÚunknownÚjpgr   zimage/)Ú	partitionÚlowerÚ
startswithÚlenÚsplitÚstripÚ _ANTHROPIC_SUPPORTED_MEDIA_TYPES)r   ÚheaderÚsubtypeÚ
media_types   &   r   Ú#unsupported_inline_image_media_typer+   #   s‘   € ð �]‰]˜3Ó Õ"×(Ñ(Ó*€FØ×Ñ˜]×+Ò+ÙØ”S˜Ó'Ð(Ð)×/Ñ/°°QÓ7¸Õ:×@Ñ@ÓB×OÐOÀi€GØ!(¨EÔ!1‘¸À¸yÐ7I€JØÔ!AÔAˆ4ÐQÀzÐQr   c               ó    € V ^8„  d   QhRRRR/# )r   Ú
image_pathr   r   r   r   )r   s   "r   r   r   4   s   € ÷ Nñ N Tð N¨cñ Nr   c                ó^   € \         P                  V P                  P                  4       R4      # )z7MIME type from file extension (defaults to image/jpeg).r   )Ú_EXTENSION_MIME_TYPESÚgetÚsuffixr"   )r-   s   &r   Ú_determine_mime_typer2   4   s$   € ä ×$Ñ$ Z×%6Ñ%6×%<Ñ%<Ó%>ÀÓMÐMr   c               ó    € V ^8„  d   QhRRRR/# )r   ÚdataÚbytesr   r   r   )r   s   "r   r   r   9   s   € ÷ .ñ .¨Uð .°}ñ .r   c                ór  € V R,          pVP                  R4      '       dF    ^ RIHp  TP	                  \        T 4      4      ;_uu_ 4       pTP                  4        RRR4       R# \         F   w  rEVP                  V4      '       g   K  Vu # 	  \        V4      ^8¼  d   VR,          R8X  d   VR,          R	8X  d   R
# \        V4      ^8¼  d­   VR,          R8X  dŸ   VR,          p\        P                  VR,          R4      pV^8  d   ^M\        V\        V4      4      pV0\        ^V^,
          ^4       U	u0 uF  q‘W™^,            kK  	  up	,          p
V
0 Rm,          '       d   R# V
0 Rm,          '       d   R# R#   \         d     R# i ; i  + '       g   i     R# ; i  \         d     R# i ; iu up	i )uµ   Magic-byte MIME sniff (authoritative; no extension trust). ``None`` for anything without a
recognized header â€” including SVG, which has none (the resolver sniffs ``<svg`` itself).:Né@   Ns   ‰PNG

©ÚImager
   N:Né   Ns   RIFF:é   é   Ns   WEBPr   :r:   r;   Ns   ftypÚbigú
image/avifú
image/heic>   ó   av01ó   avifó   avis>   ó   heicó   heimó   heisó   heixó   hevcó   hevxó   mif1ó   msf1)r#   ÚPILr9   ÚImportErrorÚopenr   ÚverifyÚ	ExceptionÚ_MAGIC_MIME_TYPESr$   ÚintÚ
from_bytesÚminÚrange)r4   r(   r9   ÚimageÚmagicÚmimeÚmajorÚbox_sizeÚlimitÚiÚbrandss   &          r   Ú"_detect_image_mime_type_from_bytesr]   9   s}  € ð �#�Y€FØ×ÑÐ-×.Ò.ð	Ý!ð	Ø—‘œG D›M×*Ô*¨eØ—‘”÷ +á÷ )‰ˆØ×Ñ˜U×#Ô#ØŠKñ )ô ˆ6ƒ{�bÔ˜V B�Z¨7Ô2°v¸dµ|ÀwÔ7NÙô ˆ6ƒ{�bÔ˜V C�[¨GÔ3Ø�t•ˆô
 —>‘> &¨¥*¨eÓ4ˆØ ”m‘¬¨X´s¸6³{Ó)CˆØ�´U¸2¸uÀq½yÈ!Ô5LÓMÑ5L° 1¨¥U›OÑ5LÑMÕMˆàÒ/×/Ô/ÙØò 
÷ 
ô 
ñ
  ÙøôK ô 	Úð	ú÷ +Ö*áûÜô 	Úð	üò* NsF   ¢E< ©"F" ÁFÁF" Ä8F4Å<FÆ
FÆF	ÆF" ÆF" Æ"F1Æ0F1c               ó   € V ^8„  d   QhRR/# )r   r   Ú	frozensetr   )r   s   "r   r   r   j   s   € ÷ ,ñ , 	ñ ,r   c                 óà   €  ^ RI Hp  ^ RIHpHp T! \        V ! R4      ;'       g    R4      \        V ! R4      ;'       g    R4      4      '       d   V#  \        #   \         d	     \        # i ; i)u  Formats the ACTIVE main model's server can decode. The managed llama-server decodes with
stb_image â€” no WebP â€” and an undecodable image part fails SILENTLY (the model confabulates),
so the set is narrowed there and normalization converts those formats to PNG.)Ú_runtime_main_value)ÚACCEPTED_IMAGE_MIMESÚis_managed_providerÚproviderÚ Úbase_url)Úagent.auxiliary_clientra   Ú%hermes_cli.local_runtime.capabilitiesrb   rc   r   rO   r'   )Ú_vrb   rc   s      r   Ú_supported_media_typesrj   j   sk   € ðÝDßcÙœs¡2 j£>×#7Ð#7°RÓ8¼#¹bÀ»n×>RÐ>RÐPRÓ:S×TÒTØ'Ð'ð Uô ,Ð+øô ô ØÜ+Ð+ðús"   ‚#A ¦A Á A ÁA ÁA-Á,A-c               ó    € V ^8„  d   QhRRRR/# )r   Úpathr   r   Úboolr   )r   s   "r   r   r   x   s   € ÷ 5ñ 5˜ð 5 $ñ 5r   c                ól   € V P                  4       ;'       d    V P                  4       P                  ^ 8„  # )é    )ÚexistsÚstatÚst_size)rl   s   &r   Ú_nonempty_filers   x   s'   € Ø�;‰;‹=×4Ð4˜TŸY™Y›[×0Ñ0°1Ñ4Ð4r   c               ó$   € V ^8„  d   QhRRRRRR/# )r   Úsvg_pathr   Úout_pathr   rm   r   )r   s   "r   r   r   |   s!   € ÷ ñ  Dð °Dð ¸Tñ r   c           	     óŠ  €  ^ RI pVP                  \        V 4      \        V4      R7       \        V4      #   \         d     Mi ; i ^ RIHp ^ RIHp T! \        T 4      4      pTe)   TP                  T\        T4      RR7       \        T4      # M  \         d     Mi ; i^ RI
p^ RIpRR\        T4      \        T 4      .R	\        T 4      R
RT 2.3 Fj  pTP                  T^ ,          4      '       g   K#   TP                  TRR^TP                  R7       \        T4      '       d    R# KZ    \         d     Kh  i ; i	  R# )u_   Best-effort SVG â†’ PNG via cairosvg, svglib+reportlab, rsvg-convert, inkscape (all soft deps).N)r   Úwrite_to)Úsvg2rlg)ÚrenderPMÚPNG)Úfmtzrsvg-convertz-oÚinkscapez--export-type=pngz--export-filename=T)ÚcheckÚcapture_outputÚtimeoutÚstdinF)ÚcairosvgÚsvg2pngr   rs   rO   Úsvglib.svglibry   Úreportlab.graphicsrz   Ú
drawToFileÚshutilÚ
subprocessÚwhichÚrunÚDEVNULL)	ru   rv   r‚   ry   rz   Údrawingr‡   rˆ   Úcmds	   &&       r   Ú_rasterize_svg_to_pngrŽ   |   s@  € ðÛØ×ÑœS ›]´S¸³]ÐÔCÜ˜hÓ'Ð'øÜô ÙðúðÝ)Ý/Ùœ#˜h›-Ó(ˆØÒØ×Ñ ¬¨X«¸EÐÔBÜ! (Ó+Ð+ð øô ô ÙðúãÛà	˜œs 8›}¬c°(«mÐ<Ø	”S˜“]Ð$7Ð;MÈhÈZÐ9XÐYó[ˆð �<‰<˜˜A�×ÔðØ—‘˜s¨$¸tÈRÐWa×WiÑWi�ÔjÜ! (×+Ò+Úñ ,øäô Úðúñ[ñ s4   ‚36 ¶AÁAÁAB ÂB ÂB Ã91D/Ä/D>Ä=D>c               ó    € V ^8„  d   QhRRRR/# r   r   )r   s   "r   r   r   œ   s   € ÷ ñ  ð ¨ñ r   c           
     ó  € ^ RI p^ RIHp ^ RIHp V P                  R4      w  rEp RVP                  4       9   d   VP                  V4      MV! V4      P                  4       p^ RI
HpHp	 T! RR4      p
T
R	\        P                  ! 4        2,          pTP                  R
4      TP                  R4      rÜ TP!                  T4       \#        YÍ4      '       g;    YÍ3 F0  pT! \$        4      ;_uu_ 4        TP'                  4        RRR4       K2  	  R# RTP)                  TP+                  4       4      P-                  R4      ,           YÍ3 F0  pT! \$        4      ;_uu_ 4        TP'                  4        RRR4       K2  	  #   \         d     R# i ; i  + '       g   i     KÅ  ; i  + '       g   i     Kl  ; i  YÍ3 FD  pT! \$        4      ;_uu_ 4        TP'                  4        RRR4       K2    + '       g   i     KC  ; i	  i ; i)uN  ``data:image/svg+xml[;base64],...`` â†’ ``data:image/png;base64,...`` through the same
soft-dependency rasterizers vision_analyze uses; None when the payload does not decode or no
rasterizer is available. Request-path callers decide the fallback (Responses backends 400 on
SVG source, so the caller must never forward the SVG itself).N)Úsuppress)Úunquoter   z;base64)Ú_secure_cache_dirÚ_write_private_bytesúcache/visionÚtemp_vision_imagesÚinline_r   r	   zdata:image/png;base64,Úascii)Úbase64Ú
contextlibr‘   Úurllib.parser’   r!   r"   Ú	b64decodeÚencoderO   Útools.vision_toolsr“   r”   ÚuuidÚuuid4Úwith_suffixÚwrite_bytesrŽ   ÚOSErrorÚunlinkÚ	b64encodeÚ
read_bytesÚdecode)r   r™   r‘   r’   r(   Ú_ÚpayloadÚrawr“   r”   Úout_dirÚstemru   Úpng_pathrl   s   &              r   Úrasterize_svg_data_urlr®   œ   s–  € ó
 Ý#Ý$ØŸ™ sÓ+Ñ€FˆwðØ+4¸¿¹»Ô+Fˆf×Ñ˜wÔ'ÉGÐT[ÓL\×LcÑLcÓLeˆ÷ KÙ Ð0DÓE€GØ�wœtŸzšz›|˜nÐ-Õ-€DØ×)Ñ)¨&Ó1°4×3CÑ3CÀFÓ3KˆhðØ×Ñ˜SÔ!Ü$ X×8Ò8Øð Ó(ˆDÙœ'×"Õ"Ø—‘”÷ #Ñ"ó )ð (¨&×*:Ñ*:¸8×;NÑ;NÓ;PÓ*Q×*XÑ*XÐY`Ó*aÕaàÓ(ˆDÙœ'×"Õ"Ø—‘”÷ #Ñ"ò )øô ô Úðú÷ #×"Ð"ú×"×"Ð"ûð Ó(ˆDÙœ'×"Õ"Ø—‘”÷ #×"×"Ò"úò )úsS   ¦<E< Â4"F6 Ã1FÄ4F6 ÅF"	Å<FÆ
FÆFÆ"F3Æ6HÇG,Ç"
HÇ,G=Ç7Hc               ó$   € V ^8„  d   QhRRRRRR/# )r   r-   r   Údetected_mimer   r   ú3tuple[Optional[Path], Optional[str], Optional[str]]r   )r   s   "r   r   r   ¸   s)   € ÷ :Bñ :BØð:BØ%(ð:BØ-`ñ:Br   c                ó  € V\        4       9   d   WR3# ^ RIHp V! RR4      pVR\        P                  ! 4        R2,          pVR8X  d   \        W4      '       d   VRR3# R# VR9   d    ^ RIpVP                  4         ^ RIHp VP                  V 4      ;_uu_ 4       pVP                  R9  d   VP                  R4      pVP!                  VRR7       RRR4       \#        V4      '       d   VRR3#  RRRV: R23#   \         d    \        P                  RT4        L¢i ; i  + '       g   i     LX; i  \         d=   p\        P%                  RY4       TR	8X  d   Ru Rp?# TR
8X  d   Ru Rp?#  Rp?L†Rp?ii ; i)uR  Ensure an image is in a provider-supported format. Returns ``(path, mime, error)``: the input
unchanged when supported; ``(new_png_path, "image/png", None)`` after conversion â€” a temp file
the CALLER must clean up; ``(None, None, message)`` when impossible. SVG is rasterized; other
Pillow-readable rasters (BMP, TIFF) re-encode to PNG.N)r“   r•   r–   Ú
converted_r	   r   r
   r?   r>   z1pillow-heif unavailable; relying on Pillow for %sr8   ÚRGBAr{   ©r   z'Failed to normalize %s image to PNG: %szImage format z– is not supported by the vision API and could not be converted to PNG (install Pillow for raster conversion). Convert it to PNG or JPEG and try again.)NNu  This is an SVG, which vision models cannot read directly, and no SVG rasterizer is installed (tried cairosvg, svglib, rsvg-convert, inkscape). Convert the SVG to PNG first â€” e.g. open it in a browser and screenshot it â€” then re-run vision_analyze on the PNG.)r?   r>   )ÚRGBr´   ÚL)NNzìThis is a HEIC/HEIF image (common for iPhone photos), which vision models cannot read directly, and no HEIF decoder is available. Install one (`pip install pillow-heif`) and re-run vision_analyze, or convert the image to PNG/JPEG first.)NNu  This is an AVIF image, which vision models cannot read directly, and no AV1 decoder is available. Upgrade Pillow (>= 11.3 bundles AVIF support) or install a pillow-heif build with an AV1 codec, then re-run vision_analyze â€” or convert the image to PNG/JPEG first.)rj   rž   r“   rŸ   r    rŽ   Úpillow_heifÚregister_heif_openerrO   ÚloggerÚdebugrK   r9   rM   ÚmodeÚconvertÚsavers   Úwarning)	r-   r°   r“   r«   rv   r¸   Ú	_PILImageÚ_imgÚ_excs	   &&       r   Ú_normalize_to_supported_imagerÃ   ¸   s—  € ð Ô.Ó0Ô0Ø¨$Ð.Ð.Ý4Ù Ð0DÓE€GØ˜:¤d§j¢j£l ^°4Ð8Õ8€HØ˜Ô'Ü  ×6Ò6Ø˜[¨$Ð.Ð.ðLð 	Lð Ð4Ô4ð	]ÛØ×,Ñ,Ô.ð,Ý*Ø�^‰^˜J×'Ô'¨4Ø�y‰yÐ 4Ô4Ø—|‘| FÓ+�Ø�I‰I�h uˆIÔ-÷ (ô ˜(×#Ò#Ø˜[¨$Ð.Ð.ð $ð$ �Ø
˜Ñ(ð )@ð 	AðBð Bøô5 ô 	]Ü�L‰LÐLÈmÖ\ð	]ú÷ (×'ûô ô ,Ü�‰Ð@À-ÔVà˜LÔ(ðKõ Kð
 ˜LÔ(ð,õ ,ô )ûð,úsT   Á*C= Á?D7 Â6D$ÃD7 Ã=!D!Ä D!Ä$D4	Ä/D7 Ä7E>ÅE9Å E>Å&E9Å.E>Å9E>i áõc               ó(   € V ^8„  d   QhRRRRRRRR/# )r   r-   r   Ú
max_framesrQ   Ú
max_pixelsr   r   r   )r   s   "r   r   r   û   s2   € ÷ !ñ !Øð!àð!ð ð!ð BOñ!r   c           
     ó˜  €  ^ RI HpHp  TP	                  T 4      ;_uu_ 4       pTP                  4        RRR4       TP	                  T 4      ;_uu_ 4       p^ p\        TP                  T4      ^R7       Fs  w  rxYq8”  d   RT RT R2u uuRRR4       # YhP                  TP                  ,          ,           p	Y’8”  d   RT	 RT R	T R
2u uuRRR4       # TP                  4        T	pKu  	  RRR4       R#   \         d     R# i ; i  + '       g   i     LÛ; i  + '       g   i     R# ; i  \         d   p
RT
 2u Rp
?
# Rp
?
ii ; i)a  Return an error unless Pillow can fully decode every frame. Header sniffing and ``Image.open``
only inspect containers: a timed-out download can look like a valid PNG with a truncated pixel
stream. Without Pillow the image passes unvalidated rather than rejecting everything.)r9   ÚImageSequenceN)Ústartz+Image validation rejected animation: frame z exceeds the maximum z validated frames.zOImage validation rejected animation: aggregate decoded pixel count would reach z
 at frame z, exceeding the maximum Ú.z"Image could not be fully decoded: )rK   r9   rÈ   rL   rM   rN   Ú	enumerateÚIteratorÚwidthÚheightÚloadrO   )r-   rÅ   rÆ   rÀ   Ú_PILImageSequencerU   Úvalidated_pixelsÚframe_numberÚframeÚnext_validated_pixelsÚexcs   &&&        r   Ú _validate_raster_image_decodablerÖ   û   sB  € ðßNð:Ø�^‰^˜J×'Ô'¨5Ø�L‰LŒN÷ (à�^‰^˜J×'Ô'¨5Ø ÐÜ'0Ð1B×1KÑ1KÈEÓ1RÐZ[×'\Ñ#�ØÔ,ð!Ø!- Ð.CØ%˜,Ð&8ð:ñ;÷	 (Ò'ð )9¿;¹;ÈÏÉÕ;UÕ(UÐ%Ø(Ô5ð3Ø3HÐ2IÈØ'˜.Ð(@Ø%˜, að)ñ*÷ (Ò'ð —
‘
”Ø#8Ò ñ (]÷ (ñ& øô1 ô Úðú÷ (×'úç'Ö'ñ& ûô ô :Ø3°C°5Ð9Õ9ûð:úsz   ‚C6 ‹D/ ¤Dµ!D/ Á4DÂ

D/ Â6DÃ
D/ ÃDÃ,D/ Ã6DÄDÄD	ÄD/ ÄD,	Ä&D/ Ä,D/ Ä/E	Ä:EÄ>E	ÅE	c               ó$   € V ^8„  d   QhRRRRRR/# )r   r-   r   Úmax_dimensionrQ   r   rm   r   )r   s   "r   r   r     s!   € ÷ 	ñ 	¨ð 	¸cð 	Àdñ 	r   c                óÔ   €  ^ RI Hp VP                  V 4      ;_uu_ 4       p\        VP                  4      V8„  uuRRR4       #   + '       g   i     R# ; i  \
         d     R# i ; i)uÛ   True if the longest side exceeds ``max_dimension`` px (Anthropic's 8000px per-side cap is
independent of bytes). False without Pillow or on unreadable files â€” a missing soft
dependency must never break the embed path.r8   NF)rK   r9   rM   ÚmaxÚsizerO   )r-   rØ   rÀ   rÁ   s   &&  r   Ú_image_exceeds_dimensionrÜ     sK   € ðÝ*Ø�^‰^˜J×'Ô'¨4Ü�t—y‘y“> MÑ1÷ (×'×'Ó'ûäô Úðús-   ‚A ¡A¹
A ÁA	ÁA ÁA ÁA'Á&A'c               ó(   € V ^8„  d   QhRRRRRRRR/# )	r   r-   r   Úregionr   Ú
offset_outzOptional[dict]r   r±   r   )r   s   "r   r   r   +  s,   € ÷ ';ñ ';Øð';Ø!ð';Ø/=ð';à8ñ';r   c                ó   €  ^ RI Hp \        T\        \
        34      '       dK   \        T4      ^8X  d;   \        ;QJ d    R T 4       F  '       d   K   RM	  RM! R T 4       4      '       g   R#  TP                  T 4      ;_uu_ 4       pTP                  w  rVR T 4       w  rxršR \        YxYš3YV3^,          4       4       w  r¼rÞYÛ8:  g   Yì8:  d)   RRRT R	T R	T	 R	T
 R
T RT RT R	T R23uuRRR4       # TP                  Y¼YÞ34      pTe!   TP                  Y¼YÛ,
          Yì,
          R7       T P                  T P                   R\        P                   ! 4       P"                  R,           R24      pTP$                  R9  d   TP'                  R4      pTP)                  TRR7       TRR3uuRRR4       #   \         d    Ru # i ; i  + '       g   i     R# ; i  \*         d   pRRRT 23u Rp?# Rp?ii ; i)u”  Crop to ``region`` = [x1, y1, x2, y2] (original-image pixels), BEFORE downscaling so the crop
gets the full resolution budget. Coordinates clamp to the image bounds; a zero-area/inverted
region is rejected with an error naming the real dimensions. Returns ``(cropped_temp_path,
mime, None)`` â€” caller owns cleanup â€” or ``(None, None, error)``.
Ported from QwenLM/qwen-code zoom-image.ts (Apache-2.0).r8   Nc              3  óˆ   "  € T F8  p\        V\        \        34      ;'       d    \        V\        4      '       * x € K:  	  R # 5i©N)Ú
isinstancerQ   Úfloatrm   ©Ú.0Úvs   & r   Ú	<genexpr>Ú%_crop_image_region.<locals>.<genexpr>:  s3   é € Ð\ÑU[ÐPQ”J˜q¤3¬ ,Ó/×KÐK¼
À1ÄdÓ8KÔ4KÔKÓU[ùs
   ‚!A¤AFTc              3  ó8   "  € T F  p\        V4      x € K  	  R # 5irâ   )rQ   rå   s   & r   rè   ré   A  s   é € Ð5©f¨œc !Ÿf˜f«fùs   ‚c              3  óP   "  € T F  w  r\        ^ \        W4      4      x € K  	  R# 5i)ro   N)rÚ   rS   )ræ   rç   Úbs   &  r   rè   ré   B  s"   é € Ð!kÑ@j¹¸¤# a¬¨Q«×"3Ð"3Ó@jùs   ‚$&zInvalid region [z, zG]: crops to zero area after clamping to the image bounds. The image is Úxu+    px â€” pick x1<x2 and y1<y2 inside [0, 0, z].)rí   ÚyrÍ   rÎ   Ú_region_:Nr;   Nr	   r¶   r{   rµ   r
   zFailed to crop region: )NNz]region cropping requires Pillow (run `hermes pm repair`); retry without the region parameter.)NNzdInvalid region: expected [x1, y1, x2, y2] as four numbers (pixel coordinates in the original image).)r¶   r´   r·   ÚLAÚP)rK   r9   rL   rã   ÚlistÚtupler$   ÚallrM   rÛ   ÚzipÚcropÚupdateÚ	with_namer¬   rŸ   r    Úhexr¼   r½   r¾   rO   )r-   rÞ   rß   r9   ÚimgrÍ   rÎ   Úx1Úy1Úx2Úy2Úcx1Úcy1Úcx2Úcy2Úcroppedrv   rÕ   s   &&&               r   Ú_crop_image_regionr  +  sù  € ð3Ýô
 �v¤¤e˜}×-Ò-´#°f³+ÀÔ2Bß“Ñ\ÑU[Ó\——’Ñ\ÑU[Ó\×\Ò\ð:ð 	:ð;Ø�Z‰Z˜
×#Ô# sØŸH™H‰MˆEÙ5©fÓ5‰NˆB�BÙ!kÄÀRÈRÐDTÐW\ÐVeÐhiÕViÔ@jÓ!kÑˆC�cØŒz˜SœZØ˜TØ& r d¨"¨R¨D°°2°$°b¸¸ð =Mà�g˜Q˜v˜hð 'Ø#˜W B v h¨bð2ð3÷ $Ò#ð —h‘h ¨#Ð3Ó4ˆGØÒ%Ø×!Ñ! C°cµiÈÍ	Ð!ÔRØ!×+Ñ+¨z¯©Ð.?¸xÌÏ
Ê
Ë×HXÑHXÐY[ÕH\ÐG]Ð]aÐ,bÓcˆHØ�|‰|Ð#BÔBØ!Ÿ/™/¨%Ó0�Ø�L‰L˜¨%ˆLÔ0Ø˜[¨$Ð.÷# $Ò#øô ô 3ð3ò 	3ð3ú÷ $×#Ð#ûô$ ô ;Ø�TÐ4°S°EÐ:Ð:Õ:ûð;ús[   ‚F9 Á1G  Â
A$GÃ.
G  Ã9B5GÆ.
G  Æ9G	ÇG	ÇG	ÇG  ÇG  Ç G=Ç+G8Ç2G=Ç8G=>   r   r
   r   r   ))s   ÿØÿr   ))s   GIF87as   GIF89ar   )s   BMr   râ   )!Ú__doc__Ú
__future__r   ÚloggingrŸ   Úior   Úpathlibr   Útypingr   r   Úhermes_constantsr   Ú	getLoggerrº   r/   r_   r'   r+   rP   r2   r]   rj   rs   rŽ   r®   rÃ   Ú!_VISION_MAX_VALIDATED_FRAME_COUNTÚ&_VISION_MAX_VALIDATED_AGGREGATE_PIXELSrÖ   rÜ   r  r   r   r   Ú<module>r     sÎ   ðñõ #ã Û Ý Ý ß  å +à	×	Ò	Ð/Ó	0€ð ˆLØˆ\Ø
ˆKØ
ˆKØ
ˆKØˆ\Ø
ˆOðÐ ñ $-Ò-cÓ#dÐ  õ	RðÐ õ
Nõ
.õb,õ5õõ@õ8:Bð~ %(Ð !Ø)4Ð &ð
 8Ø<÷!õH	÷';ñ ';r   