
    ƪbQV              	       P   d Z ddlZddlZdZdZd Z G d d      Zd Zd	 Zd
 Z	d Z
d Zd Z G d de      Zh dZd ej                   dej"                        fd ej                   ddj%                  e       d      fd ej                   d      fd ej                   d      fd ej                   dej"                        fgZd Zd2dZd2dZd Zd  Zd! Zd" Z G d# d$      Zd% Zd& Zd' Z G d( d)      Z G d* d+e      Z  G d, d-e      Z! G d. d/e!      Z" G d0 d1e      Z#y)3z
    babel.numbers
    ~~~~~~~~~~~~~

    CLDR Plural support.  See UTS #35.

    :copyright: (c) 2013-2022 by the Babel Team.
    :license: BSD, see LICENSE for more details.
    N)zeroonetwofewmanyotherr   c                    t        |       }t        |      }t        |t              r&||k(  r|}nt	        j
                  t        |            }t        |t        j
                        r|j                         }|j                  }|dk  r|j                  |d nd}dj                  d |D              }|j                  d      }t        |      }t        |      }	t        |xs d      }
t        |xs d      }ndx}x}	x}
}dx}}||||	|
|||fS )u  Extract operands from a decimal, a float or an int, according to `CLDR rules`_.

    The result is a 8-tuple (n, i, v, w, f, t, c, e), where those symbols are as follows:

    ====== ===============================================================
    Symbol Value
    ------ ---------------------------------------------------------------
    n      absolute value of the source number (integer and decimals).
    i      integer digits of n.
    v      number of visible fraction digits in n, with trailing zeros.
    w      number of visible fraction digits in n, without trailing zeros.
    f      visible fractional digits in n, with trailing zeros.
    t      visible fractional digits in n, without trailing zeros.
    c      compact decimal exponent value: exponent of the power of 10 used in compact decimal formatting.
    e      currently, synonym for ‘c’. however, may be redefined in the future.
    ====== ===============================================================

    .. _`CLDR rules`: https://www.unicode.org/reports/tr35/tr35-61/tr35-numbers.html#Operands

    :param source: A real number
    :type source: int|float|decimal.Decimal
    :return: A n-i-v-w-f-t-c-e tuple
    :rtype: tuple[decimal.Decimal, int, int, int, int, int, int, int]
    r   N  c              3   2   K   | ]  }t        |        y wNstr).0ds     ./usr/lib/python3/dist-packages/babel/plural.py	<genexpr>z#extract_operands.<locals>.<genexpr>A   s     ;a3q6;s   0)absint
isinstancefloatdecimalDecimalr   as_tupleexponentdigitsjoinrstriplen)sourceni	dec_tupleexpfraction_digitstrailingno_trailingvwftces                 r   extract_operandsr/      s   2 	FAAA!U6A A'A!W__%JJL	  47!G)**34077;?;;ooc*MA q!AAIAaAq!Q!!    c                   h    e Zd ZdZdZd Zd Zed        Ze	d        Z
 e	d d	      Zd
 Zd Zd Zy)
PluralRuleaf  Represents a set of language pluralization rules.  The constructor
    accepts a list of (tag, expr) tuples or a dict of `CLDR rules`_. The
    resulting object is callable and accepts one parameter with a positive or
    negative number (both integer and float) for the number that indicates the
    plural form for a string and returns the tag for the format:

    >>> rule = PluralRule({'one': 'n is 1'})
    >>> rule(1)
    'one'
    >>> rule(2)
    'other'

    Currently the CLDR defines these tags: zero, one, two, few, many and
    other where other is an implicit default.  Rules should be mutually
    exclusive; for a given numeric value, only one rule should apply (i.e.
    the condition should only be true for one of the plural rule elements.

    .. _`CLDR rules`: https://www.unicode.org/reports/tr35/tr35-33/tr35-numbers.html#Language_Plural_Rules
    )abstract_funcc                 z   t        |t              r|j                         }t               }g | _        t        t        |            D ]s  \  }}|t        vrt        d|z        ||v rt        d|z        |j                  |       t        |      j                  }|sW| j                  j                  ||f       u y)a$  Initialize the rule instance.

        :param rules: a list of ``(tag, expr)``) tuples with the rules
                      conforming to UTS #35 or a dict with the tags as keys
                      and expressions as values.
        :raise RuleError: if the expression is malformed
        zunknown tag %rztag %r defined twiceN)r   dictitemssetr3   sortedlist_plural_tags
ValueErroradd_Parserastappend)selfrulesfoundkeyexprr?   s         r   __init__zPluralRule.__init__d   s     eT"KKMEU, 	1IC,& !1C!788 !7#!=>>IIcN$-##C$$c3Z0	1r0   c                     | j                   }dt        |       j                  ddj                  t        D cg c]  }||v r
|d||    c}      dS c c}w )N< , z: >)rB   type__name__r   r;   )rA   rB   tags      r   __repr__zPluralRule.__repr__z   sW    

JII| (, $'c
3 ( )
 	
(s   Ac                 .    t        ||       r|S  | |      S )a
  Create a `PluralRule` instance for the given rules.  If the rules
        are a `PluralRule` object, that object is returned.

        :param rules: the rules as list or dict, or a `PluralRule` object
        :raise RuleError: if the expression is malformed
        )r   )clsrB   s     r   parsezPluralRule.parse   s     eS!L5zr0   c                     t               j                  }| j                  D ci c]  \  }}| ||       c}}S c c}}w )zThe `PluralRule` as a dict of unicode plural rules.

        >>> rule = PluralRule({'one': 'n is 1'})
        >>> rule.rules
        {'one': 'n is 1'}
        )_UnicodeCompilercompiler3   )rA   _compilerN   r?   s       r   rB   zPluralRule.rules   s7     $%--37==AxsCXc]"AAAs   ;c                 :    t        d | j                  D              S )Nc              3   &   K   | ]	  }|d      yw)r   Nr
   )r   r#   s     r   r   z&PluralRule.<lambda>.<locals>.<genexpr>   s     'A!'As   )	frozensetr3   xs    r   <lambda>zPluralRule.<lambda>   s    i'Aajj'AA r0   z
        A set of explicitly defined tags in this rule.  The implicit default
        ``'other'`` rules is not part of this set unless there is an explicit
        rule for it.)docc                     | j                   S r   r3   rA   s    r   __getstate__zPluralRule.__getstate__   s    }}r0   c                     || _         y r   r_   )rA   r3   s     r   __setstate__zPluralRule.__setstate__   s	     r0   c                 \    t        | d      st        |       | _        | j                  |      S )Nr4   )hasattr	to_pythonr4   )rA   r"   s     r   __call__zPluralRule.__call__   s%    tW%"4DJzz!}r0   N)rM   
__module____qualname____doc__	__slots__rF   rO   classmethodrR   propertyrB   tagsra   rc   rg   r
   r0   r   r2   r2   M   sf    ( &I1,
 	 	 B B A H D
!r0   r2   c                 
   t               j                  }dg}t        j                  |       j                  D ]"  \  }}|j                   ||      d|d       $ |j                  dt        z         dj                  |      S )a  Convert a list/dict of rules or a `PluralRule` object into a JavaScript
    function.  This function depends on no external library:

    >>> to_javascript({'one': 'n is 1'})
    "(function(n) { return (n == 1) ? 'one' : 'other'; })"

    Implementation detail: The function generated will probably evaluate
    expressions involved into range operations multiple times.  This has the
    advantage that external helper functions are not required and is not a
    big performance hit for these simple calculations.

    :param rule: the rules as list or dict, or a `PluralRule` object
    :raise RuleError: if the expression is malformed
    z(function(n) { return z ? z : z%r; })r   )_JavaScriptCompilerrU   r2   rR   r3   r@   _fallback_tagr   )ruleto_jsresultrN   r?   s        r   to_javascriptru      sr      !))E&'F$$T*33 8SeCj#678
MM(]*+776?r0   c           	         t         t        t        t        d}t	               j
                  }ddg}t        j                  |       j                  D ]+  \  }}|j                  d ||      dt        |             - |j                  dt        z         t        dj                  |      dd	      }t        ||       |d
   S )a<  Convert a list/dict of rules or a `PluralRule` object into a regular
    Python function.  This is useful in situations where you need a real
    function and don't are about the actual rule object:

    >>> func = to_python({'one': 'n is 1', 'few': 'n in 2..4'})
    >>> func(1)
    'one'
    >>> func(3)
    'few'
    >>> func = to_python({'one': 'n in 1,11', 'few': 'n in 3..10,13..19'})
    >>> func(11)
    'one'
    >>> func(15)
    'few'

    :param rule: the rules as list or dict, or a `PluralRule` object
    :raise RuleError: if the expression is malformed
    )INWITHINMODr/   zdef evaluate(n):z- n, i, v, w, f, t, c, e = extract_operands(n)z if (z
): return z
 return %r
z<rule>execevaluate)in_range_listwithin_range_listcldr_modulor/   _PythonCompilerrU   r2   rR   r3   r@   r   rq   r   eval)rr   	namespaceto_python_funcrt   rN   r?   codes          r   rf   rf      s    ( #,	I %&..N7F $$T*33 OS 	~c/BCHMNO MM,./499V$h7DyZ  r0   c                    t         j                  |       } | j                  t        hz  }t	               j
                  }t        D cg c]	  }||v s| c}j                  }dt        |      z  g}| j                  D ]'  \  }}|j                  d ||       ||      fz         ) |j                  d |t              z         dj                  |      S c c}w )a  The plural rule as gettext expression.  The gettext expression is
    technically limited to integers and returns indices rather than tags.

    >>> to_gettext({'one': 'n is 1', 'two': 'n is 2'})
    'nplurals=3; plural=((n == 1) ? 0 : (n == 2) ? 1 : 2);'

    :param rule: the rules as list or dict, or a `PluralRule` object
    :raise RuleError: if the expression is malformed
    znplurals=%d; plural=(z
%s ? %d : z%d);r   )r2   rR   rn   rq   _GettextCompilerrU   r;   indexr    r3   r@   r   )rr   	used_tagsrV   rN   
_get_indexrt   r?   s          r   
to_gettextr      s     D!D		]O+I!))H!-B#	1A#BHHJ%I67FMM GSlhsmZ_%EEFG
MM&:m445776? Cs   	CCc                 :    | t        |       k(  xr t        | |      S )a  Integer range list test.  This is the callback for the "in" operator
    of the UTS #35 pluralization rule language:

    >>> in_range_list(1, [(1, 3)])
    True
    >>> in_range_list(3, [(1, 3)])
    True
    >>> in_range_list(3, [(1, 3), (5, 8)])
    True
    >>> in_range_list(1.2, [(1, 4)])
    False
    >>> in_range_list(10, [(1, 4)])
    False
    >>> in_range_list(10, [(1, 4), (6, 8)])
    False
    )r   r~   num
range_lists     r   r}   r}      s    " #c(?A0jAAr0   c                 ,     t         fd|D              S )a  Float range test.  This is the callback for the "within" operator
    of the UTS #35 pluralization rule language:

    >>> within_range_list(1, [(1, 3)])
    True
    >>> within_range_list(1.0, [(1, 3)])
    True
    >>> within_range_list(1.2, [(1, 4)])
    True
    >>> within_range_list(8.8, [(1, 4), (7, 15)])
    True
    >>> within_range_list(10, [(1, 4)])
    False
    >>> within_range_list(10.5, [(1, 4), (20, 30)])
    False
    c              3   <   K   | ]  \  }}|k\  xr |k    y wr   r
   )r   min_max_r   s      r   r   z$within_range_list.<locals>.<genexpr>%  s%     HztTsd{*sd{*Hs   )anyr   s   ` r   r~   r~     s    " HZHHHr0   c                 N    d}| dk  r| dz  } d}|dk  r|dz  }| |z  }|r|dz  }|S )zJavaish modulo.  This modulo operator returns the value with the sign
    of the dividend rather than the divisor like Python does:

    >>> cldr_modulo(-3, 5)
    -3
    >>> cldr_modulo(-3, -5)
    -3
    >>> cldr_modulo(3, 5)
    3
    r      r
   )abreverservs       r   r   r   (  sH     G1u	R1u	R	
QB
bIr0   c                       e Zd ZdZy)	RuleErrorzRaised if a rule is malformed.N)rM   rh   ri   rj   r
   r0   r   r   r   ?  s    (r0   r   >   r-   r.   r+   r#   r"   r,   r)   r*   z\s+wordz"\b(and|or|is|(?:with)?in|not|mod|[r   z])\bvaluez\d+symbolz%|,|!=|=ellipsisz\.{2,3}|\u2026c                 >   | j                  d      d   } g }d}t        |       }||k  rnt        D ]N  \  }}|j                  | |      }||j	                         }|r!|j                  ||j                         f        n t        d| |   z        ||k  rn|d d d   S )N@r   z5malformed CLDR pluralization rule.  Got unexpected %rr   )splitr    _RULESmatchendr@   groupr   )srt   posr   tokrr   r   s          r   tokenize_ruler   V  s    	QAF
C
a&C
) 		:ICJJq#&E iikMM3"67		:  023C&9 : : ) $B$<r0   c                 F    | xr | d   d   |k(  xr |d u xs | d   d   |k(  S )Nr   r   r   r
   tokenstype_r   s      r   test_next_tokenr   i  s<     2fRjmu, 2	$	0&*Q-502r0   c                 >    t        | ||      r| j                         S y r   )r   popr   s      r   
skip_tokenr   n  s    vue,zz| -r0   c                     d| ffS )Nr   r
   )r   s    r   
value_noder   s  s    UIr0   c                 
    | dfS )Nr
   r
   )names    r   
ident_noder   w  s    8Or0   c                 
    d| fS )Nr   r
   )r   s    r   range_list_noder   {  s    ##r0   c                     d| ffS )Nnotr
   )r   s    r   negater     s    2%<r0   c                   N    e Zd ZdZd ZddZd Zd Zd Zd Z	d	 Z
d
 Zd Zd Zy)r>   u  Internal parser.  This class can translate a single rule into an abstract
    tree of tuples. It implements the following grammar::

        condition     = and_condition ('or' and_condition)*
                        ('@integer' samples)?
                        ('@decimal' samples)?
        and_condition = relation ('and' relation)*
        relation      = is_relation | in_relation | within_relation
        is_relation   = expr 'is' ('not')? value
        in_relation   = expr (('not')? 'in' | '=' | '!=') range_list
        within_relation = expr ('not')? 'within' range_list
        expr          = operand (('mod' | '%') value)?
        operand       = 'n' | 'i' | 'f' | 't' | 'v' | 'w'
        range_list    = (range | value) (',' range_list)*
        value         = digit+
        digit         = 0|1|2|3|4|5|6|7|8|9
        range         = value'..'value
        samples       = sampleRange (',' sampleRange)* (',' ('…'|'...'))?
        sampleRange   = decimalValue '~' decimalValue
        decimalValue  = value ('.' value)?

    - Whitespace can occur between or around any of the above tokens.
    - Rules should be mutually exclusive; for a given numeric value, only one
      rule should apply (i.e. the condition should only be true for one of
      the plural rule elements).
    - The in and within relations can take comma-separated lists, such as:
      'n in 3,5,7..15'.
    - Samples are ignored.

    The translator parses the expression on instanciation into an attribute
    called `ast`.
    c                     t        |      | _        | j                  sd | _        y | j                         | _        | j                  rt	        d| j                  d   d   z        y )NzExpected end of rule, got %rr   r   )r   r   r?   	conditionr   )rA   strings     r   rF   z_Parser.__init__  s`    #F+{{ DH>>#;;: KKOA./ 0 0 r0   Nc                     t        | j                  ||      }||S |t        |d u xr |xs |      }| j                  st        d|z        t        d|d| j                  d   d         )Nz#expected %s but end of rule reachedz	expected z	 but got r   r   )r   r   reprr   )rA   r   r   termtokens        r   expectz_Parser.expect  sq    4;;u5L</%859D{{ADHIID$++b/!:LMNNr0   c                     | j                         }t        | j                  dd      r,d|| j                         ff}t        | j                  dd      r,|S )Nr   or)and_conditionr   r   rA   ops     r   r   z_Parser.condition  sO    !fd3D..011B fd3	r0   c                     | j                         }t        | j                  dd      r,d|| j                         ff}t        | j                  dd      r,|S )Nr   and)relationr   r   r   s     r   r   z_Parser.and_condition  sI    ]]_fe4T]]_--B fe4	r0   c                    | j                         }t        | j                  dd      r1t        | j                  dd      xr dxs d|| j                         ffS t        | j                  dd      }d}t        | j                  dd      rd}n5t        | j                  dd      s|rt	        d      | j                  |      S d||| j                         ff}|rt        |      S |S )	Nr   isr   isnotinwithinz#Cannot negate operator based rules.r   )rE   r   r   r   r   newfangled_relationr   r   )rA   leftnegatedmethodr   s        r   r   z_Parser.relation  s    yy{dkk640dkk659EgMtzz|$% %T[[&%8dkk684Fdkk648#$IJJ//55&$(9::$vbz,",r0   c                     t        | j                  dd      rd}n%t        | j                  dd      rd}nt        d      dd|| j                         ff}|rt	        |      S |S )	Nr   =Fz!=Tz'Expected "=" or "!=" or legacy relationr   r   )r   r   r   r   r   )rA   r   r   r   s       r   r   z_Parser.newfangled_relation  sa    dkk8S1GXt4GEFF$doo&788$vbz,",r0   c                 z    | j                         }t        | j                  d      r|| j                         fS ||fS )Nr   )r   r   r   )rA   r   s     r   range_or_valuez_Parser.range_or_value  s6    zz|dkk:.%%:r0   c                     | j                         g}t        | j                  dd      r7|j                  | j                                t        | j                  dd      r7t	        |      S )Nr   ,)r   r   r   r@   r   )rA   r   s     r   r   z_Parser.range_list  sW    ))+,
h4d1134 h4z**r0   c                 2   t        | j                  d      }||d   t        vrt        d      |d   }t        | j                  dd      rd|df| j	                         ffS t        | j                  dd      rd|df| j	                         ffS t        |      S )Nr   r   zExpected identifier variablemodr
   r   %)r   r   _VARSr   r   r   )rA   r   r   s      r   rE   z_Parser.expr  s    $++v.<47%/:;;Awdkk651D":tzz|444Xs3D":tzz|444$r0   c                 N    t        t        | j                  d      d               S )Nr   r   )r   r   r   r`   s    r   r   z_Parser.value  s     #dkk'215677r0   )NN)rM   rh   ri   rj   rF   r   r   r   r   r   r   r   rE   r   r
   r0   r   r>   r>     s;    B
0O-"-+	 8r0   r>   c                       fdS )%Compiler factory for the `_Compiler`.c                 N    | j                  |      | j                  |      fz  S r   rU   )rA   lrtmpls      r   r\   z"_binary_compiler.<locals>.<lambda>   s!    ddll1ot||A%GG r0   r
   r   s   `r   _binary_compilerr     s	    GGr0   c                       fdS )r   c                 ,    | j                  |      z  S r   r   )rA   r[   r   s     r   r\   z!_unary_compiler.<locals>.<lambda>  s    4$,,q/1 r0   r
   r   s   `r   _unary_compilerr     s	    11r0   c                      y)Nr   r
   rZ   s    r   r\   r\         r0   c                       e Zd ZdZd Zd Zd Zd Zd Zd Z	d Z
d	 Zd
 Zd Z ed      Z ed      Z ed      Z ed      Z ed      Z ed      Zd Zy)	_CompilerzZThe compilers are able to transform the expressions into multiple
    output formats.
    c                 0    |\  }} t        | d|z         | S )Ncompile_)getattr)rA   argr   argss       r   rU   z_Compiler.compile  s#    D-wtZ"_-t44r0   c                      y)Nr"   r
   rZ   s    r   r\   z_Compiler.<lambda>  r   r0   c                      y)Nr#   r
   rZ   s    r   r\   z_Compiler.<lambda>  r   r0   c                      y)Nr)   r
   rZ   s    r   r\   z_Compiler.<lambda>  r   r0   c                      y)Nr*   r
   rZ   s    r   r\   z_Compiler.<lambda>  r   r0   c                      y)Nr+   r
   rZ   s    r   r\   z_Compiler.<lambda>  r   r0   c                      y)Nr,   r
   rZ   s    r   r\   z_Compiler.<lambda>  r   r0   c                      y)Nr-   r
   rZ   s    r   r\   z_Compiler.<lambda>  r   r0   c                      y)Nr.   r
   rZ   s    r   r\   z_Compiler.<lambda>  r   r0   c                     t        |      S r   r   )r[   r)   s     r   r\   z_Compiler.<lambda>  s
    Q r0   z
(%s && %s)z
(%s || %s)z(!%s)z
(%s %% %s)z
(%s == %s)z
(%s != %s)c                     t               r   )NotImplementedError)rA   r   rE   r   s       r   compile_relationz_Compiler.compile_relation$  s    !##r0   N)rM   rh   ri   rj   rU   	compile_n	compile_i	compile_v	compile_w	compile_f	compile_t	compile_c	compile_ecompile_valuer   compile_and
compile_orr   compile_notcompile_mod
compile_iscompile_isnotr  r
   r0   r   r   r     s|    5 IIIIIIII'M"<0K!,/J!'*K"<0K!,/J$\2M$r0   r   c                   V    e Zd ZdZ ed      Z ed      Z ed      Z ed      Z	d Z
y)r   z!Compiles an expression to Python.z(%s and %s)z
(%s or %s)z(not %s)zMOD(%s, %s)c                     ddj                  |d   D cg c]$  }dt        t        | j                  |            z  & c}      z  }|j	                         d| j                  |      d|dS c c}w )Nz[%s]r   r   z(%s, %s)(rJ   ))r   tuplemaprU   upper)rA   r   rE   r   range_compile_range_lists         r   r  z _PythonCompiler.compile_relation0  so    #chh%a=* %DLL& 9:: *'+ +  &||~t||D/A13 	3*s   )A.
N)rM   rh   ri   rj   r   r  r  r   r  r  r  r
   r0   r   r   r   (  s2    +"=1K!,/J!*-K"=1K3r0   r   c                   >    e Zd ZdZej
                  ZeZeZ	eZ
eZd Zy)r   z)Compile into a gettext plural expression.c                 >   g }| j                  |      }|d   D ]o  }|d   |d   k(  r+|j                  d|d| j                  |d         d       9t        | j                   |      \  }}|j                  d|d|d|d|d	       q d	d
j                  |      z  S )Nr   r   r  z == r  z >=  && z <= z(%s)z || )rU   r@   r  r   )rA   r   rE   r   r   itemminmaxs           r   r  z!_GettextCompiler.compile_relationA  s    ||D!qM 	DAw$q'!		LLa) 
 t||T2S			 	 B''r0   N)rM   rh   ri   rj   r   r  r  compile_zeror  r  r  r	  r  r
   r0   r   r   r   8  s)    3##IIIII(r0   r   c                   ,    e Zd ZdZd ZeZeZeZeZ	d Z
y)rp   z/Compiles the expression to plain of JavaScript.c                      y)NzparseInt(n, 10)r
   rZ   s    r   r\   z_JavaScriptCompiler.<lambda>Z  r   r0   c                 z    t         j                  | |||      }|dk(  r| j                  |      }d|d|d|d}|S )Nr   z
(parseInt(z	, 10) == r  r  )r   r  rU   )rA   r   rE   r   r   s        r   r  z$_JavaScriptCompiler.compile_relation`  sA    00&$
,T><<%D7;T4HDr0   N)rM   rh   ri   rj   r  r"  r  r  r  r	  r  r
   r0   r   rp   rp   U  s%    9 ,IIIIIr0   rp   c                   n    e Zd ZdZ ed      Z ed      Z ed      Z ed      Z ed      Z	d Z
d
dZy	)rT   z+Returns a unicode pluralization rule again.z%s is %sz%s is not %sz	%s and %sz%s or %sz	%s mod %sc                 ,     | j                   |d   ddiS )Nr   r   T)r  )rA   r   s     r   r  z_UnicodeCompiler.compile_notv  s    $t$$HQK@T@@r0   c           
      >   g }|d   D ]b  }|d   |d   k(  r$|j                  | j                  |d                2|j                  dt        t        | j                  |            z         d | j                  |      |xr dxs dd|ddj	                  |      S )Nr   r   z%s..%sz notr   rI   r   )r@   rU   r  r  r   )rA   r   rE   r   r   rangesr  s          r   r  z!_UnicodeCompiler.compile_relationy  s    qM 	IDAw$q'!dll4734hs4<</F)GGH		I LL 2F 8b 8CHHV$
 	
r0   N)F)rM   rh   ri   rj   r   r  r  r  r  r  r  r  r
   r0   r   rT   rT   i  sD    5 "*-J$^4M";/K!*-J";/KA

r0   rT   r   )$rj   r   rer;   rq   r/   r2   ru   rf   r   r}   r~   r   	Exceptionr   r   rU   UNICODEr   r   r   r   r   r   r   r   r   r>   r   r   r"  r   r   r   rp   rT   r
   r0   r   <module>r-     sj    	 >8"vZ Zz.%!P.B(I(.)	 )		 
:2::fbjj)*ZRZZ=bggen=MTRSTjbjj !zrzz+&'-rzz:;
&2

$x8 x8vH
2
 $ $:3i 3 (y (:* (
y 
r0   