§
    øžyjSk  ã                  ó‚  — d Z ddlmZ ddlZddlmZmZmZmZm	Z	 dZ
dZdZdZd	Zd
Zeeef         Z ej        d¦  «        Z ej        d¦  «        Z ej        d¦  «        Z ej        d¦  «        Z ej        d¦  «        Z ej        d¦  «        Z ej        d¦  «        ZdBd„ZdCd„Z ej        d¦  «        Z ej        d¦  «        Z ej        d¦  «        Z ej        d¦  «        Z ej        d¦  «        Z dDd!„Z!dEd#„Z"dFd%„Z#dGd'„Z$dHd(„Z%dId+„Z&dJd.„Z'dHd/„Z(dKd1„Z)dLd3„Z*dMd5„Z+dNd7„Z,dOd8„Z-	 dPdQd;„Z.dRd=„Z/dSd?„Z0dTdA„Z1dS )Uu  Render agent markdown into Slack Block Kit blocks.

Opt-in (``slack.extra.rich_blocks: true``) alternative to the flat mrkdwn
``text`` payload produced by :meth:`SlackAdapter.format_message`.  Block Kit
gives us real structural primitives â€” section headers, dividers, and true
*nested* lists via ``rich_text`` â€” that plain mrkdwn can only approximate.

Design constraints (why this module is deliberately conservative):

* **Markdown pipe-tables render as native ``table`` blocks** â€” real grid
  cells with per-column alignment and inline-formatted ``rich_text`` content.
  A table that exceeds Slack's limits (100 rows / 20 cols / 10k aggregate
  cell chars) or won't parse falls back to aligned monospace
  ``rich_text_preformatted`` so a large table never breaks the message.
* **Slack caps a message at 50 blocks** and a ``section``/text object at 3000
  characters.  :func:`render_blocks` enforces both and, if the content simply
  cannot be expressed within them, returns ``None`` so the caller falls back
  to the plain-text path.  A rich render is a nice-to-have; it must never lose
  a message.
* **Every blocks payload MUST ship a ``text`` fallback.**  Slack uses it for
  notifications, screen readers, and old clients.  This module only builds the
  ``blocks`` list; the adapter pairs it with the existing mrkdwn string.

The renderer never raises: any unexpected input degrades to ``None`` (caller
uses plain text).  It is a pure function of its input â€” no Slack client, no
adapter state â€” so it is trivially unit-testable.
é    )ÚannotationsN)ÚAnyÚDictÚListÚOptionalÚTupleé2   i¸  é–   éd   é   i'  z ^\s{0,3}([-*_])(?:\s*\1){2,}\s*$z!^\s{0,3}(#{1,6})\s+(.+?)\s*#*\s*$z^\s*(`{3,}|~{3,})(.*)$z^(\s*)(\d+)[.)]\s+(.*)$z^(\s*)[-*+]\s+(.*)$z^\s{0,3}>\s?(.*)$z1^\s*\|?\s*:?-{1,}:?\s*(\|\s*:?-{1,}:?\s*)+\|?\s*$ÚlineÚstrÚreturnÚboolc                ó„   — t          t                               | ¦  «        pt                               | ¦  «        ¦  «        S )z=True if ``line`` is a markdown list item (bullet or ordered).)r   Ú
_BULLET_REÚmatchÚ_ORDERED_RE)r   s    úG/home/ragecks/.hermes/hermes-agent/plugins/platforms/slack/block_kit.pyÚ_is_list_liner   :   s1   € å•
× Ò  Ñ&Ô&ÐA­+×*;Ò*;¸DÑ*AÔ*AÑBÔBÐBó    ÚspacesÚintc                óP   — d}| D ]}||dk    rdndz  }Œt          |dz  d¦  «        S )zHMap leading whitespace to a nesting level (2 spaces or 1 tab per level).r   ú	é   é   é   é   )Úmin)r   ÚwidthÚchs      r   Ú_indent_levelr#   ?   sB   € à€EØð (ð (ˆØ�b˜D’j�j�� aÑ'ˆˆÝˆu˜‰z˜1ÑÔÐr   z	`([^`]+)`z7(?<!!)\[([^\]]+)\]\(([^()\s]+(?:\([^()]*\)[^()\s]*)*)\)z(?:\*\*|__)(.+?)(?:\*\*|__)z?(?<![\*_])(?:\*|_)(?![\*_\s])(.+?)(?<![\*_\s])(?:\*|_)(?![\*_])z	~~(.+?)~~ÚtextúList[Dict[str, Any]]c                ón   ‡‡‡‡— g Šddˆfd„Šdˆˆfd
„}dˆˆfd„Šdˆˆfd„Š || i ¦  «         ‰pd| dœgS )a
  Parse a run of inline markdown into rich_text section child elements.

    Produces ``text`` elements (optionally styled bold/italic/strike/code) and
    ``link`` elements.  Unmatched markup is emitted verbatim as plain text, so
    this never loses characters.
    NÚsr   ÚstyleúOptional[Dict[str, bool]]r   ÚNonec                óR   •— | sd S d| dœ}|r||d<   ‰                      |¦  «         d S )Nr$   ©Útyper$   r(   )Úappend)r'   r(   ÚelÚelementss      €r   Ú	emit_textz#_inline_elements.<locals>.emit_text\   sF   ø€ Øð 	ØˆFØ&,°aÐ8Ð8ˆØð 	 ØˆBˆw‰KØ�Š˜ÑÔÐÐÐr   úDict[str, bool]c                óL  •— d}t                                | ¦  «        D ]q} ‰| ||                     ¦   «         …         |¦  «         t          |¦  «        }d|d<    ‰|                     d¦  «        |pd ¦  «         |                     ¦   «         }Œr ‰| |d …         |¦  «         d S )Nr   TÚcoder   )Ú_INLINE_CODE_REÚfinditerÚstartÚdictÚgroupÚend)r'   r(   ÚposÚmÚ
code_styleÚ_walk_linksr1   s        €€r   Úwalkz_inline_elements.<locals>.walkg   s­   ø€ Øˆå ×)Ò)¨!Ñ,Ô,ð 	ð 	ˆAØˆK˜˜#˜aŸgšg™iœi˜-Ô(¨%Ñ0Ô0Ð0Ý˜e™œˆJØ!%ˆJ�vÑØˆI�a—g’g˜a‘j”j *Ð"4°Ñ5Ô5Ð5Ø—%’%‘'”'ˆCˆCØˆ�A�c�d�d”G˜UÑ#Ô#Ð#Ð#Ð#r   c                óŒ  •— d}t                                | ¦  «        D ]‘} ‰| ||                     ¦   «         …         |¦  «         d|                     d¦  «        |                     d¦  «        dœ}|rt	          |¦  «        |d<   ‰                     |¦  «         |                     ¦   «         }Œ’ ‰| |d …         |¦  «         d S )Nr   Úlinkr   r   )r-   Úurlr$   r(   )Ú_LINK_REr6   r7   r9   r8   r.   r:   )r'   r(   r;   r<   Úlink_elÚ_walk_emphasisr0   s        €€r   r>   z%_inline_elements.<locals>._walk_linksr   sÊ   ø€ ØˆÝ×"Ò" 1Ñ%Ô%ð 	ð 	ˆAØˆN˜1˜S §¢¡¤˜]Ô+¨UÑ3Ô3Ð3Ø/5¸a¿gºgÀa¹j¼jÐRS×RYÒRYÐZ[ÑR\ÔR\Ð&]Ð&]ˆGØð /Ý#'¨¡;¤;�˜Ñ Ø�OŠO˜GÑ$Ô$Ð$Ø—%’%‘'”'ˆCˆCØˆ�q˜˜˜”w Ñ&Ô&Ð&Ð&Ð&r   c                ó¼  •— | sd S t           dft          dft          dffD ]ž\  }}|                     | ¦  «        }|r‚ ‰| d |                     ¦   «         …         |¦  «         t          |¦  «        }d||<    ‰|                     d¦  «        |¦  «          ‰| |                     ¦   «         d …         |¦  «          d S ŒŸ ‰| |rt          |¦  «        nd ¦  «         d S )NÚboldÚstrikeÚitalicTr   )Ú_BOLD_REÚ
_STRIKE_REÚ
_ITALIC_REÚsearchr7   r8   r9   r:   )r'   r(   ÚrxÚkeyr<   Úinner_stylerE   r1   s         €€r   rE   z(_inline_elements.<locals>._walk_emphasis}   sû   ø€ Øð 	ØˆFå! 6Ð*­Z¸Ð,BÅZÐQYÐDZÐ[ð 	ð 	‰GˆB�Ø—	’	˜!‘”ˆAØð Ø�˜q  !§'¢'¡)¤) œ}¨eÑ4Ô4Ð4Ý" 5™kœk�Ø#'�˜CÑ Ø�˜qŸwšw q™zœz¨;Ñ7Ô7Ð7Ø�˜q §¢¡¤  œ{¨EÑ2Ô2Ð2Ø��ðð 	ˆ	�! EÐ3•T˜%‘[”[�[¨tÑ4Ô4Ð4Ð4Ð4r   r$   r,   ©N)r'   r   r(   r)   r   r*   )r'   r   r(   r2   r   r*   © )r$   r?   rE   r>   r0   r1   s     @@@@r   Ú_inline_elementsrS   S   sÀ   øøøø€ ð &(€Hðð ð ð ð ð ð ð	$ð 	$ð 	$ð 	$ð 	$ð 	$ð 	$ð	'ð 	'ð 	'ð 	'ð 	'ð 	'ð 	'ð5ð 5ð 5ð 5ð 5ð 5ð 5ð 	€Dˆˆr�N„N€NØÐ7 °Ð6Ð6Ð7Ð7r   r0   c                ó*   — d„ | D ¦   «         }|pdddœgS )uè  Make a rich_text child-element list safe for Slack.

    Slack rejects any ``rich_text_section`` / ``rich_text_preformatted`` /
    ``rich_text_quote`` whose ``elements`` list is empty or contains a ``text``
    element of zero length (``invalid_blocks``: "missing element" / "must be
    more than 0 characters"). Empty content is common â€” ragged table rows are
    padded with ``""``, agents emit empty code fences around empty tool output,
    blank quote lines and empty list items occur in the wild â€” so drop
    zero-length text elements and, if nothing remains, substitute a single
    space, which renders as blank yet stays schema-valid. Used by every
    rich_text builder so empty content can never poison the whole payload.
    c                ón   — g | ]2}|                      d ¦  «        dk    r|                      d¦  «        ¯0|‘Œ3S r,   )Úget)Ú.0Úes     r   ú
<listcomp>z&_nonempty_elements.<locals>.<listcomp>¢   s;   € Ð
VÐ
VÐ
V� q§u¢u¨V¡}¤}¸Ò'>Ð'>ÀqÇuÂuÈVÁ}Ä}Ð'>ˆ1Ð'>Ð'>Ð'>r   r$   Ú r,   rR   )r0   Úelss     r   Ú_nonempty_elementsr\   •   s.   € ð WÐ
V�hÐ
VÑ
VÔ
V€CØÐ1˜F¨CÐ0Ð0Ð1Ð1r   úOptional[Block]c                óÆ   — t          j        dd| ¦  «                             ¦   «         }|sd S t          |¦  «        t          k    r|d t          dz
  …         dz   }dd|ddœd	œS )
Nz[*_~`]Ú r   õ   â€¦ÚheaderÚ
plain_textT)r-   r$   Úemojir,   )ÚreÚsubÚstripÚlenÚMAX_HEADER_TEXT)r$   Úcleans     r   Ú_header_blockrj   ¦   st   € åŒF�9˜b $Ñ'Ô'×-Ò-Ñ/Ô/€EØð ð ˆtÝ
ˆ5�z„z•OÒ#Ð#ØÐ+�¨!Ñ+Ð+Ô,¨uÑ4ˆØ¨|ÀUÐUYÐ&ZÐ&ZÐ[Ð[Ð[r   ÚBlockc                 ó
   — ddiS )Nr-   ÚdividerrR   rR   r   r   Ú_divider_blockrn   ³   s   € Ø�IÐÐr   c                ó\   — ddt          d|                      d¦  «        dœg¦  «        dœgdœS )NÚ	rich_textÚrich_text_preformattedr$   Ú
r,   ©r-   r0   )r\   Úrstrip©r$   s    r   Ú_preformatted_blockrv   ·   sM   € ð ð 1Ý.¸ÈÏÊÐUYÑIZÔIZÐ0[Ð0[Ð/\Ñ]Ô]ðð ð
ðð ð r   Úlinesú	List[str]c                óÔ   — g }t          | ¦  «        D ]A\  }}|r|                     dddœ¦  «         |                     t          |¦  «        ¦  «         ŒBddt	          |¦  «        dœgdœS )Nr$   rr   r,   rp   Úrich_text_quoters   )Ú	enumerater.   ÚextendrS   r\   )rw   Úsection_childrenÚiÚlns       r   Ú_quote_blockr€   Ä   s’   € Ø-/ÐÝ˜5Ñ!Ô!ð 6ð 6‰ˆˆ2Øð 	DØ×#Ò#¨V¸TÐ$BÐ$BÑCÔCÐCØ×ÒÕ 0°Ñ 4Ô 4Ñ5Ô5Ð5Ð5àØ/Õ=OÐP`Ñ=aÔ=aÐbÐbÐcðð ð r   ÚitemsúList[Tuple[int, bool, str]]c           	     óø   — g }d}d}| D ]m\  }}}||f}||k    r"d|rdnd|g dœ}|                      |¦  «         |}|€Œ5|d                               dt          t          |¦  «        ¦  «        dœ¦  «         Œnd	|dœS )
a0  Build ONE rich_text block from consecutive list items.

    ``items`` is a list of ``(indent, ordered, text)``.  Each contiguous run
    sharing the same (indent, ordered) becomes a ``rich_text_list`` element;
    indentation changes start a new element, which is how Slack renders true
    nesting.
    NÚrich_text_listÚorderedÚbullet)r-   r(   Úindentr0   r0   Úrich_text_sectionrs   rp   )r.   r\   rS   )r�   r0   ÚcurÚcur_keyr‡   r…   r$   rO   s           r   Ú_list_blockr‹   Ð   sÏ   € ð &(€HØ$(€CØ*.€GØ!&ð 
ð 
Ñˆ�˜Ø�wÐˆØ�'Š>ˆ>à(Ø&-Ð;˜˜°8Ø Øð	ð ˆCð �OŠO˜CÑ Ô Ð ØˆGØˆ;ð ØˆJŒ×ÒØ(Õ6HÕIYÐZ^ÑI_ÔI_Ñ6`Ô6`ÐaÐañ	
ô 	
ð 	
ð 	
ð  ¨XÐ6Ð6Ð6r   c                ó   — dd| dœdœS )NÚsectionÚmrkdwnr,   rR   ru   s    r   Ú_section_blockr�   ñ   s   € Ø°À$Ð'GÐ'GÐHÐHÐHr   Úsep_linec                óŽ  — g }|                       ¦   «                               d¦  «                             d¦  «        D ]‡}|                      ¦   «         }|                     d¦  «        }|                     d¦  «        }|r|r|                     d¦  «         ŒZ|r|                     d¦  «         Œr|                     d¦  «         Œˆ|S )z’Parse a markdown separator row (``|:--|:-:|--:|``) into column aligns.

    Returns a list of ``"left"``/``"center"``/``"right"`` per column.
    Ú|ú:ÚcenterÚrightÚleft)rf   ÚsplitÚ
startswithÚendswithr.   )r�   ÚalignsÚcellÚcr–   r•   s         r   Ú_parse_alignmentr�   ú   sÆ   € ð
 €FØ—’Ñ Ô ×&Ò& sÑ+Ô+×1Ò1°#Ñ6Ô6ð 	"ð 	"ˆØ�JŠJ‰LŒLˆØ�|Š|˜CÑ Ô ˆØ—
’
˜3‘”ˆØð 	"�Eð 	"Ø�MŠM˜(Ñ#Ô#Ð#Ð#Øð 	"Ø�MŠM˜'Ñ"Ô"Ð"Ð"à�MŠM˜&Ñ!Ô!Ð!Ð!Ø€Mr   Úrowc                ó¶   — |                       ¦   «                               d¦  «                             dd¦  «        }d„ |                     d¦  «        D ¦   «         S )zšSplit a markdown table row into trimmed cell strings.

    Respects backslash-escaped pipes (``\|``) so they aren't treated as
    column separators.
    r’   z\|ú PIPE c                ó^   — g | ]*}|                      ¦   «                              d d¦  «        ‘Œ+S )r    r’   )rf   Úreplace)rW   rœ   s     r   rY   z_split_row.<locals>.<listcomp>  s0   € ÐQÐQÐQ°qˆA�GŠG‰IŒI×Ò˜n¨cÑ2Ô2ÐQÐQÐQr   )rf   r¢   r—   )rž   Ú	protecteds     r   Ú
_split_rowr¤     sO   € ð —	’	‘”×!Ò! #Ñ&Ô&×.Ò.¨u°nÑEÔE€IØQÐQ¸I¿OºOÈCÑ<PÔ<PÐQÑQÔQÐQr   úDict[str, Any]c                óH   — ddt          t          | ¦  «        ¦  «        dœgdœS )a  A ``rich_text`` table cell carrying inline-formatted content.

    Empty cells are common (ragged rows are padded with ``""``); Slack rejects
    a cell whose section is empty or carries a zero-length text element, so the
    elements are routed through ``_nonempty_elements``.
    rp   rˆ   rs   )r\   rS   ru   s    r   Ú_rich_text_cellr§     s9   € ð à(Õ6HÕIYÐZ^ÑI_ÔI_Ñ6`Ô6`ÐaÐað
ðð ð r   Úrowsc                óÂ  — d„ | D ¦   «         }|sdS t          d„ |D ¦   «         ¦  «        }t          |¦  «        t          k    s|t          k    rdS |D ]+}|                     dg|t          |¦  «        z
  z  ¦  «         Œ,t          d„ |D ¦   «         ¦  «        }|t          k    rdS t          |¦  «        }d}t          t          |t          ¦  «        ¦  «        D ]'}|t          |¦  «        k     r||         nd}	|	dk    r|}Œ(g }
t          |dz   ¦  «        D ]6}|t          |¦  «        k     r||         nd}	|
 
                    d	|	i¦  «         Œ7d
d„ |D ¦   «         dœ}|
r|
|d<   |S )u­  Build a native Slack ``table`` block from markdown pipe-table rows.

    ``rows`` includes the header row (index 0) and body rows; ``sep_line`` is
    the ``|---|`` alignment row (already consumed by the caller).  Returns
    ``None`` when the table exceeds Slack's limits (100 rows / 20 cols /
    10,000 aggregate cell chars) or parses to nothing â€” the caller then falls
    back to the monospace preformatted rendering.
    c                óT   — g | ]%}|                      ¦   «         ¯t          |¦  «        ‘Œ&S rR   )rf   r¤   ©rW   Úrs     r   rY   z _table_block.<locals>.<listcomp>0  s+   € Ð7Ð7Ð7 ¨Q¯WªW©Y¬YÐ7�j˜‰mŒmÐ7Ð7Ð7r   Nc              3  ó4   K  — | ]}t          |¦  «        V — Œd S rQ   ©rg   r«   s     r   ú	<genexpr>z_table_block.<locals>.<genexpr>3  ó(   è è € Ð'Ð'˜1•�A‘”Ð'Ð'Ð'Ð'Ð'Ð'r   r_   c              3  ó>   K  — | ]}|D ]}t          |¦  «        V — ŒŒd S rQ   r®   ©rW   r¬   rœ   s      r   r¯   z_table_block.<locals>.<genexpr>:  s5   è è € Ð8Ð8 °aÐ8Ð8°•c˜!‘f”fÐ8Ð8Ð8Ð8Ð8Ð8Ð8r   éÿÿÿÿr–   r   ÚalignÚtablec                ó&   — g | ]}d „ |D ¦   «         ‘ŒS )c                ó,   — g | ]}t          |¦  «        ‘ŒS rR   )r§   )rW   r›   s     r   rY   z+_table_block.<locals>.<listcomp>.<listcomp>O  s    € Ð8Ð8Ð8¨D•/ $Ñ'Ô'Ð8Ð8Ð8r   rR   )rW   rž   s     r   rY   z _table_block.<locals>.<listcomp>O  s'   € ÐKÐKÐK¸SÐ8Ð8°CÐ8Ñ8Ô8ÐKÐKÐKr   )r-   r¨   Úcolumn_settings)Úmaxrg   ÚMAX_TABLE_ROWSÚMAX_TABLE_COLSr|   ÚsumÚMAX_TABLE_CHARSr�   Úranger    r.   )r¨   r�   ÚparsedÚncolsr¬   Útotal_charsrš   Úlast_non_defaultrœ   r´   r¸   Úblocks               r   Ú_table_blockrÄ   '  s·  € ð 8Ð7 TÐ7Ñ7Ô7€FØð ØˆtÝÐ'Ð' Ð'Ñ'Ô'Ñ'Ô'€Eå
ˆ6�{„{•^Ò#Ð# u­~Ò'=Ð'=ØˆtØð *ð *ˆØ	�Š�"�˜¥ Q¡¤™Ñ(Ñ)Ô)Ð)Ð)åÐ8Ð8 fÐ8Ñ8Ô8Ñ8Ô8€KØ•_Ò$Ð$Øˆtå˜hÑ'Ô'€Fð
 ÐÝ•3�u�nÑ-Ô-Ñ.Ô.ð !ð !ˆØ¥ V¡¤š_˜_��q”	�	°&ˆØ�FŠ?ˆ?Ø ÐøØ,.€OÝÐ# aÑ'Ñ(Ô(ð 1ð 1ˆØ¥ V¡¤š_˜_��q”	�	°&ˆØ×Ò ¨Ð/Ñ0Ô0Ð0Ð0ð ØKÐKÀFÐKÑKÔKðð €Eð ð 3Ø#2ˆÐÑ Ø€Lr   c           	     óâ  ‡‡‡— g Š| D ]&Št          ‰¦  «        }‰                     |¦  «         Œ'‰sd                     | ¦  «        S t          d„ ‰D ¦   «         ¦  «        }‰D ]+Š‰                     dg|t          ‰¦  «        z
  z  ¦  «         Œ,ˆfd„t          |¦  «        D ¦   «         Šg }t          ‰¦  «        D ]¢\  }Šd                     ˆˆfd„t          |¦  «        D ¦   «         ¦  «        }|                     |                     ¦   «         ¦  «         |dk    rA|                     d                     ˆfd	„t          |¦  «        D ¦   «         ¦  «        ¦  «         Œ£d                     |¦  «        S )
zERender markdown pipe-table rows as aligned monospace text (fallback).rr   c              3  ó4   K  — | ]}t          |¦  «        V — Œd S rQ   r®   r«   s     r   r¯   z _render_table.<locals>.<genexpr>^  r°   r   r_   c                óH   •‡— g | ]Št          ˆfd „‰D ¦   «         ¦  «        ‘ŒS )c              3  óB   •K  — | ]}t          |‰         ¦  «        V — Œd S rQ   r®   r²   s     €r   r¯   z+_render_table.<locals>.<listcomp>.<genexpr>a  s-   øè è € Ð,Ð, •#�a˜”d‘)”)Ð,Ð,Ð,Ð,Ð,Ð,r   )r¹   )rW   rœ   r¿   s    @€r   rY   z!_render_table.<locals>.<listcomp>a  s7   øø€ ÐCÐCÐC°�cÐ,Ð,Ð,Ð, VÐ,Ñ,Ô,Ñ,Ô,ÐCÐCÐCr   z | c              3  óZ   •K  — | ]%}‰|                               ‰|         ¦  «        V — Œ&d S rQ   )Úljust)rW   rœ   r¬   Úwidthss     €€r   r¯   z _render_table.<locals>.<genexpr>d  s7   øè è € ÐFÐF°A˜!˜Aœ$Ÿ*š* V¨A¤YÑ/Ô/ÐFÐFÐFÐFÐFÐFr   r   z-+-c              3  ó.   •K  — | ]}d ‰|         z  V — ŒdS )Ú-NrR   )rW   rœ   rË   s     €r   r¯   z _render_table.<locals>.<genexpr>g  s+   øè è € Ð'NÐ'N¸A¨¨f°Q¬i©Ð'NÐ'NÐ'NÐ'NÐ'NÐ'Nr   )	r¤   r.   Újoinr¹   r|   rg   r¾   r{   rt   )	r¨   ÚcellsrÀ   Ú	out_linesÚrir   r¿   r¬   rË   s	         @@@r   Ú_render_tablerÒ   V  s…  øøø€ à €FØð ð ˆÝ˜1‘”ˆØ�Š�eÑÔÐÐØð Ø�yŠy˜‰ŒÐÝÐ'Ð' Ð'Ñ'Ô'Ñ'Ô'€EØð *ð *ˆØ	�Š�"�˜¥ Q¡¤™Ñ(Ñ)Ô)Ð)Ð)ØCÐCÐCÐCµe¸E±l´lÐCÑCÔC€FØ€IÝ˜6Ñ"Ô"ð Pð P‰ˆˆAØ�zŠzÐFÐFÐFÐFÐF½¸u¹¼ÐFÑFÔFÑFÔFˆØ×Ò˜Ÿš™œÑ'Ô'Ð'Ø�Š7ˆ7Ø×Ò˜UŸZšZÐ'NÐ'NÐ'NÐ'NÅÀuÁÄÐ'NÑ'NÔ'NÑNÔNÑOÔOÐOøØ�9Š9�YÑÔÐr   ÚmarkdownúOptional[List[Block]]c                ó6  ‡‡‡— | r|                       ¦   «         sdS |pd„ Š	 g Š|                      dd¦  «                             d¦  «        }d}t          |¦  «        }g Šdˆˆˆfd„}||k     �rñ||         }|                      ¦   «         s |¦   «          |d	z  }Œ3t                               |¦  «        }|rè |¦   «          |                     d	¦  «        }g }	|d	z  }||k     r€||                              ¦   «                              |¦  «        sS|	 	                    ||         ¦  «         |d	z  }||k     r-||                              ¦   «                              |¦  «        ¯S|d	z  }‰ 	                    t          d                     |	¦  «        ¦  «        ¦  «         �Œ7t                               |¦  «        r2 |¦   «          ‰ 	                    t          ¦   «         ¦  «         |d	z  }�Œƒt                               |¦  «        }
|
rJ |¦   «          t          |
                     d
¦  «        ¦  «        }|�‰ 	                    |¦  «         |d	z  }�Œéd|v �r|d	z   |k     �rt                                ||d	z            ¦  «        rì |¦   «          |}||d	z            }|g}|d
z  }||k     rnd||         v rd||                               ¦   «         rJ| 	                    ||         ¦  «         |d	z  }||k     r$d||         v r||                               ¦   «         °Jt#          ||¦  «        }|�‰ 	                    |¦  «         n/‰ 	                    t          t%          |¦  «        ¦  «        ¦  «         �Œt&                               |¦  «        rŒ |¦   «          g }||k     rVt&                               ||         ¦  «        }|sn3| 	                    |                     d	¦  «        ¦  «         |d	z  }||k     °V‰ 	                    t)          |¦  «        ¦  «         �Œ­t+          |¦  «        �r |¦   «          g }||k     �rãt,                               ||         ¦  «        }t.                               ||         ¦  «        }|rR| 	                    t1          |                     d	¦  «        ¦  «        d|                     d
¦  «        f¦  «         |d	z  }�nH|rQ| 	                    t1          |                     d	¦  «        ¦  «        d|                     d¦  «        f¦  «         |d	z  }nõ||                               ¦   «         rU||                              d¦  «        r:|r8|d         \  }}}|||dz   ||                               ¦   «         z   f|d<   |d	z  }n†||                               ¦   «         sk|ri|d	z   }||k     r?||                               ¦   «         s%|d	z  }||k     r||                               ¦   «         ¯%||k     rt+          ||         ¦  «        r|}nnn||k     �°ã‰ 	                    t3          |¦  «        ¦  «         �Œ×‰ 	                    |¦  «         |d	z  }||k     �°ñ |¦   «          ‰sdS t          ‰¦  «        t4          k    rdS ‰S # t6          $ r Y dS w xY w)uc  Convert agent markdown to a Slack Block Kit ``blocks`` list.

    Args:
        markdown: The agent's response text (standard markdown).
        mrkdwn_fn: Optional callable converting a markdown paragraph to Slack
            mrkdwn for ``section`` blocks (the adapter passes
            ``format_message``).  When ``None``, the raw paragraph text is used.

    Returns:
        A list of Block Kit block dicts, or ``None`` when the content is empty,
        exceeds Slack's structural limits, or hits an unexpected shape â€” the
        caller then falls back to the flat ``text`` payload.  Never raises.
    Nc                ó   — | S rQ   rR   )r'   s    r   ú<lambda>zrender_blocks.<locals>.<lambda>„  s   €  !€ r   z
rr   r   r   r*   c                 ó  •— ‰sd S d                      ‰¦  «                             ¦   «         } ‰                     ¦   «          | sd S  ‰| ¦  «        }t          |t          ¦  «        D ]$}‰                     t          |¦  «        ¦  «         Œ%d S )Nrr   )rÎ   rf   ÚclearÚ_split_textÚMAX_SECTION_TEXTr.   r�   )r$   ÚrenderedÚchunkÚblocksÚfmtÚparas      €€€r   Ú
flush_paraz!render_blocks.<locals>.flush_para�  s“   ø€ Øð Ø�Ø—9’9˜T‘?”?×(Ò(Ñ*Ô*ˆDØ�JŠJ‰LŒLˆLØð Ø�Ø�s˜4‘y”yˆHå$ XÕ/?Ñ@Ô@ð 5ð 5�Ø—’�n¨UÑ3Ô3Ñ4Ô4Ð4Ð4ð5ð 5r   r   r   r’   FTé   )rZ   r   r³   rZ   )r   r*   )rf   r¢   r—   rg   Ú	_FENCE_REr   r9   Úlstripr˜   r.   rv   rÎ   Ú_HR_RErn   Ú
_HEADER_RErj   Ú_TABLE_SEP_RErÄ   rÒ   Ú	_QUOTE_REr€   r   r   r   r#   r‹   Ú
MAX_BLOCKSÚ	Exception)rÓ   Ú	mrkdwn_fnrw   r~   Únrá   r   ÚfenceÚmarkerÚbodyÚhmra   Ú
header_rowr�   Útrowsrµ   ÚqlinesÚqmr�   ÚbmÚomr‡   r…   ÚtxtÚjrÞ   rß   rà   s                            @@@r   Úrender_blocksrù   p  sÈ  øøø€ ð" ð ˜8Ÿ>š>Ñ+Ô+ð Øˆtà
Ð
$˜˜€CðQØ ˆØ× Ò  ¨Ñ.Ô.×4Ò4°TÑ:Ô:ˆØˆÝ�‰JŒJˆØˆð
	5ð 
	5ð 
	5ð 
	5ð 
	5ð 
	5ð 
	5ð 
	5ð �!Še‰eØ˜”8ˆDð —:’:‘<”<ð Ø�
‘”�Ø�Q‘�Øõ —O’O DÑ)Ô)ˆEØð 
Ø�
‘”�ØŸš Q™œ�Ø"$�Ø�Q‘�Ø˜!’e�e E¨!¤H§O¢OÑ$5Ô$5×$@Ò$@ÀÑ$HÔ$H�eØ—K’K  a¤Ñ)Ô)Ð)Ø˜‘F�Að ˜!’e�e E¨!¤H§O¢OÑ$5Ô$5×$@Ò$@ÀÑ$HÔ$H�eð �Q‘�Ø—’Õ1°$·)²)¸D±/´/ÑBÔBÑCÔCÐCÙõ �|Š|˜DÑ!Ô!ð Ø�
‘”�Ø—’�nÑ.Ô.Ñ/Ô/Ð/Ø�Q‘�Ùõ ×!Ò! $Ñ'Ô'ˆBØð Ø�
‘”�Ý& r§x¢x°¡{¤{Ñ3Ô3�ØÐ%Ø—M’M &Ñ)Ô)Ð)Ø�Q‘�Ùð �dˆ{‰{˜q 1™u qšy™y­]×-@Ò-@ÀÀqÈ1ÁuÄÑ-NÔ-N˜yØ�
‘”�Ø!�
Ø   Q¡œ<�Ø#˜�Ø�Q‘�Ø˜!’e�e  u¨Q¤x  °E¸!´H·N²NÑ4DÔ4D Ø—L’L  q¤Ñ*Ô*Ð*Ø˜‘F�Að ˜!’e�e  u¨Q¤x  °E¸!´H·N²NÑ4DÔ4D õ
 % U¨HÑ5Ô5�ØÐ$Ø—M’M %Ñ(Ô(Ð(Ð(à—M’MÕ"5µmÀEÑ6JÔ6JÑ"KÔ"KÑLÔLÐLÙõ �Š˜tÑ$Ô$ð 
Ø�
‘”�Ø$&�Ø˜!’e�eÝ"Ÿš¨¨q¬Ñ2Ô2�BØð ØØ—M’M "§(¢(¨1¡+¤+Ñ.Ô.Ð.Ø˜‘F�Að ˜!’e�eð —’�l¨6Ñ2Ô2Ñ3Ô3Ð3Ùõ ˜TÑ"Ô"ñ $Ø�
‘”�Ø57�Ø˜!’e‘eÝ#×)Ò)¨%°¬(Ñ3Ô3�BÝ$×*Ò*¨5°¬8Ñ4Ô4�BØð ØŸš¥m°B·H²H¸Q±K´KÑ&@Ô&@À%ÈÏÊÐRSÉÌÐ%UÑVÔVÐVØ˜Q™˜™Øð ØŸš¥m°B·H²H¸Q±K´KÑ&@Ô&@À$ÈÏÊÐQRÉÌÐ%TÑUÔUÐUØ˜Q™˜˜Ø˜qœŸšÑ)Ô)ð ¨e°A¬h×.AÒ.AÀ+Ñ.NÔ.Nð ÐSXð à/4°R¬yÑ,˜ ¨Ø%+¨W°c¸C±iÀ%ÈÄ(Ç.Â.ÑBRÔBRÑ6RÐ$S˜˜b™	Ø˜Q™˜˜Ø" 1œXŸ^š^Ñ-Ô-ð °%ð ð  ™E˜Ø !še˜e¨E°!¬H¯NªNÑ,<Ô,<˜eØ ™F˜Að   !še˜e¨E°!¬H¯NªNÑ,<Ô,<˜eà˜qš5˜5¥]°5¸´8Ñ%<Ô%<˜5Ø !˜A˜Aà!àð? ˜!’e‘eð@ —’�k¨%Ñ0Ô0Ñ1Ô1Ð1Ùð �KŠK˜ÑÔÐØ�‰FˆAðc �!Še‰eðf 	ˆ
‰Œˆàð 	Ø�4Ýˆv‰;Œ;�Ò#Ð#ð �4ØˆøÝð ð ð àˆtˆtðøøøs   ¢Y
Z
 Ù.Z
 ÚZ
 Ú

ZÚZÚlimitc                óf  — t          | ¦  «        |k    r| gS d| v rt          |dz
  |dz  d¦  «        n|}g }| }t          |¦  «        |k    rl|                     dd|¦  «        }|dk    r|}|                     |d|…         ¦  «         ||d…                              d¦  «        }t          |¦  «        |k    °l|r|                     |¦  «         t          |¦  «        dk    rPd| v rLg }d}|D ]C}|rd	|z   }|                     d¦  «        dz  dk    }	|	r|d
z  }|	}|                     |¦  «         ŒD|}|S )a²  Split ``text`` into <= ``limit``-char chunks on line, then hard, boundaries.

    Chunks are fence-balanced: when a split lands inside a ``` code span that
    survived into section text (the renderer normally routes fenced blocks to
    ``rich_text_preformatted``, but mrkdwn text can still carry fences), the
    fence is closed at the end of the chunk and reopened on the next so each
    section renders correctly on its own.
    z```é   r   r   rr   r   NFz```
z
```)rg   r¹   Úrfindr.   rä   Úcount)
r$   rú   Úsplit_limitÚoutÚ	remainingÚcutÚbalancedÚreopenrÝ   Úodds
             r   rÚ   rÚ     sv  € õ ˆ4�y„y�EÒÐØˆvˆà38¸D°=°=•#�e˜a‘i ¨!¡¨QÑ/Ô/Ð/Àe€KØ€CØ€IÝ
ˆi‰.Œ.˜;Ò
&Ð
&Ø�oŠo˜d A {Ñ3Ô3ˆØ�!Š8ˆ8ØˆCØ�
Š
�9˜T˜c˜T”?Ñ#Ô#Ð#Ø˜c˜d˜d”O×*Ò*¨4Ñ0Ô0ˆ	õ ˆi‰.Œ.˜;Ò
&Ð
&ð ð Ø�
Š
�9ÑÔÐÝ
ˆ3�x„x�!‚|€|˜ ˜˜Ø ˆØˆØð 	#ð 	#ˆEØð (Ø %™�Ø—+’+˜eÑ$Ô$ qÑ(¨AÒ-ˆCØð !Ø˜Ñ �ØˆFØ�OŠO˜EÑ"Ô"Ð"Ð"ØˆØ€Jr   Útext_objc                óÆ   — |                       d¦  «        pd}t          |¦  «        |k    r| S t          | ¦  «        }|d|dz
  …                              ¦   «         dz   |d<   |S )zAReturn ``text_obj`` with its ``text`` clamped to ``limit`` chars.r$   r_   Nr   r`   )rV   rg   r8   rt   )r  rú   r÷   Úclampeds       r   Ú_clamp_text_objr	  E  se   € à
�,Š,�vÑ
Ô
Ð
$ "€CÝ
ˆ3�x„x�5ÒÐØˆÝ�8‰nŒn€GØ˜+˜E A™I˜+Ô&×-Ò-Ñ/Ô/°%Ñ7€GˆF�OØ€Nr   rÞ   c                ó@  — | sdS 	 g }| D �]ð}t          |t          ¦  «        r|                     d¦  «        sŒ.|d         }|dk    rÏ|                     d¦  «        }t          |                     d¦  «        ¦  «        p!t          |                     d¦  «        ¦  «        }t          |t          ¦  «        r[|                     d¦  «        pd                     ¦   «         s|sŒÖt          |t          ¦  «        }||urt          |¦  «        }||d<   �nÖ|s�Œ	�nÐ|dk    r„|                     d¦  «        }t          |t          ¦  «        r)|                     d¦  «        pd                     ¦   «         s�Œft          |t          ¦  «        }||urt          |¦  «        }||d<   �nF|d	k    rc|                     d
¦  «        pg }|s�Œ¶d„ |D ¦   «         }t          d„ t          ||¦  «        D ¦   «         ¦  «        rt          |¦  «        }||d
<   nÝ|dv r|                     d
¦  «        s�ŒnÁ|dk    r»|                     d¦  «        s�Œ7|                     d¦  «        }	t          |	t          ¦  «        rzt          d„ |	D ¦   «         ¦  «        rad„ |	D ¦   «         }
|
r&|
d         s|
                     ¦   «          |
r|
d         ¯t          |¦  «        }|
r|
|d<   n|                     dd¦  «         |                     |¦  «         �Œò|sdS |dt          …         S # t          $ r Y dS w xY w)um  Clamp an outbound ``blocks`` payload to Slack's hard limits.

    Defensive boundary applied wherever the adapter attaches ``blocks`` to
    ``chat.postMessage`` / ``chat.update``.  One oversized or malformed block
    fails the WHOLE call with ``invalid_blocks`` â€” approval cards then never
    update and messages silently drop â€” so instead of trusting every builder,
    the payload is normalized just before the API call:

    * ``section`` / ``context`` text objects are truncated to the 3000-char
      cap with an ellipsis (Slack HTML-escapes ``< > &`` on storage, so text
      echoed back through interaction payloads can exceed the limit that the
      send path originally budgeted for â€” see #53693 / #62054).
    * ``header`` text is truncated to its 150-char cap.
    * Empty blocks (no text / no elements / no rows) are dropped â€” Slack
      rejects zero-length text objects and empty element lists.
    * ``table.column_settings`` entries must all be objects; ``null`` entries
      (emitted by older renderers, per the "use null to skip" misreading of
      the schema) are replaced with ``{}`` and default trailing entries are
      trimmed (#56615).
    * The payload is capped at Slack's 50-block maximum.

    Returns the sanitized list, or ``None`` when nothing valid remains â€” the
    caller then sends the plain ``text`` fallback alone.  Never raises.
    Nr-   r�   r$   ÚfieldsÚ	accessoryr_   ra   Úcontextr0   c                ó”   — g | ]E}t          |t          ¦  «        r,|                     d ¦  «        dv rt          |t          ¦  «        n|‘ŒFS )r-   )rŽ   rb   )Ú
isinstancer8   rV   r	  rÛ   )rW   r/   s     r   rY   z#sanitize_blocks.<locals>.<listcomp>‹  se   € ð ð ð ð õ " "¥dÑ+Ô+ðØ02·²°v±´ÐBZÐ0ZÐ0Zõ $ BÕ(8Ñ9Ô9Ð9àðð ð r   c              3  ó$   K  — | ]\  }}||uV — Œd S rQ   rR   )rW   rœ   rX   s      r   r¯   z"sanitize_blocks.<locals>.<genexpr>‘  s*   è è € ÐIÐI¡d a¨�q �zÐIÐIÐIÐIÐIÐIr   )rp   ÚactionsÚcontext_actionsrµ   r¨   r¸   c              3  óB   K  — | ]}t          |t          ¦  «         V — Œd S rQ   ©r  r8   ©rW   Úcss     r   r¯   z"sanitize_blocks.<locals>.<genexpr>�  s@   è è € ð 6ð 6Ø13�
 2¥tÑ,Ô,Ð,ð6ð 6ð 6ð 6ð 6ð 6r   c                ó@   — g | ]}t          |t          ¦  «        r|ni ‘ŒS rR   r  r  s     r   rY   z#sanitize_blocks.<locals>.<listcomp>   s+   € ÐSÐSÐSÀB¥:¨bµ$Ñ#7Ô#7Ð?˜R˜R¸RÐSÐSÐSr   r³   )r  r8   rV   r   rf   r	  rÛ   rh   ÚanyÚzipÚlistÚpopr.   ré   rê   )rÞ   r   rÃ   Úbtyper  Úhas_bodyr  r0   Úclamped_elsÚsettingsÚfixeds              r   Úsanitize_blocksr!  O  s°  € ð2 ð ØˆtðFØˆØð =	ñ =	ˆEÝ˜e¥TÑ*Ô*ð °%·)²)¸FÑ2CÔ2Cð ØØ˜&”MˆEà˜	Ò!Ð!Ø Ÿ9š9 VÑ,Ô,�Ý §	¢	¨(Ñ 3Ô 3Ñ4Ô4ÐT½¸U¿YºYÀ{Ñ=SÔ=SÑ8TÔ8T�Ý˜h­Ñ-Ô-ð Ø$ŸLšL¨Ñ0Ô0Ð6°B×=Ò=Ñ?Ô?ð !Èð !Ø Ý-¨hÕ8HÑIÔI�GØ hÐ.Ð.Ý $ U¡¤˜Ø(/˜˜f™ùØ!ð Ùñð ˜(Ò"Ð"Ø Ÿ9š9 VÑ,Ô,�Ý! (­DÑ1Ô1ð ¸(¿,º,ÀvÑ:NÔ:NÐ:TÐRT×9[Ò9[Ñ9]Ô9]ð ÙÝ)¨(µOÑDÔD�Ø (Ð*Ð*Ý  ™KœK�EØ$+�E˜&‘Mùà˜)Ò#Ð#Ø Ÿ9š9 ZÑ0Ô0Ð6°B�Øð Ùðð ð 'ð	ñ ô �õ ÐIÐI­c°+¸xÑ.HÔ.HÐIÑIÔIÑIÔIð 4Ý  ™KœK�EØ(3�E˜*Ñ%øàÐEÐEÐEØ—y’y Ñ,Ô,ð Ùðð ˜'Ò!Ð!Ø—y’y Ñ(Ô(ð ÙØ Ÿ9š9Ð%6Ñ7Ô7�Ý˜h­Ñ-Ô-ð 
;µ#ð 6ð 6Ø7?ð6ñ 6ô 6ñ 3ô 3ð 
;ð TÐSÈ(ÐSÑSÔS�EØð $¨¨b¬	ð $ØŸ	š	™œ˜ð  ð $¨¨b¬	ð $å  ™KœK�EØð ;Ø38˜Ð/Ñ0Ð0àŸ	š	Ð"3°TÑ:Ô:Ð:à�JŠJ�uÑÔÐÑàð 	Ø�4Ø�;•J�;ÔÐøÝð ð ð àˆtˆtðøøøs   †K8L Ì L Ì
LÌL)r   r   r   r   )r   r   r   r   )r$   r   r   r%   )r0   r%   r   r%   )r$   r   r   r]   )r   rk   )r$   r   r   rk   )rw   rx   r   rk   )r�   r‚   r   rk   )r�   r   r   rx   )rž   r   r   rx   )r$   r   r   r¥   )r¨   rx   r�   r   r   r]   )r¨   rx   r   r   rQ   )rÓ   r   r   rÔ   )r$   r   rú   r   r   rx   )r  r¥   rú   r   r   r¥   )rÞ   rÔ   r   rÔ   )2Ú__doc__Ú
__future__r   rd   Útypingr   r   r   r   r   ré   rÛ   rh   rº   r»   r½   r   rk   Úcompilerå   ræ   rã   r   r   rè   rç   r   r#   r5   rC   rJ   rL   rK   rS   r\   rj   rn   rv   r€   r‹   r�   r�   r¤   r§   rÄ   rÒ   rù   rÚ   r	  r!  rR   r   r   ú<module>r&     s  ððð ð8 #Ð "Ð "Ð "Ð "Ð "à 	€	€	€	Ø 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3Ð 3ð €
ØÐ Ø€à€Ø€Ø€àˆS�#ˆXŒ€ð 
ˆŒÐ7Ñ	8Ô	8€ØˆRŒZÐ<Ñ=Ô=€
ØˆBŒJÐ0Ñ1Ô1€	ØˆbŒjÐ3Ñ4Ô4€ØˆRŒZÐ.Ñ/Ô/€
ØˆBŒJÐ+Ñ,Ô,€	Ø�”
ÐOÑPÔP€ðCð Cð Cð Cð
ð ð ð ð �"”*˜\Ñ*Ô*€Øˆ2Œ:ÐPÑQÔQ€Øˆ2Œ:Ð4Ñ5Ô5€ØˆRŒZÐZÑ[Ô[€
ØˆRŒZ˜Ñ%Ô%€
ð:8ð :8ð :8ð :8ðD2ð 2ð 2ð 2ð"
\ð 
\ð 
\ð 
\ðð ð ð ð
ð 
ð 
ð 
ð	ð 	ð 	ð 	ð7ð 7ð 7ð 7ðBIð Ið Ið Iðð ð ð ð&Rð Rð Rð Rðð ð ð ð,ð ,ð ,ð ,ð^ ð  ð  ð  ð8 ðgð gð gð gð gðT#ð #ð #ð #ðVð ð ð ðað að að að að ar   