
    og                        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 d dlmZ d dlmZmZmZ e G d	 d
             Z G d d      Z G d de      Z G d de      Z G d de      Z G d de      Z G d de      Z G d de      Z G d de      Z G d de      Z G d de      Z G d d e      Z G d! d"e      Z G d# d$e      Z G d% d&e      Z  G d' d(      Z! G d) d*e      Z" G d+ d,e"      Z#y-).    )	dataclass)List)Template)render_to_string)conditional_escape)
SafeString)slugify)TEMPLATE_PACKflatattrender_fieldc                   (    e Zd ZU ee   ed<   eed<   y)Pointer	positionsnameN)__name__
__module____qualname__r   int__annotations__str     L/var/www/medrc_site/venv/lib/python3.12/site-packages/crispy_forms/layout.pyr   r      s    Cy
Ir   r   c                       e Zd Zd Zy)TemplateNameMixinc                 \    d| j                   v r| j                   |z  }|S | j                   }|S )Nz%s)template)selftemplate_packr   s      r   get_template_namez#TemplateNameMixin.get_template_name   s3    4== }}}4H  }}Hr   N)r   r   r   r    r   r   r   r   r      s    r   r   c                   L    e Zd Zd Zd Zd Zd Zd ZddZddd	d
dZ	e
fdZy)LayoutObjectc                      | j                   |   S Nfieldsr   slices     r   __getitem__zLayoutObject.__getitem__   s    {{5!!r   c                 "    || j                   |<   y r$   r%   )r   r(   values      r   __setitem__zLayoutObject.__setitem__!   s    "Er   c                     | j                   |= y r$   r%   r'   s     r   __delitem__zLayoutObject.__delitem__$   s    KKr   c                 ,    t        | j                        S r$   )lenr&   )r   s    r   __len__zLayoutObject.__len__'   s    4;;r   c                     d| j                   v r,t        | j                  |      rt        | j                  |      S t        j                  | |      S )z
        This allows us to access self.fields list methods like append or insert, without
        having to declare them one by one
        r&   )__dict__hasattrr&   getattrobject__getattribute__)r   r   s     r   __getattr__zLayoutObject.__getattr__*   sA     t}}$d)C4;;--**466r   Nc                 2    | j                  t        dd      S )a  
        Returns a list of Pointers. First parameter is the location of the
        field, second one the name of the field. Example::

            [
                Pointer([0,1,2], 'field_name1'),
                Pointer([0,3], 'field_name2'),
            ]
        NT)indexgreedy)get_layout_objectsr   )r   r:   s     r   get_field_nameszLayoutObject.get_field_names5   s     &&s$t&DDr   r   Fr:   	max_levelr;   c                   g }|t        |t              s|g}n|g }t        |      dk(  xr |d   t        k(  }t	        | j
                        D ]  \  }}t        ||      rc|r |j                  t        ||gz   |             nA|j                  t        ||gz   |j                  j                  j                                      t        |d      st        |      |k  s|s||gz   ||d}	| |j                  |i |	z   } |S )a  
        Returns a list of Pointers pointing to layout objects of any type matching
        `LayoutClasses`::

            [
                Pointer([0,1,2], 'div']),
                Pointer([0,3], 'field_name'),
            ]

        :param max_level: An integer that indicates max level depth to reach when
        traversing a layout.
        :param greedy: Boolean that indicates whether to be greedy. If set, max_level
        is skipped.
           r   r=   r>   )
isinstancelistr0   r   	enumerater&   appendr   	__class__r   lowerr4   r<   )
r   r:   r?   r;   LayoutClassespointers	str_classilayout_object
new_kwargss
             r   r<   zLayoutObject.get_layout_objectsA   s    Zt%<GE]E&!+Ga0@C0G	 )$++ 6 	eA}-7OOGEQCK$GHOOGEQCK9P9P9Y9Y9_9_9a$bc }&78c%j9>TX^',s{V\]
#&Fm&F&F&dYc&dd	e r   c                 j    t        dj                  fd| j                  D                    S )N c              3   >   K   | ]  }t        |fd i  yw)r   N)r   ).0fieldcontextformkwargsr   s     r   	<genexpr>z3LayoutObject.get_rendered_fields.<locals>.<genexpr>i   s&     wbgLg]]]V\]ws   )r   joinr&   r   rT   rS   r   rU   s    ````r   get_rendered_fieldsz LayoutObject.get_rendered_fieldsg   s)    GGwkokvkvww
 	
r   r$   )r   r   r   r)   r,   r.   r1   r8   r=   r<   r
   rY   r   r   r   r"   r"      s=    "# 	7
E 8<qQV $L @M 
r   r"   c                        e Zd ZdZd ZefdZy)Layouta  
    Form Layout. It is conformed by Layout objects: `Fieldset`, `Row`, `Column`, `MultiField`,
    `HTML`, `ButtonHolder`, `Button`, `Hidden`, `Reset`, `Submit` and fields. Form fields
    have to be strings.
    Layout objects `Fieldset`, `Row`, `Column`, `MultiField` and `ButtonHolder` can hold other
    Layout objects within. Though `ButtonHolder` should only hold `HTML` and BaseInput
    inherited classes: `Button`, `Hidden`, `Reset` and `Submit`.

    Example::

        helper.layout = Layout(
            Fieldset('Company data',
                'is_company'
            ),
            Fieldset(_('Contact details'),
                'email',
                Row('password1', 'password2'),
                'first_name',
                'last_name',
                HTML('<img src="/media/somepicture.jpg"/>'),
                'company'
            ),
            ButtonHolder(
                Submit('Save', 'Save', css_class='button white'),
            ),
        )
    c                 $    t        |      | _        y r$   )rC   r&   )r   r&   s     r   __init__zLayout.__init__   s    6lr   c                 ,     | j                   |||fi |S r$   )rY   rX   s        r   renderzLayout.render   s    't''g}OOOr   Nr   r   r   __doc__r]   r
   r_   r   r   r   r[   r[   m   s    8# 3@ Pr   r[   c                   .    e Zd ZdZdZdddddZefdZy)ButtonHolderag  
    Layout object. It wraps fields in a <div class="buttonHolder">

    This is where you should put Layout objects that render to form buttons

    Attributes
    ----------
    template: str
        The default template which this Layout Object will be rendered
        with.

    Parameters
    ----------
    *fields : HTML or BaseInput
        The layout objects to render within the ``ButtonHolder``. It should
        only hold `HTML` and `BaseInput` inherited objects.
    css_id : str, optional
        A custom DOM id for the layout object. If not provided the name
        argument is slugified and turned into the id for the submit button.
        By default None.
    css_class : str, optional
        Additional CSS classes to be applied to the ``<input>``. By default
        None.
    template : str, optional
        Overrides the default template, if provided. By default None.

    Examples
    --------

    An example using ``ButtonHolder`` in your layout::

        ButtonHolder(
            HTML(<span style="display: hidden;">Information Saved</span>),
            Submit('Save', 'Save')
        )
    z%s/layout/buttonholder.htmlNcss_id	css_classr   c                j    t        |      | _        || _        || _        |xs | j                  | _        y r$   )rC   r&   re   rf   r   )r   re   rf   r   r&   s        r   r]   zButtonHolder.__init__   s+    6l" 1DMMr   c                      | j                   |||fi |}| j                  |      }|j                  | |d       t        ||j	                               S )N)buttonholderfields_output)rY   r    updater   flatten)r   rT   rS   r   rU   htmlr   s          r   r_   zButtonHolder.render   sR    't''g}OO))-8tDE'//*;<<r   r   r   r   ra   r   r]   r
   r_   r   r   r   rc   rc      s&    #J -H'+td 2 3@ =r   rc   c                   2    e Zd ZdZdZdZdddddZefdZy)	BaseInputa  
    A base class to reduce the amount of code in the Input classes.

    Attributes
    ----------
    template: str
        The default template which this Layout Object will be rendered
        with.
    field_classes: str
        CSS classes to be applied to the ``<input>``.

    Parameters
    ----------
    name : str
        The name attribute of the button.
    value : str
        The value attribute of the button.
    css_id : str, optional
        A custom DOM id for the layout object. If not provided the name
        argument is slugified and turned into the id for the submit button.
        By default None.
    css_class : str, optional
        Additional CSS classes to be applied to the ``<input>``. By default
        None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to `flatatt` and converted into
        key="value", pairs. These attributes are added to the ``<input>``.
    z%s/layout/baseinput.htmlrO   Nrd   c                   || _         || _        |r|| _        n+t        | j                         }| j                   d| | _        i | _        |r| xj                  d| z  c_        |xs | j                  | _        t        |      | _	        y )Nz-id- )
r   r+   idr	   
input_typeattrsfield_classesr   r   
flat_attrs)r   r   r+   re   rf   r   rU   slugs           r   r]   zBaseInput.__init__   s{    	
DG499%D)dV4DG
Ai[/1 1DMM!&/r   c                     t        t        | j                              j                  |      | _        | j	                  |      }|j                  d| i       t        ||j                               S )z
        Renders an `<input />` if container is used as a Layout object.
        Input button value can be a variable in context.
        input)r   r   r+   r_   r    rk   r   rl   )r   rT   rS   r   rU   r   s         r   r_   zBaseInput.render   sW    
 c$**o.55g>
))-8''//*;<<r   )	r   r   r   ra   r   rv   r]   r
   r_   r   r   r   rp   rp      s*    > *HM.2dT *  3@ 	=r   rp   c                       e Zd ZdZdZdZy)Submita  
    Used to create a Submit button descriptor for the {% crispy %} template tag.

    Attributes
    ----------
    template: str
        The default template which this Layout Object will be rendered
        with.
    field_classes: str
        CSS classes to be applied to the ``<input>``.
    input_type: str
        The ``type`` attribute of the ``<input>``.

    Parameters
    ----------
    name : str
        The name attribute of the button.
    value : str
        The value attribute of the button.
    css_id : str, optional
        A custom DOM id for the layout object. If not provided the name
        argument is slugified and turned into the id for the submit button.
        By default None.
    css_class : str, optional
        Additional CSS classes to be applied to the ``<input>``. By default
        None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to `flatatt` and converted into
        key="value", pairs. These attributes are added to the ``<input>``.

    Examples
    --------
    Note: ``form`` arg to ``render()`` is not required for ``BaseInput``
    inherited objects.

    >>> submit = Submit('Search the Site', 'search this site')
    >>> submit.render("", "", Context())
    '<input type="submit" name="search-the-site" value="search this site" '
    'class="btn btn-primary" id="submit-id-search-the-site"/>'

    >>> submit = Submit('Search the Site', 'search this site', css_id="custom-id",
                         css_class="custom class", my_attr=True, data="my-data")
    >>> submit.render("", "", Context())
    '<input type="submit" name="search-the-site" value="search this site" '
    'class="btn btn-primary custom class" id="custom-id" data="my-data" my-attr/>'

    Usually you will not call the render method on the object directly. Instead
    add it to your ``Layout`` manually or use the `add_input` method::

        class ExampleForm(forms.Form):
        [...]
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.helper = FormHelper()
            self.helper.add_input(Submit('submit', 'Submit'))
    submitzbtn btn-primaryNr   r   r   ra   rt   rv   r   r   r   r|   r|     s    9v J%Mr   r|   c                       e Zd ZdZdZdZy)Buttonai  
    Used to create a button descriptor for the {% crispy %} template tag.

    Attributes
    ----------
    template: str
        The default template which this Layout Object will be rendered
        with.
    field_classes: str
        CSS classes to be applied to the ``<input>``.
    input_type: str
        The ``type`` attribute of the ``<input>``.

    Parameters
    ----------
    name : str
        The name attribute of the button.
    value : str
        The value attribute of the button.
    css_id : str, optional
        A custom DOM id for the layout object. If not provided the name
        argument is slugified and turned into the id for the submit button.
        By default None.
    css_class : str, optional
        Additional CSS classes to be applied to the ``<input>``. By default
        None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to `flatatt` and converted into
        key="value", pairs. These attributes are added to the ``<input>``.

    Examples
    --------
    Note: ``form`` arg to ``render()`` is not required for ``BaseInput``
    inherited objects.

    >>> button = Button('Button 1', 'Press Me!')
    >>> button.render("", "", Context())
    '<input type="button" name="button-1" value="Press Me!" '
    'class="btn" id="button-id-button-1"/>'

    >>> button = Button('Button 1', 'Press Me!', css_id="custom-id",
                         css_class="custom class", my_attr=True, data="my-data")
    >>> button.render("", "", Context())
    '<input type="button" name="button-1" value="Press Me!" '
    'class="btn custom class" id="custom-id" data="my-data" my-attr/>'

    Usually you will not call the render method on the object directly. Instead
    add it to your ``Layout`` manually or use the `add_input` method::

        class ExampleForm(forms.Form):
        [...]
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.helper = FormHelper()
            self.helper.add_input(Button('Button 1', 'Press Me!'))
    buttonbtnNr~   r   r   r   r   r   G  s    9v JMr   r   c                       e Zd ZdZdZdZy)Hiddena  
    Used to create a Hidden input descriptor for the {% crispy %} template tag.

    Attributes
    ----------
    template: str
        The default template which this Layout Object will be rendered
        with.
    field_classes: str
        CSS classes to be applied to the ``<input>``.
    input_type: str
        The ``type`` attribute of the ``<input>``.

    Parameters
    ----------
    name : str
        The name attribute of the button.
    value : str
        The value attribute of the button.
    css_id : str, optional
        A custom DOM id for the layout object. If not provided the name
        argument is slugified and turned into the id for the submit button.
        By default None.
    css_class : str, optional
        Additional CSS classes to be applied to the ``<input>``. By default
        None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to `flatatt` and converted into
        key="value", pairs. These attributes are added to the ``<input>``.

    Examples
    --------
    Note: ``form`` arg to ``render()`` is not required for ``BaseInput``
    inherited objects.

    >>> hidden = Hidden("hidden", "hide-me")
    >>> hidden.render("", "", Context())
    '<input type="hidden" name="hidden" value="hide-me"/>'

    Usually you will not call the render method on the object directly. Instead
    add it to your ``Layout`` manually or use the `add_input` method::

        class ExampleForm(forms.Form):
        [...]
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.helper = FormHelper()
            self.helper.add_input(Hidden("hidden", "hide-me"))
    hiddenNr~   r   r   r   r   r     s    2h JMr   r   c                       e Zd ZdZdZdZy)Reseta  
    Used to create a reset button descriptor for the {% crispy %} template tag.

    Attributes
    ----------
    template: str
        The default template which this Layout Object will be rendered
        with.
    field_classes: str
        CSS classes to be applied to the ``<input>``.
    input_type: str
        The ``type`` attribute of the ``<input>``.

    Parameters
    ----------
    name : str
        The name attribute of the button.
    value : str
        The value attribute of the button.
    css_id : str, optional
        A custom DOM id for the layout object. If not provided the name
        argument is slugified and turned into the id for the submit button.
        By default None.
    css_class : str, optional
        Additional CSS classes to be applied to the ``<input>``. By default
        None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to `flatatt` and converted into
        key="value", pairs. These attributes are added to the ``<input>``.

    Examples
    --------
    Note: ``form`` arg to ``render()`` is not required for ``BaseInput``
    inherited objects.

    >>> reset = Reset('Reset This Form', 'Revert Me!')
    >>> reset.render("", "", Context())
    '<input type="reset" name="reset-this-form" value="Revert Me!" '
    'class="btn btn-inverse" id="reset-id-reset-this-form"/>'

    >>> reset = Reset('Reset This Form', 'Revert Me!', css_id="custom-id",
                         css_class="custom class", my_attr=True, data="my-data")
    >>> reset.render("", "", Context())
    '<input type="reset" name="reset-this-form" value="Revert Me!" '
    'class="btn btn-inverse custom class" id="custom-id" data="my-data" my-attr/>'

    Usually you will not call the render method on the object directly. Instead
    add it to your ``Layout`` manually manually or use the `add_input` method::

        class ExampleForm(forms.Form):
        [...]
        def __init__(self, *args, **kwargs):
            super().__init__(*args, **kwargs)
            self.helper = FormHelper()
            self.helper.add_input(Reset('Reset This Form', 'Revert Me!'))
    resetzbtn btn-inverseNr~   r   r   r   r   r     s    9v J%Mr   r   c                   .    e Zd ZdZdZdddddZefdZy)Fieldseta  
    A layout object which wraps fields in a ``<fieldset>``

    Parameters
    ----------
    legend : str
        The content of the fieldset's ``<legend>``. This text is context
        aware, to bring this to life see the examples section.
    *fields : str | LayoutObject | HTML
        Any number of fields as positional arguments to be rendered within
        the ``<fieldset>``
    css_class : str, optional
        Additional CSS classes to be applied to the ``<input>``. By default
        None.
    css_id : str, optional
        A custom DOM id for the layout object. If not provided the name
        argument is slugified and turned into the id for the submit button.
        By default None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to ``flatatt`` and converted into
        key="value", pairs. These attributes are added to the ``<fieldset>``.

    Examples
    --------

    The Fieldset Layout object is added to your ``Layout`` for example::

        Fieldset("Text for the legend",
            "form_field_1",
            "form_field_2",
            css_id="my-fieldset-id",
            css_class="my-fieldset-class",
            data="my-data"
        )

    The above layout will be rendered as::

        '''
        <fieldset id="fieldset-id" class="my-fieldset-class" data="my-data">
           <legend>Text for the legend</legend>
           # form fields render here
        </fieldset>
        '''

    The first parameter is the text for the fieldset legend. This text is context aware,
    so you can do things like::

        Fieldset("Data for {{ user.username }}",
            'form_field_1',
            'form_field_2'
        )
    z%s/layout/fieldset.htmlN)rf   re   r   c                    t        |      | _        || _        || _        || _        |xs | j
                  | _        t        |      | _        y r$   )rC   r&   legendrf   re   r   r   rw   )r   r   rf   re   r   r&   rU   s          r   r]   zFieldset.__init__:  s=    6l" 1DMM!&/r   c                 6    | j                   |||fi |}| j                  r.t        t        | j                              j	                  |      }nt        d      }| j                  |      }|j                  | ||d       t        ||j                               S )NrO   )fieldsetr   r&   )
rY   r   r   r   r_   r   r    rk   r   rl   )r   rT   rS   r   rU   r&   r   r   s           r   r_   zFieldset.renderB  s    )))$Q&Q;;c$++./66w?F^F))-8DFfMN'//*;<<r   rn   r   r   r   r   r      s&    5n )H26td * 3@ 
=r   r   c                   8    e Zd ZdZdZdZddddddddZefdZy)
MultiFielda  
    MultiField container for Bootstrap3. Renders to a MultiField <div>.

    Attributes
    ----------
    template: str
        The default template which this Layout Object will be rendered
        with.
    field_template: str
        The template which fields will be rendered with.

    Parameters
    ----------
    label: str
        The label for the multifield.
    *fields: str
        The fields to be rendered within the multifield.
    label_class: str, optional
        CSS classes to be added to the multifield label. By default None.
    help_text: str, optional
        Help text will be available in the context of the multifield template.
        This is unused in the bootstrap3 template provided. By default None.
    css_class : str, optional
        Additional CSS classes to be applied to the ``<input>``. By default
        None.
    css_id : str, optional
        A DOM id for the layout object which will be added to the wrapping
        ``<div>`` if provided. By default None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    field_template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to ``flatatt`` and converted into
        key="value", pairs. These attributes are added to the wrapping
        ``<div>``.

    z%s/layout/multifield.htmlz%s/multifield.htmlN)label_class	help_textrf   re   r   field_templatec                    t        |      | _        || _        |xs d| _        |xs d| _        || _        || _        |xs | j                  | _        |xs | j                  | _        t        |	      | _
        y )N
blockLabel
ctrlHolder)rC   r&   
label_htmlr   rf   re   r   r   r   r   rw   )
r   labelr   r   rf   re   r   r   r&   rU   s
             r   r]   zMultiField.__init__z  sk     6l&6,"2l" 1DMM,C0C0C!&/r   c                 n   |d   r@d | j                         D        D ]&  }||j                  v s| xj                  dz  c_        ( | j                  |z  } | j                  |||f|| j
                  | d|}| j                  |      }|j                  | |d       t        ||j                               S )Nform_show_errorsc              3   4   K   | ]  }|j                     y wr$   )r   )rQ   pointers     r   rV   z$MultiField.render.<locals>.<genexpr>  s     M7',,Ms   z error)r   
labelclassrL   )
multifieldrj   )
r=   errorsrf   r   rY   r   r    rk   r   rl   )	r   rT   rS   r   rU   rR   r   rj   r   s	            r   r_   zMultiField.render  s    %&Md6J6J6LM /DKK'NNh.N/ ,,}<000
 $''
 
 ))-8d]KL'//*;<<r   )	r   r   r   ra   r   r   r]   r
   r_   r   r   r   r   r   O  s8    %N +H)N *, 3@ =r   r   c                   2    e Zd ZdZdZdZdddddZefdZy)Diva  
    Layout object. It wraps fields in a ``<div>``.

    Attributes
    ----------
    template : str
        The default template which this Layout Object will be rendered
        with.
    css_class : str, optional
        CSS classes to be applied to the ``<div>``. By default None.

    Parameters
    ----------
    *fields : str, LayoutObject
        Any number of fields as positional arguments to be rendered within
        the ``<div>``.
    css_id : str, optional
        A DOM id for the layout object which will be added to the ``<div>`` if
        provided. By default None.
    css_class : str, optional
        Additional CSS classes to be applied in addition to those declared by
        the class itself. By default None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to ``flatatt`` and converted into
        key="value", pairs. These attributes are added to the ``<div>``.

    Examples
    --------

    In your ``Layout`` you can::

        Div(
            'form_field_1',
            'form_field_2',
            css_id='div-example',
            css_class='divs',
        )

    It is also possible to nest Layout Objects within a Div::

        Div(
            Div(
                Field('form_field', css_class='field-class'),
                css_class='div-class',
            ),
            Div('form_field_2', css_class='div-class'),
        )
    z%s/layout/div.htmlNrd   c                    t        |      | _        | j                  r|r| xj                  d| z  c_        n	|r|| _        || _        |xs | j                  | _        t        |      | _        y )Nrr   )rC   r&   rf   re   r   r   rw   )r   re   rf   r   r&   rU   s         r   r]   zDiv.__init__  sV    6l>>iNN)o-N&DN 1DMM!&/r   c                 l     | j                   |||fi |}| j                  |      }t        || |d      S )N)divr&   )rY   r    r   )r   rT   rS   r   rU   r&   r   s          r   r_   z
Div.render  s?    )))$Q&Q))-8$&*IJJr   )	r   r   r   ra   r   rf   r]   r
   r_   r   r   r   r   r     s,    1f $HI'+td 
* 3@ Kr   r   c                       e Zd ZdZdZy)Rowa  
    Layout object. It wraps fields in a ``<div>`` and the template adds the
    appropriate class to render the contents in a row. e.g. ``form-row`` when
    using the Bootstrap4 template pack.

    Attributes
    ----------
    template : str
        The default template which this Layout Object will be rendered
        with.
    css_class : str, optional
        CSS classes to be applied to the ``<div>``. By default None.

    Parameters
    ----------
    *fields : str, LayoutObject
        Any number of fields as positional arguments to be rendered within
        the ``<div>``.
    css_id : str, optional
        A DOM id for the layout object which will be added to the ``<div>`` if
        provided. By default None.
    css_class : str, optional
        Additional CSS classes to be applied in addition to those declared by
        the class itself. By default None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to ``flatatt`` and converted into
        key="value", pairs. These attributes are added to the ``<div>``.

    Examples
    --------

    In your ``Layout`` you can::

        Row('form_field_1', 'form_field_2', css_id='row-example')

    It is also possible to nest Layout Objects within a Row::

        Row(
            Div(
                Field('form_field', css_class='field-class'),
                css_class='div-class',
            ),
            Div('form_field_2', css_class='div-class'),
        )
    z%s/layout/row.htmlNr   r   r   ra   r   r   r   r   r   r     s    .` $Hr   r   c                       e Zd ZdZdZy)Columna  
    Layout object. It wraps fields in a ``<div>`` and the template adds the
    appropriate class to render the contents in a column. e.g. ``col-md`` when
    using the Bootstrap4 template pack.

    Attributes
    ----------
    template : str
        The default template which this Layout Object will be rendered
        with.
    css_class : str, optional
        CSS classes to be applied to the ``<div>``. By default None.

    Parameters
    ----------
    *fields : str, LayoutObject
        Any number of fields as positional arguments to be rendered within
        the ``<div>``.
    css_id : str, optional
        A DOM id for the layout object which will be added to the ``<div>`` if
        provided. By default None.
    css_class : str, optional
        Additional CSS classes to be applied in addition to those declared by
        the class itself. If using the Bootstrap4 template pack the default
        ``col-md`` is removed if this string contins another ``col-`` class.
        By default None.
    template : str, optional
        Overrides the default template, if provided. By default None.
    **kwargs : dict, optional
        Additional attributes are passed to ``flatatt`` and converted into
        key="value", pairs. These attributes are added to the ``<div>``.

    Examples
    --------

    In your ``Layout`` you can::

        Column('form_field_1', 'form_field_2', css_id='col-example')

    It is also possible to nest Layout Objects within a Row::

        Div(
            Column(
                Field('form_field', css_class='field-class'),
                css_class='col-sm,
            ),
            Column('form_field_2', css_class='col-sm'),
        )
    z%s/layout/column.htmlNr   r   r   r   r   r   &  s    0d 'Hr   r   c                        e Zd ZdZd ZefdZy)HTMLa#  
    Layout object. It can contain pure HTML and it has access to the whole
    context of the page where the form is being rendered.

    Examples::

        HTML("{% if saved %}Data saved{% endif %}")
        HTML('<input type="hidden" name="{{ step_field }}" value="{{ step0 }}" />')
    c                     || _         y r$   )rm   )r   rm   s     r   r]   zHTML.__init__g  s	    	r   c                 \    t        t        | j                              j                  |      S r$   )r   r   rm   r_   rX   s        r   r_   zHTML.renderj  s     DII'..w77r   Nr`   r   r   r   r   r   \  s     3@ 8r   r   c                   4    e Zd ZdZdZi ZdddddZedfdZy)Fielda  
    A Layout object, usually containing one field name, where you can add
    attributes to it easily.

    Attributes
    ----------
    template : str
        The default template which this Layout Object will be rendered
        with.
    attrs : dict
        Attributes to be applied to the field. These are converted into html
        attributes. e.g. ``data_id: 'test'`` in the attrs dict will become
        ``data-id='test'`` on the field's ``<input>``.

    Parameters
    ----------
    *fields : str
        Usually a single field, but can be any number of fields, to be rendered
        with the same attributes applied.
    css_class : str, optional
        CSS classes to be applied to the field. These are added to any classes
        included in the ``attrs`` dict. By default ``None``.
    wrapper_class: str, optional
        CSS classes to be used when rendering the Field. This class is usually
        applied to the ``<div>`` which wraps the Field's ``<label>`` and
        ``<input>`` tags. By default ``None``.
    template : str, optional
        Overrides the default template, if provided. By default ``None``.
    **kwargs : dict, optional
        Additional attributes are converted into key="value", pairs. These
        attributes are added to the field's ``<input>``.

    Examples
    --------

    Example::

        Field('field_name', style="color: #333;", css_class="whatever", id="field_name")
    z%s/field.htmlN)rf   wrapper_classr   c          
         t        |      | _        | j                  j                         | _        |r8d| j                  v r| j                  dxx   d| z  cc<   n|| j                  d<   || _        |xs | j
                  | _        | j                  j                  |j                         D ci c]!  \  }}|j                  dd      t        |      # c}}       y c c}}w )Nclassrr   _-)
rC   r&   ru   copyr   r   rk   itemsreplacer   )r   rf   r   r   r&   rU   kvs           r   r]   zField.__init__  s    6lZZ__&
$**$

7#9+6#&/

7#* 1DMM 	

RXR^R^R`a$!Q199S#.0B10EEabas   .&C
c                     |i }| j                   r| j                   |d<   | j                  |      } | j                  |||f|| j                  |d|S )Nr   )r   ru   extra_context)r   r    rY   ru   )r   rT   rS   r   r   rU   r   s          r   r_   zField.render  sr     M-1-?-?M/*))-8't''
 **'
 
 	
r   )	r   r   r   ra   r   ru   r]   r
   r_   r   r   r   r   r   n  s.    &P HE*.dT c" 3@t 
r   r   c                        e Zd ZdZdddddZy)MultiWidgetFielda  
    Layout object. For fields with :class:`~django.forms.MultiWidget` as
    ``widget``, you can pass additional attributes to each widget.

    Attributes
    ----------
    template : str
        The default template which this Layout Object will be rendered
        with.

    Parameters
    ----------
    *fields : str
        Usually a single field, but can be any number of fields, to be rendered
        with the same attributes applied.
    attrs : str, optional
        Additional attrs to be added to each widget. These are added to any
        classes included in the ``attrs`` dict. By default ``None``.
    wrapper_class: str, optional
        CSS classes to be used when rendering the Field. This class is usually
        applied to the ``<div>`` which wraps the Field's ``<label>`` and
        ``<input>`` tags. By default ``None``.
    template : str, optional
        Overrides the default template, if provided. By default ``None``.

    Examples
    --------

    Example::

        MultiWidgetField(
            'multiwidget_field_name',
            attrs=(
                {'style': 'width: 30px;'},
                {'class': 'second_widget_class'}
            ),
        )
    N)ru   r   r   c                r    t        |      | _        |xs i | _        |xs | j                  | _        || _        y r$   )rC   r&   ru   r   r   )r   ru   r   r   r&   s        r   r]   zMultiWidgetField.__init__  s0    6l[b
 1DMM*r   )r   r   r   ra   r]   r   r   r   r   r     s    %N '+T +r   r   N)$dataclassesr   typingr   django.templater   django.template.loaderr   django.utils.htmlr   django.utils.safestringr   django.utils.textr	   crispy_forms.utilsr
   r   r   r   r   r"   r[   rc   rp   r|   r   r   r   r   r   r   r   r   r   r   r   r   r   r   <module>r      s   !  $ 3 0 . % C C   
 M
$ M
`!P\ !PH4=< 4=n<=! <=~=&Y =&@=Y =@6Y 6r=&I =&@L=| L=^V= V=rGK, GKT1$# 1$h3'S 3'l8 8$M
L M
`,+u ,+r   