Bubble up from bottom to top

@param  {HTMLELement} node     - [description]
@param  {HTMLELement} root     - [description]
@param  {Function}    validate - [description]
@return {HTMLELement}          - [description]
775960
function getAncestor (node, root, validate) {
  while (node.parent) {
    node = node.parent
    if (validate(node)) {
      return node
    }
    if (node === root) {
      break
    }
  }
  return null
}
1307843
function simplifyDOM(root, atEnd) {
    var doc = root.ownerDocument;
    var result = [];
    var leaving = true;

    function simplifyNode(node, top) {
      if (node.nodeType == 3) {
        var text = node.nodeValue = fixSpaces(node.nodeValue.replace(/[\r\u200b]/g, "").replace(/\n/g, " "));
        if (text.length) leaving = false;
        result.push(node);
      }
      else if (isBR(node) && node.childNodes.length == 0) {
        leaving = true;
        result.push(node);
      }
      else {
        forEach(node.childNodes, simplifyNode);
        if (!leaving && newlineElements.hasOwnProperty(node.nodeName.toUpperCase())) {
          leaving = true;
          if (!atEnd || !top)
            result.push(doc.createElement("BR"));
        }
      }
    }

    simplifyNode(root, true);
    return result;
  }
117750
function prepareElementRoot() {

        P.$root.

            on({

                // For iOS8.
                keydown: handleKeydownEvent,

                // When something within the root is focused, stop from bubbling
                // to the doc and remove the “focused” state from the root.
                focusin: function( event ) {
                    P.$root.removeClass( CLASSES.focused )
                    event.stopPropagation()
                },

                // When something within the root holder is clicked, stop it
                // from bubbling to the doc.
                'mousedown click': function( event ) {

                    var target = event.target

                    // Make sure the target isn’t the root holder so it can bubble up.
                    if ( target != P.$root.children()[ 0 ] ) {

                        event.stopPropagation()

                        // * For mousedown events, cancel the default action in order to
                        //   prevent cases where focus is shifted onto external elements
                        //   when using things like jQuery mobile or MagnificPopup (ref: #249 & #120).
                        //   Also, for Firefox, don’t prevent action on the `option` element.
                        if ( event.type == 'mousedown' && !$( target ).is( 'input, select, textarea, button, option' )) {

                            event.preventDefault()

                            // Re-focus onto the root so that users can click away
                            // from elements focused within the picker.
                            P.$root[0].focus()
                        }
                    }
                }
            }).

            // Add/remove the “target” class on focus and blur.
            on({
                focus: function() {
                    $ELEMENT.addClass( CLASSES.target )
                },
                blur: function() {
                    $ELEMENT.removeClass( CLASSES.target )
                }
            }).

            // Open the picker and adjust the root “focused” state
            on( 'focus.toOpen', handleFocusToOpenEvent ).

            // If there’s a click on an actionable element, carry out the actions.
            on( 'click', '[data-pick], [data-nav], [data-clear], [data-close]', function() {

                var $target = $( this ),
                    targetData = $target.data(),
                    targetDisabled = $target.hasClass( CLASSES.navDisabled ) || $target.hasClass( CLASSES.disabled ),

                    // * For IE, non-focusable elements can be active elements as well
                    //   (http://stackoverflow.com/a/2684561).
                    activeElement = getActiveElement()
                    activeElement = activeElement && ( activeElement.type || activeElement.href )

                // If it’s disabled or nothing inside is actively focused, re-focus the element.
                if ( targetDisabled || activeElement && !$.contains( P.$root[0], activeElement ) ) {
                    P.$root[0].focus()
                }

                // If something is superficially changed, update the `highlight` based on the `nav`.
                if ( !targetDisabled && targetData.nav ) {
                    P.set( 'highlight', P.component.item.highlight, { nav: targetData.nav } )
                }

                // If something is picked, set `select` then close with focus.
                else if ( !targetDisabled && 'pick' in targetData ) {
                    P.set( 'select', targetData.pick )
                }

                // If a “clear” button is pressed, empty the values and close with focus.
                else if ( targetData.clear ) {
                    P.clear().close( true )
                }

                else if ( targetData.close ) {
                    P.close( true )
                }

            }) //P.$root

        aria( P.$root[0], 'hidden', true )
    }
447031
function isNodeInRoot(node, root) {
    node = ReactDOM.findDOMNode(node), root = ReactDOM.findDOMNode(root);
    return _isNodeInRoot(node, root);
}
748849
function(key, searchRoot) {
			// Search the DOM by element ID (assuming this is faster than traversing all nodes).
			var el, match;
			// TODO: use tree.keyMap if available
			// TODO: check opts.generateIds === true
			if (!searchRoot) {
				el = document.getElementById(this.options.idPrefix + key);
				if (el) {
					return el.ftnode ? el.ftnode : null;
				}
			}
			// Not found in the DOM, but still may be in an unrendered part of tree
			searchRoot = searchRoot || this.rootNode;
			match = null;
			searchRoot.visit(function(node) {
				if (node.key === key) {
					match = node;
					return false; // Stop iteration
				}
			}, true);
			return match;
		}
911376
function setStackTop (node, exclude = this.exclude) {
  const childCount = node.children.length
  const nodeIsExcluded = isNodeExcluded(node, exclude)
  let topTotal = node.onStackTop.base

  // Will be called many many times in browser, use vanilla for/i for speed
  for (var i = 0; i < childCount; i++) {
    // Add stack top of excluded children and chains of excluded descendents
    topTotal += setStackTop(node.children[i], exclude)
  }
  node.onStackTop.asViewed = nodeIsExcluded ? 0 : topTotal
  return nodeIsExcluded ? topTotal : 0
}
140529
function truncateNestedNodeStart($element, $rootNode, $clipNode, options) {
    var element = $element[0];

    var $children = $element.contents();
    var $child, child;

    var length = $children.length;
    var index = length -1;
    var truncated = false;

    $element.empty();

    for (; index >= 0 && !truncated; index--) {

      $child = $children.eq(index);
      child = $child[0];

      if (child.nodeType === 8) { // comment node
        continue;
      }

      element.insertBefore(child, element.firstChild);

      if ($clipNode.length) {
        if ($.inArray(element.tagName.toLowerCase(), BLOCK_TAGS) >= 0) {
          // Certain elements like <li> should not be appended to.
          $element.after($clipNode);
        } else {
          $element.append($clipNode);
        }
      }

      if ($rootNode.height() > options.maxHeight) {
        if (child.nodeType === 3) { // text node
          truncated = truncateTextContent($child, $rootNode, $clipNode, options);
        } else {
          truncated = truncateNestedNode($child, $rootNode, $clipNode, options);
        }
      }

      if (!truncated && $clipNode.length) {
        $clipNode.remove();
      }

    }

    return truncated;
  }
605715
function jsTreeCtrl() {
        /*jshint validthis:true */
        var nodeSerialId = 1;
        var vm = this;

        vm.nodesFingerprint = function (e) {
            if (!e.__uiNodeId) {
                e.__uiNodeId = nodeSerialId++;
            }
            return '' + e.__uiNodeId + (e.id || '') + (e.text || '') + (e.type || '');
        };

        vm.changeWatcher = function (arraySource, tokenFn) {
            var self;
            var getTokens = function () {
                var result = [], token, el;
                if (arraySource) {
                    var array = angular.isFunction(arraySource) ? arraySource() : arraySource;
                    for (var i = 0, n = array.length; i < n; i++) {
                        el = array[i];
                        token = tokenFn(el);
                        map[token] = el;
                        result.push(token);
                    }
                }
                return result;
            };
            // returns elements in that are in a but not in b
            // subtractAsSets([4, 5, 6], [4, 5, 7]) => [6]
            var subtractAsSets = function (a, b) {
                var result = [], inB = {}, i, n;
                for (i = 0, n = b.length; i < n; i++) {
                    inB[b[i]] = true;
                }
                for (i = 0, n = a.length; i < n; i++) {
                    if (!inB[a[i]]) {
                        result.push(a[i]);
                    }
                }
                return result;
            };

            // Map objects to tokens and vice-versa
            var map = {};

            var applyChanges = function (newTokens, oldTokens) {
                var i, n, el, token;
                var replacedTokens = {};
                var removedTokens = subtractAsSets(oldTokens, newTokens);
                for (i = 0, n = removedTokens.length; i < n; i++) {
                    var removedToken = removedTokens[i];
                    el = map[removedToken];
                    delete map[removedToken];
                    var newToken = tokenFn(el);
                    // if the element wasn't removed but simply got a new token, its old token will be different from the current one
                    if (newToken === removedToken) {
                        self.onRemoved(el);
                    } else {
                        replacedTokens[newToken] = removedToken;
                        self.onChanged(el);
                    }
                }

                var addedTokens = subtractAsSets(newTokens, oldTokens);
                for (i = 0, n = addedTokens.length; i < n; i++) {
                    token = addedTokens[i];
                    el = map[token];
                    if (!replacedTokens[token]) {
                        self.onAdded(el);
                    }
                }

            };
            self = {
                subscribe: function (scope, onChanged) {
                    scope.$watch(getTokens, function (newTokens, oldTokens) {
                        if (!onChanged || onChanged(newTokens, oldTokens) !== false) {
                            applyChanges(newTokens, oldTokens);
                        }
                    }, true);
                },
                onAdded: angular.noop,
                onChanged: angular.noop,
                onRemoved: angular.noop
            };
            return self;
        };
    }
914791
function (node) {
        if (node.properties.length === 0) {
          return
        }

        var first = context.getFirstToken(node)
        var second = context.getFirstToken(node, 1)
        var penultimate = context.getLastToken(node, 1)
        var last = context.getLastToken(node)

        validateBraceSpacing(node, first, second, penultimate, last)
      }
324624
function processTopLevelNode (node, expectedIndent) {
    const token = tokenStore.getFirstToken(node)
    const offsetInfo = offsets.get(token)
    if (offsetInfo != null) {
      offsetInfo.expectedIndent = expectedIndent
    } else {
      offsets.set(token, { baseToken: null, offset: 0, baseline: false, expectedIndent })
    }
  }
719421
function(node, e){
			if (node){
				var currMousePos = e.position || e.cyPosition;
				var topLeft = {
					x: (node.position("x") - node.width() / 2 - parseFloat(node.css('padding-left'))),
					y: (node.position("y") - node.height() / 2 - parseFloat(node.css('padding-top')))};
				var bottomRight = {
					x: (node.position("x") + node.width() / 2 + parseFloat(node.css('padding-right'))),
					y: (node.position("y") + node.height() / 2+ parseFloat(node.css('padding-bottom')))};

				if (currMousePos.x >= topLeft.x && currMousePos.y >= topLeft.y &&
					currMousePos.x <= bottomRight.x && currMousePos.y <= bottomRight.y){
					return true;
				}
			}
			return false;
		}
553020
function rule( context ) {
	/**
	* FUNCTION: validateLiteral( node )
	*	Validates a regular expression literal.
	*
	* @param {Node} node - AST node
	* @returns {Void}
	*/
	function validateLiteral( node ) {
		var token = context.getTokens( node )[ 0 ];
		if (
			token.type === 'RegularExpression' &&
			!safe( token.value )
		) {
			context.report( node, 'Unsafe regular expression' );
		}
	} // end FUNCTION validateLiteral()

	/**
	* FUNCTION: validateExpression( node )
	*	Validates a regular expression creating using the `RegExp` constructor.
	*
	* @param {Node} node - AST node
	* @returns {Void}
	*/
	function validateExpression( node ) {
		var args,
			len,
			re,
			i;

		if ( node.callee.name === 'RegExp' ) {
			len = node.arguments.length;
			args = new Array( node.arguments.length );
			for ( i = 0; i < len; i++ ) {
				// NOTE: we only support literals ATM. Otherwise, we may need to walk and implement an entire tree.
				if ( node.arguments[ i ].type !== 'Literal' ) {
					return;
				}
				args[ i ] = node.arguments[ i ].value;
			}
			re = RegExp.apply( null, args );
			if ( !safe( re ) ) {
				context.report( node, 'Unsafe regular expression' );
			}
		}
	} // end FUNCTION validateExpression()

	return {
		'Literal': validateLiteral,
		'NewExpression': validateExpression,
		'CallExpression': validateExpression
	};
}
1031281
void bofFixup() {
           //
           //   The parse tree looks like this ...
           //         fTree root  --.       <cat>
           //                               /     \
           //                            <cat>   <#end node>
           //                           /     \
           //                     <bofNode>   rest
           //                               of tree
           //
           //    We will be adding things to the followPos set of the <bofNode>
           //
           RBBINode  bofNode = fRB.fTreeRoots[fRootIx].fLeftChild.fLeftChild;
           Assert.assrt(bofNode.fType == RBBINode.leafChar);
           Assert.assrt(bofNode.fVal == 2);

           // Get all nodes that can be the start a match of the user-written rules
           //  (excluding the fake bofNode)
           //  We want the nodes that can start a match in the
           //     part labeled "rest of tree"
           //
           Set<RBBINode> matchStartNodes = fRB.fTreeRoots[fRootIx].fLeftChild.fRightChild.fFirstPosSet;
           for (RBBINode startNode : matchStartNodes) {
               if (startNode.fType != RBBINode.leafChar) {
                   continue;
               }

               if (startNode.fVal == bofNode.fVal) {
                   //  We found a leaf node corresponding to a {bof} that was
                   //    explicitly written into a rule.
                   //  Add everything from the followPos set of this node to the
                   //    followPos set of the fake bofNode at the start of the tree.
                   //
                   bofNode.fFollowPos.addAll(startNode.fFollowPos);
               }
           }
       }
567942
function (root) {
    var children = root.children();
    for (var i = 0; i < children.length; i++) {
      var node = children[i];
      this.collapseBottomUp(node);
    }
    //If the root is a compound node to be collapsed then collapse it
    if (root.data("collapse") && root.children().length > 0) {
      this.collapseNode(root);
      root.removeData("collapse");
    }
  }
1316774
function(){
            var start = this.startContainer;
            if(this.collapsed && start.nodeType == 3
                && start.nodeValue.replace(new RegExp('^' + domUtils.fillChar),'').length + 1 == start.nodeValue.length
                ){
                return true;
            }
            return false;
        }
608951
function moveToCaretPosition(root) {
          var walker, node, rng, lastNode = root, tempElm;

          if (!root) {
            return;
          }

          // Old IE versions doesn't properly render blocks with br elements in them
          // For example <p><br></p> wont be rendered correctly in a contentEditable area
          // until you remove the br producing <p></p>
          if (Env.ie && Env.ie < 9 && parentBlock && parentBlock.firstChild) {
            if (parentBlock.firstChild == parentBlock.lastChild && parentBlock.firstChild.tagName == 'BR') {
              dom.remove(parentBlock.firstChild);
            }
          }

          if (/^(LI|DT|DD)$/.test(root.nodeName)) {
            var firstChild = firstNonWhiteSpaceNodeSibling(root.firstChild);

            if (firstChild && /^(UL|OL|DL)$/.test(firstChild.nodeName)) {
              root.insertBefore(dom.doc.createTextNode('\u00a0'), root.firstChild);
            }
          }

          rng = dom.createRng();

          // Normalize whitespace to remove empty text nodes. Fix for: #6904
          // Gecko will be able to place the caret in empty text nodes but it won't render propery
          // Older IE versions will sometimes crash so for now ignore all IE versions
          if (!Env.ie) {
            root.normalize();
          }

          if (root.hasChildNodes()) {
            walker = new TreeWalker(root, root);

            while ((node = walker.current())) {
              if (node.nodeType == 3) {
                rng.setStart(node, 0);
                rng.setEnd(node, 0);
                break;
              }

              if (moveCaretBeforeOnEnterElementsMap[node.nodeName.toLowerCase()]) {
                rng.setStartBefore(node);
                rng.setEndBefore(node);
                break;
              }

              lastNode = node;
              node = walker.next();
            }

            if (!node) {
              rng.setStart(lastNode, 0);
              rng.setEnd(lastNode, 0);
            }
          } else {
            if (root.nodeName == 'BR') {
              if (root.nextSibling && dom.isBlock(root.nextSibling)) {
                // Trick on older IE versions to render the caret before the BR between two lists
                if (!documentMode || documentMode < 9) {
                  tempElm = dom.create('br');
                  root.parentNode.insertBefore(tempElm, root);
                }

                rng.setStartBefore(root);
                rng.setEndBefore(root);
              } else {
                rng.setStartAfter(root);
                rng.setEndAfter(root);
              }
            } else {
              rng.setStart(root, 0);
              rng.setEnd(root, 0);
            }
          }

          selection.setRng(rng);

          // Remove tempElm created for old IE:s
          dom.remove(tempElm);
          selection.scrollIntoView(root);
        }
605540
function validate (rootPath) {
  var manifest;
  var webextensionManifest;

  var errors = {};

  try {
    manifest = JSON.parse(fs.readFileSync(join(rootPath, "package.json")));
  } catch (e) {
    errors.parsing = utils.getErrorMessage("COULD_NOT_PARSE") + "\n" + e.message;
    return errors;
  }

  if (!validateID(manifest)) {
    errors.id = utils.getErrorMessage("INVALID_ID");
  }

  if (!validateMain(rootPath)) {
    errors.main = utils.getErrorMessage("MAIN_DNE");
  }

  if (!validateTitle(manifest)) {
    errors.title = utils.getErrorMessage("INVALID_TITLE");
  }

  if (!validateName(manifest)) {
    errors.name = utils.getErrorMessage("INVALID_NAME");
  }

  if (!validateVersion(manifest)) {
    errors.version = utils.getErrorMessage("INVALID_VERSION");
  }

  // If both a package.json and a manifest.json files exists in the addon
  // root dir, raise an helpful error message that suggest to use web-ext instead.
  if (fs.existsSync(join(rootPath, "manifest.json"))) {
    errors.webextensionManifestFound = utils.getErrorMessage("WEBEXT_ERROR");
  }

  return errors;
}