3
d#                 @   s*  d 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lZdd	lmZmZmZmZmZmZmZmZmZmZ d
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/d0d1d2hZd3d4d5d6d7d8d9d:hZd$d)d;hZd<d=d>d?d@dAhZeeB eB eB eB ZdBZdCjeZ dDZ!dEje e!dFZ"dGje dHZ#dIje edJZ$dKje#dLZ%dMje"dHZ&dNjee%dOZ'dPje"e'dQZ(dRje%dSZ)dTje%dSZ*dUje%dSZ+dVje"e%e(dWZ,dXje"e%dYZ-dZje"e%dYZ.d[je%dSZ/d\je"dHZ0d]je-Z1d^je%dSZ2d_je.e"e!e e&d`Z3daje.e"e&dbZ4dcje.e"e'ddZ5deje.e"dfZ6dgje e"dhZ7dcje.e"e'ddZ8ej9dije"dHej:Z;ej9djje edJej:Z<ej9dkje"dHej:Z=ej9dlje"e'dQej>Z?ej9e Z@ej9dmje"ZAej9dnje"ZBej9doje/ej>ZCdpZDdqZEdZFdrZGdsZHdtZIduZJdvZKdwZLdxZMdyZNdzZOd{ZPd|ZQeeQd}eRee	jS ee	jT eUejVd~ddZWddddZXee	jT eeReeRe	jYf f dddZZdeRe[eRdddZ\eReRdddZ]G dd dZ^G dd de^Z_G dd dZ`G dd dZaeadjbeFeJB dZceadjbeFeJB dZdeadjbeFeJB eIB dZeeadjbeFeJB eKB dZfeadjbeFeJB dZgeadjbeFeJB dZheadjbeFeJB dZieadjbeFeJB dZjeadjbeFeJB eOB dZkeadjbeFdZleadjbeFeJB dZmeadjbeFeJB dZneadjbeFeMB eJB dZoeadjbeFeNB eJB dZpdS )zCSS selector parser.    N)	lru_cache   )util)	css_match)	css_types)SelectorSyntaxError)
OptionalDictMatchTupleTypeAnyListUnionIteratorcasti  z	: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:-soup-containsz:-soup-contains-ownz: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})*)
)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	\#{ident})r   z	\.{ident}z6(?P<tag_ns>(?:{ident}|\*)?\|)?(?P<tag_name>{ident}|\*)zD
\[{ws}*(?P<attr_ns>(?:{ident}|\*)?\|)?(?P<attr_name>{ident}){attr}
)r   r   attrz$(?P<name>:{ident})(?P<open>\({ws}*)?)r   r   z#(?P<name>:{ident})(?P<open>\({ws}*)z(?P<name>:(?=--){ident})z{ws}*\)z:{}z	@P{ident}z}
(?P<pseudo_nth_child>{name}
(?P<nth_child>{nth}|even|odd))(?:{wsc}*\)|(?P<of>{comments}*{ws}{wsc}*of{comments}*{ws}{wsc}*))
)namewscr   r   nthzA
(?P<pseudo_nth_type>{name}
(?P<nth_type>{nth}|even|odd)){ws}*\)
)r   r   r   z7{name}(?P<values>{value}(?:{ws}*,{ws}*{value})*){ws}*\))r   r   r   z{name}(?P<dir>ltr|rtl){ws}*\))r   r   z0{wsc}*?(?P<relation>[,+>~]|{ws}(?![,+>~])){wsc}*)r   r   z0(?:(\\[a-f0-9]{{1,6}}{ws}?)|(\\[^\r\n\f])|(\\$))z9(?:(\\[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   i   i  )maxsize)pattern
namespacescustomflagsreturnc             C   s(   t |}tj| t| ||dj |||S )zCached CSS compile.)r)   r*   )process_customcm	SoupSieve	CSSParserprocess_selectors)r'   r(   r)   r*   custom_selectors r2   9/tmp/pip-build-8z3xcdsh/soupsieve/soupsieve/css_parser.py_cached_css_compile   s    	
r4   )r+   c               C   s   t j  dS )zPurge the cache.N)r4   cache_clearr2   r2   r2   r3   _purge_cache   s    r6   )r)   r+   c             C   sn   i }| dk	rjx\| j  D ]P\}}tj|}tj|dkrDtdj|||krZtdj|||t|< 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css_unescape)r)   r1   keyr   r   r2   r2   r3   r,      s    
r,   F)contentstringr+   c             C   s(   t t tddd}|stntj|| S )zs
    Unescape CSS value.

    Strings allow for spanning the value on multiple strings by escaping a new line.
    )mr+   c             S   sn   | j dr8t| j ddd d}|dkr.t}t|}n2| j drV| j ddd }n| j drfd}nd}|S )	z(Replace with the appropriate substitute.r   Nr!   r   r      u   � )groupintUNICODE_REPLACEMENT_CHARchr)rA   	codepointr   r2   r2   r3   replace  s    



zcss_unescape.<locals>.replace)r
   str
RE_CSS_ESCRE_CSS_STR_ESCsub)r?   r@   rI   r2   r2   r3   r=      s    r=   )r   r+   c             C   s  g }t | }|dko| d dk}|dkr@|r@|jdj|  nFxBt| D ]4\}}t|}|dkrr|jd qLd|  kodkn  s|dkr|jdj| qL|dks|r|dkrd	|  kod
kn  r|jdj| qL|dksf|dksfd	|  ko
d
kn  sfd	|  ko&d
kn  sfd|  koBdkn  sfd|  ko^dkn  rr|j| qL|jdj| qLW dj|S )zEscape identifier.r   -r   z\{}u   �      z\{:x} 0   9   -   _   r$   A   Z   a   z   rC   )rS   rT   )lenappendr;   	enumerateordjoin)r   r@   lengthZ
start_dashindexcrH   r2   r2   r3   escape  s$     ,0Tra   c               @   sL   e Zd ZdZeeddddZedddZeeeee	e  d	d
dZ
dS )SelectorPatternzSelector pattern.N)r   r'   r+   c             C   s&   || _ tj|tjtjB tjB | _dS )zInitialize.N)r   recompileIXU
re_pattern)selfr   r'   r2   r2   r3   __init__4  s    zSelectorPattern.__init__)r+   c             C   s   | j S )z	Get name.)r   )ri   r2   r2   r3   get_name:  s    zSelectorPattern.get_name)selectorr_   r*   r+   c             C   s   | j j||S )zMatch the selector.)rh   r:   )ri   rl   r_   r*   r2   r2   r3   r:   ?  s    zSelectorPattern.match)__name__
__module____qualname____doc__rJ   rj   rk   rE   r   r
   r:   r2   r2   r2   r3   rb   1  s   rb   c               @   sj   e Zd ZdZeeeeedf eee f df ddddZeddd	Z	ee
e
eee  d
ddZdS )SpecialPseudoPatternzSelector pattern..N)patternsr+   c             C   sp   i | _ xB|D ]:}|d }|d ||d }x|d D ]}|| j |< q4W qW d| _tjttjtjB tjB | _dS )zInitialize.r   rB   r   r   N)	rr   matched_namerc   rd   PAT_PSEUDO_CLASS_SPECIALre   rf   rg   re_pseudo_name)ri   rr   pr   r'   pseudor2   r2   r3   rj   H  s    
zSpecialPseudoPattern.__init__)r+   c             C   s   | j dkrdS | j j S )z	Get name.NrC   )rs   rk   )ri   r2   r2   r3   rk   U  s    zSpecialPseudoPattern.get_name)rl   r_   r*   r+   c             C   sV   d}| j j||}|rRtjt|jd}| jj|}|rR|j|||}|rR|| _|S )zMatch the selector.Nr   )	ru   r:   r   r8   r=   rD   rr   getrs   )ri   rl   r_   r*   rw   rA   r   r'   r2   r2   r3   r:   Z  s    zSpecialPseudoPattern.match)rm   rn   ro   rp   r   rJ   r   rb   rj   rk   rE   r   r
   r:   r2   r2   r2   r3   rq   E  s   0rq   c               @   sb   e Zd ZdZeddddZed  ejdddZ	e
ejejf d	d
dZed	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.
    N)kwargsr+   c             K   s   |j dd| _|j dg | _|j dg | _|j dg | _|j dg | _|j dg | _|j dg | _|j d	d| _|j d
g | _	|j dg | _
|j dd| _|j dd| _dS )zInitialize.tagNidsclasses
attributesr   	selectors	relationsrel_typecontainslangr*   r   no_matchF)rx   r{   r|   r}   r~   r   r   r   r   r   r   r*   r   )ri   rz   r2   r2   r3   rj   s  s    z_Selector.__init__)r   r+   c             C   s<   |r0|d }|j j|dd  tj|j gS tj S dS )zFreeze relation.r   r   N)r   extendctSelectorListfreeze)ri   r   selr2   r2   r3   _freeze_relations  s
    z_Selector._freeze_relations)r+   c             C   sh   | j rtj S tj| jt| jt| jt| jt| j	t| j
| j| j| jt| jt| j| jS dS )zFreeze self.N)r   r   SelectorNullSelectorr{   tupler|   r}   r~   r   r   r   r   r   r   r   r*   )ri   r2   r2   r3   r     s    
z_Selector.freezec             C   s8   dj | 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;   r{   r|   r}   r~   r   r   r   r   r   r   r*   r   )ri   r2   r2   r3   __str__  s    z_Selector.__str__)rm   rn   ro   rp   r   rj   r   r   r   r   r   r   r   r   rJ   r   __repr__r2   r2   r2   r3   ry   j  s   
ry   c               @   s  e Zd ZdZedeeddFeefddGeefd
dHe	efddIe
efddJeeffedeedeedeedeedeedeedeedeedefZdKeeeeeeejf f  eddddZeee e e dd d!Z!eee e e dd"d#Z"eee e e dd$d%Z#eee e e$e%eee f  e e%e e f d&d'd(Z&eee e e$e%eee f  e d)d*d+Z'eee e$e%eee f  ee d,d-d.Z(eee e e)e eee%e eef d/d0d1Z*eee e e)e e)e e e ee%e ef d2	d3d4Z+eee e e dd5d6Z,eee e e dd7d8Z-eee e e dd9d:Z.eee e e dd;d<Z/dLe$e%eee f  eeejd=d>d?Z0ee$e%eee f  d@dAdBZ1dMeeejdCdDdEZ2dS )Nr/   zParse CSS selectors.pseudo_closepseudo_contains	:contains:-soup-contains:-soup-contains-ownpseudo_nth_child
:nth-child:nth-last-childpseudo_nth_type:nth-of-type:nth-last-of-typepseudo_lang:lang
pseudo_dir:dirpseudo_class_custompseudo_classpseudo_elementat_ruleidclassr{   	attributecombineNr   )rl   r)   r*   r+   c             C   s8   |j dd| _|| _| jtj@ | _|dkr.i n|| _dS )zInitialize. u   �N)rI   r'   r*   r   DEBUGdebugr)   )ri   rl   r)   r*   r2   r2   r3   rj     s    zCSSParser.__init__)r   rA   has_selectorr+   c             C   s`  d}|j d}|j dr(tj|j dnd}|j drLt|j ddd nd}t|j d}d}	d}
d}|r|d	kr|tjnd
tjB }n&tj|dkrtjtjB }d}	ntj}|r|j djdrt|j ddd d}nt|j d}|sd}n|jdrtjdtj	| |}n|jdr<tjdtj	| |}n|jdr`tjdtj	| |}n|jdr| st
j|rdntj	|}tjd| |}nJ|jdrtjdtj	| |}n&tjdtj	| |}|jdrd}|	r|rtj|j}
tj||||
}|rLt }|jj| tj|j gdd}|jj| n|jj| d}|S ) z8Create attribute selector from the returned regex match.FcmpcaseNZattr_nsr   rC   	attr_nameir   typeTr   "'^z^%s.*$z.*?%s$*z.*?%s.*~z[^\s\S]z7.*?(?:(?<=^)|(?<=[ \t\r\n\f]))%s(?=(?:[ \t\r\n\f]|$)).*|z^%s(?:-.*)?$z^%s$!)r   r   r   )rD   r   r8   r=   rc   re   DOTALL
startswithrd   ra   RE_WSsearchr'   r   ZSelectorAttributery   r~   rZ   r   r   r   )ri   r   rA   r   Zinverseopr   nsr   Zis_typeZpattern2r   r*   r'   Zsel_attrZsub_selZnot_listr2   r2   r3   parse_attribute_selector  sZ    
$"z"CSSParser.parse_attribute_selectorc             C   sH   |j dr t|j ddd nd}t|j d}tj|||_d}|S )z#Parse tag pattern from regex match.Ztag_nsNr   Ztag_nameTr   )rD   r=   r   SelectorTagr{   )ri   r   rA   r   prefixr{   r2   r2   r3   parse_tag_pattern   s
    $zCSSParser.parse_tag_patternc             C   s   t jt|jd}| jj|}|dkrJtdj||jd| j	|jdt
|tjs| j|= t|| j| jdjtd}|| j|< |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.
        r   Nz3Undefined custom selector '{}' found at position {}r   )r)   r*   )r*   T)r   r8   r=   rD   r)   rx   r   r;   endr'   
isinstancer   r   r/   r*   r0   
FLG_PSEUDOr   rZ   )ri   r   rA   r   rw   rl   r2   r2   r3   parse_pseudo_class_custom)  s     
z#CSSParser.parse_pseudo_class_custom)r   rA   r   	iselectoris_htmlr+   c          	   C   s  d}t jt|jd}|jdr&d}|rN|tkrN| j|||||jd}n| oZ|tkr`|dkrz| 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jt np|dkr|jjt nV|dkr|jjt n<|dkr8|jjt n"|dkrR|jjt n|dkrl|jjt n|dkr|jjt n|dkr|jjt n|dkr|jjt n|dkr|jjt n|dkr|jjt nl|dkr|jjt nR|dkr"|jjt n8|dkrP|jjt	jdddddt	j  n
|dkr||jjt	jdddddt	j  n|dkr|jjt	jdddddt	j  n|dkr|jjt	jdddddt	j  n|dkr|jj t	jdddddt	j t	jdddddt	j g nB|dkrZ|jj t	jdddddt	j t	jdddddt	j g d}n|r|t!kr| j"||jdt#t$B  d|_%d}nR| r|t&krd|_%d}n4|t'krt(dj)|| j*|j+dnt,d j)|||fS )"zParse pseudo class.Fr   openTr   z:rootz:definedz:scopez:empty:link	: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   )-r   r8   r=   rD   PSEUDO_COMPLEXparse_pseudo_openr   PSEUDO_SIMPLEr*   r   ZSEL_ROOTZSEL_DEFINEDZ	SEL_SCOPEZ	SEL_EMPTYr   rZ   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   r   PSEUDO_COMPLEX_NO_MATCHparse_selectorsr   FLG_OPENr   PSEUDO_SIMPLE_NO_MATCHPSEUDO_SUPPORTEDr   r;   r'   startNotImplementedError)ri   r   rA   r   r   r   Zcomplex_pseudorw   r2   r2   r3   parse_pseudo_classE  s    














$
"
"
"


zCSSParser.parse_pseudo_class)r   rA   r   r   r+   c             C   s.  |j  }|jdrd}nd}tjt|d |d< tj|jd| }|dkr\d}d}	d	}
n|d
krrd}d}	d	}
nttt tj	|}|j
dr|j
ddkrdnd}|j
d}|jd}
|jdr|d7 }n|
r||dd 7 }n||7 }|j
dr|j
ddkrdnd}|j
dr,||j
d7 }nd}t|d}t|d}	|d }|dkr|j
dr|| j||jdttB }nt}|dkr|jjtj||
|	dd| n&|dkr&|jjtj||
|	dd	| nV|dkr|jjtj||
|	d	dtj  n*|dkr&|jjtj||
|	d	d	tj  d	}|S )zParse `nth` pseudo.r   Z_child_typer   r   Zevenr   r   TZoddr   s1rN   rC   an1Ns2b0
   Zofz
:nth-childFz:nth-last-childz:nth-of-typez:nth-last-of-typer   )	groupdictrx   r   r8   r=   r   r
   rJ   RE_NTHr:   rD   endswithr   rE   r   r   r   r   CSS_NTH_OF_S_DEFAULTr   rZ   r   r   r   )ri   r   rA   r   r   ZmdictZpostfixr?   r   r   varZ	nth_partsZ_s1r   Z_s2Z
pseudo_selZnth_selr2   r2   r3   parse_pseudo_nth  sX    	
 



$





"
 zCSSParser.parse_pseudo_nth)r   r   r   r   r_   r+   c             C   s^   t tB }|dkr|tO }n&|dkr0|ttB O }n|dkr@|tO }|jj| j||| d}|S )z"Parse pseudo with opening bracket.z:notz:has:where:isT)r   r   )r   r   FLG_NOTFLG_RELATIVEFLG_FORGIVEr   rZ   r   )ri   r   r   r   r   r_   r*   r2   r2   r3   r     s    

zCSSParser.parse_pseudo_open)r   rA   r   r   r   r_   r+   c             C   s   |j dj }|st}|tkrT|s(d|_||_|d jj| dt }|jt  nH|rp||_|d	 jj| n$|dd tkrt	dj
|| j|d| }t }d}|||fS )
zParse combinator tokens.relationTr   :Nz'The multiple combinators at position {}Fr   r   )rD   stripWS_COMBINATORCOMMA_COMBINATORr   r   r   rZ   ry   r   r;   r'   )ri   r   rA   r   r   r   r_   
combinatorr2   r2   r3   parse_has_combinator  s,    zCSSParser.parse_has_combinator)	r   rA   r   r   r   	is_pseudo
is_forgiver_   r+   c	       
      C   s   |j dj }	|	st}	|sb| s(|	tkr>tdj|	|| j||	tkrd|_|dd= |j| nl|	tkr|j	 r| rt
jdd|_	|jj| |j| |dd= n&|jj| |	|_|dd= |j| t }d}||fS )zParse combinator tokens.r   zBThe combinator '{}' at position {}, must have a selector before itTNr   F)rD   r   r   r   r   r;   r'   r   rZ   r{   r   r   r   r   r   ry   )
ri   r   rA   r   r   r   r   r  r_   r   r2   r2   r3   parse_combinator,  s4    




zCSSParser.parse_combinatorc             C   sN   |j d}|jdr.|jjt|dd  n|jjt|dd  d}|S )zParse HTML classes and ids.r   .r   NT)rD   r   r}   rZ   r=   r|   )ri   r   rA   r   rl   r2   r2   r3   parse_class_id\  s    

zCSSParser.parse_class_idc       
      C   s   t jt|jd}|dkr(tjdt |dk}t|jd}g }xXtj|D ]J}|jdr^qN|jd}	|	j	drt|	d
d d}	nt|	}	|j
|	 qNW |jj
tj|| d}|S )zParse contains.r   z	:containsz\The pseudo class ':contains' is deprecated, ':-soup-contains' should be used moving forward.z:-soup-contains-ownvaluessplitr   r   r   r   T)r   r   r   )r   r8   r=   rD   warningswarnFutureWarning	RE_VALUESfinditerr   rZ   r   r   ZSelectorContains)
ri   r   rA   r   rw   Zcontains_ownr  rr   tokenr   r2   r2   r3   parse_pseudo_containsg  s&    


zCSSParser.parse_pseudo_containsc             C   s   |j d}g }xXtj|D ]J}|j dr*q|j d}|jdrRt|dd	 d}nt|}|j| qW |jjtj| d}|S )
zParse pseudo language.r  r  r   r   r   r   T)r   r   r   )	rD   r
  r  r   r=   rZ   r   r   ZSelectorLang)ri   r   rA   r   r  rr   r  r   r2   r2   r3   parse_pseudo_lang  s    



zCSSParser.parse_pseudo_langc             C   s6   t j|jddkrtjntj}| j|O  _d}|S )zParse pseudo direction.dirZltrT)r   r8   rD   r   ZSEL_DIR_LTRZSEL_DIR_RTLr*   )ri   r   rA   r   r   r2   r2   r3   parse_pseudo_dir  s     zCSSParser.parse_pseudo_dir)r   r_   r*   r+   c             C   s8  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@ }t|t@ }t|t@ }| jr6|rtd |
rtd |rtd |rtd |rtd |rtd |rtd	 |rtd
 |rtd |r(td |r6td |rH|jt   yFx>t|\}}|dkr~tdj|jdn |dkr| j|||}n|dkr| j|||||\}}n|dkrtdj|jdn|dkr| j|||}n|d+kr| j||||}nd|dkr6| j|||}nH|dkrV| j|||}d}n(|dkr|s|stdj|jd| j|jdd|_|
rd}P n tdj|jd| j|jdn|dkr|r| j|||||	|\}}}	n| j||||||||\}}nr|dkr&| j |||}nX|d krf|rVtd!j|jd| j|jd| j!|||}n|d,kr~| j"|||}|j#d}qPW W n t$k
r   Y nX |
r| rtd$j|| j||r0|j% r| rt&j'd%d&|_%|r|	|_(|d- j)j| n |j)j*| |d&d&= |j| n||r|r~|r|d. j(d&kr|	d(kr|	|_(d|_|d/ j)j| d}n.| s| rd|_|d&d&= |j| d}|stdj|| j||rt&j+|d0 _,|rt&j-|d1 _,|rt&j.|d2 _,|rt&j/|d3 _,|r t&j0|d4 _,t&j1d)d* |D ||S )5z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: Truez    is_placeholder_shown: Truez    is_forgive: Truer   zAt-rules found at position {}r   r   r   r   z#Pseudo-element found at position {}r   r   r   r   r   Tr   z"Expected a selector at position {}z+Unmatched pseudo-class close at position {}r   r   r{   z5Tag name found at position {} instead of at the startr   r   z$Unclosed pseudo-class at position {}r   Nr   z: c             S   s   g | ]}|j  qS r2   )r   ).0sr2   r2   r3   
<listcomp>Y  s    z-CSSParser.parse_selectors.<locals>.<listcomp>)r   r   )r   r   r   r   r   r   r   r   r   r   )2ry   r   boolr   r   r   r   FLG_HTMLFLG_DEFAULTFLG_INDETERMINATEFLG_IN_RANGEFLG_OUT_OF_RANGEFLG_PLACEHOLDER_SHOWNr   r   printrZ   nextr   r;   r   r   r   r  r   r  r  r   r'   r   r   r  r   r   r  r   StopIterationr{   r   r   r   r   r   ZSEL_DEFAULTr*   ZSEL_INDETERMINATEZSEL_IN_RANGEZSEL_OUT_OF_RANGEZSEL_PLACEHOLDER_SHOWNr   )ri   r   r_   r*   r   r   r   closedr   r   Zis_openr   Zis_relativeis_notr   Z
is_defaultZis_indeterminateZis_in_rangeZis_out_of_rangeZis_placeholder_shownr  r>   rA   r2   r2   r3   r     s   	













 

zCSSParser.parse_selectors)r'   r+   c       	      c   sf  t j|}|r|jdnd}tj|}|r8|jdd n
t|d }| jrXtdj| x||krPd}xd| j	D ]Z}|j
||| j}|rp|j }| jrtdj||jd|jd |jd}||fV  P qpW |dkrZ|| }|dkrdj|}nN|dkrd	j|}n8|d
krdj|}n"|dkr4dj|}ndj||}t|| j|qZW | jrbtd dS )zIterate selector tokens.r   r   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   rY   r   r  r;   
css_tokensr:   r*   rk   rD   r   r'   )	ri   r'   rA   r_   r   vr   r`   msgr2   r2   r3   selector_iter[  s>    






zCSSParser.selector_iter)r_   r*   r+   c             C   s   | j | j| j||S )zProcess selectors.)r   r'  r'   )ri   r_   r*   r2   r2   r3   r0     s    zCSSParser.process_selectors)r   r   r   )r   r   )r   r   )r   )r   )Nr   )r   r   )r   r   )3rm   rn   ro   rp   rb   PAT_PSEUDO_CLOSErq   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_ATTRPAT_COMBINEr$  rJ   r   r	   r   r   r   rE   rj   ry   r
   r  r   r   r   r   r   r   r   r   r   r   r  r  r  r  r  r   r'  r0   r2   r2   r2   r3   r/     s   


 F	Z=*&  : )r/   zhtml|*:is(a, area)[href])r*   z\
    html|*:is(input[type=checkbox], input[type=radio])[checked], html|option[selected]
    z
    :checked,

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

    /*
    This pattern must be at the end.
    Special logic is applied to the last selector.
    */
    html|input[type="radio"][name]:not([name='']):not([checked])
    a  
    html|*:is(input:not([type=hidden]), button, select, textarea, fieldset, optgroup, option, fieldset)[disabled],
    html|optgroup[disabled] > html|option,
    html|fieldset[disabled] > html|*:is(input:not([type=hidden]), button, select, textarea, fieldset),
    html|fieldset[disabled] >
        html|*:not(legend:nth-of-type(1)) html|*:is(input:not([type=hidden]), button, select, textarea, fieldset)
    z|
    html|*:is(input:not([type=hidden]), button, select, textarea, fieldset, optgroup, option, fieldset):not(:disabled)
    z,html|*:is(input, textarea, select)[required]z2html|*:is(input, textarea, select):not([required])aW  
    html|input:is(
        :not([type]),
        [type=""],
        [type=text],
        [type=search],
        [type=url],
        [type=tel],
        [type=email],
        [type=password],
        [type=number]
    )[placeholder]:not([placeholder='']):is(:not([value]), [value=""]),
    html|textarea[placeholder]:not([placeholder=''])
    z*|*a  
    html|*: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),
    html|*:is([contenteditable=""], [contenteditable="true" i])
    z!
    html|*:not(:read-write)
    z
    html|input:is(
        [type="date"],
        [type="month"],
        [type="week"],
        [type="time"],
        [type="datetime-local"],
        [type="number"],
        [type="range"]
    ):is(
        [min],
        [max]
    )
    )F)qrp   rc   	functoolsr   rC   r   r   r-   r   r   r   r  typingr   r	   r
   r   r   r   r   r   r   r   rF   r   r   r   r   ZPSEUDO_SPECIALr   NEWLINEr;   ZWSZCOMMENTSZWSCZCSS_ESCAPESZCSS_STRING_ESCAPES
IDENTIFIERZNTHZVALUEZATTRr2  r3  r4  r5  r/  rt   r.  r(  r0  r1  r*  r+  r,  r-  r6  r)  rd   re   rK   rL   r   rf   r
  r   r"  r#  r9   r   r   r   r   r   r  r  r  r   r  r  r  r   	_MAXCACHErJ   Z
NamespacesZCustomSelectorsrE   r.   r4   r6   r   r,   r  r=   ra   rb   rq   ry   r/   r0   r   r   r   r   r   r   r   r   r   r   r   r   r   r   r2   r2   r2   r3   <module>   sj  0



(%E     d	