U
    [eBS                  	   @   s  d Z ddlZddlmZ dZdZdd ZG dd	 d	eZd
d Z	dd Z
dd Zdd Zdd Zdd ZG dd deZdZdedejfdedefdedfdedfd ed!ejfgZd"d# ZdBd$d%ZdCd&d'Zd(d) Zd*d+ Zd,d- Zd.d/ ZG d0d1 d1eZd2d3 Zd4d5 Zd6d7 Z G d8d9 d9eZ!G d:d; d;e!Z"G d<d= d=e!Z#G d>d? d?e#Z$G d@dA dAe!Z%dS )Dz
    babel.numbers
    ~~~~~~~~~~~~~

    CLDR Plural support.  See UTS #35.

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

    The result is a 6-tuple (n, i, v, w, f, t), 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.
    ====== ===============================================================

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

    :param source: A real number
    :type source: int|float|decimal.Decimal
    :return: A n-i-v-w-f-t tuple
    :rtype: tuple[decimal.Decimal, int, int, int, int, int]
    r   N  c                 s   s   | ]}t |V  qd S Nstr).0dr	   r	   N/var/www/html/services/stratfitenv/lib/python3.8/site-packages/babel/plural.py	<genexpr>A   s     z#extract_operands.<locals>.<genexpr>0)absint
isinstancefloatr   Decimalr   as_tupleexponentdigitsjoinrstriplen)sourceniZ	dec_tupleexpZfraction_digitsZtrailingZno_trailingvwftr	   r	   r   extract_operands   s$    

r&   c                   @   sd   e Zd ZdZdZdd Zdd Zedd Ze	d	d
 Z
e	dd ddZdd Zdd Zdd ZdS )
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                 C   s   t |tr| }t }g | _tt|D ]Z\}}|tkrHtd| n||kr\td| |	| t
|j}|r*| j||f q*dS )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setr(   sortedlist_plural_tags
ValueErroradd_Parserastappend)selfrulesfoundkeyexprr3   r	   r	   r   __init__c   s    


zPluralRule.__init__c                    s,   | j  dt| jd fddtD f S )Nz<%s %r>z, c                    s$   g | ]}| krd | | f qS )z%s: %sr	   r   tagr6   r	   r   
<listcomp>}   s    z'PluralRule.__repr__.<locals>.<listcomp>)r6   type__name__r   r/   r5   r	   r=   r   __repr__y   s
    zPluralRule.__repr__c                 C   s   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   )clsr6   r	   r	   r   parse   s    
zPluralRule.parsec                    s    t  j t fdd| jD S )zThe `PluralRule` as a dict of unicode plural rules.

        >>> rule = PluralRule({'one': 'n is 1'})
        >>> rule.rules
        {'one': 'n is 1'}
        c                    s   g | ]\}}| |fqS r	   r	   )r   r<   r3   _compiler	   r   r>      s     z$PluralRule.rules.<locals>.<listcomp>)_UnicodeCompilercompiler*   r(   rA   r	   rE   r   r6      s    zPluralRule.rulesc                 C   s   t dd | jD S )Nc                 S   s   g | ]}|d  qS )r   r	   )r   r    r	   r	   r   r>      s     z'PluralRule.<lambda>.<locals>.<listcomp>)	frozensetr(   xr	   r	   r   <lambda>       zPluralRule.<lambda>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                 C   s   | j S r   r(   rA   r	   r	   r   __getstate__   s    zPluralRule.__getstate__c                 C   s
   || _ d S r   rO   )r5   r(   r	   r	   r   __setstate__   s    zPluralRule.__setstate__c                 C   s   t | dst| | _| |S )Nr)   )hasattr	to_pythonr)   )r5   r   r	   r	   r   __call__   s    

zPluralRule.__call__N)r@   
__module____qualname____doc__	__slots__r:   rB   classmethodrD   propertyr6   tagsrP   rQ   rT   r	   r	   r	   r   r'   L   s   


r'   c                 C   sR   t  j}dg}t| jD ]\}}|d|||f  q|dt  d|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
%s ? %r : z%r; })r
   )_JavaScriptCompilerrH   r'   rD   r(   r4   _fallback_tagr   )ruleZto_jsresultr<   r3   r	   r	   r   to_javascript   s    r`   c                 C   s   t tttd}t j}ddg}t| jD ]"\}}|	d||t
|f  q*|	dt  td|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
    )INZWITHINZMODr&   zdef evaluate(n):z' n, i, v, w, f, t = extract_operands(n)z if (%s): return %rz
 return %r
z<rule>execevaluate)in_range_listwithin_range_listcldr_modulor&   _PythonCompilerrH   r'   rD   r(   r4   r   r]   r   eval)r^   	namespaceZto_python_funcr_   r<   r3   coder	   r	   r   rS      s    
rS   c                    s   t | } | jthB  t j} fddtD j}dt  g}| j	D ]"\}}|
d||||f  qF|
d|t  d|S )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
    c                    s   g | ]}| kr|qS r	   r	   r;   Z	used_tagsr	   r   r>      s      zto_gettext.<locals>.<listcomp>znplurals=%d; plural=(z
%s ? %d : z%d)r
   )r'   rD   r[   r]   _GettextCompilerrH   r/   indexr   r(   r4   r   )r^   rF   Z
_get_indexr_   r<   r3   r	   rl   r   
to_gettext   s    

ro   c                 C   s   | t | ko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   rf   num
range_listr	   r	   r   re      s    re   c                    s   t  fd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   s"   | ]\}} |ko |kV  qd S r   r	   )r   Zmin_Zmax_rq   r	   r   r   $  s     z$within_range_list.<locals>.<genexpr>)anyrp   r	   rs   r   rf     s    rf   c                 C   s@   d}| dk r| d9 } d}|dk r(|d9 }| | }|r<|d9 }|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rvr	   r	   r   rg   '  s    rg   c                   @   s   e Zd ZdZdS )	RuleErrorzRaised if a rule is malformed.N)r@   rU   rV   rW   r	   r	   r	   r   r{   >  s   r{   Znivwftz\s+wordz)\b(and|or|is|(?:with)?in|not|mod|[{0}])\bvaluez\d+symbolz%|,|!=|=ellipsisz\.{2,3}|\u2026c                 C   s   |  dd } g }d}t| }||k r|tD ]>\}}|| |}|d k	r*| }|rd||| f  qq*td| |  q|d d d S )N@r   z5malformed CLDR pluralization rule.  Got unexpected %rru   )splitr   _RULESmatchendr4   groupr{   )sr_   posr   tokr^   r   r	   r	   r   tokenize_ruleM  s     r   c                 C   s,   | o*| d d |ko*|d kp*| d d |kS )Nru   r   rv   r	   tokenstype_r}   r	   r	   r   test_next_token`  s    r   c                 C   s   t | ||r|  S d S r   )r   popr   r	   r	   r   
skip_tokene  s    r   c                 C   s
   d| ffS )Nr}   r	   )r}   r	   r	   r   
value_nodej  s    r   c                 C   s   | dfS )Nr	   r	   )namer	   r	   r   
ident_noden  s    r   c                 C   s   d| fS )Nrr   r	   )rr   r	   r	   r   range_list_noder  s    r   c                 C   s
   d| ffS )Nnotr	   )rz   r	   r	   r   negatev  s    r   c                   @   sb   e Zd ZdZdd ZdddZdd Zd	d
 Zdd Zdd Z	dd Z
dd Zdd Zdd ZdS )r2   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                 C   sD   t || _| jsd | _d S |  | _| jr@td| jd d  d S )NzExpected end of rule, got %rru   rv   )r   r   r3   	conditionr{   )r5   stringr	   r	   r   r:     s    

z_Parser.__init__Nc                 C   sf   t | j||}|d k	r|S |d kr6t|d kr0|p2|}| jsHtd| td|| jd d f d S )Nz#expected %s but end of rule reachedzexpected %s but got %rru   rv   )r   r   reprr{   )r5   r   r}   termtokenr	   r	   r   expect  s    z_Parser.expectc                 C   s,   |   }t| jddr(d||   ff}q|S )Nr|   or)and_conditionr   r   r5   opr	   r	   r   r     s    z_Parser.conditionc                 C   s,   |   }t| jddr(d||   ff}q|S )Nr|   and)relationr   r   r   r	   r	   r   r     s    z_Parser.and_conditionc                 C   s   |   }t| jddr8t| jddr(dp*d||  ffS t| jdd}d}t| jddr^d}n$t| jdds|rxtd| |S d|||  ff}|rt|S |S )	Nr|   isr   ZisnotinZwithinz#Cannot negate operator based rules.r   )r9   r   r   r}   r{   newfangled_relationrr   r   )r5   leftnegatedmethodrz   r	   r	   r   r     s    

z_Parser.relationc                 C   sR   t | jddrd}nt | jddr(d}ntddd||  ff}|rNt|S |S )	Nr~   =Fz!=Tz'Expected "=" or "!=" or legacy relationr   r   )r   r   r{   rr   r   )r5   r   r   rz   r	   r	   r   r     s    z_Parser.newfangled_relationc                 C   s,   |   }t| jdr ||   fS ||fS d S )Nr   )r}   r   r   )r5   r   r	   r	   r   range_or_value  s    z_Parser.range_or_valuec                 C   s0   |   g}t| jddr(||    q
t|S )Nr~   ,)r   r   r   r4   r   )r5   rr   r	   r	   r   rr     s    
z_Parser.range_listc                 C   s|   t | jd}|d ks |d tkr(td|d }t | jddrRd|df|  ffS t | jddrtd|df|  ffS t|S )Nr|   rv   zExpected identifier variablemodr	   r~   %)r   r   _VARSr{   r}   r   )r5   r|   r   r	   r	   r   r9     s    z_Parser.exprc                 C   s   t t| dd S )Nr}   rv   )r   r   r   rA   r	   r	   r   r}     s    z_Parser.value)NN)r@   rU   rV   rW   r:   r   r   r   r   r   r   rr   r9   r}   r	   r	   r	   r   r2   z  s   !


r2   c                    s    fddS )%Compiler factory for the `_Compiler`.c                    s    |  ||  |f S r   rH   )r5   lrtmplr	   r   rL     rM   z"_binary_compiler.<locals>.<lambda>r	   r   r	   r   r   _binary_compiler  s    r   c                    s    fddS )r   c                    s    |  | S r   r   )r5   rK   r   r	   r   rL     rM   z!_unary_compiler.<locals>.<lambda>r	   r   r	   r   r   _unary_compiler  s    r   c                 C   s   dS )Nr   r	   rJ   r	   r	   r   rL     rM   rL   c                   @   s   e Zd ZdZdd Zdd Zdd Zdd Zdd Zd	d Z	d
d Z
dd ZedZedZedZedZedZedZdd ZdS )	_CompilerzZThe compilers are able to transform the expressions into multiple
    output formats.
    c                 C   s   |\}}t | d| | S )NZcompile_)getattr)r5   argr   argsr	   r	   r   rH     s    z_Compiler.compilec                 C   s   dS )Nr   r	   rJ   r	   r	   r   rL     rM   z_Compiler.<lambda>c                 C   s   dS )Nr    r	   rJ   r	   r	   r   rL     rM   c                 C   s   dS )Nr"   r	   rJ   r	   r	   r   rL     rM   c                 C   s   dS )Nr#   r	   rJ   r	   r	   r   rL     rM   c                 C   s   dS )Nr$   r	   rJ   r	   r	   r   rL     rM   c                 C   s   dS )Nr%   r	   rJ   r	   r	   r   rL     rM   c                 C   s   t |S r   r   )rK   r"   r	   r	   r   rL     rM   z
(%s && %s)z
(%s || %s)z(!%s)z
(%s %% %s)
(%s == %s)z
(%s != %s)c                 C   s
   t  d S r   )NotImplementedError)r5   r   r9   rr   r	   r	   r   compile_relation  s    z_Compiler.compile_relationN)r@   rU   rV   rW   rH   	compile_n	compile_i	compile_v	compile_w	compile_f	compile_tZcompile_valuer   compile_and
compile_orr   compile_notcompile_mod
compile_iscompile_isnotr   r	   r	   r	   r   r     s    r   c                   @   s8   e Zd ZdZedZedZedZedZ	dd Z
dS )	rh   z!Compiles an expression to Python.z(%s and %s)z
(%s or %s)z(not %s)zMOD(%s, %s)c                    s8   dd  fdd|d D  }d|  ||f S )Nz[%s]r   c                    s    g | ]}d t t j| qS )z(%s, %s))tuplemaprH   )r   Zrange_rA   r	   r   r>   '  s   z4_PythonCompiler.compile_relation.<locals>.<listcomp>rv   z
%s(%s, %s))r   upperrH   )r5   r   r9   rr   Zcompile_range_listr	   rA   r   r   %  s    
z _PythonCompiler.compile_relationN)r@   rU   rV   rW   r   r   r   r   r   r   r   r	   r	   r	   r   rh     s   rh   c                   @   s.   e Zd ZdZejZeZeZ	eZ
eZdd ZdS )rm   z)Compile into a gettext plural expression.c              	   C   s~   g }|  |}|d D ]X}|d |d krH|d||  |d f  qt| j |\}}|d||||f  qdd| S )Nrv   r   r   z(%s >= %s && %s <= %s)z(%s)z || )rH   r4   r   r   )r5   r   r9   rr   rz   itemminmaxr	   r	   r   r   6  s     


z!_GettextCompiler.compile_relationN)r@   rU   rV   rW   r   r   r   compile_zeror   r   r   r   r   r	   r	   r	   r   rm   -  s   rm   c                   @   s0   e Zd ZdZdd ZeZeZeZeZ	dd Z
dS )r\   z/Compiles the expression to plain of JavaScript.c                 C   s   dS )NzparseInt(n, 10)r	   rJ   r	   r	   r   rL   O  rM   z_JavaScriptCompiler.<lambda>c                 C   s4   t | |||}|dkr0| |}d|||f }|S )Nr   z(parseInt(%s, 10) == %s && %s))rm   r   rH   )r5   r   r9   rr   rk   r	   r	   r   r   U  s       
z$_JavaScriptCompiler.compile_relationN)r@   rU   rV   rW   r   r   r   r   r   r   r   r	   r	   r	   r   r\   J  s   r\   c                   @   sJ   e Zd ZdZedZedZedZedZedZ	dd Z
dd
dZdS )rG   z+Returns a unicode pluralization rule again.z%s is %sz%s is not %sz	%s and %sz%s or %sz	%s mod %sc                 C   s   | j |d ddiS )Nrv   r   T)r   )r5   r   r	   r	   r   r   k  s    z_UnicodeCompiler.compile_notFc                 C   sv   g }|d D ]D}|d |d kr6| | |d  q| dtt| j|  qd| ||rddpfd|d|f S )Nrv   r   z%s..%sz
%s%s %s %sz notr
   r   )r4   rH   r   r   r   )r5   r   r9   rr   r   rangesr   r	   r	   r   r   n  s     
 z!_UnicodeCompiler.compile_relationN)F)r@   rU   rV   rW   r   r   r   r   r   r   r   r   r	   r	   r	   r   rG   ^  s   rG   )N)N)&rW   reZbabel._compatr   r/   r]   r&   objectr'   r`   rS   ro   re   rf   rg   	Exceptionr{   r   rH   UNICODEformatr   r   r   r   r   r   r   r   r2   r   r   r   r   rh   rm   r\   rG   r	   r	   r	   r   <module>   sL   	8](



{