o
    Yh                     @  s  U d dl mZ d dl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mZmZmZmZmZmZ d dlmZ d dlmZ d d	lmZmZ d d
lmZmZmZ d dlmZ d dlm Z m!Z!m"Z"m#Z# d dl$m%Z%m&Z&m'Z' d dl(m)Z)m*Z* d dl+m,Z, d dl-m.Z/ d dl0m1Z2 d dl3m4Z5 d dl6m7Z8 d dl9m:Z: d dl;m<Z< d dl=m>Z>m?Z? d dl@mAZAmBZBmCZCmDZD d dlEmFZF d dlGmHZH d dlImJZJ erd dlKmLZL dZMdeNd< eeOePeeejQf ZRdeNd < eG d!d" d"ZSG d#d$ d$ZT	d1d2d/d0ZUdS )3    )annotationsN)	dataclass)Path)dedent)TYPE_CHECKINGBinaryIOFinalLiteralTextIOUnioncast)	TypeAlias)runtime)current_form_id
is_in_form)LayoutConfigWidthvalidate_width)check_widget_policies)Keycompute_and_register_element_idsave_for_app_testingto_key)StreamlitAPIExceptionStreamlitMissingPageLabelErrorStreamlitPageNotFoundError)get_main_script_directorynormalize_path_join)StreamlitPage)Button)DownloadButton)
LinkButton)PageLink)gather_metrics)PagesManager)ScriptRunContextget_script_run_ctx)
WidgetArgsWidgetCallbackWidgetKwargsregister_widget)validate_icon_or_emoji)is_url)
in_sidebar)DeltaGeneratorz

For more information, refer to the
[documentation for forms](https://docs.streamlit.io/develop/api-reference/execution-flow/st.form).
r   FORM_DOCS_INFOr   DownloadButtonDataTypec                   @  s    e Zd ZdddZddd	Zd
S )ButtonSerdevboolreturnc                 C  s   t |S N)r3   )selfr2    r7   b/var/www/html/Persson_Maskin/env/lib/python3.10/site-packages/streamlit/elements/widgets/button.py	serializeR      zButtonSerde.serializeui_valuebool | Nonec                 C  s   |pdS )NFr7   )r6   r;   r7   r7   r8   deserializeU   r:   zButtonSerde.deserializeN)r2   r3   r4   r3   )r;   r<   r4   r3   )__name__
__module____qualname__r9   r=   r7   r7   r7   r8   r1   P   s    
r1   c                   @  s0  e Zd Zed					dDdddddddEddZed					 		dFdddddddGd&d'Zed(ddddddd)dHd,d-Zed.ddddddd/dId2d3Z					 		dFdddddd4dJd7d8Zddddd9dKd:d;Z	dddddd<dLd=d>Z
			dMdddddd4dNd@dAZedOdBdCZdS )PButtonMixinbuttonN	secondaryFcontent)typeicondisableduse_container_widthwidthlabelstrkey
Key | Nonehelp
str | Noneon_clickWidgetCallback | NoneargsWidgetArgs | NonekwargsWidgetKwargs | NonerE   +Literal['primary', 'secondary', 'tertiary']rF   rG   r3   rH   r<   rI   r   r4   c                C  s^   t |}t }|
dur|
rdnd}|dvrtd| d| jj|||d||||	||||dS )	u  Display a button widget.

        Parameters
        ----------
        label : str
            A short label explaining to the user what this button is for.
            The label can optionally contain GitHub-flavored Markdown of the
            following types: Bold, Italics, Strikethroughs, Inline Code, Links,
            and Images. Images display like icons, with a max height equal to
            the font height.

            Unsupported Markdown elements are unwrapped so only their children
            (text contents) render. Display unsupported elements as literal
            characters by backslash-escaping them. E.g.,
            ``"1\. Not an ordered list"``.

            See the ``body`` parameter of |st.markdown|_ for additional,
            supported Markdown directives.

            .. |st.markdown| replace:: ``st.markdown``
            .. _st.markdown: https://docs.streamlit.io/develop/api-reference/text/st.markdown

        key : str or int
            An optional string or integer to use as the unique key for the widget.
            If this is omitted, a key will be generated for the widget
            based on its content. No two widgets may have the same key.

        help : str or None
            A tooltip that gets displayed when the button is hovered over. If
            this is ``None`` (default), no tooltip is displayed.

            The tooltip can optionally contain GitHub-flavored Markdown,
            including the Markdown directives described in the ``body``
            parameter of ``st.markdown``.

        on_click : callable
            An optional callback invoked when this button is clicked.

        args : list or tuple
            An optional list or tuple of args to pass to the callback.

        kwargs : dict
            An optional dict of kwargs to pass to the callback.

        type : "primary", "secondary", or "tertiary"
            An optional string that specifies the button type. This can be one
            of the following:

            - ``"primary"``: The button's background is the app's primary color
              for additional emphasis.
            - ``"secondary"`` (default): The button's background coordinates
              with the app's background color for normal emphasis.
            - ``"tertiary"``: The button is plain text without a border or
              background for subtlety.

        icon : str or None
            An optional emoji or icon to display next to the button label. If ``icon``
            is ``None`` (default), no icon is displayed. If ``icon`` is a
            string, the following options are valid:

            - A single-character emoji. For example, you can set ``icon="🚨"``
              or ``icon="🔥"``. Emoji short codes are not supported.

            - An icon from the Material Symbols library (rounded style) in the
              format ``":material/icon_name:"`` where "icon_name" is the name
              of the icon in snake case.

              For example, ``icon=":material/thumb_up:"`` will display the
              Thumb Up icon. Find additional icons in the `Material Symbols \
              <https://fonts.google.com/icons?icon.set=Material+Symbols&icon.style=Rounded>`_
              font library.

        disabled : bool
            An optional boolean that disables the button if set to ``True``.
            The default is ``False``.

        use_container_width : bool
            Whether to expand the button's width to fill its parent container.
            If ``use_container_width`` is ``False`` (default), Streamlit sizes
            the button to fit its contents. If ``use_container_width`` is
            ``True``, the width of the button matches its parent container.

            In both cases, if the contents of the button are wider than the
            parent container, the contents will line wrap.

        width : "content", "stretch", or int
            The width of the button. This can be one of the following:

            - ``"content"`` (default): The width of the button matches the
              width of its content, but doesn't exceed the width of the parent
              container.
            - ``"stretch"``: The width of the button matches the width of the
              parent container.
            - An integer specifying the width in pixels: The button has a
              fixed width. If the specified width is greater than the width of
              the parent container, the width of the button matches the width
              of the parent container.

        .. deprecated::
            ``use_container_width`` is deprecated and will be removed in a
            future release. For ``use_container_width=True``, use
            ``width="stretch"``. For ``use_container_width=False``, use
            ``width="content"``.

        Returns
        -------
        bool
            True if the button was clicked on the last run of the app,
            False otherwise.

        Examples
        --------
        **Example 1: Customize your button type**

        >>> import streamlit as st
        >>>
        >>> st.button("Reset", type="primary")
        >>> if st.button("Say hello"):
        ...     st.write("Why hello there")
        ... else:
        ...     st.write("Goodbye")
        >>>
        >>> if st.button("Aloha", type="tertiary"):
        ...     st.write("Ciao")

        .. output::
           https://doc-buton.streamlit.app/
           height: 300px

        **Example 2: Add icons to your button**

        Although you can add icons to your buttons through Markdown, the
        ``icon`` parameter is a convenient and consistent alternative.

        >>> import streamlit as st
        >>>
        >>> left, middle, right = st.columns(3)
        >>> if left.button("Plain button", width="stretch"):
        ...     left.markdown("You clicked the plain button.")
        >>> if middle.button("Emoji button", icon="😃", width="stretch"):
        ...     middle.markdown("You clicked the emoji button.")
        >>> if right.button("Material button", icon=":material/mood:", width="stretch"):
        ...     right.markdown("You clicked the Material button.")

        .. output::
           https://doc-button-icons.streamlit.app/
           height: 220px

        NstretchrD   primaryrC   tertiaryzhThe type argument to st.button must be "primary", "secondary", or "tertiary". 
The argument passed was "".F)	is_form_submitterrP   rR   rT   rG   rE   rF   ctxrI   )r   r&   r   dg_button)r6   rJ   rL   rN   rP   rR   rT   rE   rF   rG   rH   rI   r]   r7   r7   r8   rB   Z   s2    &zButtonMixin.buttondownload_buttonrerundatar0   	file_namemime2WidgetCallback | Literal['rerun', 'ignore'] | Nonec
                C  sX   t  }|dur|rdnd}|
dvrtd|
 d| j|||||||||	|
||||dS )u,  Display a download button widget.

        This is useful when you would like to provide a way for your users
        to download a file directly from your app.

        Note that the data to be downloaded is stored in-memory while the
        user is connected, so it's a good idea to keep file sizes under a
        couple hundred megabytes to conserve memory.

        If you want to prevent your app from rerunning when a user clicks the
        download button, wrap the download button in a `fragment
        <https://docs.streamlit.io/develop/concepts/architecture/fragments>`_.

        Parameters
        ----------
        label : str
            A short label explaining to the user what this button is for.
            The label can optionally contain GitHub-flavored Markdown of the
            following types: Bold, Italics, Strikethroughs, Inline Code, Links,
            and Images. Images display like icons, with a max height equal to
            the font height.

            Unsupported Markdown elements are unwrapped so only their children
            (text contents) render. Display unsupported elements as literal
            characters by backslash-escaping them. E.g.,
            ``"1\. Not an ordered list"``.

            See the ``body`` parameter of |st.markdown|_ for additional,
            supported Markdown directives.

            .. |st.markdown| replace:: ``st.markdown``
            .. _st.markdown: https://docs.streamlit.io/develop/api-reference/text/st.markdown

        data : str, bytes, or file
            The contents of the file to be downloaded.

            To prevent unncecessary recomputation, use caching when converting
            your data for download. For more information, see the Example 1
            below.

        file_name: str
            An optional string to use as the name of the file to be downloaded,
            such as ``"my_file.csv"``. If not specified, the name will be
            automatically generated.

        mime : str or None
            The MIME type of the data. If this is ``None`` (default), Streamlit
            sets the MIME type depending on the value of ``data`` as follows:

            - If ``data`` is a string or textual file (i.e. ``str`` or
              ``io.TextIOWrapper`` object), Streamlit uses the "text/plain"
              MIME type.
            - If ``data`` is a binary file or bytes (i.e. ``bytes``,
              ``io.BytesIO``, ``io.BufferedReader``, or ``io.RawIOBase``
              object), Streamlit uses the "application/octet-stream" MIME type.

            For more information about MIME types, see
            https://www.iana.org/assignments/media-types/media-types.xhtml.

        key : str or int
            An optional string or integer to use as the unique key for the widget.
            If this is omitted, a key will be generated for the widget
            based on its content. No two widgets may have the same key.

        help : str or None
            A tooltip that gets displayed when the button is hovered over. If
            this is ``None`` (default), no tooltip is displayed.

            The tooltip can optionally contain GitHub-flavored Markdown,
            including the Markdown directives described in the ``body``
            parameter of ``st.markdown``.

        on_click : callable, "rerun", "ignore", or None
            How the button should respond to user interaction. This controls
            whether or not the button triggers a rerun and if a callback
            function is called. This can be one of the following values:

            - ``"rerun"`` (default): The user downloads the file and the app
              reruns. No callback function is called.
            - ``"ignore"``: The user downloads the file and the app doesn't
              rerun. No callback function is called.
            - A ``callable``: The user downloads the file and app reruns. The
              callable is called before the rest of the app.
            - ``None``: This is same as ``on_click="rerun"``. This value exists
              for backwards compatibility and shouldn't be used.

        args : list or tuple
            An optional list or tuple of args to pass to the callback.

        kwargs : dict
            An optional dict of kwargs to pass to the callback.

        type : "primary", "secondary", or "tertiary"
            An optional string that specifies the button type. This can be one
            of the following:

            - ``"primary"``: The button's background is the app's primary color
              for additional emphasis.
            - ``"secondary"`` (default): The button's background coordinates
              with the app's background color for normal emphasis.
            - ``"tertiary"``: The button is plain text without a border or
              background for subtlety.

        icon : str or None
            An optional emoji or icon to display next to the button label. If ``icon``
            is ``None`` (default), no icon is displayed. If ``icon`` is a
            string, the following options are valid:

            - A single-character emoji. For example, you can set ``icon="🚨"``
              or ``icon="🔥"``. Emoji short codes are not supported.

            - An icon from the Material Symbols library (rounded style) in the
              format ``":material/icon_name:"`` where "icon_name" is the name
              of the icon in snake case.

              For example, ``icon=":material/thumb_up:"`` will display the
              Thumb Up icon. Find additional icons in the `Material Symbols \
              <https://fonts.google.com/icons?icon.set=Material+Symbols&icon.style=Rounded>`_
              font library.

        disabled : bool
            An optional boolean that disables the download button if set to
            ``True``. The default is ``False``.

        use_container_width : bool
            Whether to expand the button's width to fill its parent container.
            If ``use_container_width`` is ``False`` (default), Streamlit sizes
            the button to fit its contents. If ``use_container_width`` is
            ``True``, the width of the button matches its parent container.

            In both cases, if the contents of the button are wider than the
            parent container, the contents will line wrap.

        width : "content", "stretch", or int
            The width of the download button. This can be one of the following:

            - ``"content"`` (default): The width of the button matches the
              width of its content, but doesn't exceed the width of the parent
              container.
            - ``"stretch"``: The width of the button matches the width of the
              parent container.
            - An integer specifying the width in pixels: The button has a
              fixed width. If the specified width is greater than the width of
              the parent container, the width of the button matches the width
              of the parent container.

        .. deprecated::
            ``use_container_width`` is deprecated and will be removed in a
            future release. For ``use_container_width=True``, use
            ``width="stretch"``. For ``use_container_width=False``, use
            ``width="content"``.

        Returns
        -------
        bool
            True if the button was clicked on the last run of the app,
            False otherwise.

        Examples
        --------
        **Example 1: Download a dataframe as a CSV file**

        When working with a large dataframe, it's recommended to fetch your
        data with a cached function. When working with a download button, it's
        similarly recommended to convert your data into a downloadable format
        with a cached function. Caching ensures that the app reruns
        efficiently.

        >>> import streamlit as st
        >>> import pandas as pd
        >>> import numpy as np
        >>>
        >>> @st.cache_data
        >>> def get_data():
        >>>     df = pd.DataFrame(
        ...         np.random.randn(50, 20), columns=("col %d" % i for i in range(20))
        ...     )
        >>>     return df
        >>>
        >>> @st.cache_data
        >>> def convert_for_download(df):
        >>>     return df.to_csv().encode("utf-8")
        >>>
        >>> df = get_data()
        >>> csv = convert_for_download(df)
        >>>
        >>> st.download_button(
        ...     label="Download CSV",
        ...     data=csv,
        ...     file_name="data.csv",
        ...     mime="text/csv",
        ...     icon=":material/download:",
        ... )

        .. output::
           https://doc-download-button-csv.streamlit.app/
           height: 200px

        **Example 2: Download a string as a text file**

        If you pass a string to the ``data`` argument, Streamlit will
        automatically use the "text/plain" MIME type.

        When you have a widget (like a text area) affecting the value of your
        download, it's recommended to use another button to prepare the
        download. In this case, use ``on_click="ignore"`` in your download
        button to prevent the download button from rerunning your app. This
        turns the download button into a frontend-only element that can be
        nested in another button.

        Without a preparation button, a user can type something into the text
        area and immediately click the download button. Because a download is
        initiated concurrently with the app rerun, this can create a race-like
        condition where the user doesn't see the updated data in their
        download.

        .. important::
           Even when you prevent your download button from triggering a rerun,
           another widget with a pending change can still trigger a rerun. For
           example, if a text area has a pending change when a user clicks a
           download button, the text area will trigger a rerun.

        >>> import streamlit as st
        >>>
        >>> message = st.text_area("Message", value="Lorem ipsum.\nStreamlit is cool.")
        >>>
        >>> if st.button("Prepare download"):
        >>>     st.download_button(
        ...         label="Download text",
        ...         data=message,
        ...         file_name="message.txt",
        ...         on_click="ignore",
        ...         type="primary",
        ...         icon=":material/download:",
        ...     )

        .. output::
           https://doc-download-button-text.streamlit.app/
           height: 250px

        **Example 3: Download a file**

        Use a context manager to open and read a local file on your Streamlit
        server. Pass the ``io.BufferedReader`` object directly to ``data``.
        Remember to specify the MIME type if you don't want the default
        type of ``"application/octet-stream"`` for generic binary data. In the
        example below, the MIME type is set to ``"image/png"`` for a PNG file.

        >>> import streamlit as st
        >>>
        >>> with open("flower.png", "rb") as file:
        ...     st.download_button(
        ...         label="Download image",
        ...         data=file,
        ...         file_name="flower.png",
        ...         mime="image/png",
        ...     )

        .. output::
           https://doc-download-button-file.streamlit.app/
           height: 200px

        NrW   rD   rX   zqThe type argument to st.download_button must be "primary", "secondary", or "tertiary". 
The argument passed was "r[   )rJ   rb   rc   rd   rL   rN   rP   rR   rT   rE   rF   rG   r]   rI   )r&   r   _download_button)r6   rJ   rb   rc   rd   rL   rN   rP   rR   rT   rE   rF   rG   rH   rI   r]   r7   r7   r8   r`     s6     zButtonMixin.download_buttonlink_button)rN   rE   rF   rG   rH   rI   urlr.   c          	   	   C  sD   |dvrt d| d|dur|rdnd}| j|||||||dS )u  Display a link button element.

        When clicked, a new tab will be opened to the specified URL. This will
        create a new session for the user if directed within the app.

        Parameters
        ----------
        label : str
            A short label explaining to the user what this button is for.
            The label can optionally contain GitHub-flavored Markdown of the
            following types: Bold, Italics, Strikethroughs, Inline Code, Links,
            and Images. Images display like icons, with a max height equal to
            the font height.

            Unsupported Markdown elements are unwrapped so only their children
            (text contents) render. Display unsupported elements as literal
            characters by backslash-escaping them. E.g.,
            ``"1\. Not an ordered list"``.

            See the ``body`` parameter of |st.markdown|_ for additional,
            supported Markdown directives.

            .. |st.markdown| replace:: ``st.markdown``
            .. _st.markdown: https://docs.streamlit.io/develop/api-reference/text/st.markdown

        url : str
            The url to be opened on user click

        help : str or None
            A tooltip that gets displayed when the button is hovered over. If
            this is ``None`` (default), no tooltip is displayed.

            The tooltip can optionally contain GitHub-flavored Markdown,
            including the Markdown directives described in the ``body``
            parameter of ``st.markdown``.

        type : "primary", "secondary", or "tertiary"
            An optional string that specifies the button type. This can be one
            of the following:

            - ``"primary"``: The button's background is the app's primary color
              for additional emphasis.
            - ``"secondary"`` (default): The button's background coordinates
              with the app's background color for normal emphasis.
            - ``"tertiary"``: The button is plain text without a border or
              background for subtlety.

        icon : str or None
            An optional emoji or icon to display next to the button label. If ``icon``
            is ``None`` (default), no icon is displayed. If ``icon`` is a
            string, the following options are valid:

            - A single-character emoji. For example, you can set ``icon="🚨"``
              or ``icon="🔥"``. Emoji short codes are not supported.

            - An icon from the Material Symbols library (rounded style) in the
              format ``":material/icon_name:"`` where "icon_name" is the name
              of the icon in snake case.

              For example, ``icon=":material/thumb_up:"`` will display the
              Thumb Up icon. Find additional icons in the `Material Symbols \
              <https://fonts.google.com/icons?icon.set=Material+Symbols&icon.style=Rounded>`_
              font library.

        disabled : bool
            An optional boolean that disables the link button if set to
            ``True``. The default is ``False``.

        use_container_width : bool
            Whether to expand the button's width to fill its parent container.
            If ``use_container_width`` is ``False`` (default), Streamlit sizes
            the button to fit its contents. If ``use_container_width`` is
            ``True``, the width of the button matches its parent container.

            In both cases, if the contents of the button are wider than the
            parent container, the contents will line wrap.

        width : "content", "stretch", or int
            The width of the link button. This can be one of the following:

            - ``"content"`` (default): The width of the button matches the
              width of its content, but doesn't exceed the width of the parent
              container.
            - ``"stretch"``: The width of the button matches the width of the
              parent container.
            - An integer specifying the width in pixels: The button has a
              fixed width. If the specified width is greater than the width of
              the parent container, the width of the button matches the width
              of the parent container.

        .. deprecated::
            ``use_container_width`` is deprecated and will be removed in a
            future release. For ``use_container_width=True``, use
            ``width="stretch"``. For ``use_container_width=False``, use
            ``width="content"``.

        Example
        -------
        >>> import streamlit as st
        >>>
        >>> st.link_button("Go to gallery", "https://streamlit.io/gallery")

        .. output::
           https://doc-link-button.streamlit.app/
           height: 200px

        rX   zmThe type argument to st.link_button must be "primary", "secondary", or "tertiary". 
The argument passed was "r[   NrW   rD   )rJ   rh   rN   rG   rE   rF   rI   )r   _link_button)	r6   rJ   rh   rN   rE   rF   rG   rH   rI   r7   r7   r8   rg   Q  s"   yzButtonMixin.link_button	page_link)rJ   rF   rN   rG   rH   rI   pagestr | Path | StreamlitPagec                C  s8   |dur
|rdnd}t | jrd}| j||||||dS )u  Display a link to another page in a multipage app or to an external page.

        If another page in a multipage app is specified, clicking ``st.page_link``
        stops the current page execution and runs the specified page as if the
        user clicked on it in the sidebar navigation.

        If an external page is specified, clicking ``st.page_link`` opens a new
        tab to the specified page. The current script run will continue if not
        complete.

        Parameters
        ----------
        page : str, Path, or StreamlitPage
            The file path (relative to the main script) or a ``StreamlitPage``
            indicating the page to switch to. Alternatively, this can be the
            URL to an external page (must start with "http://" or "https://").

        label : str
            The label for the page link. Labels are required for external pages.
            The label can optionally contain GitHub-flavored Markdown of the
            following types: Bold, Italics, Strikethroughs, Inline Code, Links,
            and Images. Images display like icons, with a max height equal to
            the font height.

            Unsupported Markdown elements are unwrapped so only their children
            (text contents) render. Display unsupported elements as literal
            characters by backslash-escaping them. E.g.,
            ``"1\. Not an ordered list"``.

            See the ``body`` parameter of |st.markdown|_ for additional,
            supported Markdown directives.

            .. |st.markdown| replace:: ``st.markdown``
            .. _st.markdown: https://docs.streamlit.io/develop/api-reference/text/st.markdown

        icon : str or None
            An optional emoji or icon to display next to the button label. If
            ``icon`` is ``None`` (default), the icon is inferred from the
            ``StreamlitPage`` object or no icon is displayed. If ``icon`` is a
            string, the following options are valid:

            - A single-character emoji. For example, you can set ``icon="🚨"``
              or ``icon="🔥"``. Emoji short codes are not supported.

            - An icon from the Material Symbols library (rounded style) in the
              format ``":material/icon_name:"`` where "icon_name" is the name
              of the icon in snake case.

              For example, ``icon=":material/thumb_up:"`` will display the
              Thumb Up icon. Find additional icons in the `Material Symbols \
              <https://fonts.google.com/icons?icon.set=Material+Symbols&icon.style=Rounded>`_
              font library.

        help : str or None
            A tooltip that gets displayed when the link is hovered over. If
            this is ``None`` (default), no tooltip is displayed.

            The tooltip can optionally contain GitHub-flavored Markdown,
            including the Markdown directives described in the ``body``
            parameter of ``st.markdown``.

        disabled : bool
            An optional boolean that disables the page link if set to ``True``.
            The default is ``False``.

        use_container_width : bool
            Whether to expand the link's width to fill its parent container.
            The default is ``True`` for page links in the sidebar and ``False``
            for those in the main app.

        width : "content", "stretch", or int
            The width of the page-link button. This can be one of the following:

            - ``"content"`` (default): The width of the button matches the
              width of its content, but doesn't exceed the width of the parent
              container.
            - ``"stretch"``: The width of the button matches the width of the
              parent container.
            - An integer specifying the width in pixels: The button has a
              fixed width. If the specified width is greater than the width of
              the parent container, the width of the button matches the width
              of the parent container.

        .. deprecated::
            ``use_container_width`` is deprecated and will be removed in a
            future release. For ``use_container_width=True``, use
            ``width="stretch"``. For ``use_container_width=False``, use
            ``width="content"``.

        Example
        -------
        Consider the following example given this file structure:

        >>> your-repository/
        >>> ├── pages/
        >>> │   ├── page_1.py
        >>> │   └── page_2.py
        >>> └── your_app.py

        >>> import streamlit as st
        >>>
        >>> st.page_link("your_app.py", label="Home", icon="🏠")
        >>> st.page_link("pages/page_1.py", label="Page 1", icon="1️⃣")
        >>> st.page_link("pages/page_2.py", label="Page 2", icon="2️⃣", disabled=True)
        >>> st.page_link("http://www.google.com", label="Google", icon="🌎")

        The default navigation is shown here for comparison, but you can hide
        the default navigation using the |client.showSidebarNavigation|_
        configuration option. This allows you to create custom, dynamic
        navigation menus for your apps!

        .. |client.showSidebarNavigation| replace:: ``client.showSidebarNavigation``
        .. _client.showSidebarNavigation: https://docs.streamlit.io/develop/api-reference/configuration/config.toml#client

        .. output ::
            https://doc-page-link.streamlit.app/
            height: 350px

        NrW   rD   )rk   rJ   rF   rN   rG   rI   )r-   r^   
_page_link)r6   rk   rJ   rF   rN   rG   rH   rI   r7   r7   r8   rj     s    
zButtonMixin.page_link)rE   rF   rG   r]   rI   r]   ScriptRunContext | Nonec
                C  s6  t |}|d u s|dv rd ntd|}t| j||d dd td|| j||||||
|d
}t| jr8tdt t }||_	||_
d|_|
|_t| j |||| ||_|d ur^t||_|d urgt||_|dkrod	|_nd|_t }t|j	|||	|j|j|d
d}t|d	d t|d}| jjd||d |jS )N>   ra   ignorer(   F)	on_changedefault_valuewrites_allowedr`   )	user_keyr^   rJ   rF   rc   rd   rN   rE   rI   z7`st.download_button()` can't be used in an `st.form()`.ro   Ttrigger_valueon_change_handlerrR   rT   deserializer
serializerr]   
value_typeallow_contentrI   layout_config)r   r   r   r^   r   r   r   r/   DownloadButtonProtoidrJ   defaultrE   marshall_file_get_delta_path_strrG   r   rN   r+   rF   ignore_rerunr1   r*   r=   r9   r   r   _enqueuevalue)r6   rJ   rb   rc   rd   rL   rN   rP   rR   rT   rE   rF   rG   r]   rI   on_click_callback
element_iddownload_button_protoserdebutton_stater~   r7   r7   r8   rf   p  sz   



zButtonMixin._download_button)rE   rF   rG   rI   c          
      C  sj   t  }||_||_||_||_|d urt||_|d ur!t||_t	|dd t
|d}	| jjd||	dS )NTrz   r|   rg   r}   )LinkButtonProtorJ   rh   rE   rG   r   rN   r+   rF   r   r   r^   r   )
r6   rJ   rh   rN   rE   rF   rG   rI   link_button_protor~   r7   r7   r8   ri     s   


zButtonMixin._link_button)rJ   rF   rN   rG   rI   c                C  s  t  }t|dd t }|st|d}	| jjd||	dS ||_|d ur&||_|d ur/t||_	|d ur8t
||_t|trV|j|_|j|_|d u rM|j|_|d u rU|j	|_	n|t|tr_t|}t|r|d u sk|dkrnt ||_d|_t|d}	| jjd||	dS d}
i }|j}
|j }t|
}tjt||}|  D ]#}|d }|d }|d	 }||kr|d u r||_|d
 |_||_ nq|jdkrt!||t"t#j$dt|d}	| jjd||	dS )NTrz   r|   rj   r}    script_path	page_nameurl_pathnamepage_script_hash)rk   main_script_directoryuses_pages_directory)%PageLinkProtor   r&   r   r^   r   rG   rJ   r+   rF   r   rN   
isinstancer   _script_hashr   url_pathrk   titler   rK   r,   r   externalmain_script_pathpages_manager	get_pagesr   ospathrealpathr   valuesr   r3   r$   r   )r6   rk   rJ   rF   rN   rG   rI   page_link_protor]   r~   ctx_main_scriptall_app_pagesr   requested_page	page_data	full_pathr   r   r7   r7   r8   rm     s~   










zButtonMixin._page_linkr\   c                C  sF  t |}t| j||d d| d |rt| jnd}td|| j||	||||d	}t rGt| jr9|s9tdt	 t| jsG|rGtdt	 t
 }||_||_d|_||_||_||_|
|_|d urht||_|	d urqt|	|_t }t|j||||j|j|dd	}|rt|||j t|d
d t|d}| jjd||d |jS )NF)rq   rr   enable_check_callback_rulesr   rB   )rs   r^   rJ   rF   rN   r\   rE   rI   z.`st.button()` can't be used in an `st.form()`.z=`st.form_submit_button()` must be used inside an `st.form()`.rt   ru   Trz   r|   r}   )r   r   r^   r   r   r   existsr   r   r/   ButtonProtor   rJ   r   r\   form_idrE   rG   r   rN   r+   rF   r1   r*   r=   r9   r   r   r   r   r   )r6   rJ   rL   rN   r\   rP   rR   rT   rE   rF   rG   r]   rI   r   r   button_protor   r   r~   r7   r7   r8   r_   D  sv   



zButtonMixin._buttonc                 C  s
   t d| S )zGet our DeltaGenerator.r.   )r   )r6   r7   r7   r8   r^     s   
zButtonMixin.dg)NNNNN)rJ   rK   rL   rM   rN   rO   rP   rQ   rR   rS   rT   rU   rE   rV   rF   rO   rG   r3   rH   r<   rI   r   r4   r3   )NNNNra   NN)rJ   rK   rb   r0   rc   rO   rd   rO   rL   rM   rN   rO   rP   re   rR   rS   rT   rU   rE   rV   rF   rO   rG   r3   rH   r<   rI   r   r4   r3   )rJ   rK   rh   rK   rN   rO   rE   rV   rF   rO   rG   r3   rH   r<   rI   r   r4   r.   )rk   rl   rJ   rO   rF   rO   rN   rO   rG   r3   rH   r<   rI   r   r4   r.   )rJ   rK   rb   r0   rc   rO   rd   rO   rL   rM   rN   rO   rP   re   rR   rS   rT   rU   rE   rV   rF   rO   rG   r3   r]   rn   rI   r   r4   r3   )rJ   rK   rh   rK   rN   rO   rE   rV   rF   rO   rG   r3   rI   r   r4   r.   )rk   rl   rJ   rO   rF   rO   rN   rO   rG   r3   rI   r   r4   r.   )NNN)rJ   rK   rL   rO   rN   rO   r\   r3   rP   rQ   rR   rS   rT   rU   rE   rV   rF   rO   rG   r3   r]   rn   rI   r   r4   r3   )r4   r.   )r>   r?   r@   r#   rB   r`   rg   rj   rf   ri   rm   r_   propertyr^   r7   r7   r7   r8   rA   Y   s    	 A  7  c!`
]rA   coordinatesrK   rb   proto_download_buttonr   mimetyperO   rc   r4   Nonec                 C  s  t |tr| }|pd}nft |tjr!| }| }|pd}nSt |tr-|}|p+d}nGt |tjrA|d |	 }|p?d}n3t |tj
rU|d | }|pSd}nt |tjrk|d | ped}|pid}n	tdt| t rt jj||| |dd}nd}||_d S )	Nz
text/plainzapplication/octet-streamr       zInvalid binary data format: T)rc   is_for_static_downloadr   )r   rK   encodeioTextIOWrapperreadbytesBytesIOseekgetvalueBufferedReader	RawIOBaser   rE   r   r   get_instancemedia_file_mgraddrh   )r   rb   r   r   rc   data_as_bytesstring_datafile_urlr7   r7   r8   r     sB   











	
r   r5   )r   rK   rb   r0   r   r   r   rO   rc   rO   r4   r   )V
__future__r   r   r   dataclassesr   pathlibr   textwrapr   typingr   r   r   r	   r
   r   r   typing_extensionsr   	streamlitr   !streamlit.elements.lib.form_utilsr   r   #streamlit.elements.lib.layout_utilsr   r   r   streamlit.elements.lib.policiesr   streamlit.elements.lib.utilsr   r   r   r   streamlit.errorsr   r   r   streamlit.file_utilr   r   streamlit.navigation.pager   streamlit.proto.Button_pb2r   r   "streamlit.proto.DownloadButton_pb2r    r   streamlit.proto.LinkButton_pb2r!   r   streamlit.proto.PageLink_pb2r"   r   streamlit.runtime.metrics_utilr#   streamlit.runtime.pages_managerr$   streamlit.runtime.scriptrunnerr%   r&   streamlit.runtime.stater'   r(   r)   r*   streamlit.string_utilr+   streamlit.url_utilr,   streamlit.utilr-   streamlit.delta_generatorr.   r/   __annotations__rK   r   r   r0   r1   rA   r   r7   r7   r7   r8   <module>   sX   $
        [