+
    ‚V@i4b  ã                   óü  € R t ^ RIt^ RIHt ^ RIHt ^ RIHt ^ RIH	t	H
t
Ht ^ RIHt ^ RIHtHtHtHt ^ RIHtHtHtHtHtHtHtHtHtHt  ! R	 R
]P<                  4      t ! R R]4      t  ! R R]PB                  4      t" ! R R]PB                  4      t#]]R]],          ]]]$R3,          ]3,          ]]]$R3,          ]]]$]3,          3,          ]]]$R3,          ]]]$]3,          ]$3,          3,          ,          t% ! R R]4      t& ! R R] ]&4      t' ! R R4      t( ! R R4      t) ! R R])4      t* ! R R])4      t+ ! R R])4      t, ! R R ])4      t- ! R! R"](4      t.]R# R$ l4       t/]R% R& l4       t/R' R( lt/R# ))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ÚoverloadÚSequencec                   óH   a € ] tR t^Ét o RtV 3R lR ltV 3R lR ltRtV tR# )ÚRouterzAbstract router interface.c                ód   <€ V ^8„  d   QhRS[ P                  RS[RS[S[ P                  ,          /# ©é   ÚrequestÚkwargsÚreturn©r   ÚHTTPServerRequestr   r   ÚHTTPMessageDelegate)ÚformatÚ__classdict__s   "€Ú1/usr/lib/python3/dist-packages/tornado/routing.pyÚ__annotate__ÚRouter.__annotate__Ì   s6   ø€ ÷ $ñ $Ù×1Ñ1ð$Ù=@ð$á	‘(×.Ñ.Õ	/ñ$ó    c                ó   € \        4       h)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   &&,r$   Úfind_handlerÚRouter.find_handlerÌ   s   € ô "Ó#Ð#r'   c                óT   <€ V ^8„  d   QhRS[ RS[P                  RS[P                  /# )r   Úserver_connÚrequest_connr   )Úobjectr   ÚHTTPConnectionr!   )r"   r#   s   "€r$   r%   r&   Ú   s6   ø€ ÷ Añ AÙ!ðAÙ19×1HÑ1HðAá	×	%Ñ	%ñAr'   c                ó   € \        WV4      # ©N)Ú_RoutingDelegate)r+   r/   r0   s   &&&r$   Ústart_requestÚRouter.start_requestÚ   s   € ô   °<Ó@Ð@r'   © N)	Ú__name__Ú
__module__Ú__qualname__Ú__firstlineno__Ú__doc__r,   r6   Ú__static_attributes__Ú__classdictcell__©r#   s   @r$   r   r   É   s   ø‡ € Ù$÷$ð $÷Aö Ar'   r   c                   ó6   a € ] tR t^àt o RtV 3R lR ltRtV tR# )ÚReversibleRouterzpAbstract router interface for routers that can handle named routes
and support reversing them to original urls.
c                ó<   <€ V ^8„  d   QhRS[ RS[RS[S[ ,          /# ©r   ÚnameÚargsr   ©Ústrr   r   )r"   r#   s   "€r$   r%   ÚReversibleRouter.__annotate__å   s&   ø€ ÷ $ñ $¡ð $©Cð $±H¹SµMñ $r'   c                ó   € \        4       h)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+   rE   rF   s   &&*r$   Úreverse_urlÚReversibleRouter.reverse_urlå   s   € ô "Ó#Ð#r'   r8   N)r9   r:   r;   r<   r=   rK   r>   r?   r@   s   @r$   rB   rB   à   s   ø‡ € ñ÷$ö $r'   rB   c                   óz   a € ] tR t^ðt o V 3R lR ltV 3R lR ltV 3R lR ltV 3R lR ltV 3R	 lR
 ltRt	V t
R# )r5   c                óD   <€ V ^8„  d   QhRS[ RS[RS[P                  RR/# )r   Úrouterr/   r0   r   N)r   r1   r   r2   )r"   r#   s   "€r$   r%   Ú_RoutingDelegate.__annotate__ñ   s3   ø€ ÷ ñ ÙðÙ+1ðÙAI×AXÑAXðà	ñr'   c                ó8   € W n         W0n        R V n        Wn        R # r4   )r/   r0   ÚdelegaterO   )r+   rO   r/   r0   s   &&&&r$   Ú__init__Ú_RoutingDelegate.__init__ñ   s   € ð 'ÔØ(ÔØˆŒØŽr'   c                óœ   <€ V ^8„  d   QhRS[ S[P                  S[P                  3,          RS[P                  RS[S[R,          ,          /# )r   Ú
start_lineÚheadersr   N)r   r   ÚRequestStartLineÚResponseStartLineÚHTTPHeadersr   r   )r"   r#   s   "€r$   r%   rP   ù   sS   ø€ ÷ Cñ Cá™(×3Ñ3±X×5OÑ5OÐOÕPðCñ ×%Ñ%ðCñ 
‘)˜D•/Õ	"ñ	Cr'   c                óÀ  € \        V\        P                  4      '       g   Q h\        P                  ! V P                  V P
                  VVR 7      pV P                  P                  V4      V n        V P                  fG   \        P                  ! RVP                  VP                  4       \        V P                  4      V n        V P                  P                  W4      # ))Ú
connectionÚserver_connectionrV   rW   z$Delegate for %s %s request not found)Ú
isinstancer   rX   r    r0   r/   rO   r,   rR   r   ÚdebugÚmethodÚpathÚ_DefaultMessageDelegateÚheaders_received)r+   rV   rW   r   s   &&& r$   rc   Ú!_RoutingDelegate.headers_receivedù   s¯   € ô
 ˜*¤h×&?Ñ&?×@Ò@Ð@Ð@Ü×,Ò,Ø×(Ñ(Ø"×.Ñ.Ø!Øô	
ˆð Ÿ™×0Ñ0°Ó9ˆŒØ�=‰=Ò Ü�MŠMØ6Ø×!Ñ!Ø—‘ôô
 4°D×4EÑ4EÓFˆDŒMà�}‰}×-Ñ-¨jÓBÐBr'   c                óD   <€ V ^8„  d   QhRS[ RS[S[R,          ,          /# )r   Úchunkr   N)Úbytesr   r   )r"   r#   s   "€r$   r%   rP     s$   ø€ ÷ 2ñ 2¡5ð 2©X±iÀµoÕ-Fñ 2r'   c                óX   € V P                   f   Q hV P                   P                  V4      # r4   )rR   Údata_received)r+   rf   s   &&r$   ri   Ú_RoutingDelegate.data_received  s'   € Ø�}‰}Ò(Ð(Ð(Ø�}‰}×*Ñ*¨5Ó1Ð1r'   c                ó   <€ V ^8„  d   QhRR/# ©r   r   Nr8   )r"   r#   s   "€r$   r%   rP     s   ø€ ÷ ñ ˜ñ r'   c                óZ   € V P                   f   Q hV P                   P                  4        R # r4   )rR   Úfinish©r+   s   &r$   rn   Ú_RoutingDelegate.finish  s"   € Ø�}‰}Ò(Ð(Ð(Ø�‰×ÑÖr'   c                ó   <€ V ^8„  d   QhRR/# rl   r8   )r"   r#   s   "€r$   r%   rP     s   ø€ ÷ 0ñ 0 Tñ 0r'   c                óZ   € V P                   e   V P                   P                  4        R # R # r4   )rR   Úon_connection_closero   s   &r$   rs   Ú$_RoutingDelegate.on_connection_close  s!   € Ø�=‰=Ò$Ø�M‰M×-Ñ-Ö/ñ %r'   )rR   r0   rO   r/   N)r9   r:   r;   r<   rS   rc   ri   rn   rs   r>   r?   r@   s   @r$   r5   r5   ð   s9   ø‡ € ÷ð ÷Cð C÷02ð 2÷ð ÷0ö 0r'   r5   c                   óD   a € ] tR tRt o V 3R lR ltV 3R lR ltRtV tR# )rb   i  c                ó8   <€ V ^8„  d   QhRS[ P                  RR/# )r   r\   r   N)r   r2   )r"   r#   s   "€r$   r%   Ú$_DefaultMessageDelegate.__annotate__  s!   ø€ ÷ %ñ %¡8×#:Ñ#:ð %¸tñ %r'   c                ó   € Wn         R # r4   ©r\   )r+   r\   s   &&r$   rS   Ú _DefaultMessageDelegate.__init__  s   € Ø$Žr'   c                ó   <€ V ^8„  d   QhRR/# rl   r8   )r"   r#   s   "€r$   r%   rw   "  s   ø€ ÷ !ñ !˜ñ !r'   c                óÄ   € V P                   P                  \        P                  ! R RR4      \        P                  ! 4       4       V P                   P                  4        R# )zHTTP/1.1i”  z	Not FoundN)r\   Úwrite_headersr   rY   rZ   rn   ro   s   &r$   rn   Ú_DefaultMessageDelegate.finish"  sD   € Ø�‰×%Ñ%Ü×&Ò& z°3¸ÓDÜ× Ò Ó"ô	
ð 	�‰×ÑÖ r'   ry   N)r9   r:   r;   r<   rS   rn   r>   r?   r@   s   @r$   rb   rb     s   ø‡ € ÷%ð %÷!ö !r'   rb   ÚRuleÚMatcherc                   ó‚   a € ] tR tRt o RtRV 3R lR lltV 3R lR ltV 3R lR	 ltV 3R
 lR ltV 3R lR lt	Rt
V tR# )Ú
RuleRouteri7  z!Rule-based router implementation.Nc                ó4   <€ V ^8„  d   QhRS[ S[,          RR/# ©r   Úrulesr   N©r   Ú	_RuleList)r"   r#   s   "€r$   r%   ÚRuleRouter.__annotate__:  s    ø€ ÷ "ñ "™h¡yÕ1ð "¸Tñ "r'   c                óJ   € . V n         V'       d   V P                  V4       R# R# )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)r…   Ú	add_rules)r+   r…   s   &&r$   rS   ÚRuleRouter.__init__:  s   € ð6 ˆŒ
ßØ�N‰N˜5Ö!ñ r'   c                ó$   <€ V ^8„  d   QhRS[ RR/# r„   )r‡   )r"   r#   s   "€r$   r%   rˆ   Y  s   ø€ ÷ 7ñ 7™yð 7¨Tñ 7r'   c                ó^  € V F¦  p\        V\        \        34      '       d^   \        V4      R9   g   Q h\        V^ ,          \        4      '       d&   \        \        V^ ,          4      .VR,          O5!  pM	\        V!  pV P                  P                  V P                  V4      4       K¨  	  R# )z‹Appends new rules to the router.

:arg rules: a list of Rule instances (or tuples of arguments, which are
    passed to Rule constructor).
ºé   NNN)r   é   é   )
r^   ÚtupleÚlistÚlenr	   r   ÚPathMatchesr…   ÚappendÚprocess_rule)r+   r…   Úrules   && r$   rŠ   ÚRuleRouter.add_rulesY  s„   € ó ˆDÜ˜$¤¬ ×.Ò.Ü˜4“y IÔ-Ð-Ð-Ü˜d 1�g¤×7Ò7Ü¤¨D°­GÓ 4Ð@°t¸BµxÓ@‘Dä ™;�Dà�J‰J×Ñ˜d×/Ñ/°Ó5Ö6ó r'   c                ó"   <€ V ^8„  d   QhRRRR/# ©r   r˜   r   r   r8   )r"   r#   s   "€r$   r%   rˆ   i  s   ø€ ÷ ñ  ð ¨Fñ r'   c                ó   € V# )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.
r8   )r+   r˜   s   &&r$   r—   ÚRuleRouter.process_rulei  s	   € ð ˆr'   c                ód   <€ V ^8„  d   QhRS[ P                  RS[RS[S[ P                  ,          /# r   r   )r"   r#   s   "€r$   r%   rˆ   q  s6   ø€ ÷ ñ Ù×1Ñ1ðÙ=@ðá	‘(×.Ñ.Õ	/ñr'   c                óü   € V P                    Fk  pVP                  P                  V4      pVf   K$  VP                  '       d   VP                  VR&   V P                  ! VP
                  V3/ VB pVf   Ki  Vu # 	  R # )NÚtarget_kwargs)r…   ÚmatcherÚmatchr    Úget_target_delegateÚtarget)r+   r   r   r˜   Útarget_paramsrR   s   &&,   r$   r,   ÚRuleRouter.find_handlerq  s{   € ð —J”JˆDØ ŸL™L×.Ñ.¨wÓ7ˆMØÔ(Ø×%×%Ð%Ø59×5GÑ5G�M /Ñ2à×3Ò3Ø—K‘K ñØ,9ñ�ð Ô'Ø#’Oñ ñ r'   c          	      ój   <€ V ^8„  d   QhRS[ RS[P                  RS[ RS[S[P                  ,          /# )r   r¤   r   r¥   r   )r   r   r    r   r!   )r"   r#   s   "€r$   r%   rˆ   ƒ  s>   ø€ ÷ ñ ÙðÙ$,×$>Ñ$>ðÙQTðá	‘(×.Ñ.Õ	/ñr'   c                ó†  € \        V\        4      '       d   VP                  ! V3/ VB # \        V\        P                  4      '       d7   VP
                  f   Q hVP                  VP                  VP
                  4      # \        V4      '       d1   VP
                  f   Q h\        \        V3/ VB VP
                  4      # R# )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)r^   r   r,   r   ÚHTTPServerConnectionDelegater\   r6   r]   Úcallabler   r   )r+   r¤   r   r¥   s   &&&,r$   r£   ÚRuleRouter.get_target_delegateƒ  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'   )r…   r4   )r9   r:   r;   r<   r=   rS   rŠ   r—   r,   r£   r>   r?   r@   s   @r$   r‚   r‚   7  s:   ø‡ € Ù+÷"ò "÷>7ð 7÷ ð ÷ð ÷$ö r'   r‚   c                   óp   a a€ ] tR tRt oRtR
V3R lV 3R llltV3R lV 3R lltV3R lR ltR	tVt	V ;t
# )ÚReversibleRuleRouteriŸ  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`).
c                ó4   <€ V ^8„  d   QhRS[ S[,          RR/# r„   r†   )r"   r#   s   "€r$   r%   Ú!ReversibleRuleRouter.__annotate__§  s    ø€ ÷  ñ  ™h¡yÕ1ð  ¸Tñ  r'   c                ó4   <€ / V n         \        SV `	  V4       R # r4   )Únamed_rulesÚsuperrS   )r+   r…   Ú	__class__s   &&€r$   rS   ÚReversibleRuleRouter.__init__§  s   ø€ ØˆÔÜ‰Ñ˜Ör'   c                ó"   <€ V ^8„  d   QhRRRR/# r›   r8   )r"   r#   s   "€r$   r%   r¯   «  s   ø€ ÷ 
ñ 
 ð 
¨Fñ 
r'   c                óò   <€ \         SV `  V4      pVP                  '       dU   VP                  V P                  9   d"   \        P
                  ! R VP                  4       WP                  VP                  &   V# )z4Multiple handlers named %s; replacing previous value)r²   r—   rE   r±   r   Úwarning)r+   r˜   r³   s   &&€r$   r—   Ú!ReversibleRuleRouter.process_rule«  s[   ø€ Ü‰wÑ# DÓ)ˆà�9�9ˆ9Ø�y‰y˜D×,Ñ,Ô,Ü—’ØJÈDÏIÉIôð +/×Ñ˜TŸY™YÑ'àˆr'   c                ó<   <€ V ^8„  d   QhRS[ RS[RS[S[ ,          /# rD   rG   )r"   r#   s   "€r$   r%   r¯   ·  s&   ø€ ÷ 
ñ 
¡ð 
©Cð 
±H¹SµMñ 
r'   c                ó2  € WP                   9   d,   V P                   V,          P                  P                  ! V!  # V P                   FK  p\	        VP
                  \        4      '       g   K%  VP
                  P                  ! V.VO5!  pVf   KI  Vu # 	  R # r4   )r±   r¡   Úreverser…   r^   r¤   rB   rK   )r+   rE   rF   r˜   Úreversed_urls   &&*  r$   rK   Ú ReversibleRuleRouter.reverse_url·  sz   € Ø×#Ñ#Ô#Ø×#Ñ# DÕ)×1Ñ1×9Ò9¸4Ñ@Ð@à—J”JˆDÜ˜$Ÿ+™+Ô'7×8Ô8Ø#Ÿ{™{×6Ò6°tÐC¸dÓC�ØÔ+Ø'Ò'ñ	 ñ r'   )r±   r4   )r9   r:   r;   r<   r=   rS   r—   rK   r>   r?   Ú__classcell__©r³   r#   s   @@r$   r­   r­   Ÿ  s-   ù‡ € ñ÷ õ  ÷
ó 
÷
÷ 
ð 
r'   r­   c                   ó^   a € ] tR tRt o RtRV 3R lR lltV 3R lR ltV 3R lR	 ltR
tV t	R# )r   iÄ  zA routing rule.Nc          
      ój   <€ V ^8„  d   QhRRRS[ RS[S[S[S[ 3,          ,          RS[S[,          RR/# )r   r¡   r€   r¤   r    rE   r   N)r   r   r   rH   )r"   r#   s   "€r$   r%   ÚRule.__annotate__Ç  sN   ø€ ÷ ñ àðñ ðñ  ¡¡S©# X¥Õ/ð	ñ
 ‘s�mðð 
ñr'   c                óŽ   € \        V\        4      '       d   \        V4      pWn        W n        V'       d   TM/ V n        W@n        R# )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)r^   rH   r
   r¡   r¤   r    rE   )r+   r¡   r¤   r    rE   s   &&&&&r$   rS   ÚRule.__init__Ç  s8   € ô. �fœc×"Ò"ô # 6Ó*ˆFàŒØŒß.;™]ÀˆÔØŽ	r'   c                ó6   <€ V ^8„  d   QhRS[ RS[S[,          /# ©r   rF   r   ©r   r   rH   )r"   r#   s   "€r$   r%   rÂ   è  s   ø€ ÷ +ñ +™Sð +¡X©c¥]ñ +r'   c                ó6   € V P                   P                  ! V!  # r4   )r¡   r»   ©r+   rF   s   &*r$   r»   ÚRule.reverseè  s   € Ø�|‰|×#Ò# TÑ*Ð*r'   c                ó    <€ V ^8„  d   QhRS[ /# ©r   r   ©rH   )r"   r#   s   "€r$   r%   rÂ   ë  ó   ø€ ÷ 
ñ 
™#ñ 
r'   c                ó¤   € R P                  V P                  P                  V P                  V P                  V P
                  V P                  4      # ©z${}({!r}, {}, kwargs={!r}, name={!r}))r"   r³   r9   r¡   r¤   r    rE   ro   s   &r$   Ú__repr__ÚRule.__repr__ë  s@   € Ø5×<Ñ<Ø�N‰N×#Ñ#Ø�L‰LØ�K‰KØ×ÑØ�I‰Ió
ð 	
r'   )r¡   rE   r¤   r    ©NN)
r9   r:   r;   r<   r=   rS   r»   rÑ   r>   r?   r@   s   @r$   r   r   Ä  s'   ø‡ € Ù÷ò ÷B+ð +÷
ö 
r'   c                   óH   a € ] tR tRt o RtV 3R lR ltV 3R lR ltRtV tR# )	r€   iõ  z*Represents a matcher for request features.c                ó`   <€ V ^8„  d   QhRS[ P                  RS[S[S[S[3,          ,          /# ©r   r   r   ©r   r    r   r   rH   r   )r"   r#   s   "€r$   r%   ÚMatcher.__annotate__ø  s.   ø€ ÷ 
$ñ 
$™X×7Ñ7ð 
$¹HÁTÉ#ÉsÈ(Å^Õ<Tñ 
$r'   c                ó   € \        4       h)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'   c                ó6   <€ V ^8„  d   QhRS[ RS[S[,          /# rÆ   rÇ   )r"   r#   s   "€r$   r%   rØ     s   ø€ ÷ ñ ™Sð ¡X©c¥]ñ r'   c                ó   € R# )zEReconstructs full url from matcher instance and additional arguments.Nr8   rÉ   s   &*r$   r»   ÚMatcher.reverse  s   € ár'   r8   N)	r9   r:   r;   r<   r=   r¢   r»   r>   r?   r@   s   @r$   r€   r€   õ  s   ø‡ € Ù4÷
$ð 
$÷ö r'   c                   ó6   a € ] tR tRt o RtV 3R lR ltRtV tR# )Ú
AnyMatchesi	  zMatches any request.c                ó`   <€ V ^8„  d   QhRS[ P                  RS[S[S[S[3,          ,          /# rÖ   r×   )r"   r#   s   "€r$   r%   ÚAnyMatches.__annotate__  s.   ø€ ÷ ñ ™X×7Ñ7ð ¹HÁTÉ#ÉsÈ(Å^Õ<Tñ r'   c                ó   € / # r4   r8   rÚ   s   &&r$   r¢   ÚAnyMatches.match  s   € Øˆ	r'   r8   N)r9   r:   r;   r<   r=   r¢   r>   r?   r@   s   @r$   rà   rà   	  s   ø‡ € Ù÷ö r'   rà   c                   óH   a € ] tR tRt o RtV 3R lR ltV 3R lR ltRtV tR# )	ÚHostMatchesi  z@Matches requests from hosts specified by ``host_pattern`` regex.c                ó:   <€ V ^8„  d   QhRS[ S[S[3,          RR/# )r   Úhost_patternr   N©r   rH   r   )r"   r#   s   "€r$   r%   ÚHostMatches.__annotate__  s$   ø€ ÷ -ñ -¡U©3±¨<Õ%8ð -¸Tñ -r'   c                ó¸   € \        V\        4      '       d>   VP                  R 4      '       g
   VR ,          p\        P                  ! V4      V n        R# Wn        R# )Ú$N)r^   r	   ÚendswithÚreÚcompilerè   )r+   rè   s   &&r$   rS   ÚHostMatches.__init__  sA   € Ü�l¤O×4Ò4Ø×(Ñ(¨×-Ò-Ø Õ#�Ü "§
¢
¨<Ó 8ˆDÖà ,Ör'   c                ó`   <€ V ^8„  d   QhRS[ P                  RS[S[S[S[3,          ,          /# rÖ   r×   )r"   r#   s   "€r$   r%   rê     s.   ø€ ÷ ñ ™X×7Ñ7ð ¹HÁTÉ#ÉsÈ(Å^Õ<Tñ r'   c                ó`   € V P                   P                  VP                  4      '       d   / # R # r4   )rè   r¢   Ú	host_namerÚ   s   &&r$   r¢   ÚHostMatches.match  s'   € Ø×Ñ×"Ñ" 7×#4Ñ#4×5Ò5ØˆIár'   )rè   N©	r9   r:   r;   r<   r=   rS   r¢   r>   r?   r@   s   @r$   ræ   ræ     s   ø‡ € ÙJ÷-ð -÷ö r'   ræ   c                   óH   a € ] tR tRt o RtV 3R lR ltV 3R lR ltRtV tR# )	Ú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.
c                ó*   <€ V ^8„  d   QhRS[ RS[RR/# )r   Úapplicationrè   r   N)r   r   )r"   r#   s   "€r$   r%   ÚDefaultHostMatches.__annotate__'  s"   ø€ ÷ )ñ )¡Cð )±wð )À4ñ )r'   c                ó   € Wn         W n        R # r4   ©rù   rè   )r+   rù   rè   s   &&&r$   rS   ÚDefaultHostMatches.__init__'  s   € Ø&ÔØ(Ör'   c                ó`   <€ V ^8„  d   QhRS[ P                  RS[S[S[S[3,          ,          /# rÖ   r×   )r"   r#   s   "€r$   r%   rú   +  s.   ø€ ÷ ñ ™X×7Ñ7ð ¹HÁTÉ#ÉsÈ(Å^Õ<Tñ r'   c                ó–   € R VP                   9  d8   V P                  P                  V P                  P                  4      '       d   / # R# )z	X-Real-IpN)rW   rè   r¢   rù   Údefault_hostrÚ   s   &&r$   r¢   ÚDefaultHostMatches.match+  s9   € à˜gŸo™oÔ-Ø× Ñ ×&Ñ& t×'7Ñ'7×'DÑ'D×EÒEØ�	Ùr'   rü   Nrõ   r@   s   @r$   r÷   r÷   "  s   ø‡ € ñ÷)ð )÷ö r'   r÷   c                   ól   a € ] tR tRt o RtV 3R lR ltV 3R lR ltV 3R lR ltV 3R	 lR
 ltRt	V t
R# )r•   i3  z@Matches requests with paths specified by ``path_pattern`` regex.c                ó:   <€ V ^8„  d   QhRS[ S[S[3,          RR/# )r   Úpath_patternr   Nré   )r"   r#   s   "€r$   r%   ÚPathMatches.__annotate__6  s$   ø€ ÷ <ñ <¡U©3±¨<Õ%8ð <¸Tñ <r'   c                ó¨  € \        V\        4      '       d=   VP                  R 4      '       g
   VR ,          p\        P                  ! V4      V n        MWn        \        V P
                  P                  4      ^ V P
                  P                  39   g#   Q RV P
                  P                  ,          4       hV P                  4       w  V n        V n        R# )rì   zDgroups in url regexes must either be all named or all positional: %rN)r^   r	   rí   rî   rï   Úregexr”   Ú
groupindexÚgroupsÚpatternÚ_find_groupsÚ_pathÚ_group_count)r+   r  s   &&r$   rS   ÚPathMatches.__init__6  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'   c                ó`   <€ V ^8„  d   QhRS[ P                  RS[S[S[S[3,          ,          /# rÖ   r×   )r"   r#   s   "€r$   r%   r  E  s2   ø€ ÷ Bñ B™X×7Ñ7ð B¹HÁTÉ#ÉsÈ(Å^Õ<Tñ Br'   c                óÜ  € V P                   P                  VP                  4      pVf   R # V P                   P                  '       g   / # . p/ pV P                   P                  '       dF   VP                  4       P                  4        UUu/ uF  w  rV\        V4      \        V4      bK  	  pppM(VP                  4        Uu. uF  p\        V4      NK  	  pp\        W4R7      # u uppi u upi )N)Ú	path_argsÚpath_kwargs)
r  r¢   ra   r	  r  Ú	groupdictÚitemsrH   Ú_unquote_or_noneÚdict)r+   r   r¢   r  r  ÚkÚvÚss   &&      r$   r¢   ÚPathMatches.matchE  sË   € Ø—
‘
× Ñ  §¡Ó.ˆØŠ=ÙØ�z‰z× × Ð ØˆIàˆ	Øˆð �:‰:× × Ð à:?¿/¹/Ó:K×:QÑ:QÔ:SôÙ:S±°”�A“Ô(¨Ó+Ò+Ñ:Sð ñ ˆKð 7<·l±l´nÓE±n°Ô)¨!Ö,±nˆIÐEä˜iÔAÐAùóùò Fs   Â C#ÃC)c                ó6   <€ V ^8„  d   QhRS[ RS[S[,          /# rÆ   rÇ   )r"   r#   s   "€r$   r%   r  \  s   ø€ ÷ 2ñ 2™Sð 2¡X©c¥]ñ 2r'   c                óÌ  € V P                   f'   \        RV P                  P                  ,           4      h\	        V4      V P
                  8X  g   Q R4       h\	        V4      '       g   V P                   # . pV FO  p\        V\        \        34      '       g   \        V4      pVP                  \        \        V4      RR7      4       KQ  	  V P                   \        V4      ,          # )NzCannot reverse url regex z&required number of arguments not foundF)Úplus)r  Ú
ValueErrorr  r
  r”   r  r^   r   rg   rH   r–   r   r   r’   )r+   rF   Úconverted_argsÚas   &*  r$   r»   ÚPathMatches.reverse\  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                óV   <€ V ^8„  d   QhRS[ S[S[,          S[S[,          3,          /# rÌ   )r   r   rH   Úint)r"   r#   s   "€r$   r%   r  k  s&   ø€ ÷ &2ñ &2™e¡H©S¥M±8¹Cµ=Ð$@ÕAñ &2r'   c                ó®  € V P                   P                  pVP                  R4      '       d
   VR,          pVP                  R4      '       d   VRR	 pV P                   P                  VP                  R4      8w  d   R
# . pVP                  R4       Fp  pRV9   dJ   VP                  R4      pV^ 8¼  d0    \        W4^,           R 4      pTP                  RT,           4       KQ  KS   \        V4      pTP                  T4       Kr  	  RP                  V4      V P                   P                  3#   \         d    R
u u # i ; i  \         d    R
u u # i ; i)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).
Ú^rŽ   rì   NÚ(Ú)z%sÚ éÿÿÿÿrÓ   )r  r
  Ú
startswithrí   r	  ÚcountÚsplitÚindexr   r  r–   Újoin)r+   r
  ÚpiecesÚfragmentÚ	paren_locÚunescaped_fragments   &     r$   r  ÚPathMatches._find_groupsk  sA  € ð —*‘*×$Ñ$ˆØ×Ñ˜c×"Ò"Ø˜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$   Â5D-Ã&EÄ-D?Ä>D?ÅEÅE)r  r  r  N)r9   r:   r;   r<   r=   rS   r¢   r»   r  r>   r?   r@   s   @r$   r•   r•   3  s2   ø‡ € ÙJ÷<ð <÷Bð B÷.2ð 2÷&2ö &2r'   r•   c                   óX   a a€ ] tR tRt oRtRV3R lV 3R llltV3R lR ltRtVtV ;t	# )	Ú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.
c          
      ó‚   <€ V ^8„  d   QhRS[ S[S[3,          RS[RS[S[S[S[3,          ,          RS[S[,          RR/# )r   r
  Úhandlerr   rE   r   N)r   rH   r   r   r   r   )r"   r#   s   "€r$   r%   ÚURLSpec.__annotate__œ  sW   ø€ ÷ ñ á‘s™G�|Õ$ðñ ðñ ™™c¡3˜h�Õ(ð	ñ
 ‘s�mðð 
ñr'   c                óŽ   <€ \        V4      p\        SV `	  WRW44       VP                  V n        V P                  V n        W0n        R# )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²   rS   r  r¤   Úhandler_classr   )r+   r
  r7  r   rE   r¡   r³   s   &&&&& €r$   rS   ÚURLSpec.__init__œ  s:   ø€ ô0 ˜gÓ&ˆÜ‰Ñ˜¨6Ô8à—]‘]ˆŒ
Ø!Ÿ[™[ˆÔØŽr'   c                ó    <€ V ^8„  d   QhRS[ /# rÌ   rÍ   )r"   r#   s   "€r$   r%   r8  »  rÎ   r'   c                ó¸   € R P                  V P                  P                  V P                  P                  V P
                  V P                  V P                  4      # rÐ   )r"   r³   r9   r  r
  r:  r   rE   ro   s   &r$   rÑ   ÚURLSpec.__repr__»  sF   € Ø5×<Ñ<Ø�N‰N×#Ñ#Ø�J‰J×ÑØ×ÑØ�K‰KØ�I‰Ió
ð 	
r'   )r:  r   r  rÓ   )
r9   r:   r;   r<   r=   rS   rÑ   r>   r?   r¾   r¿   s   @@r$   r5  r5  ”  s#   ù‡ € ñ÷õ ÷>
÷ 
ð 
r'   r5  c                ó0   € V ^8„  d   QhR\         R\        /# ©r   r  r   )rH   rg   )r"   s   "r$   r%   r%   Æ  s   € ÷ 	ñ 	œð 	¤ñ 	r'   c                 ó   € R # r4   r8   ©r  s   &r$   r  r  Å  ó   € ár'   c                ó    € V ^8„  d   QhRRRR/# )r   r  Nr   r8   )r"   s   "r$   r%   r%   Ë  s   € ÷ 	ñ 	˜ð 	 ñ 	r'   c                 ó   € R # r4   r8   rB  s   &r$   r  r  Ê  rC  r'   c                ó\   € V ^8„  d   QhR\         \        ,          R\         \        ,          /# r@  )r   rH   rg   )r"   s   "r$   r%   r%   Ï  s"   € ÷ 	6ñ 	6œ¤�ð 	6¬(´5­/ñ 	6r'   c                ó*   € V f   V # \        V RRR7      # )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   rB  s   &r$   r  r  Ï  s   € ð 	‚yØˆÜ˜ D¨uÔ5Ð5r'   )0r=   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©   r   rB   r!   r5   rb   rH   r‡   r‚   r­   r   r€   rà   ræ   r÷   r•   r5  r  r8   r'   r$   Ú<module>rP     sš  ðñaóF 
Ý å Ý /ß 9Ñ 9Ý ß RÓ R÷÷ ÷ ôAˆX×2Ñ2ô Aô.$�vô $ô +0�x×3Ñ3ô +0ô\	!˜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.
ñ .
÷bñ ô(�ô ô�'ô ô$˜ô ô"^2�'ô ^2ôB.
ˆdô .
ðb 
ô	ó 
ð	ð 
ô	ó 
ð	÷	6r'   