
    +hs              
         U d Z ddlmZ ddlZddlZddl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 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 ej,                  rd	dlmZ  ej2                  d      ZdZ eej;                  d            ZdZeD  ci c]*  } eD ]#  }|  | j;                  d       e |  | d      % , c}} Z! e"d      D cg c]  }d|dj;                  d       c}Z# G d dejH                        Z% G d de%      Z& G d de&      Z' G d de&      Z( e       e!iZ)d e*d!<   dHdId"Z+	 	 	 	 	 	 	 	 	 	 dJd#Z,dHdKd$Z-	 dL	 	 	 	 	 	 	 dMd%Z.	 	 	 	 dN	 	 	 	 	 	 	 	 	 dOd&Z/ e/       Z0 e/d'd()      Z1dPd*Z2	 	 	 	 dN	 	 	 	 	 	 	 	 	 	 	 dQd+Z3	 dR	 	 	 	 	 	 	 	 	 dSd,Z4dTd-Z5	 	 	 dU	 	 	 	 	 	 	 	 	 dVd.Z6	 dW	 	 	 	 	 	 	 dXd/Z7dYdZd0Z8d[d1Z9 ejt                  d2e9       d\d3Z; e<g  e"d4      d5d6      j{                         Z> e;d7e>      Z? e;d8e>d9z         Z@ e;d:e>d;z         ZA e;d<e>d=z         ZB	 	 d]	 	 	 	 	 	 	 d^d>ZC	 	 	 d_	 	 	 	 	 	 	 	 	 d`d?ZDdad@ZE	 	 	 	 	 db	 	 	 	 	 	 	 	 	 	 	 	 	 dcdAZF	 	 	 	 	 	 dd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 dedBZG	 	 	 	 	 	 	 	 	 	 dfdCZH	 	 	 	 dg	 	 	 	 	 	 	 	 	 	 	 dhdDZI	 	 	 	 	 di	 	 	 	 	 	 	 	 	 	 	 	 	 djdEZJ	 dk	 	 	 	 	 	 	 dldFZK	 dY	 	 	 	 	 dmdGZLyc c}} w c c}w )nzFunctions for working with URLs.

Contains implementations of functions from :mod:`urllib.parse` that
handle bytes and strings.
    )annotationsN)quote)unquote)	urlencode)urlsplit)
urlunsplit   )_check_str_tuple)_decode_idna)_make_encode_wrapper)_to_striter_multi_items)datastructuresz^[a-zA-Z0-9+-.]+$zKabcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-._~$!'()*+,;ascii0123456789ABCDEFabcdef      %02Xc                  @    e Zd ZU ded<   ded<   ded<   ded<   ded<   y)	_URLTuplestrschemenetlocpathqueryfragmentN)__name__
__module____qualname____annotations__     @/var/www/html/venv/lib/python3.12/site-packages/werkzeug/urls.pyr   r   2   s    KK
IJMr$   r   c                  T    e Zd ZU dZdZded<   ded<   ded<   ded<   d fdZdd	Zd d
Ze	d!d       Z
e	d!d       Ze	d"d       Ze	d!d       Ze	d!d       Ze	d!d       Ze	d!d       Ze	d!d       Zd#dZddZddZddZddZd$dZd$dZ	 d%	 	 	 d&dZd'dZd(dZd(dZ xZS ))BaseURLzSuperclass of :py:class:`URL` and :py:class:`BytesURL`.

    .. deprecated:: 2.3
        Will be removed in Werkzeug 3.0. Use the ``urllib.parse`` library instead.
    r#   r   _at_colon	_lbracket	_rbracketc                ~    t        j                  d| j                   dt        d       t	        |   | g|i |S )Nz'werkzeug.urls.z\' is deprecated and will be removed in Werkzeug 3.0. Use the 'urllib.parse' library instead.   
stacklevel)warningswarnr   DeprecationWarningsuper__new__)clsargskwargs	__class__s      r%   r4   zBaseURL.__new__G   sG    cll^ ,E E		
 ws4T4V44r$   c                "    | j                         S N)to_urlselfs    r%   __str__zBaseURL.__str__P   s    {{}r$   c                &     | j                   di |S )zReturn an URL with the same values, except for those parameters
        given new values by whichever keyword arguments are specified.r#   )_replace)r=   r7   s     r%   replacezBaseURL.replaceS   s     t}}&v&&r$   c                (    | j                         d   S )zThe host part of the URL if available, otherwise `None`.  The
        host is either the hostname or the IP address mentioned in the
        URL.  It will not contain the port.
        r   )_split_hostr<   s    r%   hostzBaseURL.hostX   s     !!$$r$   c                    | j                   }|3t        |t              r#	 |j                  d      j	                  d      }|S |S # t
        $ r Y |S w xY w)a   Works exactly like :attr:`host` but will return a result that
        is restricted to ASCII.  If it finds a netloc that is not ASCII
        it will attempt to idna decode it.  This is useful for socket
        operations when the URL might include internationalized characters.
        idnar   )rD   
isinstancer   encodedecodeUnicodeErrorr=   rvs     r%   
ascii_hostzBaseURL.ascii_host`   s]     YY>jS1YYv&--g6 	r	   	s    A 	AAc                    	 t        t        | j                         d               }d|cxk  rdk  r|S  y	 y# t        t        f$ r Y yw xY w)z}The port in the URL as an integer if it was present, `None`
        otherwise.  This does not fill in default ports.
        r	   r   i  N)intr   rC   
ValueError	TypeErrorrK   s     r%   portzBaseURL.porto   sf    
	WT--/234BB%	   	    I& 		s   18 8 A
	A
c                (    | j                         d   S )zSThe authentication part in the URL if available, `None`
        otherwise.
        r   )_split_netlocr<   s    r%   authzBaseURL.auth|   s    
 !!#A&&r$   c                D    | j                         d   }|t        |      S y)zThe username if it was part of the URL, `None` otherwise.
        This undergoes URL decoding and will always be a string.
        r   N_split_auth_url_unquote_legacyrK   s     r%   usernamezBaseURL.username   *    
 ">&r**r$   c                (    | j                         d   S )zThe username if it was part of the URL, `None` otherwise.
        Unlike :attr:`username` this one is not being decoded.
        r   rX   r<   s    r%   raw_usernamezBaseURL.raw_username       
 !!$$r$   c                D    | j                         d   }|t        |      S y)zThe password if it was part of the URL, `None` otherwise.
        This undergoes URL decoding and will always be a string.
        r	   NrW   rK   s     r%   passwordzBaseURL.password   r[   r$   c                (    | j                         d   S )zThe password if it was part of the URL, `None` otherwise.
        Unlike :attr:`password` this one is not being decoded.
        r	   r]   r<   s    r%   raw_passwordzBaseURL.raw_password   r_   r$   c                4    t        | j                  g|i |S )zDecodes the query part of the URL.  Ths is a shortcut for
        calling :func:`url_decode` on the query argument.  The arguments and
        keyword arguments are forwarded to :func:`url_decode` unchanged.
        )
url_decoder   r=   r6   r7   s      r%   decode_queryzBaseURL.decode_query   s    
 $**6t6v66r$   c                2    t        t        | g|i |      S )zJoins this URL with another one.  This is just a convenience
        function for calling into :meth:`url_join` and then parsing the
        return value again.
        )	url_parseurl_joinrf   s      r%   joinzBaseURL.join   s    
 $88899r$   c                    t        |       S )zReturns a URL string or bytes depending on the type of the
        information stored.  This is just a convenience function
        for calling :meth:`url_unparse` for this URL.
        )url_unparser<   s    r%   r;   zBaseURL.to_url   s    
 4  r$   c                   | j                   xs d}d|v rd| d}| j                  }|| d| }dj                  t        dt	        | j
                  xs dddd      t	        | j                  xs dddd      g            }|r| d	| }|S )
z6Encodes the netloc part to an ASCII safe URL as bytes. :[]Nutf-8strictz/:%@)rM   rR   rk   filter	url_quoter^   rc   )r=   rL   rR   rU   s       r%   encode_netloczBaseURL.encode_netloc   s    __""9RDByy4qBxxd//52w%Pd//52w%P
 62$B	r$   c           
     f   | j                   xs d}t        |t              r|j                         }t	        |      }d|v rd| d}| j
                  }|| d| }dj                  t        dt        | j                  xs dd      t        | j                  xs dd      g            }|r| d| }|S )z&Decodes the netloc part into a string.ro   rp   rq   rr   Nz/:%@ru   )rD   rG   bytesrI   r   rR   rk   rv   rY   r^   rc   )r=   rD   rL   rR   rU   s        r%   decode_netloczBaseURL.decode_netloc   s    yyBdE";;=D$"9RDByy4qBxx'(9(9(?RH'(9(9(?RH
 62$B	r$   c                *    t        t        |             S )a*  Returns a :class:`BytesURL` tuple that holds a URI.  This will
        encode all the information in the URL properly to ASCII using the
        rules a web browser would follow.

        It's usually more interesting to directly call :meth:`iri_to_uri` which
        will return a string.
        )ri   
iri_to_urir<   s    r%   to_uri_tuplezBaseURL.to_uri_tuple   s     D)**r$   c                *    t        t        |             S )aS  Returns a :class:`URL` tuple that holds a IRI.  This will try
        to decode as much information as possible in the URL without
        losing information similar to how a web browser does it for the
        URL bar.

        It's usually more interesting to directly call :meth:`uri_to_iri` which
        will return a string.
        )ri   
uri_to_irir<   s    r%   to_iri_tuplezBaseURL.to_iri_tuple   s     D)**r$   c                (   | j                   dk7  ryt        | j                        }| j                  xs d}|t        j
                  dk(  rd}nd}|dk(  r|dd dk(  r'|dd	 j                         r|d	d
 dv r|dd	  d|d
d  }|dd
 dv }ddl}|j                  |      }|rh|f|j                  d      j                  dd      }t        |      d	k(  r|\  }}n1|d   }d}n)|dk(  rddl}|j                  |      }nt        d|      |dv rd}||fS )a@  Returns a tuple with the location of the file in the form
        ``(server, location)``.  If the netloc is empty in the URL or
        points to localhost, it's represented as ``None``.

        The `pathformat` by default is autodetection but needs to be set
        when working with URLs of a specific system.  The supported values
        are ``'windows'`` when working with Windows or DOS paths and
        ``'posix'`` when working with posix paths.

        If the URL does not point to a local file, the server and location
        are both represented as ``None``.

        :param pathformat: The expected format of the path component.
                           Currently ``'windows'`` and ``'posix'`` are
                           supported.  Defaults to ``None`` which is
                           autodetect.
        fileNNNntwindowsposixr	   /r-      z|:rp   )z\\\z///r   \ro   zInvalid path format )z	127.0.0.1z::1	localhost)r   url_unquoter   r   osnameisalphantpathnormpathlstripsplitlen	posixpathrQ   )r=   
pathformatr   rD   windows_sharer   partsr   s           r%   get_file_locationzBaseURL.get_file_location   sG   ( ;;& 499%{{"dww$&
$
"BQx34!9#4#4#64!9;Lq)Ad12hZ0 !H(;;M??4(D
 D)//a8u:?!&JD$ 8DD7"%%d+D2:.ABB44DTzr$   c                    | j                   | j                  v r-| j                  j                  | j                         \  }}}||fS d | j                  fS r:   )r(   r   	partition)r=   rU   _r   s       r%   rT   zBaseURL._split_netloc=  sI    88t{{""kk33DHH=OD!V<T[[  r$   c                    | j                         d   }|sy| j                  |vr|d fS |j                  | j                        \  }}}||fS )Nr   r   )rT   r)   r   )r=   rU   rZ   r   ra   s        r%   rX   zBaseURL._split_authC  sU    !!#A&;;d": $t{{ ;!X!!r$   c                |   | j                         d   }|sy|j                  | j                        s5| j                  |v r#|j	                  | j                        \  }}}||fS |d fS |j                  | j                        }|dk  r|d fS |d| }||dz   d  }|j                  | j                        r||dd  fS |d fS )Nr	   r   r   )rT   
startswithr*   r)   r   findr+   )r=   rL   rD   r   rR   idxrests          r%   rC   zBaseURL._split_hostM  s    !!$}}T^^,{{b  "T[[ 9aTz!t8Oggdnn%7t8O!Cy#')}??4;;'ab>!Tzr$   )r6   t.Anyr7   r   returnr'   r   r   )r7   r   r   r'   )r   
str | None)r   
int | None)r6   r   r7   r   r   ds.MultiDict[str, str])r   r'   r:   )r   r   r   tuple[str | None, str | None])r   ztuple[str | None, str])r   r   )r   r    r!   __doc__	__slots__r"   r4   r>   rA   propertyrD   rM   rR   rU   rZ   r^   ra   rc   rg   rk   r;   rx   r{   r~   r   r   rT   rX   rC   __classcell__)r8   s   @r%   r'   r'   :   s    I	HKNN5'
 % %   
 
 ' '   % %   % %7:!*6+	+ (,<$<	&<|!"r$   r'   c                  .    e Zd ZdZdZdZdZdZdZd	d
dZ	y)URLzRepresents a parsed URL.  This behaves like a regular tuple but
    also has some extra attributes that give further insight into the
    URL.

    .. deprecated:: 2.3
        Will be removed in Werkzeug 3.0. Use the ``urllib.parse`` library instead.
    r#   ru   rp   rq   rr   c           
     
   t        | j                  j                  d      | j                         | j                  j                  ||      | j
                  j                  ||      | j                  j                  ||            S )zEncodes the URL to a tuple made out of bytes.  The charset is
        only being used for the path, query and fragment.
        r   )BytesURLr   rH   rx   r   r   r   r=   charseterrorss      r%   rH   z
URL.encoder  sk     KKw' IIWf-JJgv.MM  &1
 	
r$   Nrs   rA   )r   r   r   r   r   r   )
r   r    r!   r   r   r(   r)   r*   r+   rH   r#   r$   r%   r   r   c  s'     I
CFII

r$   r   c                  >    e Zd ZdZdZdZdZdZdZddZ	ddZ
ddd	Zy
)r   zRepresents a parsed URL in bytes.

    .. deprecated:: 2.3
        Will be removed in Werkzeug 3.0. Use the ``urllib.parse`` library instead.
    r#      @   :   [   ]c                B    | j                         j                  dd      S )Nrs   rA   )r;   rI   r<   s    r%   r>   zBytesURL.__str__  s    {{}##GY77r$   c                    | j                   S )z&Returns the netloc unchanged as bytes.)r   r<   s    r%   rx   zBytesURL.encode_netloc  s    {{r$   c           
     
   t        | j                  j                  d      | j                         | j                  j                  ||      | j
                  j                  ||      | j                  j                  ||            S )zDecodes the URL to a tuple made out of strings.  The charset is
        only being used for the path, query and fragment.
        r   )r   r   rI   r{   r   r   r   r   s      r%   rI   zBytesURL.decode  sk     KKw' IIWf-JJgv.MM  &1
 	
r$   Nr   )r   rz   r   )r   r   r   r   r   r   )r   r    r!   r   r   r(   r)   r*   r+   r>   rx   rI   r#   r$   r%   r   r     s1     I
CFII8

r$   r   z&dict[frozenset[int], dict[bytes, int]]_unquote_mapsc                   t        | t              r| j                  d      } t        |t              r|j                  d      }t        t	        |            }t        | j                  d            }t	        t        |d            }	 t        |   }|D ]V  }|d d }||v r)|j                  ||          |j                  |dd         5|j                  d       |j                  |       X t        |      S # t        $ r@ t        j                         D ci c]  \  }}||vs|| nc c}}w c}}x}t        |<   Y w xY w)Nrs      %r$   r-   %   )rG   r   rH   	frozenset	bytearrayiterr   nextr   KeyError
_hextobyteitemsappendextendrz   )	stringunsafegroupsresulthex_to_bytehbgroupcodes	            r%   _unquote_to_bytesr     s-   &#w'&#w'y()F&,,t$%FtFC()F
#F+  !Ray;MM+d+,MM%)$MM"MM% ! =  
'--//
Q1F?AqD/
 /
 	
mF+
s$   	C6 6 D?D)#D)(D?>D?c              #  J  K   ddl m}  ||       }|rt        ||      }|D ]}  \  }}|	t        |t              st        |      j                  |      }n|}t        |t              st        |      j                  |      }	n|}	t        |       dt        |	         y w)Nr	   r   )key=)r   r   sortedrG   rz   r   rH   _fast_url_quote_plus)
objr   sortr   r   iterablekey_str	value_str	key_bytesvalue_bytess
             r%   _url_encode_implr     s      1,<S,AH(,& W'5)G++G4II)U+i.//8K#K%i013G3T2UVVWs   B!B#c                \    	 t        | dd|      S # t        $ r t        | d|      cY S w xY w)Nrs   rt   )r   r   r   latin1)r   r   )r   rJ   )valuer   s     r%   rY   rY     s9    C5'(6RR C5(6BBCs    ++c                \   t        j                  dt        d       t        |       t	        | t
              }| d      } d      x}x}}| j                   d            }|dkD  rVt        j                  t        | d| d	            r3| |d
z   d }|rt        fd|D              r| d| j                         |} }| dd  d      k(  ryt        |       }	 d      D ]&  }
| j                  |
d      }|dk\  st        |	|      }	( | d|	 | |	d } } d      |v r
 d      |vs d      |v r d      |vrt        d      |r% d      | v r| j                   d      d
      \  } } d      | v r| j                   d      d
      \  } }|rt         nt"        } |||| ||      S )a  Parses a URL from a string into a :class:`URL` tuple.  If the URL
    is lacking a scheme it can be provided as second argument. Otherwise,
    it is ignored.  Optionally fragments can be stripped from the URL
    by setting `allow_fragments` to `False`.

    The inverse of this function is :func:`url_unparse`.

    :param url: the URL to parse.
    :param scheme: the default schema to use if the URL is schemaless.
    :param allow_fragments: if set to `False` a fragment will be removed
                            from the URL.

    .. deprecated:: 2.3
        Will be removed in Werkzeug 3.0. Use ``urllib.parse.urlsplit`` instead.
    zq'werkzeug.urls.url_parse' is deprecated and will be removed in Werkzeug 3.0. Use 'urllib.parse.urlsplit' instead.r-   r.   Nro   rp   r   rA   )r   r	   c              3  2   K   | ]  }| d       v  yw)
0123456789Nr#   ).0css     r%   	<genexpr>zurl_parse.<locals>.<genexpr>
  s     B1AlO3Bs   ///?#rq   rr   zInvalid IPv6 URL#?)r0   r1   r2   r   rG   r   r   
_scheme_rematchr   anylowerr   minrP   r   r   r   )urlr   allow_fragmentsis_text_basedr   r   r   ir   delimr   wdelimresult_typer   s                @r%   ri   ri     s   $ MM	0	 	S!AsC(M~2 !"%F%UX3A1u!!'#bq')"DE 1q57|sBTBBbq'--/4CF
2Aw!D'C5 	+AXXa^F{E6*	+ !ElCKcFf3v!5cFf3v!5/001S6S=		!C&!,Xv}YYqvq)
U&#HKvvsE8<<r$   c                ^   t        |t              r|j                  | |      }t        |t              r|j                  | |      }t        t	        |            t
        z  t        t	        |            z
  }t        d      D cg c]  }||v rt        |      nd|d c}dfd}|S c c}w )a  Precompile the translation table for a URL encoding function.

    Unlike :func:`url_quote`, the generated function only takes the
    string to quote.

    :param charset: The charset to encode the result with.
    :param errors: How to handle encoding errors.
    :param safe: An optional sequence of safe characters to never encode.
    :param unsafe: An optional sequence of unsafe characters to always encode.
    r   r   r   c                R    dj                  | D cg c]  }|   	 c}      S c c}w Nro   )rk   )r   r   tables     r%   r   z#_make_fast_url_quote.<locals>.quote=  s$    ww&1Qa1221s   $r   rz   r   r   )rG   r   rH   r   r   _always_saferangechr)r   r   safer   r   r   r   s         @r%   _make_fast_url_quoter  $  s      ${{7F+&#w/io&59VCT9UUD;@:FaqDySV!Ck1FE3 L Gs   B* +)r  r   c                8    t        |       j                  dd      S )Nr  r  )_fast_quote_plusrA   )r   s    r%   r   r   G  s    F#++C55r$   c                v   t        j                  dt        d       t        | t        t
        t        f      st	        |       } t        | t              r| j                  ||      } t        |t              r|j                  ||      }t        |t              r|j                  ||      }t        t        |            t        z  t        t        |            z
  }t               }t        |       D ]0  }||v r|j                  |       |j                  t        |          2 t        |      j                  |      S )a  URL encode a single string with a given encoding.

    :param s: the string to quote.
    :param charset: the charset to be used.
    :param safe: an optional sequence of safe characters.
    :param unsafe: an optional sequence of unsafe characters.

    .. deprecated:: 2.3
        Will be removed in Werkzeug 3.0. Use ``urllib.parse.quote`` instead.

    .. versionadded:: 0.9.2
       The `unsafe` parameter was added.
    zn'werkzeug.urls.url_quote' is deprecated and will be removed in Werkzeug 3.0. Use 'urllib.parse.quote' instead.r-   r.   )r0   r1   r2   rG   r   rz   r   rH   r   r  r   r   
_bytetohexrI   )r   r   r   r  r   rL   chars          r%   rw   rw   K  s    ( MM	-	 fsE956V&#w/${{7F+&#w/io&59VCT9UUD	B&! (4<IIdOIIj&'	(
 9G$$r$   c                ~    t        j                  dt        d       t        | |||dz   d      j	                  dd      S )aO  URL encode a single string with the given encoding and convert
    whitespace to "+".

    :param s: The string to quote.
    :param charset: The charset to be used.
    :param safe: An optional sequence of safe characters.

    .. deprecated:: 2.3
        Will be removed in Werkzeug 3.0. Use ``urllib.parse.quote_plus`` instead.
    zx'werkzeug.urls.url_quote_plus' is deprecated and will be removed in Werkzeug 2.4. Use 'urllib.parse.quote_plus' instead.r-   r.   r  r  )r0   r1   r2   rw   rA   )r   r   r   r  s       r%   url_quote_plusr  x  sA     MM	7	 VWfdSj#>FFsCPPr$   c                   t        j                  dt        d       t        |        | \  }}}}}t	        |      } |d      }|s|rK|j                   |d            r4|r|dd  |d      k7  r |d      |z   } |d      |xs  |d      z   |z   }n|r||z  }|r| |d	      z   |z   }|r| |d
      z   |z   }|r| |d      z   |z   }|S )ai  The reverse operation to :meth:`url_parse`.  This accepts arbitrary
    as well as :class:`URL` tuples and returns a URL as a string.

    :param components: the parsed URL as tuple which should be converted
                       into a URL string.

    .. deprecated:: 2.3
        Will be removed in Werkzeug 3.0. Use ``urllib.parse.urlunsplit`` instead.
    zu'werkzeug.urls.url_unparse' is deprecated and will be removed in Werkzeug 3.0. Use 'urllib.parse.urlunsplit' instead.r-   r.   ro   r   Nr	   r   rp   r   r   )r0   r1   r2   r
   r   r   )
componentsr   r   r   r   r   r   r   s           r%   rm   rm     s     MM	2	 Z ,6)FFD%V$A
B%C &T__QsV4D!H#&S6D=Dg1R5)D0	tqvo#AcFlU"AcFlX%Jr$   c                ~    t        j                  dt        d       t        | |      }||S |j	                  ||      S )a  URL decode a single string with a given encoding.  If the charset
    is set to `None` no decoding is performed and raw bytes are
    returned.

    :param s: the string to unquote.
    :param charset: the charset of the query string.  If set to `None`
        no decoding will take place.
    :param errors: the error handling for the charset decoding.

    .. deprecated:: 2.3
        Will be removed in Werkzeug 3.0. Use ``urllib.parse.unquote`` instead.
    zr'werkzeug.urls.url_unquote' is deprecated and will be removed in Werkzeug 3.0. Use 'urllib.parse.unquote' instead.r-   r.   )r0   r1   r2   r   rI   )r   r   r   r   rL   s        r%   r   r     sD    $ MM	/	 
1f	%B	99Wf%%r$   c                    t        j                  dt        d       t        | t              r| j                  dd      } n| j                  dd      } t        | ||      S )a&  URL decode a single string with the given `charset` and decode "+" to
    whitespace.

    Per default encoding errors are ignored.  If you want a different behavior
    you can set `errors` to ``'replace'`` or ``'strict'``.

    :param s: The string to unquote.
    :param charset: the charset of the query string.  If set to `None`
        no decoding will take place.
    :param errors: The error handling for the `charset` decoding.

    .. deprecated:: 2.3
        Will be removed in Werkzeug 3.0. Use ``urllib.parse.unquote_plus`` instead.
    z|'werkzeug.urls.url_unquote_plus' is deprecated and will be removed in Werkzeug 2.4. Use 'urllib.parse.unquote_plus' instead.r-   r.   r  r     +    )r0   r1   r2   rG   r   rA   r   )r   r   r   s      r%   url_unquote_plusr    sV    " MM	9	 !SIIc3IIdD!q'6**r$   c                   t        j                  dt        d       t        | |d      j	                  dd      } | j                  d      r"| dd	 j                         r| d	d
 dv rd| dd  } t        |       }t        |j                  |d      }t        |j                  |d      }t        |j                  |d      }t        |j                  |j                         |||f      S )aF  Sometimes you get an URL by a user that just isn't a real URL because
    it contains unsafe characters like ' ' and so on. This function can fix
    some of the problems in a similar way browsers handle data entered by the
    user:

    >>> url_fix('http://de.wikipedia.org/wiki/Elf (Begriffskl\xe4rung)')
    'http://de.wikipedia.org/wiki/Elf%20(Begriffskl%C3%A4rung)'

    :param s: the string with the URL to fix.
    :param charset: The target charset for the URL if the url was given
        as a string.

    .. deprecated:: 2.3
        Will be removed in Werkzeug 3.0.
    zJ'werkzeug.urls.url_fix' is deprecated and will be removed in Werkzeug 3.0.r-   r.   rA   r   r   zfile://      
   )z:/z|/zfile:///Nz
/%+$!*'(),r  z:&%=+$!*'(),)r0   r1   r2   r   rA   r   r   ri   rw   r   r  r   r   rm   r   rx   )r   r   r   r   qsanchors         r%   url_fixr    s      MMT 	7I&..tS9A 	||I1Qq6>>#3!B<8Oqug
A,CSXXw\:D			7	@BCLL'GF

C$5$5$7r6JKKr$   c                z    t        | j                  | j                  | j                   d      }|| j                  fS )zRUsed in :func:`uri_to_iri` after unquoting to re-quote any
    invalid bytes.
    ro   r  )r   objectstartend)eouts     r%   _codec_error_url_quoter$    s1     155)
3C:r$   werkzeug.url_quotec                    dj                  d t        |      D              }t        j                  d| dt        j                        dfd}d|  |_        |S )zCreate a function that unquotes all percent encoded characters except those
    given. This allows working with unquoted characters if possible while not changing
    the meaning of a given part of a URL.
    |c              3  6   K   | ]  }t        |      d   yw)r   N)ord)r   r   s     r%   r   z%_make_unquote_part.<locals>.<genexpr>-  s     >1#a&>s   z((?:%(?:z))+)c                    t        j                  |             }g }|D ]9  }|j                  t        |||             |j                  t	        |d             ; dj                  |      S r   )r   r   r   r   r   rk   )r   encodingr   r   r#  partpatterns         r%   _unquote_partialz,_make_unquote_part.<locals>._unquote_partial0  sa    W]]5)* 	(DJJwtXv67JJtE2'	( wws|r$   	_unquote_)r   r   r+  r   r   r   r   r   )rk   r   recompileIr   )r   charschoicesr.  r-  s       @r%   _make_unquote_partr5  (  sW    
 hh>u>>Gjj8G9D12448G #,D6 2r$   !   r      r   r   z&=+#r   r   userz:@/?#c                z   t        | t              r't        j                  dt        d       t        |       } t        | t              r,t        j                  dt        d       | j                         } |t        j                  dt        d       nd}|t        j                  dt        d       nd}t        |       }t        |j                  ||      }t        |j                  ||      }t        |j                  ||      }|j                  rt!        |j                        }nd	}d
|v rd| d}|j"                  r| d
|j"                   }|j$                  rFt'        |j$                  ||      }|j(                  r| d
t'        |j(                  ||       }| d| }t        |j*                  ||||f      S )a  Convert a URI to an IRI. All valid UTF-8 characters are unquoted,
    leaving all reserved and invalid characters quoted. If the URL has
    a domain, it is decoded from Punycode.

    >>> uri_to_iri("http://xn--n3h.net/p%C3%A5th?q=%C3%A8ry%DF")
    'http://\u2603.net/p\xe5th?q=\xe8ry%DF'

    :param uri: The URI to convert.
    :param charset: The encoding to encode unquoted bytes with.
    :param errors: Error handler to use during ``bytes.encode``. By
        default, invalid bytes are left quoted.

    .. versionchanged:: 2.3
        Passing a tuple or bytes, and the ``charset`` and ``errors`` parameters, are
        deprecated and will be removed in Werkzeug 3.0.

    .. versionchanged:: 2.3
        Which characters remain quoted is specific to each part of the URL.

    .. versionchanged:: 0.15
        All reserved and invalid characters remain quoted. Previously,
        only some reserved characters were preserved, and invalid bytes
        were replaced instead of left quoted.

    .. versionadded:: 0.6
    HPassing a tuple is deprecated and will not be supported in Werkzeug 3.0.r-   r.   FPassing bytes is deprecated and will not be supported in Werkzeug 3.0.JThe 'charset' parameter is deprecated and will be removed in Werkzeug 3.0.rs   IThe 'errors' parameter is deprecated and will be removed in Werkzeug 3.0.r%  ro   rp   rq   rr   ru   )rG   tupler0   r1   r2   r   rz   rI   r   _unquote_pathr   _unquote_queryr   _unquote_fragmentr   hostnamer   rR   rZ   _unquote_userra   r   )	urir   r   r   r   r   r   r   rU   s	            r%   r   r   H  s   > #uV	

 o#uT	

 jjl 		
 W	
 &SMEWf5D5;;8E &AH~~enn-
f}VHAzz81UZZL)~~U^^Wf=>>V1]5>>7FKLMD66(#u||VT5(CDDr$   c                x   |t        j                  dt        d       nd}t        | t              r't        j                  dt        d       t        |       } t        | t              r-t        j                  dt        d       | j                  |      } |t        j                  dt        d       nd}|t        j                  d	t        d       |r1	 | j                  d
      }t        |j                               dk(  r| S 	 t        |       }t        |j                  d||      }t        |j                  d||      }t        |j                   d||      }|j"                  r+|j"                  j                  d      j                  d
      }	nd}	d|	v rd|	 d}	|j$                  r|	 d|j$                   }	|j&                  rHt        |j&                  d      }
|j(                  rt        |j(                  d      }|
 d| }
|
 d|	 }	t        |j*                  |	|||f      S # t        $ r Y 0w xY w)a   Convert an IRI to a URI. All non-ASCII and unsafe characters are
    quoted. If the URL has a domain, it is encoded to Punycode.

    >>> iri_to_uri('http://\u2603.net/p\xe5th?q=\xe8ry%DF')
    'http://xn--n3h.net/p%C3%A5th?q=%C3%A8ry%DF'

    :param iri: The IRI to convert.
    :param charset: The encoding of the IRI.
    :param errors: Error handler to use during ``bytes.encode``.

    .. versionchanged:: 2.3
        Passing a tuple or bytes, and the ``charset`` and ``errors`` parameters, are
        deprecated and will be removed in Werkzeug 3.0.

    .. versionchanged:: 2.3
        Which characters remain unquoted is specific to each part of the URL.

    .. versionchanged:: 2.3
        The ``safe_conversion`` parameter is deprecated and will be removed in Werkzeug
        2.4.

    .. versionchanged:: 0.15
        All reserved characters remain unquoted. Previously, only some reserved
        characters were left unquoted.

    .. versionchanged:: 0.9.6
       The ``safe_conversion`` parameter was added.

    .. versionadded:: 0.6
    r<  r-   r.   rs   r:  r;  r=  rt   zRThe 'safe_conversion' parameter is deprecated and will be removed in Werkzeug 3.0.r   r	   z%!$&'()*+,/:;=@)r  r+  r   z%!$&'()*+,/:;=?@z%!#$&'()*+,/:;=?@rF   ro   rp   rq   rr   z%!$&'()*+,;=r  ru   )r0   r1   r2   rG   r>  r   rz   rI   rH   r   r   rJ   r   r   r   r   r   rB  rR   rZ   ra   r   )irir   r   safe_conversion	ascii_irir   r   r   r   r   rU   pass_quoteds               r%   r}   r}     s"   H  		
 #uV	

 o#uT	

 jj!W	
 "		
 	

7+I 9??$%*
 +
 SME "3gfUD%++$6QWXE076H ~~&&v.55g>
f}VHAzz81UZZL)~~U^^.9>>^DKV1[M*D66(#u||VT5(CDDA  		s   .H, ,	H98H9c                    	 | j                  d       t        | j                  dd            dk(  r| S t	        |       S # t        $ r Y t	        |       S w xY w)a  The URL scheme ``itms-services://`` must contain the ``//`` even though it does
    not have a host component. There may be other invalid schemes as well. Currently,
    responses will always call ``iri_to_uri`` on the redirect ``Location`` header, which
    removes the ``//``. For now, if the IRI only contains ASCII and does not contain
    spaces, pass it on as-is. In Werkzeug 3.0, this should become a
    ``response.process_location`` flag.

    :meta private:
    r   Nr	   )rH   r   r   rJ   r}   )rF  s    r%   _invalid_iri_to_urirK     s\    

7 syyq!"a'Jc?  
 c?s   > 	AAc                j   t        j                  dt        d       |ddlm} |}t        | t              r&t        |t              s|j                  |xs d      }n5t        | t              r%t        |t              s|j                  |xs d      } |t        | j                  |      |||            S )a  Parse a query string and return it as a :class:`MultiDict`.

    :param s: The query string to parse.
    :param charset: Decode bytes to string with this charset. If not
        given, bytes are returned as-is.
    :param include_empty: Include keys with empty values in the dict.
    :param errors: Error handling behavior when decoding bytes.
    :param separator: Separator character between pairs.
    :param cls: Container to hold result instead of :class:`MultiDict`.

    .. deprecated:: 2.3
        Will be removed in Werkzeug 3.0. Use ``urllib.parse.parse_qs`` instead.

    .. versionchanged:: 2.1
        The ``decode_keys`` parameter was removed.

    .. versionchanged:: 0.5
        In previous versions ";" and "&" could be used for url decoding.
        Now only "&" is supported. If you want to use ";", a different
        ``separator`` can be provided.

    .. versionchanged:: 0.5
        The ``cls`` parameter was added.
    zr'werkzeug.urls.url_decode' is deprecated and will be removed in Werkzeug 2.4. Use 'urllib.parse.parse_qs' instead.r-   r.   r	   	MultiDictr   )r0   r1   r2   r   rN  rG   r   rI   rz   rH   _url_decode_implr   )r   r   include_emptyr   	separatorr5   rN  s          r%   re   re   5  s    @ MM	0	 {-!S*Y"<$$W%78		Au	jE&B$$W%78	GGI	
 r$   c                    t        j                  dt        d       ddlm}  || ||      }t        ||||      }	|ddlm}
 |
} ||	      S )a  Works like :func:`url_decode` but decodes a stream.  The behavior
    of stream and limit follows functions like
    :func:`~werkzeug.wsgi.make_line_iter`.  The generator of pairs is
    directly fed to the `cls` so you can consume the data while it's
    parsed.

    :param stream: a stream with the encoded querystring
    :param charset: the charset of the query string.  If set to `None`
        no decoding will take place.
    :param include_empty: Set to `False` if you don't want empty values to
                          appear in the dict.
    :param errors: the decoding error behavior.
    :param separator: the pair separator to be used, defaults to ``&``
    :param cls: an optional dict class to use.  If this is not specified
                       or `None` the default :class:`MultiDict` is used.
    :param limit: the content length of the URL data.  Not necessary if
                  a limited stream is provided.

    .. deprecated:: 2.3
        Will be removed in Werkzeug 2.4. Use ``urllib.parse.parse_qs`` instead.

    .. versionchanged:: 2.1
        The ``decode_keys`` and ``return_iterator`` parameters were removed.

    .. versionadded:: 0.8
    zy'werkzeug.urls.url_decode_stream' is deprecated and will be removed in Werkzeug 2.4. Use 'urllib.parse.parse_qs' instead.r-   r.   r	   )make_chunk_iterrM  )r0   r1   r2   wsgirS  rO  r   rN  )streamr   rP  r   rQ  r5   limitrS  	pair_iterdecoderrN  s              r%   url_decode_streamrY  k  sV    F MM	>	 &	59Iy'=&IG
{-w<r$   c              #     K   | D ][  }|st        |      } |d      }||v r|j                  |d      \  }}n|s6|} |d      }t        |||      t        |||      f ] y w)Nr   r	   ro   )r   r   r  )	rW  r   rP  r   pairr   equalr   r   s	            r%   rO  rO    s       
 &#D=E1-JC CbEES'62UGV4
 	

s   A"A$c                    t        j                  dt        d       t        |d      }|j	                  t        | |||            S )aP  URL encode a dict/`MultiDict`.  If a value is `None` it will not appear
    in the result string.  Per default only values are encoded into the target
    charset strings.

    :param obj: the object to encode into a query string.
    :param charset: the charset of the query string.
    :param sort: set to `True` if you want parameters to be sorted by `key`.
    :param separator: the separator to be used for the pairs.
    :param key: an optional function to be used for sorting.  For more details
                check out the :func:`sorted` documentation.

    .. deprecated:: 2.3
        Will be removed in Werkzeug 2.4. Use ``urllib.parse.urlencode`` instead.

    .. versionchanged:: 2.1
        The ``encode_keys`` parameter was removed.

    .. versionchanged:: 0.5
        Added the ``sort``, ``key``, and ``separator`` parameters.
    zs'werkzeug.urls.url_encode' is deprecated and will be removed in Werkzeug 2.4. Use 'urllib.parse.urlencode' instead.r-   r.   r   )r0   r1   r2   r   rk   r   )r   r   r   r   rQ  s        r%   
url_encoder^    sD    6 MM	1	 	7+I>>*3sCDDr$   c                    t        j                  dt        d       t        |d      }t	        | |||      }||S t        |      D ])  \  }}|r|j                  |       |j                  |       + y)a  Like :meth:`url_encode` but writes the results to a stream
    object.  If the stream is `None` a generator over all encoded
    pairs is returned.

    :param obj: the object to encode into a query string.
    :param stream: a stream to write the encoded object into or `None` if
                   an iterator over the encoded pairs should be returned.  In
                   that case the separator argument is ignored.
    :param charset: the charset of the query string.
    :param sort: set to `True` if you want parameters to be sorted by `key`.
    :param separator: the separator to be used for the pairs.
    :param key: an optional function to be used for sorting.  For more details
                check out the :func:`sorted` documentation.

    .. deprecated:: 2.3
        Will be removed in Werkzeug 2.4. Use ``urllib.parse.urlencode`` instead.

    .. versionchanged:: 2.1
        The ``encode_keys`` parameter was removed.

    .. versionadded:: 0.8
    zz'werkzeug.urls.url_encode_stream' is deprecated and will be removed in Werkzeug 2.4. Use 'urllib.parse.urlencode' instead.r-   r.   r   N)r0   r1   r2   r   r   	enumeratewrite)	r   rU  r   r   r   rQ  genr   chunks	            r%   url_encode_streamrd    sz    < MM	?	 	7+I
3s
3C~
n 
ULL#U r$   c                   t        j                  dt        d       t        | t              rt        |       } t        |t              rt        |      }t        | |f       t        |       }| s|S |s| S t        | |      \  }}}}}t        |||      \  }	}
}}}|	|k7  r|S |
rt        |	|
|||f      S |}
|dd  |d      k(  r|j                   |d            }nP|s|j                   |d            }|s5|}n2|j                   |d            dd |j                   |d            z   }|d    |d	      k(  r |d
      |d<   |D cg c]  }| |d	      k7  s| }}	 d}t        |      dz
  }||k  r=||    |d      k(  r$||dz
      |d
       |d      fvr||dz
  |dz   = n|dz  }||k  r=nT |d
       |d      g}|dd |k(  r|d= |dd |k(  r |d      j                  |      }t        |	|
|||f      S c c}w )aq  Join a base URL and a possibly relative URL to form an absolute
    interpretation of the latter.

    :param base: the base URL for the join operation.
    :param url: the URL to join.
    :param allow_fragments: indicates whether fragments should be allowed.

    .. deprecated:: 2.3
        Will be removed in Werkzeug 2.4. Use ``urllib.parse.urljoin`` instead.
    zo'werkzeug.urls.url_join' is deprecated and will be removed in Werkzeug 2.4. Use 'urllib.parse.urljoin' instead.r-   r.   )r   Nr	   r   .ro   z..)r0   r1   r2   rG   r>  rm   r
   r   ri   r   r   rk   )baser   r   r   bschemebnetlocbpathbquery	bfragmentr   r   r   r   r   segmentssegmentr   nunwanted_markers                      r%   rj   rj     s[    MM	/	 $4 #u#dC[!T"A
1:o2.GWeVY -6c7O,T)FFD%
FFD%BCCFBQx1S6::af%;;qv&E;;qv&s+djj3.@@ |qvu (0EG7af3DEHE
MA!e{ag%(1q5/!B%4AQ*QQUQU]+FA	 !e   uag&O
2A,/
)QK 2A,/
) S6;;x DeX>??% Fs   G>G>c                d    t        |       D cg c]
  }|d   	| }}t        |d|      S c c}w )Nr	   z!$'()*,/:;?@)r  r+  )r   r   )r   r+  xr   s       r%   
_urlencodert  \  s:     )/D11Q43CQDEDU(CC Es   
--)ro   )r   str | bytesr   ru  r   rz   )
r   1t.Mapping[str, str] | t.Iterable[tuple[str, str]]r   r   r   boolr   +t.Callable[[tuple[str, str]], t.Any] | Noner   zt.Iterator[str])r   r   r   r   r   r   )NT)r   r   r   r   r   rw  r   r'   )rs   rt   z/:ro   )
r   r   r   r   r  ru  r   ru  r   zt.Callable[[bytes], str]r   )r   ru  r   r   r   r   r  ru  r   ru  r   r   )rs   rt   ro   )
r   r   r   r   r   r   r  r   r   r   )r  ztuple[str, str, str, str, str]r   r   )rs   rA   ro   )
r   ru  r   r   r   r   r   r   r   r   r   )r   ru  r   r   r   r   r   r   )rs   )r   r   r   r   r   r   )r"  rJ   r   ztuple[str, int])r   r   r3  r   r   z t.Callable[[str, str, str], str]r   )rD  $str | tuple[str, str, str, str, str]r   r   r   r   r   r   )NNN)
rF  ry  r   r   r   r   rG  zbool | Noner   r   )rF  r   r   r   )rs   TrA   &N)r   zt.AnyStrr   r   rP  rw  r   r   rQ  r   r5   type[ds.MultiDict] | Noner   r   )rs   TrA      &NN)rU  zt.IO[bytes]r   r   rP  rw  r   r   rQ  rz   r5   r{  rV  r   r   r   )
rW  zt.Iterable[t.AnyStr]r   r   rP  rw  r   r   r   zt.Iterator[tuple[str, str]])rs   FNrz  )r   rv  r   r   r   rw  r   rx  rQ  r   r   r   )Nrs   FNrz  )r   rv  rU  zt.IO[str] | Noner   r   r   rw  r   rx  rQ  r   r   None)T)rh  ry  r   ry  r   rw  r   r   )r   rv  r+  r   r   r   )Mr   
__future__r   codecsr   r0  typingtr0   urllib.parser   r   r   r   r   	_internalr
   r   r   r   r   r   TYPE_CHECKINGro   dsr1  r   _always_safe_charsr   rH   r  
_hexdigitsrO   r   r  r  
NamedTupler   r'   r   r   r   r"   r   r   rY   ri   r  _fast_url_quoter	  r   rw   r  rm   r   r  r  r$  register_errorr5  rz   rI   _always_unsaferA  r@  r?  rC  r   r}   rK  re   rY  rO  r^  rd  rj   rt  )ar   r  s   000r%   <module>r     s1  
 #  	 	      " ! # ' # +  ,??& RZZ,-
  +227;<%
 	 	
 	c!IWsaS9b11

 :?sD$sn##G,D
 fi fR	
' 
8
w 
B :Cj8Q5 Q>W	:WW W 
5	W
 W<C BF:=	:= :=:>:=:=| 	  	
 > '('S= 6 *%*%*% *% 	*%
 *% 	*%\ NPQQQ14QGJQQ.%T 	&&& & 	&
 	&> ;D++ +47++@#LL   *,B C2 1t1d1D1299;&z>B #G^f-DE"6>E+AB"6>G+CD
 ZE	-ZEZE ZE 		ZE~ #'	xE	-xExE xE !	xE
 	xEv. %)333 3 	3
 3 
#3 3p %)444 4 	4
 4 
#4 4 4n
#
.1
BF
PS
 
. 7;"E	:"E"E "E 
5	"E
 "E 	"EN  $7;,	:,, , 	,
 
5, , 
,d !N@
.N@	-N@ N@ 		N@d OVD<DHKDDe)
 Es   /K%K+