/*<pseudo-selectors>
194363
function(node){
    var child = node.firstChild;
    return !(child && child.nodeType == 1) && !(node.innerText || node.textContent || '').length;
  }
1242620
function selector() {
        whitespace();

        while (css[0] === '}') {
            error('extra closing bracket');
        }

        const m = match(/^(("(?:\\"|[^"])*"|'(?:\\'|[^'])*'|[^{])+)/);

        if (m) {
            return m[0]
                .trim() // remove all comments from selectors
                .replace(/\/\*([^*]|[\r\n]|(\*+([^*/]|[\r\n])))*\*\/+/g, '')
                .replace(/"(?:\\"|[^"])*"|'(?:\\'|[^'])*'/g, function(m) {
                    return m.replace(/,/g, '\u200C');
                })
                .split(/\s*(?![^(]*\)),\s*/)
                .map(function(s) {
                    return s.replace(/\u200C/g, ',');
                });
        }
    }
1339625
function parseClasses( aRules, skipSelectors, validSelectors )
	{
		// aRules are just the different rules in the style sheets
		// We want to merge them and them split them by commas, so we end up with only
		// the selectors
		var s = aRules.join(' ');
		// Remove selectors splitting the elements, leave only the class selector (.)
		s = s.replace( /(,|>|\+|~)/g, ' ' );
		// Remove attribute selectors: table[border="0"]
		s = s.replace( /\[[^\]]*/g, '' );
		// Remove Ids: div#main
		s = s.replace( /#[^\s]*/g, '' );
		// Remove pseudo-selectors and pseudo-elements: :hover :nth-child(2n+1) ::before
		s = s.replace( /\:{1,2}[^\s]*/g, '' );

		s = s.replace( /\s+/g, ' ' );

		var aSelectors = s.split( ' ' ),
			aClasses = [];

		for ( var i = 0; i < aSelectors.length ; i++ )
		{
			var selector = aSelectors[ i ];

			if ( validSelectors.test( selector ) && !skipSelectors.test( selector ) )
			{
				// If we still don't know about this one, add it
				if ( CKEDITOR.tools.indexOf( aClasses, selector ) == -1 )
					aClasses.push( selector );
			}
		}

		return aClasses;
	}
934215
function appendElementSelector (element, selector) {
  const processor = selectorParser((selectors) => {
    let combinatorNode = null

    /**
     * looping breaks if we insert dynamically
     */
    selectors.each((selector) => {
      const elementNode = selectorParser.tag({ value: element.tag })
      selector.walk((node) => {
        if (node.type === 'combinator') { combinatorNode = node }
      })

      if (combinatorNode) {
        selector.insertAfter(combinatorNode, elementNode)
      } else {
        selector.prepend(elementNode)
      }
    })
  })

  return processor.process(selector).result
}
686060
function parseSelector(selector = '') {
  const tagMatch = selector.match(/^[a-zA-Z0-9='"[\]_-]*/g)
  const classNamesMatch = selector.match(/\.[a-zA-Z0-1_-]*/g)

  return {
    tag: tagMatch ? tagMatch[0] : undefined,
    classNames: classNamesMatch ? classNamesMatch.map(cname => cname.substr(1)) : []
  }
}
985227
function(selector) {
        var token = {},     // one token per simple selector (left selector holds combinator)
            tokens = [],    // array of tokens
            id,             // unique id for the simple selector (if found)
            found = false,  // whether or not any matches were found this pass
            patterns = Y.Selector._patterns,
            match;          // the regex match

        selector = Y.Selector._replaceShorthand(selector); // convert ID and CLASS shortcuts to attributes

        /*
            Search for selector patterns, store, and strip them from the selector string
            until no patterns match (invalid selector) or we run out of chars.

            Multiple attributes and pseudos are allowed, in any order.
            for example:
                'form:first-child[type=button]:not(button)[lang|=en]'
        */
        do {
            found = false; // reset after full pass
            for (var re in patterns) {
                if (YAHOO.lang.hasOwnProperty(patterns, re)) {
                    if (re != 'tag' && re != 'combinator') { // only one allowed
                        token[re] = token[re] || [];
                    }
                    if ( (match = patterns[re].exec(selector)) ) { // note assignment
                        found = true;
                        if (re != 'tag' && re != 'combinator') { // only one allowed
                            // capture ID for fast path to element
                            if (re === 'attributes' && match[1] === 'id') {
                                token.id = match[3];
                            }

                            token[re].push(match.slice(1));
                        } else { // single selector (tag, combinator)
                            token[re] = match[1];
                        }
                        selector = selector.replace(match[0], ''); // strip current match from selector
                        if (re === 'combinator' || !selector.length) { // next token or done
                            token.attributes = Y.Selector._fixAttributes(token.attributes);
                            token.pseudos = token.pseudos || [];
                            token.tag = token.tag ? token.tag.toUpperCase() : '*';
                            tokens.push(token);

                            token = { // prep next token
                                previous: token
                            };
                        }
                    }
                }
            }
        } while (found);

        return tokens;
    }
1370834
protected function fetchCssPseudoSelector($pseudo, $parameters = [], &$tagName)
    {
        switch ($pseudo) {
            case 'first-child':
                return 'position() = 1';
                break;
            case 'last-child':
                return 'position() = last()';
                break;
            case 'nth-child':
                $xpath = sprintf(
                    '(name()="%s") and (%s)',
                    $tagName,
                    $this->fetchCssPseudoNthSelector($parameters[ 0 ])
                );
                $tagName = '*';

                return $xpath;
                break;
            case 'contains':
                $string = trim($parameters[ 0 ], ' \'"');
                $caseSensitive = isset($parameters[ 1 ]) and (trim($parameters[ 1 ]) === 'true');

                return $this->fetchCssPseudoContainsSelector($string, $caseSensitive);
                break;
            case 'has':
                return $this->fetchCssExpression($parameters[ 0 ], './/');
                break;
            case 'not':
                return sprintf('not($this->%s)', $this->fetchCssExpression($parameters[ 0 ], ''));
                break;
            case 'nth-of-type':
                return $this->fetchCssPseudoNthSelector($parameters[ 0 ]);
                break;
            case 'empty':
                return 'count(descendant::*) = 0';
                break;
            case 'not-empty':
                return 'count(descendant::*) > 0';
                break;
        }

        throw new RuntimeException('Invalid selector: unknown pseudo-class');
    }
687223
function ( selector ) {
            var node = this.element().previousSibling;
            if ( !node ) return;
    
            //comment, text
            if ( node.nodeType == 8 || node.nodeType == 3 && !$B.string.trim(node.data) ) {
                return $B( node ).prev( selector );
            } else {
                if ( typeof selector === 'string' ) node = $B.selector.match( node, selector )? node : undefined;
                return node;
            }
        }
928221
function processPseudoClass (component, idName, pseudoData) {
  let pseudoId = component.node.getAttribute('data-pseudo-id')

  function getCssText (selector, rulesObj) {
    // TODO: must process vendors if needed.
    // !important is needed since the style rules is inline for most components.
    const rulesText = Object.keys(rulesObj).map(key => `${camelToKebab(key)}:${rulesObj[key]}!important;`).join('')
    return `${selector}{${rulesText}}`
  }

  if (!pseudoId) {
    pseudoId = getPseudoId()
    component.node.setAttribute('data-pseudo-id', pseudoId)
    const style = document.createElement('style')
    style.type = 'text/css'
    style.setAttribute('data-pseudo-id', pseudoId)
    document.getElementsByTagName('head')[0].appendChild(style)
    const cssText = Object.keys(pseudoData).map(pseudo => {
      const rules = pseudoData[pseudo]
      return getCssText(`[data-pseudo-id="${pseudoId}"]${pseudo}`, rules)
    }).join('')
    return style.appendChild(document.createTextNode(cssText))
  }

  const styleSheets = Array.prototype.slice.call(document.styleSheets || [])
    .filter(style => style.ownerNode.getAttribute('data-pseudo-id') === pseudoId)
  if (!styleSheets || styleSheets.length <= 0) {
    return
  }
  const styleSheet = styleSheet[0]
  const rules = styleSheet.cssRules || styleSheet.rules
  Object.keys(pseudoData).forEach(pseudo => {
    const data = pseudoData[pseudo]
    const selector = `[data-pseudo-id="${pseudoId}"]${pseudo}`
    const res = Array.prototype.slice.call(rules).reduce((res, rule, idx) => {
      (rule.selectorText === selector) && (res.idx = idx)
      return res
    }, { idx: -1 })
    const { idx } = res
    if (idx !== -1) {
      const pseudoRule = rules[idx]
      const match = pseudoRule.cssText.match(/^[^{]+\{([^}]+)\}/)
      if (match && match[1]) {
        const rulesData = match[1].split(';').reduce((res, str) => {
          const match = str.match(/(\S+)\s*:\s*(\S+)/)
          if (match && match[1] && match[2]) {
            res[match[1]] = match[2]
          }
          return res
        }, {})
        extend(rulesData, data)
        Object.keys(rulesData).forEach(rule => {
          if (!rulesData[rule]) { delete rulesData[rule] }
        })
        styleSheet.deleteRule(idx)
        styleSheet.insertRule(getCssText(selector, rulesData), rules.length - 1)
      }
    }
    else {
      styleSheet.insertRule(getCssText(selector, data), rules.length)
    }
  })
}
139155
function querySelectorOnBrowser(selector) {
        // stupid error catching here to stop the browser from printing null cannot be found to stdout
        var query;
        try {
            // do this to simulate a scroll to the bottom of the page to trigger loading of certain ajax elements
            //todo somehow this still doesnt work
            document.body.scrollTop = 0;
            document.body.scrollTop = 9999999999;
            //window.document.body.scrollTop = document.body.scrollHeight;
            query = document.querySelector(selector).innerHTML;

        } catch (exception) {
            return false;
        }
        return true;
    }
736503
function(selector) {
            selector = selector || '';
            selector = Selector._replaceShorthand(Y.Lang.trim(selector)); 
            var token = Selector._getToken(),     // one token per simple selector (left selector holds combinator)
                query = selector, // original query for debug report
                tokens = [],    // array of tokens
                found = false,  // whether or not any matches were found this pass
                match,         // the regex match
                test,
                i, parser;

            /*
                Search for selector patterns, store, and strip them from the selector string
                until no patterns match (invalid selector) or we run out of chars.

                Multiple attributes and pseudos are allowed, in any order.
                for example:
                    'form:first-child[type=button]:not(button)[lang|=en]'
            */
            outer:
            do {
                found = false; // reset after full pass
                for (i = 0; (parser = Selector._parsers[i++]);) {
                    if ( (match = parser.re.exec(selector)) ) { // note assignment
                        if (parser.name !== COMBINATOR ) {
                            token.selector = selector;
                        }
                        selector = selector.replace(match[0], ''); // strip current match from selector
                        if (!selector.length) {
                            token.last = true;
                        }

                        if (Selector._attrFilters[match[1]]) { // convert class to className, etc.
                            match[1] = Selector._attrFilters[match[1]];
                        }

                        test = parser.fn(match, token);
                        if (test === false) { // selector not supported
                            found = false;
                            break outer;
                        } else if (test) {
                            token.tests.push(test);
                        }

                        if (!selector.length || parser.name === COMBINATOR) {
                            tokens.push(token);
                            token = Selector._getToken(token);
                            if (parser.name === COMBINATOR) {
                                token.combinator = Y.Selector.combinators[match[1]];
                            }
                        }
                        found = true;
                    }
                }
            } while (found && selector.length);

            if (!found || selector.length) { // not fully parsed
                tokens = [];
            }
            return tokens;
        }
412920
function massageSelector(input) {
  var result = utils.clone(input);
  var wasAnded = false;
  if ('$and' in result) {
    result = mergeAndedSelectors(result['$and']);
    wasAnded = true;
  }

  if ('$not' in result) {
    //This feels a little like forcing, but it will work for now,
    //I would like to come back to this and make the merging of selectors a little more generic
    result['$not'] = mergeAndedSelectors([result['$not']]);
  }

  var fields = Object.keys(result);

  for (var i = 0; i < fields.length; i++) {
    var field = fields[i];
    var matcher = result[field];

    if (typeof matcher !== 'object' || matcher === null) {
      matcher = {$eq: matcher};
    } else if ('$ne' in matcher && !wasAnded) {
      // I put these in an array, since there may be more than one
      // but in the "mergeAnded" operation, I already take care of that
      matcher.$ne = [matcher.$ne];
    }
    result[field] = matcher;
  }

  return result;
}
326190
def parse_pseudo_open(self, sel, name, has_selector, iselector, index):
        """"""

        flags = FLG_PSEUDO | FLG_OPEN
        if name == ':not':
            flags |= FLG_NOT
        if name == ':has':
            flags |= FLG_RELATIVE

        sel.selectors.append(self.parse_selectors(iselector, index, flags))
        has_selector = True
        return has_selector
310466
function (selector) {
        var self = this, i, l, matches = [], item, match;

        // Compile string into selector expression
        if (typeof selector === "string") {
          selector = new Selector(selector);

          match = function (item) {
            return selector.match(item);
          };
        } else {
          // Use selector as matching function
          match = selector;
        }

        for (i = 0, l = self.length; i < l; i++) {
          item = self[i];

          if (match(item)) {
            matches.push(item);
          }
        }

        return new Collection(matches);
      }
195636
function isNodeMatchingSelector(tNode, selector) {
    ngDevMode && assertDefined(selector[0], 'Selector should have a tag name');
    var mode = 4 /* ELEMENT */;
    var nodeAttrs = tNode.attrs;
    var selectOnlyMarkerIdx = nodeAttrs ? nodeAttrs.indexOf(1 /* SelectOnly */) : -1;
    // When processing ":not" selectors, we skip to the next ":not" if the
    // current one doesn't match
    var skipToNextSelector = false;
    for (var i = 0; i < selector.length; i++) {
        var current = selector[i];
        if (typeof current === 'number') {
            // If we finish processing a :not selector and it hasn't failed, return false
            if (!skipToNextSelector && !isPositive(mode) && !isPositive(current)) {
                return false;
            }
            // If we are skipping to the next :not() and this mode flag is positive,
            // it's a part of the current :not() selector, and we should keep skipping
            if (skipToNextSelector && isPositive(current))
                continue;
            skipToNextSelector = false;
            mode = current | (mode & 1 /* NOT */);
            continue;
        }
        if (skipToNextSelector)
            continue;
        if (mode & 4 /* ELEMENT */) {
            mode = 2 /* ATTRIBUTE */ | mode & 1 /* NOT */;
            if (current !== '' && current !== tNode.tagName) {
                if (isPositive(mode))
                    return false;
                skipToNextSelector = true;
            }
        }
        else {
            var attrName = mode & 8 /* CLASS */ ? 'class' : current;
            var attrIndexInNode = findAttrIndexInNode(attrName, nodeAttrs);
            if (attrIndexInNode === -1) {
                if (isPositive(mode))
                    return false;
                skipToNextSelector = true;
                continue;
            }
            var selectorAttrValue = mode & 8 /* CLASS */ ? current : selector[++i];
            if (selectorAttrValue !== '') {
                var nodeAttrValue = void 0;
                var maybeAttrName = nodeAttrs[attrIndexInNode];
                if (selectOnlyMarkerIdx > -1 && attrIndexInNode > selectOnlyMarkerIdx) {
                    nodeAttrValue = '';
                }
                else {
                    ngDevMode && assertNotEqual(maybeAttrName, 0 /* NamespaceURI */, 'We do not match directives on namespaced attributes');
                    nodeAttrValue = nodeAttrs[attrIndexInNode + 1];
                }
                if (mode & 8 /* CLASS */ &&
                    !isCssClassMatching(nodeAttrValue, selectorAttrValue) ||
                    mode & 2 /* ATTRIBUTE */ && selectorAttrValue !== nodeAttrValue) {
                    if (isPositive(mode))
                        return false;
                    skipToNextSelector = true;
                }
            }
        }
    }
    return isPositive(mode) || skipToNextSelector;
}
600407
function overrideSelector(selectorContext) {
    selectorContext.overrideKeys[selectorContext.sourceKey] = true;
    selectorContext.sourceKeys[selectorContext.sourceKey] = selectorContext.targetKey;
}
1010598
function(selectors) {
		var curSelector;
		var elements;
		var attributeName;
		var attributeValue;
		var elementIndex;

		for(var selectorIndex = 0; selectorIndex < selectors.length; selectorIndex++) {
			curSelector = selectors[selectorIndex];
			elements = document.querySelectorAll(curSelector[0]);
			attributeName = 'data-' + curSelector[1];
			attributeValue = curSelector[2];

			if(!elements) {
				continue;
			}

			for(elementIndex = 0; elementIndex < elements.length; elementIndex++) {
				elements[elementIndex].setAttribute(attributeName, attributeValue);
			}
		}
	}