§
    xÅjr&  ã                   ó*  — d Z ddlmZ ddlmZmZmZmZ ddlm	Z	  e
d¦  «        Z e
d¦  «        ZdZdZdZd	Zd
ededeeeee
f         f         deeeee
f         f         fd„Z eedd¦  «        Z eedd¦  «        Z eedd¦  «        ZdZdZdZdZeeeeedœZi e eee¦  «        gZ eeeef          ed ed edi ¦  «        ¦  «        ¦  «        ¦  «        Zdedee
         fd„Zdedede	fd„Zdedede fd „Z!dedede	fd!„Z"dedede	fd"„Z#d#S )$z2Module contains the score calculation algorithems.é    )Úpartial)ÚDictÚListÚUnionÚcast)ÚSCORE_INDICESz-infÚinfg{®Gázt¿g{®Gáz„¿g      ð?Ú
char_startÚ	char_stopÚ
hash_tableÚreturnc           	      óÈ   ‡— |                      ¦   «         }|                     ˆfd„t          t          | ¦  «        t          |¦  «        dz   ¦  «        D ¦   «         ¦  «         |S )aÀ  Generate index mapping for `bonus` calculation.

    Args:
        char_start: Starting char of the range.
        char_stop: Ending char of the range.
        value: Value to give to the range of char.
        hash_table: Base dictionary to add the mapping.

    Returns:
        A dictionary containing the given range with provided index.

    Examples:
        >>> _char_range_with("a", "d", 1, {})
        {'a': 1, 'b': 1, 'c': 1, 'd': 1}
    c              3   ó:   •K  — | ]}t          |¦  «        ‰fV — Œd S )N)Úchr)Ú.0Úuni_charÚvalues     €ú;C:\Projects\Historical\venv\Lib\site-packages\pfzy/score.pyú	<genexpr>z#_char_range_with.<locals>.<genexpr>"   sB   øè è € ð ð àõ 
ˆX‰Œ˜Ððð ð ð ð ð ó    é   )ÚcopyÚupdateÚrangeÚord)r
   r   r   r   s     ` r   Ú_char_range_withr      su   ø€ ð$ —’Ñ"Ô"€JØ×Òð ð ð ð å�c *™oœo­s°9©~¬~ÀÑ/AÑBÔBðñ ô ñ ô ð ð Ðr   ÚaÚzÚAÚZÚ0Ú9gÍÌÌÌÌÌì?gš™™™™™é?gffffffæ?g333333ã?)ú/ú-Ú_ú ú.r   é   Úhaystackc                 ó¶   — d}g }| D ]Q}|                      t          t                               |d¦  «                                      |d¦  «        ¦  «         |}ŒR|S )a¨  Calculate bonus score for the given haystack.

    The bonus are applied to each char based on the previous char.

    When previous char is within the `BONUS_MAP` then additional bonus
    are applied to the current char due to it might be the start of a new
    word.

    When encountered a mix case character, if the current char is capitalised then
    if the previous char is normal case or within `BONUS_MAP`, additional bounus are applied.

    Args:
        haystack: String to calculate bonus.

    Returns:
        A list of float matching the length of the given haystack
        with each index representing the bonus score to apply.

    Examples:
        >>> _bonus("asdf")
        [0.9, 0, 0, 0]
        >>> _bonus("asdf asdf")
        [0.9, 0, 0, 0, 0, 0.8, 0, 0, 0]
        >>> _bonus("asdf aSdf")
        [0.9, 0, 0, 0, 0, 0.8, 0.7, 0, 0]
        >>> _bonus("asdf/aSdf")
        [0.9, 0, 0, 0, 0, 0.9, 0.7, 0, 0]
    r#   r   )ÚappendÚBONUS_STATESÚBONUS_INDEXÚget)r)   Ú	prev_charÚbonusÚchars       r   Ú_bonusr2   <   s^   € ð: €IØ€EØð ð ˆØ�Š•\¥+§/¢/°$¸Ñ":Ô":Ô;×?Ò?À	È1ÑMÔMÑNÔNÐNØˆ	ˆ	Ø€Lr   Úneedlec                 ó<  ‡— t          | ¦  «        t          |¦  «        c}Št          |¦  «        }|                      ¦   «         r|                     ¦   «         }|dk    s|‰k    r#t          t          t          |¦  «        ¦  «        fS ˆfd„t          |¦  «        D ¦   «         }ˆfd„t          |¦  «        D ¦   «         }t          |¦  «        D ]ú}t          }||dz
  k    rt          nt          }t          ‰¦  «        D ]Ê}	| |         ||	         k    r–t          }
|dk    r|	t          z  ||	         z   }
nK|	dk    rEt          ||dz
           |	dz
           ||	         z   ||dz
           |	dz
           t          z   ¦  «        }
|
||         |	<   t          |
||z   ¦  «        x||         |	<   }Œªt          ||         |	<   ||z   x||         |	<   }ŒËŒû|dz
  ‰dz
  }	}d}d„ t          |¦  «        D ¦   «         }|dk    r–|	dk    r…|s||         |	         ||         |	         k    rZ||         |	         t          k    rC|dk    o1|	dk    o+||         |	         ||dz
           |	dz
           t          z   k    }|	||<   |	dz  }	n|	dz  }	|	dk    °…|dz  }|dk    °–||dz
           ‰dz
           |fS )af  Use fzy logic to calculate score for `needle` within the given `haystack`.

    2 2D array to track the score.
    1. The running score (`running_score`) which represents the best score for the current position.
    2. The result score (`result_score`) which tracks to overall best score that could be for the current positon.

    With every consequtive match, additional bonuse score are given and for every non matching char, a negative
    gap score is applied.

    After the score is calculated, the final matching score will be stored at the last position of the `result_score`.

    Backtrack the result by comparing the 2 2D array to find the corresponding indices.

    Args:
        needle: Substring to find in haystack.
        haystack: String to be searched and scored.

    Returns:
        A tuple of matching score with a list of matching indices.
    r   c                 óB   •— g | ]}d „ t          ‰¦  «        D ¦   «         ‘ŒS )c                 ó   — g | ]}d ‘ŒS ©r   © ©r   r%   s     r   ú
<listcomp>z%_score.<locals>.<listcomp>.<listcomp>ƒ   ó   € Ð(Ð(Ð(ˆqˆÐ(Ð(Ð(r   ©r   ©r   r%   Úhaystack_lens     €r   r:   z_score.<locals>.<listcomp>‚   s=   ø€ ð (ð (ð (Ø-.Ð(Ð(•E˜,Ñ'Ô'Ð(Ñ(Ô(ð(ð (ð (r   c                 óB   •— g | ]}d „ t          ‰¦  «        D ¦   «         ‘ŒS )c                 ó   — g | ]}d ‘ŒS r7   r8   r9   s     r   r:   z%_score.<locals>.<listcomp>.<listcomp>ˆ   r;   r   r<   r=   s     €r   r:   z_score.<locals>.<listcomp>‡   s=   ø€ ð 'ð 'ð 'Ø-.Ð(Ð(•E˜,Ñ'Ô'Ð(Ñ(Ô(ð'ð 'ð 'r   r   Fc                 ó   — g | ]}d ‘ŒS r7   r8   r9   s     r   r:   z_score.<locals>.<listcomp>©   s   € Ð,Ð,Ð,�QˆqÐ,Ð,Ð,r   )Úlenr2   ÚislowerÚlowerÚ	SCORE_MAXÚlistr   Ú	SCORE_MINÚSCORE_GAP_TRAILINGÚSCORE_GAP_INNERÚSCORE_GAP_LEADINGÚmaxÚSCORE_MATCH_CONSECUTIVE)r3   r)   Ú
needle_lenÚbonus_scoreÚrunning_scoreÚresult_scoreÚiÚ
prev_scoreÚ	gap_scoreÚjÚscoreÚmatch_requiredÚindicesr>   s                @r   Ú_scorerX   a   sM  ø€ õ*  # 6™{œ{­C°©M¬MÐ€J�Ý˜Ñ"Ô"€Kð ‡~‚~ÑÔð $Ø—>’>Ñ#Ô#ˆð �Q‚€˜*¨Ò4Ð4Ý�$�u ZÑ0Ô0Ñ1Ô1Ð1Ð1ð(ð (ð (ð (Ý27¸
Ñ2CÔ2Cð(ñ (ô (€Mð
'ð 'ð 'ð 'Ý27¸
Ñ2CÔ2Cð'ñ 'ô '€Lõ �:ÑÔð Ið IˆÝˆ
ð +,¨z¸A©~Ò*=Ð*=Õ&Ð&Å?ˆ	å�|Ñ$Ô$ð 	Ið 	IˆAØ�aŒy˜H QœKÒ'Ð'Ý!�Ø˜’6�6ØÕ 1Ñ1°KÀ´NÑB�E�EØ˜!’V�VÝØ$ Q¨¡UÔ+¨A°©EÔ2°[À´^ÑCà% a¨!¡eÔ,¨Q°©UÔ3Õ6MÑMñô �Eð
 ',�˜aÔ  Ñ#Ý25°e¸ZÈ)Ñ=SÑ2TÔ2TÐT�˜Q” Ñ" Z Zå&/�˜aÔ  Ñ#à2<¸yÑ2HÐH�˜Q” Ñ" Z Zð!	Ið( ˜‰>˜<¨!Ñ+€q€Aà€NØ,Ð,�% 
Ñ+Ô+Ð,Ñ,Ô,€Gà
ˆqŠ&ˆ&Ø�1Šfˆfð ðØ"/°Ô"2°1Ô"5¸Àa¼ÈÔ9KÒ"KÐ"KØ Ô" 1Ô%­Ò2Ð2à˜’Eð MØ˜AšðMà$ Qœ¨Ô*Ø$ Q¨¡UÔ+¨A°©EÔ2Õ5LÑLòMð ð �˜‘
Ø�Q‘�Øà�Q‘�ð' �1Šfˆfð( 	
ˆQ‰ˆð+ ˆqŠ&ˆ&ð. ˜
 Q™Ô'¨°qÑ(8Ô9¸7ÐBÐBr   c                 ó°   — |                       ¦   «         |                      ¦   «         }} | sdS d}| D ]$}|                     ||¦  «        dz   }|dk    r dS Œ%dS )a¢  Check if needle is subsequence of haystack.

    Args:
        needle: Substring to find in haystack.
        haystack: String to be searched and scored.

    Returns:
        Boolean indicating if `needle` is subsequence of `haystack`.

    Examples:
        >>> _subsequence("as", "bbwi")
        False
        >>> _subsequence("as", "bbaiws")
        True
        >>> _subsequence("sa", "bbaiws")
        False
    Tr   r   F)rD   Úfind)r3   r)   Úoffsetr1   s       r   Ú_subsequencer\   Å   sr   € ð$ —|’|‘~”~ x§~¢~Ñ'7Ô'7ˆH€FØð ØˆtØ€FØð ð ˆØ—’˜t VÑ,Ô,¨qÑ0ˆØ�QŠ;ˆ;Ø�5�5ð àˆ4r   c                 óT   — t          | |¦  «        rt          | |¦  «        S t          dfS )aè  Use fzy matching algorithem to match needle against haystack.

    Note:
        The `fzf` unordered search is not supported for performance concern.
        When the provided `needle` is not a subsequence of `haystack` at all,
        then `(-inf, None)` is returned.

    See Also:
        https://github.com/jhawthorn/fzy/blob/master/src/match.c

    Args:
        needle: Substring to find in haystack.
        haystack: String to be searched and scored against.

    Returns:
        A tuple of matching score with a list of matching indices.

    Examples:
        >>> fzy_scorer("ab", "acb")
        (0.89, [0, 2])
        >>> fzy_scorer("ab", "acbabc")
        (0.98, [3, 4])
        >>> fzy_scorer("ab", "wc")
        (-inf, None)
    N)r\   rX   rG   )r3   r)   s     r   Ú
fzy_scorerr^   â   s0   € õ4 �F˜HÑ%Ô%ð Ý�f˜hÑ'Ô'Ð'å˜$ˆÐr   c                 óÈ  — g }d}|                       ¦   «         |                      ¦   «         }} |                      d¦  «        D ]f} | sŒ|                     | |¦  «        }|dk     rt          dfc S t	          | ¦  «        }|                     t          |||z   ¦  «        ¦  «         ||z  }Œg|sd|fS |d         dz   |d         z
   d|d         dz   z  z   d|d         dz   z  z   |fS )aU  Match needle against haystack using :meth:`str.find`.

    Note:
        Scores may be negative but the higher the score, the higher
        the match rank. `-inf` score means no match found.

    See Also:
        https://github.com/aslpavel/sweep.py/blob/3f4a179b708059c12b9e5d76d1eb3c70bf2caadc/sweep.py#L837

    Args:
        needle: Substring to find in haystack.
        haystack: String to be searched and scored against.

    Returns:
        A tuple of matching score with a list of matching indices.

    Example:
        >>> substr_scorer("ab", "awsab")
        (-1.3, [3, 4])
        >>> substr_scorer("ab", "abc")
        (0.5, [0, 1])
        >>> substr_scorer("ab", "iop")
        (-inf, None)
        >>> substr_scorer("ab", "asdafswabc")
        (-1.6388888888888888, [7, 8])
        >>> substr_scorer(" ", "asdf")
        (0, [])
    r   r&   Néÿÿÿÿr   r(   )rD   ÚsplitrZ   rG   rB   Úextendr   )r3   r)   rW   r[   rM   s        r   Úsubstr_scorerrc     s  € ð: €GØ€FØ—|’|‘~”~ x§~¢~Ñ'7Ô'7ˆH€Fà—,’,˜sÑ#Ô#ð ð ˆØð 	ØØ—’˜v vÑ.Ô.ˆØ�AŠ:ˆ:Ý˜d�?Ð"Ð"Ð"Ý˜‘[”[ˆ
Ø�Š•u˜V V¨jÑ%8Ñ9Ô9Ñ:Ô:Ð:Ø�*Ñˆˆàð Ø�'ˆzÐð �"Œ+˜‰/˜G AœJÑ
&Ð'¨!¨w°q¬z¸A©~Ñ*>Ñ>ÀÀgÈbÄkÐTUÁoÑAVÑVØðð r   N)$Ú__doc__Ú	functoolsr   Útypingr   r   r   r   Ú
pfzy.typesr   ÚfloatrG   rE   rJ   rH   rI   rL   ÚstrÚintr   Ú
lower_withÚ
upper_withÚ
digit_withÚSCORE_MATCH_SLASHÚSCORE_MATCH_WORDÚSCORE_MATCH_CAPITALÚSCORE_MATCH_DOTÚ	BONUS_MAPr,   r-   r2   rX   Úboolr\   r^   rc   r8   r   r   ú<module>rt      s‹  ðØ 8Ð 8Ø Ð Ð Ð Ð Ð Ø *Ð *Ð *Ð *Ð *Ð *Ð *Ð *Ð *Ð *Ð *Ð *à $Ð $Ð $Ð $Ð $Ð $àˆE�&‰MŒM€	ØˆE�%‰LŒL€	ØÐ ØÐ Ø€ØÐ ðØðØ #ðØ8<¸SÀ%ÈÈUÈ
ÔBSÐ=SÔ8Tðà	ˆ#ˆu�S˜%�ZÔ Ð
 Ô!ðð ð ð ð4 ˆWÐ% s¨CÑ0Ô0€
ØˆWÐ% s¨CÑ0Ô0€
ØˆWÐ% s¨CÑ0Ô0€
àÐ ØÐ ØÐ Ø€à	Ø	Ø	Ø	Ø	ðð €	ð �I˜z˜zÐ*=¸yÑIÔIÐJ€Øˆd�4˜˜S˜”> : :¨a°°¸A¸z¸zÈ!ÈRÑ?PÔ?PÑ1QÔ1QÑ#RÔ#RÑSÔS€ð"�Sð "˜T %œ[ð "ð "ð "ð "ðJaC�3ð aC #ð aC¨-ð aCð aCð aCð aCðH˜ð ¨ð °ð ð ð ð ð:�sð  cð ¨mð ð ð ð ð@1˜#ð 1¨ð 1°ð 1ð 1ð 1ð 1ð 1ð 1r   