ó
    Rì?gúa  ã                   ó¸  • S r SSKrSSKJr  SSKJr  SSKJr  SSKJ	r	J
r
Jr  SSKJr  SSKJrJrJrJr  SS	KJrJrJrJrJrJrJrJrJr   " S
 S\R:                  5      r " S S\5      r " S S\R@                  5      r! " S S\R@                  5      r"\\S\\   \\\#S4   \4   \\\#S4   \\\#\4   4   \\\#S4   \\\#\4   \#4   4      r$ " S S\5      r% " S S\\%5      r& " S S\'5      r( " S S\'5      r) " S S\)5      r* " S S\)5      r+ " S S\)5      r, " S  S!\)5      r- " S" S#\(5      r.\S$\#S%\/4S& j5       r0\S)S' j5       r0S$\\#   S%\\/   4S( jr0g)*ap  Flexible routing implementation.

Tornado routes HTTP requests to appropriate handlers using `Router`
class implementations. The `tornado.web.Application` class is a
`Router` implementation and may be used directly, or the classes in
this module may be used for additional flexibility. The `RuleRouter`
class can match on more criteria than `.Application`, or the `Router`
interface can be subclassed for maximum customization.

`Router` interface extends `~.httputil.HTTPServerConnectionDelegate`
to provide additional routing capabilities. This also means that any
`Router` implementation can be used directly as a ``request_callback``
for `~.httpserver.HTTPServer` constructor.

`Router` subclass must implement a ``find_handler`` method to provide
a suitable `~.httputil.HTTPMessageDelegate` instance to handle the
request:

.. code-block:: python

    class CustomRouter(Router):
        def find_handler(self, request, **kwargs):
            # some routing logic providing a suitable HTTPMessageDelegate instance
            return MessageDelegate(request.connection)

    class MessageDelegate(HTTPMessageDelegate):
        def __init__(self, connection):
            self.connection = connection

        def finish(self):
            self.connection.write_headers(
                ResponseStartLine("HTTP/1.1", 200, "OK"),
                HTTPHeaders({"Content-Length": "2"}),
                b"OK")
            self.connection.finish()

    router = CustomRouter()
    server = HTTPServer(router)

The main responsibility of `Router` implementation is to provide a
mapping from a request to `~.httputil.HTTPMessageDelegate` instance
that will handle this request. In the example above we can see that
routing is possible even without instantiating an `~.web.Application`.

For routing to `~.web.RequestHandler` implementations we need an
`~.web.Application` instance. `~.web.Application.get_handler_delegate`
provides a convenient way to create `~.httputil.HTTPMessageDelegate`
for a given request and `~.web.RequestHandler`.

Here is a simple example of how we can we route to
`~.web.RequestHandler` subclasses by HTTP method:

.. code-block:: python

    resources = {}

    class GetResource(RequestHandler):
        def get(self, path):
            if path not in resources:
                raise HTTPError(404)

            self.finish(resources[path])

    class PostResource(RequestHandler):
        def post(self, path):
            resources[path] = self.request.body

    class HTTPMethodRouter(Router):
        def __init__(self, app):
            self.app = app

        def find_handler(self, request, **kwargs):
            handler = GetResource if request.method == "GET" else PostResource
            return self.app.get_handler_delegate(request, handler, path_args=[request.path])

    router = HTTPMethodRouter(Application())
    server = HTTPServer(router)

`ReversibleRouter` interface adds the ability to distinguish between
the routes and reverse them to the original urls using route's name
and additional arguments. `~.web.Application` is itself an
implementation of `ReversibleRouter` class.

`RuleRouter` and `ReversibleRuleRouter` are implementations of
`Router` and `ReversibleRouter` interfaces and can be used for
creating rule-based routing configurations.

Rules are instances of `Rule` class. They contain a `Matcher`, which
provides the logic for determining whether the rule is a match for a
particular request and a target, which can be one of the following.

1) An instance of `~.httputil.HTTPServerConnectionDelegate`:

.. code-block:: python

    router = RuleRouter([
        Rule(PathMatches("/handler"), ConnectionDelegate()),
        # ... more rules
    ])

    class ConnectionDelegate(HTTPServerConnectionDelegate):
        def start_request(self, server_conn, request_conn):
            return MessageDelegate(request_conn)

2) A callable accepting a single argument of `~.httputil.HTTPServerRequest` type:

.. code-block:: python

    router = RuleRouter([
        Rule(PathMatches("/callable"), request_callable)
    ])

    def request_callable(request):
        request.write(b"HTTP/1.1 200 OK\r\nContent-Length: 2\r\n\r\nOK")
        request.finish()

3) Another `Router` instance:

.. code-block:: python

    router = RuleRouter([
        Rule(PathMatches("/router.*"), CustomRouter())
    ])

Of course a nested `RuleRouter` or a `~.web.Application` is allowed:

.. code-block:: python

    router = RuleRouter([
        Rule(HostMatches("example.com"), RuleRouter([
            Rule(PathMatches("/app1/.*"), Application([(r"/app1/handler", Handler)])),
        ]))
    ])

    server = HTTPServer(router)

In the example below `RuleRouter` is used to route between applications:

.. code-block:: python

    app1 = Application([
        (r"/app1/handler", Handler1),
        # other handlers ...
    ])

    app2 = Application([
        (r"/app2/handler", Handler2),
        # other handlers ...
    ])

    router = RuleRouter([
        Rule(PathMatches("/app1.*"), app1),
        Rule(PathMatches("/app2.*"), app2)
    ])

    server = HTTPServer(router)

For more information on application-level routing see docs for `~.web.Application`.

.. versionadded:: 4.5

é    N)Úpartial)Úhttputil)Ú_CallableAdapter)Ú
url_escapeÚurl_unescapeÚutf8)Úapp_log)Úbasestring_typeÚimport_objectÚre_unescapeÚunicode_type)	ÚAnyÚUnionÚOptionalÚ	AwaitableÚListÚDictÚPatternÚTupleÚoverloadc                   óš   • \ rS rSrSrS\R                  S\S\\R                     4S jr
S\S\R                  S\R                  4S	 jrS
rg)ÚRouteré¾   zAbstract router interface.ÚrequestÚkwargsÚreturnc                 ó   • [        5       e)aº  Must be implemented to return an appropriate instance of `~.httputil.HTTPMessageDelegate`
that can serve the request.
Routing implementations may pass additional kwargs to extend the routing logic.

:arg httputil.HTTPServerRequest request: current HTTP request.
:arg kwargs: additional keyword arguments passed by routing implementation.
:returns: an instance of `~.httputil.HTTPMessageDelegate` that will be used to
    process the request.
©ÚNotImplementedError)Úselfr   r   s      Ú1/usr/lib/python3/dist-packages/tornado/routing.pyÚfind_handlerÚRouter.find_handlerÁ   s   € ô "Ó#Ð#ó    Úserver_connÚrequest_connc                 ó   • [        XU5      $ ©N)Ú_RoutingDelegate)r    r%   r&   s      r!   Ústart_requestÚRouter.start_requestÏ   s   € ô   °<Ó@Ð@r$   © N)Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r   ÚHTTPServerRequestr   r   ÚHTTPMessageDelegater"   ÚobjectÚHTTPConnectionr*   Ú__static_attributes__r,   r$   r!   r   r   ¾   s`   † Ù$ð$Ø×1Ñ1ð$Ø=@ð$à	�(×.Ñ.Ñ	/ô$ðAØ!ðAØ19×1HÑ1HðAà	×	%Ñ	%÷Ar$   r   c                   ó4   • \ rS rSrSrS\S\S\\   4S jrSr	g)	ÚReversibleRouteréÕ   zpAbstract router interface for routers that can handle named routes
and support reversing them to original urls.
ÚnameÚargsr   c                 ó   • [        5       e)zÙReturns url string for a given route name and arguments
or ``None`` if no match is found.

:arg str name: route name.
:arg args: url parameters.
:returns: parametrized url string for a given route name (or ``None``).
r   )r    r:   r;   s      r!   Úreverse_urlÚReversibleRouter.reverse_urlÚ   s   € ô "Ó#Ð#r$   r,   N)
r-   r.   r/   r0   r1   Ústrr   r   r=   r6   r,   r$   r!   r8   r8   Õ   s%   † ñð$ ð $¨Cð $°H¸S±M÷ $r$   r8   c                   óÜ   • \ rS rSrS\S\S\R                  SS4S jrS\	\R                  \R                  4   S	\R                  S\\S      4S
 jrS\S\\S      4S jrSS jrSS jrSrg)r)   éå   Úrouterr%   r&   r   Nc                 ó6   • X l         X0l        S U l        Xl        g r(   )r%   r&   ÚdelegaterB   )r    rB   r%   r&   s       r!   Ú__init__Ú_RoutingDelegate.__init__æ   s   € ð 'ÔØ(ÔØˆŒØ�r$   Ú
start_lineÚheadersc                 ó¶  • [        U[        R                  5      (       d   e[        R                  " U R                  U R
                  UUS9nU R                  R                  U5      U l        U R                  cF  [        R                  " SUR                  UR                  5        [        U R                  5      U l        U R                  R                  X5      $ )N)Ú
connectionÚserver_connectionrG   rH   z$Delegate for %s %s request not found)Ú
isinstancer   ÚRequestStartLiner2   r&   r%   rB   r"   rD   r	   ÚdebugÚmethodÚpathÚ_DefaultMessageDelegateÚheaders_received)r    rG   rH   r   s       r!   rR   Ú!_RoutingDelegate.headers_receivedî   s¯   € ô
 ˜*¤h×&?Ñ&?×@Ñ@Ð@Ð@Ü×,Ò,Ø×(Ñ(Ø"×.Ñ.Ø!Øñ	
ˆð Ÿ™×0Ñ0°Ó9ˆŒØ�=‰=Ñ Ü�MŠMØ6Ø×!Ñ!Ø—‘ôô
 4°D×4EÑ4EÓFˆDŒMà�}‰}×-Ñ-¨jÓBÐBr$   Úchunkc                 óV   • U R                   c   eU R                   R                  U5      $ r(   )rD   Údata_received)r    rT   s     r!   rV   Ú_RoutingDelegate.data_received  s'   € Ø�}‰}Ñ(Ð(Ð(Ø�}‰}×*Ñ*¨5Ó1Ð1r$   c                 óV   • U R                   c   eU R                   R                  5         g r(   )rD   Úfinish©r    s    r!   rY   Ú_RoutingDelegate.finish
  s"   € Ø�}‰}Ñ(Ð(Ð(Ø�‰×ÑÕr$   c                 óV   • U R                   c   eU R                   R                  5         g r(   )rD   Úon_connection_closerZ   s    r!   r]   Ú$_RoutingDelegate.on_connection_close  s"   € Ø�}‰}Ñ(Ð(Ð(Ø�‰×)Ñ)Õ+r$   )rD   r&   rB   r%   ©r   N)r-   r.   r/   r0   r   r4   r   r5   rE   r   rM   ÚResponseStartLineÚHTTPHeadersr   r   rR   ÚbytesrV   rY   r]   r6   r,   r$   r!   r)   r)   å   s�   † ðØðØ+1ðØAI×AXÑAXðà	ôðCà˜(×3Ñ3°X×5OÑ5OÐOÑPðCð ×%Ñ%ðCð 
�)˜D‘/Ñ	"ô	Cð02 5ð 2¨X°iÀ±oÑ-Fô 2ô÷,r$   r)   c                   óD   • \ rS rSrS\R
                  SS4S jrSS jrSrg)	rQ   i  rJ   r   Nc                 ó   • Xl         g r(   ©rJ   )r    rJ   s     r!   rE   Ú _DefaultMessageDelegate.__init__  s   € Ø$�r$   c                 óÂ   • U R                   R                  [        R                  " SSS5      [        R                  " 5       5        U R                   R                  5         g )NzHTTP/1.1é”  z	Not Found)rJ   Úwrite_headersr   r`   ra   rY   rZ   s    r!   rY   Ú_DefaultMessageDelegate.finish  sD   € Ø�‰×%Ñ%Ü×&Ò& z°3¸ÓDÜ× Ò Ó"ô	
ð 	�‰×ÑÕ r$   re   r_   )	r-   r.   r/   r0   r   r5   rE   rY   r6   r,   r$   r!   rQ   rQ     s    † ð% 8×#:Ñ#:ð %¸tô %÷!r$   rQ   ÚRuleÚMatcherc            	       óÜ   • \ rS rSrSrSS\\   SS4S jjrS\SS4S jrSS jr	S	\
R                  S
\S\\
R                     4S jrS\S	\
R                  S\S\\
R                     4S jrSrg)Ú
RuleRouteri,  z!Rule-based router implementation.NÚrulesr   c                 óD   • / U l         U(       a  U R                  U5        gg)a¹  Constructs a router from an ordered list of rules::

    RuleRouter([
        Rule(PathMatches("/handler"), Target),
        # ... more rules
    ])

You can also omit explicit `Rule` constructor and use tuples of arguments::

    RuleRouter([
        (PathMatches("/handler"), Target),
    ])

`PathMatches` is a default matcher, so the example above can be simplified::

    RuleRouter([
        ("/handler", Target),
    ])

In the examples above, ``Target`` can be a nested `Router` instance, an instance of
`~.httputil.HTTPServerConnectionDelegate` or an old-style callable,
accepting a request argument.

:arg rules: a list of `Rule` instances or tuples of `Rule`
    constructor arguments.
N)ro   Ú	add_rules)r    ro   s     r!   rE   ÚRuleRouter.__init__/  s   € ð6 ˆŒ
ÞØ�N‰N˜5Õ!ð r$   c                 ó:  • U H•  n[        U[        [        45      (       aM  [        U5      S;   d   e[        US   [        5      (       a  [        [        US   5      /USS Q76 nO[        U6 nU R                  R                  U R                  U5      5        M—     g)z‹Appends new rules to the router.

:arg rules: a list of Rule instances (or tuples of arguments, which are
    passed to Rule constructor).
)é   é   é   r   é   N)
rL   ÚtupleÚlistÚlenr
   rk   ÚPathMatchesro   ÚappendÚprocess_rule)r    ro   Úrules      r!   rq   ÚRuleRouter.add_rulesN  s†   € ó ˆDÜ˜$¤¬ ×.Ñ.Ü˜4“y IÓ-Ð-Ð-Ü˜d 1™g¤×7Ñ7Ü¤¨D°©GÓ 4Ð@°t¸A¸B°xÒ@‘Dä ˜;�Dà�J‰J×Ñ˜d×/Ñ/°Ó5Ö6ò r$   c                 ó   • U$ )z—Override this method for additional preprocessing of each rule.

:arg Rule rule: a rule to be processed.
:returns: the same or modified Rule instance.
r,   )r    r~   s     r!   r}   ÚRuleRouter.process_rule^  s	   € ð ˆr$   r   r   c                 óô   • U R                    Hh  nUR                  R                  U5      nUc  M#  UR                  (       a  UR                  US'   U R                  " UR
                  U40 UD6nUc  Mf  Us  $    g )NÚtarget_kwargs)ro   ÚmatcherÚmatchrƒ   Úget_target_delegateÚtarget)r    r   r   r~   Útarget_paramsrD   s         r!   r"   ÚRuleRouter.find_handlerf  sx   € ð —J”JˆDØ ŸL™L×.Ñ.¨wÓ7ˆMØÓ(Ø×%×%Ø59×5GÑ5G�M /Ñ2à×3Ò3Ø—K‘K ñØ,9ñ�ð Ó'Ø#’Oñ ð r$   r‡   rˆ   c                 óz  • [        U[        5      (       a  UR                  " U40 UD6$ [        U[        R                  5      (       a5  UR
                  c   eUR                  UR                  UR
                  5      $ [        U5      (       a/  UR
                  c   e[        [        U40 UD6UR
                  5      $ g)ax  Returns an instance of `~.httputil.HTTPMessageDelegate` for a
Rule's target. This method is called by `~.find_handler` and can be
extended to provide additional target types.

:arg target: a Rule's target.
:arg httputil.HTTPServerRequest request: current request.
:arg target_params: additional parameters that can be useful
    for `~.httputil.HTTPMessageDelegate` creation.
N)rL   r   r"   r   ÚHTTPServerConnectionDelegaterJ   r*   rK   Úcallabler   r   )r    r‡   r   rˆ   s       r!   r†   ÚRuleRouter.get_target_delegatex  s¯   € ô �fœf×%Ñ%Ø×&Ò& wÑ@°-Ñ@Ð@ä˜¤× EÑ E×FÑFØ×%Ñ%Ñ1Ð1Ð1Ø×'Ñ'¨×(AÑ(AÀ7×CUÑCUÓVÐVä�f×ÑØ×%Ñ%Ñ1Ð1Ð1Ü#Ü˜Ñ0 -Ñ0°'×2DÑ2Dóð ð r$   )ro   r(   ©r~   rk   r   rk   )r-   r.   r/   r0   r1   r   Ú	_RuleListrE   rq   r}   r   r2   r   r3   r"   r†   r6   r,   r$   r!   rn   rn   ,  s™   † Ù+ñ"˜h yÑ1ð "¸Tõ "ð>7˜yð 7¨Tô 7ô ðØ×1Ñ1ðØ=@ðà	�(×.Ñ.Ñ	/ôð$ØðØ$,×$>Ñ$>ðØQTðà	�(×.Ñ.Ñ	/÷r$   rn   c                   ón   ^ • \ rS rSrSrSS\\   SS4U 4S jjjrSU 4S jjrS\	S	\
S\\	   4S
 jrSrU =r$ )ÚReversibleRuleRouterrh   zþA rule-based router that implements ``reverse_url`` method.

Each rule added to this router may have a ``name`` attribute that can be
used to reconstruct an original uri. The actual reconstruction takes place
in a rule's matcher (see `Matcher.reverse`).
Nro   r   c                 ó2   >• 0 U l         [        TU ]	  U5        g r(   )Únamed_rulesÚsuperrE   )r    ro   Ú	__class__s     €r!   rE   ÚReversibleRuleRouter.__init__œ  s   ø€ ØˆÔÜ‰Ñ˜Õr$   c                 óî   >• [         TU ]  U5      nUR                  (       aS  UR                  U R                  ;   a!  [        R
                  " SUR                  5        XR                  UR                  '   U$ )Nz4Multiple handlers named %s; replacing previous value)r”   r}   r:   r“   r	   Úwarning)r    r~   r•   s     €r!   r}   Ú!ReversibleRuleRouter.process_rule   sY   ø€ Ü‰wÑ# DÓ)ˆà�9�9Ø�y‰y˜D×,Ñ,Ó,Ü—’ØJÈDÏIÉIôð +/×Ñ˜TŸY™YÑ'àˆr$   r:   r;   c                 ó  • XR                   ;   a&  U R                   U   R                  R                  " U6 $ U R                   HH  n[	        UR
                  [        5      (       d  M$  UR
                  R                  " U/UQ76 nUc  MF  Us  $    g r(   )r“   r„   Úreversero   rL   r‡   r8   r=   )r    r:   r;   r~   Úreversed_urls        r!   r=   Ú ReversibleRuleRouter.reverse_url¬  sz   € Ø×#Ñ#Ó#Ø×#Ñ# DÑ)×1Ñ1×9Ò9¸4Ð@Ð@à—J”JˆDÜ˜$Ÿ+™+Ô'7×8Ó8Ø#Ÿ{™{×6Ò6°tÐC¸dÒC�ØÓ+Ø'Ò'ñ	 ð r$   )r“   r(   rŽ   )r-   r.   r/   r0   r1   r   r�   rE   r}   r?   r   r=   r6   Ú__classcell__©r•   s   @r!   r‘   r‘   ”  sM   ø† ññ ˜h yÑ1ð  ¸T÷  ð  ÷
ð
 ð 
¨Cð 
°H¸S±M÷ 
ò 
r$   r‘   c                   óz   • \ rS rSrSr  SSSS\S\\\\4      S\\   S	S4
S
 jjr	S\S	\\   4S jr
S	\4S jrSrg)rk   i¹  zA routing rule.Nr„   rl   r‡   rƒ   r:   r   c                 óˆ   • [        U[        5      (       a  [        U5      nXl        X l        U(       a  UO0 U l        X@l        g)aô  Constructs a Rule instance.

:arg Matcher matcher: a `Matcher` instance used for determining
    whether the rule should be considered a match for a specific
    request.
:arg target: a Rule's target (typically a ``RequestHandler`` or
    `~.httputil.HTTPServerConnectionDelegate` subclass or even a nested `Router`,
    depending on routing implementation).
:arg dict target_kwargs: a dict of parameters that can be useful
    at the moment of target instantiation (for example, ``status_code``
    for a ``RequestHandler`` subclass). They end up in
    ``target_params['target_kwargs']`` of `RuleRouter.get_target_delegate`
    method.
:arg str name: the name of the rule that can be used to find it
    in `ReversibleRouter.reverse_url` implementation.
N)rL   r?   r   r„   r‡   rƒ   r:   )r    r„   r‡   rƒ   r:   s        r!   rE   ÚRule.__init__¼  s8   € ô. �fœc×"Ñ"ô # 6Ó*ˆFàŒØŒÞ.;™]ÀˆÔØ�	r$   r;   c                 ó4   • U R                   R                  " U6 $ r(   )r„   r›   ©r    r;   s     r!   r›   ÚRule.reverseÝ  s   € Ø�|‰|×#Ò# TÐ*Ð*r$   c           
      ó¦   • U R                   R                  < SU R                  < SU R                  < SU R                  < SU R
                  < S3
$ ©NÚ(z, z	, kwargs=z, name=Ú))r•   r-   r„   r‡   rƒ   r:   rZ   s    r!   Ú__repr__ÚRule.__repr__à  s7   € à�N‰N×#Ô#Ø�LŒLØ�KŒKØ×ÔØ�IŒIð
ð 	
r$   )r„   r:   r‡   rƒ   ©NN)r-   r.   r/   r0   r1   r   r   r   r?   rE   r›   rª   r6   r,   r$   r!   rk   rk   ¹  sw   † Ùð 37Ø"ñàðð ðð    S¨# X¡Ñ/ð	ð
 �s‰mðð 
õðB+˜Sð + X¨c¡]ô +ð
˜#÷ 
r$   c                   óf   • \ rS rSrSrS\R                  S\\\	\
4      4S jrS\
S\\	   4S jrSrg	)
rl   iê  z*Represents a matcher for request features.r   r   c                 ó   • [        5       e)aù  Matches current instance against the request.

:arg httputil.HTTPServerRequest request: current HTTP request
:returns: a dict of parameters to be passed to the target handler
    (for example, ``handler_kwargs``, ``path_args``, ``path_kwargs``
    can be passed for proper `~.web.RequestHandler` instantiation).
    An empty dict is a valid (and common) return value to indicate a match
    when the argument-passing features are not used.
    ``None`` must be returned to indicate that there is no match.r   ©r    r   s     r!   r…   ÚMatcher.matchí  s   € ô "Ó#Ð#r$   r;   c                 ó   • g)zEReconstructs full url from matcher instance and additional arguments.Nr,   r¤   s     r!   r›   ÚMatcher.reverseù  s   € àr$   r,   N)r-   r.   r/   r0   r1   r   r2   r   r   r?   r   r…   r›   r6   r,   r$   r!   rl   rl   ê  sB   † Ù4ð
$˜X×7Ñ7ð 
$¸HÀTÈ#ÈsÈ(Á^Ñ<Tô 
$ð˜Sð  X¨c¡]÷ r$   c                   óN   • \ rS rSrSrS\R                  S\\\	\
4      4S jrSrg)Ú
AnyMatchesiþ  zMatches any request.r   r   c                 ó   • 0 $ r(   r,   r¯   s     r!   r…   ÚAnyMatches.match  s   € Øˆ	r$   r,   N)r-   r.   r/   r0   r1   r   r2   r   r   r?   r   r…   r6   r,   r$   r!   r´   r´   þ  s+   † Ùð˜X×7Ñ7ð ¸HÀTÈ#ÈsÈ(Á^Ñ<T÷ r$   r´   c                   ój   • \ rS rSrSrS\\\4   SS4S jrS\	R                  S\\\\4      4S jrS	rg)
ÚHostMatchesi  z@Matches requests from hosts specified by ``host_pattern`` regex.Úhost_patternr   Nc                 ó¨   • [        U[        5      (       a7  UR                  S5      (       d  US-  n[        R                  " U5      U l        g Xl        g )NÚ$)rL   r
   ÚendswithÚreÚcompiler¹   )r    r¹   s     r!   rE   ÚHostMatches.__init__  sA   € Ü�l¤O×4Ñ4Ø×(Ñ(¨×-Ñ-Ø Ñ#�Ü "§
¢
¨<Ó 8ˆDÕà ,Õr$   r   c                 ó\   • U R                   R                  UR                  5      (       a  0 $ g r(   )r¹   r…   Ú	host_namer¯   s     r!   r…   ÚHostMatches.match  s'   € Ø×Ñ×"Ñ" 7×#4Ñ#4×5Ñ5ØˆIàr$   )r¹   )r-   r.   r/   r0   r1   r   r?   r   rE   r   r2   r   r   r   r…   r6   r,   r$   r!   r¸   r¸     sG   † ÙJð- U¨3°¨<Ñ%8ð -¸Tô -ð˜X×7Ñ7ð ¸HÀTÈ#ÈsÈ(Á^Ñ<T÷ r$   r¸   c                   ód   • \ rS rSrSrS\S\SS4S jrS\R                  S\
\\\4      4S	 jrS
rg)ÚDefaultHostMatchesi  z„Matches requests from host that is equal to application's default_host.
Always returns no match if ``X-Real-Ip`` header is present.
Úapplicationr¹   r   Nc                 ó   • Xl         X l        g r(   ©rÅ   r¹   )r    rÅ   r¹   s      r!   rE   ÚDefaultHostMatches.__init__  s   € Ø&ÔØ(Õr$   r   c                 ó�   • SUR                   ;  a6  U R                  R                  U R                  R                  5      (       a  0 $ g )Nz	X-Real-Ip)rH   r¹   r…   rÅ   Údefault_hostr¯   s     r!   r…   ÚDefaultHostMatches.match   s9   € à˜gŸo™oÓ-Ø× Ñ ×&Ñ& t×'7Ñ'7×'DÑ'D×EÑEØ�	Ør$   rÇ   )r-   r.   r/   r0   r1   r   r   rE   r   r2   r   r   r?   r…   r6   r,   r$   r!   rÄ   rÄ     sG   † ñð) Cð )°wð )À4ô )ð˜X×7Ñ7ð ¸HÀTÈ#ÈsÈ(Á^Ñ<T÷ r$   rÄ   c                   ó¦   • \ rS rSrSrS\\\4   SS4S jrS\	R                  S\\\\4      4S jrS	\S\\   4S
 jrS\\\   \\   4   4S jrSrg)r{   i(  z@Matches requests with paths specified by ``path_pattern`` regex.Úpath_patternr   Nc                 ó�  • [        U[        5      (       a7  UR                  S5      (       d  US-  n[        R                  " U5      U l        OXl        [        U R
                  R                  5      SU R
                  R                  4;   d   SU R
                  R                  -  5       eU R                  5       u  U l        U l        g )Nr»   r   zDgroups in url regexes must either be all named or all positional: %r)rL   r
   r¼   r½   r¾   Úregexrz   Ú
groupindexÚgroupsÚpatternÚ_find_groupsÚ_pathÚ_group_count)r    rÍ   s     r!   rE   ÚPathMatches.__init__+  s£   € Ü�l¤O×4Ñ4Ø×(Ñ(¨×-Ñ-Ø Ñ#�ÜŸš LÓ1ˆD�Jà%ŒJä�4—:‘:×(Ñ(Ó)¨a°·±×1BÑ1BÐ-CÓCð 	
ðØ#Ÿz™z×1Ñ1ñ2ó	
ÐCð
 )-×(9Ñ(9Ó(;Ñ%ˆŒ
�DÕ%r$   r   c                 ó˜  • U R                   R                  UR                  5      nUc  g U R                   R                  (       d  0 $ / n0 nU R                   R                  (       a/  [        S UR                  5       R                  5        5       5      nO)UR                  5        Vs/ s H  n[        U5      PM     nn[        X4S9$ s  snf )Nc              3   óR   #   • U  H  u  p[        U5      [        U5      4v •  M     g 7fr(   )r?   Ú_unquote_or_none)Ú.0ÚkÚvs      r!   Ú	<genexpr>Ú$PathMatches.match.<locals>.<genexpr>I  s%   é € ð Ú<U±&°1”�Q“Ô)¨!Ó,Õ-Ò<Uùs   ‚%')Ú	path_argsÚpath_kwargs)	rÏ   r…   rP   rÑ   rÐ   ÚdictÚ	groupdictÚitemsrÙ   )r    r   r…   rß   rà   Úss         r!   r…   ÚPathMatches.match:  s§   € Ø—
‘
× Ñ  §¡Ó.ˆØ‰=ØØ�z‰z× × ØˆIàˆ	Øˆð �:‰:× × Üñ Ø<A¿O¹OÓ<M×<SÑ<SÔ<Uóó ‰Kð 7<·l±l´nÓE²n°Ô)¨!Ö,±nˆIÐEä˜iÑAÐAùò Fs   Â'Cr;   c                 ó®  • U R                   c"  [        SU R                  R                  -   5      e[	        U5      U R
                  :X  d   S5       e[	        U5      (       d  U R                   $ / nU HK  n[        U[        [        45      (       d  [        U5      nUR                  [        [        U5      SS95        MM     U R                   [        U5      -  $ )NzCannot reverse url regex z&required number of arguments not foundF)Úplus)rÔ   Ú
ValueErrorrÏ   rÒ   rz   rÕ   rL   r   rb   r?   r|   r   r   rx   )r    r;   Úconverted_argsÚas       r!   r›   ÚPathMatches.reverseQ  s·   € Ø�:‰:ÑÜÐ8¸4¿:¹:×;MÑ;MÑMÓNÐNÜ�4‹y˜D×-Ñ-Ó-ð 	
Ø7ó	
Ð-ô �4�y‰yØ—:‘:ÐØˆÛˆAÜ˜a¤,´Ð!6×7Ñ7Ü˜“F�Ø×!Ñ!¤*¬T°!«W¸5Ñ"AÖBñ ð �z‰zœE .Ó1Ñ1Ð1r$   c                 óz  • U R                   R                  nUR                  S5      (       a  USS nUR                  S5      (       a  USS nU R                   R                  UR                  S5      :w  a  g/ nUR                  S5       Hf  nSU;   a@  UR                  S5      nUS	:¼  a'   [        X4S-   S 5      nUR                  S
U-   5        MG  MI   [        U5      nUR                  U5        Mh     SR                  U5      U R                   R                  4$ ! [         a       gf = f! [         a       gf = f)zžReturns a tuple (reverse string, group count) for a url.

For example: Given the url pattern /([0-9]{4})/([a-z-]+)/, this method
would return ('/%s/%s/', 2).
Ú^rw   Nr»   éÿÿÿÿr¨   r¬   r©   r   z%sÚ )rÏ   rÒ   Ú
startswithr¼   rÑ   ÚcountÚsplitÚindexr   rè   r|   Újoin)r    rÒ   ÚpiecesÚfragmentÚ	paren_locÚunescaped_fragments         r!   rÓ   ÚPathMatches._find_groups`  s:  € ð —*‘*×$Ñ$ˆØ×Ñ˜c×"Ñ"Ø˜a˜b�kˆGØ×Ñ˜C× Ñ Ø˜c˜r�lˆGà�:‰:×Ñ §¡¨cÓ 2Ó2ð àˆØŸ™ cÖ*ˆHØ�h‹Ø$ŸN™N¨3Ó/�	Ø “>ð,Ü-8¸ÈaÁ-À/Ð9RÓ-SÐ*ð
 —M‘M $Ð);Ñ";Ö<ñ "ð(Ü)4°XÓ)>Ð&ð
 —‘Ð0Ö1ñ% +ð( �w‰w�v‹ §
¡
× 1Ñ 1Ð1Ð1øô &ó ,ò  ,ð,ûô "ó (ò (ð(ús$   Â+DÃD,Ä
D)Ä(D)Ä,
D:Ä9D:)rÕ   rÔ   rÏ   )r-   r.   r/   r0   r1   r   r?   r   rE   r   r2   r   r   r   r…   r›   r   ÚintrÓ   r6   r,   r$   r!   r{   r{   (  s   † ÙJð< U¨3°¨<Ñ%8ð <¸Tô <ðB˜X×7Ñ7ð B¸HÀTÈ#ÈsÈ(Á^Ñ<Tô Bð.2˜Sð 2 X¨c¡]ô 2ð&2˜e H¨S¡M°8¸C±=Ð$@ÑA÷ &2r$   r{   c                   óz   ^ • \ rS rSrSr  SS\\\4   S\S\	\
\\4      S\	\   SS4
U 4S	 jjjrS\4S
 jrSrU =r$ )ÚURLSpeci‰  z½Specifies mappings between URLs and handlers.

.. versionchanged: 4.5
   `URLSpec` is now a subclass of a `Rule` with `PathMatches` matcher and is preserved for
   backwards compatibility.
NrÒ   Úhandlerr   r:   r   c                 óŒ   >• [        U5      n[        TU ]	  XRX45        UR                  U l        U R                  U l        X0l        g)a+  Parameters:

* ``pattern``: Regular expression to be matched. Any capturing
  groups in the regex will be passed in to the handler's
  get/post/etc methods as arguments (by keyword if named, by
  position if unnamed. Named and unnamed capturing groups
  may not be mixed in the same rule).

* ``handler``: `~.web.RequestHandler` subclass to be invoked.

* ``kwargs`` (optional): A dictionary of additional arguments
  to be passed to the handler's constructor.

* ``name`` (optional): A name for this handler.  Used by
  `~.web.Application.reverse_url`.

N)r{   r”   rE   rÏ   r‡   Úhandler_classr   )r    rÒ   rý   r   r:   r„   r•   s         €r!   rE   ÚURLSpec.__init__‘  s:   ø€ ô0 ˜gÓ&ˆÜ‰Ñ˜¨6Ô8à—]‘]ˆŒ
Ø!Ÿ[™[ˆÔØ�r$   c           
      óº   • U R                   R                  < SU R                  R                  < SU R                  < SU R
                  < SU R                  < S3
$ r§   )r•   r-   rÏ   rÒ   rÿ   r   r:   rZ   s    r!   rª   ÚURLSpec.__repr__°  s=   € à�N‰N×#Ô#Ø�J‰J×ÔØ×ÔØ�KŒKØ�IŒIð
ð 	
r$   )rÿ   r   rÏ   r¬   )r-   r.   r/   r0   r1   r   r?   r   r   r   r   rE   rª   r6   rž   rŸ   s   @r!   rü   rü   ‰  su   ø† ñð ,0Ø"ñà�s˜G�|Ñ$ðð ðð ˜˜c 3˜h™Ñ(ð	ð
 �s‰mðð 
÷ð ð>
˜#÷ 
ò 
r$   rü   rä   r   c                 ó   • g r(   r,   ©rä   s    r!   rÙ   rÙ   º  ó   € àr$   c                 ó   • g r(   r,   r  s    r!   rÙ   rÙ   ¿  r  r$   c                 ó"   • U c  U $ [        U SSS9$ )z©None-safe wrapper around url_unescape to handle unmatched optional
groups correctly.

Note that args are passed as bytes so the handler can decide what
encoding to use.
NF)Úencodingrç   )r   r  s    r!   rÙ   rÙ   Ä  s   € ð 	�yØˆÜ˜ D¨uÑ5Ð5r$   )rä   Nr   N)1r1   r½   Ú	functoolsr   Útornador   Útornado.httpserverr   Útornado.escaper   r   r   Útornado.logr	   Útornado.utilr
   r   r   r   Útypingr   r   r   r   r   r   r   r   r   r‹   r   r8   r3   r)   rQ   r?   r�   rn   r‘   r4   rk   rl   r´   r¸   rÄ   r{   rü   rb   rÙ   r,   r$   r!   Ú<module>r     s¼  ðñaóF 
Ý å Ý /ß 9Ñ 9Ý ß RÓ Rç X× XÕ XôAˆX×2Ñ2ô Aô.$�vô $ô +,�x×3Ñ3ô +,ô\	!˜h×:Ñ:ô 	!ð Ø	ØØˆS‰	Øˆe�C˜�NÑ# SÐ(Ñ)Øˆe�C˜�NÑ# S¨$¨s°C¨x©.Ð8Ñ9Øˆe�C˜�NÑ# S¨$¨s°C¨x©.¸#Ð=Ñ>ð		@ññ€	ôe�ô eôP"Ð+¨Zô "ôJ.
ˆ6ô .
ôbˆfô ô(�ô ô�'ô ô$˜ô ô"^2�'ô ^2ôB.
ˆdô .
ðb 
ð	˜ð 	 ó 	ó 
ð	ð 
ó	ó 
ð	ð	6˜ ™ð 	6¨(°5©/õ 	6r$   