a
    oÝEbù" ã                
   @  s  d dl mZ d dlmZ d dlmZ d dlZd dlmZm	Z	m
Z
mZmZmZmZmZmZmZ d dlmZ d dlZd dlmZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dl m!Z!m"Z"m#Z#m$Z$m%Z%m&Z& d dl'm(Z( d dl)m*  m+Z, eddd�Z-d dl.m/Z0 ee1e	f Z2ee2eeee2 f f Z3ee1ee1e4e5f f Z6ee6 Z7ee1e7f Z8G dd„ deƒZ9ee9 Z:ee;ee"f Z<dddœdd„Z=G dd„ dƒZ>ddddddœdd„Z?did!d"œd#d$„Z@djd%dd&d'd(œd)d*„ZAdd"œd+d,„ZBd-d-d.œd/d0„ZCdkdd&ddd2œd3d4„ZDd5dd6d5d7œd8d9„ZEd:d;„ ZFd<d=„ ZGdld?d6d@dd6d6d6d5dAœdBdC„ZHdDdEœdFdG„ZIdHdIdJœdKdL„ZJdMd%dNdOœdPdQ„ZKG dRdS„ dSƒZLd-d6ddTœdUdV„ZMd-dd6dWœdXdY„ZNdmdIddddZœd[d\„ZOdnd]dddddd^œd_d`„ZPdadddbœdcdd„ZQdIdId.œdedf„ZRdgdh„ ZSdS )oé    )Úannotations)Údefaultdict)ÚpartialN)
ÚAnyÚCallableÚDefaultDictÚDictÚListÚOptionalÚSequenceÚTupleÚ	TypedDictÚUnion)Úuuid4)Ú
get_option)Úlib)ÚLevel)Úimport_optional_dependency)Ú	ABCSeries)Ú	DataFrameÚIndexÚ
IndexSliceÚ
MultiIndexÚSeriesÚisna)Úis_list_likeÚjinja2z DataFrame.style requires jinja2.)Úextra©Úescapec                   @  s   e Zd ZU ded< ded< dS )ÚCSSDictÚstrÚselectorÚCSSPropertiesÚpropsN)Ú__name__Ú
__module__Ú__qualname__Ú__annotations__© r)   r)   ú^/home/ja/django-apps/lartica_env/lib/python3.9/site-packages/pandas/io/formats/style_render.pyr    3   s   
r    r   )ÚobjÚreturnc                 C  s   d| j  | _ | S )z$Adjust docstrings for Numpydoc GLO1.Ú
)Ú__doc__©r+   r)   r)   r*   Ú_gl01_adjust<   s    r0   c                   @  s�  e Zd ZdZee dd¡ƒZeejedd�ƒZ	ee	 
d¡ƒZee	 
d¡ƒZee	 
d¡ƒZee	 
d	¡ƒZdGdddddddddœdd„ZdHddddddœdd„Zdddddœdd„Zdd„ ZdIdddddd œd!d"„Zddd#œd$d%„Zd&dd'd(œd)d*„Zd&dd'd(œd+d,„Zd'ddd-œd.d/„Zdd0d1œd2d3„Zd&dd'd4œd5d6„Zd'dd7d8œd9d:„ZdJd<d=ddddddd d>œ	d?d@„ZdKd<dBdCddddddd dDœ
dEdF„Zd
S )LÚStylerRendererzT
    Base class to process rendering a Styler with a specified jinja2 template.
    Úpandaszio/formats/templatesT)ÚloaderZtrim_blockszhtml.tplzhtml_table.tplzhtml_style.tplz	latex.tplNé   zDataFrame | Seriesú
str | NoneÚintzCSSStyles | Nonezstr | tuple | NoneÚboolú
int | None)ÚdataÚuuidÚuuid_lenÚtable_stylesÚtable_attributesÚcaptionÚcell_idsÚ	precisionc	           	        sl  t |tƒr| ¡ }t |tƒs$tdƒ‚|| _|j| _|j| _t |tƒrL|dksTtdƒ‚|plt	ƒ j
d td|ƒ… | _t| jƒ| _|| _|| _|| _|| _ddddd	d
dddddœ
| _d| _d| _dg| jj | _dg| jj | _g | _g | _ttƒ| _ttƒ| _ttƒ| _tt ƒ| _!g | _"d | _#ˆ d u �r.t$dƒnˆ ‰ t‡ fdd„ƒ| _%t‡ fdd„ƒ| _&t‡ fdd„ƒ| _'d S )Nz&``data`` must be a Series or DataFramer   z1``uuid_len`` must be an integer in range [0, 32].é    Úrow_headingÚcol_headingÚ
index_nameÚcolÚrowÚcol_trimÚrow_trimÚlevelr9   Úblank)
rB   rC   rD   rE   rF   rG   rH   rI   r9   rJ   Fústyler.format.precisionc                     s   t tˆ d�S ©N©r@   ©r   Ú_default_formatterr)   rM   r)   r*   Ú<lambda>‰   ó    z)StylerRenderer.__init__.<locals>.<lambda>c                     s   t tˆ d�S rL   rN   r)   rM   r)   r*   rP   Œ   rQ   c                     s   t tˆ d�S rL   rN   r)   rM   r)   r*   rP   �   rQ   )(Ú
isinstancer   Zto_framer   Ú	TypeErrorr9   ÚindexÚcolumnsr6   r   ÚhexÚminr:   Úlenr;   r<   r=   r>   r?   ÚcssÚhide_index_namesÚhide_column_namesÚnlevelsÚhide_index_Úhide_columns_Úhidden_rowsÚhidden_columnsr   ÚlistÚctxÚ	ctx_indexÚctx_columnsr!   Úcell_contextÚ_todoÚtooltipsr   Ú_display_funcsÚ_display_funcs_indexÚ_display_funcs_columns)	Úselfr9   r:   r;   r<   r=   r>   r?   r@   r)   rM   r*   Ú__init__N   s\    

ö



ÿþþþzStylerRenderer.__init__r!   )Úsparse_indexÚsparse_columnsÚmax_rowsÚmax_colsr,   c                 K  sB   |   ¡  |  ||||¡}| |¡ | jjf i |¤| j| jdœ¤ŽS )z˜
        Renders the ``Styler`` including all applied styles to HTML.
        Generates a dict with necessary kwargs passed to jinja2 template.
        )Zhtml_table_tplZhtml_style_tpl)Ú_computeÚ
_translateÚupdateÚtemplate_htmlÚrenderÚtemplate_html_tableÚtemplate_html_style)rk   rm   rn   ro   rp   ÚkwargsÚdr)   r)   r*   Ú_render_html‘   s    

ÿýzStylerRenderer._render_html)rm   rn   Úclinesr,   c                 K  sr   |   ¡  | j||dd�}| j||d� t| jjd< t| jjd< t| jjd< t| jjd< | 	|¡ | jj
f i |¤ŽS )z1
        Render a Styler in latex format
        Ú )rJ   )r{   Z
parse_wrapZparse_tableZ
parse_cellÚparse_header)rq   rr   Ú_translate_latexÚ_parse_latex_table_wrappingÚtemplate_latexÚglobalsÚ_parse_latex_table_stylesÚ_parse_latex_cell_stylesÚ_parse_latex_header_spanrs   ru   )rk   rm   rn   r{   rx   ry   r)   r)   r*   Ú_render_latex§   s    
zStylerRenderer._render_latexc                 C  sJ   | j  ¡  | j ¡  | j ¡  | }| jD ]\}}}|| ƒ|i |¤Ž}q(|S )a  
        Execute the style functions built up in `self._todo`.

        Relies on the conventions that all style functions go through
        .apply or .applymap. The append styles to apply as tuples of

        (application method, *args, **kwargs)
        )rb   Úclearrc   rd   rf   )rk   ÚrÚfuncÚargsrx   r)   r)   r*   rq   º   s    	


zStylerRenderer._computeú&nbsp;)rm   Úsparse_colsro   rp   rJ   c                 C  sŠ  || j d< | jt| jpg ƒ| jdœ}tdƒ}|r4|ntdƒ}|rD|ntdƒ}tt| jj	ƒt| jj
ƒ|||ƒ\}}ttƒ| _|  ||¡}| d|i¡ t| j	||| jƒ}	| d|	i¡ ttƒ| _ttƒ| _|  |	||¡}
| d|
i¡ d	d
ddœ}| ¡ D ].\}}dd„ t| |ƒ ¡ D ƒ}| ||i¡ qø| j}tdƒ�sb|�p@d}d|v �rZ| dd¡}n|d7 }| d|i¡ | j�r†| j | |¡}|S )a  
        Process Styler data and settings into a dict for template rendering.

        Convert data and settings from ``Styler`` attributes such as ``self.data``,
        ``self.tooltips`` including applying any methods in ``self._todo``.

        Parameters
        ----------
        sparse_index : bool
            Whether to sparsify the index or print all hierarchical index elements.
            Upstream defaults are typically to `pandas.options.styler.sparse.index`.
        sparse_cols : bool
            Whether to sparsify the columns or print all hierarchical column elements.
            Upstream defaults are typically to `pandas.options.styler.sparse.columns`.
        blank : str
            Entry to top-left blank cells.
        max_rows, max_cols : int, optional
            Specific max rows and cols. max_elements always take precedence in render.

        Returns
        -------
        d : dict
            The following structure: {uuid, table_styles, caption, head, body,
            cellstyle, table_attributes}
        Úblank_value)r:   r<   r>   zstyler.render.max_elementszstyler.render.max_rowszstyler.render.max_columnsÚheadÚindex_lengthsÚbodyÚcellstyle_mapÚcellstyle_map_indexÚcellstyle_map_columns)Ú	cellstyleZcellstyle_indexZcellstyle_columnsc                 S  s   g | ]\}}t |ƒ|d œ‘qS ))r$   Ú	selectors)ra   )Ú.0r$   r”   r)   r)   r*   Ú
<listcomp>  s   ÿz-StylerRenderer._translate.<locals>.<listcomp>zstyler.html.mathjaxr|   zclass="zclass="tex2jax_ignore z class="tex2jax_ignore"r=   )rY   r:   Úformat_table_stylesr<   r>   r   Ú_get_trimming_maximumsrX   r9   rT   rU   r   ra   r’   Ú_translate_headerrs   Ú_get_level_lengthsr_   r�   r‘   Ú_translate_bodyÚitemsÚgetattrr=   Úreplacerg   rr   )rk   rm   r‹   ro   rp   rJ   ry   Úmax_elementsr�   Úidx_lengthsr�   Zctx_mapsÚkÚattrÚmapZ
table_attrr)   r)   r*   rr   Ë   sb    !
ý

û
þÿÿþýþ


zStylerRenderer._translate)Úsparsify_colsrp   c           
      C  sÌ   t | j||| jƒ}| jj ¡ }| jjjdkr:dd„ |D ƒ}tt|Ž ƒ}g }t| j	ƒD ]0\}}|sT|shqTqT|  
||f||¡}| |¡ qT| jjjrÈtj| jjjŽ rÈt| jƒsÈ| jsÈ|  |||¡}	| |	¡ |S )aN  
        Build each <tr> within table <head> as a list

        Using the structure:
             +----------------------------+---------------+---------------------------+
             |  index_blanks ...          | column_name_0 |  column_headers (level_0) |
          1) |       ..                   |       ..      |             ..            |
             |  index_blanks ...          | column_name_n |  column_headers (level_n) |
             +----------------------------+---------------+---------------------------+
          2) |  index_names (level_0 to level_n) ...      | column_blanks ...         |
             +----------------------------+---------------+---------------------------+

        Parameters
        ----------
        sparsify_cols : bool
            Whether column_headers section will add colspan attributes (>1) to elements.
        max_cols : int
            Maximum number of columns to render. If exceeded will contain `...` filler.

        Returns
        -------
        head : list
            The associated HTML elements needed for template rendering.
        é   c                 S  s   g | ]
}|g‘qS r)   r)   ©r•   Úxr)   r)   r*   r–   O  rQ   z4StylerRenderer._translate_header.<locals>.<listcomp>)rš   rU   r`   r9   Útolistr\   ra   ÚzipÚ	enumerater^   Ú_generate_col_header_rowÚappendrT   ÚnamesÚcomZany_not_noneÚallr]   rZ   Ú_generate_index_names_row)
rk   r¤   rp   Úcol_lengthsÚclabelsr�   r‡   ÚhideÚ
header_rowZindex_names_rowr)   r)   r*   r™   /  s8    ÿ
ÿÿþýüÿ
z StylerRenderer._translate_headerÚtupleÚdict)Úiterrp   r±   c                 C  s’  |\}}t d| jd | jd dƒg| jjt| jƒ d  }| jjj| }t d|du rr| jd › d| jd › |› �n| jd	 › d| jd › |› �|dur | j	s |n| jd t
| jƒ ƒg}g d
 }	}
t|| ƒD �]´\}}t|||ƒ}|rü|
| ||fd
¡7 }
|
|k�rJ|	 t d| jd › d| jd › |› d| jd › �dddd�¡  �q†t d| jd › d| jd › |› d| jd › |› �||| j||f |ƒ| ||fd
¡dk�r¼d| ||fd
¡› d�ndd�}| j�rò| jd › |› d| jd › |› �|d< |�rz||f| jv �rz| j||f �rz| jd › |› d| jd › |› �|d< | jt| j||f ƒ  | jd › |› d| jd › |› �¡ |	 |¡ qÎ|| |	 S )aC  
        Generate the row containing column headers:

         +----------------------------+---------------+---------------------------+
         |  index_blanks ...          | column_name_i |  column_headers (level_i) |
         +----------------------------+---------------+---------------------------+

        Parameters
        ----------
        iter : tuple
            Looping variables from outer scope
        max_cols : int
            Permissible number of columns
        col_lenths :
            c

        Returns
        -------
        list of elements
        ÚthrJ   rŒ   Tr¥   Nú rI   rD   r   rC   rG   ú...r|   ©Ú
attributesrE   ú	colspan="ú"©Údisplay_valuer¼   Ú_Úid)Ú_elementrY   rT   r\   Úsumr]   r9   rU   r­   r[   r¯   rª   Ú_is_visibleÚgetr¬   rj   r?   rd   r’   rµ   )rk   r·   rp   r±   r‡   r²   Zindex_blanksÚnameZcolumn_nameZcolumn_headersÚvisible_col_countÚcÚvalueÚheader_element_visibleÚheader_elementr)   r)   r*   r«   k  s‚    ÿþÿ ÿÿ
öÿ

ÿøÿÿÿÿô&ÿþý& ÿz'StylerRenderer._generate_col_header_rowc                   sú   |}‡ fdd„t ˆ jjjƒD ƒ}g d }}|ròˆ jjd }t || ƒD ]ª\}	}
t|	||ƒ}|rf|d7 }||kr¶| tdˆ j	d › dˆ j	d › |	› dˆ j	d	 › �ˆ j	d
 ddd�¡  qò| tdˆ j	d › dˆ j	d › |	› �ˆ j	d
 |	ˆ j
vƒ¡ qF|| S )a  
        Generate the row containing index names

         +----------------------------+---------------+---------------------------+
         |  index_names (level_0 to level_n) ...      | column_blanks ...         |
         +----------------------------+---------------+---------------------------+

        Parameters
        ----------
        iter : tuple
            Looping variables from outer scope
        max_cols : int
            Permissible number of columns

        Returns
        -------
        list of elements
        c                   sR   g | ]J\}}t d ˆ jd › dˆ jd › |› �|du r>ˆ jd n|ˆ j|  ƒ‘qS )r¸   rD   r¹   rI   NrŒ   ©rÃ   rY   r]   )r•   rÉ   rÇ   ©rk   r)   r*   r–   ã  s   ú
üz<StylerRenderer._generate_index_names_row.<locals>.<listcomp>r   r¥   r¸   rJ   r¹   rE   rG   rŒ   Tr|   r»   )rª   r9   rT   r­   rU   r\   rÅ   r¬   rÃ   rY   r`   )rk   r·   rp   r±   r²   Zindex_namesZcolumn_blanksrÈ   Z
last_levelrÉ   rÊ   rË   r)   rÎ   r*   r°   Í  sB    
ù

ÿøÿüÿ	z(StylerRenderer._generate_index_names_row)r    ro   rp   c                   s¢   ˆ j j ¡ }tˆ j jtƒs(dd„ |D ƒ}g d }}‡ fdd„tˆ j  ¡ ƒD ƒD ]N\}}|d7 }||kr~ˆ  |¡}	| |	¡  qžˆ  	|||f||¡}
| |
¡ qN|S )aó  
        Build each <tr> within table <body> as a list

        Use the following structure:
          +--------------------------------------------+---------------------------+
          |  index_header_0    ...    index_header_n   |  data_by_column   ...     |
          +--------------------------------------------+---------------------------+

        Also add elements to the cellstyle_map for more efficient grouped elements in
        <style></style> block

        Parameters
        ----------
        sparsify_index : bool
            Whether index_headers section will add rowspan attributes (>1) to elements.

        Returns
        -------
        body : list
            The associated HTML elements needed for template rendering.
        c                 S  s   g | ]
}|g‘qS r)   r)   r¦   r)   r)   r*   r–   &  rQ   z2StylerRenderer._translate_body.<locals>.<listcomp>r   c                   s   g | ]}|d  ˆ j vr|‘qS ©r   ©r_   )r•   ÚzrÎ   r)   r*   r–   )  s   r¥   )
r9   rT   r¨   rR   r   rª   Z
itertuplesÚ_generate_trimmed_rowr¬   Ú_generate_body_row)rk   r    ro   rp   Úrlabelsr�   Ú	row_countr‡   Úrow_tupZtrimmed_rowZbody_rowr)   rÎ   r*   r›     s"    

ÿ

ÿzStylerRenderer._translate_bodyra   )rp   r,   c                   sÜ   ‡ fdd„t ˆ jjjƒD ƒ}g d }}tˆ jƒD ]¢\}}|ˆ jv}|rN|d7 }||kr”| tdˆ j	d › dˆ j	d › dˆ j	d	 › �d
ddd�¡  qÔ| tdˆ j	d › dˆ j	d › |› dˆ j	d › �d
|dd�¡ q0|| S )zÿ
        When a render has too many rows we generate a trimming row containing "..."

        Parameters
        ----------
        max_cols : int
            Number of permissible columns

        Returns
        -------
        list of elements
        c                   sL   g | ]D}t d ˆ jd › dˆ jd › |› dˆ jd › �dˆ j|  dd�‘qS )r¸   rB   r¹   rI   rH   rº   r|   r»   rÍ   )r•   rÉ   rÎ   r)   r*   r–   D  s   öÿ
øz8StylerRenderer._generate_trimmed_row.<locals>.<listcomp>r   r¥   Útdr9   r¹   rH   rG   rº   Tr|   r»   rE   )
Úranger9   rT   r\   rª   rU   r`   r¬   rÃ   rY   )rk   rp   Úindex_headersr9   rÈ   rÉ   rÁ   Údata_element_visibler)   rÎ   r*   rÒ   7  s>    
õ

ÿøÿ(ûÿ
z$StylerRenderer._generate_trimmed_row)r·   rp   r    c                 C  sL  |\}}}g }t || ƒD �]V\}}	t|||ƒo:| j|  }
td| jd › d| jd › |› d| jd › |› �|	|
| j||f |	ƒ| ||fd¡dkr¬d| ||fd¡› d	�nd
d�}| jrà| jd › |› d| jd › |› �|d< |
�rh||f| jv �rh| j||f �rh| jd › |› d| jd › |› �|d< | j	t
| j||f ƒ  | jd › |› d| jd › |› �¡ | |¡ qg d }}t |dd… ƒD �]²\}}	|| jv�o¬|| jv}|�r¼|d7 }||k�r
| td| jd › d| jd › |› d| jd › �ddd
d�¡  �qDd
}||f| jv �r0d| j||f  }td| jd › d| jd › |› d| jd › |› |› �|	|d
| j||f |	ƒd�}| j�r®| jd › |› d| jd › |› �|d< |�r6||f| jv �r6| j||f �r6| jd › |› d| jd › |› �|d< | jt
| j||f ƒ  | jd › |› d| jd › |› �¡ | |¡ �qŽ|| S )a¿  
        Generate a regular row for the body section of appropriate format.

          +--------------------------------------------+---------------------------+
          |  index_header_0    ...    index_header_n   |  data_by_column   ...     |
          +--------------------------------------------+---------------------------+

        Parameters
        ----------
        iter : tuple
            Iterable from outer scope: row number, row data tuple, row index labels.
        max_cols : int
            Number of permissible columns.
        idx_lengths : dict
            A map of the sparsification structure of the index

        Returns
        -------
            list of elements
        r¸   rB   r¹   rI   rF   r   r¥   ú	rowspan="r¾   r|   r¿   rÁ   rÂ   Nr×   r9   rG   rº   Tr»   rE   )r¼   rÀ   )rª   rÅ   r]   rÃ   rY   ri   rÆ   r?   rc   r‘   rµ   r¬   r`   r_   re   rh   rb   r�   )rk   r·   rp   r    r‡   rÖ   rÔ   rÙ   rÉ   rÊ   rË   rÌ   r9   rÈ   rÚ   ÚclsZdata_elementr)   r)   r*   rÓ   r  s     
ÿÿÿÿô þÿÿþý& ÿ
ÿ
ÿøÿÿÿÿ÷&&& ÿz!StylerRenderer._generate_body_rowÚNone)ry   r{   r,   c              	     sâ  ˆj j}|tˆjƒ ‰‡‡fdd„t|d ƒD ƒ|d< g }t‡fdd„ttˆjj ƒƒD ƒ|d ƒD ]f\‰ }t	ˆjƒrzg }n ‡ ‡fdd„t|d|… ƒD ƒ}‡ ‡fdd„t||d… ƒD ƒ}| 
|| ¡ qb||d< |d	vrìtd
|› d�ƒ‚nò|du�rÞd|v �rt|ƒnd}ttƒ|d< ‡fdd„ttˆjj ƒƒD ƒ}	‡fdd„t|ƒD ƒ}
t|	ƒD ]ˆ\}‰ t|
ƒD ]t\}}||d k�rˆd|v �rˆ�qd|d  |ˆ fd¡}|du�rd|d ||   
d|d › dt|
ƒ| › d�¡ �qd�qTdS )aÈ  
        Post-process the default render dict for the LaTeX template format.

        Processing items included are:
          - Remove hidden columns from the non-headers part of the body.
          - Place cellstyles directly in td cells rather than use cellstyle_map.
          - Remove hidden indexes or reinsert missing th elements if part of multiindex
            or multirow sparsification (so that \multirow and \multicol work correctly).
        c                   s*   g | ]"\‰ }‡ ‡‡fd d„t |ƒD ƒ‘qS )c                   s6   g | ].\}}|d  ri |¥dˆj ˆ |ˆ f i¥‘qS )Ú
is_visibler“   )rd   ©r•   rÉ   rE   ©r‡   rk   Úvisible_index_level_nr)   r*   r–   õ  s   þz>StylerRenderer._translate_latex.<locals>.<listcomp>.<listcomp>)rª   )r•   rF   )rk   rá   )r‡   r*   r–   ô  s   ûþz3StylerRenderer._translate_latex.<locals>.<listcomp>r�   c                   s   g | ]}|ˆ j vr|‘qS r)   rÐ   ©r•   r‡   rÎ   r)   r*   r–   þ  rQ   r�   c                   sR   g | ]J\}}|d  dkrˆj | si |¥|d r8|d ndˆjˆ |f dœ¥‘qS )Útyper¸   rÞ   rÀ   r|   )rÀ   r“   )r]   rc   rß   ©r‡   rk   r)   r*   r–     s   øÿÿ
ûNc                   s>   g | ]6\}}|d  r|d dkri |¥dˆj ˆ |f i¥‘qS )rÞ   rã   r×   r“   )rb   rß   rä   r)   r*   r–     s   þ)Nzall;dataz	all;indexzskip-last;datazskip-last;indexz`clines` value of zj is invalid. Should either be None or one of 'all;data', 'all;index', 'skip-last;data', 'skip-last;index'.r9   r   r{   c                   s   g | ]}|ˆ j vr|‘qS r)   rÐ   râ   rÎ   r)   r*   r–   -  s   c                   s   g | ]}ˆ j | s|‘qS r)   )r]   ©r•   ÚirÎ   r)   r*   r–   0  s   r¥   z	skip-lastrŽ   z\cline{ú-Ú})rT   r\   rÄ   r]   rª   r©   rØ   rX   r9   r¯   r¬   Ú
ValueErrorr   ra   rÆ   )rk   ry   r{   Zindex_levelsr�   rF   Zrow_body_headersZrow_body_cellsÚdata_lenZvisible_row_indexesZvisible_index_levelsÚrnZlvlnÚlvlZidx_lenr)   rà   r*   r~   è  sT    

ú
þ
øþ
ÿ

ÿ
ÿ
ÿzStylerRenderer._translate_latexÚ.zExtFormatter | NonezSubset | None)	Ú	formatterÚsubsetÚna_repr@   ÚdecimalÚ	thousandsr   Ú
hyperlinksr,   c	              
     sð   t ˆ du |du |du |dk|du |du |du |du fƒrF| j ¡  | S |du rVtdƒn|}t|ƒ}| jj| }	tˆ tƒsŒ‡ fdd„|	j	D ƒ‰ | j	 
|	j	¡}
| j 
|	j¡}|
D ]>}tˆ  | j	| ¡||||||d�}|D ]}|| j||f< qÖq¬| S )u  
        Format the text display value of cells.

        Parameters
        ----------
        formatter : str, callable, dict or None
            Object to define how values are displayed. See notes.
        subset : label, array-like, IndexSlice, optional
            A valid 2d input to `DataFrame.loc[<subset>]`, or, in the case of a 1d input
            or single key, to `DataFrame.loc[:, <subset>]` where the columns are
            prioritised, to limit ``data`` to *before* applying the function.
        na_rep : str, optional
            Representation for missing values.
            If ``na_rep`` is None, no special formatting is applied.

            .. versionadded:: 1.0.0

        precision : int, optional
            Floating point precision to use for display purposes, if not determined by
            the specified ``formatter``.

            .. versionadded:: 1.3.0

        decimal : str, default "."
            Character used as decimal separator for floats, complex and integers.

            .. versionadded:: 1.3.0

        thousands : str, optional, default None
            Character used as thousands separator for floats, complex and integers.

            .. versionadded:: 1.3.0

        escape : str, optional
            Use 'html' to replace the characters ``&``, ``<``, ``>``, ``'``, and ``"``
            in cell display string with HTML-safe sequences.
            Use 'latex' to replace the characters ``&``, ``%``, ``$``, ``#``, ``_``,
            ``{``, ``}``, ``~``, ``^``, and ``\`` in the cell display string with
            LaTeX-safe sequences.
            Escaping is done before ``formatter``.

            .. versionadded:: 1.3.0

        hyperlinks : {"html", "latex"}, optional
            Convert string patterns containing https://, http://, ftp:// or www. to
            HTML <a> tags as clickable URL hyperlinks if "html", or LaTeX \href
            commands if "latex".

            .. versionadded:: 1.4.0

        Returns
        -------
        self : Styler

        Notes
        -----
        This method assigns a formatting function, ``formatter``, to each cell in the
        DataFrame. If ``formatter`` is ``None``, then the default formatter is used.
        If a callable then that function should take a data value as input and return
        a displayable representation, such as a string. If ``formatter`` is
        given as a string this is assumed to be a valid Python format specification
        and is wrapped to a callable as ``string.format(x)``. If a ``dict`` is given,
        keys should correspond to column names, and values should be string or
        callable, as above.

        The default formatter currently expresses floats and complex numbers with the
        pandas display precision unless using the ``precision`` argument here. The
        default formatter does not adjust the representation of missing values unless
        the ``na_rep`` argument is used.

        The ``subset`` argument defines which region to apply the formatting function
        to. If the ``formatter`` argument is given in dict form but does not include
        all columns within the subset then these columns will have the default formatter
        applied. Any columns in the formatter dict excluded from the subset will
        be ignored.

        When using a ``formatter`` string the dtypes must be compatible, otherwise a
        `ValueError` will be raised.

        When instantiating a Styler, default formatting can be applied be setting the
        ``pandas.options``:

          - ``styler.format.formatter``: default None.
          - ``styler.format.na_rep``: default None.
          - ``styler.format.precision``: default 6.
          - ``styler.format.decimal``: default ".".
          - ``styler.format.thousands``: default None.
          - ``styler.format.escape``: default None.

        Examples
        --------
        Using ``na_rep`` and ``precision`` with the default ``formatter``

        >>> df = pd.DataFrame([[np.nan, 1.0, 'A'], [2.0, np.nan, 3.0]])
        >>> df.style.format(na_rep='MISS', precision=3)  # doctest: +SKIP
                0       1       2
        0    MISS   1.000       A
        1   2.000    MISS   3.000

        Using a ``formatter`` specification on consistent column dtypes

        >>> df.style.format('{:.2f}', na_rep='MISS', subset=[0,1])  # doctest: +SKIP
                0      1          2
        0    MISS   1.00          A
        1    2.00   MISS   3.000000

        Using the default ``formatter`` for unspecified columns

        >>> df.style.format({0: '{:.2f}', 1: 'Â£ {:.1f}'}, na_rep='MISS', precision=1)
        ...  # doctest: +SKIP
                 0      1     2
        0    MISS   Â£ 1.0     A
        1    2.00    MISS   3.0

        Multiple ``na_rep`` or ``precision`` specifications under the default
        ``formatter``.

        >>> df.style.format(na_rep='MISS', precision=1, subset=[0])
        ...     .format(na_rep='PASS', precision=2, subset=[1, 2])  # doctest: +SKIP
                0      1      2
        0    MISS   1.00      A
        1     2.0   PASS   3.00

        Using a callable ``formatter`` function.

        >>> func = lambda s: 'STRING' if isinstance(s, str) else 'FLOAT'
        >>> df.style.format({0: '{:.1f}', 2: func}, precision=4, na_rep='MISS')
        ...  # doctest: +SKIP
                0        1        2
        0    MISS   1.0000   STRING
        1     2.0     MISS    FLOAT

        Using a ``formatter`` with HTML ``escape`` and ``na_rep``.

        >>> df = pd.DataFrame([['<div></div>', '"A&B"', None]])
        >>> s = df.style.format(
        ...     '<a href="a.com/{0}">{0}</a>', escape="html", na_rep="NA"
        ...     )
        >>> s.to_html()  # doctest: +SKIP
        ...
        <td .. ><a href="a.com/&lt;div&gt;&lt;/div&gt;">&lt;div&gt;&lt;/div&gt;</a></td>
        <td .. ><a href="a.com/&#34;A&amp;B&#34;">&#34;A&amp;B&#34;</a></td>
        <td .. >NA</td>
        ...

        Using a ``formatter`` with LaTeX ``escape``.

        >>> df = pd.DataFrame([["123"], ["~ ^"], ["$%#"]])
        >>> df.style.format("\\textbf{{{}}}", escape="latex").to_latex()
        ...  # doctest: +SKIP
        \begin{tabular}{ll}
        {} & {0} \\
        0 & \textbf{123} \\
        1 & \textbf{\textasciitilde \space \textasciicircum } \\
        2 & \textbf{\$\%\#} \\
        \end{tabular}
        Nrí   c                   s   i | ]
}|ˆ “qS r)   r)   )r•   rE   ©rî   r)   r*   Ú
<dictcomp>ù  rQ   z)StylerRenderer.format.<locals>.<dictcomp>©rð   r@   rñ   rò   r   ró   )r¯   rh   r†   ÚsliceÚnon_reducing_slicer9   ÚlocrR   r¶   rU   Zget_indexer_forrT   Ú_maybe_wrap_formatterrÆ   )rk   rî   rï   rð   r@   rñ   rò   r   ró   r9   ZcisZrisÚciÚformat_funcÚrir)   rô   r*   Úformat=  sD     )øÿ

ù	zStylerRenderer.formatr   z	int | strúLevel | list[Level] | None)
rî   ÚaxisrI   rð   r@   rñ   rò   r   ró   r,   c
              
     s  | j  ˆ ¡‰ ˆ dkr$| j| j }
‰n| j| j }
‰t|ˆƒ}tˆdu |du |du |dk|du |du |du |	du fƒr€|
 ¡  | S t	ˆt
ƒsž‡fdd„|D ƒ‰n‡fdd„ˆ ¡ D ƒ‰|D ]J‰tˆ ˆ¡||||||	d�}‡ ‡fdd	„ttˆƒƒD ƒD ]}||
|< qôq¸| S )
aÝ  
        Format the text display value of index labels or column headers.

        .. versionadded:: 1.4.0

        Parameters
        ----------
        formatter : str, callable, dict or None
            Object to define how values are displayed. See notes.
        axis : {0, "index", 1, "columns"}
            Whether to apply the formatter to the index or column headers.
        level : int, str, list
            The level(s) over which to apply the generic formatter.
        na_rep : str, optional
            Representation for missing values.
            If ``na_rep`` is None, no special formatting is applied.
        precision : int, optional
            Floating point precision to use for display purposes, if not determined by
            the specified ``formatter``.
        decimal : str, default "."
            Character used as decimal separator for floats, complex and integers.
        thousands : str, optional, default None
            Character used as thousands separator for floats, complex and integers.
        escape : str, optional
            Use 'html' to replace the characters ``&``, ``<``, ``>``, ``'``, and ``"``
            in cell display string with HTML-safe sequences.
            Use 'latex' to replace the characters ``&``, ``%``, ``$``, ``#``, ``_``,
            ``{``, ``}``, ``~``, ``^``, and ``\`` in the cell display string with
            LaTeX-safe sequences.
            Escaping is done before ``formatter``.
        hyperlinks : {"html", "latex"}, optional
            Convert string patterns containing https://, http://, ftp:// or www. to
            HTML <a> tags as clickable URL hyperlinks if "html", or LaTeX \href
            commands if "latex".

        Returns
        -------
        self : Styler

        Notes
        -----
        This method assigns a formatting function, ``formatter``, to each level label
        in the DataFrame's index or column headers. If ``formatter`` is ``None``,
        then the default formatter is used.
        If a callable then that function should take a label value as input and return
        a displayable representation, such as a string. If ``formatter`` is
        given as a string this is assumed to be a valid Python format specification
        and is wrapped to a callable as ``string.format(x)``. If a ``dict`` is given,
        keys should correspond to MultiIndex level numbers or names, and values should
        be string or callable, as above.

        The default formatter currently expresses floats and complex numbers with the
        pandas display precision unless using the ``precision`` argument here. The
        default formatter does not adjust the representation of missing values unless
        the ``na_rep`` argument is used.

        The ``level`` argument defines which levels of a MultiIndex to apply the
        method to. If the ``formatter`` argument is given in dict form but does
        not include all levels within the level argument then these unspecified levels
        will have the default formatter applied. Any levels in the formatter dict
        specifically excluded from the level argument will be ignored.

        When using a ``formatter`` string the dtypes must be compatible, otherwise a
        `ValueError` will be raised.

        Examples
        --------
        Using ``na_rep`` and ``precision`` with the default ``formatter``

        >>> df = pd.DataFrame([[1, 2, 3]], columns=[2.0, np.nan, 4.0])
        >>> df.style.format_index(axis=1, na_rep='MISS', precision=3)  # doctest: +SKIP
            2.000    MISS   4.000
        0       1       2       3

        Using a ``formatter`` specification on consistent dtypes in a level

        >>> df.style.format_index('{:.2f}', axis=1, na_rep='MISS')  # doctest: +SKIP
             2.00   MISS    4.00
        0       1      2       3

        Using the default ``formatter`` for unspecified levels

        >>> df = pd.DataFrame([[1, 2, 3]],
        ...     columns=pd.MultiIndex.from_arrays([["a", "a", "b"],[2, np.nan, 4]]))
        >>> df.style.format_index({0: lambda v: upper(v)}, axis=1, precision=1)
        ...  # doctest: +SKIP
                       A       B
              2.0    nan     4.0
        0       1      2       3

        Using a callable ``formatter`` function.

        >>> func = lambda s: 'STRING' if isinstance(s, str) else 'FLOAT'
        >>> df.style.format_index(func, axis=1, na_rep='MISS')
        ...  # doctest: +SKIP
                  STRING  STRING
            FLOAT   MISS   FLOAT
        0       1      2       3

        Using a ``formatter`` with HTML ``escape`` and ``na_rep``.

        >>> df = pd.DataFrame([[1, 2, 3]], columns=['"A"', 'A&B', None])
        >>> s = df.style.format_index('$ {0}', axis=1, escape="html", na_rep="NA")
        ...  # doctest: +SKIP
        <th .. >$ &#34;A&#34;</th>
        <th .. >$ A&amp;B</th>
        <th .. >NA</td>
        ...

        Using a ``formatter`` with LaTeX ``escape``.

        >>> df = pd.DataFrame([[1, 2, 3]], columns=["123", "~", "$%#"])
        >>> df.style.format_index("\\textbf{{{}}}", escape="latex", axis=1).to_latex()
        ...  # doctest: +SKIP
        \begin{tabular}{lrrr}
        {} & {\textbf{123}} & {\textbf{\textasciitilde }} & {\textbf{\$\%\#}} \\
        0 & 1 & 2 & 3 \\
        \end{tabular}
        r   Nrí   c                   s   i | ]
}|ˆ “qS r)   r)   )r•   rI   rô   r)   r*   rõ   ¦  rQ   z/StylerRenderer.format_index.<locals>.<dictcomp>c                   s   i | ]\}}ˆ   |¡|“qS r)   )Ú_get_level_number)r•   rI   Z
formatter_r/   r)   r*   rõ   ¨  s   ÿrö   c                   s$   g | ]}ˆ d kr|ˆfnˆ|f‘qS rÏ   r)   rå   )r   rì   r)   r*   r–   ¸  rQ   z/StylerRenderer.format_index.<locals>.<listcomp>)r9   Z_get_axis_numberri   rT   rj   rU   Úrefactor_levelsr¯   r†   rR   r¶   rœ   rú   rÆ   rØ   rX   )rk   rî   r   rI   rð   r@   rñ   rò   r   ró   Zdisplay_funcs_Úlevels_rü   Úidxr)   )r   rî   rì   r+   r*   Úformat_index  sJ     
øÿ

þù
 zStylerRenderer.format_index)Nr4   NNNTN)NN)NNrŠ   )NNNNrí   NNN)	Nr   NNNrí   NNN)r%   r&   r'   r.   r0   r   ZPackageLoaderr3   ÚEnvironmentÚenvZget_templatert   rv   rw   r€   rl   rz   r…   rq   rr   r™   r«   r°   r›   rÒ   rÓ   r~   rþ   r  r)   r)   r)   r*   r1   B   sf          ÷G  û   úd<bA);vW        ÷  R         ör1   r!   r7   r¶   )Úhtml_elementÚ
html_classrÊ   rÞ   r,   c                 K  s"   d|vr||d< | |||dœ|¥S )z]
    Template to return container with information for a <td></td> or <th></th> element.
    rÀ   )rã   rÊ   ÚclassrÞ   r)   )r  r	  rÊ   rÞ   rx   r)   r)   r*   rÃ   ¾  s    
üûrÃ   çš™™™™™é?ztuple[int, int]©r,   c                   sX   ‡ fdd„}|r | |kr|n| } |r4||kr0|n|}| | |krP|| |ƒ\} }q4| |fS )a:  
    Recursively reduce the number of rows and columns to satisfy max elements.

    Parameters
    ----------
    rn, cn : int
        The number of input rows / columns
    max_elements : int
        The number of allowable elements
    max_rows, max_cols : int, optional
        Directly specify an initial maximum rows or columns before compression.
    scaling_factor : float
        Factor at which to reduce the number of rows / columns to fit.

    Returns
    -------
    rn, cn : tuple
        New rn and cn values that satisfy the max_elements constraint
    c                   s,   || kr| t |ˆ  ƒfS t | ˆ  ƒ|fS d S ©N)r6   )rë   Úcn©Úscaling_factorr)   r*   Ú
scale_downï  s    z*_get_trimming_maximums.<locals>.scale_downr)   )rë   r  rŸ   ro   rp   r  r  r)   r  r*   r˜   Ó  s    r˜   r   r6   zSequence[int] | None)rT   ÚsparsifyÚ	max_indexÚhidden_elementsc                 C  st  t | tƒr| jtjdd�}n|  ¡ }|du r0g }i }t | tƒsht|ƒD ]\}}||vrFd|d|f< qF|S t|ƒD ]ì\}}d}	t|ƒD ]Ö\}
}|	|kr˜ qp|sº|
|vr¸d|||
f< |	d7 }	q„|tjuræ|
|vræ|
}d|||f< |	d7 }	q„|tju�r|
}d|||f< q„|
|vr„|	d7 }	|	|k�r" qp|||f dk�rF|
}d|||f< q„|||f  d7  < q„qpdd„ | ¡ D ƒ}|S )aZ  
    Given an index, find the level length for each element.

    Parameters
    ----------
    index : Index
        Index or columns to determine lengths of each element
    sparsify : bool
        Whether to hide or show each distinct element in a MultiIndex
    max_index : int
        The maximum number of elements to analyse along the index due to trimming
    hidden_elements : sequence of int
        Index positions of elements hidden from display in the index affecting
        length

    Returns
    -------
    Dict :
        Result is a dictionary of (level, initial_position): span
    F)r  ZadjoinNr¥   r   c                 S  s   i | ]\}}|d kr||“qS )r¥   r)   )r•   ÚelementÚlengthr)   r)   r*   rõ   J  s   z&_get_level_lengths.<locals>.<dictcomp>)rR   r   rþ   r   Z
no_defaultrª   rœ   )rT   r  r  r  ZlevelsÚlengthsræ   rÊ   rì   Zvisible_row_countÚjrF   Z
last_labelZnon_zero_lengthsr)   r)   r*   rš      sN    




ÿrš   c                 C  s   || f|v S )z/
    Index -> {(idx_row, idx_col): bool}).
    r)   )Zidx_rowZidx_colr  r)   r)   r*   rÅ   Q  s    rÅ   Ú	CSSStyles)Ústylesr,   c                 C  s   dd„ | D ƒS )zÒ
    looks for multiple CSS selectors and separates them:
    [{'selector': 'td, th', 'props': 'a:v;'}]
        ---> [{'selector': 'td', 'props': 'a:v;'},
              {'selector': 'th', 'props': 'a:v;'}]
    c                 S  s.   g | ]&}|d    d¡D ]}||d dœ‘qqS )r"   ú,r$   ©r"   r$   )Úsplit)r•   Zcss_dictr"   r)   r)   r*   r–   _  s   þz'format_table_styles.<locals>.<listcomp>r)   )r  r)   r)   r*   r—   X  s    þr—   F)r§   r@   rò   r,   c                 C  sT   t | ttfƒr2|r"| d|› d�›S | d|› d�›S t | tƒrP|rH| d›S | d›S | S )aµ  
    Format the display of a value

    Parameters
    ----------
    x : Any
        Input variable to be formatted
    precision : Int
        Floating point precision used if ``x`` is float or complex.
    thousands : bool, default False
        Whether to group digits with thousands separated with ",".

    Returns
    -------
    value : Any
        Matches input type, or string if input is float or complex or int with sep.
    z,.Úfrí   z,.0fz.0f)rR   ÚfloatÚcomplexr6   )r§   r@   rò   r)   r)   r*   rO   f  s
    $
rO   r   r5   )rî   rñ   rò   r,   c                   s   ‡ ‡‡fdd„}|S )zÉ
    Takes a string formatting function and wraps logic to deal with thousands and
    decimal parameters, in the case that they are non-standard and that the input
    is a (float, complex, int).
    c                   s    t | tttfƒr˜ˆ dkrHˆd urHˆdkrHˆ| ƒ dd¡ dˆ ¡ dˆ¡S ˆ dkrpˆd u s`ˆdkrpˆ| ƒ dˆ ¡S ˆ dkr˜ˆd ur˜ˆdkr˜ˆ| ƒ dˆ¡S ˆ| ƒS )Nrí   r  u   Â§_Â§-)rR   r  r   r6   rž   ©r§   ©rñ   rî   rò   r)   r*   Úwrapperˆ  s    ÿþýÿz(_wrap_decimal_thousands.<locals>.wrapperr)   )rî   rñ   rò   r#  r)   r"  r*   Ú_wrap_decimal_thousands  s    	r$  c                 C  s<   t | tƒr8|dkrt| ƒS |dkr*t| ƒS td|› �ƒ‚| S )z/if escaping: only use on str, else return inputÚhtmlÚlatexz2`escape` only permitted in {'html', 'latex'}, got )rR   r!   Úescape_htmlÚ_escape_latexré   )r§   r   r)   r)   r*   Ú_str_escapeš  s    
ÿr)  c                   sL   t | tƒrH|dkrd‰ n|dkr&d‰ ntdƒ‚d}t |‡ fdd„| ¡S | S )	zMuses regex to detect a common URL pattern and converts to href tag in format.r%  z%<a href="{0}" target="_blank">{0}</a>r&  z\href{{{0}}}{{{0}}}z3``hyperlinks`` format can only be 'html' or 'latex'z6(https?:\/\/|ftp:\/\/|www.)[\w/\-?=%.]+\.[\w/\-&?=%.]+c                   s   ˆ   |  d¡¡S )Nr   )rþ   Úgroup)Úm©Úhrefr)   r*   rP   ²  rQ   z_render_href.<locals>.<lambda>)rR   r!   ré   ÚreÚsub)r§   rþ   Úpatr)   r,  r*   Ú_render_href¨  s    
r1  rí   zBaseFormatter | Noner8   )rî   rð   r@   rñ   rò   r   ró   r,   c                   sê   t ˆtƒr‡fdd„‰nPtˆƒr&ˆ‰nBˆdu rV|du r>tdƒn|}tt||dud�‰ntdtˆƒ› �ƒ‚ˆ dur€‡ ‡fdd„}nˆ}|dksœ|dur¬|d	kr¬t|||d
�‰n|‰ˆdurÈ‡‡fdd„‰nˆ‰ˆdu rØˆS ‡‡fdd„S dS )zº
    Allows formatters to be expressed as str, callable or None, where None returns
    a default formatting function. wraps with na_rep, and precision where they are
    available.
    c                   s
   ˆ   | ¡S r  ©rþ   r!  rô   r)   r*   rP   Æ  rQ   z'_maybe_wrap_formatter.<locals>.<lambda>NrK   )r@   rò   z*'formatter' expected str or callable, got c                   s   ˆt | ˆ d�ƒS )Nr   )r)  r!  )r   Úfunc_0r)   r*   rP   Õ  rQ   rí   r  )rñ   rò   c                   s   ˆ t | ˆd�ƒS )Nr2  )r1  r!  )Úfunc_2ró   r)   r*   rP   á  rQ   c                   s   t | ƒrˆS ˆ | ƒS r  )r   r!  )Úfunc_3rð   r)   r*   rP   é  rQ   )	rR   r!   Úcallabler   r   rO   rS   rã   r$  )rî   rð   r@   rñ   rò   r   ró   Zfunc_1r)   )r   rî   r3  r4  r5  ró   rð   r*   rú   ¶  s.    
ÿ
ÿrú   ÚSubset)Úslice_c                   sv   t tjtttf}t| |ƒr*tdd…| f } ddœdd„‰ t| ƒs\t| t	ƒsT| gg} qn| g} n‡ fdd„| D ƒ} t
| ƒS )z¶
    Ensure that a slice doesn't reduce to a Series or Scalar.

    Any user-passed `subset` should have this called on it
    to make sure we're always working with DataFrames.
    Nr7   r  c                 S  s2   t | tƒrtdd„ | D ƒƒS t | tƒp,t| ƒS dS )z‹
        Returns
        -------
        bool
            True if slice does *not* reduce,
            False if `part` is a tuple.
        c                 s  s    | ]}t |tƒpt|ƒV  qd S r  )rR   r÷   r   )r•   Úsr)   r)   r*   Ú	<genexpr>  rQ   z3non_reducing_slice.<locals>.pred.<locals>.<genexpr>N)rR   rµ   Úanyr÷   r   )Úpartr)   r)   r*   Úpredù  s    

z non_reducing_slice.<locals>.predc                   s   g | ]}ˆ |ƒr|n|g‘qS r)   r)   )r•   Úp©r=  r)   r*   r–     rQ   z&non_reducing_slice.<locals>.<listcomp>)r   ÚnpZndarrayr   ra   r!   rR   r   r   r÷   rµ   )r8  Úkindsr)   r?  r*   rø   ì  s    	


rø   r#   ÚCSSList)Ústyler,   c                 C  sL   t | tƒrH|  d¡}zdd„ |D ƒW S  tyF   td| › d�ƒ‚Y n0 | S )zÌ
    Convert css-string to sequence of tuples format if needed.
    'color:red; border:1px solid black;' -> [('color', 'red'),
                                             ('border','1px solid red')]
    ú;c                 S  s<   g | ]4}|  ¡ d kr| d¡d   ¡ | d¡d   ¡ f‘qS )r|   ú:r   r¥   )Ústripr  r¦   r)   r)   r*   r–      s   þz/maybe_convert_css_to_tuples.<locals>.<listcomp>zSStyles supplied as string must follow CSS rule formats, for example 'attr: val;'. 'z' was given.)rR   r!   r  Ú
IndexErrorré   )rC  r9  r)   r)   r*   Úmaybe_convert_css_to_tuples  s    

þÿÿ
rH  rÿ   z	list[int])rI   r+   r,   c                   sl   | du rt tˆ jƒƒ}nPt| tƒr*| g}n>t| tƒrBˆ  | ¡g}n&t| t ƒr`‡ fdd„| D ƒ}ntdƒ‚|S )aX  
    Returns a consistent levels arg for use in ``hide_index`` or ``hide_columns``.

    Parameters
    ----------
    level : int, str, list
        Original ``level`` arg supplied to above methods.
    obj:
        Either ``self.index`` or ``self.columns``

    Returns
    -------
    list : refactored arg with a list of levels to hide
    Nc                   s$   g | ]}t |tƒsˆ  |¡n|‘qS r)   )rR   r6   r  )r•   Zlevr/   r)   r*   r–   F  s   ÿz#refactor_levels.<locals>.<listcomp>z4`level` must be of type `int`, `str` or list of such)ra   rØ   r\   rR   r6   r!   r  ré   )rI   r+   r  r)   r/   r*   r  -  s    



þr  c                   @  sb   e Zd ZdZg d¢deƒ fddddœdd	„Zed
d„ ƒZddddddœdd„Zdddœdd„Z	dS )ÚTooltipsa�  
    An extension to ``Styler`` that allows for and manipulates tooltips on hover
    of ``<td>`` cells in the HTML result.

    Parameters
    ----------
    css_name: str, default "pd-t"
        Name of the CSS class that controls visualisation of tooltips.
    css_props: list-like, default; see Notes
        List of (attr, value) tuples defining properties of the CSS class.
    tooltips: DataFrame, default empty
        DataFrame of strings aligned with underlying Styler data for tooltip
        display.

    Notes
    -----
    The default properties for the tooltip CSS class are:

        - visibility: hidden
        - position: absolute
        - z-index: 1
        - background-color: black
        - color: white
        - transform: translate(-20px, -20px)

    Hidden visibility is a key prerequisite to the hover functionality, and should
    always be included in any manual properties specification.
    ))Ú
visibilityÚhidden)ÚpositionÚabsolute)zz-indexr¥   )úbackground-colorÚblack)ÚcolorÚwhite)Z	transformztranslate(-20px, -20px)zpd-tr#   r!   r   )Ú	css_propsÚcss_namerg   c                 C  s   || _ || _|| _g | _d S r  )Ú
class_nameÚclass_propertiesÚtt_datar<   )rk   rR  rS  rg   r)   r)   r*   rl   m  s    zTooltips.__init__c                 C  s   d| j › �t| jƒdœgS )a  
        Combine the ``_Tooltips`` CSS class name and CSS properties to the format
        required to extend the underlying ``Styler`` `table_styles` to allow
        tooltips to render in HTML.

        Returns
        -------
        styles : List
        rí   r  )rT  rH  rU  rÎ   r)   r)   r*   Ú_class_styles  s    
þÿzTooltips._class_stylesr6   )r:   rÇ   rF   rE   Útextc                 C  sZ   d| d t |ƒ d t |ƒ }|d|› � dgdœ|d|› d� d	d
|› d
�fgdœgS )a:  
        For every table data-cell that has a valid tooltip (not None, NaN or
        empty string) must create two pseudo CSS entries for the specific
        <td> element id which are added to overall table styles:
        an on hover visibility change and a content change
        dependent upon the user's chosen display string.

        For example:
            [{"selector": "T__row1_col1:hover .pd-t",
             "props": [("visibility", "visible")]},
            {"selector": "T__row1_col1 .pd-t::after",
             "props": [("content", "Some Valid Text String")]}]

        Parameters
        ----------
        uuid: str
            The uuid of the Styler instance
        name: str
            The css-name of the class used for styling tooltips
        row : int
            The row index of the specified tooltip string data
        col : int
            The col index of the specified tooltip string data
        text : str
            The textual content of the tooltip to be displayed in HTML.

        Returns
        -------
        pseudo_css : List
        z#T_Z_rowZ_colz:hover .)rJ  Úvisibler  z .z::afterÚcontentr¾   )r!   )rk   r:   rÇ   rF   rE   rX  Zselector_idr)   r)   r*   Ú_pseudo_css‘  s     þþûzTooltips._pseudo_cssr1   r¶   )Ústylerry   c                   sÔ   ˆj  ˆj¡ˆ_ ˆj jr|S ˆj‰ˆj  ¡ ˆj  d¡B ‰ dd„ ‡ ‡‡‡fdd„ttˆj j	ƒƒD ƒD ƒˆ_
ˆj
rÐ|d D ]8}|D ].}|d dkr~t|d ƒd	ˆj› d
� |d< q~qv|d  ˆj¡ |d  ˆj
¡ |S )a=  
        Mutate the render dictionary to allow for tooltips:

        - Add ``<span>`` HTML element to each data cells ``display_value``. Ignores
          headers.
        - Add table level CSS styles to control pseudo classes.

        Parameters
        ----------
        styler_data : DataFrame
            Underlying ``Styler`` DataFrame used for reindexing.
        uuid : str
            The underlying ``Styler`` uuid for CSS id.
        d : dict
            The dictionary prior to final render

        Returns
        -------
        render_dict : Dict
        r|   c                 S  s   g | ]}|D ]}|‘qqS r)   r)   )r•   ZsublistrC  r)   r)   r*   r–   ×  s   
õz'Tooltips._translate.<locals>.<listcomp>c                   sh   g | ]`}t tˆjjƒƒD ]J}ˆ j||f s|ˆjv s|ˆjv sˆ ˆjˆ||t	ˆjj||f ƒ¡‘qqS r)   )
rØ   rX   rV  rU   Zilocr_   r`   r[  r:   r!   )r•   ræ   r  ©ÚmaskrÇ   rk   r\  r)   r*   r–   Ù  s   

úr�   rã   r×   rÀ   z<span class="z	"></span>r<   )rV  Zreindex_liker9   ÚemptyrT  r   ÚeqrØ   rX   rT   r<   r!   ÚextendrW  )rk   r\  ry   rF   Úitemr)   r]  r*   rr   ¼  s*    þþ
ÿÿ
zTooltips._translateN)
r%   r&   r'   r.   r   rl   ÚpropertyrW  r[  rr   r)   r)   r)   r*   rI  O  s   õ
+rI  )r<   r>   r,   c                   s.   g d¢‰ | dur&t ‡ fdd„| D ƒƒp,|duS )a8  
    Indicate whether LaTeX {tabular} should be wrapped with a {table} environment.

    Parses the `table_styles` and detects any selectors which must be included outside
    of {tabular}, i.e. indicating that wrapping must occur, and therefore return True,
    or if a caption exists and requires similar.
    )ZtopruleZmidruleZ
bottomruleZcolumn_formatNc                 3  s   | ]}|d  ˆ vV  qdS )r"   Nr)   )r•   ry   ©ZIGNORED_WRAPPERSr)   r*   r:    rQ   z._parse_latex_table_wrapping.<locals>.<genexpr>)r;  )r<   r>   r)   rd  r*   r   õ  s    þýr   )r<   r"   r,   c                 C  sD   | ddd… D ]0}|d |krt |d d d ƒ dd¡  S qdS )	uy  
    Return the first 'props' 'value' from ``tables_styles`` identified by ``selector``.

    Examples
    --------
    >>> table_styles = [{'selector': 'foo', 'props': [('attr','value')]},
    ...                 {'selector': 'bar', 'props': [('attr', 'overwritten')]},
    ...                 {'selector': 'bar', 'props': [('a1', 'baz'), ('a2', 'ignore')]}]
    >>> _parse_latex_table_styles(table_styles, selector='bar')
    'baz'

    Notes
    -----
    The replacement of "Â§" with ":" is to avoid the CSS problem where ":" has structural
    significance and cannot be used in LaTeX labels, but is often required by them.
    Néÿÿÿÿr"   r$   r   r¥   õ   Â§rE  )r!   rž   )r<   r"   rC  r)   r)   r*   r‚     s    "r‚   )Úlatex_stylesrÀ   Úconvert_cssr,   c              
   C  sÀ   |rt | ƒ} | ddd… D ] \}}d|› d|› d�d|› d|› �d|› d|› �d|› d|› d�d|› d	|› d�d
œ}d|› |› d|› �}dD ],}|t|ƒv rŒ||  dt||d�¡} qqŒq|S )a•  
    Mutate the ``display_value`` string including LaTeX commands from ``latex_styles``.

    This method builds a recursive latex chain of commands based on the
    CSSList input, nested around ``display_value``.

    If a CSS style is given as ('<command>', '<options>') this is translated to
    '\<command><options>{display_value}', and this value is treated as the
    display value for the next iteration.

    The most recent style forms the inner component, for example for styles:
    `[('c1', 'o1'), ('c2', 'o2')]` this returns: `\c1o1{\c2o2{display_value}}`

    Sometimes latex commands have to be wrapped with curly braces in different ways:
    We create some parsing flags to identify the different behaviours:

     - `--rwrap`        : `\<command><options>{<display_value>}`
     - `--wrap`         : `{\<command><options> <display_value>}`
     - `--nowrap`       : `\<command><options> <display_value>`
     - `--lwrap`        : `{\<command><options>} <display_value>`
     - `--dwrap`        : `{\<command><options>}{<display_value>}`

    For example for styles:
    `[('c1', 'o1--wrap'), ('c2', 'o2')]` this returns: `{\c1o1 \c2o2{display_value}}
    Nre  z{\z--to_parse rè   ú\z--to_parse} z--to_parse{z--to_parse}{)ú--wrapú--nowrapú--lwrapú--rwrapú--dwrapr¹   )rk  rj  rl  rm  rn  z
--to_parse©rÊ   Úarg)Ú_parse_latex_css_conversionr!   rž   Ú_parse_latex_options_strip)rg  rÀ   rh  ÚcommandÚoptionsrî   rp  r)   r)   r*   rƒ     s"    ûÿrƒ   zdict[str, Any])ÚcellÚmultirow_alignÚmulticol_alignÚwraprh  r,   c                 C  s\  t | d | d |ƒ}d| v �rB| d }d|v ræ|| d¡d d… }t|d| d¡… ƒ}d|kr”|rrd	|› d
�n|› }|r€dnd}	||	|d   S d|krÎ|r¬d	|› d
�n|› }|rºdnd}	|	|d  | S d|› d|› d|› d
�S d|v �rB|dk� rþ|S || d¡d d… }
t|
d|
 d¡… ƒ}
d|› d|
› d|› d
�S |�rTd	|› d
�S |S dS )aè  
    Refactor the cell `display_value` if a 'colspan' or 'rowspan' attribute is present.

    'rowspan' and 'colspan' do not occur simultaneouly. If they are detected then
    the `display_value` is altered to a LaTeX `multirow` or `multicol` command
    respectively, with the appropriate cell-span.

    ``wrap`` is used to enclose the `display_value` in braces which is needed for
    column headers using an siunitx package.

    Requires the package {multirow}, whereas multicol support is usually built in
    to the {tabular} environment.

    Examples
    --------
    >>> cell = {'cellstyle': '', 'display_value':'text', 'attributes': 'colspan="3"'}
    >>> _parse_latex_header_span(cell, 't', 'c')
    '\\multicolumn{3}{c}{text}'
    r“   rÀ   r¼   r½   é	   Nr¾   znaive-lÚ{rè   z & {}z &r¥   znaive-rz{} & z& z\multicolumn{z}{rÛ   Znaivez
\multirow[z]{z}{*}{)rƒ   Úfindr6   )ru  rv  rw  rx  rh  Zdisplay_valÚattrsZcolspanÚoutZblanksZrowspanr)   r)   r*   r„   L  s4    ÿ


r„   zstr | int | float)rÊ   rp  r,   c                 C  s$   t | ƒ |d¡ dd¡ dd¡ ¡ S )zÐ
    Strip a css_value which may have latex wrapping arguments, css comment identifiers,
    and whitespaces, to a valid string for latex options parsing.

    For example: 'red /* --wrap */  ' --> 'red'
    r|   z/*z*/)r!   rž   rF  ro  r)   r)   r*   rr  ƒ  s    rr  c                 C  sÔ   dd„ }dd„ }dd„ }|t |ddd	�t |d
dd	�|dœ}g }| D ]Œ\}}t|tƒrrd|v rr| || dd¡f¡ || ¡ v rBd}dD ]$}	|	t|ƒv r†|	t||	ƒ }} q¬q†|| ||ƒ}
|
durB| |
g¡ qB|S )z²
    Convert CSS (attribute,value) pairs to equivalent LaTeX (command,options) pairs.

    Ignore conversion if tagged with `--latex` option, skipped if no conversion found.
    c                 S  s   | dks| dkrd|› fS d S )NÚboldZbolderZbfseriesr)   ro  r)   r)   r*   Úfont_weight”  s    
z0_parse_latex_css_conversion.<locals>.font_weightc                 S  s(   | dkrd|› fS | dkr$d|› fS d S )NÚitalicZitshapeZobliqueZslshaper)   ro  r)   r)   r*   Ú
font_style™  s
    

z/_parse_latex_css_conversion.<locals>.font_stylec           	   	   S  sÔ  |dkr|n|}| d dkrHt | ƒdkrH|d| dd…  ¡ › d|› �fS | d dkr¨t | ƒd	kr¨| d  ¡ d
 › | d
  ¡ d
 › | d  ¡ d
 › �}|d|› d|› �fS | dd… dk�r¼t d| ¡d  ¡ }d|v rêt|dd… ƒd n
t|ƒd }t d| ¡d  ¡ }d|v �r(t|dd… ƒd n
t|ƒd }| d dk�rXt d| ¡d  ¡ }nt d| ¡d  ¡ }d|v �rŠt|dd… ƒd n
t|ƒd }|d|d›d|d›d|d›d|› �fS |d| › d|› �fS dS )aË  
        CSS colors have 5 formats to process:

         - 6 digit hex code: "#ff23ee"     --> [HTML]{FF23EE}
         - 3 digit hex code: "#f0e"        --> [HTML]{FF00EE}
         - rgba: rgba(128, 255, 0, 0.5)    --> [rgb]{0.502, 1.000, 0.000}
         - rgb: rgb(128, 255, 0,)          --> [rbg]{0.502, 1.000, 0.000}
         - string: red                     --> {red}

        Additionally rgb or rgba can be expressed in % which is also parsed.
        r|   r   ú#é   z[HTML]{r¥   Nrè   é   é   é   Úrgbz(?<=\()[0-9\s%]+(?=,)ú%re  éd   éÿ   z(?<=,)[0-9\s%]+(?=,)Úaz(?<=,)[0-9\s%]+(?=\))z[rgb]{z.3fz, rz  )rX   Úupperr.  ÚfindallrF  r  r6   )	rÊ   Zuser_argrs  Úcomm_argrp  Úvalr‡   ÚgÚbr)   r)   r*   rP     s"     4(**&z*_parse_latex_css_conversion.<locals>.colorZ	cellcolorrl  )rs  rŽ  rP  r|   )zfont-weightrN  rP  z
font-stylez--latex)rj  rk  rl  rn  rm  N)r   rR   r!   r¬   rž   Úkeysrr  ra  )r  r  r�  rP  ZCONVERTED_ATTRIBUTESrg  Ú	attributerÊ   rp  r§   Zlatex_styler)   r)   r*   rq  �  s,    "ürq  c                 C  st   |   dd¡  dd¡  dd¡  dd¡  d	d
¡  dd¡  dd¡  dd¡  dd¡  dd¡  dd¡  dd¡  dd¡  dd¡S )al  
    Replace the characters ``&``, ``%``, ``$``, ``#``, ``_``, ``{``, ``}``,
    ``~``, ``^``, and ``\`` in the string with LaTeX-safe sequences.

    Use this if you need to display text that might contain such characters in LaTeX.

    Parameters
    ----------
    s : str
        Input to be escaped

    Return
    ------
    str :
        Escaped string
    ri  u   ab2Â§=Â§8yzu   ab2Â§=Â§8yz u   ab2Â§=Â§8yz\space ú&z\&rˆ  z\%ú$z\$r‚  z\#rÁ   z\_rz  z\{rè   z\}z~ z~\space ú~z\textasciitilde z^ z^\space ú^z\textasciicircum z\textbackslash )rž   )r9  r)   r)   r*   r(  Ù  s8    ÿþýüûúùø	÷
öõôóÿr(  )NNr  )N)F)NNNrí   NNN)F)FF)TÚ
__future__r   Úcollectionsr   Ú	functoolsr   r.  Útypingr   r   r   r   r	   r
   r   r   r   r   r:   r   Únumpyr@  Zpandas._configr   Zpandas._libsr   Zpandas._typingr   Zpandas.compat._optionalr   Zpandas.core.dtypes.genericr   r2   r   r   r   r   r   r   Zpandas.api.typesr   Zpandas.core.commonÚcoreÚcommonr®   r   Z
markupsafer   r'  r!   ÚBaseFormatterZExtFormatterr6   r  ZCSSPairrB  r#   r    r  r÷   r7  r0   r1   rÃ   r˜   rš   rÅ   r—   rO   r$  r)  r1  rú   rø   rH  r  rI  r   r‚   rƒ   r„   rr  rq  r(  r)   r)   r)   r*   Ú<module>   sŽ   0             ú1 üQ       ù6+" ' ÿ4  û7
L