B
    Ésˆ\"§  ã               @   s¨  d Z ddlmZ ddlZddlmZ ddlmZ ddlmZ	 ddl
mZ dd	lmZ d
dddddddddddddddddddddd d!hZd"d#d$d%d&d'd(d)d*d+d,d-d.d/d0d1hZd2d3d4d5d6d7hZd#d(d8hZd9d:d;d<d=d>hZeeB eB eB eB Zd?Zd@ e¡ZdAZdBjeedCZdDjedEZdFjeedGZdHjedIZdJjedEZdKjeedLZdMjeedNZdOjedIZdMjeedNZdPjedQZ dRjedQZ!dSjedQZ"dTjeeedUZ#dVjeeedUZ$dWjeedXZ%dYjedQZ&dZjedEZ'd[ e%¡Z(d\jedQZ)d]jeeeed^Z*d_jeed`Z+dajeedNZ,dbjedEZ-dcjeeddZ.dejeedNZ/e 0dfjedEej1¡Z2e 0dgjeedGej1¡Z3e 0dhjedEej1¡Z4e 0dijeedNej5¡Z6e 0e¡Z7e 0dj e¡¡Z8e 0dk e¡¡Z9e 0dl e&¡ej5¡Z:dmZ;dnZ<dZ=doZ>dpZ?dqZ@drZAdsZBdtZCduZDdvZEdwZFejGeFdxdydz„ ƒZHd{d|„ ZId}d~„ ZJd˜d€d„ZKG d‚dƒ„ dƒeLƒZMG d„d…„ d…eMƒZNG d†d‡„ d‡eLƒZOG dˆd‰„ d‰eLƒZPePdŠƒjQe=eAB d‹ZRePdŒƒjQe=eAB d‹ZSePdƒjQe=eAB e@B d‹ZTePdŽƒjQe=eAB eBB d‹ZUePdƒjQe=eAB d‹ZVePdƒjQe=eAB d‹ZWePd‘ƒjQe=eAB d‹ZXePd’ƒjQe=eAB d‹ZYePd“ƒjQe=eAB d‹ZZePd”ƒjQe=d‹Z[ePd•ƒjQe=eAB d‹Z\ePd–ƒjQe=eAB d‹Z]ePd—ƒjQe=eDB eAB d‹Z^ePd—ƒjQe=eEB eAB d‹Z_dS )™zCSS selector parser.é    )Úunicode_literalsNé   )Úutil)Ú	css_match)Ú	css_types)ÚOrderedDict)ÚSelectorSyntaxErrorz	:any-linkz:emptyz:first-childz:first-of-typez	:in-rangez:out-of-rangez:last-childz:last-of-typez:linkz:only-childz:only-of-typez:rootz:checkedz:defaultz	:disabledz:enabledz:indeterminatez	:optionalz:placeholder-shownz
:read-onlyz:read-writez	:requiredz:scopez:definedz:activez:currentz:focusz:focus-visiblez:focus-withinz:futurez:hostz:hoverz:local-linkz:pastz:pausedz:playingz:targetz:target-withinz:user-invalidz:visitedz	:containsz:hasz:isz:matchesz:notz:wherez:host-contextz:dirz:langz
:nth-childz:nth-last-childz:nth-last-of-typez:nth-of-typez(?:\r\n|(?!\r\n)[\n\f\r])z(?:[ \t]|{})z"(?:/\*[^*]*\*+(?:[^/*][^*]*\*+)*/)z(?:{ws}|{comments}))ÚwsÚcommentsz&(?:\\[a-f0-9]{{1,6}}{ws}?|\\[^\r\n\f]))r	   z-(?:\\[a-f0-9]{{1,6}}{ws}?|\\[^\r\n\f]|\\{nl}))r	   Únlz„
(?:(?:-?(?:[^\x00-\x2f\x30-\x40\x5B-\x5E\x60\x7B-\x9f]|{esc})+|--)
(?:[^\x00-\x2c\x2e\x2f\x3A-\x40\x5B-\x5E\x60\x7B-\x9f]|{esc})*)
)Zescz>(?:[-+])?(?:[0-9]+n?|n)(?:(?<=n){ws}*(?:[-+]){ws}*(?:[0-9]+))?zT
(?:"(?:\\(?:.|{nl})|[^\\"\r\n\f]+)*?"|'(?:\\(?:.|{nl})|[^\\'\r\n\f]+)*?'|{ident}+)
)r   ÚidentzU
(?:{ws}*(?P<cmp>[!~^|*$]?=){ws}*(?P<value>{value})(?:{ws}+(?P<case>[is]))?)?{ws}*\]
)r	   Úvaluez&(?:(?:{esc}|(?!/\*)[^"\] \t\r\n\f])+?)z	\#{ident})r   z	\.{ident}z$(?:(?:{ident}|\*)?\|)?(?:{ident}|\*)z7\[{ws}*(?P<ns_attr>(?:(?:{ident}|\*)?\|)?{ident}){attr})r	   r   Úattrz9
\[{ws}*(?P<ns_attr>(?:(?:{ident}|\*)?\|)?{ident}){attr}
z$(?P<name>:{ident})(?P<open>\({ws}*)?)r	   r   z(?P<name>:(?=--){ident})z{ws}*\)z:{}z	@P{ident}z’
(?P<pseudo_nth_child>:nth-(?:last-)?child
\({ws}*(?P<nth_child>{nth}|even|odd))(?:{wsc}*\)|(?P<of>{comments}*{ws}{wsc}*of{comments}*{ws}{wsc}*))
)Úwscr
   r	   ÚnthzX
(?P<pseudo_nth_type>:nth-(?:last-)?of-type
\({ws}*(?P<nth_type>{nth}|even|odd)){ws}*\)
)r	   r   z;:lang\({ws}*(?P<lang>{value}(?:{ws}*,{ws}*{value})*){ws}*\)z":dir\({ws}*(?P<dir>ltr|rtl){ws}*\)z0{wsc}*?(?P<relation>[,+>~]|{ws}(?![,+>~])){wsc}*)r	   r   z):contains\({ws}*(?P<value>{value}){ws}*\)z*(?:(\\[a-f0-9]{{1,6}}{ws}?)|(\\[^\r\n\f]))z3(?:(\\[a-f0-9]{{1,6}}{ws}?)|(\\[^\r\n\f])|(\\{nl}))zL(?P<s1>[-+])?(?P<a>[0-9]+n?|n)(?:(?<=n){ws}*(?P<s2>[-+]){ws}*(?P<b>[0-9]+))?z-(?:(?P<value>{value})|(?P<split>{ws}*,{ws}*))z^{}*z{}*$z^{}$ú,ú é   é   é   é   é    é@   é€   é   iô  )Úmaxsizec             C   s(   t |ƒ}t | t| ||d ¡ |||¡S )zCached CSS compile.)ÚcustomÚflags)Úprocess_customÚcmZ	SoupSieveÚ	CSSParserÚprocess_selectors)ÚpatternZ
namespacesr   r   Úcustom_selectors© r$   ú3lib/python3.7/site-packages/soupsieve/css_parser.pyÚ_cached_css_compileÆ   s    r&   c               C   s   t  ¡  dS )zPurge the cache.N)r&   Úcache_clearr$   r$   r$   r%   Ú_purge_cacheÔ   s    r(   c             C   sj   i }| dk	rfxX|   ¡ D ]L\}}t |¡}t |¡dkrDtd |¡ƒ‚||krZtd |¡ƒ‚|||< qW |S )zProcess custom.Nz5The name '{}' is not a valid custom pseudo-class namez4The custom selector '{}' has already been registered)Úitemsr   ÚlowerÚ	RE_CUSTOMÚmatchr   ÚformatÚKeyError)r   r#   Úkeyr   Únamer$   r$   r%   r   Ú   s    
r   Fc             C   s,   dd„ }dd„ }|s t  || ¡S t || ¡S )zs
    Unescape CSS value.

    Strings allow for spanning the value on multiple strings by escaping a new line.
    c             S   s:   |   d¡r(t t|   d¡dd… dƒ¡S |   d¡dd… S )z(Replace with the appropriate substitute.r   Nr   r   )Úgroupr   ÚuchrÚint)Úmr$   r$   r%   Úreplaceð   s    zcss_unescape.<locals>.replacec             S   sP   |   d¡r*t t|   d¡dd… dƒ¡}n"|   d¡rH|   d¡dd… }nd}|S )z5Replace with the appropriate substitute for a string.r   Nr   r   Ú )r1   r   r2   r3   )r4   r   r$   r$   r%   Úreplace_stringõ   s    
 
z$css_unescape.<locals>.replace_string)Ú
RE_CSS_ESCÚsubÚRE_CSS_STR_ESC)ÚcontentÚstringr5   r7   r$   r$   r%   Úcss_unescapeé   s    r=   c               @   s    e Zd ZdZdd„ Zdd„ ZdS )ÚSelectorPatternzSelector pattern.c             C   s    t  |t jt jB t jB ¡| _dS )zInitialize.N)ÚreÚcompileÚIÚXÚUr"   )Úselfr"   r$   r$   r%   Ú__init__  s    zSelectorPattern.__init__c             C   s   dS )zEnabled.Tr$   )rD   r   r$   r$   r%   Úenabled  s    zSelectorPattern.enabledN)Ú__name__Ú
__module__Ú__qualname__Ú__doc__rE   rF   r$   r$   r$   r%   r>     s   r>   c               @   s   e Zd ZdZdd„ ZdS )ÚQuirkPatternz Selector pattern for quirk mode.c             C   s
   |t j@ S )z"Enabled if quirks flag is present.)r   Ú_QUIRKS)rD   r   r$   r$   r%   rF     s    zQuirkPattern.enabledN)rG   rH   rI   rJ   rF   r$   r$   r$   r%   rK     s   rK   c               @   s4   e Zd ZdZdd„ Zdd„ Zdd„ Zdd	„ ZeZd
S )Ú	_Selectorzý
    Intermediate selector class.

    This stores selector data for a compound selector as we are acquiring them.
    Once we are done collecting the data for a compound selector, we freeze
    the data in an object that can be pickled and hashed.
    c             K   s¬   |  dd¡| _|  dg ¡| _|  dg ¡| _|  dg ¡| _|  dg ¡| _|  dg ¡| _|  dg ¡| _|  d	d¡| _|  d
g ¡| _	|  dg ¡| _
|  dd¡| _|  dd¡| _dS )zInitialize.ÚtagNÚidsÚclassesÚ
attributesr   Ú	selectorsÚ	relationsÚrel_typeÚcontainsÚlangr   r   Úno_matchF)ÚgetrN   rO   rP   rQ   r   rR   rS   rT   rU   rV   r   rW   )rD   Úkwargsr$   r$   r%   rE   $  s    z_Selector.__init__c             C   s<   |r0|d }|j  |dd… ¡ t | ¡ g¡S t ¡ S dS )zFreeze relation.r   r   N)rS   ÚextendÚctÚSelectorListÚfreeze)rD   rS   Úselr$   r$   r%   Ú_freeze_relations4  s
    z_Selector._freeze_relationsc             C   sh   | j rt ¡ S t | jt| jƒt| jƒt| jƒt| j	ƒt| j
ƒ|  | j¡| jt| jƒt| jƒ| j¡S dS )zFreeze self.N)rW   r[   ZSelectorNullZSelectorrN   ÚtuplerO   rP   rQ   r   rR   r_   rS   rT   rU   rV   r   )rD   r$   r$   r%   r]   >  s    
z_Selector.freezec             C   s8   d  | j| j| j| j| j| j| j| j| j	| j
| j| j¡S )zString representation.zª_Selector(tag={!r}, ids={!r}, classes={!r}, attributes={!r}, nth={!r}, selectors={!r}, relations={!r}, rel_type={!r}, contains={!r}, lang={!r}, flags={!r}, no_match={!r}))r-   rN   rO   rP   rQ   r   rR   rS   rT   rU   rV   r   rW   )rD   r$   r$   r%   Ú__str__R  s    z_Selector.__str__N)	rG   rH   rI   rJ   rE   r_   r]   ra   Ú__repr__r$   r$   r$   r%   rM     s   
rM   c               @   s>  e Zd ZdZedeeƒfdeeƒfdeeƒfdee	ƒfdee
ƒfdeeƒfdeeƒfd	eeƒfd
eeƒfdeeƒfdeeƒfdeeƒfdeeƒfdeeƒfdeeƒfdeeƒfgƒZd4d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&d'„ Z!d(d)„ Z"d*d+„ Z#d,d-„ Z$d5d.d/„Z%d0d1„ Z&d6d2d3„Z'dS )7r    zParse CSS selectors.Úpseudo_closeÚpseudo_containsÚpseudo_nth_childÚpseudo_nth_typeÚpseudo_langÚ
pseudo_dirÚpseudo_class_customÚpseudo_classÚpseudo_elementÚat_ruleÚidÚclassrN   Ú	attributeÚquirks_attributeÚcombineNr   c             C   s>   || _ || _| jtj@ | _| jtj@ | _|dkr4i n|| _dS )zInitialize.N)r"   r   r   ÚDEBUGÚdebugrL   Úquirksr   )rD   Úselectorr   r   r$   r$   r%   rE   x  s
    zCSSParser.__init__c             C   s„  d}|  d¡}|  d¡r(t |  d¡¡nd}dd„ |  d¡ d¡D ƒ}d	}	d}
d}t|ƒd
krp|d }	|d
 }n|d }|r|dkrŠtjnd}nt |¡dkrªtj}d}
nd}|rð|  d¡ d¡rà|sàt|  d¡d
d… dƒ}qôt|  d¡ƒ}nd}|sd}n| d¡r&t 	dt 
|¡ |¡}nè| d¡rJt 	dt 
|¡ |¡}nÄ| d¡rnt 	dt 
|¡ |¡}n | d¡r¬|rŒt |¡rdnt 
|¡}t 	d| |¡}nb| d¡rÐt 	dt 
|¡ |¡}n>| d¡røt 	dt 
|¡ |¡}d}nt 	dt 
|¡ |¡}|
r&|r&t 	|j¡}t ||	||¡}|rptƒ }|j |¡ t | ¡ gdd¡}|j |¡ n|j |¡ d}|S )z8Create attribute selector from the returned regex match.FZcmpÚcaseNc             S   s   g | ]}t |ƒ‘qS r$   )r=   )Ú.0Úar$   r$   r%   ú
<listcomp>‡  s    z6CSSParser.parse_attribute_selector.<locals>.<listcomp>Zns_attrú|r6   r   r   ÚiÚtypeTr   )ú"ú'éÿÿÿÿú^z^%s.*ú$z.*?%s$Ú*z.*?%s.*ú~z[^\s\S]z7.*?(?:(?<=^)|(?<=[ \t\r\n\f]))%s(?=(?:[ \t\r\n\f]|$)).*z^%s(?:-.*)?$ú!z^%s$)r1   r   r*   ÚsplitÚlenr?   rA   Ú
startswithr=   r@   ÚescapeÚRE_WSÚsearchr"   r[   ZSelectorAttributerM   rQ   Úappendr\   r]   rR   )rD   r^   r4   Úhas_selectorrt   ZinverseÚoprv   ÚpartsÚnsZis_typeZpattern2r   r   r   r"   Zsel_attrZsub_selZnot_listr$   r$   r%   Úparse_attribute_selector  sd    

 z"CSSParser.parse_attribute_selectorc             C   sZ   dd„ |  d¡ d¡D ƒ}t|ƒdkr8|d }|d }n|d }d}t ||¡|_d}|S )z#Parse tag pattern from regex match.c             S   s   g | ]}t |ƒ‘qS r$   )r=   )rw   Úxr$   r$   r%   ry   Ï  s    z/CSSParser.parse_tag_pattern.<locals>.<listcomp>r   rz   r   NT)r1   r…   r†   r[   ÚSelectorTagrN   )rD   r^   r4   rŒ   rŽ   ÚprefixrN   r$   r$   r%   Úparse_tag_patternÌ  s    
zCSSParser.parse_tag_patternc             C   s”   t  | d¡¡}| j |¡}|dkrFtd || d¡¡| j| d¡ƒ‚t	|t
jƒs€d| j|< t|| j| jdjtd}|| j|< |j |¡ d}|S )zÔ
        Parse custom pseudo class alias.

        Compile custom selectors as we need them. When compiling a custom selector,
        set it to `None` in the dictionary so we can avoid an infinite loop.
        r0   Nz2Undefined custom selector '{}' found at postion {}r   )r   r   )r   T)r   r*   r1   r   rX   r   r-   Úendr"   Ú
isinstancer[   r\   r    r   r!   Ú
FLG_PSEUDOrR   r‹   )rD   r^   r4   rŒ   Úpseudoru   r$   r$   r%   Úparse_pseudo_class_customÚ  s     

z#CSSParser.parse_pseudo_class_customc             C   sæ  d}t  | d¡¡}| d¡r"d}|rJ|tkrJ|  ||||| d¡¡}n”|sZ|tkrZ|dkrv| jtj	O  _nÞ|dkr–| jtj
O  _d}n¾|dkr²| jtjO  _n¢|d	krÎ| jtjO  _n†|d
kræ|j t¡ nn|dkrþ|j t¡ nV|dkr|j t¡ n<|dkr2|j t¡ n"|dkrL|j t¡ n|dkrf|j t¡ nî|dkr€|j t¡ nÔ|dkrš|j t¡ nº|dkr´|j t¡ n |dkrÎ|j t¡ n†|dkrè|j t¡ nl|dkr|j t¡ nR|dkr|j t¡ n8|dkrJ|j t dddddt ¡ ¡¡ n
|dkrv|j t dddddt ¡ ¡¡ nÞ|dkr¢|j t dddddt ¡ ¡¡ n²|dkrÎ|j t dddddt ¡ ¡¡ n†|dkr|j t dddddt ¡ ¡t dddddt ¡ ¡g¡ nB|dkrT|j t dddddt ¡ ¡t dddddt ¡ ¡g¡ d}n„|rŽ|t krŽ|  !|| d¡t"t#B ¡ d|_$d}nP|sª|t%krªd|_$d}n4|t&krÐt'd (|¡| j)| *d¡ƒ‚nt+d (|¡ƒ‚||fS ) zParse pseudo class.Fr0   ÚopenTr   z:rootz:definedz:scopez:empty)z:linkz	:any-linkz:checkedz:defaultz:indeterminatez	:disabledz:enabledz	:requiredz	:optionalz
:read-onlyz:read-writez	:in-rangez:out-of-rangez:placeholder-shownz:first-childr   z:last-childz:first-of-typez:last-of-typez:only-childz:only-of-typez$Invalid syntax for pseudo class '{}'z1'{}' pseudo-class is not implemented at this time),r   r*   r1   ÚPSEUDO_COMPLEXÚparse_pseudo_openr•   ÚPSEUDO_SIMPLEr   r[   ZSEL_ROOTZSEL_DEFINEDÚ	SEL_SCOPEZ	SEL_EMPTYrR   r‹   ÚCSS_LINKÚCSS_CHECKEDÚCSS_DEFAULTÚCSS_INDETERMINATEÚCSS_DISABLEDÚCSS_ENABLEDÚCSS_REQUIREDÚCSS_OPTIONALÚCSS_READ_ONLYÚCSS_READ_WRITEÚCSS_IN_RANGEÚCSS_OUT_OF_RANGEÚCSS_PLACEHOLDER_SHOWNr   ÚSelectorNthr\   rZ   ÚPSEUDO_COMPLEX_NO_MATCHÚparse_selectorsr—   ÚFLG_OPENrW   ÚPSEUDO_SIMPLE_NO_MATCHÚPSEUDO_SUPPORTEDr   r-   r"   ÚstartÚNotImplementedError)rD   r^   r4   rŒ   Ú	iselectorÚis_htmlZcomplex_pseudor˜   r$   r$   r%   Úparse_pseudo_classö  s”    












$
"
"
"


zCSSParser.parse_pseudo_classc             C   s  |  ¡ }| d¡rdnd}| d| ¡}|dkr>d}d}	d}
nØ|d	krTd}d
}	d}
nÂt |¡}| d¡rz| d¡dkrzdnd}| d¡}| d¡}
| d¡r¦|d7 }n|
r¼||dd… 7 }n||7 }| d¡rà| d¡dkràdnd}	| d¡rþ|	| d¡7 }	nd}	t|dƒ}t|	dƒ}	t 	| d| ¡¡}|dkr²| d¡rZ|  
|| d¡ttB ¡}nt}| d¡rˆ|j t ||
|	dd|¡¡ n(| d¡r|j t ||
|	dd|¡¡ nZ| d¡rà|j t ||
|	ddt ¡ ¡¡ n,| d¡r|j t ||
|	ddt ¡ ¡¡ d}|S )zParse `nth` pseudo.re   Z_childZ_typer   Zevenr   r   TZoddr   Ús1ú-r6   rx   ÚnÚ1Nr   Ús2ÚbÚ0é
   Z
pseudo_nthZofz
:nth-childFz:nth-last-childz:nth-of-typez:nth-last-of-type)Ú	groupdictrX   ÚRE_NTHr,   r1   Úendswithr‡   r3   r   r*   r®   r•   r—   r¯   ÚCSS_NTH_OF_S_DEFAULTr   r‹   r[   r¬   r\   )rD   r^   r4   rŒ   r´   ZmdictZpostfixr;   r·   r»   ÚvarZ	nth_partsrx   Z
pseudo_selZnth_selr$   r$   r%   Úparse_pseudo_nthN  sR    
 



 



" zCSSParser.parse_pseudo_nthc             C   sF   t tB }|dkr|tO }|dkr(|tO }|j |  |||¡¡ d}|S )z"Parse pseudo with opening bracket.z:notz:hasT)r—   r¯   ÚFLG_NOTÚFLG_RELATIVErR   r‹   r®   )rD   r^   r0   rŒ   r´   Úindexr   r$   r$   r%   rœ   …  s    zCSSParser.parse_pseudo_openc             C   sÀ   |  d¡ ¡ }|st}|tkrd|s8td ||¡| j|ƒ‚||_|d j 	|¡ dt }| 	t
ƒ ¡ nH|r€||_|d j 	|¡ n$|dd… tkr¤td |¡| j|ƒ‚d| }t
ƒ }d}|||fS )	zParse combinator tokens.ÚrelationzAThe combinator '{}' at postion {}, must have a selector before itr   ú:r   Nz'The multiple combinators at position {}F)r1   ÚstripÚWS_COMBINATORÚCOMMA_COMBINATORr   r-   r"   rT   rS   r‹   rM   )rD   r^   r4   rŒ   rR   rT   rÇ   Ú
combinatorr$   r$   r%   Úparse_has_combinator’  s2    
zCSSParser.parse_has_combinatorc       	      C   sè   |  d¡ ¡ }|st}|sn| jr0|s0|tks0|rFtd ||¡| j|ƒ‚t 	d |¡d| j|¡ | j
tjO  _
|tkr°|jsŽ|sŽt dd¡|_|j |¡ | |¡ |dd…= n&|j |¡ ||_|dd…= | |¡ tƒ }d}||fS )zParse combinator tokens.rÈ   zAThe combinator '{}' at postion {}, must have a selector before itzSYou have attempted to use a combinator without a selector before it at position {}.zathe :scope pseudo class (or another appropriate selector) should be placed before the combinator.r‚   NF)r1   rÊ   rË   rt   rÌ   r   r-   r"   r   Úwarn_quirksr   r[   rž   rN   r’   rS   rZ   r‹   rT   rM   )	rD   r^   r4   rŒ   rR   rS   Ú	is_pseudorÇ   rÍ   r$   r$   r%   Úparse_combinator¼  s8    




zCSSParser.parse_combinatorc             C   sN   |  d¡}| d¡r.|j t|dd… ƒ¡ n|j t|dd… ƒ¡ d}|S )zParse HTML classes and ids.r   Ú.r   NT)r1   r‡   rP   r‹   r=   rO   )rD   r^   r4   rŒ   ru   r$   r$   r%   Úparse_class_idä  s    

zCSSParser.parse_class_idc             C   sD   |  d¡}| d¡r(t|dd… dƒ}nt|ƒ}|j |¡ d}|S )zParse contains.r   )r~   r}   r   r   T)r1   r‡   r=   rU   r‹   )rD   r^   r4   rŒ   r;   r$   r$   r%   Úparse_pseudo_containsï  s    

zCSSParser.parse_pseudo_containsc          
   C   sþ   |  d¡}g }xÔt |¡D ]Æ}|  d¡r*q|  d¡}| d¡rXt|dd… dƒ d¡}nt|ƒ d¡}g }	d}
xP|D ]H}|d	kr|
r|	 d
¡ n$|d	kr´|	 |
r¤dndt |¡ ¡ |
rtd}
qtW | t 	d 
d |	¡¡tj¡¡ qW |j t |¡¡ d}|S )zParse pseudo language.rV   r…   r   )r}   r~   r   r   Tr¸   r‚   z(?!x)[a-z0-9]+?r6   z(-(?!x)[a-z0-9]+)*?\-Fz^{}(?:-.*)?$)r1   ÚRE_LANGÚfinditerr‡   r=   r…   r‹   r?   rˆ   r@   r-   ÚjoinrA   rV   r[   ZSelectorLang)rD   r^   r4   rŒ   rV   ZpatternsÚtokenr   rŽ   Z	new_partsÚfirstÚpartr$   r$   r%   Úparse_pseudo_langû  s,    




$zCSSParser.parse_pseudo_langc             C   s6   t  | d¡¡dkrtjntj}| j|O  _d}|S )zParse pseudo direction.ÚdirZltrT)r   r*   r1   r[   ZSEL_DIR_LTRZSEL_DIR_RTLr   )rD   r^   r4   rŒ   r   r$   r$   r%   Úparse_pseudo_dir  s     zCSSParser.parse_pseudo_dirc          	   C   sš  t ƒ }g }d}d}g }dt }	t|t@ ƒ}
t|t@ ƒ}t|t@ ƒ}t|t@ ƒ}t|t@ ƒ}t|t@ ƒ}t|t	@ ƒ}t|t
@ ƒ}t|t@ ƒ}| jrü|rœtdƒ |
r¨tdƒ |r´tdƒ |rÀtdƒ |rÌtdƒ |rØtdƒ |rätd	ƒ |rðtd
ƒ |rütdƒ |r| t ƒ ¡ y|xtt|ƒ\}}|dkrDtd | d¡¡ƒ‚n6|dkr`|  |||¡}n|dkr„|  |||||¡\}}nö|dkr¦td | d¡¡ƒ‚nÔ|dkrÂ|  |||¡}n¸|dkrà|  ||||¡}nš|dkrü|  |||¡}n~|dkr|  |||¡}d}n^|dkr||sLtd | d¡¡| j| d¡ƒ‚|
rZd}P n td | d¡¡| j| d¡ƒ‚nþ|dkrÄ|r¨|  |||||	|¡\}}}	n|  |||||||¡\}}n¶|dkr"|dk}|r|| d¡ d¡ d }t  d d! |¡ d"| j|¡ |  !||||¡}nX|d#krb|rRtd$ | d¡¡| j| d¡ƒ‚|  "|||¡}n|d%krz|  #|||¡}| $d¡}qW W n t%k
r¢   Y nX |
rÄ|sÄtd& |¡| j|ƒ‚|r&|j&sæ|sæt' (d'd(¡|_&|r|	|_)|d) j* |¡ n |j* +|¡ |d(d(…= | |¡ ntd* |¡| j|ƒ‚|rLt'j,|d) _-|r^t'j.|d) _-|rpt'j/|d) _-|r‚t'j0|d) _-t' 1d+d,„ |D ƒ||¡S )-zParse selectors.FrÉ   z    is_pseudo: Truez    is_open: Truez    is_relative: Truez    is_not: Truez    is_html: Truez    is_default: Truez    is_indeterminate: Truez    is_in_range: Truez    is_out_of_range: Truerl   zAt-rules found at position {}r   ri   rj   rk   z#Psuedo-element found at position {}rd   )rf   re   rg   rh   Trc   z!Expected a selector at postion {}z*Unmatched pseudo-class close at postion {}rq   )ro   rp   rp   ú=r   z'You have attempted to use an attribute z2value that should have been quoted at position {}.z%the attribute value should be quoted.rN   z5Tag name found at position {} instead of at the start)rn   rm   z$Unclosed pseudo-class at position {}r‚   Nr   z"Expected a selector at position {}c             S   s   g | ]}|  ¡ ‘qS r$   )r]   )rw   Úsr$   r$   r%   ry   »  s    z-CSSParser.parse_selectors.<locals>.<listcomp>)2rM   rË   Úboolr¯   r—   rÆ   rÅ   ÚFLG_HTMLÚFLG_DEFAULTÚFLG_INDETERMINATEÚFLG_IN_RANGEÚFLG_OUT_OF_RANGErs   Úprintr‹   Únextr³   r-   r²   r™   r¶   rÔ   rÄ   rÛ   rÝ   r   r"   rÎ   rÑ   r1   Úfindr   rÏ   r   r”   rÓ   r•   ÚStopIterationrN   r[   r’   rT   rS   rZ   ZSEL_DEFAULTr   ZSEL_INDETERMINATEZSEL_IN_RANGEZSEL_OUT_OF_RANGEr\   )rD   r´   rÇ   r   r^   rR   rŒ   ÚclosedrS   rT   Zis_openrÐ   Zis_relativeÚis_notrµ   Z
is_defaultZis_indeterminateZis_in_rangeZis_out_of_ranger/   r4   rt   Z
temp_indexr$   r$   r%   r®      sú    














zCSSParser.parse_selectorsc       	   	   c   s„  t  |¡}|r| d¡nd}t |¡}|r8| d¡d n
t|ƒd }| jrf| jrXtdƒ td 	|¡ƒ x||krnd}xp| j
 ¡ D ]b\}}| | j¡sšq„|j ||¡}|r„| jrÐtd 	|| d¡| d¡¡ƒ | d¡}||fV  P q„W |dkrj|| }|dkrd 	|¡}nN|d	kr&d
 	|¡}n8|dkr<d 	|¡}n"|dkrRd 	|¡}nd 	||¡}t|| j|ƒ‚qjW | jr€tdƒ dS )zIterate selector tokens.r   r   z&## QUIRKS MODE: Throwing out the spec!z## PARSING: {!r}Nz#TOKEN: '{}' --> {!r} at position {}ú[z+Malformed attribute selector at position {}rÒ   z'Malformed class selector at position {}ú#z$Malformed id selector at position {}rÉ   z.Malformed pseudo-class selector at position {}z"Invalid character {!r} position {}z## END PARSING)ÚRE_WS_BEGINrŠ   r•   Ú	RE_WS_ENDr²   r†   rs   rt   ræ   r-   Ú
css_tokensr)   rF   r   r"   r,   r1   r   )	rD   r"   r4   rÇ   r•   ÚkÚvÚcÚmsgr$   r$   r%   Úselector_iter½  sD    







zCSSParser.selector_iterc             C   s   |   |  | j¡||¡S )zÎ
        Process selectors.

        We do our own selectors as BeautifulSoup4 has some annoying quirks,
        and we don't really need to do nth selectors or siblings or
        descendants etc.
        )r®   rõ   r"   )rD   rÇ   r   r$   r$   r%   r!   é  s    	zCSSParser.process_selectors)Nr   )r   r   )r   r   )(rG   rH   rI   rJ   r   r>   ÚPAT_PSEUDO_CLOSEÚPAT_PSEUDO_CONTAINSÚPAT_PSEUDO_NTH_CHILDÚPAT_PSEUDO_NTH_TYPEÚPAT_PSEUDO_LANGÚPAT_PSEUDO_DIRÚPAT_PSEUDO_CLASS_CUSTOMÚPAT_PSEUDO_CLASSÚPAT_PSEUDO_ELEMENTÚPAT_AT_RULEÚPAT_IDÚ	PAT_CLASSÚPAT_TAGÚPAT_ATTRrK   ÚPAT_QUIRKS_ATTRÚPAT_COMBINErð   rE   r   r”   r™   r¶   rÄ   rœ   rÎ   rÑ   rÓ   rÔ   rÛ   rÝ   r®   rõ   r!   r$   r$   r$   r%   r    `  sF   















	KX7*(
 ,r    z:is(a, area, link)[href])r   z^
    :is(input[type=checkbox], input[type=radio])[checked],
    select > option[selected]
    z¥
    :checked,

    /*
    This pattern must be at the end.
    Special logic is applied to the last selector.
    */
    form :is(button, input)[type="submit"]
    a-  
    input[type="checkbox"][indeterminate],
    input[type="radio"]:is(:not([name]), [name=""]):not([checked]),
    progress:not([value]),

    /*
    This pattern must be at the end.
    Special logic is applied to the last selector.
    */
    input[type="radio"][name][name!='']:not([checked])
    aW  
    :is(input[type!=hidden], button, select, textarea, fieldset, optgroup, option, fieldset)[disabled],
    optgroup[disabled] > option,
    fieldset[disabled] > :is(input[type!=hidden], button, select, textarea, fieldset),
    fieldset[disabled] > :not(legend:nth-of-type(1)) :is(input[type!=hidden], button, select, textarea, fieldset)
    zq
    :is(input[type!=hidden], button, select, textarea, fieldset, optgroup, option, fieldset):not(:disabled)
    z&:is(input, textarea, select)[required]z,:is(input, textarea, select):not([required])aF  
    :is(
        input:is(
            :not([type]),
            [type=""],
            [type=text],
            [type=search],
            [type=url],
            [type=tel],
            [type=email],
            [type=password],
            [type=number]
        ),
        textarea
    )[placeholder][placeholder!='']
    z*|*a  
    :is(
        textarea,
        input:is(
            :not([type]),
            [type=""],
            [type=text],
            [type=search],
            [type=url],
            [type=tel],
            [type=email],
            [type=number],
            [type=password],
            [type=date],
            [type=datetime-local],
            [type=month],
            [type=time],
            [type=week]
        )
    ):not([readonly], :disabled),
    :is([contenteditable=""], [contenteditable="true" i])
    z
    :not(:read-write)
    zî
    input:is(
        [type="date"],
        [type="month"],
        [type="week"],
        [type="time"],
        [type="datetime-local"],
        [type="number"],
        [type="range"]
    ):is(
        [min],
        [max]
    )
    )F)`rJ   Z
__future__r   r?   r6   r   r   r   r   r[   Úcollectionsr   r   r   r°   r›   r­   ZPSEUDO_SPECIALr±   ÚNEWLINEr-   ZWSZCOMMENTSZWSCZCSS_ESCAPESZCSS_STRING_ESCAPESZ
IDENTIFIERZNTHZVALUEZATTRZQUIRKS_ATTR_IDENTIFIERZQUIRKS_ATTRr   r  r  r  r  rý   rü   rö   rþ   rÿ   rø   rù   rú   rû   r  r÷   r@   rA   r8   r:   rÀ   rB   rÕ   r‰   rî   rï   r+   rÌ   rË   r—   rÅ   rÆ   râ   rá   rã   r¯   rä   rå   Ú	_MAXCACHEÚ	lru_cacher&   r(   r   r=   Úobjectr>   rK   rM   r    r!   rŸ   r    r¡   r¢   r£   r¤   r¥   r¦   r«   rÂ   r¨   r§   r©   rª   r$   r$   r$   r%   Ú<module>   sP  




	E     	